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 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.SetTextColor(100, 100, 100)
51 _ = pdf.Cell(nil, id)
52 pdf.Br(48)
53}
54
55func writeBillTo(pdf *gopdf.GoPdf, to string) {
56 pdf.SetTextColor(75, 75, 75)
57 _ = pdf.SetFont("Inter", "", 9)
58 _ = pdf.Cell(nil, "BILL TO")
59 pdf.Br(14)
60 pdf.SetTextColor(75, 75, 75)
61 _ = pdf.SetFont("Inter", "", 15)
62 _ = pdf.Cell(nil, to)
63 pdf.Br(64)
64}
65
66func writeHeaderRow(pdf *gopdf.GoPdf) {
67 _ = pdf.SetFont("Inter", "", 9)
68 pdf.SetTextColor(55, 55, 55)
69 _ = pdf.Cell(nil, "ITEM")
70 pdf.SetX(quantityColumnOffset)
71 _ = pdf.Cell(nil, "QTY")
72 pdf.SetX(rateColumnOffset)
73 _ = pdf.Cell(nil, "RATE")
74 pdf.SetX(amountColumnOffset)
75 _ = pdf.Cell(nil, "AMOUNT")
76 pdf.Br(24)
77}
78
79func writeNotes(pdf *gopdf.GoPdf, notes string) {
80 pdf.SetY(650)
81
82 _ = pdf.SetFont("Inter", "", 10)
83 pdf.SetTextColor(55, 55, 55)
84 _ = pdf.Cell(nil, "Notes")
85 pdf.Br(18)
86 pdf.SetTextColor(0, 0, 0)
87 _ = pdf.Cell(nil, notes)
88 pdf.Br(48)
89}
90
91func writeFooter(pdf *gopdf.GoPdf, id string) {
92 pdf.SetY(800)
93
94 _ = pdf.SetFont("Inter", "", 10)
95 pdf.SetTextColor(55, 55, 55)
96 _ = pdf.Cell(nil, id)
97 pdf.SetStrokeColor(225, 225, 225)
98 pdf.Line(pdf.GetX()+10, pdf.GetY()+6, 550, pdf.GetY()+6)
99 pdf.Br(48)
100}
101
102func writeRow(pdf *gopdf.GoPdf, item string, quantity int, rate float64) {
103 _ = pdf.SetFont("Inter", "", 11)
104 pdf.SetTextColor(0, 0, 0)
105
106 total := float64(quantity) * rate
107 amount := strconv.FormatFloat(total, 'f', 2, 64)
108
109 _ = pdf.Cell(nil, item)
110 pdf.SetX(quantityColumnOffset)
111 _ = pdf.Cell(nil, strconv.Itoa(quantity))
112 pdf.SetX(rateColumnOffset)
113 _ = pdf.Cell(nil, currencySymbols[currency]+strconv.FormatFloat(rate, 'f', 2, 64))
114 pdf.SetX(amountColumnOffset)
115 _ = pdf.Cell(nil, currencySymbols[currency]+amount)
116 pdf.Br(24)
117}
118
119func writeTotals(pdf *gopdf.GoPdf, subtotal float64, tax float64, discount float64) {
120 pdf.SetY(650)
121
122 writeTotal(pdf, subtotalLabel, subtotal)
123 if tax > 0 {
124 writeTotal(pdf, taxLabel, tax)
125 }
126 if discount > 0 {
127 writeTotal(pdf, discountLabel, discount)
128 }
129 writeTotal(pdf, totalLabel, subtotal+tax-discount)
130}
131
132func writeTotal(pdf *gopdf.GoPdf, label string, total float64) {
133 _ = pdf.SetFont("Inter", "", 9)
134 pdf.SetTextColor(75, 75, 75)
135 pdf.SetX(rateColumnOffset)
136 _ = pdf.Cell(nil, label)
137 pdf.SetTextColor(0, 0, 0)
138 _ = pdf.SetFontSize(12)
139 pdf.SetX(amountColumnOffset - 15)
140 if label == totalLabel {
141 _ = pdf.SetFont("Inter-Bold", "", 11.5)
142 }
143 _ = pdf.Cell(nil, currencySymbols[currency]+strconv.FormatFloat(total, 'f', 2, 64))
144 pdf.Br(24)
145}
146
147func getImageDimension(imagePath string) (int, int) {
148 file, err := os.Open(imagePath)
149 if err != nil {
150 fmt.Fprintf(os.Stderr, "%v\n", err)
151 }
152 defer file.Close()
153
154 image, _, err := image.DecodeConfig(file)
155 if err != nil {
156 fmt.Fprintf(os.Stderr, "%s: %v\n", imagePath, err)
157 }
158 return image.Width, image.Height
159}