openapi: 3.0.3 info: title: Walet Inventory API version: 1.0.0 description: API untuk sistem inventory sarang burung walet berbasis lot, traceability, sorting, dan partial sales allocation. servers: - url: /api/v1 paths: /auth/login: post: summary: Login requestBody: required: true content: application/json: schema: type: object required: [email, password] properties: email: type: string password: type: string responses: '200': description: Login success /suppliers: get: summary: List suppliers responses: '200': description: OK content: application/json: schema: type: array items: type: object properties: id: { type: integer } code: { type: string } name: { type: string } phone: { type: string } email: { type: string } bank_name: { type: string } bank_account_number: { type: string } address: { type: string } post: summary: Create supplier requestBody: required: true content: application/json: schema: type: object properties: code: type: string name: type: string phone: type: string email: type: string bank_name: type: string bank_account_number: type: string address: type: string responses: '201': description: Created /customers: get: summary: List customers responses: '200': description: OK content: application/json: schema: type: array items: type: object properties: id: { type: integer } code: { type: string } name: { type: string } phone: { type: string } email: { type: string } bank_name: { type: string } bank_account_number: { type: string } address: { type: string } post: summary: Create customer requestBody: required: true content: application/json: schema: type: object properties: code: type: string name: type: string phone: type: string email: type: string bank_name: type: string bank_account_number: type: string address: type: string responses: '201': description: Created /item-types: get: summary: List item types responses: '200': description: OK /item-grades: get: summary: List item grades responses: '200': description: OK /warehouses: get: summary: List warehouses responses: '200': description: OK /purchases: get: summary: List purchases parameters: - in: query name: supplier_id schema: { type: integer } - in: query name: status schema: { type: string } responses: '200': description: OK post: summary: Create purchase requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreatePurchaseRequest' responses: '201': description: Created /purchases/{id}: get: summary: Purchase detail parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: OK /receipts: get: summary: List receipts responses: '200': description: OK post: summary: Create receipt requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateReceiptRequest' responses: '201': description: Created /receipts/{id}/generate-lots: post: summary: Generate lots from receipt parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Lots generated /lots: get: summary: List inventory lots parameters: - in: query name: supplier_id schema: { type: integer } - in: query name: item_type_id schema: { type: integer } - in: query name: item_grade_id schema: { type: integer } - in: query name: warehouse_id schema: { type: integer } - in: query name: status schema: { type: string } responses: '200': description: OK /lots/{id}: get: summary: Lot detail parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: OK /lots/{id}/movements: get: summary: Lot movement history parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: OK /lots/{id}/trace: get: summary: Lot traceability detail parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: OK /lots/{id}/hold: post: summary: Hold lot parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Lot held /lots/{id}/release: post: summary: Release lot parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Lot released /lots/{id}/transfer: post: summary: Transfer lot parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: type: object properties: to_warehouse_id: type: integer to_location_id: type: integer qty: type: number notes: type: string responses: '200': description: Transfer success /sorting-sessions: get: summary: List sorting sessions responses: '200': description: OK post: summary: Create sorting session requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateSortingSessionRequest' responses: '201': description: Created /lots/{id}/regrade: post: summary: Regrade lot parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: type: object required: [target_grade_id, qty, reason_id] properties: target_grade_id: type: integer qty: type: number reason_id: type: integer notes: type: string responses: '200': description: Regrade success /sales: get: summary: List sales responses: '200': description: OK post: summary: Create sales order requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateSalesRequest' responses: '201': description: Created /sales/{id}: get: summary: Sales detail parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: OK /sales/{id}/allocate: post: summary: Manual allocate lots to sales lines parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AllocateSalesRequest' responses: '200': description: Allocation success /sales/{id}/auto-allocate: post: summary: Auto allocate by policy parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: type: object properties: policy: type: string example: FIFO responses: '200': description: Auto allocation success /sales/{id}/confirm-picking: post: summary: Confirm picked quantities parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ConfirmPickingRequest' responses: '200': description: Picking confirmed /stock-adjustments: get: summary: List stock adjustments responses: '200': description: OK post: summary: Create stock adjustment requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateStockAdjustmentRequest' responses: '201': description: Created /sales-returns: post: summary: Create sales return requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateSalesReturnRequest' responses: '201': description: Created /purchase-returns: post: summary: Create purchase return responses: '201': description: Created /barcode/lookup/{value}: get: summary: Lookup lot by barcode or QR value parameters: - in: path name: value required: true schema: type: string responses: '200': description: OK /reports/stock-summary: get: summary: Stock summary report responses: '200': description: OK /reports/stock-lots: get: summary: Stock lots report responses: '200': description: OK /reports/purchases: get: summary: Purchases report responses: '200': description: OK /reports/sales: get: summary: Sales report responses: '200': description: OK /reports/margins: get: summary: Margin report responses: '200': description: OK /reports/shrinkage: get: summary: Shrinkage report responses: '200': description: OK /reports/supplier-quality: get: summary: Supplier quality report responses: '200': description: OK /reports/traceability: get: summary: Traceability report parameters: - in: query name: sales_id schema: { type: integer } - in: query name: lot_id schema: { type: integer } responses: '200': description: OK components: parameters: IdParam: in: path name: id required: true schema: type: integer schemas: CreatePurchaseRequest: type: object required: [supplier_id, purchase_date, lines] properties: supplier_id: type: integer purchase_date: type: string format: date supplier_invoice_no: type: string notes: type: string lines: type: array items: type: object required: [item_type_id, qty_ordered, unit_id, unit_price, classification_status] properties: item_type_id: type: integer item_grade_id: type: integer nullable: true qty_ordered: type: number unit_id: type: integer unit_price: type: number classification_status: type: string CreateReceiptRequest: type: object required: [purchase_id, supplier_id, receipt_date, lines] properties: purchase_id: type: integer supplier_id: type: integer receipt_date: type: string format: date notes: type: string lines: type: array items: type: object required: [purchase_line_id, item_type_id, qty_received, qty_accepted, unit_id, unit_cost, warehouse_id] properties: purchase_line_id: type: integer item_type_id: type: integer item_grade_id: type: integer nullable: true qty_received: type: number qty_accepted: type: number qty_rejected: type: number unit_id: type: integer unit_cost: type: number warehouse_id: type: integer warehouse_location_id: type: integer CreateSortingSessionRequest: type: object required: [source_lot_id, sorting_date, input_qty, results] properties: source_lot_id: type: integer sorting_date: type: string format: date-time input_qty: type: number shrinkage_qty: type: number notes: type: string results: type: array items: type: object required: [item_type_id, item_grade_id, qty_result, unit_cost] properties: item_type_id: type: integer item_grade_id: type: integer qty_result: type: number unit_cost: type: number CreateSalesRequest: type: object required: [customer_id, sales_date, lines] properties: customer_id: type: integer sales_date: type: string format: date notes: type: string lines: type: array items: type: object required: [item_type_id, item_grade_id, qty_sold, unit_id, selling_price] properties: item_type_id: type: integer item_grade_id: type: integer qty_sold: type: number unit_id: type: integer selling_price: type: number AllocateSalesRequest: type: object required: [lines] properties: lines: type: array items: type: object required: [sales_line_id, allocations] properties: sales_line_id: type: integer allocations: type: array items: type: object required: [inventory_lot_id, qty_allocated] properties: inventory_lot_id: type: integer qty_allocated: type: number ConfirmPickingRequest: type: object required: [lines] properties: lines: type: array items: type: object required: [sales_line_id, picked_allocations] properties: sales_line_id: type: integer picked_allocations: type: array items: type: object required: [inventory_lot_id, qty_picked] properties: inventory_lot_id: type: integer qty_picked: type: number CreateStockAdjustmentRequest: type: object required: [inventory_lot_id, adjustment_type, reason_id, qty_change] properties: inventory_lot_id: type: integer adjustment_type: type: string reason_id: type: integer qty_change: type: number notes: type: string CreateSalesReturnRequest: type: object required: [sales_id, customer_id, return_date, lines] properties: sales_id: type: integer customer_id: type: integer return_date: type: string format: date lines: type: array items: type: object required: [sales_line_id, item_type_id, item_grade_id, qty_returned] properties: sales_line_id: type: integer inventory_lot_id: type: integer item_type_id: type: integer item_grade_id: type: integer qty_returned: type: number return_condition: type: string resolution: type: string notes: type: string