Product Bundles

Products now carry a type: PRODUCT for a standalone product, and BUNDLE for a product made up
of other products. Bundles can be listed, fetched, created, updated and deleted through the product endpoints.

  • GET /products returns bundles alongside standalone products. Filter by type, for example
    ?type=PRODUCT to list standalone products only.
  • GET /products/{product_id} also returns bundles. A bundle carries bundle, with its components and
    invoice display, and has no account_code or revenue_pattern.
  • POST /products with type: BUNDLE and bundle creates a bundle.
  • PUT /products/{product_id} updates a bundle, including its components, invoice display and status. Send
    type: BUNDLE with every update; type can't change.
  • DELETE /products/{product_id} deletes a bundle that no contract, invoice or credit memo uses. A bundle in use
    returns 409.
  • POST /products/{product_id}/refresh-bundle updates the details a bundle keeps for each component product to
    the products' current values. Contracts that already sold the bundle don't change.

Contract lines now carry a product_type. A bundle line carries bundle, with its invoice display and its
components as recorded when the contract was signed: product, name, quantity per bundle unit, revenue pattern
and allocated amount. It has no line-level revenue_pattern.

POST /contracts accepts a bundle as a line's product_id. POST /contracts/{contract_id}/amendments and its
preview amend a contract's existing bundle lines, but can't add a bundle line or switch a line to a bundle.
Bundle lines ignore revenue_pattern.

account_code and revenue_pattern are now optional on Product and ProductRequest, and revenue_pattern
on ContractItem, ContractItemRequest and AmendFullContractItemRequest. Standalone products and lines
always include them in responses, and requests still require them for standalone products.

Applies to V4 only.