Freezer / Warehouse Transfer
Freezer / Warehouse Transfer moves stock from the current branch warehouse group to another warehouse/freezer. The flow is document-based: save the header first, create/update/delete item rows, assign batch quantities, then send the completed document to B1.
App Entry Points
| App | Target |
|---|
| Mobile | TransferWarehouseList -> TransferWarehouseDetail |
| POS Terminal | transferWarehouse -> TransferWarehouseDetailForm |
Document Lifecycle
Workflow With Conditions
| Rule | Behavior |
|---|
| Required warehouse | Destination whsCode and whsName are required before saving. |
| Company change | Mobile blocks changing company after items exist; user must delete all items first. |
| Owner identity | Header saves branch, warehouse group, user code, responsible user, company, destination warehouse, notes, and totals. |
| Create vs update | If transferBranchId is missing, the form creates a header; otherwise it patches the existing header. |
| Destination list | Destination warehouse/sub-warehouse options filter out excluded NF-/DR- records before being shown. |
Item And Batch Rules
| Rule | Behavior |
|---|
| Owner edit | Only the document owner can add/edit/delete item rows. Batch picking may still be available depending on canUserPickBatch(user). |
| Existing batch quantity | If an item already has batch numbers, quantity cannot be increased above the original item quantity. Mobile trims existing batches when quantity is reduced. |
| Required quantity | Item quantity must be greater than 0. |
| Required batch | When batch picking is required, at least one batch row is required and every batch needs a number and quantity greater than 0. |
| Batch total | When batch picking is required, total batch quantity must exactly match the item move quantity. |
| Duplicate batch | Duplicate batch numbers are blocked per item. |
| Lot balance | Non-dummy products cannot move more than the selected lot balance. |
| Date validation | Batch expiry/due-date validation runs before save. When transfer due date/deposit logic is active, due date must be later than admission date. |
| Dummy items | Dummy transfer items can use generated/manual batch numbers instead of lot lookup. |
| Submit warehouse codes | Item payload sends destination warehouseCode and source fromWarehouseCode, both normalized through company-specific warehouse-code logic. |
B1 Send Rules
Services / APIs
| Operation | Service |
|---|
| List | GET /transfer-branches?page=...&branchId=...&whGrpCode=... via getTransferWarehouses. The current logged-in warehouse group's whGrpCode scopes the list. |
| Detail | GET /transfer-branches/:id via getTransferWarehouseById |
| Header create | POST /transfer-branches via createTransferWarehouse |
| Header update | PATCH /transfer-branches/:id via updateTransferWarehouse |
| Header delete | DELETE /transfer-branches/:id via deleteTransferWarehouse |
| Item create/update/delete | createTransferWarehouseItem, updateTransferWarehouseItem, deleteTransferWarehouseItem |
| Final integration | sendTransferWarehouseToB1(transferBranchId) |
DISABLE_TRANSFER_WAREHOUSE_MUTATION_API exists in the service and can turn mutation calls into dry-run cache behavior when enabled. It is currently false in the checked code.
Field Dictionary And Provenance
Unlike the other inventory menus, this flow creates and updates its own header and items through REST APIs. The list comes from GET /transfer-branches scoped by selected branchId and whGrpCode; detail comes from GET /transfer-branches/:id.
| Field | Meaning | Source / submit rule |
|---|
transferBranchId, transferBranchNo, createdAt | Document ID, number, and creation time | Backend response fields; not sent on create/update. |
whsCode, whsName | Destination warehouse/freezer | Selected by user; both are required. |
companyCode, companyName | Company identity | User selection; empty values fall back to getCompanyOption. |
notes | Header note | User input. |
branchId, branchName, whGrpCode, whGrpName | Creating branch and warehouse group | Current selected branch. |
amount | Header total | App currently sends constant 0. |
userCode, userResponsible | Document owner | Logged-in user; responsible name is first + last name with username fallback on Terminal. |
priceList | B1 price list | Constant -2. |
Items and batches (POST/PATCH /transfer-branches/:id/items)
| Field | Meaning | Source / submit rule |
|---|
id | Item ID | Backend detail field used for update/delete; not sent in item payload. |
productCode, productName | Item identity | User-selected inventory or dummy item. |
warehouseCode, fromWarehouseCode | Destination and source warehouses | Header/item selection; source falls back to selected whsGrpCode; both normalized for company rules. |
qty, price | Move quantity and unit price | User/product values converted to numbers; quantity must be positive. |
UOMCode, UOMEntry, remark | Unit and item note | Product/item values; UOMEntry falls back to 0. |
batchNumbers[].batchNumber, quantity | Moved lot and quantity | User-selected lot or dummy/manual batch; total must match qty when batch selection is required. |
admissionDate, manufacturingDate, expiryDate, dueDate | Receipt date plus batch dates | Existing/editor values; missing dates fall back to the current date. admissionDate and dueDate are submitted as YYYY-MM-DDTHH:mm:ss. |
Permissions And Guards
| Topic | Behavior |
|---|
| Terminal menu key | transferWarehouse |
| deptCode menu set | -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 12, 13, 16, 20, 22, 23, 27, 28 |
| Branch rule | allowNonMainBranch = true; branch warehouse users can move stock locally. |
| Full non-main access | Users with non-main warehouse full access can pass menu access checks. |
| Owner rule | The user who created/saved the document owns item edit and B1 send authority. |
| Batch authority | canUserPickBatch(user) controls whether the user can assign batch rows; current deptCode set is 2, 4, 8, 12, 22, 28, 29. |
Mobile vs POS Terminal
| Topic | Mobile | POS Terminal |
|---|
| Detail | Stack detail screen | HomeScreen detail form |
| Header save | ensureTransferBranch / handleSaveHeader | saveHeader inside item submit |
| Company guard | Blocks company change after items exist | Same business intent in detail flow |
| Batch picker | Loads lots using source warehouse transformed by company | Loads lots from branch warehouse group/company |
| B1 send | Owner + item/batch completeness required | Same owner + completeness rule |
Developer Handoff Map
| Area | Code |
|---|
| Mobile detail | apps/mobile/src/screens/transferWarehouseStack/transferWarehouseDetailScreen/index.tsx |
| Mobile service | apps/mobile/src/services/transferWarehouse.ts |
| Terminal detail | apps/pos-terminal/src/screens/HomeScreen/TransferWarehouseDetailForm.tsx |
| Terminal service | apps/pos-terminal/src/services/transferWarehouse.ts |
| Product lot lookup | services/common.ts / getProductLots |
| Product inventory | services/products.ts |