Project: Invoice Date Extractor
Every failure mode at once: dates, numbers, and large state. Extract with Jev, compute in code.
This is the capstone, and it is deliberately the ugliest problem in the course. An invoice arrives as a scanned PDF that some upstream OCR step has turned into a wall of text. You need the issue date, the due date, and the total. Every documented failure mode is present at once: dates that Jev reads as text rather than ordered quantities, amounts that Jev cannot add, and a state stuffed with remittance boilerplate, terms and conditions, and a footer about the supplier’s environmental policy.
The discipline that makes it work is one sentence. Jev extracts, code computes. Every time you feel the pull to ask the model for a number, a comparison, or a sum, that is the failure mode announcing itself.
Cut the state down first
Before a single question is asked, the invoice text gets shrunk. Not because of the 32k limit, which a one-page invoice will not approach, but because context rot starts biting long before the ceiling and every line of boilerplate is a distractor competing for the judgment.
import re
BOILERPLATE = re.compile(
r"(terms and conditions|remittance advice|privacy policy"
r"|please do not reply|registered office|environmental)",
re.IGNORECASE,
)
AMOUNT = re.compile(r"[$£€]\s?\d[\d,]*\.\d{2}")
DATE_LINE = re.compile(r"(date|due|issued|invoice)", re.IGNORECASE)
def build_state(raw: str) -> dict:
lines = [ln.strip() for ln in raw.splitlines() if ln.strip()]
kept = [ln for ln in lines if not BOILERPLATE.search(ln)]
# Code finds the candidates. Jev never generates a number or a date string.
amount_candidates = sorted({m.group(0) for ln in kept for m in AMOUNT.finditer(ln)})
date_lines = [ln for ln in kept if DATE_LINE.search(ln)]
return {
"invoice": {
"header": kept[:25],
"date_lines": date_lines,
"amount_candidates": amount_candidates,
}
}Look at what the regex did to the shape of the problem. Amounts are no longer something the model has to find, read, or transcribe. They are a numbered list of strings, and the only thing left for Jev is the one genuinely semantic question: which of these candidates is the invoice total, as opposed to a line item, a subtotal, a tax figure, or the previous balance carried forward.
Full lesson
Keep reading Project: Invoice Date Extractor
The rest of this lesson — including the interactive exercises and the worked project — is part of Jagged Edges.
- ✓Every lesson in all three courses
- ✓Interactive builders, graders, and playgrounds
- ✓1,000 live Jev credits, for the courses and the playground
- ✓Project source you can run yourself
- ✓Free updates as Jev ships new versions
Already bought them? Sign in to unlock — no need to buy twice.