Line item sections for projects, invoices, and bills

Line items can now be grouped into named sections — the same grouping you see on quotes and in the Coperniq UI — across project line items, invoices, and bills.

Sections on write

PUT /projects/{projectId}/line-items, POST/PATCH /invoices, and POST/PATCH /bills accept a sections array alongside (or instead of) lineItems:

1{
2 "lineItems": [ { "catalogItemId": 101, "quantity": 1, "unitCost": 10, "unitPrice": 20 } ],
3 "sections": [
4 { "name": "Labor", "lineItems": [ { "catalogItemId": 202, "quantity": 4, "unitCost": 30, "unitPrice": 60 } ] }
5 ]
6}
  • lineItems and sections may be combined in one request: top-level lineItems stay ungrouped, sections carry named groups.
  • A section’s name may be omitted or null for an unnamed group.
  • A catalogItemId may appear at most once across the flattened set (lineItems + every section’s items); duplicates are rejected with 400.

Section name on read

Every line item in project, invoice, bill, and quote responses now includes sectionName — the name of the section the item belongs to, or null when the item is ungrouped. (sectionId is not returned; replacing all line items is the only update path, so the name is the grouping signal.)

Invoice creation: status and issueDate

  • status is now optional and defaults to DRAFT; issueDate is now optional. Omit both to create a draft invoice.
  • A finalized status (SENT, PARTIALLY_PAID, PAID) requires an issueDate. An issueDate without a finalized status is ignored (the invoice is created as a draft).
  • Lifecycle statuses (DECLINED, OVERDUE) cannot be set at creation and are rejected with 400.
  • description is fully optional — invoice creation no longer fails when it is omitted.

Invoice updates: calculationMethod is fixed at creation

PATCH /invoices/{invoiceId} no longer accepts calculationMethod (matching bills, where this was already the case). Sending it returns 400. percentage cannot be combined with lineItems/sections in the same update.

Validation tightening

  • calculationMethod: PERCENTAGE invoices and bills now reject lineItems (previously they were silently ignored), in addition to the existing sections rejection.
  • PUT /projects/{projectId}/line-items validation errors now surface the specific problem (e.g. the duplicate-catalog-item message) instead of a generic “Invalid input”.

Deprecation

Passing a bare top-level array of line items to PUT /projects/{projectId}/line-items is deprecated. It is still accepted for backwards compatibility but will not be supported in a future version — use the object form with lineItems and/or sections.