Offers
A quote for a project. Offers are built from materials, services and costs, move through DRAFT → PUBLISHED → ACCEPTED/DECLINED, and can be created as a complete nested document or edited piece by piece.
List offers
List offers
Create an offer
Creates a new offer (starts as DRAFT). All collections are optional — a minimal body is just `offer`.
Get an offer
Get an offer
Replace an offer
Atomically replaces the entire offer (delete + re-insert) from a full payload. Only DRAFT offers can be replaced: a published, accepted or declined offer is what the customer saw and answers 409 `offer_not_draft` — create a new offer instead.
Delete an offer
Delete an offer
Change offer state
Transition an offer's state (e.g. publish or accept). The DB trigger materializes the published/accepted snapshot. Offers move DRAFT → PUBLISHED → ACCEPTED/DECLINED: a draft is published before it can be accepted or declined (409 `offer_not_published`), and once an offer left DRAFT it cannot go back to DRAFT (409 `offer_not_draft`) — create a new offer instead. An offer can be accepted until the end of its `validTo` day (German time); after that, accepting answers 409 `offer_expired` — publish a new offer instead. Accepting here takes the offer as it was offered: the recommended module variant of each roof, the offered battery, wallbox and emergency power, and no optional extras. An offer whose roof has several module variants and none marked as the offered one cannot be accepted here (409 `offer_selection_required`). A draft is checked before it is published: with its `validTo` day over (`valid_to_past`) or a price of zero or less (`price_not_positive`) publishing answers 409 `offer_not_publishable`, and the message names what stands in the way.
Offer services
4 items
Offer additional costs
4 items
Offer batteries
4 items
Offer wallboxes
4 items
Offer misc materials
4 items