# Invoice Payment and Profit Handling Guide

## Problem you raised
You have an invoice (example: 1000) and user may try to pay 3000 or 5000.
You also need gross profit and net profit to be recognized correctly when payment is partial.

## What is implemented in backend

### Endpoint
`PATCH /api/v1/invoices/:id/payment`

### Supported payloads

Single input only:

```json
{
  "paymentAmount": 300
}
```

This adds payment on top of current `amountPaid`.

## Overpayment handling (invoice 1000, pay 3000/5000)

If incoming payment exceeds remaining balance:
- `amountPaid` is capped at `totalAmount`.
- extra is stored in `overpaymentAmount`.

Example:
- invoice total: 1000
- existing paid: 0
- request: `{ "paymentAmount": 3000 }`

Result:
- `amountPaid = 1000`
- `paymentStatus = paid`
- `overpaymentAmount = 2000`

## Payment status rules
- `paid` if `amountPaid >= totalAmount`
- `partial` if `0 < amountPaid < totalAmount`
- `unpaid` if `amountPaid = 0` and not overdue
- `overdue` if unpaid and past due date

## Response helpers now available
- `overpaymentAmount`
- `outstandingAmount = max(totalAmount - amountPaid, 0)`
- `paidRatio = min(amountPaid, totalAmount) / totalAmount`
- `realizedGrossProfit = totalGrossProfit * paidRatio`

### Payment collection fields returned by payment endpoint
`PATCH /api/v1/invoices/:id/payment` also returns:
- `paymentInput`
- `paymentApplied`
- `overpaymentAdded`
- `paidDeltaApplied`
- `grossMarginRatio`
- `realizedGrossFromPayment`
- `realizedNetFromPayment`

`realizedNetFromPayment` currently equals `realizedGrossFromPayment` because shared operating costs are not allocated at payment transaction level.

---

## Gross profit recognition for partial payments

## Example
Two items:
- selling price 120 each
- main price 110 each

Invoice total = 220, invoice gross profit = 20.

If customer pays 50 only:

$$
  ext{Paid Ratio} = \frac{50}{220}
$$

$$
  ext{Realized Gross Profit} = 20 \times \frac{50}{220} = 4.55
$$

So from this payment, recognized gross profit is 4.55 (not full 20).

## Formula used

$$
  ext{Paid Ratio} = \frac{\min(\text{amountPaid}, \text{totalAmount})}{\text{totalAmount}}
$$

$$
  ext{Realized Invoice Gross Profit} = \text{Invoice Gross Profit} \times \text{Paid Ratio}
$$

---

## Net profit in analytics (current behavior)

Period net profit is computed as:

$$
  ext{Net Profit} = \text{Paid Bill Gross Profit} + \text{Realized Invoice Gross Profit} - \text{Expenses} - \text{Payroll Deduction}
$$

Endpoint:
`GET /api/v1/analytics/net-profit?timeRange=7d`

This is the correct business-level net profit extraction for the selected period.

---

## Exact frontend changes required

1. Payment modal request logic
- Keep only one input field: `paymentAmount`.
- Always call `PATCH /api/v1/invoices/:id/payment` with `paymentAmount`.
- Remove `amountPaid` and `paymentStatus` payload usage from this payment modal.

2. Invoice UI fields to display
- `amountPaid`
- `outstandingAmount`
- `overpaymentAmount`
- `paidRatio` (progress bar or percent)
- `realizedGrossProfit` (recognized gross from paid portion)
- `totalGrossProfit` (full gross potential)

3. Payment result card/row (after submit)
- `paymentInput`
- `paymentApplied`
- `overpaymentAdded`
- `realizedGrossFromPayment`
- `realizedNetFromPayment`

4. KPI wording update
- Change invoice gross label from "Paid only" to "Realized by payments".

5. Validation UX
- Prevent negative payment input.
- Round to max 2 decimals before submit.
- Keep input required and > 0.

---

## API examples

### Add 500 payment

```http
PATCH /api/v1/invoices/INVOICE_ID/payment
Content-Type: application/json

{
  "paymentAmount": 500
}
```
