Skip to main content

Booking Price

The Booking Price menu reserves customer pricing and stock before the document is converted into a real sales order. Its structure is close to Sales Order, because it uses the same customer, product, warehouse, step-price, weight, and total concepts. The difference is that a booking price does not continue to invoice/payment until the user converts it to a sales order.

The key special field is item-level currentStepPrice. It stores the step-price snapshot/fallback used by the booking item so the later sales order can keep the same step-price context.

Open workflowOpen currentStepPriceOpen conversion notes

App Entry Points

AppEntry pointMain files
MobileHome -> BookingPriceList -> CustomerList mode booking -> BookingPriceDetailbookingPriceListScreen, bookingPriceDetailScreen
POS TerminalHomeScreen split-pane -> bookingPrice menu -> customer picker/detail panelHomeScreen/index.tsx, BookingPriceDetailForm.tsx, BookingProductPicker.tsx

Services And Endpoints

JobEndpoint / service
Load booking price listGET /booking-price via getBookingPrices(...)
Load detailGET /booking-price/{bookingPriceId}
Create headerPOST /booking-price
Update headerPATCH /booking-price/{bookingPriceId}
Delete documentDELETE /booking-price/{bookingPriceId}
Add itemPOST /booking-price/{bookingPriceId}/items
Update itemPATCH /booking-price/{bookingPriceId}/items/{itemId}
Delete itemDELETE /booking-price/{bookingPriceId}/items/{itemId}
Convert to sales orderPOST /booking-price/{bookingPriceId}/convert
Load step priceproduct step-price API through getProductStepPrice(...)

Main Workflow

Booking Price List

The list is loaded through getBookingPrices(...) with selected branch context:

  • branchId from selected branch
  • whGrpCode from selected warehouse group
  • page, pageLimit, search
  • bookingPriceStatus
  • userCode
  • sorted DESC by CreatedAt

List behavior:

  • rows are deduped by bookingPriceId, bookingPriceStorageId, or bookingPriceNo
  • search and pagination are supported
  • card color communicates document status
  • Mobile uses the floating plus button to start CustomerList mode booking
  • Terminal uses the split-pane list and create action to open the customer picker
  • created-day edit guards use the server business date from GET /api/healthz when available, then fall back to the device date

Draft From Customer

Booking price creation starts from customer selection, using mode = booking.

Fields seeded into detail:

FieldSource
customerCode, customerName, phone1, phone2customer detail
shippingTypecustomer / branch rule
routeCode, routeNamecustomer address
U_BFP_Latitude, U_BFP_Longitudecustomer address
branchId, whGrpCode, whGrpNamebranch storage
userCode, userResponsiblecurrent user
bookingPriceStatusstarts as DRAFT

Terminal parity note: customer-seeded booking drafts use the first customer address for route and coordinates, matching the current Mobile booking-price initialization.

Add And Edit Items

Adding items is close to sales order item entry:

  1. open product picker
  2. selecting an existing product opens edit overlay instead of adding a duplicate
  3. validate quantity as an integer greater than 0
  4. check available stock from onHand - bookingQty
  5. weight-based amount is qty * price * weight
  6. normal amount is qty * price
  7. if stepPriceFlag applies and quantity qualifies, load step price before calculating price
  8. persist in order: ensure/create booking header -> create/update item -> update totals -> reload detail

Important item payload fields:

FieldMeaning
productCode, productNameproduct identity
qty, price, amount, weight, limitWeightquantity, price, amount, and weight
onHand, bookingQtystock validation
uomCode, uomName, UOMCode, UOMName, UOMEntryUOM
whsCode, whGrpCode, whGrpNamewarehouse and warehouse group
companyCode, companyName, taxNo, vatGroupcompany/tax data
weightBaseFlagweight-based product
stepPriceFlagstep-price product
currentStepPricesnapshot/fallback step price for this item
editPriceByuser who edited price

Header Remark

The booking-price remark field is a multiline input. It starts at a minimum height of one line (about 40px) and grows or shrinks with the text content, so longer notes remain readable without leaving a large empty field on short notes. Mobile and POS Terminal use the same behavior, and the input height resets when switching booking-price documents.

currentStepPrice

