format invoice, multipage invoice

This commit is contained in:
Joerg Lehmann 2020-07-02 14:34:23 +02:00
parent b05854a20c
commit 7471882878
1 changed files with 66 additions and 30 deletions

View File

@ -23,6 +23,7 @@ type Metadata struct {
Vat float64 `yaml:"vat"`
Account string `yaml:"account"`
DueDate string `yaml:"due_date"`
VatNumber string `yaml:"vat_number"`
}
// Address type
@ -57,20 +58,21 @@ var invoiceData InvoiceData
var progDir string
var currentPage int
var totalPages int
var totalItemLines int
var totalNetAmount float64
var totalInvoiceAmount float64
const defaultFontSize = 9
const fontSizeSmall = 7
const marginTop = 7
const logoTop = 6
const logoHeight = 20
const lineSpacing = 5
const lineSpacingSmall = 3.5
const addressTop = 50
const metadataTop = 70
const metadataTopFirstPage = 70
const metadataTopNotFirstPage = 30
const tabstopLeft = 20
const tabstopLeftAlt = 32
const tabstopLeftAlt = 40
const tabstopMetadata = 60
const tabstopAddress = 120
const tabstopLogo = 155
@ -82,8 +84,10 @@ const widthPrice = 28
const tabstopQuantity = tabstopRight - widthPrice - widthPricePerUnit - widthQuantity
const tabstopPricePerUnit = tabstopRight - widthPrice - widthPricePerUnit
const tabstopPrice = tabstopRight - widthPrice
const itemsTop = 105
const totalsTop = 150
const itemsTopFirstPage = 105
const itemsTopNotFirstPage = 50
const totalsTop = 165
const maxYPos = 265
func round5rappen(f float64) float64 {
return (math.Round(f*20) / 20)
@ -139,21 +143,25 @@ func printPageHeader(firstPage bool) {
currentPage = currentPage + 1
pdf.AddPage()
yPos = marginTop
pdf.SetFont("Dejavusans-Bold", "", fontSizeSmall)
writeText(tabstopLeft, yPos, 0, "nbit Informatik GmbH")
pdf.SetFont("Dejavusans", "", fontSizeSmall)
yPos = yPos + lineSpacingSmall
writeText(tabstopLeft, yPos, 0, "Kirchweg 2")
yPos = yPos + lineSpacingSmall
writeText(tabstopLeft, yPos, 0, "3510 Konolfingen")
yPos = yPos + lineSpacingSmall
yPos = yPos + lineSpacingSmall
writeText(tabstopLeft, yPos, 0, "Tel.")
writeText(tabstopLeftAlt, yPos, 0, "+41 31 792 00 40")
yPos = yPos + lineSpacingSmall
writeText(tabstopLeft, yPos, 0, "EMail")
writeText(tabstopLeftAlt, yPos, 0, "joerg.lehmann@nbit.ch")
yPos = yPos + lineSpacingSmall
pdf.SetFont("Dejavusans-Bold", "", defaultFontSize)
writeText(tabstopLeft, yPos, 0, invoiceData.SenderAddress.Name)
pdf.SetFont("Dejavusans", "", defaultFontSize)
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, 0, invoiceData.SenderAddress.Street)
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, 0, invoiceData.SenderAddress.Zip+" "+invoiceData.SenderAddress.City)
if firstPage {
yPos = yPos + lineSpacing
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, 0, "Telefon")
writeText(tabstopLeftAlt, yPos, 0, invoiceData.SenderAddress.TelNo)
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, 0, "E-Mail")
writeText(tabstopLeftAlt, yPos, 0, invoiceData.SenderAddress.Email)
yPos = yPos + lineSpacing
writeText(tabstopLeft, yPos, 0, "MwSt. Nr.")
writeText(tabstopLeftAlt, yPos, 0, invoiceData.Metadata.VatNumber)
}
opt.ImageType = "png"
opt.ReadDpi = true
@ -170,25 +178,39 @@ func printAddress() {
writeText(tabstopAddress, yPos, 0, invoiceData.BillingAddress.Zip+" "+invoiceData.BillingAddress.City)
}
func printMetadataFirstPage() {
yPos = metadataTop
pdf.SetFont("Dejavusans-Bold", "", 16)
writeText(tabstopLeft, yPos, 0, "Rechnung")
yPos = yPos + lineSpacing
yPos = yPos + lineSpacing
func printMetadata(firstPage bool) {
yPos = metadataTopNotFirstPage
if firstPage {
yPos = metadataTopFirstPage
pdf.SetFont("Dejavusans-Bold", "", 16)
writeText(tabstopLeft, yPos, 0, "Rechnung")
yPos = yPos + lineSpacing
yPos = yPos + lineSpacing
}
pdf.SetFont("Dejavusans-Bold", "", defaultFontSize)
writeText(tabstopLeft, yPos, 0, "Rechnungsnummer:")
pdf.SetFont("Dejavusans", "", defaultFontSize)
writeText(tabstopMetadata, yPos, 0, invoiceData.Metadata.InvoiceNr)
yPos = yPos + lineSpacing
if firstPage {
pdf.SetFont("Dejavusans-Bold", "", defaultFontSize)
writeText(tabstopLeft, yPos, 0, "Rechnungsdatum:")
pdf.SetFont("Dejavusans", "", defaultFontSize)
writeText(tabstopMetadata, yPos, 0, invoiceData.Metadata.InvoiceDate)
yPos = yPos + lineSpacing
}
pdf.SetFont("Dejavusans-Bold", "", defaultFontSize)
writeText(tabstopLeft, yPos, 0, "Rechnungsdatum:")
writeText(tabstopLeft, yPos, 0, "Seite:")
pdf.SetFont("Dejavusans", "", defaultFontSize)
writeText(tabstopMetadata, yPos, 0, invoiceData.Metadata.InvoiceDate)
writeText(tabstopMetadata, yPos, 0, fmt.Sprintf("%d von %d", currentPage, totalPages))
}
func printItemsHeader() {
yPos = itemsTop
if currentPage == 1 {
yPos = itemsTopFirstPage
} else {
yPos = itemsTopNotFirstPage
}
pdf.SetFont("Dejavusans-Bold", "", defaultFontSize)
writeText(tabstopLeft, yPos, 0, "Bezeichnung")
writeText(tabstopQuantity, yPos, widthQuantity, "Menge", "TR")
@ -200,6 +222,14 @@ func printItemsHeader() {
yPos = yPos + lineSpacing
}
func maybeNewPage() {
if yPos > maxYPos {
printPageHeader(false)
printMetadata(false)
printItemsHeader()
}
}
func printItems() {
for _, i := range invoiceData.InvoiceItems {
if i.Quantity != 0 {
@ -212,11 +242,15 @@ func printItems() {
if i.Text != "" {
lines := pdf.SplitText(i.Text, widthItemText)
for _, il := range lines {
totalItemLines = totalItemLines + 1
writeText(tabstopLeft, yPos, 0, strings.ReplaceAll(il, "_", " "))
yPos = yPos + lineSpacing
maybeNewPage()
}
} else {
totalItemLines = totalItemLines + 1
yPos = yPos + lineSpacing
maybeNewPage()
}
}
}
@ -274,11 +308,12 @@ func printQR() {
func CreateInvoice() {
totalNetAmount = 0
totalItemLines = 0
readInvoiceData(os.Args[1])
setupInvoice()
printPageHeader(true)
printAddress()
printMetadataFirstPage()
printMetadata(true)
printItemsHeader()
printItems()
printTotals()
@ -301,6 +336,7 @@ func main() {
CreateInvoice()
totalPages = pdf.PageNo()
fmt.Printf("Total Pages is: %d\n", totalPages)
fmt.Printf("Total Item Lines is: %d\n", totalItemLines)
// Second Run
CreateInvoice()