From 8e0696d43851a8a3fe516ffb2f251c2a65e37085 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 6 Jan 2025 16:04:51 +0100 Subject: [PATCH] Use Laravel-Dompdf and create pdf invoices. --- app/Http/Controllers/PdfController.php | 24 ++ composer.json | 1 + composer.lock | 366 +++++++++++++++++- config/dompdf.php | 300 ++++++++++++++ lang/de/common.php | 4 + lang/de/configuration.php | 1 + lang/de/invoice.php | 11 + resources/views/components/pdf-icon.blade.php | 3 + resources/views/invoice/show.blade.php | 11 +- resources/views/option/index.blade.php | 8 + resources/views/pdfs/address.blade.php | 35 ++ resources/views/pdfs/footer.blade.php | 17 + resources/views/pdfs/header.blade.php | 14 + resources/views/pdfs/invoice.blade.php | 79 ++++ routes/web.php | 2 + 15 files changed, 872 insertions(+), 4 deletions(-) create mode 100644 app/Http/Controllers/PdfController.php create mode 100644 config/dompdf.php create mode 100644 resources/views/components/pdf-icon.blade.php create mode 100644 resources/views/pdfs/address.blade.php create mode 100644 resources/views/pdfs/footer.blade.php create mode 100644 resources/views/pdfs/header.blade.php create mode 100644 resources/views/pdfs/invoice.blade.php diff --git a/app/Http/Controllers/PdfController.php b/app/Http/Controllers/PdfController.php new file mode 100644 index 0000000..2daaa06 --- /dev/null +++ b/app/Http/Controllers/PdfController.php @@ -0,0 +1,24 @@ +name; + $options->$key = $option->value; + } + + return Pdf::loadView('pdfs.invoice', ['invoice' => $invoice->load(['address', 'delivery']), 'options' => $options])->stream(); + } +} diff --git a/composer.json b/composer.json index 9a1cae4..6e5d7c3 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "license": "MIT", "require": { "php": "^8.4", + "barryvdh/laravel-dompdf": "^3.0", "laravel/framework": "^11.31", "laravel/sanctum": "^4.0", "laravel/tinker": "^2.9" diff --git a/composer.lock b/composer.lock index aa855aa..6ab3267 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,85 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "56fda0642f43208331e4c9898bb04606", + "content-hash": "09a328fa763194a399764179c2191104", "packages": [ + { + "name": "barryvdh/laravel-dompdf", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/laravel-dompdf.git", + "reference": "2d814cd25e299be022a4fa0fb4509d7ccd353d8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/2d814cd25e299be022a4fa0fb4509d7ccd353d8a", + "reference": "2d814cd25e299be022a4fa0fb4509d7ccd353d8a", + "shasum": "" + }, + "require": { + "dompdf/dompdf": "^3.0", + "illuminate/support": "^9|^10|^11", + "php": "^8.1" + }, + "require-dev": { + "larastan/larastan": "^2.7.0", + "orchestra/testbench": "^7|^8|^9", + "phpro/grumphp": "^2.5", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "PDF": "Barryvdh\\DomPDF\\Facade\\Pdf", + "Pdf": "Barryvdh\\DomPDF\\Facade\\Pdf" + }, + "providers": [ + "Barryvdh\\DomPDF\\ServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Barryvdh\\DomPDF\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "A DOMPDF Wrapper for Laravel", + "keywords": [ + "dompdf", + "laravel", + "pdf" + ], + "support": { + "issues": "https://github.com/barryvdh/laravel-dompdf/issues", + "source": "https://github.com/barryvdh/laravel-dompdf/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2024-07-31T14:45:16+00:00" + }, { "name": "brick/math", "version": "0.12.1", @@ -378,6 +455,161 @@ ], "time": "2024-02-05T11:56:58+00:00" }, + { + "name": "dompdf/dompdf", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/dompdf/dompdf.git", + "reference": "baf4084b27c7f4b5b7a221b19a94d11327664eb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/baf4084b27c7f4b5b7a221b19a94d11327664eb8", + "reference": "baf4084b27c7f4b5b7a221b19a94d11327664eb8", + "shasum": "" + }, + "require": { + "dompdf/php-font-lib": "^1.0.0", + "dompdf/php-svg-lib": "^1.0.0", + "ext-dom": "*", + "ext-mbstring": "*", + "masterminds/html5": "^2.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "ext-gd": "*", + "ext-json": "*", + "ext-zip": "*", + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0" + }, + "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/v3.0.2" + }, + "time": "2024-12-27T20:27:37+00:00" + }, + { + "name": "dompdf/php-font-lib", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-font-lib.git", + "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", + "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0" + }, + "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": "The FontLib Community", + "homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md" + } + ], + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/dompdf/php-font-lib", + "support": { + "issues": "https://github.com/dompdf/php-font-lib/issues", + "source": "https://github.com/dompdf/php-font-lib/tree/1.0.1" + }, + "time": "2024-12-02T14:37:59+00:00" + }, + { + "name": "dompdf/php-svg-lib", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-svg-lib.git", + "reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/eb045e518185298eb6ff8d80d0d0c6b17aecd9af", + "reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af", + "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": "The SvgLib Community", + "homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md" + } + ], + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/dompdf/php-svg-lib", + "support": { + "issues": "https://github.com/dompdf/php-svg-lib/issues", + "source": "https://github.com/dompdf/php-svg-lib/tree/1.0.0" + }, + "time": "2024-04-29T13:26:35+00:00" + }, { "name": "dragonmantank/cron-expression", "version": "v3.4.0", @@ -1893,6 +2125,73 @@ ], "time": "2024-09-21T08:32:55+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": "monolog/monolog", "version": "3.8.0", @@ -3186,6 +3485,71 @@ ], "time": "2024-04-27T21:32:50+00:00" }, + { + "name": "sabberworm/php-css-parser", + "version": "v8.7.0", + "source": { + "type": "git", + "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git", + "reference": "f414ff953002a9b18e3a116f5e462c56f21237cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/f414ff953002a9b18e3a116f5e462c56f21237cf", + "reference": "f414ff953002a9b18e3a116f5e462c56f21237cf", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "require-dev": { + "phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.40" + }, + "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.7.0" + }, + "time": "2024-10-27T17:38:32+00:00" + }, { "name": "symfony/clock", "version": "v7.1.6", diff --git a/config/dompdf.php b/config/dompdf.php new file mode 100644 index 0000000..c37e402 --- /dev/null +++ b/config/dompdf.php @@ -0,0 +1,300 @@ + false, // Throw an Exception on warnings from dompdf + + 'public_path' => null, // Override the public path if needed + + /* + * Dejavu Sans font is missing glyphs for converted entities, turn it off if you need to show € and £. + */ + 'convert_entities' => true, + + 'options' => [ + /** + * The location of the DOMPDF font directory + * + * The location of the directory where DOMPDF will store fonts and font metrics + * Note: This directory must exist and be writable by the webserver process. + * *Please note the trailing slash.* + * + * Notes regarding fonts: + * Additional .afm font metrics can be added by executing load_font.php from command line. + * + * Only the original "Base 14 fonts" are present on all pdf viewers. Additional fonts must + * be embedded in the pdf file or the PDF may not display correctly. This can significantly + * increase file size unless font subsetting is enabled. Before embedding a font please + * review your rights under the font license. + * + * Any font specification in the source HTML is translated to the closest font available + * in the font directory. + * + * The pdf standard "Base 14 fonts" are: + * Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique, + * Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique, + * Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic, + * Symbol, ZapfDingbats. + */ + 'font_dir' => storage_path('fonts'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782) + + /** + * The location of the DOMPDF font cache directory + * + * This directory contains the cached font metrics for the fonts used by DOMPDF. + * This directory can be the same as DOMPDF_FONT_DIR + * + * Note: This directory must exist and be writable by the webserver process. + */ + 'font_cache' => storage_path('fonts'), + + /** + * The location of a temporary directory. + * + * The directory specified must be writeable by the webserver process. + * The temporary directory is required to download remote images and when + * using the PDFLib back end. + */ + 'temp_dir' => sys_get_temp_dir(), + + /** + * ==== IMPORTANT ==== + * + * dompdf's "chroot": Prevents dompdf from accessing system files or other + * files on the webserver. All local files opened by dompdf must be in a + * subdirectory of this directory. DO NOT set it to '/' since this could + * allow an attacker to use dompdf to read any files on the server. This + * should be an absolute path. + * This is only checked on command line call by dompdf.php, but not by + * direct class use like: + * $dompdf = new DOMPDF(); $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output(); + */ + 'chroot' => realpath(base_path()), + + /** + * Protocol whitelist + * + * Protocols and PHP wrappers allowed in URIs, and the validation rules + * that determine if a resouce may be loaded. Full support is not guaranteed + * for the protocols/wrappers specified + * by this array. + * + * @var array + */ + 'allowed_protocols' => [ + 'file://' => ['rules' => []], + 'http://' => ['rules' => []], + 'https://' => ['rules' => []], + ], + + /** + * Operational artifact (log files, temporary files) path validation + */ + 'artifactPathValidation' => null, + + /** + * @var string + */ + 'log_output_file' => null, + + /** + * Whether to enable font subsetting or not. + */ + 'enable_font_subsetting' => false, + + /** + * The PDF rendering backend to use + * + * Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and + * 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will + * fall back on CPDF. 'GD' renders PDFs to graphic files. + * {@link * Canvas_Factory} ultimately determines which rendering class to + * instantiate based on this setting. + * + * Both PDFLib & CPDF rendering backends provide sufficient rendering + * capabilities for dompdf, however additional features (e.g. object, + * image and font support, etc.) differ between backends. Please see + * {@link PDFLib_Adapter} for more information on the PDFLib backend + * and {@link CPDF_Adapter} and lib/class.pdf.php for more information + * on CPDF. Also see the documentation for each backend at the links + * below. + * + * The GD rendering backend is a little different than PDFLib and + * CPDF. Several features of CPDF and PDFLib are not supported or do + * not make any sense when creating image files. For example, + * multiple pages are not supported, nor are PDF 'objects'. Have a + * look at {@link GD_Adapter} for more information. GD support is + * experimental, so use it at your own risk. + * + * @link http://www.pdflib.com + * @link http://www.ros.co.nz/pdf + * @link http://www.php.net/image + */ + 'pdf_backend' => 'CPDF', + + /** + * html target media view which should be rendered into pdf. + * List of types and parsing rules for future extensions: + * http://www.w3.org/TR/REC-html40/types.html + * screen, tty, tv, projection, handheld, print, braille, aural, all + * Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3. + * Note, even though the generated pdf file is intended for print output, + * the desired content might be different (e.g. screen or projection view of html file). + * Therefore allow specification of content here. + */ + 'default_media_type' => 'screen', + + /** + * The default paper size. + * + * North America standard is "letter"; other countries generally "a4" + * + * @see CPDF_Adapter::PAPER_SIZES for valid sizes ('letter', 'legal', 'A4', etc.) + */ + 'default_paper_size' => 'a4', + + /** + * The default paper orientation. + * + * The orientation of the page (portrait or landscape). + * + * @var string + */ + 'default_paper_orientation' => 'portrait', + + /** + * The default font family + * + * Used if no suitable fonts can be found. This must exist in the font folder. + * + * @var string + */ + 'default_font' => 'serif', + + /** + * Image DPI setting + * + * This setting determines the default DPI setting for images and fonts. The + * DPI may be overridden for inline images by explictly setting the + * image's width & height style attributes (i.e. if the image's native + * width is 600 pixels and you specify the image's width as 72 points, + * the image will have a DPI of 600 in the rendered PDF. The DPI of + * background images can not be overridden and is controlled entirely + * via this parameter. + * + * For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI). + * If a size in html is given as px (or without unit as image size), + * this tells the corresponding size in pt. + * This adjusts the relative sizes to be similar to the rendering of the + * html page in a reference browser. + * + * In pdf, always 1 pt = 1/72 inch + * + * Rendering resolution of various browsers in px per inch: + * Windows Firefox and Internet Explorer: + * SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:? + * Linux Firefox: + * about:config *resolution: Default:96 + * (xorg screen dimension in mm and Desktop font dpi settings are ignored) + * + * Take care about extra font/image zoom factor of browser. + * + * In images, size in pixel attribute, img css style, are overriding + * the real image dimension in px for rendering. + * + * @var int + */ + 'dpi' => 96, + + /** + * Enable embedded PHP + * + * If this setting is set to true then DOMPDF will automatically evaluate embedded PHP contained + * within tags. + * + * ==== IMPORTANT ==== Enabling this for documents you do not trust (e.g. arbitrary remote html pages) + * is a security risk. + * Embedded scripts are run with the same level of system access available to dompdf. + * Set this option to false (recommended) if you wish to process untrusted documents. + * This setting may increase the risk of system exploit. + * Do not change this settings without understanding the consequences. + * Additional documentation is available on the dompdf wiki at: + * https://github.com/dompdf/dompdf/wiki + * + * @var bool + */ + 'enable_php' => false, + + /** + * Rnable inline JavaScript + * + * If this setting is set to true then DOMPDF will automatically insert JavaScript code contained + * within tags as written into the PDF. + * NOTE: This is PDF-based JavaScript to be executed by the PDF viewer, + * not browser-based JavaScript executed by Dompdf. + * + * @var bool + */ + 'enable_javascript' => true, + + /** + * Enable remote file access + * + * If this setting is set to true, DOMPDF will access remote sites for + * images and CSS files as required. + * + * ==== IMPORTANT ==== + * This can be a security risk, in particular in combination with isPhpEnabled and + * allowing remote html code to be passed to $dompdf = new DOMPDF(); $dompdf->load_html(...); + * This allows anonymous users to download legally doubtful internet content which on + * tracing back appears to being downloaded by your server, or allows malicious php code + * in remote html pages to be executed by your server with your account privileges. + * + * This setting may increase the risk of system exploit. Do not change + * this settings without understanding the consequences. Additional + * documentation is available on the dompdf wiki at: + * https://github.com/dompdf/dompdf/wiki + * + * @var bool + */ + 'enable_remote' => false, + + /** + * List of allowed remote hosts + * + * Each value of the array must be a valid hostname. + * + * This will be used to filter which resources can be loaded in combination with + * isRemoteEnabled. If enable_remote is FALSE, then this will have no effect. + * + * Leave to NULL to allow any remote host. + * + * @var array|null + */ + 'allowed_remote_hosts' => null, + + /** + * A ratio applied to the fonts height to be more like browsers' line height + */ + 'font_height_ratio' => 1.1, + + /** + * Use the HTML5 Lib parser + * + * @deprecated This feature is now always on in dompdf 2.x + * + * @var bool + */ + 'enable_html5_parser' => true, + ], + +]; diff --git a/lang/de/common.php b/lang/de/common.php index 2777ca2..f552101 100644 --- a/lang/de/common.php +++ b/lang/de/common.php @@ -20,6 +20,9 @@ return [ 'Email' => 'Email', 'Password' => 'Passwort', 'Phone' => 'Telefon', + 'Phone_short' => 'Tel', + 'Web_short' => 'Web', + 'Email_short' => 'Email', 'Address' => 'Adresse', 'Zip Code' => 'Postleitzahl', 'City' => 'Stadt', @@ -29,5 +32,6 @@ return [ 'Confirm' => 'Bestätigen', 'Email Password Reset Link' => 'Email Passwort-Reset Link', 'Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.' => 'Passwort vergessen? Kein Problem. Teilen Sie uns einfach Ihre E-Mail-Adresse mit und wir senden Ihnen per E-Mail einen Link zum Zurücksetzen Ihres Passworts, mit dem Sie ein neues Passwort auswählen können.', + 'Date' => 'Datum', ]; diff --git a/lang/de/configuration.php b/lang/de/configuration.php index 256fa13..fb79dd7 100644 --- a/lang/de/configuration.php +++ b/lang/de/configuration.php @@ -43,5 +43,6 @@ return [ 'Correspondence' => 'Schriftverkehr', 'Color' => 'Farbe', 'Company logo' => 'Firmenlogo', + 'Activity' => 'Tätigkeitsfeld', ]; diff --git a/lang/de/invoice.php b/lang/de/invoice.php index a2c4d5e..ed76e91 100644 --- a/lang/de/invoice.php +++ b/lang/de/invoice.php @@ -29,9 +29,20 @@ return [ 'Description' => 'Beschreibung', 'State' => 'Status', 'Invoice Number' => 'Rechnungsnummer', + 'Invoice Number short' => 'Rechnung-Nr.', 'Sum' => 'Summe', 'Net' => 'Nettobetrag', 'From' => 'Von', 'End' => 'Bis', 'Enter your invoice items. Click add for an additional invoice item.' => 'Gib Deine Rechnungspositionen ein. Klicke auf "Hinzufügen" für weitere Rechnungspositionen.', + 'Item position short' => 'Pos.', + 'Item amount short' => 'Anz.', + 'Item description' => 'Beschreibung', + 'Item single price short' => 'E-Preis', + 'Vat short' => 'MwSt.', + 'Item total price short' => 'G-Preis', + 'Net long' => 'Netto zuzüglich MwSt.', + 'Gross long' => 'Gesamtpreis inkl. gesetzlicher MwSt.', + 'Final sentence' => 'Bitte überweisen Sie den fälligen Rechnungsbetrag in Höhe von :sum bis spätestens :date auf das unten genannte Konto.' + ]; diff --git a/resources/views/components/pdf-icon.blade.php b/resources/views/components/pdf-icon.blade.php new file mode 100644 index 0000000..3fe1517 --- /dev/null +++ b/resources/views/components/pdf-icon.blade.php @@ -0,0 +1,3 @@ +merge(['class' => 'size-8 p-1']) }}>> + + diff --git a/resources/views/invoice/show.blade.php b/resources/views/invoice/show.blade.php index 8b0587e..bf17129 100644 --- a/resources/views/invoice/show.blade.php +++ b/resources/views/invoice/show.blade.php @@ -1,8 +1,13 @@ -

