expense-processing

jgtolentino's avatarfrom jgtolentino

Automates expense receipt capture, validation, and Odoo posting

⭐1stars🔀1forks📁View on GitHub🕐Updated Jan 10, 2026

When & Why to Use This Skill

The Expense Processing skill is a comprehensive automation solution designed to streamline the end-to-end reimbursement workflow. By leveraging AI-powered OCR (PaddleOCR) and Claude's data structuring capabilities, it transforms raw receipt images into validated financial records. It features robust policy compliance checks, multi-level approval routing, and direct integration with Odoo ERP, significantly reducing manual data entry and ensuring financial accuracy.

Use Cases

  • Automated Receipt Data Extraction: Using AI to accurately capture merchant details, dates, taxes, and total amounts from photos or PDFs, eliminating manual typing errors.
  • Corporate Policy Enforcement: Automatically validating expense submissions against company spending limits and category rules to ensure compliance before manager review.
  • Seamless Odoo ERP Integration: Synchronizing approved expenses directly into Odoo's hr.expense module with automated account mapping and category assignment.
  • Multi-Channel Submission Management: Allowing employees to submit receipts via mobile uploads, email forwarding, or messaging bots (like Telegram) for real-time processing.
  • Automated Approval Workflows: Routing expense reports to the appropriate stakeholders (Managers, Dept Heads, or CFOs) based on transaction value and department logic.
nameexpense-processing
descriptionAutomates expense receipt capture, validation, and Odoo posting
version1.0.0
authorInsightPulse AI
tags[expense, receipt, ocr, reimbursement, hr]

Expense Processing Skill

Overview

This skill handles the complete expense management workflow from receipt capture through reimbursement, including OCR extraction, policy validation, and Odoo integration.

Capabilities

  • Receipt image OCR via PaddleOCR
  • AI-powered data extraction
  • Policy compliance validation
  • Automatic expense categorization
  • Odoo hr.expense creation
  • Approval workflow routing
  • Reimbursement tracking

Workflow

Step 1: Receipt Capture

Input Methods:

Supported Formats:

  • Images: JPG, PNG, HEIC
  • Documents: PDF (first page)
  • Max size: 10MB

Step 2: OCR Extraction

PaddleOCR Endpoint: https://ocr.insightpulseai.net/api/ocr/receipt

Request:

{
  "image": "<base64_encoded_image>",
  "language": "en"
}

Response:

{
  "text": "JOLLIBEE STORE 1234\n...",
  "confidence": 0.95,
  "regions": [...]
}

Step 3: AI Data Structuring

Claude Prompt:

Extract receipt data and return JSON:
- merchant_name: string
- merchant_tin: string (if visible)
- receipt_date: YYYY-MM-DD
- receipt_number: string
- subtotal: number
- vat_amount: number
- total_amount: number
- payment_method: cash|credit_card|gcash|paymaya|other
- expense_category: meals|transportation|supplies|communication|accommodation|other
- description: brief description

Step 4: Policy Validation

Approval Thresholds (PHP):

Amount Approval Route
< 5,000 Self Auto-approve
5,000 - 25,000 Manager Notify manager
25,000 - 100,000 Dept Head + Finance Escalate
> 100,000 CFO Escalate + alert

Policy Rules:

rules = [
    Rule("amount_limit", lambda e: e.amount <= 100000, "Amount exceeds maximum"),
    Rule("valid_category", lambda e: e.category in ALLOWED_CATEGORIES, "Invalid category"),
    Rule("has_receipt", lambda e: e.receipt_image is not None, "Receipt required"),
    Rule("or_required", lambda e: e.amount < 1000 or e.has_official_receipt, "OR required > 1000"),
    Rule("not_weekend", lambda e: not e.is_personal, "Personal expenses not allowed"),
]

Step 5: Odoo Integration

hr.expense Creation:

{
  "name": "Jollibee - Client Meeting Lunch",
  "product_id": 1,  // Meals category
  "unit_amount": 1250.00,
  "quantity": 1,
  "date": "2026-01-06",
  "employee_id": 77,  // RIM
  "payment_mode": "own_account",
  "reference": "OR-12345678",
  "description": "Client meeting with ACME Foods project team"
}

Category Mapping:

Category Odoo Product ID Account
meals 1 6210 - Meals & Entertainment
transportation 2 6220 - Transportation
supplies 3 6230 - Office Supplies
communication 4 6240 - Communication
accommodation 5 6250 - Travel & Lodging
other 6 6290 - Miscellaneous

Step 6: Approval Workflow

Odoo States:

draft → reported → submitted → approved → posted → done
                 ↘ refused ↙

Notifications:

  • On submit: Notify approver via Mattermost
  • On approve/refuse: Notify employee
  • On post: Update reimbursement queue

n8n Workflow Integration

The expense_receipt_capture.json workflow:

  1. Webhook receives image
  2. PaddleOCR extracts text
  3. Claude structures data
  4. Policy check (IF node)
    • Pass: Create expense in Odoo
    • Fail: Alert to #finance-general
  5. Respond with result

Mattermost Notifications

Policy Violation Alert:

#### :warning: Policy Violation Alert
| Field | Value |
|:--|:--|
| **Amount** | PHP 7,500 |
| **Threshold** | PHP 5,000 |
| **Merchant** | Restaurant ABC |
| **Category** | meals |

**Action Required:** Manager approval needed

Expense Created:

#### :receipt: Expense Submitted
| Field | Value |
|:--|:--|
| **Employee** | Rey Meran (RIM) |
| **Amount** | PHP 1,250 |
| **Category** | Meals |
| **Status** | Pending Approval |

Receipt Requirements

Valid Receipt Elements

  • Date of purchase
  • Merchant/vendor name
  • Itemized list
  • Total amount
  • OR number (for amounts > ₱1,000)
  • VAT details (if applicable)

Common Issues

Issue Resolution
Faded receipt Re-scan or request duplicate
Missing OR Request from vendor
Foreign currency Include exchange rate
Handwritten Attach explanation

Reimbursement Schedule

  • Cutoff 1: Submit by 10th → Reimbursed on 15th
  • Cutoff 2: Submit by 25th → Reimbursed on 30th

Error Handling

errors = {
    "OCR_FAILED": "Could not extract text. Please re-upload clearer image.",
    "INVALID_DATE": "Receipt date could not be parsed. Please enter manually.",
    "CATEGORY_UNKNOWN": "Could not determine expense category. Please select.",
    "EMPLOYEE_NOT_FOUND": "Employee not found in system. Contact HR.",
    "DUPLICATE_RECEIPT": "This receipt may already exist. Please verify.",
}

Commands

Command Action
/expense submit Start expense submission
/expense status [id] Check expense status
/expense history View recent expenses
/expense policy Show expense policy

Changelog

  • v1.0.0 (2026-01-06): Initial release