Internal provisioning tool — admin/superuser access only.
Checking sign-in status…
Enter your email and we'll send you a password reset link.
Ninja Van staff (@ninjavan.co emails) sign in with Google only — no reset email is sent. Use the “Sign in with Google” button instead.
Icon comes from this customer's list in the Categories tab.
Units & conversions
Ordering UOM (what branches order in) is required. Supplier UOM = how goods arrive; Accounting UOM = base unit for stock accounting (e.g. grams). Fill the ratios to power the converter.
Product photo (optional)
Compressed to <100 KB on save.
Color tag (optional)
Warehouse assignment (optional)
Pick a warehouse to assign this SKU to it. Rack fields are optional — fill all three to also pin a slot.
Line Items
Email delivery failed — share this link directly with the user:
This field is required.
Filter By
Quick Presets
Custom Range
Quick Presets
Custom Range
Logo
Max 2 MB · PNG / JPG / WebP
Name
Order-number prefix
Leads every order number: PREFIX-BRANCHCODE-YYYYMMDD-001. Applies to orders submitted from now on. Optional.
Ordering days
Ordering days are now set per branch — open a branch in the Branches tab to choose which weekdays that branch may submit orders.
Stock-check schedule
Fulfillment sync pauses automatically on matching days; an admin must lift the hold to resume.
e.g. "1st Saturday" = stock-check on the first Saturday of each month.
Past dates are ignored by the daily sweep automatically.
Holiday calendar
Blocked dates are per-customer. Sundays are always closed. Saturdays are working days (an order placed Saturday targets Monday delivery, SLA = 1 day).
Branches cannot submit orders on these dates (company holidays).
Warehouse cannot pick on these dates; fulfillment target rolls forward (public holidays).
Pre-order window
SKUs flagged Pre-order can only be ordered between these days of the month. They are never out of stock, and the warehouse starts picking the day after the window closes. Leave both blank to disable pre-ordering for this customer.
Capped at 28 so the window never falls off the end of a short month.
Ordering note
Shown below the SLA banner when a branch user is placing an order, and at the top of the area manager's approval queue. Clear to use the default system message on the order screen (the approval queue then shows no note).
Broadcast message
Shown as a banner to all branches under this customer. Clear the field to remove the banner.
TMS integration
Links this customer's fulfillments to a TMS shipper so drivers see the pickup manifest automatically.
Must match the Global Shipper ID in operator.html.
Brands
Free-text list of brands under this customer account (for reference).
Orders placed before the cut-off on a business day are tagged same-day SLA; orders placed after it are tagged next business day.
Type this code into Drop_BranchCode on the TMS route. Letters, digits and hyphens; must be unique. Changing it breaks matching on routes already built with the old code.
Defaults to 12:00 if left blank
Contact details only — no longer used to match TMS drops (branches share numbers). Branch code does that.
Unchecking a day blocks order submission for this branch on that weekday. Leave all checked for no restriction.
Each row is one delivery weekday for this branch: the Day it's delivered, the Route (e.g. NINJA-1) and its stop Seq on that route (1 = first drop). The pick slip prints the next delivery strictly after the order's approval date — e.g. Day WED + Route NINJA-1 → WEDNINJA-1, SEQ 1.
CSV columns: name, brands (optional), tmsShipperId (optional), orderingNote (optional) — header row optional.
Names already in use are skipped. Schedules, holiday calendars and logos are set afterwards from the customer's edit sheet.
Moving a warehouse to another customer does not move the branches already pointing at it.
CSV columns: name, customerName (header row optional; the customer name must match an existing customer exactly).
A name that already exists for the same customer is skipped.
Orders placed before the cut-off on a business day are tagged same-day SLA; orders placed after it are tagged next business day.
CSV columns: name, customerName, warehouseName, orderCutoffTime, mon, tue, wed, thu, fri, sat, sun, branchCode, brands (header row optional; names must match existing records exactly).
orderCutoffTime is HH:MM (optional, defaults 12:00). Ordering-day columns accept 1/0, yes/no, or true/false — leave all seven blank for "every day allowed". branchCode (e.g. BHC-CHA) is required — it links the branch to its TMS delivery drops. brands is the last column (optional) — a branch only sees SKUs of its own brand(s); separate multiple brands with | (e.g. TSJ|TRF); leave blank to see all brands.
CSV columns: skuId (blank = create new, existing ID = update), skuName, customerName, category, isPreOrder (optional, yes/no — blank leaves it unchanged), orderingUnit, supplierUnit (optional), supplierToOrderingQty (optional, positive integer), value (optional), currency (optional, default THB), skuNoExt (optional), weightKg (optional), cbm (optional), warehouseName (optional), rackNumber (optional), rackLevel (optional), locationIndex (optional, positive integer), stockCheckFrequency (optional, monthly/quarterly/annual/not_required — blank leaves it unchanged), batchTracked (optional, yes/no — blank leaves it unchanged). warehouseName alone assigns the SKU to a warehouse; add rackNumber + rackLevel + locationIndex together to also pin a rack slot. Leave all blank to skip. Customer name and warehouse name must match existing records exactly.
Upload a CSV with a single skuId column. Each listed SKU and its cost data will be permanently deleted. Use the SKU export to get valid IDs.
qty is written in — SupplierUnit, OrderingUnit or AccountingUnit. Rows may mix units; each is auto-converted to ordering units (the unit the stock ledger stores and that orders reserve & deduct against) before saving. The Inventory view can then show any unit. A blank qtyUnit is read as OrderingUnit (stored as entered).Upload a CSV with columns customerName, warehouseName, brand, productId, qty, qtyUnit (also accepts the export headers Brand, Product ID, Amount). productId is the SKU's Ext. SKU No.; brand is optional but required when a Product ID is shared across brands within a customer (it picks the right SKU). qtyUnit accepts SupplierUnit / OrderingUnit / AccountingUnit (case-insensitive). The resulting ordering-unit balance is what shows in OMS and what orders deduct against. Customer and warehouse names must match existing records exactly. A SKU missing the conversion ratio needed for its Qty unit is skipped. Export the sheet as CSV (UTF-8) first.
Pick the customer, warehouse and brand, then search the SKU by Ext SKU ID or name, and add / deduct or set an opening / ending balance. The quantity is read in the Qty unit you choose and converted to ordering units before saving. Every change is recorded below with the before → after balance and who made it. Admin only.
Upload a CSV with columns orderId, reference. orderId accepts either the readable order number (e.g. SOL-CTW-20260813-001) or the internal UUID. Each reference must be unique per customer — two different customers may reuse the same reference. A blank reference clears it. The whole file is applied together — if any row is rejected, nothing is changed and the failing rows are listed so you can fix and re-upload.
Writes the role-specific binding doc, sets branch assignments if applicable, and mints custom claims. Re-submitting for the same email updates their binding and claims.
CSV columns: email, role, customerName, branchName (header row optional). Up to 100 users per upload.
role must be branch_user, customer_admin or area_manager (invite roles). branch_user requires branchName — it must match an existing branch under that customer, else the row errors. area_manager is granted all branches of the customer (leave branchName blank). customer_admin ignores branchName. @gmail.com addresses are set up for Google sign-in (no invite); other addresses are emailed a set-password invite. Warehouse staff and admins (Google SSO) use the single-user form.
Changes the address this user signs in with, on the same account. Their role and scope are unchanged. A fresh invite (or Google sign-in, for a @gmail.com address) is sent to the new email, any old invite link is invalidated, and the user is signed out on next token refresh.