pdf.go

  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	formattedNotes := strings.ReplaceAll(notes, `\n`, "\n")
106	notesLines := strings.Split(formattedNotes, "\\n")
107
108	for i := 0; i < len(notesLines); i++ {
109		_ = pdf.Cell(nil, notesLines[i])
110		pdf.Br(15)
111	}
112
113	pdf.Br(48)
114}
115func writeFooter(pdf *gopdf.GoPdf, id string) {
116	pdf.SetY(800)
117
118	_ = pdf.SetFont("Inter", "", 10)
119	pdf.SetTextColor(55, 55, 55)
120	_ = pdf.Cell(nil, id)
121	pdf.SetStrokeColor(225, 225, 225)
122	pdf.Line(pdf.GetX()+10, pdf.GetY()+6, 550, pdf.GetY()+6)
123	pdf.Br(48)
124}
125
126func writeRow(pdf *gopdf.GoPdf, item string, quantity int, rate float64) {
127	_ = pdf.SetFont("Inter", "", 11)
128	pdf.SetTextColor(0, 0, 0)
129
130	total := float64(quantity) * rate
131	amount := strconv.FormatFloat(total, 'f', 2, 64)
132
133	_ = pdf.Cell(nil, item)
134	pdf.SetX(quantityColumnOffset)
135	_ = pdf.Cell(nil, strconv.Itoa(quantity))
136	pdf.SetX(rateColumnOffset)
137	_ = pdf.Cell(nil, currencySymbols[file.Currency]+strconv.FormatFloat(rate, 'f', 2, 64))
138	pdf.SetX(amountColumnOffset)
139	_ = pdf.Cell(nil, currencySymbols[file.Currency]+amount)
140	pdf.Br(24)
141}
142
143func writeTotals(pdf *gopdf.GoPdf, subtotal float64, tax float64, discount float64) {
144	pdf.SetY(650)
145
146	writeTotal(pdf, subtotalLabel, subtotal)
147	if tax > 0 {
148		writeTotal(pdf, taxLabel, tax)
149	}
150	if discount > 0 {
151		writeTotal(pdf, discountLabel, discount)
152	}
153	writeTotal(pdf, totalLabel, subtotal+tax-discount)
154}
155
156func writeTotal(pdf *gopdf.GoPdf, label string, total float64) {
157	_ = pdf.SetFont("Inter", "", 9)
158	pdf.SetTextColor(75, 75, 75)
159	pdf.SetX(rateColumnOffset)
160	_ = pdf.Cell(nil, label)
161	pdf.SetTextColor(0, 0, 0)
162	_ = pdf.SetFontSize(12)
163	pdf.SetX(amountColumnOffset - 15)
164	if label == totalLabel {
165		_ = pdf.SetFont("Inter-Bold", "", 11.5)
166	}
167	_ = pdf.Cell(nil, currencySymbols[file.Currency]+strconv.FormatFloat(total, 'f', 2, 64))
168	pdf.Br(24)
169}
170
171func getImageDimension(imagePath string) (int, int) {
172	file, err := os.Open(imagePath)
173	if err != nil {
174		fmt.Fprintf(os.Stderr, "%v\n", err)
175	}
176	defer file.Close()
177
178	image, _, err := image.DecodeConfig(file)
179	if err != nil {
180		fmt.Fprintf(os.Stderr, "%s: %v\n", imagePath, err)
181	}
182	return image.Width, image.Height
183}