# templates/brick-example as a module spec: what `erp-compose scaffold` regenerates the starter brick's shape from.
id: example
name: Quotes
version: 1
summary: Quotes a company sends its customers — draft them, add lines, send, and record the customer's acceptance.
facets:
depends_on:
- { module: business-partner, why: "the customer is a party", required: recommended }
brick:
package: brick_example
short_name: example
actors:
- { id: rep, name: Sales rep, permissions: [example:quote:write, example:quote:send] }
- { id: customer, name: The customer, external: true, permissions: [example:quote:accept] }
stories:
- id: EX-01
kind: person
actor: rep
story: As a sales rep, I want a quote's total to be exact, so that the customer pays what was agreed.
given: a draft quote
when: I add 3 x 33.33 and 1 x 0.01
then: the quote totals 100.00 exactly
- id: EX-02
kind: person
actor: rep
story: As a sales rep, I want an empty quote refused at send, so that no customer receives nothing.
given: a draft quote with no lines
when: I send it
then: the send is refused ("an empty quote cannot be sent")
- id: EX-03
kind: person
actor: customer
story: As the customer, I want to accept a sent quote, so that the deal is recorded.
given: a sent quote
when: I accept it twice
then: the quote is accepted once; accepting a draft quote is refused
workflows:
- entity: quote
states: [draft, sent, accepted]
transitions:
- { key: draft_quote, from: none, to: draft, by: rep, effect: "a quote with lines, editable" }
- { key: send_quote, from: draft, to: sent, by: rep, gate: "at least one line", effect: "frozen: copy it to change it" }
- { key: accept_quote, from: sent, to: accepted, by: customer, effect: "the customer's acceptance is recorded" }
entities:
- id: quote
meaning: an offer to one customer, in one currency
natural_key: quote_id
key_attributes: [customer, owner, status, currency]
reference_table: example_quotes
- id: line
meaning: one priced line of a quote
natural_key: "quote_id|line_no"
key_attributes: [description, quantity, unit_price]
reference_table: example_lines
permissions:
namespace: example
catalog: [example:quote:write, example:quote:send, example:quote:accept]
row_visibility:
rule: "a rep sees the quotes they own; managers see every quote"
config_rows:
- { table: example_settings_currency, changes: "the currencies a quote may be in" }
tests:
scenarios:
- id: SC-EX-01
name: a quote from draft to accepted
stories: [EX-01, EX-03]
given: a rep with a customer
when: the rep drafts, prices and sends a quote, and the customer accepts it
then: the quote is accepted with its exact total
ai_steps:
- { step: send_quote, capability: mail.send, benefit: "drafts the cover email", safe: false }