Skip to main content

Borrow Fish

Borrow Fish manages fish/product borrowing before the normal sales-order flow. It is close to Sales Orders because it starts with a customer, branch/warehouse context, product lines, quantities, and later can become a sales order. The important differences are borrow type, pickup/license-plate rules for non-main SPEC borrows, expected purchase quantity, acceptance/stock-cut workflow, retry handling, and conversion to sales order.

App Entry Points

AppTarget
MobileBorrowList -> BorrowDetail
POS TerminalborrowFish -> BorrowDetailForm in HomeScreen

Borrow Types

TypeLabel
SPECCustomer sample/inspection
MARKETMarket visit
VIDEOVideo shooting
SEMINARSeminar
DESTROYDestroy
LABResearch/lab

The type must be selected before products can be added. For a non-main branch, changing a borrow to SPEC is blocked when the document already has product items; users must remove items first because SPEC adds required pickup and customer-license-plate rules.

Lifecycle

End-To-End Workflow

Header Rules

TopicBehavior
CustomerBorrow starts from a selected customer and stores customer code/name context.
Branch and warehouse groupPayload carries branchId, whGrpCode, and whGrpName from selected branch/document context.
Borrow typeRequired before adding products or confirming.
NotesStored in notes and can be updated while the draft is editable.
dateOfPickupSent only for SPEC; non-SPEC payload clears it to null.
Customer license plateRequired before adding items for non-main SPEC; kept in customerLicensePlate.
Pickup date edit lockFor non-main SPEC, pickup date cannot be changed after items exist.
Past pickup dateMobile blocks pickup dates before the current day.

Product And Quantity Rules

Important item rules:

RuleMain BranchNon-main Branch
Expected purchase quantityNot required; payload sends 0/undefined.Required and must be a number greater than 0.
Quantity per lineSPEC (customer sample/inspection) only: maximum 3. Other borrow types have no per-line quantity cap.Maximum 5 for every borrow type.
Number of product rowsSPEC only: maximum 3 rows. Other borrow types have no row-count cap.No 3-row cap in the UI guard.
SPEC pickup/license plateNot required by the branch-specific guard.Required before adding product.
Quantity formatPositive integer only.Positive integer only.
Stock guardAdd checks onHand - booking; edit allows available stock plus the original item quantity.Same.

The item payload is built from product inventory data, including product code/name, quantity, expected quantity, price, amount, weight, warehouse, company, tax/VAT, UOM, weight-base flag, step-price flag, and editPriceBy = null.

Editing Existing Items

Existing item edits are allowed only while the document is an editable draft. On edit, the app reloads the current product inventory by product code and calculates maxEditableStock = availableStock + originalQty for the same product. This lets the user keep or reduce an existing reservation while still preventing the final quantity from exceeding stock.

For non-main branch edits, expectedQty remains required and must be greater than 0. The per-line quantity cap remains 5 for every non-main borrow type. On the main branch, the cap is 3 only for SPEC; other borrow types have no per-line cap. All types still require a positive integer quantity and available stock.

Product Picker And First-Item Persistence

  • When an existing borrow has a borrowId, adding products does not show a blocking full-screen loading state. The product picker remains open after a successful add so the operator can continue adding products.
  • A new draft follows a two-stage persistence flow: create the borrow header first, use the returned borrowId as the item-create identity, then create the first item.
  • borrowNo is a display/document number and is not used as a substitute for borrowId when creating the item.
  • After the first item is created, the app refreshes the borrow detail/list and synchronizes the route with the returned borrow identity. The header and first item therefore appear immediately instead of only after a second item is added.
  • Mobile and POS Terminal follow the same persistence behavior.

Confirm, Accept, Complete, Retry

Confirm saves the latest header first, then calls confirmBorrow. After confirmation, direct draft editing is locked by status. Completion uses approveBorrow when the document has no failed sub-borrow. If hasFailedSubBorrow is true, the complete action becomes a retry action and calls retryBorrow.

Convert To Sales Order

The convert button is shown when all of these are true:

ConditionRequired Value
BranchNon-main branch
Borrow typeSPEC
StatusDONE

Conversion calls convertBorrow(borrowId). The converted document should carry customer, branch/warehouse, product, quantity, expected quantity, and pricing context into the Sales Order flow. After conversion, the borrow status becomes CONVERTED.

Two print paths are exposed:

PrintBehavior
Borrow packPrints customer/borrow/product packing document.
Borrow storagePrints warehouse/storage-facing borrow document.

Both print actions require at least one product item. Printing does not change business status by itself.

Permissions And Guards

PermissionRule
Terminal menu keyborrowFish
Menu deptCode set-2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 12, 13, 14, 30, 16, 20, 22, 23, 27, 28
Create borrowAdmin, or dept -2, 1, 2, 4, 7, 8, 9, 13, 16, 21, 29
Cancel/delete borrowAdmin; owner when status NEW; or allowed cancel depts/users while status is NEW or WAITING
Cancel departments-2, 1, 2, 4, 9; dept 8 and 22 also override for NEW/WAITING
Cancel override user codes008045, 012521, 012508, 008051, 012388, 012428, 008060
B1 processingAdmin, or dept 2, 8, 12, 22, 28
Owner processingThe document owner can process if borrow type is not DESTROY
Main branch processingMain branch requires B1 processing permission
Draft editingStatus must be NEW and current user must own the draft, or the draft is not persisted yet
Borrow type editingAllowed before persistence or by the document owner

Mobile vs POS Terminal

TopicMobilePOS Terminal
NavigationFull borrow stack list/detailHomeScreen split-pane menu borrowFish
Product flowBorrow detail screen and product-flow hookBorrow detail form, panels, and product picker
Header saveSaves through borrow service when existing detail changesSaves raw detail through HomeScreen handlers
ValidationSame business rules in mobile componentsSame business rules in HomeScreen handlers
PrintingprintBorrowPack, printBorrowStorageSame print utilities
ConversionCalls convertBorrow and refreshes detailCalls convertBorrow and refreshes split list/detail

API And Data Map

OperationService
ListgetBorrows
DetailgetBorrowDetail(borrowId)
Create/update/delete headercreateBorrow, updateBorrow, deleteBorrow
Item CRUDcreateBorrowItem, updateBorrowItem, deleteBorrowItem
ConfirmconfirmBorrow
AcceptacceptBorrow
Complete/cut stockapproveBorrow
Retry failed sub-borrowretryBorrow
Convert to sales orderconvertBorrow

Developer Handoff Map

AreaCode
Mobile permissions/helpersapps/mobile/src/utils/borrow.ts
Mobile list/detailapps/mobile/src/screens/borrowStack/borrowListScreen, borrowDetailScreen
Mobile product flowapps/mobile/src/screens/borrowStack/borrowDetailScreen/useBorrowProductFlow.ts
Terminal permissions/panelsapps/pos-terminal/src/screens/HomeScreen/BorrowPanels.tsx
Terminal detailapps/pos-terminal/src/screens/HomeScreen/BorrowDetailForm.tsx
Terminal handlersapps/pos-terminal/src/screens/HomeScreen/index.tsx
Servicesapps/*/src/services/borrow.ts
Converted targetSales Order docs and order services