├── .editorconfig ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── phpcs.xml ├── phpunit.xml.dist ├── src ├── AdditionalDocumentReference.php ├── Address.php ├── AllowanceCharge.php ├── Attachment.php ├── BillingReference.php ├── ClassifiedTaxCategory.php ├── CommodityClassification.php ├── Contact.php ├── ContractDocumentReference.php ├── Country.php ├── CreditNote.php ├── CreditNoteLine.php ├── Delivery.php ├── EASCode.php ├── FinancialInstitutionBranch.php ├── Generator.php ├── ICDCode.php ├── Invoice.php ├── InvoiceDocumentReference.php ├── InvoiceLine.php ├── InvoicePeriod.php ├── InvoiceTypeCode.php ├── Item.php ├── LegalEntity.php ├── LegalMonetaryTotal.php ├── NumberFormatter.php ├── OrderLineReference.php ├── OrderReference.php ├── Party.php ├── PartyTaxScheme.php ├── PayeeFinancialAccount.php ├── PaymentMeans.php ├── PaymentTerms.php ├── Price.php ├── ProjectReference.php ├── Schema.php ├── SettlementPeriod.php ├── TaxCategory.php ├── TaxScheme.php ├── TaxSubTotal.php ├── TaxTotal.php ├── UNCL4461.php ├── UNCL5305.php ├── UnitCode.php └── VatExemptionCode.php └── tests ├── BillingReferenceCreditNoteTest.php ├── ContractDocumentReferenceTest.php ├── DocumentTypeTest.php ├── DueDateTest.php ├── EN16931Test.php ├── EmptyAttachmentTest.php ├── MultiplePaymentMeansTest.php ├── NumberFormatterTest.php ├── PartyIdentificationSchemeNameTest.php ├── ProjectReferenceTest.php ├── SampleInvoice.pdf ├── SimpleCreditNoteTest.php ├── SimpleInvoiceTest.php ├── SimpleInvoiceWithFilePathPdfTest.php ├── SimpleInvoiceWithInlinePdfTest.php └── SimpleUBL22InvoiceTest.php /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_size = 4 9 | indent_style = space 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Composer 2 | .idea 3 | composer.phar 4 | /vendor/ 5 | 6 | 7 | ## Linux 8 | # temporary files which can be created if a process still has a handle open of a deleted file 9 | .fuse_hidden* 10 | 11 | # KDE directory preferences 12 | .directory 13 | 14 | # Linux trash folder which might appear on any partition or disk 15 | .Trash-* 16 | 17 | # .nfs files are created when an open file is removed but is still being accessed 18 | .nfs* 19 | 20 | 21 | ## macOS 22 | # General 23 | .DS_Store 24 | .AppleDouble 25 | .LSOverride 26 | 27 | # Icon must end with two \r 28 | Icon 29 | 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | .com.apple.timemachine.donotpresent 42 | 43 | # Directories potentially created on remote AFP share 44 | .AppleDB 45 | .AppleDesktop 46 | Network Trash Folder 47 | Temporary Items 48 | .apdisk 49 | 50 | 51 | ## Windows 52 | # Windows thumbnail cache files 53 | Thumbs.db 54 | ehthumbs.db 55 | ehthumbs_vista.db 56 | 57 | # Dump file 58 | *.stackdump 59 | 60 | # Folder config file 61 | [Dd]esktop.ini 62 | 63 | # Recycle Bin used on file shares 64 | $RECYCLE.BIN/ 65 | 66 | # Windows Installer files 67 | *.cab 68 | *.msi 69 | *.msix 70 | *.msm 71 | *.msp 72 | 73 | # Windows shortcuts 74 | *.lnk 75 | 76 | # Generated XML files from tests 77 | /tests/*.xml 78 | 79 | # Test cache 80 | .phpunit.result.cache 81 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to ubl-invoice 2 | 3 | Are you missing a feature and would you like to add it to the library? Great! Any contributions to this library are welcome. We try to be responsive and release new, non-breaking features as fast as possible. 4 | 5 | ## Reporting issues 6 | 7 | This package uses the [GitHub issue tracker](https://github.com/num-num/ubl-invoice/issues) to track bugs and features. Before submitting a bug report or feature request, check to make sure it hasn't already been submitted. 8 | 9 | ## Contributing code 10 | 11 | If you want to add additional tags, attributes or functionality to the library, please feel free to create a [pull request](https://github.com/num-num/ubl-invoice/pulls) with your changes. 12 | 13 | Please try to follow this workflow: 14 | 15 | - Fork the project 16 | - Create a new branch forked from the master branch with a title for your feature (e.g. feature-that-i-want) 17 | - Commit all your code into this branch until you are happy with your contribution 18 | - Document your changes in the **changelog/next-release.md** file ⚠️ 19 | - If possible; try to add unit tests for your contribution 20 | - Create a pull request with your commits 21 | 22 | ## Formatting ⚠️ 23 | 24 | Please try to follow [PSR-12](https://www.php-fig.org/psr/psr-12/) rules when writing code. A PSR-12 compliant [phpcs.xml](phpcs.xml) is provided, so if your editor supports [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), your editor should automatically warn you if you are deviating from PSR-12 compliant formatting. 25 | 26 | You can also check code style manually by running `composer phpcs` in the projects' root folder on your disk. 27 | 28 | ```zsh 29 | $ cd ubl-invoice 30 | $ composer phpcs 31 | ``` 32 | 33 | The project also has PHPStan integrated for code checking, which can be triggered with: 34 | 35 | ```zsh 36 | $ cd ubl-invoice 37 | $ composer phpstan 38 | ``` 39 | 40 | ## Unit testing ⚠️ 41 | 42 | ### A note on unit testing 43 | 44 | Although unit testing is included, this repository does not provide exhaustive unit testing for *all* possibilities the library offers. This is definitely a long-term goal. So please try to add unit tests for new functionality that you add. 45 | 46 | ### Running the unit tests 47 | 48 | To run the complete suite of unit tests 49 | 50 | ```zsh 51 | $ cd ubl-invoice 52 | $ composer test 53 | ``` 54 | 55 | To run a single unit test 56 | 57 | ```zsh 58 | $ cd ubl-invoice 59 | $ composer test tests/SimpleInvoiceTest.php 60 | ``` 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2018 Num•Num 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without 8 | restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following 12 | conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UBL-Invoice 2 | 3 | A modern object-oriented PHP library to create valid UBL and Peppol BIS 3.0 files. Please feel free to [contribute](https://github.com/num-num/ubl-invoice/pulls) if you are missing features or tags. 4 | 5 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/num-num/ubl-invoice.svg?style=rounded-square)](https://packagist.org/packages/num-num/ubl-invoice) 6 | [![Total Downloads](https://img.shields.io/packagist/dt/num-num/ubl-invoice.svg?style=rounded-square)](https://packagist.org/packages/num-num/ubl-invoice) 7 | 8 | ![Num•Num UBL Invoice](https://i.imgur.com/JPyFBYQ.png) 9 | 10 | ## Installation and usage 11 | 12 | This package requires PHP 7.4 or higher and is fully compatible with PHP8. Installation can be done through [composer](https://www.getcomposer.org). 13 | 14 | ```zsh 15 | $ composer require num-num/ubl-invoice 16 | ``` 17 | 18 | ## Contributing 19 | 20 | This library is not 100% UBL/Peppol feature-complete, in the sense that it doesn't (yet) support **all** UBL XML tags & functionality. "Yet" being the keyword, since this definitely is the long-term goal. All common UBL tags that are required for most invoices are present in the library. This includes tags for discounts, cash discounts, special vat rates, etc... 21 | 22 | If you are missing functionality, please feel free to add it :-) Adding additional tags & attributes is fairly straight-forward. Check out [CONTRIBUTING.md](CONTRIBUTING.md) for more information. 23 | 24 | ## Examples & documentation 25 | 26 | This repository does not have a documentation website at this moment. For now, please check out some code examples by checking the unit tests in the `tests` folder. 27 | 28 | ## Changelog 29 | 30 | A changelog is available since version v1.9.0. If you are upgrading a minor version (1.x) or major version, please check the changelog to see if you need to implement any breaking changes... 31 | 32 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "num-num/ubl-invoice", 3 | "description": "A modern object-oriented PHP library to create valid UBL and Peppol BIS 3.0 files", 4 | "keywords": [ 5 | "ubl", 6 | "invoice", 7 | "ublinvoice", 8 | "ubl invoice", 9 | "efff", 10 | "electronic invoice", 11 | "digital invoice", 12 | "xml", 13 | "xml invoice", 14 | "peppol", 15 | "peppol bis", 16 | "peppolbis", 17 | "peppol invoice", 18 | "e-invoice", 19 | "einvoice", 20 | "euinvoice" 21 | ], 22 | "homepage": "https://github.com/num-num/ubl-invoice", 23 | "license": "MIT", 24 | "authors": [ 25 | { 26 | "name": "Bert Devriese", 27 | "email": "bert@numnum.be", 28 | "homepage": "https://www.numnum.be", 29 | "role": "Developer" 30 | } 31 | ], 32 | "require": { 33 | "php": "^7.3 || ^8.0", 34 | "sabre/xml": "^4.0" 35 | }, 36 | "require-dev": { 37 | "phpunit/phpunit": "^9.0", 38 | "squizlabs/php_codesniffer": "^3.7", 39 | "phpstan/phpstan": "^1.10" 40 | }, 41 | "autoload": { 42 | "psr-4": { 43 | "NumNum\\UBL\\": [ 44 | "src" 45 | ], 46 | "NumNum\\UBL\\Tests\\": [ 47 | "tests" 48 | ] 49 | } 50 | }, 51 | "scripts": { 52 | "test": "vendor/bin/phpunit", 53 | "phpstan": "vendor/bin/phpstan analyse src tests", 54 | "phpcs": "vendor/bin/phpcs -n --standard=phpcs.xml ./src/" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | src/ 6 | 7 | 8 | 9 | 10 | tests 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/AdditionalDocumentReference.php: -------------------------------------------------------------------------------- 1 | id; 22 | } 23 | 24 | /** 25 | * @param string $id 26 | * @return AdditionalDocumentReference 27 | */ 28 | public function setId(string $id): AdditionalDocumentReference 29 | { 30 | $this->id = $id; 31 | return $this; 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getDocumentType(): ?string 38 | { 39 | return $this->documentType; 40 | } 41 | 42 | /** 43 | * @param string $documentType 44 | * @return AdditionalDocumentReference 45 | */ 46 | public function setDocumentType(string $documentType): AdditionalDocumentReference 47 | { 48 | $this->documentType = $documentType; 49 | return $this; 50 | } 51 | 52 | /** 53 | * @return int 54 | */ 55 | public function getDocumentTypeCode(): ?int 56 | { 57 | return $this->documentTypeCode; 58 | } 59 | 60 | /** 61 | * @param int $documentTypeCode 62 | * @return AdditionalDocumentReference 63 | */ 64 | public function setDocumentTypeCode(int $documentTypeCode): AdditionalDocumentReference 65 | { 66 | $this->documentTypeCode = $documentTypeCode; 67 | return $this; 68 | } 69 | 70 | /** 71 | * @return string 72 | */ 73 | public function getDocumentDescription(): ?string 74 | { 75 | return $this->documentDescription; 76 | } 77 | 78 | /** 79 | * @param string $documentDescription 80 | * @return AdditionalDocumentReference 81 | */ 82 | public function setDocumentDescription(string $documentDescription): AdditionalDocumentReference 83 | { 84 | $this->documentDescription = $documentDescription; 85 | return $this; 86 | } 87 | 88 | /** 89 | * @return Attachment 90 | */ 91 | public function getAttachment(): ?Attachment 92 | { 93 | return $this->attachment; 94 | } 95 | 96 | /** 97 | * @param Attachment $attachment 98 | * @return AdditionalDocumentReference 99 | */ 100 | public function setAttachment(Attachment $attachment): AdditionalDocumentReference 101 | { 102 | $this->attachment = $attachment; 103 | return $this; 104 | } 105 | 106 | /** 107 | * The xmlSerialize method is called during xml writing. 108 | * 109 | * @param Writer $writer 110 | * @return void 111 | */ 112 | public function xmlSerialize(Writer $writer): void 113 | { 114 | $writer->write([ Schema::CBC . 'ID' => $this->id ]); 115 | 116 | if ($this->documentTypeCode !== null) { 117 | $writer->write([ 118 | Schema::CBC . 'DocumentTypeCode' => $this->documentTypeCode 119 | ]); 120 | } else if ($this->documentType !== null) { 121 | $writer->write([ 122 | Schema::CBC . 'DocumentType' => $this->documentType 123 | ]); 124 | } 125 | 126 | if ($this->documentDescription !== null) { 127 | $writer->write([ 128 | Schema::CBC . 'DocumentDescription' => $this->documentDescription 129 | ]); 130 | } 131 | 132 | if ($this->attachment !== null) { 133 | $writer->write([ 134 | Schema::CAC . 'Attachment' => $this->attachment 135 | ]); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/Address.php: -------------------------------------------------------------------------------- 1 | streetName; 24 | } 25 | 26 | /** 27 | * @param string $streetName 28 | * @return Address 29 | */ 30 | public function setStreetName(?string $streetName): Address 31 | { 32 | $this->streetName = $streetName; 33 | return $this; 34 | } 35 | 36 | /** 37 | * @return string 38 | */ 39 | public function getAdditionalStreetName(): ?string 40 | { 41 | return $this->additionalStreetName; 42 | } 43 | 44 | /** 45 | * @param string $additionalStreetName 46 | * @return Address 47 | */ 48 | public function setAdditionalStreetName(?string $additionalStreetName): Address 49 | { 50 | $this->additionalStreetName = $additionalStreetName; 51 | return $this; 52 | } 53 | 54 | /** 55 | /** 56 | * @return string 57 | */ 58 | public function getBuildingNumber(): ?string 59 | { 60 | return $this->buildingNumber; 61 | } 62 | 63 | /** 64 | * @param string $buildingNumber 65 | * @return Address 66 | */ 67 | public function setBuildingNumber(?string $buildingNumber): Address 68 | { 69 | $this->buildingNumber = $buildingNumber; 70 | return $this; 71 | } 72 | 73 | /** 74 | * @return string 75 | */ 76 | public function getCityName(): ?string 77 | { 78 | return $this->cityName; 79 | } 80 | 81 | /** 82 | * @param string $cityName 83 | * @return Address 84 | */ 85 | public function setCityName(?string $cityName): Address 86 | { 87 | $this->cityName = $cityName; 88 | return $this; 89 | } 90 | 91 | /** 92 | * @return string 93 | */ 94 | public function getPostalZone(): ?string 95 | { 96 | return $this->postalZone; 97 | } 98 | 99 | /** 100 | * @param string $postalZone 101 | * @return Address 102 | */ 103 | public function setPostalZone(?string $postalZone): Address 104 | { 105 | $this->postalZone = $postalZone; 106 | return $this; 107 | } 108 | 109 | /** 110 | * @return string 111 | */ 112 | public function getCountrySubentity(): ?string 113 | { 114 | return $this->countrySubentity; 115 | } 116 | 117 | /** 118 | * @param string $subentity 119 | * @return Address 120 | */ 121 | public function setCountrySubentity(string $countrySubentity): Address 122 | { 123 | $this->countrySubentity = $countrySubentity; 124 | return $this; 125 | } 126 | 127 | /** 128 | * @return Country 129 | */ 130 | public function getCountry(): ?Country 131 | { 132 | return $this->country; 133 | } 134 | 135 | /** 136 | * @param Country $country 137 | * @return Address 138 | */ 139 | public function setCountry(Country $country): Address 140 | { 141 | $this->country = $country; 142 | return $this; 143 | } 144 | 145 | /** 146 | * The xmlSerialize method is called during xml writing. 147 | * 148 | * @param Writer $writer 149 | * @return void 150 | */ 151 | public function xmlSerialize(Writer $writer): void 152 | { 153 | if ($this->streetName !== null) { 154 | $writer->write([ 155 | Schema::CBC . 'StreetName' => $this->streetName 156 | ]); 157 | } 158 | if ($this->additionalStreetName !== null) { 159 | $writer->write([ 160 | Schema::CBC . 'AdditionalStreetName' => $this->additionalStreetName 161 | ]); 162 | } 163 | if ($this->buildingNumber !== null) { 164 | $writer->write([ 165 | Schema::CBC . 'BuildingNumber' => $this->buildingNumber 166 | ]); 167 | } 168 | if ($this->cityName !== null) { 169 | $writer->write([ 170 | Schema::CBC . 'CityName' => $this->cityName, 171 | ]); 172 | } 173 | if ($this->postalZone !== null) { 174 | $writer->write([ 175 | Schema::CBC . 'PostalZone' => $this->postalZone, 176 | ]); 177 | } 178 | if ($this->countrySubentity !== null) { 179 | $writer->write([ 180 | Schema::CBC . 'CountrySubentity' => $this->countrySubentity, 181 | ]); 182 | } 183 | if ($this->country !== null) { 184 | $writer->write([ 185 | Schema::CAC . 'Country' => $this->country, 186 | ]); 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/AllowanceCharge.php: -------------------------------------------------------------------------------- 1 | chargeIndicator; 25 | } 26 | 27 | /** 28 | * @param bool $chargeIndicator 29 | * @return AllowanceCharge 30 | */ 31 | public function setChargeIndicator(bool $chargeIndicator): AllowanceCharge 32 | { 33 | $this->chargeIndicator = $chargeIndicator; 34 | return $this; 35 | } 36 | 37 | /** 38 | * @return int 39 | */ 40 | public function getAllowanceChargeReasonCode(): ?int 41 | { 42 | return $this->allowanceChargeReasonCode; 43 | } 44 | 45 | /** 46 | * @param int $allowanceChargeReasonCode 47 | * @return AllowanceCharge 48 | */ 49 | public function setAllowanceChargeReasonCode(?int $allowanceChargeReasonCode): AllowanceCharge 50 | { 51 | $this->allowanceChargeReasonCode = $allowanceChargeReasonCode; 52 | return $this; 53 | } 54 | 55 | /** 56 | * @return string 57 | */ 58 | public function getAllowanceChargeReason(): ?string 59 | { 60 | return $this->allowanceChargeReason; 61 | } 62 | 63 | /** 64 | * @param string $allowanceChargeReason 65 | * @return AllowanceCharge 66 | */ 67 | public function setAllowanceChargeReason(?string $allowanceChargeReason): AllowanceCharge 68 | { 69 | $this->allowanceChargeReason = $allowanceChargeReason; 70 | return $this; 71 | } 72 | 73 | /** 74 | * @return float 75 | */ 76 | public function getMultiplierFactorNumeric(): ?float 77 | { 78 | return $this->multiplierFactorNumeric; 79 | } 80 | 81 | /** 82 | * @param float $multiplierFactorNumeric 83 | * @return AllowanceCharge 84 | */ 85 | public function setMultiplierFactorNumeric(?float $multiplierFactorNumeric): AllowanceCharge 86 | { 87 | $this->multiplierFactorNumeric = $multiplierFactorNumeric; 88 | return $this; 89 | } 90 | 91 | /** 92 | * @return float 93 | */ 94 | public function getBaseAmount(): ?float 95 | { 96 | return $this->baseAmount; 97 | } 98 | 99 | /** 100 | * @param float $baseAmount 101 | * @return AllowanceCharge 102 | */ 103 | public function setBaseAmount(?float $baseAmount): AllowanceCharge 104 | { 105 | $this->baseAmount = $baseAmount; 106 | return $this; 107 | } 108 | 109 | /** 110 | * @return float 111 | */ 112 | public function getAmount(): ?float 113 | { 114 | return $this->amount; 115 | } 116 | 117 | /** 118 | * @param float $amount 119 | * @return AllowanceCharge 120 | */ 121 | public function setAmount(?float $amount): AllowanceCharge 122 | { 123 | $this->amount = $amount; 124 | return $this; 125 | } 126 | 127 | /** 128 | * @return TaxCategory 129 | */ 130 | public function getTaxCategory(): ?TaxCategory 131 | { 132 | return $this->taxCategory; 133 | } 134 | 135 | /** 136 | * @param TaxCategory $taxCategory 137 | * @return AllowanceCharge 138 | */ 139 | public function setTaxCategory(?TaxCategory $taxCategory): AllowanceCharge 140 | { 141 | $this->taxCategory = $taxCategory; 142 | return $this; 143 | } 144 | 145 | /** 146 | * @return TaxCategory 147 | */ 148 | public function getTaxtotal(): ?TaxTotal 149 | { 150 | return $this->taxTotal; 151 | } 152 | 153 | /** 154 | * @param TaxTotal $taxTotal 155 | * @return AllowanceCharge 156 | */ 157 | public function setTaxtotal(?TaxTotal $taxTotal): AllowanceCharge 158 | { 159 | $this->taxTotal = $taxTotal; 160 | return $this; 161 | } 162 | 163 | /** 164 | * The xmlSerialize method is called during xml writing. 165 | * 166 | * @param Writer $writer 167 | * @return void 168 | */ 169 | public function xmlSerialize(Writer $writer): void 170 | { 171 | $writer->write([ 172 | Schema::CBC . 'ChargeIndicator' => $this->chargeIndicator ? 'true' : 'false', 173 | ]); 174 | 175 | if ($this->allowanceChargeReasonCode !== null) { 176 | $writer->write([ 177 | Schema::CBC . 'AllowanceChargeReasonCode' => $this->allowanceChargeReasonCode 178 | ]); 179 | } 180 | 181 | if ($this->allowanceChargeReason !== null) { 182 | $writer->write([ 183 | Schema::CBC . 'AllowanceChargeReason' => $this->allowanceChargeReason 184 | ]); 185 | } 186 | 187 | if ($this->multiplierFactorNumeric !== null) { 188 | $writer->write([ 189 | Schema::CBC . 'MultiplierFactorNumeric' => $this->multiplierFactorNumeric 190 | ]); 191 | } 192 | 193 | $writer->write([ 194 | [ 195 | 'name' => Schema::CBC . 'Amount', 196 | 'value' => NumberFormatter::format($this->amount, 2), 197 | 'attributes' => [ 198 | 'currencyID' => Generator::$currencyID 199 | ] 200 | ], 201 | ]); 202 | 203 | if ($this->baseAmount !== null) { 204 | $writer->write([ 205 | [ 206 | 'name' => Schema::CBC . 'BaseAmount', 207 | 'value' => NumberFormatter::format($this->baseAmount, 2), 208 | 'attributes' => [ 209 | 'currencyID' => Generator::$currencyID 210 | ] 211 | ] 212 | ]); 213 | } 214 | 215 | if ($this->taxCategory !== null) { 216 | $writer->write([ 217 | Schema::CAC . 'TaxCategory' => $this->taxCategory 218 | ]); 219 | } 220 | 221 | if ($this->taxTotal !== null) { 222 | $writer->write([ 223 | Schema::CAC . 'TaxTotal' => $this->taxTotal 224 | ]); 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /src/Attachment.php: -------------------------------------------------------------------------------- 1 | filePath)) !== false) { 26 | return $mime_type; 27 | } 28 | 29 | throw new Exception('Could not determine mime_type of '.$this->filePath); 30 | } 31 | 32 | /** 33 | * @return string 34 | */ 35 | public function getFilePath(): ?string 36 | { 37 | return $this->filePath; 38 | } 39 | 40 | /** 41 | * @param string $filePath 42 | * @return Attachment 43 | */ 44 | public function setFilePath(string $filePath): Attachment 45 | { 46 | $this->filePath = $filePath; 47 | return $this; 48 | } 49 | 50 | /** 51 | * @return string 52 | */ 53 | public function getExternalReference(): ?string 54 | { 55 | return $this->externalReference; 56 | } 57 | 58 | /** 59 | * @param string $externalReference 60 | * @return Attachment 61 | */ 62 | public function setExternalReference(string $externalReference): Attachment 63 | { 64 | $this->externalReference = $externalReference; 65 | return $this; 66 | } 67 | 68 | public function getFileStream(): ?string 69 | { 70 | return $this->fileStream; 71 | } 72 | 73 | /** 74 | * @param string $fileStream Base64 encoded filestream 75 | * @param string $fileName 76 | * @return Attachment 77 | */ 78 | public function setFileStream(string $fileStream, string $fileName, ?string $mimeType): Attachment 79 | { 80 | $this->fileStream = $fileStream; 81 | $this->fileName = $fileName; 82 | $this->mimeType = $mimeType; 83 | 84 | return $this; 85 | } 86 | 87 | /** 88 | * @return string 89 | */ 90 | public function getFileName(): string 91 | { 92 | return $this->fileName; 93 | } 94 | 95 | /** 96 | * @param string $fileName 97 | * @return Attachment 98 | */ 99 | public function setFileName(string $fileName): Attachment 100 | { 101 | $this->fileName = $fileName; 102 | return $this; 103 | } 104 | 105 | /** 106 | * @return ?string 107 | */ 108 | public function getMimeType(): ?string 109 | { 110 | return $this->mimeType; 111 | } 112 | 113 | /** 114 | * @param ?string $mimeType 115 | * @return Attachment 116 | */ 117 | public function setMimeType(?string $mimeType): Attachment 118 | { 119 | $this->mimeType = $mimeType; 120 | return $this; 121 | } 122 | 123 | /** 124 | * The validate function that is called during xml writing to valid the data of the object. 125 | * 126 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 127 | * @return void 128 | */ 129 | public function validate() 130 | { 131 | if ($this->filePath === null && $this->externalReference === null && $this->fileStream === null) { 132 | throw new InvalidArgumentException('Attachment must have a filePath, an externalReference, or a fileContent'); 133 | } 134 | 135 | if ($this->fileStream !== null && $this->mimeType === null) { 136 | throw new InvalidArgumentException('Using fileStream, you need to define a mimeType by also using setFileMimeType'); 137 | } 138 | 139 | if ($this->filePath !== null && !file_exists($this->filePath)) { 140 | throw new InvalidArgumentException('Attachment at filePath does not exist'); 141 | } 142 | } 143 | 144 | /** 145 | * The xmlSerialize method is called during xml writing. 146 | * 147 | * @param Writer $writer 148 | * @return void 149 | */ 150 | public function xmlSerialize(Writer $writer): void 151 | { 152 | $this->validate(); 153 | 154 | if (!empty($this->filePath)) { 155 | $fileContents = base64_encode(file_get_contents($this->filePath)); 156 | $fileName = basename($this->filePath); 157 | $mimeType = $this->getFilePathMimeType(); 158 | } else { 159 | $fileContents = $this->fileStream; 160 | $fileName = $this->fileName; 161 | $mimeType = $this->mimeType; 162 | } 163 | 164 | $writer->write([ 165 | 'name' => Schema::CBC . 'EmbeddedDocumentBinaryObject', 166 | 'value' => $fileContents, 167 | 'attributes' => [ 168 | 'mimeCode' => $mimeType, 169 | 'filename' => $fileName, 170 | ] 171 | ]); 172 | 173 | if ($this->externalReference) { 174 | $writer->writeElement( 175 | Schema::CAC . 'ExternalReference', 176 | [ Schema::CBC . 'URI' => $this->externalReference ] 177 | ); 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/BillingReference.php: -------------------------------------------------------------------------------- 1 | invoiceDocumentReference; 21 | } 22 | 23 | /** 24 | * 25 | * @return BillingReference 26 | */ 27 | public function setInvoiceDocumentReference($invoiceDocumentReference): BillingReference 28 | { 29 | $this->invoiceDocumentReference = $invoiceDocumentReference; 30 | return $this; 31 | } 32 | 33 | /** 34 | * The validate function that is called during xml writing to valid the data of the object. 35 | * 36 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 37 | * @return void 38 | */ 39 | public function validate() 40 | { 41 | if ($this->invoiceDocumentReference === null) { 42 | throw new InvalidArgumentException('Missing billingreference invoicedocumentreference'); 43 | } 44 | } 45 | 46 | /** 47 | * The xmlSerialize method is called during xml writing. 48 | * @param Writer $writer 49 | * @return void 50 | */ 51 | public function xmlSerialize(Writer $writer): void 52 | { 53 | $this->validate(); 54 | 55 | $writer->write([Schema::CAC . 'InvoiceDocumentReference' => $this->invoiceDocumentReference]); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/ClassifiedTaxCategory.php: -------------------------------------------------------------------------------- 1 | id)) { 27 | return $this->id; 28 | } 29 | 30 | if ($this->getPercent() !== null) { 31 | return ($this->getPercent() > 0) 32 | ? UNCL5305::STANDARD_RATE 33 | : UNCL5305::ZERO_RATED_GOODS; 34 | } 35 | 36 | return null; 37 | } 38 | 39 | /** 40 | * @param string $id 41 | * @return ClassifiedTaxCategory 42 | */ 43 | public function setId(?string $id): ClassifiedTaxCategory 44 | { 45 | $this->id = $id; 46 | return $this; 47 | } 48 | 49 | /** 50 | * @return string 51 | */ 52 | public function getName(): ?string 53 | { 54 | return $this->name; 55 | } 56 | 57 | /** 58 | * @param string $name 59 | * @return ClassifiedTaxCategory 60 | */ 61 | public function setName(?string $name): ClassifiedTaxCategory 62 | { 63 | $this->name = $name; 64 | return $this; 65 | } 66 | 67 | /** 68 | * @return float 69 | */ 70 | public function getPercent(): ?float 71 | { 72 | return $this->percent; 73 | } 74 | 75 | /** 76 | * @param float $percent 77 | * @return ClassifiedTaxCategory 78 | */ 79 | public function setPercent(?float $percent): ClassifiedTaxCategory 80 | { 81 | $this->percent = $percent; 82 | return $this; 83 | } 84 | 85 | /** 86 | * @return TaxScheme 87 | */ 88 | public function getTaxScheme(): ?TaxScheme 89 | { 90 | return $this->taxScheme; 91 | } 92 | 93 | /** 94 | * @param TaxScheme $taxScheme 95 | * @return ClassifiedTaxCategory 96 | */ 97 | public function setTaxScheme(?TaxScheme $taxScheme): ClassifiedTaxCategory 98 | { 99 | $this->taxScheme = $taxScheme; 100 | return $this; 101 | } 102 | 103 | /** 104 | * @return string 105 | */ 106 | public function getSchemeID(): ?string 107 | { 108 | return $this->schemeID; 109 | } 110 | 111 | /** 112 | * @param string $id 113 | * @return ClassifiedTaxCategory 114 | */ 115 | public function setSchemeID(?string $id): ClassifiedTaxCategory 116 | { 117 | $this->schemeID = $id; 118 | return $this; 119 | } 120 | 121 | /** 122 | * @return string 123 | */ 124 | public function getSchemeName(): ?string 125 | { 126 | return $this->schemeName; 127 | } 128 | 129 | /** 130 | * @param string $name 131 | * @return ClassifiedTaxCategory 132 | */ 133 | public function setSchemeName(?string $name): ClassifiedTaxCategory 134 | { 135 | $this->schemeName = $name; 136 | return $this; 137 | } 138 | 139 | /** 140 | * @return string 141 | */ 142 | public function getTaxExemptionReason(): ?string 143 | { 144 | return $this->taxExemptionReason; 145 | } 146 | 147 | /** 148 | * @param string $taxExemptionReason 149 | * @return ClassifiedTaxCategory 150 | */ 151 | public function setTaxExemptionReason(?string $taxExemptionReason): ClassifiedTaxCategory 152 | { 153 | $this->taxExemptionReason = $taxExemptionReason; 154 | return $this; 155 | } 156 | 157 | /** 158 | * @return string 159 | */ 160 | public function getTaxExemptionReasonCode(): ?string 161 | { 162 | return $this->taxExemptionReasonCode; 163 | } 164 | 165 | /** 166 | * @param string $taxExemptionReasonCode 167 | * @return ClassifiedTaxCategory 168 | */ 169 | public function setTaxExemptionReasonCode(?string $taxExemptionReasonCode): ClassifiedTaxCategory 170 | { 171 | $this->taxExemptionReasonCode = $taxExemptionReasonCode; 172 | return $this; 173 | } 174 | 175 | /** 176 | * The validate function that is called during xml writing to valid the data of the object. 177 | * 178 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 179 | * @return void 180 | */ 181 | public function validate() 182 | { 183 | if ($this->getId() === null) { 184 | throw new InvalidArgumentException('Missing taxcategory id'); 185 | } 186 | 187 | if ($this->getPercent() === null) { 188 | throw new InvalidArgumentException('Missing taxcategory percent'); 189 | } 190 | } 191 | 192 | /** 193 | * The xmlSerialize method is called during xml writing. 194 | * 195 | * @param Writer $writer 196 | * @return void 197 | */ 198 | public function xmlSerialize(Writer $writer): void 199 | { 200 | $this->validate(); 201 | 202 | $schemeAttributes = []; 203 | if ($this->schemeID !== null) { 204 | $schemeAttributes['schemeID'] = $this->schemeID; 205 | } 206 | if ($this->schemeName !== null) { 207 | $schemeAttributes['schemeName'] = $this->schemeName; 208 | } 209 | 210 | $writer->write([ 211 | 'name' => Schema::CBC . 'ID', 212 | 'value' => $this->getId(), 213 | 'attributes' => $schemeAttributes 214 | ]); 215 | 216 | if ($this->name !== null) { 217 | $writer->write([ 218 | Schema::CBC . 'Name' => $this->name, 219 | ]); 220 | } 221 | 222 | $writer->write([ 223 | Schema::CBC . 'Percent' => NumberFormatter::format($this->percent, 2) 224 | ]); 225 | 226 | if ($this->taxExemptionReasonCode !== null) { 227 | $writer->write([ 228 | Schema::CBC . 'TaxExemptionReasonCode' => $this->taxExemptionReasonCode, 229 | Schema::CBC . 'TaxExemptionReason' => $this->taxExemptionReason, 230 | ]); 231 | } 232 | 233 | if ($this->taxScheme !== null) { 234 | $writer->write([Schema::CAC . 'TaxScheme' => $this->taxScheme]); 235 | } else { 236 | $writer->write([ 237 | Schema::CAC . 'TaxScheme' => null, 238 | ]); 239 | } 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /src/CommodityClassification.php: -------------------------------------------------------------------------------- 1 | itemClassificationCode; 20 | } 21 | 22 | /** 23 | * @param string $itemClassificationCode 24 | * @return CommodityClassification 25 | */ 26 | public function setItemClassificationCode(?string $itemClassificationCode): CommodityClassification 27 | { 28 | $this->itemClassificationCode = $itemClassificationCode; 29 | return $this; 30 | } 31 | 32 | /** 33 | * @return ?string 34 | */ 35 | public function getItemClassificationListId(): ?string 36 | { 37 | return $this->itemClassificationListId; 38 | } 39 | 40 | /** 41 | * @param ?string $itemClassificationListId 42 | * @return CommodityClassification 43 | */ 44 | public function setItemClassificationListId(?string $itemClassificationListId): CommodityClassification 45 | { 46 | $this->itemClassificationListId = $itemClassificationListId; 47 | return $this; 48 | } 49 | 50 | /** 51 | * @return ?string 52 | */ 53 | public function getItemClassificationListVersionId(): ?string 54 | { 55 | return $this->itemClassificationListVersionId; 56 | } 57 | 58 | /** 59 | * @param ?string $itemClassificationListVersionId 60 | * @return CommodityClassification 61 | */ 62 | public function setItemClassificationListVersionId(?string $itemClassificationListVersionId): CommodityClassification 63 | { 64 | $this->itemClassificationListVersionId = $itemClassificationListVersionId; 65 | return $this; 66 | } 67 | 68 | /** 69 | * The xmlSerialize method is called during xml writing. 70 | * 71 | * @param Writer $writer 72 | * @return void 73 | */ 74 | public function xmlSerialize(Writer $writer): void 75 | { 76 | $attributes = [ 77 | 'listID' => $this->itemClassificationListId ?? '', 78 | ]; 79 | 80 | if (!empty($this->itemClassificationListVersionId)) { 81 | $attributes['listVersionID'] = $this->itemClassificationListVersionId; 82 | } 83 | 84 | $writer->write([ 85 | 'name' => Schema::CBC . 'ItemClassificationCode', 86 | 'value' => $this->itemClassificationCode ?? '', 87 | 'attributes' => $attributes 88 | ]); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Contact.php: -------------------------------------------------------------------------------- 1 | name; 21 | } 22 | 23 | /** 24 | * @param mixed $name 25 | * @return Contact 26 | */ 27 | public function setName($name): Contact 28 | { 29 | $this->name = $name; 30 | return $this; 31 | } 32 | 33 | /** 34 | * @return mixed 35 | */ 36 | public function getTelephone(): ?string 37 | { 38 | return $this->telephone; 39 | } 40 | 41 | /** 42 | * @param string $telephone 43 | * @return Contact 44 | */ 45 | public function setTelephone(?string $telephone): Contact 46 | { 47 | $this->telephone = $telephone; 48 | return $this; 49 | } 50 | 51 | /** 52 | * @return string 53 | */ 54 | public function getTelefax(): ?string 55 | { 56 | return $this->telefax; 57 | } 58 | 59 | /** 60 | * @param string $telefax 61 | * @return Contact 62 | */ 63 | public function setTelefax(?string $telefax): Contact 64 | { 65 | $this->telefax = $telefax; 66 | return $this; 67 | } 68 | 69 | /** 70 | * @return string 71 | */ 72 | public function getElectronicMail(): ?string 73 | { 74 | return $this->electronicMail; 75 | } 76 | 77 | /** 78 | * @param string $electronicMail 79 | * @return Contact 80 | */ 81 | public function setElectronicMail(?string $electronicMail): Contact 82 | { 83 | $this->electronicMail = $electronicMail; 84 | return $this; 85 | } 86 | 87 | /** 88 | * The xmlSerialize method is called during xml writing. 89 | * 90 | * @param Writer $writer 91 | * @return void 92 | */ 93 | public function xmlSerialize(Writer $writer): void 94 | { 95 | if ($this->name !== null) { 96 | $writer->write([ 97 | Schema::CBC . 'Name' => $this->name 98 | ]); 99 | } 100 | 101 | if ($this->telephone !== null) { 102 | $writer->write([ 103 | Schema::CBC . 'Telephone' => $this->telephone 104 | ]); 105 | } 106 | 107 | if ($this->telefax !== null) { 108 | $writer->write([ 109 | Schema::CBC . 'Telefax' => $this->telefax 110 | ]); 111 | } 112 | 113 | if ($this->electronicMail !== null) { 114 | $writer->write([ 115 | Schema::CBC . 'ElectronicMail' => $this->electronicMail 116 | ]); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/ContractDocumentReference.php: -------------------------------------------------------------------------------- 1 | id; 18 | } 19 | 20 | /** 21 | * @param string $id 22 | * @return ContractDocumentReference 23 | */ 24 | public function setId(string $id): ContractDocumentReference 25 | { 26 | $this->id = $id; 27 | return $this; 28 | } 29 | 30 | /** 31 | * The xmlSerialize method is called during xml writing. 32 | * 33 | * @param Writer $writer 34 | * @return void 35 | */ 36 | public function xmlSerialize(Writer $writer): void 37 | { 38 | if ($this->id !== null) { 39 | $writer->write([ Schema::CBC . 'ID' => $this->id ]); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Country.php: -------------------------------------------------------------------------------- 1 | identificationCode; 19 | } 20 | 21 | /** 22 | * @param mixed $identificationCode 23 | * @return Country 24 | */ 25 | public function setIdentificationCode(?string $identificationCode): Country 26 | { 27 | $this->identificationCode = $identificationCode; 28 | return $this; 29 | } 30 | 31 | /** 32 | * @return mixed 33 | */ 34 | public function getListId(): ?string 35 | { 36 | return $this->listId; 37 | } 38 | 39 | /** 40 | * @param mixed $listId 41 | * @return Country 42 | */ 43 | public function setListId(?string $listId): Country 44 | { 45 | $this->listId = $listId; 46 | return $this; 47 | } 48 | 49 | /** 50 | * The xmlSerialize method is called during xml writing. 51 | * 52 | * @param Writer $writer 53 | * @return void 54 | */ 55 | public function xmlSerialize(Writer $writer): void 56 | { 57 | $attributes = []; 58 | 59 | if (!empty($this->listId)) { 60 | $attributes['listID'] = 'ISO3166-1:Alpha2'; 61 | } 62 | 63 | $writer->write([ 64 | 'name' => Schema::CBC . 'IdentificationCode', 65 | 'value' => $this->identificationCode, 66 | 'attributes' => $attributes 67 | ]); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/CreditNote.php: -------------------------------------------------------------------------------- 1 | invoiceLines; 19 | } 20 | 21 | /** 22 | * @param CreditNoteLine[] $creditNoteLines 23 | * @return CreditNote 24 | */ 25 | public function setCreditNoteLines(array $creditNoteLines): CreditNote 26 | { 27 | $this->invoiceLines = $creditNoteLines; 28 | return $this; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/CreditNoteLine.php: -------------------------------------------------------------------------------- 1 | invoicedQuantity; 16 | } 17 | 18 | /** 19 | * @param ?float $creditedQuantity 20 | * @return CreditNoteLine 21 | */ 22 | public function setCreditedQuantity(?float $creditedQuantity): CreditNoteLine 23 | { 24 | $this->invoicedQuantity = $creditedQuantity; 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Delivery.php: -------------------------------------------------------------------------------- 1 | actualDeliveryDate; 21 | } 22 | 23 | /** 24 | * @param DateTime $actualDeliveryDate 25 | * @return Delivery 26 | */ 27 | public function setActualDeliveryDate($actualDeliveryDate): Delivery 28 | { 29 | $this->actualDeliveryDate = $actualDeliveryDate; 30 | return $this; 31 | } 32 | 33 | /** 34 | * @return Address 35 | */ 36 | public function getDeliveryLocation() 37 | { 38 | return $this->deliveryLocation; 39 | } 40 | 41 | /** 42 | * @param Address $deliveryLocation 43 | * @return Delivery 44 | */ 45 | public function setDeliveryLocation($deliveryLocation): Delivery 46 | { 47 | $this->deliveryLocation = $deliveryLocation; 48 | return $this; 49 | } 50 | 51 | /** 52 | * @return Party 53 | */ 54 | public function getDeliveryParty() 55 | { 56 | return $this->deliveryParty; 57 | } 58 | 59 | /** 60 | * @param Party $deliveryParty 61 | * @return Delivery 62 | */ 63 | public function setDeliveryParty($deliveryParty): Delivery 64 | { 65 | $this->deliveryParty = $deliveryParty; 66 | return $this; 67 | } 68 | 69 | /** 70 | * The xmlSerialize method is called during xml writing. 71 | * 72 | * @param Writer $writer 73 | * @return void 74 | */ 75 | public function xmlSerialize(Writer $writer): void 76 | { 77 | if ($this->actualDeliveryDate != null) { 78 | $writer->write([ 79 | Schema::CBC . 'ActualDeliveryDate' => $this->actualDeliveryDate->format('Y-m-d') 80 | ]); 81 | } 82 | if ($this->deliveryLocation != null) { 83 | $writer->write([ 84 | Schema::CAC . 'DeliveryLocation' => [ Schema::CAC . 'Address' => $this->deliveryLocation ] 85 | ]); 86 | } 87 | if ($this->deliveryParty != null) { 88 | $writer->write([ 89 | Schema::CAC . 'DeliveryParty' => $this->deliveryParty 90 | ]); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/EASCode.php: -------------------------------------------------------------------------------- 1 | id; 18 | } 19 | 20 | /** 21 | * @param string $id 22 | * @return FinancialInstitutionBranch 23 | */ 24 | public function setId(?string $id): FinancialInstitutionBranch 25 | { 26 | $this->id = $id; 27 | return $this; 28 | } 29 | 30 | public function xmlSerialize(Writer $writer): void 31 | { 32 | $writer->write([ 33 | Schema::CBC . 'ID' => $this->id 34 | ]); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Generator.php: -------------------------------------------------------------------------------- 1 | namespaceMap = [ 18 | 'urn:oasis:names:specification:ubl:schema:xsd:' . $invoice->xmlTagName . '-2' => '', 19 | 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' => 'cbc', 20 | 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' => 'cac' 21 | ]; 22 | 23 | return $xmlService->write($invoice->xmlTagName, [ 24 | $invoice 25 | ]); 26 | } 27 | 28 | public static function creditNote(CreditNote $creditNote, $currencyId = 'EUR') 29 | { 30 | self::$currencyID = $currencyId; 31 | 32 | $xmlService = new Service(); 33 | 34 | $xmlService->namespaceMap = [ 35 | 'urn:oasis:names:specification:ubl:schema:xsd:' . $creditNote->xmlTagName . '-2' => '', 36 | 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' => 'cbc', 37 | 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' => 'cac' 38 | ]; 39 | 40 | return $xmlService->write($creditNote->xmlTagName, [ 41 | $creditNote 42 | ]); 43 | } 44 | } -------------------------------------------------------------------------------- /src/ICDCode.php: -------------------------------------------------------------------------------- 1 | originalInvoiceId; 23 | } 24 | 25 | /** 26 | * Set the id of the invoice that is being credited 27 | * 28 | * @return InvoiceDocumentReference 29 | */ 30 | public function setOriginalInvoiceId(string $invoiceRef): InvoiceDocumentReference 31 | { 32 | $this->originalInvoiceId = $invoiceRef; 33 | return $this; 34 | } 35 | 36 | /** 37 | * Get the issue date of the original invoice that is being credited 38 | * 39 | * @return ?DateTime 40 | */ 41 | public function getIssueDate(): ?DateTime 42 | { 43 | return $this->issueDate; 44 | } 45 | 46 | /** 47 | * Set the issue date of the original invoice that is being credited 48 | * 49 | * @return InvoiceDocumentReference 50 | */ 51 | public function setIssueDate(DateTime $issueDate): InvoiceDocumentReference 52 | { 53 | $this->issueDate = $issueDate; 54 | return $this; 55 | } 56 | 57 | /** 58 | * The validate function that is called during xml writing to valid the data of the object. 59 | * 60 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 61 | * @return void 62 | */ 63 | public function validate() 64 | { 65 | if ($this->originalInvoiceId === null) { 66 | throw new InvalidArgumentException('Missing invoicedocumentreference originalinvoiceid'); 67 | } 68 | } 69 | 70 | /** 71 | * The xmlSerialize method is called during xml writing. 72 | * @param Writer $writer 73 | * @return void 74 | */ 75 | public function xmlSerialize(Writer $writer): void 76 | { 77 | $this->validate(); 78 | 79 | $writer->write([ 80 | [ 81 | 'name' => Schema::CBC . 'ID', 82 | 'value' => $this->originalInvoiceId 83 | ] 84 | ]); 85 | 86 | if ($this->issueDate != null) 87 | { 88 | $writer->write([ 89 | [ 90 | 'name' => Schema::CBC . 'IssueDate', 91 | 'value' => $this->issueDate->format('Y-m-d') 92 | ] 93 | ]); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/InvoicePeriod.php: -------------------------------------------------------------------------------- 1 | startDate; 22 | } 23 | 24 | /** 25 | * @param DateTime $startDate 26 | * @return InvoicePeriod 27 | */ 28 | public function setStartDate(?DateTime $startDate): InvoicePeriod 29 | { 30 | $this->startDate = $startDate; 31 | return $this; 32 | } 33 | 34 | /** 35 | * @return DateTime 36 | */ 37 | public function getEndDate(): ?DateTime 38 | { 39 | return $this->endDate; 40 | } 41 | 42 | /** 43 | * @param DateTime $endDate 44 | * @return InvoicePeriod 45 | */ 46 | public function setEndDate(?DateTime $endDate): InvoicePeriod 47 | { 48 | $this->endDate = $endDate; 49 | return $this; 50 | } 51 | 52 | /** 53 | * @return int 54 | */ 55 | public function getDescriptionCode(): ?int 56 | { 57 | return $this->descriptionCode; 58 | } 59 | 60 | /** 61 | * @param Integer $descriptionCode 62 | * @return InvoicePeriod 63 | */ 64 | public function setDescriptionCode(?int $descriptionCode): InvoicePeriod 65 | { 66 | $this->descriptionCode = $descriptionCode; 67 | return $this; 68 | } 69 | 70 | /** 71 | * The validate function that is called during xml writing to valid the data of the object. 72 | * 73 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 74 | * @return void 75 | */ 76 | public function validate() 77 | { 78 | if ($this->descriptionCode === null && ($this->startDate === null && $this->endDate === null)) { 79 | throw new InvalidArgumentException('Missing startDate or endDate or descriptionCode'); 80 | } 81 | } 82 | 83 | /** 84 | * The xmlSerialize method is called during xml writing. 85 | * 86 | * @param Writer $writer 87 | * @return void 88 | */ 89 | public function xmlSerialize(Writer $writer): void 90 | { 91 | $this->validate(); 92 | 93 | if ($this->startDate != null) { 94 | $writer->write([ 95 | Schema::CBC . 'StartDate' => $this->startDate->format('Y-m-d'), 96 | ]); 97 | } 98 | if ($this->endDate != null) { 99 | $writer->write([ 100 | Schema::CBC . 'EndDate' => $this->endDate->format('Y-m-d'), 101 | ]); 102 | } 103 | if ($this->descriptionCode !== null) { 104 | $writer->write([ 105 | Schema::CBC . 'DescriptionCode' => $this->descriptionCode, 106 | ]); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/InvoiceTypeCode.php: -------------------------------------------------------------------------------- 1 | description; 25 | } 26 | 27 | /** 28 | * @param string $description 29 | * @return Item 30 | */ 31 | public function setDescription(?string $description): Item 32 | { 33 | $this->description = $description; 34 | return $this; 35 | } 36 | 37 | /** 38 | * @return mixed 39 | */ 40 | public function getName(): ?string 41 | { 42 | return $this->name; 43 | } 44 | 45 | /** 46 | * @param mixed $name 47 | * @return Item 48 | */ 49 | public function setName(?string $name): Item 50 | { 51 | $this->name = $name; 52 | return $this; 53 | } 54 | 55 | /** 56 | * @return mixed 57 | */ 58 | public function getSellersItemIdentification(): ?string 59 | { 60 | return $this->sellersItemIdentification; 61 | } 62 | 63 | /** 64 | * @param mixed $sellersItemIdentification 65 | * @return Item 66 | */ 67 | public function setSellersItemIdentification(?string $sellersItemIdentification): Item 68 | { 69 | $this->sellersItemIdentification = $sellersItemIdentification; 70 | return $this; 71 | } 72 | 73 | /** 74 | * @return mixed 75 | */ 76 | public function getStandardItemIdentification(): ?string 77 | { 78 | return $this->standardItemIdentification; 79 | } 80 | 81 | /** 82 | * @param mixed $standardItemIdentification 83 | * @return Item 84 | */ 85 | public function setStandardItemIdentification(?string $standardItemIdentification, $attributes = null): Item 86 | { 87 | $this->standardItemIdentification = $standardItemIdentification; 88 | if (isset($attributes)) { 89 | $this->standardItemIdentificationAttributes = $attributes; 90 | } 91 | return $this; 92 | } 93 | 94 | /** 95 | * @return CommodityClassification 96 | */ 97 | public function getCommodityClassification(): ?CommodityClassification 98 | { 99 | return $this->commodityClassification; 100 | } 101 | 102 | /** 103 | * @param mixed $commodityClassification 104 | * @return Item 105 | */ 106 | public function setCommodityClassification(CommodityClassification $commodityClassification): Item 107 | { 108 | $this->commodityClassification = $commodityClassification; 109 | return $this; 110 | } 111 | 112 | /** 113 | * @return mixed 114 | */ 115 | public function getBuyersItemIdentification(): ?string 116 | { 117 | return $this->buyersItemIdentification; 118 | } 119 | 120 | /** 121 | * @param mixed $buyersItemIdentification 122 | * @return Item 123 | */ 124 | public function setBuyersItemIdentification(?string $buyersItemIdentification): Item 125 | { 126 | $this->buyersItemIdentification = $buyersItemIdentification; 127 | return $this; 128 | } 129 | 130 | /** 131 | * @return ClassifiedTaxCategory 132 | */ 133 | public function getClassifiedTaxCategory(): ?ClassifiedTaxCategory 134 | { 135 | return $this->classifiedTaxCategory; 136 | } 137 | 138 | /** 139 | * @param ClassifiedTaxCategory $classifiedTaxCategory 140 | * @return Item 141 | */ 142 | public function setClassifiedTaxCategory(?ClassifiedTaxCategory $classifiedTaxCategory): Item 143 | { 144 | $this->classifiedTaxCategory = $classifiedTaxCategory; 145 | return $this; 146 | } 147 | 148 | /** 149 | * The xmlSerialize method is called during xml writing. 150 | * 151 | * @param Writer $writer 152 | * @return void 153 | */ 154 | public function xmlSerialize(Writer $writer): void 155 | { 156 | if (!empty($this->getDescription())) { 157 | $writer->write([ 158 | Schema::CBC . 'Description' => $this->description 159 | ]); 160 | } 161 | 162 | $writer->write([ 163 | Schema::CBC . 'Name' => $this->name 164 | ]); 165 | 166 | if (!empty($this->getBuyersItemIdentification())) { 167 | $writer->write([ 168 | Schema::CAC . 'BuyersItemIdentification' => [ 169 | Schema::CBC . 'ID' => $this->buyersItemIdentification 170 | ], 171 | ]); 172 | } 173 | 174 | if (!empty($this->getSellersItemIdentification())) { 175 | $writer->write([ 176 | Schema::CAC . 'SellersItemIdentification' => [ 177 | Schema::CBC . 'ID' => $this->sellersItemIdentification 178 | ], 179 | ]); 180 | } 181 | 182 | if (!empty($this->getStandardItemIdentification())) { 183 | $writer->write([ 184 | Schema::CAC . 'StandardItemIdentification' => [ 185 | Schema::CBC . 'ID' => [ 186 | 'value' => $this->standardItemIdentification, 187 | 'attributes' => $this->standardItemIdentificationAttributes 188 | ] 189 | ] 190 | ]); 191 | } 192 | 193 | if (!empty($this->getCommodityClassification())) { 194 | $writer->write([ 195 | Schema::CAC . 'CommodityClassification' => $this->commodityClassification 196 | ]); 197 | } 198 | 199 | if (!empty($this->getClassifiedTaxCategory())) { 200 | $writer->write([ 201 | Schema::CAC . 'ClassifiedTaxCategory' => $this->classifiedTaxCategory 202 | ]); 203 | } 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/LegalEntity.php: -------------------------------------------------------------------------------- 1 | registrationName; 22 | } 23 | 24 | /** 25 | * @param string $registrationName 26 | * @return LegalEntity 27 | */ 28 | public function setRegistrationName(?string $registrationName): LegalEntity 29 | { 30 | $this->registrationName = $registrationName; 31 | return $this; 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getCompanyId(): ?string 38 | { 39 | return $this->companyId; 40 | } 41 | 42 | /** 43 | * @param string $companyId 44 | * @return LegalEntity 45 | */ 46 | public function setCompanyId(?string $companyId, $attributes = null): LegalEntity 47 | { 48 | $this->companyId = $companyId; 49 | if (isset($attributes)) { 50 | $this->companyIdAttributes = $attributes; 51 | } 52 | return $this; 53 | } 54 | 55 | /** 56 | * 57 | * @param string $legalForm 58 | * @return LegalEntity 59 | */ 60 | public function setCompanyLegalForm(?string $legalForm, $attributes = null) : LegalEntity 61 | { 62 | $this->companyLegalForm = $legalForm; 63 | if (isset($attributes)) { 64 | $this->companyLegalFormAttributes = $attributes; 65 | } 66 | return $this; 67 | } 68 | 69 | /** 70 | * The xmlSerialize method is called during xml writing. 71 | * 72 | * @param Writer $writer 73 | * @return void 74 | */ 75 | public function xmlSerialize(Writer $writer): void 76 | { 77 | $writer->write([ 78 | Schema::CBC . 'RegistrationName' => $this->registrationName, 79 | ]); 80 | if ($this->companyId !== null) { 81 | $writer->write([ 82 | [ 83 | 'name' => Schema::CBC . 'CompanyID', 84 | 'value' => $this->companyId, 85 | 'attributes' => $this->companyIdAttributes, 86 | ], 87 | ]); 88 | } 89 | if ($this->companyLegalForm !== null) { 90 | $writer->write([ 91 | [ 92 | 'name' => Schema::CBC . 'CompanyLegalForm', 93 | 'value' => $this->companyLegalForm, 94 | 'attributes' => $this->companyLegalFormAttributes 95 | ] 96 | ]); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/LegalMonetaryTotal.php: -------------------------------------------------------------------------------- 1 | lineExtensionAmount; 25 | } 26 | 27 | /** 28 | * @param float $lineExtensionAmount 29 | * @return LegalMonetaryTotal 30 | */ 31 | public function setLineExtensionAmount(?float $lineExtensionAmount): LegalMonetaryTotal 32 | { 33 | $this->lineExtensionAmount = $lineExtensionAmount; 34 | return $this; 35 | } 36 | 37 | /** 38 | * @return float 39 | */ 40 | public function getTaxExclusiveAmount(): ?float 41 | { 42 | return $this->taxExclusiveAmount; 43 | } 44 | 45 | /** 46 | * @param float $taxExclusiveAmount 47 | * @return LegalMonetaryTotal 48 | */ 49 | public function setTaxExclusiveAmount(?float $taxExclusiveAmount): LegalMonetaryTotal 50 | { 51 | $this->taxExclusiveAmount = $taxExclusiveAmount; 52 | return $this; 53 | } 54 | 55 | /** 56 | * @return float 57 | */ 58 | public function getTaxInclusiveAmount(): ?float 59 | { 60 | return $this->taxInclusiveAmount; 61 | } 62 | 63 | /** 64 | * @param float $taxInclusiveAmount 65 | * @return LegalMonetaryTotal 66 | */ 67 | public function setTaxInclusiveAmount(?float $taxInclusiveAmount): LegalMonetaryTotal 68 | { 69 | $this->taxInclusiveAmount = $taxInclusiveAmount; 70 | return $this; 71 | } 72 | 73 | /** 74 | * @return float 75 | */ 76 | public function getAllowanceTotalAmount(): ?float 77 | { 78 | return $this->allowanceTotalAmount; 79 | } 80 | 81 | /** 82 | * @param float $allowanceTotalAmount 83 | * @return LegalMonetaryTotal 84 | */ 85 | public function setAllowanceTotalAmount(?float $allowanceTotalAmount): LegalMonetaryTotal 86 | { 87 | $this->allowanceTotalAmount = $allowanceTotalAmount; 88 | return $this; 89 | } 90 | 91 | /** 92 | * @return float 93 | */ 94 | public function getChargeTotalAmount(): ?float 95 | { 96 | return $this->chargeTotalAmount; 97 | } 98 | 99 | /** 100 | * @param float $chargeTotalAmount 101 | * @return LegalMonetaryTotal 102 | */ 103 | public function setChargeTotalAmount(?float $chargeTotalAmount): LegalMonetaryTotal 104 | { 105 | $this->chargeTotalAmount = $chargeTotalAmount; 106 | return $this; 107 | } 108 | 109 | /** 110 | * @return ?float 111 | */ 112 | public function getPrepaidAmount(): ?float 113 | { 114 | return $this->prepaidAmount; 115 | } 116 | 117 | /** 118 | * @param ?float $prepaidAmount 119 | * @return LegalMonetaryTotal 120 | */ 121 | public function setPrepaidAmount(?float $prepaidAmount): LegalMonetaryTotal 122 | { 123 | $this->prepaidAmount = $prepaidAmount; 124 | return $this; 125 | } 126 | 127 | /** 128 | * @return float 129 | */ 130 | public function getPayableAmount(): ?float 131 | { 132 | return $this->payableAmount; 133 | } 134 | 135 | /** 136 | * @param float $payableAmount 137 | * @return LegalMonetaryTotal 138 | */ 139 | public function setPayableAmount(?float $payableAmount): LegalMonetaryTotal 140 | { 141 | $this->payableAmount = $payableAmount; 142 | return $this; 143 | } 144 | 145 | public function getPayableRoundingAmount(): ?float 146 | { 147 | return $this->payableRoundingAmount; 148 | } 149 | 150 | /** 151 | * @param float|null $payableRoundingAmount 152 | * @return LegalMonetaryTotal 153 | */ 154 | public function setPayableRoundingAmount(?float $payableRoundingAmount): LegalMonetaryTotal 155 | { 156 | $this->payableRoundingAmount = $payableRoundingAmount; 157 | return $this; 158 | } 159 | 160 | /** 161 | * The xmlSerialize method is called during xml writing. 162 | * 163 | * @param Writer $writer 164 | * @return void 165 | */ 166 | public function xmlSerialize(Writer $writer): void 167 | { 168 | $writer->write([ 169 | [ 170 | 'name' => Schema::CBC . 'LineExtensionAmount', 171 | 'value' => NumberFormatter::format($this->lineExtensionAmount, 2), 172 | 'attributes' => [ 173 | 'currencyID' => Generator::$currencyID 174 | ] 175 | 176 | ], 177 | [ 178 | 'name' => Schema::CBC . 'TaxExclusiveAmount', 179 | 'value' => NumberFormatter::format($this->taxExclusiveAmount, 2), 180 | 'attributes' => [ 181 | 'currencyID' => Generator::$currencyID 182 | ] 183 | 184 | ], 185 | [ 186 | 'name' => Schema::CBC . 'TaxInclusiveAmount', 187 | 'value' => NumberFormatter::format($this->taxInclusiveAmount, 2), 188 | 'attributes' => [ 189 | 'currencyID' => Generator::$currencyID 190 | ] 191 | 192 | ], 193 | [ 194 | 'name' => Schema::CBC . 'AllowanceTotalAmount', 195 | 'value' => NumberFormatter::format($this->allowanceTotalAmount,2), 196 | 'attributes' => [ 197 | 'currencyID' => Generator::$currencyID 198 | ] 199 | 200 | ], 201 | [ 202 | 'name' => Schema::CBC . 'ChargeTotalAmount', 203 | 'value' => NumberFormatter::format($this->chargeTotalAmount, 2), 204 | 'attributes' => [ 205 | 'currencyID' => Generator::$currencyID 206 | ] 207 | 208 | ] 209 | ]); 210 | 211 | if ($this->prepaidAmount !== null) { 212 | $writer->write([ 213 | [ 214 | 'name' => Schema::CBC . 'PrepaidAmount', 215 | 'value' => NumberFormatter::format($this->prepaidAmount, 2), 216 | 'attributes' => [ 217 | 'currencyID' => Generator::$currencyID 218 | ] 219 | ] 220 | ]); 221 | } 222 | 223 | if ($this->payableRoundingAmount !== null) { 224 | $writer->write([ 225 | [ 226 | 'name' => Schema::CBC . 'PayableRoundingAmount', 227 | 'value' => NumberFormatter::format($this->payableRoundingAmount, 2), 228 | 'attributes' => [ 229 | 'currencyID' => Generator::$currencyID 230 | ] 231 | ], 232 | ]); 233 | } 234 | 235 | $writer->write([ 236 | [ 237 | 'name' => Schema::CBC . 'PayableAmount', 238 | 'value' => NumberFormatter::format($this->payableAmount, 2), 239 | 'attributes' => [ 240 | 'currencyID' => Generator::$currencyID 241 | ] 242 | ], 243 | ]); 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /src/NumberFormatter.php: -------------------------------------------------------------------------------- 1 | lineId; 22 | } 23 | 24 | /** 25 | * @param string $lineId 26 | * @return OrderLineReference 27 | */ 28 | public function setLineId(?string $lineId): OrderLineReference 29 | { 30 | $this->lineId = $lineId; 31 | return $this; 32 | } 33 | 34 | /** 35 | * The validate function that is called during xml writing to valid the data of the object. 36 | * 37 | * @return void 38 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 39 | */ 40 | public function validate() 41 | { 42 | if ($this->lineId === null) { 43 | throw new InvalidArgumentException('Missing OrderLineReference LineID'); 44 | } 45 | } 46 | 47 | public function xmlSerialize(Writer $writer): void 48 | { 49 | $this->validate(); 50 | 51 | $writer->write([ 52 | Schema::CBC . 'LineID' => $this->lineId 53 | ]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/OrderReference.php: -------------------------------------------------------------------------------- 1 | id; 21 | } 22 | 23 | /** 24 | * @param string $id 25 | * @return OrderReference 26 | */ 27 | public function setId(string $id): OrderReference 28 | { 29 | $this->id = $id; 30 | return $this; 31 | } 32 | 33 | /** 34 | * @return string 35 | */ 36 | public function getSalesOrderId(): string 37 | { 38 | return $this->salesOrderId; 39 | } 40 | 41 | /** 42 | * @return DateTime 43 | */ 44 | public function getIssueDate(): ?DateTime 45 | { 46 | return $this->issueDate; 47 | } 48 | 49 | /** 50 | * @param DateTime $issueDate 51 | * @return OrderReference 52 | */ 53 | public function setIssueDate(DateTime $issueDate): OrderReference 54 | { 55 | $this->issueDate = $issueDate; 56 | return $this; 57 | } 58 | 59 | /** 60 | * @param string $salesOrderId 61 | * @return OrderReference 62 | */ 63 | public function setSalesOrderId(string $salesOrderId): OrderReference 64 | { 65 | $this->salesOrderId = $salesOrderId; 66 | return $this; 67 | } 68 | 69 | /** 70 | * The xmlSerialize method is called during xml writing. 71 | * 72 | * @param Writer $writer 73 | * @return void 74 | */ 75 | public function xmlSerialize(Writer $writer): void 76 | { 77 | if ($this->id !== null) { 78 | $writer->write([Schema::CBC . 'ID' => $this->id]); 79 | } 80 | if ($this->salesOrderId !== null) { 81 | $writer->write([Schema::CBC . 'SalesOrderID' => $this->salesOrderId]); 82 | } 83 | if ($this->issueDate !== null) { 84 | $writer->write([ 85 | Schema::CBC . 'IssueDate' => $this->issueDate->format('Y-m-d'), 86 | ]); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Party.php: -------------------------------------------------------------------------------- 1 | name; 28 | } 29 | 30 | /** 31 | * @param string $name 32 | * @return Party 33 | */ 34 | public function setName(?string $name): Party 35 | { 36 | $this->name = $name; 37 | return $this; 38 | } 39 | 40 | /** 41 | * @return string 42 | */ 43 | public function getPartyIdentificationId(): ?string 44 | { 45 | return $this->partyIdentificationId; 46 | } 47 | 48 | /** 49 | * @param string $partyIdentificationId 50 | * @return Party 51 | */ 52 | public function setPartyIdentificationId(?string $partyIdentificationId): Party 53 | { 54 | $this->partyIdentificationId = $partyIdentificationId; 55 | return $this; 56 | } 57 | 58 | /** 59 | * @return string 60 | */ 61 | public function getPartyIdentificationSchemeId(): ?string 62 | { 63 | return $this->partyIdentificationSchemeId; 64 | } 65 | 66 | /** 67 | * @param string $partyIdentificationSchemeId 68 | * @return Party 69 | */ 70 | public function setPartyIdentificationSchemeId(?string $partyIdentificationSchemeId): Party 71 | { 72 | $this->partyIdentificationSchemeId = $partyIdentificationSchemeId; 73 | return $this; 74 | } 75 | 76 | /** 77 | * @return string 78 | */ 79 | public function getPartyIdentificationSchemeName(): ?string 80 | { 81 | return $this->partyIdentificationSchemeName; 82 | } 83 | 84 | /** 85 | * @param string $partyIdentificationSchemeName 86 | * @return Party 87 | */ 88 | public function setPartyIdentificationSchemeName(?string $partyIdentificationSchemeName): Party 89 | { 90 | $this->partyIdentificationSchemeName = $partyIdentificationSchemeName; 91 | return $this; 92 | } 93 | 94 | /** 95 | * @return Address 96 | */ 97 | public function getPostalAddress(): ?Address 98 | { 99 | return $this->postalAddress; 100 | } 101 | 102 | /** 103 | * @param Address $postalAddress 104 | * @return Party 105 | */ 106 | public function setPostalAddress(?Address $postalAddress): Party 107 | { 108 | $this->postalAddress = $postalAddress; 109 | return $this; 110 | } 111 | 112 | /** 113 | * @return LegalEntity 114 | */ 115 | public function getLegalEntity(): ?LegalEntity 116 | { 117 | return $this->legalEntity; 118 | } 119 | 120 | /** 121 | * @param LegalEntity $legalEntity 122 | * @return Party 123 | */ 124 | public function setLegalEntity(?LegalEntity $legalEntity): Party 125 | { 126 | $this->legalEntity = $legalEntity; 127 | return $this; 128 | } 129 | 130 | /** 131 | * @return Address 132 | */ 133 | public function getPhysicalLocation(): ?Address 134 | { 135 | return $this->physicalLocation; 136 | } 137 | 138 | /** 139 | * @param Address $physicalLocation 140 | * @return Party 141 | */ 142 | public function setPhysicalLocation(?Address $physicalLocation): Party 143 | { 144 | $this->physicalLocation = $physicalLocation; 145 | return $this; 146 | } 147 | 148 | /** 149 | * @return PartyTaxScheme 150 | */ 151 | public function getPartyTaxScheme(): ?PartyTaxScheme 152 | { 153 | return $this->partyTaxScheme; 154 | } 155 | 156 | /** 157 | * @param PartyTaxScheme $partyTaxScheme 158 | * @return Party 159 | */ 160 | public function setPartyTaxScheme(PartyTaxScheme $partyTaxScheme) 161 | { 162 | $this->partyTaxScheme = $partyTaxScheme; 163 | return $this; 164 | } 165 | 166 | /** 167 | * @return Contact 168 | */ 169 | public function getContact(): ?Contact 170 | { 171 | return $this->contact; 172 | } 173 | 174 | /** 175 | * @param Contact $contact 176 | * @return Party 177 | */ 178 | public function setContact(?Contact $contact): Party 179 | { 180 | $this->contact = $contact; 181 | return $this; 182 | } 183 | 184 | /** 185 | * @param $endpointID 186 | * @param int|string $schemeID See list at https://docs.peppol.eu/poacc/billing/3.0/codelist/eas/ 187 | * @return Party 188 | */ 189 | public function setEndpointID($endpointID, $schemeID): Party 190 | { 191 | $this->endpointID = $endpointID; 192 | $this->endpointID_schemeID = $schemeID; 193 | return $this; 194 | } 195 | 196 | /** 197 | * The xmlSerialize method is called during xml writing. 198 | * 199 | * @param Writer $writer 200 | * @return void 201 | */ 202 | public function xmlSerialize(Writer $writer): void 203 | { 204 | if ($this->endpointID !== null && $this->endpointID_schemeID !== null) { 205 | $writer->write([ 206 | [ 207 | 'name' => Schema::CBC . 'EndpointID', 208 | 'value' => $this->endpointID, 209 | 'attributes' => [ 210 | 'schemeID' => is_numeric($this->endpointID_schemeID) 211 | ? sprintf('%04d', +$this->endpointID_schemeID) 212 | : $this->endpointID_schemeID 213 | ] 214 | ] 215 | ]); 216 | } 217 | 218 | if ($this->partyIdentificationId !== null) { 219 | $partyIdentificationAttributes = []; 220 | 221 | if (!empty($this->getPartyIdentificationSchemeId())) { 222 | $partyIdentificationAttributes['schemeID'] = $this->getPartyIdentificationSchemeId(); 223 | } 224 | 225 | if (!empty($this->getPartyIdentificationSchemeName())) { 226 | $partyIdentificationAttributes['schemeName'] = $this->getPartyIdentificationSchemeName(); 227 | } 228 | 229 | $writer->write([ 230 | Schema::CAC . 'PartyIdentification' => [ 231 | [ 232 | 'name' => Schema::CBC . 'ID', 233 | 'value' => $this->partyIdentificationId, 234 | 'attributes' => $partyIdentificationAttributes 235 | ] 236 | ], 237 | ]); 238 | } 239 | 240 | if ($this->name !== null) { 241 | $writer->write([ 242 | Schema::CAC . 'PartyName' => [ 243 | Schema::CBC . 'Name' => $this->name 244 | ] 245 | ]); 246 | } 247 | 248 | $writer->write([ 249 | Schema::CAC . 'PostalAddress' => $this->postalAddress 250 | ]); 251 | 252 | if ($this->physicalLocation !== null) { 253 | $writer->write([ 254 | Schema::CAC . 'PhysicalLocation' => [Schema::CAC . 'Address' => $this->physicalLocation] 255 | ]); 256 | } 257 | 258 | if ($this->partyTaxScheme !== null) { 259 | $writer->write([ 260 | Schema::CAC . 'PartyTaxScheme' => $this->partyTaxScheme 261 | ]); 262 | } 263 | 264 | if ($this->legalEntity !== null) { 265 | $writer->write([ 266 | Schema::CAC . 'PartyLegalEntity' => $this->legalEntity 267 | ]); 268 | } 269 | 270 | if ($this->contact !== null) { 271 | $writer->write([ 272 | Schema::CAC . 'Contact' => $this->contact 273 | ]); 274 | } 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /src/PartyTaxScheme.php: -------------------------------------------------------------------------------- 1 | registrationName; 22 | } 23 | 24 | /** 25 | * @param string $registrationName 26 | * @return PartyTaxScheme 27 | */ 28 | public function setRegistrationName($registrationName): PartyTaxScheme 29 | { 30 | $this->registrationName = $registrationName; 31 | return $this; 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getCompanyId(): ?string 38 | { 39 | return $this->companyId; 40 | } 41 | 42 | /** 43 | * @param string $companyId 44 | * @return PartyTaxScheme 45 | */ 46 | public function setCompanyId($companyId): PartyTaxScheme 47 | { 48 | $this->companyId = $companyId; 49 | return $this; 50 | } 51 | 52 | /** 53 | * @param TaxScheme $taxScheme. 54 | * @return mixed 55 | */ 56 | public function getTaxScheme(): ?TaxScheme 57 | { 58 | return $this->taxScheme; 59 | } 60 | 61 | /** 62 | * @param TaxScheme $taxScheme 63 | * @return PartyTaxScheme 64 | */ 65 | public function setTaxScheme(TaxScheme $taxScheme): PartyTaxScheme 66 | { 67 | $this->taxScheme = $taxScheme; 68 | return $this; 69 | } 70 | 71 | /** 72 | * The validate function that is called during xml writing to valid the data of the object. 73 | * 74 | * @return void 75 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 76 | */ 77 | public function validate() 78 | { 79 | if ($this->taxScheme === null) { 80 | throw new InvalidArgumentException('Missing TaxScheme'); 81 | } 82 | } 83 | 84 | /** 85 | * The xmlSerialize method is called during xml writing. 86 | * 87 | * @param Writer $writer 88 | * @return void 89 | */ 90 | public function xmlSerialize(Writer $writer): void 91 | { 92 | if ($this->registrationName !== null) { 93 | $writer->write([ 94 | Schema::CBC . 'RegistrationName' => $this->registrationName 95 | ]); 96 | } 97 | if ($this->companyId !== null) { 98 | $writer->write([ 99 | Schema::CBC . 'CompanyID' => $this->companyId 100 | ]); 101 | } 102 | 103 | $writer->write([ 104 | Schema::CAC . 'TaxScheme' => $this->taxScheme 105 | ]); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/PayeeFinancialAccount.php: -------------------------------------------------------------------------------- 1 | id; 21 | } 22 | 23 | /** 24 | * @param string $id 25 | * @return PayeeFinancialAccount 26 | */ 27 | public function setId(?string $id): PayeeFinancialAccount 28 | { 29 | $this->id = $id; 30 | return $this; 31 | } 32 | 33 | /** 34 | * @return string 35 | */ 36 | public function getName(): ?string 37 | { 38 | return $this->name; 39 | } 40 | 41 | /** 42 | * @param string $name 43 | * @return PayeeFinancialAccount 44 | */ 45 | public function setName(?string $name): PayeeFinancialAccount 46 | { 47 | $this->name = $name; 48 | return $this; 49 | } 50 | 51 | /** 52 | * @return FinancialInstitutionBranch 53 | */ 54 | public function getFinancialInstitutionBranch(): ?FinancialInstitutionBranch 55 | { 56 | return $this->financialInstitutionBranch; 57 | } 58 | 59 | /** 60 | * @param FinancialInstitutionBranch $financialInstitutionBranch 61 | * @return PayeeFinancialAccount 62 | */ 63 | public function setFinancialInstitutionBranch(?FinancialInstitutionBranch $financialInstitutionBranch): PayeeFinancialAccount 64 | { 65 | $this->financialInstitutionBranch = $financialInstitutionBranch; 66 | return $this; 67 | } 68 | 69 | public function xmlSerialize(Writer $writer): void 70 | { 71 | $writer->write([ 72 | 'name' => Schema::CBC . 'ID', 73 | 'value' => $this->id, 74 | 'attributes' => [ 75 | //'schemeID' => 'IBAN' 76 | ] 77 | ]); 78 | 79 | if ($this->getName() !== null) { 80 | $writer->write([ 81 | Schema::CBC . 'Name' => $this->getName() 82 | ]); 83 | } 84 | 85 | if ($this->getFinancialInstitutionBranch() !== null) { 86 | $writer->write([ 87 | Schema::CAC . 'FinancialInstitutionBranch' => $this->getFinancialInstitutionBranch() 88 | ]); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/PaymentMeans.php: -------------------------------------------------------------------------------- 1 | 'UN/ECE 4461', 15 | 'listName' => 'Payment Means', 16 | 'listURI' => 'http://docs.oasis-open.org/ubl/os-UBL-2.0-update/cl/gc/default/PaymentMeansCode-2.0.gc']; 17 | private $paymentDueDate; 18 | private $instructionId; 19 | private $instructionNote; 20 | private $paymentId; 21 | private $payeeFinancialAccount; 22 | 23 | /** 24 | * @return string 25 | */ 26 | public function getPaymentMeansCode(): ?string 27 | { 28 | return $this->paymentMeansCode; 29 | } 30 | 31 | /** 32 | * @param string $paymentMeansCode 33 | * @return PaymentMeans 34 | */ 35 | public function setPaymentMeansCode(?string $paymentMeansCode, $attributes = null): PaymentMeans 36 | { 37 | $this->paymentMeansCode = $paymentMeansCode; 38 | if (isset($attributes)) { 39 | $this->paymentMeansCodeAttributes = $attributes; 40 | } 41 | return $this; 42 | } 43 | 44 | /** 45 | * @return DateTime 46 | */ 47 | public function getPaymentDueDate(): ?DateTime 48 | { 49 | return $this->paymentDueDate; 50 | } 51 | 52 | /** 53 | * @param DateTime $paymentDueDate 54 | * @return PaymentMeans 55 | */ 56 | public function setPaymentDueDate(?DateTime $paymentDueDate): PaymentMeans 57 | { 58 | $this->paymentDueDate = $paymentDueDate; 59 | return $this; 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | public function getInstructionId(): ?string 66 | { 67 | return $this->instructionId; 68 | } 69 | 70 | /** 71 | * @param string $instructionId 72 | * @return PaymentMeans 73 | */ 74 | public function setInstructionId(?string $instructionId): PaymentMeans 75 | { 76 | $this->instructionId = $instructionId; 77 | return $this; 78 | } 79 | 80 | /** 81 | * @return string 82 | */ 83 | public function getInstructionNote(): ?string 84 | { 85 | return $this->instructionNote; 86 | } 87 | 88 | /** 89 | * @param string $instructionNote 90 | * @return PaymentMeans 91 | */ 92 | public function setInstructionNote(?string $instructionNote): PaymentMeans 93 | { 94 | $this->instructionNote = $instructionNote; 95 | return $this; 96 | } 97 | 98 | /** 99 | * @return string 100 | */ 101 | public function getPaymentId(): ?string 102 | { 103 | return $this->paymentId; 104 | } 105 | 106 | /** 107 | * @param string $paymentId 108 | * @return PaymentMeans 109 | */ 110 | public function setPaymentId(?string $paymentId): PaymentMeans 111 | { 112 | $this->paymentId = $paymentId; 113 | return $this; 114 | } 115 | 116 | /** 117 | * @return mixed 118 | */ 119 | public function getPayeeFinancialAccount(): ?PayeeFinancialAccount 120 | { 121 | return $this->payeeFinancialAccount; 122 | } 123 | 124 | /** 125 | * @param mixed $payeeFinancialAccount 126 | * @return PaymentMeans 127 | */ 128 | public function setPayeeFinancialAccount(?PayeeFinancialAccount $payeeFinancialAccount): PaymentMeans 129 | { 130 | $this->payeeFinancialAccount = $payeeFinancialAccount; 131 | return $this; 132 | } 133 | 134 | public function xmlSerialize(Writer $writer): void 135 | { 136 | $writer->write([ 137 | 'name' => Schema::CBC . 'PaymentMeansCode', 138 | 'value' => $this->paymentMeansCode, 139 | 'attributes' => $this->paymentMeansCodeAttributes 140 | ]); 141 | 142 | if ($this->getPaymentDueDate() !== null) { 143 | $writer->write([ 144 | Schema::CBC . 'PaymentDueDate' => $this->getPaymentDueDate()->format('Y-m-d') 145 | ]); 146 | } 147 | 148 | if ($this->getInstructionId() !== null) { 149 | $writer->write([ 150 | Schema::CBC . 'InstructionID' => $this->getInstructionId() 151 | ]); 152 | } 153 | 154 | if ($this->getInstructionNote() !== null) { 155 | $writer->write([ 156 | Schema::CBC . 'InstructionNote' => $this->getInstructionNote() 157 | ]); 158 | } 159 | 160 | if ($this->getPaymentId() !== null) { 161 | $writer->write([ 162 | Schema::CBC . 'PaymentID' => $this->getPaymentId() 163 | ]); 164 | } 165 | 166 | if ($this->getPayeeFinancialAccount() !== null) { 167 | $writer->write([ 168 | Schema::CAC . 'PayeeFinancialAccount' => $this->getPayeeFinancialAccount() 169 | ]); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/PaymentTerms.php: -------------------------------------------------------------------------------- 1 | note; 21 | } 22 | 23 | /** 24 | * @param string $note 25 | * @return PaymentTerms 26 | */ 27 | public function setNote(?string $note): PaymentTerms 28 | { 29 | $this->note = $note; 30 | return $this; 31 | } 32 | 33 | /** 34 | * @return float 35 | */ 36 | public function getSettlementDiscountPercent(): ?float 37 | { 38 | return $this->settlementDiscountPercent; 39 | } 40 | 41 | /** 42 | * @param float $settlementDiscountPercent 43 | * @return PaymentTerms 44 | */ 45 | public function setSettlementDiscountPercent(?float $settlementDiscountPercent): PaymentTerms 46 | { 47 | $this->settlementDiscountPercent = $settlementDiscountPercent; 48 | return $this; 49 | } 50 | 51 | /** 52 | * @return float 53 | */ 54 | public function getAmount(): ?float 55 | { 56 | return $this->amount; 57 | } 58 | 59 | /** 60 | * @param float $amount 61 | * @return PaymentTerms 62 | */ 63 | public function setAmount(?float $amount): PaymentTerms 64 | { 65 | $this->amount = $amount; 66 | return $this; 67 | } 68 | 69 | /** 70 | * @return SettlementPeriod 71 | */ 72 | public function getSettlementPeriod(): ?SettlementPeriod 73 | { 74 | return $this->settlementPeriod; 75 | } 76 | 77 | /** 78 | * @param SettlementPeriod $settlementPeriod 79 | * @return PaymentTerms 80 | */ 81 | public function setSettlementPeriod(?SettlementPeriod $settlementPeriod): PaymentTerms 82 | { 83 | $this->settlementPeriod = $settlementPeriod; 84 | return $this; 85 | } 86 | 87 | public function xmlSerialize(Writer $writer): void 88 | { 89 | if ($this->note !== null) { 90 | $writer->write([ Schema::CBC . 'Note' => $this->note ]); 91 | } 92 | 93 | if ($this->settlementDiscountPercent !== null) { 94 | $writer->write([ Schema::CBC . 'SettlementDiscountPercent' => $this->settlementDiscountPercent ]); 95 | } 96 | 97 | if ($this->amount !== null) { 98 | $writer->write([ 99 | [ 100 | 'name' => Schema::CBC . 'Amount', 101 | 'value' => NumberFormatter::format($this->amount, 2), 102 | 'attributes' => [ 103 | 'currencyID' => 'EUR' 104 | ] 105 | ] 106 | ]); 107 | } 108 | 109 | if ($this->settlementPeriod !== null) { 110 | $writer->write([ Schema::CAC . 'SettlementPeriod' => $this->settlementPeriod ]); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/Price.php: -------------------------------------------------------------------------------- 1 | priceAmount; 22 | } 23 | 24 | /** 25 | * @param float $priceAmount 26 | * @return Price 27 | */ 28 | public function setPriceAmount(?float $priceAmount): Price 29 | { 30 | $this->priceAmount = $priceAmount; 31 | return $this; 32 | } 33 | 34 | /** 35 | * @return float 36 | */ 37 | public function getBaseQuantity(): ?float 38 | { 39 | return $this->baseQuantity; 40 | } 41 | 42 | /** 43 | * @param float $baseQuantity 44 | * @return Price 45 | */ 46 | public function setBaseQuantity(?float $baseQuantity): Price 47 | { 48 | $this->baseQuantity = $baseQuantity; 49 | return $this; 50 | } 51 | 52 | /** 53 | * @return string 54 | */ 55 | public function getUnitCode(): ?string 56 | { 57 | return $this->unitCode; 58 | } 59 | 60 | /** 61 | * @param string $unitCode 62 | * See also: src/UnitCode.php 63 | * @return Price 64 | */ 65 | public function setUnitCode(?string $unitCode): Price 66 | { 67 | $this->unitCode = $unitCode; 68 | return $this; 69 | } 70 | 71 | 72 | /** 73 | * @return string 74 | */ 75 | public function getUnitCodeListId(): ?string 76 | { 77 | return $this->unitCodeListId; 78 | } 79 | 80 | /** 81 | * @param string $unitCodeListId 82 | * @return Price 83 | */ 84 | public function setUnitCodeListId(?string $unitCodeListId): Price 85 | { 86 | $this->unitCodeListId = $unitCodeListId; 87 | return $this; 88 | } 89 | 90 | /** 91 | * @return AllowanceCharge 92 | */ 93 | public function getAllowanceCharge(): ?AllowanceCharge 94 | { 95 | return $this->allowanceCharge; 96 | } 97 | 98 | /** 99 | * @param AllowanceCharge $allowanceCharge 100 | * @return Price 101 | */ 102 | public function setAllowanceCharge(?AllowanceCharge $allowanceCharge): Price 103 | { 104 | $this->allowanceCharge = $allowanceCharge; 105 | return $this; 106 | } 107 | 108 | /** 109 | * The xmlSerialize method is called during xml writing. 110 | * 111 | * @param Writer $writer 112 | * @return void 113 | */ 114 | public function xmlSerialize(Writer $writer): void 115 | { 116 | $baseQuantityAttributes = [ 117 | 'unitCode' => $this->unitCode, 118 | ]; 119 | 120 | if (!empty($this->getUnitCodeListId())) { 121 | $baseQuantityAttributes['unitCodeListID'] = $this->getUnitCodeListId(); 122 | } 123 | 124 | $writer->write([ 125 | [ 126 | 'name' => Schema::CBC . 'PriceAmount', 127 | 'value' => NumberFormatter::format($this->priceAmount), 128 | 'attributes' => [ 129 | 'currencyID' => Generator::$currencyID 130 | ] 131 | ], 132 | [ 133 | 'name' => Schema::CBC . 'BaseQuantity', 134 | 'value' => NumberFormatter::format($this->baseQuantity), 135 | 'attributes' => $baseQuantityAttributes 136 | ] 137 | ]); 138 | 139 | if ($this->allowanceCharge !== null) { 140 | $writer->write([ 141 | Schema::CAC . 'AllowanceCharge' => $this->allowanceCharge, 142 | ]); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/ProjectReference.php: -------------------------------------------------------------------------------- 1 | id; 19 | } 20 | 21 | /** 22 | * @param string $id 23 | * @return ProjectReference 24 | */ 25 | public function setId(string $id): ProjectReference 26 | { 27 | $this->id = $id; 28 | return $this; 29 | } 30 | 31 | /** 32 | * The xmlSerialize method is called during xml writing. 33 | * 34 | * @param Writer $writer 35 | * @return void 36 | */ 37 | public function xmlSerialize(Writer $writer): void 38 | { 39 | if ($this->id !== null) { 40 | $writer->write([Schema::CBC . 'ID' => $this->id]); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Schema.php: -------------------------------------------------------------------------------- 1 | startDate; 22 | } 23 | 24 | /** 25 | * @param DateTime $startDate 26 | * @return SettlementPeriod 27 | */ 28 | public function setStartDate(DateTime $startDate): SettlementPeriod 29 | { 30 | $this->startDate = $startDate; 31 | return $this; 32 | } 33 | 34 | /** 35 | * @return DateTime 36 | */ 37 | public function getEndDate(): ?DateTime 38 | { 39 | return $this->endDate; 40 | } 41 | 42 | /** 43 | * @param DateTime $endDate 44 | * @return SettlementPeriod 45 | */ 46 | public function setEndDate(DateTime $endDate): SettlementPeriod 47 | { 48 | $this->endDate = $endDate; 49 | return $this; 50 | } 51 | 52 | /** 53 | * The validate function that is called during xml writing to valid the data of the object. 54 | * 55 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 56 | * @return void 57 | */ 58 | public function validate() 59 | { 60 | if ($this->startDate === null) { 61 | throw new InvalidArgumentException('Missing startDate'); 62 | } 63 | if ($this->endDate === null) { 64 | throw new InvalidArgumentException('Missing endDate'); 65 | } 66 | } 67 | 68 | /** 69 | * The xmlSerialize method is called during xml writing. 70 | * 71 | * @param Writer $writer 72 | * @return void 73 | */ 74 | public function xmlSerialize(Writer $writer): void 75 | { 76 | $this->validate(); 77 | 78 | $writer->write([ 79 | Schema::CBC . 'StartDate' => $this->startDate->format('Y-m-d'), 80 | Schema::CBC . 'EndDate' => $this->endDate->format('Y-m-d'), 81 | ]); 82 | 83 | $writer->write([ 84 | [ 85 | 'name' => Schema::CBC . 'DurationMeasure', 86 | 'value' => $this->endDate->diff($this->startDate)->format('%d'), 87 | 'attributes' => [ 88 | 'unitCode' => 'DAY' 89 | ] 90 | ] 91 | ]); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/TaxCategory.php: -------------------------------------------------------------------------------- 1 | UNCL5305::UNCL5305, 15 | 'schemeName' => 'Duty or tax or fee category' 16 | ]; 17 | private $name; 18 | private $percent; 19 | private $taxScheme; 20 | private $taxExemptionReason; 21 | private $taxExemptionReasonCode; 22 | 23 | /** 24 | * @return string 25 | */ 26 | public function getId(): ?string 27 | { 28 | if (!empty($this->id)) { 29 | return $this->id; 30 | } 31 | 32 | // Default behaviour, overrrule by using setId() 33 | if ($this->getPercent() !== null) { 34 | return ($this->getPercent() > 0) 35 | ? UNCL5305::STANDARD_RATE 36 | : UNCL5305::ZERO_RATED_GOODS; 37 | } 38 | 39 | return null; 40 | } 41 | 42 | /** 43 | * @param string $id 44 | * @param array $attributes 45 | * @return TaxCategory 46 | */ 47 | public function setId(?string $id, $attributes = null): TaxCategory 48 | { 49 | $this->id = $id; 50 | if (isset($attributes)) { 51 | $this->idAttributes = $attributes; 52 | } 53 | return $this; 54 | } 55 | 56 | /** 57 | * @return string 58 | */ 59 | public function getName(): ?string 60 | { 61 | return $this->name; 62 | } 63 | 64 | /** 65 | * @param string $name 66 | * @return TaxCategory 67 | */ 68 | public function setName(?string $name): TaxCategory 69 | { 70 | $this->name = $name; 71 | return $this; 72 | } 73 | 74 | /** 75 | * @return string 76 | */ 77 | public function getPercent(): ?float 78 | { 79 | return $this->percent; 80 | } 81 | 82 | /** 83 | * @param string $percent 84 | * @return TaxCategory 85 | */ 86 | public function setPercent(?float $percent): TaxCategory 87 | { 88 | $this->percent = $percent; 89 | return $this; 90 | } 91 | 92 | /** 93 | * @return string 94 | */ 95 | public function getTaxScheme(): ?TaxScheme 96 | { 97 | return $this->taxScheme; 98 | } 99 | 100 | /** 101 | * @param TaxScheme $taxScheme 102 | * @return TaxCategory 103 | */ 104 | public function setTaxScheme(?TaxScheme $taxScheme): TaxCategory 105 | { 106 | $this->taxScheme = $taxScheme; 107 | return $this; 108 | } 109 | 110 | /** 111 | * @return string 112 | */ 113 | public function getTaxExemptionReason(): ?string 114 | { 115 | return $this->taxExemptionReason; 116 | } 117 | 118 | /** 119 | * @param string $taxExemptionReason 120 | * @return TaxCategory 121 | */ 122 | public function setTaxExemptionReason(?string $taxExemptionReason): TaxCategory 123 | { 124 | $this->taxExemptionReason = $taxExemptionReason; 125 | return $this; 126 | } 127 | 128 | /** 129 | * @return string 130 | */ 131 | public function getTaxExemptionReasonCode(): ?string 132 | { 133 | return $this->taxExemptionReasonCode; 134 | } 135 | 136 | /** 137 | * @param string $taxExemptionReason 138 | * @return TaxCategory 139 | */ 140 | public function setTaxExemptionReasonCode(?string $taxExemptionReasonCode): TaxCategory 141 | { 142 | $this->taxExemptionReasonCode = $taxExemptionReasonCode; 143 | return $this; 144 | } 145 | 146 | /** 147 | * The validate function that is called during xml writing to valid the data of the object. 148 | * 149 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 150 | * @return void 151 | */ 152 | public function validate() 153 | { 154 | if ($this->getId() === null) { 155 | throw new InvalidArgumentException('Missing taxcategory id'); 156 | } 157 | 158 | if ($this->getPercent() === null) { 159 | throw new InvalidArgumentException('Missing taxcategory percent'); 160 | } 161 | } 162 | 163 | /** 164 | * The xmlSerialize method is called during xml writing. 165 | * 166 | * @param Writer $writer 167 | * @return void 168 | */ 169 | public function xmlSerialize(Writer $writer): void 170 | { 171 | $this->validate(); 172 | 173 | $writer->write([ 174 | [ 175 | 'name' => Schema::CBC . 'ID', 176 | 'value' => $this->getId(), 177 | 'attributes' => $this->idAttributes, 178 | ], 179 | ]); 180 | 181 | if ($this->name !== null) { 182 | $writer->write([ 183 | Schema::CBC . 'Name' => $this->name, 184 | ]); 185 | } 186 | $writer->write([ 187 | Schema::CBC . 'Percent' => NumberFormatter::format($this->percent, 2), 188 | ]); 189 | 190 | if ($this->taxExemptionReasonCode !== null) { 191 | $writer->write([ 192 | Schema::CBC . 'TaxExemptionReasonCode' => $this->taxExemptionReasonCode, 193 | ]); 194 | } 195 | 196 | if ($this->taxExemptionReason !== null) { 197 | $writer->write([ 198 | Schema::CBC . 'TaxExemptionReason' => $this->taxExemptionReason, 199 | ]); 200 | } 201 | 202 | if ($this->taxScheme !== null) { 203 | $writer->write([Schema::CAC . 'TaxScheme' => $this->taxScheme]); 204 | } else { 205 | $writer->write([ 206 | Schema::CAC . 'TaxScheme' => null, 207 | ]); 208 | } 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/TaxScheme.php: -------------------------------------------------------------------------------- 1 | id; 21 | } 22 | 23 | /** 24 | * @param string $id 25 | * @return TaxScheme 26 | */ 27 | public function setId(string $id): TaxScheme 28 | { 29 | $this->id = $id; 30 | return $this; 31 | } 32 | 33 | /** 34 | * @return string 35 | */ 36 | public function getName(): ?string 37 | { 38 | return $this->name; 39 | } 40 | 41 | /** 42 | * @param string $name 43 | * @return TaxScheme 44 | */ 45 | public function setName(?string $name) 46 | { 47 | $this->name = $name; 48 | return $this; 49 | } 50 | 51 | /** 52 | * @return string 53 | */ 54 | public function getTaxTypeCode(): ?string 55 | { 56 | return $this->taxTypeCode; 57 | } 58 | 59 | /** 60 | * @param string $taxTypeCode 61 | * @return TaxScheme 62 | */ 63 | public function setTaxTypeCode(?string $taxTypeCode) 64 | { 65 | $this->taxTypeCode = $taxTypeCode; 66 | return $this; 67 | } 68 | 69 | /** 70 | * @return string 71 | */ 72 | public function getCurrencyCode(): ?string 73 | { 74 | return $this->currencyCode; 75 | } 76 | 77 | /** 78 | * @param string $currencyCode 79 | * @return TaxScheme 80 | */ 81 | public function setCurrencyCode(?string $currencyCode) 82 | { 83 | $this->currencyCode = $currencyCode; 84 | return $this; 85 | } 86 | 87 | /** 88 | * The xmlSerialize method is called during xml writing. 89 | * 90 | * @param Writer $writer 91 | * @return void 92 | */ 93 | public function xmlSerialize(Writer $writer): void 94 | { 95 | $writer->write([ 96 | Schema::CBC . 'ID' => $this->id 97 | ]); 98 | if ($this->name !== null) { 99 | $writer->write([ 100 | Schema::CBC . 'Name' => $this->name 101 | ]); 102 | } 103 | if ($this->taxTypeCode !== null) { 104 | $writer->write([ 105 | Schema::CBC . 'TaxTypeCode' => $this->taxTypeCode 106 | ]); 107 | } 108 | if ($this->currencyCode !== null) { 109 | $writer->write([ 110 | Schema::CBC . 'CurrencyCode' => $this->currencyCode 111 | ]); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/TaxSubTotal.php: -------------------------------------------------------------------------------- 1 | taxableAmount; 23 | } 24 | 25 | /** 26 | * @param mixed $taxableAmount 27 | * @return TaxSubTotal 28 | */ 29 | public function setTaxableAmount(?float $taxableAmount): TaxSubTotal 30 | { 31 | $this->taxableAmount = $taxableAmount; 32 | return $this; 33 | } 34 | 35 | /** 36 | * @return mixed 37 | */ 38 | public function getTaxAmount(): ?float 39 | { 40 | return $this->taxAmount; 41 | } 42 | 43 | /** 44 | * @param mixed $taxAmount 45 | * @return TaxSubTotal 46 | */ 47 | public function setTaxAmount(?float $taxAmount): TaxSubTotal 48 | { 49 | $this->taxAmount = $taxAmount; 50 | return $this; 51 | } 52 | 53 | /** 54 | * @return TaxCategory 55 | */ 56 | public function getTaxCategory(): ?TaxCategory 57 | { 58 | return $this->taxCategory; 59 | } 60 | 61 | /** 62 | * @param TaxCategory $taxCategory 63 | * @return TaxSubTotal 64 | */ 65 | public function setTaxCategory(TaxCategory $taxCategory): TaxSubTotal 66 | { 67 | $this->taxCategory = $taxCategory; 68 | return $this; 69 | } 70 | 71 | /** 72 | * @return float 73 | */ 74 | public function getPercent(): ?float 75 | { 76 | return $this->percent; 77 | } 78 | 79 | /** 80 | * @param float $percent 81 | * @return TaxSubTotal 82 | */ 83 | public function setPercent(?float $percent): TaxSubTotal 84 | { 85 | $this->percent = $percent; 86 | return $this; 87 | } 88 | 89 | /** 90 | * The validate function that is called during xml writing to valid the data of the object. 91 | * 92 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 93 | * @return void 94 | */ 95 | public function validate() 96 | { 97 | if ($this->taxableAmount === null) { 98 | throw new InvalidArgumentException('Missing taxsubtotal taxableAmount'); 99 | } 100 | 101 | if ($this->taxAmount === null) { 102 | throw new InvalidArgumentException('Missing taxsubtotal taxamount'); 103 | } 104 | 105 | if ($this->taxCategory === null) { 106 | throw new InvalidArgumentException('Missing taxsubtotal taxcategory'); 107 | } 108 | } 109 | 110 | /** 111 | * The xmlSerialize method is called during xml writing. 112 | * @param Writer $writer 113 | * @return void 114 | */ 115 | public function xmlSerialize(Writer $writer): void 116 | { 117 | $this->validate(); 118 | 119 | $writer->write([ 120 | [ 121 | 'name' => Schema::CBC . 'TaxableAmount', 122 | 'value' => NumberFormatter::format($this->taxableAmount, 2), 123 | 'attributes' => [ 124 | 'currencyID' => Generator::$currencyID 125 | ] 126 | ], 127 | [ 128 | 'name' => Schema::CBC . 'TaxAmount', 129 | 'value' => NumberFormatter::format($this->taxAmount, 2), 130 | 'attributes' => [ 131 | 'currencyID' => Generator::$currencyID 132 | ] 133 | ] 134 | ]); 135 | 136 | if ($this->percent !== null) { 137 | $writer->write([ 138 | Schema::CBC . 'Percent' => $this->percent 139 | ]); 140 | } 141 | 142 | $writer->write([ 143 | Schema::CAC . 'TaxCategory' => $this->taxCategory 144 | ]); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/TaxTotal.php: -------------------------------------------------------------------------------- 1 | taxAmount; 21 | } 22 | 23 | /** 24 | * @param mixed $taxAmount 25 | * @return TaxTotal 26 | */ 27 | public function setTaxAmount(?float $taxAmount): TaxTotal 28 | { 29 | $this->taxAmount = $taxAmount; 30 | return $this; 31 | } 32 | 33 | /** 34 | * @return array 35 | */ 36 | public function getTaxSubTotals(): array 37 | { 38 | return $this->taxSubTotals; 39 | } 40 | 41 | /** 42 | * @param TaxSubTotal $taxSubTotal 43 | * @return TaxTotal 44 | */ 45 | public function addTaxSubTotal(TaxSubTotal $taxSubTotal): TaxTotal 46 | { 47 | $this->taxSubTotals[] = $taxSubTotal; 48 | return $this; 49 | } 50 | 51 | /** 52 | * The validate function that is called during xml writing to valid the data of the object. 53 | * 54 | * @throws InvalidArgumentException An error with information about required data that is missing to write the XML 55 | * @return void 56 | */ 57 | public function validate() 58 | { 59 | if ($this->taxAmount === null) { 60 | throw new InvalidArgumentException('Missing taxtotal taxamount'); 61 | } 62 | } 63 | 64 | /** 65 | * The xmlSerialize method is called during xml writing. 66 | * @param Writer $writer 67 | * @return void 68 | */ 69 | public function xmlSerialize(Writer $writer): void 70 | { 71 | $this->validate(); 72 | 73 | $writer->write([ 74 | [ 75 | 'name' => Schema::CBC . 'TaxAmount', 76 | 'value' => NumberFormatter::format($this->taxAmount, 2), 77 | 'attributes' => [ 78 | 'currencyID' => Generator::$currencyID 79 | ] 80 | ], 81 | ]); 82 | 83 | foreach ($this->taxSubTotals as $taxSubTotal) { 84 | $writer->write([Schema::CAC . 'TaxSubtotal' => $taxSubTotal]); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/UNCL4461.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address); 34 | 35 | // Client company node 36 | $clientCompany = (new \NumNum\UBL\Party()) 37 | ->setName('My client') 38 | ->setPostalAddress($address); 39 | 40 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 41 | ->setPayableAmount(10 + 2) 42 | ->setAllowanceTotalAmount(0); 43 | 44 | // Tax scheme 45 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 46 | ->setId(0); 47 | 48 | // Product 49 | $productItem = (new \NumNum\UBL\Item()) 50 | ->setName('Product Name') 51 | ->setDescription('Product Description') 52 | ->setSellersItemIdentification('SELLERID') 53 | ->setBuyersItemIdentification('BUYERID'); 54 | 55 | // Price 56 | $price = (new \NumNum\UBL\Price()) 57 | ->setBaseQuantity(1) 58 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 59 | ->setPriceAmount(10); 60 | 61 | // Invoice Line tax totals 62 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 63 | ->setTaxAmount(2.1); 64 | 65 | // Invoice Line(s) 66 | $creditNoteLine = (new \NumNum\UBL\CreditNoteLine()) 67 | ->setId(0) 68 | ->setItem($productItem) 69 | ->setPrice($price) 70 | ->setTaxTotal($lineTaxTotal) 71 | ->setInvoicedQuantity(1); 72 | 73 | $creditNoteLines = [$creditNoteLine]; 74 | 75 | // Total Taxes 76 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 77 | ->setId(0) 78 | ->setName('VAT21%') 79 | ->setPercent(.21) 80 | ->setTaxScheme($taxScheme); 81 | 82 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 83 | ->setTaxableAmount(10) 84 | ->setTaxAmount(2.1) 85 | ->setTaxCategory($taxCategory); 86 | 87 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 88 | ->addTaxSubTotal($taxSubTotal) 89 | ->setTaxAmount(2.1); 90 | 91 | $billingReference = (new \NumNum\UBL\BillingReference()) 92 | ->setInvoiceDocumentReference((new \NumNum\UBL\InvoiceDocumentReference()) 93 | ->setOriginalInvoiceId(1234) 94 | ->setIssueDate(new \DateTime())); 95 | 96 | 97 | // Invoice object 98 | $creditNote = (new \NumNum\UBL\CreditNote()) 99 | ->setId(1234) 100 | ->setCopyIndicator(false) 101 | ->setIssueDate(new \DateTime()) 102 | ->setAccountingSupplierParty($supplierCompany) 103 | ->setAccountingCustomerParty($clientCompany) 104 | ->setBillingReference($billingReference) 105 | ->setCreditNoteLines($creditNoteLines) 106 | ->setLegalMonetaryTotal($legalMonetaryTotal) 107 | ->setTaxTotal($taxTotal) 108 | ->setInvoiceTypeCode(\NumNum\UBL\InvoiceTypeCode::CREDIT_NOTE); 109 | 110 | // Test created object 111 | // Use \NumNum\UBL\Generator to generate an XML string 112 | $generator = new \NumNum\UBL\Generator(); 113 | $outputXMLString = $generator->creditNote($creditNote); 114 | 115 | // Create PHP Native DomDocument object, that can be 116 | // used to validate the generate XML 117 | $dom = new \DOMDocument; 118 | $dom->loadXML($outputXMLString); 119 | 120 | $dom->save('./tests/SimpleCreditNoteTest.xml'); 121 | 122 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /tests/ContractDocumentReferenceTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 21 | 22 | // Full address 23 | $address = (new \NumNum\UBL\Address()) 24 | ->setStreetName('Korenmarkt') 25 | ->setBuildingNumber(1) 26 | ->setCityName('Gent') 27 | ->setPostalZone('9000') 28 | ->setCountry($country); 29 | 30 | // Supplier company node 31 | $supplierCompany = (new \NumNum\UBL\Party()) 32 | ->setName('Supplier Company Name') 33 | ->setPhysicalLocation($address) 34 | ->setPostalAddress($address); 35 | 36 | // Client company node 37 | $clientCompany = (new \NumNum\UBL\Party()) 38 | ->setName('My client') 39 | ->setPostalAddress($address); 40 | 41 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 42 | ->setPayableAmount(10 + 2) 43 | ->setAllowanceTotalAmount(0); 44 | 45 | // Tax scheme 46 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 47 | ->setId(0); 48 | 49 | // Product 50 | $productItem = (new \NumNum\UBL\Item()) 51 | ->setName('Product Name') 52 | ->setDescription('Product Description'); 53 | 54 | // Price 55 | $price = (new \NumNum\UBL\Price()) 56 | ->setBaseQuantity(1) 57 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 58 | ->setPriceAmount(10); 59 | 60 | // Invoice Line tax totals 61 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 62 | ->setTaxAmount(2.1); 63 | 64 | // Invoice Line(s) 65 | $invoiceLine = (new \NumNum\UBL\InvoiceLine()) 66 | ->setId(0) 67 | ->setItem($productItem) 68 | ->setPrice($price) 69 | ->setTaxTotal($lineTaxTotal) 70 | ->setInvoicedQuantity(1); 71 | 72 | $invoiceLines = [$invoiceLine]; 73 | 74 | // Total Taxes 75 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 76 | ->setId(0) 77 | ->setName('VAT21%') 78 | ->setPercent(.21) 79 | ->setTaxScheme($taxScheme); 80 | 81 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 82 | ->setTaxableAmount(10) 83 | ->setTaxAmount(2.1) 84 | ->setTaxCategory($taxCategory); 85 | 86 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 87 | ->addTaxSubTotal($taxSubTotal) 88 | ->setTaxAmount(2.1); 89 | 90 | $contractDocumentReference = (new \NumNum\UBL\ContractDocumentReference()) 91 | ->setId("123Test"); 92 | 93 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 94 | ->setStartDate(new \DateTime('-31 days')) 95 | ->setEndDate(new \DateTime()); 96 | 97 | // Invoice object 98 | $invoice = (new \NumNum\UBL\Invoice()) 99 | ->setUBLVersionID('2.2') 100 | ->setId(1234) 101 | ->setCopyIndicator(false) 102 | ->setIssueDate(new \DateTime()) 103 | ->setInvoiceTypeCode(\NumNum\UBL\InvoiceTypeCode::INVOICE) 104 | ->setDueDate(new \DateTime()) 105 | ->setAccountingSupplierParty($supplierCompany) 106 | ->setAccountingCustomerParty($clientCompany) 107 | ->setInvoiceLines($invoiceLines) 108 | ->setLegalMonetaryTotal($legalMonetaryTotal) 109 | ->setTaxTotal($taxTotal) 110 | ->setContractDocumentReference($contractDocumentReference) 111 | ->setBuyerReference("SomeReference") 112 | ->setInvoicePeriod($invoicePeriod); 113 | 114 | // Test created object 115 | // Use \NumNum\UBL\Generator to generate an XML string 116 | $generator = new \NumNum\UBL\Generator(); 117 | $outputXMLString = $generator->invoice($invoice); 118 | 119 | // Create PHP Native DomDocument object, that can be 120 | // used to validate the generate XML 121 | $dom = new \DOMDocument; 122 | $dom->loadXML($outputXMLString); 123 | 124 | $dom->save('./tests/ContractDocumentReferenceTest.xml'); 125 | 126 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /tests/DocumentTypeTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address); 34 | 35 | // Client contact node 36 | $clientContact = (new \NumNum\UBL\Contact()) 37 | ->setName('Client name') 38 | ->setElectronicMail('email@client.com') 39 | ->setTelephone('0032 472 123 456') 40 | ->setTelefax('0032 9 1234 567'); 41 | 42 | // Client company node 43 | $clientCompany = (new \NumNum\UBL\Party()) 44 | ->setName('My client') 45 | ->setPostalAddress($address) 46 | ->setContact($clientContact); 47 | 48 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 49 | ->setPayableAmount(10 + 2) 50 | ->setAllowanceTotalAmount(0); 51 | 52 | // Tax scheme 53 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 54 | ->setId(0); 55 | 56 | // Product 57 | $productItem = (new \NumNum\UBL\Item()) 58 | ->setName('Product Name') 59 | ->setDescription('Product Description') 60 | ->setSellersItemIdentification('SELLERID'); 61 | 62 | // Price 63 | $price = (new \NumNum\UBL\Price()) 64 | ->setBaseQuantity(1) 65 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 66 | ->setPriceAmount(10); 67 | 68 | // Invoice Line tax totals 69 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 70 | ->setTaxAmount(2.1); 71 | 72 | // InvoicePeriod 73 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 74 | ->setStartDate(new \DateTime()); 75 | 76 | // Invoice Line(s) 77 | $invoiceLines = []; 78 | 79 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 80 | ->setId(0) 81 | ->setItem($productItem) 82 | ->setInvoicePeriod($invoicePeriod) 83 | ->setPrice($price) 84 | ->setTaxTotal($lineTaxTotal) 85 | ->setInvoicedQuantity(1); 86 | 87 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 88 | ->setId(0) 89 | ->setItem($productItem) 90 | ->setInvoicePeriod($invoicePeriod) 91 | ->setPrice($price) 92 | ->setAccountingCost('Product 123') 93 | ->setTaxTotal($lineTaxTotal) 94 | ->setInvoicedQuantity(1); 95 | 96 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 97 | ->setId(0) 98 | ->setItem($productItem) 99 | ->setInvoicePeriod($invoicePeriod) 100 | ->setPrice($price) 101 | ->setAccountingCostCode('Product 123') 102 | ->setTaxTotal($lineTaxTotal) 103 | ->setInvoicedQuantity(1); 104 | 105 | 106 | // Total Taxes 107 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 108 | ->setId(0) 109 | ->setName('VAT21%') 110 | ->setPercent(.21) 111 | ->setTaxScheme($taxScheme); 112 | 113 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 114 | ->setTaxableAmount(10) 115 | ->setTaxAmount(2.1) 116 | ->setTaxCategory($taxCategory); 117 | 118 | 119 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 120 | ->addTaxSubTotal($taxSubTotal) 121 | ->setTaxAmount(2.1); 122 | 123 | // Attachment 124 | $attachment = (new \NumNum\UBL\Attachment()) 125 | ->setFilePath(__DIR__.DIRECTORY_SEPARATOR.'SampleInvoice.pdf'); 126 | 127 | $additionalDocumentReference = new \NumNum\UBL\AdditionalDocumentReference(); 128 | $additionalDocumentReference->setId('SomeID'); 129 | $additionalDocumentReference->setDocumentType("CommercialInvoice"); 130 | 131 | // Invoice object 132 | $invoice = (new \NumNum\UBL\Invoice()) 133 | ->setId(1234) 134 | ->setCopyIndicator(false) 135 | ->setIssueDate(new \DateTime()) 136 | ->setAccountingSupplierParty($supplierCompany) 137 | ->setAccountingCustomerParty($clientCompany) 138 | ->setSupplierAssignedAccountID('10001') 139 | ->setInvoiceLines($invoiceLines) 140 | ->setLegalMonetaryTotal($legalMonetaryTotal) 141 | ->setTaxTotal($taxTotal) 142 | ->setAdditionalDocumentReference($additionalDocumentReference); 143 | 144 | // Test created object 145 | // Use \NumNum\UBL\Generator to generate an XML string 146 | $generator = new \NumNum\UBL\Generator(); 147 | $outputXMLString = $generator->invoice($invoice); 148 | 149 | // Create PHP Native DomDocument object, that can be 150 | // used to validate the generate XML 151 | $dom = new \DOMDocument; 152 | $dom->loadXML($outputXMLString); 153 | 154 | $dom->save('./tests/EmptyAttachmentTest.xml'); 155 | 156 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /tests/DueDateTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 21 | 22 | // Full address 23 | $address = (new \NumNum\UBL\Address()) 24 | ->setStreetName('Korenmarkt') 25 | ->setBuildingNumber(1) 26 | ->setCityName('Gent') 27 | ->setPostalZone('9000') 28 | ->setCountry($country); 29 | 30 | // Supplier company node 31 | $supplierCompany = (new \NumNum\UBL\Party()) 32 | ->setName('Supplier Company Name') 33 | ->setPhysicalLocation($address) 34 | ->setPostalAddress($address); 35 | 36 | // Client company node 37 | $clientCompany = (new \NumNum\UBL\Party()) 38 | ->setName('My client') 39 | ->setPostalAddress($address); 40 | 41 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 42 | ->setPayableAmount(10 + 2) 43 | ->setAllowanceTotalAmount(0); 44 | 45 | // Tax scheme 46 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 47 | ->setId(0); 48 | 49 | // Product 50 | $productItem = (new \NumNum\UBL\Item()) 51 | ->setName('Product Name') 52 | ->setDescription('Product Description'); 53 | 54 | // Price 55 | $price = (new \NumNum\UBL\Price()) 56 | ->setBaseQuantity(1) 57 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 58 | ->setPriceAmount(10); 59 | 60 | // Invoice Line tax totals 61 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 62 | ->setTaxAmount(2.1); 63 | 64 | // Invoice Line(s) 65 | $invoiceLine = (new \NumNum\UBL\InvoiceLine()) 66 | ->setId(0) 67 | ->setItem($productItem) 68 | ->setPrice($price) 69 | ->setTaxTotal($lineTaxTotal) 70 | ->setInvoicedQuantity(1); 71 | 72 | $invoiceLines = [$invoiceLine]; 73 | 74 | // Total Taxes 75 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 76 | ->setId(0) 77 | ->setName('VAT21%') 78 | ->setPercent(.21) 79 | ->setTaxScheme($taxScheme); 80 | 81 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 82 | ->setTaxableAmount(10) 83 | ->setTaxAmount(2.1) 84 | ->setTaxCategory($taxCategory); 85 | 86 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 87 | ->addTaxSubTotal($taxSubTotal) 88 | ->setTaxAmount(2.1); 89 | 90 | // Invoice object 91 | $invoice = (new \NumNum\UBL\Invoice()) 92 | ->setUBLVersionID('2.2') 93 | ->setId(1234) 94 | ->setCopyIndicator(false) 95 | ->setIssueDate(new \DateTime()) 96 | ->setInvoiceTypeCode(\NumNum\UBL\InvoiceTypeCode::INVOICE) 97 | ->setDueDate(new \DateTime()) 98 | ->setAccountingSupplierParty($supplierCompany) 99 | ->setAccountingCustomerParty($clientCompany) 100 | ->setInvoiceLines($invoiceLines) 101 | ->setLegalMonetaryTotal($legalMonetaryTotal) 102 | ->setTaxTotal($taxTotal); 103 | 104 | // Test created object 105 | // Use \NumNum\UBL\Generator to generate an XML string 106 | $generator = new \NumNum\UBL\Generator(); 107 | $outputXMLString = $generator->invoice($invoice); 108 | 109 | // Create PHP Native DomDocument object, that can be 110 | // used to validate the generate XML 111 | $dom = new \DOMDocument; 112 | $dom->loadXML($outputXMLString); 113 | 114 | $dom->save('./tests/DueDateTest.xml'); 115 | 116 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /tests/EN16931Test.php: -------------------------------------------------------------------------------- 1 | setId('VAT'); 22 | 23 | // Address country 24 | $country = (new \NumNum\UBL\Country()) 25 | ->setIdentificationCode('BE'); 26 | 27 | // Full address 28 | $address = (new \NumNum\UBL\Address()) 29 | ->setStreetName('Korenmarkt 1') 30 | ->setAdditionalStreetName('Building A') 31 | ->setCityName('Gent') 32 | ->setPostalZone('9000') 33 | ->setCountry($country); 34 | 35 | $financialInstitutionBranch = (new \NumNum\UBL\FinancialInstitutionBranch()) 36 | ->setId('RABONL2U'); 37 | 38 | $payeeFinancialAccount = (new \NumNum\UBL\PayeeFinancialAccount()) 39 | ->setFinancialInstitutionBranch($financialInstitutionBranch) 40 | ->setName('Customer Account Holder') 41 | ->setId('NL00RABO0000000000'); 42 | 43 | $paymentMeans = (new \NumNum\UBL\PaymentMeans()) 44 | ->setPayeeFinancialAccount($payeeFinancialAccount) 45 | ->setPaymentMeansCode(UNCL4461::DEBIT_TRANSFER, []) 46 | ->setPaymentId('our invoice 1234'); 47 | 48 | // Supplier company node 49 | $supplierLegalEntity = (new \NumNum\UBL\LegalEntity()) 50 | ->setRegistrationName('Supplier Company Name') 51 | ->setCompanyId('BE123456789'); 52 | 53 | $supplierPartyTaxScheme = (new \NumNum\UBL\PartyTaxScheme()) 54 | ->setTaxScheme($taxScheme) 55 | ->setCompanyId('BE123456789'); 56 | 57 | $supplierCompany = (new \NumNum\UBL\Party()) 58 | ->setName('Supplier Company Name') 59 | ->setLegalEntity($supplierLegalEntity) 60 | ->setPartyTaxScheme($supplierPartyTaxScheme) 61 | ->setPartyIdentificationId('BE123456789') 62 | ->setPostalAddress($address); 63 | 64 | // Client company node 65 | $clientLegalEntity = (new \NumNum\UBL\LegalEntity()) 66 | ->setRegistrationName('Client Company Name') 67 | ->setCompanyId('Client Company Registration'); 68 | 69 | $clientPartyTaxScheme = (new \NumNum\UBL\PartyTaxScheme()) 70 | ->setTaxScheme($taxScheme) 71 | ->setCompanyId('BE123456789'); 72 | 73 | $clientCompany = (new \NumNum\UBL\Party()) 74 | ->setName('Client Company Name') 75 | ->setLegalEntity($clientLegalEntity) 76 | ->setPartyTaxScheme($clientPartyTaxScheme) 77 | ->setPartyIdentificationId('BE123456789') 78 | ->setPostalAddress($address); 79 | 80 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 81 | ->setPayableAmount(10 + 2.1) 82 | ->setPayableRoundingAmount(0) 83 | ->setTaxInclusiveAmount(10 + 2.1) 84 | ->setLineExtensionAmount(10) 85 | ->setTaxExclusiveAmount(10); 86 | 87 | $classifiedTaxCategory = (new \NumNum\UBL\ClassifiedTaxCategory()) 88 | ->setId('S') 89 | ->setPercent(21.00) 90 | ->setTaxScheme($taxScheme); 91 | 92 | // Product 93 | $productItem = (new \NumNum\UBL\Item()) 94 | ->setName('Product Name') 95 | ->setClassifiedTaxCategory($classifiedTaxCategory) 96 | ->setDescription('Product Description'); 97 | 98 | // Price 99 | $price = (new \NumNum\UBL\Price()) 100 | ->setBaseQuantity(1) 101 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 102 | ->setPriceAmount(10); 103 | 104 | // Invoice Line tax totals 105 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 106 | ->setTaxAmount(2.1); 107 | 108 | // InvoicePeriod 109 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 110 | ->setStartDate(new \DateTime()); 111 | 112 | // Invoice Line(s) 113 | $invoiceLine = (new \NumNum\UBL\InvoiceLine()) 114 | ->setId(0) 115 | ->setItem($productItem) 116 | ->setPrice($price) 117 | ->setInvoicePeriod($invoicePeriod) 118 | ->setLineExtensionAmount(10) 119 | ->setInvoicedQuantity(1); 120 | 121 | $invoiceLines = [$invoiceLine]; 122 | 123 | // Total Taxes 124 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 125 | ->setId('S', []) 126 | ->setPercent(21.00) 127 | ->setTaxScheme($taxScheme); 128 | 129 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 130 | ->setTaxableAmount(10) 131 | ->setTaxAmount(2.1) 132 | ->setTaxCategory($taxCategory); 133 | 134 | 135 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 136 | ->addTaxSubTotal($taxSubTotal) 137 | ->setTaxAmount(2.1); 138 | 139 | // Payment Terms 140 | $paymentTerms = (new \NumNum\UBL\PaymentTerms()) 141 | ->setNote('30 days net'); 142 | 143 | // Delivery 144 | $deliveryLocation = (new \NumNum\UBL\Address()) 145 | ->setCountry($country); 146 | 147 | $delivery = (new \NumNum\UBL\Delivery()) 148 | ->setActualDeliveryDate(new \DateTime()) 149 | ->setDeliveryLocation($deliveryLocation); 150 | 151 | $orderReference = (new \NumNum\UBL\OrderReference()) 152 | ->setId('5009567') 153 | ->setSalesOrderId('tRST-tKhM'); 154 | 155 | // Invoice object 156 | $invoice = (new \NumNum\UBL\Invoice()) 157 | ->setCustomizationID('urn:cen.eu:en16931:2017') 158 | ->setId(1234) 159 | ->setIssueDate(new \DateTime()) 160 | ->setNote('invoice note') 161 | ->setDelivery($delivery) 162 | ->setAccountingSupplierParty($supplierCompany) 163 | ->setAccountingCustomerParty($clientCompany) 164 | ->setInvoiceLines($invoiceLines) 165 | ->setLegalMonetaryTotal($legalMonetaryTotal) 166 | ->setPaymentTerms($paymentTerms) 167 | ->setInvoicePeriod($invoicePeriod) 168 | ->setPaymentMeans([$paymentMeans]) 169 | ->setBuyerReference('BUYER_REF') 170 | ->setOrderReference($orderReference) 171 | ->setTaxTotal($taxTotal); 172 | 173 | // Test created object 174 | // Use \NumNum\UBL\Generator to generate an XML string 175 | $generator = new \NumNum\UBL\Generator(); 176 | $outputXMLString = $generator->invoice($invoice); 177 | 178 | // Create PHP Native DomDocument object, that can be 179 | // used to validate the generate XML 180 | $dom = new \DOMDocument; 181 | $dom->loadXML($outputXMLString); 182 | 183 | $dom->save('./tests/EN16931Test.xml'); 184 | 185 | // $this->assertEquals(true, $dom->schemaValidate($this->schema)); 186 | 187 | // Use webservice at peppol.helger.com to verify the result 188 | $wsdl = "http://peppol.helger.com/wsdvs?wsdl=1"; 189 | $client = new \SoapClient($wsdl); 190 | $response = $client->validate(['XML' => $outputXMLString, 'VESID' => 'eu.cen.en16931:ubl:1.3.1']); 191 | 192 | // Output validation warnings if present 193 | if ($response->mostSevereErrorLevel == 'WARN' && isset($response->Result[1]->Item)) { 194 | foreach ($response->Result[1]->Item as $responseWarning) { 195 | // fwrite(STDERR, '*** '.$responseWarning->errorText."\n"); 196 | fwrite(STDERR, '*** '.json_encode($responseWarning)."\n"); 197 | } 198 | } 199 | 200 | $this->assertEquals('SUCCESS', $response->mostSevereErrorLevel); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /tests/EmptyAttachmentTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address); 34 | 35 | // Client contact node 36 | $clientContact = (new \NumNum\UBL\Contact()) 37 | ->setName('Client name') 38 | ->setElectronicMail('email@client.com') 39 | ->setTelephone('0032 472 123 456') 40 | ->setTelefax('0032 9 1234 567'); 41 | 42 | // Client company node 43 | $clientCompany = (new \NumNum\UBL\Party()) 44 | ->setName('My client') 45 | ->setPostalAddress($address) 46 | ->setContact($clientContact); 47 | 48 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 49 | ->setPayableAmount(10 + 2) 50 | ->setAllowanceTotalAmount(0); 51 | 52 | // Tax scheme 53 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 54 | ->setId(0); 55 | 56 | // Product 57 | $productItem = (new \NumNum\UBL\Item()) 58 | ->setName('Product Name') 59 | ->setDescription('Product Description') 60 | ->setSellersItemIdentification('SELLERID'); 61 | 62 | // Price 63 | $price = (new \NumNum\UBL\Price()) 64 | ->setBaseQuantity(1) 65 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 66 | ->setPriceAmount(10); 67 | 68 | // Invoice Line tax totals 69 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 70 | ->setTaxAmount(2.1); 71 | 72 | // InvoicePeriod 73 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 74 | ->setStartDate(new \DateTime()); 75 | 76 | // Invoice Line(s) 77 | $invoiceLines = []; 78 | 79 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 80 | ->setId(0) 81 | ->setItem($productItem) 82 | ->setInvoicePeriod($invoicePeriod) 83 | ->setPrice($price) 84 | ->setTaxTotal($lineTaxTotal) 85 | ->setInvoicedQuantity(1); 86 | 87 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 88 | ->setId(0) 89 | ->setItem($productItem) 90 | ->setInvoicePeriod($invoicePeriod) 91 | ->setPrice($price) 92 | ->setAccountingCost('Product 123') 93 | ->setTaxTotal($lineTaxTotal) 94 | ->setInvoicedQuantity(1); 95 | 96 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 97 | ->setId(0) 98 | ->setItem($productItem) 99 | ->setInvoicePeriod($invoicePeriod) 100 | ->setPrice($price) 101 | ->setAccountingCostCode('Product 123') 102 | ->setTaxTotal($lineTaxTotal) 103 | ->setInvoicedQuantity(1); 104 | 105 | 106 | // Total Taxes 107 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 108 | ->setId(0) 109 | ->setName('VAT21%') 110 | ->setPercent(.21) 111 | ->setTaxScheme($taxScheme); 112 | 113 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 114 | ->setTaxableAmount(10) 115 | ->setTaxAmount(2.1) 116 | ->setTaxCategory($taxCategory); 117 | 118 | 119 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 120 | ->addTaxSubTotal($taxSubTotal) 121 | ->setTaxAmount(2.1); 122 | 123 | // Attachment 124 | $attachment = (new \NumNum\UBL\Attachment()) 125 | ->setFilePath(__DIR__.DIRECTORY_SEPARATOR.'SampleInvoice.pdf'); 126 | 127 | $additionalDocumentReference = new \NumNum\UBL\AdditionalDocumentReference(); 128 | $additionalDocumentReference->setId('SomeID'); 129 | $additionalDocumentReference->setDocumentTypeCode(130); 130 | 131 | // Not adding an attachment to AdditionalDocumentReference should not trigger an error 132 | // $additionalDocumentReference->setAttachment($attachment); 133 | 134 | // Invoice object 135 | $invoice = (new \NumNum\UBL\Invoice()) 136 | ->setId(1234) 137 | ->setCopyIndicator(false) 138 | ->setIssueDate(new \DateTime()) 139 | ->setAccountingSupplierParty($supplierCompany) 140 | ->setAccountingCustomerParty($clientCompany) 141 | ->setSupplierAssignedAccountID('10001') 142 | ->setInvoiceLines($invoiceLines) 143 | ->setLegalMonetaryTotal($legalMonetaryTotal) 144 | ->setTaxTotal($taxTotal) 145 | ->setAdditionalDocumentReference($additionalDocumentReference); 146 | 147 | // Test created object 148 | // Use \NumNum\UBL\Generator to generate an XML string 149 | $generator = new \NumNum\UBL\Generator(); 150 | $outputXMLString = $generator->invoice($invoice); 151 | 152 | // Create PHP Native DomDocument object, that can be 153 | // used to validate the generate XML 154 | $dom = new \DOMDocument; 155 | $dom->loadXML($outputXMLString); 156 | 157 | $dom->save('./tests/EmptyAttachmentTest.xml'); 158 | 159 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /tests/MultiplePaymentMeansTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address); 34 | 35 | // Client contact node 36 | $clientContact = (new \NumNum\UBL\Contact()) 37 | ->setName('Client name') 38 | ->setElectronicMail('email@client.com') 39 | ->setTelephone('0032 472 123 456') 40 | ->setTelefax('0032 9 1234 567'); 41 | 42 | // Client company node 43 | $clientCompany = (new \NumNum\UBL\Party()) 44 | ->setName('My client') 45 | ->setPostalAddress($address) 46 | ->setContact($clientContact); 47 | 48 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 49 | ->setPayableAmount(10 + 2) 50 | ->setAllowanceTotalAmount(0); 51 | 52 | // Tax scheme 53 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 54 | ->setId(0); 55 | 56 | $commodityClassification = (new \NumNum\UBL\CommodityClassification()) 57 | ->setItemClassificationCode('123456') 58 | ->setItemClassificationListId('urn:ean.ucc:eanucc:2:2') 59 | ->setItemClassificationListVersionId('16'); 60 | 61 | // Product 62 | $productItem = (new \NumNum\UBL\Item()) 63 | ->setName('Product Name') 64 | ->setDescription('Product Description') 65 | ->setSellersItemIdentification('SELLERID') 66 | ->setCommodityClassification($commodityClassification); 67 | 68 | 69 | // Price 70 | $price = (new \NumNum\UBL\Price()) 71 | ->setBaseQuantity(1) 72 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 73 | ->setPriceAmount(10); 74 | 75 | // Invoice Line tax totals 76 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 77 | ->setTaxAmount(2.1); 78 | 79 | // InvoicePeriod 80 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 81 | ->setStartDate(new \DateTime()); 82 | 83 | // Invoice Line(s) 84 | $invoiceLines = []; 85 | 86 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 87 | ->setId(0) 88 | ->setItem($productItem) 89 | ->setInvoicePeriod($invoicePeriod) 90 | ->setPrice($price) 91 | ->setTaxTotal($lineTaxTotal) 92 | ->setInvoicedQuantity(1); 93 | 94 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 95 | ->setId(0) 96 | ->setItem($productItem) 97 | ->setInvoicePeriod($invoicePeriod) 98 | ->setPrice($price) 99 | ->setAccountingCost('Product 123') 100 | ->setTaxTotal($lineTaxTotal) 101 | ->setInvoicedQuantity(1); 102 | 103 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 104 | ->setId(0) 105 | ->setItem($productItem) 106 | ->setInvoicePeriod($invoicePeriod) 107 | ->setPrice($price) 108 | ->setAccountingCostCode('Product 123') 109 | ->setTaxTotal($lineTaxTotal) 110 | ->setInvoicedQuantity(1); 111 | 112 | 113 | // Total Taxes 114 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 115 | ->setId(0) 116 | ->setName('VAT21%') 117 | ->setPercent(.21) 118 | ->setTaxScheme($taxScheme); 119 | 120 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 121 | ->setTaxableAmount(10) 122 | ->setTaxAmount(2.1) 123 | ->setTaxCategory($taxCategory); 124 | 125 | 126 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 127 | ->addTaxSubTotal($taxSubTotal) 128 | ->setTaxAmount(2.1); 129 | 130 | $paymentMeans = []; 131 | 132 | $payeeFinancialAccount = (new \NumNum\UBL\PayeeFinancialAccount)->setId('RO123456789012345'); 133 | $paymentMeans[] = (new \NumNum\UBL\PaymentMeans()) 134 | ->setPaymentMeansCode(31) 135 | ->setPaymentDueDate(new \DateTime()) 136 | ->setPayeeFinancialAccount($payeeFinancialAccount); 137 | 138 | $payeeFinancialAccount = (new \NumNum\UBL\PayeeFinancialAccount)->setId('RO544456789067890'); 139 | $paymentMeans[] = (new \NumNum\UBL\PaymentMeans()) 140 | ->setPaymentMeansCode(31) 141 | ->setPaymentDueDate(new \DateTime()) 142 | ->setPayeeFinancialAccount($payeeFinancialAccount); 143 | 144 | // Invoice object 145 | $invoice = (new \NumNum\UBL\Invoice()) 146 | ->setId(1234) 147 | ->setCopyIndicator(false) 148 | ->setIssueDate(new \DateTime()) 149 | ->setAccountingSupplierParty($supplierCompany) 150 | ->setAccountingCustomerParty($clientCompany) 151 | ->setSupplierAssignedAccountID('10001') 152 | ->setPaymentMeans($paymentMeans) 153 | ->setInvoiceLines($invoiceLines) 154 | ->setLegalMonetaryTotal($legalMonetaryTotal) 155 | ->setTaxTotal($taxTotal); 156 | 157 | // Test created object 158 | // Use \NumNum\UBL\Generator to generate an XML string 159 | $generator = new \NumNum\UBL\Generator(); 160 | $outputXMLString = $generator->invoice($invoice); 161 | 162 | // Create PHP Native DomDocument object, that can be 163 | // used to validate the generate XML 164 | $dom = new \DOMDocument; 165 | $dom->loadXML($outputXMLString); 166 | 167 | $dom->save('./tests/MultiplePaymentMeansTest.xml'); 168 | 169 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /tests/NumberFormatterTest.php: -------------------------------------------------------------------------------- 1 | assertEqualsCanonicalizing($formattedNumber, $result); 20 | } 21 | 22 | public function formattedNumbersProvider(): array 23 | { 24 | return [ 25 | [0.0, '0', null], 26 | [0.1, '0.1', null], 27 | [0.1200500, '0.12005', null], 28 | [1.2345678, '1.2345678', null], 29 | [1.236789, '1.236789', null], 30 | [1.236789, '1.24', 2], 31 | [1, '1.00', 2], 32 | [1.000, '1', null], 33 | ]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/PartyIdentificationSchemeNameTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address) 34 | ->setPartyIdentificationSchemeName("SomeScheme"); 35 | 36 | // Client company node 37 | $clientCompany = (new \NumNum\UBL\Party()) 38 | ->setName('My client') 39 | ->setPostalAddress($address); 40 | 41 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 42 | ->setPayableAmount(10 + 2) 43 | ->setAllowanceTotalAmount(0); 44 | 45 | // Tax scheme 46 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 47 | ->setId(0); 48 | 49 | // Product 50 | $productItem = (new \NumNum\UBL\Item()) 51 | ->setName('Product Name') 52 | ->setDescription('Product Description'); 53 | 54 | // Price 55 | $price = (new \NumNum\UBL\Price()) 56 | ->setBaseQuantity(1) 57 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 58 | ->setPriceAmount(10); 59 | 60 | // Invoice Line tax totals 61 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 62 | ->setTaxAmount(2.1); 63 | 64 | // Invoice Line(s) 65 | $invoiceLine = (new \NumNum\UBL\InvoiceLine()) 66 | ->setId(0) 67 | ->setItem($productItem) 68 | ->setPrice($price) 69 | ->setTaxTotal($lineTaxTotal) 70 | ->setInvoicedQuantity(1); 71 | 72 | $invoiceLines = [$invoiceLine]; 73 | 74 | // Total Taxes 75 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 76 | ->setId(0) 77 | ->setName('VAT21%') 78 | ->setPercent(.21) 79 | ->setTaxScheme($taxScheme); 80 | 81 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 82 | ->setTaxableAmount(10) 83 | ->setTaxAmount(2.1) 84 | ->setTaxCategory($taxCategory); 85 | 86 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 87 | ->addTaxSubTotal($taxSubTotal) 88 | ->setTaxAmount(2.1); 89 | 90 | $contractDocumentReference = (new \NumNum\UBL\ContractDocumentReference()) 91 | ->setId("123Test"); 92 | 93 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 94 | ->setStartDate(new \DateTime('-31 days')) 95 | ->setEndDate(new \DateTime()); 96 | 97 | // Invoice object 98 | $invoice = (new \NumNum\UBL\Invoice()) 99 | ->setUBLVersionID('2.2') 100 | ->setId(1234) 101 | ->setCopyIndicator(false) 102 | ->setIssueDate(new \DateTime()) 103 | ->setInvoiceTypeCode(\NumNum\UBL\InvoiceTypeCode::INVOICE) 104 | ->setDueDate(new \DateTime()) 105 | ->setAccountingSupplierParty($supplierCompany) 106 | ->setAccountingCustomerParty($clientCompany) 107 | ->setInvoiceLines($invoiceLines) 108 | ->setLegalMonetaryTotal($legalMonetaryTotal) 109 | ->setTaxTotal($taxTotal) 110 | ->setContractDocumentReference($contractDocumentReference) 111 | ->setBuyerReference("SomeReference") 112 | ->setInvoicePeriod($invoicePeriod); 113 | 114 | // Test created object 115 | // Use \NumNum\UBL\Generator to generate an XML string 116 | $generator = new \NumNum\UBL\Generator(); 117 | $outputXMLString = $generator->invoice($invoice); 118 | 119 | // Create PHP Native DomDocument object, that can be 120 | // used to validate the generate XML 121 | $dom = new \DOMDocument; 122 | $dom->loadXML($outputXMLString); 123 | 124 | $dom->save('./tests/PartyIdentificationSchemeNameTest.xml'); 125 | 126 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /tests/ProjectReferenceTest.php: -------------------------------------------------------------------------------- 1 | setId('VAT'); 22 | 23 | // Address country 24 | $country = (new \NumNum\UBL\Country()) 25 | ->setIdentificationCode('BE'); 26 | 27 | // Full address 28 | $address = (new \NumNum\UBL\Address()) 29 | ->setStreetName('Korenmarkt 1') 30 | ->setAdditionalStreetName('Building A') 31 | ->setCityName('Gent') 32 | ->setPostalZone('9000') 33 | ->setCountry($country); 34 | 35 | $financialInstitutionBranch = (new \NumNum\UBL\FinancialInstitutionBranch()) 36 | ->setId('RABONL2U'); 37 | 38 | $payeeFinancialAccount = (new \NumNum\UBL\PayeeFinancialAccount()) 39 | ->setFinancialInstitutionBranch($financialInstitutionBranch) 40 | ->setName('Customer Account Holder') 41 | ->setId('NL00RABO0000000000'); 42 | 43 | $paymentMeans = (new \NumNum\UBL\PaymentMeans()) 44 | ->setPayeeFinancialAccount($payeeFinancialAccount) 45 | ->setPaymentMeansCode(UNCL4461::DEBIT_TRANSFER, []) 46 | ->setPaymentId('our invoice 1234'); 47 | 48 | // Supplier company node 49 | $supplierLegalEntity = (new \NumNum\UBL\LegalEntity()) 50 | ->setRegistrationName('Supplier Company Name') 51 | ->setCompanyId('BE123456789'); 52 | 53 | $supplierPartyTaxScheme = (new \NumNum\UBL\PartyTaxScheme()) 54 | ->setTaxScheme($taxScheme) 55 | ->setCompanyId('BE123456789'); 56 | 57 | $supplierCompany = (new \NumNum\UBL\Party()) 58 | ->setName('Supplier Company Name') 59 | ->setLegalEntity($supplierLegalEntity) 60 | ->setPartyTaxScheme($supplierPartyTaxScheme) 61 | ->setPartyIdentificationId('BE123456789') 62 | ->setPostalAddress($address); 63 | 64 | // Client company node 65 | $clientLegalEntity = (new \NumNum\UBL\LegalEntity()) 66 | ->setRegistrationName('Client Company Name') 67 | ->setCompanyId('Client Company Registration'); 68 | 69 | $clientPartyTaxScheme = (new \NumNum\UBL\PartyTaxScheme()) 70 | ->setTaxScheme($taxScheme) 71 | ->setCompanyId('BE123456789'); 72 | 73 | $clientCompany = (new \NumNum\UBL\Party()) 74 | ->setName('Client Company Name') 75 | ->setLegalEntity($clientLegalEntity) 76 | ->setPartyTaxScheme($clientPartyTaxScheme) 77 | ->setPartyIdentificationId('BE123456789') 78 | ->setPostalAddress($address); 79 | 80 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 81 | ->setPayableAmount(10 + 2.1) 82 | ->setAllowanceTotalAmount(0) 83 | ->setTaxInclusiveAmount(10 + 2.1) 84 | ->setLineExtensionAmount(10) 85 | ->setTaxExclusiveAmount(10); 86 | 87 | $classifiedTaxCategory = (new \NumNum\UBL\ClassifiedTaxCategory()) 88 | ->setId('S') 89 | ->setPercent(21.00) 90 | ->setTaxScheme($taxScheme); 91 | 92 | // Product 93 | $productItem = (new \NumNum\UBL\Item()) 94 | ->setName('Product Name') 95 | ->setClassifiedTaxCategory($classifiedTaxCategory) 96 | ->setDescription('Product Description'); 97 | 98 | // Price 99 | $price = (new \NumNum\UBL\Price()) 100 | ->setBaseQuantity(1) 101 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 102 | ->setPriceAmount(10); 103 | 104 | // Invoice Line tax totals 105 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 106 | ->setTaxAmount(2.1); 107 | 108 | // InvoicePeriod 109 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 110 | ->setStartDate(new \DateTime()); 111 | 112 | // Invoice Line(s) 113 | $invoiceLine = (new \NumNum\UBL\InvoiceLine()) 114 | ->setId(0) 115 | ->setItem($productItem) 116 | ->setPrice($price) 117 | ->setInvoicePeriod($invoicePeriod) 118 | ->setLineExtensionAmount(10) 119 | ->setInvoicedQuantity(1); 120 | 121 | $invoiceLines = [$invoiceLine]; 122 | 123 | // Total Taxes 124 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 125 | ->setId('S', []) 126 | ->setPercent(21.00) 127 | ->setTaxScheme($taxScheme); 128 | 129 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 130 | ->setTaxableAmount(10) 131 | ->setTaxAmount(2.1) 132 | ->setTaxCategory($taxCategory); 133 | 134 | 135 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 136 | ->addTaxSubTotal($taxSubTotal) 137 | ->setTaxAmount(2.1); 138 | 139 | // Payment Terms 140 | $paymentTerms = (new \NumNum\UBL\PaymentTerms()) 141 | ->setNote('30 days net'); 142 | 143 | // Delivery 144 | $deliveryLocation = (new \NumNum\UBL\Address()) 145 | ->setCountry($country); 146 | 147 | $delivery = (new \NumNum\UBL\Delivery()) 148 | ->setActualDeliveryDate(new \DateTime()) 149 | ->setDeliveryLocation($deliveryLocation); 150 | 151 | $orderReference = (new \NumNum\UBL\OrderReference()) 152 | ->setId('5009567') 153 | ->setSalesOrderId('tRST-tKhM'); 154 | 155 | // Test Project Reference 156 | $projectReference = (new \NumNum\UBL\ProjectReference()) 157 | ->setId('Project1234'); 158 | 159 | // Invoice object 160 | $invoice = (new \NumNum\UBL\Invoice()) 161 | ->setCustomizationID('urn:cen.eu:en16931:2017') 162 | ->setId(1234) 163 | ->setIssueDate(new \DateTime()) 164 | ->setNote('invoice note') 165 | ->setDelivery($delivery) 166 | ->setAccountingSupplierParty($supplierCompany) 167 | ->setAccountingCustomerParty($clientCompany) 168 | ->setInvoiceLines($invoiceLines) 169 | ->setLegalMonetaryTotal($legalMonetaryTotal) 170 | ->setPaymentTerms($paymentTerms) 171 | ->setInvoicePeriod($invoicePeriod) 172 | ->setPaymentMeans([$paymentMeans]) 173 | ->setBuyerReference('BUYER_REF') 174 | ->setOrderReference($orderReference) 175 | ->setTaxTotal($taxTotal) 176 | ->setProjectReference($projectReference); 177 | 178 | // Test created object 179 | // Use \NumNum\UBL\Generator to generate an XML string 180 | $generator = new \NumNum\UBL\Generator(); 181 | $outputXMLString = $generator->invoice($invoice); 182 | 183 | // Create PHP Native DomDocument object, that can be 184 | // used to validate the generate XML 185 | $dom = new \DOMDocument; 186 | $dom->loadXML($outputXMLString); 187 | 188 | $dom->save('./tests/ProjectReferenceTest.xml'); 189 | 190 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /tests/SampleInvoice.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/num-num/ubl-invoice/f3cb04003586bffe6117a6a381d1d6d7cd2baf6f/tests/SampleInvoice.pdf -------------------------------------------------------------------------------- /tests/SimpleCreditNoteTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address); 34 | 35 | // Client company node 36 | $clientCompany = (new \NumNum\UBL\Party()) 37 | ->setName('My client') 38 | ->setPostalAddress($address); 39 | 40 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 41 | ->setPayableAmount(10 + 2) 42 | ->setAllowanceTotalAmount(0); 43 | 44 | // Tax scheme 45 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 46 | ->setId(0); 47 | 48 | // Product 49 | $productItem = (new \NumNum\UBL\Item()) 50 | ->setName('Product Name') 51 | ->setDescription('Product Description') 52 | ->setSellersItemIdentification('SELLERID') 53 | ->setBuyersItemIdentification('BUYERID'); 54 | 55 | // Price 56 | $price = (new \NumNum\UBL\Price()) 57 | ->setBaseQuantity(1) 58 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 59 | ->setPriceAmount(10); 60 | 61 | // Invoice Line tax totals 62 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 63 | ->setTaxAmount(2.1); 64 | 65 | // Invoice Line(s) 66 | $creditNoteLine = (new \NumNum\UBL\CreditNoteLine()) 67 | ->setId(0) 68 | ->setItem($productItem) 69 | ->setPrice($price) 70 | ->setTaxTotal($lineTaxTotal) 71 | ->setInvoicedQuantity(1); 72 | 73 | $creditNoteLines = [$creditNoteLine]; 74 | 75 | // Total Taxes 76 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 77 | ->setId(0) 78 | ->setName('VAT21%') 79 | ->setPercent(.21) 80 | ->setTaxScheme($taxScheme); 81 | 82 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 83 | ->setTaxableAmount(10) 84 | ->setTaxAmount(2.1) 85 | ->setTaxCategory($taxCategory); 86 | 87 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 88 | ->addTaxSubTotal($taxSubTotal) 89 | ->setTaxAmount(2.1); 90 | 91 | // Invoice object 92 | $creditNote = (new \NumNum\UBL\CreditNote()) 93 | ->setId(1234) 94 | ->setCopyIndicator(false) 95 | ->setIssueDate(new \DateTime()) 96 | ->setAccountingSupplierParty($supplierCompany) 97 | ->setAccountingCustomerParty($clientCompany) 98 | ->setCreditNoteLines($creditNoteLines) 99 | ->setLegalMonetaryTotal($legalMonetaryTotal) 100 | ->setTaxTotal($taxTotal) 101 | ->setInvoiceTypeCode(\NumNum\UBL\InvoiceTypeCode::CREDIT_NOTE); 102 | 103 | // Test created object 104 | // Use \NumNum\UBL\Generator to generate an XML string 105 | $generator = new \NumNum\UBL\Generator(); 106 | $outputXMLString = $generator->creditNote($creditNote); 107 | 108 | // Create PHP Native DomDocument object, that can be 109 | // used to validate the generate XML 110 | $dom = new \DOMDocument; 111 | $dom->loadXML($outputXMLString); 112 | 113 | $dom->save('./tests/SimpleCreditNoteTest.xml'); 114 | 115 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/SimpleInvoiceTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address); 34 | 35 | // Client contact node 36 | $clientContact = (new \NumNum\UBL\Contact()) 37 | ->setName('Client name') 38 | ->setElectronicMail('email@client.com') 39 | ->setTelephone('0032 472 123 456') 40 | ->setTelefax('0032 9 1234 567'); 41 | 42 | // Client company node 43 | $clientCompany = (new \NumNum\UBL\Party()) 44 | ->setName('My client') 45 | ->setPostalAddress($address) 46 | ->setContact($clientContact); 47 | 48 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 49 | ->setPayableAmount(10 + 2) 50 | ->setAllowanceTotalAmount(0); 51 | 52 | // Tax scheme 53 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 54 | ->setId(0); 55 | 56 | // Product 57 | $productItem = (new \NumNum\UBL\Item()) 58 | ->setName('Product Name') 59 | ->setDescription('Product Description') 60 | ->setSellersItemIdentification('SELLERID'); 61 | 62 | // Price 63 | $price = (new \NumNum\UBL\Price()) 64 | ->setBaseQuantity(1) 65 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 66 | ->setPriceAmount(10); 67 | 68 | // Invoice Line tax totals 69 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 70 | ->setTaxAmount(2.1); 71 | 72 | // InvoicePeriod 73 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 74 | ->setStartDate(new \DateTime()); 75 | 76 | // Invoice Line(s) 77 | $invoiceLines = []; 78 | 79 | $orderLineReference = (new \NumNum\UBL\OrderLineReference) 80 | ->setLineId('#ABC123'); 81 | 82 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 83 | ->setId(0) 84 | ->setItem($productItem) 85 | ->setInvoicePeriod($invoicePeriod) 86 | ->setPrice($price) 87 | ->setTaxTotal($lineTaxTotal) 88 | ->setInvoicedQuantity(1) 89 | ->setOrderLineReference($orderLineReference); 90 | 91 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 92 | ->setId(0) 93 | ->setItem($productItem) 94 | ->setInvoicePeriod($invoicePeriod) 95 | ->setPrice($price) 96 | ->setAccountingCost('Product 123') 97 | ->setTaxTotal($lineTaxTotal) 98 | ->setInvoicedQuantity(1) 99 | ->setOrderLineReference($orderLineReference); 100 | 101 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 102 | ->setId(0) 103 | ->setItem($productItem) 104 | ->setInvoicePeriod($invoicePeriod) 105 | ->setPrice($price) 106 | ->setAccountingCostCode('Product 123') 107 | ->setTaxTotal($lineTaxTotal) 108 | ->setInvoicedQuantity(1) 109 | ->setOrderLineReference($orderLineReference); 110 | 111 | 112 | // Total Taxes 113 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 114 | ->setId(0) 115 | ->setName('VAT21%') 116 | ->setPercent(.21) 117 | ->setTaxScheme($taxScheme); 118 | 119 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 120 | ->setTaxableAmount(10) 121 | ->setTaxAmount(2.1) 122 | ->setTaxCategory($taxCategory); 123 | 124 | 125 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 126 | ->addTaxSubTotal($taxSubTotal) 127 | ->setTaxAmount(2.1); 128 | 129 | // Invoice object 130 | $invoice = (new \NumNum\UBL\Invoice()) 131 | ->setId(1234) 132 | ->setCopyIndicator(false) 133 | ->setIssueDate(new \DateTime()) 134 | ->setAccountingSupplierParty($supplierCompany) 135 | ->setAccountingCustomerParty($clientCompany) 136 | ->setSupplierAssignedAccountID('10001') 137 | ->setInvoiceLines($invoiceLines) 138 | ->setLegalMonetaryTotal($legalMonetaryTotal) 139 | ->setTaxTotal($taxTotal); 140 | 141 | // Test created object 142 | // Use \NumNum\UBL\Generator to generate an XML string 143 | $generator = new \NumNum\UBL\Generator(); 144 | $outputXMLString = $generator->invoice($invoice); 145 | 146 | // Create PHP Native DomDocument object, that can be 147 | // used to validate the generate XML 148 | $dom = new \DOMDocument; 149 | $dom->loadXML($outputXMLString); 150 | 151 | $dom->save('./tests/SimpleInvoiceTest.xml'); 152 | 153 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /tests/SimpleInvoiceWithFilePathPdfTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address); 34 | 35 | // Client contact node 36 | $clientContact = (new \NumNum\UBL\Contact()) 37 | ->setName('Client name') 38 | ->setElectronicMail('email@client.com') 39 | ->setTelephone('0032 472 123 456') 40 | ->setTelefax('0032 9 1234 567'); 41 | 42 | // Client company node 43 | $clientCompany = (new \NumNum\UBL\Party()) 44 | ->setName('My client') 45 | ->setPostalAddress($address) 46 | ->setContact($clientContact); 47 | 48 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 49 | ->setPayableAmount(10 + 2) 50 | ->setAllowanceTotalAmount(0); 51 | 52 | // Tax scheme 53 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 54 | ->setId(0); 55 | 56 | // Product 57 | $productItem = (new \NumNum\UBL\Item()) 58 | ->setName('Product Name') 59 | ->setDescription('Product Description') 60 | ->setSellersItemIdentification('SELLERID'); 61 | 62 | // Price 63 | $price = (new \NumNum\UBL\Price()) 64 | ->setBaseQuantity(1) 65 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 66 | ->setPriceAmount(10); 67 | 68 | // Invoice Line tax totals 69 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 70 | ->setTaxAmount(2.1); 71 | 72 | // InvoicePeriod 73 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 74 | ->setStartDate(new \DateTime()); 75 | 76 | // Invoice Line(s) 77 | $invoiceLines = []; 78 | 79 | $orderLineReference = (new \NumNum\UBL\OrderLineReference) 80 | ->setLineId('#ABC123'); 81 | 82 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 83 | ->setId(0) 84 | ->setItem($productItem) 85 | ->setInvoicePeriod($invoicePeriod) 86 | ->setPrice($price) 87 | ->setTaxTotal($lineTaxTotal) 88 | ->setInvoicedQuantity(1) 89 | ->setOrderLineReference($orderLineReference); 90 | 91 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 92 | ->setId(0) 93 | ->setItem($productItem) 94 | ->setInvoicePeriod($invoicePeriod) 95 | ->setPrice($price) 96 | ->setAccountingCost('Product 123') 97 | ->setTaxTotal($lineTaxTotal) 98 | ->setInvoicedQuantity(1) 99 | ->setOrderLineReference($orderLineReference); 100 | 101 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 102 | ->setId(0) 103 | ->setItem($productItem) 104 | ->setInvoicePeriod($invoicePeriod) 105 | ->setPrice($price) 106 | ->setAccountingCostCode('Product 123') 107 | ->setTaxTotal($lineTaxTotal) 108 | ->setInvoicedQuantity(1) 109 | ->setOrderLineReference($orderLineReference); 110 | 111 | 112 | // Total Taxes 113 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 114 | ->setId(0) 115 | ->setName('VAT21%') 116 | ->setPercent(.21) 117 | ->setTaxScheme($taxScheme); 118 | 119 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 120 | ->setTaxableAmount(10) 121 | ->setTaxAmount(2.1) 122 | ->setTaxCategory($taxCategory); 123 | 124 | 125 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 126 | ->addTaxSubTotal($taxSubTotal) 127 | ->setTaxAmount(2.1); 128 | 129 | $attachment = (new \NumNum\UBL\Attachment()) 130 | ->setFilePath(__DIR__.DIRECTORY_SEPARATOR.'SampleInvoice.pdf'); 131 | 132 | $additionalDocumentReference = (new \NumNum\UBL\AdditionalDocumentReference()) 133 | ->setAttachment($attachment); 134 | 135 | // Invoice object 136 | $invoice = (new \NumNum\UBL\Invoice()) 137 | ->setId(1234) 138 | ->setAdditionalDocumentReference($additionalDocumentReference) 139 | ->setCopyIndicator(false) 140 | ->setIssueDate(new \DateTime()) 141 | ->setAccountingSupplierParty($supplierCompany) 142 | ->setAccountingCustomerParty($clientCompany) 143 | ->setSupplierAssignedAccountID('10001') 144 | ->setInvoiceLines($invoiceLines) 145 | ->setLegalMonetaryTotal($legalMonetaryTotal) 146 | ->setTaxTotal($taxTotal); 147 | 148 | // Test created object 149 | // Use \NumNum\UBL\Generator to generate an XML string 150 | $generator = new \NumNum\UBL\Generator(); 151 | $outputXMLString = $generator->invoice($invoice); 152 | 153 | // Create PHP Native DomDocument object, that can be 154 | // used to validate the generate XML 155 | $dom = new \DOMDocument; 156 | $dom->loadXML($outputXMLString); 157 | 158 | $dom->save('./tests/SimpleInvoiceWithFilePathPdfTest.xml'); 159 | 160 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /tests/SimpleInvoiceWithInlinePdfTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE'); 20 | 21 | // Full address 22 | $address = (new \NumNum\UBL\Address()) 23 | ->setStreetName('Korenmarkt') 24 | ->setBuildingNumber(1) 25 | ->setCityName('Gent') 26 | ->setPostalZone('9000') 27 | ->setCountry($country); 28 | 29 | // Supplier company node 30 | $supplierCompany = (new \NumNum\UBL\Party()) 31 | ->setName('Supplier Company Name') 32 | ->setPhysicalLocation($address) 33 | ->setPostalAddress($address); 34 | 35 | // Client contact node 36 | $clientContact = (new \NumNum\UBL\Contact()) 37 | ->setName('Client name') 38 | ->setElectronicMail('email@client.com') 39 | ->setTelephone('0032 472 123 456') 40 | ->setTelefax('0032 9 1234 567'); 41 | 42 | // Client company node 43 | $clientCompany = (new \NumNum\UBL\Party()) 44 | ->setName('My client') 45 | ->setPostalAddress($address) 46 | ->setContact($clientContact); 47 | 48 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 49 | ->setPayableAmount(10 + 2) 50 | ->setAllowanceTotalAmount(0); 51 | 52 | // Tax scheme 53 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 54 | ->setId(0); 55 | 56 | // Product 57 | $productItem = (new \NumNum\UBL\Item()) 58 | ->setName('Product Name') 59 | ->setDescription('Product Description') 60 | ->setSellersItemIdentification('SELLERID'); 61 | 62 | // Price 63 | $price = (new \NumNum\UBL\Price()) 64 | ->setBaseQuantity(1) 65 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 66 | ->setPriceAmount(10); 67 | 68 | // Invoice Line tax totals 69 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 70 | ->setTaxAmount(2.1); 71 | 72 | // InvoicePeriod 73 | $invoicePeriod = (new \NumNum\UBL\InvoicePeriod()) 74 | ->setStartDate(new \DateTime()); 75 | 76 | // Invoice Line(s) 77 | $invoiceLines = []; 78 | 79 | $orderLineReference = (new \NumNum\UBL\OrderLineReference) 80 | ->setLineId('#ABC123'); 81 | 82 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 83 | ->setId(0) 84 | ->setItem($productItem) 85 | ->setInvoicePeriod($invoicePeriod) 86 | ->setPrice($price) 87 | ->setTaxTotal($lineTaxTotal) 88 | ->setInvoicedQuantity(1) 89 | ->setOrderLineReference($orderLineReference); 90 | 91 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 92 | ->setId(0) 93 | ->setItem($productItem) 94 | ->setInvoicePeriod($invoicePeriod) 95 | ->setPrice($price) 96 | ->setAccountingCost('Product 123') 97 | ->setTaxTotal($lineTaxTotal) 98 | ->setInvoicedQuantity(1) 99 | ->setOrderLineReference($orderLineReference); 100 | 101 | $invoiceLines[] = (new \NumNum\UBL\InvoiceLine()) 102 | ->setId(0) 103 | ->setItem($productItem) 104 | ->setInvoicePeriod($invoicePeriod) 105 | ->setPrice($price) 106 | ->setAccountingCostCode('Product 123') 107 | ->setTaxTotal($lineTaxTotal) 108 | ->setInvoicedQuantity(1) 109 | ->setOrderLineReference($orderLineReference); 110 | 111 | 112 | // Total Taxes 113 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 114 | ->setId(0) 115 | ->setName('VAT21%') 116 | ->setPercent(.21) 117 | ->setTaxScheme($taxScheme); 118 | 119 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 120 | ->setTaxableAmount(10) 121 | ->setTaxAmount(2.1) 122 | ->setTaxCategory($taxCategory); 123 | 124 | 125 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 126 | ->addTaxSubTotal($taxSubTotal) 127 | ->setTaxAmount(2.1); 128 | 129 | // Example if you have some inline or in-memory filestream/file contents 130 | $fileStream = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'SampleInvoice.pdf'); // this would be your file contents 131 | 132 | $base64EncodedFileStream = base64_encode($fileStream); 133 | 134 | $attachment = (new \NumNum\UBL\Attachment()) 135 | ->setFileStream($base64EncodedFileStream, 'Invoice.pdf', 'application/pdf'); 136 | 137 | $additionalDocumentReference = (new \NumNum\UBL\AdditionalDocumentReference()) 138 | ->setAttachment($attachment); 139 | 140 | // Invoice object 141 | $invoice = (new \NumNum\UBL\Invoice()) 142 | ->setId(1234) 143 | ->setAdditionalDocumentReference($additionalDocumentReference) 144 | ->setCopyIndicator(false) 145 | ->setIssueDate(new \DateTime()) 146 | ->setAccountingSupplierParty($supplierCompany) 147 | ->setAccountingCustomerParty($clientCompany) 148 | ->setSupplierAssignedAccountID('10001') 149 | ->setInvoiceLines($invoiceLines) 150 | ->setLegalMonetaryTotal($legalMonetaryTotal) 151 | ->setTaxTotal($taxTotal); 152 | 153 | // Test created object 154 | // Use \NumNum\UBL\Generator to generate an XML string 155 | $generator = new \NumNum\UBL\Generator(); 156 | $outputXMLString = $generator->invoice($invoice); 157 | 158 | // Create PHP Native DomDocument object, that can be 159 | // used to validate the generate XML 160 | $dom = new \DOMDocument; 161 | $dom->loadXML($outputXMLString); 162 | 163 | $dom->save('./tests/SimpleInvoiceWithInlinePdfTest.xml'); 164 | 165 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /tests/SimpleUBL22InvoiceTest.php: -------------------------------------------------------------------------------- 1 | setIdentificationCode('BE') 20 | ->setListId('ISO3166-1:Alpha2'); 21 | 22 | // Full address 23 | $address = (new \NumNum\UBL\Address()) 24 | ->setStreetName('Korenmarkt') 25 | ->setBuildingNumber(1) 26 | ->setCityName('Gent') 27 | ->setPostalZone('9000') 28 | ->setCountry($country); 29 | 30 | // Supplier company node 31 | $supplierCompany = (new \NumNum\UBL\Party()) 32 | ->setName('Supplier Company Name') 33 | ->setPhysicalLocation($address) 34 | ->setPostalAddress($address); 35 | 36 | // Client company node 37 | $clientCompany = (new \NumNum\UBL\Party()) 38 | ->setName('My client') 39 | ->setPostalAddress($address); 40 | 41 | $legalMonetaryTotal = (new \NumNum\UBL\LegalMonetaryTotal()) 42 | ->setPayableAmount(10 + 2) 43 | ->setAllowanceTotalAmount(0); 44 | 45 | // Tax scheme 46 | $taxScheme = (new \NumNum\UBL\TaxScheme()) 47 | ->setId(0); 48 | 49 | // Product 50 | $productItem = (new \NumNum\UBL\Item()) 51 | ->setName('Product Name') 52 | ->setDescription('Product Description'); 53 | 54 | // Price 55 | $price = (new \NumNum\UBL\Price()) 56 | ->setBaseQuantity(1) 57 | ->setUnitCode(\NumNum\UBL\UnitCode::UNIT) 58 | ->setUnitCodeListId('UNECERec20') 59 | ->setPriceAmount(10); 60 | 61 | // Invoice Line tax totals 62 | $lineTaxTotal = (new \NumNum\UBL\TaxTotal()) 63 | ->setTaxAmount(2.1); 64 | 65 | // Invoice Line(s) 66 | $invoiceLine = (new \NumNum\UBL\InvoiceLine()) 67 | ->setId(0) 68 | ->setItem($productItem) 69 | ->setUnitCode('C62') 70 | ->setUnitCodeListID('UNECERec20') 71 | ->setPrice($price) 72 | ->setTaxTotal($lineTaxTotal) 73 | ->setInvoicedQuantity(1); 74 | 75 | $invoiceLines = [$invoiceLine]; 76 | 77 | // Total Taxes 78 | $taxCategory = (new \NumNum\UBL\TaxCategory()) 79 | ->setId(0) 80 | ->setName('VAT21%') 81 | ->setPercent(.21) 82 | ->setTaxScheme($taxScheme); 83 | 84 | $taxSubTotal = (new \NumNum\UBL\TaxSubTotal()) 85 | ->setTaxableAmount(10) 86 | ->setTaxAmount(2.1) 87 | ->setTaxCategory($taxCategory); 88 | 89 | $taxTotal = (new \NumNum\UBL\TaxTotal()) 90 | ->addTaxSubTotal($taxSubTotal) 91 | ->setTaxAmount(2.1); 92 | 93 | // Invoice object 94 | $invoice = (new \NumNum\UBL\Invoice()) 95 | ->setUBLVersionID('2.2') 96 | ->setId(1234) 97 | ->setCopyIndicator(false) 98 | ->setIssueDate(new \DateTime()) 99 | ->setAccountingSupplierParty($supplierCompany) 100 | ->setAccountingCustomerParty($clientCompany) 101 | ->setInvoiceLines($invoiceLines) 102 | ->setLegalMonetaryTotal($legalMonetaryTotal) 103 | ->setTaxTotal($taxTotal); 104 | 105 | // Test created object 106 | // Use \NumNum\UBL\Generator to generate an XML string 107 | $generator = new \NumNum\UBL\Generator(); 108 | $outputXMLString = $generator->invoice($invoice); 109 | 110 | // Create PHP Native DomDocument object, that can be 111 | // used to validate the generate XML 112 | $dom = new \DOMDocument; 113 | $dom->loadXML($outputXMLString); 114 | 115 | $dom->save('./tests/SimpleUBL22InvoiceTest.xml'); 116 | 117 | $this->assertEquals(true, $dom->schemaValidate($this->schema)); 118 | } 119 | } 120 | --------------------------------------------------------------------------------