1package main
2
3import (
4 _ "embed"
5 "flag"
6 "log"
7 "time"
8
9 "github.com/signintech/gopdf"
10 "github.com/spf13/cobra"
11)
12
13//go:embed Inter.ttf
14var interFont []byte
15
16var (
17 id string
18 title string
19
20 logo string
21 from string
22 to string
23 date string
24 due string
25
26 items []string
27 quantities []int
28 rates []float64
29
30 tax float64
31 discount float64
32 currency string
33
34 note string
35 output string
36)
37
38func init() {
39 generateCmd.Flags().StringVar(&id, "id", time.Now().Format("20060102"), "ID")
40 generateCmd.Flags().StringVar(&title, "title", "INVOICE", "Title")
41
42 generateCmd.Flags().Float64SliceVarP(&rates, "rate", "r", []float64{25}, "Rates")
43 generateCmd.Flags().IntSliceVarP(&quantities, "quantity", "q", []int{2}, "Quantities")
44 generateCmd.Flags().StringSliceVarP(&items, "item", "i", []string{"Paper Cranes"}, "Items")
45
46 generateCmd.Flags().StringVarP(&logo, "logo", "l", "", "Company logo")
47 generateCmd.Flags().StringVarP(&from, "from", "f", "Project Folded, Inc.", "Issuing company")
48 generateCmd.Flags().StringVarP(&to, "to", "t", "Untitled Corporation, Inc.", "Recipient company")
49 generateCmd.Flags().StringVar(&date, "date", time.Now().Format("Jan 02, 2006"), "Date")
50 generateCmd.Flags().StringVar(&due, "due", time.Now().AddDate(0, 0, 14).Format("Jan 02, 2006"), "Payment due date")
51
52 generateCmd.Flags().Float64Var(&tax, "tax", 0.13, "Tax")
53 generateCmd.Flags().Float64VarP(&discount, "discount", "d", 0.0, "Discount")
54 generateCmd.Flags().StringVarP(¤cy, "currency", "c", "USD", "Currency")
55
56 generateCmd.Flags().StringVarP(¬e, "note", "n", "For debugging purposes.", "Note")
57 generateCmd.Flags().StringVarP(&output, "output", "o", "invoice.pdf", "Output file (.pdf)")
58
59 flag.Parse()
60}
61
62var rootCmd = &cobra.Command{
63 Use: "invoice",
64 Short: "Invoice generates invoices from the command line.",
65 Long: `Invoice generates invoices from the command line.`,
66}
67
68var generateCmd = &cobra.Command{
69 Use: "generate",
70 Short: "Generate an invoice",
71 Long: `Generate an invoice`,
72 RunE: func(cmd *cobra.Command, args []string) error {
73 pdf := gopdf.GoPdf{}
74 pdf.Start(gopdf.Config{
75 PageSize: *gopdf.PageSizeA4,
76 })
77 pdf.SetMargins(40, 40, 40, 40)
78 pdf.AddPage()
79 err := pdf.AddTTFFontData("Inter", interFont)
80 if err != nil {
81 return err
82 }
83
84 writeLogo(&pdf, logo, from)
85 writeTitle(&pdf, title, id)
86 writeBillTo(&pdf, to)
87 writeHeaderRow(&pdf)
88 subtotal := 0.0
89 for i := range items {
90 q := 1
91 if len(quantities) > i {
92 q = quantities[i]
93 }
94
95 r := 0.0
96 if len(rates) > i {
97 r = rates[i]
98 }
99
100 writeRow(&pdf, items[i], q, r)
101 subtotal += float64(q) * r
102 }
103 writeNotes(&pdf, note)
104 writeTotals(&pdf, subtotal, subtotal*tax, subtotal*discount)
105 writeFooter(&pdf, id)
106 return pdf.WritePdf(output)
107 },
108}
109
110func main() {
111 rootCmd.AddCommand(generateCmd)
112 err := rootCmd.Execute()
113 if err != nil {
114 log.Fatal(err)
115 }
116}