← All ivy-agents
IVYXSTUDIO · IVY AGENT
S

Supplier invoice

ivy.agent.supplier-invoice · v0.1.0

ivyx

Reads a supplier's invoice (ulazna faktura), however it arrived (by e-mail, dropped into a folder or posted by a webhook): a model reads the text after a person has looked at the e-mail, then the numbers are checked against themselves (net plus VAT is the total, a dated and numbered invoice from a named supplier). What comes out is the invoice's fields and lines with kind: invoice, which IVYX Finance turns into a draft DOB voucher. An e-mail is marked read when the numbers added up.

Steps

In the order the agent's file lists them, each with where its inputs come from and the values the file fixes. A branch or a loop is a step too.

  1. 01
    Read the invoice's text
    ivy.node.pdf-text

    Extracts the text of a PDF file, page by page and as one text, with the page count.

    takes
    path from the agent's input
    returns
    page_count
    Ivy Node
  2. 02
    Read the invoice with a model

    The context is the text of a supplier's invoice (faktura) to the firm, in Montenegrin or English. Return a JSON object with: supplier (the supplier's name as printed, the legal form kept), supplier_pib (the supplier's tax number, PIB, digits only, or empty), iban (the supplier's bank account or IBAN as printed, or empty), number (the invoice number as printed), date (the invoice date, YYYY-MM-DD), due_date (the payment due date, YYYY-MM-DD, or empty), currency (ISO 4217, EUR when the invoice is in euros), net (the amount before VAT, a number), vat (the VAT amount, a number), total (the amount to pay, a number; decimal comma and thousand separators converted), description (one short line saying what was bought, from the invoice's own words), and lines: one object per invoice line, in the order printed, each with description, quantity (a number), unit_price (a number) and amount (a number). Copy the numbers as printed; do not compute a total the invoice does not print, and do not invent lines.

    takes
    context from step 1, text
    returns
    supplier, supplier_pib, iban, number, date, due_date, currency, net, vat, total, description, lines
    Model turn
  3. 03
    Do the numbers add up?
    ivy.node.invoice-check

    Checks what a model read off a supplier invoice against itself: the net and the VAT add up to the total, the date is a date, the number and the supplier are there.

    takes
    supplier from step 2, output.supplier
    number from step 2, output.number
    date from step 2, output.date
    net from step 2, output.net
    vat from step 2, output.vat
    total from step 2, output.total
    returns
    kind, verified, problems
    Ivy Node
  4. 04
    Did they?

    Lets what follows run only when verified of step 3 is true.

    Branch
  5. 05
    Did it come by e-mail?
    ivy.node.has-mail

    Says whether a statement came with an e-mail to mark: true when both the mail's uid and the mailbox login are known, false for a file dropped into a folder or posted by a webhook.

    takes
    uid from the agent's input
    username from the agent's input
    Ivy Node
  6. 06
    Is there an e-mail to mark?

    Lets what follows run only when has_mail of step 5 is true.

    Runs only on the then branch of step 4.

    Branch
  7. 07
    Mark the e-mail read
    ivy.node.mail-mark

    Marks messages of a mailbox folder as read or unread, moves them to another folder or adds a Gmail label, by uid over IMAP, and returns how many it changed.

    Runs only on the then branch of step 6.

    takes
    uids from the agent's input, uid
    imap_host from the agent's input
    imap_port from the agent's input
    use_ssl from the agent's input
    username from the agent's input
    folder from the agent's input
    mail_password from the agent's input
    set
    seen true
    returns
    mail_marked
    Ivy Node

Nodes it brings

Adding this agent in IVYX Studio adds these nodes with it. A node your workspace already has is kept as it is, even at another version.

What it touches

Collected from what each of its nodes declares, plus the model call when a step is a model turn. A declaration is the author's statement, and it is what policy rules select on.

Calls a modelNetwork

Inputs

FieldTypeDescription
pathrequiredstringThe invoice file, a PDF, as a path under the project.
attachmentstringThe attachment's file name.
fromstringWho sent the e-mail.
subjectstringThe e-mail's subject.
receivedstringWhen the e-mail arrived, ISO 8601.
uidstringThe e-mail's id in the mailbox.
imap_hoststringThe mailbox the e-mail is in, as the source that saw it was configured; the agent marks the e-mail there.
imap_portintegerThe mailbox's IMAP port.
use_sslbooleanWhether the mailbox is reached over SSL.
usernamestringThe mailbox's login name.
folderstringThe folder the e-mail is in.
mail_passwordstringThe mailbox password as a reference to a stored secret ({ $secret: name }), handed on by the source that read the mail; the gateway resolves it inside the mark step and never records the value.

Outputs

FieldTypeDescription
kindstringinvoice: what this output is, for a receiver that takes several kinds.
supplierstringThe supplier's name as printed.
supplier_pibstringThe supplier's tax number (PIB), when printed.
ibanstringThe supplier's account or IBAN, when printed.
numberstringThe invoice number as printed.
datestringThe invoice date, YYYY-MM-DD.
due_datestringWhen it is due, YYYY-MM-DD, when printed.
currencystringISO 4217.
netnumberThe amount before VAT.
vatnumberThe VAT amount.
totalnumberThe amount to pay.
descriptionstringWhat was bought, in one line.
linesarrayThe invoice's lines as printed.
page_countintegerHow many pages the invoice has.
verifiedbooleanTrue when the net and the VAT add up to the total and the invoice names its supplier, number and date; false when a person should look.
problemsarrayWhat did not hold, one sentence each.
mail_markedinteger1 when the e-mail was marked read: the numbers added up; absent for a file that came some other way.

Tests

2 of 2 test cases passed on Oct 25, 2026, in the publisher's own environment, before this version was published. The registry keeps that record; it does not run the cases again.

Requires: python:3.9, pypdf, a model core

  • adds-up

    A supplier's invoice that adds up is read into its fields and verified, with nothing to mark since it came as a file.

    given
    path samples/faktura-2026-117.pdf
    expects
    verified equals true
    problems equals []
    number equals 2026-117
    net equals 1000
    vat equals 210
    total equals 1210
    supplier matches MANUFAKTUR|Manufaktur
  • off-total

    An invoice whose total is not its net plus VAT is read and left unverified, the problem said in a sentence.

    given
    path samples/faktura-2026-118.pdf
    expects
    verified equals false
    total equals 1300
    problems.0 matches add up to 1210.00, not the total 1300.00