import { api } from '@/lib/api' import type { PaginatedResponse, PurchaseOrderResponse, GrnResponse, PurchaseOrderStatus, PurchaseReturnResponse, } from '@/types/api' import type { PageParams } from './master' // ─── Purchase Orders ────────────────────────────────────────────────────────── export interface PurchaseOrderItemBody { itemId: string quantity: number unitCost: number } export interface PurchaseOrderBody { supplierId: string items: PurchaseOrderItemBody[] // TEMPORARY: required while auth doesn't resolve a logged-in user server-side — see testbug.md #28. createdByUserId: string } export interface UpdatePurchaseOrderLineBody { purchaseOrderItemId?: string itemId: string quantity: number unitCost: number } export interface UpdatePurchaseOrderBody { items: UpdatePurchaseOrderLineBody[] } export interface PurchaseOrderListParams extends PageParams { supplierId?: string status?: PurchaseOrderStatus } export const purchaseOrders = { list: (params?: PurchaseOrderListParams) => api.get>('/purchase-orders', { params }).then(r => r.data), get: (id: string) => api.get(`/purchase-orders/${id}`).then(r => r.data), create: (body: PurchaseOrderBody) => api.post('/purchase-orders', body).then(r => r.data), update: (id: string, body: UpdatePurchaseOrderBody) => api.put(`/purchase-orders/${id}`, body).then(r => r.data), cancel: (id: string, reason: string) => api.post(`/purchase-orders/${id}/cancel`, { reason }).then(r => r.data), } // ─── Goods Receipts (GRN) ───────────────────────────────────────────────────── export interface GrnBatchLineBody { /** Null for an expiry-only lot (item tracks expiry but not batch numbers). */ batchNumber: string | null expiryDate: string | null quantity: number } export interface GrnItemBody { /** Set for a PO receipt; omitted for a direct receipt (itemId is used instead). */ purchaseOrderItemId?: string /** Set for a direct receipt line. */ itemId?: string acceptedQuantity: number rejectedQuantity: number /** Only for items with TracksBatches and/or TracksExpiryDate. */ batches?: GrnBatchLineBody[] /** Only for items with TracksSerialNumbers — exactly acceptedQuantity entries. */ serialNumbers?: string[] /** Cost per base-UOM unit. Omitted on a PO line falls back to the PO line's cost. */ unitCost?: number /** Omitted falls back to the GRN-wide percentage. */ discountPercent?: number vatPercent?: number /** Free-issue units: stocked but not costed. Serials/batches must cover accepted + free. */ freeQuantity?: number } export interface GrnBody { purchaseOrderId: string warehouseId: string receivedAt: string items: GrnItemBody[] /** GRN-wide defaults for lines that don't set their own. */ discountPercent?: number vatPercent?: number // TEMPORARY: required while auth doesn't resolve a logged-in user server-side — see testbug.md #28. receivedByUserId: string } export interface DirectGrnBody { warehouseId: string supplierId?: string items: GrnItemBody[] discountPercent?: number vatPercent?: number // TEMPORARY: required while auth doesn't resolve a logged-in user server-side — see testbug.md #28. receivedByUserId: string } export const grn = { list: (params?: PageParams & { purchaseOrderId?: string }) => api.get>('/goods-receipts', { params }).then(r => r.data), get: (id: string) => api.get(`/goods-receipts/${id}`).then(r => r.data), create: (body: GrnBody) => api.post('/goods-receipts', body).then(r => r.data), /** Receive goods with no purchase order. */ createDirect: (body: DirectGrnBody) => api.post('/goods-receipts/direct', body).then(r => r.data), } // ─── Purchase Returns ───────────────────────────────────────────────────────── export interface PurchaseReturnItemBody { itemId: string quantity: number } export interface PurchaseReturnBody { reason: string items: PurchaseReturnItemBody[] // TEMPORARY: required while auth doesn't resolve a logged-in user server-side — see testbug.md #28. createdByUserId: string } export const purchaseReturns = { get: (id: string) => api.get(`/purchase-returns/${id}`).then(r => r.data), listByPurchaseOrder: (purchaseOrderId: string) => api.get(`/purchase-orders/${purchaseOrderId}/returns`).then(r => r.data), create: (purchaseOrderId: string, body: PurchaseReturnBody) => api.post(`/purchase-orders/${purchaseOrderId}/returns`, body).then(r => r.data), }