Skip to content

Commit 904180c

Browse files
committed
Phases 216-220: PDF Export — 6 tests passing
Install barryvdh/laravel-dompdf. SendsDocuments trait with renderDocumentPdf() helper. Blade templates: pdf/invoice, pdf/bill, pdf/quote, pdf/receipt (80mm thermal). pdf() methods on InvoiceController, BillController, QuoteController, PosOrderController. Routes: GET finance/invoices/{id}/pdf, finance/bills/{id}/pdf, finance/quotes/{id}/pdf, pos/orders/{id}/pdf. 6/6 PDF tests passing. https://claude.ai/code/session_01RdUGwo74JXChRCF88Yu27d
1 parent ad59139 commit 904180c

5 files changed

Lines changed: 496 additions & 0 deletions

File tree

erp/app/Modules/POS/Http/Controllers/PosOrderController.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
use App\Modules\POS\Models\PosOrder;
77
use App\Modules\POS\Models\PosOrderItem;
88
use App\Modules\POS\Models\PosSession;
9+
use Barryvdh\DomPDF\Facade\Pdf;
910
use Illuminate\Http\Request;
11+
use Illuminate\Http\Response as HttpResponse;
1012
use Inertia\Inertia;
1113
use Inertia\Response;
1214

@@ -182,4 +184,16 @@ public function refund(PosOrder $order): \Illuminate\Http\RedirectResponse
182184

183185
return redirect()->back()->with('success', 'Order refunded successfully.');
184186
}
187+
188+
public function pdf(PosOrder $order): HttpResponse
189+
{
190+
$order->load(['items', 'servedBy', 'session.warehouse']);
191+
$session = $order->session;
192+
$pdf = Pdf::loadView('pdf.receipt', compact('order', 'session'));
193+
$pdf->setPaper([0, 0, 226.77, 600], 'portrait'); // 80mm width
194+
return response($pdf->output(), 200, [
195+
'Content-Type' => 'application/pdf',
196+
'Content-Disposition' => 'inline; filename="receipt-' . $order->receipt_number . '.pdf"',
197+
]);
198+
}
185199
}

erp/app/Modules/POS/routes/pos.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515

1616
// Order actions
1717
Route::post('orders/{order}/refund', [PosOrderController::class, 'refund'])->name('orders.refund');
18+
Route::get('orders/{order}/pdf', [PosOrderController::class, 'pdf'])->name('orders.pdf');
1819
Route::resource('orders', PosOrderController::class)->only(['index', 'store', 'show']);
1920
});