currentStepPrice is an item-level field that stores the step-price data used when the booking item was created or edited. It is usually a JSON string of step-price rows, or a fallback JSON string when the step-price API has no rows.

Fallback shape:

[
{
From: 0,
Price: item.price,
BPLName: item.whGrpName || item.whsName || ''
}
]

Important behavior:

  • when adding a new item, the app creates currentStepPrice through buildDefaultCurrentStepPrice(product) if step-price rows are not available yet
  • if the item has stepPriceFlag and quantity qualifies, the app loads step prices from the API and stores that response as JSON in currentStepPrice
  • when editing an existing item, the app refreshes inventory from Firestore by productCode before showing stock and booking values
  • for step-price items, the app reloads step price from the MST API, but currentStepPrice is still saved as fallback data, not as the only price source
  • after conversion, the sales order item keeps currentStepPrice so sales order detail can preserve the booking/step-price context

Convert To Sales Order

Conversion runs from the Convert to sales order action in detail:

After conversion:

  • booking price status becomes DONE
  • detail shows that the document has already been converted to a sales order
  • Mobile uses navigation.replace('OrderDetail', { orderId })
  • Terminal creates/opens the order detail in the split pane and refreshes the booking list
  • order detail recognizes the source by bookingPriceId or bookingPriceStorageId

Permissions And Guards

AreaCondition
See Booking Price menuMENU_BOOKING.has(deptCode) or admin/full non-main warehouse access
menu dept codes-2, 1, 2, 3, 4, 7, 8, 9, 13, 16, 20, 21, 22, 23, 27, 29
Home create shortcutsame create-order shortcut set (CAN_CREATE_ORDER) or full non-main warehouse access
Create from list/detailmust pass canCreateSalesOrder
Delete from listowner of DRAFT, or DRAFT/NEW where user is admin, override user, dept 8, or dept 22
delete override users008045, 012521, 012508, 008051, 012388, 012428, 008060
Edit items in detailsame created day and owner/override rules based on status
Convert to sales orderbooking price has id, status is DRAFT, current user is owner, and there is at least one item

Status edit rules:

  • DRAFT: owner can edit items on the created day
  • NEW: requires override rights such as fillWeight or editPrice
  • DONE, CANCELED, DELETED: locked
  • documents past their created day disable add/edit/delete item, remark/header edit, and save

Difference From Sales Order

TopicBooking PriceSales Order
Purposereserve price and stock firstcreate an order for invoice/payment
Next documentconvert to ordercreate invoice and open payment
main statusesDRAFT, NEW, DONE, CANCELED, DELETEDDRAFT, NEW, WAITING_PAYMENT, CONFIRMED, ...
item step pricestores currentStepPrice snapshot/fallbackreceives currentStepPrice from booking or product picker
editing booking-origin itemedit before conversionafter conversion, quantity can be reduced; the order uses currentStepPrice for step-price matching and falls back to base price
historical editstricter created-day guarddepends on order action state/status
stock checkuses onHand - bookingQtyuses available stock and order item rules

Mobile vs POS Terminal

TopicMobilePOS Terminal
Navigationstack: BookingPriceList -> CustomerList -> BookingPriceDetailsplit-pane: menu, list/customer picker, detail
Product pickerMobile picker/screen flowfull-screen modal host in BookingProductPicker
Add/edit itemoverlay inside product picker flowsingle overlay in modal host to avoid nested native modals on iOS
created-day guardserver date when availableGET /api/healthz, fallback device date
conversionreplace to OrderDetailopen order detail in panel and refresh list

Developer Handoff Map

JobMobilePOS Terminal
listapps/mobile/src/screens/bookingPriceStack/bookingPriceListScreen/index.tsxHomeScreen/index.tsx, ListPane.tsx
detailapps/mobile/src/screens/bookingPriceStack/bookingPriceDetailScreen/index.tsxBookingPriceDetailForm.tsx
product pickerdetail screen logicBookingProductPicker.tsx
payload helpersdetail screen helpersHomeScreen/helpers.ts
serviceapps/mobile/src/services/bookingPrice.tsapps/pos-terminal/src/services/bookingPrice.ts
shared typesapps/mobile/src/types/bookingPrice.tspackages/types/src/bookingPrice.ts
order receiving booking dataorderDetailScreen/index.tsxOrderDetailForm.tsx