xforge · tài liệu FE

FE: module purchase_order — đơn mua hàng #

Phần chung (khởi tạo client, lỗi, danh sách, ngôn ngữ) ở tài liệu FE của Core: docs/fe/common.md; mẫu in: docs/fe/cms.md (bản đọc: xforge-documentation, ADR-0102 của xforge-core). Sửa file này CÙNG PR khi đổi hành vi FE thấy được của module.

Chỉ có ở CMS (XforgeClient). Menu: key purchase_order.orders (quyền purchase_order.read). listPurchaseOrders lọc status, supplier_id, warehouse_id; q tìm số đơn.

Vòng đời #

draft → ordered → partial → received → closed. Từ partial đóng được luôn (chốt thiếu). draft / ordered → cancelled. Trả hàng làm đơn lùi về partial hoặc ordered.

Mỗi đơn có actions (danh sách + chi tiết): thao tác người gọi làm được lúc này, đã xét cả trạng thái lẫn quyền (superuser thấy hết). Bật / tắt nút theo đó, đừng tự suy từ status. actions là chuỗi, giá trị lạ thì bỏ qua.

actionsGọiTrạng tháiQuyền
placeplacePurchaseOrderdraftpurchase_order.update
receivereceivePurchaseOrderordered, partialpurchase_order.receive + stock.view_cost
returnreturnPurchaseOrderItemspartial, receivedpurchase_order.receive
closeclosePurchaseOrderreceivedpurchase_order.update
short_closeshortClosePurchaseOrderpartialpurchase_order.update
cancelcancelPurchaseOrderdraft, orderedpurchase_order.update
deletedeletePurchaseOrderdraftpurchase_order.delete

Gọi sai trạng thái (đơn vừa đổi ở tab khác) → 409 purchase_order_invalid_status (details.status, details.action): đọc lại đơn.

Tạo #

createPurchaseOrder (quyền purchase_order.create). Dòng chốt từ lúc tạo: sai thì huỷ rồi tạo lại. Mỗi dòng theo ĐƠN VỊ MUA (uomId: đơn vị gốc hoặc đơn vị thêm của sản phẩm; response null = đơn vị gốc), unitCost theo đơn vị mua. Hệ số chụp lúc tạo vào factor, baseQtyOrdered là số vào kho khi nhận đủ.

Lỗi theo dòng (error.at = lines.<i>):

Lỗi của đơn: 400 purchase_order_supplier_invalid (kể cả nhà cung cấp ngừng giao dịch), purchase_order_warehouse_invalid.

Nhận hàng, trả hàng #

receivePurchaseOrder: lines: [{ itemId, qty, lotNumber?, expiryDate?, manufactureDate?, serialNumbers? }]. itemId là items[].id của đơn, qty theo đơn vị mua. Cả lần nhận vào MỘT phiếu PN-…, giá vốn mỗi đơn vị gốc = unitCost / factor. Nhận nhiều lần được.

returnPurchaseOrderItems: lines: [{ itemId, qty, lotNumber?, serialNumbers? }], reason?, note?. Ra MỘT phiếu PX-…, giảm qtyReceived.

Lỗi theo dòng (error.at = lines.<i>, i là chỉ số trong body):

Lô / serial. Biến thể theo lô cần lotNumber (400 stock_lot_number_required); theo serial cần một số serial mỗi đơn vị GỐC, không phải đơn vị mua: 2 thùng 24 cái là 48 số (400 stock_serial_numbers_required; trùng → 409 stock_serial_exists). Biết chế độ qua getStockTracking. Trả hàng theo lô / serial phải nêu đúng lô / số đã nhận.

Giá vốn #

unitCost, lineTotal, itemsTotal của đơn là giá mua, người có purchase_order.read đều đọc được. Nhận hàng thì cần thêm stock.view_cost vì giá đi vào sổ kho: thiếu thì 403 và actions không có receive.

Mẫu in: purchase_order.receipt #

printDocument({ params: { name: "purchase_order.receipt", id } }), quyền purchase_order.read. Phiếu nhập hàng: số đã đặt + đã nhận của từng dòng, in được ở mọi trạng thái. Đơn giá, thành tiền, tổng chỉ có khi người in có stock.view_cost; thiếu quyền thì bản in không có các cột đó. Không gửi email. Thiếu quyền, sai id hay phiếu của store khác đều trả 404.

Nguồn: xforge-modules: modules/inventory/purchase_order/FE.md