Claim Payment Documentation¶
Overview¶
The Claim Payment model (claim.payment) is a transient wizard model that provides a streamlined interface for recording payments against expense claims. It simplifies the reimbursement process by automatically creating and posting payment records.
Model Information¶
Model Name: claim.payment
Display Name: Claim Payment
Key Fields: None (transient model)
Features¶
- ✅ Transient model (temporary data)
- ❌ Audit logging enabled (
_audit_log) - ❌ Multi-company support (
company_id) - ✅ Automatic payment creation and posting
- ✅ Amount validation against due amount
- ✅ Bank account filtering
Key Fields Reference¶
All Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
amount |
Decimal | ✅ | Payment amount |
date |
Date | ✅ | Payment date |
account_id |
Many2One | ✅ | Bank account for payment |
claim_id |
Many2One | ✅ | Claim being paid |
ref |
Char | ❌ | Payment reference |
Account Filtering¶
The account_id field is filtered to show only bank accounts:
API Methods¶
1. Add Payment¶
Method: add_payment(ids, context)
Creates and posts a payment for the expense claim.
Behavior:
1. Validates payment amount doesn't exceed amount due
2. Gets unpaid claims account from Settings
3. Creates outgoing payment with type claim
4. Posts the payment
5. Returns navigation to claim edit view
Example:
# Create payment wizard
wizard_id = get_model("claim.payment").create({
"claim_id": claim_id,
"amount": 1000.00,
"date": "2024-12-15",
"account_id": bank_account_id,
"ref": "REIMB-001",
})
# Process payment
result = get_model("claim.payment").add_payment([wizard_id])
# Returns: {"next": {...}, "flash": "Payment recorded"}
Raises:
- Exception("Amound paid exceeds the amount due.") - If amount > claim.amount_due
- AssertionError - If unpaid claims account not configured
Payment Structure¶
The wizard creates a payment with:
{
"type": "out", # Outgoing payment
"pay_type": "claim", # Payment for claim
"date": wizard.date,
"ref": wizard.ref,
"account_id": wizard.account_id, # Bank account
"currency_id": settings.currency_id,
"lines": [{
"type": "claim",
"claim_id": claim.id,
"account_id": claim.account_id, # Unpaid claims account
"amount": wizard.amount,
}]
}
Related Models¶
| Model | Relationship | Description |
|---|---|---|
account.claim |
Many2One (claim_id) | Claim being reimbursed |
account.account |
Many2One (account_id) | Bank account |
account.payment |
Created | Payment record |
settings |
Reference | For unpaid claims account |
Common Use Cases¶
Use Case 1: Full Claim Reimbursement¶
# Get claim
claim = get_model("account.claim").browse([claim_id])[0]
# Pay full amount due
wizard_id = get_model("claim.payment").create({
"claim_id": claim_id,
"amount": claim.amount_due,
"date": "2024-12-15",
"account_id": bank_account_id,
"ref": "REIMB-FULL",
})
get_model("claim.payment").add_payment([wizard_id])
# Claim should now be "paid"
claim = get_model("account.claim").browse([claim_id])[0]
assert claim.state == "paid"
Use Case 2: Partial Reimbursement¶
# Pay partial amount
wizard_id = get_model("claim.payment").create({
"claim_id": claim_id,
"amount": 500.00, # Partial
"date": "2024-12-15",
"account_id": bank_account_id,
"ref": "REIMB-PARTIAL-1",
})
get_model("claim.payment").add_payment([wizard_id])
# Claim remains in "waiting_payment" with reduced amount_due
Use Case 3: Multiple Payments¶
# First payment
wizard1 = get_model("claim.payment").create({
"claim_id": claim_id,
"amount": 300.00,
"date": "2024-12-10",
"account_id": bank_account_id,
"ref": "REIMB-1",
})
get_model("claim.payment").add_payment([wizard1])
# Second payment
wizard2 = get_model("claim.payment").create({
"claim_id": claim_id,
"amount": 200.00,
"date": "2024-12-15",
"account_id": bank_account_id,
"ref": "REIMB-2",
})
get_model("claim.payment").add_payment([wizard2])
# Track payments
claim = get_model("account.claim").browse([claim_id])[0]
print(f"Total paid: {claim.amount_paid}")
print(f"Remaining: {claim.amount_due}")
Reimbursement Flow¶
1. Claim is in "waiting_payment" state
│
2. User initiates payment
│
3. Payment wizard displayed
│
├─ Enter payment amount
├─ Select bank account
└─ Add reference
│
4. System validates amount <= amount_due
│
5. Payment created and posted
│
6. Claim amount_due reduced
│
7. If amount_due = 0, state changes to "paid"
Best Practices¶
1. Verify Claim State First¶
# Good: Check claim is ready for payment
claim = get_model("account.claim").browse([claim_id])[0]
if claim.state != "waiting_payment":
raise Exception(f"Claim not ready for payment (state: {claim.state})")
if claim.amount_due <= 0:
raise Exception("No amount due on this claim")
2. Include Reference for Audit Trail¶
# Good: Clear reference
wizard = get_model("claim.payment").create({
"ref": f"REIMB-{claim.number}-{date}",
...
})
3. Use Correct Bank Account¶
# Good: Use designated reimbursement account
wizard = get_model("claim.payment").create({
"account_id": petty_cash_account_id, # or payroll_bank_id
...
})
Troubleshooting¶
"Amound paid exceeds the amount due"¶
Cause: Payment amount greater than claim.amount_due Solution: Reduce amount to claim.amount_due or less
"Missing unpaid expense claims account"¶
Cause: unpaid_claim_id not configured in Settings Solution: Configure Settings > unpaid_claim_id
"No bank accounts in dropdown"¶
Cause: No accounts with type="bank" Solution: Create bank account in Chart of Accounts
Testing Examples¶
Unit Test: Claim Payment¶
def test_claim_payment():
# Assume claim exists in waiting_payment state
claim = get_model("account.claim").browse([claim_id])[0]
initial_due = claim.amount_due
# Create payment
wizard_id = get_model("claim.payment").create({
"claim_id": claim_id,
"amount": 100.00,
"date": "2024-12-15",
"account_id": bank_account_id,
})
# Process
get_model("claim.payment").add_payment([wizard_id])
# Verify
claim = get_model("account.claim").browse([claim_id])[0]
assert claim.amount_due == initial_due - 100.00
assert claim.amount_paid >= 100.00
Security Considerations¶
Permission Model¶
- Users need payment creation permissions
- Bank account access required
Data Access¶
- Transient model - wizard data not persisted
- Creates permanent payment records
Configuration Requirements¶
| Setting | Location | Description |
|---|---|---|
unpaid_claim_id |
Settings | Account for unpaid claims liability |
currency_id |
Settings | Default currency |
Version History¶
Last Updated: December 2024 Model Version: claim_payment.py Framework: Netforce
Additional Resources¶
- Account Claim Documentation:
account.claim - Payment Documentation:
account.payment - Account Documentation:
account.account
This documentation is generated for developer onboarding and reference purposes.