Skip to main content

Storefront Picking / Delivery Sheet

Storefront Picking is the workflow for invoices whose goods are prepared and handed out at a branch/storefront. It is different from route delivery and different from cashier POS. The work unit shown to the user is now a sales order (orderNo), while API acceptance, Lot/Batch persistence, delivery creation, and B1 stock movement still run one invoice at a time.

App Entry Points​

AppTarget
MobileStorefrontListScreen -> StorefrontDetailScreen
POS TerminalshippingStorefront -> StorefrontDetailForm in HomeScreen

What This Menu Shows​

The list is built from invoices with shippingType = 2. Rows with invoiceStatus = CANCELED are removed completely before grouping. The remaining rows are deduplicated and grouped by orderNo; an invoice-specific fallback key is used only when an order number is missing.

Each card displays the customer, sales order number, every included invoice number on its own row, sales employee, and warehouse employee. The NEW tab is evaluated from the grouped card: a group remains NEW until every included invoice is CONFIRMED.

Group card background colors​

Color conditions are evaluated after canceled invoices have been removed and in this order:

Group conditionBackground
Every invoice is CONFIRMEDGreen #76ffa3
Any invoice is NEW and has hasDelivery != nullPurple #d382ff
Any invoice has a pending cancel request (canceledNote != null and rejectCanceledAt == null)Light purple #e7bce7
All other mixed/unconfirmed groupsYellow-green #cffd67

Opening a card passes all grouped invoice IDs plus orderNo into the detail flow. Detail data for every ID is loaded with includeLot=true and combined into one screen. Product rows retain sourceInvoiceId, sourceInvoiceNo, sourceInvoiceStatus, and the source acceptance owner so that validation and API work remain invoice-specific.

Main Workflow​

Accept Job Rules​

ConditionBehavior
Main branchUsers in accept departments are prompted to accept the job when acceptedBy is empty.
Non-main branchAccept flow is enabled, but Lot/Batch editing uses the same permission as the main branch and does not depend on isMain.
Every invoice already acceptedThe prompt is skipped.
Mixed acceptance stateOne modal is shown; confirmation calls the accept API sequentially only for invoices whose acceptedBy is empty. Already accepted invoices are not sent again.
Accepted by current userThat user can continue editing and saving.
Override userUser code 999997 is treated as an accepted/action user.

Accept permission is controlled by departments 8, 12, 22, 28.

Item Checking And Lot/Batch Rules​

Important item rules:

RuleBehavior
Editable statusProduct checks are editable only when their source invoice is NEW. Rows from a CONFIRMED invoice remain visible but cannot open the Lot/Batch editor.
Invoice prefilled lotsA non-empty, valid items[].lots[] response from GET /invoices/{id}?includeLot=true is displayed as the initial value. Users can edit quantity, delete it, or select a replacement lot while the invoice is NEW and they have edit permission.
Lot selectionOn the first tap after loading detail, recalculate the full invoice line quantity even if saved lots are prefilled. Reuse saved lots first, then fill the remainder in API expiry order. Later taps open the current selection for editing without reapplying saved lots.
isMainIt does not lock or restrict Lot/Batch selection. Lot editing uses the same rule for main and non-main branches.
Available stockRetain zero-available API lots for reservation recovery. Restore only this invoice line’s matching product/company/warehouse reservations, capped by API booking and physical stock when supplied. A saved batch missing from the response is added with its reserved quantity and its own dates. Recovery changes local picker balances only.
Insufficient stockOn the first tap, if total stock after recovery is below the full line quantity (including no stock), show an error with required/available/missing quantities before changing the selection or opening a modal. Manual picker reloads still display the no-data message and reload action when empty.
Required product contextitemCode, whsCode, and company are required before lot options can be loaded.
Duplicate lotThe same Lot/Batch cannot be selected twice for one item.
Lot balanceEntered quantity cannot exceed the selected lot balance.
Invoice line quantityEntered quantity cannot exceed the pending quantity of that invoice line.
CompletionEvery line must have checked quantity greater than or equal to invoice quantity before save.
Automatic selectionA complete reused selection skips the modal when there are at most two distinct positive-balance batches across all restored options. More than two opens the editor. With no reusable reservation, one sufficient lot remains automatic and multiple lots remain manual.

