Handle Compose Proposal Draft
CRM-10244 — a draft proposal composed into its template's PDF.
Stateless and read-only: the editor sends what Generate returned plus
what the rep typed, and gets the PDF back, with the DRAFT watermark and
a marker in every empty box. The preview refresh and the download both
call it. A plain def, like the active-template read: composing is
synchronous work that belongs in the thread pool.
Two headers report what the document could not show as given, so the
editor can flag the slot: X-Proposal-Unsupported-Slots lists slots
holding characters the document's font cannot draw, and
X-Proposal-Cut-Slots what was cut with "…": slots whose text would
have run past the page's bottom edge, and line-item table cells whose
text did not fit their row. Each is a comma-separated list, sent only
when not empty.
Body·
What the editor sends to have a draft composed: everything Generate
returned for the proposal, plus what the rep typed. Values are already
formatted for display. The keys inside values (slot ids) and inside each
line (line source keys, such as line.name) are passed as they are, not
camel-cased.
- Type: stringproposal
Name min length:1max length:256requiredNames the downloaded file
- Type: stringtemplate
Version Id min length:1max length:50requiredTemplate version ID (dtv-)
- Type: array of object …500linesProperties: 1
The line items, in order, by line source key
- Type: ValuesvaluesProperties: 1
Each slot's value, by slot id
Responses
- application/pdf
- application/json
- application/json
curl https://crm.dreamhub.ai/api/v1/contracts/proposals/compose \
--request POST \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
--data '{
"templateVersionId": "",
"proposalName": "",
"values": {
"additionalProperty": ""
},
"lines": [
{
"additionalProperty": ""
}
]
}'

