6.6 KiB
6.6 KiB
API Spec Backend Sistem Inventory Walet
1. Prinsip API
API berbasis REST JSON dengan fokus pada:
- lot-based inventory
- traceability
- partial allocation
- shrinkage and adjustment
- barcode/QR lookup
Base path contoh:
/api/v1
2. Auth
POST /auth/login
Request:
{
"email": "admin@example.com",
"password": "secret"
}
Response:
{
"token": "jwt-token",
"user": {
"id": 1,
"name": "Admin",
"role": "ADMIN"
}
}
3. Master Data
GET /suppliers
POST /suppliers
Field penting supplier:
- code
- name
- phone
- bank_name
- bank_account_number
- address
GET /suppliers/{id}
PUT /suppliers/{id}
DELETE /suppliers/{id}
GET /customers
POST /customers
Field penting customer:
- code
- name
- phone
- bank_name
- bank_account_number
- address
GET /item-types
POST /item-types
GET /item-grades
POST /item-grades
GET /warehouses
POST /warehouses
GET /warehouse-locations
POST /warehouse-locations
GET /adjustment-reasons
POST /adjustment-reasons
4. Purchasing
GET /purchases
Filter:
- supplier_id
- status
- date_from
- date_to
POST /purchases
{
"supplier_id": 1,
"purchase_date": "2026-04-28",
"supplier_invoice_no": "INV-8891",
"notes": "Pembelian campuran",
"lines": [
{
"item_type_id": 1,
"item_grade_id": 1,
"qty_ordered": 50,
"unit_id": 1,
"unit_price": 18000000,
"classification_status": "FINAL"
},
{
"item_type_id": 1,
"item_grade_id": null,
"qty_ordered": 40,
"unit_id": 1,
"unit_price": 17500000,
"classification_status": "PROVISIONAL"
}
]
}
GET /purchases/{id}
PUT /purchases/{id}
POST /purchases/{id}/submit
POST /purchases/{id}/cancel
5. Receiving
GET /receipts
POST /receipts
{
"purchase_id": 1,
"supplier_id": 1,
"receipt_date": "2026-04-28",
"notes": "Barang diterima baik",
"lines": [
{
"purchase_line_id": 1,
"item_type_id": 1,
"item_grade_id": 1,
"qty_received": 50,
"qty_accepted": 50,
"qty_rejected": 0,
"unit_id": 1,
"unit_cost": 18000000,
"warehouse_id": 1,
"warehouse_location_id": 1
}
]
}
GET /receipts/{id}
POST /receipts/{id}/generate-lots
Response contoh:
{
"receipt_id": 1,
"lots": [
{
"id": 10,
"lot_code": "LOT-260428-SPA-001",
"qr_code_value": "LOT-260428-SPA-001"
}
]
}
6. Inventory Lots
GET /lots
Filter:
- supplier_id
- item_type_id
- item_grade_id
- warehouse_id
- status
- keyword
GET /lots/{id}
GET /lots/{id}/movements
GET /lots/{id}/trace
POST /lots/{id}/hold
POST /lots/{id}/release
POST /lots/{id}/transfer
{
"to_warehouse_id": 2,
"to_location_id": 5,
"qty": 10,
"notes": "Pindah ke gudang cabang"
}
7. Sorting / Regrade
POST /sorting-sessions
{
"source_lot_id": 10,
"sorting_date": "2026-04-28T15:00:00Z",
"input_qty": 40,
"shrinkage_qty": 3,
"notes": "Sortasi batch campuran",
"results": [
{
"item_type_id": 1,
"item_grade_id": 1,
"qty_result": 18,
"unit_cost": 17500000
},
{
"item_type_id": 1,
"item_grade_id": 2,
"qty_result": 12,
"unit_cost": 17500000
},
{
"item_type_id": 2,
"item_grade_id": 1,
"qty_result": 7,
"unit_cost": 17500000
}
]
}
GET /sorting-sessions
GET /sorting-sessions/{id}
POST /lots/{id}/regrade
{
"target_grade_id": 2,
"qty": 5,
"reason_id": 3,
"notes": "Turun grade setelah QC"
}
8. Sales
GET /sales
POST /sales
{
"customer_id": 1,
"sales_date": "2026-04-28",
"notes": "Order customer X",
"lines": [
{
"item_type_id": 1,
"item_grade_id": 1,
"qty_sold": 30,
"unit_id": 1,
"selling_price": 22000000
}
]
}
GET /sales/{id}
POST /sales/{id}/allocate
{
"lines": [
{
"sales_line_id": 1,
"allocations": [
{
"inventory_lot_id": 10,
"qty_allocated": 20
},
{
"inventory_lot_id": 11,
"qty_allocated": 10
}
]
}
]
}
POST /sales/{id}/auto-allocate
{
"policy": "FIFO"
}
POST /sales/{id}/confirm-picking
{
"lines": [
{
"sales_line_id": 1,
"picked_allocations": [
{
"inventory_lot_id": 10,
"qty_picked": 20
},
{
"inventory_lot_id": 11,
"qty_picked": 10
}
]
}
]
}
9. Adjustments & Shrinkage
POST /stock-adjustments
{
"inventory_lot_id": 11,
"adjustment_type": "SHRINKAGE",
"reason_id": 1,
"qty_change": -1.2,
"notes": "Selisih opname"
}
GET /stock-adjustments
10. Returns
POST /sales-returns
POST /purchase-returns
POST /sales-returns
{
"sales_id": 1,
"customer_id": 1,
"return_date": "2026-04-29",
"lines": [
{
"sales_line_id": 1,
"inventory_lot_id": 10,
"item_type_id": 1,
"item_grade_id": 1,
"qty_returned": 2,
"return_condition": "GOOD",
"resolution": "RESTOCK"
}
]
}
11. Barcode / QR
GET /barcode/lookup/{value}
Response:
{
"lot_id": 10,
"lot_code": "LOT-260428-SPA-001",
"supplier": "Supplier A",
"supplier_bank_name": "BCA",
"supplier_bank_account_number": "1234567890",
"item_type": "Jenis A",
"grade": "Grade A",
"available_qty": 30,
"warehouse": "Gudang Pusat",
"location": "Rak A1",
"status": "ACTIVE"
}
POST /lots/{id}/print-label
GET /lots/{id}/labels
12. Reports
GET /reports/stock-summary
GET /reports/stock-lots
GET /reports/purchases
GET /reports/sales
GET /reports/margins
GET /reports/shrinkage
GET /reports/supplier-quality
GET /reports/traceability
Contoh:
GET /reports/traceability?sales_id=1
GET /reports/traceability?lot_id=10
13. Error Rules
Format error:
{
"message": "Validation error",
"errors": {
"qty_allocated": ["qty allocated melebihi stok tersedia"]
}
}
14. Business Validation Rules
- total allocation harus sama dengan qty sales line
- qty allocation tidak boleh melebihi available qty lot
- sorting result total + shrinkage tidak boleh melebihi input qty
- lot hold tidak boleh dipakai untuk sales allocation
- lot closed tidak boleh dipakai lagi
- transfer dan adjustment harus menghasilkan movement ledger
- receipt yang belum finalized tidak boleh dipakai untuk sales