From 1c89fd7af38571eb8583ec46915a4ef4b93c5973 Mon Sep 17 00:00:00 2001 From: Joerg Lehmann Date: Thu, 11 Jun 2020 20:15:28 +0200 Subject: [PATCH] one step forward --- .gitignore | 5 +- makefont.go | 4 +- mkinvoice.go | 149 ++++++++++++++++++++++++++++++++++++++++---------- qrbill.sh | 36 ++++++++++++ testqrbill.sh | 16 ++++++ 5 files changed, 177 insertions(+), 33 deletions(-) create mode 100755 qrbill.sh create mode 100755 testqrbill.sh diff --git a/.gitignore b/.gitignore index 11f22b0..79dd72f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ mkinvoice makefont -*.pdf +temp/* +qr-images/* +output/* +yaml/* diff --git a/makefont.go b/makefont.go index 474a9e3..1a67522 100644 --- a/makefont.go +++ b/makefont.go @@ -17,6 +17,6 @@ func main() { if errs2 != nil { fmt.Println(errs) } - pdf.AddFont("DejaVuSans", "", "DejaVuSans.json") - pdf.AddFont("DejaVuSans-Bold", "", "DejaVuSans-Bold.json") + pdf.AddFont("DejaVuSans", "", "DejaVuSans.json") + pdf.AddFont("DejaVuSans-Bold", "", "DejaVuSans-Bold.json") } diff --git a/mkinvoice.go b/mkinvoice.go index 295cc27..e5274a1 100644 --- a/mkinvoice.go +++ b/mkinvoice.go @@ -3,61 +3,91 @@ package main import ( "fmt" "github.com/jung-kurt/gofpdf" + "gopkg.in/yaml.v2" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" ) -type Adress struct { - lines []string +type Metadata struct { + Invoice_nr string + Invoice_info string + Invoice_date string + Vat float64 + Account string + Due_date string } -type Item struct { - text string - count float64 - price float64 +type Address struct { + Name string + Street string + Zip string + City string + Tel_no string + Email string +} + +type InvoiceItem struct { + Text string + Quantity float64 + Pice_per_unit float64 } type InvoiceData struct { - invoice_number string - invoice_date string - address Adress - items []Item - invoice_total_net float64 - invoice_mwst float64 - invoice_total float64 + Metadata Metadata + Sender_address Address + Billing_address Address + Item []InvoiceItem } /* global variable declaration */ var pdf *gofpdf.Fpdf var y_pos float64 var invoice_data InvoiceData +var prog_dir string + const margin_top = 7 const logo_top = 6 -const logo_height = 23 -const line_spacing = 4 +const logo_height = 20 +const line_spacing = 5 +const address_top = 50 +const line1_top = 100 const tabstop_left = 20 const tabstop_left_2 = 32 -const tabstop_address = 10 +const tabstop_address = 120 const tabstop_count = 10 const tabstop_price = 10 const tabstop_total = 170 const tabstop_logo = 155 +const tabstop_right = 200 func ReadInvoiceData(filename string) { - invoice_data.invoice_number = "1" - invoice_data.invoice_date = "01.01.2021" - invoice_data.address = Adress{ []string{"Jörg Lehmann", "Kirchweg 2", "3510 Konolfingen" }} - invoice_data.items = []Item{ Item{ "Item 1",1,10 }, Item{"Text only",0,0 } } - invoice_data.invoice_total_net = 100 - invoice_data.invoice_mwst = 10 - invoice_data.invoice_total = 110 + data, err := ioutil.ReadFile(filename) + if err != nil { + log.Fatal(err) + } + + //fmt.Printf("File contents: %s", data) + + err = yaml.Unmarshal([]byte(data), &invoice_data) + if err != nil { + log.Fatalf("error: %v", err) + } + + fmt.Printf("--- t:\n%v\n\n", invoice_data) + fmt.Printf("%s\n", invoice_data.Billing_address.Name) } func WriteText(x float64, y float64, text string, alignStr ...string) { + tr := pdf.UnicodeTranslatorFromDescriptor("") align := "LT" if len(alignStr) > 0 { align = alignStr[0] } pdf.SetXY(x, y) - pdf.CellFormat(0, 10, text, "", 0, align, false, 0, "") + pdf.CellFormat(0, 11, tr(text), "", 0, align, false, 0, "") } func SetupInvoice() { @@ -66,17 +96,17 @@ func SetupInvoice() { pdf.SetFontLocation("fonts") pdf.AddFont("Dejavusans", "", "DejaVuSans.json") pdf.AddFont("Dejavusans-Bold", "", "DejaVuSans-Bold.json") - pdf.SetFont("Dejavusans", "", 9) + pdf.SetFont("Dejavusans", "", 10) } func PrintPageHeader(firstPage bool) { - var opt gofpdf.ImageOptions + var opt gofpdf.ImageOptions pdf.AddPage() y_pos = margin_top - pdf.SetFont("Dejavusans-Bold", "", 9) + pdf.SetFont("Dejavusans-Bold", "", 10) WriteText(tabstop_left, y_pos, "nbit Informatik GmbH") - pdf.SetFont("Dejavusans", "", 9) + pdf.SetFont("Dejavusans", "", 10) y_pos = y_pos + line_spacing WriteText(tabstop_left, y_pos, "Kirchweg 2") y_pos = y_pos + line_spacing @@ -92,14 +122,73 @@ func PrintPageHeader(firstPage bool) { opt.ImageType = "png" opt.ReadDpi = true - pdf.ImageOptions("logos/nbit-logo.png", tabstop_logo, logo_top, 0, logo_height, false, opt, 0, "") + pdf.ImageOptions("logos/nbit-logo.png", tabstop_logo, logo_top, 0, logo_height, false, opt, 0, "") +} + +func PrintAddress() { + fmt.Printf("Blabla: %s\n", invoice_data.Billing_address.Name) + y_pos = address_top + WriteText(tabstop_address, y_pos, invoice_data.Billing_address.Name) + y_pos = y_pos + line_spacing + WriteText(tabstop_address, y_pos, invoice_data.Billing_address.Street) + y_pos = y_pos + line_spacing + WriteText(tabstop_address, y_pos, invoice_data.Billing_address.Zip+" "+invoice_data.Billing_address.City) + y_pos = y_pos + line_spacing + + pdf.Line(tabstop_left, line1_top, tabstop_right, line1_top) +} + +func PrintQR() { + var opt gofpdf.ImageOptions + + cmd := exec.Command(filepath.Join(prog_dir, "qrbill.sh"), + "--account", invoice_data.Metadata.Account, + "--amount", "123.00", + "--creditor-name", invoice_data.Sender_address.Name, + "--creditor-street", invoice_data.Sender_address.Street, + "--creditor-postalcode", invoice_data.Sender_address.Zip, + "--creditor-city", invoice_data.Sender_address.City, + "--extra-infos", invoice_data.Metadata.Invoice_info, + "--debtor-name", invoice_data.Billing_address.Name, + "--debtor-street", invoice_data.Billing_address.Street, + "--debtor-postalcode", invoice_data.Billing_address.Zip, + "--debtor-city", invoice_data.Billing_address.City, + "--due-date", invoice_data.Metadata.Due_date, + "--language", "de") + cmd.Env = append(os.Environ(), + "INVNO="+invoice_data.Metadata.Invoice_nr, + ) + stdoutStderr, err := cmd.CombinedOutput() + fmt.Printf("%s\n", stdoutStderr) + if err != nil { + log.Fatal(err) + } + fmt.Printf("%s\n", stdoutStderr) + + opt.ImageType = "jpeg" + opt.ReadDpi = true + pdf.ImageOptions("qr-images/"+invoice_data.Metadata.Invoice_nr+".jpg", 0, 200, 0, 0, false, opt, 0, "") } func main() { + dir, err := filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + log.Fatal(err) + } + prog_dir = dir + + if len(os.Args) != 2 { + fmt.Printf("usage: mkinvoice \n") + os.Exit(1) + } + + ReadInvoiceData(os.Args[1]) SetupInvoice() PrintPageHeader(true) + PrintAddress() + PrintQR() - err := pdf.OutputFileAndClose("hello.pdf") + err = pdf.OutputFileAndClose(filepath.Join(prog_dir, "output", invoice_data.Metadata.Invoice_nr+".pdf")) if err == nil { fmt.Printf("Successfully created invoice\n") } else { diff --git a/qrbill.sh b/qrbill.sh new file mode 100755 index 0000000..de90492 --- /dev/null +++ b/qrbill.sh @@ -0,0 +1,36 @@ +#!/bin/bash +mydir="$(dirname $0)" +if [ -z "${INVNO}" ]; then + echo "ERROR: INVNO must be set as ENV variable" + exit 1 +fi + +echo "INVNO: ${INVNO}" + +# should be called with following arguments (example) +# INVNO must be set as ENV variable + +# --account "CH92 0023 5235 5662 3601 G" +# --amount 123.00 +# --creditor-name "nbit Informatik GmbH" +# --creditor-street "Kirchweg 2" +# --creditor-postalcode "3510" +# --creditor-city "Konolfingen" +# --extra-infos "Rechnung Nummer ${INVNO}" +# --debtor-name "Wilhelm Tell" +# --debtor-street "Marktgasse 28" +# --debtor-postalcode "9400" +# --debtor-city "Rorschach" +# --due-date "2019-10-31" +# --language "de" + +qrbill "$@" --output ${mydir}/temp/${INVNO}.svg +if [ $? -ne 0 ]; then + echo "ERROR: cannot create qrbill image" + exit 2 +fi + +convert ${mydir}/temp/${INVNO}.svg ${mydir}/qr-images/${INVNO}.jpg +if [ $? -eq 0 ]; then + rm ${mydir}/temp/${INVNO}.svg +fi diff --git a/testqrbill.sh b/testqrbill.sh new file mode 100755 index 0000000..326af6c --- /dev/null +++ b/testqrbill.sh @@ -0,0 +1,16 @@ +#!/bin/bash +mydir="$(dirname $0)" +export INVNO=123456789 +${mydir}/qrbill.sh --account "CH92 0023 5235 5662 3601 G" \ + --amount 123.00 \ + --creditor-name "nbit Informatik GmbH" \ + --creditor-street "Kirchweg 2" \ + --creditor-postalcode "3510" \ + --creditor-city "Konolfingen" \ + --extra-infos "Rechnung Nummer 123456789" \ + --debtor-name "Wilhelm Tell" \ + --debtor-street "Marktgasse 28" \ + --debtor-postalcode "9400" \ + --debtor-city "Rorschach" \ + --due-date "2019-10-31" \ + --language "de"