invoices: rework of PDF
This commit is contained in:
parent
cb52388bf1
commit
16680be309
1 changed files with 29 additions and 22 deletions
|
|
@ -13,8 +13,6 @@ class InvoicePdf
|
||||||
name_alt: 'SERGEI POLJANSKI',
|
name_alt: 'SERGEI POLJANSKI',
|
||||||
name_georgian: 'ინდ. მეწარმე სერგეი პოლჯანსკი',
|
name_georgian: 'ინდ. მეწარმე სერგეი პოლჯანსკი',
|
||||||
tax_id: '304813343',
|
tax_id: '304813343',
|
||||||
reg_number: 'B26353511',
|
|
||||||
registered: '2026-05-04',
|
|
||||||
address: [
|
address: [
|
||||||
'Ilia and Nino Nakashidze St, N 1, Building N3, Apt N3',
|
'Ilia and Nino Nakashidze St, N 1, Building N3, Apt N3',
|
||||||
'Krtsanisi, Tbilisi, Georgia'
|
'Krtsanisi, Tbilisi, Georgia'
|
||||||
|
|
@ -31,6 +29,13 @@ class InvoicePdf
|
||||||
COLOR_RULE = 'DADADA'.freeze
|
COLOR_RULE = 'DADADA'.freeze
|
||||||
COLOR_ACCENT = '1A1A1A'.freeze
|
COLOR_ACCENT = '1A1A1A'.freeze
|
||||||
|
|
||||||
|
# Uniform line spacing for the FROM / BILL TO party blocks: every line gets the
|
||||||
|
# same leading, no extra gaps between groups, so both columns read as one even
|
||||||
|
# rhythm and line up. NAME_GAP is the one exception — a little extra air after
|
||||||
|
# the bold company name to set it off from the details below.
|
||||||
|
PARTY_LEADING = 2
|
||||||
|
NAME_GAP = 3
|
||||||
|
|
||||||
# `status` overrides the status shown in the PDF (e.g. to pre-render a "paid"
|
# `status` overrides the status shown in the PDF (e.g. to pre-render a "paid"
|
||||||
# copy before any payment date exists). Defaults to the invoice's live status.
|
# copy before any payment date exists). Defaults to the invoice's live status.
|
||||||
def self.render(invoice, status: nil)
|
def self.render(invoice, status: nil)
|
||||||
|
|
@ -109,17 +114,17 @@ class InvoicePdf
|
||||||
|
|
||||||
pdf.bounding_box([0, pdf.cursor], width: col_w) do
|
pdf.bounding_box([0, pdf.cursor], width: col_w) do
|
||||||
draw_party_label(pdf, 'FROM')
|
draw_party_label(pdf, 'FROM')
|
||||||
pdf.font_size(11) { pdf.text ISSUER[:name_latin], style: :bold, leading: 2 }
|
pdf.font_size(11) { pdf.text ISSUER[:name_latin], style: :bold, leading: PARTY_LEADING }
|
||||||
|
pdf.move_down NAME_GAP
|
||||||
pdf.font_size(9) do
|
pdf.font_size(9) do
|
||||||
pdf.text ISSUER[:name_georgian], leading: 4
|
lines = [
|
||||||
pdf.move_down 8
|
ISSUER[:name_georgian],
|
||||||
pdf.text ISSUER[:address].join("\n"), leading: 3
|
*ISSUER[:address],
|
||||||
pdf.move_down 8
|
"Tax ID: #{ISSUER[:tax_id]}",
|
||||||
pdf.text "Tax ID: #{ISSUER[:tax_id]}", leading: 3
|
ISSUER[:email],
|
||||||
pdf.text "Reg. №: #{ISSUER[:reg_number]} (#{ISSUER[:registered]})", leading: 3
|
ISSUER[:phone]
|
||||||
pdf.move_down 8
|
]
|
||||||
pdf.text ISSUER[:email], leading: 3
|
pdf.text lines.join("\n"), leading: PARTY_LEADING
|
||||||
pdf.text ISSUER[:phone]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
from_y = pdf.y
|
from_y = pdf.y
|
||||||
|
|
@ -127,13 +132,12 @@ class InvoicePdf
|
||||||
pdf.y = top_y
|
pdf.y = top_y
|
||||||
pdf.bounding_box([right, pdf.cursor], width: pdf.bounds.right - right) do
|
pdf.bounding_box([right, pdf.cursor], width: pdf.bounds.right - right) do
|
||||||
draw_party_label(pdf, 'BILL TO')
|
draw_party_label(pdf, 'BILL TO')
|
||||||
pdf.font_size(11) { pdf.text @invoice.client_name, style: :bold, leading: 2 }
|
pdf.font_size(11) { pdf.text @invoice.client_name, style: :bold, leading: PARTY_LEADING }
|
||||||
|
pdf.move_down NAME_GAP
|
||||||
pdf.font_size(9) do
|
pdf.font_size(9) do
|
||||||
pdf.text @invoice.client_email, leading: 3
|
lines = [@invoice.client_email]
|
||||||
unless @invoice.client_address.to_s.strip.empty?
|
lines << @invoice.client_address unless @invoice.client_address.to_s.strip.empty?
|
||||||
pdf.move_down 8
|
pdf.text lines.join("\n"), leading: PARTY_LEADING
|
||||||
pdf.text @invoice.client_address, leading: 3
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
bill_y = pdf.y
|
bill_y = pdf.y
|
||||||
|
|
@ -152,7 +156,7 @@ class InvoicePdf
|
||||||
def draw_meta(pdf)
|
def draw_meta(pdf)
|
||||||
pdf.stroke_color COLOR_RULE
|
pdf.stroke_color COLOR_RULE
|
||||||
pdf.stroke_horizontal_rule
|
pdf.stroke_horizontal_rule
|
||||||
pdf.move_down 10
|
pdf.move_down 8
|
||||||
|
|
||||||
cells = [
|
cells = [
|
||||||
['ISSUED', @invoice.issued_on.strftime('%Y-%m-%d')],
|
['ISSUED', @invoice.issued_on.strftime('%Y-%m-%d')],
|
||||||
|
|
@ -168,13 +172,16 @@ class InvoicePdf
|
||||||
pdf.fill_color COLOR_MUTED
|
pdf.fill_color COLOR_MUTED
|
||||||
pdf.font_size(7) { pdf.text label, character_spacing: 1.2 }
|
pdf.font_size(7) { pdf.text label, character_spacing: 1.2 }
|
||||||
pdf.fill_color COLOR_TEXT
|
pdf.fill_color COLOR_TEXT
|
||||||
pdf.move_down 3
|
pdf.move_down 2
|
||||||
pdf.font_size(10) { pdf.text value, style: :bold }
|
pdf.font_size(10) { pdf.text value, style: :bold }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Reserve the height the row actually used.
|
# The cells are absolutely-positioned boxes that don't advance the outer
|
||||||
pdf.move_down 30
|
# cursor, so reserve the row height manually. Tuned (measured from the
|
||||||
|
# rendered PNG) so the gap below the values matches the ~10pt gap above the
|
||||||
|
# labels rather than ballooning to ~29pt.
|
||||||
|
pdf.move_down 9
|
||||||
pdf.stroke_horizontal_rule
|
pdf.stroke_horizontal_rule
|
||||||
pdf.move_down 16
|
pdf.move_down 16
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue