Skip to main content

Generate & Edit

After reviewing the prefill preview, users generate a draft invoice (saving to PostgreSQL) and can then edit any field before finalizing.

Generate Flow​

Generate Request​

curl -X POST http://localhost:8081/api/v1/invoices/generate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"application_key": "APP-001",
"period_start": "2026-02-01",
"period_end": "2026-02-28",
"deal_type": "SUP",
"currency": "UZS",
"base_amount": "15000000.00",
"total_amount": "15825000.00",
"total_hours": "45.50",
"overtime_hours": "5.50",
"overtime_amount": "825000.00",
"is_overtime": true,
"line_items": [...]
}'

The frontend sends the full prefill result (possibly modified by the user) as the generate request. The backend:

  1. Fetches client_invoice_config for the application
  2. Validates the numbering seed exists (rejects generation if last_invoice_number is NULL)
  3. Begins a transaction
  4. Atomically increments last_invoice_number using SELECT ... FOR UPDATE
  5. Copies display toggle defaults and legal text from the config
  6. Inserts the invoice and line items
  7. Commits the transaction

This ensures sequential, collision-free invoice numbering even under concurrent requests.

Bulk Generate​

For generating invoices for all active clients at once:

curl -X POST http://localhost:8081/api/v1/invoices/generate-bulk \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"period_start": "2026-02-01",
"period_end": "2026-02-28"
}'

This runs the prefill pipeline for every active application and generates draft invoices for each.

Edit Flow​

Draft invoices are fully editable. All edits are tracked in invoice_edit_history.

Edit Invoice Fields​

curl -X PATCH http://localhost:8081/api/v1/invoices/{id} \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"base_amount": "16000000.00",
"total_amount": "16825000.00",
"invoice_date": "2026-03-01"
}'

Editable fields: base_amount, total_amount, overtime_hours, overtime_amount, is_overtime, invoice_date, show_task_list, show_tracked_time, show_task_pricing, show_overtime, legal_text.

Edit Line Items​

Line items support three operations in a single request:

curl -X PATCH http://localhost:8081/api/v1/invoices/{id}/line-items \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"add": [
{
"line_type": "task",
"description": "Additional consulting",
"time_seconds": 3600,
"billable_seconds": 3600,
"unit_price": "150000.00",
"quantity": "1.00",
"line_total": "150000.00",
"source": "manual"
}
],
"update": [
{
"id": "uuid-of-existing-line",
"description": "Updated description",
"line_total": "500000.00"
}
],
"remove": ["uuid-of-line-to-remove"]
}'
OperationEffect
addCreates new line items with source = 'manual'
updateModifies existing line items, records changes in edit history
removeSoft-deletes line items, records removal in edit history

Edit History​

Every edit is recorded with before/after values:

curl http://localhost:8081/api/v1/invoices/{id}/edit-history \
-H "Authorization: Bearer $TOKEN"
{
"data": [
{
"edit_type": "line_modified",
"field_name": "line_total",
"old_value": "300000.00",
"new_value": "500000.00",
"edited_by": "[email protected]",
"edited_at": "2026-02-15T10:30:00Z"
},
{
"edit_type": "line_added",
"field_name": null,
"old_value": null,
"new_value": "Additional consulting",
"edited_by": "[email protected]",
"edited_at": "2026-02-15T10:31:00Z"
}
]
}

Edit types: line_modified, line_added, line_removed, total_override, deal_amount_override.

Regenerate​

Regenerating re-fetches fresh data from ClickHouse and resets the invoice to draft:

curl -X PUT http://localhost:8081/api/v1/invoices/{id}/regenerate \
-H "Authorization: Bearer $TOKEN"

This is used when:

  • An invoice was declined and needs rework
  • A client rejected an invoice
  • Worklog data has been updated in ClickHouse

The regenerate flow re-runs the full prefill pipeline and replaces the current line items. Previous edit history is preserved for audit purposes.