For example, a line requiring 9 units with 8 reserved on 260812-NMA8033 and 15 available on 260812-NMA8034 selects 8 from the old batch plus 1 from the new batch. If both batches are the only selectable options, no modal opens. Reservations from other invoice lines are not returned to this line.

Mobile and POS Terminal use packages/utils/src/storefrontLots.ts, which shares reservation recovery and allocation with the shipping route flow. Selection does not release stock through an API; the existing per-invoice save contract below is unchanged.

Save To Delivery / B1 Rules​

The submit button is shown when at least one grouped invoice is not CONFIRMED/CANCELED and the current user has action permission for that invoice. A CONFIRMED source invoice is display-only and is excluded from submit processing.

Before saving, the app blocks:

GuardError Case
PermissionUser cannot save storefront data.
SAP referencerefKey is missing, which means the invoice has not reached SAP/B1 context.
Cancellation requestcanceledAt exists and rejectCanceledAt is still empty.
Incomplete checksNot all items have been checked to the required quantity.

Validation is performed per pending invoice against only its own product rows. When every pending invoice passes, Mobile and POS Terminal iterate through those invoices sequentially:

  1. Skip invoices already in CONFIRMED state.
  2. Add the current invoice to delivery 0 when its deliveryId is missing.
  3. Build invoices[].items[].lots[] from only that invoice's selected product rows.
  4. Save delivery lots for the current invoice.
  5. Create delivery/send stock movement for the current invoice.
  6. Continue with the next invoice, then reload grouped detail and list state.

Grouped Detail Metadata​

FieldDisplay
CustomerShared customer name from the grouped order
Sales orderorderNo
Picking invoiceEvery invoiceNo, joined with , in detail metadata
ProductsProduct rows from every grouped invoice
Confirmed productsVisible as completed/read-only rows; Lot/Batch selection is disabled

Cancel Rules​

Cancellation is a request with a required reason. It does not hard-delete invoice history. In grouped detail, cancellation validation is checked across the group and the request is sent sequentially to non-confirmed invoices only. Printing an invoice from grouped detail prints every included invoice sequentially.

Permissions And Guards​

TopicBehavior
Terminal menu keyshippingStorefront
Menu deptCode set-2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 12, 20, 22, 23, 27, 28
Accept departments8, 12, 22, 28
Save/action departments2, 8, 22, or the user who accepted the job, or override user 999997
Editable invoice statusSource invoice NEW only
Hidden submit statesCONFIRMED, CANCELED, or no action permission

Mobile vs POS Terminal​

TopicMobilePOS Terminal
NavigationFull-screen storefront stackHomeScreen split-pane detail
Accept flowPrompted in detail screenPrompted in detail form
Lot selectionOn the first tap after loading detail, recalculate the full invoice line quantity even if saved lots are prefilled. Reuse saved lots first, then fill the remainder in API expiry order. Later taps open the current selection for editing without reapplying saved lots.
Save behaviorDelivery lots + create deliverySame service behavior
CancelReason modalReason modal

Developer Handoff Map​

AreaCode
Mobile list/detailapps/mobile/src/screens/storefrontStack/storefrontListScreen, storefrontDetailScreen
Mobile storefront helpersapps/mobile/src/screens/storefrontStack/storefrontDetailScreen/helpers.ts
Terminal split dataapps/pos-terminal/src/services/splitMenuData.ts -> shippingStorefront
Terminal detailapps/pos-terminal/src/screens/HomeScreen/StorefrontDetailForm.tsx
Terminal rulesapps/pos-terminal/src/screens/HomeScreen/StorefrontDetailHelpers.ts
Storefront serviceapps/*/src/services/storefront.ts
Delivery/lot serviceapps/*/src/services/shipping.ts

Cancellation from this screen sends a request for review in the Invoice menu. Eligible invoices with explicit hasDelivery = null can instead be canceled without a pending request from the invoice list; see that page for owner/admin permissions, required notes, and global Sweet Alert behavior.