Releases: bilouro/vendus-python
Releases · bilouro/vendus-python
v0.1.0
Added
create_simplified_invoice(FS) andcreate_receipt(RG), sync + async. An FS is a
simplified invoice paid on issue (requirespayments); an RG (Recibo) acknowledges
payment of one or more invoices, referenced by document number. Both live-validated;
a real RG was cancellable (receipts can be cancelled, unlike FT/FR/NC).modeparameter (DocumentModeenum:NORMAL/TESTS) oncreate_invoice,
create_invoice_receipt,create_credit_note(sync + async) — issue non-fiscal
test-mode documents that Vendus does not communicate to the ATdefault_modeonVendusClient/from_env— applied to every create that omits
mode, so the intended mode is set once (a per-callmodestill overrides it).
modeotherwise inherits the register's mode, which istestson new accountsDocument.tax_authority_id— the AT-generated id, empty until Vendus reports the
document to the AT (lets you confirm a test document was not reported)TaxCategoryenum (NORMAL/INTERMEDIATE/REDUCED/EXEMPT/OTHER) for line-item VATPaymentmodel andlist_payment_methods()(sync + async) — a Fatura-Recibo now
takespayments=[Payment(method_id=..., amount=...)]; method ids are account-specificPaymentMethodmodel returned bylist_payment_methods()CreditLinemodel +linesargument oncreate_credit_note— credit only specific
rows/quantities (partial credit); omit for a full credit, which now skips lines that
are already fully credited. Verified live on a real multi-line invoiceerror_codeattribute on every exception (the Vendus error code, e.g.P001)DocumentTypenow covers the fulldocuments/typesreference (FG,GA,GD,GR,
DC,PF,OT,EC) plusRG(observed live)- Docs: a dedicated Payment methods page (
list_payment_methods, thePaymentmodel,
split payments,date_due), all live-validated list_registers()(sync + async) and theRegistermodel — read the account's
registers (caixas) to discover aregister_idand its working mode. Registers are
read-only via the API (configured in the Vendus backoffice)DocumentType.UNKNOWN— forward-compat sentinel so the SDK does not crash on type
codes the API returns but the enum does not model (e.g.RG); the raw code stays in
raw_response- Live integration tests (
tests/integration/, excluded by default): FT and FR in test
mode, plus read-onlylist_payment_methods/list/getagainst real documents - Initial project skeleton
VendusClientwith HTTP Basic AuthDocumentsService.create_invoice(sync + async)DocumentsService.create_simplified_invoice(sync + async)DocumentsService.create_invoice_receipt(sync + async)DocumentsService.create_receipt(sync + async)DocumentsService.create_credit_note(sync + async)get/list/cancel(sync + async)ClientDatasupports three shapes: with NIF, name-only, or omitted (final consumer)- Pydantic v2 models for documents, items, taxes, inline client data
- Portuguese NIF validation
- PII redaction filter for logging
- HttpTransport with conditional POST retries (R3)
- 100 unit tests with
respxmocks (94% coverage), plus live integration tests - Bilingual documentation (PT/EN) with mkdocs-material + i18n
- 10 runnable examples, including an all-scenarios reference
- CI workflow (ruff, mypy --strict, pytest on Python 3.9–3.13)
- Docs auto-deploy to GitHub Pages
- Issue/PR templates and Dependabot config
Changed
- A Vendus
P001(field-validation error, returned with HTTP 403) now raises
ValidationErrorinstead of the misleadingAuthorizationError. DocumentType.QUOTEis now"OT"(was the incorrect"OR") andDocumentType.RECEIPT
is"RG"(observed live; was the unverified"RC"), aligning with the Vendus reference.- Breaking:
DocumentItem.tax_rate(aDecimalpercentage) is nowtax_category
(aTaxCategoryenum). Vendus classifies line-item VAT by category (tax_id:
NOR/INT/RED/ISE/OUT), not by a numeric rate — the rate is defined by the category in
the merchant's Vendus configuration. - Breaking:
cancel(document_id)no longer takes areason— the Vendus document
PATCH endpoint has no field for a cancellation reason. It now also fetches the document
and refuses to cancel FT/FR/NC (fiscal documents cannot be cancelled; reverse them
with a credit note), raisingValidationErrorwith that guidance. - Breaking:
create_credit_note(reference_document_id, reason, ...)no longer takes
register_id/items/client. It fetches the original and credits its full set of
lines (the original must be a real, retrievable document). The previous signature never
worked: Vendus rejected the old top-levelreference_document_idfield. - Breaking:
create_invoice_receipt(...)now requirespayments— an FR records
payment on issue and Vendus rejects it otherwise. - Docs: replaced the "Sandbox" section with a sourced "Testing" section. Vendus has
no separate sandbox host; testing is done via document-level test mode. Corrects a
prior unsourced claim that every call creates real fiscal documents.
Fixed
- Line items now send the field names the real Vendus API actually accepts — found by
live validation, which returnedP001for the old names:tax_id(wastax_rate),
discount_percentage(wasdiscount),id(wasproduct_id).create_invoicehad
never succeeded against the live API before this. cancelno longer sendsnotes(rejected by the document PATCH endpoint, which
accepts onlystatus/mode).- Credit notes now build the wire body Vendus accepts — found live: each credit line
references the original viareference_document(number + row) and the original line
id, instead of the rejected top-levelreference_document_id. _parse_documenttolerates unknown document type codes instead of raising
(the live account returnedRG, which is absent from the documents/types reference).create_credit_noteraises a clearerNotFoundErrorwhen the original can't be read
(e.g. a test-mode document), explaining it must be a real, retrievable document.- Error-message extraction for the
{"errors": [{"code", "message"}]}body shape — the
message (not the raw dict) is now used for the exception text.
Quality
mypy --strictpasses with zero errorsruff check/ruff formatclean