toga-ai 1.0.103 → 1.0.104
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.
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
| [Carrier Shipping Labels (UPS/FedEx) & NetSuite Item Fulfillment](features/carrier-shipping-labels.md) | Backend mechanics behind TOGa Supply's Fulfill & Ship: buying a carrier label (UPS/FedEx), persisting it, and creating the NetSuite Item Fulfillment with tracki | _underscore/Model/Client/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Trait/Netsuite/SalesOrder.php, _underscore/Component/Library/NetSuite/NetSuite.php, _underscore/Model/Client/TrackingNumber.php, _underscore/Model/Client/ShippingMethod.php, _underscore/Model.php, _underscore/Cloud.php |
|
|
7
7
|
| [Client Email Template Sending](features/email-template-sending.md) | `_Model_Client_EmailTemplate` sends a stored, client-defined email template by UUID. | _underscore/Model/Client/EmailTemplate.php, _underscore/Model/Client/EmailTemplateOutgoingEmailAddress.php, _underscore/Email.php |
|
|
8
8
|
| [Recursive Item Fulfillments (upstream mirroring)](features/recursive-item-fulfillments.md) | In a multi-tier supply chain a sales order (SO) spawns a purchase order (PO) that becomes another SO downstream, and so on. | _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Client/ItemFulfillmentItem.php, _underscore/Model/Client/ItemFulfillmentItemUnit.php, _underscore/Model/Client/ItemFulfillmentPackage.php, _underscore/Model/Compass/AdvanceShippingNotice.php, dbchanges2/Core/2026-02-13 - 75601 - RecursiveItemFulfillmentCreation.sql, dbchanges2/Core/2026-06-04 - RecursiveItemFulfillmentPut.sql |
|
|
9
|
-
| [Tracking-Number Bridge Migration (ASN / Item Fulfillment / Item Receipt)](features/tracking-number-bridges.md) | Shipment tracking numbers used to live as **scalar FK columns** (`trackingNumberId`, `returnTrackingNumberId`) directly on the lowest-level "unit"/"item" tables | _underscore/Model/Client/AdvanceShippingNoticeItemUnit.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillmentItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Prudential/AdvanceShippingNotice.php, _underscore/Model/Compass/AdvanceShippingNotice.php, _underscore/Trait/Netsuite/ItemFulfillment.php, api2/Component/Api/Cxml/Cxml.php, dbchanges2/Client/2026-06-10 - TrackingNumberBridges.sql, dbchanges2/Core/2026-06-10 - TrackingNumberBridges.sql |
|
|
9
|
+
| [Tracking-Number Bridge Migration (ASN / Item Fulfillment / Item Receipt)](features/tracking-number-bridges.md) | Shipment tracking numbers used to live as **scalar FK columns** (`trackingNumberId`, `returnTrackingNumberId`) directly on the lowest-level "unit"/"item" tables | api2/Component/Api/V2/V2.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnit.php, _underscore/Model/Client/AdvanceShippingNoticeItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillmentItemUnits/TrackingNumber.php, _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Prudential/AdvanceShippingNotice.php, _underscore/Model/Compass/AdvanceShippingNotice.php, _underscore/Trait/Netsuite/ItemFulfillment.php, api2/Component/Api/Cxml/Cxml.php, dbchanges2/Client/2026-06-10 - TrackingNumberBridges.sql, dbchanges2/Core/2026-06-10 - TrackingNumberBridges.sql |
|
|
@@ -6,9 +6,10 @@ project: _Underscore
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-06-
|
|
10
|
-
owners: ["jcardinal"]
|
|
9
|
+
updated: 2026-06-16
|
|
10
|
+
owners: ["jcardinal", "mhammontree"]
|
|
11
11
|
files:
|
|
12
|
+
- api2/Component/Api/V2/V2.php
|
|
12
13
|
- _underscore/Model/Client/AdvanceShippingNoticeItemUnit.php
|
|
13
14
|
- _underscore/Model/Client/AdvanceShippingNoticeItemUnits/TrackingNumber.php
|
|
14
15
|
- _underscore/Model/Client/ItemFulfillmentItemUnits/TrackingNumber.php
|
|
@@ -116,8 +117,25 @@ returnTrackingNumber: {...} }]`, and an IFIU's as `itemFulfillmentItemUnitTracki
|
|
|
116
117
|
- **Deploy coupling:** renames are NOT backward compatible — apply the DB migration and deploy
|
|
117
118
|
`_underscore` + `api2` + `worker` + `library` together. Run the additions/migrations DB file first;
|
|
118
119
|
run the companion `..._DROPS.sql` (and the Core deletes) only after the bridges + app are confirmed.
|
|
120
|
+
- **⚠ Bridge ACL is incomplete — non-Super-User reads get 403 (prod + every client).** The migration
|
|
121
|
+
registers `AclRecordPermissions` for the new bridge records 317–322 (Core §7 = Super User; Client §6b
|
|
122
|
+
= per-client copies of the parent record's perms) but **never creates the
|
|
123
|
+
`AclLogicGroups` → `AclLogicGroupExpressions` → `AclRecordExpressions` chain beneath them.** A 2.0
|
|
124
|
+
record read requires that full chain (`api2/Component/Api/V2/V2.php`, `!$aclLogicGroupsDefined`), so a
|
|
125
|
+
role hitting a bridge route (e.g. `item-fulfillment-tracking-numbers`) gets **403 EZ-1** with DEBUG
|
|
126
|
+
"No ACL Logic Groups defined for ACL Record Permissions". Confirmed in **prod and every client** —
|
|
127
|
+
working analogs (parent 28, ASN bridges 216/217/218) have 1 logic group + 1 expression each; the IF/IR
|
|
128
|
+
bridges 317–322 have **0**. Downstream symptom: nested bridge fields return `null` (TOGa Supply's
|
|
129
|
+
fulfilled-shipments lists shipments but `itemFulfillmentTrackingNumbers` is null → reprint has no
|
|
130
|
+
label). **Fix:** per bridge `AclRecordPermission`, add one `AclLogicGroup` + `AclLogicGroupExpression` +
|
|
131
|
+
`AclRecordExpression` (`slug='all'`, `sqlExpression='1'`) — mirroring how 28 / 216 work. Run in **both**
|
|
132
|
+
`Core` (Super User) **and** each `Client_*` (per-role; `Client_Growrk` fixed on beta this way).
|
|
133
|
+
**Client-DB caveat:** `Records` is a Core-only table, so the client-side `AclRecordExpressions` insert
|
|
134
|
+
must derive record ids from `AclRecordPermissions` (`SELECT DISTINCT recordId ... WHERE recordId IN (...)`),
|
|
135
|
+
**not** join `Records`. This gap belongs back in the migration (Core §7 + Client §6b + blank-client template).
|
|
119
136
|
|
|
120
137
|
## Change history
|
|
138
|
+
- 2026-06-16 — Found + documented the bridge ACL gap: the migration creates bridge `AclRecordPermissions` (317–322) but not their `AclLogicGroups`/`AclLogicGroupExpressions`/`AclRecordExpressions` chain → 403 "No ACL Logic Groups defined" for non-Super-User reads (confirmed prod + all clients). Recorded the `slug='all'`/`sqlExpression='1'` fix for Core + per-client, plus the Client-DB `Records`-table caveat. (mhammontree)
|
|
121
139
|
- 2026-06-10 — Documented the tracking-number bridge migration: scalar FK columns → `*_TrackingNumbers` bridge tables across ASN/IF/IR, ASN unit table rename, packages-table consolidation. (jcardinal)
|
|
122
140
|
|
|
123
141
|
## Related docs
|
|
@@ -6,7 +6,7 @@ project: TOGa Supply
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-06-
|
|
9
|
+
updated: 2026-06-16
|
|
10
10
|
owners: [mhammontree]
|
|
11
11
|
files:
|
|
12
12
|
- toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx
|
|
@@ -40,7 +40,10 @@ GroWrk, June 2026); FedEx + UPS both need verification before prod.
|
|
|
40
40
|
**This is the only place the SO syncs from NetSuite into Toga.**
|
|
41
41
|
2. `/edit-shipment` submit (`onFormSubmit("fulfillAndShip")` in `EditShipmentForm.tsx`):
|
|
42
42
|
- `saveShipment` → POST `/item-fulfillments`, `/tracking-numbers`,
|
|
43
|
-
`/item-fulfillment-
|
|
43
|
+
`/item-fulfillment-tracking-numbers` (the bridge — payload key
|
|
44
|
+
`itemFulfillmentTrackingNumbers`, **not** the old `itemFulfillmentPackages`; see the
|
|
45
|
+
`_underscore` tracking-number-bridges doc). The frontend migration to the bridge is prod
|
|
46
|
+
commit `b5c16592d`.
|
|
44
47
|
- `fulfillShipment` → GET `/item-fulfillments/upsShipmentApi` (or `fedexShipmentApi`)
|
|
45
48
|
for the label, then `saveShipmentToNetsuite` →
|
|
46
49
|
GET `/item-fulfillments/createNetsuiteItemFulfillment`.
|
|
@@ -91,6 +94,29 @@ likely moves to the backend.
|
|
|
91
94
|
`hostname LIKE '%ups.com%'`, `responsePayload`).
|
|
92
95
|
- React warning: `setState`-in-render in `ShipmentItemsTable.tsx` (~line 149,
|
|
93
96
|
`clearErrors` inside a `setRowsClicked` updater) — move out of the updater.
|
|
97
|
+
- **Local frontend runs against the *deployed* beta backend.** The dev frontend
|
|
98
|
+
(`growrk.togasupply:5173`) calls `api.beta.togahub.com`, so **any `_underscore` change
|
|
99
|
+
only takes effect after a deploy to beta** — a fix you made locally looks "unfixed" until
|
|
100
|
+
deployed (and a local frontend ahead of the deployed backend produces skew errors, e.g.
|
|
101
|
+
`Unknown named parameter $labelFileInternalId` when the FE passes a param the deployed
|
|
102
|
+
method lacks). When chasing a beta error, confirm what commit is deployed before assuming
|
|
103
|
+
the local code is what ran.
|
|
104
|
+
- **Fulfilled vs pending is driven by `ItemFulfillments.dtSubmitted`** (`ShipmentsApi.ts`
|
|
105
|
+
`getShipments`: fulfilled = `dtSubmitted ne null`, pending = `eq null`). `dtSubmitted` is
|
|
106
|
+
set **only** by `createNetsuiteItemFulfillment` on a successful NetSuite IF creation
|
|
107
|
+
(`Trait/Netsuite/ItemFulfillment.php`). So if the NetSuite step fails, the shipment stays
|
|
108
|
+
on the **pending** page, never the fulfilled one — "no fulfilled shipments" usually means
|
|
109
|
+
the NS step didn't complete, not a UI bug.
|
|
110
|
+
- **`createNetsuiteItemFulfillment` line mapping is fragile on partial/already-fulfilled
|
|
111
|
+
orders.** It `get`s the NetSuite SO and sets the fulfillment `orderLine` = the SO's `line`.
|
|
112
|
+
If a line is already fulfilled (or NetSuite re-sequences the fulfillable sublist because a
|
|
113
|
+
line isn't committed), NetSuite returns **"Unable to find a matching line for sublist item
|
|
114
|
+
with key: [orderLine] and value: [N]"**. Test against an SO line that's genuinely open;
|
|
115
|
+
robust fix = NetSuite `initialize`/`transform` (only exposes fulfillable lines).
|
|
116
|
+
- **Bridge ACL blocks the tracking/label read (reprint).** Reading tracking via the
|
|
117
|
+
`item-fulfillment-tracking-numbers` bridge requires the bridge record's ACL logic-group
|
|
118
|
+
chain to exist for the user's role, or it 403s and `itemFulfillmentTrackingNumbers` returns
|
|
119
|
+
`null` (so reprint has no label). See the tracking-number-bridges doc's ACL gotcha + fix.
|
|
94
120
|
|
|
95
121
|
## Remaining work
|
|
96
122
|
|
|
@@ -112,4 +138,5 @@ not the base `_Model_Client_ItemFulfillment`. Tested with GroWrk; UPS support wa
|
|
|
112
138
|
for Compass and is not yet in prod.
|
|
113
139
|
|
|
114
140
|
## Change history
|
|
141
|
+
- 2026-06-16 — Drove the full beta flow green for UPS/GroWrk. Updated the save step to the `/item-fulfillment-tracking-numbers` bridge (FE commit `b5c16592d`, key `itemFulfillmentTrackingNumbers`). Added gotchas: local-FE↔deployed-beta-BE skew, `dtSubmitted` fulfilled/pending gating, `createNetsuiteItemFulfillment` orderLine fragility on partial/already-fulfilled orders, and the bridge-ACL 403 that nulls tracking/labels (reprint). (mhammontree)
|
|
115
142
|
- 2026-06-10 — Documented the Fulfill & Ship flow (SO sync, label purchase, NetSuite IF creation, success gating, reprint). Driven green on beta for UPS/GroWrk; FedEx + prod verification pending. (mhammontree)
|
package/package.json
CHANGED