one step forward
This commit is contained in:
parent
a86fa3c9ee
commit
1c89fd7af3
|
|
@ -1,3 +1,6 @@
|
||||||
mkinvoice
|
mkinvoice
|
||||||
makefont
|
makefont
|
||||||
*.pdf
|
temp/*
|
||||||
|
qr-images/*
|
||||||
|
output/*
|
||||||
|
yaml/*
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,6 @@ func main() {
|
||||||
if errs2 != nil {
|
if errs2 != nil {
|
||||||
fmt.Println(errs)
|
fmt.Println(errs)
|
||||||
}
|
}
|
||||||
pdf.AddFont("DejaVuSans", "", "DejaVuSans.json")
|
pdf.AddFont("DejaVuSans", "", "DejaVuSans.json")
|
||||||
pdf.AddFont("DejaVuSans-Bold", "", "DejaVuSans-Bold.json")
|
pdf.AddFont("DejaVuSans-Bold", "", "DejaVuSans-Bold.json")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
149
mkinvoice.go
149
mkinvoice.go
|
|
@ -3,61 +3,91 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jung-kurt/gofpdf"
|
"github.com/jung-kurt/gofpdf"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Adress struct {
|
type Metadata struct {
|
||||||
lines []string
|
Invoice_nr string
|
||||||
|
Invoice_info string
|
||||||
|
Invoice_date string
|
||||||
|
Vat float64
|
||||||
|
Account string
|
||||||
|
Due_date string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Item struct {
|
type Address struct {
|
||||||
text string
|
Name string
|
||||||
count float64
|
Street string
|
||||||
price float64
|
Zip string
|
||||||
|
City string
|
||||||
|
Tel_no string
|
||||||
|
Email string
|
||||||
|
}
|
||||||
|
|
||||||
|
type InvoiceItem struct {
|
||||||
|
Text string
|
||||||
|
Quantity float64
|
||||||
|
Pice_per_unit float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type InvoiceData struct {
|
type InvoiceData struct {
|
||||||
invoice_number string
|
Metadata Metadata
|
||||||
invoice_date string
|
Sender_address Address
|
||||||
address Adress
|
Billing_address Address
|
||||||
items []Item
|
Item []InvoiceItem
|
||||||
invoice_total_net float64
|
|
||||||
invoice_mwst float64
|
|
||||||
invoice_total float64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* global variable declaration */
|
/* global variable declaration */
|
||||||
var pdf *gofpdf.Fpdf
|
var pdf *gofpdf.Fpdf
|
||||||
var y_pos float64
|
var y_pos float64
|
||||||
var invoice_data InvoiceData
|
var invoice_data InvoiceData
|
||||||
|
var prog_dir string
|
||||||
|
|
||||||
const margin_top = 7
|
const margin_top = 7
|
||||||
const logo_top = 6
|
const logo_top = 6
|
||||||
const logo_height = 23
|
const logo_height = 20
|
||||||
const line_spacing = 4
|
const line_spacing = 5
|
||||||
|
const address_top = 50
|
||||||
|
const line1_top = 100
|
||||||
const tabstop_left = 20
|
const tabstop_left = 20
|
||||||
const tabstop_left_2 = 32
|
const tabstop_left_2 = 32
|
||||||
const tabstop_address = 10
|
const tabstop_address = 120
|
||||||
const tabstop_count = 10
|
const tabstop_count = 10
|
||||||
const tabstop_price = 10
|
const tabstop_price = 10
|
||||||
const tabstop_total = 170
|
const tabstop_total = 170
|
||||||
const tabstop_logo = 155
|
const tabstop_logo = 155
|
||||||
|
const tabstop_right = 200
|
||||||
|
|
||||||
func ReadInvoiceData(filename string) {
|
func ReadInvoiceData(filename string) {
|
||||||
invoice_data.invoice_number = "1"
|
data, err := ioutil.ReadFile(filename)
|
||||||
invoice_data.invoice_date = "01.01.2021"
|
if err != nil {
|
||||||
invoice_data.address = Adress{ []string{"Jörg Lehmann", "Kirchweg 2", "3510 Konolfingen" }}
|
log.Fatal(err)
|
||||||
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
|
//fmt.Printf("File contents: %s", data)
|
||||||
invoice_data.invoice_total = 110
|
|
||||||
|
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) {
|
func WriteText(x float64, y float64, text string, alignStr ...string) {
|
||||||
|
tr := pdf.UnicodeTranslatorFromDescriptor("")
|
||||||
align := "LT"
|
align := "LT"
|
||||||
if len(alignStr) > 0 {
|
if len(alignStr) > 0 {
|
||||||
align = alignStr[0]
|
align = alignStr[0]
|
||||||
}
|
}
|
||||||
pdf.SetXY(x, y)
|
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() {
|
func SetupInvoice() {
|
||||||
|
|
@ -66,17 +96,17 @@ func SetupInvoice() {
|
||||||
pdf.SetFontLocation("fonts")
|
pdf.SetFontLocation("fonts")
|
||||||
pdf.AddFont("Dejavusans", "", "DejaVuSans.json")
|
pdf.AddFont("Dejavusans", "", "DejaVuSans.json")
|
||||||
pdf.AddFont("Dejavusans-Bold", "", "DejaVuSans-Bold.json")
|
pdf.AddFont("Dejavusans-Bold", "", "DejaVuSans-Bold.json")
|
||||||
pdf.SetFont("Dejavusans", "", 9)
|
pdf.SetFont("Dejavusans", "", 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrintPageHeader(firstPage bool) {
|
func PrintPageHeader(firstPage bool) {
|
||||||
var opt gofpdf.ImageOptions
|
var opt gofpdf.ImageOptions
|
||||||
|
|
||||||
pdf.AddPage()
|
pdf.AddPage()
|
||||||
y_pos = margin_top
|
y_pos = margin_top
|
||||||
pdf.SetFont("Dejavusans-Bold", "", 9)
|
pdf.SetFont("Dejavusans-Bold", "", 10)
|
||||||
WriteText(tabstop_left, y_pos, "nbit Informatik GmbH")
|
WriteText(tabstop_left, y_pos, "nbit Informatik GmbH")
|
||||||
pdf.SetFont("Dejavusans", "", 9)
|
pdf.SetFont("Dejavusans", "", 10)
|
||||||
y_pos = y_pos + line_spacing
|
y_pos = y_pos + line_spacing
|
||||||
WriteText(tabstop_left, y_pos, "Kirchweg 2")
|
WriteText(tabstop_left, y_pos, "Kirchweg 2")
|
||||||
y_pos = y_pos + line_spacing
|
y_pos = y_pos + line_spacing
|
||||||
|
|
@ -92,14 +122,73 @@ func PrintPageHeader(firstPage bool) {
|
||||||
|
|
||||||
opt.ImageType = "png"
|
opt.ImageType = "png"
|
||||||
opt.ReadDpi = true
|
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() {
|
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 <yaml-file>\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadInvoiceData(os.Args[1])
|
||||||
SetupInvoice()
|
SetupInvoice()
|
||||||
PrintPageHeader(true)
|
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 {
|
if err == nil {
|
||||||
fmt.Printf("Successfully created invoice\n")
|
fmt.Printf("Successfully created invoice\n")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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"
|
||||||
Loading…
Reference in New Issue