Skip to content

Partial Payment & Receipt System - Documentation

✅ YES - Partial Payments ARE Fully Supported!

The system already has a complete partial payment and receipt allocation system implemented for both customers and vendors.


How It Works

Payment Allocation Model

Backend: PaymentAllocation

class PaymentAllocation(models.Model):
    payment = ForeignKey(Payment)
    invoice = ForeignKey(Invoice)
    amount = DecimalField(max_digits=20, decimal_places=2)

Key Features: - One payment can be allocated to multiple invoices - One invoice can receive multiple partial payments - Tracks exact allocation amount per invoice


User Interface

Payment Registration Screen

Location: CreatePayment.tsx

Features: 1. Partner Selection: Choose Customer/Vendor/Employee 2. Unpaid Invoice List: Shows all POSTED invoices for selected partner 3. Allocation Grid: - Invoice Date, Due Date, Reference - Total Amount - Balance Due - Allocate Amount (editable field)

  1. Flexible Allocation:
  2. Pay full invoice amount
  3. Pay partial amount
  4. Split one payment across multiple invoices
  5. Leave some invoices unpaid

Example Scenarios

Scenario 1: Partial Payment from Customer

Invoice: INV-001 = AED 10,000
Customer pays: AED 6,000

Action: 1. Go to Payments → Register Customer Receipt 2. Select Customer 3. Enter Amount: 6,000 4. In allocation grid, allocate 6,000 to INV-001 5. Post Payment

Result: - Payment recorded: AED 6,000 - Invoice balance: AED 4,000 (remaining) - Invoice status: PARTIALLY_PAID

Scenario 2: One Payment for Multiple Invoices

Invoices: - INV-001 = AED 5,000 - INV-002 = AED 3,000 - INV-003 = AED 2,000

Customer pays: AED 7,500

Action: 1. Register Receipt: AED 7,500 2. Allocate: - INV-001: AED 5,000 (full) - INV-002: AED 2,500 (partial) - INV-003: AED 0 (skip) 3. Post Payment

Result: - INV-001: PAID - INV-002: PARTIALLY_PAID (AED 500 remaining) - INV-003: NOT_PAID

Scenario 3: Multiple Payments for One Invoice

Invoice: BILL-001 = AED 20,000

Payments: - Payment 1: AED 8,000 - Payment 2: AED 7,000 - Payment 3: AED 5,000

Result: Invoice fully paid with 3 separate payments


Payment States

The system tracks invoice payment status:

State Description
NOT_PAID No payments received
PARTIALLY_PAID Some payments received, balance remaining
PAID Fully paid
OVERPAID Received more than invoice amount

Backend Logic

Allocation Creation

File: serializers.py

When posting a payment:

for allocation in allocations_data:
    PaymentAllocation.objects.create(
        payment=payment,
        invoice_id=allocation['invoice_id'],
        amount=allocation['amount']
    )

Balance Calculation

The system calculates: - Total Allocated: Sum of all PaymentAllocation.amount for an invoice - Balance Due: Invoice.amount_total - Total Allocated


Frontend Implementation

Allocation Input

Lines 317-327 in CreatePayment.tsx:

<input
    type="number"
    value={allocations[inv.id] || 0}
    onChange={(e) => handleAllocationChange(inv.id, parseFloat(e.target.value))}
    max={inv.amount_total}
    step="0.01"
/>

Validation

  • Total allocated cannot exceed payment amount
  • Shows warning if over-allocated
  • Displays total allocated vs payment amount

Known Limitation (Minor)

Issue: Aging Report shows full invoice amount instead of remaining balance
Location: utils.py:198

balance = inv.amount_total # TODO: handle partial payments

Impact: Low - Aging report is still accurate for unpaid invoices
Fix Needed: Calculate amount_total - sum(allocations.amount) for each invoice


How to Use

For Customer Receipts:

  1. Navigate to Payments → Customer Receipts
  2. Click Register Receipt
  3. Select Customer
  4. Enter total amount received
  5. Allocate to invoices (full or partial)
  6. Post Payment

For Vendor Payments:

  1. Navigate to Payments → Supplier Payments
  2. Click Register Payment
  3. Select Vendor
  4. Enter total amount to pay
  5. Allocate to bills (full or partial)
  6. Post Payment

Direct from Invoice:

  1. Open any invoice
  2. Click Register Payment button
  3. Amount pre-filled with invoice total
  4. Adjust allocation as needed
  5. Post Payment

Conclusion

✅ Partial payments are fully supported
✅ Works for Customers, Vendors, and Employees
✅ Flexible allocation across multiple invoices
✅ Tracks payment history per invoice
✅ Production-ready

The only minor enhancement needed is updating the Aging Report to show remaining balances instead of total amounts.