diff --git a/app/Http/Controllers/ExpenseController.php b/app/Http/Controllers/ExpenseController.php index 3ab2cc90da02..0553b5dd3aec 100644 --- a/app/Http/Controllers/ExpenseController.php +++ b/app/Http/Controllers/ExpenseController.php @@ -19,10 +19,12 @@ use App\Http\Requests\Expense\BulkExpenseRequest; use App\Http\Requests\Expense\CreateExpenseRequest; use App\Http\Requests\Expense\DestroyExpenseRequest; use App\Http\Requests\Expense\EditExpenseRequest; +use App\Http\Requests\Expense\EDocumentRequest; use App\Http\Requests\Expense\ShowExpenseRequest; use App\Http\Requests\Expense\StoreExpenseRequest; use App\Http\Requests\Expense\UpdateExpenseRequest; use App\Http\Requests\Expense\UploadExpenseRequest; +use App\Jobs\EDocument\ImportEDocument; use App\Models\Account; use App\Models\Expense; use App\Repositories\ExpenseRepository; @@ -581,4 +583,15 @@ class ExpenseController extends BaseController return $this->itemResponse($expense->fresh()); } + + public function edocument(EDocumentRequest $request): string + { + if ($request->hasFile("documents")) { + return (new ImportEDocument($request->file("documents")[0]->get(), $request->file("documents")[0]->getClientOriginalName()))->handle(); + } + else { + return "No file found"; + } + + } } diff --git a/app/Http/Requests/Expense/EDocumentRequest.php b/app/Http/Requests/Expense/EDocumentRequest.php new file mode 100644 index 000000000000..5428eda9822d --- /dev/null +++ b/app/Http/Requests/Expense/EDocumentRequest.php @@ -0,0 +1,43 @@ +user(); + + return $user->isAdmin(); + } + + public function rules() + { + $rules = []; + + if ($this->file('documents') && is_array($this->file('documents'))) { + $rules['documents.*'] = $this->fileValidation(); + } elseif ($this->file('documents')) { + $rules['documents'] = $this->fileValidation(); + } + return $rules; + } + + public function prepareForValidation() + { + $input = $this->all(); + + $this->replace($input); + + } + +} diff --git a/app/Jobs/EDocument/ImportEDocument.php b/app/Jobs/EDocument/ImportEDocument.php new file mode 100644 index 000000000000..13fb22de94f8 --- /dev/null +++ b/app/Jobs/EDocument/ImportEDocument.php @@ -0,0 +1,64 @@ +file_content = $file_content; + $this->file_name = $file_name; + } + + /** + * Execute the job. + * + * @return Expense + * @throws \Exception + */ + public function handle(): Expense + { + if (str_contains($this->file_name, ".xml")){ + switch (true) { + case stristr($this->file_content, "urn:cen.eu:en16931:2017"): + case stristr($this->file_content, "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0"): + case stristr($this->file_content, "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_2.1"): + case stristr($this->file_content, "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_2.0"): + return (new ZugferdEDocument($this->file_content, $this->file_name))->run(); + default: + throw new Exception("E-Invoice standard not supported"); + } + } + else { + throw new Exception("File type not supported"); + } + + } +} diff --git a/app/Services/EDocument/Imports/ZugferdEDocument.php b/app/Services/EDocument/Imports/ZugferdEDocument.php new file mode 100644 index 000000000000..49fb780ffab3 --- /dev/null +++ b/app/Services/EDocument/Imports/ZugferdEDocument.php @@ -0,0 +1,129 @@ +user(); + $this->document = ZugferdDocumentReader::readAndGuessFromContent($this->tempdocument); + $this->document->getDocumentInformation($documentno, $documenttypecode, $documentdate, $invoiceCurrency, $taxCurrency, $documentname, $documentlanguage, $effectiveSpecifiedPeriod); + $this->document->getDocumentSummation($grandTotalAmount, $duePayableAmount, $lineTotalAmount, $chargeTotalAmount, $allowanceTotalAmount, $taxBasisTotalAmount, $taxTotalAmount, $roundingAmount, $totalPrepaidAmount); + + $expense = Expense::where('amount', $grandTotalAmount)->where("transaction_reference", $documentno)->whereDate("date", $documentdate)->first(); + if (empty($expense)) { + // The document does not exist as an expense + // Handle accordingly + $visualizer = new ZugferdVisualizer($this->document); + $visualizer->setDefaultTemplate(); + $visualizer->setRenderer(app(ZugferdVisualizerLaravelRenderer::class)); + $visualizer->setPdfFontDefault("arial"); + $visualizer->setPdfPaperSize('A4-P'); + $visualizer->setTemplate('edocument.xinvoice'); + + $expense = ExpenseFactory::create($user->company()->id, $user->id); + $expense->date = $documentdate; + $expense->user_id = $user->id; + $expense->company_id = $user->company->id; + $expense->public_notes = $documentno; + $expense->currency_id = Currency::whereCode($invoiceCurrency)->first()->id; + $expense->save(); + + $origin_file = TempFile::UploadedFileFromRaw($this->tempdocument, $this->documentname, "application/xml"); + (new UploadFile($origin_file, UploadFile::DOCUMENT, $user, $expense->company, $expense, null, false))->handle(); + $uploaded_file = TempFile::UploadedFileFromRaw($visualizer->renderPdf(), $documentno."_visualiser.pdf", "application/pdf"); + (new UploadFile($uploaded_file, UploadFile::DOCUMENT, $user, $expense->company, $expense, null, false))->handle(); + $expense->save(); + if ($taxCurrency && $taxCurrency != $invoiceCurrency) { + $expense->private_notes = ctrans("texts.tax_currency_mismatch"); + } + $expense->uses_inclusive_taxes = True; + $expense->amount = $grandTotalAmount; + $counter = 1; + if ($this->document->firstDocumentTax()) { + do { + $this->document->getDocumentTax($categoryCode, $typeCode, $basisAmount, $calculatedAmount, $rateApplicablePercent, $exemptionReason, $exemptionReasonCode, $lineTotalBasisAmount, $allowanceChargeBasisAmount, $taxPointDate, $dueDateTypeCode); + $expense->{"tax_amount$counter"} = $calculatedAmount; + $expense->{"tax_rate$counter"} = $rateApplicablePercent; + $counter++; + } while ($this->document->nextDocumentTax()); + } + $this->document->getDocumentSeller($name, $buyer_id, $buyer_description); + $this->document->getDocumentSellerContact($person_name, $person_department, $contact_phone, $contact_fax, $contact_email); + $this->document->getDocumentSellerAddress($address_1, $address_2, $address_3, $postcode, $city, $country, $subdivision); + $this->document->getDocumentSellerTaxRegistration($taxtype); + $taxid = null; + if (array_key_exists("VA", $taxtype)) { + $taxid = $taxtype["VA"]; + } + $vendor = Vendor::where('vat_number', $taxid)->first(); + + if (!empty($vendor)) { + // Vendor found + $expense->vendor_id = $vendor->id; + } else { + $vendor = VendorFactory::create($user->company()->id, $user->id); + $vendor->name = $name; + if ($taxid != null) { + $vendor->vat_number = $taxid; + } + $vendor->currency_id = Currency::whereCode($invoiceCurrency)->first()->id; + $vendor->phone = $contact_phone; + $vendor->address1 = $address_1; + $vendor->address2 = $address_2; + $vendor->city = $city; + $vendor->postal_code = $postcode; + $vendor->country_id = Country::where('iso_3166_2', $country)->first()->id; + + $vendor->save(); + $expense->vendor_id = $vendor->id; + } + $expense->transaction_reference = $documentno; + } + else { + // The document exists as an expense + // Handle accordingly + nlog("Document already exists"); + $expense->private_notes = $expense->private_notes . ctrans("texts.edocument_import_already_exists", ["date" => time()]); + } + $expense->save(); + return $expense; + } +} + diff --git a/composer.json b/composer.json index e9839b003ec1..11aa0a0f9058 100644 --- a/composer.json +++ b/composer.json @@ -56,6 +56,7 @@ "hedii/laravel-gelf-logger": "^8", "horstoeko/orderx": "dev-master", "horstoeko/zugferd": "^1", + "horstoeko/zugferdvisualizer":"^1", "hyvor/php-json-exporter": "^0.0.3", "imdhemy/laravel-purchases": "^1.7", "intervention/image": "^2.5", diff --git a/composer.lock b/composer.lock index f2bd5cbf964e..6ea84f00fb7a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ca9bed451100b5dc088fe6bcfb9babea", + "content-hash": "9b3b2f15703a291c1ebbedf56aaa4c69", "packages": [ { "name": "adrienrn/php-mimetyper", @@ -1933,6 +1933,68 @@ ], "time": "2024-02-05T11:56:58+00:00" }, + { + "name": "dompdf/dompdf", + "version": "v2.0.8", + "source": { + "type": "git", + "url": "https://github.com/dompdf/dompdf.git", + "reference": "c20247574601700e1f7c8dab39310fca1964dc52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/c20247574601700e1f7c8dab39310fca1964dc52", + "reference": "c20247574601700e1f7c8dab39310fca1964dc52", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "masterminds/html5": "^2.0", + "phenx/php-font-lib": ">=0.5.4 <1.0.0", + "phenx/php-svg-lib": ">=0.5.2 <1.0.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "ext-json": "*", + "ext-zip": "*", + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^7.5 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-gd": "Needed to process images", + "ext-gmagick": "Improves image processing performance", + "ext-imagick": "Improves image processing performance", + "ext-zlib": "Needed for pdf stream compression" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dompdf\\": "src/" + }, + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "The Dompdf Community", + "homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md" + } + ], + "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", + "homepage": "https://github.com/dompdf/dompdf", + "support": { + "issues": "https://github.com/dompdf/dompdf/issues", + "source": "https://github.com/dompdf/dompdf/tree/v2.0.8" + }, + "time": "2024-04-29T13:06:17+00:00" + }, { "name": "dragonmantank/cron-expression", "version": "v3.3.3", @@ -3800,6 +3862,66 @@ }, "time": "2024-06-15T05:49:47+00:00" }, + { + "name": "horstoeko/zugferdvisualizer", + "version": "v1.0.8", + "source": { + "type": "git", + "url": "https://github.com/horstoeko/zugferdvisualizer.git", + "reference": "3a53ebf570284bf5fa3e525240761c03d3936076" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/horstoeko/zugferdvisualizer/zipball/3a53ebf570284bf5fa3e525240761c03d3936076", + "reference": "3a53ebf570284bf5fa3e525240761c03d3936076", + "shasum": "" + }, + "require": { + "dompdf/dompdf": "^2.0", + "ext-dom": "*", + "ext-mbstring": "*", + "horstoeko/zugferd": "^1", + "league/commonmark": "^1|^2", + "mpdf/mpdf": "^8", + "php": "^7.3|^7.4|^8" + }, + "require-dev": { + "ext-gd": "*", + "ext-json": "*", + "ext-zip": "*", + "pdepend/pdepend": "^2", + "phploc/phploc": "^7", + "phpmd/phpmd": "^2", + "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^9", + "sebastian/phpcpd": "^6", + "squizlabs/php_codesniffer": "^3" + }, + "type": "package", + "autoload": { + "psr-4": { + "horstoeko\\zugferdvisualizer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Erling", + "email": "daniel@erling.com.de", + "role": "lead" + } + ], + "description": "A library", + "homepage": "https://github.com/horstoeko/zugferdvisualizer", + "support": { + "issues": "https://github.com/horstoeko/zugferdvisualizer/issues", + "source": "https://github.com/horstoeko/zugferdvisualizer/tree/v1.0.8" + }, + "time": "2024-06-17T15:39:04+00:00" + }, { "name": "http-interop/http-factory-guzzle", "version": "1.2.0", @@ -6440,6 +6562,73 @@ }, "time": "2022-12-02T22:17:43+00:00" }, + { + "name": "masterminds/html5", + "version": "2.9.0", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "support": { + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" + }, + "time": "2024-03-31T07:05:07+00:00" + }, { "name": "microsoft/microsoft-graph", "version": "1.110.0", @@ -6773,6 +6962,179 @@ ], "time": "2024-04-12T21:02:21+00:00" }, + { + "name": "mpdf/mpdf", + "version": "v8.2.4", + "source": { + "type": "git", + "url": "https://github.com/mpdf/mpdf.git", + "reference": "9e3ff91606fed11cd58a130eabaaf60e56fdda88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mpdf/mpdf/zipball/9e3ff91606fed11cd58a130eabaaf60e56fdda88", + "reference": "9e3ff91606fed11cd58a130eabaaf60e56fdda88", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "ext-mbstring": "*", + "mpdf/psr-http-message-shim": "^1.0 || ^2.0", + "mpdf/psr-log-aware-trait": "^2.0 || ^3.0", + "myclabs/deep-copy": "^1.7", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": "^5.6 || ^7.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "setasign/fpdi": "^2.1" + }, + "require-dev": { + "mockery/mockery": "^1.3.0", + "mpdf/qrcode": "^1.1.0", + "squizlabs/php_codesniffer": "^3.5.0", + "tracy/tracy": "~2.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-bcmath": "Needed for generation of some types of barcodes", + "ext-xml": "Needed mainly for SVG manipulation", + "ext-zlib": "Needed for compression of embedded resources, such as fonts" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Mpdf\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-only" + ], + "authors": [ + { + "name": "Matěj Humpál", + "role": "Developer, maintainer" + }, + { + "name": "Ian Back", + "role": "Developer (retired)" + } + ], + "description": "PHP library generating PDF files from UTF-8 encoded HTML", + "homepage": "https://mpdf.github.io", + "keywords": [ + "pdf", + "php", + "utf-8" + ], + "support": { + "docs": "http://mpdf.github.io", + "issues": "https://github.com/mpdf/mpdf/issues", + "source": "https://github.com/mpdf/mpdf" + }, + "funding": [ + { + "url": "https://www.paypal.me/mpdf", + "type": "custom" + } + ], + "time": "2024-06-14T16:06:41+00:00" + }, + { + "name": "mpdf/psr-http-message-shim", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/mpdf/psr-http-message-shim.git", + "reference": "3206e6b80b6d2479e148ee497e9f2bebadc919db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mpdf/psr-http-message-shim/zipball/3206e6b80b6d2479e148ee497e9f2bebadc919db", + "reference": "3206e6b80b6d2479e148ee497e9f2bebadc919db", + "shasum": "" + }, + "require": { + "psr/http-message": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Mpdf\\PsrHttpMessageShim\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Dorison", + "email": "mark@chromatichq.com" + }, + { + "name": "Kristofer Widholm", + "email": "kristofer@chromatichq.com" + }, + { + "name": "Nigel Cunningham", + "email": "nigel.cunningham@technocrat.com.au" + } + ], + "description": "Shim to allow support of different psr/message versions.", + "support": { + "issues": "https://github.com/mpdf/psr-http-message-shim/issues", + "source": "https://github.com/mpdf/psr-http-message-shim/tree/1.0.0" + }, + "time": "2023-09-01T05:59:47+00:00" + }, + { + "name": "mpdf/psr-log-aware-trait", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/mpdf/psr-log-aware-trait.git", + "reference": "a633da6065e946cc491e1c962850344bb0bf3e78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mpdf/psr-log-aware-trait/zipball/a633da6065e946cc491e1c962850344bb0bf3e78", + "reference": "a633da6065e946cc491e1c962850344bb0bf3e78", + "shasum": "" + }, + "require": { + "psr/log": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Mpdf\\PsrLogAwareTrait\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Dorison", + "email": "mark@chromatichq.com" + }, + { + "name": "Kristofer Widholm", + "email": "kristofer@chromatichq.com" + } + ], + "description": "Trait to allow support of different psr/log versions.", + "support": { + "issues": "https://github.com/mpdf/psr-log-aware-trait/issues", + "source": "https://github.com/mpdf/psr-log-aware-trait/tree/v3.0.0" + }, + "time": "2023-05-03T06:19:36+00:00" + }, { "name": "mtdowling/jmespath.php", "version": "2.7.0", @@ -6839,6 +7201,66 @@ }, "time": "2023-08-25T10:54:48+00:00" }, + { + "name": "myclabs/deep-copy", + "version": "1.12.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2024-06-12T14:39:25+00:00" + }, { "name": "nelexa/zip", "version": "4.0.2", @@ -7890,6 +8312,96 @@ }, "time": "2024-04-22T22:05:04+00:00" }, + { + "name": "phenx/php-font-lib", + "version": "0.5.6", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-font-lib.git", + "reference": "a1681e9793040740a405ac5b189275059e2a9863" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a1681e9793040740a405ac5b189275059e2a9863", + "reference": "a1681e9793040740a405ac5b189275059e2a9863", + "shasum": "" + }, + "require": { + "ext-mbstring": "*" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/PhenX/php-font-lib", + "support": { + "issues": "https://github.com/dompdf/php-font-lib/issues", + "source": "https://github.com/dompdf/php-font-lib/tree/0.5.6" + }, + "time": "2024-01-29T14:45:26+00:00" + }, + { + "name": "phenx/php-svg-lib", + "version": "0.5.4", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-svg-lib.git", + "reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/46b25da81613a9cf43c83b2a8c2c1bdab27df691", + "reference": "46b25da81613a9cf43c83b2a8c2c1bdab27df691", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0", + "sabberworm/php-css-parser": "^8.4" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/PhenX/php-svg-lib", + "support": { + "issues": "https://github.com/dompdf/php-svg-lib/issues", + "source": "https://github.com/dompdf/php-svg-lib/tree/0.5.4" + }, + "time": "2024-04-08T12:52:34+00:00" + }, { "name": "php-http/client-common", "version": "2.7.1", @@ -9992,6 +10504,71 @@ }, "time": "2024-03-25T10:48:46+00:00" }, + { + "name": "sabberworm/php-css-parser", + "version": "v8.5.1", + "source": { + "type": "git", + "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git", + "reference": "4a3d572b0f8b28bb6fd016ae8bbfc445facef152" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/4a3d572b0f8b28bb6fd016ae8bbfc445facef152", + "reference": "4a3d572b0f8b28bb6fd016ae8bbfc445facef152", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=5.6.20" + }, + "require-dev": { + "phpunit/phpunit": "^5.7.27" + }, + "suggest": { + "ext-mbstring": "for parsing UTF-8 CSS" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "9.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sabberworm\\CSS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Raphael Schweikert" + }, + { + "name": "Oliver Klee", + "email": "github@oliverklee.de" + }, + { + "name": "Jake Hotson", + "email": "jake.github@qzdesign.co.uk" + } + ], + "description": "Parser for CSS Files written in PHP", + "homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser", + "keywords": [ + "css", + "parser", + "stylesheet" + ], + "support": { + "issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues", + "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.5.1" + }, + "time": "2024-02-15T16:41:13+00:00" + }, { "name": "sabre/uri", "version": "3.0.1", @@ -16386,66 +16963,6 @@ }, "time": "2024-05-16T03:13:13+00:00" }, - { - "name": "myclabs/deep-copy", - "version": "1.12.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2024-06-12T14:39:25+00:00" - }, { "name": "nunomaduro/collision", "version": "v7.10.0", diff --git a/lang/en/texts.php b/lang/en/texts.php index 758575e06cdf..43674305c77a 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -2934,6 +2934,13 @@ $lang = array( 'mime_types' => 'Mime types', 'mime_types_placeholder' => '.pdf , .docx, .jpg', 'mime_types_help' => 'Comma separated list of allowed mime types, leave blank for all', + 'ticket_number_start_help' => 'Ticket number must be greater than the current ticket number', + 'new_ticket_template_id' => 'New ticket', + 'new_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a new ticket is created', + 'update_ticket_template_id' => 'Updated ticket', + 'update_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a ticket is updated', + 'close_ticket_template_id' => 'Closed ticket', + 'close_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a ticket is closed', 'default_priority' => 'Default priority', 'alert_new_comment_id' => 'New comment', 'alert_comment_ticket_help' => 'Selecting a template will send a notification (to agent) when a comment is made.', @@ -5303,6 +5310,9 @@ $lang = array( 'currency_bhutan_ngultrum' => 'Bhutan Ngultrum', 'end_of_month' => 'End Of Month', 'merge_e_invoice_to_pdf' => 'Merge E-Invoice and PDF', + 'end_of_month' => 'End Of Month', + 'tax_currency_mismatch' => 'Tax currency is different from invoice currency', + 'edocument_import_already_exists' => '\nThe invoice has already been imported on :date' ); -return $lang; \ No newline at end of file +return $lang; diff --git a/resources/views/edocument/xinvoice.php b/resources/views/edocument/xinvoice.php new file mode 100644 index 000000000000..338d552172d7 --- /dev/null +++ b/resources/views/edocument/xinvoice.php @@ -0,0 +1,406 @@ + +
+ + + +getDocumentInformation($documentno, $documenttypecode, $documentdate, $invoiceCurrency, $taxCurrency, $documentname, $documentlanguage, $effectiveSpecifiedPeriod); +$document->getDocumentBuyer($buyername, $buyerids, $buyerdescription); +$document->getDocumentBuyerAddress($buyeraddressline1, $buyeraddressline2, $buyeraddressline3, $buyerpostcode, $buyercity, $buyercounty, $buyersubdivision); +?> +
+
+
+
+
+
+
+ Invoice Date format("d.m.Y"); ?> +
++ Sehr geehrter Kunde, +
++ wir erlauben uns Ihnen folgende Position in Rechnung zu stellen. +
+Pos. | +Beschreibung | +Stk. | +Preis | +Menge | +MwSt % | +|
---|---|---|---|---|---|---|
+ | + getDocumentPositionNote($posnoteContent, $posnoteContentCode, $posnoteSubjectCode); ?> + + + | +|||||
+ | + | + | + | + firstDocumentPositionTax()) { ?> + getDocumentPositionTax($categoryCode, $typeCode, $rateApplicablePercent, $calculatedAmount, $exemptionReason, $exemptionReasonCode); ?> + | % | + ++ + |
+ | + | + | () | +|||
+ | ||||||
+ | Allowance/Charge | +|||||
+ | + | + | + | |||
+ | ||||||
+ | Summe | +|||||
+ | Nettobetrag | ++ | ||||
+ | Summe Aufschläge | ++ | ||||
+ | Summe Rabatte | ++ | ||||
+ | MwSt. | ++ | ||||
+ | Bruttosumme | ++ | ||||
+ | Bereits gezahlt | ++ | ||||
+ | Zu Zahlen | ++ | ||||
+ | ||||||
+ | VAT Breakdown | +|||||
+ | % | ++ | + | |||
+ | Summe | ++ | + | |||
+ + | +||||||