toga-ai 1.0.417 → 1.0.418
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,8 +6,8 @@ project: _Underscore
|
|
|
6
6
|
client: compass-usa
|
|
7
7
|
type: client-feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-07-
|
|
10
|
-
owners: ["apeterson", "dfranks"]
|
|
9
|
+
updated: 2026-07-23
|
|
10
|
+
owners: ["apeterson", "dfranks", "bala"]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/Model/Compass/ApprovalDecision.php
|
|
13
13
|
- _underscore/Model/Compass/SalesOrder.php
|
|
@@ -50,11 +50,35 @@ tenants differ, the **parent** branches on `$api->client->clientIdentifier === '
|
|
|
50
50
|
- **Email-template resolution** — `resolveEmailTemplateUuid()` picks the tenant's template UUID.
|
|
51
51
|
- **EN/FR localization** — user language is read from `UserGlobalSettings` (`settingId = 2`;
|
|
52
52
|
`en` / `fr-CA`) so Canadian notifications go out in the recipient's language.
|
|
53
|
+
- **Web-link host resolution** — `_Model_Compass_SalesOrder::resolveSupplyHost()` /
|
|
54
|
+
`resolveCommerceHost()` pick the tenant's supply/commerce domain for the links embedded in
|
|
55
|
+
approval and order-status emails (see below).
|
|
53
56
|
|
|
54
57
|
Because the divergence is a runtime branch and not an override, do **not** add per-client logic to
|
|
55
58
|
the empty subclasses — extend the shared parent and branch there if a genuine tenant difference is
|
|
56
59
|
needed.
|
|
57
60
|
|
|
61
|
+
### Email-link host resolution (US vs Canada domains)
|
|
62
|
+
The "Review Order" link (togasupply) and the user order-details link (togacommerce) embedded in
|
|
63
|
+
Compass approval and order-status emails are built from a **client-aware host resolver** on the
|
|
64
|
+
shared parent `_Model_Compass_SalesOrder`, so the link always points at the domain that actually
|
|
65
|
+
holds the order:
|
|
66
|
+
- Four host constants: `HOST_SUPPLY__COMPASS_US = 'compass.togasupply.com'`,
|
|
67
|
+
`HOST_SUPPLY__COMPASS_CANADA = 'compasscanada.togasupply.com'`,
|
|
68
|
+
`HOST_COMMERCE__COMPASS_US = 'compass.togacommerce.com'`,
|
|
69
|
+
`HOST_COMMERCE__COMPASS_CANADA = 'compasscanada.togacommerce.com'`.
|
|
70
|
+
- Public static `resolveSupplyHost(&$api)` / `resolveCommerceHost(&$api)` return the correct host;
|
|
71
|
+
private static `isCompassCanadaClient(&$api)` returns
|
|
72
|
+
`($api->client->clientIdentifier ?? '') === 'Compass_Canada'`. Anything not Canada falls back to
|
|
73
|
+
the **US** host, so US behavior is unchanged.
|
|
74
|
+
- All 8 link-building sites build the URL as `"https://" . resolveSupplyHost($api) . "/?..."` (only
|
|
75
|
+
the host varies; the query string / uuid is identical). Sites wired: `ApprovalDecision.php` —
|
|
76
|
+
manager-approval-request block and VIP auto-approve block (`orderUrl` + `userOrderUrl` in each);
|
|
77
|
+
`SalesOrder.php` — admin-approved block (`postPut`), in-transit/delivered block, and
|
|
78
|
+
`_sendVipManagerNotification`.
|
|
79
|
+
- This reuses the **same `$api->client->clientIdentifier` signal** as the email-template language
|
|
80
|
+
resolver, so the link host and the email template can never disagree.
|
|
81
|
+
|
|
58
82
|
### VIP manager auto-approve — the rule and its three (all supervisor-derived) triggers
|
|
59
83
|
A single rule governs VIP auto-approve: a **manager-stage (step 2)** approval auto-approves iff the
|
|
60
84
|
assigned manager's `Users.c_isVip = 1` **AND** the order subtotal
|
|
@@ -114,8 +138,25 @@ requester**. All of these comparisons are case-insensitive (`strcasecmp()`), mat
|
|
|
114
138
|
requester/new-manager guards.
|
|
115
139
|
- **Don't put tenant behavior in the empty subclasses.** `Usa`/`Canada` `ApprovalDecision` are
|
|
116
140
|
intentionally empty; the tenant branch lives in the parent on `clientIdentifier`.
|
|
141
|
+
- **Never hardcode the web host in email links.** The email links previously used string literals
|
|
142
|
+
`compass.togasupply.com` / `compass.togacommerce.com` in the parent classes. Because the tenant
|
|
143
|
+
subclasses are empty, **Compass Canada orders inherited the US links** and sent Canada
|
|
144
|
+
recipients to the US supply/commerce site, which does not contain their order — so the link never
|
|
145
|
+
opened. Always build the host via `_Model_Compass_SalesOrder::resolveSupplyHost()` /
|
|
146
|
+
`resolveCommerceHost()`, never a literal. Real incident: order SAC100650 — manager Gary Berenz
|
|
147
|
+
could not open the order from the "Manager Approval Needed" email, so admin Kai Wong had to
|
|
148
|
+
approve as manager on his behalf. (Fixed 2026-07-23.)
|
|
117
149
|
|
|
118
150
|
## Change history
|
|
151
|
+
- 2026-07-23 — Fixed Compass approval/status **email links** being hardcoded to the US domains
|
|
152
|
+
(`compass.togasupply.com` / `compass.togacommerce.com`) in the parent classes, so Compass Canada
|
|
153
|
+
orders (empty `Canada` subclass) inherited US links and Canada recipients were sent to a site
|
|
154
|
+
without their order. Added a client-aware host resolver to `_Model_Compass_SalesOrder` (four
|
|
155
|
+
`HOST_*` constants, `resolveSupplyHost()`/`resolveCommerceHost()`, `isCompassCanadaClient()`
|
|
156
|
+
branching on `clientIdentifier === 'Compass_Canada'`, US fallback), and rewired all 8 link sites
|
|
157
|
+
in `ApprovalDecision.php` and `SalesOrder.php` to build the host through it — reusing the same
|
|
158
|
+
`clientIdentifier` signal as the email-template resolver so host and template always agree.
|
|
159
|
+
Verified both client contexts resolve correctly; `php -l` clean. Prod incident SAC100650. (bala)
|
|
119
160
|
- 2026-07-17 — Documented the VIP manager auto-approve rule (VIP manager + subtotal ≤ $5000) and
|
|
120
161
|
its three supervisor-derived triggers (`postPost` creation, `postPut` contact change,
|
|
121
162
|
`handleManagerReassignment` on `postPut`), plus the **POST-path gap**: a requester with no
|
package/package.json
CHANGED