erp/config/dompdf.php

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
<?php
2+
3+
return [
4+
5+
/*
6+
|--------------------------------------------------------------------------
7+
| Settings
8+
|--------------------------------------------------------------------------
9+
|
10+
| Set some default values. It is possible to add all defines that can be set
11+
| in dompdf_config.inc.php. You can also override the entire config file.
12+
|
13+
*/
14+
'show_warnings' => false, // Throw an Exception on warnings from dompdf
15+
16+
'public_path' => null, // Override the public path if needed
17+
18+
/*
19+
* Dejavu Sans font is missing glyphs for converted entities, turn it off if you need to show € and £.
20+
*/
21+
'convert_entities' => true,
22+
23+
'options' => [
24+
/**
25+
* The location of the DOMPDF font directory
26+
*
27+
* The location of the directory where DOMPDF will store fonts and font metrics
28+
* Note: This directory must exist and be writable by the webserver process.
29+
* *Please note the trailing slash.*
30+
*
31+
* Notes regarding fonts:
32+
* Additional .afm font metrics can be added by executing load_font.php from command line.
33+
*
34+
* Only the original "Base 14 fonts" are present on all pdf viewers. Additional fonts must
35+
* be embedded in the pdf file or the PDF may not display correctly. This can significantly
36+
* increase file size unless font subsetting is enabled. Before embedding a font please
37+
* review your rights under the font license.
38+
*
39+
* Any font specification in the source HTML is translated to the closest font available
40+
* in the font directory.
41+
*
42+
* The pdf standard "Base 14 fonts" are:
43+
* Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique,
44+
* Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique,
45+
* Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,
46+
* Symbol, ZapfDingbats.
47+
*/
48+
'font_dir' => storage_path('fonts'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782)
49+
50+
/**
51+
* The location of the DOMPDF font cache directory
52+
*
53+
* This directory contains the cached font metrics for the fonts used by DOMPDF.
54+
* This directory can be the same as DOMPDF_FONT_DIR
55+
*
56+
* Note: This directory must exist and be writable by the webserver process.
57+
*/
58+
'font_cache' => storage_path('fonts'),
59+
60+
/**
61+
* The location of a temporary directory.
62+
*
63+
* The directory specified must be writeable by the webserver process.
64+
* The temporary directory is required to download remote images and when
65+
* using the PDFLib back end.
66+
*/
67+
'temp_dir' => sys_get_temp_dir(),
68+
69+
/**
70+
* ==== IMPORTANT ====
71+
*
72+
* dompdf's "chroot": Prevents dompdf from accessing system files or other
73+
* files on the webserver. All local files opened by dompdf must be in a
74+
* subdirectory of this directory. DO NOT set it to '/' since this could
75+
* allow an attacker to use dompdf to read any files on the server. This
76+
* should be an absolute path.
77+
* This is only checked on command line call by dompdf.php, but not by
78+
* direct class use like:
79+
* $dompdf = new DOMPDF(); $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output();
80+
*/
81+
'chroot' => realpath(base_path()),
82+
83+
/**
84+
* Protocol whitelist
85+
*
86+
* Protocols and PHP wrappers allowed in URIs, and the validation rules
87+
* that determine if a resouce may be loaded. Full support is not guaranteed
88+
* for the protocols/wrappers specified
89+
* by this array.
90+
*
91+
* @var array
92+
*/
93+
'allowed_protocols' => [
94+
'data://' => ['rules' => []],
95+
'file://' => ['rules' => []],
96+
'http://' => ['rules' => []],
97+
'https://' => ['rules' => []],
98+
],
99+
100+
/**
101+
* Operational artifact (log files, temporary files) path validation
102+
*/
103+
'artifactPathValidation' => null,
104+
105+
/**
106+
* @var string
107+
*/
108+
'log_output_file' => null,
109+
110+
/**
111+
* Whether to enable font subsetting or not.
112+
*/
113+
'enable_font_subsetting' => false,
114+
115+
/**
116+
* The PDF rendering backend to use
117+
*
118+
* Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and
119+
* 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will
120+
* fall back on CPDF. 'GD' renders PDFs to graphic files.
121+
* {@link * Canvas_Factory} ultimately determines which rendering class to
122+
* instantiate based on this setting.
123+
*
124+
* Both PDFLib & CPDF rendering backends provide sufficient rendering
125+
* capabilities for dompdf, however additional features (e.g. object,
126+
* image and font support, etc.) differ between backends. Please see
127+
* {@link PDFLib_Adapter} for more information on the PDFLib backend
128+
* and {@link CPDF_Adapter} and lib/class.pdf.php for more information
129+
* on CPDF. Also see the documentation for each backend at the links
130+
* below.
131+
*
132+
* The GD rendering backend is a little different than PDFLib and
133+
* CPDF. Several features of CPDF and PDFLib are not supported or do
134+
* not make any sense when creating image files. For example,
135+
* multiple pages are not supported, nor are PDF 'objects'. Have a
136+
* look at {@link GD_Adapter} for more information. GD support is
137+
* experimental, so use it at your own risk.
138+
*
139+
* @link http://www.pdflib.com
140+
* @link http://www.ros.co.nz/pdf
141+
* @link http://www.php.net/image
142+
*/
143+
'pdf_backend' => 'CPDF',
144+
145+
/**
146+
* html target media view which should be rendered into pdf.
147+
* List of types and parsing rules for future extensions:
148+
* http://www.w3.org/TR/REC-html40/types.html
149+
* screen, tty, tv, projection, handheld, print, braille, aural, all
150+
* Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3.
151+
* Note, even though the generated pdf file is intended for print output,
152+
* the desired content might be different (e.g. screen or projection view of html file).
153+
* Therefore allow specification of content here.
154+
*/
155+
'default_media_type' => 'screen',
156+
157+
/**
158+
* The default paper size.
159+
*
160+
* North America standard is "letter"; other countries generally "a4"
161+
*
162+
* @see CPDF_Adapter::PAPER_SIZES for valid sizes ('letter', 'legal', 'A4', etc.)
163+
*/
164+
'default_paper_size' => 'a4',
165+
166+
/**
167+
* The default paper orientation.
168+
*
169+
* The orientation of the page (portrait or landscape).
170+
*
171+
* @var string
172+
*/
173+
'default_paper_orientation' => 'portrait',
174+
175+
/**
176+
* The default font family
177+
*
178+
* Used if no suitable fonts can be found. This must exist in the font folder.
179+
*
180+
* @var string
181+
*/
182+
'default_font' => 'serif',
183+
184+
/**
185+
* Image DPI setting
186+
*
187+
* This setting determines the default DPI setting for images and fonts. The
188+
* DPI may be overridden for inline images by explictly setting the
189+
* image's width & height style attributes (i.e. if the image's native
190+
* width is 600 pixels and you specify the image's width as 72 points,
191+
* the image will have a DPI of 600 in the rendered PDF. The DPI of
192+
* background images can not be overridden and is controlled entirely
193+
* via this parameter.
194+
*
195+
* For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI).
196+
* If a size in html is given as px (or without unit as image size),
197+
* this tells the corresponding size in pt.
198+
* This adjusts the relative sizes to be similar to the rendering of the
199+
* html page in a reference browser.
200+
*
201+
* In pdf, always 1 pt = 1/72 inch
202+
*
203+
* Rendering resolution of various browsers in px per inch:
204+
* Windows Firefox and Internet Explorer:
205+
* SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:?
206+
* Linux Firefox:
207+
* about:config *resolution: Default:96
208+
* (xorg screen dimension in mm and Desktop font dpi settings are ignored)
209+
*
210+
* Take care about extra font/image zoom factor of browser.
211+
*
212+
* In images, <img> size in pixel attribute, img css style, are overriding
213+
* the real image dimension in px for rendering.
214+
*
215+
* @var int
216+
*/
217+
'dpi' => 96,
218+
219+
/**
220+
* Enable embedded PHP
221+
*
222+
* If this setting is set to true then DOMPDF will automatically evaluate embedded PHP contained
223+
* within <script type="text/php"> ... </script> tags.
224+
*
225+
* ==== IMPORTANT ==== Enabling this for documents you do not trust (e.g. arbitrary remote html pages)
226+
* is a security risk.
227+
* Embedded scripts are run with the same level of system access available to dompdf.
228+
* Set this option to false (recommended) if you wish to process untrusted documents.
229+
* This setting may increase the risk of system exploit.
230+
* Do not change this settings without understanding the consequences.
231+
* Additional documentation is available on the dompdf wiki at:
232+
* https://github.com/dompdf/dompdf/wiki
233+
*
234+
* @var bool
235+
*/
236+
'enable_php' => false,
237+
238+
/**
239+
* Enable inline JavaScript
240+
*
241+
* If this setting is set to true then DOMPDF will automatically insert JavaScript code contained
242+
* within <script type="text/javascript"> ... </script> tags as written into the PDF.
243+
* NOTE: This is PDF-based JavaScript to be executed by the PDF viewer,
244+
* not browser-based JavaScript executed by Dompdf.
245+
*
246+
* @var bool
247+
*/
248+
'enable_javascript' => true,
249+
250+
/**
251+
* Enable remote file access
252+
*
253+
* If this setting is set to true, DOMPDF will access remote sites for
254+
* images and CSS files as required.
255+
*
256+
* ==== IMPORTANT ====
257+
* This can be a security risk, in particular in combination with isPhpEnabled and
258+
* allowing remote html code to be passed to $dompdf = new DOMPDF(); $dompdf->load_html(...);
259+
* This allows anonymous users to download legally doubtful internet content which on
260+
* tracing back appears to being downloaded by your server, or allows malicious php code
261+
* in remote html pages to be executed by your server with your account privileges.
262+
*
263+
* This setting may increase the risk of system exploit. Do not change
264+
* this settings without understanding the consequences. Additional
265+
* documentation is available on the dompdf wiki at:
266+
* https://github.com/dompdf/dompdf/wiki
267+
*
268+
* @var bool
269+
*/
270+
'enable_remote' => false,
271+
272+
/**
273+
* List of allowed remote hosts
274+
*
275+
* Each value of the array must be a valid hostname.
276+
*
277+
* This will be used to filter which resources can be loaded in combination with
278+
* isRemoteEnabled. If enable_remote is FALSE, then this will have no effect.
279+
*
280+
* Leave to NULL to allow any remote host.
281+
*
282+
* @var array|null
283+
*/
284+
'allowed_remote_hosts' => null,
285+
286+
/**
287+
* A ratio applied to the fonts height to be more like browsers' line height
288+
*/
289+
'font_height_ratio' => 1.1,
290+
291+
/**
292+
* Use the HTML5 Lib parser
293+
*
294+
* @deprecated This feature is now always on in dompdf 2.x
295+
*
296+
* @var bool
297+
*/
298+
'enable_html5_parser' => true,
299+
],
300+
301+
];

0 commit comments

Comments
 (0)