Customer Management handles customer draft creation, editing, address/branch maintenance, and approval before customer data becomes usable as SAP customer master data. It is the write-side flow for customer master changes.
App Entry Points
| App | Target |
|---|
| Mobile | CustomerManagementList -> detail/edit/address screens |
| POS Terminal | customerManagement -> CustomerManagementDetailForm |
Draft Lifecycle
Workflow With Permissions
Data And API Rules
Page-Level Flow And Actions
The draft is not one flat form. Developers must treat profile, addresses, and billable branches as three related resources and refresh the detail after every child mutation.
| Area / action | Conditions and result |
|---|
| Create draft | Available only when customer-management access allows creation; starts a draft and does not create SAP master data immediately. |
| Edit customer data | Save header fields independently from addresses and branch links. Server validation remains authoritative. |
| Add/edit address | Stores address text, address type/context, branch association and latitude/longitude where supplied. Invalid or empty coordinates must not be presented as a usable location. |
| Delete address | Requires confirmation and deletes only the draft-address child. Reload the parent detail afterward. |
| Open map | Enabled only when usable coordinates exist; it is a review action and does not save a location. |
| Add billable branch | Show only branches not already linked to the draft. A branch link means the approved customer can open bills in that branch. |
| Remove billable branch | Deletes the relationship, not the branch and not the customer. |
| Approve/reject | Separate from edit permission. DRAFT shows approve/reject controls. Approval publishes the reviewed draft; rejection keeps a correction path and should include a reason. |
| Retry partial SAP approval | A draft with SAP_PARTIAL shows only Retry approval submission to an approver. It calls POST /customer-draft/:id/retry. |
| Operation | Service |
|---|
| List drafts | getCustomerDrafts -> GET /customer-draft?branchId=... |
| Detail | getCustomerDraftById -> GET /customer-draft/:id |
| Create/update profile | createCustomerDraft, updateCustomerDraft |
| Approve/reject | approveCustomerDraft, rejectCustomerDraft(payload) |
| Retry partial SAP approval | retryCustomerDraft -> POST /customer-draft/:id/retry |
| Draft addresses | createCustomerDraftAddress, updateCustomerDraftAddress, deleteCustomerDraftAddress |
| Draft branch links | createCustomerDraftBranch, deleteCustomerDraftBranch |
Important implementation notes:
- Draft list is selected-branch scoped.
- Approval is separate from saving profile/address data.
- Rejection should include reviewer context/reason in payload where the UI collects it.
- Draft addresses and branch links are child resources; changing the profile does not automatically change children.
- After approval, operational lookup moves to Customers.
SAP B1 Approval Failure And Retry
- A new individual customer is always saved as a draft first. If the user chooses immediate B1 approval and it fails, Mobile shows an error and replaces the edit screen with that draft's detail screen. Back therefore returns to the draft list rather than the old edit form.
- The detail screen reloads the draft after an approval failure before choosing actions from its latest
status.
DRAFT keeps Approve and Reject. SAP_PARTIAL hides those actions and shows Retry approval submission instead.
- A retry uses
POST /customer-draft/:id/retry; on success it reports approval success and exits the detail flow. If it fails, the detail is reloaded again so the available action matches the server status.
Customer Data: Individual vs Legal Entity
Changing person type changes the form and payload, not only the display label.
| Data / behavior | Individual (Individual) | Legal entity (company) |
|---|
| Required name | First name and last name | Company/business/organization name in firstname; lastname is cleared |
| Tax ID | Hidden and cleared from payload | Required, digits only, exactly 13 digits |
| Name limit | Combined first/last name: 200 characters | Organization name: 200 characters |
| Address branch fields | Removed during normalization | Shown on BillTo; choose head office or enter a branch |
| Default BillTo branch | None | Empty branch becomes 00000 / สำนักงานใหญ่ (head office) |
| First save | Can choose immediate B1 approval when approval validation passes | Remains a draft awaiting review; it can still be edited |
| Existing SAP customer | Saved as a change request awaiting Marketing approval | Same change-request flow |
Both types require customer type, acquisition source, delivery type, a 10-digit primary phone, both billing and shipping addresses at approval, and at least one billable branch. A secondary phone is optional but must also be 10 digits when entered. Date of birth, alias and email are optional; the UI converts the selected Buddhist Era birth year to Gregorian year in the payload.
Address Types And Required Fields
| Field / rule | Requirement |
|---|
| Type | Required: BillTo (billing) or ShipTo (delivery). |
| Address name | Required and unique within the same address type for this customer. The same label can exist once in each different type. |
| Core address | Street/house number, subdistrict, district, province and postcode are all required. Address search fills administrative fields and applies Bangkok แขวง/เขต formatting. |
| Landmark | Optional (checkAddressName). |
| Legal-entity BillTo branch | Choose head office, or enter both branch code and name. Code is digits only, max 5, and left-padded to 5 digits. One field without the other is invalid. |
| Individual / ShipTo branch | Branch code and name are cleared on normalization. |
| Route | Required only on ShipTo for route-delivery customers (shippingType = 1); cleared from BillTo. |
| Coordinates | Required for route-delivery ShipTo; both values must be finite, non-zero numbers. GPS, map picker and manual input are supported. |
| Auto-create ShipTo | Available while adding a new non-ShipTo address. Creates a second child, clears branch data, and independently validates duplicate name, route and coordinates. |
Save vs Approval Validation
| Stage | Checks |
|---|
| Save draft | Header fields, phone, legal-entity Tax ID; legal entities require BillTo; route customers require ShipTo with route and coordinates. |
| Approve to B1 | Rechecks the header; requires both BillTo and ShipTo for every customer; validates all six address fields, legal-entity branch pairs, route/coordinates, duplicate address names, and duplicate billable branches. |
| Error output | Shows the first five validation errors and a remaining count; approval API is not called until valid. |
Billable Branch Rules
- A resolvable login branch is prepared as the initial billable branch for a new customer.
- Duplicate branch identities are ignored when adding and rejected during approval.
- The last billable branch cannot be deleted; at least one must remain.
- A billable branch controls which operational branch may issue bills. It is separate from the head-office/branch identity stored on a legal entity's
BillTo tax address.
Permissions And Guards
| Topic | Behavior |
|---|
| Terminal menu key | customerManagement |
| deptCode menu set | -2, 1, 2, 3, 4, 7, 29, 21, 8, 9, 13, 14, 16, 27, 30 |
| Approval flag | approveCustomer on the user enables approval/rejection controls. |
| Branch rule | Available by customer-management menu permission and selected branch. |
Mobile vs POS Terminal
| Topic | Mobile | POS Terminal |
|---|
| Navigation | Multiple stack screens for list/detail/edit/address | Single detail form with sections and modals |
| Address edit | Dedicated address detail screens | Embedded section/actions in CustomerManagementDetailForm |
| Map/location | Mobile can request device location/map helpers | Terminal form includes map/search helper code where available |
| Approval | DRAFT offers approve/reject; SAP_PARTIAL offers retry | Same status-based actions in the split detail form |
Developer Handoff Map
| Area | Code |
|---|
| Mobile stack | apps/mobile/src/screens/customerManagementStack/* |
| Terminal detail | apps/pos-terminal/src/screens/HomeScreen/CustomerManagementDetailForm.tsx |
| Customer services | apps/*/src/services/customers.ts |
| Terminal split data | apps/pos-terminal/src/services/splitMenuData.ts -> customerManagement |
| Permission source | user field approveCustomer and menu deptCode config |