{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"AppController_getHello","parameters":[],"responses":{"200":{"description":""}},"tags":["App"]}},"/api/users":{"get":{"operationId":"UserController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserResponseDto"}}}}]}}}}},"summary":"Get all users (optional pagination)","tags":["Users"]},"post":{"operationId":"UserController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/UserResponseDto"}}}]}}}}},"summary":"Create user","tags":["Users"]}},"/api/users/{id}":{"get":{"operationId":"UserController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/UserResponseDto"}}}]}}}}},"summary":"Get user by ID","tags":["Users"]},"put":{"operationId":"UserController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/UserResponseDto"}}}]}}}}},"summary":"Update user","tags":["Users"]},"delete":{"operationId":"UserController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Delete user","tags":["Users"]}},"/api/auth/login":{"post":{"operationId":"AuthController_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/LoginResponseDto"}}}]}}}}},"summary":"Login user","tags":["Auth"]}},"/api/auth/forgot-password":{"post":{"operationId":"AuthController_forgotPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Request password reset email","tags":["Auth"]}},"/api/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Reset user password","tags":["Auth"]}},"/api/auth/logout":{"post":{"operationId":"AuthController_logout","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Logout user","tags":["Auth"]}},"/api/voyages":{"get":{"operationId":"VoyageController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VoyageResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get all voyages (optional pagination)","tags":["Voyages"]},"post":{"operationId":"VoyageController_create","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateVoyageRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create a new voyage","tags":["Voyages"]}},"/api/voyages/stats":{"get":{"operationId":"VoyageController_getStats","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageStatsResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Voyage statistics (no filters)","tags":["Voyages"]}},"/api/voyages/{id}":{"get":{"operationId":"VoyageController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get voyage by ID","tags":["Voyages"]},"put":{"operationId":"VoyageController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UpdateVoyageRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update a voyage by stage","tags":["Voyages"]},"delete":{"operationId":"VoyageController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Delete a voyage","tags":["Voyages"]}},"/api/voyages/v2":{"post":{"description":"Versi baru create voyage dengan named file fields. Tidak perlu field `metas` JSON — category dan uploader di-derive otomatis dari nama field. OWNER/TC: wajib files_si_customer + files_spal_customer. FC: wajib semua 4 file fields.","operationId":"VoyageController_createV2","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateVoyageV2RequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create a new voyage (v2)","tags":["Voyages"]}},"/api/voyages/{id}/stages/invoice-dp":{"put":{"description":"Maju ke stage INVOICE_DP. action=EXECUTE: kirim data invoice (items, dp_percentage, pajak) — BE generate PDF otomatis. action=SKIP: tidak perlu data, stage tetap tercatat sebagai skip.","operationId":"VoyageController_stageInvoiceDp","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceDpStageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Stage: INVOICE_DP (v2)","tags":["Voyages"]}},"/api/voyages/{id}/stages/draft-survey":{"put":{"description":"Maju ke stage DRAFT_SURVEY. Wajib file dan data hasil survey.","operationId":"VoyageController_stageDraftSurvey","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/DraftSurveyStageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Stage: DRAFT_SURVEY (v2)","tags":["Voyages"]}},"/api/voyages/{id}/stages/invoice-full":{"put":{"description":"Maju ke stage INVOICE_FULL. Wajib file invoice pelunasan.","operationId":"VoyageController_stageInvoiceFull","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/InvoiceFullStageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Stage: INVOICE_FULL (v2)","tags":["Voyages"]}},"/api/voyages/{id}/stages/prorata":{"put":{"description":"Maju ke stage PRORATA. Isi 4 timestamp untuk kalkulasi otomatis. Tidak ada file. Response menyertakan prorata_summary (is_demurrage, overage_days, dll).","operationId":"VoyageController_stageProrata","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProrataStageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Stage: PRORATA (v2)","tags":["Voyages"]}},"/api/voyages/{id}/stages/demurrage":{"put":{"description":"Maju ke stage DEMURRAGE. action=EXECUTE: wajib files_invoice_demurrage, opsional files_supporting_demurrage. action=SKIP: tidak perlu file.","operationId":"VoyageController_stageDemurrage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/DemurrageStageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Stage: DEMURRAGE (v2)","tags":["Voyages"]}},"/api/voyages/{id}/stages/completed":{"put":{"description":"Maju ke stage COMPLETED. files_other opsional (maks 5).","operationId":"VoyageController_stageCompleted","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CompletedStageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Stage: COMPLETED (v2)","tags":["Voyages"]}},"/api/voyages/{id}/full":{"put":{"operationId":"VoyageController_updateFull","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UpdateVoyageFullRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VoyageDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Full update voyage","tags":["Voyages"]}},"/api/vessels":{"get":{"operationId":"VesselController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VesselResponseDto"}}}}]}}}}},"summary":"Get all vessels (optional pagination)","tags":["Vessels"]},"post":{"operationId":"VesselController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVesselRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VesselResponseDto"}}}]}}}}},"summary":"Create a new vessel","tags":["Vessels"]}},"/api/vessels/{id}":{"get":{"operationId":"VesselController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VesselResponseDto"}}}]}}}}},"summary":"Get vessel by ID","tags":["Vessels"]},"put":{"operationId":"VesselController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVesselRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VesselResponseDto"}}}]}}}}},"summary":"Update a vessel","tags":["Vessels"]},"delete":{"operationId":"VesselController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Soft delete a vessel (sets flag = 2)","tags":["Vessels"]}},"/api/vendors":{"get":{"operationId":"VendorController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VendorResponseDto"}}}}]}}}}},"summary":"Get all vendors (optional pagination)","tags":["Vendors"]},"post":{"operationId":"VendorController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVendorRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorResponseDto"}}}]}}}}},"summary":"Create a new vendor","tags":["Vendors"]}},"/api/vendors/{id}":{"get":{"operationId":"VendorController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorResponseDto"}}}]}}}}},"summary":"Get vendor by ID","tags":["Vendors"]},"put":{"operationId":"VendorController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVendorRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorResponseDto"}}}]}}}}},"summary":"Update a vendor","tags":["Vendors"]},"delete":{"operationId":"VendorController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Delete a vendor","tags":["Vendors"]}},"/api/customers":{"get":{"operationId":"CustomerController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CustomerResponseDto"}}}}]}}}}},"summary":"Get all customers (optional pagination)","tags":["Customers"]},"post":{"operationId":"CustomerController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/CustomerResponseDto"}}}]}}}}},"summary":"Create a new customer","tags":["Customers"]}},"/api/customers/{id}":{"get":{"operationId":"CustomerController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/CustomerResponseDto"}}}]}}}}},"summary":"Get customer by ID","tags":["Customers"]},"put":{"operationId":"CustomerController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomerRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/CustomerResponseDto"}}}]}}}}},"summary":"Update a customer","tags":["Customers"]},"delete":{"operationId":"CustomerController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Delete a customer","tags":["Customers"]}},"/api/approval-workflows":{"get":{"operationId":"ApprovalWorkflowsController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalWorkflowResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get all approval workflows (optional pagination)","tags":["Approval Workflows"]},"post":{"operationId":"ApprovalWorkflowsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalWorkflowRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ApprovalWorkflowResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create a new approval workflow","tags":["Approval Workflows"]}},"/api/approval-workflows/{id}":{"get":{"operationId":"ApprovalWorkflowsController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ApprovalWorkflowResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get approval workflow by ID","tags":["Approval Workflows"]},"put":{"operationId":"ApprovalWorkflowsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateApprovalWorkflowRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ApprovalWorkflowResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update an approval workflow","tags":["Approval Workflows"]},"delete":{"operationId":"ApprovalWorkflowsController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Delete an approval workflow","tags":["Approval Workflows"]}},"/api/approval-requests":{"post":{"operationId":"ApprovalRequestsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApprovalRequestDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Submit approval request","tags":["Approval Requests"]}},"/api/approval-requests/{id}":{"get":{"operationId":"ApprovalRequestsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get approval request detail","tags":["Approval Requests"]}},"/api/approval-tasks/inbox":{"get":{"operationId":"ApprovalTasksController_inbox","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Get pending tasks for current user (paginated)","tags":["Approval Tasks"]}},"/api/approval-tasks/{taskId}/decide":{"post":{"operationId":"ApprovalTasksController_decide","parameters":[{"name":"taskId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecideApprovalTaskDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Approve/Reject a task","tags":["Approval Tasks"]}},"/api/references/{entity}":{"get":{"operationId":"ReferenceController_getAll","parameters":[{"name":"entity","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ReferenceResponseDto"}}}}]}}}}},"summary":"Get reference data dynamically by entity","tags":["References"]},"post":{"operationId":"ReferenceController_create","parameters":[{"name":"entity","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Body mengikuti field entity...","content":{"application/json":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ReferenceResponseDto"}}}]}}}}},"summary":"Create reference (dynamic entity)","tags":["References"]}},"/api/references/{entity}/{id}":{"get":{"operationId":"ReferenceController_getOne","parameters":[{"name":"entity","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ReferenceResponseDto"}}}]}}}}},"summary":"Get reference by ID (dynamic entity)","tags":["References"]},"put":{"operationId":"ReferenceController_update","parameters":[{"name":"entity","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ReferenceResponseDto"}}}]}}}}},"summary":"Update reference (dynamic entity)","tags":["References"]},"delete":{"operationId":"ReferenceController_delete","parameters":[{"name":"entity","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ReferenceResponseDto"}}}]}}}}},"summary":"Delete reference (dynamic entity)","tags":["References"]}},"/api/monitoring/logs":{"get":{"operationId":"MonitoringController_getLogs","parameters":[],"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/api/monitoring/metrics":{"get":{"operationId":"MonitoringController_getMetrics","parameters":[],"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/api/monitoring/stream":{"get":{"operationId":"MonitoringController_stream","parameters":[],"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/api/monitoring":{"get":{"operationId":"MonitoringUiController_getPage","parameters":[],"responses":{"200":{"description":""}},"tags":["MonitoringUi"]}},"/api/contracts/templates":{"get":{"operationId":"ContractTemplateController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ContractTemplateResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get all contract templates (optional pagination)","tags":["Contract Templates"]},"post":{"operationId":"ContractTemplateController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContractTemplateRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractTemplateResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create a new contract template (DRAFT)","tags":["Contract Templates"]}},"/api/contracts/templates/{id}":{"get":{"operationId":"ContractTemplateController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractTemplateResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get template by ID","tags":["Contract Templates"]},"put":{"operationId":"ContractTemplateController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContractTemplateRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractTemplateResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update a contract template (DRAFT)","tags":["Contract Templates"]},"delete":{"operationId":"ContractTemplateController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Soft delete a template (flag=2)","tags":["Contract Templates"]}},"/api/contracts/templates/{id}/versions":{"get":{"operationId":"ContractTemplateController_listVersions","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ContractTemplateVersionResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List published versions (snapshots)","tags":["Contract Templates"]}},"/api/contracts/templates/{id}/versions/{version}":{"get":{"operationId":"ContractTemplateController_getVersion","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"version","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractTemplateVersionResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get a specific published version snapshot","tags":["Contract Templates"]}},"/api/contracts/templates/{id}/publish":{"put":{"operationId":"ContractTemplateController_publish","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishTemplateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractTemplateResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Publish a template (create immutable snapshot, version++)","tags":["Contract Templates"]}},"/api/contracts/templates/{id}/field-registry":{"get":{"operationId":"ContractTemplateController_getFieldRegistryLatest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/TemplateFieldRegistryResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get latest field registry (from latest PUBLISHED snapshot)","tags":["Contract Templates"]}},"/api/contracts/templates/{id}/field-registry/{version}":{"get":{"operationId":"ContractTemplateController_getFieldRegistry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"version","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/TemplateFieldRegistryResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get field registry for a specific published version","tags":["Contract Templates"]}},"/api/contracts/templates/{id}/field-registry/rebuild":{"post":{"operationId":"ContractTemplateController_rebuildFieldRegistry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"version","required":true,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TemplateFieldRegistryResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"Rebuild field registry from snapshots (all or specific version)","tags":["Contract Templates"]}},"/api/contracts/templates/{id}/clone":{"post":{"operationId":"ContractTemplateController_clone","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloneContractTemplateRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractTemplateResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Clone a template (from DRAFT or PUBLISHED) into a new DRAFT template","tags":["Contract Templates"]}},"/api/contracts/generate":{"post":{"operationId":"ContractDocumentController_generate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateContractRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractDocumentResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Generate a contract document (PDF/DOCX)","tags":["Contracts"]}},"/api/contracts/preview":{"post":{"operationId":"ContractDocumentController_preview","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewContractRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractPreviewResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Preview a SAVED template (DRAFT or PUBLISHED). Does not persist or upload.","tags":["Contracts"]}},"/api/contracts/preview-draft":{"post":{"operationId":"ContractDocumentController_previewDraft","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewDraftTemplateRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractPreviewResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Preview an UNSAVED draft coming directly from the template builder (raw content). No DB read/write.","tags":["Contracts"]}},"/api/contracts/generate/validate":{"post":{"operationId":"ContractDocumentController_validate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateGenerateRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ValidateGenerateResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Dry-run validate payload against Field Registry (no render, no upload)","tags":["Contracts"]}},"/api/contracts/assets":{"get":{"operationId":"ContractAssetController_list","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ContractAssetResponseDto"}}}}]}}}}},"summary":"List assets (filter by type/status)","tags":["Contract Assets"]},"post":{"operationId":"ContractAssetController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContractAssetDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractAssetResponseDto"}}}]}}}}},"summary":"Create HEADER/FOOTER asset","tags":["Contract Assets"]}},"/api/contracts/assets/{id}":{"get":{"operationId":"ContractAssetController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractAssetResponseDto"}}}]}}}}},"summary":"Get asset by ID","tags":["Contract Assets"]},"put":{"operationId":"ContractAssetController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContractAssetDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractAssetResponseDto"}}}]}}}}},"summary":"Update HEADER/FOOTER asset","tags":["Contract Assets"]},"delete":{"operationId":"ContractAssetController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"summary":"Soft delete asset","tags":["Contract Assets"]}},"/api/contracts/assets/{id}/publish":{"put":{"operationId":"ContractAssetController_publish","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ContractAssetResponseDto"}}}]}}}}},"summary":"Publish asset","tags":["Contract Assets"]}},"/api/inventory-items":{"get":{"description":"Retrieve a paginated list of active and draft inventory items with optional filters. Supports filtering by category, type, and cost category. Default sorting by description ascending. Returns items with flag=1 (active) or flag=2 (draft), excludes non-active items (flag=3).","operationId":"InventoryItemController_findAll","parameters":[{"name":"category","required":false,"in":"query","description":"Filter by product categories (multiple values supported)","schema":{"example":["SAFETY_EQUIPMENT","DECK_SUPPLIES"],"type":"array","items":{"type":"string","enum":["SAFETY_EQUIPMENT","NAVIGATION_EQUIPMENT","MACHINERY_PARTS","ELECTRICAL_COMPONENTS","DECK_SUPPLIES","ENGINE_SUPPLIES","GALLEY_SUPPLIES","CABIN_SUPPLIES"]}}},{"name":"type","required":false,"in":"query","description":"Filter by product types (multiple values supported)","schema":{"example":["EQUIPMENT","SPARE_PART"],"type":"array","items":{"type":"string","enum":["CONSUMABLE","SPARE_PART","EQUIPMENT","TOOL","MATERIAL","CHEMICAL","ELECTRONIC","MECHANICAL"]}}},{"name":"cost_category","required":false,"in":"query","description":"Filter by cost categories (multiple values supported)","schema":{"example":["SAFETY","EQUIPMENT"],"type":"array","items":{"type":"string","enum":["PROPERTY","EQUIPMENT","OPERATIONAL","MAINTENANCE","ADMINISTRATIVE","SAFETY"]}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/InventoryItemResponseDto"}}}}]}}}},"401":{"description":"Unauthorized - Invalid or missing JWT token","content":{"application/json":{"schema":{"example":{"statusCode":401,"message":"Unauthorized"}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"example":{"statusCode":500,"message":"An error occurred while retrieving inventory items."}}}}}},"security":[{"bearer":[]}],"summary":"Get all inventory items (optional pagination)","tags":["Inventory Items"]}},"/api/inventory-items/{id}":{"get":{"description":"Retrieve detailed information of a specific inventory item by its ID. Returns items with flag=1 (active) or flag=2 (draft), excludes non-active items (flag=3).","operationId":"InventoryItemController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/InventoryItemResponseDto"}}}]}}}},"400":{"description":"Bad Request - Invalid ID format","content":{"application/json":{"schema":{"example":{"statusCode":400,"message":"Validation failed (numeric string is expected)","error":"Bad Request"}}}}},"401":{"description":"Unauthorized - Invalid or missing JWT token","content":{"application/json":{"schema":{"example":{"statusCode":401,"message":"Unauthorized"}}}}},"404":{"description":"Not Found - Inventory item does not exist","content":{"application/json":{"schema":{"example":{"statusCode":404,"message":"Inventory item not found."}}}}}},"security":[{"bearer":[]}],"summary":"Get inventory item by ID","tags":["Inventory Items"]},"patch":{"description":"Update an inventory item. Only product_category, product_type, and description can be modified. Other fields (quantity, cost, sales_price) are locked and cannot be changed. Attempting to update locked fields will result in 400 error.","operationId":"InventoryItemController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInventoryItemDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/InventoryItemResponseDto"}}}]}}}},"400":{"description":"Bad Request - Invalid fields or validation error","content":{"application/json":{"schema":{"examples":{"lockedFields":{"value":{"statusCode":400,"message":"Only product_category, product_type, and description can be updated."},"summary":"Attempting to update locked fields"},"validationError":{"value":{"statusCode":400,"message":["Description cannot be empty","Product category must be a valid enum value"],"error":"Bad Request"},"summary":"Validation errors"}}}}}},"401":{"description":"Unauthorized - Invalid or missing JWT token","content":{"application/json":{"schema":{"example":{"statusCode":401,"message":"Unauthorized"}}}}},"404":{"description":"Not Found - Inventory item does not exist","content":{"application/json":{"schema":{"example":{"statusCode":404,"message":"Inventory item not found."}}}}}},"security":[{"bearer":[]}],"summary":"Update inventory item (restricted fields only)","tags":["Inventory Items"]},"delete":{"description":"Perform a soft delete on an inventory item by setting flag=3 (non-active). The item will no longer appear in listing but remains in database for audit purposes. This operation is irreversible through the API.","operationId":"InventoryItemController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}},"400":{"description":"Bad Request - Invalid ID format","content":{"application/json":{"schema":{"example":{"statusCode":400,"message":"Validation failed (numeric string is expected)","error":"Bad Request"}}}}},"401":{"description":"Unauthorized - Invalid or missing JWT token","content":{"application/json":{"schema":{"example":{"statusCode":401,"message":"Unauthorized"}}}}},"404":{"description":"Not Found - Inventory item does not exist or already deleted","content":{"application/json":{"schema":{"example":{"statusCode":404,"message":"Inventory item not found."}}}}}},"security":[{"bearer":[]}],"summary":"Soft delete inventory item","tags":["Inventory Items"]}},"/api/purchase/purchase-requests":{"get":{"description":"Supports:\n- `search` — across reference_code, source_document, description\n- `filters` — JSON: status, department, purchase_team\n- `sortBy` / `sortOrder`\n- `page` / `limit`\n\nResponse does **not** include line items or files — use the detail endpoint for those.","operationId":"PurchaseRequestController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseRequestListResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List all Purchase Requests","tags":["Purchase > Purchase Requests"]},"post":{"description":"Creates a PR in **DRAFT** status, then submits to approval → **TO_BE_APPROVED**.\n\n**Content-Type:** `multipart/form-data`\n\n- `created_by` — auto-populated from JWT, do not pass in body.\n- `items` — JSON string. Minimum 1 item required.\n- `files` — Optional. Max 10 files, 10MB each. Allowed: PDF, JPG, PNG, DOC, DOCX, XLS, XLSX.\n\n**Example items:**\n`[{\"id_item\":1,\"item_name_snapshot\":\"HFO 380\",\"id_uom\":3,\"uom_snapshot\":\"MT\",\"qty_requested\":500}]`","operationId":"PurchaseRequestController_create","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreatePurchaseRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/PurchaseRequestDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create a new Purchase Request","tags":["Purchase > Purchase Requests"]}},"/api/purchase/purchase-requests/{id}":{"get":{"description":"Includes line items, inventory item info, full user objects for all actors, and uploaded files.","operationId":"PurchaseRequestController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/PurchaseRequestDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get Purchase Request detail","tags":["Purchase > Purchase Requests"]}},"/api/purchase/purchase-requests/{prId}/rfq":{"get":{"description":"Returns all RFQs created from this Purchase Request across all vendors.","operationId":"PurchaseRequestController_getRfqs","parameters":[{"name":"prId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RfqListResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List all RFQs derived from this PR","tags":["Purchase > Purchase Requests"]},"post":{"description":"PR must be in **APPROVED** status.\nRFQ is created with source document and items copied from PR (unit_price = 0).\nComplete vendor, pricing, and logistics via **PUT /purchase/rfq/:id**.","operationId":"PurchaseRequestController_convertToRfq","parameters":[{"name":"prId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/RfqDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Convert approved PR to RFQ","tags":["Purchase > Purchase Requests"]}},"/api/purchase/rfq":{"get":{"description":"Supports:\n- `search` — across reference_code, source_document, deliver_to\n- `filters` — JSON: status, currency, id_vendor, id_buyer\n- `sortBy` / `sortOrder`\n- `page` / `limit`\n\nResponse does **not** include line items — use the detail endpoint for those.","operationId":"RfqController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RfqListResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List all RFQs","tags":["Purchase > RFQ"]},"post":{"description":"Creates an RFQ in **DRAFT** status.\n\n- `source_document` — must match a PR `reference_code`. `id_purchase_request` will be auto-resolved if not provided.\n- `source_vendor` — optional, auto-populated from vendor record if omitted.\n- `items` — JSON array. Minimum 1 item required.","operationId":"RfqController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRfqRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/RfqDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create RFQ manually","tags":["Purchase > RFQ"]}},"/api/purchase/rfq/{id}":{"get":{"description":"Includes line items with pricing, vendor info, and buyer info.","operationId":"RfqController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/RfqDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get RFQ detail","tags":["Purchase > RFQ"]},"put":{"description":"Only allowed in **DRAFT** or **SENT** status.\n\n- `source_document` — if updated, `id_purchase_request` will be re-resolved automatically.\n- `source_vendor` — optional, auto-populated from vendor if omitted when changing vendor.\n- `items` — replaces all existing items. Each item requires `id_purchase_request_item` to resolve asset info.","operationId":"RfqController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRfqRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/RfqDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update RFQ header and/or items","tags":["Purchase > RFQ"]},"delete":{"description":"Sets flag=0. Not allowed in TO_BE_APPROVED or APPROVED status.","operationId":"RfqController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft delete RFQ","tags":["Purchase > RFQ"]}},"/api/purchase/rfq/{id}/send-email":{"post":{"description":"Transitions status **DRAFT → SENT**. Silently skips if vendor has no email.","operationId":"RfqController_sendEmail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/RfqDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Send RFQ to vendor via email","tags":["Purchase > RFQ"]}},"/api/purchase/rfq/{id}/confirm":{"post":{"description":"Transitions status **SENT → TO_BE_APPROVED**. Auto-creates a PO draft. Approval is APPROVE/REJECT only.","operationId":"RfqController_confirm","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/RfqDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Submit RFQ to approval workflow","tags":["Purchase > RFQ"]}},"/api/purchase/purchase-orders":{"get":{"description":"Supports:\n- `search` — across reference_code, source_document, deliver_to\n- `filters` — JSON: status, currency, id_vendor\n- `sortBy` / `sortOrder`\n- `page` / `limit`","operationId":"PurchaseOrderController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PoListResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List all purchase orders","tags":["Purchase > Purchase Order"]}},"/api/purchase/purchase-orders/{id}":{"get":{"description":"Includes line items with pricing, vendor info, and creator info.","operationId":"PurchaseOrderController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/PoDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get purchase order detail","tags":["Purchase > Purchase Order"]},"put":{"description":"Only **arrival_date** and **note** are editable.\n\n- `arrival_date` — actual date goods arrived (different from expected_arrival).\n- `note` — internal note for this PO.","operationId":"PurchaseOrderController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePurchaseOrderDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/PoDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update purchase order","tags":["Purchase > Purchase Order"]}},"/api/purchase/purchase-orders/{id}/send-email":{"post":{"description":"Transitions status **DRAFT → WAITING_BILLS**.\nResend also allowed from **WAITING_BILLS**.\nSilently skips if vendor has no registered email.","operationId":"PurchaseOrderController_sendEmail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/PoDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Send PO to vendor via email","tags":["Purchase > Purchase Order"]}},"/api/purchase/purchase-orders/{poId}/vendor-bill":{"post":{"description":"PO must be in **WAITING_BILLS** status.\nAll items and pricing are copied from the PO.\n`account_snapshot` per item is populated from the asset's `expense_account_asset`.\nComplete remaining fields via **PUT /purchase/vendor-bills/:id**.","operationId":"PurchaseOrderController_convertToVendorBill","parameters":[{"name":"poId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorBillDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Generate vendor bill from this Purchase Order","tags":["Purchase > Purchase Order"]}},"/api/purchase/vendor-bills":{"get":{"description":"Supports:\n- `search` — across reference_code, source_document, bill_reference\n- `filters` — JSON: status, currency, id_vendor\n- `sortBy` / `sortOrder`\n- `page` / `limit`","operationId":"VendorBillController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VendorBillListResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List all vendor bills","tags":["Purchase > Vendor Bill"]},"post":{"description":"Create a vendor bill without a Purchase Order.\nUsed for operational expenses, utilities, etc.\n\nItems use free-text description (not linked to assets).","operationId":"VendorBillController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVendorBillDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorBillDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create standalone vendor bill","tags":["Purchase > Vendor Bill"]}},"/api/purchase/vendor-bills/{id}":{"get":{"description":"Includes line items with account snapshots, vendor info, and payment records.","operationId":"VendorBillController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorBillDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get vendor bill detail","tags":["Purchase > Vendor Bill"]},"put":{"description":"Only allowed in **DRAFT** status.\n\nEditable fields: `bill_reference`, `bill_date`, `accounting_date`,\n`payment_reference`, `recipient_bank`, `due_date`, `journal`.","operationId":"VendorBillController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVendorBillDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorBillDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update vendor bill","tags":["Purchase > Vendor Bill"]},"delete":{"description":"Sets flag=2. Only allowed in DRAFT status.","operationId":"VendorBillController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft delete vendor bill","tags":["Purchase > Vendor Bill"]}},"/api/purchase/vendor-bills/{id}/post":{"post":{"description":"Transitions status **DRAFT → POSTED**.\nBill is no longer editable after posting.","operationId":"VendorBillController_post","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorBillDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Post vendor bill","tags":["Purchase > Vendor Bill"]}},"/api/purchase/vendor-bills/{id}/register-payment":{"post":{"description":"Bill must be in **POSTED** status.\n\nSide effects:\n- Vendor Bill status → **FULLY_PAID**\n- Linked Purchase Order status → **FULLY_BILLED**\n\n`memo` defaults to the vendor bill's `reference_code` if not provided.","operationId":"VendorBillController_registerPayment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterPaymentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/VendorBillDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Register payment for vendor bill","tags":["Purchase > Vendor Bill"]}},"/api/purchase/good-receipts":{"get":{"description":"Supports:\n- `search` — across reference_code, source_document, tracking_reference\n- `filters` — JSON: status, id_vendor, id_pic\n- `sortBy` / `sortOrder`\n- `page` / `limit`","operationId":"GoodReceiptController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GrListResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List all good receipts","tags":["Purchase > Good Receipt"]}},"/api/purchase/good-receipts/{id}":{"get":{"description":"Includes items (demand & done), vendor, and PIC.","operationId":"GoodReceiptController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/GrDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get good receipt detail","tags":["Purchase > Good Receipt"]},"put":{"description":"All header fields editable in **DRAFT** and **RECEIPT** status.\nItem `done` quantity only editable in **RECEIPT** status.\nNothing editable in **DONE** status.","operationId":"GoodReceiptController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateGoodReceiptDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/GrDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update good receipt","tags":["Purchase > Good Receipt"]}},"/api/purchase/good-receipts/{id}/receipt":{"post":{"description":"Transitions status **DRAFT → RECEIPT**. Enables done qty input per item.","operationId":"GoodReceiptController_toReceipt","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/GrDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Transition good receipt to RECEIPT status","tags":["Purchase > Good Receipt"]}},"/api/purchase/good-receipts/{id}/done":{"post":{"description":"Transitions status **RECEIPT → DONE**.\nAll items must have `done` quantity > 0 before this is allowed.","operationId":"GoodReceiptController_toDone","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/GrDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Complete good receipt (DONE)","tags":["Purchase > Good Receipt"]}},"/api/purchase/good-receipts/{id}/print":{"get":{"description":"Returns a PDF file of the full Good Receipt document.","operationId":"GoodReceiptController_print","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Print Good Receipt document as PDF","tags":["Purchase > Good Receipt"]}},"/api/purchase/good-receipts/{id}/print-label":{"get":{"description":"Returns a PDF with one label per item page. Suitable for printing on label stickers.","operationId":"GoodReceiptController_printLabel","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Print Good Receipt item labels as PDF","tags":["Purchase > Good Receipt"]}},"/api/assets":{"get":{"operationId":"AssetController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AssetResponseDto"}}}}]}}}}},"summary":"Get all assets (optional pagination)","tags":["Assets"]},"post":{"operationId":"AssetController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssetRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/AssetResponseDto"}}}]}}}}},"summary":"Create a new asset","tags":["Assets"]}},"/api/assets/{id}":{"get":{"operationId":"AssetController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/AssetResponseDto"}}}]}}}}},"summary":"Get asset by ID","tags":["Assets"]},"put":{"operationId":"AssetController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAssetRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/AssetResponseDto"}}}]}}}}},"summary":"Update an asset","tags":["Assets"]},"delete":{"operationId":"AssetController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Soft delete an asset (sets flag = 2)","tags":["Assets"]}},"/api/assets/{id}/depreciation-board":{"get":{"operationId":"AssetController_getBoard","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DepreciationBoardResponseDto"}}}}]}}}}},"summary":"Get depreciation board for an asset","tags":["Assets"]},"post":{"operationId":"AssetController_createBoardEntry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDepreciationBoardRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/DepreciationBoardResponseDto"}}}]}}}}},"summary":"Add a depreciation board entry to an asset","tags":["Assets"]}},"/api/assets/{id}/depreciation-board/{boardId}":{"put":{"operationId":"AssetController_updateBoardEntry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"boardId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDepreciationBoardRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/DepreciationBoardResponseDto"}}}]}}}}},"summary":"Update a depreciation board entry","tags":["Assets"]},"delete":{"operationId":"AssetController_deleteBoardEntry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"boardId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/EmptyDto"}}}]}}}}},"summary":"Soft delete a depreciation board entry","tags":["Assets"]}},"/api/accounting/coa":{"get":{"description":"Returns a paginated list of all active accounts.\n\n**Search** — across `account_number`, `account_name`, and `group_name`.\n\n**Filters** (JSON object via `filters` query param):\n- `account_type` — e.g. `\"CASH_AND_BANK\"`\n- `id_coa_group` — restrict to a specific group\n\n**Sort** — default: `account_number ASC`\n\n**Account types:** CASH_AND_BANK, FIXED_ASSETS, TRADE_PAYABLES, TAX_PAYABLE,\nEQUITY, REVENUE, COST_OF_GOODS_SOLD, TAX, RELATED_PARTY, INVESTMENT, OPERATING_EXPENSE, OTHERS\n\n**Classifications:** CURRENT_ASSETS, NON_CURRENT_ASSETS, CURRENT_LIABILITIES, EQUITY, INCOME, EXPENSES, TAX","operationId":"CoaController_getAll","parameters":[{"name":"filters","required":false,"in":"query","description":"JSON filter object, e.g. {\"account_type\":\"CASH_AND_BANK\"}","schema":{"example":"{\"account_type\":\"CASH_AND_BANK\"}"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CoaListItemDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List Chart of Accounts","tags":["Accounting > Chart of Accounts"]},"post":{"description":"Creates a new account and registers it under the specified account group.\n\n**Validation rules:**\n- `account_number` must be unique among all active accounts.\n- `id_coa_group` must reference an existing, active account group.\n- `account_number` must consist of digits only (e.g. `\"11101\"`).\n- `amount` (if provided) must be ≥ 0 with at most 2 decimal places.","operationId":"CoaController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCoaDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/CoaDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create a new Chart of Accounts entry","tags":["Accounting > Chart of Accounts"]}},"/api/accounting/coa/groups":{"get":{"description":"Returns all active account groups ordered by `group_code` ascending.\n\nUse this endpoint to populate the `id_coa_group` selector when creating or\nupdating a Chart of Accounts entry.\n\nEach group includes its code, name, and financial-statement classification.","operationId":"CoaController_getAllGroups","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CoaGroupSummaryDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List all Account Groups","tags":["Accounting > Chart of Accounts"]}},"/api/accounting/coa/{id}":{"get":{"description":"Returns the full detail of a single account record, including its parent account group.","operationId":"CoaController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/CoaDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get Chart of Accounts entry by ID","tags":["Accounting > Chart of Accounts"]},"patch":{"description":"Updates one or more fields of an existing account. Only the fields included\nin the request body are changed; omitted fields remain unchanged.\n\n**Validation rules:**\n- If `account_number` is provided, it must not conflict with any other active account.\n- If `id_coa_group` is provided, it must reference an existing, active account group.\n- `amount` (if provided) must be ≥ 0 with at most 2 decimal places.","operationId":"CoaController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCoaDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/CoaDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Partially update a Chart of Accounts entry","tags":["Accounting > Chart of Accounts"]},"delete":{"description":"Soft-deletes an account by setting its flag to 2 (inactive). The record is retained in the database for audit purposes and cannot be restored via the API.","operationId":"CoaController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete a Chart of Accounts entry","tags":["Accounting > Chart of Accounts"]}},"/api/accounting/journals":{"get":{"description":"Supports:\n- `search` — across journal_name\n- `filters` — JSON: journal_type\n- `sortBy` / `sortOrder` — default: journal_name ASC\n- `page` / `limit`\n\nJournal Types: CASH, BANK, SALES, PURCHASE, MISCELLANEOUS","operationId":"JournalController_getAll","parameters":[{"name":"filters","required":false,"in":"query","description":"JSON filter object, e.g. {\"journal_type\":\"CASH\"}","schema":{"example":"{\"journal_type\":\"CASH\"}"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/JournalListItemDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List Journals","tags":["Accounting > Journal Configuration"]},"post":{"description":"Creates a new journal configuration including:\n- Basic info (journal_name, journal_type)\n- Journal Entries accounts (suspense, loss, profit — FK to COA)\n- Incoming and outgoing payment methods\n- Advanced settings (account_type, allowed_account_type, communication, follow-up)","operationId":"JournalController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJournalDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create Journal","tags":["Accounting > Journal Configuration"]}},"/api/accounting/journals/{id}":{"get":{"description":"Returns a single journal including COA references and all payment methods.","operationId":"JournalController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get Journal by ID","tags":["Accounting > Journal Configuration"]},"patch":{"description":"Partially updates a journal. Only the fields included in the request body are changed.\n\nPayment methods:\n- Provide `incoming_payment_methods` to replace ALL existing incoming methods.\n- Provide `outgoing_payment_methods` to replace ALL existing outgoing methods.\n- Omit either array to leave that direction unchanged.","operationId":"JournalController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateJournalDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update Journal","tags":["Accounting > Journal Configuration"]},"delete":{"description":"Soft-deletes a journal (sets flag = 2). Cannot be undone via API.","operationId":"JournalController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete Journal","tags":["Accounting > Journal Configuration"]}},"/api/accounting/journal-entries":{"get":{"description":"Returns a paginated list of journal entries with totals.\n\nSupports:\n- `search` — across entry_number, reference, source_document\n- `filters` — JSON: status, id_journal\n- `sortBy` / `sortOrder` — default: accounting_date DESC\n- `page` / `limit`\n\nStatus values: DRAFT, POSTED","operationId":"JournalEntryController_getAll","parameters":[{"name":"filters","required":false,"in":"query","description":"JSON filter object, e.g. {\"status\":\"POSTED\",\"id_journal\":1}","schema":{"example":"{\"status\":\"POSTED\"}"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/JournalEntryListItemDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List Journal Entries","tags":["Accounting > Journal Entries"]},"post":{"description":"Creates a new journal entry in DRAFT status.\n\n- Entry number is auto-generated: JE/{year}/{seq:04d}\n- Requires at least 2 line items\n- Validates that all COA accounts and the journal exist\n- Debit/credit balance is NOT enforced at creation time — only at post time","operationId":"JournalEntryController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJournalEntryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalEntryDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create Journal Entry","tags":["Accounting > Journal Entries"]}},"/api/accounting/journal-entries/report":{"get":{"description":"Returns a hierarchical journal report grouped by journal → entries → line items.\n\nOnly **POSTED** entries are included.\n\n**Default range**: Jan 1 – Dec 31 of the current year.\n\n**Taxes column**: populated from lines whose COA `account_type` is `TAX` or `TAX_PAYABLE`\n(the debit + credit amount for that line). All other lines show 0.\n\n**Filters**:\n- `date_from` / `date_to` — date range (ISO 8601 date string)\n- `id_journal` — restrict to a single journal\n- `is_reversal` — `true` for reversal entries only, `false` to exclude reversals","operationId":"JournalEntryController_getReport","parameters":[{"name":"date_from","required":false,"in":"query","description":"Start date of the report range (inclusive). Defaults to Jan 1 of the current year.","schema":{"format":"date","example":"2026-01-01","type":"string"}},{"name":"date_to","required":false,"in":"query","description":"End date of the report range (inclusive). Defaults to Dec 31 of the current year.","schema":{"format":"date","example":"2026-12-31","type":"string"}},{"name":"id_journal","required":false,"in":"query","description":"Filter to a single journal.","schema":{"example":1,"type":"number"}},{"name":"is_reversal","required":false,"in":"query","description":"Filter by reversal flag. true = reversals only, false = non-reversals only. Omit to include all.","schema":{"example":false,"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalReportDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Journal Report","tags":["Accounting > Journal Entries"]}},"/api/accounting/journal-entries/{id}":{"get":{"description":"Returns a single journal entry including all line items with COA account details.","operationId":"JournalEntryController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalEntryDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get Journal Entry by ID","tags":["Accounting > Journal Entries"]},"patch":{"description":"Partially updates a DRAFT journal entry. POSTED entries cannot be updated.\n\n- Omit any field to leave it unchanged.\n- Providing `items` replaces ALL existing line items for this entry.\n- Omitting `items` leaves existing items unchanged.","operationId":"JournalEntryController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateJournalEntryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalEntryDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update Journal Entry","tags":["Accounting > Journal Entries"]},"delete":{"description":"Soft-deletes a DRAFT journal entry (sets flag = 2). POSTED entries cannot be deleted.","operationId":"JournalEntryController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete Journal Entry","tags":["Accounting > Journal Entries"]}},"/api/accounting/journal-entries/{id}/post":{"post":{"description":"Transitions a DRAFT entry to POSTED status.\n\nValidations:\n- Entry must have at least one debit line and one credit line\n- Total debits must equal total credits (within 0.001 tolerance)\n\nOnce posted, the entry cannot be edited or deleted. Use reverse or reset-to-draft instead.","operationId":"JournalEntryController_post","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalEntryDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Post Journal Entry","tags":["Accounting > Journal Entries"]}},"/api/accounting/journal-entries/{id}/reset-to-draft":{"post":{"description":"Reverts a POSTED entry back to DRAFT status, allowing edits. Only applicable to POSTED entries.","operationId":"JournalEntryController_resetToDraft","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalEntryDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Reset Journal Entry to Draft","tags":["Accounting > Journal Entries"]}},"/api/accounting/journal-entries/{id}/reverse":{"post":{"description":"Creates a new reversal entry (DRAFT) that mirrors the original with debit/credit swapped.\n\n- Original entry must be in POSTED status\n- Each original entry can only be reversed once\n- The reversal entry is created in DRAFT status and must be posted separately\n- `reversal_date` defaults to today if not provided","operationId":"JournalEntryController_reverse","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReverseJournalEntryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalEntryDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Reverse Journal Entry","tags":["Accounting > Journal Entries"]}},"/api/accounting/journal-entries/{id}/items":{"get":{"description":"Returns all active line items for the given journal entry.","operationId":"JournalEntryController_getItems","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/JournalItemResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List Items of a Journal Entry","tags":["Accounting > Journal Entries"]}},"/api/accounting/journal-entries/{id}/items/{itemId}":{"get":{"description":"Returns a single active line item validated against its parent entry.","operationId":"JournalEntryController_getItemById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"itemId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalItemResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get a Single Item of a Journal Entry","tags":["Accounting > Journal Entries"]}},"/api/accounting/journal-items":{"get":{"description":"Returns a paginated list of all journal line items across all entries.\n\nEach row includes: accounting date, journal entry reference, COA account,\npartner, label, debit, and credit.\n\nSupports:\n- `search` — across account name, account number, entry number, partner, label\n- `page` / `limit`","operationId":"JournalItemController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/JournalItemListItemDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List All Journal Items","tags":["Accounting > Journal Items"]}},"/api/accounting/journal-items/{id}":{"get":{"description":"Returns full detail of a single journal line item, including:\n- Accounting date and entry reference (entry number, status)\n- Journal name\n- COA account (number + name)\n- Partner and label\n- Debit / credit amounts\n- Narration, reversal flags from the parent entry\n- Timestamps (created_at, updated_at)","operationId":"JournalItemController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/JournalItemDetailDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get Journal Item by ID","tags":["Accounting > Journal Items"]}},"/api/accounting/reports/balance-sheet":{"get":{"description":"Generates a standard double-entry Balance Sheet as of the specified date.\n\n**Data source:** COA account balances (`coa.amount`), grouped by financial-statement classification.\n\n**Structure:**\n\n**Assets**\n- Current Assets — cash, receivables, prepaid tax, cash advance\n- Non-Current Assets — fixed assets, related-party deposits, deferred assets, investments\n- Total Assets\n\n**Liabilities and Equity**\n- Current Liabilities — trade payables, tax payable, related-party payables, other payables\n- Equity — paid-in capital, retained earnings\n- Total Liabilities and Equity\n\n**Note on TAX classification:**\nAccounts in the TAX classification are routed by group code prefix:\n- `1xxx` → Current Assets (prepaid tax)\n- `2xxx` → Current Liabilities (tax payable)\n- `9xxx` → excluded from Balance Sheet (income tax belongs to the P&L)","operationId":"AccountingReportController_getBalanceSheet","parameters":[{"name":"as_of_date","required":false,"in":"query","description":"Snapshot date for the balance sheet. The report will display the account balances as recorded in the COA master data. Defaults to today when omitted.","schema":{"format":"date","example":"2026-12-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/BalanceSheetResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Balance Sheet","tags":["Accounting > Reports"]}},"/api/accounting/reports/assets":{"get":{"description":"Generates the Assets side of the Balance Sheet as of the specified date.\n\n**Data source:** COA account balances (`coa.amount`), filtered to asset-related classifications.\n\n**Structure:**\n\n- **Current Assets** — Cash & Bank, Receivables, Cash Advance, Prepaid Tax (TAX group `1xxx`)\n- **Non-Current Assets** — Fixed Assets, Related-Party Deposits, Deferred Assets, Investments\n- **Total Assets**\n\n**Default date:** today.","operationId":"AccountingReportController_getAssets","parameters":[{"name":"as_of_date","required":false,"in":"query","description":"Snapshot date for the balance sheet. The report will display the account balances as recorded in the COA master data. Defaults to today when omitted.","schema":{"format":"date","example":"2026-12-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/AssetsResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Assets Report","tags":["Accounting > Reports"]}},"/api/accounting/reports/liabilities-and-equity":{"get":{"description":"Generates the Liabilities and Equity side of the Balance Sheet as of the specified date.\n\n**Data source:** COA account balances (`coa.amount`), filtered to liability and equity classifications.\n\n**Structure:**\n\n- **Current Liabilities** — Trade Payables, Tax Payable (TAX group `2xxx`), Related-Party Payables, Other Payables\n- **Equity** — Paid-in Capital, Retained Earnings\n- **Total Liabilities and Equity**\n\n**Default date:** today.","operationId":"AccountingReportController_getLiabilitiesAndEquity","parameters":[{"name":"as_of_date","required":false,"in":"query","description":"Snapshot date for the balance sheet. The report will display the account balances as recorded in the COA master data. Defaults to today when omitted.","schema":{"format":"date","example":"2026-12-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/LiabilitiesEquityResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Liabilities and Equity Report","tags":["Accounting > Reports"]}},"/api/accounting/reports/profit-and-loss":{"get":{"description":"Generates the Statement of Profit and Loss (Income Statement) for the specified period.\n\n**Data source:** Posted journal entry line items aggregated by COA account within the date range.\nOnly **POSTED** journal entries are included.\n\n**Structure:**\n\n- **Revenue** — INCOME classification accounts (net credit: credit − debit)\n- **Cost of Goods Sold (COGS)** — accounts with `account_type = COST_OF_GOODS_SOLD` (net debit)\n- **Gross Profit / (Loss)** = Revenue − COGS\n- **Expenses** — OPERATING_EXPENSE and OTHERS account types (net debit)\n- **Net Income** = Gross Profit − Expenses\n- **Tax** — income tax expense accounts (group code `9xxx`, net debit)\n- **Profit for the Year** = Net Income − Tax\n\n**Default range:** Jan 1 – Dec 31 of the current year.","operationId":"AccountingReportController_getProfitLoss","parameters":[{"name":"date_from","required":false,"in":"query","description":"Start date of the reporting period (inclusive). Defaults to January 1 of the current year when omitted.","schema":{"format":"date","example":"2026-01-01","type":"string"}},{"name":"date_to","required":false,"in":"query","description":"End date of the reporting period (inclusive). Defaults to December 31 of the current year when omitted.","schema":{"format":"date","example":"2026-12-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ProfitLossResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Statement of Profit and Loss","tags":["Accounting > Reports"]}},"/api/accounting/reports/trial-balance":{"get":{"description":"Generates the Trial Balance for the specified period.\n\n**Data source:** Posted journal entry line items aggregated by COA account within the date range.\nOnly **POSTED** journal entries are included.\n\n**Structure:**\n\nEach account row displays:\n- `account_number` / `account_name` — account identifier\n- `total_debit` — sum of all posted debit movements within the period\n- `total_credit` — sum of all posted credit movements within the period\n\nThe `totals` row is the column-wise sum of all account rows.\nIn a balanced set of books, `totals.total_debit` should equal `totals.total_credit`.\n\n**Default range:** Jan 1 – Dec 31 of the current year.","operationId":"AccountingReportController_getTrialBalance","parameters":[{"name":"date_from","required":false,"in":"query","description":"Start date of the reporting period (inclusive). Defaults to January 1 of the current year when omitted.","schema":{"format":"date","example":"2026-01-01","type":"string"}},{"name":"date_to","required":false,"in":"query","description":"End date of the reporting period (inclusive). Defaults to December 31 of the current year when omitted.","schema":{"format":"date","example":"2026-12-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/TrialBalanceResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Trial Balance","tags":["Accounting > Reports"]}},"/api/accounting/reports/changes-in-equity":{"get":{"description":"Generates the Statement of Changes in Equity for the specified period.\n\n**Data source:** Posted journal entry line items for **EQUITY**-classified accounts,\naggregated by COA account within the date range.\n\n**Structure:**\n\nEach account row displays its net movement (credit − debit) distributed into one equity sub-category column:\n- **Paid-in Capital** — accounts in group 3110 (Shareholders' Equity)\n- **Retained Earnings** — accounts in group 3111 (Retained Earnings)\n- **Other Comprehensive Income** — all other EQUITY-classified accounts\n- **Total Equity** — sum of all three columns for that account\n\nThe `totals` row represents the column-wise ending balance across all equity accounts.\n\n**Default range:** Jan 1 – Dec 31 of the current year.","operationId":"AccountingReportController_getChangesInEquity","parameters":[{"name":"date_from","required":false,"in":"query","description":"Start date of the reporting period (inclusive). Defaults to January 1 of the current year when omitted.","schema":{"format":"date","example":"2026-01-01","type":"string"}},{"name":"date_to","required":false,"in":"query","description":"End date of the reporting period (inclusive). Defaults to December 31 of the current year when omitted.","schema":{"format":"date","example":"2026-12-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ChangesInEquityResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Statement of Changes in Equity","tags":["Accounting > Reports"]}},"/api/accounting/receivables":{"get":{"description":"Supports:\n- `search` — across reference_code, description\n- `filters` — JSON: status, id_customer\n- `sortBy` / `sortOrder`\n- `page` / `limit`","operationId":"AccountReceivableController_getAll","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ArInvoiceListResponseDto"}}}}]}}}}},"security":[{"bearer":[]}],"summary":"List all AR invoices","tags":["Accounting > Account Receivable"]},"post":{"description":"Create an AR invoice manually (not linked to a voyage invoice).\nItems are provided directly in the request body.","operationId":"AccountReceivableController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateArInvoiceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ArInvoiceDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create standalone AR invoice","tags":["Accounting > Account Receivable"]}},"/api/accounting/receivables/from-voyage/{voyageInvoiceId}":{"post":{"description":"Creates an AR invoice by copying financial data and items from an existing voyage invoice.\nThe voyage invoice can only be linked to one AR invoice.","operationId":"AccountReceivableController_createFromVoyageInvoice","parameters":[{"name":"voyageInvoiceId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ArInvoiceDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Create AR invoice from voyage invoice","tags":["Accounting > Account Receivable"]}},"/api/accounting/receivables/{id}":{"get":{"description":"Includes line items, customer info, and payment records.","operationId":"AccountReceivableController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ArInvoiceDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Get AR invoice detail","tags":["Accounting > Account Receivable"]},"patch":{"description":"Only allowed in **DRAFT** status.\n\nEditable fields: `invoice_date`, `due_date`, `accounting_date`,\n`description`, `include_vat`, `include_withholding`.","operationId":"AccountReceivableController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateArInvoiceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ArInvoiceDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Update AR invoice","tags":["Accounting > Account Receivable"]},"delete":{"description":"Sets flag=2. Only allowed in DRAFT status.","operationId":"AccountReceivableController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft delete AR invoice","tags":["Accounting > Account Receivable"]}},"/api/accounting/receivables/{id}/post":{"post":{"description":"Transitions status **DRAFT → POSTED**.\nInvoice must have at least one item.\nInvoice is no longer editable after posting.","operationId":"AccountReceivableController_post","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ArInvoiceDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Post AR invoice","tags":["Accounting > Account Receivable"]}},"/api/accounting/receivables/{id}/register-payment":{"post":{"description":"Invoice must be in **POSTED** status.\nAmount must equal grand_total (full payment only, no partial).\n\nSide effects:\n- AR Invoice status → **FULLY_PAID**\n\n`memo` defaults to the AR invoice's `reference_code` if not provided.","operationId":"AccountReceivableController_registerPayment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterArPaymentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"properties":{"data":{"$ref":"#/components/schemas/ArInvoiceDetailResponseDto"}}}]}}}}},"security":[{"bearer":[]}],"summary":"Register payment for AR invoice","tags":["Accounting > Account Receivable"]}}},"info":{"title":"API Documentation","description":"API documentation for the application","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"StatusDto":{"type":"object","properties":{"code":{"type":"number","example":200},"detail":{"type":"string","example":"Request was successful"}},"required":["code","detail"]},"RequestDto":{"type":"object","properties":{"method":{"type":"string","description":"HTTP method used for the request","example":"POST"},"url":{"type":"string","description":"Original request URL","example":"/contacts/123"},"headers":{"type":"object","description":"Headers sent by the client in the request","additionalProperties":{"type":"string"},"example":{"host":"localhost:3000","user-agent":"PostmanRuntime/7.32.3","accept":"*/*"}}},"required":["method","url","headers"]},"MetaDto":{"type":"object","properties":{"total":{"type":"number","default":0},"page":{"type":"number","default":1},"limit":{"type":"number","default":10}}},"BaseResponse":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/StatusDto"},"message":{"type":"string"},"timestamp":{"type":"string"},"request":{"$ref":"#/components/schemas/RequestDto"},"data":{"type":"object"},"meta":{"$ref":"#/components/schemas/MetaDto"}},"required":["status","message","timestamp","request","data","meta"]},"UserResponseDto":{"type":"object","properties":{"id_user":{"type":"number","example":1,"description":"Unique identifier of the user."},"email":{"type":"string","example":"rhazes@codenito.id","description":"Email address of the user."},"username":{"type":"string","example":"rhazes","description":"Username of the user."},"phone_number":{"type":"string","example":"081234567890","description":"Optional phone number provided by the user."},"created_at":{"format":"date-time","type":"string","example":"2025-07-16T10:24:00.000Z","description":"Timestamp when the user was created."},"updated_at":{"format":"date-time","type":"string","example":"2025-07-16T12:00:00.000Z","description":"Timestamp of the latest user update."}},"required":["id_user","email","username","created_at","updated_at"]},"CreateUserRequestDto":{"type":"object","properties":{"email":{"type":"string","example":"rhazes@codenito.id","description":"Valid and unique email address of the user."},"username":{"type":"string","example":"rhazes","description":"Unique username used for login or display."},"password":{"type":"string","example":"StrongP@ssw0rd!","description":"User password, should follow your platform’s policy."},"phone_number":{"type":"string","example":"081234567890","description":"Optional user phone number (mobile format preferred)."}},"required":["email","username","password"]},"UpdateUserRequestDto":{"type":"object","properties":{"email":{"type":"string","example":"rhazes@codenito.id","description":"Valid and unique email address of the user."},"username":{"type":"string","example":"rhazes","description":"Unique username used for login or display."},"password":{"type":"string","example":"StrongP@ssw0rd!","description":"User password, should follow your platform’s policy."},"phone_number":{"type":"string","example":"081234567890","description":"Optional user phone number (mobile format preferred)."}}},"EmptyDto":{"type":"object","properties":{"placeholder":{"type":"string","example":{}}},"required":["placeholder"]},"BaseUserDto":{"type":"object","properties":{"id":{"type":"number","description":"Unique identifier of the user"},"email":{"type":"string","description":"Email of the user"},"username":{"type":"string","description":"Username of the user"},"phoneNumber":{"type":"string","description":"Phone number of the user"}},"required":["id","email","username","phoneNumber"]},"LoginResponseDto":{"type":"object","properties":{"token":{"type":"string"},"user":{"$ref":"#/components/schemas/BaseUserDto"}},"required":["token","user"]},"LoginRequestDto":{"type":"object","properties":{"identifier":{"type":"string","description":"The email or username of the user","example":"user@example.com"},"password":{"type":"string","description":"The password of the user","example":"strongpassword123"},"rememberMe":{"type":"boolean","description":"Remember me option for extended token expiration","example":true}},"required":["identifier","password","rememberMe"]},"ForgotPasswordRequestDto":{"type":"object","properties":{"identifier":{"type":"string","description":"Email or username of the user requesting the password reset","example":"user@example.com or username123"}},"required":["identifier"]},"ResetPasswordRequestDto":{"type":"object","properties":{"password":{"type":"string","description":"The new password for the user","example":"NewPassword123!"}},"required":["password"]},"CustomerResponseDto":{"type":"object","properties":{"id_customer":{"type":"number"},"name_customer":{"type":"string"},"npwp_customer":{"type":"string"},"company_code_customer":{"type":"string"},"address_customer":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"}},"required":["id_customer","name_customer","created_at","updated_at"]},"Vendor":{"type":"object","properties":{}},"VendorInfoDto":{"type":"object","properties":{"id_vendor":{"type":"number"},"name_vendor":{"type":"string"},"npwp_vendor":{"type":"string"},"company_code_vendor":{"type":"string"},"address_vendor":{"type":"string"}},"required":["id_vendor","name_vendor"]},"VesselResponseDto":{"type":"object","properties":{"id_vessel":{"type":"number","example":20,"description":"Unique identifier of the vessel"},"code_vessel":{"type":"string","example":"MV-009","description":"Unique vessel code"},"name_vessel":{"type":"string","example":"KM Nusantara Raya","description":"Name of the vessel"},"description_vessel":{"type":"string","example":"Large container vessel for international shipping","description":"Vessel description or notes","nullable":true},"dwt_vessel":{"type":"number","example":10000,"description":"Deadweight tonnage (DWT) capacity of the vessel"},"type_vessel":{"type":"string","enum":["BULK_CARRIER","TANKER","CONTAINER","LNG_CARRIER","RO_RO","GENERAL_CARGO"],"example":"CONTAINER","description":"Type of the vessel"},"ownership_type_vessel":{"type":"string","enum":["COMPANY","VENDOR"],"example":"VENDOR","description":"Ownership type of the vessel (COMPANY or VENDOR)"},"owner_vessel":{"description":"Owner vendor information (only if ownership_type_vessel is VENDOR)","nullable":true,"allOf":[{"$ref":"#/components/schemas/VendorInfoDto"}]},"status_vessel":{"type":"string","enum":["AVAILABLE","NOT_AVAILABLE"],"example":"AVAILABLE","description":"Operational availability status of the vessel"},"latitude_vessel":{"type":"number","example":-8.75,"description":"Current latitude of the vessel","nullable":true},"longitude_vessel":{"type":"number","example":115.2167,"description":"Current longitude of the vessel","nullable":true},"created_at":{"format":"date-time","type":"string","example":"2025-08-04T03:04:50.871Z","description":"Creation timestamp of the vessel record"},"updated_at":{"format":"date-time","type":"string","example":"2025-08-04T03:04:50.871Z","description":"Last update timestamp of the vessel record"},"flag":{"type":"number","example":1,"description":"Logical deletion flag (1 = active, 0 = deleted)"}},"required":["id_vessel","code_vessel","name_vessel","dwt_vessel","type_vessel","ownership_type_vessel","status_vessel","created_at","updated_at","flag"]},"ProrataResponseDto":{"type":"object","properties":{"id_prorata":{"type":"number","example":1,"description":"Unique identifier of the prorata record"},"max_loading_days_prorata":{"type":"number","example":3,"description":"Maximum allowed days for loading operations"},"max_unloading_days_prorata":{"type":"number","example":2,"description":"Maximum allowed days for unloading operations"},"maximum_number_of_days_loading_unloading_prorata":{"type":"number","example":5,"description":"Total maximum days allowed for both loading and unloading combined"},"arrived_loading_port_prorata":{"type":"object","example":"2025-08-03T10:00:00Z","nullable":true,"description":"Date and time when the vessel arrived at the loading port"},"depart_loading_port_prorata":{"type":"object","example":"2025-08-05T15:00:00Z","nullable":true,"description":"Date and time when the vessel departed from the loading port"},"arrived_unloading_port_prorata":{"type":"object","example":"2025-08-10T09:00:00Z","nullable":true,"description":"Date and time when the vessel arrived at the unloading port"},"leaving_port_of_discharge_prorata":{"type":"object","example":"2025-08-12T18:30:00Z","nullable":true,"description":"Date and time when the vessel left the port of discharge (after unloading)"},"total_usage_prorata":{"type":"object","example":4.5,"nullable":true,"description":"Total prorata usage in days (loading + unloading) for calculation purposes"}},"required":["id_prorata","max_loading_days_prorata","max_unloading_days_prorata","maximum_number_of_days_loading_unloading_prorata","arrived_loading_port_prorata","depart_loading_port_prorata","arrived_unloading_port_prorata","leaving_port_of_discharge_prorata","total_usage_prorata"]},"CargoType":{"type":"object","properties":{}},"CargoPackaging":{"type":"object","properties":{}},"Port":{"type":"object","properties":{}},"Uom":{"type":"object","properties":{}},"ShipRouteResponseDto":{"type":"object","properties":{"id_ship_route":{"type":"number","example":1,"description":"Unique identifier of the ship route"},"id_port_of_loading_ship_route":{"type":"number","example":1,"description":"ID of the port where cargo loading takes place"},"port_of_loading":{"description":"Port entity details of loading port","nullable":false,"allOf":[{"$ref":"#/components/schemas/Port"}]},"id_port_of_discharge_ship_route":{"type":"number","example":2,"description":"ID of the port where cargo unloading takes place"},"port_of_discharge":{"description":"Port entity details of unloading port","nullable":false,"allOf":[{"$ref":"#/components/schemas/Port"}]},"freight_rate_ship_route":{"type":"object","example":1250000.5,"description":"Freight rate (in Rupiah) for this shipping route","nullable":true},"id_uom_ship_route":{"type":"object","example":3,"description":"ID of the unit of measure (UOM) for freight rate","nullable":true},"arrival_day_ship_route":{"type":"string","enum":["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"],"example":"MONDAY","description":"Expected arrival day at port (Sunday–Saturday).","nullable":true},"uom":{"description":"UOM entity details for the freight rate","nullable":true,"allOf":[{"$ref":"#/components/schemas/Uom"}]}},"required":["id_ship_route","id_port_of_loading_ship_route","port_of_loading","id_port_of_discharge_ship_route","port_of_discharge","freight_rate_ship_route","id_uom_ship_route","arrival_day_ship_route","uom"]},"VoyageStageHistory":{"type":"object","properties":{}},"ProrataSummaryDto":{"type":"object","properties":{}},"VoyageResponseDto":{"type":"object","properties":{"id_voyage":{"type":"number"},"number_voyage":{"type":"string"},"date_voyage":{"format":"date-time","type":"string"},"type_of_ship_voyage":{"type":"string"},"id_customer":{"type":"number"},"id_vendor":{"type":"number"},"id_ship_route":{"type":"number"},"id_vessel":{"type":"number"},"id_prorata":{"type":"number"},"id_cargo_type_voyage":{"type":"number"},"id_cargo_packaging_voyage":{"type":"number"},"cargo_quantity_voyage":{"type":"number"},"id_uom_cargo_quantity_voyage":{"type":"number"},"total_quantity_loading_draft_survey_voyage":{"type":"number"},"description_draft_survey_voyage":{"type":"string"},"voyage_status_voyage":{"type":"string","enum":["NEW","ONGOING","DEMURRAGE","COMPLETED"]},"laycan_start_voyage":{"format":"date-time","type":"string"},"laycan_end_voyage":{"format":"date-time","type":"string"},"created_by":{"type":"number"},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"customer":{"$ref":"#/components/schemas/CustomerResponseDto"},"vendor":{"$ref":"#/components/schemas/Vendor"},"vessel":{"$ref":"#/components/schemas/VesselResponseDto"},"prorata":{"$ref":"#/components/schemas/ProrataResponseDto"},"cargo_type":{"$ref":"#/components/schemas/CargoType"},"cargo_packaging":{"$ref":"#/components/schemas/CargoPackaging"},"ship_route":{"$ref":"#/components/schemas/ShipRouteResponseDto"},"stage_histories":{"type":"array","items":{"$ref":"#/components/schemas/VoyageStageHistory"}},"prorata_summary":{"$ref":"#/components/schemas/ProrataSummaryDto"}},"required":["id_voyage","number_voyage","date_voyage","type_of_ship_voyage","id_customer","id_vendor","id_ship_route","id_vessel","id_prorata","id_cargo_type_voyage","id_cargo_packaging_voyage","cargo_quantity_voyage","id_uom_cargo_quantity_voyage","voyage_status_voyage","created_by","created_at","updated_at","customer","vendor","vessel","prorata","cargo_type","cargo_packaging","ship_route","stage_histories"]},"VoyageStatsResponseDto":{"type":"object","properties":{"totals":{"type":"object","example":{"total_voyages":42,"demurrage_count":5,"demurrage_ratio":0.119}},"status_breakdown":{"type":"object","example":{"NEW":10,"ONGOING":20,"DEMURRAGE":5,"COMPLETED":7}},"type_of_ship_breakdown":{"type":"object","example":{"OWNER":12,"TC":20,"FC":10}},"cargo":{"type":"object","example":{"total_cargo_quantity":250000,"avg_cargo_per_voyage":5952.38,"by_type":[{"id":5,"name":"Coal","count":12,"total_qty":120000}],"by_packaging":[{"id":2,"name":"Bulk","count":30,"total_qty":210000}]}},"time":{"type":"object","example":{"avg_laycan_span_days":3.25,"avg_total_days_used":5.5,"avg_allowed_days":6,"utilization_rate":0.917,"recent_activity_7d":12,"recent_activity_30d":40}},"routes":{"type":"object","example":{"top_routes":[{"loading_port":"Tj. Priok","discharge_port":"Belawan","count":6}],"port_usage_loading":[{"port":"Tj. Priok","count":10}],"port_usage_discharge":[{"port":"Belawan","count":8}],"freight_rate":{"min":15000000,"max":45000000,"avg":27500000}}},"parties":{"type":"object","example":{"top_customers_by_voyage":[{"id":1,"name":"PT A","count":9}],"top_vendors_by_voyage":[{"id":2,"name":"PT B","count":7}],"top_vessels_by_voyage":[{"id":10,"name":"MV Nusantara","count":4}],"vessel_ownership_breakdown":{"COMPANY":12,"VENDOR":18}}},"files":{"type":"object","example":{"total_files":120,"by_category":[{"category":"INVOICE_FULL","count":12},{"category":"DRAFT_SURVEY","count":8}]}}},"required":["totals","status_breakdown","type_of_ship_breakdown","cargo","time","routes","parties","files"]},"VoyageDetailResponseDto":{"type":"object","properties":{"id_voyage":{"type":"number"},"number_voyage":{"type":"string"},"date_voyage":{"type":"object"},"type_of_ship_voyage":{"type":"string"},"id_customer":{"type":"object"},"id_vendor":{"type":"object"},"id_ship_route":{"type":"object"},"id_vessel":{"type":"object"},"id_prorata":{"type":"object"},"id_cargo_type_voyage":{"type":"object"},"id_cargo_packaging_voyage":{"type":"object"},"cargo_quantity_voyage":{"type":"object"},"id_uom_cargo_quantity_voyage":{"type":"object"},"total_quantity_loading_draft_survey_voyage":{"type":"object"},"description_draft_survey_voyage":{"type":"object"},"voyage_status_voyage":{"type":"string","enum":["NEW","ONGOING","DEMURRAGE","COMPLETED"]},"laycan_start_voyage":{"type":"object","nullable":true},"laycan_end_voyage":{"type":"object","nullable":true},"updated_at":{"type":"object"},"created_by":{"type":"number"},"createdBy":{"type":"object","example":{"id_user":1,"email":"rhazes@codenito.id","username":"rhazes","phone_number":"08xxxx"}},"customer":{"type":"object","example":{"id_customer":11,"name_customer":"PT Pertamina","npwp_customer":"...","company_code_customer":"...","address_customer":"..."}},"ship_route":{"type":"object","example":{"id_ship_route":31,"id_port_of_loading_ship_route":11,"id_port_of_discharge_ship_route":12,"freight_rate_ship_route":1250000.5,"uom":{"id_uom":34,"code_uom":"UM.0001","name_uom":"Metrik Ton","description_uom":"..."},"port_of_loading":{"id_port":11,"code_port":"IDJKT","name_port":"Tanjung Priok Port","city":{"id_city":12,"name_city":"Jakarta","province":{"id_province":13,"name_province":"DKI Jakarta","country":{"id_country":11,"code_country":"ID","name_country":"Indonesia"}}}},"port_of_discharge":{}}},"vessel":{"type":"object","example":{"id_vessel":15,"name_vessel":"KM Armada Sejahtera","dwt_vessel":7000,"type_vessel":"BULK_CARRIER","ownership_type_vessel":"VENDOR","owner_vessel":{"id_vendor":1,"name_vendor":"PT. Armada Laut","npwp_vendor":"...","company_code_vendor":"...","address_vendor":"..."}}},"prorata":{"type":"object","example":{"id_prorata":30,"max_loading_days_prorata":3,"max_unloading_days_prorata":2,"maximum_number_of_days_loading_unloading_prorata":5}},"vendor":{"type":"object","example":{"id_vendor":1,"name_vendor":"PT. Armada Laut","npwp_vendor":"...","company_code_vendor":"...","address_vendor":"..."}},"cargo_type":{"type":"object","example":{"id_cargo_type":5,"code_cargo_type":"HAZ","name_cargo_type":"Hazardous Cargo","description_cargo_type":"..."}},"cargo_packaging":{"type":"object","example":{"id_cargo_packaging":2,"code_cargo_packaging":"DRUM","name_cargo_packaging":"Drum","description_cargo_packaging":"..."}},"uom_cargo_quantity":{"type":"object","example":{"id_uom":34,"code_uom":"UM.0001","name_uom":"Metrik Ton","description_uom":"Metric ton ..."}},"stage_histories":{"example":[{"id_voyage_stage_history":22,"id_voyage":35,"voyage_stage_history":"INVOICE_DP","description_voyage_stage_history":"..."}],"type":"array","items":{"type":"string"}},"files":{"example":[{"id_file":70,"id_voyage":35,"name_file":"x.pdf","path_file":"uploads/...pdf","type_file":"application/pdf","size_file":13264,"category_file":"INVOICE_DP","uploaded_at_file":"2025-08-09T18:26:36.135Z","flag":1}],"type":"array","items":{"type":"string"}}},"required":["id_voyage","number_voyage","date_voyage","type_of_ship_voyage","id_customer","id_vendor","id_ship_route","id_vessel","id_prorata","id_cargo_type_voyage","id_cargo_packaging_voyage","cargo_quantity_voyage","id_uom_cargo_quantity_voyage","voyage_status_voyage","laycan_start_voyage","laycan_end_voyage","updated_at","created_by","stage_histories","files"]},"CreateProrataRequestDto":{"type":"object","properties":{"max_loading_days_prorata":{"type":"number","description":"Maximum number of allowed days for loading operations.","example":3},"max_unloading_days_prorata":{"type":"number","description":"Maximum number of allowed days for unloading operations.","example":2},"maximum_number_of_days_loading_unloading_prorata":{"type":"number","description":"Total maximum number of days allowed for both loading and unloading activities combined.","example":5}},"required":["max_loading_days_prorata","max_unloading_days_prorata","maximum_number_of_days_loading_unloading_prorata"]},"CreateShipRouteRequestDto":{"type":"object","properties":{"id_port_of_loading_ship_route":{"type":"number","example":1,"description":"ID of the port where cargo loading takes place."},"id_port_of_discharge_ship_route":{"type":"number","example":2,"description":"ID of the port where cargo unloading takes place."},"freight_rate_ship_route":{"type":"number","example":1250000.5,"description":"Freight rate (in Rupiah) for this shipping route."},"id_uom_ship_route":{"type":"number","example":3,"description":"ID of the unit of measure (UOM) for the freight rate (e.g., MT)."},"arrival_day_ship_route":{"type":"string","enum":["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"],"example":"MONDAY","description":"Expected arrival day at port (Sunday–Saturday)."}},"required":["id_port_of_loading_ship_route","id_port_of_discharge_ship_route","freight_rate_ship_route","id_uom_ship_route"]},"CreateVoyageRequestDto":{"type":"object","properties":{"number_voyage":{"type":"string","example":"VY-2025-001","description":"Unique voyage number used for identification."},"type_of_ship_voyage":{"type":"string","enum":["OWNER","TC","FC"],"example":"OWNER","description":"Type of service used in the voyage (OWNER, TC, or FC)."},"date_voyage":{"type":"string","example":"2025-08-01T00:00:00Z","description":"The official date of the voyage (represents when the voyage is planned or started, not the creation timestamp).","format":"date-time"},"id_vendor":{"type":"number","description":"Vendor ID required if type_of_service is TC or FC.","example":202},"id_customer":{"type":"number","description":"Customer ID is required","example":101},"id_vessel":{"type":"number","description":"Vessel ID associated with this voyage.","example":501},"laycan_start_voyage":{"type":"string","example":"2025-08-01T08:00:00Z","description":"Laycan start date and time of the voyage.","format":"date-time"},"laycan_end_voyage":{"type":"string","example":"2025-08-05T17:00:00Z","description":"Laycan end date and time of the voyage.","format":"date-time"},"cargo_quantity_voyage":{"type":"number","description":"Quantity of cargo for this voyage (numeric value only, without unit).","example":25000},"id_uom_cargo_quantity_voyage":{"type":"number","description":"Unit of measurement (UOM) for the cargo quantity, e.g., metric tons, barrels, etc.","example":1},"id_cargo_type_voyage":{"type":"number","description":"Cargo type ID for this voyage.","example":5},"id_cargo_packaging_voyage":{"type":"number","description":"Cargo packaging ID for this voyage.","example":2},"prorata":{"description":"Prorata data to be created together with the voyage.","allOf":[{"$ref":"#/components/schemas/CreateProrataRequestDto"}]},"ship_route":{"description":"Ship route data to be created with the voyage.","allOf":[{"$ref":"#/components/schemas/CreateShipRouteRequestDto"}]}},"required":["number_voyage","type_of_ship_voyage","date_voyage","id_customer","id_vessel","laycan_start_voyage","laycan_end_voyage","cargo_quantity_voyage","id_uom_cargo_quantity_voyage","id_cargo_type_voyage","id_cargo_packaging_voyage","prorata","ship_route"]},"CreateVoyageV2RequestDto":{"type":"object","properties":{"number_voyage":{"type":"string","example":"VY-2025-001","description":"Unique voyage number used for identification."},"type_of_ship_voyage":{"type":"string","enum":["OWNER","TC","FC"],"example":"OWNER","description":"Type of service used in the voyage (OWNER, TC, or FC)."},"date_voyage":{"type":"string","example":"2025-08-01T00:00:00Z","description":"The official date of the voyage (represents when the voyage is planned or started, not the creation timestamp).","format":"date-time"},"id_vendor":{"type":"number","description":"Vendor ID required if type_of_service is TC or FC.","example":202},"id_customer":{"type":"number","description":"Customer ID is required","example":101},"id_vessel":{"type":"number","description":"Vessel ID associated with this voyage.","example":501},"laycan_start_voyage":{"type":"string","example":"2025-08-01T08:00:00Z","description":"Laycan start date and time of the voyage.","format":"date-time"},"laycan_end_voyage":{"type":"string","example":"2025-08-05T17:00:00Z","description":"Laycan end date and time of the voyage.","format":"date-time"},"cargo_quantity_voyage":{"type":"number","description":"Quantity of cargo for this voyage (numeric value only, without unit).","example":25000},"id_uom_cargo_quantity_voyage":{"type":"number","description":"Unit of measurement (UOM) for the cargo quantity, e.g., metric tons, barrels, etc.","example":1},"id_cargo_type_voyage":{"type":"number","description":"Cargo type ID for this voyage.","example":5},"id_cargo_packaging_voyage":{"type":"number","description":"Cargo packaging ID for this voyage.","example":2},"prorata":{"description":"Prorata data to be created together with the voyage.","allOf":[{"$ref":"#/components/schemas/CreateProrataRequestDto"}]},"ship_route":{"description":"Ship route data to be created with the voyage.","allOf":[{"$ref":"#/components/schemas/CreateShipRouteRequestDto"}]},"files_si_customer":{"type":"string","format":"binary","description":"Shipping Instruction (SI) dari customer. Wajib untuk OWNER, TC, dan FC."},"files_spal_customer":{"type":"string","format":"binary","description":"Surat Pemberitahuan Angkutan Laut (SPAL) dari customer. Wajib untuk OWNER, TC, dan FC."},"files_si_vendor":{"type":"string","format":"binary","description":"Shipping Instruction (SI) dari vendor. Wajib hanya untuk tipe FC."},"files_spal_vendor":{"type":"string","format":"binary","description":"SPAL dari vendor. Wajib hanya untuk tipe FC."}},"required":["number_voyage","type_of_ship_voyage","date_voyage","id_customer","id_vessel","laycan_start_voyage","laycan_end_voyage","cargo_quantity_voyage","id_uom_cargo_quantity_voyage","id_cargo_type_voyage","id_cargo_packaging_voyage","prorata","ship_route","files_si_customer","files_spal_customer"]},"InvoiceDpItemDto":{"type":"object","properties":{"description":{"type":"string","description":"Deskripsi item / pekerjaan","example":"Freight Charge"},"quantity":{"type":"number","description":"Jumlah / kuantitas (opsional)","example":1},"id_uom":{"type":"number","description":"ID unit of measure (opsional)","example":1},"unit_price":{"type":"number","description":"Harga per unit (opsional)","example":5000000},"total_price":{"type":"number","description":"Total harga line item ini","example":5000000}},"required":["description","total_price"]},"InvoiceDpStageDto":{"type":"object","properties":{"action":{"type":"string","enum":["EXECUTE","SKIP"],"description":"EXECUTE = generate invoice DP. SKIP = lewati tahap ini.","example":"EXECUTE"},"dp_percentage":{"type":"number","description":"Persentase down payment terhadap grand total (1–100). Wajib jika action = EXECUTE.","example":50},"items":{"description":"Daftar line item invoice. Wajib jika action = EXECUTE.","type":"array","items":{"$ref":"#/components/schemas/InvoiceDpItemDto"}},"include_vat":{"type":"boolean","description":"Apakah PPN 11% dikenakan? Default false.","default":false},"include_withholding":{"type":"boolean","description":"Apakah PPH 2% dikenakan? Default false.","default":false}},"required":["action"]},"DraftSurveyStageDto":{"type":"object","properties":{"total_quantity_loading_draft_survey_voyage":{"type":"number","description":"Jumlah muatan aktual yang terukur saat draft survey (dalam unit UOM voyage).","example":24850},"description_draft_survey_voyage":{"type":"string","description":"Catatan atau deskripsi hasil draft survey.","example":"Draft survey selesai. Actual loading 24,850 MT dari estimasi 25,000 MT."},"files_draft_survey":{"type":"string","format":"binary","description":"Dokumen hasil draft survey. Wajib."}},"required":["total_quantity_loading_draft_survey_voyage","description_draft_survey_voyage","files_draft_survey"]},"InvoiceFullStageDto":{"type":"object","properties":{"files_invoice_full":{"type":"string","format":"binary","description":"File invoice pelunasan penuh. Wajib."}},"required":["files_invoice_full"]},"ProrataStageDto":{"type":"object","properties":{"arrived_loading_port_prorata":{"type":"string","format":"date-time","description":"Waktu kapal tiba di loading port.","example":"2025-08-02T06:00:00Z"},"depart_loading_port_prorata":{"type":"string","format":"date-time","description":"Waktu kapal berangkat dari loading port setelah selesai muat.","example":"2025-08-04T14:00:00Z"},"arrived_unloading_port_prorata":{"type":"string","format":"date-time","description":"Waktu kapal tiba di port of discharge.","example":"2025-08-07T08:00:00Z"},"leaving_port_of_discharge_prorata":{"type":"string","format":"date-time","description":"Waktu kapal meninggalkan port of discharge setelah selesai bongkar.","example":"2025-08-09T16:00:00Z"}},"required":["arrived_loading_port_prorata","depart_loading_port_prorata","arrived_unloading_port_prorata","leaving_port_of_discharge_prorata"]},"DemurrageStageDto":{"type":"object","properties":{"action":{"type":"string","enum":["EXECUTE","SKIP"],"description":"EXECUTE = ada demurrage yang harus dibayar (wajib file invoice). SKIP = tidak ada demurrage atau dibebaskan.","example":"EXECUTE"},"files_invoice_demurrage":{"type":"string","format":"binary","description":"Invoice demurrage. Wajib jika action = EXECUTE."},"files_supporting_demurrage":{"type":"array","items":{"type":"string","format":"binary"},"description":"Dokumen pendukung demurrage (maks 5 file). Opsional."}},"required":["action"]},"CompletedStageDto":{"type":"object","properties":{"files_other":{"type":"array","items":{"type":"string","format":"binary"},"description":"Dokumen penutup / lainnya (maks 5 file). Opsional."}}},"UpdateProrataRequestDto":{"type":"object","properties":{"arrived_loading_port_prorata":{"format":"date-time","type":"string","description":"Datetime when the vessel arrived at loading port","example":"2025-08-03T10:00:00Z"},"depart_loading_port_prorata":{"format":"date-time","type":"string","description":"Datetime when the vessel departed from loading port","example":"2025-08-05T15:00:00Z"},"arrived_unloading_port_prorata":{"format":"date-time","type":"string","description":"Datetime when the vessel arrived at unloading port","example":"2025-08-10T09:00:00Z"},"leaving_port_of_discharge_prorata":{"format":"date-time","type":"string","description":"Datetime when the vessel left the port of discharge","example":"2025-08-12T18:30:00Z"},"total_usage_prorata":{"type":"number","description":"Total days used (loading + unloading) for prorata calculation","example":4.5}}},"UpdateVoyageRequestDto":{"type":"object","properties":{"stage":{"type":"string","enum":["CREATED","DRAFT_SURVEY","INVOICE_DP","INVOICE_FULL","PRORATA","DEMURRAGE","COMPLETED"],"description":"Stage of the voyage workflow","example":"DRAFT_SURVEY"},"total_quantity_loading_draft_survey_voyage":{"type":"number","description":"Total cargo quantity recorded during the draft survey. Required if stage is DRAFT_SURVEY.","example":20000},"description_draft_survey_voyage":{"type":"string","description":"Description of the draft survey process. Required if stage is DRAFT_SURVEY.","example":"Initial draft survey completed successfully with 20,000 MT."},"prorata":{"description":"Prorata-related information. Required if stage is PRORATA and flag is 1 (executed).","allOf":[{"$ref":"#/components/schemas/UpdateProrataRequestDto"}]},"flag_stage":{"type":"number","description":"Action flag: 1 = executed, 3 = skipped.","example":1}},"required":["stage","total_quantity_loading_draft_survey_voyage","description_draft_survey_voyage","prorata","flag_stage"]},"UpdateShipRouteRequestDto":{"type":"object","properties":{"id_port_of_loading_ship_route":{"type":"number","example":1,"description":"ID of the port where cargo loading takes place."},"id_port_of_discharge_ship_route":{"type":"number","example":2,"description":"ID of the port where cargo unloading takes place."},"freight_rate_ship_route":{"type":"number","example":1250000.5,"description":"Freight rate (in Rupiah) for this shipping route."},"id_uom_ship_route":{"type":"number","example":3,"description":"ID of the unit of measure (UOM) for the freight rate (e.g., MT)."},"arrival_day_ship_route":{"type":"string","enum":["SUNDAY","MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY"],"example":"MONDAY","description":"Expected arrival day at port (Sunday–Saturday)."}}},"UpdateVoyageFullRequestDto":{"type":"object","properties":{"type_of_ship_voyage":{"type":"string","enum":["OWNER","TC","FC"]},"date_voyage":{"type":"object","format":"date-time"},"id_customer":{"type":"number"},"id_vendor":{"type":"number"},"id_vessel":{"type":"number"},"laycan_start_voyage":{"type":"object","format":"date-time"},"laycan_end_voyage":{"type":"object","format":"date-time"},"cargo_quantity_voyage":{"type":"number"},"id_uom_cargo_quantity_voyage":{"type":"number"},"id_cargo_type_voyage":{"type":"number"},"id_cargo_packaging_voyage":{"type":"number"},"total_quantity_loading_draft_survey_voyage":{"type":"number","description":"If you send this, you should also send description_draft_survey_voyage","example":20000},"description_draft_survey_voyage":{"type":"string","description":"If you send this, you should also send total_quantity_loading_draft_survey_voyage","example":"Initial draft survey completed successfully with 20,000 MT."},"prorata":{"$ref":"#/components/schemas/UpdateProrataRequestDto"},"ship_route":{"$ref":"#/components/schemas/UpdateShipRouteRequestDto"}}},"CreateVesselRequestDto":{"type":"object","properties":{"code_vessel":{"type":"string","example":"IMO9876543","description":"Unique vessel code or IMO number"},"name_vessel":{"type":"string","example":"MV Titan","description":"The registered name of the vessel."},"description_vessel":{"type":"string","example":"Modern bulk carrier with advanced navigation systems","description":"Vessel description or notes"},"dwt_vessel":{"type":"number","example":50000,"description":"Deadweight tonnage (DWT) of the vessel, representing its maximum carrying capacity in metric tons."},"type_vessel":{"type":"string","enum":["BULK_CARRIER","TANKER","CONTAINER","LNG_CARRIER","RO_RO","GENERAL_CARGO"],"example":"BULK_CARRIER","description":"The vessel type, e.g., BULK_CARRIER, TANKER, CONTAINER, etc."},"ownership_type_vessel":{"type":"string","enum":["COMPANY","VENDOR"],"example":"COMPANY","description":"Indicates whether the vessel is owned by the company or a vendor."},"id_owner_vessel":{"type":"number","example":3,"description":"Required when ownership_type_vessel is VENDOR. The vendor ID that owns the vessel."},"latitude_vessel":{"type":"number","example":-6.1064,"description":"Current latitude of the vessel"},"longitude_vessel":{"type":"number","example":106.8818,"description":"Current longitude of the vessel"}},"required":["code_vessel","name_vessel","dwt_vessel","type_vessel"]},"UpdateVesselRequestDto":{"type":"object","properties":{"name_vessel":{"type":"string","example":"MV Titan","description":"The registered name of the vessel."},"description_vessel":{"type":"string","example":"Modern bulk carrier with advanced navigation systems","description":"Vessel description or notes"},"dwt_vessel":{"type":"number","example":50000,"description":"Deadweight tonnage (DWT) of the vessel"},"type_vessel":{"type":"string","enum":["BULK_CARRIER","TANKER","CONTAINER","LNG_CARRIER","RO_RO","GENERAL_CARGO"],"example":"BULK_CARRIER","description":"The vessel type"},"ownership_type_vessel":{"type":"string","enum":["COMPANY","VENDOR"],"example":"VENDOR","description":"Ownership type of the vessel"},"id_owner_vessel":{"type":"number","example":3,"description":"Required when ownership_type_vessel is VENDOR. The vendor ID that owns the vessel."},"status_vessel":{"type":"string","enum":["AVAILABLE","NOT_AVAILABLE"],"example":"NOT_AVAILABLE","description":"Operational availability status of the vessel"},"latitude_vessel":{"type":"number","example":-6.1064,"description":"Current latitude of the vessel"},"longitude_vessel":{"type":"number","example":106.8818,"description":"Current longitude of the vessel"}}},"VendorResponseDto":{"type":"object","properties":{"id_vendor":{"type":"number"},"name_vendor":{"type":"string"},"npwp_vendor":{"type":"string"},"company_code_vendor":{"type":"string"},"address_vendor":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"}},"required":["id_vendor","name_vendor","created_at","updated_at"]},"CreateVendorRequestDto":{"type":"object","properties":{"name_vendor":{"type":"string"},"npwp_vendor":{"type":"string"},"company_code_vendor":{"type":"string"},"address_vendor":{"type":"string"}},"required":["name_vendor"]},"UpdateVendorRequestDto":{"type":"object","properties":{"name_vendor":{"type":"string"},"npwp_vendor":{"type":"string"},"company_code_vendor":{"type":"string"},"address_vendor":{"type":"string"}}},"CreateCustomerRequestDto":{"type":"object","properties":{"name_customer":{"type":"string"},"npwp_customer":{"type":"string"},"company_code_customer":{"type":"string"},"address_customer":{"type":"string"}},"required":["name_customer"]},"UpdateCustomerRequestDto":{"type":"object","properties":{"name_customer":{"type":"string"},"npwp_customer":{"type":"string"},"company_code_customer":{"type":"string"},"address_customer":{"type":"string"}}},"ApprovalWorkflowStepResponseDto":{"type":"object","properties":{"id_approval_workflow_step":{"type":"number"},"step_order":{"type":"number"},"approver_user_id":{"type":"object"},"min_approvals_required":{"type":"object"},"is_parallel":{"type":"object"},"note":{"type":"object"},"approver_user":{"$ref":"#/components/schemas/UserResponseDto"}},"required":["id_approval_workflow_step","step_order"]},"ApprovalWorkflowResponseDto":{"type":"object","properties":{"id_approval_workflow":{"type":"number"},"module":{"type":"string","enum":["VOYAGE","PURCHASE_REQUEST","RFQ"]},"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"]},"name_approval_workflow":{"type":"string"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalWorkflowStepResponseDto"}},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"created_by":{"type":"number"}},"required":["id_approval_workflow","module","action","name_approval_workflow","steps","created_at","updated_at"]},"CreateApprovalWorkflowStepDto":{"type":"object","properties":{"step_order":{"type":"number","example":1,"description":"Sequential order of the step. Must start at 1 and be continuous (1,2,3, ...)."},"approver_user_id":{"type":"number","example":12,"description":"ID of the user who will approve this step. Required for serial steps; may be omitted only for parallel configurations handled elsewhere."},"min_approvals_required":{"type":"number","example":1,"description":"Minimum number of approvals required when the step is parallel. Defaults to 1."},"is_parallel":{"type":"boolean","example":false,"description":"Whether this step allows parallel approvals. If true, multiple approvers can decide in parallel."},"note":{"type":"string","example":"Initial review by Project Manager","description":"Optional note describing the intent of this step."}},"required":["step_order"]},"CreateApprovalWorkflowRequestDto":{"type":"object","properties":{"module":{"type":"string","enum":["VOYAGE","PURCHASE_REQUEST","RFQ"],"example":"VOYAGE","description":"The domain/module this workflow belongs to (e.g., VOYAGE, CONTRACT, FINANCE)."},"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"example":"CREATE","description":"The action governed by this workflow (e.g., CREATE, UPDATE, DELETE)."},"name_approval_workflow":{"type":"string","example":"Voyage Creation Approval Workflow","description":"Human-readable name of the workflow."},"steps":{"description":"Ordered array of steps that define the approval sequence. Each step must have a unique, continuous `step_order`.","example":[{"step_order":1,"approver_user_id":101,"min_approvals_required":1,"is_parallel":false,"note":"Initial review by Project Manager"},{"step_order":2,"approver_user_id":205,"min_approvals_required":2,"is_parallel":true,"note":"Parallel approval by two Department Heads"}],"type":"array","items":{"$ref":"#/components/schemas/CreateApprovalWorkflowStepDto"}}},"required":["module","action","name_approval_workflow","steps"]},"UpdateApprovalWorkflowStepDto":{"type":"object","properties":{"step_order":{"type":"number","example":1,"description":"The sequential order of this step in the approval workflow. Must start at 1 and increase continuously."},"approver_user_id":{"type":"number","example":12,"description":"The unique ID of the approver (user) responsible for this step. Must be a valid user ID."},"min_approvals_required":{"type":"number","example":1,"description":"The minimum number of approvals required if this step is parallel. Defaults to 1."},"is_parallel":{"type":"boolean","example":false,"description":"Indicates whether this step allows parallel approvals. If true, multiple approvers can approve in parallel."},"note":{"type":"string","example":"Department Head approval","description":"Optional note or remark describing the purpose of this step."}}},"UpdateApprovalWorkflowRequestDto":{"type":"object","properties":{"module":{"type":"string","enum":["VOYAGE","PURCHASE_REQUEST","RFQ"],"example":"VOYAGE","description":"The module associated with this workflow (e.g., VOYAGE, CONTRACT, FINANCE). Optional during update."},"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"example":"CREATE","description":"The specific action that this workflow governs (e.g., CREATE, UPDATE, DELETE). Optional during update."},"name_approval_workflow":{"type":"string","example":"Voyage Creation Approval Workflow","description":"The human-readable name of this approval workflow. Optional during update."},"steps":{"description":"An array of steps defining the approval sequence. Each step must have a unique, continuous `step_order`.","example":[{"step_order":1,"approver_user_id":101,"min_approvals_required":1,"is_parallel":false,"note":"Initial review by Project Manager"},{"step_order":2,"approver_user_id":205,"min_approvals_required":2,"is_parallel":true,"note":"Parallel approval by Department Heads"}],"type":"array","items":{"$ref":"#/components/schemas/UpdateApprovalWorkflowStepDto"}}}},"OnTheFlyStepDto":{"type":"object","properties":{"order":{"type":"number","example":1,"description":"Sequential order of this step. Must start at 1 and be continuous across steps."},"approver_user_id":{"type":"number","example":123,"description":"Approver user ID. Required for serial steps; may be omitted only for parallel flows configured elsewhere."},"min_approvals_required":{"type":"number","example":1,"description":"Minimum approvals required for a parallel step. Defaults to 1. Must be >= 1 if `is_parallel` is true."},"is_parallel":{"type":"boolean","example":false,"description":"Whether this step is parallel. If true, multiple approvers may act concurrently."},"note":{"type":"string","example":"Initial screening by Operations","description":"Optional note for this step."}},"required":["order"]},"CreateApprovalRequestDto":{"type":"object","properties":{"module":{"type":"string","enum":["VOYAGE","PURCHASE_REQUEST","RFQ"],"example":"VOYAGE","description":"Domain/module of the approval request (e.g., VOYAGE, CONTRACT, FINANCE)."},"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"example":"CREATE","description":"Type of action to be approved (e.g., CREATE, UPDATE, DELETE)."},"resource_type":{"type":"string","example":"voyage","description":"The target resource type being requested (e.g., \"voyage\", \"contract\")."},"resource_id":{"type":"number","example":101,"description":"Identifier of the target resource (e.g., Voyage ID)."},"payload":{"type":"object","description":"Arbitrary payload representing proposed changes or metadata for the request.","example":{"title":"New Voyage A-12","eta":"2025-11-12T00:00:00Z"}},"steps":{"description":"Optional on-the-fly steps. Provide when you want to override or define a workflow inline. If provided, the array must contain at least one step.","example":[{"order":1,"approver_user_id":201,"is_parallel":false,"min_approvals_required":1,"note":"Project Manager review"},{"order":2,"approver_user_id":305,"is_parallel":false,"min_approvals_required":1,"note":"Finance approval"}],"type":"array","items":{"$ref":"#/components/schemas/OnTheFlyStepDto"}}},"required":["module","action","resource_type","resource_id"]},"DecideApprovalTaskDto":{"type":"object","properties":{"decision":{"type":"string","enum":["SUBMIT","APPROVE","REJECT","CANCEL"],"example":"APPROVE","description":"Decision taken by the approver for the current task. Must be one of the defined values: APPROVE or REJECT."},"note":{"type":"string","example":"All requirements verified. Proceeding with approval.","description":"Optional note or comment provided by the approver. Useful for audit or communication purposes."},"amendments":{"type":"object","description":"\n      Module-specific amendment payload. Only valid when decision=APPROVE.\n      Structure depends on the module — approval core treats this as opaque JSON.\n\n      Purchase Request example:\n      {\n        \"items\": [\n          { \"id_purchase_request_item\": 1, \"qty_requested\": 3 },\n          { \"id_purchase_request_item\": 2, \"qty_requested\": 5 }\n        ]\n      }\n    ","example":{"items":[{"id_purchase_request_item":1,"qty_requested":3},{"id_purchase_request_item":2,"qty_requested":5}]}}},"required":["decision"]},"ReferenceResponseDto":{"type":"object","properties":{"id":{"type":"number","example":1},"code":{"type":"string","example":"UOM-KG","description":"Unique code or identifier"},"name":{"type":"string","example":"Kilogram"},"description":{"type":"string","example":"Unit of measurement for weight"}},"required":["id","code","name"]},"ContractTemplateResponseDto":{"type":"object","properties":{"id_contract_template":{"type":"number","description":"Unique template ID.","example":17},"name_template":{"type":"string","description":"Human-readable template name.","example":"SI – Default"},"code_template":{"type":"string","description":"Unique template code used for reference/pathing (A–Z, 0–9, underscore).","example":"SI_DEFAULT"},"category_template":{"type":"object","description":"Optional category label for grouping/filtering.","example":"SI","nullable":true},"format_template":{"type":"string","description":"Template format used by the rendering engine.","enum":["HTML","PDFME"],"example":"HTML"},"content_template":{"type":"string","description":"Stored template content (HTML string for HTML; JSON string for PDFME).","example":"<h1 class=\"title\">Shipping Instruction</h1><p>Shipper: {{shipper_name}}</p>"},"css_template":{"type":"object","description":"Additional CSS for HTML templates. Ignored by PDFME.","example":".title{ font-weight:700 }","nullable":true},"status_template":{"type":"string","description":"Current template status (DRAFT, PUBLISHED, ARCHIVED).","enum":["DRAFT","PUBLISHED","ARCHIVED"],"example":"DRAFT"},"version_template":{"type":"number","description":"Latest version number associated with this template (master pointer).","example":3},"created_at":{"format":"date-time","type":"string","description":"Creation timestamp (UTC).","example":"2025-08-20T07:12:05.123Z"},"updated_at":{"format":"date-time","type":"string","description":"Last updated timestamp (UTC).","example":"2025-08-23T10:05:41.987Z"},"flag":{"type":"number","description":"Soft-delete flag (1 = active, 2 = deleted).","example":1}},"required":["id_contract_template","name_template","code_template","format_template","content_template","status_template","version_template","created_at","updated_at","flag"]},"ContractTemplateVersionResponseDto":{"type":"object","properties":{"id_contract_template_version":{"type":"number","description":"Snapshot row ID.","example":112},"template_id":{"type":"number","description":"Parent template ID.","example":17},"version":{"type":"number","description":"Snapshot version number.","example":3},"format_template":{"type":"string","description":"Template format at publish time.","enum":["HTML","PDFME"],"example":"HTML"},"content_template":{"type":"string","description":"Frozen content at publish time (HTML string; or JSON string for PDFME).","example":"<h1 class=\"title\">Shipping Instruction</h1><p>Shipper: {{shipper_name}}</p>"},"css_template":{"type":"object","description":"Frozen CSS at publish time (nullable).","example":".title{ font-weight:700 }","nullable":true},"name_template":{"type":"object","description":"Frozen name at publish time (nullable).","example":"SI – Default","nullable":true},"code_template":{"type":"object","description":"Frozen code at publish time (nullable).","example":"SI_DEFAULT","nullable":true},"category_template":{"type":"object","description":"Frozen category at publish time (nullable).","example":"SI","nullable":true},"hash_checksum":{"type":"string","description":"Stable SHA-256 checksum (content + metadata).","example":"0a9c4c0e4c6e8b2c7f2c1a5b9d3f7c1e2d4f6a8b0c2d4e6f8a0b2c4d6e8f0a1"},"changelog":{"type":"object","description":"Optional changelog describing the changes for this version.","example":"Add consignee block and fix logo position.","nullable":true},"published_by":{"type":"object","description":"User ID who published this version (nullable).","example":1024,"nullable":true},"published_at":{"format":"date-time","type":"string","description":"Published at (UTC).","example":"2025-08-21T03:45:12.000Z"},"created_at":{"format":"date-time","type":"string","description":"Row created at (UTC).","example":"2025-08-21T03:45:12.000Z"},"updated_at":{"format":"date-time","type":"string","description":"Row updated at (UTC).","example":"2025-08-21T03:45:12.000Z"},"flag":{"type":"number","description":"Soft-delete flag (1 = active, 2 = deleted).","example":1}},"required":["id_contract_template_version","template_id","version","format_template","content_template","hash_checksum","published_at","created_at","updated_at","flag"]},"CreateContractTemplateRequestDto":{"type":"object","properties":{"name_template":{"type":"string","description":"Human-readable template name (displayed in UI).","example":"SI – Default"},"code_template":{"type":"string","description":"Unique code for reference/pathing. Allowed: A–Z, 0–9, underscore (3–100).","example":"SI_DEFAULT"},"category_template":{"type":"string","description":"Optional category label for grouping/filtering.","example":"SI"},"format_template":{"type":"string","description":"Rendering format of the template.","enum":["HTML","PDFME"],"example":"HTML"},"content_template":{"description":"Template content. HTML: string with optional Handlebars. PDFME: JSON object (preferred) or JSON string.","oneOf":[{"type":"string","description":"HTML string or JSON string"},{"type":"object","description":"PDFME schema object"}],"examples":{"HTML_MINIMAL":{"summary":"HTML – minimal","value":"<h1 class=\"title\">Shipping Instruction</h1><p>Shipper: {{shipper_name}}</p>"},"PDFME_MINIMAL":{"summary":"PDFME – minimal","value":{"basePdf":{"width":210,"height":297,"padding":[10,10,10,10]},"schemas":[[{"name":"title","type":"text","position":{"x":20,"y":20},"width":170,"height":12}]]}}}},"css_template":{"type":"string","description":"Additional CSS for HTML format. Ignored by PDFME.","example":".title{ font-weight:700 } .table{ width:100%; border-collapse:collapse; }"}},"required":["name_template","code_template","format_template","content_template"]},"UpdateContractTemplateRequestDto":{"type":"object","properties":{"name_template":{"type":"string","description":"Human-readable template name (displayed in UI).","example":"SI – Default"},"code_template":{"type":"string","description":"Unique code for reference/pathing. Allowed: A–Z, 0–9, underscore (3–100).","example":"SI_DEFAULT"},"category_template":{"type":"string","description":"Optional category label for grouping/filtering.","example":"SI"},"format_template":{"type":"string","description":"Rendering format of the template.","enum":["HTML","PDFME"],"example":"HTML"},"content_template":{"description":"Template content. HTML: string with optional Handlebars. PDFME: JSON object (preferred) or JSON string.","oneOf":[{"type":"string","description":"HTML string or JSON string"},{"type":"object","description":"PDFME schema object"}],"examples":{"HTML_MINIMAL":{"summary":"HTML – minimal","value":"<h1 class=\"title\">Shipping Instruction</h1><p>Shipper: {{shipper_name}}</p>"},"PDFME_MINIMAL":{"summary":"PDFME – minimal","value":{"basePdf":{"width":210,"height":297,"padding":[10,10,10,10]},"schemas":[[{"name":"title","type":"text","position":{"x":20,"y":20},"width":170,"height":12}]]}}}},"css_template":{"type":"string","description":"Additional CSS for HTML format. Ignored by PDFME.","example":".title{ font-weight:700 } .table{ width:100%; border-collapse:collapse; }"}}},"PublishTemplateDto":{"type":"object","properties":{"idempotency_key":{"type":"string","description":"Optional idempotency key to prevent duplicate publish.","example":"publish-24a9aef0"},"changelog":{"type":"string","description":"Optional human-readable changelog for this published version.","example":"Add consignee block and fix logo position."}}},"TemplateFieldItemDto":{"type":"object","properties":{"name":{"type":"string","description":"Field path/name (e.g., \"title\", \"shipper.name\", \"items[].desc\").","example":"shipper.name"},"type":{"type":"object","description":"Field type (PDFME only: text/image/line/rectangle). Null for HTML.","example":"text","nullable":true},"array":{"type":"object","description":"True if the root field is used inside an #each (HTML extractor only).","nullable":true,"example":false},"occurrences":{"type":"number","description":"Number of occurrences of this field in the template.","example":2},"pages":{"description":"List of pages where the field appears (PDFME only).","nullable":true,"example":[0,1],"type":"array","items":{"type":"number"}},"viaHelpers":{"description":"Helpers that reference this field (HTML only, e.g., currency/formatDate).","nullable":true,"example":["currency"],"type":"array","items":{"type":"string"}}},"required":["name","type","array","occurrences","pages","viaHelpers"]},"TemplateFieldRegistryResponseDto":{"type":"object","properties":{"template_id":{"type":"number","description":"Parent template ID.","example":17},"version":{"type":"number","description":"Snapshot version that this registry was built from.","example":3},"format_template":{"type":"string","description":"Template format for which these fields were extracted.","enum":["HTML","PDFME"],"example":"PDFME"},"source_checksum":{"type":"string","description":"Checksum (sha256) of the source snapshot used for the registry (for ETag).","example":"0a9c4c0e4c6e8b2c7f2c1a5b9d3f7c1e2d4f6a8b0c2d4e6f8a0b2c4d6e8f0a1"},"fields":{"description":"Extracted fields from the snapshot.","type":"array","items":{"$ref":"#/components/schemas/TemplateFieldItemDto"}}},"required":["template_id","version","format_template","source_checksum","fields"]},"CloneContractTemplateRequestDto":{"type":"object","properties":{"source":{"type":"string","description":"Clone source: 'DRAFT' (master) or 'PUBLISHED' (snapshot). Default 'PUBLISHED'.","enum":["DRAFT","PUBLISHED"],"default":"PUBLISHED"},"template_version":{"type":"number","description":"Published version to clone (only for source=PUBLISHED). If omitted, uses latest.","example":3},"name_template":{"type":"string","description":"Optional override for new template name. Default: \"<source name> (Clone)\".","example":"SI – Default (Clone)"},"code_template":{"type":"string","description":"Optional override for new template code (A–Z, 0–9, underscore, 3–100). If omitted, server generates a unique *_CLONE code.","example":"SI_DEFAULT_CLONE"},"category_template":{"type":"string","description":"Optional category. Default: inherits source category.","example":"SI"},"idempotency_key":{"type":"string","description":"Optional idempotency key to avoid duplicate clone.","example":"clone-req-2f9c7a"}}},"ContractDocumentResponseDto":{"type":"object","properties":{"id_contract_document":{"type":"number","description":"Unique ID of the generated document record.","example":245},"template_id":{"type":"number","description":"Template ID used during generation.","example":17},"template_version":{"type":"number","description":"Published template version used for this document.","example":3},"output_url":{"type":"string","description":"Storage URL of the rendered output file.","example":"https://files.example.com/contracts/SI_DEFAULT/v3/ShippingInstruction_Aug2025-1724461339123.pdf"},"output_type":{"type":"string","description":"Rendered output type.","enum":["PDF","DOCX"],"example":"PDF"},"hash_html":{"type":"object","description":"Deterministic content hash used for deduplication. May be null if hashing is not applicable.","example":"a2f0c4b7d3e9e1f1b8b3e6c2d4a5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3","nullable":true},"idempotency_key":{"type":"object","description":"Idempotency key echoed from the request, if provided during generation.","example":"req-7d3b1a42a1","nullable":true},"generated_by":{"type":"number","description":"User ID of the requester who generated the document.","example":1024,"nullable":true},"payload_json":{"type":"object","description":"Rendering context persisted for traceability (mirrors `payload_manual`).","additionalProperties":true,"example":{"shipper_name":"PT Samudra Nusantara","consignee_name":"PT Bahari Sejahtera","issue_date":"2025-08-20"}},"created_at":{"format":"date-time","type":"string","description":"Creation timestamp (UTC).","example":"2025-08-24T09:12:05.123Z"}},"required":["id_contract_document","template_id","template_version","output_url","output_type","payload_json","created_at"]},"GenerateContractRequestDto":{"type":"object","properties":{"template_id":{"type":"number","description":"Numeric ID of the template to render from. Must reference an active Contract Template.","example":17,"minimum":1},"template_version":{"type":"number","description":"Exact published snapshot version to use. If omitted, the latest published version is used.","example":3,"minimum":1,"nullable":true},"payload_manual":{"type":"object","description":"Rendering context passed to the engine (Handlebars/PDFMe). Include assets under `payload_manual.__assets` when needed.","additionalProperties":true,"example":{"shipper_name":"PT Samudra Nusantara","consignee_name":"PT Bahari Sejahtera","issue_date":"2025-08-20","__assets":{"logoPng":"data:image/png;base64,iVBORw0K..."}}},"output":{"type":"string","description":"Desired output format. For PDFMe templates, only `PDF` is supported.","enum":["PDF","DOCX"],"example":"PDF"},"file_name":{"type":"string","description":"Base file name (without extension). The service may append a nonce and enforce the correct extension.","example":"ShippingInstruction_Aug2025","nullable":true},"idempotency_key":{"type":"string","description":"Idempotency key scoped by (template_id, template_version, output). Prevents duplicate generation.","example":"req-7d3b1a42a1","minLength":1,"maxLength":128,"nullable":true}},"required":["template_id","payload_manual","output"]},"ContractPreviewResponseDto":{"type":"object","properties":{"type":{"type":"string","enum":["html","pdf"],"description":"Preview output type."},"html":{"type":"object","nullable":true,"description":"Rendered HTML string (only for HTML templates). Use as <iframe srcdoc=\"...\"> or directly in an editor."},"pdf_base64":{"type":"object","nullable":true,"description":"Base64-encoded PDF (without \"data:application/pdf;base64,\" prefix). Convert to a Blob on the client for inline preview or download.","example":"JVBERi0xLjQKJcTl8uXr... (truncated)"}},"required":["type","html","pdf_base64"]},"PreviewContractRequestDto":{"type":"object","properties":{"template_id":{"type":"number","description":"ID of the template to preview.","example":17,"minimum":1},"template_version":{"type":"number","description":"When source=PUBLISHED: specific published version. If omitted, latest published is used.","example":3,"minimum":1,"nullable":true},"payload_manual":{"type":"object","description":"Data context fed into the engine (Handlebars for HTML / inputs for PDFMe).","additionalProperties":true,"example":{"title":"Invoice #123","amount":250000}},"mode":{"type":"string","description":"Preview mode. AUTO lets the engine decide (HTML → html, PDFMe → pdf). Explicit HTML/PDF only for compatible engines.","enum":["AUTO","HTML","PDF"],"default":"AUTO","nullable":true},"source":{"type":"string","description":"Preview source. 'PUBLISHED' (default) uses immutable snapshots; 'DRAFT' uses the working copy.","enum":["PUBLISHED","DRAFT"],"default":"PUBLISHED","nullable":true}},"required":["template_id","payload_manual"]},"PreviewDraftTemplateRequestDto":{"type":"object","properties":{"format_template":{"type":"string","description":"Template format that decides the renderer to use.","enum":["HTML","PDFME"],"example":"HTML"},"content_template":{"description":"Template content. HTML: a string (supports Handlebars). PDFME: schema object or JSON string.","oneOf":[{"type":"string","description":"HTML string or JSON string"},{"type":"object","description":"PDFMe schema object"}],"examples":{"HTML_MIN":{"summary":"HTML – minimal","value":"<h1>{{title}}</h1><p>By {{author}}</p>"},"PDFME_MIN":{"summary":"PDFME – minimal","value":{"basePdf":{"width":210,"height":297},"schemas":[[{"name":"title","type":"text","x":20,"y":20,"width":170,"height":12}]]}}}},"css_template":{"type":"string","description":"Optional CSS for HTML format. Ignored by PDFME.","example":"h1{font-weight:700;}","nullable":true},"payload_manual":{"type":"object","description":"Manual fields to feed into the engine. For images, prefer data URLs. Remote URLs allowed only if backend enables it.","additionalProperties":true,"example":{"title":"Hello","author":"Ada Lovelace"}},"mode":{"type":"string","description":"Preview mode. AUTO lets the engine decide (HTML → html, PDFMe → pdf). HTML only for HTML; PDF only for PDFMe.","enum":["AUTO","HTML","PDF"],"default":"AUTO","nullable":true}},"required":["format_template","content_template","payload_manual"]},"ValidateGenerateResponseDto":{"type":"object","properties":{"valid":{"type":"boolean","description":"Overall validation result."},"template_id":{"type":"number","description":"Validated Template ID."},"template_version":{"type":"number","description":"Validated Template Version."},"engine":{"type":"string","description":"Resolved engine for the target snapshot.","enum":["HTML","PDFME"]},"summary":{"type":"object","description":"Summary counts for quick diagnostics.","example":{"total_fields":17,"provided_fields":15}},"errors":{"type":"object","description":"Validation errors (present only when valid=false): missing fields, extra fields, and type mismatches.","example":{"missing_fields":["shipper_name"],"extra_fields":["typo_shiper"],"type_mismatches":[{"field":"amount","expected":"number","received":"string"}]},"nullable":true},"warnings":{"type":"object","description":"Non-fatal warnings detected during validation.","example":["asset 'logo2' present but not referenced"],"nullable":true}},"required":["valid","template_id","template_version","engine","summary"]},"ValidateGenerateRequestDto":{"type":"object","properties":{"template_id":{"type":"number","description":"Template ID to validate against.","example":42,"minimum":1},"template_version":{"type":"number","description":"Exact published version to validate against. If omitted, latest published snapshot is used.","example":3,"minimum":1,"nullable":true},"payload_manual":{"type":"object","description":"Rendering context (same shape as payload_manual in /generate). Assets may be sent under __assets.","additionalProperties":true,"example":{"shipper_name":"PT Samudra Nusantara","consignee_name":"PT Bahari Sejahtera","issue_date":"2025-08-20","amount":123.45,"__assets":{"logoPng":"data:image/png;base64,iVBOR..."}}}},"required":["template_id","payload_manual"]},"ContractAssetResponseDto":{"type":"object","properties":{"id_contract_asset":{"type":"number"},"name_asset":{"type":"string"},"code_asset":{"type":"string"},"type_asset":{"type":"string","enum":["HEADER","FOOTER"]},"content_asset":{"type":"string"},"css_asset":{"type":"string"},"height":{"type":"string"},"status_asset":{"type":"string","enum":["DRAFT","PUBLISHED","ARCHIVED"]},"meta_json":{"type":"object"},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"flag":{"type":"number"}},"required":["id_contract_asset","name_asset","code_asset","type_asset","content_asset","css_asset","height","status_asset","meta_json","created_at","updated_at","flag"]},"CreateContractAssetDto":{"type":"object","properties":{"name_asset":{"type":"string"},"code_asset":{"type":"string"},"type_asset":{"type":"string","enum":["HEADER","FOOTER"]},"content_asset":{"type":"string","description":"HTML fragment (tanpa <html>)"},"css_asset":{"type":"string"},"height":{"type":"string","example":"15mm"},"meta_json":{"type":"object"}},"required":["name_asset","code_asset","type_asset","content_asset"]},"UpdateContractAssetDto":{"type":"object","properties":{"name_asset":{"type":"string"},"code_asset":{"type":"string"},"type_asset":{"type":"string","enum":["HEADER","FOOTER"]},"content_asset":{"type":"string","description":"HTML fragment (tanpa <html>)"},"css_asset":{"type":"string"},"height":{"type":"string","example":"15mm"},"meta_json":{"type":"object"}}},"InventoryItemResponseDto":{"type":"object","properties":{"id_inventory_item":{"type":"number","description":"Inventory item ID"},"product_category":{"type":"string","description":"Product category","enum":["SAFETY_EQUIPMENT","NAVIGATION_EQUIPMENT","MACHINERY_PARTS","ELECTRICAL_COMPONENTS","DECK_SUPPLIES","ENGINE_SUPPLIES","GALLEY_SUPPLIES","CABIN_SUPPLIES"]},"product_type":{"type":"string","description":"Product type","enum":["CONSUMABLE","SPARE_PART","EQUIPMENT","TOOL","MATERIAL","CHEMICAL","ELECTRONIC","MECHANICAL"]},"quantity":{"type":"string","description":"Quantity with unit (e.g., 70pcs)"},"description":{"type":"string","description":"Product description"},"cost":{"type":"string","description":"Cost category","enum":["PROPERTY","EQUIPMENT","OPERATIONAL","MAINTENANCE","ADMINISTRATIVE","SAFETY"]},"sales_price":{"type":"number","description":"Sales price"},"created_at":{"format":"date-time","type":"string","description":"Created at timestamp"},"updated_at":{"format":"date-time","type":"string","description":"Updated at timestamp"},"flag":{"type":"number","description":"Flag (1=active, 2=draft, 3=non-active)"}},"required":["id_inventory_item","product_category","product_type","quantity","description","cost","sales_price","created_at","updated_at","flag"]},"UpdateInventoryItemDto":{"type":"object","properties":{"product_category":{"type":"string","description":"Product category. Only this field, product_type, and description can be updated. Other fields are locked.","enum":["SAFETY_EQUIPMENT","NAVIGATION_EQUIPMENT","MACHINERY_PARTS","ELECTRICAL_COMPONENTS","DECK_SUPPLIES","ENGINE_SUPPLIES","GALLEY_SUPPLIES","CABIN_SUPPLIES"],"example":"SAFETY_EQUIPMENT"},"product_type":{"type":"string","description":"Product type classification. Only this field, product_category, and description can be updated.","enum":["CONSUMABLE","SPARE_PART","EQUIPMENT","TOOL","MATERIAL","CHEMICAL","ELECTRONIC","MECHANICAL"],"example":"EQUIPMENT"},"description":{"type":"string","description":"Detailed product description. Only this field, product_category, and product_type can be updated. Cannot be empty if provided.","example":"Life jackets - adult size, SOLAS approved, updated specifications","minLength":1}}},"UserSummaryDto":{"type":"object","properties":{"id_user":{"type":"number"},"username":{"type":"string"},"email":{"type":"string"},"phone_number":{"type":"object"}},"required":["id_user","username","email"]},"ApprovalTaskSummaryDto":{"type":"object","properties":{"id_approval_task":{"type":"number"},"step_order":{"type":"number"},"status":{"type":"string","enum":["DRAFT","PENDING","IN_REVIEW","APPROVED","REJECTED","CANCELLED"]},"assignee_user_id":{"type":"object"},"decided_at":{"type":"object"},"note":{"type":"object"},"amendments":{"type":"object","description":"Module-specific amendments applied during approval.","example":{"items":[{"id_purchase_request_item":22,"qty_requested":1}]}}},"required":["id_approval_task","step_order","status"]},"ApprovalSummaryDto":{"type":"object","properties":{"id_approval_request":{"type":"number"},"status":{"type":"string","enum":["DRAFT","PENDING","IN_REVIEW","APPROVED","REJECTED","CANCELLED"]},"current_step_order":{"type":"object"},"tasks":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalTaskSummaryDto"}},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"}},"required":["id_approval_request","status","tasks","created_at","updated_at"]},"PurchaseRequestListResponseDto":{"type":"object","properties":{"id_purchase_request":{"type":"number"},"reference_code":{"type":"string"},"source_document":{"type":"object"},"id_requested_by":{"type":"number"},"id_created_by":{"type":"number"},"department":{"type":"string","enum":["OPERATIONS","TECHNICAL","MARINE","ENGINE","DECK","PROCUREMENT","FINANCE","HR","IT","HSSE","LEGAL","COMMERCIAL","GENERAL_AFFAIRS"]},"purchase_team":{"type":"string","enum":["TECHNICAL_SUPPLIES","DECK_STORES","ENGINE_STORES","PROVISION_STORES","SAFETY_EQUIPMENT","BUNKER_FUEL","LUBRICANTS","CHEMICALS","MAJOR_REPAIRS","GENERAL_PROCUREMENT","SERVICES","CAPEX","MEDICAL_SUPPLIES","NAVIGATION_EQUIPMENT","COMMUNICATION"]},"status":{"type":"string","enum":["DRAFT","TO_BE_APPROVED","REJECTED","APPROVED","IN_PROGRESS","DONE"]},"description":{"type":"object"},"estimated_cost":{"type":"object"},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"requested_by":{"$ref":"#/components/schemas/UserSummaryDto"},"created_by":{"$ref":"#/components/schemas/UserSummaryDto"},"approval":{"$ref":"#/components/schemas/ApprovalSummaryDto"}},"required":["id_purchase_request","reference_code","id_requested_by","id_created_by","department","purchase_team","status","created_at","updated_at","requested_by","created_by"]},"AssetSummaryDto":{"type":"object","properties":{"id_asset":{"type":"number"},"code_asset":{"type":"string"},"name_asset":{"type":"string"},"status_asset":{"type":"string","enum":["DRAFT","RUNNING"]}},"required":["id_asset","code_asset","name_asset","status_asset"]},"PurchaseRequestItemResponseDto":{"type":"object","properties":{"id_purchase_request_item":{"type":"number"},"id_asset":{"type":"number"},"asset":{"$ref":"#/components/schemas/AssetSummaryDto"},"asset_code_snapshot":{"type":"string"},"asset_name_snapshot":{"type":"string"},"qty_requested":{"type":"number"},"updated_at":{"format":"date-time","type":"string"}},"required":["id_purchase_request_item","id_asset","asset_code_snapshot","asset_name_snapshot","qty_requested","updated_at"]},"PurchaseRequestFileDto":{"type":"object","properties":{"id_file":{"type":"number"},"name_file":{"type":"string"},"path_file":{"type":"string"},"type_file":{"type":"string"},"size_file":{"type":"number"},"uploaded_at_file":{"format":"date-time","type":"string"}},"required":["id_file","name_file","path_file","type_file","size_file","uploaded_at_file"]},"PurchaseRequestDetailResponseDto":{"type":"object","properties":{"id_purchase_request":{"type":"number"},"reference_code":{"type":"string"},"source_document":{"type":"object"},"id_requested_by":{"type":"number"},"id_created_by":{"type":"number"},"department":{"type":"string","enum":["OPERATIONS","TECHNICAL","MARINE","ENGINE","DECK","PROCUREMENT","FINANCE","HR","IT","HSSE","LEGAL","COMMERCIAL","GENERAL_AFFAIRS"]},"purchase_team":{"type":"string","enum":["TECHNICAL_SUPPLIES","DECK_STORES","ENGINE_STORES","PROVISION_STORES","SAFETY_EQUIPMENT","BUNKER_FUEL","LUBRICANTS","CHEMICALS","MAJOR_REPAIRS","GENERAL_PROCUREMENT","SERVICES","CAPEX","MEDICAL_SUPPLIES","NAVIGATION_EQUIPMENT","COMMUNICATION"]},"status":{"type":"string","enum":["DRAFT","TO_BE_APPROVED","REJECTED","APPROVED","IN_PROGRESS","DONE"]},"description":{"type":"object"},"estimated_cost":{"type":"object"},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"requested_by":{"$ref":"#/components/schemas/UserSummaryDto"},"created_by":{"$ref":"#/components/schemas/UserSummaryDto"},"approval":{"$ref":"#/components/schemas/ApprovalSummaryDto"},"items":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseRequestItemResponseDto"}},"files":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseRequestFileDto"}}},"required":["id_purchase_request","reference_code","id_requested_by","id_created_by","department","purchase_team","status","created_at","updated_at","requested_by","created_by","items","files"]},"CreatePurchaseRequestDto":{"type":"object","properties":{"source_document":{"type":"string","description":"External source document reference (voyage number, work order, project code, etc.).","example":"VY-20240315-0012","maxLength":255},"id_requested_by":{"type":"number","description":"User ID of the requester.","example":5},"department":{"type":"string","description":"Department initiating the purchase request","enum":["OPERATIONS","TECHNICAL","MARINE","ENGINE","DECK","PROCUREMENT","FINANCE","HR","IT","HSSE","LEGAL","COMMERCIAL","GENERAL_AFFAIRS"],"example":"TECHNICAL"},"purchase_team":{"type":"string","description":"Purchase team responsible for handling this request.","enum":["TECHNICAL_SUPPLIES","DECK_STORES","ENGINE_STORES","PROVISION_STORES","SAFETY_EQUIPMENT","BUNKER_FUEL","LUBRICANTS","CHEMICALS","MAJOR_REPAIRS","GENERAL_PROCUREMENT","SERVICES","CAPEX","MEDICAL_SUPPLIES","NAVIGATION_EQUIPMENT","COMMUNICATION"],"example":"ENGINE_STORES"},"description":{"type":"string","description":"General description or purpose of this purchase request.","example":"Monthly maintenance for MV Armada - Q1 2024"},"estimated_cost":{"type":"number","description":"Total estimated cost at header level.","example":4250000000,"minimum":0},"items":{"type":"string","description":"Line items as JSON string. Minimum 1 item required.","example":"[{\"id_asset\":1,\"qty_requested\":1}]"}},"required":["id_requested_by","department","purchase_team","items"]},"RfqVendorDto":{"type":"object","properties":{"id_vendor":{"type":"number"},"name_vendor":{"type":"string"},"company_code_vendor":{"type":"object"},"address_vendor":{"type":"object"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"]}},"required":["id_vendor","name_vendor"]},"RfqBuyerDto":{"type":"object","properties":{"id_user":{"type":"number"},"username":{"type":"string"},"email":{"type":"string"}},"required":["id_user","username","email"]},"RfqApprovalTaskDto":{"type":"object","properties":{"id_approval_task":{"type":"number"},"step_order":{"type":"number"},"assignee_name":{"type":"object"},"status":{"type":"string","enum":["DRAFT","PENDING","IN_REVIEW","APPROVED","REJECTED","CANCELLED"]},"note":{"type":"object"},"decided_at":{"type":"object"}},"required":["id_approval_task","step_order","status"]},"RfqApprovalDto":{"type":"object","properties":{"id_approval_request":{"type":"number"},"status":{"type":"string","enum":["DRAFT","PENDING","IN_REVIEW","APPROVED","REJECTED","CANCELLED"]},"current_step_order":{"type":"object"},"tasks":{"type":"array","items":{"$ref":"#/components/schemas/RfqApprovalTaskDto"}}},"required":["id_approval_request","status","tasks"]},"RfqListResponseDto":{"type":"object","properties":{"id_rfq":{"type":"number"},"reference_code":{"type":"string"},"id_purchase_request":{"type":"object"},"source_document":{"type":"object"},"id_vendor":{"type":"object"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"]},"id_buyer":{"type":"object"},"currency":{"type":"string","enum":["IDR","USD"]},"order_deadline":{"type":"object"},"expected_arrival":{"type":"object"},"deliver_to":{"type":"object"},"grand_total":{"type":"number"},"status":{"type":"string","enum":["DRAFT","SENT","TO_BE_APPROVED","APPROVED","REJECTED","PO"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"vendor":{"$ref":"#/components/schemas/RfqVendorDto"},"buyer":{"$ref":"#/components/schemas/RfqBuyerDto"},"approval":{"$ref":"#/components/schemas/RfqApprovalDto"}},"required":["id_rfq","reference_code","grand_total","status","created_at","updated_at"]},"RfqAssetSummaryDto":{"type":"object","properties":{"id_asset":{"type":"number"},"code_asset":{"type":"string"},"name_asset":{"type":"string"},"status_asset":{"type":"string","enum":["DRAFT","RUNNING"]}},"required":["id_asset","code_asset","name_asset","status_asset"]},"RfqItemResponseDto":{"type":"object","properties":{"id_rfq_item":{"type":"number"},"id_asset":{"type":"number"},"asset":{"$ref":"#/components/schemas/RfqAssetSummaryDto"},"asset_code_snapshot":{"type":"string"},"asset_name_snapshot":{"type":"string"},"qty":{"type":"number"},"unit_price":{"type":"number"},"discount_percent":{"type":"number"},"total_price":{"type":"number"},"note":{"type":"object"},"updated_at":{"format":"date-time","type":"string"}},"required":["id_rfq_item","id_asset","asset_code_snapshot","asset_name_snapshot","qty","unit_price","discount_percent","total_price","updated_at"]},"RfqDetailResponseDto":{"type":"object","properties":{"id_rfq":{"type":"number"},"reference_code":{"type":"string"},"id_purchase_request":{"type":"object"},"source_document":{"type":"object"},"id_vendor":{"type":"object"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"]},"id_buyer":{"type":"object"},"currency":{"type":"string","enum":["IDR","USD"]},"order_deadline":{"type":"object"},"expected_arrival":{"type":"object"},"deliver_to":{"type":"object"},"grand_total":{"type":"number"},"status":{"type":"string","enum":["DRAFT","SENT","TO_BE_APPROVED","APPROVED","REJECTED","PO"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"vendor":{"$ref":"#/components/schemas/RfqVendorDto"},"buyer":{"$ref":"#/components/schemas/RfqBuyerDto"},"approval":{"$ref":"#/components/schemas/RfqApprovalDto"},"items":{"type":"array","items":{"$ref":"#/components/schemas/RfqItemResponseDto"}}},"required":["id_rfq","reference_code","grand_total","status","created_at","updated_at","items"]},"CreateRfqItemDto":{"type":"object","properties":{"id_asset":{"type":"number"},"qty":{"type":"number"},"unit_price":{"type":"number"},"discount_percent":{"type":"number"},"note":{"type":"string"}},"required":["id_asset","qty","unit_price"]},"CreateRfqRequestDto":{"type":"object","properties":{"source_document":{"type":"string","description":"Must match an existing PR reference_code (e.g. PR-2026-001). If id_purchase_request is not provided, it will be auto-resolved by querying PR with this reference_code."},"id_purchase_request":{"type":"number","description":"FK to Purchase Request. Optional — auto-resolved from source_document if omitted."},"id_vendor":{"type":"number"},"id_buyer":{"type":"number"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"],"description":"Vendor source (LOCAL/IMPORT). If omitted, auto-populated from the vendor record."},"currency":{"type":"string","enum":["IDR","USD"]},"order_deadline":{"type":"string"},"expected_arrival":{"type":"string"},"deliver_to":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/CreateRfqItemDto"}}},"required":["id_vendor","id_buyer","currency","order_deadline","expected_arrival","deliver_to"]},"UpdateRfqItemDto":{"type":"object","properties":{"id_rfq_item":{"type":"number","description":"ID of the RFQ item to update."},"qty":{"type":"number"},"unit_price":{"type":"number"},"discount_percent":{"type":"number"},"note":{"type":"string"}},"required":["id_rfq_item"]},"UpdateRfqRequestDto":{"type":"object","properties":{"source_document":{"type":"string","description":"Must match an existing PR reference_code. If id_purchase_request is not provided, it will be auto-resolved by querying PR with this reference_code."},"id_purchase_request":{"type":"number","description":"FK to Purchase Request. Optional — auto-resolved from source_document if omitted."},"id_vendor":{"type":"number"},"id_buyer":{"type":"number"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"],"description":"Vendor source override. Auto-populated from vendor if omitted when changing vendor."},"currency":{"type":"string","enum":["IDR","USD"]},"order_deadline":{"type":"string"},"expected_arrival":{"type":"string"},"deliver_to":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/UpdateRfqItemDto"}}}},"PoVendorDto":{"type":"object","properties":{"id_vendor":{"type":"number"},"name_vendor":{"type":"string"},"company_code_vendor":{"type":"object"},"address_vendor":{"type":"object"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"]}},"required":["id_vendor","name_vendor"]},"PoCreatorDto":{"type":"object","properties":{"id_user":{"type":"number"},"username":{"type":"string"},"email":{"type":"string"}},"required":["id_user","username","email"]},"PoListResponseDto":{"type":"object","properties":{"id_purchase_order":{"type":"number"},"reference_code":{"type":"string"},"id_rfq":{"type":"object"},"id_purchase_request":{"type":"object"},"source_document":{"type":"object"},"id_vendor":{"type":"object"},"currency":{"type":"string","enum":["IDR","USD"]},"confirmation_date":{"type":"object"},"expected_arrival":{"type":"object"},"arrival_date":{"type":"object"},"deliver_to":{"type":"object"},"note":{"type":"object"},"grand_total":{"type":"number"},"status":{"type":"string","enum":["DRAFT","WAITING_BILLS","FULLY_BILLED","REJECTED"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"vendor":{"$ref":"#/components/schemas/PoVendorDto"},"creator":{"$ref":"#/components/schemas/PoCreatorDto"}},"required":["id_purchase_order","reference_code","grand_total","status","created_at","updated_at"]},"PoAssetSummaryDto":{"type":"object","properties":{"id_asset":{"type":"number"},"code_asset":{"type":"string"},"name_asset":{"type":"string"},"status_asset":{"type":"string","enum":["DRAFT","RUNNING"]}},"required":["id_asset","code_asset","name_asset","status_asset"]},"PoItemResponseDto":{"type":"object","properties":{"id_po_item":{"type":"number"},"id_asset":{"type":"number"},"asset":{"$ref":"#/components/schemas/PoAssetSummaryDto"},"asset_code_snapshot":{"type":"string"},"asset_name_snapshot":{"type":"string"},"qty":{"type":"number"},"unit_price":{"type":"number"},"discount_percent":{"type":"number"},"total_price":{"type":"number"},"note":{"type":"object"},"updated_at":{"format":"date-time","type":"string"}},"required":["id_po_item","id_asset","asset_code_snapshot","asset_name_snapshot","qty","unit_price","discount_percent","total_price","updated_at"]},"PoDetailResponseDto":{"type":"object","properties":{"id_purchase_order":{"type":"number"},"reference_code":{"type":"string"},"id_rfq":{"type":"object"},"id_purchase_request":{"type":"object"},"source_document":{"type":"object"},"id_vendor":{"type":"object"},"currency":{"type":"string","enum":["IDR","USD"]},"confirmation_date":{"type":"object"},"expected_arrival":{"type":"object"},"arrival_date":{"type":"object"},"deliver_to":{"type":"object"},"note":{"type":"object"},"grand_total":{"type":"number"},"status":{"type":"string","enum":["DRAFT","WAITING_BILLS","FULLY_BILLED","REJECTED"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"vendor":{"$ref":"#/components/schemas/PoVendorDto"},"creator":{"$ref":"#/components/schemas/PoCreatorDto"},"items":{"type":"array","items":{"$ref":"#/components/schemas/PoItemResponseDto"}}},"required":["id_purchase_order","reference_code","grand_total","status","created_at","updated_at","items"]},"UpdatePurchaseOrderDto":{"type":"object","properties":{"arrival_date":{"type":"string","description":"Actual date goods arrived. Different from expected_arrival.","example":"2026-04-05"},"note":{"type":"string","description":"Internal note for this PO."}}},"VendorBillVendorDto":{"type":"object","properties":{"id_vendor":{"type":"number"},"name_vendor":{"type":"string"},"company_code_vendor":{"type":"object"},"address_vendor":{"type":"object"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"]}},"required":["id_vendor","name_vendor"]},"VendorBillAssetDto":{"type":"object","properties":{"id_asset":{"type":"number"},"code_asset":{"type":"string"},"name_asset":{"type":"string"},"status_asset":{"type":"string","enum":["DRAFT","RUNNING"]}},"required":["id_asset","code_asset","name_asset","status_asset"]},"VendorBillItemResponseDto":{"type":"object","properties":{"id_vendor_bill_item":{"type":"number"},"id_asset":{"type":"object"},"asset":{"$ref":"#/components/schemas/VendorBillAssetDto"},"asset_code_snapshot":{"type":"string"},"asset_name_snapshot":{"type":"string"},"qty":{"type":"number"},"unit_price":{"type":"number"},"discount_percent":{"type":"number"},"total_price":{"type":"number"},"account_snapshot":{"type":"object"},"note":{"type":"object"}},"required":["id_vendor_bill_item","asset_code_snapshot","asset_name_snapshot","qty","unit_price","discount_percent","total_price"]},"VendorBillPaymentResponseDto":{"type":"object","properties":{"id_vendor_bill_payment":{"type":"number"},"journal":{"type":"string"},"payment_method":{"type":"string","enum":["CASH"]},"recipient_bank_account":{"type":"object"},"amount":{"type":"number"},"payment_date":{"format":"date-time","type":"string"},"memo":{"type":"object"},"created_at":{"format":"date-time","type":"string"}},"required":["id_vendor_bill_payment","journal","payment_method","amount","payment_date","created_at"]},"VendorBillDetailResponseDto":{"type":"object","properties":{"id_vendor_bill":{"type":"number"},"reference_code":{"type":"string"},"id_purchase_order":{"type":"object"},"source_document":{"type":"object"},"id_vendor":{"type":"object"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"]},"bill_reference":{"type":"object"},"bill_date":{"type":"object"},"accounting_date":{"type":"object"},"payment_reference":{"type":"object"},"recipient_bank":{"type":"object"},"due_date":{"type":"object"},"journal":{"type":"object"},"currency":{"type":"string","enum":["IDR","USD"]},"grand_total":{"type":"number"},"status":{"type":"string","enum":["DRAFT","POSTED","FULLY_PAID"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"vendor":{"$ref":"#/components/schemas/VendorBillVendorDto"},"items":{"type":"array","items":{"$ref":"#/components/schemas/VendorBillItemResponseDto"}},"payments":{"type":"array","items":{"$ref":"#/components/schemas/VendorBillPaymentResponseDto"}}},"required":["id_vendor_bill","reference_code","grand_total","status","created_at","updated_at","items","payments"]},"VendorBillListResponseDto":{"type":"object","properties":{"id_vendor_bill":{"type":"number"},"reference_code":{"type":"string"},"id_purchase_order":{"type":"object"},"source_document":{"type":"object"},"id_vendor":{"type":"object"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"]},"bill_reference":{"type":"object"},"bill_date":{"type":"object"},"accounting_date":{"type":"object"},"payment_reference":{"type":"object"},"recipient_bank":{"type":"object"},"due_date":{"type":"object"},"journal":{"type":"object"},"currency":{"type":"string","enum":["IDR","USD"]},"grand_total":{"type":"number"},"status":{"type":"string","enum":["DRAFT","POSTED","FULLY_PAID"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"vendor":{"$ref":"#/components/schemas/VendorBillVendorDto"}},"required":["id_vendor_bill","reference_code","grand_total","status","created_at","updated_at"]},"CreateVendorBillItemDto":{"type":"object","properties":{"description":{"type":"string","description":"Item description (free text).","maxLength":255},"qty":{"type":"number","description":"Quantity.","minimum":0},"unit_price":{"type":"number","description":"Unit price.","minimum":0},"discount_percent":{"type":"number","description":"Discount percentage (0–100). Defaults to 0.","default":0},"account":{"type":"string","description":"COA account number.","maxLength":100},"note":{"type":"string","description":"Note for this item."}},"required":["description","qty","unit_price"]},"CreateVendorBillDto":{"type":"object","properties":{"id_vendor":{"type":"number","description":"Vendor ID."},"bill_reference":{"type":"string","description":"Vendor's own bill/invoice reference number."},"bill_date":{"type":"string","description":"Date of the vendor bill. Format: YYYY-MM-DD."},"accounting_date":{"type":"string","description":"Accounting date for journal entries. Format: YYYY-MM-DD."},"due_date":{"type":"string","description":"Due date for payment. Format: YYYY-MM-DD."},"journal":{"type":"string","description":"Journal identifier."},"currency":{"type":"string","enum":["IDR","USD"],"description":"Currency."},"payment_reference":{"type":"string","description":"Payment reference number."},"recipient_bank":{"type":"string","description":"Recipient bank name or account info."},"items":{"description":"Line items. At least 1 required.","type":"array","items":{"$ref":"#/components/schemas/CreateVendorBillItemDto"}}},"required":["id_vendor","items"]},"UpdateVendorBillDto":{"type":"object","properties":{"bill_reference":{"type":"string","description":"Vendor's own bill/invoice reference number."},"bill_date":{"type":"string","description":"Date of the vendor bill. Format: YYYY-MM-DD."},"accounting_date":{"type":"string","description":"Accounting date for journal entries. Format: YYYY-MM-DD."},"payment_reference":{"type":"string","description":"Payment reference number."},"recipient_bank":{"type":"string","description":"Recipient bank name or account info."},"due_date":{"type":"string","description":"Due date for payment. Format: YYYY-MM-DD."},"journal":{"type":"string","description":"Journal identifier."}}},"RegisterPaymentDto":{"type":"object","properties":{"journal":{"type":"string","description":"Journal for this payment."},"payment_method":{"type":"string","enum":["CASH"],"description":"Payment method. Currently only CASH."},"recipient_bank_account":{"type":"string","description":"Recipient bank account."},"amount":{"type":"number","description":"Payment amount."},"payment_date":{"type":"string","description":"Payment date. Format: YYYY-MM-DD."},"memo":{"type":"string","description":"Memo. Defaults to vendor bill reference_code if omitted."}},"required":["journal","payment_method","amount","payment_date"]},"GrVendorDto":{"type":"object","properties":{"id_vendor":{"type":"number"},"name_vendor":{"type":"string"},"company_code_vendor":{"type":"object"},"source_vendor":{"type":"string","enum":["LOCAL","IMPORT"]}},"required":["id_vendor","name_vendor"]},"GrPicDto":{"type":"object","properties":{"id_user":{"type":"number"},"username":{"type":"string"},"email":{"type":"string"}},"required":["id_user","username","email"]},"GrListResponseDto":{"type":"object","properties":{"id_good_receipt":{"type":"number"},"reference_code":{"type":"string"},"id_purchase_order":{"type":"number"},"id_vendor":{"type":"object"},"deliver_to":{"type":"object"},"operation_type":{"type":"string","enum":["RECEIPTS","DELIVERY_ORDERS","INTERNAL_TRANSFER","RETURNS"]},"schedule_date":{"type":"object"},"effective_date":{"type":"object"},"source_document":{"type":"object"},"id_pic":{"type":"object"},"carrier":{"type":"string","enum":["JNE","JNT","TIKI","SICEPAT","POS_INDONESIA","ANTERAJA","NINJA_XPRESS","LION_PARCEL","ID_EXPRESS","WAHANA","SAP_EXPRESS","RPX","DHL","FEDEX"]},"tracking_reference":{"type":"object"},"status":{"type":"string","enum":["DRAFT","RECEIPT","DONE"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"vendor":{"$ref":"#/components/schemas/GrVendorDto"},"pic":{"$ref":"#/components/schemas/GrPicDto"}},"required":["id_good_receipt","reference_code","id_purchase_order","status","created_at","updated_at"]},"GrAssetSummaryDto":{"type":"object","properties":{"id_asset":{"type":"number"},"code_asset":{"type":"string"},"name_asset":{"type":"string"},"status_asset":{"type":"string","enum":["DRAFT","RUNNING"]}},"required":["id_asset","code_asset","name_asset","status_asset"]},"GrItemResponseDto":{"type":"object","properties":{"id_good_receipt_item":{"type":"number"},"id_asset":{"type":"number"},"asset":{"$ref":"#/components/schemas/GrAssetSummaryDto"},"asset_code_snapshot":{"type":"string"},"asset_name_snapshot":{"type":"string"},"demand":{"type":"number"},"done":{"type":"number"},"updated_at":{"format":"date-time","type":"string"}},"required":["id_good_receipt_item","id_asset","asset_code_snapshot","asset_name_snapshot","demand","done","updated_at"]},"GrDetailResponseDto":{"type":"object","properties":{"id_good_receipt":{"type":"number"},"reference_code":{"type":"string"},"id_purchase_order":{"type":"number"},"id_vendor":{"type":"object"},"deliver_to":{"type":"object"},"operation_type":{"type":"string","enum":["RECEIPTS","DELIVERY_ORDERS","INTERNAL_TRANSFER","RETURNS"]},"schedule_date":{"type":"object"},"effective_date":{"type":"object"},"source_document":{"type":"object"},"id_pic":{"type":"object"},"carrier":{"type":"string","enum":["JNE","JNT","TIKI","SICEPAT","POS_INDONESIA","ANTERAJA","NINJA_XPRESS","LION_PARCEL","ID_EXPRESS","WAHANA","SAP_EXPRESS","RPX","DHL","FEDEX"]},"tracking_reference":{"type":"object"},"status":{"type":"string","enum":["DRAFT","RECEIPT","DONE"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"vendor":{"$ref":"#/components/schemas/GrVendorDto"},"pic":{"$ref":"#/components/schemas/GrPicDto"},"items":{"type":"array","items":{"$ref":"#/components/schemas/GrItemResponseDto"}}},"required":["id_good_receipt","reference_code","id_purchase_order","status","created_at","updated_at","items"]},"UpdateGoodReceiptItemDto":{"type":"object","properties":{"id_good_receipt_item":{"type":"number"},"done":{"type":"number","description":"Actual received quantity. Only editable in RECEIPT status."}}},"UpdateGoodReceiptDto":{"type":"object","properties":{"id_vendor":{"type":"number"},"deliver_to":{"type":"string"},"schedule_date":{"type":"string"},"operation_type":{"type":"string","enum":["RECEIPTS","DELIVERY_ORDERS","INTERNAL_TRANSFER","RETURNS"]},"effective_date":{"type":"string"},"source_document":{"type":"string"},"id_pic":{"type":"number"},"carrier":{"type":"string","enum":["JNE","JNT","TIKI","SICEPAT","POS_INDONESIA","ANTERAJA","NINJA_XPRESS","LION_PARCEL","ID_EXPRESS","WAHANA","SAP_EXPRESS","RPX","DHL","FEDEX"]},"tracking_reference":{"type":"string"},"items":{"description":"Item done quantities. Only processed in RECEIPT status.","type":"array","items":{"$ref":"#/components/schemas/UpdateGoodReceiptItemDto"}}}},"DepreciationBoardResponseDto":{"type":"object","properties":{"id_depreciation_board_asset":{"type":"number","example":1},"id_asset":{"type":"number","example":1},"depreciation_date_asset":{"format":"date-time","type":"string","example":"2024-02-01"},"reference_asset":{"type":"string","example":"DEPR/2024/02/001","nullable":true},"depreciation_value_asset":{"type":"number","example":2500000},"cumulative_depreciation_asset":{"type":"number","example":2500000},"depreciable_value_asset":{"type":"number","example":147500000},"created_at":{"format":"date-time","type":"string","example":"2025-08-04T03:04:50.871Z"},"updated_at":{"format":"date-time","type":"string","example":"2025-08-04T03:04:50.871Z"}},"required":["id_depreciation_board_asset","id_asset","depreciation_date_asset","reference_asset","depreciation_value_asset","cumulative_depreciation_asset","depreciable_value_asset","created_at","updated_at"]},"AssetResponseDto":{"type":"object","properties":{"id_asset":{"type":"number","example":1},"code_asset":{"type":"string","example":"AST-001"},"name_asset":{"type":"string","example":"Forklift Unit 1"},"acquisition_date_asset":{"format":"date-time","type":"string","example":"2024-01-15"},"original_value_asset":{"type":"number","example":150000000},"not_depreciable_value_asset":{"type":"number","example":500000,"description":"Salvage value — portion of original value that will not be depreciated"},"depreciation_method_asset":{"type":"string","enum":["STRAIGHT_LINE","DECLINING_BALANCE"]},"duration_asset":{"type":"number","example":60},"computation_asset":{"type":"string","enum":["CONSTANT_PERIOD"]},"prorata_date_asset":{"format":"date-time","type":"string","example":"2024-01-15"},"book_value_asset":{"type":"number","example":147500000,"description":"Computed: original_value - cumulative_depreciation"},"depreciable_value_asset":{"type":"number","example":147500000,"description":"Computed: remaining depreciable value from last board entry"},"status_asset":{"type":"string","enum":["DRAFT","RUNNING"]},"company_asset":{"type":"string","example":"PT Maju Bersama"},"depreciation_account_asset":{"type":"string","example":"1.2.3.001"},"expense_account_asset":{"type":"string","example":"6.1.1.001"},"journal_asset":{"type":"string","example":"DEPR-JOURNAL"},"depreciation_board_asset":{"type":"array","items":{"$ref":"#/components/schemas/DepreciationBoardResponseDto"}},"created_at":{"format":"date-time","type":"string","example":"2025-08-04T03:04:50.871Z"},"updated_at":{"format":"date-time","type":"string","example":"2025-08-04T03:04:50.871Z"},"flag":{"type":"number","example":1}},"required":["id_asset","code_asset","name_asset","acquisition_date_asset","original_value_asset","not_depreciable_value_asset","depreciation_method_asset","duration_asset","computation_asset","prorata_date_asset","book_value_asset","depreciable_value_asset","status_asset","company_asset","depreciation_account_asset","expense_account_asset","journal_asset","depreciation_board_asset","created_at","updated_at","flag"]},"CreateAssetRequestDto":{"type":"object","properties":{"name_asset":{"type":"string","example":"Forklift Unit 1","description":"Name of the asset"},"acquisition_date_asset":{"type":"string","example":"2024-01-15","description":"Acquisition date of the asset"},"original_value_asset":{"type":"number","example":150000000,"description":"Original purchase value of the asset"},"not_depreciable_value_asset":{"type":"number","example":500000,"description":"Salvage value — portion that will not be depreciated. Defaults to 0."},"depreciation_method_asset":{"type":"string","enum":["STRAIGHT_LINE","DECLINING_BALANCE"],"example":"STRAIGHT_LINE","description":"Depreciation method"},"duration_asset":{"type":"number","example":60,"description":"Depreciation duration in months"},"computation_asset":{"type":"string","enum":["CONSTANT_PERIOD"],"example":"CONSTANT_PERIOD","description":"Computation method for depreciation periods"},"prorata_date_asset":{"type":"string","example":"2024-01-15","description":"Start date for depreciation calculation"},"company_asset":{"type":"string","example":"PT Maju Bersama","description":"Company associated with this asset"},"depreciation_account_asset":{"type":"string","example":"1.2.3.001","description":"Account code for accumulated depreciation"},"expense_account_asset":{"type":"string","example":"6.1.1.001","description":"Account code for depreciation expense"},"journal_asset":{"type":"string","example":"DEPR-JOURNAL","description":"Journal identifier for depreciation entries"}},"required":["name_asset","acquisition_date_asset","original_value_asset","depreciation_method_asset","duration_asset","prorata_date_asset","company_asset","depreciation_account_asset","expense_account_asset","journal_asset"]},"UpdateAssetRequestDto":{"type":"object","properties":{"name_asset":{"type":"string","example":"Forklift Unit 1"},"acquisition_date_asset":{"type":"string","example":"2024-01-15"},"original_value_asset":{"type":"number","example":150000000},"not_depreciable_value_asset":{"type":"number","example":500000,"description":"Salvage value — portion that will not be depreciated"},"depreciation_method_asset":{"type":"string","enum":["STRAIGHT_LINE","DECLINING_BALANCE"]},"duration_asset":{"type":"number","example":60},"computation_asset":{"type":"string","enum":["CONSTANT_PERIOD"]},"prorata_date_asset":{"type":"string","example":"2024-01-15"},"status_asset":{"type":"string","enum":["DRAFT","RUNNING"]},"company_asset":{"type":"string","example":"PT Maju Bersama"},"depreciation_account_asset":{"type":"string","example":"1.2.3.001"},"expense_account_asset":{"type":"string","example":"6.1.1.001"},"journal_asset":{"type":"string","example":"DEPR-JOURNAL"}}},"CreateDepreciationBoardRequestDto":{"type":"object","properties":{"depreciation_date_asset":{"type":"string","example":"2024-02-01","description":"Date of this depreciation entry"},"reference_asset":{"type":"string","example":"DEPR/2024/02/001","description":"Journal entry reference"},"depreciation_value_asset":{"type":"number","example":2500000,"description":"Depreciation amount for this period"},"cumulative_depreciation_asset":{"type":"number","example":2500000,"description":"Total cumulative depreciation up to this entry"},"depreciable_value_asset":{"type":"number","example":147500000,"description":"Remaining depreciable value after this entry"}},"required":["depreciation_date_asset","depreciation_value_asset","cumulative_depreciation_asset","depreciable_value_asset"]},"UpdateDepreciationBoardRequestDto":{"type":"object","properties":{"depreciation_date_asset":{"type":"string","example":"2024-02-01"},"reference_asset":{"type":"string","example":"DEPR/2024/02/001"},"depreciation_value_asset":{"type":"number","example":2500000},"cumulative_depreciation_asset":{"type":"number","example":2500000},"depreciable_value_asset":{"type":"number","example":147500000}}},"CoaGroupSummaryDto":{"type":"object","properties":{"id_coa_group":{"type":"number","description":"Primary key of the account group.","example":3},"group_code":{"type":"string","description":"Short code identifying the Notes Lines group, e.g. \"1110\" for Cash & Bank.","example":"1110"},"group_name":{"type":"string","description":"Human-readable group name shown on financial statements.","example":"Cash & Bank"},"classification":{"type":"string","description":"Financial statement classification of this group.\n- CURRENT_ASSETS      : cash, receivables, prepaid, inventory\n- NON_CURRENT_ASSETS  : fixed assets, investments, deferred, related party deposits\n- CURRENT_LIABILITIES : trade payables, short-term obligations\n- EQUITY              : share capital, retained earnings\n- INCOME              : revenue accounts\n- EXPENSES            : operating expenses, COGS, other costs\n- TAX                 : prepaid tax, tax payable, tax expense","enum":["CURRENT_ASSETS","NON_CURRENT_ASSETS","CURRENT_LIABILITIES","EQUITY","INCOME","EXPENSES","TAX"],"example":"CURRENT_ASSETS"}},"required":["id_coa_group","group_code","group_name","classification"]},"CoaListItemDto":{"type":"object","properties":{"id_coa":{"type":"number","description":"Primary key of the account.","example":1},"account_number":{"type":"string","description":"Unique account code following the chart of accounts numbering convention, e.g. \"11101\".","example":"11101"},"account_name":{"type":"string","description":"Descriptive account name shown on journals and reports.","example":"Cash"},"account_type":{"type":"string","description":"Fine-grained account type for system-level categorisation.\nPossible values: CASH_AND_BANK, FIXED_ASSETS, TRADE_PAYABLES, TAX_PAYABLE,\nEQUITY, REVENUE, COST_OF_GOODS_SOLD, TAX, RELATED_PARTY, INVESTMENT,\nOPERATING_EXPENSE, OTHERS.\nNull when not yet classified.","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"],"example":"CASH_AND_BANK","nullable":true},"amount":{"type":"number","description":"Current account balance. Null when no transactions have been posted yet.","example":150000000,"nullable":true},"group":{"description":"Parent account group that determines the classification.","allOf":[{"$ref":"#/components/schemas/CoaGroupSummaryDto"}]},"updated_at":{"format":"date-time","type":"string","description":"Timestamp of the most recent update to this account record.","example":"2026-03-05T08:00:00.000Z"}},"required":["id_coa","account_number","account_name","group","updated_at"]},"CoaDetailDto":{"type":"object","properties":{"id_coa":{"type":"number","description":"Primary key of the account.","example":1},"account_number":{"type":"string","description":"Unique account code following the chart of accounts numbering convention, e.g. \"11101\".","example":"11101"},"account_name":{"type":"string","description":"Descriptive account name shown on journals and reports.","example":"Cash"},"account_type":{"type":"string","description":"Fine-grained account type for system-level categorisation.\nPossible values: CASH_AND_BANK, FIXED_ASSETS, TRADE_PAYABLES, TAX_PAYABLE,\nEQUITY, REVENUE, COST_OF_GOODS_SOLD, TAX, RELATED_PARTY, INVESTMENT,\nOPERATING_EXPENSE, OTHERS.\nNull when not yet classified.","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"],"example":"CASH_AND_BANK","nullable":true},"amount":{"type":"number","description":"Current account balance. Null when no transactions have been posted yet.","example":150000000,"nullable":true},"group":{"description":"Parent account group that determines the classification.","allOf":[{"$ref":"#/components/schemas/CoaGroupSummaryDto"}]},"updated_at":{"format":"date-time","type":"string","description":"Timestamp of the most recent update to this account record.","example":"2026-03-05T08:00:00.000Z"},"created_at":{"format":"date-time","type":"string","description":"Timestamp when this account was first created.","example":"2026-01-01T00:00:00.000Z"}},"required":["id_coa","account_number","account_name","group","updated_at","created_at"]},"CreateCoaDto":{"type":"object","properties":{"account_number":{"type":"string","description":"Unique account code following the chart-of-accounts numbering convention. Must consist of numeric digits only, e.g. \"11101\" for Cash or \"21101\" for Trade Payables. Maximum length: 20 characters.","example":"11101","maxLength":20},"account_name":{"type":"string","description":"Descriptive name of the account as displayed on journals, ledgers, and financial reports. Use a clear, unambiguous name, e.g. \"Cash\", \"Bank Mandiri — USD\", \"Trade Payables\". Maximum length: 255 characters.","example":"Cash","maxLength":255},"id_coa_group":{"type":"number","description":"FK → coa_group.id_coa_group. The parent account group that determines the financial-statement classification (e.g. CURRENT_ASSETS, INCOME) and the Notes Line this account rolls up into. Must reference an active CoaGroup record.","example":3},"account_type":{"type":"string","description":"Fine-grained account type used for system-level categorisation and journal entry filtering.\n\nAccepted values:\n- `CASH_AND_BANK`      : cash on hand and all bank accounts\n- `FIXED_ASSETS`       : long-term tangible assets (equipment, property, vehicles)\n- `TRADE_PAYABLES`     : amounts owed to suppliers for goods or services received\n- `TAX_PAYABLE`        : tax obligations payable to the government\n- `EQUITY`             : share capital, retained earnings, and other equity accounts\n- `REVENUE`            : income earned from primary business operations\n- `COST_OF_GOODS_SOLD` : direct costs attributable to the production of goods sold\n- `TAX`                : general tax-related accounts (prepaid tax, tax expense)\n- `RELATED_PARTY`      : intercompany balances and deposits with affiliates\n- `INVESTMENT`         : long-term investments in subsidiaries or associates\n- `OPERATING_EXPENSE`  : indirect costs of running the business (admin, legal, depreciation)\n- `OTHERS`             : miscellaneous accounts not classified elsewhere\n\nOmit or set to `null` when no specific type applies.","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"],"example":"CASH_AND_BANK","nullable":true},"amount":{"type":"number","description":"Opening or current account balance. Accepts up to 2 decimal places; must be zero or positive. Omit or set to null when no balance has been established yet.","example":150000000,"nullable":true}},"required":["account_number","account_name","id_coa_group"]},"UpdateCoaDto":{"type":"object","properties":{"account_number":{"type":"string","description":"Unique account code following the chart-of-accounts numbering convention. Must consist of numeric digits only, e.g. \"11101\" for Cash or \"21101\" for Trade Payables. Maximum length: 20 characters.","example":"11101","maxLength":20},"account_name":{"type":"string","description":"Descriptive name of the account as displayed on journals, ledgers, and financial reports. Use a clear, unambiguous name, e.g. \"Cash\", \"Bank Mandiri — USD\", \"Trade Payables\". Maximum length: 255 characters.","example":"Cash","maxLength":255},"id_coa_group":{"type":"number","description":"FK → coa_group.id_coa_group. The parent account group that determines the financial-statement classification (e.g. CURRENT_ASSETS, INCOME) and the Notes Line this account rolls up into. Must reference an active CoaGroup record.","example":3},"account_type":{"type":"string","description":"Fine-grained account type used for system-level categorisation and journal entry filtering.\n\nAccepted values:\n- `CASH_AND_BANK`      : cash on hand and all bank accounts\n- `FIXED_ASSETS`       : long-term tangible assets (equipment, property, vehicles)\n- `TRADE_PAYABLES`     : amounts owed to suppliers for goods or services received\n- `TAX_PAYABLE`        : tax obligations payable to the government\n- `EQUITY`             : share capital, retained earnings, and other equity accounts\n- `REVENUE`            : income earned from primary business operations\n- `COST_OF_GOODS_SOLD` : direct costs attributable to the production of goods sold\n- `TAX`                : general tax-related accounts (prepaid tax, tax expense)\n- `RELATED_PARTY`      : intercompany balances and deposits with affiliates\n- `INVESTMENT`         : long-term investments in subsidiaries or associates\n- `OPERATING_EXPENSE`  : indirect costs of running the business (admin, legal, depreciation)\n- `OTHERS`             : miscellaneous accounts not classified elsewhere\n\nOmit or set to `null` when no specific type applies.","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"],"example":"CASH_AND_BANK","nullable":true},"amount":{"type":"number","description":"Opening or current account balance. Accepts up to 2 decimal places; must be zero or positive. Omit or set to null when no balance has been established yet.","example":150000000,"nullable":true}}},"JournalListItemDto":{"type":"object","properties":{"id_journal":{"type":"number","description":"Primary key of the journal.","example":1},"journal_name":{"type":"string","description":"Human-readable journal name.","example":"Bank Mandiri"},"journal_type":{"type":"string","description":"High-level journal type that controls posting behaviour.","enum":["CASH","BANK","SALES","PURCHASE","MISCELLANEOUS"],"example":"BANK"},"updated_at":{"format":"date-time","type":"string","description":"Timestamp of the most recent update to this journal.","example":"2026-03-05T08:00:00.000Z"}},"required":["id_journal","journal_name","journal_type","updated_at"]},"JournalCoaRefDto":{"type":"object","properties":{"id_coa":{"type":"number","description":"Primary key of the referenced COA account.","example":10},"account_number":{"type":"string","description":"Unique account code of the referenced COA account.","example":"11101"},"account_name":{"type":"string","description":"Name of the referenced COA account.","example":"Cash"}},"required":["id_coa","account_number","account_name"]},"JournalPaymentMethodDto":{"type":"object","properties":{"id_journal_payment_method":{"type":"number","description":"Primary key of the payment method record.","example":1},"direction":{"type":"string","description":"Whether this method is for receiving money (INCOMING) or sending money (OUTGOING).","enum":["INCOMING","OUTGOING"],"example":"INCOMING"},"name":{"type":"string","description":"Display name of the payment method.","example":"Manual Cash"},"payment_type":{"type":"string","description":"How the payment is processed. Currently always MANUAL.","enum":["MANUAL"],"example":"MANUAL"},"payment_method":{"type":"string","description":"Physical or digital payment instrument used.","enum":["CASH","BANK_TRANSFER","CHECK","CREDIT_CARD"],"example":"CASH"}},"required":["id_journal_payment_method","direction","name","payment_type","payment_method"]},"JournalDetailDto":{"type":"object","properties":{"id_journal":{"type":"number","description":"Primary key of the journal.","example":1},"journal_name":{"type":"string","description":"Human-readable journal name.","example":"Bank Mandiri"},"journal_type":{"type":"string","description":"High-level journal type that controls posting behaviour.","enum":["CASH","BANK","SALES","PURCHASE","MISCELLANEOUS"],"example":"BANK"},"updated_at":{"format":"date-time","type":"string","description":"Timestamp of the most recent update to this journal.","example":"2026-03-05T08:00:00.000Z"},"suspense_account":{"description":"Temporary holding account used when a payment is registered before reconciliation. Null if not configured.","nullable":true,"allOf":[{"$ref":"#/components/schemas/JournalCoaRefDto"}]},"loss_account":{"description":"Account for posting currency exchange losses. Null if not configured.","nullable":true,"allOf":[{"$ref":"#/components/schemas/JournalCoaRefDto"}]},"profit_account":{"description":"Account for posting currency exchange gains. Null if not configured.","nullable":true,"allOf":[{"$ref":"#/components/schemas/JournalCoaRefDto"}]},"incoming_payment_methods":{"description":"Payment methods available for registering incoming receipts (money received from customers). Empty array if none configured.","type":"array","items":{"$ref":"#/components/schemas/JournalPaymentMethodDto"}},"outgoing_payment_methods":{"description":"Payment methods available for registering outgoing payments (money sent to vendors). Empty array if none configured.","type":"array","items":{"$ref":"#/components/schemas/JournalPaymentMethodDto"}},"account_type":{"type":"string","description":"Default account type pre-selected when creating entries for this journal. Null if no default is set.","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"],"example":"CASH_AND_BANK","nullable":true},"allowed_account_type":{"type":"array","description":"Whitelist of account types permitted for entries in this journal. Null means all account types are allowed.","example":["CASH_AND_BANK","OTHERS"],"nullable":true,"items":{"type":"string","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"]}},"communication_type":{"type":"string","description":"Channel used for automated follow-up communications on overdue payments. Null if not configured.","enum":["EMAIL","PHONE","LETTER","INTERNAL"],"example":"EMAIL","nullable":true},"communication_standard":{"type":"string","description":"Frequency cadence for automated follow-up messages. Null if not configured.","enum":["NONE","DAILY","WEEKLY","BIWEEKLY","MONTHLY"],"example":"WEEKLY","nullable":true},"follow_up_level":{"type":"string","description":"Urgency level for overdue payment escalation. Null if not configured.","enum":["LOW","MEDIUM","HIGH"],"example":"MEDIUM","nullable":true},"follow_up_responsible":{"type":"object","description":"Name or role of the person responsible for following up on overdue items. Null if not configured.","example":"Finance Manager","nullable":true},"created_at":{"format":"date-time","type":"string","description":"Timestamp when this journal was first created.","example":"2026-01-01T00:00:00.000Z"}},"required":["id_journal","journal_name","journal_type","updated_at","incoming_payment_methods","outgoing_payment_methods","created_at"]},"CreateJournalPaymentMethodDto":{"type":"object","properties":{"name":{"type":"string","description":"Display name shown in the payment registration screen, e.g. \"Manual Cash\", \"Bank Transfer\".","example":"Manual Cash","maxLength":150},"payment_type":{"type":"string","description":"How the payment is processed. Currently only MANUAL (one-by-one entry) is supported.","enum":["MANUAL"],"example":"MANUAL"},"payment_method":{"type":"string","description":"Physical or digital payment instrument.\n- CASH         : physical cash\n- BANK_TRANSFER: wire / inter-bank transfer\n- CHECK        : paper cheque\n- CREDIT_CARD  : credit card","enum":["CASH","BANK_TRANSFER","CHECK","CREDIT_CARD"],"example":"CASH"}},"required":["name","payment_type","payment_method"]},"CreateJournalDto":{"type":"object","properties":{"journal_name":{"type":"string","description":"Human-readable journal name displayed across the accounting module, e.g. \"Cash\", \"Bank Mandiri\", \"Customer Invoices\".","example":"Bank Mandiri","maxLength":150},"journal_type":{"type":"string","description":"High-level type that controls posting behaviour and available features.\n- CASH        : petty cash or cash-on-hand journals\n- BANK        : bank account journals (supports reconciliation)\n- SALES       : customer invoice journals\n- PURCHASE    : vendor bill journals\n- MISCELLANEOUS: general-purpose / adjustment journals","enum":["CASH","BANK","SALES","PURCHASE","MISCELLANEOUS"],"example":"BANK"},"id_suspense_account":{"type":"number","description":"FK → coa.id_coa.\nSuspense account used as a temporary holding account when a payment is\nregistered before it is matched to an invoice. Cleared automatically\nonce the reconciliation is confirmed.\nLeave null if not applicable.","example":10},"id_loss_account":{"type":"number","description":"FK → coa.id_coa.\nAccount used to post currency exchange losses that arise from\ndifferences between the invoice rate and the payment rate.\nLeave null if the journal does not involve foreign currency.","example":11},"id_profit_account":{"type":"number","description":"FK → coa.id_coa.\nAccount used to post currency exchange gains that arise from\ndifferences between the invoice rate and the payment rate.\nLeave null if the journal does not involve foreign currency.","example":12},"incoming_payment_methods":{"description":"Payment methods available when registering incoming receipts (money received from customers). Omit or send empty array [] to have no incoming methods.","example":[{"name":"Manual Bank Transfer","payment_type":"MANUAL","payment_method":"BANK_TRANSFER"}],"type":"array","items":{"$ref":"#/components/schemas/CreateJournalPaymentMethodDto"}},"outgoing_payment_methods":{"description":"Payment methods available when registering outgoing payments (money sent to vendors). Omit or send empty array [] to have no outgoing methods.","example":[{"name":"Manual Bank Transfer","payment_type":"MANUAL","payment_method":"BANK_TRANSFER"}],"type":"array","items":{"$ref":"#/components/schemas/CreateJournalPaymentMethodDto"}},"account_type":{"type":"string","description":"Default account type pre-selected when creating journal entries for this journal. Can be overridden per entry. Leave null for no default.","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"],"example":"CASH_AND_BANK","nullable":true},"allowed_account_type":{"type":"array","description":"Whitelist of account types that may be used in journal entries for this journal. Leave null or omit to allow all account types.","example":["CASH_AND_BANK","OTHERS"],"nullable":true,"items":{"type":"string","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"]}},"communication_type":{"type":"string","description":"Channel used when sending automated payment follow-up notifications.\n- EMAIL   : send via email\n- PHONE   : call by phone\n- LETTER  : postal mail\n- INTERNAL: internal note / memo","enum":["EMAIL","PHONE","LETTER","INTERNAL"],"example":"EMAIL","nullable":true},"communication_standard":{"type":"string","description":"Frequency cadence for automated follow-up messages on overdue payments.\n- NONE     : no automated follow-up\n- DAILY    : every day\n- WEEKLY   : once a week\n- BIWEEKLY : twice a month\n- MONTHLY  : once a month","enum":["NONE","DAILY","WEEKLY","BIWEEKLY","MONTHLY"],"example":"WEEKLY","nullable":true},"follow_up_level":{"type":"string","description":"Urgency level used when escalating overdue payment follow-ups.\n- LOW    : reminder only, no escalation\n- MEDIUM : escalate if no response after one follow-up cycle\n- HIGH   : immediate escalation required","enum":["LOW","MEDIUM","HIGH"],"example":"MEDIUM","nullable":true},"follow_up_responsible":{"type":"string","description":"Name or role of the person responsible for following up on overdue items associated with this journal.","example":"Finance Manager","maxLength":150,"nullable":true}},"required":["journal_name","journal_type"]},"UpdateJournalDto":{"type":"object","properties":{"journal_name":{"type":"string","description":"Human-readable journal name displayed across the accounting module, e.g. \"Cash\", \"Bank Mandiri\", \"Customer Invoices\".","example":"Bank Mandiri","maxLength":150},"journal_type":{"type":"string","description":"High-level type that controls posting behaviour and available features.\n- CASH        : petty cash or cash-on-hand journals\n- BANK        : bank account journals (supports reconciliation)\n- SALES       : customer invoice journals\n- PURCHASE    : vendor bill journals\n- MISCELLANEOUS: general-purpose / adjustment journals","enum":["CASH","BANK","SALES","PURCHASE","MISCELLANEOUS"],"example":"BANK"},"id_suspense_account":{"type":"number","description":"FK → coa.id_coa.\nSuspense account used as a temporary holding account when a payment is\nregistered before it is matched to an invoice. Cleared automatically\nonce the reconciliation is confirmed.\nLeave null if not applicable.","example":10},"id_loss_account":{"type":"number","description":"FK → coa.id_coa.\nAccount used to post currency exchange losses that arise from\ndifferences between the invoice rate and the payment rate.\nLeave null if the journal does not involve foreign currency.","example":11},"id_profit_account":{"type":"number","description":"FK → coa.id_coa.\nAccount used to post currency exchange gains that arise from\ndifferences between the invoice rate and the payment rate.\nLeave null if the journal does not involve foreign currency.","example":12},"incoming_payment_methods":{"description":"Payment methods available when registering incoming receipts (money received from customers). Omit or send empty array [] to have no incoming methods.","example":[{"name":"Manual Bank Transfer","payment_type":"MANUAL","payment_method":"BANK_TRANSFER"}],"type":"array","items":{"$ref":"#/components/schemas/CreateJournalPaymentMethodDto"}},"outgoing_payment_methods":{"description":"Payment methods available when registering outgoing payments (money sent to vendors). Omit or send empty array [] to have no outgoing methods.","example":[{"name":"Manual Bank Transfer","payment_type":"MANUAL","payment_method":"BANK_TRANSFER"}],"type":"array","items":{"$ref":"#/components/schemas/CreateJournalPaymentMethodDto"}},"account_type":{"type":"string","description":"Default account type pre-selected when creating journal entries for this journal. Can be overridden per entry. Leave null for no default.","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"],"example":"CASH_AND_BANK","nullable":true},"allowed_account_type":{"type":"array","description":"Whitelist of account types that may be used in journal entries for this journal. Leave null or omit to allow all account types.","example":["CASH_AND_BANK","OTHERS"],"nullable":true,"items":{"type":"string","enum":["CASH_AND_BANK","FIXED_ASSETS","TRADE_PAYABLES","TRADE_RECEIVABLES","TAX_PAYABLE","EQUITY","REVENUE","COST_OF_GOODS_SOLD","TAX","RELATED_PARTY","INVESTMENT","OPERATING_EXPENSE","OTHERS"]}},"communication_type":{"type":"string","description":"Channel used when sending automated payment follow-up notifications.\n- EMAIL   : send via email\n- PHONE   : call by phone\n- LETTER  : postal mail\n- INTERNAL: internal note / memo","enum":["EMAIL","PHONE","LETTER","INTERNAL"],"example":"EMAIL","nullable":true},"communication_standard":{"type":"string","description":"Frequency cadence for automated follow-up messages on overdue payments.\n- NONE     : no automated follow-up\n- DAILY    : every day\n- WEEKLY   : once a week\n- BIWEEKLY : twice a month\n- MONTHLY  : once a month","enum":["NONE","DAILY","WEEKLY","BIWEEKLY","MONTHLY"],"example":"WEEKLY","nullable":true},"follow_up_level":{"type":"string","description":"Urgency level used when escalating overdue payment follow-ups.\n- LOW    : reminder only, no escalation\n- MEDIUM : escalate if no response after one follow-up cycle\n- HIGH   : immediate escalation required","enum":["LOW","MEDIUM","HIGH"],"example":"MEDIUM","nullable":true},"follow_up_responsible":{"type":"string","description":"Name or role of the person responsible for following up on overdue items associated with this journal.","example":"Finance Manager","maxLength":150,"nullable":true}}},"JournalRefDto":{"type":"object","properties":{"id_journal":{"type":"number","example":2},"journal_name":{"type":"string","example":"Bank Mandiri"}},"required":["id_journal","journal_name"]},"JournalEntryListItemDto":{"type":"object","properties":{"id_journal_entry":{"type":"number","description":"Primary key of the journal entry.","example":1},"entry_number":{"type":"string","description":"Auto-generated sequential entry number.","example":"JE/2026/0001"},"journal":{"description":"Journal this entry belongs to.","allOf":[{"$ref":"#/components/schemas/JournalRefDto"}]},"accounting_date":{"format":"date","type":"string","description":"Date the transaction is recognised in the books.","example":"2026-03-05"},"reference":{"type":"object","description":"Source document reference, e.g. \"TAGIH/2026/02/0001\".","example":"TAGIH/2026/02/0001","nullable":true},"source_document":{"type":"object","description":"Linked invoice or document number.","example":"INV/MPE-MPE/2026/III/001","nullable":true},"status":{"type":"string","description":"Current status of the entry.","enum":["DRAFT","POSTED"],"example":"DRAFT"},"total_debit":{"type":"number","description":"Sum of all debit lines.","example":111000000},"total_credit":{"type":"number","description":"Sum of all credit lines.","example":111000000},"is_reversal":{"type":"boolean","description":"True when this entry was auto-created as a reversal of another entry.","example":false},"id_reversed_entry":{"type":"object","description":"ID of the original entry that this entry reverses. Null for non-reversal entries.","example":null,"nullable":true},"updated_at":{"format":"date-time","type":"string","description":"Timestamp of the most recent update.","example":"2026-03-05T08:00:00.000Z"}},"required":["id_journal_entry","entry_number","journal","accounting_date","status","total_debit","total_credit","is_reversal","updated_at"]},"AccountRefDto":{"type":"object","properties":{"id_coa":{"type":"number","example":23101},"account_number":{"type":"string","example":"23101"},"account_name":{"type":"string","example":"FC Payable"}},"required":["id_coa","account_number","account_name"]},"JournalReportLineDto":{"type":"object","properties":{"id_journal_item":{"type":"number","example":1},"account":{"$ref":"#/components/schemas/AccountRefDto"},"partner":{"type":"object","example":"PT. Kapal ABC","nullable":true},"label":{"type":"object","example":"Freight charter voyage VY-2026-0012","nullable":true},"debit":{"type":"number","description":"Debit amount for this line.","example":100000000},"credit":{"type":"number","description":"Credit amount for this line.","example":0},"taxes":{"type":"number","description":"Tax amount on this line. Equals debit+credit when account_type is TAX or TAX_PAYABLE, otherwise 0.","example":0}},"required":["id_journal_item","account","debit","credit","taxes"]},"JournalReportEntryDto":{"type":"object","properties":{"id_journal_entry":{"type":"number","example":1},"entry_number":{"type":"string","example":"JE/2026/0001"},"accounting_date":{"format":"date","type":"string","example":"2026-03-05"},"reference":{"type":"object","example":"TAGIH/2026/02/0001","nullable":true},"source_document":{"type":"object","example":"INV/MPE-MPE/2026/III/001","nullable":true},"is_reversal":{"type":"boolean","example":false},"lines":{"type":"array","items":{"$ref":"#/components/schemas/JournalReportLineDto"}},"subtotal_debit":{"type":"number","description":"Sum of debit lines for this entry.","example":111000000},"subtotal_credit":{"type":"number","description":"Sum of credit lines for this entry.","example":111000000},"subtotal_taxes":{"type":"number","description":"Sum of tax amounts for this entry.","example":0}},"required":["id_journal_entry","entry_number","accounting_date","is_reversal","lines","subtotal_debit","subtotal_credit","subtotal_taxes"]},"JournalReportGroupDto":{"type":"object","properties":{"id_journal":{"type":"number","example":2},"journal_name":{"type":"string","example":"Bank Mandiri"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/JournalReportEntryDto"}},"total_debit":{"type":"number","description":"Total debit for all entries in this journal.","example":222000000},"total_credit":{"type":"number","description":"Total credit for all entries in this journal.","example":222000000},"total_taxes":{"type":"number","description":"Total tax amount for all entries in this journal.","example":0}},"required":["id_journal","journal_name","entries","total_debit","total_credit","total_taxes"]},"JournalReportDto":{"type":"object","properties":{"date_from":{"type":"string","description":"Start of the report range.","example":"2026-01-01"},"date_to":{"type":"string","description":"End of the report range.","example":"2026-12-31"},"groups":{"type":"array","items":{"$ref":"#/components/schemas/JournalReportGroupDto"}},"grand_total_debit":{"type":"number","description":"Grand total debit across all journals.","example":444000000},"grand_total_credit":{"type":"number","description":"Grand total credit across all journals.","example":444000000},"grand_total_taxes":{"type":"number","description":"Grand total taxes across all journals.","example":0}},"required":["date_from","date_to","groups","grand_total_debit","grand_total_credit","grand_total_taxes"]},"JournalItemResponseDto":{"type":"object","properties":{"id_journal_item":{"type":"number","description":"Primary key of the journal item.","example":1},"account":{"description":"COA account debited or credited on this line.","allOf":[{"$ref":"#/components/schemas/AccountRefDto"}]},"partner":{"type":"object","description":"Vendor or customer associated with this line.","example":"PT. Kapal ABC","nullable":true},"label":{"type":"object","description":"Description for this line.","example":"Freight charter voyage VY-2026-0012","nullable":true},"debit":{"type":"number","description":"Debit amount. 0 when this is a credit line.","example":100000000},"credit":{"type":"number","description":"Credit amount. 0 when this is a debit line.","example":0}},"required":["id_journal_item","account","debit","credit"]},"JournalEntryDetailDto":{"type":"object","properties":{"id_journal_entry":{"type":"number","description":"Primary key of the journal entry.","example":1},"entry_number":{"type":"string","description":"Auto-generated sequential entry number.","example":"JE/2026/0001"},"journal":{"description":"Journal this entry belongs to.","allOf":[{"$ref":"#/components/schemas/JournalRefDto"}]},"accounting_date":{"format":"date","type":"string","description":"Date the transaction is recognised in the books.","example":"2026-03-05"},"reference":{"type":"object","description":"Source document reference, e.g. \"TAGIH/2026/02/0001\".","example":"TAGIH/2026/02/0001","nullable":true},"source_document":{"type":"object","description":"Linked invoice or document number.","example":"INV/MPE-MPE/2026/III/001","nullable":true},"status":{"type":"string","description":"Current status of the entry.","enum":["DRAFT","POSTED"],"example":"DRAFT"},"total_debit":{"type":"number","description":"Sum of all debit lines.","example":111000000},"total_credit":{"type":"number","description":"Sum of all credit lines.","example":111000000},"is_reversal":{"type":"boolean","description":"True when this entry was auto-created as a reversal of another entry.","example":false},"id_reversed_entry":{"type":"object","description":"ID of the original entry that this entry reverses. Null for non-reversal entries.","example":null,"nullable":true},"updated_at":{"format":"date-time","type":"string","description":"Timestamp of the most recent update.","example":"2026-03-05T08:00:00.000Z"},"narration":{"type":"object","description":"Free-text notes or internal memo.","example":"Freight charter payment for voyage VY-2026-0012","nullable":true},"items":{"description":"All line items of this entry.","type":"array","items":{"$ref":"#/components/schemas/JournalItemResponseDto"}},"created_at":{"format":"date-time","type":"string","description":"Timestamp when this entry was first created.","example":"2026-03-05T08:00:00.000Z"}},"required":["id_journal_entry","entry_number","journal","accounting_date","status","total_debit","total_credit","is_reversal","updated_at","items","created_at"]},"CreateJournalItemDto":{"type":"object","properties":{"id_coa":{"type":"number","description":"FK → coa.id_coa.\nThe COA account being debited or credited on this line.","example":23101},"partner":{"type":"string","description":"Vendor or customer name associated with this line. Used for partner-level AP/AR reporting.","example":"PT. Kapal ABC","maxLength":255,"nullable":true},"label":{"type":"string","description":"Short description for this line, e.g. asset name, invoice line description, or memo.","example":"Freight charter voyage VY-2026-0012","maxLength":255,"nullable":true},"debit":{"type":"number","description":"Debit amount for this line. Set to 0 (or omit) when this is a credit line. Cannot be non-zero at the same time as credit.","example":100000000,"minimum":0,"default":0},"credit":{"type":"number","description":"Credit amount for this line. Set to 0 (or omit) when this is a debit line. Cannot be non-zero at the same time as debit.","example":0,"minimum":0,"default":0}},"required":["id_coa"]},"CreateJournalEntryDto":{"type":"object","properties":{"id_journal":{"type":"number","description":"FK → journal.id_journal.\nThe journal this entry is posted to. Determines available accounts and payment methods.","example":2},"accounting_date":{"type":"string","description":"Date this transaction is recognised in the accounting books. May differ from the physical transaction date.","example":"2026-03-05","format":"date"},"reference":{"type":"string","description":"Source document number that triggered this entry.\ne.g. \"TAGIH/2026/02/0001\", \"WH/IN/00721 - Stem\".\nFree text — populated by the user or auto-filled from a linked document.","example":"TAGIH/2026/02/0001","maxLength":255,"nullable":true},"source_document":{"type":"string","description":"Invoice or document this entry replaces / is linked to.\nCorresponds to the \"Replace Invoice\" selector in the UI.\nStores the invoice or bill document number for traceability.","example":"INV/MPE-MPE/2026/III/001","maxLength":255,"nullable":true},"narration":{"type":"string","description":"Free-text notes or internal memo for this entry.","example":"Freight charter payment for voyage VY-2026-0012","nullable":true},"items":{"description":"Journal line items — minimum 2 lines required (at least one debit and one credit).\nTotal debit across all lines must equal total credit before the entry can be posted.","minItems":2,"type":"array","items":{"$ref":"#/components/schemas/CreateJournalItemDto"}}},"required":["id_journal","accounting_date","items"]},"UpdateJournalEntryDto":{"type":"object","properties":{"id_journal":{"type":"number","description":"FK → journal.id_journal.\nThe journal this entry is posted to. Determines available accounts and payment methods.","example":2},"accounting_date":{"type":"string","description":"Date this transaction is recognised in the accounting books. May differ from the physical transaction date.","example":"2026-03-05","format":"date"},"reference":{"type":"string","description":"Source document number that triggered this entry.\ne.g. \"TAGIH/2026/02/0001\", \"WH/IN/00721 - Stem\".\nFree text — populated by the user or auto-filled from a linked document.","example":"TAGIH/2026/02/0001","maxLength":255,"nullable":true},"source_document":{"type":"string","description":"Invoice or document this entry replaces / is linked to.\nCorresponds to the \"Replace Invoice\" selector in the UI.\nStores the invoice or bill document number for traceability.","example":"INV/MPE-MPE/2026/III/001","maxLength":255,"nullable":true},"narration":{"type":"string","description":"Free-text notes or internal memo for this entry.","example":"Freight charter payment for voyage VY-2026-0012","nullable":true},"items":{"description":"Journal line items — minimum 2 lines required (at least one debit and one credit).\nTotal debit across all lines must equal total credit before the entry can be posted.","minItems":2,"type":"array","items":{"$ref":"#/components/schemas/CreateJournalItemDto"}}}},"ReverseJournalEntryDto":{"type":"object","properties":{"reversal_date":{"type":"string","description":"Accounting date for the reverse entry. Defaults to today if not provided.","example":"2026-03-31","format":"date"},"narration":{"type":"string","description":"Optional memo for the reverse entry. Defaults to \"Reversal of {entry_number}\".","example":"Reversal of incorrectly posted freight charter entry","maxLength":255}}},"JournalEntryRefDto":{"type":"object","properties":{"id_journal_entry":{"type":"number","example":1},"entry_number":{"type":"string","example":"JE/2026/0001"},"accounting_date":{"format":"date","type":"string","description":"Date the transaction is recognised in the books.","example":"2026-03-05"},"status":{"type":"string","enum":["DRAFT","POSTED"],"example":"POSTED"}},"required":["id_journal_entry","entry_number","accounting_date","status"]},"JournalItemListItemDto":{"type":"object","properties":{"id_journal_item":{"type":"number","description":"Primary key of the journal item.","example":1},"journal_entry":{"description":"Parent journal entry reference (includes accounting date).","allOf":[{"$ref":"#/components/schemas/JournalEntryRefDto"}]},"account":{"description":"COA account debited or credited on this line.","allOf":[{"$ref":"#/components/schemas/AccountRefDto"}]},"partner":{"type":"object","description":"Vendor or customer associated with this line.","example":"PT. Kapal ABC","nullable":true},"label":{"type":"object","description":"Description for this line.","example":"Freight charter voyage VY-2026-0012","nullable":true},"debit":{"type":"number","description":"Debit amount (0 on a credit line).","example":100000000},"credit":{"type":"number","description":"Credit amount (0 on a debit line).","example":0}},"required":["id_journal_item","journal_entry","account","debit","credit"]},"JournalItemDetailDto":{"type":"object","properties":{"id_journal_item":{"type":"number","description":"Primary key of the journal item.","example":1},"journal_entry":{"description":"Parent journal entry reference (includes accounting date).","allOf":[{"$ref":"#/components/schemas/JournalEntryRefDto"}]},"account":{"description":"COA account debited or credited on this line.","allOf":[{"$ref":"#/components/schemas/AccountRefDto"}]},"partner":{"type":"object","description":"Vendor or customer associated with this line.","example":"PT. Kapal ABC","nullable":true},"label":{"type":"object","description":"Description for this line.","example":"Freight charter voyage VY-2026-0012","nullable":true},"debit":{"type":"number","description":"Debit amount (0 on a credit line).","example":100000000},"credit":{"type":"number","description":"Credit amount (0 on a debit line).","example":0},"journal":{"description":"Journal this entry belongs to.","allOf":[{"$ref":"#/components/schemas/JournalRefDto"}]},"narration":{"type":"object","description":"Free-text notes from the parent journal entry.","example":"Freight charter payment for voyage VY-2026-0012","nullable":true},"is_reversal":{"type":"boolean","description":"True when the parent entry is a reversal.","example":false},"id_reversed_entry":{"type":"object","description":"ID of the original entry that this entry reverses.","example":null,"nullable":true},"created_at":{"format":"date-time","type":"string","description":"Timestamp when this item was created.","example":"2026-03-05T08:00:00.000Z"},"updated_at":{"format":"date-time","type":"string","description":"Timestamp of the most recent update.","example":"2026-03-05T08:00:00.000Z"}},"required":["id_journal_item","journal_entry","account","debit","credit","journal","is_reversal","created_at","updated_at"]},"BalanceSheetAccountDto":{"type":"object","properties":{"account_number":{"type":"string","description":"Unique account code, e.g. \"11101\".","example":"11101"},"account_name":{"type":"string","description":"Descriptive account name.","example":"Cash"},"amount":{"type":"number","description":"Current account balance as recorded in the Chart of Accounts. Null values are treated as zero in totals.","example":150000000,"nullable":true}},"required":["account_number","account_name","amount"]},"BalanceSheetSectionDto":{"type":"object","properties":{"accounts":{"description":"Ordered list of account lines within this section.","type":"array","items":{"$ref":"#/components/schemas/BalanceSheetAccountDto"}},"total":{"type":"number","description":"Sum of all account balances in this section. Null amounts are treated as zero.","example":980000000}},"required":["accounts","total"]},"BalanceSheetAssetsDto":{"type":"object","properties":{"current_assets":{"description":"Current assets — accounts expected to be converted to cash within one year (Cash & Bank, Receivables, Cash Advance, Prepaid Tax).","allOf":[{"$ref":"#/components/schemas/BalanceSheetSectionDto"}]},"non_current_assets":{"description":"Non-current assets — long-term resources not expected to be liquidated within one year (Fixed Assets, Related-Party Deposits, Deferred Assets, Investments).","allOf":[{"$ref":"#/components/schemas/BalanceSheetSectionDto"}]},"total_assets":{"type":"number","description":"Total assets: sum of current assets and non-current assets.","example":1500000000}},"required":["current_assets","non_current_assets","total_assets"]},"BalanceSheetLiabilitiesEquityDto":{"type":"object","properties":{"current_liabilities":{"description":"Current liabilities — obligations due within one year (Trade Payables, Tax Payable, Related-Party Payables, Other Payables).","allOf":[{"$ref":"#/components/schemas/BalanceSheetSectionDto"}]},"equity":{"description":"Equity — shareholders' funds including paid-in capital and retained earnings.","allOf":[{"$ref":"#/components/schemas/BalanceSheetSectionDto"}]},"total_liabilities_and_equity":{"type":"number","description":"Total liabilities and equity: sum of current liabilities and equity. Should equal total assets in a balanced set of books.","example":1500000000}},"required":["current_liabilities","equity","total_liabilities_and_equity"]},"BalanceSheetResponseDto":{"type":"object","properties":{"as_of_date":{"type":"string","description":"Snapshot date for this report.","example":"2026-12-31"},"assets":{"description":"Assets side of the balance sheet.","allOf":[{"$ref":"#/components/schemas/BalanceSheetAssetsDto"}]},"liabilities_and_equity":{"description":"Liabilities and equity side of the balance sheet.","allOf":[{"$ref":"#/components/schemas/BalanceSheetLiabilitiesEquityDto"}]}},"required":["as_of_date","assets","liabilities_and_equity"]},"AssetsResponseDto":{"type":"object","properties":{"as_of_date":{"type":"string","description":"Snapshot date for this report.","example":"2026-12-31"},"current_assets":{"description":"Current assets — accounts expected to be converted to cash within one year (Cash & Bank, Receivables, Cash Advance, Prepaid Tax).","allOf":[{"$ref":"#/components/schemas/BalanceSheetSectionDto"}]},"non_current_assets":{"description":"Non-current assets — long-term resources not expected to be liquidated within one year (Fixed Assets, Related-Party Deposits, Deferred Assets, Investments).","allOf":[{"$ref":"#/components/schemas/BalanceSheetSectionDto"}]},"total_assets":{"type":"number","description":"Total assets: sum of current assets and non-current assets.","example":1500000000}},"required":["as_of_date","current_assets","non_current_assets","total_assets"]},"LiabilitiesEquityResponseDto":{"type":"object","properties":{"as_of_date":{"type":"string","description":"Snapshot date for this report.","example":"2026-12-31"},"current_liabilities":{"description":"Current liabilities — obligations due within one year (Trade Payables, Tax Payable, Related-Party Payables, Other Payables).","allOf":[{"$ref":"#/components/schemas/BalanceSheetSectionDto"}]},"equity":{"description":"Equity — shareholders' funds including paid-in capital and retained earnings.","allOf":[{"$ref":"#/components/schemas/BalanceSheetSectionDto"}]},"total_liabilities_and_equity":{"type":"number","description":"Total liabilities and equity: sum of current liabilities and equity. Should equal total assets in a balanced set of books.","example":1500000000}},"required":["as_of_date","current_liabilities","equity","total_liabilities_and_equity"]},"PLAccountDto":{"type":"object","properties":{"account_number":{"type":"string","description":"Unique account code, e.g. \"41101\".","example":"41101"},"account_name":{"type":"string","description":"Descriptive account name.","example":"Shipment Revenue - FC"},"amount":{"type":"number","description":"Net amount for this account over the reporting period. For revenue accounts: net credit (credit − debit). For expense/COGS/tax accounts: net debit (debit − credit). A positive value indicates normal activity for the account type.","example":500000000}},"required":["account_number","account_name","amount"]},"PLSectionDto":{"type":"object","properties":{"accounts":{"description":"Ordered list of account lines within this section.","type":"array","items":{"$ref":"#/components/schemas/PLAccountDto"}},"total":{"type":"number","description":"Sum of all account amounts in this section.","example":1000000000}},"required":["accounts","total"]},"ProfitLossResponseDto":{"type":"object","properties":{"date_from":{"type":"string","description":"Start date of the reporting period (inclusive).","example":"2026-01-01"},"date_to":{"type":"string","description":"End date of the reporting period (inclusive).","example":"2026-12-31"},"revenue":{"description":"Revenue — all income earned from primary and secondary business operations.","allOf":[{"$ref":"#/components/schemas/PLSectionDto"}]},"cogs":{"description":"Cost of Goods Sold (COGS) — direct costs attributable to revenue-generating activities (freight charter, time charter, salaries, BPJS, etc.).","allOf":[{"$ref":"#/components/schemas/PLSectionDto"}]},"gross_profit":{"type":"number","description":"Gross Profit / (Loss): Revenue − COGS. A negative value indicates a gross loss.","example":350000000},"expenses":{"description":"Operating and other expenses — indirect costs not directly tied to revenue (transportation, legal, consultant, depreciation, bank charges, rounding, etc.).","allOf":[{"$ref":"#/components/schemas/PLSectionDto"}]},"net_income":{"type":"number","description":"Net Income: Gross Profit − Expenses. A negative value indicates a net loss.","example":200000000},"tax":{"description":"Tax — income tax expense for the period (e.g. PPh 29, PPh 21). Sourced from accounts in the Income Tax group (group code 9xxx).","allOf":[{"$ref":"#/components/schemas/PLSectionDto"}]},"profit_for_the_year":{"type":"number","description":"Profit for the Year: Net Income − Tax. A negative value indicates a net loss for the year.","example":175000000}},"required":["date_from","date_to","revenue","cogs","gross_profit","expenses","net_income","tax","profit_for_the_year"]},"TrialBalanceAccountDto":{"type":"object","properties":{"account_number":{"type":"string","description":"Unique account code, e.g. \"11101\".","example":"11101"},"account_name":{"type":"string","description":"Descriptive account name.","example":"Cash"},"total_debit":{"type":"number","description":"Total debit movements posted to this account within the reporting period.","example":5000000},"total_credit":{"type":"number","description":"Total credit movements posted to this account within the reporting period.","example":3000000}},"required":["account_number","account_name","total_debit","total_credit"]},"TrialBalanceTotalsDto":{"type":"object","properties":{"total_debit":{"type":"number","description":"Sum of all debit movements across all accounts.","example":50000000},"total_credit":{"type":"number","description":"Sum of all credit movements across all accounts.","example":50000000}},"required":["total_debit","total_credit"]},"TrialBalanceResponseDto":{"type":"object","properties":{"date_from":{"type":"string","description":"Start date of the reporting period.","example":"2026-01-01"},"date_to":{"type":"string","description":"End date of the reporting period.","example":"2026-12-31"},"accounts":{"description":"Ordered list of all accounts with posted activity in the period.","type":"array","items":{"$ref":"#/components/schemas/TrialBalanceAccountDto"}},"totals":{"description":"Grand total of all debit and credit movements. Should be equal in a balanced set of books.","allOf":[{"$ref":"#/components/schemas/TrialBalanceTotalsDto"}]}},"required":["date_from","date_to","accounts","totals"]},"EquityAccountRowDto":{"type":"object","properties":{"account_number":{"type":"string","description":"Unique account code, e.g. \"31101\".","example":"31101"},"account_name":{"type":"string","description":"Descriptive account name.","example":"Shareholders' Equity"},"paid_in_capital":{"type":"number","description":"Net movement in the Paid-in Capital column for this account over the period. Non-zero only for accounts belonging to group 3110.","example":1000000000},"retained_earnings":{"type":"number","description":"Net movement in the Retained Earnings column for this account over the period. Non-zero only for accounts belonging to group 3111.","example":0},"other_comprehensive_income":{"type":"number","description":"Net movement in the Other Comprehensive Income column for this account over the period. Non-zero for equity accounts not classified under groups 3110 or 3111.","example":0},"total_equity":{"type":"number","description":"Total equity movement for this account: paid_in_capital + retained_earnings + other_comprehensive_income.","example":1000000000}},"required":["account_number","account_name","paid_in_capital","retained_earnings","other_comprehensive_income","total_equity"]},"EquityTotalsDto":{"type":"object","properties":{"paid_in_capital":{"type":"number","description":"Total net movement in Paid-in Capital across all equity accounts.","example":1000000000},"retained_earnings":{"type":"number","description":"Total net movement in Retained Earnings across all equity accounts.","example":175000000},"other_comprehensive_income":{"type":"number","description":"Total net movement in Other Comprehensive Income across all equity accounts.","example":0},"total_equity":{"type":"number","description":"Grand total equity movement: sum of all three columns across all accounts.","example":1175000000}},"required":["paid_in_capital","retained_earnings","other_comprehensive_income","total_equity"]},"ChangesInEquityResponseDto":{"type":"object","properties":{"date_from":{"type":"string","description":"Start date of the reporting period (inclusive).","example":"2026-01-01"},"date_to":{"type":"string","description":"End date of the reporting period (inclusive).","example":"2026-12-31"},"accounts":{"description":"One row per equity account with its net movement distributed across equity sub-category columns.","type":"array","items":{"$ref":"#/components/schemas/EquityAccountRowDto"}},"totals":{"description":"Ending balance — column-wise sum of all account rows. Represents the total movement in each equity sub-category for the period.","allOf":[{"$ref":"#/components/schemas/EquityTotalsDto"}]}},"required":["date_from","date_to","accounts","totals"]},"ArCustomerDto":{"type":"object","properties":{"id_customer":{"type":"number"},"name_customer":{"type":"string"},"npwp_customer":{"type":"object"},"company_code_customer":{"type":"object"},"address_customer":{"type":"object"}},"required":["id_customer","name_customer"]},"ArInvoiceListResponseDto":{"type":"object","properties":{"id_ar_invoice":{"type":"number"},"reference_code":{"type":"string"},"id_customer":{"type":"number"},"id_voyage":{"type":"object"},"id_voyage_invoice":{"type":"object"},"invoice_date":{"type":"object"},"due_date":{"type":"object"},"accounting_date":{"type":"object"},"description":{"type":"object"},"subtotal":{"type":"number"},"include_vat":{"type":"boolean"},"vat_amount":{"type":"number"},"include_withholding":{"type":"boolean"},"withholding_amount":{"type":"number"},"grand_total":{"type":"number"},"status":{"type":"string","enum":["DRAFT","POSTED","FULLY_PAID"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"customer":{"$ref":"#/components/schemas/ArCustomerDto"}},"required":["id_ar_invoice","reference_code","id_customer","subtotal","include_vat","vat_amount","include_withholding","withholding_amount","grand_total","status","created_at","updated_at"]},"ArInvoiceItemResponseDto":{"type":"object","properties":{"id_ar_invoice_item":{"type":"number"},"description":{"type":"object"},"quantity":{"type":"object"},"unit_price":{"type":"object"},"total_price":{"type":"number"},"sort_order":{"type":"number"}},"required":["id_ar_invoice_item","total_price","sort_order"]},"ArPaymentResponseDto":{"type":"object","properties":{"id_ar_payment":{"type":"number"},"payment_method":{"type":"string","enum":["CASH","BANK_TRANSFER"]},"amount":{"type":"number"},"payment_date":{"format":"date-time","type":"string"},"journal":{"type":"object"},"recipient_bank_account":{"type":"object"},"memo":{"type":"object"},"created_at":{"format":"date-time","type":"string"}},"required":["id_ar_payment","payment_method","amount","payment_date","created_at"]},"ArInvoiceDetailResponseDto":{"type":"object","properties":{"id_ar_invoice":{"type":"number"},"reference_code":{"type":"string"},"id_customer":{"type":"number"},"id_voyage":{"type":"object"},"id_voyage_invoice":{"type":"object"},"invoice_date":{"type":"object"},"due_date":{"type":"object"},"accounting_date":{"type":"object"},"description":{"type":"object"},"subtotal":{"type":"number"},"include_vat":{"type":"boolean"},"vat_amount":{"type":"number"},"include_withholding":{"type":"boolean"},"withholding_amount":{"type":"number"},"grand_total":{"type":"number"},"status":{"type":"string","enum":["DRAFT","POSTED","FULLY_PAID"]},"created_at":{"format":"date-time","type":"string"},"updated_at":{"format":"date-time","type":"string"},"customer":{"$ref":"#/components/schemas/ArCustomerDto"},"items":{"type":"array","items":{"$ref":"#/components/schemas/ArInvoiceItemResponseDto"}},"payments":{"type":"array","items":{"$ref":"#/components/schemas/ArPaymentResponseDto"}}},"required":["id_ar_invoice","reference_code","id_customer","subtotal","include_vat","vat_amount","include_withholding","withholding_amount","grand_total","status","created_at","updated_at","items","payments"]},"CreateArInvoiceItemDto":{"type":"object","properties":{"description":{"type":"string","description":"Item description."},"quantity":{"type":"number","description":"Quantity.","minimum":0},"unit_price":{"type":"number","description":"Unit price.","minimum":0},"total_price":{"type":"number","description":"Total price for this line.","minimum":0},"sort_order":{"type":"number","description":"Sort order.","default":0}},"required":["total_price"]},"CreateArInvoiceDto":{"type":"object","properties":{"id_customer":{"type":"number","description":"Customer ID."},"id_voyage":{"type":"number","description":"Voyage ID (optional, for linked invoices)."},"invoice_date":{"type":"string","description":"Invoice date. Format: YYYY-MM-DD."},"due_date":{"type":"string","description":"Due date. Format: YYYY-MM-DD."},"accounting_date":{"type":"string","description":"Accounting date. Format: YYYY-MM-DD."},"description":{"type":"string","description":"Description / memo."},"include_vat":{"type":"boolean","description":"Include VAT (11%).","default":false},"include_withholding":{"type":"boolean","description":"Include withholding tax (2%).","default":false},"items":{"description":"Line items. At least 1 required.","type":"array","items":{"$ref":"#/components/schemas/CreateArInvoiceItemDto"}}},"required":["id_customer","items"]},"UpdateArInvoiceDto":{"type":"object","properties":{"invoice_date":{"type":"string","description":"Invoice date. Format: YYYY-MM-DD."},"due_date":{"type":"string","description":"Due date. Format: YYYY-MM-DD."},"accounting_date":{"type":"string","description":"Accounting date. Format: YYYY-MM-DD."},"description":{"type":"string","description":"Description / memo."},"include_vat":{"type":"boolean","description":"Include VAT (11%)."},"include_withholding":{"type":"boolean","description":"Include withholding tax (2%)."}}},"RegisterArPaymentDto":{"type":"object","properties":{"payment_method":{"type":"string","enum":["CASH","BANK_TRANSFER"],"description":"Payment method: CASH or BANK_TRANSFER."},"amount":{"type":"number","description":"Payment amount. Must equal grand_total (full payment)."},"payment_date":{"type":"string","description":"Payment date. Format: YYYY-MM-DD."},"journal":{"type":"string","description":"Journal name."},"recipient_bank_account":{"type":"string","description":"Recipient bank account."},"memo":{"type":"string","description":"Memo. Defaults to AR invoice reference_code if omitted."}},"required":["payment_method","amount","payment_date"]}}}}