Clinic Shipment Order Builder
Add locations and manage products for each shipping destination
No locations added
Add locations to start building orders
Order Summary
Last batch was sent to ShipStation. — use only if you intend to submit again (duplicates are possible).
ShipStation orders
One list of orders and tracking for this deployment (including sends from other signed-in users). Refresh tracking updates tracking from ShipStation. When webhooks are enabled on the server, this tab can pick up tracking from the webhook cache while it’s open.
Line items for Build PO are saved when you send from Build orders. Build PO downloads the Zenoti Excel immediately (vendor V1, center + date PO code) without leaving this tab. A green check in the PO column means that order already had a PO generated. Use Build PO markers below to mark many orders at once for a date range.
No ShipStation order history yet. After anyone sends to ShipStation from Build orders, orders appear here — or use to load a sample order, then Refresh tracking.
| Order # | Location | Sent by | Status | Tracking | Last update | PO | Build PO |
|---|
Settings
Product catalog, clinic list (Zenoti codes and Zipline), and optional tests for ShipStation and SES.
Product catalog
Use Edit to change SKU, name, or Zenoti code (optional; if blank, Zenoti uses SKU with spaces removed). Optional zenotiCode and per-SKU vendor (vendorCode) and retail / consumable (zenotiPoChannel) live in deployable products.json. The app loads the bundled list from https://files.slc.skin/products.json first, then same-origin products.json if that fails. Per-browser overrides save to localStorage.
When Zenoti PO Creator is enabled: Vendor ID and Retail / consumable drive ShipStation → Build PO and Excel export. Regenerate vendor tags with node scripts/generate-public-products.mjs.
| SKU | Name | Zenoti code | Vendor ID | Retail / consumable |
|---|
Clinics
Zenoti center codes come from the hub clinic feed (or bundled clinics.json). The same codes appear as suggestions when you type in Zenoti PO Creator → Center code.
By clinic
| Clinic | Zenoti center | Zipline label | Zipline workflow emails |
|---|
District lists
| Label |
|---|
Testing
Optional checks for ShipStation API lookup and SES incoming-shipment email. Not needed for day-to-day ordering.
Sample order for tracking lookup
Adds sample order # 20260408-1109-Westport to the saved list on the ShipStation orders tab. Use Refresh tracking there to load live data from ShipStation when that order exists in your account.
Incoming shipment email (SES)
Runs the same Incoming Shipment Notification path as a real tracking update. Delivery goes to SES_TRACKING_TEST_TO (default brian.taniyama@skinlaundry.com); the message body includes which address production would use from clinic-notification-emails.json. Uses a unique synthetic order # (TESTMSG-…); does not call ShipStation. Requires SES_TRACKING_NOTIFICATIONS, SES_FROM_EMAIL, and IAM ses:SendEmail (mapping optional if SES_TRACKING_EMAIL_TEST_OVERRIDE is set for non–test-button flows).
Zenoti PO Creator
Download an Excel Purchase Order for Zenoti import. Product codes come from Settings → Product catalog (or SKU without spaces). Center codes match Settings → Clinics. Vendor defaults to V1 (editable header); each product can set a Vendor ID in the catalog to override the header for that row in the export. ShipStation orders → Build PO downloads the file immediately (same rules); use this tab to adjust and re-download.
Export rules
- PurchaseOrderCode and CenterCode apply to every row. VendorCode per line uses
products.jsonvendorCodewhen set (V1 / V0 / …), then the Zenoti header field, then V1. Settings → Product catalog can still override vendor per SKU in this browser. - Leave Retail or Consumable blank for unused columns — do not enter 0.
- VendorCode, CenterCode, and ProductCode: letters and numbers only (no spaces). Column order matches the Zenoti template.
Center code: type for suggestions from Settings → Clinics.
| Product | SKU · Zenoti Product Code | Vendor ID | Retail Qty | Consumable Qty |
|---|