Draft.
This commit is contained in:
commit
b49d840391
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
vendor/
|
||||||
|
config/parameters.yaml
|
||||||
|
.idea/
|
28
composer.json
Normal file
28
composer.json
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "skobkin/bilingual-invoice-generator",
|
||||||
|
"type": "project",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Alexey Skobkin",
|
||||||
|
"email": "skobkin-ru@ya.ru"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.4",
|
||||||
|
"asika/simple-console": "^1.0",
|
||||||
|
"kwn/number-to-words": "^1.9",
|
||||||
|
"mpdf/mpdf": "^8.0",
|
||||||
|
"symfony/yaml": "^5.0",
|
||||||
|
"twig/html-extra": "^3.0",
|
||||||
|
"twig/twig": "^3.0"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"sort-packages": true
|
||||||
|
}
|
||||||
|
}
|
842
composer.lock
generated
Normal file
842
composer.lock
generated
Normal file
|
@ -0,0 +1,842 @@
|
||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "c214995f6d2d08b81315006f8b75ff8f",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "asika/simple-console",
|
||||||
|
"version": "1.0.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/asika32764/php-simple-console.git",
|
||||||
|
"reference": "0b624c1a999849dc6481a47182e58d593bf65068"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/asika32764/php-simple-console/zipball/0b624c1a999849dc6481a47182e58d593bf65068",
|
||||||
|
"reference": "0b624c1a999849dc6481a47182e58d593bf65068",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Asika\\SimpleConsole\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Simon Asika",
|
||||||
|
"email": "asika32764@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "One file console framework to help you write build scripts.",
|
||||||
|
"time": "2018-03-08T12:05:40+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kwn/number-to-words",
|
||||||
|
"version": "1.9.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/kwn/number-to-words.git",
|
||||||
|
"reference": "1cbfbeb3fb2083c2af9aa47de20d9357b12eccb3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/kwn/number-to-words/zipball/1cbfbeb3fb2083c2af9aa47de20d9357b12eccb3",
|
||||||
|
"reference": "1cbfbeb3fb2083c2af9aa47de20d9357b12eccb3",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.6|>=7.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^5.7.9",
|
||||||
|
"squizlabs/php_codesniffer": "^3.3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"NumberToWords\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Karol Wnuk",
|
||||||
|
"email": "k.wnuk@ascetic.pl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Multi language standalone PHP number to words converter. Fully tested, open for extensions and new languages.",
|
||||||
|
"keywords": [
|
||||||
|
"currency",
|
||||||
|
"money",
|
||||||
|
"number",
|
||||||
|
"numbers",
|
||||||
|
"string",
|
||||||
|
"to",
|
||||||
|
"words"
|
||||||
|
],
|
||||||
|
"time": "2020-01-16T15:22:16+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mpdf/mpdf",
|
||||||
|
"version": "v8.0.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/mpdf/mpdf.git",
|
||||||
|
"reference": "d3147a0d790b6d11936fd9c73fa31a7ed45e3f6f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/mpdf/mpdf/zipball/d3147a0d790b6d11936fd9c73fa31a7ed45e3f6f",
|
||||||
|
"reference": "d3147a0d790b6d11936fd9c73fa31a7ed45e3f6f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"myclabs/deep-copy": "^1.7",
|
||||||
|
"paragonie/random_compat": "^1.4|^2.0|9.99.99",
|
||||||
|
"php": "^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0",
|
||||||
|
"psr/log": "^1.0",
|
||||||
|
"setasign/fpdi": "^2.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "^0.9.5",
|
||||||
|
"mpdf/qrcode": "^1.0.0",
|
||||||
|
"phpunit/phpunit": "^5.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5.0",
|
||||||
|
"tracy/tracy": "^2.4"
|
||||||
|
},
|
||||||
|
"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",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-development": "7.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"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"
|
||||||
|
],
|
||||||
|
"time": "2019-11-28T09:39:33+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "myclabs/deep-copy",
|
||||||
|
"version": "1.9.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||||
|
"reference": "b2c28789e80a97badd14145fda39b545d83ca3ef"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef",
|
||||||
|
"reference": "b2c28789e80a97badd14145fda39b545d83ca3ef",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1"
|
||||||
|
},
|
||||||
|
"replace": {
|
||||||
|
"myclabs/deep-copy": "self.version"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/collections": "^1.0",
|
||||||
|
"doctrine/common": "^2.6",
|
||||||
|
"phpunit/phpunit": "^7.1"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"DeepCopy\\": "src/DeepCopy/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/DeepCopy/deep_copy.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"description": "Create deep copies (clones) of your objects",
|
||||||
|
"keywords": [
|
||||||
|
"clone",
|
||||||
|
"copy",
|
||||||
|
"duplicate",
|
||||||
|
"object",
|
||||||
|
"object graph"
|
||||||
|
],
|
||||||
|
"time": "2020-01-17T21:11:47+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "paragonie/random_compat",
|
||||||
|
"version": "v9.99.99",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/paragonie/random_compat.git",
|
||||||
|
"reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
|
||||||
|
"reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "4.*|5.*",
|
||||||
|
"vimeo/psalm": "^1"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Paragon Initiative Enterprises",
|
||||||
|
"email": "security@paragonie.com",
|
||||||
|
"homepage": "https://paragonie.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||||
|
"keywords": [
|
||||||
|
"csprng",
|
||||||
|
"polyfill",
|
||||||
|
"pseudorandom",
|
||||||
|
"random"
|
||||||
|
],
|
||||||
|
"time": "2018-07-02T15:55:56+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/log",
|
||||||
|
"version": "1.1.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/log.git",
|
||||||
|
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
|
||||||
|
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Log\\": "Psr/Log/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for logging libraries",
|
||||||
|
"homepage": "https://github.com/php-fig/log",
|
||||||
|
"keywords": [
|
||||||
|
"log",
|
||||||
|
"psr",
|
||||||
|
"psr-3"
|
||||||
|
],
|
||||||
|
"time": "2019-11-01T11:05:21+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "setasign/fpdi",
|
||||||
|
"version": "v2.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Setasign/FPDI.git",
|
||||||
|
"reference": "3c266002f8044f61b17329f7cd702d44d73f0f7f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Setasign/FPDI/zipball/3c266002f8044f61b17329f7cd702d44d73f0f7f",
|
||||||
|
"reference": "3c266002f8044f61b17329f7cd702d44d73f0f7f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"php": "^5.6 || ^7.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~5.7",
|
||||||
|
"setasign/fpdf": "~1.8",
|
||||||
|
"setasign/tfpdf": "1.25",
|
||||||
|
"tecnickcom/tcpdf": "~6.2"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured.",
|
||||||
|
"setasign/fpdi-fpdf": "Use this package to automatically evaluate dependencies to FPDF.",
|
||||||
|
"setasign/fpdi-tcpdf": "Use this package to automatically evaluate dependencies to TCPDF.",
|
||||||
|
"setasign/fpdi-tfpdf": "Use this package to automatically evaluate dependencies to tFPDF."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"setasign\\Fpdi\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jan Slabon",
|
||||||
|
"email": "jan.slabon@setasign.com",
|
||||||
|
"homepage": "https://www.setasign.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Maximilian Kresse",
|
||||||
|
"email": "maximilian.kresse@setasign.com",
|
||||||
|
"homepage": "https://www.setasign.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.",
|
||||||
|
"homepage": "https://www.setasign.com/fpdi",
|
||||||
|
"keywords": [
|
||||||
|
"fpdf",
|
||||||
|
"fpdi",
|
||||||
|
"pdf"
|
||||||
|
],
|
||||||
|
"time": "2019-01-30T14:11:19+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/mime",
|
||||||
|
"version": "v5.0.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/mime.git",
|
||||||
|
"reference": "2a3c7fee1f1a0961fa9cf360d5da553d05095e59"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/mime/zipball/2a3c7fee1f1a0961fa9cf360d5da553d05095e59",
|
||||||
|
"reference": "2a3c7fee1f1a0961fa9cf360d5da553d05095e59",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2.5",
|
||||||
|
"symfony/polyfill-intl-idn": "^1.10",
|
||||||
|
"symfony/polyfill-mbstring": "^1.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/mailer": "<4.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"egulias/email-validator": "^2.1.10",
|
||||||
|
"symfony/dependency-injection": "^4.4|^5.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "5.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Mime\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library to manipulate MIME messages",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"mime",
|
||||||
|
"mime-type"
|
||||||
|
],
|
||||||
|
"time": "2020-01-04T14:08:26+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-ctype",
|
||||||
|
"version": "v1.13.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
|
"reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
|
||||||
|
"reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-ctype": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.13-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Ctype\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gert de Pagter",
|
||||||
|
"email": "BackEndTea@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for ctype functions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"ctype",
|
||||||
|
"polyfill",
|
||||||
|
"portable"
|
||||||
|
],
|
||||||
|
"time": "2019-11-27T13:56:44+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-intl-idn",
|
||||||
|
"version": "v1.13.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||||
|
"reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6f9c239e61e1b0c9229a28ff89a812dc449c3d46",
|
||||||
|
"reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3",
|
||||||
|
"symfony/polyfill-mbstring": "^1.3",
|
||||||
|
"symfony/polyfill-php72": "^1.9"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-intl": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.13-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Intl\\Idn\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Laurent Bassin",
|
||||||
|
"email": "laurent@bassin.info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"idn",
|
||||||
|
"intl",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"time": "2019-11-27T13:56:44+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-mbstring",
|
||||||
|
"version": "v1.13.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
|
"reference": "7b4aab9743c30be783b73de055d24a39cf4b954f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f",
|
||||||
|
"reference": "7b4aab9743c30be783b73de055d24a39cf4b954f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-mbstring": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.13-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for the Mbstring extension",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"mbstring",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"time": "2019-11-27T14:18:11+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-php72",
|
||||||
|
"version": "v1.13.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||||
|
"reference": "66fea50f6cb37a35eea048d75a7d99a45b586038"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038",
|
||||||
|
"reference": "66fea50f6cb37a35eea048d75a7d99a45b586038",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.13-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Php72\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"time": "2019-11-27T13:56:44+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/yaml",
|
||||||
|
"version": "v5.0.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/yaml.git",
|
||||||
|
"reference": "69b44e3b8f90949aee2eb3aa9b86ceeb01cbf62a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/yaml/zipball/69b44e3b8f90949aee2eb3aa9b86ceeb01cbf62a",
|
||||||
|
"reference": "69b44e3b8f90949aee2eb3aa9b86ceeb01cbf62a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2.5",
|
||||||
|
"symfony/polyfill-ctype": "~1.8"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/console": "<4.4"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/console": "^4.4|^5.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/console": "For validating YAML files using the lint command"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "5.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Yaml\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony Yaml Component",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"time": "2020-01-21T11:12:28+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "twig/html-extra",
|
||||||
|
"version": "v3.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/twigphp/html-extra.git",
|
||||||
|
"reference": "4ddd2b6500d074d71930a46a6ba315f31515b6f3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/twigphp/html-extra/zipball/4ddd2b6500d074d71930a46a6ba315f31515b6f3",
|
||||||
|
"reference": "4ddd2b6500d074d71930a46a6ba315f31515b6f3",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1.3",
|
||||||
|
"symfony/mime": "^4.3|^5.0",
|
||||||
|
"twig/twig": "^2.4|^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "^4.4|^5.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Twig\\Extra\\Html\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com",
|
||||||
|
"homepage": "http://fabien.potencier.org",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A Twig extension for HTML",
|
||||||
|
"homepage": "https://twig.symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"html",
|
||||||
|
"twig"
|
||||||
|
],
|
||||||
|
"time": "2019-12-28T07:09:27+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "twig/twig",
|
||||||
|
"version": "v3.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/twigphp/Twig.git",
|
||||||
|
"reference": "28f856a4c57eeb24485916e8a68403f41a133616"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/twigphp/Twig/zipball/28f856a4c57eeb24485916e8a68403f41a133616",
|
||||||
|
"reference": "28f856a4c57eeb24485916e8a68403f41a133616",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2.5",
|
||||||
|
"symfony/polyfill-ctype": "^1.8",
|
||||||
|
"symfony/polyfill-mbstring": "^1.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"psr/container": "^1.0",
|
||||||
|
"symfony/phpunit-bridge": "^4.4|^5.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Twig\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com",
|
||||||
|
"homepage": "http://fabien.potencier.org",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Twig Team",
|
||||||
|
"role": "Contributors"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Armin Ronacher",
|
||||||
|
"email": "armin.ronacher@active-4.com",
|
||||||
|
"role": "Project Founder"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||||
|
"homepage": "https://twig.symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"templating"
|
||||||
|
],
|
||||||
|
"time": "2019-12-28T07:17:28+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": {
|
||||||
|
"php": ">=7.4"
|
||||||
|
},
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
70
config/parameters.yaml.dist
Normal file
70
config/parameters.yaml.dist
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
configuration:
|
||||||
|
date_format:
|
||||||
|
source: ''
|
||||||
|
target: ''
|
||||||
|
locales:
|
||||||
|
source: ru
|
||||||
|
target: en
|
||||||
|
images:
|
||||||
|
signature: ''
|
||||||
|
stamp: ''
|
||||||
|
|
||||||
|
services:
|
||||||
|
-
|
||||||
|
name:
|
||||||
|
source: 'Работа'
|
||||||
|
target: 'Work'
|
||||||
|
amount: 1000
|
||||||
|
units:
|
||||||
|
source: 'часа'
|
||||||
|
target: 'hour'
|
||||||
|
price: 1000
|
||||||
|
|
||||||
|
translations:
|
||||||
|
source:
|
||||||
|
variables:
|
||||||
|
title: 'Счёт на оплату №%invoice_number% от %invoice_date%'
|
||||||
|
currency: '%currency%'
|
||||||
|
rows:
|
||||||
|
supplier: 'Поставщик'
|
||||||
|
buyer: 'Покупатель'
|
||||||
|
# service table
|
||||||
|
th_number: '№'
|
||||||
|
th_name: 'Наименование работ, услуг'
|
||||||
|
th_amount: 'Кол-во'
|
||||||
|
th_units: 'Ед.'
|
||||||
|
th_price: 'Цена'
|
||||||
|
th_sum: 'Сумма'
|
||||||
|
tf_total: 'Итого'
|
||||||
|
# bank data
|
||||||
|
account_data: 'Банковские реквизиты поставщика'
|
||||||
|
account_number: 'Номер счёта'
|
||||||
|
bank: 'Банк'
|
||||||
|
bank_address: 'Адрес'
|
||||||
|
swift: 'SWIFT'
|
||||||
|
corr_bank: 'Банк-посредник'
|
||||||
|
total_to_pay: 'Всего к оплате'
|
||||||
|
signature: 'Подпись'
|
||||||
|
supplier:
|
||||||
|
title: '123456'
|
||||||
|
short_title: '123'
|
||||||
|
address: 'some address'
|
||||||
|
extra: []
|
||||||
|
bank:
|
||||||
|
account: '9999999999999999999'
|
||||||
|
name: 'Some Bank of some Country'
|
||||||
|
address: 'Some address'
|
||||||
|
swift: 'SOMESWIFT'
|
||||||
|
corr_bank:
|
||||||
|
name: 'SOME CORR BANK'
|
||||||
|
swift: 'SOMESWIFT2'
|
||||||
|
buyer:
|
||||||
|
title: '"Some Client" LLC'
|
||||||
|
address: 'Some Address'
|
||||||
|
extra:
|
||||||
|
- 'VAT: EU12313123'
|
||||||
|
- 'IBAN: EU123131231231232112'
|
||||||
|
static_substitutions:
|
||||||
|
'%contract_date%': '01.01.1970'
|
||||||
|
'%currency%': 'EUR'
|
||||||
|
#target:
|
9
generate
Executable file
9
generate
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
include_once __DIR__.'/vendor/autoload.php';
|
||||||
|
|
||||||
|
use App\Command\InvoiceGeneratorCommand;
|
||||||
|
|
||||||
|
$generator = new InvoiceGeneratorCommand();
|
||||||
|
$generator->execute();
|
2
images/.gitignore
vendored
Normal file
2
images/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
19
show.php
Normal file
19
show.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__.'/vendor/autoload.php';
|
||||||
|
|
||||||
|
use App\Generator\InvoiceGenerator;
|
||||||
|
use Mpdf\Mpdf;
|
||||||
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
|
$config = Yaml::parseFile(__DIR__.'/config/parameters.yaml');
|
||||||
|
|
||||||
|
$pdf = $_GET['pdf'] ?? false;
|
||||||
|
|
||||||
|
if ($pdf) {
|
||||||
|
$mpdf = new Mpdf();
|
||||||
|
$mpdf->WriteHTML(InvoiceGenerator::generate($config));
|
||||||
|
$mpdf->Output();
|
||||||
|
} else {
|
||||||
|
echo InvoiceGenerator::generate($config);
|
||||||
|
}
|
13
src/Command/InvoiceGeneratorCommand.php
Normal file
13
src/Command/InvoiceGeneratorCommand.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Command;
|
||||||
|
|
||||||
|
use Asika\SimpleConsole\Console;
|
||||||
|
|
||||||
|
class InvoiceGeneratorCommand extends Console
|
||||||
|
{
|
||||||
|
protected function doExecute(): int
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
62
src/Generator/InvoiceGenerator.php
Normal file
62
src/Generator/InvoiceGenerator.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Generator;
|
||||||
|
|
||||||
|
use App\Kernel;
|
||||||
|
use App\Twig\NumberToWordsExtension;
|
||||||
|
use App\Util\StringReplacer;
|
||||||
|
use Twig\Environment as Twig;
|
||||||
|
use Twig\Extra\Html\HtmlExtension;
|
||||||
|
use Twig\Loader\FilesystemLoader;
|
||||||
|
|
||||||
|
class InvoiceGenerator
|
||||||
|
{
|
||||||
|
public static function generate(array $config): string
|
||||||
|
{
|
||||||
|
$twig = static::createTwig();
|
||||||
|
|
||||||
|
$sourceStaticSubstitutions = $config['translations']['source']['static_substitutions'];
|
||||||
|
//$sourceStaticSubstitutions = $config['translations']['target']['static_substitutions'];
|
||||||
|
$source = StringReplacer::recursiveReplace(
|
||||||
|
$config['translations']['source']['variables'],
|
||||||
|
$sourceStaticSubstitutions
|
||||||
|
);
|
||||||
|
//$target = StringReplacer::recursiveReplace($config['translations']['target']['variables']);
|
||||||
|
|
||||||
|
// @TODO fix multilingual substitution depending on the context
|
||||||
|
$services = StringReplacer::recursiveReplace($config['services'], $sourceStaticSubstitutions);
|
||||||
|
$images = static::getImagesContent($config['configuration']['images']);
|
||||||
|
|
||||||
|
return $twig->render('invoice.html.twig', [
|
||||||
|
'configuration' => $config['configuration'],
|
||||||
|
'trans_data' => [
|
||||||
|
'source' => $source,
|
||||||
|
//'target' => $target,
|
||||||
|
],
|
||||||
|
'services' => $services,
|
||||||
|
'images' => $images,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getImagesContent(array $paths): array
|
||||||
|
{
|
||||||
|
$new = [];
|
||||||
|
|
||||||
|
foreach ($paths as $key => $path) {
|
||||||
|
$new[$key] = file_get_contents(Kernel::getProjectRoot().'/'.$path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $new;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function createTwig(): Twig
|
||||||
|
{
|
||||||
|
$loader = new FilesystemLoader(__DIR__.'/../../templates');
|
||||||
|
$twig = new Twig($loader);
|
||||||
|
|
||||||
|
$twig->addExtension(new NumberToWordsExtension());
|
||||||
|
$twig->addExtension(new HtmlExtension());
|
||||||
|
|
||||||
|
return $twig;
|
||||||
|
}
|
||||||
|
}
|
11
src/Kernel.php
Normal file
11
src/Kernel.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
class Kernel
|
||||||
|
{
|
||||||
|
public static function getProjectRoot(): string
|
||||||
|
{
|
||||||
|
return dirname(__DIR__);
|
||||||
|
}
|
||||||
|
}
|
23
src/Twig/NumberToWordsExtension.php
Normal file
23
src/Twig/NumberToWordsExtension.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Twig;
|
||||||
|
|
||||||
|
use NumberToWords\NumberToWords;
|
||||||
|
use Twig\Extension\AbstractExtension;
|
||||||
|
use Twig\TwigFilter;
|
||||||
|
|
||||||
|
class NumberToWordsExtension extends AbstractExtension
|
||||||
|
{
|
||||||
|
public function getFilters(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFilter('ntw', [$this, 'numberToWords'])
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function numberToWords(int $number, string $locale): string
|
||||||
|
{
|
||||||
|
$ntw = new NumberToWords();
|
||||||
|
return $ntw->getNumberTransformer($locale)->toWords($number);
|
||||||
|
}
|
||||||
|
}
|
54
src/Util/StringReplacer.php
Normal file
54
src/Util/StringReplacer.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Util;
|
||||||
|
|
||||||
|
class StringReplacer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array $variables
|
||||||
|
* @param string[]|array $staticReplaces
|
||||||
|
* @param callable[]|array $dynamicReplaces
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function recursiveReplace(
|
||||||
|
array $variables,
|
||||||
|
array $staticReplaces = [],
|
||||||
|
array $dynamicReplaces = []
|
||||||
|
): array {
|
||||||
|
foreach ($variables as $key => &$value) {
|
||||||
|
if (is_string($value)) {
|
||||||
|
$value = static::replaceString($value, $staticReplaces);
|
||||||
|
} elseif (is_int($value)) {
|
||||||
|
continue;
|
||||||
|
} elseif (is_array($value)) {
|
||||||
|
$value = static::recursiveReplace($value, $staticReplaces);
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException(sprintf(
|
||||||
|
'Invalid value. string/array allowed, %s (%s) given.',
|
||||||
|
gettype($value),
|
||||||
|
print_r($value, true)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function replaceString(
|
||||||
|
string $string,
|
||||||
|
array $staticReplaces
|
||||||
|
): string {
|
||||||
|
// Process static replaces
|
||||||
|
$string = str_replace(
|
||||||
|
array_keys($staticReplaces),
|
||||||
|
array_values($staticReplaces),
|
||||||
|
$string
|
||||||
|
);
|
||||||
|
|
||||||
|
// TBI
|
||||||
|
// ...
|
||||||
|
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
}
|
27
templates/invoice.css
Normal file
27
templates/invoice.css
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
table.fat
|
||||||
|
{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.bordered,
|
||||||
|
tr.bordered td,
|
||||||
|
tr.bordered th
|
||||||
|
{
|
||||||
|
border: 1px solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.bordered-fully td,
|
||||||
|
table.bordered-fully th
|
||||||
|
{
|
||||||
|
border: 1px solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
table#invoice td {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
40
templates/invoice.html.twig
Normal file
40
templates/invoice.html.twig
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<title>Invoice</title>
|
||||||
|
{#<meta name="description" content="">#}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
{{ include ('invoice.css') }}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<table width="1400px" id="invoice">
|
||||||
|
<tr>
|
||||||
|
<td width="50%">
|
||||||
|
{{ include ('invoice_side.html.twig', {
|
||||||
|
t: trans_data.source,
|
||||||
|
services: services,
|
||||||
|
images: images,
|
||||||
|
context: 'source',
|
||||||
|
locale: configuration.locales.source
|
||||||
|
}, with_context = false) }}
|
||||||
|
</td>
|
||||||
|
<td width="50%">
|
||||||
|
{{ include ('invoice_side.html.twig', {
|
||||||
|
t: trans_data.source,
|
||||||
|
services: services,
|
||||||
|
images: images,
|
||||||
|
context: 'target',
|
||||||
|
locale: configuration.locales.target
|
||||||
|
}, with_context = false) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
125
templates/invoice_side.html.twig
Normal file
125
templates/invoice_side.html.twig
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<h2 class="title">{{ t.title }}</h2>
|
||||||
|
|
||||||
|
<!-- Party attributes -->
|
||||||
|
<table class="bordered fat">
|
||||||
|
<tr>
|
||||||
|
<td colspan="3"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td rowspan="2">{{ t.rows.supplier }}</td>
|
||||||
|
<td colspan="2">{{ t.supplier.title }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">{{ t.supplier.address }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td rowspan="{{ 2 + t.buyer.extra|length }}">{{ t.rows.buyer }}</td>
|
||||||
|
<td colspan="2">{{ t.buyer.title }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">{{ t.buyer.address }}</td>
|
||||||
|
</tr>
|
||||||
|
{% for item in t.buyer.extra %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">{{ item }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- Services table -->
|
||||||
|
<table class="bordered bordered-fully fat">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{ t.rows.th_number }}</th>
|
||||||
|
<th>{{ t.rows.th_name }}</th>
|
||||||
|
<th>{{ t.rows.th_amount }}</th>
|
||||||
|
<th>{{ t.rows.th_units }}</th>
|
||||||
|
<th>{{ t.rows.th_price }}</th>
|
||||||
|
<th>{{ t.rows.th_sum }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% set total = 0 %}
|
||||||
|
{% for service in services %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ loop.index }}</td>
|
||||||
|
<td width="60%">{{ service.name[context] }}</td>
|
||||||
|
<td>{{ service.amount }}</td>
|
||||||
|
<td>{{ service.units[context] }}</td>
|
||||||
|
<td>{{ service.amount }} {{ t.currency }}</td>
|
||||||
|
{% set sum = service.amount * service.price %}
|
||||||
|
<td>{{ sum }} {{ t.currency }}</td>
|
||||||
|
</tr>
|
||||||
|
{% set total = total + sum %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td colspan="5" align="right">{{ t.rows.tf_total }}</td>
|
||||||
|
<td>{{ total }} {{ t.currency }}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<table class="fat">
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">
|
||||||
|
{{ t.rows.total_to_pay }}: {{ total|ntw(locale) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- Bank account data -->
|
||||||
|
<table id="bank-details" class="fat">
|
||||||
|
<tr class="bordered">
|
||||||
|
<td colspan="3"><strong>{{ t.rows.account_data }}:</strong></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ t.rows.account_number }}</td>
|
||||||
|
<td colspan="2">{{ t.supplier.bank.account }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">{{ t.rows.bank }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">{{ t.supplier.bank.name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ t.rows.bank_address }}</td>
|
||||||
|
<td colspan="2">{{ t.supplier.bank.address }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ t.rows.swift }}</td>
|
||||||
|
<td colspan="2">{{ t.supplier.bank.swift }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>{{ t.rows.corr_bank }}</strong></td>
|
||||||
|
<td colspan="2">{{ t.supplier.bank.corr_bank.name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ t.rows.swift }}</td>
|
||||||
|
<td colspan="2">{{ t.supplier.bank.corr_bank.swift }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">{{ t.supplier.short_title }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td height="50px">{{ t.rows.signature }}</td>
|
||||||
|
<td colspan="2" valign="bottom">
|
||||||
|
<img src="{{ images.signature|data_uri(mime='image/png') }}" alt="Signature">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% if images.stamp is defined %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">
|
||||||
|
<img src="{{ images.stamp|data_uri(mime='image/png') }}" alt="Stamp">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
Loading…
Reference in a new issue