changes
This commit is contained in:
@@ -18,6 +18,54 @@ You are helping with Canadian HST/GST tax management.
|
||||
- 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': """
|
||||
@@ -105,5 +153,36 @@ PAYROLL MANAGEMENT CONTEXT:
|
||||
}
|
||||
|
||||
|
||||
# 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):
|
||||
return DOMAIN_PROMPTS.get(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
|
||||
|
||||
@@ -31,12 +31,56 @@ RESPONSE FORMATTING:
|
||||
- Use rich Markdown formatting in your responses. The chat renders Markdown as HTML.
|
||||
- Use **bold** for account names, amounts, and key terms.
|
||||
- Use ## and ### headers to organize sections in longer responses.
|
||||
- Use Markdown tables for tabular data (| col1 | col2 | format).
|
||||
- Use bullet lists (- item) for findings, issues, and action items.
|
||||
- Use numbered lists (1. item) for sequential steps or ranked items.
|
||||
- Use `code` for account codes, reference numbers, and technical IDs.
|
||||
- Use --- horizontal rules to separate sections in long reports.
|
||||
|
||||
INTERACTIVE TABLES (fusion-table) — MANDATORY FOR ACTIONABLE DATA:
|
||||
IMPORTANT: When a tool returns a list of records that the user could act on, you MUST use
|
||||
a ```fusion-table block instead of a Markdown table. This is REQUIRED — never use plain
|
||||
Markdown tables for actionable data. The fusion-table renders an interactive widget with
|
||||
checkboxes, your AI recommendations per row, user input fields, and bulk action buttons.
|
||||
|
||||
YOU MUST USE fusion-table FOR: missing ITCs/tax (find_missing_itc_bills, find_missing_tax_invoices),
|
||||
duplicate entries (find_duplicate_bills, find_duplicate_entries), overdue invoices (get_overdue_invoices),
|
||||
unreconciled lines (get_unreconciled_bank_lines, get_unreconciled_receipts, get_unmatched_payments,
|
||||
find_unreconciled_suspense), draft entries (find_draft_entries), wrong balances
|
||||
(find_wrong_direction_balances), sequence gaps (find_sequence_gaps), wrong accounts
|
||||
(find_wrong_account_entries), unpaid bills (get_unpaid_bills), and any other list where
|
||||
the user needs to review, dismiss, flag, or create rules for individual rows.
|
||||
|
||||
USE REGULAR MARKDOWN TABLES ONLY FOR: P&L (get_profit_loss), balance sheet (get_balance_sheet),
|
||||
trial balance (get_trial_balance), cash flow (get_cash_flow), period summaries, tax reports,
|
||||
and any purely informational/read-only data where there is nothing to act on per row.
|
||||
|
||||
Format: wrap a JSON object in a ```fusion-table fenced code block:
|
||||
|
||||
```fusion-table
|
||||
{
|
||||
"mode": "interactive",
|
||||
"title": "Descriptive Title",
|
||||
"columns": ["Col1", "Col2", "Col3"],
|
||||
"rows": [
|
||||
{"id": 123, "cells": ["val1", "val2", "val3"], "recommendation": {"action": "dismiss", "reason": "Brief explanation"}},
|
||||
{"id": 456, "cells": ["val1", "val2", "val3"], "recommendation": {"action": "flag", "reason": "Brief explanation"}}
|
||||
],
|
||||
"actions": ["dismiss", "flag", "create_rule"],
|
||||
"source_tool": "tool_name_that_produced_this"
|
||||
}
|
||||
```
|
||||
|
||||
- "mode": "interactive" (actionable) or "readonly" (informational but structured)
|
||||
- "id": the Odoo record ID (account.move id, account.bank.statement.line id, etc.)
|
||||
- "recommendation.action": one of "dismiss", "flag", "create_rule"
|
||||
- "recommendation.reason": short explanation of why you recommend this action
|
||||
- "actions": which bulk action buttons to show
|
||||
- "source_tool": the tool name that produced the data
|
||||
- You MUST provide a recommendation for each row when using interactive mode.
|
||||
- Format monetary amounts as "$X,XXX.XX" in cells.
|
||||
- Always include the record ID so actions can target the correct Odoo record.
|
||||
- Add a brief text summary before or after the fusion-table block for context.
|
||||
|
||||
LINKING TO ODOO RECORDS:
|
||||
- When referencing specific records, include clickable Odoo links.
|
||||
- Journal entries: [INV/2026/00123](/odoo/accounting/123) where 123 is the move ID.
|
||||
@@ -60,12 +104,14 @@ def _build_rules_section(rules):
|
||||
for rule in rules:
|
||||
priority = 'ADMIN' if rule.created_by == 'admin' else 'AI'
|
||||
tier = 'auto' if rule.approval_tier == 'auto' else 'needs-approval'
|
||||
conf_str = f', confidence={rule.confidence_score:.0%}, uses={rule.total_uses}' if rule.total_uses > 0 else ''
|
||||
lines.append(
|
||||
f'- [{priority}/{tier}] {rule.name} ({rule.rule_type}): '
|
||||
f'- [{priority}/{tier}{conf_str}] {rule.name} ({rule.rule_type}): '
|
||||
f'{rule.description or rule.match_logic or "No description"}'
|
||||
)
|
||||
if rule.match_logic:
|
||||
lines.append(f' Match logic: {rule.match_logic}')
|
||||
logic_text = rule.match_logic[:500] # Prevent prompt bloat
|
||||
lines.append(f' Match logic: {logic_text}')
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
@@ -73,7 +119,9 @@ def _build_history_section(history):
|
||||
if not history:
|
||||
return ''
|
||||
lines = ['RECENT MATCH HISTORY (learn from these patterns):']
|
||||
for h in history[:50]:
|
||||
# A4: Don't hard-cap at 50 — the caller (_load_match_history) already
|
||||
# respects the history_in_prompt config setting
|
||||
for h in history:
|
||||
status = h.decision
|
||||
reason = ''
|
||||
if h.rejection_reason:
|
||||
|
||||
Reference in New Issue
Block a user