pure golang version
This commit is contained in:
parent
4ab3666a98
commit
0ce37e9aa9
|
|
@ -5,12 +5,10 @@ purpose to generate PDF-Invoices for nbit Informatik GmbH
|
|||
|
||||
Font File can be generated with makefont
|
||||
|
||||
Payment Slip is generated using https://github.com/claudep/swiss-qr-bill
|
||||
|
||||
Installation / Upgrade
|
||||
$ pip install --user qrbill -U
|
||||
To generate the QRCode, following library is used:
|
||||
https://github.com/stapelberg/qrbill
|
||||
|
||||
Usage (Example):
|
||||
$ ./mkinvoice yaml/123456.yml
|
||||
|
||||
Joerg Lehmann, April 2020
|
||||
Joerg Lehmann, December 2020
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
width="100"
|
||||
height="60"
|
||||
id="svg2">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
id="Scissors"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
d="M 9.0898857,-3.6061018 C 8.1198849,-4.7769976 6.3697607,-4.7358294 5.0623558,-4.2327734 l -8.2124046,3.0779029 c -2.3882933,-1.3067135 -4.7482873,-0.9325372 -4.7482873,-1.5687873 0,-0.4973164 0.4566662,-0.3883222 0.3883068,-1.6831941 -0.065635,-1.2432767 -1.3635771,-2.1630796 -2.5903987,-2.0816435 -1.227271,-0.00735 -2.499439,0.9331613 -2.510341,2.2300611 -0.09143,1.3063864 1.007209,2.5196896 2.306764,2.6052316 1.5223406,0.2266616 4.218258,-0.6955566 5.482945,1.57086006 -0.9422847,1.73825774 -2.6140244,1.74307674 -4.1255107,1.65607034 -1.2548743,-0.072235 -2.7620933,0.2873979 -3.3606483,1.5208605 -0.578367,1.1820862 -0.0112,2.8646022 1.316749,3.226412 1.3401912,0.4918277 3.1806689,-0.129711 3.4993722,-1.6707242 0.2456585,-1.187823 -0.5953659,-1.7459574 -0.2725074,-2.1771537 0.2436135,-0.32536 1.7907806,-0.1368452 4.5471053,-1.3748244 L 5.6763468,4.2330688 C 6.8000164,4.5467672 8.1730685,4.5362646 9.1684433,3.4313614 L -0.05164093,-0.05372222 9.0898857,-3.6061018 z m -18.3078016,-1.900504 c 1.294559,0.7227998 1.1888392,2.6835702 -0.1564272,3.0632889 -1.2165179,0.423661 -2.7710269,-0.7589694 -2.3831779,-2.0774648 0.227148,-1.0818519 1.653387,-1.480632 2.5396051,-0.9858241 z m 0.056264,8.0173649 c 1.3508301,0.4988648 1.1214429,2.7844356 -0.2522207,3.091609 -0.9110594,0.3163391 -2.2135494,-0.1387976 -2.3056964,-1.2121394 -0.177609,-1.305055 1.356085,-2.4841482 2.5579171,-1.8794696 z"
|
||||
id="schere"
|
||||
style="marker-start:none" />
|
||||
</marker>
|
||||
</defs>
|
||||
<g
|
||||
transform="translate(0,-992.36218)"
|
||||
id="layer1">
|
||||
<g
|
||||
transform="matrix(4.2610846,-1.2351263,1.2351263,4.2610846,-1337.7659,-2994.9736)"
|
||||
id="g4593">
|
||||
<path
|
||||
d="m 59.731665,956.40057 c -0.609784,-1.39286 -2.303491,-1.83556 -3.698902,-1.71226 l -8.742604,0.69566 c -1.935736,-1.91425 -4.307466,-2.2049 -4.132136,-2.81651 0.137044,-0.47806 0.545993,-0.24745 0.837105,-1.51102 0.279511,-1.21323 -0.714709,-2.45509 -1.916471,-2.71488 -1.177727,-0.34526 -2.659814,0.20827 -3.027677,1.45195 -0.447882,1.23061 0.273869,2.69969 1.499535,3.14003 1.400938,0.6374 4.246607,0.49379 4.837778,3.02096 -1.384807,1.41129 -2.993148,0.95525 -4.422137,0.4551 -1.186382,-0.41524 -2.734347,-0.48487 -3.649629,0.53589 -0.881717,0.97694 -0.800158,2.7506 0.376675,3.46434 1.15277,0.8421 3.093263,0.7518 3.824279,-0.64172 0.563472,-1.07414 -0.09119,-1.84242 0.337995,-2.16796 0.32384,-0.24563 1.759155,0.36194 4.749906,-0.0686 l 7.684693,5.46398 c 0.993719,0.61119 2.316503,0.97947 3.577814,0.19164 l -7.902726,-5.8909 9.766502,-0.89574 z m -17.075242,-6.87194 c 1.045256,1.05155 0.403306,2.90727 -0.994512,2.90157 -1.286163,0.072 -2.454591,-1.49318 -1.718425,-2.65375 0.516476,-0.97737 1.997384,-0.96769 2.712937,-0.24782 z m -2.155235,7.72245 c 1.161058,0.85179 0.310724,2.98566 -1.0944,2.9024 -0.962958,0.053 -2.089598,-0.7434 -1.882399,-1.80058 0.188897,-1.30347 1.988129,-2.01427 2.976799,-1.10182 z"
|
||||
id="path4599"
|
||||
style="marker-start:none" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.9 KiB |
213
mkinvoice.go
213
mkinvoice.go
|
|
@ -1,18 +1,21 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/jung-kurt/gofpdf"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
"gopkg.in/yaml.v2"
|
||||
"image/png"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/stapelberg/qrbill"
|
||||
)
|
||||
|
||||
// Metadata type
|
||||
|
|
@ -28,6 +31,7 @@ type Metadata struct {
|
|||
type Address struct {
|
||||
Name string `yaml:"name"`
|
||||
Street string `yaml:"street"`
|
||||
StreetNumber string `yaml:"streetnumber"`
|
||||
Zip string `yaml:"zip"`
|
||||
City string `yaml:"city"`
|
||||
TelNo string `yaml:"tel_no"`
|
||||
|
|
@ -62,11 +66,17 @@ var totalInvoiceAmount float64
|
|||
|
||||
const defaultFontSize = 9
|
||||
const smallFontSize = 7
|
||||
const paymentSlipTitleFontSize = 11
|
||||
const paymentSlipHeadingFontSize = 6
|
||||
const paymentSlipValuesFontSize = 8
|
||||
const marginTop = 7
|
||||
const logoTop = 6
|
||||
const logoHeight = 20
|
||||
const lineSpacing = 5
|
||||
const lineSpacingSmall = 4.5
|
||||
const lineSpacingPaymentSlipBig = 6
|
||||
const lineSpacingPaymentSlipBelowHeading = 2.8
|
||||
const lineSpacingPaymentSlipSmall = 3.175
|
||||
const addressTop = 50
|
||||
const metadataTopFirstPage = 70
|
||||
const metadataTopNotFirstPage = 30
|
||||
|
|
@ -87,14 +97,26 @@ const itemsTopFirstPage = 105
|
|||
const itemsTopNotFirstPage = 50
|
||||
const totalsTop = 158
|
||||
const maxYPos = 265
|
||||
const paymentSlipTop = 190
|
||||
const paymentSlipWaehrung = 270
|
||||
const paymentSlipDashLeft = 63
|
||||
const tabstopPaymentSlipLeft = 5
|
||||
const tabstopPaymentSlipLeft2 = 17
|
||||
const tabstopPaymentSlipLeft3 = 40
|
||||
const tabstopPaymentSlipMiddle = 68
|
||||
const tabstopPaymentSlipMiddle2 = 80
|
||||
const tabstopPaymentSlipRight = 125
|
||||
const scissorsTop = 200
|
||||
const widthA4 = 210
|
||||
const lengthA4 = 297
|
||||
|
||||
func round5rappen(f float64) float64 {
|
||||
return (math.Round(f*20) / 20)
|
||||
}
|
||||
|
||||
func floatToString(f float64) string {
|
||||
func floatToString(f float64, sep string) string {
|
||||
p := message.NewPrinter(language.English)
|
||||
s := strings.ReplaceAll(p.Sprintf("%.2f", f), ",", "'")
|
||||
s := strings.ReplaceAll(p.Sprintf("%.2f", f), ",", sep)
|
||||
//fmt.Printf("--- s: @%s@\n", s)
|
||||
return s
|
||||
}
|
||||
|
|
@ -128,6 +150,7 @@ func writeText(x float64, y float64, w float64, text string, alignStr ...string)
|
|||
func setupInvoice() {
|
||||
pdf = gofpdf.New("P", "mm", "A4", "")
|
||||
pdf.SetMargins(0, 0, 0)
|
||||
pdf.SetAutoPageBreak(false, 0)
|
||||
pdf.SetFontLocation("fonts")
|
||||
pdf.AddFont("Dejavusans", "", "DejaVuSans.json")
|
||||
pdf.AddFont("Dejavusans-Bold", "", "DejaVuSans-Bold.json")
|
||||
|
|
@ -145,7 +168,7 @@ func printPageHeader(firstPage bool) {
|
|||
writeText(tabstopLeft, yPos, 0, invoiceData.SenderAddress.Name)
|
||||
pdf.SetFont("Dejavusans", "", defaultFontSize)
|
||||
yPos = yPos + lineSpacing
|
||||
writeText(tabstopLeft, yPos, 0, invoiceData.SenderAddress.Street)
|
||||
writeText(tabstopLeft, yPos, 0, invoiceData.SenderAddress.Street+" "+invoiceData.SenderAddress.StreetNumber)
|
||||
yPos = yPos + lineSpacing
|
||||
writeText(tabstopLeft, yPos, 0, invoiceData.SenderAddress.Zip+" "+invoiceData.SenderAddress.City)
|
||||
if firstPage {
|
||||
|
|
@ -171,7 +194,7 @@ func printAddress() {
|
|||
yPos = addressTop
|
||||
writeText(tabstopAddress, yPos, 0, invoiceData.BillingAddress.Name)
|
||||
yPos = yPos + lineSpacing
|
||||
writeText(tabstopAddress, yPos, 0, invoiceData.BillingAddress.Street)
|
||||
writeText(tabstopAddress, yPos, 0, invoiceData.BillingAddress.Street+" "+invoiceData.BillingAddress.StreetNumber)
|
||||
yPos = yPos + lineSpacing
|
||||
writeText(tabstopAddress, yPos, 0, invoiceData.BillingAddress.Zip+" "+invoiceData.BillingAddress.City)
|
||||
}
|
||||
|
|
@ -235,7 +258,7 @@ func printItems() {
|
|||
writeText(tabstopPricePerUnit, yPos, widthPricePerUnit, fmt.Sprintf("%.2f", i.PricePerUnit), "TR")
|
||||
itemNetAmount := round5rappen(i.Quantity * i.PricePerUnit)
|
||||
totalNetAmount = totalNetAmount + itemNetAmount
|
||||
writeText(tabstopPrice, yPos, widthPrice, floatToString(itemNetAmount), "TR")
|
||||
writeText(tabstopPrice, yPos, widthPrice, floatToString(itemNetAmount, "'"), "TR")
|
||||
}
|
||||
if i.Text != "" {
|
||||
lines := pdf.SplitText(i.Text, widthItemText)
|
||||
|
|
@ -260,52 +283,181 @@ func printTotals() {
|
|||
yPos = yPos + lineSpacing
|
||||
writeText(tabstopLeft, yPos, 0, "Summe")
|
||||
pdf.SetFont("Dejavusans", "", defaultFontSize)
|
||||
writeText(tabstopPrice, yPos, widthPrice, floatToString(totalNetAmount), "TR")
|
||||
writeText(tabstopPrice, yPos, widthPrice, floatToString(totalNetAmount, "'"), "TR")
|
||||
yPos = yPos + lineSpacing
|
||||
pdf.SetFont("Dejavusans-Bold", "", defaultFontSize)
|
||||
writeText(tabstopLeft, yPos, 0, fmt.Sprintf("MwSt. %.1f%%", invoiceData.Metadata.Vat))
|
||||
mwstAmount := round5rappen(totalNetAmount * invoiceData.Metadata.Vat / 100)
|
||||
pdf.SetFont("Dejavusans", "", defaultFontSize)
|
||||
writeText(tabstopPrice, yPos, widthPrice, floatToString(mwstAmount), "TR")
|
||||
writeText(tabstopPrice, yPos, widthPrice, floatToString(mwstAmount, "'"), "TR")
|
||||
yPos = yPos + lineSpacing
|
||||
yPos = yPos + lineSpacing
|
||||
pdf.SetFont("Dejavusans-Bold", "", defaultFontSize)
|
||||
writeText(tabstopLeft, yPos, 0, "Rechnungbetrag in CHF")
|
||||
totalInvoiceAmount = totalNetAmount + mwstAmount
|
||||
writeText(tabstopPrice, yPos, widthPrice, floatToString(totalNetAmount+mwstAmount), "TR")
|
||||
writeText(tabstopPrice, yPos, widthPrice, floatToString(totalNetAmount+mwstAmount, "'"), "TR")
|
||||
yPos = yPos + lineSpacingSmall
|
||||
pdf.SetFont("Dejavusans", "", smallFontSize)
|
||||
writeText(tabstopLeft, yPos, 0, "30 Tage netto")
|
||||
}
|
||||
|
||||
func qrchFromInvoiceData(id InvoiceData) *qrbill.QRCH {
|
||||
return &qrbill.QRCH{
|
||||
CdtrInf: qrbill.QRCHCdtrInf{
|
||||
IBAN: id.Metadata.Account,
|
||||
Cdtr: qrbill.Address{
|
||||
AdrTp: qrbill.AddressType(string(qrbill.AddressTypeStructured)),
|
||||
Name: id.SenderAddress.Name,
|
||||
StrtNmOrAdrLine1: id.SenderAddress.Street,
|
||||
BldgNbOrAdrLine2: id.SenderAddress.StreetNumber,
|
||||
PstCd: id.SenderAddress.Zip,
|
||||
TwnNm: id.SenderAddress.City,
|
||||
Ctry: "CH",
|
||||
},
|
||||
},
|
||||
CcyAmt: qrbill.QRCHCcyAmt{
|
||||
Amt: fmt.Sprintf("%.2f", totalInvoiceAmount),
|
||||
Ccy: "CHF",
|
||||
},
|
||||
UltmtDbtr: qrbill.Address{
|
||||
AdrTp: qrbill.AddressType(string(qrbill.AddressTypeStructured)),
|
||||
Name: id.BillingAddress.Name,
|
||||
StrtNmOrAdrLine1: id.BillingAddress.Street,
|
||||
BldgNbOrAdrLine2: id.BillingAddress.StreetNumber,
|
||||
PstCd: id.BillingAddress.Zip,
|
||||
TwnNm: id.BillingAddress.City,
|
||||
Ctry: "CH",
|
||||
},
|
||||
RmtInf: qrbill.QRCHRmtInf{
|
||||
Tp: "NON", // Reference type
|
||||
Ref: "", // Reference
|
||||
AddInf: qrbill.QRCHRmtInfAddInf{
|
||||
Ustrd: "Rechnung Nummer " + id.Metadata.InvoiceNr,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func printPaymentSlip() {
|
||||
var opt gofpdf.ImageOptions
|
||||
|
||||
pdf.SetDashPattern([]float64{0.8, 0.8}, 0)
|
||||
pdf.Line(0, paymentSlipTop, widthA4, paymentSlipTop)
|
||||
pdf.Line(paymentSlipDashLeft, paymentSlipTop, paymentSlipDashLeft, lengthA4)
|
||||
opt.ImageType = "png"
|
||||
pdf.ImageOptions("logos/scissors-rotated.png", paymentSlipDashLeft-1.5, paymentSlipTop+10, 3, 3, false, opt, 0, "")
|
||||
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipTitleFontSize)
|
||||
yPos = paymentSlipTop + 7
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, "Empfangsschein")
|
||||
yPos = yPos + lineSpacingPaymentSlipBig
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipHeadingFontSize)
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, "Konto / Zahlbar an")
|
||||
yPos = yPos + lineSpacingPaymentSlipBelowHeading
|
||||
pdf.SetFont("Helvetica", "", paymentSlipValuesFontSize)
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, invoiceData.Metadata.Account)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, invoiceData.SenderAddress.Name)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, invoiceData.SenderAddress.Street+" "+invoiceData.SenderAddress.StreetNumber)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, invoiceData.SenderAddress.Zip+" "+invoiceData.SenderAddress.City)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipHeadingFontSize)
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, "Zahlbar durch")
|
||||
yPos = yPos + lineSpacingPaymentSlipBelowHeading
|
||||
pdf.SetFont("Helvetica", "", paymentSlipValuesFontSize)
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, invoiceData.BillingAddress.Name)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, invoiceData.BillingAddress.Street+" "+invoiceData.BillingAddress.StreetNumber)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, invoiceData.BillingAddress.Zip+" "+invoiceData.BillingAddress.City)
|
||||
yPos = paymentSlipWaehrung
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipHeadingFontSize)
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, "Währung")
|
||||
writeText(tabstopPaymentSlipLeft2, yPos, 0, "Betrag")
|
||||
yPos = yPos + lineSpacingPaymentSlipBelowHeading
|
||||
pdf.SetFont("Helvetica", "", paymentSlipValuesFontSize)
|
||||
writeText(tabstopPaymentSlipLeft, yPos, 0, "CHF")
|
||||
writeText(tabstopPaymentSlipLeft2, yPos, 0, floatToString(totalInvoiceAmount, " "))
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipHeadingFontSize)
|
||||
writeText(tabstopPaymentSlipLeft3, yPos, 0, "Annahmestelle")
|
||||
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipTitleFontSize)
|
||||
yPos = paymentSlipTop + 7
|
||||
writeText(tabstopPaymentSlipMiddle, yPos, 0, "Zahlteil")
|
||||
yPos = paymentSlipWaehrung
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipHeadingFontSize)
|
||||
writeText(tabstopPaymentSlipMiddle, yPos, 0, "Währung")
|
||||
writeText(tabstopPaymentSlipMiddle2, yPos, 0, "Betrag")
|
||||
yPos = yPos + lineSpacingPaymentSlipBelowHeading
|
||||
pdf.SetFont("Helvetica", "", paymentSlipValuesFontSize)
|
||||
writeText(tabstopPaymentSlipMiddle, yPos, 0, "CHF")
|
||||
writeText(tabstopPaymentSlipMiddle2, yPos, 0, floatToString(totalInvoiceAmount, " "))
|
||||
|
||||
yPos = paymentSlipTop + 7
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipHeadingFontSize)
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, "Konto / Zahlbar an")
|
||||
yPos = yPos + lineSpacingPaymentSlipBelowHeading
|
||||
pdf.SetFont("Helvetica", "", paymentSlipValuesFontSize)
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, invoiceData.Metadata.Account)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, invoiceData.SenderAddress.Name)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, invoiceData.SenderAddress.Street+" "+invoiceData.SenderAddress.StreetNumber)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, invoiceData.SenderAddress.Zip+" "+invoiceData.SenderAddress.City)
|
||||
yPos = yPos + (lineSpacingPaymentSlipSmall * 1.5)
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipHeadingFontSize)
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, "Zusätzliche Informationen")
|
||||
yPos = yPos + lineSpacingPaymentSlipBelowHeading
|
||||
pdf.SetFont("Helvetica", "", paymentSlipValuesFontSize)
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, "Rechnung Nummer "+invoiceData.Metadata.InvoiceNr)
|
||||
yPos = yPos + (lineSpacingPaymentSlipSmall * 1.5)
|
||||
pdf.SetFont("Helvetica", "B", paymentSlipHeadingFontSize)
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, "Zahlbar durch")
|
||||
yPos = yPos + lineSpacingPaymentSlipBelowHeading
|
||||
pdf.SetFont("Helvetica", "", paymentSlipValuesFontSize)
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, invoiceData.BillingAddress.Name)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, invoiceData.BillingAddress.Street+" "+invoiceData.BillingAddress.StreetNumber)
|
||||
yPos = yPos + lineSpacingPaymentSlipSmall
|
||||
writeText(tabstopPaymentSlipRight, yPos, 0, invoiceData.BillingAddress.Zip+" "+invoiceData.BillingAddress.City)
|
||||
}
|
||||
|
||||
func printQR() {
|
||||
var opt gofpdf.ImageOptions
|
||||
|
||||
cmd := exec.Command(filepath.Join(progDir, "qrbill.sh"),
|
||||
"--account", invoiceData.Metadata.Account,
|
||||
"--amount", floatToString(totalInvoiceAmount),
|
||||
"--creditor-name", invoiceData.SenderAddress.Name,
|
||||
"--creditor-street", invoiceData.SenderAddress.Street,
|
||||
"--creditor-postalcode", invoiceData.SenderAddress.Zip,
|
||||
"--creditor-city", invoiceData.SenderAddress.City,
|
||||
"--extra-infos", "Rechnung Nummer " + invoiceData.Metadata.InvoiceNr,
|
||||
"--debtor-name", invoiceData.BillingAddress.Name,
|
||||
"--debtor-street", invoiceData.BillingAddress.Street,
|
||||
"--debtor-postalcode", invoiceData.BillingAddress.Zip,
|
||||
"--debtor-city", invoiceData.BillingAddress.City,
|
||||
"--language", "de")
|
||||
cmd.Env = append(os.Environ(),
|
||||
"INVNO="+invoiceData.Metadata.InvoiceNr,
|
||||
)
|
||||
stdoutStderr, err := cmd.CombinedOutput()
|
||||
fmt.Printf("%s\n", stdoutStderr)
|
||||
var b []byte
|
||||
var err error
|
||||
qrch := qrchFromInvoiceData(invoiceData)
|
||||
bill, err := qrch.Encode()
|
||||
|
||||
code, err := bill.EncodeToImage()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Printf("%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := png.Encode(&buf, code); err != nil {
|
||||
log.Printf("%s", err)
|
||||
return
|
||||
}
|
||||
b = buf.Bytes()
|
||||
|
||||
err = ioutil.WriteFile("qr-images/"+invoiceData.Metadata.InvoiceNr+".png", b, 0644)
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
|
||||
opt.ImageType = "png"
|
||||
opt.ReadDpi = true
|
||||
pdf.ImageOptions("qr-images/"+invoiceData.Metadata.InvoiceNr+".png", 0, 193, -1, -1, false, opt, 0, "")
|
||||
opt.ReadDpi = false
|
||||
|
||||
pdf.ImageOptions("qr-images/"+invoiceData.Metadata.InvoiceNr+".png", tabstopPaymentSlipMiddle-2, paymentSlipTop+13, 56, 56, false, opt, 0, "")
|
||||
}
|
||||
|
||||
func CreateInvoice() {
|
||||
|
|
@ -319,6 +471,7 @@ func CreateInvoice() {
|
|||
printItemsHeader()
|
||||
printItems()
|
||||
printTotals()
|
||||
printPaymentSlip()
|
||||
printQR()
|
||||
}
|
||||
|
||||
|
|
|
|||
39
qrbill.sh
39
qrbill.sh
|
|
@ -1,39 +0,0 @@
|
|||
#!/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
|
||||
#inkscape ${mydir}/temp/${INVNO}.svg --export-width=794 --export-height=397 --export-filename ${mydir}/qr-images/${INVNO}.png
|
||||
inkscape ${mydir}/temp/${INVNO}.svg --export-dpi=300 --export-filename ${mydir}/qr-images/${INVNO}.png
|
||||
#cairosvg ${mydir}/temp/${INVNO}.svg -o ${mydir}/qr-images/${INVNO}.png
|
||||
if [ $? -eq 0 ]; then
|
||||
rm ${mydir}/temp/${INVNO}.svg
|
||||
fi
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#!/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