Skip to content

Delivery notes

A delivery note hands goods to a customer or a construction site. It produces one issue movement per line and one delivery_note record. Signatures can be captured right away or added later, which writes a new version of the note.

sequenceDiagram
  autonumber
  actor U as User
  participant D as Device
  participant S as Server
  U->>D: pick recipient, scan items, sign (optional)
  Note over D: check every line against the stock<br/>left by the lines before
  Note over D: take a number (reserved server number<br/>or device format)
  loop each line
    Note over D: write movement issue,<br/>delivery_note_id, note = number
  end
  Note over D: store signature PNGs and the rendered PDF<br/>as attachments (content-addressed)
  Note over D: write delivery_note with items,<br/>signatures, pdf, template_hlc
  D->>S: HEAD/PUT attachments (signature PNGs, PDF)
  D->>S: push [movement, ..., delivery_note]
  S-->>D: applied, ...
  1. Check. The device checks each line like an issue: quantity available at the line's location, serial numbers in stock there. Lines are checked in order against the stock the previous lines leave, so two lines cannot take the same unit.
  2. Number. The device takes the next number from the delivery note template's numbering: a reserved server number in server mode, otherwise the device format.
  3. Movements. One issue movement per line, with delivery_note_id set to the new note's id, the number in note, and the line's article, location, quantity and serials.
  4. Attachments. Signature images (PNG) and the rendered PDF are stored by their SHA-256.
  5. Note. The delivery_note record with copies of the recipient's address and of each article's item number, name and unit, the location code, the first barcode, movement_id of each line, the signatures, pdf and template_hlc.
  6. Sync. The outbox now holds the movements and the note, in that order. The next sync round uploads the attachments and pushes them.

For a note with one line of 4 access points and the recipient's signature (stamps on node 3F2A9C1B at 10:15):

[
{
"entity": "movement",
"id": "1D5F7A93-6C2E-4B8D-A0F4-8E3B5C7D9A26",
"op": "upsert",
"hlc": "001791800100000-0000-3F2A9C1B",
"data": {
"type": "issue",
"article_id": "8C1F3D2E-5B7A-4A61-9F0E-2B4C6D8E0A13",
"from_location_id": "2B0E6C1A-7D44-4F1B-9C3E-5A8D2F6B1C07",
"quantity": 4,
"note": "LS-2026-3F-0007",
"delivery_note_id": "9B4D6F18-2A7C-4E3B-8D51-6F0A2C4E8B73",
"booked_at": "2026-10-12T10:15:00Z",
"booked_by": "Erika Mustermann"
}
},
{
"entity": "delivery_note",
"id": "9B4D6F18-2A7C-4E3B-8D51-6F0A2C4E8B73",
"op": "upsert",
"hlc": "001791800100000-0001-3F2A9C1B",
"data": {
"number": "LS-2026-3F-0007",
"recipient_id": "5E2A8C14-9D3B-4A7F-B6C0-1E4D7F2A9B35",
"recipient": { "kind": "site", "name": "Northring construction site", "number": "K-10042", "street": "Northring 12", "postal_code": "10115", "city": "Berlin", "country": "Germany", "contact": "Max Mustermann" },
"reference": "Order 2026-118",
"issued_at": "2026-10-12T10:15:00Z",
"issued_by": "Erika Mustermann",
"items": [
{
"position": 1, "article_id": "8C1F3D2E-5B7A-4A61-9F0E-2B4C6D8E0A13", "sku": "100101", "name": "Wireless access point AP-7",
"unit": "Stk", "quantity": 4, "from_location_id": "2B0E6C1A-7D44-4F1B-9C3E-5A8D2F6B1C07", "location_code": "N-A01",
"serials": [], "barcode": "4012345678901", "movement_id": "1D5F7A93-6C2E-4B8D-A0F4-8E3B5C7D9A26"
}
],
"signatures": [
{ "role": "recipient", "name": "Max Mustermann", "signed_at": "2026-10-12T10:16:00Z", "image": "acc6bcb1913432eed9c60781607713d63c802ff23893d35b88b1903ed04c2f50" }
],
"pdf": "c99cb4424e483419efb1abf7772d7e47ec6de50715b1004641b0f9858362015c",
"template_hlc": "001791792000123-0000-3F2A9C1B"
}
}
]

Derived on every device: stock at N-A01 −4; the movement history shows the issue with the note number; the note appears in the recipient's list.

The recipient was not there when the goods left; the issuer signs now and the recipient signs on delivery.

sequenceDiagram
  autonumber
  actor R as Recipient
  participant D as Device
  participant S as Server
  R->>D: signs on the device
  Note over D: replace a signature of the same role,<br/>keep recipient first,<br/>render the PDF again
  Note over D: write delivery_note version 2<br/>(new hlc, new pdf hash)
  D->>S: PUT signature PNG, PUT new PDF
  D->>S: push [delivery_note]
  S-->>D: applied
  Note over S: other devices pull version 2<br/>and download the new PDF

The new version contains the complete note again with the extra signature and a new pdf hash. The movements do not change. If two devices add different signatures to the same note offline, the later version wins and the other signature is lost; the device that lost sees the winning version on its next pull and can sign again.

A server receives the movements and the note as ordinary changes. A server that mirrors delivery notes into an ERP reads the note for the document (number, recipient, lines) and the movements for the stock effect; items[].movement_id and movement.delivery_note_id link them in both directions. Because records can arrive in any order, a mirror must accept a movement whose note it has not seen yet, and the other way round.

The PDF is rendered on the issuing device from the note, the company profile and the delivery note template:

  • header: logo (if show_logo and a logo exists), company name and address (if show_company and a name exists), recipient address, number, date, reference,
  • title (title or the standard title) with the number, then intro with placeholders replaced,
  • the item table with the template's columns, serial numbers under the name when serials is among the columns,
  • the note's note, then closing,
  • signature fields for the roles switched on in signatures, with captions, the captured images, the signer's name and date,
  • footer: footer, then company name, register, tax id and bank, and page numbers.

The PDF is part of the record as an attachment so that every device shows the same document. A device that does not have the PDF yet may render it again from the record.