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