jaz-cli 2.0.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.
@@ -0,0 +1,130 @@
1
+ ---
2
+ name: conversion
3
+ version: 2.0.0
4
+ description: Accounting data conversion skill — migrates customer data from Xero, QuickBooks, Sage, and Excel exports to Jaz. Covers full and quick conversion workflows, Excel parsing, CoA/contact/tax mapping, clearing accounts, TTB, and TB verification.
5
+ ---
6
+
7
+ # Jaz Conversion Skill
8
+
9
+ You are performing an **accounting data conversion** — migrating a customer's financial data from their previous accounting software (Xero, QuickBooks, Sage, or Excel-based systems) into Jaz.
10
+
11
+ **This skill provides conversion domain knowledge. For API details (field names, endpoints, gotchas), load the `jaz-api` skill alongside this one.**
12
+
13
+ ## When to Use This Skill
14
+
15
+ - Analyzing customer-provided Excel/CSV files for conversion
16
+ - Mapping source Chart of Accounts, contacts, tax codes, or items to Jaz
17
+ - Creating conversion transactions (invoices, bills, journals)
18
+ - Building or reviewing TTB (Transfer Trial Balance) entries
19
+ - Verifying post-conversion Trial Balance accuracy
20
+ - Troubleshooting TB mismatches after a conversion
21
+
22
+ ## Two Conversion Types
23
+
24
+ Both types use the **same pipeline** — only the scope (which entity types) differs.
25
+
26
+ ### Quick Conversion (Option 2 — recommended starting point)
27
+ - **Scope:** Open AR/AP at FYE + TTB opening balances
28
+ - **Creates:** CoA, contacts, currencies, tax mapping, conversion invoices/bills, TTB journal, lock date
29
+ - **When:** Customer wants to start fresh on Jaz with correct opening balances
30
+ - **Accuracy check:** TB at FYE must match between source and Jaz
31
+ - **See:** `references/option2-quick.md`
32
+
33
+ ### Full Conversion (Option 1)
34
+ - **Scope:** ALL transactions for FY + FY-1 (complete history)
35
+ - **Creates:** Everything in Quick + items, detailed invoices, bills, payments, journals, credit notes, cash-in/out/transfers, bank records, fixed assets
36
+ - **When:** Customer needs full audit trail preserved
37
+ - **Accuracy check:** TB at multiple dates, plus detailed ledger comparison
38
+ - **See:** `references/option1-full.md`
39
+
40
+ ## Conversion Pipeline
41
+
42
+ Every conversion follows this pipeline. Steps 1-3 use the parser + AI. Steps 4-8 use the jaz-api skill.
43
+
44
+ ### Step 1: Intake
45
+ Receive customer files. Organize by type. Expect messy Excel files with grouped sections, merged cells, subtotals, and inconsistent formatting.
46
+
47
+ **Common file types:**
48
+ - Chart of Accounts (CoA export)
49
+ - Trial Balance (TB at FYE)
50
+ - AR Aging / AP Aging (outstanding receivables/payables at FYE)
51
+ - Contact list (customers and suppliers)
52
+ - Tax profile list
53
+ - Exchange rates (closing rates at FYE)
54
+ - General Ledger detail (for Full only)
55
+ - Invoice/bill detail (for Full only)
56
+
57
+ ### Step 2: Parse (3-pass approach)
58
+ See `references/file-analysis.md` for parsing guidance and `references/file-types.md` for the comprehensive file type catalog (22 types across all source systems).
59
+
60
+ **Pass A — Raw dump:** Run the parser (`parseFile()`) to extract all cells + merge metadata from Excel files. The parser handles merged cell propagation automatically.
61
+
62
+ **Pass B — AI structure detection:** Read the raw JSON dump and identify:
63
+ - Where are the data tables? (header row + data rows)
64
+ - What are subtotal/total rows? (exclude from data extraction)
65
+ - What is metadata vs actual data? (company name, report date = metadata)
66
+ - Are there multiple data frames per sheet? (some exports have AR and AP on same sheet)
67
+
68
+ **Pass C — AI classification:** For each identified data table:
69
+ - What type of data is this? (TB, AR aging, AP aging, CoA, contacts, etc.)
70
+ - What are the column headers mapped to? (Account Code, Account Name, Debit, Credit, etc.)
71
+ - What date range does it cover?
72
+ - What currency is it in?
73
+
74
+ ### Step 3: Map
75
+ See `references/mapping-rules.md` for detailed rules.
76
+
77
+ For each entity type, map source data → Jaz entities:
78
+ - **CoA:** Match by code AND name. Fresh org = replace non-system accounts. Existing org = fuzzy match.
79
+ - **Contacts:** Match by name. Create if not found.
80
+ - **Tax:** Read-only in Jaz — discover existing profiles, match source codes to Jaz tax types.
81
+ - **Currencies:** Enable required currencies, set FYE exchange rates.
82
+
83
+ Assign confidence scores (high/medium/low) to each mapping. Flag low-confidence for human review.
84
+
85
+ ### Step 4: Transform
86
+ Convert mapped data into Jaz API payloads. Different per conversion type:
87
+ - **Quick:** See `references/option2-quick.md` — clearing account pattern
88
+ - **Full:** See `references/option1-full.md` — detailed transaction creation
89
+
90
+ ### Step 5: Dry Run
91
+ Before any API calls, present a summary for human review:
92
+ - Entity counts (how many of each type will be created)
93
+ - CoA mapping table (source → Jaz, with confidence)
94
+ - Contact list to be created
95
+ - For Quick: each conversion invoice/bill (contact, amount, currency)
96
+ - Edge cases flagged (FX, unmapped accounts, partial payments)
97
+
98
+ **Do NOT project a Trial Balance.** TB comes from the ledger after execution. Projecting it is unreliable and misleading.
99
+
100
+ ### Step 6: Execute
101
+ Create records via Jaz API. Follow the dependency order:
102
+ 1. Currencies (must exist before CoA with foreign currency)
103
+ 2. CoA (must exist before transactions reference accounts)
104
+ 3. Contacts (must exist before invoices/bills reference them)
105
+ 4. Tax profiles (read-only — just discover and map)
106
+ 5. Transactions (invoices, bills, journals)
107
+ 6. Payments (must reference existing invoices/bills)
108
+
109
+ ### Step 7: Verify
110
+ After execution, pull the Trial Balance from Jaz and compare against the source TB.
111
+ See `references/verification.md` for the full checklist format.
112
+
113
+ ### Step 8: Triage (if TB doesn't match)
114
+ If TB doesn't match, identify the discrepancy:
115
+ - Missing accounts? → Create them + journal adjustment
116
+ - Rounding drift? → Small adjustment journal
117
+ - FX differences? → Check rates, may need unrealized gain/loss journal
118
+ - Missed transactions? → Create them
119
+ - Re-verify after each fix until TB matches
120
+
121
+ ## Critical Rules
122
+
123
+ 1. **TTB is a regular journal entry** — Jaz's TTB module is not yet on the API. Create via `POST /journals`. Lock date is set separately via CoA API.
124
+ 2. **Fixed asset transfers use `POST /api/v1/transfer-fixed-assets`** — not the "new asset" endpoint. Preserves accumulated depreciation.
125
+ 3. **Clearing accounts must net to zero** — if they don't, something was missed in the conversion.
126
+ 4. **Never project TB before execution** — verify AFTER, then triage.
127
+ 5. **FYE exchange rates + original dates** — Quick conversion uses original dates (for aging) but explicit FYE rate via `currency: { sourceCurrency, exchangeRate }` on every FX transaction. Prior UGL is in the TTB; explicit rate ensures zero UGL in Jaz. See `references/edge-cases.md`.
128
+ 6. **System-generated CoA accounts cannot be deleted** — discover them via API before attempting a wipe-and-replace.
129
+ 7. **100% accuracy is required** — customer's accountant signs off on TB match. No rounding errors, no missing balances.
130
+ 8. **Always load `jaz-api` skill alongside this one** — this skill has conversion domain knowledge, `jaz-api` has API field names, endpoints, and gotchas.
@@ -0,0 +1,174 @@
1
+ # Edge Cases — FX, Clearing Accounts, Rounding, and More
2
+
3
+ ## Foreign Exchange (FX)
4
+
5
+ ### Setting Org-Level FYE Rates
6
+ Enable currencies and set FYE closing rates before creating any FX transactions:
7
+
8
+ ```
9
+ PUT /api/v1/organization/currencies // Enable currency
10
+ { "currencies": ["USD"] }
11
+
12
+ POST /api/v1/organization-currencies/USD/rates // Set FYE rate
13
+ { "rate": 1.35, "rateApplicableFrom": "2024-12-31" }
14
+ ```
15
+
16
+ **Rate direction:** Jaz uses `functionalToSource` — how many functional currency units per 1 source currency unit. If base = SGD and "1 USD = 1.35 SGD", then `rate = 1.35`.
17
+
18
+ **CRITICAL:** `currencyCode: "USD"` (string) is **silently ignored** by the API — it creates the transaction in base currency. You MUST use the `currency` object form.
19
+
20
+ ### Quick Conversion — Explicit FYE Rate on Transactions
21
+
22
+ FX conversion transactions use **original dates** (for aging) but an **explicit FYE exchange rate** (for zero UGL):
23
+
24
+ ```json
25
+ {
26
+ "valueDate": "2024-06-15",
27
+ "dueDate": "2024-07-15",
28
+ "currency": {
29
+ "sourceCurrency": "USD",
30
+ "exchangeRate": 1.35
31
+ }
32
+ }
33
+ ```
34
+
35
+ The `exchangeRate` field overrides Jaz's rate auto-fetch. This is essential because:
36
+
37
+ 1. **Prior UGL is in the TTB:** The old platform already computed unrealized FX gains/losses up to FYE. That UGL sits in the TTB journal (Unrealized FX Gain/Loss account balance). If conversion invoices used a different rate, Jaz would compute additional UGL — doubling up.
38
+
39
+ 2. **Zero UGL on day 1:** FYE rate = transferred transaction rate → Jaz sees zero unrealized gain/loss from these conversion invoices/bills.
40
+
41
+ 3. **Correct future RGL:** When a payment is recorded against a conversion invoice, Jaz computes realized gain/loss against the FYE rate — which is correct. The balance was already marked-to-market at FYE by the prior platform.
42
+
43
+ 4. **Correct aging:** Original dates preserve the aging schedule (30/60/90/120+ buckets) so the AR/AP aging report in Jaz matches the source.
44
+
45
+ ### Full Conversion — Original Transaction Rates
46
+
47
+ Full conversion uses the **original exchange rate** from each transaction (the rate at the time the invoice/bill was created). If the source provides per-transaction rates, pass them via `exchangeRate`. If not, Jaz auto-fetches ECB rates via the Frankfurter provider based on `valueDate`.
48
+
49
+ ### Unrealized FX Gains/Losses — Quick vs. Full
50
+
51
+ **Quick Conversion:** UGL from the prior platform is captured in the TTB journal. Conversion invoices/bills are recorded at FYE rate with explicit `exchangeRate`, producing zero UGL in Jaz. No separate UGL journals are needed.
52
+
53
+ **Full Conversion:** Replicate any unrealized FX revaluation journals from the source system as manual journals in Jaz, if they fall within the conversion period. These preserve the historical UGL trail.
54
+
55
+ ## Clearing Account Mechanics
56
+
57
+ ### How Clearing Accounts Work
58
+
59
+ **After Phase 2 (conversion invoices/bills):**
60
+ - AR Clearing has a CREDIT balance (from invoice line items)
61
+ - AP Clearing has a DEBIT balance (from bill line items)
62
+
63
+ **After Phase 3 (TTB journal):**
64
+ - TTB debits AR Clearing (for the AR balance amount)
65
+ - TTB credits AP Clearing (for the AP balance amount)
66
+ - Both clearing accounts should now be **exactly zero**
67
+
68
+ ### Debugging Non-Zero Clearing Accounts
69
+
70
+ If AR Clearing ≠ 0:
71
+ ```
72
+ AR Clearing balance = (TTB AR debit) - (sum of all conversion invoice amounts)
73
+ ```
74
+ - **Positive balance:** TTB AR amount > sum of invoices → missing invoices or wrong amounts
75
+ - **Negative balance:** Sum of invoices > TTB AR amount → extra invoices or wrong TB amount
76
+
77
+ Same logic applies for AP Clearing.
78
+
79
+ ### Common Causes
80
+ 1. **Rounding in FX conversions** — functional currency amounts may differ by $0.01-0.02
81
+ 2. **AR aging doesn't match TB** — some aging reports exclude credit balances or include disputed amounts
82
+ 3. **Missing invoices/bills** — some entries in the aging report were missed during creation
83
+ 4. **Different FX rates** — invoice created with a different rate than TTB (should not happen if explicit `exchangeRate` is used on FX transactions)
84
+
85
+ ### Fix
86
+ Create a small adjustment journal to bring the clearing account to zero. Document the reason (e.g., "FX rounding adjustment — $0.02").
87
+
88
+ ## Rounding
89
+
90
+ ### The $0.01 Problem
91
+ Accounting systems often produce rounding differences when converting between currencies. A source TB may show $1,234.57 but the sum of individual conversion invoices totals $1,234.56.
92
+
93
+ **Rules:**
94
+ 1. Always use the source's exact amounts — never round or truncate
95
+ 2. If the source has amounts to more than 2 decimal places, use them as-is (Jaz supports up to 6 decimals on unit prices)
96
+ 3. If a rounding difference exists after all transactions are created, add a small adjustment journal
97
+
98
+ ### Rounding in Tax Calculations
99
+ If the source calculates tax differently from Jaz (e.g., tax per line item vs tax on total), small differences may arise. Create an adjustment journal if needed.
100
+
101
+ ## Partial Payments in AR/AP Aging
102
+
103
+ ### Quick Conversion
104
+ The AR/AP Aging report shows **outstanding amounts only**. Partial payments are already factored in — the aging shows what's still owed.
105
+
106
+ Create conversion invoices/bills for the outstanding amount, not the original amount. Historical payments are not relevant.
107
+
108
+ ### Full Conversion
109
+ Each payment must be linked to its invoice/bill. If a single payment covers multiple invoices, create separate payment records:
110
+
111
+ ```
112
+ POST /api/v1/invoices/<invoice1>/payments
113
+ { "payments": [{ "paymentAmount": 500, "transactionAmount": 500, ... }] }
114
+
115
+ POST /api/v1/invoices/<invoice2>/payments
116
+ { "payments": [{ "paymentAmount": 300, "transactionAmount": 300, ... }] }
117
+ ```
118
+
119
+ ## Credit Balances
120
+
121
+ ### Negative AR (Customer Credit Balance)
122
+ If the AR Aging shows a negative amount for a customer, they have a credit balance (overpayment or unapplied credit note).
123
+
124
+ **Options:**
125
+ 1. Create a customer credit note for the amount
126
+ 2. Create a conversion invoice with negative amount (if the API allows)
127
+ 3. Include in the TTB journal as a credit to AR
128
+
129
+ ### Negative AP (Supplier Credit Balance)
130
+ Same logic — create a supplier credit note or include in TTB.
131
+
132
+ ## System-Generated Accounts
133
+
134
+ When doing a CoA wipe-and-replace on a fresh org:
135
+
136
+ ### Accounts That Cannot Be Deleted
137
+ - **Retained Earnings** — system-controlled, used for year-end close
138
+ - **Unrealized Currency Gain/Loss** — system auto-creates for FX revaluation
139
+ - **Rounding** — system account for rounding adjustments
140
+ - **Bank accounts linked to payment methods** — must unlink first
141
+
142
+ ### Discovery
143
+ ```
144
+ GET /api/v1/accounts
145
+ ```
146
+ Check for `isSystemGenerated: true` or equivalent flag. These must be preserved.
147
+
148
+ ### Strategy
149
+ 1. Map source accounts to system accounts where possible (e.g., source "Retained Earnings" → Jaz's system "Retained Earnings")
150
+ 2. Skip deletion of system accounts
151
+ 3. Create only the accounts that don't already exist
152
+
153
+ ## Void and Rollback
154
+
155
+ If a conversion goes wrong mid-execution:
156
+
157
+ ### For Invoices/Bills
158
+ - `POST /api/v1/invoices/<id>/void` — voids the document (cannot be undone)
159
+ - `DELETE /api/v1/invoices/<id>` — deletes draft invoices only
160
+
161
+ ### For Journals
162
+ - `DELETE /api/v1/journals/<id>` — deletes the journal entry
163
+
164
+ ### For Contacts/Items
165
+ - `DELETE /api/v1/contacts/<id>` — only if no transactions reference them
166
+ - `DELETE /api/v1/items/<id>` — only if no transactions reference them
167
+
168
+ ### For CoA
169
+ - `DELETE /api/v1/accounts/<id>` — only if no transactions reference them
170
+
171
+ ### Rollback Strategy
172
+ 1. Delete in reverse order of creation (payments → transactions → contacts → CoA)
173
+ 2. Some entities may be undeletable if they have dependencies
174
+ 3. In worst case, voiding is always available for transactions
@@ -0,0 +1,120 @@
1
+ # Analyzing Excel Accounting Reports
2
+
3
+ ## The Challenge
4
+
5
+ Accounting exports from Xero, QuickBooks, Sage, and generic Excel are messy:
6
+ - **Merged cells** — headers span multiple columns, category labels span rows
7
+ - **Grouped sections** — rows grouped by account type, customer, date range
8
+ - **Subtotals everywhere** — per group, per page, grand totals
9
+ - **Metadata rows** — company name, report title, date range, print date (not data)
10
+ - **Multiple data frames** — some sheets have AR and AP in different sections
11
+ - **Inconsistent formatting** — bold totals, blank separator rows, indented sub-accounts
12
+
13
+ The parser library handles raw cell extraction and merged cell propagation. **You** do the intelligent work of understanding the structure.
14
+
15
+ ## 3-Pass Approach
16
+
17
+ ### Pass A: Raw Dump
18
+ Run the parser to get `ParsedFile` with cells + merge metadata.
19
+
20
+ When reviewing the raw output, note:
21
+ - **Row 0-5:** Usually metadata (company name, report title, date generated)
22
+ - **First row with many populated cells:** Likely the header row
23
+ - **Rows with cells only in column 0-1:** Category labels or group headers
24
+ - **Rows where numeric columns sum to a group total:** Subtotal rows
25
+ - **Blank rows:** Section separators
26
+
27
+ ### Pass B: Structure Detection
28
+ For each sheet, identify:
29
+
30
+ 1. **Header row(s):** The row(s) containing column labels. Look for:
31
+ - Row with the most populated cells
32
+ - Keywords: "Account", "Code", "Name", "Debit", "Credit", "Balance", "Amount", "Contact", "Date", "Reference"
33
+ - Sometimes headers span 2 rows (main header + sub-header)
34
+
35
+ 2. **Data rows:** Rows between header and first total/blank section. Characteristics:
36
+ - Have values in the same columns as headers
37
+ - Account codes are numeric or alphanumeric (e.g., "1000", "4-1000", "GST7")
38
+ - Amounts are numeric (possibly with accounting formatting: parentheses for negatives)
39
+
40
+ 3. **Subtotal/total rows:** Rows to EXCLUDE. Characteristics:
41
+ - Contain keywords: "Total", "Sub-total", "Grand Total", "Net", "Balance"
42
+ - Have values only in amount columns (not in code/name columns)
43
+ - Often preceded or followed by blank rows
44
+ - In merged cell sheets, the label cell often spans multiple columns
45
+
46
+ 4. **Group headers:** Category rows (e.g., "Current Assets", "Revenue"). Characteristics:
47
+ - Text in column 0-1 only, no amounts
48
+ - Often merged across columns
49
+ - Followed by indented data rows
50
+
51
+ 5. **Multiple data frames:** Some exports put different reports on the same sheet:
52
+ - Look for a second header row mid-sheet
53
+ - Blank rows or merged section titles between frames
54
+ - Different column structures in different sections
55
+
56
+ ### Pass C: Classification
57
+ For each identified data table, determine the type. See `references/file-types.md` for the comprehensive catalog of all 22 file types with source-system-specific patterns.
58
+
59
+ Quick reference for the most common types:
60
+
61
+ | Type | Key Indicators |
62
+ |------|---------------|
63
+ | **Trial Balance** | "Debit" + "Credit" columns OR "Balance" column. Account codes + names. No dates per row. |
64
+ | **AR Aging Detail** | Customer names. Aging buckets (Current/30/60/90+). Per-invoice rows. |
65
+ | **AP Aging Detail** | Supplier names. Same aging bucket pattern as AR. |
66
+ | **Chart of Accounts** | Account code + name + type/classification. No balances or dates. |
67
+ | **General Ledger Detail** | Dates + account + source module + description + debit/credit per transaction. Grouped by account. |
68
+ | **Contact List** | Names + addresses/phones/emails. No financial data. |
69
+ | **GL Subledger** | Single control account detail (AR/AP/Intercompany). Sheet within multi-report workbook. |
70
+ | **Platform Export (Jaz)** | CSV with UUIDs, `resource_id`, `jaz.ai` emails. **SKIP — not source data.** |
71
+
72
+ ## Common Source System Patterns
73
+
74
+ ### Xero Exports
75
+ - Clean CSV/Excel exports with consistent headers
76
+ - Account codes are numeric (e.g., "200", "400")
77
+ - Tax codes: "GST on Income", "GST on Expenses", "BAS Excluded", "GST Free"
78
+ - Contact type clearly labeled as "Customer" or "Supplier"
79
+
80
+ ### QuickBooks Exports
81
+ - Often have grouped/indented accounts (sub-accounts indented under parents)
82
+ - May use "Total <category>" rows extensively
83
+ - Account numbers may be optional (some QB setups don't use them)
84
+ - Tax codes vary by region
85
+
86
+ ### Sage Exports
87
+ - Typically clean tabular exports
88
+ - Account codes often in "XXXX" format (4 digits)
89
+ - May include "Nominal Code" + "Nominal Name" columns
90
+ - Tax codes: "T0" (Zero Rated), "T1" (Standard Rate), etc.
91
+
92
+ ### Generic Excel (manual)
93
+ - Most unpredictable format
94
+ - May have custom formulas, conditional formatting
95
+ - Watch for:
96
+ - Hidden rows/columns (SheetJS extracts these)
97
+ - Grouped/outlined rows (collapsed sections)
98
+ - Cross-sheet references (formulas referencing other sheets)
99
+
100
+ ## Amount Parsing
101
+
102
+ Accounting exports use various number formats:
103
+ - `1,234.56` — standard with comma grouping
104
+ - `(1,234.56)` — parentheses = negative (accounting convention)
105
+ - `-1,234.56` — negative sign
106
+ - `1234.56` — no grouping
107
+ - `$1,234.56` — with currency symbol (strip the symbol)
108
+ - Blank or `-` — zero / no value
109
+
110
+ The CSV parser handles these automatically. For Excel files, SheetJS provides the numeric value directly.
111
+
112
+ ## Confidence Scoring for AI Classification
113
+
114
+ When analyzing a sheet, assign confidence:
115
+
116
+ - **High (>80%):** Headers clearly match a known type, data structure is consistent
117
+ - **Medium (50-80%):** Partial match — some expected columns present, some missing or renamed
118
+ - **Low (<50%):** Ambiguous — could be multiple types, or unknown format
119
+
120
+ Flag medium and low confidence for human review before proceeding.