invoice_printer 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|