Before any screen is designed, the nouns and their cardinalities settle a
surprising number of arguments.
ENTITIES
entity means identifier notable attributes
-------------- ----------------------------- ---------------- --------------------------
Supplier A legal entity we can pay supplier_id vat_no, payment_terms,
status, bank_account_id
Purchase order A commitment to buy, approved po_number supplier_id, raised_by,
before goods arrive approved_at, currency
PO line One orderable item on a PO po_number + description, qty, unit
line_no price, gl_code
Goods receipt Evidence something arrived grn_id po_number, received_at,
received_by
Invoice A supplier's demand for invoice_id supplier_id, supplier_ref,
payment gross, net, tax, due_date
Invoice line One charged item invoice_id + description, qty, amount
line_no
Match The link asserting that an match_id invoice_line_id,
invoice line is covered by po_line_id, matched_by,
a PO line and a receipt confidence, method
Payment Money leaving, possibly payment_id run_id, amount, cleared_at
covering several invoices
RELATIONSHIPS
Supplier 1 --- 0..* Purchase order a supplier may have none
Purchase order 1 --- 1..* PO line a PO with no lines is invalid
Purchase order 1 --- 0..* Goods receipt partial deliveries are normal
Supplier 1 --- 0..* Invoice
Invoice 1 --- 1..* Invoice line
Invoice line 0..1 --- 0..1 Match unmatched lines are the 8%
PO line 1 --- 0..* Match one PO line covers several
invoice lines over time
Invoice 0..* --- 0..* Payment a payment covers many invoices
and an invoice may be part paid
DECISIONS THIS MODEL FORCES
- supplier_ref is the supplier's own invoice number. It is not unique
across suppliers and is not our identifier. Uniqueness rule agreed:
supplier_id + supplier_ref, used for duplicate detection.
- Match is an entity, not a foreign key. It carries who matched, how,
and with what confidence, which the audit requirement needs.
- Invoice-to-payment is many-to-many, so a resolving entity is
required. Every project that models it as one-to-many rediscovers
part payments in UAT.
The cardinalities are the substance. Each 0..* is a case that must exist in the
user interface and in the tests — the purchase order with no receipt yet, the
invoice line matched to nothing, the part-paid invoice — and each one is a screen
state or an error message that gets forgotten when the model is only drawn as
boxes and lines.
Promoting Match from a relationship to an entity is the modelling decision worth
being able to defend. The moment the business needs to know who matched an invoice
line, when, by which method and how confidently, the link carries attributes and
is therefore a thing rather than a pointer. Recognising when a relationship has
become an entity is most of the skill in this technique.
The duplicate-detection rule is the requirement the model produced rather than
recorded. Once you notice that the supplier's reference is not globally unique, you
have discovered that duplicate-invoice prevention needs a composite rule, and
duplicate payments are among the most expensive defects in accounts payable.
What the sketch deliberately omits is data types, indexes and nullability. This is
a conceptual model for agreeing meaning with the business, and dragging physical
detail into it moves the conversation to people who cannot validate the meaning,
which is the only thing the model is for.