invoice_printer 1.0.0 → 1.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +62 -5
- data/bin/invoice_printer +140 -0
- data/examples/complex_invoice.rb +11 -1
- data/examples/czech_invoice.rb +12 -0
- data/examples/international_invoice.rb +9 -0
- data/examples/long_invoice.rb +9 -1
- data/examples/promo.rb +9 -0
- data/examples/simple_invoice.rb +7 -0
- data/invoice_printer.gemspec +1 -0
- data/lib/invoice_printer/document/item.rb +37 -21
- data/lib/invoice_printer/document.rb +130 -90
- data/lib/invoice_printer/pdf_document.rb +153 -108
- data/lib/invoice_printer/version.rb +1 -1
- data/lib/invoice_printer.rb +6 -4
- data/test/cli_test.rb +76 -0
- data/test/examples_test.rb +5 -0
- data/test/inputs_test.rb +9 -0
- data/test/invoice_printer_test.rb +13 -2
- metadata +9 -5
@@ -17,6 +17,7 @@ module InvoicePrinter
|
|
17
17
|
class PDFDocument
|
18
18
|
class FontFileNotFound < StandardError; end
|
19
19
|
class LogoFileNotFound < StandardError; end
|
20
|
+
class StampFileNotFound < StandardError; end
|
20
21
|
class InvalidInput < StandardError; end
|
21
22
|
|
22
23
|
attr_reader :invoice, :labels, :file_name, :font, :stamp, :logo
|
@@ -45,7 +46,14 @@ module InvoicePrinter
|
|
45
46
|
amount: 'Amount',
|
46
47
|
subtotal: 'Subtotal',
|
47
48
|
total: 'Total',
|
48
|
-
sublabels: {}
|
49
|
+
sublabels: {},
|
50
|
+
}
|
51
|
+
|
52
|
+
PageSize = Struct.new(:name, :width, :height)
|
53
|
+
|
54
|
+
PAGE_SIZES = {
|
55
|
+
letter: PageSize.new('LETTER', 612.00, 792.00),
|
56
|
+
a4: PageSize.new('A4', 595.28, 841.89),
|
49
57
|
}
|
50
58
|
|
51
59
|
def self.labels
|
@@ -56,13 +64,14 @@ module InvoicePrinter
|
|
56
64
|
@@labels = DEFAULT_LABELS.merge(labels)
|
57
65
|
end
|
58
66
|
|
59
|
-
def initialize(document: Document.new, labels: {}, font: nil, stamp: nil, logo: nil, background: nil)
|
60
|
-
@document
|
61
|
-
@labels
|
62
|
-
@
|
63
|
-
@
|
64
|
-
@
|
65
|
-
@
|
67
|
+
def initialize(document: Document.new, labels: {}, font: nil, stamp: nil, logo: nil, background: nil, page_size: :letter)
|
68
|
+
@document = document
|
69
|
+
@labels = PDFDocument.labels.merge(labels)
|
70
|
+
@page_size = PAGE_SIZES[page_size.to_sym]
|
71
|
+
@pdf = Prawn::Document.new(background: background, page_size: @page_size.name)
|
72
|
+
@font = font
|
73
|
+
@stamp = stamp
|
74
|
+
@logo = logo
|
66
75
|
|
67
76
|
raise InvalidInput, 'document is not a type of InvoicePrinter::Document' \
|
68
77
|
unless @document.is_a?(InvoicePrinter::Document)
|
@@ -75,6 +84,14 @@ module InvoicePrinter
|
|
75
84
|
end
|
76
85
|
end
|
77
86
|
|
87
|
+
if used? @stamp
|
88
|
+
if File.exist?(@stamp)
|
89
|
+
@stamp = stamp
|
90
|
+
else
|
91
|
+
raise StampFileNotFound, "Stamp file not found at #{@stamp}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
78
95
|
if used? @font
|
79
96
|
if File.exist?(@font)
|
80
97
|
set_fonts(@font) if @font
|
@@ -138,17 +155,17 @@ module InvoicePrinter
|
|
138
155
|
@pdf.text_box(
|
139
156
|
@labels[:name],
|
140
157
|
size: 20,
|
141
|
-
|
142
|
-
|
143
|
-
|
158
|
+
align: :left,
|
159
|
+
at: [0, y(720) - @push_down],
|
160
|
+
width: x(300),
|
144
161
|
)
|
145
162
|
|
146
163
|
if used? @labels[:sublabels][:name]
|
147
164
|
@pdf.text_box(
|
148
165
|
@labels[:sublabels][:name],
|
149
166
|
size: 12,
|
150
|
-
at: [0, 720 - @push_down - 22],
|
151
|
-
width: 300,
|
167
|
+
at: [0, y(720) - @push_down - 22],
|
168
|
+
width: x(300),
|
152
169
|
align: :left
|
153
170
|
)
|
154
171
|
end
|
@@ -156,10 +173,11 @@ module InvoicePrinter
|
|
156
173
|
@pdf.text_box(
|
157
174
|
@document.number,
|
158
175
|
size: 20,
|
159
|
-
at: [240, 720 - @push_down],
|
160
|
-
width: 300,
|
176
|
+
at: [x(240), y(720) - @push_down],
|
177
|
+
width: x(300),
|
161
178
|
align: :right
|
162
179
|
)
|
180
|
+
|
163
181
|
@pdf.move_down(250)
|
164
182
|
|
165
183
|
if used? @labels[:sublabels][:name]
|
@@ -184,75 +202,75 @@ module InvoicePrinter
|
|
184
202
|
@pdf.text_box(
|
185
203
|
@document.provider_name,
|
186
204
|
size: 15,
|
187
|
-
at: [10, 640 - @push_down],
|
188
|
-
width:
|
205
|
+
at: [10, y(640) - @push_down],
|
206
|
+
width: x(220)
|
189
207
|
)
|
190
208
|
@pdf.text_box(
|
191
209
|
@labels[:provider],
|
192
210
|
size: 11,
|
193
|
-
at: [10, 660 - @push_down],
|
194
|
-
width: 240
|
211
|
+
at: [10, y(660) - @push_down],
|
212
|
+
width: x(240)
|
195
213
|
)
|
196
214
|
if used? @labels[:sublabels][:provider]
|
197
215
|
@pdf.text_box(
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
216
|
+
@labels[:sublabels][:provider],
|
217
|
+
size: 10,
|
218
|
+
at: [10, y(660) - @push_down],
|
219
|
+
width: x(246),
|
220
|
+
align: :right
|
221
|
+
)
|
204
222
|
end
|
205
223
|
@pdf.text_box(
|
206
224
|
"#{@document.provider_street} #{@document.provider_street_number}",
|
207
225
|
size: 10,
|
208
|
-
at: [10, 620 - @push_down],
|
209
|
-
width: 240
|
226
|
+
at: [10, y(620) - @push_down],
|
227
|
+
width: x(240)
|
210
228
|
)
|
211
229
|
@pdf.text_box(
|
212
230
|
@document.provider_postcode,
|
213
231
|
size: 10,
|
214
|
-
at: [10, 605 - @push_down],
|
215
|
-
width: 240
|
232
|
+
at: [10, y(605) - @push_down],
|
233
|
+
width: x(240)
|
216
234
|
)
|
217
235
|
@pdf.text_box(
|
218
236
|
@document.provider_city,
|
219
237
|
size: 10,
|
220
|
-
at: [60, 605 - @push_down],
|
221
|
-
width: 240
|
238
|
+
at: [60, y(605) - @push_down],
|
239
|
+
width: x(240)
|
222
240
|
)
|
223
241
|
unless @document.provider_city_part.empty?
|
224
242
|
@pdf.text_box(
|
225
243
|
@document.provider_city_part,
|
226
244
|
size: 10,
|
227
|
-
at: [60, 590 - @push_down],
|
228
|
-
width: 240
|
245
|
+
at: [60, y(590) - @push_down],
|
246
|
+
width: x(240)
|
229
247
|
)
|
230
248
|
end
|
231
249
|
unless @document.provider_extra_address_line.empty?
|
232
250
|
@pdf.text_box(
|
233
251
|
@document.provider_extra_address_line,
|
234
252
|
size: 10,
|
235
|
-
at: [10, 575 - @push_down],
|
236
|
-
width: 240
|
253
|
+
at: [10, y(575) - @push_down],
|
254
|
+
width: x(240)
|
237
255
|
)
|
238
256
|
end
|
239
257
|
unless @document.provider_tax_id.empty?
|
240
258
|
@pdf.text_box(
|
241
259
|
"#{@labels[:tax_id]}: #{@document.provider_tax_id}",
|
242
260
|
size: 10,
|
243
|
-
at: [10, 550 - @push_down],
|
244
|
-
width: 240
|
261
|
+
at: [10, y(550) - @push_down],
|
262
|
+
width: x(240)
|
245
263
|
)
|
246
264
|
end
|
247
265
|
unless @document.provider_tax_id2.empty?
|
248
266
|
@pdf.text_box(
|
249
267
|
"#{@labels[:tax_id2]}: #{@document.provider_tax_id2}",
|
250
268
|
size: 10,
|
251
|
-
at: [10, 535 - @push_down],
|
252
|
-
width: 240
|
269
|
+
at: [10, y(535) - @push_down],
|
270
|
+
width: x(240)
|
253
271
|
)
|
254
272
|
end
|
255
|
-
@pdf.stroke_rounded_rectangle([0, 670 - @push_down],
|
273
|
+
@pdf.stroke_rounded_rectangle([0, y(670) - @push_down], x(266), y(150), 6)
|
256
274
|
end
|
257
275
|
|
258
276
|
# Build the following purchaser box:
|
@@ -272,75 +290,76 @@ module InvoicePrinter
|
|
272
290
|
@pdf.text_box(
|
273
291
|
@document.purchaser_name,
|
274
292
|
size: 15,
|
275
|
-
at: [
|
276
|
-
width: 240
|
293
|
+
at: [x(284), y(640) - @push_down],
|
294
|
+
width: x(240)
|
277
295
|
)
|
278
296
|
@pdf.text_box(
|
279
297
|
@labels[:purchaser],
|
280
298
|
size: 11,
|
281
|
-
at: [
|
282
|
-
width: 240
|
299
|
+
at: [x(284), y(660) - @push_down],
|
300
|
+
width: x(240)
|
283
301
|
)
|
284
302
|
|
285
303
|
if used? @labels[:sublabels][:purchaser]
|
286
304
|
@pdf.text_box(
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
305
|
+
@labels[:sublabels][:purchaser],
|
306
|
+
size: 10,
|
307
|
+
at: [10, y(660) - @push_down],
|
308
|
+
width: x(520),
|
309
|
+
align: :right
|
310
|
+
)
|
292
311
|
end
|
293
312
|
@pdf.text_box(
|
294
313
|
"#{@document.purchaser_street} #{@document.purchaser_street_number}",
|
295
314
|
size: 10,
|
296
|
-
at: [
|
297
|
-
width: 240
|
315
|
+
at: [x(284), y(620) - @push_down],
|
316
|
+
width: x(240)
|
298
317
|
)
|
299
318
|
@pdf.text_box(
|
300
319
|
@document.purchaser_postcode,
|
301
320
|
size: 10,
|
302
|
-
at: [
|
303
|
-
width: 240
|
321
|
+
at: [x(284), y(605) - @push_down],
|
322
|
+
width: x(240)
|
304
323
|
)
|
305
324
|
@pdf.text_box(
|
306
325
|
@document.purchaser_city,
|
307
326
|
size: 10,
|
308
|
-
at: [
|
309
|
-
width: 240
|
327
|
+
at: [x(334), y(605) - @push_down],
|
328
|
+
width: x(240)
|
310
329
|
)
|
311
330
|
unless @document.purchaser_city_part.empty?
|
312
331
|
@pdf.text_box(
|
313
332
|
@document.purchaser_city_part,
|
314
333
|
size: 10,
|
315
|
-
at: [
|
316
|
-
width: 240
|
334
|
+
at: [x(334), y(590) - @push_down],
|
335
|
+
width: x(240)
|
317
336
|
)
|
318
337
|
end
|
319
338
|
unless @document.purchaser_extra_address_line.empty?
|
320
339
|
@pdf.text_box(
|
321
340
|
@document.purchaser_extra_address_line,
|
322
341
|
size: 10,
|
323
|
-
at: [
|
324
|
-
width: 240
|
342
|
+
at: [x(284), y(575) - @push_down],
|
343
|
+
width: x(240)
|
325
344
|
)
|
326
345
|
end
|
327
|
-
unless @document.
|
346
|
+
unless @document.purchaser_tax_id.empty?
|
328
347
|
@pdf.text_box(
|
329
|
-
"#{@labels[:
|
348
|
+
"#{@labels[:tax_id]}: #{@document.purchaser_tax_id}",
|
330
349
|
size: 10,
|
331
|
-
at: [
|
332
|
-
width: 240
|
350
|
+
at: [x(284), y(550) - @push_down],
|
351
|
+
width: x(240)
|
333
352
|
)
|
334
353
|
end
|
335
|
-
unless @document.
|
354
|
+
unless @document.purchaser_tax_id2.empty?
|
336
355
|
@pdf.text_box(
|
337
|
-
"#{@labels[:
|
356
|
+
"#{@labels[:tax_id2]}: #{@document.purchaser_tax_id2}",
|
338
357
|
size: 10,
|
339
|
-
at: [
|
340
|
-
width: 240
|
358
|
+
at: [x(284), y(535) - @push_down],
|
359
|
+
width: x(240)
|
341
360
|
)
|
342
361
|
end
|
343
|
-
@pdf.stroke_rounded_rectangle([
|
362
|
+
@pdf.stroke_rounded_rectangle([x(274), y(670) - @push_down], x(266), y(150), 6)
|
344
363
|
end
|
345
364
|
|
346
365
|
# Build the following payment box:
|
@@ -360,6 +379,10 @@ module InvoicePrinter
|
|
360
379
|
def build_payment_method_box
|
361
380
|
@push_down -= 3
|
362
381
|
|
382
|
+
unless letter?
|
383
|
+
@push_items_table += 18
|
384
|
+
end
|
385
|
+
|
363
386
|
# Match the height of next box if needed
|
364
387
|
# TODO: it's smaller without sublabels
|
365
388
|
min_height = 60
|
@@ -372,14 +395,14 @@ module InvoicePrinter
|
|
372
395
|
@pdf.text_box(
|
373
396
|
@labels[:payment],
|
374
397
|
size: 10,
|
375
|
-
at: [10, 498 - @push_down],
|
376
|
-
width:
|
398
|
+
at: [10, y(498) - @push_down],
|
399
|
+
width: x(234)
|
377
400
|
)
|
378
401
|
@pdf.text_box(
|
379
402
|
@labels[:payment_in_cash],
|
380
403
|
size: 10,
|
381
|
-
at: [10, 483 - @push_down],
|
382
|
-
width:
|
404
|
+
at: [10, y(483) - @push_down],
|
405
|
+
width: x(234)
|
383
406
|
)
|
384
407
|
@pdf.stroke_rounded_rectangle([0, 508 - @push_down], 270, 45, 6)
|
385
408
|
else
|
@@ -389,28 +412,28 @@ module InvoicePrinter
|
|
389
412
|
@pdf.text_box(
|
390
413
|
@labels[:payment_by_transfer],
|
391
414
|
size: 10,
|
392
|
-
at: [10, 498 - @push_down],
|
393
|
-
width:
|
415
|
+
at: [10, y(498) - @push_down],
|
416
|
+
width: x(234)
|
394
417
|
)
|
395
418
|
@pdf.text_box(
|
396
419
|
"#{@labels[:account_number]}",
|
397
420
|
size: 11,
|
398
|
-
at: [10, 483 - @push_down],
|
399
|
-
width:
|
421
|
+
at: [10, y(483) - @push_down],
|
422
|
+
width: x(134)
|
400
423
|
)
|
401
424
|
@pdf.text_box(
|
402
425
|
@document.bank_account_number,
|
403
426
|
size: 13,
|
404
|
-
at: [21, 483 - @push_down],
|
405
|
-
width:
|
427
|
+
at: [21, y(483) - @push_down],
|
428
|
+
width: x(234),
|
406
429
|
align: :right
|
407
430
|
)
|
408
431
|
if used? @labels[:sublabels][:account_number]
|
409
432
|
@pdf.text_box(
|
410
433
|
"#{@labels[:sublabels][:account_number]}",
|
411
434
|
size: 10,
|
412
|
-
at: [10, 468 - @push_down],
|
413
|
-
width:
|
435
|
+
at: [10, y(468) - @push_down],
|
436
|
+
width: x(334)
|
414
437
|
)
|
415
438
|
else
|
416
439
|
@payment_box_height -= 10
|
@@ -420,14 +443,14 @@ module InvoicePrinter
|
|
420
443
|
@pdf.text_box(
|
421
444
|
"#{@labels[:swift]}",
|
422
445
|
size: 11,
|
423
|
-
at: [10, 453 - @push_down - sublabel_change],
|
424
|
-
width:
|
446
|
+
at: [10, y(453) - @push_down - sublabel_change],
|
447
|
+
width: x(134)
|
425
448
|
)
|
426
449
|
@pdf.text_box(
|
427
450
|
@document.account_swift,
|
428
451
|
size: 13,
|
429
|
-
at: [21, 453 - @push_down - sublabel_change],
|
430
|
-
width:
|
452
|
+
at: [21, y(453) - @push_down - sublabel_change],
|
453
|
+
width: x(234),
|
431
454
|
align: :right
|
432
455
|
)
|
433
456
|
|
@@ -435,8 +458,8 @@ module InvoicePrinter
|
|
435
458
|
@pdf.text_box(
|
436
459
|
"#{@labels[:sublabels][:swift]}",
|
437
460
|
size: 10,
|
438
|
-
at: [10, 438 - @push_down - sublabel_change],
|
439
|
-
width:
|
461
|
+
at: [10, y(438) - @push_down - sublabel_change],
|
462
|
+
width: x(334)
|
440
463
|
)
|
441
464
|
@push_items_table += 10
|
442
465
|
else
|
@@ -452,14 +475,14 @@ module InvoicePrinter
|
|
452
475
|
@pdf.text_box(
|
453
476
|
"#{@labels[:iban]}",
|
454
477
|
size: 11,
|
455
|
-
at: [10, 453 - @push_iban - @push_down - sublabel_change],
|
456
|
-
width:
|
478
|
+
at: [10, y(453) - @push_iban - @push_down - sublabel_change],
|
479
|
+
width: x(134)
|
457
480
|
)
|
458
481
|
@pdf.text_box(
|
459
482
|
@document.account_iban,
|
460
483
|
size: 13,
|
461
|
-
at: [21, 453 - @push_iban - @push_down - sublabel_change],
|
462
|
-
width:
|
484
|
+
at: [21, y(453) - @push_iban - @push_down - sublabel_change],
|
485
|
+
width: x(234),
|
463
486
|
align: :right
|
464
487
|
)
|
465
488
|
|
@@ -467,8 +490,8 @@ module InvoicePrinter
|
|
467
490
|
@pdf.text_box(
|
468
491
|
"#{@labels[:sublabels][:iban]}",
|
469
492
|
size: 10,
|
470
|
-
at: [10, 438 - @push_iban - @push_down - sublabel_change],
|
471
|
-
width:
|
493
|
+
at: [10, y(438) - @push_iban - @push_down - sublabel_change],
|
494
|
+
width: x(334)
|
472
495
|
)
|
473
496
|
@push_items_table += 10
|
474
497
|
else
|
@@ -487,7 +510,7 @@ module InvoicePrinter
|
|
487
510
|
@push_items_table += 2
|
488
511
|
end
|
489
512
|
|
490
|
-
@pdf.stroke_rounded_rectangle([0, 508 - @push_down],
|
513
|
+
@pdf.stroke_rounded_rectangle([0, y(508) - @push_down], x(266), @payment_box_height, 6)
|
491
514
|
end
|
492
515
|
end
|
493
516
|
|
@@ -507,13 +530,14 @@ module InvoicePrinter
|
|
507
530
|
@pdf.text_box(
|
508
531
|
@labels[:issue_date],
|
509
532
|
size: 11,
|
510
|
-
at: [
|
511
|
-
width: 240
|
533
|
+
at: [x(284), y(498) - @push_down],
|
534
|
+
width: x(240)
|
512
535
|
)
|
513
536
|
@pdf.text_box(
|
514
537
|
@document.issue_date,
|
515
538
|
size: 13,
|
516
|
-
at: [
|
539
|
+
at: [x(384), y(498) - @push_down],
|
540
|
+
width: x(146),
|
517
541
|
align: :right
|
518
542
|
)
|
519
543
|
end
|
@@ -524,8 +548,8 @@ module InvoicePrinter
|
|
524
548
|
@pdf.text_box(
|
525
549
|
@labels[:sublabels][:issue_date],
|
526
550
|
size: 10,
|
527
|
-
at: [
|
528
|
-
width: 240
|
551
|
+
at: [x(284), y(position) - @push_down],
|
552
|
+
width: x(240)
|
529
553
|
)
|
530
554
|
end
|
531
555
|
|
@@ -538,13 +562,14 @@ module InvoicePrinter
|
|
538
562
|
@pdf.text_box(
|
539
563
|
@labels[:due_date],
|
540
564
|
size: 11,
|
541
|
-
at: [
|
542
|
-
width: 240
|
565
|
+
at: [x(284), y(position) - @push_down],
|
566
|
+
width: x(240)
|
543
567
|
)
|
544
568
|
@pdf.text_box(
|
545
569
|
@document.due_date,
|
546
570
|
size: 13,
|
547
|
-
at: [
|
571
|
+
at: [x(384), y(position) - @push_down],
|
572
|
+
width: x(146),
|
548
573
|
align: :right
|
549
574
|
)
|
550
575
|
end
|
@@ -556,8 +581,8 @@ module InvoicePrinter
|
|
556
581
|
@pdf.text_box(
|
557
582
|
@labels[:sublabels][:due_date],
|
558
583
|
size: 10,
|
559
|
-
at: [
|
560
|
-
width: 240
|
584
|
+
at: [x(284), y(position) - @push_down],
|
585
|
+
width: x(240)
|
561
586
|
)
|
562
587
|
end
|
563
588
|
|
@@ -565,7 +590,7 @@ module InvoicePrinter
|
|
565
590
|
height = (issue_date_present && due_date_present) ? 75 : 60
|
566
591
|
height = @payment_box_height if @payment_box_height > height
|
567
592
|
|
568
|
-
@pdf.stroke_rounded_rectangle([
|
593
|
+
@pdf.stroke_rounded_rectangle([x(274), y(508) - @push_down], x(266), height, 6)
|
569
594
|
end
|
570
595
|
end
|
571
596
|
|
@@ -598,7 +623,7 @@ module InvoicePrinter
|
|
598
623
|
styles = {
|
599
624
|
headers: headers,
|
600
625
|
row_colors: ['F5F5F5', nil],
|
601
|
-
width:
|
626
|
+
width: x(540, 2),
|
602
627
|
align: {
|
603
628
|
0 => :left,
|
604
629
|
1 => :right,
|
@@ -698,7 +723,7 @@ module InvoicePrinter
|
|
698
723
|
"#{@labels[:tax]}#{@document.tax}".size,
|
699
724
|
"#{@labels[:tax2]}#{@document.tax2}".size,
|
700
725
|
"#{@labels[:tax3]}#{@document.tax3}".size
|
701
|
-
].max *
|
726
|
+
].max * 8
|
702
727
|
|
703
728
|
styles = {
|
704
729
|
border_width: 0,
|
@@ -708,7 +733,7 @@ module InvoicePrinter
|
|
708
733
|
}
|
709
734
|
}
|
710
735
|
|
711
|
-
@pdf.span(width, position: :right) do
|
736
|
+
@pdf.span(x(width), position: :right) do
|
712
737
|
@pdf.table(items, styles) unless items.empty?
|
713
738
|
end
|
714
739
|
|
@@ -767,7 +792,7 @@ module InvoicePrinter
|
|
767
792
|
"#{@document.note}",
|
768
793
|
size: 10,
|
769
794
|
at: [0, 10],
|
770
|
-
width: 450,
|
795
|
+
width: x(450),
|
771
796
|
align: :left
|
772
797
|
)
|
773
798
|
end
|
@@ -786,5 +811,25 @@ module InvoicePrinter
|
|
786
811
|
def used?(element)
|
787
812
|
element && !element.empty?
|
788
813
|
end
|
814
|
+
|
815
|
+
def letter?
|
816
|
+
@page_size.name == 'LETTER'
|
817
|
+
end
|
818
|
+
|
819
|
+
# Return correct x/width relative to page size
|
820
|
+
def x(value, adjust = 1)
|
821
|
+
return value if letter?
|
822
|
+
|
823
|
+
width_ratio = value / PAGE_SIZES[:letter].width
|
824
|
+
(width_ratio * @page_size.width) - adjust
|
825
|
+
end
|
826
|
+
|
827
|
+
# Return correct y/height relative to page size
|
828
|
+
def y(value)
|
829
|
+
return value if letter?
|
830
|
+
|
831
|
+
width_ratio = value / PAGE_SIZES[:letter].height
|
832
|
+
width_ratio * @page_size.height
|
833
|
+
end
|
789
834
|
end
|
790
835
|
end
|
data/lib/invoice_printer.rb
CHANGED
@@ -62,14 +62,15 @@ module InvoicePrinter
|
|
62
62
|
# font - font file to use
|
63
63
|
# stamp - stamp & signature (image)
|
64
64
|
# logo - logotype (image)
|
65
|
-
def self.print(document:, file_name:, labels: {}, font: nil, stamp: nil, logo: nil, background: nil)
|
65
|
+
def self.print(document:, file_name:, labels: {}, font: nil, stamp: nil, logo: nil, background: nil, page_size: :letter)
|
66
66
|
PDFDocument.new(
|
67
67
|
document: document,
|
68
68
|
labels: labels,
|
69
69
|
font: font,
|
70
70
|
stamp: stamp,
|
71
71
|
logo: logo,
|
72
|
-
background: background
|
72
|
+
background: background,
|
73
|
+
page_size: page_size
|
73
74
|
).print(file_name)
|
74
75
|
end
|
75
76
|
|
@@ -80,14 +81,15 @@ module InvoicePrinter
|
|
80
81
|
# font - font file to use
|
81
82
|
# stamp - stamp & signature (image)
|
82
83
|
# logo - logotype (image)
|
83
|
-
def self.render(document:, labels: {}, font: nil, stamp: nil, logo: nil, background: nil)
|
84
|
+
def self.render(document:, labels: {}, font: nil, stamp: nil, logo: nil, background: nil, page_size: :letter)
|
84
85
|
PDFDocument.new(
|
85
86
|
document: document,
|
86
87
|
labels: labels,
|
87
88
|
font: font,
|
88
89
|
stamp: stamp,
|
89
90
|
logo: logo,
|
90
|
-
background: background
|
91
|
+
background: background,
|
92
|
+
page_size: page_size
|
91
93
|
).render
|
92
94
|
end
|
93
95
|
end
|
data/test/cli_test.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
class CLITest < Minitest::Test
|
5
|
+
include InvoicePrinterHelpers
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@invoice = InvoicePrinter::Document.new(default_document_params)
|
9
|
+
@invoice_as_json = @invoice.to_json
|
10
|
+
@output_path = Dir::Tmpname.make_tmpname('/tmp/invoice', nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
File.unlink @output_path if File.exist?(@output_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_print_to_file
|
18
|
+
command = "bin/invoice_printer --filename #{@output_path} --document '#{@invoice_as_json}'"
|
19
|
+
|
20
|
+
exit_status, command_stdout, command_stderr = nil
|
21
|
+
|
22
|
+
Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
|
23
|
+
stdin.close
|
24
|
+
command_stdout = stdout.read
|
25
|
+
command_stderr = stderr.read
|
26
|
+
exit_status = wait_thr.value
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_equal '', command_stderr
|
30
|
+
assert_equal '', command_stdout
|
31
|
+
assert_equal 0, exit_status
|
32
|
+
|
33
|
+
expected_pdf_path = "#{@output_path}.expected_letter"
|
34
|
+
|
35
|
+
InvoicePrinter.print(
|
36
|
+
document: @invoice,
|
37
|
+
file_name: expected_pdf_path,
|
38
|
+
page_size: :letter
|
39
|
+
)
|
40
|
+
|
41
|
+
similarity = (File.read(expected_pdf_path) == File.read(@output_path))
|
42
|
+
assert_equal true, similarity, "#{@output_path} does not match #{expected_pdf_path}"
|
43
|
+
|
44
|
+
File.unlink expected_pdf_path
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_print_to_file_a4
|
48
|
+
command = "bin/invoice_printer --filename #{@output_path} --page-size a4 --document '#{@invoice_as_json}'"
|
49
|
+
|
50
|
+
exit_status, command_stdout, command_stderr = nil
|
51
|
+
|
52
|
+
Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
|
53
|
+
stdin.close
|
54
|
+
command_stdout = stdout.read
|
55
|
+
command_stderr = stderr.read
|
56
|
+
exit_status = wait_thr.value
|
57
|
+
end
|
58
|
+
|
59
|
+
assert_equal '', command_stderr
|
60
|
+
assert_equal '', command_stdout
|
61
|
+
assert_equal 0, exit_status
|
62
|
+
|
63
|
+
expected_pdf_path = "#{@output_path}.expected_a4"
|
64
|
+
|
65
|
+
InvoicePrinter.print(
|
66
|
+
document: @invoice,
|
67
|
+
file_name: expected_pdf_path,
|
68
|
+
page_size: :a4
|
69
|
+
)
|
70
|
+
|
71
|
+
similarity = (File.read(expected_pdf_path) == File.read(@output_path))
|
72
|
+
assert_equal true, similarity, "#{@output_path} does not match #{expected_pdf_path}"
|
73
|
+
|
74
|
+
File.unlink expected_pdf_path
|
75
|
+
end
|
76
|
+
end
|