189 lines
7.8 KiB
Python
189 lines
7.8 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.
|
|
""",
|
|
|
|
'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 RECONCILIATION CONTEXT:
|
|
- ADP Receivable tracked on account 1101.
|
|
- ADP invoices have customer portion + ADP portion = total.
|
|
- Government deposits should match ADP invoices.
|
|
""",
|
|
|
|
'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
|