punchout-simulator 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -6
- package/dist/server/cli.js +287 -61
- package/dist/web/assets/{cssMode-uoWbxmRA.js → cssMode-CJ0pl8aC.js} +1 -1
- package/dist/web/assets/{freemarker2-DNR9Witk.js → freemarker2-2fJlciUR.js} +1 -1
- package/dist/web/assets/{handlebars-Cz4BZbpY.js → handlebars-5dZcbLn3.js} +1 -1
- package/dist/web/assets/{html-B08afy-k.js → html-DGPPwllN.js} +1 -1
- package/dist/web/assets/{htmlMode-DwllrnDj.js → htmlMode-DtXuV7Ej.js} +1 -1
- package/dist/web/assets/{index-DLIyRG88.css → index-B2TOY2Lh.css} +1 -1
- package/dist/web/assets/{index-BzgSetIt.js → index-BBqxMuv9.js} +190 -188
- package/dist/web/assets/{javascript-CSO3Lh8M.js → javascript-FH1B7R5g.js} +1 -1
- package/dist/web/assets/{jsonMode-BQc0D6l3.js → jsonMode-CV67hBvi.js} +1 -1
- package/dist/web/assets/{liquid-D_Cq8kS0.js → liquid-DdRsn7Vl.js} +1 -1
- package/dist/web/assets/{mdx-9UNHMbIw.js → mdx-Dovg1GA1.js} +1 -1
- package/dist/web/assets/{python-BziTtpp-.js → python-CzgcLU_4.js} +1 -1
- package/dist/web/assets/{razor-CqSSZBI0.js → razor-DCGsvo9Y.js} +1 -1
- package/dist/web/assets/{tsMode-BXILR9lc.js → tsMode-gs0Re4an.js} +1 -1
- package/dist/web/assets/{typescript-lG76zlZP.js → typescript-D_0DkNkW.js} +1 -1
- package/dist/web/assets/{xml-D1mrwtCd.js → xml-DOUouEEo.js} +1 -1
- package/dist/web/assets/{yaml-DWKj4dJQ.js → yaml-Co8k5eYC.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,8 +99,8 @@ Document-specific:
|
|
|
99
99
|
| Document | Checks |
|
|
100
100
|
|---|---|
|
|
101
101
|
| **PunchOutSetupResponse** | `Status` present & `200`; valid `StartPage/URL` |
|
|
102
|
-
| **PunchOutOrderMessage** (punchback) | `BuyerCookie` matches the session; header `Total`/`Money`+currency; each `ItemIn` has quantity, `SupplierPartID`, `UnitPrice`+currency, `Description`, `UnitOfMeasure`, `Classification`@domain; **Total consistency** (sum of line totals) |
|
|
103
|
-
| **OrderRequest** | `orderID`/`orderDate`/`Total`; `ShipTo`/`BillTo`; each `ItemOut`; **attachment `cid:` resolution** (see below) |
|
|
102
|
+
| **PunchOutOrderMessage** (punchback) | `BuyerCookie` matches the session; header `Total`/`Money`+currency; each `ItemIn` has quantity, `SupplierPartID`, `UnitPrice`+currency, `Description`, `UnitOfMeasure`, `Classification`@domain; **single currency** (mixed-currency is an error unless the supplier allows it); **Total consistency** (sum of line totals) |
|
|
103
|
+
| **OrderRequest** | `orderID`/`orderDate`/`Total`; `ShipTo`/`BillTo`; each `ItemOut`; **single currency** (as above); **attachment `cid:` resolution** (see below) |
|
|
104
104
|
| **OrderResponse** | `Status` code present / not an error |
|
|
105
105
|
|
|
106
106
|
> Note: full cXML DTD validation would require a native validating XML parser,
|
|
@@ -167,7 +167,7 @@ backend, so there is no CORS between them).
|
|
|
167
167
|
| XML parsing | `fast-xml-parser` |
|
|
168
168
|
| cXML building | template literals (full control over shape/ordering/`xml:lang`) |
|
|
169
169
|
| multipart/related | hand-assembled (`Buffer` + boundary) |
|
|
170
|
-
| Storage | `lowdb` (`config.json`) for buyers/suppliers/connections/profiles · append-only JSONL per session for logs · separate files for attachments |
|
|
170
|
+
| Storage | `lowdb` (`config.json`) for buyers/suppliers/connections/product-lists/profiles · append-only JSONL per session for logs · separate files for attachments |
|
|
171
171
|
|
|
172
172
|
```
|
|
173
173
|
src/
|
|
@@ -178,15 +178,41 @@ src/
|
|
|
178
178
|
|
|
179
179
|
### Data model
|
|
180
180
|
|
|
181
|
-
The config is normalized into
|
|
181
|
+
The config is normalized into five entities:
|
|
182
182
|
|
|
183
183
|
- **Buyer** — a reusable party holding its own cXML identity (the `From` credential) and an optional **platform profile** reference (see below).
|
|
184
|
-
- **Supplier** — a reusable party holding its cXML identity (`To`) plus its **endpoints** (PunchOut URL, Order URL) and
|
|
185
|
-
- **Connection** — the edge pairing one Buyer with one Supplier. It holds only what is specific to that pair: which side the tool simulates (`mode`), the `sharedSecret`, an optional per-pair Sender identity override (defaults to the buyer's identity), `
|
|
184
|
+
- **Supplier** — a reusable party holding its cXML identity (`To`) plus its **endpoints** (PunchOut URL, Order URL) and the **product lists** it serves as its Mode-B catalog. Endpoints are intrinsic to the supplier — defined once, not per relationship. An optional `allowMixedCurrency` flag relaxes the multi-currency check for this supplier (see below).
|
|
185
|
+
- **Connection** — the edge pairing one Buyer with one Supplier. It holds only what is specific to that pair: which side the tool simulates (`mode`), the `sharedSecret`, an optional per-pair Sender identity override (defaults to the buyer's identity), `deploymentMode`, and `attachmentEncoding`.
|
|
186
|
+
- **Product List** — a reusable, named set of catalog products. Assigned to one or more Suppliers; each supplier serves the **union** of its lists as its mock catalog. See below.
|
|
186
187
|
- **Profile** — a reusable **procurement-platform profile** (Ariba/Coupa/Jaggaer/…) referenced by a Buyer. See below.
|
|
187
188
|
|
|
188
189
|
At send time: `From` = buyer identity, `To` = supplier identity, `Sender` = the connection's override (or the buyer), and the request targets the supplier's endpoints. The mock-supplier endpoints are keyed by supplier id (`/sim/<supplierId>/…`).
|
|
189
190
|
|
|
191
|
+
### Product lists (Mode-B catalogs)
|
|
192
|
+
|
|
193
|
+
A **Product List** is a named set of catalog items, edited on its own and assigned to one or
|
|
194
|
+
more Suppliers from the **Products** tab. In Mode B a supplier serves the union of its assigned
|
|
195
|
+
lists; a supplier with no lists falls back to a small built-in demo catalog. A built-in
|
|
196
|
+
**Sample assortment** (~20 office/industrial items) ships out of the box and can be **loaded
|
|
197
|
+
into the editor** as a starting point. You can also **import a CSV** (a header row, any column
|
|
198
|
+
order; `SupplierPartID` required) to bulk-load a real catalog — a template is downloadable from
|
|
199
|
+
the editor. Recognized columns: `SupplierPartID`, `SupplierPartAuxiliaryID`, `Description`,
|
|
200
|
+
`UnitPrice`, `Currency`, `UoM`, `UNSPSC` (or a `Classifications` column as
|
|
201
|
+
`UNSPSC:31161500;eCl@ss:27-06`), `ManufacturerPartID`, `ManufacturerName`, `AllowFractional`.
|
|
202
|
+
|
|
203
|
+
Each product carries a `SupplierPartID`, an optional `SupplierPartAuxiliaryID`, description, unit
|
|
204
|
+
price + currency, unit of measure, manufacturer info, and **one or more `Classification`** entries
|
|
205
|
+
(each with its own `domain`, e.g. `UNSPSC` plus a supplier scheme like `eCl@ss`). A product may opt
|
|
206
|
+
into **fractional order quantities** (e.g. `1.5` m of cable) via its `allowFractional` flag — the
|
|
207
|
+
Mode-B catalog then accepts decimals for that item; all other items stay whole-number. These fields
|
|
208
|
+
flow through to the punchback (`ItemIn`) and the resulting OrderRequest (`ItemOut`).
|
|
209
|
+
|
|
210
|
+
**Currency.** A cXML `Total` is a single `Money`, so a document is expected to be single-currency.
|
|
211
|
+
If a cart/order spans more than one currency the mock supplier emits `Total` `0` (rather than a
|
|
212
|
+
meaningless cross-currency sum) and validation raises a `mixed-currency` **error**. A supplier that
|
|
213
|
+
genuinely handles multi-currency orders can set **`allowMixedCurrency`**, which downgrades that to a
|
|
214
|
+
non-blocking **warning** (the per-line `Money` currencies are always preserved either way).
|
|
215
|
+
|
|
190
216
|
### Simulating different procurement platforms (Buyer profiles)
|
|
191
217
|
|
|
192
218
|
Real procurement systems emit cXML differently. A **Profile** captures a platform's
|
|
@@ -218,6 +244,7 @@ cxml-urlencoded) — i.e. the tool's original behavior.
|
|
|
218
244
|
|
|
219
245
|
- `*/api/buyers`, `*/api/suppliers` — CRUD for the reusable parties
|
|
220
246
|
- `*/api/profiles` — CRUD for procurement-platform profiles · `GET /api/profile-presets` — the built-in preset library
|
|
247
|
+
- `*/api/product-lists` — CRUD for product lists · `GET /api/product-list-presets` — the built-in sample library
|
|
221
248
|
- `*/api/connections` — CRUD for connection edges (reference a buyer + supplier)
|
|
222
249
|
- `GET /api/connections/:id/setup/preview` · `POST …/setup` — preview / send the SetupRequest
|
|
223
250
|
- `POST /api/connections/:id/order/preview` · `POST …/order` — preview / send the OrderRequest (multipart if attachments)
|