mkinvoice/mkinvoice.go

203 lines
4.8 KiB
Go

package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"github.com/jung-kurt/gofpdf"
"gopkg.in/yaml.v2"
)
// Metadata type
type Metadata struct {
InvoiceNr string
InvoiceInfo string
InvoiceDdate string
Vat float64
Account string
DueDate string
}
// Address type
type Address struct {
Name string
Street string
Zip string
City string
TelNo string
Email string
}
// InvoiceItem type
type InvoiceItem struct {
Text string
Quantity float64
PicePerUnit float64
}
// InvoiceData type
type InvoiceData struct {
Metadata Metadata
SenderAddress Address
BillingAddress Address
Item []InvoiceItem
}
/* global variable declaration */
var pdf *gofpdf.Fpdf
var yPos float64
var invoiceData InvoiceData
var progDir string
const marginTop = 7
const logoTop = 6
const logoHeight = 20
const lineSpacing = 5
const addressTop = 50
const line1Top = 100
const tabstopLeft = 20
const tabstopLeftAlt = 32
const tabstopAddress = 120
const tabstopCount = 10
const tabstopPrice = 10
const tabstopTotal = 170
const tabstopLogo = 155
const tabstopRight = 200
func readInvoiceData(filename string) {
data, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
}
//fmt.Printf("File contents: %s", data)
err = yaml.Unmarshal([]byte(data), &invoiceData)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("--- t:\n%v\n\n", invoiceData)
fmt.Printf("%s\n", invoiceData.BillingAddress.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, 11, tr(text), "", 0, align, false, 0, "")
}
func setupInvoice() {
pdf = gofpdf.New("P", "mm", "A4", "")
pdf.SetMargins(0, 0, 0)
pdf.SetFontLocation("fonts")
pdf.AddFont("Dejavusans", "", "DejaVuSans.json")
pdf.AddFont("Dejavusans-Bold", "", "DejaVuSans-Bold.json")
pdf.SetFont("Dejavusans", "", 10)
}
func printPageHeader(firstPage bool) {
var opt gofpdf.ImageOptions
pdf.AddPage()
yPos = marginTop
pdf.SetFont("Dejavusans-Bold", "", 10)
writeText(tabstopLeft, yPos, "nbit Informatik GmbH")
pdf.SetFont("Dejavusans", "", 10)
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, "Kirchweg 2")
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, "3510 Konolfingen")
yPos = yPos + lineSpacing
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, "Tel.")
writeText(tabstopLeftAlt, yPos, "+41 31 792 00 40")
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, "EMail")
writeText(tabstopLeftAlt, yPos, "joerg.lehmann@nbit.ch")
yPos = yPos + lineSpacing
opt.ImageType = "png"
opt.ReadDpi = true
pdf.ImageOptions("logos/nbit-logo.png", tabstopLogo, logoTop, 0, logoHeight, false, opt, 0, "")
}
func printAddress() {
fmt.Printf("Blabla: %s\n", invoiceData.BillingAddress.Name)
yPos = addressTop
writeText(tabstopAddress, yPos, invoiceData.BillingAddress.Name)
yPos = yPos + lineSpacing
writeText(tabstopAddress, yPos, invoiceData.BillingAddress.Street)
yPos = yPos + lineSpacing
writeText(tabstopAddress, yPos, invoiceData.BillingAddress.Zip+" "+invoiceData.BillingAddress.City)
yPos = yPos + lineSpacing
pdf.Line(tabstopLeft, line1Top, tabstopRight, line1Top)
}
func printQR() {
var opt gofpdf.ImageOptions
cmd := exec.Command(filepath.Join(progDir, "qrbill.sh"),
"--account", invoiceData.Metadata.Account,
"--amount", "123.00",
"--creditor-name", invoiceData.SenderAddress.Name,
"--creditor-street", invoiceData.SenderAddress.Street,
"--creditor-postalcode", invoiceData.SenderAddress.Zip,
"--creditor-city", invoiceData.SenderAddress.City,
"--extra-infos", invoiceData.Metadata.InvoiceInfo,
"--debtor-name", invoiceData.BillingAddress.Name,
"--debtor-street", invoiceData.BillingAddress.Street,
"--debtor-postalcode", invoiceData.BillingAddress.Zip,
"--debtor-city", invoiceData.BillingAddress.City,
"--due-date", invoiceData.Metadata.DueDate,
"--language", "de")
cmd.Env = append(os.Environ(),
"INVNO="+invoiceData.Metadata.InvoiceNr,
)
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/"+invoiceData.Metadata.InvoiceNr+".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)
}
progDir = dir
if len(os.Args) != 2 {
fmt.Printf("usage: mkinvoice <yaml-file>\n")
os.Exit(1)
}
readInvoiceData(os.Args[1])
setupInvoice()
printPageHeader(true)
printAddress()
printQR()
err = pdf.OutputFileAndClose(filepath.Join(progDir, "output", invoiceData.Metadata.InvoiceNr+".pdf"))
if err == nil {
fmt.Printf("Successfully created invoice\n")
} else {
fmt.Printf("Error: %v\n", err)
}
}