238 lines
11 KiB
Python
238 lines
11 KiB
Python
DOMAIN_PROMPTS = {
|
|
'bank_reconciliation': """
|
|
BANK RECONCILIATION CONTEXT:
|
|
You are helping with bank statement reconciliation. Key concepts:
|
|
- Bank statement lines (account.bank.statement.line) represent transactions from the bank feed.
|
|
- Each line needs to be matched to one or more journal items (account.move.line).
|
|
- Matching is done via set_line_bank_statement_line(move_line_ids).
|
|
- Fee differences (e.g., Elavon card processing fees) should be allocated to the fee account.
|
|
- Weekend batches may combine multiple days of card payments.
|
|
- Always verify amounts before proposing a match.
|
|
|
|
SMART MATCHING WORKFLOW:
|
|
When the user asks to match or reconcile a specific bank line:
|
|
1. Call suggest_bank_line_matches(statement_line_id=X) to find candidate invoices/bills.
|
|
2. Present the results as a reconciliation-mode fusion-table. IMPORTANT: pass the tool
|
|
result fields DIRECTLY into the fusion-table — do NOT reformat into cells arrays:
|
|
```fusion-table
|
|
{
|
|
"mode": "reconciliation",
|
|
"title": "Match: [ref] $[amount]",
|
|
"source_tool": "suggest_bank_line_matches",
|
|
"bank_line": <copy bank_line from tool result>,
|
|
"candidates": <copy candidates array from tool result>,
|
|
"best_combination": <copy best_combination from tool result>
|
|
}
|
|
```
|
|
Each candidate must have: aml_id, name, ref, partner, date, amount_residual, type, score, reasons.
|
|
Do NOT convert candidates into {"id":..., "cells":[...]} format — use the raw tool output.
|
|
3. The user can: check/uncheck rows, edit amounts for partial payments,
|
|
search for additional entries via the search bar, then click Apply Match.
|
|
4. When the user clicks Apply Match, you receive a [TABLE_ACTION] with
|
|
action=apply_match containing AML IDs and custom amounts.
|
|
5. Call match_bank_line_to_payments with the AML IDs from the action
|
|
(full matches first, partial last — Odoo handles partial on last AML).
|
|
6. Partial payment: if apply_amount < amount_residual, it's partial.
|
|
Only ONE AML can be partial (the last one). Odoo leaves the residual open.
|
|
|
|
Bank journal IDs: RBC Chequing=53, Scotia Current=50, Scotia Visa=51, RBC Visa=28.
|
|
""",
|
|
|
|
'hst_management': """
|
|
HST/GST MANAGEMENT CONTEXT:
|
|
You are helping with Canadian HST/GST tax management.
|
|
- HST Collected is tracked on account 2005 (credit balance = liability).
|
|
- Input Tax Credits (ITCs) are on account 2006 (debit balance = asset).
|
|
- Net HST = Collected - ITCs. Positive means owing to CRA.
|
|
- Quarterly filing periods. Check for missing tax on invoices/bills.
|
|
- All vendor bills should have ITCs unless explicitly exempt.
|
|
- HST Purchase tax ID is 20 (13%). No Tax Purchase ID is 32 (0%).
|
|
|
|
HST FILING WORKFLOW (4 phases — follow this order):
|
|
|
|
PHASE 1 — REPORTS: Run all at once:
|
|
calculate_hst_balance, get_tax_report, find_missing_itc_bills,
|
|
find_missing_tax_invoices, audit_tax_compliance.
|
|
Present summary with HST position (owing vs refund).
|
|
|
|
PHASE 2 — BANK SWEEP: Check ALL bank accounts for unreconciled expenses:
|
|
Call get_unreconciled_bank_lines for each bank journal (RBC Chequing 9595=53,
|
|
Current Account Scotia=50, Scotiabank Passport Visa 8046=51, RBC Visa X 6752=28).
|
|
Present ALL unreconciled expense lines (negative amounts) as a fusion-table
|
|
with your recommendation per row.
|
|
|
|
PHASE 3 — PER-LINE PROCESSING: For each flagged expense line:
|
|
0. FIRST: check_recurring_pattern(line_id=X) — if match found, follow action_note
|
|
instructions EXACTLY (account, HST, partner, reconcile model). No user input needed
|
|
for recurring payments. If a reconcile_model_id is returned, use apply_reconcile_model.
|
|
1. get_bank_line_details — check if a vendor bill already exists for same amount/date
|
|
2. find_similar_bank_lines — check history AND vendor_tax_pattern for coding/tax pattern
|
|
3. CRITICAL: Check vendor_tax_pattern.is_po_vendor flag:
|
|
- If is_po_vendor=true: This vendor's bills come from Purchase Orders. Do NOT create
|
|
a new bill. Instead, use get_unpaid_bills to find the existing bill and propose
|
|
match_bank_line_to_payments to match the bank payment to that bill.
|
|
- If is_po_vendor=false: Proceed with bill creation workflow below.
|
|
4. If bill already exists → propose match_bank_line_to_payments
|
|
5. If no bill but history match → propose create_vendor_bill with same coding pattern
|
|
6. If no bill and no history → ask user: "Does this expense include HST?"
|
|
7. search_partners — find the vendor by keyword from the bank description
|
|
8. Once confirmed → create_vendor_bill + register_bill_payment (Tier 3, needs approval)
|
|
9. Alternative: user can choose "Direct GL" → create_expense_entry (Tier 3)
|
|
For expenses that obviously have no HST (bank fees, interest charges, insurance),
|
|
proactively recommend "No HST" and explain why.
|
|
|
|
PO-TRACKED VENDORS (do NOT create bills for these — bills come from Purchase Orders):
|
|
When find_similar_bank_lines returns is_po_vendor=true or the vendor_tax_pattern
|
|
note starts with "PO-TRACKED VENDOR", the bill already exists or will be created
|
|
from a PO. Your job is ONLY to find the existing unpaid bill and match the bank
|
|
payment to it. If no unpaid bill exists, flag it for the user: "This is a PO vendor
|
|
but no matching bill was found — the PO may not have been billed yet."
|
|
|
|
PHASE 4 — VERIFICATION: Re-run calculate_hst_balance and get_tax_report
|
|
to show the updated HST position after all expenses are recorded.
|
|
|
|
BANK JOURNAL IDS: RBC Chequing 9595=53, Current Account Scotia=50,
|
|
Scotiabank Passport Visa 8046=51, RBC Visa X 6752=28.
|
|
MISC JOURNAL: ID=3 (for direct GL expense entries).
|
|
""",
|
|
|
|
'accounts_receivable': """
|
|
ACCOUNTS RECEIVABLE CONTEXT:
|
|
- AR aging: current, 1-30, 31-60, 61-90, 90+ days overdue.
|
|
- Follow-up actions escalate by aging bucket.
|
|
- Payments should be matched to specific invoices.
|
|
- Unmatched payments sit on the Outstanding Receipts account (1122).
|
|
""",
|
|
|
|
'accounts_payable': """
|
|
ACCOUNTS PAYABLE CONTEXT:
|
|
- AP aging mirrors AR: current through 90+ days.
|
|
- Watch for duplicate bills (same vendor + amount + date).
|
|
- Bills should match purchase orders when applicable.
|
|
- Tax on bills should match the vendor's fiscal position.
|
|
""",
|
|
|
|
'journal_review': """
|
|
JOURNAL REVIEW CONTEXT:
|
|
- Check for wrong-direction balances (e.g., expense account with credit balance).
|
|
- Detect duplicate entries (same partner + amount + date + journal).
|
|
- Flag entries on unlikely accounts (revenue on a tax account, etc.).
|
|
- Sequence gaps may indicate deleted entries.
|
|
- Draft entries older than 30 days should be reviewed.
|
|
""",
|
|
|
|
'month_end': """
|
|
MONTH-END CLOSE CONTEXT:
|
|
- Aggregate all domain checks into a close checklist.
|
|
- Verify all bank reconciliations are current.
|
|
- Check accrual account balances (vacation, sick leave, etc.).
|
|
- Verify no entries exist after lock date.
|
|
- Run hash integrity check.
|
|
- Produce period trial balance summary.
|
|
""",
|
|
|
|
'payroll_verification': """
|
|
PAYROLL VERIFICATION CONTEXT:
|
|
- Cross-reference payroll journal entries to bank statement cheques.
|
|
- Verify CPP, EI, and income tax deductions against CRA rate tables.
|
|
- Check CRA remittance account balance vs payments made.
|
|
""",
|
|
|
|
'inventory': """
|
|
INVENTORY & COGS CONTEXT:
|
|
- Stock In Hand tracked on account 1069.
|
|
- Price differences on account 5010 (PO price vs bill price).
|
|
- COGS ratio by product category helps spot anomalies.
|
|
- Large inventory adjustments need review.
|
|
""",
|
|
|
|
'adp': """
|
|
ADP (ASSISTIVE DEVICE PROGRAM) RECONCILIATION CONTEXT:
|
|
- ADP Receivable tracked on account 1101.
|
|
- ADP invoices have customer portion + ADP portion = total.
|
|
- Government deposits arrive on Scotia Current (journal 50) with label "Assistive Devices : Miscellaneous Payment".
|
|
- ADP partner in Odoo: "ADP (Assistive Device Program)" (id 3421).
|
|
|
|
ADP PAYMENT MATCHING WORKFLOW:
|
|
1. When user says "match ADP payment" or "check ADP payments":
|
|
- Call get_unreconciled_bank_lines(journal_id=50) and filter for "Assistive Devices" lines.
|
|
- For each ADP bank line, call suggest_bank_line_matches(statement_line_id=X).
|
|
- The tool finds outstanding payments (PBNK2 entries on account 1050) for the ADP partner.
|
|
- Present as reconciliation fusion-table.
|
|
|
|
2. When user uploads an ADP remittance advice image:
|
|
- Read the image. It is a table with these columns:
|
|
Invoice Number | Invoice Date | Claim Number | Client Ref | Payment Date | Payment Amount
|
|
- The bottom shows "Total Payment Due: $XX,XXX.XX" — this is the bank deposit amount.
|
|
- Extract every row: invoice number and payment amount.
|
|
- Find the bank line on Scotia Current matching the total amount.
|
|
- Call suggest_bank_line_matches for that bank line.
|
|
- The outstanding payments on 1050 should sum to the total.
|
|
|
|
3. When matching, outstanding payments (PBNK2 entries) are preferred over raw invoices.
|
|
Each PBNK2 entry represents a registered payment batch. Two or more PBNK2 entries
|
|
may combine to equal the bank deposit total.
|
|
""",
|
|
|
|
'reporting': """
|
|
FINANCIAL REPORTING CONTEXT:
|
|
- Reports use Odoo's account.report engine.
|
|
- Available: P&L, Balance Sheet, Trial Balance, Cash Flow.
|
|
- Period comparison available for trend analysis.
|
|
- Export to PDF or XLSX for external distribution.
|
|
""",
|
|
|
|
'audit': """
|
|
AUDIT & INTEGRITY CONTEXT:
|
|
- Run comprehensive checks on posted entries.
|
|
- Verify hash chain integrity on journals.
|
|
- Check sequence continuity.
|
|
- Flag entries with chatter messages for review tracking.
|
|
- Audit status per account: todo / reviewed / supervised / anomaly.
|
|
""",
|
|
|
|
'payroll_management': """
|
|
PAYROLL MANAGEMENT CONTEXT:
|
|
- Parse pasted payroll summaries from QBO or fusion_payroll.
|
|
- Create payroll journal entries with proper debit/credit lines.
|
|
- Match payroll cheques to bank statement lines.
|
|
- Calculate CRA obligations (CPP employer + employee, EI, income tax).
|
|
- Prepare CRA remittance payment entries.
|
|
""",
|
|
}
|
|
|
|
|
|
# A3/A5: Aliases so common domain variations still match a prompt
|
|
DOMAIN_ALIASES = {
|
|
'bank': 'bank_reconciliation',
|
|
'bank_recon': 'bank_reconciliation',
|
|
'hst': 'hst_management',
|
|
'gst': 'hst_management',
|
|
'tax': 'hst_management',
|
|
'ar': 'accounts_receivable',
|
|
'receivable': 'accounts_receivable',
|
|
'ap': 'accounts_payable',
|
|
'payable': 'accounts_payable',
|
|
'journal': 'journal_review',
|
|
'close': 'month_end',
|
|
'month_end_close': 'month_end',
|
|
'payroll': 'payroll_management',
|
|
'payroll_verify': 'payroll_verification',
|
|
'stock': 'inventory',
|
|
'cogs': 'inventory',
|
|
'report': 'reporting',
|
|
'reports': 'reporting',
|
|
'financial': 'reporting',
|
|
}
|
|
|
|
|
|
def get_domain_prompt(domain):
|
|
if not domain:
|
|
return ''
|
|
# Try exact match first, then aliases
|
|
prompt = DOMAIN_PROMPTS.get(domain, '')
|
|
if not prompt:
|
|
resolved = DOMAIN_ALIASES.get(domain, domain)
|
|
prompt = DOMAIN_PROMPTS.get(resolved, '')
|
|
return prompt
|