- {{ __('invoice.Invoice') }} {{ $invoice->number }} -

+
+

+ {{ __('invoice.Invoice') }} {{ $invoice->number }} +

+

+ +

+
diff --git a/resources/views/option/index.blade.php b/resources/views/option/index.blade.php index a3398e4..8653ae4 100644 --- a/resources/views/option/index.blade.php +++ b/resources/views/option/index.blade.php @@ -115,6 +115,14 @@ autocomplete="jurisdiction" x-model="options.jurisdiction"/>
+
+ + +
diff --git a/resources/views/pdfs/address.blade.php b/resources/views/pdfs/address.blade.php new file mode 100644 index 0000000..4cad9b7 --- /dev/null +++ b/resources/views/pdfs/address.blade.php @@ -0,0 +1,35 @@ +
+
{{ $options->company_name }}, {{ $options->address }} + , {{ $options->zip }} {{ $options->city }}
+
+
{{ $invoice->address->name }}
+
{{ $invoice->address->address }}
+
 
+
{{ $invoice->address->zip }} {{ $invoice->address->city }}
+
+
+ +
+
{{ __('common.Phone_short') }}:
+
{{ $options->phone }}
+
+
{{ __('common.Email_short') }}:
+
{{ $options->email }}
+
+
{{ __('common.Web_short') }}:
+
{{ $options->website }}
+
+
{!! nl2br($options->activity) !!}
+
+
+ +
+ +
+ {{ __('invoice.Invoice Number short') }}: {{ $invoice->number }} +
+
+
{{ __('common.Date') }}:
+
{{ $invoice->created }}
+
+
diff --git a/resources/views/pdfs/footer.blade.php b/resources/views/pdfs/footer.blade.php new file mode 100644 index 0000000..591cfda --- /dev/null +++ b/resources/views/pdfs/footer.blade.php @@ -0,0 +1,17 @@ +
+
+ + + +
+
+
diff --git a/resources/views/pdfs/header.blade.php b/resources/views/pdfs/header.blade.php new file mode 100644 index 0000000..ef57d5e --- /dev/null +++ b/resources/views/pdfs/header.blade.php @@ -0,0 +1,14 @@ +
+
+
+ +
+
+
{{ $options->company_name }}
+
{{ $options->representative }}
+
{{ $options->address }}
+
{{ $options->zip }} {{ $options->city }}
+
+
+ +
diff --git a/resources/views/pdfs/invoice.blade.php b/resources/views/pdfs/invoice.blade.php new file mode 100644 index 0000000..f85f5fb --- /dev/null +++ b/resources/views/pdfs/invoice.blade.php @@ -0,0 +1,79 @@ + + + + + {{ __('invoice.Invoice') }} + + + + @include('pdfs.header') + + @include('pdfs.footer') + +
+ @include('pdfs.address') + +
+
+
{{ __('invoice.Item position short') }}
+
{{ __('invoice.Item amount short') }}
+
{{ __('invoice.Item description') }}
+
{{ __('invoice.Item single price short') }}
+
{{ __('invoice.Vat short') }}
+
{{ __('invoice.Item total price short') }}
+
+
+ + @foreach ($invoice->items as $key => $item) +
+
{{ $key + 1 }}
+
{{ \Illuminate\Support\Number::format($item->amount) }}
+
{{ $item->name }}
+
{{ \Illuminate\Support\Number::currency($item->price) }}
+
{{ \Illuminate\Support\Number::percentage($item->tax) }}
+
{{ \Illuminate\Support\Number::currency($item->total) }}
+
+
+
{{ $item->description }}
+
{{ \Illuminate\Support\Number::currency($item->amount * $item->price * $item->tax / 100) }}
+
+
+ @endforeach + +
{{ __('invoice.Net long') }}
+
{{ \Illuminate\Support\Number::currency($invoice->sum - $invoice->tax) }}
+
+
+ {{ __('invoice.Vat short') }}
+
{{ \Illuminate\Support\Number::currency($invoice->tax) }}
+
+
+
{{ __('invoice.Gross long') }}
+
{{ \Illuminate\Support\Number::currency($invoice->sum) }}
+
+ +
{{ __('invoice.Final sentence', ['sum' => \Illuminate\Support\Number::currency($invoice->sum), 'date' => \Illuminate\Support\Carbon::parse($invoice->created_at)->addDays(14)->format('d.m.Y')]) }}
+ +
+
+ + + diff --git a/routes/web.php b/routes/web.php index 047e84c..f70e08c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,6 +3,7 @@ use App\Http\Controllers\CustomerController; use App\Http\Controllers\InvoiceController; use App\Http\Controllers\OptionController; +use App\Http\Controllers\PdfController; use App\Http\Controllers\ProfileController; use App\Http\Controllers\TaxrateController; use Illuminate\Support\Facades\Route; @@ -24,6 +25,7 @@ Route::middleware('auth')->group(function () { Route::resource('/taxrate', TaxrateController::class)->only(['index', 'create', 'edit']); Route::resource('/invoice', InvoiceController::class)->only(['index', 'create', 'show', 'edit']); Route::get('/option', [OptionController::class, 'index'])->name('option.index'); + Route::get('/invoice/{id}/download', [PdfController::class, 'downloadInvoice'])->name('invoice.download'); }); require __DIR__.'/auth.php';