Skip to content

Invoice Overpay Documentation

Overview

The Invoice Overpay model (invoice.overpay) is a transient wizard model that handles overpayment scenarios when a payment exceeds the invoice amount due. It allows users to confirm and process overpayments with an optional description.


Model Information

Model Name: invoice.overpay Display Name: Invoice Overpay Key Fields: None (transient model)

Features

  • ✅ Transient model (temporary data)
  • ❌ Audit logging enabled (_audit_log)
  • ❌ Multi-company support (company_id)
  • ✅ Automatic overpayment calculation
  • ✅ Overpayment description support

Key Fields Reference

All Fields

Field Type Required Description
payment_id Many2One Payment record with overpayment
amount_overpay Decimal Calculated overpayment amount (readonly)
description Char Description for overpayment record

Default Values

_defaults = {
    "payment_id": _get_payment,      # From context payment_id
    "amount_overpay": _get_amount,   # Calculated overpayment amount
}

API Methods

1. Get Payment (Default)

Method: _get_payment(context)

Gets the payment ID from context.

Context Parameters: - payment_id - ID of the payment with overpayment


2. Get Amount (Default)

Method: _get_amount(context)

Calculates the total overpayment amount from payment lines.

Logic:

# For each invoice line in payment
amt_over = sum(
    max(0, line.amount_invoice - line.invoice_id.amount_due)
    for line in payment.invoice_lines
)

Raises: - Exception("Wrong payment type") - If payment type is not invoice


3. Process Overpay

Method: do_overpay(ids, context)

Confirms and processes the overpayment.

Behavior: 1. Posts the payment with overpayment description in context 2. Returns navigation to payment form view

Context Passed to Post:

context = {
    "overpay_description": obj.description
}

Example:

# Create overpay wizard
wizard_id = get_model("invoice.overpay").create({
    "payment_id": payment_id,
    "description": "Customer advance payment for future orders",
}, context={"payment_id": payment_id})

# Process overpayment
result = get_model("invoice.overpay").do_overpay([wizard_id])


Model Relationship Description
account.payment Many2One (payment_id) Payment with overpayment
account.payment.line Reference Payment lines for calculation
account.invoice Reference Invoices being overpaid

Common Use Cases

Use Case 1: Process Customer Advance Payment

# Customer pays more than invoice amount
# Payment is created but not posted due to overpayment

# Create overpay wizard to confirm
wizard_id = get_model("invoice.overpay").create({
    "description": "Customer advance - credit on account",
}, context={"payment_id": payment_id})

# Check overpayment amount
wizard = get_model("invoice.overpay").browse([wizard_id])[0]
print(f"Overpayment amount: {wizard.amount_overpay}")

# Confirm and process
get_model("invoice.overpay").do_overpay([wizard_id])

Use Case 2: Bulk Payment with Overpay

# Payment covers multiple invoices with excess
# Example: Pay 5000 for invoices totaling 4500

# After payment creation triggers overpay wizard
wizard_id = get_model("invoice.overpay").create({
    "description": "Excess payment - apply to next invoice",
}, context={"payment_id": payment_id})

wizard = get_model("invoice.overpay").browse([wizard_id])[0]
print(f"Total overpayment: {wizard.amount_overpay}")  # Shows 500

get_model("invoice.overpay").do_overpay([wizard_id])

Overpayment Flow

1. User creates payment with amount > invoice due
2. System detects overpayment
3. Overpay wizard is displayed
   ├─ Shows overpayment amount
   └─ Allows description entry
4. User confirms overpayment
5. Payment is posted
6. Overpayment recorded (creates credit on account)

Best Practices

1. Always Provide Description

# Good: Clear description for audit trail
wizard = get_model("invoice.overpay").create({
    "description": "Customer prepayment for PO-2024-001",
}, context={"payment_id": payment_id})

# Bad: No description
wizard = get_model("invoice.overpay").create({
}, context={"payment_id": payment_id})

2. Review Overpayment Amount

# Good: Verify overpayment before confirming
wizard = get_model("invoice.overpay").browse([wizard_id])[0]

if wizard.amount_overpay > expected_advance:
    print(f"Warning: Overpayment {wizard.amount_overpay} higher than expected")
    # Investigate before proceeding

Troubleshooting

"Wrong payment type"

Cause: Payment is not of type invoice Solution: Only use this wizard for invoice payments

"Overpayment amount is 0"

Cause: Payment lines don't exceed invoice amounts Solution: Verify payment amounts vs invoice due amounts

"Payment not posting"

Cause: Overpayment not confirmed through wizard Solution: Complete the overpay wizard to post payment


Testing Examples

Unit Test: Overpayment Calculation

def test_overpay_calculation():
    # Create invoice for 1000
    invoice_id = get_model("account.invoice").create({
        "type": "out",
        "contact_id": customer_id,
        "lines": [("create", {
            "description": "Test",
            "qty": 1,
            "unit_price": 1000.00,
        })]
    })
    get_model("account.invoice").post([invoice_id])

    # Create payment for 1500 (500 overpay)
    payment_id = get_model("account.payment").create({
        "type": "in",
        "pay_type": "invoice",
        "contact_id": customer_id,
        "account_id": bank_account_id,
        "lines": [("create", {
            "invoice_id": invoice_id,
            "amount": 1500.00,
        })]
    }, context={"type": "in"})

    # Create overpay wizard
    wizard_id = get_model("invoice.overpay").create({
        "description": "Test overpay",
    }, context={"payment_id": payment_id})

    wizard = get_model("invoice.overpay").browse([wizard_id])[0]
    assert wizard.amount_overpay == 500.00

Security Considerations

Permission Model

  • Users need payment posting permissions
  • Overpayment requires explicit confirmation

Data Access

  • Transient model - not persisted
  • Creates permanent records in payment system

Version History

Last Updated: December 2024 Model Version: invoice_overpay.py Framework: Netforce


Additional Resources

  • Invoice Documentation: account.invoice
  • Payment Documentation: account.payment
  • Invoice Payment Wizard: invoice.payment

This documentation is generated for developer onboarding and reference purposes.