1package main
2
3import (
4 "fmt"
5 "image"
6 "os"
7 "strconv"
8
9 "github.com/signintech/gopdf"
10)
11
12const (
13 quantityColumnOffset = 360
14 rateColumnOffset = 405
15 amountColumnOffset = 480
16)
17
18const (
19 subtotalLabel = "Subtotal"
20 discountLabel = "Discount"
21 taxLabel = "Tax"
22 totalLabel = "Total"
23)
24
25func writeLogo(pdf *gopdf.GoPdf, logo string, from string) {
26 if logo != "" {
27 width, height := getImageDimension(logo)
28 scaledWidth := 100.0
29 scaledHeight := float64(height) * scaledWidth / float64(width)
30 _ = pdf.Image(logo, pdf.GetX(), pdf.GetY(), &gopdf.Rect{W: scaledWidth, H: scaledHeight})
31 pdf.Br(scaledHeight + 24)
32 }
33 _ = pdf.SetFont("Inter", "", 12)
34 pdf.SetTextColor(55, 55, 55)
35 _ = pdf.Cell(nil, from)
36 pdf.Br(36)
37 pdf.SetStrokeColor(225, 225, 225)
38 pdf.Line(pdf.GetX(), pdf.GetY(), 100, pdf.GetY())
39 pdf.Br(36)
40}
41
42func writeTitle(pdf *gopdf.GoPdf, title, id, date string) {
43 _ = pdf.SetFont("Inter-Bold", "", 24)
44 pdf.SetTextColor(0, 0, 0)
45 _ = pdf.Cell(nil, title)
46 pdf.Br(36)
47 _ = pdf.SetFont("Inter", "", 12)
48 pdf.SetTextColor(100, 100, 100)
49 _ = pdf.Cell(nil, "#")
50 _ = pdf.Cell(nil, id)
51 pdf.SetTextColor(150, 150, 150)
52 _ = pdf.Cell(nil, " · ")
53 pdf.SetTextColor(100, 100, 100)
54 _ = pdf.Cell(nil, date)
55 pdf.Br(36)
56}
57
58func writeDueDate(pdf *gopdf.GoPdf, due string) {
59 _ = pdf.SetFont("Inter", "", 9)
60 pdf.SetTextColor(75, 75, 75)
61 pdf.SetX(rateColumnOffset)
62 _ = pdf.Cell(nil, "Due Date")
63 pdf.SetTextColor(0, 0, 0)
64 _ = pdf.SetFontSize(11)
65 pdf.SetX(amountColumnOffset - 15)
66 _ = pdf.Cell(nil, due)
67 pdf.Br(12)
68}
69
70func writeBillTo(pdf *gopdf.GoPdf, to string) {
71 pdf.SetTextColor(75, 75, 75)
72 _ = pdf.SetFont("Inter", "", 9)
73 _ = pdf.Cell(nil, "BILL TO")
74 pdf.Br(18)
75 pdf.SetTextColor(75, 75, 75)
76 _ = pdf.SetFont("Inter", "", 15)
77 _ = pdf.Cell(nil, to)
78 pdf.Br(64)
79}
80
81func writeHeaderRow(pdf *gopdf.GoPdf) {
82 _ = pdf.SetFont("Inter", "", 9)
83 pdf.SetTextColor(55, 55, 55)
84 _ = pdf.Cell(nil, "ITEM")
85 pdf.SetX(quantityColumnOffset)
86 _ = pdf.Cell(nil, "QTY")
87 pdf.SetX(rateColumnOffset)
88 _ = pdf.Cell(nil, "RATE")
89 pdf.SetX(amountColumnOffset)
90 _ = pdf.Cell(nil, "AMOUNT")
91 pdf.Br(24)
92}
93
94func writeNotes(pdf *gopdf.GoPdf, notes string) {
95 pdf.SetY(650)
96
97 _ = pdf.SetFont("Inter", "", 10)
98 pdf.SetTextColor(55, 55, 55)
99 _ = pdf.Cell(nil, "Notes")
100 pdf.Br(18)
101 pdf.SetTextColor(0, 0, 0)
102 _ = pdf.Cell(nil, notes)
103 pdf.Br(48)
104}
105
106func writeFooter(pdf *gopdf.GoPdf, id string) {
107 pdf.SetY(800)
108
109 _ = pdf.SetFont("Inter", "", 10)
110 pdf.SetTextColor(55, 55, 55)
111 _ = pdf.Cell(nil, id)
112 pdf.SetStrokeColor(225, 225, 225)
113 pdf.Line(pdf.GetX()+10, pdf.GetY()+6, 550, pdf.GetY()+6)
114 pdf.Br(48)
115}
116
117func writeRow(pdf *gopdf.GoPdf, item string, quantity int, rate float64) {
118 _ = pdf.SetFont("Inter", "", 11)
119 pdf.SetTextColor(0, 0, 0)
120
121 total := float64(quantity) * rate
122 amount := strconv.FormatFloat(total, 'f', 2, 64)
123
124 _ = pdf.Cell(nil, item)
125 pdf.SetX(quantityColumnOffset)
126 _ = pdf.Cell(nil, strconv.Itoa(quantity))
127 pdf.SetX(rateColumnOffset)
128 _ = pdf.Cell(nil, currencySymbols[currency]+strconv.FormatFloat(rate, 'f', 2, 64))
129 pdf.SetX(amountColumnOffset)
130 _ = pdf.Cell(nil, currencySymbols[currency]+amount)
131 pdf.Br(24)
132}
133
134func writeTotals(pdf *gopdf.GoPdf, subtotal float64, tax float64, discount float64) {
135 pdf.SetY(650)
136
137 writeTotal(pdf, subtotalLabel, subtotal)
138 if tax > 0 {
139 writeTotal(pdf, taxLabel, tax)
140 }
141 if discount > 0 {
142 writeTotal(pdf, discountLabel, discount)
143 }
144 writeTotal(pdf, totalLabel, subtotal+tax-discount)
145}
146
147func writeTotal(pdf *gopdf.GoPdf, label string, total float64) {
148 _ = pdf.SetFont("Inter", "", 9)
149 pdf.SetTextColor(75, 75, 75)
150 pdf.SetX(rateColumnOffset)
151 _ = pdf.Cell(nil, label)
152 pdf.SetTextColor(0, 0, 0)
153 _ = pdf.SetFontSize(12)
154 pdf.SetX(amountColumnOffset - 15)
155 if label == totalLabel {
156 _ = pdf.SetFont("Inter-Bold", "", 11.5)
157 }
158 _ = pdf.Cell(nil, currencySymbols[currency]+strconv.FormatFloat(total, 'f', 2, 64))
159 pdf.Br(24)
160}
161
162func getImageDimension(imagePath string) (int, int) {
163 file, err := os.Open(imagePath)
164 if err != nil {
165 fmt.Fprintf(os.Stderr, "%v\n", err)
166 }
167 defer file.Close()
168
169 image, _, err := image.DecodeConfig(file)
170 if err != nil {
171 fmt.Fprintf(os.Stderr, "%s: %v\n", imagePath, err)
172 }
173 return image.Width, image.Height
174}