toga-ai 1.0.130 → 1.0.131
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.
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
|
|
3
3
|
| Doc | Framework | Summary | Files |
|
|
4
4
|
|-----|-----------|---------|-------|
|
|
5
|
-
| [Credit Card Receipt Processing](features/receipt-processing.md) | 2.0 | Automated processing of credit card receipts uploaded to SharePoint. | worker2/Worker/Client/TowFoundation.php, worker2/Worker/Client/TowFoundation/ProcessReceipts.php |
|
|
5
|
+
| [Credit Card Receipt Processing](features/receipt-processing.md) | 2.0 | Automated processing of credit card receipts uploaded to SharePoint. | worker2/Worker/Client/TowFoundation.php, worker2/Worker/Client/TowFoundation/ProcessReceipts.php, worker2/Worker/Client/TowFoundation/TowFoundationVendors.php |
|
|
6
6
|
| [Tow Foundation](profile.md) | 2.0 | Tow Foundation is a nonprofit client. | |
|
|
@@ -5,11 +5,12 @@ project: Worker
|
|
|
5
5
|
client: tow-foundation
|
|
6
6
|
type: client-feature
|
|
7
7
|
status: active
|
|
8
|
-
updated: 2026-06-
|
|
8
|
+
updated: 2026-06-18
|
|
9
9
|
owners: ["rgirish"]
|
|
10
10
|
files:
|
|
11
11
|
- worker2/Worker/Client/TowFoundation.php
|
|
12
12
|
- worker2/Worker/Client/TowFoundation/ProcessReceipts.php
|
|
13
|
+
- worker2/Worker/Client/TowFoundation/TowFoundationVendors.php
|
|
13
14
|
related:
|
|
14
15
|
- clients/tow-foundation/profile.md
|
|
15
16
|
---
|
|
@@ -23,7 +24,7 @@ Excel file per person, uploads it to SharePoint, and sends a summary email.
|
|
|
23
24
|
|
|
24
25
|
Invocation: `{"action": "Client/TowFoundation/ProcessReceipts/Run", "parameters": {}}`
|
|
25
26
|
|
|
26
|
-
Optional filter parameters: `limit` (int), `year` (string e.g. `"2026"`), `person` (string e.g. `"Brent Peterkin"`).
|
|
27
|
+
Optional filter parameters: `limit` (int), `year` (string e.g. `"2026"`), `person` (string e.g. `"Brent Peterkin"`), `billingCycle` (string — matches the **end** of the billing-cycle folder name, e.g. `"06-03-2026"` matches `"Amex ending in 06-03-2026"`, `"Mastercard ending in 06-03-2026"`, etc.).
|
|
27
28
|
|
|
28
29
|
## Key files / entry points
|
|
29
30
|
|
|
@@ -48,7 +49,7 @@ Credit Card Receipts/
|
|
|
48
49
|
|
|
49
50
|
1. **Auth** — OAuth2 client-credentials token from Microsoft Graph
|
|
50
51
|
2. **Walk** — `walkReceiptsFolder()` enumerates all receipt files and statement Excels
|
|
51
|
-
3. **Filter** — optional `$year` / `$person` / `$limit` applied to the receipt list
|
|
52
|
+
3. **Filter** — optional `$year` / `$person` / `$billingCycle` / `$limit` applied to the receipt list. `$billingCycle` uses `str_ends_with()` so passing just the date (e.g. `"06-03-2026"`) matches any card type. Person folders named `"Brent Peterkin CC receipts"` are normalized to `"Brent Peterkin"` via regex strip of ` CC receipts` suffix before any map lookups.
|
|
52
53
|
4. **Pre-load statements** — all billing-cycle `.xlsx` files under `reports/` are downloaded
|
|
53
54
|
and parsed upfront via PhpSpreadsheet (auto-detect header row by scanning for
|
|
54
55
|
description/amount keywords)
|
|
@@ -59,8 +60,9 @@ Credit Card Receipts/
|
|
|
59
60
|
- Cross-verify amount ± $0.01 against parsed statement; if matched, override `payment_memo` with statement description
|
|
60
61
|
- Build base filename (no suffix yet) and store in `$pendingRenames`
|
|
61
62
|
- On extract failure → move to `Archive/exception/` immediately
|
|
62
|
-
6. **
|
|
63
|
-
7. **
|
|
63
|
+
6. **Deduplication** — after Pass 1, receipts sharing identical `(personName, invoice_date, vendor_name, total)` are deduplicated; only the first is kept, the rest are logged as `DUPLICATE skipped` and dropped. This catches the same receipt uploaded twice to SharePoint.
|
|
64
|
+
7. **Collision detection** — count base name occurrences across remaining pending renames
|
|
65
|
+
8. **Pass 2 — Move** — for each pending rename:
|
|
64
66
|
- If base name appears more than once, assign `_a`, `_b`, `_c`... suffix to **all** colliding files (including the first)
|
|
65
67
|
- PATCH SharePoint to rename + move to `Archive/` (flat — no person subfolder)
|
|
66
68
|
8. **Excel generation** — one `.xlsx` per person (PhpSpreadsheet); columns: Row #, Account Name, QB Vendor, Payment Amount, Date, Payment Method, Payment Memo, QB Description, Class, Category, Payment Account, Ref No.
|
|
@@ -80,6 +82,25 @@ Amex billing cycle runs 3rd-to-3rd. `computeRefNo()` returns the cycle-end date
|
|
|
80
82
|
- Charge on or before the 3rd → cycle ends on the 3rd of the same month
|
|
81
83
|
- Charge after the 3rd → cycle ends on the 3rd of the next month
|
|
82
84
|
|
|
85
|
+
### QB vendor matching
|
|
86
|
+
`TowFoundationVendors.php` holds 2,994 vendor names exported verbatim from Tow Foundation's
|
|
87
|
+
QuickBooks vendor list (June 2026). `matchQbVendor()` runs three passes against this list:
|
|
88
|
+
1. Exact match (case-insensitive)
|
|
89
|
+
2. Substring match — QB name contains extracted name or vice versa (min 4 chars); picks shortest match on multiple hits
|
|
90
|
+
3. `similar_text()` similarity ≥ 80% — picks highest scorer
|
|
91
|
+
|
|
92
|
+
Returns the exact QB vendor string or `''` if no confident match. The AI only extracts
|
|
93
|
+
`vendor_name`; QB matching is done entirely in PHP — no tokens spent per receipt on the list.
|
|
94
|
+
|
|
95
|
+
To update the vendor list: re-export from QuickBooks → run the extraction script →
|
|
96
|
+
replace `TowFoundationVendors.php`. The matching logic is in `matchQbVendor()` and needs no changes.
|
|
97
|
+
|
|
98
|
+
### AI category values
|
|
99
|
+
The AI is prompted to return **specific expense types** — e.g. `"Dining"`, `"Travel"`,
|
|
100
|
+
`"Accommodation"`, `"Transportation"`, `"Office Supplies"`, `"Entertainment"`,
|
|
101
|
+
`"Professional Services"`, `"Subscriptions"`. It must not use broad accounting labels
|
|
102
|
+
like `"Administrative Expenses"`.
|
|
103
|
+
|
|
83
104
|
### Per-person constants
|
|
84
105
|
`CLASS_MAP` and `PAYMENT_ACCOUNT_MAP` in `ProcessReceipts.php` map each cardholder's name
|
|
85
106
|
to their QuickBooks Class and Payment Account strings. Ryan Farrell uses Bank of America
|
|
@@ -133,7 +154,13 @@ Fatal errors send only to `NOTIFY_EMAIL_DEV` (no CC/BCC).
|
|
|
133
154
|
`Credit Card Receipts/3. QB Excel/` (not inside each person's subfolder). This folder
|
|
134
155
|
exists at the root of `Credit Card Receipts/` alongside the person folders.
|
|
135
156
|
|
|
157
|
+
- **Person folder name normalization** — SharePoint folders are named `"Brent Peterkin CC receipts"` but `CLASS_MAP` / `PAYMENT_ACCOUNT_MAP` keys are just `"Brent Peterkin"`. The ` CC receipts` suffix is stripped via regex in `walkReceiptsFolder()`. Without this, Class and Payment Account columns are blank for those persons.
|
|
158
|
+
- **`billingCycle` filter is suffix-match, not exact** — always pass just the date portion (`"06-03-2026"`), not the full folder name. Passing the full name (`"Amex ending in 06-03-2026"`) also works but would miss Mastercard folders.
|
|
159
|
+
- **Ole Mole not in QB vendor list** — as of June 2026 this vendor is not in Tow Foundation's QuickBooks, so `qb_vendor` will be blank for Ole Mole charges until they add it to QB and the vendor list is refreshed.
|
|
160
|
+
- **Duplicate detection is within-run only** — if the same receipt was processed in a prior run and archived, it won't be caught. The dedup only covers receipts present in the current run's `$pendingRenames`.
|
|
161
|
+
|
|
136
162
|
## Change history
|
|
137
163
|
|
|
164
|
+
- 2026-06-18 — QB vendor matching via local fuzzy match against `TowFoundationVendors.php` (2,994 vendors); AI category prompt updated to return specific types (Dining, Travel, etc.); duplicate receipt detection added (person+date+vendor+amount dedup); `billingCycle` filter parameter added (suffix-match — card-type agnostic); person folder ` CC receipts` suffix stripped so CLASS_MAP/PAYMENT_ACCOUNT_MAP resolve correctly (rgirish)
|
|
138
165
|
- 2026-06-12 — QB Excel upload moved to root-level `3. QB Excel/`; Archive/exception folders flattened (no person subfolder); unsupported mime types (`application/octet-stream`) now throw ReceiptProcessingException instead of being silently skipped (rgirish)
|
|
139
166
|
- 2026-06-11 — Added CC (Magdalena), BCC (devteam@togatech.com), per-cardholder Archive subfolders, Excel upload to "3. QB Excel" SharePoint folder, two-pass rename with alphabetical duplicate suffix, rename format changed to `YYYY.MM.DD Full Name_Vendor_Amount` (rgirish)
|
package/package.json
CHANGED