invoice_printer 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -2
- data/examples/czech_invoice.jpg +0 -0
- data/examples/czech_invoice.pdf +174 -181
- data/examples/simple_invoice.pdf +127 -134
- data/lib/invoice_printer/pdf_document.rb +140 -83
- data/lib/invoice_printer/version.rb +1 -1
- data/test/dates_box_test.rb +4 -0
- data/test/invoice_printer_test.rb +1 -1
- data/test/items_table_test.rb +3 -5
- data/test/labels_test.rb +0 -2
- data/test/test_ext.rb +52 -20
- data/test/test_helper.rb +1 -1
- metadata +3 -2
@@ -96,19 +96,24 @@ module InvoicePrinter
|
|
96
96
|
|
97
97
|
private
|
98
98
|
|
99
|
+
# Add font family in Prawn for a given +font+ file
|
99
100
|
def set_fonts(font)
|
100
101
|
font_name = Pathname.new(font).basename
|
101
|
-
@pdf.font_families.update(
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
102
|
+
@pdf.font_families.update(
|
103
|
+
"#{font_name}" => {
|
104
|
+
normal: font,
|
105
|
+
italic: font,
|
106
|
+
bold: font,
|
107
|
+
bold_italic: font
|
108
|
+
}
|
109
|
+
)
|
107
110
|
@pdf.font(font_name)
|
108
111
|
end
|
109
112
|
|
113
|
+
# Build the PDF version of the document (@pdf)
|
110
114
|
def build_pdf
|
111
|
-
@push_down =
|
115
|
+
@push_down = 0
|
116
|
+
@push_items_table = 0
|
112
117
|
@pdf.fill_color '000000'
|
113
118
|
build_header
|
114
119
|
build_provider_box
|
@@ -121,54 +126,74 @@ module InvoicePrinter
|
|
121
126
|
build_footer
|
122
127
|
end
|
123
128
|
|
129
|
+
# Build the document name and number
|
124
130
|
def build_header
|
125
|
-
@pdf.
|
131
|
+
@pdf.text_box(
|
132
|
+
@labels[:name],
|
133
|
+
size: 20,
|
134
|
+
at: [0, 720 - @push_down],
|
135
|
+
width: 300,
|
136
|
+
align: :left
|
137
|
+
)
|
126
138
|
@pdf.text_box(
|
127
139
|
@document.number,
|
128
140
|
size: 20,
|
129
|
-
at: [240, 720],
|
141
|
+
at: [240, 720 - @push_down],
|
130
142
|
width: 300,
|
131
143
|
align: :right
|
132
144
|
)
|
133
145
|
@pdf.move_down(250)
|
134
146
|
end
|
135
147
|
|
148
|
+
# Build the following provider box:
|
149
|
+
#
|
150
|
+
# -------------------------------------
|
151
|
+
# | Provider |
|
152
|
+
# | PROVIDER co. |
|
153
|
+
# | 5th Street |
|
154
|
+
# | 747 27 City |
|
155
|
+
# | Part of the city |
|
156
|
+
# | |
|
157
|
+
# | Identification number: Number |
|
158
|
+
# | Identification number: Number 2 |
|
159
|
+
# -------------------------------------
|
160
|
+
#
|
136
161
|
def build_provider_box
|
137
162
|
@pdf.text_box(
|
138
163
|
@labels[:provider],
|
139
164
|
size: 10,
|
140
|
-
at: [10, 660],
|
165
|
+
at: [10, 660 - @push_down],
|
141
166
|
width: 240
|
142
167
|
)
|
143
168
|
@pdf.text_box(
|
144
169
|
@document.provider_name,
|
145
170
|
size: 14,
|
146
|
-
at: [10, 640],
|
171
|
+
at: [10, 640 - @push_down],
|
147
172
|
width: 240
|
148
173
|
)
|
149
174
|
@pdf.text_box(
|
150
175
|
"#{@document.provider_street} #{@document.provider_street_number}",
|
151
176
|
size: 10,
|
152
|
-
at: [10, 620],
|
177
|
+
at: [10, 620 - @push_down],
|
153
178
|
width: 240
|
154
179
|
)
|
155
180
|
@pdf.text_box(
|
156
181
|
@document.provider_postcode,
|
157
182
|
size: 10,
|
158
|
-
at: [10, 605],
|
183
|
+
at: [10, 605 - @push_down],
|
159
184
|
width: 240
|
160
185
|
)
|
161
186
|
@pdf.text_box(
|
162
187
|
@document.provider_city,
|
163
188
|
size: 10,
|
164
|
-
at: [60, 605],
|
189
|
+
at: [60, 605 - @push_down],
|
165
190
|
width: 240
|
166
191
|
)
|
167
192
|
unless @document.provider_city_part.empty?
|
168
193
|
@pdf.text_box(
|
169
194
|
@document.provider_city_part,
|
170
195
|
size: 10,
|
171
|
-
at: [60, 590],
|
196
|
+
at: [60, 590 - @push_down],
|
172
197
|
width: 240
|
173
198
|
)
|
174
199
|
end
|
@@ -176,7 +201,7 @@ module InvoicePrinter
|
|
176
201
|
@pdf.text_box(
|
177
202
|
@document.provider_extra_address_line,
|
178
203
|
size: 10,
|
179
|
-
at: [10, 575],
|
204
|
+
at: [10, 575 - @push_down],
|
180
205
|
width: 240
|
181
206
|
)
|
182
207
|
end
|
@@ -184,7 +209,7 @@ module InvoicePrinter
|
|
184
209
|
@pdf.text_box(
|
185
210
|
"#{@labels[:ic]}: #{@document.provider_ic}",
|
186
211
|
size: 10,
|
187
|
-
at: [10, 550],
|
212
|
+
at: [10, 550 - @push_down],
|
188
213
|
width: 240
|
189
214
|
)
|
190
215
|
end
|
@@ -192,48 +217,62 @@ module InvoicePrinter
|
|
192
217
|
@pdf.text_box(
|
193
218
|
"#{@labels[:dic]}: #{@document.provider_dic}",
|
194
219
|
size: 10,
|
195
|
-
at: [10, 535],
|
220
|
+
at: [10, 535 - @push_down],
|
196
221
|
width: 240
|
197
222
|
)
|
198
223
|
end
|
224
|
+
@pdf.stroke_rounded_rectangle([0, 670 - @push_down], 270, 150, 6)
|
199
225
|
end
|
200
226
|
|
227
|
+
# Build the following purchaser box:
|
228
|
+
#
|
229
|
+
# -------------------------------------
|
230
|
+
# | Purchaser |
|
231
|
+
# | PURCHASER co. |
|
232
|
+
# | 5th Street |
|
233
|
+
# | 747 27 City |
|
234
|
+
# | Part of the city |
|
235
|
+
# | |
|
236
|
+
# | Identification number: Number |
|
237
|
+
# | Identification number: Number 2 |
|
238
|
+
# -------------------------------------
|
239
|
+
#
|
201
240
|
def build_purchaser_box
|
202
241
|
@pdf.text_box(
|
203
242
|
@labels[:purchaser],
|
204
243
|
size: 10,
|
205
|
-
at: [290, 660],
|
244
|
+
at: [290, 660 - @push_down],
|
206
245
|
width: 240
|
207
246
|
)
|
208
247
|
@pdf.text_box(
|
209
248
|
@document.purchaser_name,
|
210
249
|
size: 14,
|
211
|
-
at: [290, 640],
|
250
|
+
at: [290, 640 - @push_down],
|
212
251
|
width: 240
|
213
252
|
)
|
214
253
|
@pdf.text_box(
|
215
254
|
"#{@document.purchaser_street} #{@document.purchaser_street_number}",
|
216
255
|
size: 10,
|
217
|
-
at: [290, 620],
|
256
|
+
at: [290, 620 - @push_down],
|
218
257
|
width: 240
|
219
258
|
)
|
220
259
|
@pdf.text_box(
|
221
260
|
@document.purchaser_postcode,
|
222
261
|
size: 10,
|
223
|
-
at: [290, 605],
|
262
|
+
at: [290, 605 - @push_down],
|
224
263
|
width: 240
|
225
264
|
)
|
226
265
|
@pdf.text_box(
|
227
266
|
@document.purchaser_city,
|
228
267
|
size: 10,
|
229
|
-
at: [340, 605],
|
268
|
+
at: [340, 605 - @push_down],
|
230
269
|
width: 240
|
231
270
|
)
|
232
271
|
unless @document.purchaser_city_part.empty?
|
233
272
|
@pdf.text_box(
|
234
273
|
@document.purchaser_city_part,
|
235
274
|
size: 10,
|
236
|
-
at: [340, 590],
|
275
|
+
at: [340, 590 - @push_down],
|
237
276
|
width: 240
|
238
277
|
)
|
239
278
|
end
|
@@ -241,17 +280,15 @@ module InvoicePrinter
|
|
241
280
|
@pdf.text_box(
|
242
281
|
@document.purchaser_extra_address_line,
|
243
282
|
size: 10,
|
244
|
-
at: [290, 575],
|
283
|
+
at: [290, 575 - @push_down],
|
245
284
|
width: 240
|
246
285
|
)
|
247
286
|
end
|
248
|
-
@pdf.stroke_rounded_rectangle([0, 670], 270, 150, 6)
|
249
|
-
@pdf.stroke_rounded_rectangle([280, 670], 270, 150, 6)
|
250
287
|
unless @document.purchaser_dic.empty?
|
251
288
|
@pdf.text_box(
|
252
289
|
"#{@labels[:dic]}: #{@document.purchaser_dic}",
|
253
290
|
size: 10,
|
254
|
-
at: [290, 550],
|
291
|
+
at: [290, 550 - @push_down],
|
255
292
|
width: 240
|
256
293
|
)
|
257
294
|
end
|
@@ -259,83 +296,104 @@ module InvoicePrinter
|
|
259
296
|
@pdf.text_box(
|
260
297
|
"#{@labels[:ic]}: #{@document.purchaser_ic}",
|
261
298
|
size: 10,
|
262
|
-
at: [290, 535],
|
299
|
+
at: [290, 535 - @push_down],
|
263
300
|
width: 240
|
264
301
|
)
|
265
302
|
end
|
303
|
+
@pdf.stroke_rounded_rectangle([280, 670 - @push_down], 270, 150, 6)
|
266
304
|
end
|
267
305
|
|
306
|
+
# Build the following payment box:
|
307
|
+
#
|
308
|
+
# -----------------------------------------
|
309
|
+
# | Payment on the following bank account: |
|
310
|
+
# | Number: 3920392032 |
|
311
|
+
# | SWIFT: ... |
|
312
|
+
# | IBAN: ... |
|
313
|
+
# -----------------------------------------
|
314
|
+
#
|
315
|
+
# If the bank account number is not provided include a note about payment
|
316
|
+
# in cash.
|
268
317
|
def build_payment_method_box
|
269
318
|
if @document.bank_account_number.empty?
|
270
|
-
@pdf.stroke_rounded_rectangle([0, 540 - @push_down], 270, 45, 6)
|
271
319
|
@pdf.text_box(
|
272
320
|
@labels[:payment],
|
273
321
|
size: 10,
|
274
|
-
at: [10,
|
322
|
+
at: [10, 498 - @push_down],
|
275
323
|
width: 240
|
276
324
|
)
|
277
325
|
@pdf.text_box(
|
278
326
|
@labels[:payment_in_cash],
|
279
327
|
size: 10,
|
280
|
-
at: [10,
|
281
|
-
width: 240
|
282
|
-
)
|
283
|
-
return
|
284
|
-
end
|
285
|
-
box_height = 45
|
286
|
-
push_iban = 0
|
287
|
-
@pdf.text_box(
|
288
|
-
@labels[:payment_by_transfer],
|
289
|
-
size: 10,
|
290
|
-
at: [10, 530 - @push_down],
|
291
|
-
width: 240
|
292
|
-
)
|
293
|
-
@pdf.text_box(
|
294
|
-
"#{@labels[:account_number]}:",
|
295
|
-
size: 10,
|
296
|
-
at: [10, 515 - @push_down],
|
297
|
-
width: 240
|
298
|
-
)
|
299
|
-
@pdf.text_box(
|
300
|
-
@document.bank_account_number,
|
301
|
-
size: 10,
|
302
|
-
at: [75, 515 - @push_down],
|
303
|
-
width: 240
|
304
|
-
)
|
305
|
-
unless @document.account_swift.empty?
|
306
|
-
@pdf.text_box(
|
307
|
-
"#{@labels[:swift]}:",
|
308
|
-
size: 10,
|
309
|
-
at: [10, 500 - @push_down],
|
328
|
+
at: [10, 483 - @push_down],
|
310
329
|
width: 240
|
311
330
|
)
|
331
|
+
@pdf.stroke_rounded_rectangle([0, 508 - @push_down], 270, 45, 6)
|
332
|
+
else
|
333
|
+
box_height = 45
|
334
|
+
push_iban = 0
|
312
335
|
@pdf.text_box(
|
313
|
-
@
|
336
|
+
@labels[:payment_by_transfer],
|
314
337
|
size: 10,
|
315
|
-
at: [
|
338
|
+
at: [10, 498 - @push_down],
|
316
339
|
width: 240
|
317
340
|
)
|
318
|
-
box_height += 15
|
319
|
-
push_iban = 15
|
320
|
-
end
|
321
|
-
unless @document.account_iban.empty?
|
322
341
|
@pdf.text_box(
|
323
|
-
"#{@labels[:
|
342
|
+
"#{@labels[:account_number]}:",
|
324
343
|
size: 10,
|
325
|
-
at: [10,
|
344
|
+
at: [10, 483 - @push_down],
|
326
345
|
width: 240
|
327
346
|
)
|
328
347
|
@pdf.text_box(
|
329
|
-
@document.
|
348
|
+
@document.bank_account_number,
|
330
349
|
size: 10,
|
331
|
-
at: [75,
|
350
|
+
at: [75, 483 - @push_down],
|
332
351
|
width: 240
|
333
352
|
)
|
334
|
-
|
353
|
+
unless @document.account_swift.empty?
|
354
|
+
@pdf.text_box(
|
355
|
+
"#{@labels[:swift]}:",
|
356
|
+
size: 10,
|
357
|
+
at: [10, 468 - @push_down],
|
358
|
+
width: 240
|
359
|
+
)
|
360
|
+
@pdf.text_box(
|
361
|
+
@document.account_swift,
|
362
|
+
size: 10,
|
363
|
+
at: [75, 468 - @push_down],
|
364
|
+
width: 240
|
365
|
+
)
|
366
|
+
box_height += 15
|
367
|
+
push_iban = 15
|
368
|
+
@push_items_table += 15
|
369
|
+
end
|
370
|
+
unless @document.account_iban.empty?
|
371
|
+
@pdf.text_box(
|
372
|
+
"#{@labels[:iban]}:",
|
373
|
+
size: 10,
|
374
|
+
at: [10, 468 - push_iban - @push_down],
|
375
|
+
width: 240
|
376
|
+
)
|
377
|
+
@pdf.text_box(
|
378
|
+
@document.account_iban,
|
379
|
+
size: 10,
|
380
|
+
at: [75, 468 - push_iban - @push_down],
|
381
|
+
width: 240
|
382
|
+
)
|
383
|
+
box_height += 15
|
384
|
+
@push_items_table += 15
|
385
|
+
end
|
386
|
+
@pdf.stroke_rounded_rectangle([0, 508 - @push_down], 270, box_height, 6)
|
335
387
|
end
|
336
|
-
@pdf.stroke_rounded_rectangle([0, 540 - @push_down], 270, box_height, 6)
|
337
388
|
end
|
338
389
|
|
390
|
+
# Build the following info box:
|
391
|
+
#
|
392
|
+
# --------------------------------
|
393
|
+
# | Issue date: 03/03/2016 |
|
394
|
+
# | Due date: 03/03/2016 |
|
395
|
+
# --------------------------------
|
396
|
+
#
|
339
397
|
def build_info_box
|
340
398
|
issue_date_present = !@document.issue_date.empty?
|
341
399
|
due_date_present = !@document.due_date.empty?
|
@@ -343,18 +401,18 @@ module InvoicePrinter
|
|
343
401
|
@pdf.text_box(
|
344
402
|
"#{@labels[:issue_date]}:",
|
345
403
|
size: 10,
|
346
|
-
at: [290,
|
404
|
+
at: [290, 498 - @push_down],
|
347
405
|
width: 240
|
348
406
|
)
|
349
407
|
@pdf.text_box(
|
350
408
|
@document.issue_date,
|
351
409
|
size: 10,
|
352
|
-
at: [390,
|
410
|
+
at: [390, 498 - @push_down],
|
353
411
|
width: 240
|
354
412
|
)
|
355
413
|
end
|
356
414
|
if due_date_present
|
357
|
-
position = issue_date_present ?
|
415
|
+
position = issue_date_present ? 483 : 498
|
358
416
|
@pdf.text_box(
|
359
417
|
"#{@labels[:due_date]}:",
|
360
418
|
size: 10,
|
@@ -370,22 +428,22 @@ module InvoicePrinter
|
|
370
428
|
end
|
371
429
|
if issue_date_present || due_date_present
|
372
430
|
height = (issue_date_present && due_date_present) ? 45 : 30
|
373
|
-
@pdf.stroke_rounded_rectangle([280,
|
431
|
+
@pdf.stroke_rounded_rectangle([280, 508 - @push_down], 270, height, 6)
|
374
432
|
end
|
375
433
|
end
|
376
434
|
|
377
435
|
# Build the following table for document items:
|
378
436
|
#
|
379
|
-
#
|
437
|
+
# =================================================================
|
380
438
|
# |Item | Quantity | Unit | Price per item | Tax | Total per item |
|
381
439
|
# |-----|----------|------|----------------|-----|----------------|
|
382
440
|
# | x | 2 | hr | $ 2 | $1 | $ 4 |
|
383
|
-
#
|
441
|
+
# =================================================================
|
384
442
|
#
|
385
443
|
# If a specific column miss data, it's omittted.
|
386
444
|
# Tax2 and tax3 fields can be added as well if necessary.
|
387
445
|
def build_items
|
388
|
-
@pdf.move_down(25 + @push_down)
|
446
|
+
@pdf.move_down(25 + @push_items_table + @push_down)
|
389
447
|
|
390
448
|
items_params = determine_items_structure
|
391
449
|
items = build_items_data(items_params)
|
@@ -413,7 +471,6 @@ module InvoicePrinter
|
|
413
471
|
# Determine sections of the items table to show based on provided data
|
414
472
|
def determine_items_structure
|
415
473
|
items_params = {}
|
416
|
-
|
417
474
|
@document.items.each do |item|
|
418
475
|
items_params[:names] = true unless item.name.empty?
|
419
476
|
items_params[:quantities] = true unless item.quantity.empty?
|
@@ -424,7 +481,6 @@ module InvoicePrinter
|
|
424
481
|
items_params[:taxes3] = true unless item.tax3.empty?
|
425
482
|
items_params[:amounts] = true unless item.amount.empty?
|
426
483
|
end
|
427
|
-
|
428
484
|
items_params
|
429
485
|
end
|
430
486
|
|
@@ -506,6 +562,7 @@ module InvoicePrinter
|
|
506
562
|
)
|
507
563
|
end
|
508
564
|
|
565
|
+
# Insert a logotype at the left bottom of the document
|
509
566
|
def build_logo
|
510
567
|
@pdf.image(@logo, at: [0, 50]) if @logo && !@logo.empty?
|
511
568
|
end
|
@@ -515,7 +572,7 @@ module InvoicePrinter
|
|
515
572
|
@pdf.number_pages(
|
516
573
|
'<page> / <total>',
|
517
574
|
start_count_at: 1,
|
518
|
-
page_filter: ->(page) { page !=
|
575
|
+
page_filter: ->(page) { page != 1 },
|
519
576
|
at: [@pdf.bounds.right - 50, 0],
|
520
577
|
align: :right,
|
521
578
|
size: 12
|