You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Single PHP rules can be switched off, re-rated or replaced by their code: validation.rules.disabled, validation.rules.severity and Quittio::extend('rule', …) in Laravel, RuleOverrides with Quittio::configureRules() in the core. Official EN 16931 and Peppol rules need allow_official; unknown codes are refused. Quittio::ruleCodes() lists the known codes.
The calculation policy decides what happens with declared amounts of other systems: calculation.declared_amounts (keep, recalculate, reject), CalculationPolicy and DeclaredAmountsMode in the core. An own calculator is configured with calculation.calculator or passed to Quittio::create(calculator: …); Quittio::calculator() returns it.
Quittio::edit() (core and Laravel) and InvoiceBuilder::fromUsing() continue existing invoice data with the calculator of the instance; cancellations and the document calculator of QuittioFake use it as well. InvoiceFactory::calculated() takes a calculator.
Tax presets whose rate depends on the date (Quittio\Core\Tax\DatedTaxPreset) are resolved with the supply date of each line (SupplyDate: line period, VAT point date, delivery date, invoicing period, issue date). DatedValues holds values that change on dates; TaxPresetCollection::alias() finds presets under further keys.
VatPreset::Standard (de.standard) and VatPreset::Reduced (de.reduced) take the German rate of the supply date (TaxTables), e.g. 16 % and 5 % from July to December 2020. The plausibility rule DE-VAT-RATE warns about rates that applied neither as standard nor as reduced rate on the supply date. The small amount limit of DE-USTG-08 is that of the issue date (150.00 EUR before 2017).
Country packs register output formats, aliases and serializers (Countries\Capabilities\ProvidesFormats, implemented by AbstractCountryPack); the German pack brings XRechnung (XRechnungFormats). Profiles declare sub lines, extension fields and third party payments with capabilities (SupportsSubLines, SupportsExtensionFields, SupportsThirdPartyPayments) instead of the core checking XRechnung keys.
Default interest for every country pack with a reference rate: Quittio\Core\Dunning\DefaultInterest (forCountry($pack)), the contract Dunning\ReferenceRates and the capability ProvidesReferenceRates; the German pack provides its base rates (BaseRateTable implements ReferenceRates) and its DefaultInterest uses the core calculation. DocumentBuilder::interestCharge() adds calculated charges with their day count and texts.
Documents can be queued in Laravel: Quittio::document($quote)->queue()->save($disk, $path) with the job RenderDocument, the events QueuedDocumentStored and QueuedDocumentFailed and QuittioManager::queueDocument(); QuittioFake records them (assertDocumentQueued(), queuedDocuments()). Documents are stored as versioned snapshots (DocumentData::toSnapshot(), fromSnapshot(), toArray(), toJson() …) with their own upcasters (quittio.snapshots.document_upcasters, SnapshotUpcasterChain::documentDefault()); Mapping\Attributes\MapOf keeps keyed arrays.
The German special cases are reached with the builder macro de(): ->de()->smallAmount(), ->de()->selfBilled(), ->de()->deductAdvance($advance) … (GermanInvoice).
Changed
Lines without VAT treatment of a German seller get the preset key de.standard instead of de.standard_19, and quittio.defaults.vat = 'de.reduced_7' gives de.reduced. Applications that compare preset keys use VatPreset::fromKey($key)?->canonical(). Supplies from 2020-07-01 to 2020-12-31 get 16 % and 5 %.
CiiWriter, UblWriter, CiiReader and UblReader keep no state between calls: each call works with its own internal worker, so one instance can be used reentrantly. The readers no longer extend the internal XPathReader and therefore no longer expose its constants.
The render run resolves the logo of the presentation before it builds the view model (ViewContext::$logo, ResolvedLogo), so the view layer does no I/O; ViewModelFactory keeps no state between calls.
The documentation website is versioned: the root shows the latest release, /next/ the development version and /X.Y/ older minor versions, with a version switcher (docs/_versioning/build.mjs). Every version has a generated API reference under api/ (phpDocumentor, tools/docs/phpdoc.sh); the builder traits under Builder\Concerns are no longer @internal, so their methods appear there.
Pull requests opened in the read-only split repositories quittio/core, quittio/laravel and quittio/country-de are closed automatically with a pointer to the monorepo.
Deprecated
VatPreset::Standard19 and VatPreset::Reduced7: use VatPreset::Standard and VatPreset::Reduced; the keys de.standard_19 and de.reduced_7 stay readable. Flags::SMALL_AMOUNT_LIMIT: use TaxTables::smallAmountLimitOn().
The builder macros smallAmount(), propertyRelatedService(), newVehicle(), selfBilled(), deductAdvance() and consumerDefaultNotice() directly on the builder: use ->de()->…. GermanInvoiceMacros::ADVANCE_TYPES: use GermanInvoice::ADVANCE_TYPES. FormatRegistry::XRECHNUNG_CII and XRECHNUNG_UBL: use XRechnungFormats::CII and UBL of the German pack, which registers the formats; the core keeps them until 1.0.
Fixed
Peppol invoices with an electronic address scheme that Peppol does not accept, e.g. EM (e-mail), are rejected with the new rule PEPPOL-EN16931-CL008 instead of passing the PHP rules and failing the official Peppol validation. The allowed schemes are the code list CodeList::PEPPOL_EAS (peppol-eas-codes.json, from the Peppol BIS rules 3.0.20); tools/codelists/update.php regenerates it with CodeListGenerator::generatePeppol().