dodil/erp-brick-quote

src/brick_quote/application/process.yaml

# The quote's process, as the customer sees and signs it (erp_platform.bpmn renders it at GET /process/bpmn).
# The shape of a module spec's `workflows:` (erp-method modules/crm, workflows.quote), written from what this brick's
# use cases do: one entity per offer VERSION (a revision is a new draft). Keys are the BPMN ids: frozen once signed.
version: 1
name: Quotes
actors:
  - { id: rep, name: Sales rep }
  - { id: deal_desk, name: Deal desk }
  - { id: customer, name: The customer, external: true }
  - { id: system, name: The system }
workflows:
  - entity: quote
    states: [draft, sent, accepted, declined, superseded, expired]
    terminal: [accepted, superseded]
    transitions:
      - { key: open_quote, from: none, to: draft, by: rep, name: Draft a quote }
      - { key: approve_discount, from: draft, to: draft, by: deal_desk, name: Approve the discount, approval: true,
          gate: "the discount is above the policy's auto-approve percentage and within its maximum",
          effect: "the quote's owner cannot approve it" }
      - { key: send_quote, from: draft, to: sent, by: rep, name: Send,
          gate: "has lines; the discount is within the policy, or approved for at least this much" }
      - { key: accept_quote, from: sent, to: accepted, by: customer, name: Accept, gate: "not expired",
          effect: "every other open version is superseded; the deal can be won with this total" }
      - { key: decline_quote, from: sent, to: declined, by: customer, name: Decline }
      - { key: revise_quote, from: [sent, declined, expired], to: draft, by: rep, name: Revise,
          effect: "a new version carries the lines; a sent one is superseded" }
      - { key: expire_quote, from: sent, to: expired, by: system, timer: "valid_until passed",
          effect: "derived from the date, never stored" }