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