FE: module stock_transfer — chuyển kho #
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 stock_transfer.transfers (quyền
stock_transfer.read). listStockTransfers lọc status, from_warehouse_id,
to_warehouse_id; q tìm số phiếu.
Vòng đời #
draft → in_transit (đã xuất khỏi kho nguồn) → completed (đã vào kho đích).
draft / in_transit → cancelled: đang chuyển mà huỷ thì hàng về kho nguồn.
Phiếu completed không huỷ được: tạo phiếu chuyển ngược.
Trong lúc in_transit, hàng không nằm ở kho nào: onHand kho nguồn đã giảm,
kho đích chưa tăng.
Mỗi phiếu 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.
actions | Gọi | Trạng thái | Quyền |
|---|---|---|---|
ship | shipStockTransfer | draft | stock_transfer.ship |
receive | receiveStockTransfer | in_transit | stock_transfer.receive |
cancel | cancelStockTransfer | draft, in_transit | stock_transfer.ship |
delete | deleteStockTransfer | draft | stock_transfer.delete |
Gọi sai trạng thái → 409 stock_transfer_invalid_status (details.status,
details.action): đọc lại phiếu.
Tạo #
createStockTransfer (quyền stock_transfer.create): fromWarehouseId,
toWarehouseId, note?, lines: [{ variantId, uomId?, qty }], tối đa 200
dòng. Dòng chốt từ lúc tạo. uomId là đơn vị thêm của sản phẩm (response null
= đơn vị gốc), baseQty là số thật sự rời kho. Tạo xong chưa đổi gì ở kho.
- 400
stock_transfer_same_warehouse,stock_transfer_warehouse_invalid(details.warehouseId); - Theo dòng (
error.at = lines.<i>): 400stock_transfer_variant_invalid,stock_transfer_uom_invalid,stock_transfer_qty_not_exact.
Xuất, nhận, huỷ #
Ba thao tác không có body. Lỗi của một dòng mang error.at = items.<i>, i là
thứ tự dòng trong items của phiếu (không phải body lúc tạo).
Thiếu hàng khi xuất. Chặn cứng, không bán vượt, không xuất một phần: cả
phiếu giữ nguyên draft.
- 409
stock_insufficient_available(details.available): theo đơn vị GỐC, trong khi dòng có thể theo đơn vị thêm: so vớibaseQty; - 409
stock_insufficient_batch_available(details.available): chỉ tính lô / serial còn hạn, nên có thể nhỏ hơnavailablecủa dòng tồn; - 404
stock_level_not_found: biến thể chưa từng có ở kho nguồn.
Tô đỏ dòng theo error.at, cho sửa bằng cách huỷ rồi tạo lại (dòng đã chốt)
hoặc nhập thêm rồi xuất lại.
Lô / serial. Không chọn được lô / serial khi xuất: kho tự chọn theo hạn gần
trước (FEFO), lô / serial đã hết hạn không được lấy. items[].detail (có sau
khi xuất) cho biết đã lấy gì, null nếu hàng không theo dõi:
{ kind: "batches", batches: [{ id, lotNumber, expiryDate, qty }] };{ kind: "serials", serials: [{ id, serialNo }] }.
Nhận và huỷ dùng lại ĐÚNG lô / serial này. Ở kho đích, lô được tạo mới hoặc cộng theo số lô.
Giá vốn #
Phiếu không mang giá vốn, không cần stock.view_cost. Chuyển kho không ghi giá
vốn vào sổ, kể cả lô tạo mới ở kho đích: unitCost của lô đó là null.
Mẫu in: stock_transfer.note #
printDocument({ params: { name: "stock_transfer.note", id } }), quyền
stock_transfer.read. Phiếu chuyển kho: kho xuất / nhận, số lượng, lô / serial
đã xuất (trống khi chưa xuất); không có giá vốn. Không gửi email. Thiếu quyền,
sai id hay phiếu của store khác đều trả 404.