Skip to content

Repair

Location: dg_smart_pos_api/modules/Repair. Owns the repair-shop job card workflow end to end: intake (from a walk-in customer, or from a device already in shop stock), diagnosis and status tracking, parts consumption from stock, outsourcing to third-party vendors, payments, and collection. It uses its own RepairCustomer model, entirely separate from Sale Customers, and moves stock through RepairStockService, which calls Modules\Inventory\Services\InventoryAdjustmentService, rather than owning stock adjustments itself.

Gated per store by the enable_repair_module system config, enforced by the system.config:enable_repair_module route middleware on the whole route group, confirmed in modules/Repair/Routes/repair.php.

  • RepairJobCard - the job itself: source (customer/shop_stock), item details, dates, amounts computed on the model (laborAmount(), partsTotal(), paidTotal(), balance()), current status.
  • RepairJobCardPart - a stock part consumed on a job.
  • RepairJobCardPropertyValue - a value for one of the item type’s custom properties.
  • RepairCustomer - repair-specific clientele (a phone lookup may return several; distinct from SaleCustomer and from the base customers table).
  • RepairItemType / RepairItemTypeProperty - configurable device categories and their custom fields.
  • RepairVendor - an outsourcing vendor.
  • RepairOutsourcing - a job sent to a vendor.
  • RepairPayment - a payment against a job.
  • RepairStatusHistory - an audit trail row per status transition.
  • RepairJobCounter - backs sequential job_number generation (RepairJobNumberService).

RepairJobCardController::store takes source (customer or shop_stock), either a repair_customer_id or inline customer details (name/phone required together), optional custom property_values, and an optional initial_payment. If source is customer (the default), the request is rejected unless an existing client or a new name+phone is supplied. If source is shop_stock, stock_id is required and RepairJobCardService::create calls RepairStockService::deviceOut, moving the device out of sellable inventory via InventoryAdjustmentService (action RepairOut).

RepairJobCardController::transition moves a job through RepairStatus’s explicit transition graph (RepairStatus::allowedTransitions()): received -> diagnosing -> {awaiting_approval, in_repair} -> ... -> {repaired, unrepairable} -> collected, with cancelled reachable from every non-terminal state up through in_repair. repaired and unrepairable can only move on to collected; collected and cancelled are terminal. A job card’s other fields can no longer be edited once its status is terminal (isTerminal()).

RepairJobCardController::collect is the endpoint that actually closes out a customer job: RepairPartService::collect sells the consumed parts through a real POS sale, records any remaining labor balance as a RepairPayment, and transitions the job to collected, all in one transaction. Waiving an outstanding balance (waive_balance) requires the caller to be an admin, checked inline in the controller by matching role names, rather than through the permission: middleware the rest of the module uses.

RepairPartController::store draws a part from stock onto a job card; writeOff marks a part unusable without returning it to stock. RepairOutsourcingController sends a job to a RepairVendor and updates it on return.

All under auth:sanctum + system.config:enable_repair_module, prefix repairs/stores/{store}, registered via modules/Repair/Routes/repair.php (required once from routes/tenant.php):

Method Path Controller method Permission
POST item-types RepairItemTypeController::store store:edit-settings
PUT item-types/{itemType} RepairItemTypeController::update store:edit-settings
DELETE item-types/{itemType} RepairItemTypeController::destroy store:edit-settings
POST item-types/{itemType}/properties RepairPropertyController::store store:edit-settings
PUT properties/{property} RepairPropertyController::update store:edit-settings
DELETE properties/{property} RepairPropertyController::destroy store:edit-settings
POST vendors RepairVendorController::store store:edit-settings
PUT vendors/{vendor} RepairVendorController::update store:edit-settings
DELETE vendors/{vendor} RepairVendorController::destroy store:edit-settings
GET item-types RepairItemTypeController::index (none)
GET item-types/{itemType}/properties RepairPropertyController::index (none)
GET vendors RepairVendorController::index (none)
GET vendors/{vendor}/summary RepairVendorController::summary (none)
GET customers RepairCustomerController::index (none)
POST customers RepairCustomerController::store (none)
PUT customers/{customer} RepairCustomerController::update (none)
GET job-cards RepairJobCardController::index (none)
GET job-cards/stats RepairJobCardController::stats (none)
POST job-cards RepairJobCardController::store (none)
GET job-cards/{jobCard} RepairJobCardController::show (none)
PUT job-cards/{jobCard} RepairJobCardController::update (none)
POST job-cards/{jobCard}/status RepairJobCardController::transition (none)
POST job-cards/{jobCard}/collect RepairJobCardController::collect (none)
POST job-cards/{jobCard}/payments RepairPaymentController::store (none)
DELETE payments/{payment} RepairPaymentController::destroy sales:delete
POST job-cards/{jobCard}/parts RepairPartController::store (none)
DELETE parts/{part} RepairPartController::destroy (none)
POST parts/{part}/write-off RepairPartController::writeOff (none)
POST job-cards/{jobCard}/outsourcings RepairOutsourcingController::store (none)
PUT outsourcings/{outsourcing} RepairOutsourcingController::update (none)

“(none)” means only auth:sanctum and the module-enabled gate apply, no permission: middleware wraps that specific route.