[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs:managed":3},{"versions":4,"version":26,"nav":28,"path":88,"kind":106,"page":107},[5,10,13,16,18,20,22,24],{"name":6,"label":7,"prefix":8,"channel":9},"0.7","0.7 (latest)","","latest",{"name":11,"label":12,"prefix":11,"channel":11},"next","next (unreleased)",{"name":14,"label":14,"prefix":14,"channel":15},"0.6","old",{"name":17,"label":17,"prefix":17,"channel":15},"0.5",{"name":19,"label":19,"prefix":19,"channel":15},"0.4",{"name":21,"label":21,"prefix":21,"channel":15},"0.3",{"name":23,"label":23,"prefix":23,"channel":15},"0.2",{"name":25,"label":25,"prefix":25,"channel":15},"0.1",{"name":6,"label":7,"prefix":8,"channel":9,"base":27},"\u002Fdocs",[29,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,91,94,97,100,103],{"slug":30,"title":31,"preview":32},"index","Home",false,{"slug":34,"title":35,"preview":32},"getting-started","Getting started",{"slug":37,"title":38,"preview":32},"concepts","E-invoicing basics",{"slug":40,"title":41,"preview":32},"examples","Examples",{"slug":43,"title":44,"preview":32},"building-invoices","Building invoices",{"slug":46,"title":47,"preview":32},"formats","Formats and profiles",{"slug":49,"title":50,"preview":32},"validation","Validation",{"slug":52,"title":53,"preview":32},"templates","Templates and design",{"slug":55,"title":56,"preview":32},"documents","Quotes and other documents",{"slug":58,"title":59,"preview":32},"reading","Reading incoming invoices",{"slug":61,"title":62,"preview":32},"laravel","Laravel integration",{"slug":64,"title":65,"preview":32},"configuration","Configuration",{"slug":67,"title":68,"preview":32},"commands","Artisan commands",{"slug":70,"title":71,"preview":32},"testing","Testing",{"slug":73,"title":74,"preview":32},"country-packs","Country packs",{"slug":76,"title":77,"parent":74,"preview":32},"country-at","Austria",{"slug":79,"title":80,"parent":74,"preview":32},"country-be","Belgium",{"slug":82,"title":83,"parent":74,"preview":32},"country-ch","Switzerland",{"slug":85,"title":86,"parent":74,"preview":32},"country-fr","France",{"slug":88,"title":89,"preview":90},"managed","Managed layer (preview)",true,{"slug":92,"title":93,"preview":32},"troubleshooting","Troubleshooting",{"slug":95,"title":96,"preview":32},"faq","FAQ",{"slug":98,"title":99,"preview":32},"compatibility","Versioning and compatibility",{"slug":101,"title":102,"preview":32},"field-reference","Field reference",{"slug":104,"title":105,"preview":32},"ai","AI assistants","page",{"title":89,"description":108,"html":109,"headings":110,"editUrl":394,"markdownUrl":395,"prev":396,"next":397},"The Managed layer stores your invoices in the database and handles what happens after you build them: numbering, issuing, archiving, cancelling, correcting, sending, and deleting them after the retention period.","\u003Ch1 id=\"managed-layer-quittiomanaged\">Managed layer (\u003Ccode>quittio\u002Fmanaged\u003C\u002Fcode>)\u003C\u002Fh1>\n\u003Cblockquote class=\"q-doc-note\">\n\u003Cp>\u003Cstrong>Preview of an unreleased package.\u003C\u002Fstrong> \u003Ccode>quittio\u002Fmanaged\u003C\u002Fcode> is not released yet, and nothing on\nthis page can be installed today. The page describes the package as it is planned to ship:\ncommercially licensed and distributed separately from the open source packages. Names,\nconfiguration keys and behaviour may still change before the release.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>The Managed layer stores your invoices in the database and handles what happens after you\nbuild them: numbering, issuing, archiving, cancelling, correcting, sending, and deleting them\nafter the retention period. You need it when your Laravel application issues the invoices\nitself and has to keep them. Read \u003Ca href=\"\u002Fdocs\u002Fgetting-started\">Getting started\u003C\u002Fa> first: the Managed\nlayer uses the same invoice builder. Terms such as e-invoice, format and profile are explained\nin \u003Ca href=\"\u002Fdocs\u002Fconcepts\">E-invoicing basics\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"what-managed-adds\">What Managed adds\u003Ca class=\"q-doc-anchor\" href=\"#what-managed-adds\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The open source packages (\u003Ccode>quittio\u002Fcore\u003C\u002Fcode>, \u003Ccode>quittio\u002Flaravel\u003C\u002Fcode> and a country pack) build,\ncalculate, validate and render an invoice. What happens with the result is up to you. The\nManaged layer adds the records and rules around it:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Task\u003C\u002Fth>\n\u003Cth>Without Managed you …\u003C\u002Fth>\n\u003Cth>With Managed …\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Seller\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">set your company in the \u003Ccode>seller\u003C\u002Fcode> section of \u003Ccode>config\u002Fquittio.php\u003C\u002Fcode>, or pass \u003Ccode>-&gt;seller()\u003C\u002Fcode> per invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">keep one or more issuer profiles in the database, each with bank accounts, defaults, texts, design and numbering (\u003Ca href=\"#issuer-profiles\">Issuer profiles\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Customers\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">pass the buyer data for every invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">still pass the buyer data, and every invoice also links to your own models, e.g. \u003Ccode>$user-&gt;invoices()\u003C\u002Fcode> (\u003Ca href=\"#customers-and-references\">Customers and references\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Invoice numbers\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">set \u003Ccode>-&gt;number('RE-2026-0042')\u003C\u002Fcode> yourself and make sure numbers are unique and have no gaps\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">get the next number when you issue, from a pattern such as \u003Ccode>RE-{Y}-{seq:4}\u003C\u002Fcode>, gapless and unique per company (\u003Ca href=\"#numbering\">Numbering\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Storing invoices\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">store the data, PDF and XML yourself\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">keep drafts and issued invoices as rows; drafts can be changed, previewed and deleted (\u003Ca href=\"#drafts\">Drafts\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>After issuing\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">have nothing that stops your code from changing an invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">cannot change an issued invoice: the model, its query builder and optional database triggers block it (\u003Ca href=\"#immutability\">Immutability\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Archive\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">save files with \u003Ccode>$result-&gt;save()\u003C\u002Fcode>, which overwrites existing files\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">get a write-once archive with SHA-256 hashes, document versions and an integrity check (\u003Ca href=\"#rendering-and-archive\">Rendering and archive\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Cancellations and corrections\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">render a cancellation with \u003Ccode>$result-&gt;cancel('ST-…')\u003C\u002Fcode>, track what was cancelled and pass the history for partial cancellations\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">call \u003Ccode>$invoice-&gt;cancel()\u003C\u002Fcode>, \u003Ccode>cancelPartially()\u003C\u002Fcode> or \u003Ccode>correct()\u003C\u002Fcode>; numbers, links, VAT and status are kept for you (\u003Ca href=\"#cancellations-and-corrections\">Cancellations and corrections\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Sending\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">write your own Mailable\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">call \u003Ccode>$invoice-&gt;send()\u003C\u002Fcode>, with a log of every delivery attempt (\u003Ca href=\"#delivery\">Delivery\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Audit and retention\u003C\u002Ftd>\n\u003Ctd data-label=\"Without Managed you …\">keep your own records\u003C\u002Ftd>\n\u003Ctd data-label=\"With Managed …\">get an append-only audit log, a retention period per invoice, a legal hold and a command that deletes expired invoices (\u003Ca href=\"#audit-log\">Audit log\u003C\u002Fa>, \u003Ca href=\"#retention-and-deletion\">Retention and deletion\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The Managed layer uses only the public API of \u003Ccode>quittio\u002Flaravel\u003C\u002Fcode> and \u003Ccode>quittio\u002Fcore\u003C\u002Fcode>:\neverything it produces could also be produced by hand with the core.\u003C\u002Fp>\n\u003Ch3 id=\"when-to-use-it\">When to use it\u003Ca class=\"q-doc-anchor\" href=\"#when-to-use-it\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Use only the open source packages when another system (an ERP, accounting software or a\nshop) keeps the invoices and assigns their numbers, and Quittio only produces the files.\u003C\u002Fp>\n\u003Cp>Use the Managed layer when your application is the system that issues the invoices. Then the\nnumbers must be unique and without gaps, an issued invoice must never change, and the\ndocuments must be kept for the retention period. In Germany these rules come from the VAT Act\n(UStG), the Fiscal Code (AO) and the \u003Ca href=\"\u002Fdocs\u002Fconcepts#german-terms\">GoBD\u003C\u002Fa>, the German rules for\ndigital bookkeeping; invoices must be kept for 8 years.\u003C\u002Fp>\n\u003Cp>With the Managed layer installed, \u003Ccode>Quittio::invoice()\u003C\u002Fcode> takes the seller from the current\nissuer profile instead of \u003Ccode>config\u002Fquittio.php\u003C\u002Fcode> (see \u003Ca href=\"#the-issuer-builder\">The issuer builder\u003C\u002Fa>).\nIt therefore needs an issuer profile and throws \u003Ccode>IssuerNotFound\u003C\u002Fcode> without one (see\n\u003Ca href=\"#current-issuer\">Current issuer\u003C\u002Fa>). The installer asks for the first profile.\u003C\u002Fp>\n\u003Cp>Not part of version 1.0: recording payments (the payment columns exist, see\n\u003Ca href=\"#payment-status\">Payment status\u003C\u002Fa>), bank reconciliation, dunning runs (automatic payment\nreminders), subscriptions and recurring invoices, advance and final invoices, self-billing,\ninbound invoices, transmission over the \u003Ca href=\"\u002Fdocs\u002Fconcepts#formats\">Peppol network\u003C\u002Fa> and exports for\nDATEV (German accounting software). See \u003Ca href=\"#known-limitations\">Known limitations\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"overview\">Overview\u003Ca class=\"q-doc-anchor\" href=\"#overview\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The Managed layer works with these records:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Concept\u003C\u002Fth>\n\u003Cth>Model\u003C\u002Fth>\n\u003Cth>Description\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Issuer profile\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Issuer\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Your company as seller: master data, bank accounts, defaults, texts, branding, numbering\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Draft\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Invoice\u003C\u002Fcode> (status \u003Ccode>draft\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Freely changeable, no number, can be deleted\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Issued invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Invoice\u003C\u002Fcode> (status \u003Ccode>issued\u003C\u002Fcode> …)\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Number, data snapshot, dates and totals frozen; archived as XML and\u002For PDF\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Cancellation, correction\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Invoice\u003C\u002Fcode> (kind \u003Ccode>cancellation\u003C\u002Fcode>, \u003Ccode>correction\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Invoices of their own, with their own numbers, that refer to the original\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Relation\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>InvoiceRelation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Link from a cancellation or correction to the original, with the cancelled lines and VAT\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Sequence\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Sequence\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Counter of a number sequence (\u003Ccode>{issuer}:{sequence}:{period}\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Delivery\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Delivery\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">One delivery attempt by mail\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Audit entry\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>AuditLog\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Append-only record of every business relevant action\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>An invoice starts as a draft. \u003Ccode>issue()\u003C\u002Fcode> gives it a number and freezes it. After that, only\ncancellations and corrections change its status:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>text\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan>draft ──issue()──▶ issued ──cancelPartially()──▶ partially_cancelled ──▶ … ──▶ cancelled\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:23ch;text-indent:-23ch\">\u003Cspan>                     └──────── cancel() or an issued correction ─────────────▶ cancelled\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ch2 id=\"installation\">Installation\u003Ca class=\"q-doc-anchor\" href=\"#installation\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>These steps apply once \u003Ccode>quittio\u002Fmanaged\u003C\u002Fcode> is released.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">composer\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> require\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio\u002Fmanaged\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:install\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --managed\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> vendor:publish\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --tag=quittio-managed-triggers\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">   # recommended for production\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> migrate\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Requirements: PHP 8.3 or later, Laravel 13, and \u003Ccode>quittio\u002Fcore\u003C\u002Fcode> and \u003Ccode>quittio\u002Flaravel\u003C\u002Fcode> in the\nsame version.\u003C\u002Fp>\n\u003Cp>\u003Ccode>quittio:install --managed\u003C\u002Fcode> runs these steps (see also \u003Ca href=\"\u002Fdocs\u002Fcommands\">Artisan commands\u003C\u002Fa>):\u003C\u002Fp>\n\u003Col>\n\u003Cli>It publishes \u003Ccode>config\u002Fquittio.php\u003C\u002Fcode> and \u003Ccode>config\u002Fquittio-managed.php\u003C\u002Fcode> (\u003Ccode>--force\u003C\u002Fcode> overwrites\nthem).\u003C\u002Fli>\n\u003Cli>It publishes the migrations, unless they were published before. It recognises them by\ntheir file name, because \u003Ccode>vendor:publish\u003C\u002Fcode> gives migrations a new timestamp each time.\u003C\u002Fli>\n\u003Cli>It asks &quot;Run the migrations now?&quot; and runs \u003Ccode>migrate --force\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>If no issuer profile exists, it asks for the first one: key (default \u003Ccode>default\u003C\u002Fcode>), company\nname (required), street and number, postcode, city, country (default \u003Ccode>DE\u003C\u002Fcode>), VAT id, tax\nnumber (asked only without a VAT id), e-mail address for invoices, IBAN, BIC (asked only\nwith an IBAN) and time zone. The e-mail address is stored as contact e-mail and as\nelectronic address with scheme \u003Ccode>EM\u003C\u002Fcode> (e-mail). The time zone defaults to \u003Ccode>app.timezone\u003C\u002Fcode>;\nwhen that is \u003Ccode>UTC\u003C\u002Fcode>, to \u003Ccode>Europe\u002FBerlin\u003C\u002Fcode> for Germany and \u003Ccode>UTC\u003C\u002Fcode> for other countries. The\nprofile is marked as default.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>With \u003Ccode>--no-interaction\u003C\u002Fcode>, the migrations run without asking and no issuer is created. The\ninstaller does not publish the immutability triggers: publish them with the third command\nabove (see \u003Ca href=\"#database-triggers\">Database triggers\u003C\u002Fa>).\u003C\u002Fp>\n\u003Cp>The migrations use the database connection and table prefix of \u003Ccode>config\u002Fquittio-managed.php\u003C\u002Fcode>\n(\u003Ccode>connection\u003C\u002Fcode>, \u003Ccode>table_prefix\u003C\u002Fcode>, see \u003Ca href=\"#database-settings\">Database settings\u003C\u002Fa>): set both before\nmigrating. To change them, answer &quot;no&quot; when the installer asks to run the migrations, edit\nthe configuration, run \u003Ccode>php artisan migrate\u003C\u002Fcode> and run the installer again for the issuer\nprofile.\u003C\u002Fp>\n\u003Cp>The country pack of the issuer's country supplies the defaults for numbering, retention and\ncorrections (e.g. \u003Ccode>quittio\u002Fcountry-de\u003C\u002Fcode>, see \u003Ca href=\"\u002Fdocs\u002Fcountry-packs\">Country packs\u003C\u002Fa>). For a country\nwithout a pack, generic rules apply: pattern \u003Ccode>INV-{Y}-{seq:4}\u003C\u002Fcode>, yearly reset, retention 10\nyears after the end of the year, cancellation by credit note, correction by cancel and\nreissue (see \u003Ca href=\"#cancellations-and-corrections\">Cancellations and corrections\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch3 id=\"databases\">Databases\u003Ca class=\"q-doc-anchor\" href=\"#databases\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Supported: SQLite, MySQL 8 \u002F MariaDB and PostgreSQL (the test matrix uses MySQL 8.4 and\nPostgreSQL 16).\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Database\u003C\u002Fth>\n\u003Cth>Notes\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>SQLite\u003C\u002Ftd>\n\u003Ctd data-label=\"Notes\">Set \u003Ccode>'transaction_mode' =&gt; 'IMMEDIATE'\u003C\u002Fcode> and a \u003Ccode>busy_timeout\u003C\u002Fcode> (e.g. \u003Ccode>5000\u003C\u002Fcode>) on the connection in \u003Ccode>config\u002Fdatabase.php\u003C\u002Fcode>. Without the immediate transaction mode, the numbering logs a warning once per process. Concurrent issuing is then retried, but this is not recommended for production.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>MySQL, MariaDB\u003C\u002Ftd>\n\u003Ctd data-label=\"Notes\">\u003Ccode>number\u003C\u002Fcode>, \u003Ccode>number_space\u003C\u002Fcode> and the archive paths use the collation \u003Ccode>utf8mb4_bin\u003C\u002Fcode> (case sensitive, as on the other databases). Creating the triggers with binary logging needs the \u003Ccode>TRIGGER\u003C\u002Fcode> privilege and \u003Ccode>log_bin_trust_function_creators\u003C\u002Fcode> (or \u003Ccode>SUPER\u003C\u002Fcode>). MySQL fires no triggers on \u003Ccode>TRUNCATE\u003C\u002Fcode> (see \u003Ca href=\"#what-is-not-prevented\">What is not prevented\u003C\u002Fa>).\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>PostgreSQL\u003C\u002Ftd>\n\u003Ctd data-label=\"Notes\">The invoice data is stored as \u003Ccode>jsonb\u003C\u002Fcode>. The triggers also reject \u003Ccode>TRUNCATE\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"queue-worker\">Queue worker\u003Ca class=\"q-doc-anchor\" href=\"#queue-worker\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Issued invoices are rendered by the job \u003Ccode>RenderInvoiceDocuments\u003C\u002Fcode> on the queue \u003Ccode>quittio\u003C\u002Fcode> (see\n\u003Ca href=\"#rendering-and-archive\">Rendering and archive\u003C\u002Fa>). Run a worker that listens to it, e.g.\n\u003Ccode>php artisan queue:work --queue=quittio,default\u003C\u002Fcode>, or set \u003Ccode>queue.render_sync\u003C\u002Fcode> to render in the\nrequest.\u003C\u002Fp>\n\u003Ch3 id=\"morph-map\">Morph map\u003Ca class=\"q-doc-anchor\" href=\"#morph-map\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Invoices, deliveries and the audit log keep references to your own models (\u003Ccode>billable\u003C\u002Fcode>,\n\u003Ccode>invoiceable\u003C\u002Fcode>, \u003Ccode>causer\u003C\u002Fcode>, \u003Ccode>tenant\u003C\u002Fcode>, see \u003Ca href=\"#customers-and-references\">Customers and references\u003C\u002Fa>)\nfor many years. Eloquent stores such polymorphic references with the class name, unless a\nmorph map gives the class a short name. Register a morph map for your models\n(\u003Ccode>Relation::enforceMorphMap()\u003C\u002Fcode>), so that renaming a class does not break old references.\u003C\u002Fp>\n\u003Cp>The package registers \u003Ccode>quittio.issuer\u003C\u002Fcode>, \u003Ccode>quittio.invoice\u003C\u002Fcode>, \u003Ccode>quittio.sequence\u003C\u002Fcode> and\n\u003Ccode>quittio.delivery\u003C\u002Fcode> itself (for the configured model classes); \u003Ccode>enforceMorphMap()\u003C\u002Fcode> merges your\nentries with these.\u003C\u002Fp>\n\u003Ch2 id=\"a-first-invoice\">A first invoice\u003Ca class=\"q-doc-anchor\" href=\"#a-first-invoice\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>This walkthrough creates an issuer profile, a draft, an issued invoice and its cancellation.\nIt assumes that the installation is done and a queue worker runs (or \u003Ccode>queue.render_sync\u003C\u002Fcode> is\nset).\u003C\u002Fp>\n\u003Cp>\u003Cstrong>1. Issuer profile.\u003C\u002Fstrong> The installer asks for the first one. To create it in code instead,\ne.g. in a seeder:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Builder\\Party\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$issuer \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">setSellerParty\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Party\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">make\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Muster GmbH'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">vatId\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'DE123456789'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">address\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Hauptstraße 1'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'12345'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Musterstadt'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'DE'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">electronicAddress\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'rechnung@muster.de'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'EM'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">buildSeller\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'key'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'default'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,                                  \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F part of the sequence keys and archive paths\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'timezone'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'Europe\u002FBerlin'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'bank_accounts'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [[\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'iban'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'DE02120300000000202051'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'bic'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'BYLADEM1001'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'name'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'Muster GmbH'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">]],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'defaults'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'locale'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'de'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'due_days'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 14\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'is_default'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> true\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,                                \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F Issuer::current() returns it\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Cstrong>2. Draft.\u003C\u002Fstrong> Build the invoice as in \u003Ca href=\"\u002Fdocs\u002Fgetting-started\">Getting started\u003C\u002Fa>, but pass the\nbuilder to \u003Ccode>Invoice::draft()\u003C\u002Fcode> instead of calling \u003Ccode>render()\u003C\u002Fcode>. \u003Ccode>Quittio::invoice()\u003C\u002Fcode> starts with\nthe seller, bank account and defaults of the current issuer. Leave out \u003Ccode>-&gt;number()\u003C\u002Fcode> and\n\u003Ccode>-&gt;issueDate()\u003C\u002Fcode>: \u003Ccode>issue()\u003C\u002Fcode> sets both.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Builder\\Party\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Enums\\UnitCode\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Laravel\\Facades\\Quittio\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draft\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Quittio\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">buyer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Party\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">make\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Kunde AG'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">vatId\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'DE987654321'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">address\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Bahnhofstraße 5'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'54321'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Beispielstadt'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'DE'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">electronicAddress\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'ap@kunde.de'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'EM'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">deliveryDate\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'2026-09-30'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">line\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Consulting'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">netPrice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'120.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">quantity\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">8\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">unit\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">UnitCode\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Hour\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$preview \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">preview\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F PDF with the watermark \"ENTWURF\" (draft), no number;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:47ch;text-indent:-47ch\">\u003Cspan style=\"color:#8B949E\">                                             \u002F\u002F return it from a controller to show it in the browser\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Cstrong>3. Issue.\u003C\u002Fstrong> \u003Ccode>issue()\u003C\u002Fcode> validates the invoice, takes the next number and freezes the data.\nThe PDF and XML are rendered and archived by the queued job. If the validation fails, a\n\u003Ccode>ValidationException\u003C\u002Fcode> is thrown and no number is used up.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                  \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F today in the issuer's time zone\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">number;                            \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F RE-2026-0001 (German default pattern)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Cstrong>4. Send.\u003C\u002Fstrong> \u003Ccode>send()\u003C\u002Fcode> mails the archived documents. Without an address, it takes the buyer's\ne-mail address, here \u003Ccode>ap@kunde.de\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">send\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Cstrong>5. Cancel.\u003C\u002Fstrong> An issued invoice never changes. To reverse it, issue a cancellation: an\ninvoice of its own, with its own number, that refers to the original.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$cancellation \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">cancel\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">reason\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Charged twice'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$cancellation\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">number;                       \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F RE-2026-0002 (cancellations share the sequence by default)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">status;                            \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F Status::Cancelled\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Next steps: link invoices to your customer model\n(\u003Ca href=\"#customers-and-references\">Customers and references\u003C\u002Fa>), choose a number pattern\n(\u003Ca href=\"#numbering\">Numbering\u003C\u002Fa>), cancel only some lines\n(\u003Ca href=\"#partial-cancellation\">Partial cancellation\u003C\u002Fa>) or correct an invoice\n(\u003Ca href=\"#corrections\">Corrections\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch2 id=\"issuer-profiles\">Issuer profiles\u003Ca class=\"q-doc-anchor\" href=\"#issuer-profiles\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>An issuer profile is the company that issues the invoices. Every invoice belongs to exactly\none issuer, and the issuer is always its seller. The profile replaces the \u003Ccode>seller\u003C\u002Fcode> section of\n\u003Ccode>config\u002Fquittio.php\u003C\u002Fcode> and adds bank accounts, defaults, texts, design and numbering. Most\napplications need one profile. Create more for several companies, brands or tenants.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Builder\\Party\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$issuer \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">setSellerParty\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Party\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">make\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Muster GmbH'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">vatId\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'DE123456789'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">address\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Hauptstraße 1'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'12345'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Musterstadt'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'DE'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">electronicAddress\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'rechnung@muster.de'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'EM'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">buildSeller\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'key'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'default'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'timezone'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'Europe\u002FBerlin'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'bank_accounts'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [[\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'iban'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'DE02120300000000202051'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'bic'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'BYLADEM1001'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'name'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'Muster GmbH'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">]],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'defaults'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'locale'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'de'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'due_days'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 14\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'currency'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'EUR'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'format'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'zugferd'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'tax_settings'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'small_business'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> false\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'branding'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'logo'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> storage_path\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'app\u002Flogo.png'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">), \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'colors'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'primary'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> '#0f766e'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">]],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#8B949E\">    \u002F\u002F German texts on the PDF: \"Thank you for your order.\", \"Payable within 14 days.\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'texts'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'de'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'intro'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'Vielen Dank für Ihren Auftrag.'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'payment_terms'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'Zahlbar innerhalb von 14 Tagen.'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">]],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'numbering'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'pattern'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'RE-{Y}-{seq:5}'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'is_default'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> true\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>setSellerParty()\u003C\u002Fcode> stores the seller (\u003Ccode>Party::make()\u003C\u002Fcode> returns a \u003Ccode>PartyBuilder\u003C\u002Fcode>, see\n\u003Ca href=\"\u002Fdocs\u002Fbuilding-invoices\">Building invoices\u003C\u002Fa>) and sets \u003Ccode>country\u003C\u002Fcode> from its address. The country\nselects the country pack. The logo must exist when the profile is saved (see\n\u003Ca href=\"#branding-check\">Branding check\u003C\u002Fa>). All columns are listed in \u003Ca href=\"#columns\">Columns\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch3 id=\"the-issuer-builder\">The issuer builder\u003Ca class=\"q-doc-anchor\" href=\"#the-issuer-builder\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>$issuer-&gt;builder()\u003C\u002Fcode> returns an \u003Ccode>InvoiceBuilder\u003C\u002Fcode> with the issuer's data:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>the seller and the time zone,\u003C\u002Fli>\n\u003Cli>the first bank account (as credit transfer),\u003C\u002Fli>\n\u003Cli>the payment terms (text and \u003Ccode>due_days\u003C\u002Fcode>),\u003C\u002Fli>\n\u003Cli>locale and currency,\u003C\u002Fli>\n\u003Cli>the presentation (branding and texts),\u003C\u002Fli>\n\u003Cli>the small business flag (see \u003Ca href=\"#small-business\">Small business\u003C\u002Fa>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Ccode>Quittio::invoice()\u003C\u002Fcode> and the document methods (\u003Ccode>Quittio::quote()\u003C\u002Fcode>,\n\u003Ccode>Quittio::paymentReminder()\u003C\u002Fcode> …) start with the current issuer in the same way. The Managed\nlayer binds \u003Ccode>InvoiceDefaults\u003C\u002Fcode> to \u003Ccode>Issuer::current()-&gt;applyTo($builder)\u003C\u002Fcode> (see\n\u003Ca href=\"\u002Fdocs\u002Flaravel#starting-invoices\">Starting invoices\u003C\u002Fa>). The first two drafts below are therefore\nthe same:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Laravel\\Facades\\Quittio\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draft\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Quittio\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">buyer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($customer)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">line\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Consulting'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">netPrice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'120.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draft\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">current\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">builder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">buyer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($customer)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">line\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Consulting'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">netPrice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'120.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#8B949E\">\u002F\u002F another issuer than the current one: start from its builder and pass it to draft()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draft\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">builder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">buyer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($customer)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">line\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Consulting'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">netPrice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'120.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">), $issuer);\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>-&gt;seller(...)\u003C\u002Fcode> with another seller removes the issuer's values again (see\n\u003Ca href=\"\u002Fdocs\u002Flaravel#starting-invoices\">Starting invoices\u003C\u002Fa>). The Managed layer still checks that the\nseller of a draft is its issuer.\u003C\u002Fp>\n\u003Cp>The builder copies these values into the draft. Later changes of the issuer do not change\nexisting drafts, except the seller: it is taken from the profile again when the draft is\nissued.\u003C\u002Fp>\n\u003Cp>Further methods of \u003Ccode>Issuer\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Method\u003C\u002Fth>\n\u003Cth>Returns\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Issuer::current()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">The issuer of the configured resolver\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>builder()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>InvoiceBuilder\u003C\u002Fcode> with the issuer's data (see above)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>applyTo(InvoiceBuilder $builder)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">Sets the issuer's data (see above) on an existing builder and returns it; \u003Ccode>builder()\u003C\u002Fcode> is \u003Ccode>applyTo(InvoiceBuilder::make())\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>sellerParty()\u003C\u002Fcode> \u002F \u003Ccode>setSellerParty(SellerParty $seller)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">The seller; the setter also sets \u003Ccode>country\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>presentation(?string $locale = null)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>Presentation\u003C\u002Fcode> from branding and texts, \u003Ccode>null\u003C\u002Fcode> if the issuer defines none\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>locale()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>defaults.locale\u003C\u002Fcode> or \u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>isSmallBusiness()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>tax_settings.small_business\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>applyTaxSettings(InvoiceData $data)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">The data with the small business flag, if the issuer is one\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>settings(string $column)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">Typed access to a JSON column (\u003Ccode>Settings\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>invoices()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>HasMany\u003C\u002Fcode> of the issuer's invoices\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>tenant()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>MorphTo\u003C\u002Fcode> of the tenant\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"defaults-texts-and-branding\">Defaults, texts and branding\u003Ca class=\"q-doc-anchor\" href=\"#defaults-texts-and-branding\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The JSON columns \u003Ccode>defaults\u003C\u002Fcode>, \u003Ccode>tax_settings\u003C\u002Fcode>, \u003Ccode>texts\u003C\u002Fcode> and \u003Ccode>branding\u003C\u002Fcode> hold the settings of the\nissuer:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>defaults.locale\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Locale of \u003Ccode>builder()\u003C\u002Fcode>, of the texts, the preview watermark and the mail\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>defaults.currency\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Currency of \u003Ccode>builder()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>defaults.due_days\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Integer: payment terms in days; the due date is the issue date plus these days\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>defaults.format\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Format of new drafts (\u003Ccode>zugferd\u003C\u002Fcode>, \u003Ccode>xrechnung-cii\u003C\u002Fcode>, \u003Ccode>xrechnung-ubl\u003C\u002Fcode>, \u003Ccode>cii\u003C\u002Fcode>, \u003Ccode>ubl\u003C\u002Fcode>, \u003Ccode>peppol\u003C\u002Fcode>, \u003Ccode>pdf\u003C\u002Fcode>, see \u003Ca href=\"\u002Fdocs\u002Fformats\">Formats\u003C\u002Fa>); \u003Ccode>null\u003C\u002Fcode> or \u003Ccode>auto\u003C\u002Fcode> = automatic choice when the invoice is issued\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>defaults.profile\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ca href=\"\u002Fdocs\u002Fconcepts#profiles\">Profile\u003C\u002Fa> of new drafts (e.g. \u003Ccode>xrechnung\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>tax_settings.small_business\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Small business that charges no VAT (in Germany a Kleinunternehmer under section 19 UStG, see \u003Ca href=\"\u002Fdocs\u002Fconcepts#german-terms\">German terms\u003C\u002Fa>). See \u003Ca href=\"#small-business\">Small business\u003C\u002Fa>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>texts.{locale}.intro\u003C\u002Fcode>, \u003Ccode>closing\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Intro and closing text of the PDF\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>texts.{locale}.payment_terms\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Text of the payment terms\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>texts.{locale}.footer_columns\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Footer columns, a list of lists of strings\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>branding.template\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">PDF template (see \u003Ca href=\"#branding-check\">Branding check\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>branding.logo\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Logo: local file, data URI or public http(s) URL\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>branding.colors\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ccode>primary\u003C\u002Fcode> (default \u003Ccode>#2741d9\u003C\u002Fcode>), \u003Ccode>text\u003C\u002Fcode> (\u003Ccode>#15171c\u003C\u002Fcode>), \u003Ccode>muted\u003C\u002Fcode> (\u003Ccode>#5f6470\u003C\u002Fcode>), \u003Ccode>secondary\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>branding.font\u003C\u002Fcode>, \u003Ccode>sender_line\u003C\u002Fcode>, \u003Ccode>letter_layout\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Font, sender line above the address, letter layout (e.g. DIN 5008, the German standard for business letters)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>branding.payment_qr\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ca href=\"\u002Fdocs\u002Ftemplates#payment-qr-codes\">Payment QR code\u003C\u002Fa> on the PDF: \u003Ccode>auto\u003C\u002Fcode> (default), \u003Ccode>girocode\u003C\u002Fcode> (the EPC QR code for SEPA credit transfers), \u003Ccode>swiss-qr-bill\u003C\u002Fcode> or \u003Ccode>none\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Texts are looked up for the locale, then under the key \u003Ccode>default\u003C\u002Fcode>, then the first entry. See\n\u003Ca href=\"\u002Fdocs\u002Ftemplates\">Templates\u003C\u002Fa> for what the presentation settings do in the PDF.\u003C\u002Fp>\n\u003Ch3 id=\"small-business\">Small business\u003Ca class=\"q-doc-anchor\" href=\"#small-business\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>With \u003Ccode>tax_settings.small_business\u003C\u002Fcode>, \u003Ccode>builder()\u003C\u002Fcode> sets the flag \u003Ccode>Meta::FLAG_SMALL_BUSINESS\u003C\u002Fcode>.\n\u003Ccode>Invoice::draft()\u003C\u002Fcode> sets it also on data that was not built with \u003Ccode>builder()\u003C\u002Fcode>. The country pack\ndecides what follows. The German pack rejects invoices that charge VAT (rule DE-USTG-09, see\n\u003Ca href=\"\u002Fdocs\u002Fconcepts#rules-and-validation\">Rules and validation\u003C\u002Fa>). It also rejects the tax exemption\nof an \u003Ca href=\"\u002Fdocs\u002Fconcepts#german-terms\">intra-community supply\u003C\u002Fa> except for new vehicles\n(DE-USTG-14). Such a draft cannot be issued. Give the lines the preset\n\u003Ccode>VatPreset::SmallBusiness\u003C\u002Fcode> of the German pack (see \u003Ca href=\"\u002Fdocs\u002Fcountry-packs\">Country packs\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch3 id=\"current-issuer\">Current issuer\u003Ca class=\"q-doc-anchor\" href=\"#current-issuer\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>Issuer::current()\u003C\u002Fcode> asks the resolver configured in \u003Ccode>quittio-managed.issuer_resolver\u003C\u002Fcode>. The\ndefault resolver returns:\u003C\u002Fp>\n\u003Col>\n\u003Cli>the issuer marked as default (\u003Ccode>is_default\u003C\u002Fcode>; the lowest id if several are),\u003C\u002Fli>\n\u003Cli>otherwise the only issuer, if there is exactly one,\u003C\u002Fli>\n\u003Cli>otherwise it throws \u003Ccode>IssuerNotFound\u003C\u002Fcode>.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>\u003Ccode>Invoice::draft()\u003C\u002Fcode>, \u003Ccode>HasInvoices\u003C\u002Fcode> and the tenancy scope use the current issuer when none is\ngiven. In an application with several companies, write a resolver that picks the issuer of\nthe logged-in user, e.g. by team:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Issuers\\IssuerResolver\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Managed\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">final\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> class\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> TeamIssuerResolver\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> implements\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> IssuerResolver\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> resolve\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Issuer\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#E6EDF3\">        $team \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> auth\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">user\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">currentTeam;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Managed\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issuerModel\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:14ch;text-indent:-14ch\">\u003Cspan style=\"color:#FF7B72\">            ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">where\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'tenant_type'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, $team\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">getMorphClass\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:14ch;text-indent:-14ch\">\u003Cspan style=\"color:#FF7B72\">            ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">where\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'tenant_id'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, $team\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">getKey\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:14ch;text-indent:-14ch\">\u003Cspan style=\"color:#FF7B72\">            ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">firstOrFail\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#8B949E\">\u002F\u002F config\u002Fquittio-managed.php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#A5D6FF\">'issuer_resolver'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> App\\Billing\\TeamIssuerResolver\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>A Closure (\u003Ccode>'issuer_resolver' =&gt; fn () =&gt; …\u003C\u002Fcode>) works as well. It must return an \u003Ccode>Issuer\u003C\u002Fcode>\n(\u003Ccode>ConfigurationException\u003C\u002Fcode> otherwise). Laravel cannot cache a configuration that contains a\nClosure (\u003Ccode>config:cache\u003C\u002Fcode>), so prefer a class in production.\u003C\u002Fp>\n\u003Ch3 id=\"tenancy-scope\">Tenancy scope\u003Ca class=\"q-doc-anchor\" href=\"#tenancy-scope\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>In a multi-tenant application, one installation serves several customers (tenants, e.g.\nteams), each with its own issuer profiles. The tenancy scope restricts every invoice query to\nthe current issuer.\u003C\u002Fp>\n\u003Cp>With \u003Ccode>tenancy.scope\u003C\u002Fcode>, the invoice model gets the global scope \u003Ccode>Invoice::TENANCY_SCOPE\u003C\u002Fcode>\n(\u003Ccode>'quittio.issuer'\u003C\u002Fcode>). Every invoice query is then restricted to \u003Ccode>issuer_id\u003C\u002Fcode> of the current\nissuer, including relations such as \u003Ccode>$user-&gt;invoices()\u003C\u002Fcode> and route model binding. Every such\nquery calls the resolver. Remove the scope where needed:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">withoutGlobalScope\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">TENANCY_SCOPE\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">count\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>The jobs and commands of the package bypass the scope. It applies to invoices only, not to\nissuers, sequences, deliveries or audit entries. It also changes the number spaces of issuers\nwithout a tenant (see \u003Ca href=\"#number-spaces\">Number spaces\u003C\u002Fa>): decide on it before issuing invoices.\u003C\u002Fp>\n\u003Ch3 id=\"seller-identity\">Seller identity\u003Ca class=\"q-doc-anchor\" href=\"#seller-identity\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The seller of an invoice is always its issuer:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>A draft whose seller has another VAT id or tax number than the issuer is rejected\n(\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>When a draft is issued, the seller (name, address, VAT id, tax number, legal information)\nis taken from the issuer profile as it is then. Payment instructions and terms stay as the\ndraft sets them.\u003C\u002Fli>\n\u003Cli>Issued invoices keep their own snapshot, so later changes of the issuer never affect them.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Identifiers are compared in upper case and without spaces (also no-break and zero-width\nspaces), dots, slashes and dashes.\u003C\u002Fp>\n\u003Ch3 id=\"changing-and-deleting-issuers\">Changing and deleting issuers\u003Ca class=\"q-doc-anchor\" href=\"#changing-and-deleting-issuers\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>Changes only affect invoices issued afterwards (drafts only through the seller, see above).\u003C\u002Fli>\n\u003Cli>Creating, changing and deleting a profile is written to the audit log with the old and new\nvalues (\u003Ccode>issuer_created\u003C\u002Fcode>, \u003Ccode>issuer_updated\u003C\u002Fcode>, \u003Ccode>issuer_deleted\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>The \u003Ccode>key\u003C\u002Fcode> cannot change once number sequences use it (\u003Ccode>NumberingException\u003C\u002Fcode>): it is part of\nthe sequence keys, and a new key would start the numbering again.\u003C\u002Fli>\n\u003Cli>The number space and the tenant cannot change once the issuer has issued invoices\n(\u003Ccode>NumberingException\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>An issuer with invoices cannot be deleted: the foreign key of \u003Ccode>quittio_invoices.issuer_id\u003C\u002Fcode>\nrestricts it (the database throws).\u003C\u002Fli>\n\u003Cli>Saves that change the seller, the key, the number space or the tenant run in a\ntransaction under a lock of the tenant (see \u003Ca href=\"#number-spaces\">Number spaces\u003C\u002Fa>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"branding-check\">Branding check\u003Ca class=\"q-doc-anchor\" href=\"#branding-check\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>branding.template\u003C\u002Fcode> and \u003Ccode>branding.logo\u003C\u002Fcode> are checked when the issuer is saved, with the rules\nthe rendering applies. Other values throw \u003Ccode>InvalidIssuerProfile\u003C\u002Fcode>. The reason: the logo becomes\npart of the invoice data, and an issued invoice whose logo cannot be rendered can never be\narchived.\u003C\u002Fp>\n\u003Cp>The template is checked by the engine of the rendering and the preview\n(\u003Ccode>BladeTemplateEngine::fromSettings()\u003C\u002Fcode>). It must be one of:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>default\u003C\u002Fcode> or the template configured in \u003Ccode>quittio.pdf.template\u003C\u002Fcode>,\u003C\u002Fli>\n\u003Cli>a view under \u003Ccode>quittio::templates.\u003C\u002Fcode> (no partials),\u003C\u002Fli>\n\u003Cli>a view of \u003Ccode>quittio.pdf.templates\u003C\u002Fcode> (\u003Ccode>invoices.*\u003C\u002Fcode> allows every view below the prefix),\u003C\u002Fli>\n\u003Cli>a plain PHP template of the core.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The logo must be one of:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>a readable local file of at most 10 MB, given as a path (not as a \u003Ccode>file:\u002F\u002F\u003C\u002Fcode> URI),\u003C\u002Fli>\n\u003Cli>a data URI (\u003Ccode>data:image\u002F…\u003C\u002Fcode>) that decodes to at most 10 MB (base64 strictly),\u003C\u002Fli>\n\u003Cli>an http(s) URL of a public host. IP addresses must be public. Host names are resolved and\nchecked when the logo is downloaded. Other spellings of addresses (\u003Ccode>2130706433\u003C\u002Fcode>,\n\u003Ccode>localhost.\u003C\u002Fcode>) are refused.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The value must have no surrounding whitespace, no backslashes and no leading \u003Ccode>\u002F\u002F\u003C\u002Fcode>. An SVG logo\nmust be self-contained (no external references such as \u003Ccode>href=&quot;http:\u002F\u002F…&quot;\u003C\u002Fcode> or \u003Ccode>url(…)\u003C\u002Fcode>, no\nentity declarations). A raster logo may have at most 25 megapixels.\u003C\u002Fp>\n\u003Ch3 id=\"columns\">Columns\u003Ca class=\"q-doc-anchor\" href=\"#columns\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Column\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>key\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string, unique\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Short name; part of the sequence keys and the archive paths; cannot change once number sequences use it\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>seller\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">The seller party (\u003Ccode>SellerParty\u003C\u002Fcode>, normalised); read with \u003Ccode>sellerParty()\u003C\u002Fcode>, write with \u003Ccode>setSellerParty()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>country\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">char(2)\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Country of the seller address; selects the country pack\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>timezone\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string, default \u003Ccode>UTC\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Time zone of issue dates, &quot;today&quot; and the retention period\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>number_space\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string(128)\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Invoice numbers of one company, set on save (see \u003Ca href=\"#number-spaces\">Number spaces\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>tenant_type\u003C\u002Fcode>, \u003Ccode>tenant_id\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">morph, nullable\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Tenant of the issuer (relation \u003Ccode>tenant()\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>bank_accounts\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON list\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ccode>[{iban, bic, name}, …]\u003C\u002Fcode>; the first account goes into \u003Ccode>builder()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>defaults\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ccode>locale\u003C\u002Fcode>, \u003Ccode>currency\u003C\u002Fcode>, \u003Ccode>due_days\u003C\u002Fcode>, \u003Ccode>format\u003C\u002Fcode>, \u003Ccode>profile\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>tax_settings\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ccode>small_business\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>texts\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Texts per locale: \u003Ccode>intro\u003C\u002Fcode>, \u003Ccode>closing\u003C\u002Fcode>, \u003Ccode>payment_terms\u003C\u002Fcode>, \u003Ccode>footer_columns\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>branding\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ccode>template\u003C\u002Fcode>, \u003Ccode>logo\u003C\u002Fcode>, \u003Ccode>colors\u003C\u002Fcode>, \u003Ccode>font\u003C\u002Fcode>, \u003Ccode>sender_line\u003C\u002Fcode>, \u003Ccode>letter_layout\u003C\u002Fcode>, \u003Ccode>payment_qr\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>numbering\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ccode>pattern\u003C\u002Fcode>, \u003Ccode>reset\u003C\u002Fcode>, \u003Ccode>start\u003C\u002Fcode>, \u003Ccode>per_kind\u003C\u002Fcode> (override of the configuration)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>registrations\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Further VAT registrations and establishments in other countries; stored, not evaluated yet\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>network_ids\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">JSON\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Network identifiers (e.g. Peppol); stored, not evaluated yet\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>is_default\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">bool\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Chosen by the default issuer resolver\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>All columns except \u003Ccode>id\u003C\u002Fcode> are mass assignable (\u003Ccode>Issuer::create([...])\u003C\u002Fcode>, \u003Ccode>fill()\u003C\u002Fcode>). The JSON\ncolumns accept arrays only.\u003C\u002Fp>\n\u003Ch2 id=\"customers-and-references\">Customers and references\u003Ca class=\"q-doc-anchor\" href=\"#customers-and-references\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Every invoice can point to two of your own models. Both are optional and polymorphic, so any\nEloquent model works (user, team, company, order, subscription):\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Reference\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003Cth>Example\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>billable\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">who is invoiced, the customer\u003C\u002Ftd>\n\u003Ctd data-label=\"Example\">\u003Ccode>User\u003C\u002Fcode>, \u003Ccode>Team\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>invoiceable\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">what is invoiced\u003C\u002Ftd>\n\u003Ctd data-label=\"Example\">\u003Ccode>Order\u003C\u002Fcode>, \u003Ccode>Subscription\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Prepare the customer model with the \u003Ccode>HasInvoices\u003C\u002Fcode> trait. \u003Ccode>ProvidesParty\u003C\u002Fcode> supplies the buyer\ndata. \u003Ccode>HasInvoiceEmail\u003C\u002Fcode> supplies the delivery address; it is optional, without it the \u003Ccode>email\u003C\u002Fcode>\nattribute is used.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Builder\\PartyBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Contracts\\ProvidesParty\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Concerns\\HasInvoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Delivery\\HasInvoiceEmail\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">class\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> User\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> extends\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Authenticatable\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> implements\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> ProvidesParty\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">HasInvoiceEmail\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> HasInvoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> fillParty\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">PartyBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $party)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> void\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#E6EDF3\">        $party\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">name\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">company \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">??\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> $this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">name)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:14ch;text-indent:-14ch\">\u003Cspan style=\"color:#FF7B72\">            ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">vatId\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">vat_id)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:14ch;text-indent:-14ch\">\u003Cspan style=\"color:#FF7B72\">            ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">address\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">street, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">postcode, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">city, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">country)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:14ch;text-indent:-14ch\">\u003Cspan style=\"color:#FF7B72\">            ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">electronicAddress\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">email, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'EM'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> invoiceEmail\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> ?string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> $this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">billing_email \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">??\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> $this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">email;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Register short names for these models in the morph map (see \u003Ca href=\"#morph-map\">Morph map\u003C\u002Fa>):\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#8B949E\">\u002F\u002F AppServiceProvider::boot()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Relation\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">enforceMorphMap\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'user'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> User\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'order'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Order\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>The trait adds three methods:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Method\u003C\u002Fth>\n\u003Cth>Returns\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>invoices()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>MorphMany\u003C\u002Fcode> relation of all invoices, cancellations and corrections of the model (drafts included)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>invoiceBuilder(?Issuer $issuer = null)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>$issuer-&gt;builder()\u003C\u002Fcode> (default: the current issuer) with the model as buyer when it implements \u003Ccode>ProvidesParty\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>draftInvoice($data, ?Issuer $issuer = null, ?Model $invoiceable = null)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">A new draft with the model as billable\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>\u003Ccode>draftInvoice()\u003C\u002Fcode> accepts:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>a callable: it receives the builder of \u003Ccode>invoiceBuilder()\u003C\u002Fcode>, so the model is already the buyer,\u003C\u002Fli>\n\u003Cli>a builder or \u003Ccode>InvoiceData\u003C\u002Fcode>: used as they are, including their buyer,\u003C\u002Fli>\n\u003Cli>an application model implementing \u003Ccode>ProvidesInvoiceData\u003C\u002Fcode>: used as it is; the model becomes\nthe invoiceable unless \u003Ccode>$invoiceable\u003C\u002Fcode> is given.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Builder\\InvoiceBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Enums\\UnitCode\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Enums\\Kind\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draftInvoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $b) => $b\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">deliveryDate\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'2026-10-31'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    ->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">line\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Pro plan October'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">netPrice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'29.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">unit\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">UnitCode\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Month\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FFA657\">    invoiceable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: $subscription,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">send\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                                    \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F to $user->invoiceEmail()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draftInvoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($order)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F $order implements ProvidesInvoiceData\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">invoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issued\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">latest\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'issue_date'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">invoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">overdue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">invoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">ofKind\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Kind\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Cancellation\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Without the trait, pass the references yourself. \u003Ccode>forBillable()\u003C\u002Fcode> queries without a relation\non the model:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draft\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($builder, $issuer, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">billable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: $user, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">invoiceable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: $order);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draftFor\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($order, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">billable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: $order\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">user);   \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F $order becomes the invoiceable\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forBillable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($user)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">open\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">billable;                                  \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F the user, or null if it was deleted\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">invoiceable;\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Laravel Cashier's \u003Ccode>Billable\u003C\u002Fcode> trait also has an \u003Ccode>invoices()\u003C\u002Fcode> method (Stripe invoices) and\ncalls it internally. If you use both, keep Cashier's method and rename Quittio's relation:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Billable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">HasInvoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#79C0FF\">    Billable\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">invoices\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> insteadof\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> HasInvoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#79C0FF\">    HasInvoices\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">invoices\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> as\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> quittioInvoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">quittioInvoices\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">open\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Rules worth knowing:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>The references only link records. What counts legally is the buyer copied into the\ninvoice data when the draft was built. When the user changes the address later, issued\ninvoices stay as they are (section 14 UStG, the German VAT Act, and the\n\u003Ca href=\"\u002Fdocs\u002Fconcepts#german-terms\">GoBD\u003C\u002Fa>).\u003C\u002Fli>\n\u003Cli>A draft keeps its buyer until you set it again:\n\u003Ccode>$draft-&gt;updateData(fn (InvoiceBuilder $b) =&gt; $b-&gt;buyer($user))\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Cancellations, partial cancellations and corrections take \u003Ccode>billable\u003C\u002Fcode> and \u003Ccode>invoiceable\u003C\u002Fcode>\nover from the original invoice.\u003C\u002Fli>\n\u003Cli>There is no foreign key to your models. Deleting a user leaves the invoices in place,\nbecause they must be kept for eight years (section 14b UStG and section 147 AO, the German\nFiscal Code). \u003Ccode>billable\u003C\u002Fcode> then returns \u003Ccode>null\u003C\u002Fcode>. The buyer data in the archived files is\nunaffected.\u003C\u002Fli>\n\u003Cli>With \u003Ccode>tenancy.scope\u003C\u002Fcode>, the queries above are additionally restricted to the current issuer.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"drafts\">Drafts\u003Ca class=\"q-doc-anchor\" href=\"#drafts\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>A draft is an invoice that is not issued yet. It has no number, can be changed freely and\ncan be deleted without leaving a gap in the numbers.\u003C\u002Fp>\n\u003Ch3 id=\"creating-drafts\">Creating drafts\u003Ca class=\"q-doc-anchor\" href=\"#creating-drafts\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Builder\\InvoiceBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draft\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($builder);                                    \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F current issuer\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draft\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($builder, $issuer, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">billable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: $user, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">invoiceable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: $order);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draft\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoiceData, $issuer);                       \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F InvoiceData works too\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draftFor\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($order);                 \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F ProvidesInvoiceData, $order becomes the invoiceable\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draftFor\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($order, $issuer, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">billable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: $order\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">user);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">draftInvoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $b) => $b\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">line\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Consulting'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">netPrice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'120.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">));   \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F HasInvoices\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Method\u003C\u002Fth>\n\u003Cth>Parameters\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Invoice::draft()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Parameters\">\u003Ccode>InvoiceData|InvoiceBuilder $data, ?Issuer $issuer = null, ?Model $billable = null, ?Model $invoiceable = null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Invoice::draftFor()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Parameters\">\u003Ccode>ProvidesInvoiceData $source, ?Issuer $issuer = null, ?Model $billable = null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Creating a draft:\u003C\u002Fp>\n\u003Col>\n\u003Cli>takes the given issuer or the current one,\u003C\u002Fli>\n\u003Cli>builds the data without calculating or validating it (\u003Ccode>InvoiceBuilder::buildDraft()\u003C\u002Fcode>;\nlines are not yet required),\u003C\u002Fli>\n\u003Cli>rejects a seller with another VAT id or tax number than the issuer\n(\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>),\u003C\u002Fli>\n\u003Cli>sets the small business flag of the issuer, the format and profile of\n\u003Ccode>defaults.format\u003C\u002Fcode> (\u003Ccode>auto\u003C\u002Fcode> = \u003Ccode>null\u003C\u002Fcode>) and \u003Ccode>defaults.profile\u003C\u002Fcode>, kind \u003Ccode>invoice\u003C\u002Fcode>, status \u003Ccode>draft\u003C\u002Fcode>\nand \u003Ccode>created_by\u003C\u002Fcode> (the authenticated user, if any),\u003C\u002Fli>\n\u003Cli>stores the data without number and totals, and copies the type code (the document type,\ne.g. \u003Ccode>380\u003C\u002Fcode> invoice), currency, buyer country, due date, service date, service period and\nlocale into columns for queries,\u003C\u002Fli>\n\u003Cli>writes the audit entry \u003Ccode>drafted\u003C\u002Fcode> and dispatches \u003Ccode>InvoiceDrafted\u003C\u002Fcode> once the draft is\ncommitted (at once outside a transaction).\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>\u003Ccode>$invoice-&gt;createdBy\u003C\u002Fcode> and \u003Ccode>$invoice-&gt;issuedBy\u003C\u002Fcode> return the users who created the draft and\nissued the invoice (\u003Ccode>MorphTo\u003C\u002Fcode>; \u003Ccode>null\u003C\u002Fcode> without an authenticated user, e.g. in queued jobs).\u003C\u002Fp>\n\u003Cp>A draft holds no number, number space, sequence key or sequence value: \u003Ccode>issue()\u003C\u002Fcode> sets them.\u003C\u002Fp>\n\u003Ch3 id=\"changing-drafts\">Changing drafts\u003Ca class=\"q-doc-anchor\" href=\"#changing-drafts\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Builder\\InvoiceBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">updateData\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $b) => $b\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">line\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Travel costs'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">netPrice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'80.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">buyerReference\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'PO-4711'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'format'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'xrechnung-cii'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'profile'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'xrechnung'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">billable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">associate\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($user)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>updateData()\u003C\u002Fcode> starts an \u003Ccode>InvoiceBuilder\u003C\u002Fcode> from the current data (\u003Ccode>InvoiceBuilder::from()\u003C\u002Fcode>),\npasses it to the callable and stores the result. It throws \u003Ccode>InvoiceNotDraft\u003C\u002Fcode> for issued\ninvoices.\u003C\u002Fp>\n\u003Cp>The other columns of a draft can be changed through the model. They are guarded, so use\n\u003Ccode>forceFill()\u003C\u002Fcode>. Exceptions: \u003Ccode>kind\u003C\u002Fcode> and \u003Ccode>preceding_invoice_id\u003C\u002Fcode> are fixed when the draft is\ncreated, and the number columns are set only by \u003Ccode>issue()\u003C\u002Fcode>. Unsaved changes of the model are\nsaved together with \u003Ccode>issue()\u003C\u002Fcode>. Draft changes are not written to the audit log.\u003C\u002Fp>\n\u003Cp>A draft keeps no totals: the invoice is calculated again when it is issued. This also applies\nto a draft started with \u003Ccode>InvoiceBuilder::from()\u003C\u002Fcode> on data another system rounded. Only the VAT\nbreakdown of an aligned partial cancellation is kept (see\n\u003Ca href=\"#vat-of-partial-cancellations\">VAT of partial cancellations\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch3 id=\"preview-and-validation\">Preview and validation\u003Ca class=\"q-doc-anchor\" href=\"#preview-and-validation\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">return\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">preview\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                 \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F Responsable: PDF in the browser\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">preview\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">download\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'draft.pdf'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$result \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">validate\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();             \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F Quittio\\Core\\Validation\\ValidationResult\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$result\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">isValid\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>preview()\u003C\u002Fcode> renders a PDF without validation:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>always in the format \u003Ccode>pdf\u003C\u002Fcode>,\u003C\u002Fli>\n\u003Cli>with the watermark of the translation \u003Ccode>quittio-managed::invoice.draft_watermark\u003C\u002Fcode>\n(&quot;ENTWURF&quot; in German, &quot;DRAFT&quot; in English), in the locale of the draft or of the issuer,\u003C\u002Fli>\n\u003Cli>without a number,\u003C\u002Fli>\n\u003Cli>dated today in the issuer's time zone.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>It returns a \u003Ccode>RenderedInvoice\u003C\u002Fcode> of \u003Ccode>quittio\u002Flaravel\u003C\u002Fcode> (\u003Ccode>pdf()\u003C\u002Fcode>, \u003Ccode>download()\u003C\u002Fcode>, usable as response\nor mail attachment). It throws \u003Ccode>InvoiceNotDraft\u003C\u002Fcode> for issued invoices.\u003C\u002Fp>\n\u003Cp>\u003Ccode>validate()\u003C\u002Fcode> runs the full validation as if the draft were issued today with the next number.\nThe number comes from the number generator's preview; nothing is used up. It uses the format,\nprofile and locale of the draft. On an issued invoice it validates the frozen data with the\nformat, profile, locale and country pack it was issued with. See \u003Ca href=\"\u002Fdocs\u002Fvalidation\">Validation\u003C\u002Fa>\nfor the result.\u003C\u002Fp>\n\u003Ch3 id=\"deleting-drafts\">Deleting drafts\u003Ca class=\"q-doc-anchor\" href=\"#deleting-drafts\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">delete\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                                         \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F audit entry deleted_draft\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">drafts\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">where\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'created_at'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'&#x3C;'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">now\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">subYear\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">())\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">delete\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Deleting a draft leaves no gap in the numbers, since drafts hold none. A bulk delete:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>only removes drafts,\u003C\u002Fli>\n\u003Cli>throws \u003Ccode>InvoiceImmutable\u003C\u002Fcode> if the query would reach an issued invoice,\u003C\u002Fli>\n\u003Cli>writes no audit entries (it runs without model events).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Drafts of cancellations and corrections that can no longer be issued are removed by\n\u003Ccode>quittio:drafts:prune\u003C\u002Fcode> (see \u003Ca href=\"#left-behind-drafts\">Left-behind drafts\u003C\u002Fa>). Ordinary drafts are\nnever deleted automatically.\u003C\u002Fp>\n\u003Ch2 id=\"issuing\">Issuing\u003Ca class=\"q-doc-anchor\" href=\"#issuing\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                 \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F today in the issuer's time zone\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'2026-10-05'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);     \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F string, DateTimeInterface or Quittio\\Core\\Support\\Date\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>issue()\u003C\u002Fcode> returns the same model, now issued. In short: it validates the invoice, takes the\nnext number inside a short transaction, freezes the data and queues the rendering. When\nanything fails before the commit, the draft stays a draft and no number is used up.\u003C\u002Fp>\n\u003Cp>The steps in detail:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\n\u003Cp>The invoice must be a draft (\u003Ccode>InvoiceNotDraft\u003C\u002Fcode>). Drafts of cancellations are issued by\n\u003Ccode>cancel()\u003C\u002Fcode> and \u003Ccode>cancelPartially()\u003C\u002Fcode> only (\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>). Drafts of corrections\nfollow the correction strategy (see \u003Ca href=\"#corrections\">Corrections\u003C\u002Fa>).\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>The issue date is the given date or today in the issuer's time zone. Cancellations and\ncorrections cannot be dated before the invoice they refer to. The issuer must still be\nthe company that issued the original (same VAT id or tax number). Otherwise\n\u003Ccode>InvalidInvoiceState\u003C\u002Fcode> is thrown.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>The seller is taken from the issuer profile as it is now, and the issue date is set. The\nnumber generator prepares the sequence (outside the transaction). The data is calculated\nand fully validated with the probable number, with the format, profile and locale of the\ndraft.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>A format that produces neither a PDF nor an XML invoice (\u003Ccode>html\u003C\u002Fcode>, \u003Ccode>json\u003C\u002Fcode>) is refused with\n\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>, because the archive must hold the invoice itself.\u003C\u002Fli>\n\u003Cli>Validation errors throw \u003Ccode>Quittio\\Core\\Validation\\ValidationException\u003C\u002Fcode> (\u003Ccode>$e-&gt;result\u003C\u002Fcode>\nholds the messages). With \u003Ccode>quittio.validation.block_on_warnings\u003C\u002Fcode>, warnings do as well.\nNo number is used up.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Ccode>InvoiceIssuing\u003C\u002Fcode> is dispatched. A listener that throws stops the issue before a number is\nassigned.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>A short transaction:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>locks the draft (\u003Ccode>SELECT … FOR UPDATE\u003C\u002Fcode>) and checks again that it is a draft (another\nprocess may have issued or deleted it),\u003C\u002Fli>\n\u003Cli>takes the next number,\u003C\u002Fli>\n\u003Cli>reads the issuer with a shared lock and checks that no other issuer of the number space\nused the number,\u003C\u002Fli>\n\u003Cli>freezes the invoice: number, number space, sequence key and value, status \u003Ccode>issued\u003C\u002Fcode>,\n\u003Ccode>issued_at\u003C\u002Fcode>, issue date, totals, the calculated data snapshot, standard version, the\nformat and profile actually used, country pack, locale, render status \u003Ccode>pending\u003C\u002Fcode>,\nvalidation status, retention period and \u003Ccode>issued_by\u003C\u002Fcode> (the authenticated user, if any).\nCancellation and archive columns are reset.\u003C\u002Fli>\n\u003Cli>writes the audit entry \u003Ccode>issued\u003C\u002Fcode>.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Deadlocks, serialisation failures and concurrent sequence changes are retried (three\nattempts).\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>After the commit, the documents are rendered by the job \u003Ccode>RenderInvoiceDocuments\u003C\u002Fcode> (or at\nonce with \u003Ccode>queue.render_sync\u003C\u002Fcode>). Then \u003Ccode>InvoiceIssued\u003C\u002Fcode> is dispatched. If a listener throws,\nthe exception reaches the caller, but the invoice is issued: the model shows the committed\nstate and the job is queued.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>The retention period (\u003Ccode>retention_until\u003C\u002Fcode>) follows the rule of the country pack (DE: 8 years\nafter the end of the year). It is counted from the year of issue, but never from a year\nbefore the invoice is actually issued: a backdated invoice keeps the full period.\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Exception\u003C\u002Fth>\n\u003Cth>When\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>ValidationException\u003C\u002Fcode> (core)\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">The calculated invoice is invalid (or has warnings with \u003Ccode>block_on_warnings\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceNotDraft\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">Not a draft, or issued or deleted by another process meanwhile\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">Cancellation draft, date before the original, another company, issuer deleted, format without PDF or XML (\u003Ccode>html\u003C\u002Fcode>, \u003Ccode>json\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>NumberingException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">Invalid pattern, number already taken (also by another issuer of the number space)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>ConfigurationException\u003C\u002Fcode> (core)\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">Reset not allowed by the country pack, \u003Ccode>retention.years\u003C\u002Fcode> too short, invalid generator\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceImmutable\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">The draft row was changed by another process since it was loaded\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"issuing-inside-your-own-transaction\">Issuing inside your own transaction\u003Ca class=\"q-doc-anchor\" href=\"#issuing-inside-your-own-transaction\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>issue()\u003C\u002Fcode> (and \u003Ccode>cancel()\u003C\u002Fcode>, \u003Ccode>cancelPartially()\u003C\u002Fcode> and issuing a correction) can run inside a\ndatabase transaction of your application on the Managed connection. Then:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>there are no retries: your transaction decides,\u003C\u002Fli>\n\u003Cli>the render job and the events \u003Ccode>InvoiceIssued\u003C\u002Fcode>, \u003Ccode>InvoiceCancelled\u003C\u002Fcode> … run only when your\ntransaction commits, and an exception of a listener reaches the code that commits,\u003C\u002Fli>\n\u003Cli>a rollback leaves the draft a draft and uses up no number. The model in memory still shows\nthe issued state then, so load it again.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"statuses\">Statuses\u003Ca class=\"q-doc-anchor\" href=\"#statuses\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Status, payment, delivery, rendering and validation are separate columns. Their enums are\nlisted in \u003Ca href=\"#enums\">Enums\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch3 id=\"status\">Status\u003Ca class=\"q-doc-anchor\" href=\"#status\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>status\u003C\u002Fcode> moves only forward: \u003Ccode>draft\u003C\u002Fcode> → \u003Ccode>issued\u003C\u002Fcode> → \u003Ccode>partially_cancelled\u003C\u002Fcode> → \u003Ccode>cancelled\u003C\u002Fcode>. It\nchanges only through \u003Ccode>issue()\u003C\u002Fcode>, \u003Ccode>cancel()\u003C\u002Fcode>, \u003Ccode>cancelPartially()\u003C\u002Fcode> and the issue of a\ncorrection, never through \u003Ccode>save()\u003C\u002Fcode> or bulk updates (see \u003Ca href=\"#immutability\">Immutability\u003C\u002Fa>).\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>issued\u003C\u002Fcode>: issued and not cancelled. Cancellations and corrections are themselves \u003Ccode>issued\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Ccode>partially_cancelled\u003C\u002Fcode>: at least one partial cancellation refers to the invoice.\u003C\u002Fli>\n\u003Cli>\u003Ccode>cancelled\u003C\u002Fcode>: cancelled completely, by \u003Ccode>cancel()\u003C\u002Fcode>, by partial cancellations that together\ncover everything, or by an issued correction. \u003Ccode>cancelled_at\u003C\u002Fcode> and \u003Ccode>cancellation_reason\u003C\u002Fcode>\nare set then, once.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Ccode>cancellations\u003C\u002Fcode> counts the documents that cancel (part of) the invoice (relations \u003Ccode>cancels\u003C\u002Fcode>,\n\u003Ccode>partially_cancels\u003C\u002Fcode>, \u003Ccode>replaces\u003C\u002Fcode>).\u003C\u002Fp>\n\u003Ch3 id=\"payment-status\">Payment status\u003Ca class=\"q-doc-anchor\" href=\"#payment-status\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The package does not record payments in version 1.0 (planned from version 1.1): every issued\ninvoice stays \u003Ccode>unpaid\u003C\u002Fcode> until you change it. The payment columns stay changeable after\nissuing, through the model or in bulk:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Enums\\PaymentStatus\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'payment_status'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> PaymentStatus\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Paid\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'paid_total'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">amount_due,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'paid_at'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> now\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">whereIn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'number'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, $numbers)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">update\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'payment_status'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'paid'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'paid_at'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> now\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()]);\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Case\u003C\u002Fth>\n\u003Cth>Value\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Unpaid\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Value\">\u003Ccode>unpaid\u003C\u002Fcode> (default)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>PartiallyPaid\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Value\">\u003Ccode>partially_paid\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Paid\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Value\">\u003Ccode>paid\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Overpaid\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Value\">\u003Ccode>overpaid\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>WrittenOff\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Value\">\u003Ccode>written_off\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The package does not check these values against the amounts, writes no audit entry and\ndispatches no event for them. Amounts accept at most two decimals (\u003Ccode>InvalidArgumentException\u003C\u002Fcode>\notherwise).\u003C\u002Fp>\n\u003Ch3 id=\"open-and-overdue\">Open and overdue\u003Ca class=\"q-doc-anchor\" href=\"#open-and-overdue\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>&quot;Overdue&quot; is not stored, it is a query:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Carbon\\CarbonImmutable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">open\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();        \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F issued or partially cancelled, no cancellation, unpaid or partially paid\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">overdue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();     \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F open and due_date before today\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">overdue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">CarbonImmutable\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">parse\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'2026-12-31'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">))\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>overdue()\u003C\u002Fcode> compares with today in the application's time zone, or with the given date.\n\u003Ccode>open()\u003C\u002Fcode> includes corrections and credit notes of kind \u003Ccode>invoice\u003C\u002Fcode>; filter by \u003Ccode>type_code\u003C\u002Fcode> if\nyou need to tell them apart.\u003C\u002Fp>\n\u003Ch3 id=\"delivery-status\">Delivery status\u003Ca class=\"q-doc-anchor\" href=\"#delivery-status\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>delivery_status\u003C\u002Fcode> of the invoice:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>not_sent\u003C\u002Fcode>,\u003C\u002Fli>\n\u003Cli>\u003Ccode>sent\u003C\u002Fcode> after a successful \u003Ccode>send()\u003C\u002Fcode>,\u003C\u002Fli>\n\u003Cli>\u003Ccode>failed\u003C\u002Fcode> after a failed attempt (a failed attempt after a successful one keeps \u003Ccode>sent\u003C\u002Fcode>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Every attempt is a row in \u003Ccode>quittio_deliveries\u003C\u002Fcode> with its own state \u003Ccode>queued\u003C\u002Fcode>, \u003Ccode>sent\u003C\u002Fcode> or\n\u003Ccode>failed\u003C\u002Fcode> (see \u003Ca href=\"#delivery\">Delivery\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch3 id=\"render-and-validation-status\">Render and validation status\u003Ca class=\"q-doc-anchor\" href=\"#render-and-validation-status\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>render_status\u003C\u002Fcode>: \u003Ccode>null\u003C\u002Fcode> for drafts, \u003Ccode>pending\u003C\u002Fcode> after issuing, \u003Ccode>rendering\u003C\u002Fcode> while the documents\nare rendered, \u003Ccode>done\u003C\u002Fcode> once they are archived, \u003Ccode>failed\u003C\u002Fcode> after the last attempt failed.\n\u003Ccode>render_attempts\u003C\u002Fcode> counts the attempts.\u003C\u002Fp>\n\u003Cp>\u003Ccode>validation_status\u003C\u002Fcode>: \u003Ccode>not_checked\u003C\u002Fcode> for drafts, then \u003Ccode>valid\u003C\u002Fcode>, \u003Ccode>warnings\u003C\u002Fcode> or \u003Ccode>invalid\u003C\u002Fcode>. It is\nset from the validation when the invoice is issued. It is replaced by the validation of the\narchived rendering, whose report is stored with the documents.\u003C\u002Fp>\n\u003Ch2 id=\"numbering\">Numbering\u003Ca class=\"q-doc-anchor\" href=\"#numbering\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>An invoice gets its number when it is issued, from a pattern and a counter (sequence). With\nthe German defaults, the invoices of 2026 are numbered \u003Ccode>RE-2026-0001\u003C\u002Fcode>, \u003Ccode>RE-2026-0002\u003C\u002Fcode> …, and\nthe counter starts again in 2027. Cancellations and corrections take the next number of the\nsame sequence, unless you give them their own pattern.\u003C\u002Fp>\n\u003Cp>Change the scheme in \u003Ccode>config\u002Fquittio-managed.php\u003C\u002Fcode>. This example keeps the German pattern and\ngives cancellations their own sequence (\u003Ccode>ST-2026-0001\u003C\u002Fcode> …):\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#8B949E\">\u002F\u002F config\u002Fquittio-managed.php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#A5D6FF\">'numbering'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'pattern'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'RE-{Y}-{seq:4}'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,          \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F null = country pack (DE: RE-{Y}-{seq:4})\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'reset'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'yearly'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,                    \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F never | yearly | monthly, within the country pack's rules\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'start'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 1\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,                           \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F first value of every new sequence (and period)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'per_kind'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#A5D6FF\">        'cancellation'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'ST-{Y}-{seq:4}'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F own sequence, null = shared\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#A5D6FF\">        'correction'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> null\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    ],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'generator'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> null\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,                    \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F class implementing NumberGenerator\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">],\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>An issuer can override \u003Ccode>pattern\u003C\u002Fcode>, \u003Ccode>reset\u003C\u002Fcode>, \u003Ccode>start\u003C\u002Fcode> and \u003Ccode>per_kind\u003C\u002Fcode> in its \u003Ccode>numbering\u003C\u002Fcode> column.\nEach setting is taken from the issuer, then from the configuration, then from the country\npack:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'numbering'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'pattern'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'B-{Y}-{seq:4}'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'start'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 10\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'per_kind'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'cancellation'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'BS-{Y}-{seq:4}'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">]])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ch3 id=\"placeholders\">Placeholders\u003Ca class=\"q-doc-anchor\" href=\"#placeholders\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Placeholder\u003C\u002Fth>\n\u003Cth>Replaced by\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{Y}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Year of the issue date, four digits\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{y}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Year of the issue date, two digits\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{m}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Month of the issue date, two digits\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{seq}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Running number without padding\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{seq:N}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Running number with at least \u003Ccode>N\u003C\u002Fcode> digits (\u003Ccode>N\u003C\u002Fcode> has one or two digits), e.g. \u003Ccode>{seq:4}\u003C\u002Fcode> → \u003Ccode>0042\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{issuer}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Key of the issuer\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{customer}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Buyer identifier (BT-46, see \u003Ca href=\"\u002Fdocs\u002Fconcepts#en-16931-and-business-terms\">Business terms\u003C\u002Fa>), empty without one\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Patterns are checked when they are used (issuing, \u003Ccode>validate()\u003C\u002Fcode>, \u003Ccode>quittio:sequence:set\u003C\u002Fcode>). They\nthrow a \u003Ccode>NumberingException\u003C\u002Fcode> (&quot;Invalid numbering pattern …&quot;) when:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>they contain no \u003Ccode>{seq}\u003C\u002Fcode> \u002F \u003Ccode>{seq:N}\u003C\u002Fcode>, or more than one,\u003C\u002Fli>\n\u003Cli>they contain an unknown placeholder,\u003C\u002Fli>\n\u003Cli>the reset is \u003Ccode>yearly\u003C\u002Fcode> without \u003Ccode>{Y}\u003C\u002Fcode> or \u003Ccode>{y}\u003C\u002Fcode>, or \u003Ccode>monthly\u003C\u002Fcode> without a year and \u003Ccode>{m}\u003C\u002Fcode>\n(numbers would repeat),\u003C\u002Fli>\n\u003Cli>an own sequence per kind could produce the numbers of another sequence of the issuer.\n\u003Ccode>RE-{Y}-{seq}\u003C\u002Fcode> next to \u003Ccode>RE-{Y}-{seq:4}\u003C\u002Fcode> is rejected, and so is \u003Ccode>RE{Y}-{seq:2}7\u003C\u002Fcode> next to\n\u003Ccode>RE{Y}-7{seq:2}\u003C\u002Fcode> (both give \u003Ccode>RE2026-707\u003C\u002Fcode>); \u003Ccode>ST-{Y}-{seq:4}\u003C\u002Fcode> is fine. The check compares\nthe patterns exactly; \u003Ccode>{customer}\u003C\u002Fcode> counts as any text.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>A reset the country pack does not allow, or a \u003Ccode>start\u003C\u002Fcode> below 1, throws a\n\u003Ccode>ConfigurationException\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch3 id=\"sequences-and-resets\">Sequences and resets\u003Ca class=\"q-doc-anchor\" href=\"#sequences-and-resets\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Every number comes from a sequence with the key \u003Ccode>{issuer}:{sequence}:{period}\u003C\u002Fcode>, e.g.\n\u003Ccode>default:invoice:2026\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>{issuer}\u003C\u002Fcode> is the issuer key,\u003C\u002Fli>\n\u003Cli>\u003Ccode>{sequence}\u003C\u002Fcode> is \u003Ccode>invoice\u003C\u002Fcode> (shared by all kinds), or \u003Ccode>cancellation\u003C\u002Fcode> or \u003Ccode>correction\u003C\u002Fcode> when\n\u003Ccode>per_kind\u003C\u002Fcode> gives that kind a pattern of its own,\u003C\u002Fli>\n\u003Cli>\u003Ccode>{period}\u003C\u002Fcode> follows from the reset and the issue date: \u003Ccode>2026\u003C\u002Fcode> (yearly), \u003Ccode>2026-10\u003C\u002Fcode> (monthly)\nor \u003Ccode>all\u003C\u002Fcode> (never).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>A backdated invoice uses the sequence of its period: an invoice dated 2026-12-30 and issued\nin January 2027 gets the next number of \u003Ccode>default:invoice:2026\u003C\u002Fcode>. Resets apply to all\nsequences of an issuer alike.\u003C\u002Fp>\n\u003Cp>\u003Ccode>start\u003C\u002Fcode> is the first value of every new sequence, i.e. also of every new period. To continue\nthe numbers of an old system once, raise the sequence with \u003Ccode>quittio:sequence:set\u003C\u002Fcode> instead\n(see \u003Ca href=\"#managing-sequences\">Managing sequences\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch3 id=\"gapless-numbers\">Gapless numbers\u003Ca class=\"q-doc-anchor\" href=\"#gapless-numbers\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Numbers are assigned inside the issuing transaction only. A draft has none, validation errors\nand failed cancellations use none, and a rolled back transaction gives its number back.\nDeleting a draft therefore never leaves a gap. The unique indexes \u003Ccode>(number_space, number)\u003C\u002Fcode>,\n\u003Ccode>(issuer_id, number)\u003C\u002Fcode> and \u003Ccode>(sequence_key, sequence_value)\u003C\u002Fcode> are the last line of defence.\u003C\u002Fp>\n\u003Cp>How the default generator (\u003Ccode>SequenceNumberGenerator\u003C\u002Fcode>) serialises concurrent issues:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Before the transaction, a missing sequence row is created with \u003Ccode>INSERT … OR IGNORE\u003C\u002Fcode>, so\nthat concurrent first invoices of a period do not deadlock (MySQL).\u003C\u002Fli>\n\u003Cli>Inside the transaction, the row is locked (\u003Ccode>SELECT … FOR UPDATE\u003C\u002Fcode>), the number is formed\nand the counter is raised with a conditional update. If another process changed it in\nbetween (e.g. SQLite without an immediate transaction), the attempt fails and the\ntransaction is retried.\u003C\u002Fli>\n\u003Cli>Deadlocks, lock wait timeouts, serialisation failures (PostgreSQL \u003Ccode>40001\u003C\u002Fcode>, \u003Ccode>40P01\u003C\u002Fcode>) and\n\u003Ccode>database is locked\u003C\u002Fcode> (SQLite) are retried up to three attempts with a short random pause.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>For SQLite in production, set \u003Ccode>'transaction_mode' =&gt; 'IMMEDIATE'\u003C\u002Fcode> and a \u003Ccode>busy_timeout\u003C\u002Fcode> on\nthe connection. The numbering logs a warning once per process when the mode is missing.\u003C\u002Fp>\n\u003Ch3 id=\"number-spaces\">Number spaces\u003Ca class=\"q-doc-anchor\" href=\"#number-spaces\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Invoice numbers must be unique per company (section 14 (4) no. 4 UStG, the German VAT Act).\nA company can have several issuer profiles, e.g. one per brand. The number space\n(\u003Ccode>number_space\u003C\u002Fcode>) groups the profiles of one company: they share their numbers, so a number\nthat one of them used is taken for the others.\u003C\u002Fp>\n\u003Cp>Issued invoices store the number space of their issuer. The unique index\n\u003Ccode>(number_space, number)\u003C\u002Fcode> (and \u003Ccode>(issuer_id, number)\u003C\u002Fcode> as a safeguard) holds even when two\nissuers of the company issue at the same moment.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Default.\u003C\u002Fstrong> When the issuer is created, its number space is \u003Ccode>vat:{VAT id}\u003C\u002Fcode>, otherwise\n\u003Ccode>tax:{tax number}\u003C\u002Fcode>, otherwise \u003Ccode>issuer:{key}\u003C\u002Fcode>. The identifiers are normalised: upper case,\nwithout spaces (also no-break and zero-width spaces), dots, slashes and dashes. Issuers with\nthe same VAT id thus share a number space by default. Until the issuer issues its first\ninvoice, a default follows changes of its VAT id, tax number or key; an explicit value\nstays.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Explicit.\u003C\u002Fstrong> For several brands of one company, give them the same space:\n\u003Ccode>$brand-&gt;forceFill(['number_space' =&gt; $main-&gt;number_space])-&gt;save()\u003C\u002Fcode>. Any name of your own\nworks as well: at most 128 characters, no \u003Ccode>|\u003C\u002Fcode>, no control characters, no surrounding\nwhitespace (\u003Ccode>InvalidIssuerProfile\u003C\u002Fcode> otherwise).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>One company, one space.\u003C\u002Fstrong> Within a tenant, issuers that share a VAT id or a tax number\nmust have the same number space. Saving an issuer that would split a company throws\n\u003Ccode>InvalidIssuerProfile\u003C\u002Fcode> and names the other issuer. Examples: a brand with only the tax\nnumber of the main profile, or a tax number added later to a profile whose other brands use\nanother space.\n\u003Cul>\n\u003Cli>Sharing is transitive: A with VAT id and tax number, B with the tax number and C with the\nVAT id share one space.\u003C\u002Fli>\n\u003Cli>To change the space of issuers that share an identifier, change them together:\n\u003Ccode>NumberSpaces::assign([$a, $b], 'muster')\u003C\u002Fcode> (\u003Ccode>Quittio\\Managed\\Support\\NumberSpaces\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>Saves of issuers of one tenant are serialised (an advisory lock on PostgreSQL,\n\u003Ccode>GET_LOCK()\u003C\u002Fcode> on MySQL with a timeout of 10 seconds, after which \u003Ccode>InvalidIssuerProfile\u003C\u002Fcode>\nasks to try again). So concurrent saves cannot split a company either.\u003C\u002Fli>\n\u003Cli>The check also runs for saves without model events (\u003Ccode>saveQuietly()\u003C\u002Fcode>, \u003Ccode>Event::fake()\u003C\u002Fcode>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Notations are not unified.\u003C\u002Fstrong> A German tax number in the 13-digit format of ELSTER (the\nGerman tax authorities' electronic filing system) and in the regional format\n(\u003Ccode>12\u002F345\u002F67890\u003C\u002Fcode>) are different values. If the profiles of one company use different\nnotations, or one has only the VAT id and another only the tax number, set the same\n\u003Ccode>number_space\u003C\u002Fcode> explicitly.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Tenants.\u003C\u002Fstrong> Number spaces apply within the tenant of the issuer (\u003Ccode>tenant_type\u003C\u002Fcode>,\n\u003Ccode>tenant_id\u003C\u002Fcode>). The invoices store them qualified by the tenant, e.g. \u003Ccode>team:7|vat:DE123456789\u003C\u002Fcode>\nfor \u003Ccode>tenant_type\u003C\u002Fcode> \u003Ccode>team\u003C\u002Fcode> and \u003Ccode>tenant_id\u003C\u002Fcode> 7 (\u003Ccode>NumberSpaces::qualified($issuer)\u003C\u002Fcode>). So the same\nVAT id or space name in another tenant never blocks a number, and errors never name issuers\nof other tenants. With \u003Ccode>tenancy.scope\u003C\u002Fcode>, an issuer without a tenant is a tenant of its own\n(\u003Ccode>issuer:{id}|…\u003C\u002Fcode>; give the issuers of one company the same tenant). Without it, the issuers\nwithout a tenant form one tenant. Decide on \u003Ccode>tenancy.scope\u003C\u002Fcode> before issuing invoices: it\nchanges the number spaces of issuers without a tenant.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Frozen.\u003C\u002Fstrong> Once an issuer has issued invoices, its number space and its tenant cannot\nchange (\u003Ccode>NumberingException\u003C\u002Fcode>). Its VAT id and tax number still can, within the rule above.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Issuers that share a number space and use the same pattern compete for the same numbers: the\nsecond one cannot use a number the first one took (\u003Ccode>NumberingException\u003C\u002Fcode> naming the other\nissuer). Give such issuers different patterns, e.g. with \u003Ccode>{issuer}\u003C\u002Fcode>, also for the sequences\nper kind (\u003Ccode>numbering.per_kind\u003C\u002Fcode> per issuer).\u003C\u002Fp>\n\u003Ch3 id=\"managing-sequences\">Managing sequences\u003Ca class=\"q-doc-anchor\" href=\"#managing-sequences\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:sequence:show\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">                               # all sequences\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:sequence:show\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --issuer=default\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:sequence:set\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> default:invoice:2026\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 1043\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">      # only increases, asks\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:sequence:set\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> default:invoice:2027\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 1\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --force\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\"> # creates a sequence ahead of time\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>quittio:sequence:show\u003C\u002Fcode> lists key, next value and pattern.\u003C\u002Fp>\n\u003Cp>\u003Ccode>quittio:sequence:set\u003C\u002Fcode> sets the next value of a sequence: a positive integer above the\ncurrent one, after a confirmation unless \u003Ccode>--force\u003C\u002Fcode>. It only creates sequences the numbering\nwould use:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>the issuer must exist,\u003C\u002Fli>\n\u003Cli>the sequence must be \u003Ccode>invoice\u003C\u002Fcode> or a kind with its own pattern,\u003C\u002Fli>\n\u003Cli>the period must match the reset (\u003Ccode>2026\u003C\u002Fcode>, \u003Ccode>2026-10\u003C\u002Fcode> or \u003Ccode>all\u003C\u002Fcode>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The pattern comes from the configuration at that moment. Sequences are created automatically\nwhen the first invoice of a period is issued.\u003C\u002Fp>\n\u003Cp>The \u003Ccode>Sequence\u003C\u002Fcode> model never lowers a counter (also not from a stale model) and writes every\nchange to the audit log (\u003Ccode>sequence_changed\u003C\u002Fcode>). Key and pattern never change, and sequences\ncannot be deleted. Bulk updates, increments, touches, upserts, deletes and\n\u003Ccode>updateOrInsert()\u003C\u002Fcode> of these columns throw \u003Ccode>NumberingException\u003C\u002Fcode>. Change a counter through the\nmodel only:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Managed\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$sequence \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Managed\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">sequenceModel\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">where\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'key'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'default:invoice:2026'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">sole\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$sequence\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'next_value'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 1043\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();     \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F lower values throw\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ch3 id=\"own-number-generators\">Own number generators\u003Ca class=\"q-doc-anchor\" href=\"#own-number-generators\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Numbers from another system (e.g. an ERP) come from a class implementing\n\u003Ccode>Quittio\\Managed\\Numbering\\NumberGenerator\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Data\\InvoiceData\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Support\\Date\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Numbering\\IssuedNumber\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Numbering\\NumberGenerator\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">final\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> class\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> ErpNumbers\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> implements\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> NumberGenerator\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#8B949E\">    \u002F\u002F Before the issuing transaction, e.g. to create a missing counter.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> prepare\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Date\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $issueDate, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceData\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $data)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> void\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> {}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#8B949E\">    \u002F\u002F The probable number, used to validate the invoice; must not consume a number.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> preview\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Date\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $issueDate, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceData\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $data)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> $this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">erp\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">peek\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#8B949E\">    \u002F\u002F Inside the issuing transaction; a rollback must give the number back.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> next\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Date\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $issueDate, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceData\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $data)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> IssuedNumber\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> IssuedNumber\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">erp\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">take\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">());   \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F sequenceKey and sequenceValue optional\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#8B949E\">\u002F\u002F config\u002Fquittio-managed.php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#A5D6FF\">'numbering'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'generator'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> App\\Billing\\ErpNumbers\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>An own generator is responsible for unique and gapless numbers. The unique index\n\u003Ccode>(number_space, number)\u003C\u002Fcode> (and \u003Ccode>(issuer_id, number)\u003C\u002Fcode>) remains as a safeguard: a number already\nused in the number space throws \u003Ccode>NumberingException\u003C\u002Fcode> (&quot;The invoice number … is already\ntaken&quot;). \u003Ccode>IssuedNumber\u003C\u002Fcode> takes \u003Ccode>string $number, ?string $sequenceKey = null, ?int $sequenceValue = null\u003C\u002Fcode>. To change only the format, extend \u003Ccode>SequenceNumberGenerator\u003C\u002Fcode> and\noverride its protected methods \u003Ccode>scheme()\u003C\u002Fcode> or \u003Ccode>format()\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"rendering-and-archive\">Rendering and archive\u003Ca class=\"q-doc-anchor\" href=\"#rendering-and-archive\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Issuing only stores data. The documents (PDF and\u002For XML) are rendered afterwards by a queued\njob and stored in the archive. The archive is write-once: a file is never overwritten. For\nevery file, a SHA-256 hash (a fingerprint that changes when the file changes) is stored with\nthe invoice, so that changed or missing files are detected.\u003C\u002Fp>\n\u003Ch3 id=\"render-job\">Render job\u003Ca class=\"q-doc-anchor\" href=\"#render-job\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>After the issuing transaction has been committed, the job\n\u003Ccode>Quittio\\Managed\\Rendering\\RenderInvoiceDocuments\u003C\u002Fcode> renders and archives the documents of the\ninvoice. It runs on \u003Ccode>queue.connection\u003C\u002Fcode> and \u003Ccode>queue.queue\u003C\u002Fcode> (default queue \u003Ccode>quittio\u003C\u002Fcode>).\u003C\u002Fp>\n\u003Cp>It is tried \u003Ccode>count(queue.backoff) + 1\u003C\u002Fcode> times, by default again after 10 s, 1 min, 5 min and\n30 min. After the last attempt, the invoice is marked \u003Ccode>failed\u003C\u002Fcode>, the audit entry\n\u003Ccode>render_failed\u003C\u002Fcode> is written and \u003Ccode>InvoiceRenderFailed\u003C\u002Fcode> is dispatched. The invoice stays issued.\u003C\u002Fp>\n\u003Cp>With \u003Ccode>queue.render_sync\u003C\u002Fcode>, the documents are rendered in the same request, right after the\ncommit and before \u003Ccode>InvoiceIssued\u003C\u002Fcode>. A failure is logged as an error and marks the invoice\n\u003Ccode>failed\u003C\u002Fcode> at once (no retries). It never undoes the issue.\u003C\u002Fp>\n\u003Cp>The documents are rendered from the frozen data snapshot with the format, profile, locale\nand country pack of the invoice. Validation runs again but does not block: its result is\nstored as the validation report and as \u003Ccode>validation_status\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch3 id=\"archive-layout\">Archive layout\u003Ca class=\"q-doc-anchor\" href=\"#archive-layout\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Documents are stored on the disk \u003Ccode>quittio-managed.disk\u003C\u002Fcode>, in the directory of\n\u003Ccode>quittio-managed.path\u003C\u002Fcode> (default \u003Ccode>{issuer}\u002F{Y}\u002F{m}\u002F{number}\u002Fv{version}\u003C\u002Fcode>):\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Placeholder\u003C\u002Fth>\n\u003Cth>Replaced by\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{issuer}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Issuer key\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{Y}\u003C\u002Fcode>, \u003Ccode>{m}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Year and month of the issue date\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{number}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Invoice number\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{uuid}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">UUID of the invoice\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>{version}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Replaced by\">Document version (1, 2, …)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>\u003Ccode>{issuer}\u003C\u002Fcode> and \u003Ccode>{number}\u003C\u002Fcode> are made safe as single path segments: characters other than\nletters, digits, \u003Ccode>.\u003C\u002Fcode>, \u003Ccode>_\u003C\u002Fcode> and \u003Ccode>-\u003C\u002Fcode> become \u003Ccode>_\u003C\u002Fcode>, so \u003Ccode>RE\u002F2026\u002F1\u003C\u002Fcode> becomes \u003Ccode>RE_2026_1\u003C\u002Fcode>. The pattern\nmust contain \u003Ccode>{version}\u003C\u002Fcode> and \u003Ccode>{number}\u003C\u002Fcode> or \u003Ccode>{uuid}\u003C\u002Fcode>, because every version and every invoice\nneeds a directory of its own. Otherwise archiving throws a \u003Ccode>ConfigurationException\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>The file names follow \u003Ccode>quittio.pdf.filename\u003C\u002Fcode> (default \u003Ccode>{title}_{number}.{ext}\u003C\u002Fcode>), e.g.\n\u003Ccode>default\u002F2026\u002F10\u002FRE-2026-0042\u002Fv1\u002FRechnung_RE-2026-0042.pdf\u003C\u002Fcode> (&quot;Rechnung&quot; is the German title,\ninvoice).\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Format\u003C\u002Fth>\n\u003Cth>Archived files\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>zugferd\u003C\u002Fcode> (\u003Ccode>factur-x\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Archived files\">PDF\u002FA-3 and the embedded XML as its own file (byte-identical)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>xrechnung-cii\u003C\u002Fcode>, \u003Ccode>xrechnung-ubl\u003C\u002Fcode>, \u003Ccode>cii\u003C\u002Fcode>, \u003Ccode>ubl\u003C\u002Fcode>, \u003Ccode>peppol\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Archived files\">XML\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pdf\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Archived files\">PDF\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>See \u003Ca href=\"\u002Fdocs\u002Fconcepts#formats\">Formats\u003C\u002Fa> for what these formats are. Every version also holds\n\u003Ccode>validation-report.json\u003C\u002Fcode>, the validation result of the rendering.\u003C\u002Fp>\n\u003Cp>The invoice keeps \u003Ccode>disk\u003C\u002Fcode>, \u003Ccode>xml_path\u003C\u002Fcode>, \u003Ccode>pdf_path\u003C\u002Fcode>, the SHA-256 hashes \u003Ccode>xml_hash\u003C\u002Fcode> and\n\u003Ccode>pdf_hash\u003C\u002Fcode>, \u003Ccode>validation_report_path\u003C\u002Fcode> and \u003Ccode>document_version\u003C\u002Fcode>. Archiving writes the audit\nentry \u003Ccode>rendered\u003C\u002Fcode> (version, disk, files, report, hashes) and dispatches\n\u003Ccode>InvoiceDocumentsStored\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>For production, use an object store with object lock (WORM: write once, read many) and\nversioning, so that nobody can delete or replace the files.\u003C\u002Fp>\n\u003Ch3 id=\"versions-and-re-rendering\">Versions and re-rendering\u003Ca class=\"q-doc-anchor\" href=\"#versions-and-re-rendering\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Files are never overwritten: writing a file that exists with other content throws an\n\u003Ccode>ArchiveException\u003C\u002Fcode> (identical content is accepted). Archiving an invoice again:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>does nothing when the files of the current version are complete and unchanged (only the\nrender status is set to \u003Ccode>done\u003C\u002Fcode>),\u003C\u002Fli>\n\u003Cli>renders a new version when files are missing (\u003Ccode>ArchiveIntegrityViolation\u003C\u002Fcode> with the problem\n\u003Ccode>missing\u003C\u002Fcode> is dispatched for each),\u003C\u002Fli>\n\u003Cli>never replaces damaged files: a hash mismatch dispatches \u003Ccode>ArchiveIntegrityViolation\u003C\u002Fcode> and\nthrows an \u003Ccode>ArchiveException\u003C\u002Fcode>, so the files stay for the investigation.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>A version directory that already holds files (e.g. of a failed attempt), or whose files are\nrecorded for another invoice, is skipped. Only the archiver changes the archive columns of an\nissued invoice, and only together with a higher document version.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:render\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> RE-2026-0042\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">    # number, UUID or id; renders missing or failed documents\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>quittio:render {invoice}\u003C\u002Fcode> prints the problems it found and the new version, or that the\ndocuments are complete. Damaged files are not rendered again: the command reports the\n\u003Ccode>ArchiveException\u003C\u002Fcode> and fails. A number that exists for several issuers must be given as UUID.\nDrafts cannot be rendered.\u003C\u002Fp>\n\u003Ch3 id=\"archive-manifest\">Archive manifest\u003Ca class=\"q-doc-anchor\" href=\"#archive-manifest\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Every archive file is recorded in \u003Ccode>quittio_archive_files\u003C\u002Fcode> (invoice id, disk, path) before it\nis written. The manifest has two purposes:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>quittio:retention:check\u003C\u002Fcode> can delete the files of all versions, also those of a rendering\nthat failed halfway, and retry files it could not delete.\u003C\u002Fli>\n\u003Cli>Two invoices with the same archive path cannot write into the same directory.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The rows have no foreign key: they outlive their invoice until the files are gone.\u003C\u002Fp>\n\u003Ch3 id=\"integrity-checks\">Integrity checks\u003Ca class=\"q-doc-anchor\" href=\"#integrity-checks\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:verify\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">                                   # all issued invoices\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:verify\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --from=2026-01-01\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --to=2026-12-31\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --issuer=default\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>quittio:verify\u003C\u002Fcode> checks the SHA-256 hashes of the current version of every issued invoice\n(issue date from \u003Ccode>--from\u003C\u002Fcode> to \u003Ccode>--to\u003C\u002Fcode>, optionally of one issuer key). It also reports issued\ninvoices whose documents were never archived (render status \u003Ccode>pending\u003C\u002Fcode>, \u003Ccode>rendering\u003C\u002Fcode> or\n\u003Ccode>failed\u003C\u002Fcode>).\u003C\u002Fp>\n\u003Cp>It dispatches \u003Ccode>ArchiveIntegrityViolation\u003C\u002Fcode> for every problem, writes the audit entry\n\u003Ccode>verified\u003C\u002Fcode> (checked, violations, from, to), prints a table and exits with a failure code if\nit found problems. \u003Ccode>send()\u003C\u002Fcode> checks the hashes before every delivery as well.\u003C\u002Fp>\n\u003Cp>\u003Ccode>ArchiveIntegrityViolation\u003C\u002Fcode> carries the invoice, the path and the problem: \u003Ccode>missing\u003C\u002Fcode>,\n\u003Ccode>hash mismatch\u003C\u002Fcode> or (from \u003Ccode>quittio:verify\u003C\u002Fcode>) \u003Ccode>not archived (render status: …)\u003C\u002Fcode>. The path is \u003Ccode>-\u003C\u002Fcode>\nwhen the invoice has no archived file at all.\u003C\u002Fp>\n\u003Ch3 id=\"reading-archived-documents\">Reading archived documents\u003Ca class=\"q-doc-anchor\" href=\"#reading-archived-documents\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Illuminate\\Support\\Facades\\Storage\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Rendering\\DocumentArchiver\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#D2A8FF\">app\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">DocumentArchiver\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">assertIntact\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoice);    \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F ArchiveException if missing or changed\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">return\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Storage\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">disk\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">disk)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">download\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">pdf_path);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#D2A8FF\">app\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">DocumentArchiver\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">problems\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoice);        \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F ['path' => 'missing' | 'hash mismatch']\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>\u003Ccode>DocumentArchiver\u003C\u002Fcode> method\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>archive(Invoice $invoice): bool\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Renders and archives unless the current version is complete; \u003Ccode>false\u003C\u002Fcode> when nothing had to be done\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>assertIntact(Invoice $invoice): void\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Throws \u003Ccode>ArchiveException\u003C\u002Fcode> (and dispatches \u003Ccode>ArchiveIntegrityViolation\u003C\u002Fcode>) unless the current version is complete and unchanged\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>problems(Invoice $invoice): array\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Missing files and hash mismatches of the current version\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"own-archive-storage\">Own archive storage\u003Ca class=\"q-doc-anchor\" href=\"#own-archive-storage\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The archive goes through \u003Ccode>Quittio\\Managed\\Rendering\\ArchiveStorage\u003C\u002Fcode> (default:\n\u003Ccode>FilesystemArchive\u003C\u002Fcode> on Laravel disks). An own implementation must keep files write-once:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Method\u003C\u002Fth>\n\u003Cth>Contract\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>put(string $disk, string $path, string $contents): void\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Contract\">Never overwrites: identical content is accepted, other content throws \u003Ccode>ArchiveException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>get(string $disk, string $path): ?string\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Contract\">\u003Ccode>null\u003C\u002Fcode> when the file is missing\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>exists(string $disk, string $path): bool\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Contract\">\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>delete(string $disk, string $path): bool\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Contract\">Used after the retention period\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Bind it in a service provider (see \u003Ca href=\"#own-services\">Own services\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch2 id=\"cancellations-and-corrections\">Cancellations and corrections\u003Ca class=\"q-doc-anchor\" href=\"#cancellations-and-corrections\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>An issued invoice is never changed. To reverse or fix it, you issue a new document that\nrefers to it:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>cancel()\u003C\u002Fcode> reverses the whole invoice (or what is left of it), e.g. when it was charged\ntwice. The result is a cancellation invoice, in Germany titled &quot;Stornorechnung&quot;.\u003C\u002Fli>\n\u003Cli>\u003Ccode>cancelPartially()\u003C\u002Fcode> reverses some lines, quantities or amounts, e.g. a returned item or a\nprice reduction.\u003C\u002Fli>\n\u003Cli>\u003Ccode>correct()\u003C\u002Fcode> starts a draft with the data of the original. You change it and issue it as the\ncorrected invoice.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Builder\\InvoiceBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$cancellation \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">cancel\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">reason\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Charged twice'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$cancellation \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">cancel\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Charged twice'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'2026-10-06'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);   \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F with issue date\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$cancellation \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">cancelPartially\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'line'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> '3'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],                       \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F whole line (or what is left of it)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'line'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> '1'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'quantity'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> 1\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],      \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F 1 of 3\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'line'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> '2'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'amount'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> '50.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">],  \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F amount, e.g. a price reduction\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">], \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">reason\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Partial return'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">correct\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">updateData\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceBuilder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $b) => $b\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">updateLine\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'2'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">netPrice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'80.00'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>The original only gets a new status. Every cancellation and correction is an invoice of its\nown with its own number. It is built from the snapshot of the original,\nin the same format, profile and locale, with the same \u003Ccode>billable\u003C\u002Fcode> and \u003Ccode>invoiceable\u003C\u002Fcode>. It refers\nto the original (preceding invoice reference, BG-3, and \u003Ccode>preceding_invoice_id\u003C\u002Fcode>).\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Method\u003C\u002Fth>\n\u003Cth>Signature\u003C\u002Fth>\n\u003Cth>Returns\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancel()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Signature\">\u003Ccode>?string $reason = null, Date|DateTimeInterface|string|null $issueDate = null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">The issued cancellation\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancelPartially()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Signature\">\u003Ccode>array $lines, ?string $reason = null, Date|DateTimeInterface|string|null $issueDate = null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">The issued partial cancellation\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>correct()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Signature\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">A draft of kind \u003Ccode>correction\u003C\u002Fcode>; issue it with \u003Ccode>issue()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Allowed for\u003C\u002Fth>\n\u003Cth>\u003Ccode>cancel()\u003C\u002Fcode>\u003C\u002Fth>\n\u003Cth>\u003Ccode>cancelPartially()\u003C\u002Fcode>\u003C\u002Fth>\n\u003Cth>\u003Ccode>correct()\u003C\u002Fcode>\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issued\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"cancel()\">yes\u003C\u002Ftd>\n\u003Ctd data-label=\"cancelPartially()\">yes\u003C\u002Ftd>\n\u003Ctd data-label=\"correct()\">yes\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>partially_cancelled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"cancel()\">yes (the remainder)\u003C\u002Ftd>\n\u003Ctd data-label=\"cancelPartially()\">yes\u003C\u002Ftd>\n\u003Ctd data-label=\"correct()\">no\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancelled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"cancel()\">no (\u003Ccode>NothingToCancel\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"cancelPartially()\">no (\u003Ccode>NothingToCancel\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"correct()\">no\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>draft\u003C\u002Ftd>\n\u003Ctd data-label=\"cancel()\">no\u003C\u002Ftd>\n\u003Ctd data-label=\"cancelPartially()\">no\u003C\u002Ftd>\n\u003Ctd data-label=\"correct()\">no\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>kind \u003Ccode>cancellation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"cancel()\">no\u003C\u002Ftd>\n\u003Ctd data-label=\"cancelPartially()\">no\u003C\u002Ftd>\n\u003Ctd data-label=\"correct()\">no\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>document level allowances or charges\u003C\u002Ftd>\n\u003Ctd data-label=\"cancel()\">yes\u003C\u002Ftd>\n\u003Ctd data-label=\"cancelPartially()\">no\u003C\u002Ftd>\n\u003Ctd data-label=\"correct()\">yes\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"full-cancellation\">Full cancellation\u003Ca class=\"q-doc-anchor\" href=\"#full-cancellation\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>cancel()\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Col>\n\u003Cli>checks the original (see the table above: \u003Ccode>InvalidInvoiceState\u003C\u002Fcode> or \u003Ccode>NothingToCancel\u003C\u002Fcode>) and\nthat the issuer is still the company that issued it,\u003C\u002Fli>\n\u003Cli>builds the cancellation with the core (see\n\u003Ca href=\"\u002Fdocs\u002Fgetting-started#cancellation\">Getting started\u003C\u002Fa>): for an invoice that was partially\ncancelled before, only what is left,\u003C\u002Fli>\n\u003Cli>creates a draft of kind \u003Ccode>cancellation\u003C\u002Fcode> and issues it with its own number (the steps of\n\u003Ca href=\"#issuing\">Issuing\u003C\u002Fa>). Inside the issuing transaction:\n\u003Cul>\n\u003Cli>the original is locked and read again, and the remainder is checked again,\u003C\u002Fli>\n\u003Cli>the relation \u003Ccode>cancels\u003C\u002Fcode> is recorded,\u003C\u002Fli>\n\u003Cli>the original becomes \u003Ccode>cancelled\u003C\u002Fcode> (with \u003Ccode>cancelled_at\u003C\u002Fcode>, \u003Ccode>cancellation_reason\u003C\u002Fcode> and a\nraised \u003Ccode>cancellations\u003C\u002Fcode> counter),\u003C\u002Fli>\n\u003Cli>the audit entry \u003Ccode>cancelled\u003C\u002Fcode> is written on the original,\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fli>\n\u003Cli>dispatches \u003Ccode>InvoiceCancelled\u003C\u002Fcode> after the commit.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>If the cancellation cannot be issued (e.g. because it is invalid), its draft is deleted again\n(audit entry \u003Ccode>deleted_draft\u003C\u002Fcode>), the original model shows its stored state again and no number\nis used up.\u003C\u002Fp>\n\u003Cp>The cancellation document:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>has the type code of the sign strategy (see\n\u003Ca href=\"#sign-strategies-and-credit-notes\">Sign strategies and credit notes\u003C\u002Fa>) and the title of the\ncountry pack (DE: &quot;Stornorechnung&quot;, cancellation invoice),\u003C\u002Fli>\n\u003Cli>states in a note which invoice it cancels and the reason, e.g. &quot;Stornierung der Rechnung\nRE-2026-0042 vom 05.10.2026. Grund: Charged twice&quot; (Cancellation of invoice RE-2026-0042 of\n05.10.2026. Reason: Charged twice),\u003C\u002Fli>\n\u003Cli>keeps the regulatory and tax notes of the original (invoice notes, BT-22, with the subject\ncodes \u003Ccode>REG\u003C\u002Fcode> or \u003Ccode>TXD\u003C\u002Fcode>),\u003C\u002Fli>\n\u003Cli>keeps, when it cancels everything that is left, the paid amount (BT-113) and the rounding\namount (BT-114), so that all cancellations together reverse exactly the amount due,\u003C\u002Fli>\n\u003Cli>cannot be dated before the original.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"partial-cancellation\">Partial cancellation\u003Ca class=\"q-doc-anchor\" href=\"#partial-cancellation\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>cancelPartially()\u003C\u002Fcode> takes a list of line selections:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Selection\u003C\u002Fth>\n\u003Cth>Cancels\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>['line' =&gt; '3']\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cancels\">The whole line, or what is left of it\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>['line' =&gt; '1', 'quantity' =&gt; 1]\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cancels\">A quantity (int or numeric string)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>['line' =&gt; '2', 'amount' =&gt; '50.00']\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cancels\">An amount (string): the net amount; for a line with a price including VAT, the amount including VAT\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>\u003Ccode>line\u003C\u002Fcode> is the line id (BT-126, \u003Ccode>InvoiceLine::$id\u003C\u002Fcode>). The builder numbers lines \u003Ccode>'1'\u003C\u002Fcode>, \u003Ccode>'2'\u003C\u002Fcode>, …\nunless you set ids. The rules:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Cancelled quantities and amounts are tracked per line. More than invoiced cannot be\ncancelled, also not by processes that cancel at the same time.\u003C\u002Fli>\n\u003Cli>Quantities and amounts are magnitudes: negative lines (discounts, returns) are reversed with\ntheir sign.\u003C\u002Fli>\n\u003Cli>After an amount cancellation, the rest of a line can only be cancelled by amount.\u003C\u002Fli>\n\u003Cli>The last part of a line cancels exactly its remaining net amount (as an amount), so the net\namounts of all cancellations add up exactly to the original. A line whose net amount is\ncancelled completely is closed, even if rounding left a quantity.\u003C\u002Fli>\n\u003Cli>Lines with a price including VAT (gross price mode) are tracked and cancelled by their\namount including VAT. The last part cancels exactly the remaining gross amount, so the\namounts due add up exactly.\u003C\u002Fli>\n\u003Cli>Partial cancellations are not possible for invoices with document level allowances or\ncharges (\u003Ccode>InvalidArgumentException\u003C\u002Fcode> of the core): cancel the invoice fully and issue a new\none.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The original becomes \u003Ccode>partially_cancelled\u003C\u002Fcode> (relation \u003Ccode>partially_cancels\u003C\u002Fcode>, audit entry\n\u003Ccode>partially_cancelled\u003C\u002Fcode>, event \u003Ccode>InvoicePartiallyCancelled\u003C\u002Fcode>). Once the partial cancellations\ncover everything, it becomes \u003Ccode>cancelled\u003C\u002Fcode> instead, with \u003Ccode>cancelled_at\u003C\u002Fcode> and the reason of the\nlast part, the audit entry \u003Ccode>cancelled\u003C\u002Fcode> and the event \u003Ccode>InvoiceCancelled\u003C\u002Fcode>. \u003Ccode>cancel()\u003C\u002Fcode> on a\npartially cancelled invoice cancels the remainder.\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Error\u003C\u002Fth>\n\u003Cth>Exception\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Empty list\u003C\u002Ftd>\n\u003Ctd data-label=\"Exception\">\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Unknown line, line already cancelled completely, more than is left, a quantity after an amount cancellation\u003C\u002Ftd>\n\u003Ctd data-label=\"Exception\">\u003Ccode>UnexpectedValueException\u003C\u002Fcode> (message names the line and what is left)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Document level allowances or charges\u003C\u002Ftd>\n\u003Ctd data-label=\"Exception\">\u003Ccode>InvalidArgumentException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Quantity or amount given as float (\u003Ccode>2.5\u003C\u002Fcode> instead of \u003Ccode>'2.5'\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Exception\">\u003Ccode>InvalidArgumentException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Another partial cancellation was issued meanwhile\u003C\u002Ftd>\n\u003Ctd data-label=\"Exception\">\u003Ccode>InvalidInvoiceState\u003C\u002Fcode> (&quot;… partially cancelled in the meantime; try again&quot;), no number used up\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"vat-of-partial-cancellations\">VAT of partial cancellations\u003Ca class=\"q-doc-anchor\" href=\"#vat-of-partial-cancellations\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>VAT is calculated per document and VAT group (category and rate) and rounded there (EN 16931\nrule BR-CO-17, see \u003Ca href=\"\u002Fdocs\u002Fconcepts#rules-and-validation\">Rules and validation\u003C\u002Fa>). If every partial\ncancellation rounded its VAT on its own, all parts together could differ from the original by\na cent or more. A partial cancellation therefore rounds its VAT cumulatively, together with\nthe earlier partial cancellations of the same original:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Per VAT group, the target is round2(taxable amount of all cancellations so far × rate).\nOnce all lines of the group are cancelled, the target is the original's VAT amount\n(BT-117).\u003C\u002Fli>\n\u003Cli>The cancellation carries the target minus the VAT already cancelled.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Example: three parts of 9.67, 9.67 and 9.66 net at 19 % carry 1.84, 1.83 and 1.84 VAT, 5.51\nin total. Rounded per document, they would carry 3 × 1.84 = 5.52.\u003C\u002Fp>\n\u003Cp>In gross price mode, the taxable amount follows the same way from the gross amount. Per VAT\ngroup it is round2(gross amount cancelled so far \u002F (1 + rate)), as for the original, or the\noriginal's taxable amount (BT-116) once the group is closed. The rounding amount (BT-114)\nfollows, so that the amount due of every part stays the gross amount of its lines. Example:\n3 × 9.99 including 19 % (25.18 net, 4.78 VAT, rounding amount 0.01) are cancelled as 8.39,\n8.40 and 8.39 net (rounded per document: 3 × 8.39 = 25.17).\u003C\u002Fp>\n\u003Cp>This holds for every sequence of partial cancellations (and the rest with \u003Ccode>cancel()\u003C\u002Fcode>):\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Per VAT group, the taxable amounts (BT-116, the taxable amount of section 17 (1) UStG) and\nthe VAT amounts (BT-117) of all cancellations add up exactly to the original's. So do the\ntotals and amounts due (BT-109 net total, BT-110 VAT total, BT-112 gross total, BT-114\nrounding amount, BT-115 amount due).\u003C\u002Fli>\n\u003Cli>Every single cancellation differs by at most one cent from round2(its own taxable amount ×\nrate), and its VAT has the sign of its taxable amount (0.00 on 0.00).\u003C\u002Fli>\n\u003Cli>BR-CO-17 and BR-S-09 accept up to one currency unit (the official Schematron validation\nrules check exactly this tolerance), so every document stays valid.\u003C\u002Fli>\n\u003Cli>Such a cancellation says so in its note: &quot;Rundungsausgleich: Die Umsatzsteuer dieses\nTeilstornos ist so bemessen, dass alle Teilstornos zur Rechnung RE-… zusammen deren\nUmsatzsteuer exakt berichtigen.&quot; (Rounding adjustment: all partial cancellations together\ncorrect the VAT of the invoice exactly.) The\nvalidation reports the information \u003Ccode>QUITTIO-CANCELLATION-VAT-ALIGNED\u003C\u002Fcode> instead of the\nwarning \u003Ccode>QUITTIO-VAT-ROUNDING\u003C\u002Fcode>. That warning still reports a larger difference or another\nsign.\u003C\u002Fli>\n\u003Cli>The VAT total in accounting currency (BT-111, with a VAT accounting currency BT-6) is\naligned the same way: round2(VAT cancelled so far × exchange rate), and the original's\nBT-111 with the last part.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>How it is recorded:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>The relation of every cancellation records (column \u003Ccode>vat\u003C\u002Fcode>), per VAT group, the taxable\namount, the VAT, the share of BT-111 and, in gross price mode, the gross amount.\u003C\u002Fli>\n\u003Cli>A partial cancellation that another process issues in the meantime changes the VAT of the\nnext part. That part is then rejected (&quot;partially cancelled in the meantime; try again&quot;)\nwithout using up a number.\u003C\u002Fli>\n\u003Cli>A single full cancellation reverses the original exactly.\u003C\u002Fli>\n\u003Cli>Drafts keep a declared VAT breakdown only for such aligned cancellations. Every other\ninvoice is recalculated with Quittio's rounding when it is issued, also a draft started with\n\u003Ccode>InvoiceBuilder::from()\u003C\u002Fcode> on data another system rounded.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The one-cent alignment was confirmed by a tax adviser in October 2026 (see the legal review in\nthe README).\u003C\u002Fp>\n\u003Ch3 id=\"sign-strategies-and-credit-notes\">Sign strategies and credit notes\u003Ca class=\"q-doc-anchor\" href=\"#sign-strategies-and-credit-notes\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>A cancellation is either a credit note with positive amounts or an invoice with negative\namounts. The type code (the document type, BT-3, from the UN code list UNTDID 1001) tells\nwhich:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Strategy (\u003Ccode>quittio.corrections.cancellation_strategy\u003C\u002Fcode>)\u003C\u002Fth>\n\u003Cth>Type code\u003C\u002Fth>\n\u003Cth>Amounts\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>credit_note\u003C\u002Fcode> (default, also of the German pack)\u003C\u002Ftd>\n\u003Ctd data-label=\"Type code\">381\u003C\u002Ftd>\n\u003Ctd data-label=\"Amounts\">positive; the \u003Ca href=\"\u002Fdocs\u002Fconcepts#syntaxes-cii-and-ubl\">UBL syntax\u003C\u002Fa> writes a \u003Ccode>CreditNote\u003C\u002Fcode> document\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>negative_invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type code\">380\u003C\u002Ftd>\n\u003Ctd data-label=\"Amounts\">negative\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The key lives in \u003Ccode>config\u002Fquittio.php\u003C\u002Fcode> (env \u003Ccode>QUITTIO_CANCELLATION_STRATEGY\u003C\u002Fcode>); \u003Ccode>null\u003C\u002Fcode> takes the\ncountry pack's default. A credit note (381 and the other credit note type codes) is\ncancelled with an invoice (380) with the same positive amounts in both strategies.\u003C\u002Fp>\n\u003Cp>Credit notes can be issued as ordinary managed invoices: set the type code in the builder\n(\u003Ccode>-&gt;type(InvoiceTypeCode::CreditNote)\u003C\u002Fcode>). They are cancelled with a 380 invoice and corrected\nwith a credit note, with the strategy \u003Ccode>cancel_and_reissue\u003C\u002Fcode> only.\u003C\u002Fp>\n\u003Ch3 id=\"cancellation-ledger\">Cancellation ledger\u003Ca class=\"q-doc-anchor\" href=\"#cancellation-ledger\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Relations (\u003Ccode>quittio_invoice_relations\u003C\u002Fcode>) point from the new document (\u003Ccode>invoice_id\u003C\u002Fcode>) to the\noriginal (\u003Ccode>related_invoice_id\u003C\u002Fcode>). The cancelling ones (\u003Ccode>cancels\u003C\u002Fcode>, \u003Ccode>partially_cancels\u003C\u002Fcode>,\n\u003Ccode>replaces\u003C\u002Fcode>) make up the cancellation ledger of the original:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Column\u003C\u002Fth>\n\u003Cth>Content\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>type\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">\u003Ccode>cancels\u003C\u002Fcode>, \u003Ccode>partially_cancels\u003C\u002Fcode>, \u003Ccode>corrects\u003C\u002Fcode>, \u003Ccode>replaces\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>amount\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Cancellations: the cancelled net amount, always positive\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>lines\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Cancellations: per original line \u003Ccode>line\u003C\u002Fcode>, \u003Ccode>quantity\u003C\u002Fcode> (\u003Ccode>null\u003C\u002Fcode> for amount cancellations), \u003Ccode>net\u003C\u002Fcode> and, for gross price lines, \u003Ccode>gross\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>vat\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Cancellations: per VAT group \u003Ccode>key\u003C\u002Fcode> (e.g. \u003Ccode>S|19.00\u003C\u002Fcode>), \u003Ccode>category\u003C\u002Fcode>, \u003Ccode>rate\u003C\u002Fcode>, \u003Ccode>taxable\u003C\u002Fcode>, \u003Ccode>tax\u003C\u002Fcode>, \u003Ccode>tax_in_tax_currency\u003C\u002Fcode>, \u003Ccode>gross\u003C\u002Fcode>, signed like the original\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>created_at\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Time of the relation\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">inverseRelations;                 \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F cancellations and corrections of this invoice\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$cancellation\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">relations;                   \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F what this document cancels or corrects\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$cancellation\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">precedingInvoice;            \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F the original\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$relation\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">cancelledLines\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F decoded lines\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$relation\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">cancelledVat\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                  \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F decoded VAT groups, null if not recorded\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>The service \u003Ccode>Quittio\\Managed\\Corrections\\CancellationLedger\u003C\u002Fcode> computes what is left:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Corrections\\CancellationLedger\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$ledger \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> app\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">CancellationLedger\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">foreach\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> ($ledger\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">balances\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoice) \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">as\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $lineId \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $balance) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#8B949E\">    \u002F\u002F LineBalance: quantity, amount, remainingQuantity, remainingAmount, amountCancelled, gross\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#79C0FF\">    echo\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $lineId, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">': '\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, $balance\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">remainingQuantity, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">' \u002F '\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, $balance\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">remainingAmount, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">PHP_EOL\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$ledger\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">isFullyCancelled\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoice);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$ledger\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">remainder\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoice);               \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F null if nothing was cancelled, otherwise the open selections\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$ledger\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">count\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($invoice);                   \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F number of cancelling documents\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Method\u003C\u002Fth>\n\u003Cth>Returns\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>balances(Invoice $original)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>LineBalance\u003C\u002Fcode> per line id: \u003Ccode>isOpen()\u003C\u002Fcode>, \u003Ccode>byAmount()\u003C\u002Fcode>, \u003Ccode>isUntouched()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>remainder(Invoice $original)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">Selections for the rest (\u003Ccode>NothingToCancel\u003C\u002Fcode> if nothing is left), \u003Ccode>null\u003C\u002Fcode> if untouched\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>isFullyCancelled(Invoice $original)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">Whether no line is open\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>count(Invoice $original)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">Number of cancelling relations\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>normalize(Invoice $original, array $requested)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">The selections checked against the remainder (whole lines become quantities or amounts)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>history(Invoice $original, array $recorded)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">\u003Ccode>CancellationHistory\u003C\u002Fcode> of the core: VAT cancelled so far per group\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>record(InvoiceData $cancellation, ?array $requested)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">The \u003Ccode>lines\u003C\u002Fcode> entry of a relation\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>vat(InvoiceData $original, InvoiceData $cancellation)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Returns\">The \u003Ccode>vat\u003C\u002Fcode> entry of a relation\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The amount of a line is its net amount, for gross price lines its gross amount (as\nmagnitudes). Relations cannot be changed. They are deleted only together with their invoice\nafter its retention period.\u003C\u002Fp>\n\u003Ch3 id=\"corrections\">Corrections\u003Ca class=\"q-doc-anchor\" href=\"#corrections\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>correct()\u003C\u002Fcode> creates a draft of kind \u003Ccode>correction\u003C\u002Fcode> with the data of the original:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>no number,\u003C\u002Fli>\n\u003Cli>the type code 380 (a credit note keeps its credit note type code),\u003C\u002Fli>\n\u003Cli>a reference to the original (BG-3, number and date),\u003C\u002Fli>\n\u003Cli>no due date: it follows from the payment terms again when the correction is issued.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Change it with \u003Ccode>updateData()\u003C\u002Fcode>, preview it, then \u003Ccode>issue()\u003C\u002Fcode> it. Issuing follows\n\u003Ccode>quittio-managed.correction.strategy\u003C\u002Fcode> (env \u003Ccode>QUITTIO_CORRECTION_STRATEGY\u003C\u002Fcode>; \u003Ccode>null\u003C\u002Fcode> = the\ncountry pack's default, DE: \u003Ccode>cancel_and_reissue\u003C\u002Fcode>):\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Strategy\u003C\u002Fth>\n\u003Cth>Issuing the correction\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancel_and_reissue\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Issuing the correction\">Cancels the original completely, then issues the correction as a new invoice with the relation \u003Ccode>corrects\u003C\u002Fcode>. The reason of the cancellation comes from the translation \u003Ccode>quittio-managed::invoice.correction_reason\u003C\u002Fcode> (&quot;Rechnungskorrektur.&quot;, invoice correction). Events \u003Ccode>InvoiceCancelled\u003C\u002Fcode> and \u003Ccode>InvoiceCorrected\u003C\u002Fcode>; two numbers are used.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>corrected_invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Issuing the correction\">Issues the correction with type code 384 (corrected invoice) and the title of the country pack (DE: &quot;Rechnungskorrektur&quot;), relation \u003Ccode>replaces\u003C\u002Fcode>. The original becomes \u003Ccode>cancelled\u003C\u002Fcode> with the reason \u003Ccode>quittio-managed::invoice.replaced_by\u003C\u002Fcode> (&quot;Ersetzt durch Rechnung RE-2026-0043.&quot;, replaced by invoice RE-2026-0043). Event \u003Ccode>InvoiceCorrected\u003C\u002Fcode> (no \u003Ccode>InvoiceCancelled\u003C\u002Fcode>).\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Both steps run in one transaction: either both documents exist or none (an invalid correction\nalso rolls back the cancellation). The audit entry \u003Ccode>corrected\u003C\u002Fcode> (correction number and\nrelation type) is written on the original.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Only \u003Ccode>issued\u003C\u002Fcode> invoices can be corrected, not cancellations and not partially cancelled ones\n(\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>). For a partially cancelled invoice, cancel the remainder with\n\u003Ccode>cancel()\u003C\u002Fcode> and issue a new invoice.\u003C\u002Fli>\n\u003Cli>A credit note is corrected with a credit note and only with \u003Ccode>cancel_and_reissue\u003C\u002Fcode>.\n\u003Ccode>corrected_invoice\u003C\u002Fcode> throws \u003Ccode>InvalidInvoiceState\u003C\u002Fcode> for credit notes, because 384 is a\ncorrected invoice.\u003C\u002Fli>\n\u003Cli>An unknown strategy throws \u003Ccode>ConfigurationException\u003C\u002Fcode>. The strategy is checked when the draft\nis created and again when it is issued.\u003C\u002Fli>\n\u003Cli>The correction cannot be dated before the original, and the issuer must still be the company\nthat issued it.\u003C\u002Fli>\n\u003Cli>Corrections can themselves be cancelled, partially cancelled and corrected.\u003C\u002Fli>\n\u003Cli>A correction draft whose original was cancelled, partially cancelled or replaced meanwhile\ncan no longer be issued; \u003Ccode>quittio:drafts:prune\u003C\u002Fcode> deletes it.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The default strategy, cancel and reissue, was confirmed by a tax adviser in October 2026 (see the\nlegal review in the README).\u003C\u002Fp>\n\u003Ch3 id=\"left-behind-drafts\">Left-behind drafts\u003Ca class=\"q-doc-anchor\" href=\"#left-behind-drafts\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>A draft of a cancellation exists only while \u003Ccode>cancel()\u003C\u002Fcode> or \u003Ccode>cancelPartially()\u003C\u002Fcode> issues it. A\ncorrection draft can only be issued while its original can be corrected. Drafts that are left\nbehind are removed by a command:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:drafts:prune\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">                     # asks\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:drafts:prune\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --older-than=120\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --force\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>quittio:drafts:prune\u003C\u002Fcode> deletes:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>cancellation drafts older than \u003Ccode>--older-than\u003C\u002Fcode> minutes (default 60), left behind e.g. by a\ncrash,\u003C\u002Fli>\n\u003Cli>correction drafts whose original can no longer be corrected (cancelled, partially cancelled\nor replaced meanwhile, or deleted).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>A draft that has been issued meanwhile is never deleted. Every deletion writes\n\u003Ccode>deleted_draft\u003C\u002Fcode> to the audit log.\u003C\u002Fp>\n\u003Ch3 id=\"self-billing\">Self-billing\u003Ca class=\"q-doc-anchor\" href=\"#self-billing\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Self-billing means that the buyer issues the invoice for the seller's supply (in Germany a\n&quot;Gutschrift&quot; in the sense of the UStG; see \u003Ca href=\"\u002Fdocs\u002Fconcepts#german-terms\">German terms\u003C\u002Fa>). It is not\npart of version 1.0: the seller of every managed invoice is its issuer. The core keeps\nself-billed documents self-billed when it cancels them (type codes 389 and 261).\u003C\u002Fp>\n\u003Ch2 id=\"delivery\">Delivery\u003Ca class=\"q-doc-anchor\" href=\"#delivery\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>\u003Ccode>send()\u003C\u002Fcode> mails the archived documents of an issued invoice and logs every attempt.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$delivery \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">send\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                                    \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F address from the billable or the buyer\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$delivery \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">send\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'accounting@kunde.de'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'cfo@kunde.de'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>send(?string $to = null, array $cc = [])\u003C\u002Fcode> returns the \u003Ccode>Delivery\u003C\u002Fcode> row. It:\u003C\u002Fp>\n\u003Col>\n\u003Cli>refuses drafts (\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>); cancelled invoices, cancellations and corrections\ncan be sent,\u003C\u002Fli>\n\u003Cli>renders and archives the documents first if the render status is not \u003Ccode>done\u003C\u002Fcode> (in the\nrequest, so it can throw),\u003C\u002Fli>\n\u003Cli>checks the hashes of the archived files: missing or damaged files dispatch\n\u003Ccode>ArchiveIntegrityViolation\u003C\u002Fcode> and throw an \u003Ccode>ArchiveException\u003C\u002Fcode>; nothing is sent and no\ndelivery is logged,\u003C\u002Fli>\n\u003Cli>takes the recipient from \u003Ccode>$to\u003C\u002Fcode> or the recipient resolver (\u003Ccode>NoRecipient\u003C\u002Fcode> if there is none),\u003C\u002Fli>\n\u003Cli>attaches the archived PDF (ZUGFeRD, PDF), otherwise the archived XML (XRechnung, CII, UBL,\nPeppol). With \u003Ccode>delivery.mail.xrechnung_visualization\u003C\u002Fcode>, a PDF visualisation of an XML-only\ninvoice is rendered from the snapshot and attached as well (it is not archived),\u003C\u002Fli>\n\u003Cli>logs the attempt in \u003Ccode>quittio_deliveries\u003C\u002Fcode> (status \u003Ccode>queued\u003C\u002Fcode>) and sends the mail at once with\nthe default mailer (\u003Ccode>sendNow()\u003C\u002Fcode>, also for an own Mailable that implements \u003Ccode>ShouldQueue\u003C\u002Fcode>):\nto \u003Ccode>$to\u003C\u002Fcode>, with \u003Ccode>$cc\u003C\u002Fcode> and a blind copy to \u003Ccode>delivery.mail.bcc_archive\u003C\u002Fcode>,\u003C\u002Fli>\n\u003Cli>on success: delivery \u003Ccode>sent\u003C\u002Fcode> with \u003Ccode>message_id\u003C\u002Fcode> (\u003Ccode>null\u003C\u002Fcode> when the mailer returns no message,\ne.g. with \u003Ccode>Mail::fake()\u003C\u002Fcode>) and \u003Ccode>sent_at\u003C\u002Fcode>; invoice \u003Ccode>delivery_status\u003C\u002Fcode> \u003Ccode>sent\u003C\u002Fcode>, \u003Ccode>sent_at\u003C\u002Fcode> and\n\u003Ccode>channel\u003C\u002Fcode> \u003Ccode>mail\u003C\u002Fcode>; audit entry \u003Ccode>sent\u003C\u002Fcode>; event \u003Ccode>InvoiceSent\u003C\u002Fcode>,\u003C\u002Fli>\n\u003Cli>on failure: delivery \u003Ccode>failed\u003C\u002Fcode> with the error message; invoice \u003Ccode>delivery_status\u003C\u002Fcode> \u003Ccode>failed\u003C\u002Fcode>\n(unless it was sent before); audit entry \u003Ccode>delivery_failed\u003C\u002Fcode>; event \u003Ccode>InvoiceDeliveryFailed\u003C\u002Fcode>;\nthe exception is rethrown.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Every call is a new attempt and a new row; \u003Ccode>$invoice-&gt;deliveries\u003C\u002Fcode> lists them. \u003Ccode>send()\u003C\u002Fcode> sends\nsynchronously. To send in the background, dispatch an own job that calls \u003Ccode>send()\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch3 id=\"recipients\">Recipients\u003Ca class=\"q-doc-anchor\" href=\"#recipients\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The recipient comes from \u003Ccode>delivery.recipient_resolver\u003C\u002Fcode>. The default\n(\u003Ccode>DefaultRecipientResolver\u003C\u002Fcode>) takes the first valid address of:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Ccode>invoiceEmail()\u003C\u002Fcode> of the billable, when it implements\n\u003Ccode>Quittio\\Managed\\Delivery\\HasInvoiceEmail\u003C\u002Fcode>,\u003C\u002Fli>\n\u003Cli>the \u003Ccode>email\u003C\u002Fcode> attribute of the billable,\u003C\u002Fli>\n\u003Cli>the buyer's contact e-mail (BT-58) in the invoice data,\u003C\u002Fli>\n\u003Cli>the buyer's electronic address (BT-49) with scheme \u003Ccode>EM\u003C\u002Fcode>.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>To take the address from elsewhere, implement \u003Ccode>RecipientResolver\u003C\u002Fcode> and set it in\n\u003Ccode>delivery.recipient_resolver\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Delivery\\RecipientResolver\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">final\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> class\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> AccountingRecipient\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> implements\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> RecipientResolver\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> resolve\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> ?string\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">billable\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">?->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">accounting_email;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ch3 id=\"mail-content\">Mail content\u003Ca class=\"q-doc-anchor\" href=\"#mail-content\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The default Mailable \u003Ccode>Quittio\\Managed\\Delivery\\InvoiceMail\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>uses the locale of the invoice, else of the issuer, else \u003Ccode>en\u003C\u002Fcode>,\u003C\u002Fli>\n\u003Cli>has a subject and text by kind (invoice, correction, cancellation),\u003C\u002Fli>\n\u003Cli>has a due date line, except for cancellations and invoices without due date,\u003C\u002Fli>\n\u003Cli>has the seller's name below the closing.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The texts are translations of the namespace \u003Ccode>quittio-managed\u003C\u002Fcode>. Publish them with\n\u003Ccode>--tag=quittio-managed-lang\u003C\u002Fcode>, the Markdown view with \u003Ccode>--tag=quittio-managed-views\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>German default\u003C\u002Fth>\n\u003Cth>English default\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.subject.invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>Rechnung :number von :seller\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>Invoice :number from :seller\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.subject.correction\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>Rechnungskorrektur :number von :seller\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>Corrected invoice :number from :seller\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.subject.cancellation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>Stornorechnung :number von :seller\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>Cancellation :number from :seller\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.greeting\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>Guten Tag,\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>Hello,\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.body.invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>anbei erhalten Sie die Rechnung :number über :amount.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>please find attached invoice :number for :amount.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.body.correction\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>anbei erhalten Sie die Rechnung :number über :amount. Sie korrigiert eine frühere Rechnung.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>please find attached invoice :number for :amount, which corrects an earlier invoice.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.body.cancellation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>anbei erhalten Sie die Stornorechnung :number.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>please find attached the cancellation :number.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.due\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>Bitte überweisen Sie den Betrag bis zum :due_date.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>Please pay the amount by :due_date.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>mail.closing\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>Mit freundlichen Grüßen\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>Kind regards\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>invoice.draft_watermark\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>ENTWURF\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>DRAFT\u003C\u002Fcode> (preview watermark)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>invoice.correction_reason\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>Rechnungskorrektur.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>Correction of the invoice.\u003C\u002Fcode> (reason of the cancellation of \u003Ccode>cancel_and_reissue\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>invoice.replaced_by\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"German default\">\u003Ccode>Ersetzt durch Rechnung :number.\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"English default\">\u003Ccode>Replaced by invoice :number.\u003C\u002Fcode> (reason with \u003Ccode>corrected_invoice\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Placeholders: \u003Ccode>:number\u003C\u002Fcode>, \u003Ccode>:seller\u003C\u002Fcode>, \u003Ccode>:amount\u003C\u002Fcode> (amount due, formatted for the locale) and\n\u003Ccode>:due_date\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>An own Mailable is configured in \u003Ccode>delivery.mail.mailable\u003C\u002Fcode>. The container builds it with the\nnamed arguments \u003Ccode>invoice\u003C\u002Fcode> (the \u003Ccode>Invoice\u003C\u002Fcode>) and \u003Ccode>files\u003C\u002Fcode> (list of \u003Ccode>Illuminate\\Mail\\Attachment\u003C\u002Fcode>\nwith the archived documents). Return the files from \u003Ccode>attachments()\u003C\u002Fcode>; extending \u003Ccode>InvoiceMail\u003C\u002Fcode>\ndoes that for you:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Illuminate\\Mail\\Mailables\\Content\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Delivery\\InvoiceMail\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">final\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> class\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> BrandedInvoiceMail\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> extends\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> InvoiceMail\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> content\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Content\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Content\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">markdown\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'mail.invoice'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\">with\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">: [\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'invoice'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> $this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">invoice]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>send()\u003C\u002Fcode> sends it at once even if it implements \u003Ccode>ShouldQueue\u003C\u002Fcode>, so that the delivery log holds\nthe result of the transport. To send in the background, dispatch an own job that calls\n\u003Ccode>send()\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"audit-log\">Audit log\u003Ca class=\"q-doc-anchor\" href=\"#audit-log\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The audit log records who did what to invoices, issuers and sequences. \u003Ccode>quittio_audit_logs\u003C\u002Fcode>\nis append-only: entries are never changed or deleted. Every entry has:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>an action,\u003C\u002Fli>\n\u003Cli>a subject (the invoice, issuer or sequence; \u003Ccode>null\u003C\u002Fcode> for \u003Ccode>verified\u003C\u002Fcode>),\u003C\u002Fli>\n\u003Cli>a JSON payload,\u003C\u002Fli>\n\u003Cli>the causer: the authenticated user of the default guard (any Eloquent model),\u003C\u002Fli>\n\u003Cli>for HTTP requests, IP address and user agent (at most 255 characters). Console commands and\nqueue jobs record neither.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Action\u003C\u002Fth>\n\u003Cth>Subject\u003C\u002Fth>\n\u003Cth>Payload\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>drafted\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>kind\u003C\u002Fcode>, \u003Ccode>preceding\u003C\u002Fcode> (number of the original)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issued\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>number\u003C\u002Fcode>, \u003Ccode>sequence_key\u003C\u002Fcode>, \u003Ccode>issue_date\u003C\u002Fcode>, \u003Ccode>gross_total\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>rendered\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>version\u003C\u002Fcode>, \u003Ccode>disk\u003C\u002Fcode>, \u003Ccode>files\u003C\u002Fcode>, \u003Ccode>report\u003C\u002Fcode>, \u003Ccode>hashes\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>render_failed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>error\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>sent\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>channel\u003C\u002Fcode>, \u003Ccode>delivery\u003C\u002Fcode> (id), \u003Ccode>attachments\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>delivery_failed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>channel\u003C\u002Fcode>, \u003Ccode>delivery\u003C\u002Fcode> (id)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancelled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">original\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>cancellation\u003C\u002Fcode> (number), \u003Ccode>reason\u003C\u002Fcode>, \u003Ccode>net\u003C\u002Fcode>, \u003Ccode>lines\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>partially_cancelled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">original\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>cancellation\u003C\u002Fcode> (number), \u003Ccode>reason\u003C\u002Fcode>, \u003Ccode>net\u003C\u002Fcode>, \u003Ccode>lines\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>corrected\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">original\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>correction\u003C\u002Fcode> (number), \u003Ccode>type\u003C\u002Fcode> (\u003Ccode>corrects\u003C\u002Fcode> or \u003Ccode>replaces\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>deleted_draft\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>number\u003C\u002Fcode>, \u003Ccode>retention_until\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>deleted\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">invoice\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>number\u003C\u002Fcode>, \u003Ccode>retention_until\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>sequence_changed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">sequence\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>key\u003C\u002Fcode>, \u003Ccode>from\u003C\u002Fcode>, \u003Ccode>to\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issuer_created\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">issuer\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>key\u003C\u002Fcode>, \u003Ccode>changes\u003C\u002Fcode> (per column \u003Ccode>old\u003C\u002Fcode> \u003Ccode>null\u003C\u002Fcode>, \u003Ccode>new\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issuer_updated\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">issuer\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>key\u003C\u002Fcode>, \u003Ccode>changes\u003C\u002Fcode> (per changed column \u003Ccode>old\u003C\u002Fcode>, \u003Ccode>new\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issuer_deleted\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">issuer\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>key\u003C\u002Fcode>, \u003Ccode>changes\u003C\u002Fcode> (per column \u003Ccode>old\u003C\u002Fcode>, \u003Ccode>new\u003C\u002Fcode> \u003Ccode>null\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>verified\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Subject\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Payload\">\u003Ccode>checked\u003C\u002Fcode>, \u003Ccode>violations\u003C\u002Fcode>, \u003Ccode>from\u003C\u002Fcode>, \u003Ccode>to\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">auditLogs\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">orderBy\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'id'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">AuditLog\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">query\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">where\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'action'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'issued'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">where\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'causer_id'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, $user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">id)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">get\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$entry\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">causer;     \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F MorphTo\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$entry\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">subject;    \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F MorphTo\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Not logged:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>changes of drafts (\u003Ccode>updateData()\u003C\u002Fcode>, \u003Ccode>save()\u003C\u002Fcode>), previews and validations,\u003C\u002Fli>\n\u003Cli>bulk deletes of drafts,\u003C\u002Fli>\n\u003Cli>payment, legal hold and retention changes,\u003C\u002Fli>\n\u003Cli>archive integrity violations outside \u003Ccode>quittio:verify\u003C\u002Fcode> (they are events),\u003C\u002Fli>\n\u003Cli>read access.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Recipients and other customer data are not part of the entries: \u003Ccode>sent\u003C\u002Fcode> and \u003Ccode>delivery_failed\u003C\u002Fcode>\nrefer to the delivery row, which is deleted with the invoice (see\n\u003Ca href=\"#personal-data\">Personal data\u003C\u002Fa>).\u003C\u002Fp>\n\u003Cp>\u003Ccode>audit.enabled =&gt; false\u003C\u002Fcode> switches the log off completely. An own implementation of\n\u003Ccode>Quittio\\Managed\\Audit\\Auditor\u003C\u002Fcode> (\u003Ccode>record(?Model $subject, string $action, array $payload = []): ?AuditLog\u003C\u002Fcode>) can be bound in the container, e.g. to write to another store as well.\u003C\u002Fp>\n\u003Ch2 id=\"authorisation\">Authorisation\u003Ca class=\"q-doc-anchor\" href=\"#authorisation\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The package ships two policies, \u003Ccode>InvoicePolicy\u003C\u002Fcode> and \u003Ccode>IssuerPolicy\u003C\u002Fcode>. With \u003Ccode>policies.register\u003C\u002Fcode>,\nthey are registered for the configured invoice and issuer models. The package does not check\nthem itself: call them in your controllers (\u003Ccode>$this-&gt;authorize('issue', $invoice)\u003C\u002Fcode>,\n\u003Ccode>Gate::authorize()\u003C\u002Fcode>, \u003Ccode>@can\u003C\u002Fcode>).\u003C\u002Fp>\n\u003Cp>Every ability needs an authenticated user. It combines the state of the record with an\noptional gate named \u003Ccode>quittio.{ability}\u003C\u002Fcode>. Without such a gate, every authenticated user is\nallowed.\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Policy ability\u003C\u002Fth>\n\u003Cth>Allowed when\u003C\u002Fth>\n\u003Cth>Gate\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>viewAny\u003C\u002Fcode> (invoice class)\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">always\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.viewAny\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>view\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">always\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.view\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>createDraft\u003C\u002Fcode> (invoice class)\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">always\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.createDraft\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>updateDraft\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">the invoice is a draft\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.updateDraft\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>deleteDraft\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">the invoice is a draft\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.deleteDraft\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issue\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">a draft that is not a cancellation draft\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.issue\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancel\u003C\u002Fcode> (also for partial cancellations)\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">issued or partially cancelled, no cancellation\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.cancel\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>correct\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">issued (not partially cancelled), no cancellation\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.correct\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>send\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">issued (any status but draft)\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.send\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>viewAuditLog\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">always\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.viewAuditLog\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>viewAny\u003C\u002Fcode>, \u003Ccode>view\u003C\u002Fcode> (issuer)\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">always\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.manageIssuers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>manageIssuers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">always\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.manageIssuers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>manageSequences\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Allowed when\">always\u003C\u002Ftd>\n\u003Ctd data-label=\"Gate\">\u003Ccode>quittio.manageSequences\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Illuminate\\Support\\Facades\\Gate\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Managed\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Gate\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">define\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'quittio.issue'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">User\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $user, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $invoice) => $user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">isAccountant\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Gate\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">define\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'quittio.manageSequences'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">User\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $user) => $user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">isAdmin\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">can\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'createDraft'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Managed\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">invoiceModel\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">());\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$user\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">can\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'manageSequences'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Managed\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issuerModel\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">());\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Gates receive the user and, for record abilities, the invoice or issuer. \u003Ccode>manageIssuers\u003C\u002Fcode> and\n\u003Ccode>manageSequences\u003C\u002Fcode> receive the issuer or \u003Ccode>null\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"immutability\">Immutability\u003Ca class=\"q-doc-anchor\" href=\"#immutability\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>An issued invoice must stay as it was issued; changes are made with cancellations and\ncorrections. Issued invoices are protected on three levels:\u003C\u002Fp>\n\u003Col>\n\u003Cli>the model (\u003Ccode>ImmutableInvoiceGuard\u003C\u002Fcode>),\u003C\u002Fli>\n\u003Cli>its query builder (\u003Ccode>InvoiceQuery\u003C\u002Fcode>),\u003C\u002Fli>\n\u003Cli>database triggers, recommended for production.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Violations throw \u003Ccode>InvoiceImmutable\u003C\u002Fcode> (model and query builder) or a database error (triggers).\u003C\u002Fp>\n\u003Ch3 id=\"what-can-still-change\">What can still change\u003Ca class=\"q-doc-anchor\" href=\"#what-can-still-change\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>After issuing, the model only lets these columns change. Everything else throws\n\u003Ccode>InvoiceImmutable\u003C\u002Fcode> (&quot;… is issued and immutable; these attributes cannot be changed: …&quot;):\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Columns\u003C\u002Fth>\n\u003Cth>Rule\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>payment_status\u003C\u002Fcode>, \u003Ccode>paid_total\u003C\u002Fcode>, \u003Ccode>paid_at\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Free (see \u003Ca href=\"#payment-status\">Payment status\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>delivery_status\u003C\u002Fcode>, \u003Ccode>sent_at\u003C\u002Fcode>, \u003Ccode>channel\u003C\u002Fcode>, \u003Ccode>lifecycle_status\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Free\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>render_status\u003C\u002Fcode>, \u003Ccode>render_attempts\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Free\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>legal_hold\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">\u003Ccode>true\u003C\u002Fcode>, \u003Ccode>false\u003C\u002Fcode>, \u003Ccode>1\u003C\u002Fcode>, \u003Ccode>0\u003C\u002Fcode>, \u003Ccode>&quot;1&quot;\u003C\u002Fcode> or \u003Ccode>&quot;0&quot;\u003C\u002Fcode> only\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>retention_until\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Can only be extended\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>status\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Forward only, and only through \u003Ccode>issue()\u003C\u002Fcode>, \u003Ccode>cancel()\u003C\u002Fcode>, \u003Ccode>cancelPartially()\u003C\u002Fcode> and the issue of a correction\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancelled_at\u003C\u002Fcode>, \u003Ccode>cancellation_reason\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Written once, together with the status \u003Ccode>cancelled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancellations\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Rises with every cancelling document, up to the number of their relations; the status becomes (partially) cancelled only together with such a rise\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>document_version\u003C\u002Fcode>, \u003Ccode>disk\u003C\u002Fcode>, \u003Ccode>xml_path\u003C\u002Fcode>, \u003Ccode>pdf_path\u003C\u002Fcode>, \u003Ccode>xml_hash\u003C\u002Fcode>, \u003Ccode>pdf_hash\u003C\u002Fcode>, \u003Ccode>validation_status\u003C\u002Fcode>, \u003Ccode>validation_report_path\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Archiver only, together with a higher document version\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>updated_at\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Rule\">Free\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Further rules:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Columns you add to \u003Ccode>quittio_invoices\u003C\u002Fcode> yourself are frozen after issuing as well.\u003C\u002Fli>\n\u003Cli>Invoices are inserted as drafts only.\u003C\u002Fli>\n\u003Cli>Drafts hold no number, number space, sequence key or sequence value (\u003Ccode>issue()\u003C\u002Fcode> sets them).\nThey keep their kind and the invoice they refer to (\u003Ccode>kind\u003C\u002Fcode>, \u003Ccode>preceding_invoice_id\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>Issued invoices can only be deleted one by one after the retention period (plus two days,\nsee \u003Ca href=\"#retention-and-deletion\">Retention and deletion\u003C\u002Fa>) and never under legal hold.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"optimistic-concurrency\">Optimistic concurrency\u003Ca class=\"q-doc-anchor\" href=\"#optimistic-concurrency\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>A save or delete only applies while the row still has the status (and the other stored\nvalues) the model was loaded with. Otherwise it throws \u003Ccode>InvoiceImmutable\u003C\u002Fcode> (&quot;… was changed\n(e.g. issued or cancelled) by another process since it was loaded; load it again&quot;) and\nchanges nothing. Examples: a draft that another process issued meanwhile, or a model whose\noriginal values were changed.\u003C\u002Fp>\n\u003Cp>Partly loaded models (\u003Ccode>select('id')\u003C\u002Fcode>) are checked against the stored row. Load the invoice\nagain in that case.\u003C\u002Fp>\n\u003Ch3 id=\"bulk-queries\">Bulk queries\u003Ca class=\"q-doc-anchor\" href=\"#bulk-queries\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The query builder applies the same rules to bulk operations:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\n\u003Cp>Bulk updates, touches and increments of frozen columns only reach drafts. This also holds\nwith \u003Ccode>orWhere()\u003C\u002Fcode> and with qualified column names (\u003Ccode>quittio_invoices.status\u003C\u002Fcode>) or other letter\ncases.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>On issued invoices, bulk updates may:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>change payment, delivery and rendering columns,\u003C\u002Fli>\n\u003Cli>set \u003Ccode>legal_hold\u003C\u002Fcode> (\u003Ccode>true\u003C\u002Fcode>, \u003Ccode>1\u003C\u002Fcode> or \u003Ccode>&quot;1&quot;\u003C\u002Fcode>; values other than these and \u003Ccode>false\u003C\u002Fcode>, \u003Ccode>0\u003C\u002Fcode>, \u003Ccode>&quot;0&quot;\u003C\u002Fcode>\nthrow),\u003C\u002Fli>\n\u003Cli>extend \u003Ccode>retention_until\u003C\u002Fcode> (rows whose period would shrink are left out).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The status never changes in bulk (it throws), and a legal hold is only released through the\nmodel.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Bulk updates and inserts cannot set \u003Ccode>number\u003C\u002Fcode>, \u003Ccode>number_space\u003C\u002Fcode>, \u003Ccode>sequence_key\u003C\u002Fcode>,\n\u003Ccode>sequence_value\u003C\u002Fcode>, \u003Ccode>kind\u003C\u002Fcode> or \u003Ccode>preceding_invoice_id\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Upserts may only change the bulk columns and insert drafts only. Inserts create drafts\nonly. Bulk deletes, \u003Ccode>forceDelete()\u003C\u002Fcode> and \u003Ccode>truncate()\u003C\u002Fcode> throw if they would reach an issued\ninvoice.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Ccode>updateOrInsert()\u003C\u002Fcode>, \u003Ccode>updateFrom()\u003C\u002Fcode>, \u003Ccode>insertUsing()\u003C\u002Fcode> and \u003Ccode>insertOrIgnoreUsing()\u003C\u002Fcode> are not\navailable.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"append-only-tables\">Append-only tables\u003Ca class=\"q-doc-anchor\" href=\"#append-only-tables\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The audit log and the invoice relations are append-only in the same way: updates, upserts,\nincrements, touches and deletes through the model or its query builder throw. Relations are\nonly deleted together with their invoice after its retention period. Number sequences only\nchange through the \u003Ccode>Sequence\u003C\u002Fcode> model (see \u003Ca href=\"#managing-sequences\">Managing sequences\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch3 id=\"database-triggers\">Database triggers\u003Ca class=\"q-doc-anchor\" href=\"#database-triggers\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Only the base query builder (\u003Ccode>toBase()\u003C\u002Fcode>, \u003Ccode>getQuery()\u003C\u002Fcode>, \u003Ccode>DB::table()\u003C\u002Fcode>) and raw SQL bypass the\nrules above. The database triggers, recommended for production, enforce them against direct\nqueries as well (MySQL\u002FMariaDB, PostgreSQL, SQLite):\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> vendor:publish\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --tag=quittio-managed-triggers\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> migrate\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>The triggers protect:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>issued invoices: frozen columns; a forward-only status that only becomes (partially)\ncancelled together with a rise of the \u003Ccode>cancellations\u003C\u002Fcode> counter, which cannot exceed the\nnumber of cancelling relations; write-once cancellation columns (only together with the\nstatus \u003Ccode>cancelled\u003C\u002Fcode>); a retention period that can only be extended; archive columns only\nwith a higher document version; deletes only two days after the retention period in the\ndatabase clock and never under legal hold,\u003C\u002Fli>\n\u003Cli>drafts: inserted and kept without number, number space and sequence value; fixed kind and\noriginal; issued only with a number, a number space and a retention period and without\ncancellation columns,\u003C\u002Fli>\n\u003Cli>the audit log: no updates, no deletes,\u003C\u002Fli>\n\u003Cli>the invoice relations: no updates; deletes only once their invoice is past its retention\nperiod,\u003C\u002Fli>\n\u003Cli>the number sequences: no lower counter, no new key or pattern, no deletes,\u003C\u002Fli>\n\u003Cli>on PostgreSQL only: none of these tables can be truncated.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The triggers raise errors such as \u003Ccode>quittio: issued invoice is immutable\u003C\u002Fcode>, \u003Ccode>quittio: audit log is append-only\u003C\u002Fcode>, \u003Ccode>quittio: invoice relations are immutable\u003C\u002Fcode> and \u003Ccode>quittio: number sequences only increase\u003C\u002Fcode>. On MySQL with binary logging, creating triggers needs the \u003Ccode>TRIGGER\u003C\u002Fcode> privilege and\n\u003Ccode>log_bin_trust_function_creators\u003C\u002Fcode> (or \u003Ccode>SUPER\u003C\u002Fcode>). Unlike the model, the triggers do not limit\nreleasing a legal hold or which code changes the status.\u003C\u002Fp>\n\u003Cp>Frozen are all columns of an issued invoice except those of\n\u003Ca href=\"#what-can-still-change\">What can still change\u003C\u002Fa>. On PostgreSQL the trigger compares the whole\nrow without them, so columns you add to \u003Ccode>quittio_invoices\u003C\u002Fcode> later are frozen as well. On MySQL,\nMariaDB and SQLite the trigger lists the columns that exist when it is created. Recreate it in\nthe migration that adds columns, with \u003Ccode>ImmutabilityTriggers::refresh()\u003C\u002Fcode>\n(\u003Ccode>Quittio\\Managed\\Immutability\u003C\u002Fcode>):\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Illuminate\\Database\\Schema\\Blueprint\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Illuminate\\Support\\Facades\\Schema\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Immutability\\ImmutabilityTriggers\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Schema\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">table\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'quittio_invoices'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">function\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Blueprint\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $table)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> void\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    $table\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">string\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'erp_reference'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">nullable\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">});\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">ImmutabilityTriggers\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">refresh\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>refresh()\u003C\u002Fcode> recreates only the check of invoice updates, with the columns the table has now.\nIt returns \u003Ccode>false\u003C\u002Fcode> without doing anything when the triggers are not installed.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>On SQLite and PostgreSQL it runs in one transaction.\u003C\u002Fli>\n\u003Cli>MySQL commits each statement, so between dropping and creating the update trigger\n(milliseconds) direct updates are not checked: run it with the migrations, not under load.\u003C\u002Fli>\n\u003Cli>On PostgreSQL it is not needed for new columns. It replaces the trigger function, which\nswitches triggers installed with an earlier version (a column list) to the comparison of\nthe whole row.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"what-is-not-prevented\">What is not prevented\u003Ca class=\"q-doc-anchor\" href=\"#what-is-not-prevented\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>MySQL fires no triggers on \u003Ccode>TRUNCATE\u003C\u002Fcode>. The foreign keys keep invoices and relations from\nbeing truncated, but the audit log and the sequences are not protected. Give the database\nuser of the application no \u003Ccode>DROP\u003C\u002Fcode> privilege on the \u003Ccode>quittio_\u003C\u002Fcode> tables (\u003Ccode>TRUNCATE\u003C\u002Fcode> needs it)\nand run migrations with a separate user.\u003C\u002Fli>\n\u003Cli>Without the triggers, the base query builder and raw SQL can change anything.\u003C\u002Fli>\n\u003Cli>Issuer profiles are protected by their model only: change number spaces, tenants, keys and\nseller identifiers with model saves (\u003Ccode>$issuer-&gt;save()\u003C\u002Fcode>, \u003Ccode>NumberSpaces::assign()\u003C\u002Fcode>). Bulk\nupdates of issuers through the query builder or raw SQL bypass the freeze and the\nconsistency check. The unique index on number space and number still prevents duplicate\nnumbers within a space.\u003C\u002Fli>\n\u003Cli>Deliveries are ordinary rows without protection.\u003C\u002Fli>\n\u003Cli>The archived files are protected by the archive (write-once) and the hashes. A disk without\nobject lock cannot keep an administrator from deleting them; \u003Ccode>quittio:verify\u003C\u002Fcode> detects it.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"retention-and-deletion\">Retention and deletion\u003Ca class=\"q-doc-anchor\" href=\"#retention-and-deletion\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Invoices must be kept for a retention period. In Germany it is 8 years after the end of the\nyear of issue (section 14b UStG, the German VAT Act, and section 147 AO, the German Fiscal\nCode). Without a country pack, it is 10 years.\u003C\u002Fp>\n\u003Cp>\u003Ccode>retention_until\u003C\u002Fcode> is set when the invoice is issued, by the rule of the country pack. It is\ncounted from the later of the issue date and the day the invoice is actually issued.\n\u003Ccode>retention.years\u003C\u002Fcode> can only lengthen it.\u003C\u002Fp>\n\u003Cp>The period can be extended per invoice. An invoice can also be put on legal hold: then it is\nkept beyond its retention period, e.g. during a tax audit or a lawsuit.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'retention_until'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> '2040-12-31'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();   \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F only later dates\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'legal_hold'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> true\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F also in bulk\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">forceFill\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'legal_hold'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> false\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">])\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">save\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();               \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F release: model only\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>The period ends with \u003Ccode>retention_until\u003C\u002Fcode> in the issuer's time zone. The command, the model and\nthe triggers compare with their own clock. They count an invoice as past its period two days\nlater (\u003Ccode>retain until 2034-12-31\u003C\u002Fcode> → from 2035-01-03), when it has ended in every time zone\n(time zones differ by up to 26 hours).\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:retention:check\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">              # list, dispatch RetentionExpired\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:retention:check\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --delete\u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">     # delete, asks for confirmation\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:retention:check\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --delete\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --force\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>\u003Ccode>quittio:retention:check\u003C\u002Fcode> lists the issued invoices past their retention period that are not\non legal hold. It dispatches \u003Ccode>RetentionExpired\u003C\u002Fcode> for each of them, before anything is deleted.\u003C\u002Fp>\n\u003Cp>With \u003Ccode>--delete\u003C\u002Fcode>, it deletes invoices by group:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>A group is an invoice together with all invoices connected to it through cancellations,\npartial cancellations, corrections and replacements (transitively).\u003C\u002Fli>\n\u003Cli>A group is deleted only when every one of its invoices is past its retention period and\nnone is on legal hold. Otherwise the whole group is kept, and the command says which\ninvoice keeps it.\u003C\u002Fli>\n\u003Cli>The rows of a group (invoices, relations, deliveries with recipients and errors, and drafts\nthat refer to one of the invoices) are deleted in one transaction with audit entries\n(\u003Ccode>deleted\u003C\u002Fcode>, \u003Ccode>deleted_draft\u003C\u002Fcode>). Then all archived files of all document versions from the\nmanifest are deleted.\u003C\u002Fli>\n\u003Cli>A file that cannot be deleted stays recorded. The next run reports it\n(\u003Ccode>… archived file(s) of deleted invoices could not be deleted yet\u003C\u002Fcode>) and, with \u003Ccode>--delete\u003C\u002Fcode>,\ntries again.\u003C\u002Fli>\n\u003Cli>With \u003Ccode>--delete\u003C\u002Fcode>, the command fails (exit code 1, \u003Ccode>Not everything could be deleted: …\u003C\u002Fcode>) when\na group or an archived file could not be deleted, after it has dealt with the others. Groups\nkept for a legal hold or a retention period are no failure.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Schedule the command (e.g. monthly) to keep the archive clean.\u003C\u002Fp>\n\u003Cp>Delete issued invoices through this command. A single \u003Ccode>$invoice-&gt;delete()\u003C\u002Fcode> after the\nretention period is allowed by the model, but it fails on the foreign keys while relations or\ncancellations refer to the invoice, and it leaves deliveries and archived files behind.\u003C\u002Fp>\n\u003Ch3 id=\"personal-data\">Personal data\u003Ca class=\"q-doc-anchor\" href=\"#personal-data\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The audit log is append-only and stays after the retention period (GDPR Art. 17, the right to\nerasure, and GoBD), so it holds no recipients or other data of the customers. \u003Ccode>sent\u003C\u002Fcode> and\n\u003Ccode>delivery_failed\u003C\u002Fcode> refer to the delivery (\u003Ccode>delivery\u003C\u002Fcode>: id of the row in \u003Ccode>quittio_deliveries\u003C\u002Fcode>),\nwhich is deleted with the invoice. The invoice data itself is in the invoice row and the\narchived files.\u003C\u002Fp>\n\u003Cp>The audit log keeps the causer, IP address and user agent of the users who acted, and the\nchanges of issuer profiles (the company's own master data). There is no function to\nanonymise issued invoices before the end of their retention period.\u003C\u002Fp>\n\u003Ch2 id=\"testing\">Testing\u003Ca class=\"q-doc-anchor\" href=\"#testing\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Ch3 id=\"factories\">Factories\u003Ca class=\"q-doc-anchor\" href=\"#factories\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Data\\InvoiceData\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Models\\Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$issuer \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">factory\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">default\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">create\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();                 \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F key default, Muster GmbH, DE123456789\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$other \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Issuer\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">factory\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">company\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Andere AG'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'DE111111111'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">create\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'key'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> 'other'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">factory\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">for\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($issuer)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">create\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();              \u003C\u002Fspan>\u003Cspan style=\"color:#8B949E\">\u002F\u002F draft with two sample lines\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$draft \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">factory\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">data\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceData\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">factory\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">reverseCharge\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">make\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">())\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">create\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">$invoice \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">factory\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">create\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'2026-10-05'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Factory\u003C\u002Fth>\n\u003Cth>Definition and states\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Issuer::factory()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Definition and states\">Random key, Muster GmbH with a random VAT id (a company of its own), Germany, \u003Ccode>Europe\u002FBerlin\u003C\u002Fcode>, one bank account, \u003Ccode>defaults\u003C\u002Fcode> locale \u003Ccode>de\u003C\u002Fcode> and 14 due days\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>-&gt;default()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Definition and states\">Key \u003Ccode>default\u003C\u002Fcode>, \u003Ccode>is_default\u003C\u002Fcode>, VAT id \u003Ccode>DE123456789\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>-&gt;company(string $name, string $vatId)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Definition and states\">Another company with its own name and VAT id\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Invoice::factory()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Definition and states\">Draft with \u003Ccode>InvoiceData::factory()-&gt;withLines(2)\u003C\u002Fcode> data and a new issuer\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>-&gt;data(InvoiceData $data)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Definition and states\">Draft with the given data\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The factories make the configured models (\u003Ccode>quittio-managed.models.invoice\u003C\u002Fcode> and \u003Ccode>.issuer\u003C\u002Fcode>),\nalso through the factory of a subclass. Factory drafts are saved directly: they skip the\nseller check, the issuer defaults and the audit entry \u003Ccode>drafted\u003C\u002Fcode>. Issue them with \u003Ccode>issue()\u003C\u002Fcode>;\nthe seller is taken from the issuer then.\u003C\u002Fp>\n\u003Cp>Useful in tests:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>Queue::fake()\u003C\u002Fcode> keeps the render job from running (render status stays \u003Ccode>pending\u003C\u002Fcode>).\n\u003Ccode>config(['quittio-managed.queue.render_sync' =&gt; true])\u003C\u002Fcode> renders at once.\u003C\u002Fli>\n\u003Cli>\u003Ccode>Mail::fake()\u003C\u002Fcode> for \u003Ccode>send()\u003C\u002Fcode>, and a temporary local disk for \u003Ccode>quittio-managed.disk\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Fake single events (\u003Ccode>Event::fake([InvoiceIssued::class])\u003C\u002Fcode>). Faking all events also stops\nthe model events that write the issuer and deletion audit entries.\u003C\u002Fli>\n\u003Cli>SQLite in memory works. Set \u003Ccode>'transaction_mode' =&gt; 'IMMEDIATE'\u003C\u002Fcode> on the test connection to\navoid the numbering warning.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>See \u003Ca href=\"\u002Fdocs\u002Ftesting\">Testing\u003C\u002Fa> for \u003Ccode>Quittio::fake()\u003C\u002Fcode> and the e-invoice assertions.\u003C\u002Fp>\n\u003Ch3 id=\"testing-against-mysql-and-postgresql\">Testing against MySQL and PostgreSQL\u003Ca class=\"q-doc-anchor\" href=\"#testing-against-mysql-and-postgresql\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The package's own test suite (in the repository of \u003Ccode>quittio\u002Fmanaged\u003C\u002Fcode>) runs against SQLite by\ndefault and against MySQL and PostgreSQL from \u003Ccode>tools\u002Fdocker\u002Fdatabases\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">docker\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> compose\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> -f\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> tools\u002Fdocker\u002Fdatabases\u002Fcompose.yaml\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> up\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> -d\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --wait\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">QUITTIO_DB\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">mysql\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> vendor\u002Fbin\u002Fpest\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --testsuite=managed\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">QUITTIO_DB\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">pgsql\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> QUITTIO_DB_TRIGGERS\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> vendor\u002Fbin\u002Fpest\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --testsuite=managed\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cul>\n\u003Cli>\u003Ccode>QUITTIO_DB\u003C\u002Fcode> selects \u003Ccode>sqlite\u003C\u002Fcode> (default, in memory), \u003Ccode>mysql\u003C\u002Fcode> (port 33061) or \u003Ccode>pgsql\u003C\u002Fcode> (port\n54321). \u003Ccode>DB_HOST\u003C\u002Fcode>, \u003Ccode>DB_PORT\u003C\u002Fcode>, \u003Ccode>DB_DATABASE\u003C\u002Fcode>, \u003Ccode>DB_USERNAME\u003C\u002Fcode> and \u003Ccode>DB_PASSWORD\u003C\u002Fcode> override the\nconnection.\u003C\u002Fli>\n\u003Cli>\u003Ccode>QUITTIO_DB_TRIGGERS=1\u003C\u002Fcode> also installs the immutability triggers.\u003C\u002Fli>\n\u003Cli>The group \u003Ccode>concurrency\u003C\u002Fcode> forks processes that issue invoices at the same time (needs \u003Ccode>pcntl\u003C\u002Fcode>\nand MySQL or PostgreSQL).\u003C\u002Fli>\n\u003Cli>The group \u003Ccode>official\u003C\u002Fcode> validates the archived documents with the KoSIT validator (the\nofficial validator for XRechnung and EN 16931) and is skipped when it is not installed.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"known-limitations\">Known limitations\u003Ca class=\"q-doc-anchor\" href=\"#known-limitations\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>Payments, bank reconciliation, dunning runs, subscriptions, advance and final invoices,\nself-billing, inbound invoices, Peppol transmission and DATEV exports are not part of 1.0.\nThe payment columns are maintained by your application.\u003C\u002Fli>\n\u003Cli>Delivery is by mail only (\u003Ccode>channel\u003C\u002Fcode> \u003Ccode>mail\u003C\u002Fcode>). \u003Ccode>lifecycle_status\u003C\u002Fcode>, \u003Ccode>registrations\u003C\u002Fcode> and\n\u003Ccode>network_ids\u003C\u002Fcode> are stored but not evaluated.\u003C\u002Fli>\n\u003Cli>Partial cancellations of invoices with document level allowances or charges are not\nsupported: cancel fully and issue a new invoice.\u003C\u002Fli>\n\u003Cli>Issuer profiles are protected by their model only; bulk updates of issuers bypass the\nnumber space checks.\u003C\u002Fli>\n\u003Cli>Without the triggers, the base query builder and raw SQL bypass the immutability rules.\nMySQL fires no triggers on \u003Ccode>TRUNCATE\u003C\u002Fcode>. On MySQL, MariaDB and SQLite the triggers cover the\ninvoice columns that existed when they were created (see \u003Ccode>ImmutabilityTriggers::refresh()\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>Different notations of one tax number are not unified for the number spaces.\u003C\u002Fli>\n\u003Cli>Issued invoices can be deleted only after their retention period; there is no early\nanonymisation.\u003C\u002Fli>\n\u003Cli>The PDF visualisation sent with an XRechnung (\u003Ccode>delivery.mail.xrechnung_visualization\u003C\u002Fcode>) is\nnot archived. Keep it with the XML if you send it.\u003C\u002Fli>\n\u003Cli>A future DATEV export has to show cash discounts taken per VAT rate with the reduction of\nnet amount and VAT, the invoice number as document field and the payment date, as the\nreduction is corrected in the period of the payment (section 17 UStG).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"configuration\">Configuration\u003Ca class=\"q-doc-anchor\" href=\"#configuration\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>The settings of the Managed layer are in \u003Ccode>config\u002Fquittio-managed.php\u003C\u002Fcode>. The installer\npublishes it; otherwise publish it with \u003Ccode>--tag=quittio-managed-config\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>Values are read when they are used. Exceptions: the classes of the resolvers and the number\ngenerator are resolved once per process, and the morph map, the policies and the tenancy scope\nare registered when the application boots. A value of the wrong type throws a\n\u003Ccode>ConfigurationException\u003C\u002Fcode> (&quot;… must be a string&quot;, &quot;… must be a boolean&quot;, &quot;… must be an\ninteger&quot;). An empty string counts as \u003Ccode>null\u003C\u002Fcode> for string values.\u003C\u002Fp>\n\u003Ch3 id=\"database-settings\">Database settings\u003Ca class=\"q-doc-anchor\" href=\"#database-settings\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Env\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>connection\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">\u003Ccode>QUITTIO_DB_CONNECTION\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Database connection of all Managed tables, models and migrations; \u003Ccode>null\u003C\u002Fcode> = default connection\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>table_prefix\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>'quittio_'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Prefix of every table (\u003Ccode>quittio_invoices\u003C\u002Fcode> …)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>models.issuer\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own subclass of \u003Ccode>Issuer\u003C\u002Fcode> (see \u003Ca href=\"#own-models\">Own models\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>models.invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own subclass of \u003Ccode>Invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>models.sequence\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own subclass of \u003Ccode>Sequence\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>models.invoice_relation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own subclass of \u003Ccode>InvoiceRelation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>models.delivery\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own subclass of \u003Ccode>Delivery\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>models.audit_log\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own subclass of \u003Ccode>AuditLog\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"issuer-and-tenancy-settings\">Issuer and tenancy settings\u003Ca class=\"q-doc-anchor\" href=\"#issuer-and-tenancy-settings\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issuer_resolver\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|Closure|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Determines the current issuer: a class implementing \u003Ccode>IssuerResolver\u003C\u002Fcode> or a Closure returning an \u003Ccode>Issuer\u003C\u002Fcode>; \u003Ccode>null\u003C\u002Fcode> = the issuer marked as default (see \u003Ca href=\"#current-issuer\">Current issuer\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>tenancy.scope\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">bool\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Restricts all invoice queries to the current issuer (see \u003Ca href=\"#tenancy-scope\">Tenancy scope\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"archive-settings\">Archive settings\u003Ca class=\"q-doc-anchor\" href=\"#archive-settings\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Env\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>disk\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>'local'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">\u003Ccode>QUITTIO_DISK\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Filesystem disk of the archive; for production an object store with object lock (WORM) and versioning\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>path\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>'{issuer}\u002F{Y}\u002F{m}\u002F{number}\u002Fv{version}'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Directory of a document version; placeholders \u003Ccode>{issuer}\u003C\u002Fcode> \u003Ccode>{Y}\u003C\u002Fcode> \u003Ccode>{m}\u003C\u002Fcode> \u003Ccode>{number}\u003C\u002Fcode> \u003Ccode>{uuid}\u003C\u002Fcode> \u003Ccode>{version}\u003C\u002Fcode> (see \u003Ca href=\"#archive-layout\">Archive layout\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"queue-settings\">Queue settings\u003Ca class=\"q-doc-anchor\" href=\"#queue-settings\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Env\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>queue.connection\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">\u003Ccode>QUITTIO_QUEUE_CONNECTION\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Queue connection of the render job; \u003Ccode>null\u003C\u002Fcode> = default connection\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>queue.queue\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>'quittio'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">\u003Ccode>QUITTIO_QUEUE\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Queue name of the render job; empty = default queue\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>queue.render_sync\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">bool\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Render in the same request after the commit instead of queueing the job\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>queue.backoff\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">list of int\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>[10, 60, 300, 1800]\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Seconds before each retry; the job tries \u003Ccode>count + 1\u003C\u002Fcode> times\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"numbering-settings\">Numbering settings\u003Ca class=\"q-doc-anchor\" href=\"#numbering-settings\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>numbering.pattern\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Number pattern; \u003Ccode>null\u003C\u002Fcode> = country pack (DE: \u003Ccode>RE-{Y}-{seq:4}\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>numbering.reset\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">\u003Ccode>never\u003C\u002Fcode>, \u003Ccode>yearly\u003C\u002Fcode> or \u003Ccode>monthly\u003C\u002Fcode>; \u003Ccode>null\u003C\u002Fcode> = country pack (DE: \u003Ccode>yearly\u003C\u002Fcode>), limited to the resets the pack allows\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>numbering.start\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">int\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>1\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">First value of every new sequence, also of every new period after a reset; to continue the numbers of an old system, raise its sequence with \u003Ccode>quittio:sequence:set\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>numbering.per_kind.cancellation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own sequence and pattern for cancellations; \u003Ccode>null\u003C\u002Fcode> = shared invoice sequence\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>numbering.per_kind.correction\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own sequence and pattern for corrections; \u003Ccode>null\u003C\u002Fcode> = shared invoice sequence\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>numbering.generator\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Class implementing \u003Ccode>NumberGenerator\u003C\u002Fcode>; \u003Ccode>null\u003C\u002Fcode> = \u003Ccode>SequenceNumberGenerator\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Issuer profiles can override \u003Ccode>pattern\u003C\u002Fcode>, \u003Ccode>reset\u003C\u002Fcode>, \u003Ccode>start\u003C\u002Fcode> and \u003Ccode>per_kind\u003C\u002Fcode> (see\n\u003Ca href=\"#numbering\">Numbering\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch3 id=\"correction-settings\">Correction settings\u003Ca class=\"q-doc-anchor\" href=\"#correction-settings\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Env\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>correction.strategy\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">\u003Ccode>QUITTIO_CORRECTION_STRATEGY\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">\u003Ccode>cancel_and_reissue\u003C\u002Fcode> or \u003Ccode>corrected_invoice\u003C\u002Fcode>; \u003Ccode>null\u003C\u002Fcode> = country pack (DE: \u003Ccode>cancel_and_reissue\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The sign strategy of cancellations is configured in \u003Ccode>config\u002Fquittio.php\u003C\u002Fcode>, see\n\u003Ca href=\"#sign-strategies-and-credit-notes\">Sign strategies and credit notes\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch3 id=\"delivery-settings\">Delivery settings\u003Ca class=\"q-doc-anchor\" href=\"#delivery-settings\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Env\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>delivery.mail.mailable\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Own Mailable (receives \u003Ccode>invoice\u003C\u002Fcode> and \u003Ccode>files\u003C\u002Fcode> in the constructor); \u003Ccode>null\u003C\u002Fcode> = \u003Ccode>InvoiceMail\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>delivery.mail.bcc_archive\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">\u003Ccode>QUITTIO_BCC_ARCHIVE\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Address that receives a blind copy of every invoice mail\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>delivery.mail.xrechnung_visualization\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">bool\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Attach a PDF visualisation to mails of XML-only formats\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>delivery.recipient_resolver\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">class-string|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Env\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Class implementing \u003Ccode>RecipientResolver\u003C\u002Fcode>; \u003Ccode>null\u003C\u002Fcode> = \u003Ccode>DefaultRecipientResolver\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"audit-retention-and-policy-settings\">Audit, retention and policy settings\u003Ca class=\"q-doc-anchor\" href=\"#audit-retention-and-policy-settings\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Type\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Effect\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>audit.enabled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">bool\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">\u003Ccode>false\u003C\u002Fcode> writes no audit entries at all\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>retention.years\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">int|null\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>null\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Retention in years; \u003Ccode>null\u003C\u002Fcode> = country pack (DE: 8 years after the end of the year of issue); a value can only lengthen it, a shorter one throws a \u003Ccode>ConfigurationException\u003C\u002Fcode> when an invoice is issued\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>policies.register\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Type\">bool\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect\">Register \u003Ccode>InvoicePolicy\u003C\u002Fcode> and \u003Ccode>IssuerPolicy\u003C\u002Fcode> with the gate (see \u003Ca href=\"#authorisation\">Authorisation\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"settings-of-configquittiophp-the-managed-layer-uses\">Settings of \u003Ccode>config\u002Fquittio.php\u003C\u002Fcode> the Managed layer uses\u003Ca class=\"q-doc-anchor\" href=\"#settings-of-configquittiophp-the-managed-layer-uses\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Key\u003C\u002Fth>\n\u003Cth>Effect on the Managed layer\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>corrections.cancellation_strategy\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect on the Managed layer\">Sign strategy of cancellations (\u003Ccode>credit_note\u003C\u002Fcode>, \u003Ccode>negative_invoice\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>validation.block_on_warnings\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect on the Managed layer\">\u003Ccode>issue()\u003C\u002Fcode> also refuses invoices with warnings\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>validation.*\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect on the Managed layer\">Validation levels applied when issuing and archiving (see \u003Ca href=\"\u002Fdocs\u002Fvalidation\">Validation\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pdf.template\u003C\u002Fcode>, \u003Ccode>pdf.templates\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect on the Managed layer\">Templates an issuer may choose in \u003Ccode>branding.template\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pdf.filename\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect on the Managed layer\">File names in the archive (default \u003Ccode>{title}_{number}.{ext}\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>countries\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Effect on the Managed layer\">Country packs (numbering, retention, correction policy, titles)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>See \u003Ca href=\"\u002Fdocs\u002Fconfiguration\">Configuration\u003C\u002Fa> for these keys. The \u003Ccode>seller\u003C\u002Fcode> section is not used for\ninvoices of the Managed layer: issuer profiles replace it.\u003C\u002Fp>\n\u003Ch3 id=\"own-models\">Own models\u003Ca class=\"q-doc-anchor\" href=\"#own-models\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Replace a model with your own subclass:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#8B949E\">\u002F\u002F config\u002Fquittio-managed.php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#A5D6FF\">'models'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#A5D6FF\">    'invoice'\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> App\\Models\\Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">],\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">namespace\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> App\\Models\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Enums\\PaymentStatus\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">class\u003C\u002Fspan>\u003Cspan style=\"color:#FFA657\"> Invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> extends\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> \\Quittio\\Managed\\Models\\Invoice\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    public\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> isPaid\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\"> bool\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:10ch;text-indent:-10ch\">\u003Cspan style=\"color:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> $this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">payment_status \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">===\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> PaymentStatus\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Paid\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>The class must extend the package model, otherwise a \u003Ccode>ConfigurationException\u003C\u002Fcode> (&quot;… must be a\nsubclass of …&quot;) is thrown. The package resolves every model through \u003Ccode>Managed::issuerModel()\u003C\u002Fcode>,\n\u003Ccode>Managed::invoiceModel()\u003C\u002Fcode>, \u003Ccode>Managed::sequenceModel()\u003C\u002Fcode>, \u003Ccode>Managed::relationModel()\u003C\u002Fcode>,\n\u003Ccode>Managed::deliveryModel()\u003C\u002Fcode> and \u003Ccode>Managed::auditLogModel()\u003C\u002Fcode> (class \u003Ccode>Quittio\\Managed\\Managed\u003C\u002Fcode>).\nUse them in your code as well. The morph map, the policies and the tenancy scope use the\nconfigured classes.\u003C\u002Fp>\n\u003Cp>Keep the query builders of the package models (\u003Ccode>InvoiceQuery\u003C\u002Fcode>, \u003Ccode>SequenceQuery\u003C\u002Fcode>,\n\u003Ccode>AppendOnlyQuery\u003C\u002Fcode>): the invoice model throws a \u003Ccode>LogicException\u003C\u002Fcode> without its \u003Ccode>InvoiceQuery\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>Further helpers: \u003Ccode>Managed::table('invoices')\u003C\u002Fcode> (table name with prefix),\n\u003Ccode>Managed::connection()\u003C\u002Fcode> and \u003Ccode>Managed::settings()\u003C\u002Fcode> (typed access to the configuration).\u003C\u002Fp>\n\u003Ch3 id=\"own-services\">Own services\u003Ca class=\"q-doc-anchor\" href=\"#own-services\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>The package binds these services as singletons. Replace them in a service provider, or, where\na key exists, in the configuration:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Contract\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Configuration key\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Quittio\\Managed\\Issuers\\IssuerResolver\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>DefaultIssuerResolver\u003C\u002Fcode> (\u003Ccode>CallbackIssuerResolver\u003C\u002Fcode> for a Closure)\u003C\u002Ftd>\n\u003Ctd data-label=\"Configuration key\">\u003Ccode>issuer_resolver\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Quittio\\Managed\\Numbering\\NumberGenerator\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>SequenceNumberGenerator\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Configuration key\">\u003Ccode>numbering.generator\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Quittio\\Managed\\Delivery\\RecipientResolver\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>DefaultRecipientResolver\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Configuration key\">\u003Ccode>delivery.recipient_resolver\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Quittio\\Managed\\Rendering\\ArchiveStorage\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>FilesystemArchive\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Configuration key\">–\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Quittio\\Managed\\Audit\\Auditor\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Default\">\u003Ccode>DatabaseAuditor\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Configuration key\">–\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">$this\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">app\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">singleton\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">ArchiveStorage\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">MyWormArchive\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Classes from the configuration are resolved through the container and must implement the\ncontract (\u003Ccode>ConfigurationException\u003C\u002Fcode> otherwise). Only \u003Ccode>issuer_resolver\u003C\u002Fcode> accepts a Closure.\u003C\u002Fp>\n\u003Ch2 id=\"console-commands\">Console commands\u003Ca class=\"q-doc-anchor\" href=\"#console-commands\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Command\u003C\u002Fth>\n\u003Cth>Purpose\u003C\u002Fth>\n\u003Cth>See\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio:install --managed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Purpose\">Publish configuration and migrations, migrate, create the first issuer\u003C\u002Ftd>\n\u003Ctd data-label=\"See\">\u003Ca href=\"#installation\">Installation\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio:render {invoice}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Purpose\">Render missing or failed documents of a stored invoice as a new version\u003C\u002Ftd>\n\u003Ctd data-label=\"See\">\u003Ca href=\"#versions-and-re-rendering\">Versions and re-rendering\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio:verify {--from=} {--to=} {--issuer=}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Purpose\">Check the archive hashes\u003C\u002Ftd>\n\u003Ctd data-label=\"See\">\u003Ca href=\"#integrity-checks\">Integrity checks\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio:sequence:show {--issuer=}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Purpose\">List the number sequences\u003C\u002Ftd>\n\u003Ctd data-label=\"See\">\u003Ca href=\"#managing-sequences\">Managing sequences\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio:sequence:set {key} {value} {--force}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Purpose\">Raise or create a number sequence\u003C\u002Ftd>\n\u003Ctd data-label=\"See\">\u003Ca href=\"#managing-sequences\">Managing sequences\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio:retention:check {--delete} {--force}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Purpose\">List and delete invoices past their retention period\u003C\u002Ftd>\n\u003Ctd data-label=\"See\">\u003Ca href=\"#retention-and-deletion\">Retention and deletion\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio:drafts:prune {--older-than=60} {--force}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Purpose\">Delete left-behind cancellation and correction drafts\u003C\u002Ftd>\n\u003Ctd data-label=\"See\">\u003Ca href=\"#left-behind-drafts\">Left-behind drafts\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The commands ignore the tenancy scope. See \u003Ca href=\"\u002Fdocs\u002Fcommands\">Artisan commands\u003C\u002Fa> for all\nsignatures. For example, scheduled in production:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#8B949E\">\u002F\u002F routes\u002Fconsole.php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Illuminate\\Support\\Facades\\Schedule\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Schedule\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">command\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'quittio:verify'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">daily\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Schedule\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">command\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'quittio:drafts:prune --force'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">hourly\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Schedule\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">command\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'quittio:retention:check'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">)\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">monthly\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ch3 id=\"publish-tags\">Publish tags\u003Ca class=\"q-doc-anchor\" href=\"#publish-tags\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>\u003Ccode>php artisan vendor:publish --tag=…\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Tag\u003C\u002Fth>\n\u003Cth>Publishes\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio-managed-config\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Publishes\">\u003Ccode>config\u002Fquittio-managed.php\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio-managed-migrations\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Publishes\">the migrations\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio-managed-triggers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Publishes\">the immutability triggers (recommended, see \u003Ca href=\"#database-triggers\">Database triggers\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio-managed-views\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Publishes\">the mail view (\u003Ccode>resources\u002Fviews\u002Fvendor\u002Fquittio-managed\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio-managed-lang\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Publishes\">the translations (\u003Ccode>lang\u002Fvendor\u002Fquittio-managed\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch2 id=\"events\">Events\u003Ca class=\"q-doc-anchor\" href=\"#events\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>All events are in the namespace \u003Ccode>Quittio\\Managed\\Events\u003C\u002Fcode> and have public readonly properties.\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Event\u003C\u002Fth>\n\u003Cth>Dispatched\u003C\u002Fth>\n\u003Cth>Properties\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceDrafted\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">A draft was created (also drafts of cancellations and corrections); after the commit when it was created inside a transaction, so the cancellation draft of a correction that rolls back is not announced\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceIssuing\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">A draft is about to be issued: validated, no number yet; a listener that throws stops the issue. Not followed by \u003Ccode>InvoiceIssued\u003C\u002Fcode> when the issue fails afterwards\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceIssued\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">After the issuing transaction was committed and the render job was queued (or the documents rendered)\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceDocumentsStored\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">A new document version was rendered and archived\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceRenderFailed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">Rendering failed after the last attempt (with \u003Ccode>render_sync\u003C\u002Fcode>: after the first); the invoice stays issued\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>, \u003Ccode>exception\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceCancelled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">After the commit: the original was cancelled completely (\u003Ccode>cancel()\u003C\u002Fcode>, the last partial cancellation, \u003Ccode>cancel_and_reissue\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode> (original), \u003Ccode>cancellation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoicePartiallyCancelled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">After the commit: parts of the original were cancelled\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode> (original), \u003Ccode>cancellation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceCorrected\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">After the commit: a correction of the original was issued\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode> (original), \u003Ccode>correction\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceSent\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">The mail was sent\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>, \u003Ccode>delivery\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceDeliveryFailed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">Sending failed (before the exception is rethrown)\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>, \u003Ccode>delivery\u003C\u002Fcode>, \u003Ccode>exception\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>ArchiveIntegrityViolation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">An archived file is missing or changed (archiving, \u003Ccode>send()\u003C\u002Fcode>, \u003Ccode>quittio:verify\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>, \u003Ccode>path\u003C\u002Fcode>, \u003Ccode>problem\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>RetentionExpired\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Dispatched\">\u003Ccode>quittio:retention:check\u003C\u002Fcode> found the invoice past its retention period and not on legal hold, before anything is deleted\u003C\u002Ftd>\n\u003Ctd data-label=\"Properties\">\u003Ccode>invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>After a cancellation is committed, the order is: render job of the cancellation,\n\u003Ccode>InvoiceIssued\u003C\u002Fcode> (of the cancellation), then \u003Ccode>InvoiceCancelled\u003C\u002Fcode> or \u003Ccode>InvoicePartiallyCancelled\u003C\u002Fcode>.\nA listener of an after-commit event that throws does not undo anything: the exception reaches\nthe caller after all after-commit work has run.\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Event\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">listen\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceIssued\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">InvoiceIssued\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $e) => $e\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">billable\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">?->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">notify\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">new\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> InvoiceReady\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($e\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">invoice)));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#79C0FF\">Event\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">listen\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">ArchiveIntegrityViolation\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::class\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> ($e) => \u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">Log\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">critical\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\">'Archive'\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">, [$e\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">invoice\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">label\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(), $e\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">path, $e\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">problem]));\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ch2 id=\"exceptions\">Exceptions\u003Ca class=\"q-doc-anchor\" href=\"#exceptions\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>All exceptions of the Managed layer implement \u003Ccode>Quittio\\Managed\\Exceptions\\ManagedException\u003C\u002Fcode>,\nwhich extends \u003Ccode>Quittio\\Core\\Exceptions\\QuittioException\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Exception\u003C\u002Fth>\n\u003Cth>Base class\u003C\u002Fth>\n\u003Cth>Thrown when\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvalidInvoiceState\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>LogicException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">The action is not possible in the current state: issuing a cancellation draft directly, cancelling or correcting what cannot be (see the table in \u003Ca href=\"#cancellations-and-corrections\">Cancellations and corrections\u003C\u002Fa>), a date before the original, another company, a seller with another VAT id or tax number, sending a draft, an empty partial cancellation, a cancellation that raced with another one\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceNotDraft\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>LogicException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">\u003Ccode>updateData()\u003C\u002Fcode>, \u003Ccode>preview()\u003C\u002Fcode> or \u003Ccode>issue()\u003C\u002Fcode> on an issued invoice, or a draft issued or deleted by another process meanwhile\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceImmutable\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>LogicException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">A frozen column, status, retention, archive or cancellation column would change, an issued invoice would be deleted, a bulk operation would reach one, a stale model is saved, or the audit log or relations would change\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>NothingToCancel\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>LogicException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">\u003Ccode>cancel()\u003C\u002Fcode> or \u003Ccode>cancelPartially()\u003C\u002Fcode> of an invoice that is cancelled completely\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>NoRecipient\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>LogicException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">\u003Ccode>send()\u003C\u002Fcode> finds no e-mail address\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>NumberingException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>RuntimeException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">Invalid pattern, number already taken, a sequence lowered, changed or deleted, an issuer key used by sequences changed, a frozen number space or tenant changed, an invalid sequence key; \u003Ccode>$e-&gt;retryable\u003C\u002Fcode> is \u003Ccode>true\u003C\u002Fcode> for concurrent sequence changes, which are retried automatically\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>ArchiveException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>RuntimeException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">An archive file exists with other content, cannot be written, is missing or damaged, or an invoice has no archived documents\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvalidIssuerProfile\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>InvalidArgumentException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">Branding template or logo the rendering would refuse; an invalid number space, one that would split a company, or a tenant lock that timed out\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>IssuerNotFound\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Base class\">\u003Ccode>RuntimeException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Thrown when\">The default resolver finds no issuer marked as default and not exactly one issuer\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Other exceptions you may meet:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Exception\u003C\u002Fth>\n\u003Cth>When\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Quittio\\Core\\Validation\\ValidationException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">\u003Ccode>issue()\u003C\u002Fcode> (also of cancellations and corrections) of an invalid invoice; \u003Ccode>$e-&gt;result\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Quittio\\Core\\Exceptions\\ConfigurationException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">Invalid configuration: model classes, resolver, generator and recipient classes, Mailable, archive path, reset, start, \u003Ccode>retention.years\u003C\u002Fcode>, correction strategy, value types\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>UnexpectedValueException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">Invalid partial cancellation selections, malformed relation JSON, an invoice not found or ambiguous in \u003Ccode>quittio:render\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvalidArgumentException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">Partial cancellation of an invoice with document level allowances or charges, an unknown cancellation strategy (core); an amount with more than two decimals\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Illuminate\\Database\\QueryException\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"When\">Foreign keys (e.g. deleting an issuer with invoices) and the triggers\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Validation\\ValidationException\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Managed\\Exceptions\\ManagedException\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">try\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    $invoice \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $draft\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">issue\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">} \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">ValidationException\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $e) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#FF7B72\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\"> back\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">withErrors\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">array_map\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">fn\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> ($m) => $m\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">message, $e\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">result\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">errors\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">()));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">} \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">ManagedException\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $e) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#D2A8FF\">    report\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($e);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>For common errors and their fixes, see also \u003Ca href=\"\u002Fdocs\u002Ftroubleshooting\">Troubleshooting\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"models-and-enums\">Models and enums\u003Ca class=\"q-doc-anchor\" href=\"#models-and-enums\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>All models extend \u003Ccode>Quittio\\Managed\\Models\\Model\u003C\u002Fcode>, which takes table prefix and connection from\nthe configuration.\u003C\u002Fp>\n\u003Ch3 id=\"tables\">Tables\u003Ca class=\"q-doc-anchor\" href=\"#tables\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Table\u003C\u002Fth>\n\u003Cth>Model\u003C\u002Fth>\n\u003Cth>Content\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio_issuers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Issuer\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Issuer profiles\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio_sequences\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Sequence\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Number sequences\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio_invoices\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Invoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Drafts and issued invoices, cancellations and corrections\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio_invoice_relations\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>InvoiceRelation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">\u003Ccode>cancels\u003C\u002Fcode>, \u003Ccode>partially_cancels\u003C\u002Fcode>, \u003Ccode>corrects\u003C\u002Fcode>, \u003Ccode>replaces\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio_deliveries\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>Delivery\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Delivery attempts\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio_audit_logs\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">\u003Ccode>AuditLog\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Audit log\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>quittio_archive_files\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Model\">–\u003C\u002Ftd>\n\u003Ctd data-label=\"Content\">Manifest of every archived file (no model, see \u003Ca href=\"#archive-manifest\">Archive manifest\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>The names use the default prefix \u003Ccode>quittio_\u003C\u002Fcode> (\u003Ccode>table_prefix\u003C\u002Fcode>, see\n\u003Ca href=\"#database-settings\">Database settings\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch3 id=\"invoice\">Invoice\u003Ca class=\"q-doc-anchor\" href=\"#invoice\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Column\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>id\u003C\u002Fcode>, \u003Ccode>uuid\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Key and UUID (generated)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issuer_id\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Issuer\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>billable_type\u003C\u002Fcode>, \u003Ccode>billable_id\u003C\u002Fcode>, \u003Ccode>invoiceable_type\u003C\u002Fcode>, \u003Ccode>invoiceable_id\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">References to your models\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>kind\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ccode>Kind\u003C\u002Fcode>: \u003Ccode>invoice\u003C\u002Fcode>, \u003Ccode>cancellation\u003C\u002Fcode>, \u003Ccode>correction\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>type_code\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Document type code (BT-3, UNTDID 1001), e.g. \u003Ccode>380\u003C\u002Fcode> invoice, \u003Ccode>381\u003C\u002Fcode> credit note, \u003Ccode>384\u003C\u002Fcode> corrected invoice\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>status\u003C\u002Fcode>, \u003Ccode>payment_status\u003C\u002Fcode>, \u003Ccode>delivery_status\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">See \u003Ca href=\"#statuses\">Statuses\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>format\u003C\u002Fcode>, \u003Ccode>profile\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Draft: chosen (or \u003Ccode>null\u003C\u002Fcode> for the automatic choice); issued: used\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>country_pack\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Country pack the invoice was issued under\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>buyer_country\u003C\u002Fcode>, \u003Ccode>currency\u003C\u002Fcode>, \u003Ccode>locale\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">From the data\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>standard_version\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">EN 16931 version of the data\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>channel\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">\u003Ccode>mail\u003C\u002Fcode> after a successful delivery\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>lifecycle_status\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Reserved for network status, not set in 1.0\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>number\u003C\u002Fcode>, \u003Ccode>number_space\u003C\u002Fcode>, \u003Ccode>sequence_key\u003C\u002Fcode>, \u003Ccode>sequence_value\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Set when issued\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issue_date\u003C\u002Fcode>, \u003Ccode>due_date\u003C\u002Fcode>, \u003Ccode>service_date\u003C\u002Fcode>, \u003Ccode>service_period_start\u003C\u002Fcode>, \u003Ccode>service_period_end\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Dates (\u003Ccode>CarbonImmutable\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>net_total\u003C\u002Fcode>, \u003Ccode>tax_total\u003C\u002Fcode>, \u003Ccode>gross_total\u003C\u002Fcode>, \u003Ccode>prepaid_total\u003C\u002Fcode>, \u003Ccode>amount_due\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Totals, set when issued (strings with two decimals, e.g. \u003Ccode>&quot;2747.71&quot;\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>paid_total\u003C\u002Fcode>, \u003Ccode>paid_at\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Payments (default \u003Ccode>&quot;0.00&quot;\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>data\u003C\u002Fcode>, \u003Ccode>data_version\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Data snapshot and its version\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>preceding_invoice_id\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Original of a cancellation or correction\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancelled_at\u003C\u002Fcode>, \u003Ccode>cancellation_reason\u003C\u002Fcode>, \u003Ccode>cancellations\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">See \u003Ca href=\"#status\">Status\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>render_status\u003C\u002Fcode>, \u003Ccode>render_attempts\u003C\u002Fcode>, \u003Ccode>document_version\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Rendering\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>disk\u003C\u002Fcode>, \u003Ccode>xml_path\u003C\u002Fcode>, \u003Ccode>pdf_path\u003C\u002Fcode>, \u003Ccode>xml_hash\u003C\u002Fcode>, \u003Ccode>pdf_hash\u003C\u002Fcode>, \u003Ccode>validation_status\u003C\u002Fcode>, \u003Ccode>validation_report_path\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Archive\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>retention_until\u003C\u002Fcode>, \u003Ccode>legal_hold\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Retention\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issued_at\u003C\u002Fcode>, \u003Ccode>sent_at\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Times of issue and last delivery\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issued_by_type\u003C\u002Fcode>, \u003Ccode>issued_by_id\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Authenticated user who issued the invoice\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>created_by_type\u003C\u002Fcode>, \u003Ccode>created_by_id\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Authenticated user who created the draft (frozen once issued)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>created_at\u003C\u002Fcode>, \u003Ccode>updated_at\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Meaning\">Timestamps\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Columns are guarded: write them with \u003Ccode>forceFill()\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Method\u003C\u002Fth>\n\u003Cth>Description\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Invoice::draft()\u003C\u002Fcode>, \u003Ccode>Invoice::draftFor()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">New draft (see \u003Ca href=\"#drafts\">Drafts\u003C\u002Fa>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issuer()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">\u003Ccode>BelongsTo\u003C\u002Fcode> issuer\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>billable()\u003C\u002Fcode>, \u003Ccode>invoiceable()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">\u003Ccode>MorphTo\u003C\u002Fcode> your models\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>precedingInvoice()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">\u003Ccode>BelongsTo\u003C\u002Fcode> the original\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>createdBy()\u003C\u002Fcode>, \u003Ccode>issuedBy()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">\u003Ccode>MorphTo\u003C\u002Fcode> the users who created the draft and issued the invoice\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>relations()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">\u003Ccode>HasMany\u003C\u002Fcode> relations of this invoice to earlier ones\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>inverseRelations()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">\u003Ccode>HasMany\u003C\u002Fcode> relations of later invoices to this one (its cancellations and corrections)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>deliveries()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">\u003Ccode>MorphMany\u003C\u002Fcode> delivery attempts\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>auditLogs()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">\u003Ccode>MorphMany\u003C\u002Fcode> audit entries\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>isDraft()\u003C\u002Fcode>, \u003Ccode>isIssued()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Status checks (\u003Ccode>isIssued()\u003C\u002Fcode> is true for every status but draft)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>assertDraft()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Throws \u003Ccode>InvoiceNotDraft\u003C\u002Fcode> unless draft\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>label()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">The number, or \u003Ccode>#id\u003C\u002Fcode> for drafts\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>updateData(callable $change)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Changes the draft data\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>preview()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Draft PDF with watermark\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>validate()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Full validation without issuing\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issue($issueDate = null)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Issues the draft\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancel($reason = null, $issueDate = null)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Full cancellation\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cancelPartially(array $lines, $reason = null, $issueDate = null)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Partial cancellation\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>correct()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Correction draft\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>send(?string $to = null, array $cc = [])\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">Mail delivery\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>toInvoiceData()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Description\">The data (draft or frozen snapshot), upcast to the current snapshot version; the stored snapshot is never rewritten\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Query method\u003C\u002Fth>\n\u003Cth>Restricts to\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>drafts()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Restricts to\">Drafts\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>issued()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Restricts to\">Issued invoices, including (partially) cancelled ones\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>open()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Restricts to\">Issued or partially cancelled, not a cancellation, unpaid or partially paid\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>overdue(?CarbonImmutable $today = null)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Restricts to\">Open and due before today\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>forBillable(Model $billable)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Restricts to\">Invoices of a billable\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>ofKind(Kind $kind)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Restricts to\">One kind\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>forIssuer(Issuer|int $issuer)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Restricts to\">One issuer\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"other-models\">Other models\u003Ca class=\"q-doc-anchor\" href=\"#other-models\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Model\u003C\u002Fth>\n\u003Cth>Columns\u003C\u002Fth>\n\u003Cth>Methods\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Issuer\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Columns\">see \u003Ca href=\"#columns\">Columns\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">see \u003Ca href=\"#the-issuer-builder\">The issuer builder\u003C\u002Fa>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Sequence\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Columns\">\u003Ccode>key\u003C\u002Fcode> (unique), \u003Ccode>next_value\u003C\u002Fcode>, \u003Ccode>pattern_snapshot\u003C\u002Fcode>, timestamps\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">–\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>InvoiceRelation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Columns\">\u003Ccode>invoice_id\u003C\u002Fcode>, \u003Ccode>related_invoice_id\u003C\u002Fcode>, \u003Ccode>type\u003C\u002Fcode>, \u003Ccode>amount\u003C\u002Fcode>, \u003Ccode>lines\u003C\u002Fcode>, \u003Ccode>vat\u003C\u002Fcode>, \u003Ccode>created_at\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">\u003Ccode>invoice()\u003C\u002Fcode>, \u003Ccode>related()\u003C\u002Fcode>, \u003Ccode>cancelledLines()\u003C\u002Fcode>, \u003Ccode>cancelledVat()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Delivery\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Columns\">\u003Ccode>deliverable_type\u003C\u002Fcode>, \u003Ccode>deliverable_id\u003C\u002Fcode>, \u003Ccode>channel\u003C\u002Fcode>, \u003Ccode>recipient\u003C\u002Fcode>, \u003Ccode>cc\u003C\u002Fcode>, \u003Ccode>attachments\u003C\u002Fcode> (file names), \u003Ccode>status\u003C\u002Fcode>, \u003Ccode>message_id\u003C\u002Fcode>, \u003Ccode>error\u003C\u002Fcode>, \u003Ccode>sent_at\u003C\u002Fcode>, timestamps\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">\u003Ccode>deliverable()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>AuditLog\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Columns\">\u003Ccode>subject_type\u003C\u002Fcode>, \u003Ccode>subject_id\u003C\u002Fcode>, \u003Ccode>action\u003C\u002Fcode>, \u003Ccode>causer_type\u003C\u002Fcode>, \u003Ccode>causer_id\u003C\u002Fcode>, \u003Ccode>payload\u003C\u002Fcode>, \u003Ccode>ip\u003C\u002Fcode>, \u003Ccode>user_agent\u003C\u002Fcode>, \u003Ccode>created_at\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">\u003Ccode>subject()\u003C\u002Fcode>, \u003Ccode>causer()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3 id=\"enums\">Enums\u003Ca class=\"q-doc-anchor\" href=\"#enums\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>Namespace \u003Ccode>Quittio\\Managed\\Enums\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Enum\u003C\u002Fth>\n\u003Cth>Cases (value)\u003C\u002Fth>\n\u003Cth>Methods\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Status\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cases (value)\">\u003Ccode>Draft\u003C\u002Fcode> (\u003Ccode>draft\u003C\u002Fcode>), \u003Ccode>Issued\u003C\u002Fcode> (\u003Ccode>issued\u003C\u002Fcode>), \u003Ccode>PartiallyCancelled\u003C\u002Fcode> (\u003Ccode>partially_cancelled\u003C\u002Fcode>), \u003Ccode>Cancelled\u003C\u002Fcode> (\u003Ccode>cancelled\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">\u003Ccode>rank()\u003C\u002Fcode>, \u003Ccode>canMoveTo(Status $next)\u003C\u002Fcode>, \u003Ccode>isIssued()\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Kind\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cases (value)\">\u003Ccode>Invoice\u003C\u002Fcode> (\u003Ccode>invoice\u003C\u002Fcode>), \u003Ccode>Cancellation\u003C\u002Fcode> (\u003Ccode>cancellation\u003C\u002Fcode>), \u003Ccode>Correction\u003C\u002Fcode> (\u003Ccode>correction\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">–\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>PaymentStatus\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cases (value)\">\u003Ccode>Unpaid\u003C\u002Fcode> (\u003Ccode>unpaid\u003C\u002Fcode>), \u003Ccode>PartiallyPaid\u003C\u002Fcode> (\u003Ccode>partially_paid\u003C\u002Fcode>), \u003Ccode>Paid\u003C\u002Fcode> (\u003Ccode>paid\u003C\u002Fcode>), \u003Ccode>Overpaid\u003C\u002Fcode> (\u003Ccode>overpaid\u003C\u002Fcode>), \u003Ccode>WrittenOff\u003C\u002Fcode> (\u003Ccode>written_off\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">–\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>DeliveryStatus\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cases (value)\">\u003Ccode>NotSent\u003C\u002Fcode> (\u003Ccode>not_sent\u003C\u002Fcode>), \u003Ccode>Sent\u003C\u002Fcode> (\u003Ccode>sent\u003C\u002Fcode>), \u003Ccode>Failed\u003C\u002Fcode> (\u003Ccode>failed\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">–\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>DeliveryState\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cases (value)\">\u003Ccode>Queued\u003C\u002Fcode> (\u003Ccode>queued\u003C\u002Fcode>), \u003Ccode>Sent\u003C\u002Fcode> (\u003Ccode>sent\u003C\u002Fcode>), \u003Ccode>Failed\u003C\u002Fcode> (\u003Ccode>failed\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">–\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>RenderStatus\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cases (value)\">\u003Ccode>Pending\u003C\u002Fcode> (\u003Ccode>pending\u003C\u002Fcode>), \u003Ccode>Rendering\u003C\u002Fcode> (\u003Ccode>rendering\u003C\u002Fcode>), \u003Ccode>Done\u003C\u002Fcode> (\u003Ccode>done\u003C\u002Fcode>), \u003Ccode>Failed\u003C\u002Fcode> (\u003Ccode>failed\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">–\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>ValidationStatus\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cases (value)\">\u003Ccode>Valid\u003C\u002Fcode> (\u003Ccode>valid\u003C\u002Fcode>), \u003Ccode>Warnings\u003C\u002Fcode> (\u003Ccode>warnings\u003C\u002Fcode>), \u003Ccode>Invalid\u003C\u002Fcode> (\u003Ccode>invalid\u003C\u002Fcode>), \u003Ccode>NotChecked\u003C\u002Fcode> (\u003Ccode>not_checked\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">\u003Ccode>ValidationStatus::of(ValidationResult $result)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>RelationType\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Cases (value)\">\u003Ccode>Cancels\u003C\u002Fcode> (\u003Ccode>cancels\u003C\u002Fcode>), \u003Ccode>PartiallyCancels\u003C\u002Fcode> (\u003Ccode>partially_cancels\u003C\u002Fcode>), \u003Ccode>Corrects\u003C\u002Fcode> (\u003Ccode>corrects\u003C\u002Fcode>), \u003Ccode>Replaces\u003C\u002Fcode> (\u003Ccode>replaces\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003Ctd data-label=\"Methods\">\u003Ccode>RelationType::cancelling()\u003C\u002Fcode>: the values of the cancelling relations\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n",[111,115,119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173,176,179,182,185,188,191,194,197,200,203,206,209,212,215,218,221,224,227,230,233,236,239,242,245,248,251,254,257,260,263,266,269,272,275,278,281,284,287,290,293,296,299,302,305,308,311,314,317,320,323,324,327,330,333,334,337,340,343,346,349,352,355,358,361,364,367,370,373,376,379,382,385,388,391],{"id":112,"text":113,"level":114},"what-managed-adds","What Managed adds",2,{"id":116,"text":117,"level":118},"when-to-use-it","When to use it",3,{"id":120,"text":121,"level":114},"overview","Overview",{"id":123,"text":124,"level":114},"installation","Installation",{"id":126,"text":127,"level":118},"databases","Databases",{"id":129,"text":130,"level":118},"queue-worker","Queue worker",{"id":132,"text":133,"level":118},"morph-map","Morph map",{"id":135,"text":136,"level":114},"a-first-invoice","A first invoice",{"id":138,"text":139,"level":114},"issuer-profiles","Issuer profiles",{"id":141,"text":142,"level":118},"the-issuer-builder","The issuer builder",{"id":144,"text":145,"level":118},"defaults-texts-and-branding","Defaults, texts and branding",{"id":147,"text":148,"level":118},"small-business","Small business",{"id":150,"text":151,"level":118},"current-issuer","Current issuer",{"id":153,"text":154,"level":118},"tenancy-scope","Tenancy scope",{"id":156,"text":157,"level":118},"seller-identity","Seller identity",{"id":159,"text":160,"level":118},"changing-and-deleting-issuers","Changing and deleting issuers",{"id":162,"text":163,"level":118},"branding-check","Branding check",{"id":165,"text":166,"level":118},"columns","Columns",{"id":168,"text":169,"level":114},"customers-and-references","Customers and references",{"id":171,"text":172,"level":114},"drafts","Drafts",{"id":174,"text":175,"level":118},"creating-drafts","Creating drafts",{"id":177,"text":178,"level":118},"changing-drafts","Changing drafts",{"id":180,"text":181,"level":118},"preview-and-validation","Preview and validation",{"id":183,"text":184,"level":118},"deleting-drafts","Deleting drafts",{"id":186,"text":187,"level":114},"issuing","Issuing",{"id":189,"text":190,"level":118},"issuing-inside-your-own-transaction","Issuing inside your own transaction",{"id":192,"text":193,"level":114},"statuses","Statuses",{"id":195,"text":196,"level":118},"status","Status",{"id":198,"text":199,"level":118},"payment-status","Payment status",{"id":201,"text":202,"level":118},"open-and-overdue","Open and overdue",{"id":204,"text":205,"level":118},"delivery-status","Delivery status",{"id":207,"text":208,"level":118},"render-and-validation-status","Render and validation status",{"id":210,"text":211,"level":114},"numbering","Numbering",{"id":213,"text":214,"level":118},"placeholders","Placeholders",{"id":216,"text":217,"level":118},"sequences-and-resets","Sequences and resets",{"id":219,"text":220,"level":118},"gapless-numbers","Gapless numbers",{"id":222,"text":223,"level":118},"number-spaces","Number spaces",{"id":225,"text":226,"level":118},"managing-sequences","Managing sequences",{"id":228,"text":229,"level":118},"own-number-generators","Own number generators",{"id":231,"text":232,"level":114},"rendering-and-archive","Rendering and archive",{"id":234,"text":235,"level":118},"render-job","Render job",{"id":237,"text":238,"level":118},"archive-layout","Archive layout",{"id":240,"text":241,"level":118},"versions-and-re-rendering","Versions and re-rendering",{"id":243,"text":244,"level":118},"archive-manifest","Archive manifest",{"id":246,"text":247,"level":118},"integrity-checks","Integrity checks",{"id":249,"text":250,"level":118},"reading-archived-documents","Reading archived documents",{"id":252,"text":253,"level":118},"own-archive-storage","Own archive storage",{"id":255,"text":256,"level":114},"cancellations-and-corrections","Cancellations and corrections",{"id":258,"text":259,"level":118},"full-cancellation","Full cancellation",{"id":261,"text":262,"level":118},"partial-cancellation","Partial cancellation",{"id":264,"text":265,"level":118},"vat-of-partial-cancellations","VAT of partial cancellations",{"id":267,"text":268,"level":118},"sign-strategies-and-credit-notes","Sign strategies and credit notes",{"id":270,"text":271,"level":118},"cancellation-ledger","Cancellation ledger",{"id":273,"text":274,"level":118},"corrections","Corrections",{"id":276,"text":277,"level":118},"left-behind-drafts","Left-behind drafts",{"id":279,"text":280,"level":118},"self-billing","Self-billing",{"id":282,"text":283,"level":114},"delivery","Delivery",{"id":285,"text":286,"level":118},"recipients","Recipients",{"id":288,"text":289,"level":118},"mail-content","Mail content",{"id":291,"text":292,"level":114},"audit-log","Audit log",{"id":294,"text":295,"level":114},"authorisation","Authorisation",{"id":297,"text":298,"level":114},"immutability","Immutability",{"id":300,"text":301,"level":118},"what-can-still-change","What can still change",{"id":303,"text":304,"level":118},"optimistic-concurrency","Optimistic concurrency",{"id":306,"text":307,"level":118},"bulk-queries","Bulk queries",{"id":309,"text":310,"level":118},"append-only-tables","Append-only tables",{"id":312,"text":313,"level":118},"database-triggers","Database triggers",{"id":315,"text":316,"level":118},"what-is-not-prevented","What is not prevented",{"id":318,"text":319,"level":114},"retention-and-deletion","Retention and deletion",{"id":321,"text":322,"level":118},"personal-data","Personal data",{"id":70,"text":71,"level":114},{"id":325,"text":326,"level":118},"factories","Factories",{"id":328,"text":329,"level":118},"testing-against-mysql-and-postgresql","Testing against MySQL and PostgreSQL",{"id":331,"text":332,"level":114},"known-limitations","Known limitations",{"id":64,"text":65,"level":114},{"id":335,"text":336,"level":118},"database-settings","Database settings",{"id":338,"text":339,"level":118},"issuer-and-tenancy-settings","Issuer and tenancy settings",{"id":341,"text":342,"level":118},"archive-settings","Archive settings",{"id":344,"text":345,"level":118},"queue-settings","Queue settings",{"id":347,"text":348,"level":118},"numbering-settings","Numbering settings",{"id":350,"text":351,"level":118},"correction-settings","Correction settings",{"id":353,"text":354,"level":118},"delivery-settings","Delivery settings",{"id":356,"text":357,"level":118},"audit-retention-and-policy-settings","Audit, retention and policy settings",{"id":359,"text":360,"level":118},"settings-of-configquittiophp-the-managed-layer-uses","Settings of config\u002Fquittio.php the Managed layer uses",{"id":362,"text":363,"level":118},"own-models","Own models",{"id":365,"text":366,"level":118},"own-services","Own services",{"id":368,"text":369,"level":114},"console-commands","Console commands",{"id":371,"text":372,"level":118},"publish-tags","Publish tags",{"id":374,"text":375,"level":114},"events","Events",{"id":377,"text":378,"level":114},"exceptions","Exceptions",{"id":380,"text":381,"level":114},"models-and-enums","Models and enums",{"id":383,"text":384,"level":118},"tables","Tables",{"id":386,"text":387,"level":118},"invoice","Invoice",{"id":389,"text":390,"level":118},"other-models","Other models",{"id":392,"text":393,"level":118},"enums","Enums","https:\u002F\u002Fgithub.com\u002FQuittio\u002Fquittio\u002Fedit\u002Fmaster\u002Fdocs\u002Fmanaged.md","\u002Fdocs\u002Fmanaged.md",{"slug":85,"title":86},{"slug":92,"title":93}]