working balance sheet...
This commit is contained in:
parent
d9e2ed5e2f
commit
8580faefab
124
bookkeeper.go
124
bookkeeper.go
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
"golang.org/x/text/message"
|
"golang.org/x/text/message"
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
@ -42,24 +43,25 @@ var accounts = make(map[string]string)
|
||||||
var transactions = make(map[uint16]Transaction)
|
var transactions = make(map[uint16]Transaction)
|
||||||
var account_balance = make(map[string]Balance)
|
var account_balance = make(map[string]Balance)
|
||||||
var balanceYear = "UNDEFINED"
|
var balanceYear = "UNDEFINED"
|
||||||
|
var profit float64 = 0.0
|
||||||
|
|
||||||
const reportTitle = "Jahresrechnung - nbit Informatik GmbH"
|
const reportTitle = "Jahresrechnung - nbit Informatik GmbH"
|
||||||
const MWST_ACCOUNT = "2201"
|
const MWST_ACCOUNT = "2201"
|
||||||
const defaultFontSize = 9
|
const defaultFontSize = 12
|
||||||
const smallFontSize = 7
|
const smallFontSize = 8
|
||||||
const marginTop = 10
|
const marginTop = 10
|
||||||
const smallLineSpacing = 4
|
const smallLineSpacing = 5
|
||||||
const lineSpacing = 5
|
const lineSpacing = 6
|
||||||
const tabstopLeft = 35
|
const tabstopLeft = 35
|
||||||
const tabstopRight = 160
|
const tabstopRight = 160
|
||||||
const widthAmount = 28
|
const widthAmount = 28
|
||||||
const dashCorrectionXleft = 1.2
|
const dashCorrectionXleft = 1.2
|
||||||
const dashCorrectionXright = -1.3
|
const dashCorrectionXright = -1.3
|
||||||
const dashCorrectionY = 3
|
const dashCorrectionY = 3.5
|
||||||
|
|
||||||
//func round5rappen(f float64) float64 {
|
func roundRappen(f float64) float64 {
|
||||||
// return (math.Round(f*20) / 20)
|
return (math.Round(f*100) / 100)
|
||||||
//}
|
}
|
||||||
|
|
||||||
func accountExists(s string) bool {
|
func accountExists(s string) bool {
|
||||||
_, ok := accounts[s]
|
_, ok := accounts[s]
|
||||||
|
|
@ -86,14 +88,14 @@ func calculateVAT(vat_code string, amount float64) float64 {
|
||||||
vat_type := string(vat_code[0])
|
vat_type := string(vat_code[0])
|
||||||
vat_perc, err := strconv.Atoi(vat_code[1:])
|
vat_perc, err := strconv.Atoi(vat_code[1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Printf("ERROR: %v\n", err)
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
||||||
vat_perc_f64 := float64(vat_perc)
|
vat_perc_f64 := float64(vat_perc)
|
||||||
if vat_type == "V" {
|
if vat_type == "V" {
|
||||||
return 0 - (amount / (1000.0 + vat_perc_f64) * vat_perc_f64)
|
return roundRappen(0 - (amount / (1000.0 + vat_perc_f64) * vat_perc_f64))
|
||||||
} else if vat_type == "I" {
|
} else if vat_type == "I" {
|
||||||
return (amount / (1000.0 + vat_perc_f64) * vat_perc_f64)
|
return roundRappen(amount / (1000.0 + vat_perc_f64) * vat_perc_f64)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("WARNING: Invalid Vat Type: %s\n", vat_type)
|
fmt.Printf("WARNING: Invalid Vat Type: %s\n", vat_type)
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
@ -105,7 +107,7 @@ func addTransaction(document_number string, date string, text string, account_nu
|
||||||
mydate, error := time.Parse(dateString, date)
|
mydate, error := time.Parse(dateString, date)
|
||||||
|
|
||||||
if error != nil {
|
if error != nil {
|
||||||
fmt.Println(error)
|
fmt.Printf("ERROR: %v\n", error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +132,7 @@ func addTransaction(document_number string, date string, text string, account_nu
|
||||||
myItem.Debit = account_number_debit
|
myItem.Debit = account_number_debit
|
||||||
myItem.Credit = account_number_credit
|
myItem.Credit = account_number_credit
|
||||||
if s, err := strconv.ParseFloat(amount, 64); err == nil {
|
if s, err := strconv.ParseFloat(amount, 64); err == nil {
|
||||||
myItem.Amount = s
|
myItem.Amount = roundRappen(s)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("WARNING: Document %s, cannot convert Amount to Float64: %s and will be ignored\n", document_number, amount)
|
fmt.Printf("WARNING: Document %s, cannot convert Amount to Float64: %s and will be ignored\n", document_number, amount)
|
||||||
return
|
return
|
||||||
|
|
@ -152,9 +154,6 @@ func addTransaction(document_number string, date string, text string, account_nu
|
||||||
myBalance.balance_end = myBalance.balance_end - myItem.Amount_Vat
|
myBalance.balance_end = myBalance.balance_end - myItem.Amount_Vat
|
||||||
}
|
}
|
||||||
account_balance[account_number_debit] = myBalance
|
account_balance[account_number_debit] = myBalance
|
||||||
if account_number_debit == "3400" {
|
|
||||||
fmt.Printf("DEBUG DEBIT: %s,%s,%v,%v\n", account_number_debit, account_type, myItem.Amount, myBalance)
|
|
||||||
}
|
|
||||||
|
|
||||||
myBalance = account_balance[account_number_credit]
|
myBalance = account_balance[account_number_credit]
|
||||||
account_type2 := accountType(account_number_credit)
|
account_type2 := accountType(account_number_credit)
|
||||||
|
|
@ -167,22 +166,11 @@ func addTransaction(document_number string, date string, text string, account_nu
|
||||||
myBalance.balance_end = myBalance.balance_end + myItem.Amount_Vat
|
myBalance.balance_end = myBalance.balance_end + myItem.Amount_Vat
|
||||||
}
|
}
|
||||||
account_balance[account_number_credit] = myBalance
|
account_balance[account_number_credit] = myBalance
|
||||||
if account_number_credit == "3400" {
|
|
||||||
fmt.Printf("DEBUG CREDIT: %s,%s,%v,%v\n", account_number_credit, account_type2, myItem.Amount, myBalance)
|
|
||||||
}
|
|
||||||
|
|
||||||
myBalance = account_balance[MWST_ACCOUNT]
|
myBalance = account_balance[MWST_ACCOUNT]
|
||||||
myBalance.balance_end = myBalance.balance_end + myItem.Amount_Vat
|
myBalance.balance_end = myBalance.balance_end + myItem.Amount_Vat
|
||||||
fmt.Printf("DEBUG MWST: %s: %v,%v\n", document_number, myItem.Amount_Vat, myBalance)
|
|
||||||
account_balance[MWST_ACCOUNT] = myBalance
|
account_balance[MWST_ACCOUNT] = myBalance
|
||||||
|
|
||||||
if account_number_debit == "3400" {
|
|
||||||
fmt.Printf("DEBUG DEBIT: Document %s, found 3400 transaction: %v\n", document_number, amount)
|
|
||||||
}
|
|
||||||
if account_number_credit == "3400" {
|
|
||||||
fmt.Printf("DEBUG CREDIT: Document %s, found 3400 transaction: %v\n", document_number, account_balance["3400"])
|
|
||||||
}
|
|
||||||
|
|
||||||
_, ok := transactions[uint16(document_number_i)]
|
_, ok := transactions[uint16(document_number_i)]
|
||||||
if ok {
|
if ok {
|
||||||
newtransactions := transactions[uint16(document_number_i)]
|
newtransactions := transactions[uint16(document_number_i)]
|
||||||
|
|
@ -234,15 +222,20 @@ func readAccountData(filename string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func floatToString(f float64, sep string) string {
|
func floatToString(f float64, sep string) string {
|
||||||
|
var s string
|
||||||
p := message.NewPrinter(language.English)
|
p := message.NewPrinter(language.English)
|
||||||
s := strings.ReplaceAll(p.Sprintf("%.2f", f), ",", sep)
|
if roundRappen(f) == 0.00 {
|
||||||
|
s = "-.-"
|
||||||
|
} else {
|
||||||
|
s = strings.ReplaceAll(p.Sprintf("%.2f", f), ",", sep)
|
||||||
//fmt.Printf("--- s: @%s@\n", s)
|
//fmt.Printf("--- s: @%s@\n", s)
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func str2float64(f string) float64 {
|
func str2float64(f string) float64 {
|
||||||
if s, err := strconv.ParseFloat(f, 64); err == nil {
|
if s, err := strconv.ParseFloat(f, 64); err == nil {
|
||||||
return (s)
|
return roundRappen(s)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("WARNING: cannot convert Amount to Float64: %s and will be ignored\n", f)
|
fmt.Printf("WARNING: cannot convert Amount to Float64: %s and will be ignored\n", f)
|
||||||
return 0
|
return 0
|
||||||
|
|
@ -311,7 +304,6 @@ func readTransactionData(filename string) {
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
//fmt.Printf("DEBUG BLABLA: %v\n", account_balance["3400"])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeText(x float64, y float64, w float64, text string, alignStr ...string) {
|
func writeText(x float64, y float64, w float64, text string, alignStr ...string) {
|
||||||
|
|
@ -371,6 +363,8 @@ func printSection(section string) {
|
||||||
pdf.SetFont("Dejavusans-Bold", "", smallFontSize)
|
pdf.SetFont("Dejavusans-Bold", "", smallFontSize)
|
||||||
writeText(tabstopLeft, yPos, 0, title)
|
writeText(tabstopLeft, yPos, 0, title)
|
||||||
writeText(tabstopRight, yPos, widthAmount, "31.12."+balanceYear, "TR")
|
writeText(tabstopRight, yPos, widthAmount, "31.12."+balanceYear, "TR")
|
||||||
|
pdf.SetDashPattern([]float64{}, 0)
|
||||||
|
pdf.Line(tabstopLeft+dashCorrectionXleft, yPos+dashCorrectionY, tabstopRight+widthAmount+dashCorrectionXright, yPos+dashCorrectionY)
|
||||||
yPos = yPos + smallLineSpacing
|
yPos = yPos + smallLineSpacing
|
||||||
pdf.SetFont("Dejavusans", "", smallFontSize)
|
pdf.SetFont("Dejavusans", "", smallFontSize)
|
||||||
pdf.SetDashPattern([]float64{0.2, 0.2}, 0)
|
pdf.SetDashPattern([]float64{0.2, 0.2}, 0)
|
||||||
|
|
@ -397,10 +391,52 @@ func printSection(section string) {
|
||||||
yPos = yPos + smallLineSpacing
|
yPos = yPos + smallLineSpacing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch section {
|
||||||
|
case "A":
|
||||||
|
if profit < 0 {
|
||||||
|
writeText(tabstopLeft, yPos, 0, "Verlust")
|
||||||
|
writeText(tabstopRight, yPos, widthAmount, floatToString(0-profit, "'"), "TR")
|
||||||
|
pdf.Line(tabstopLeft+dashCorrectionXleft, yPos+dashCorrectionY, tabstopRight+widthAmount+dashCorrectionXright, yPos+dashCorrectionY)
|
||||||
|
total = total - profit
|
||||||
|
yPos = yPos + smallLineSpacing
|
||||||
|
}
|
||||||
|
case "L":
|
||||||
|
if profit >= 0 {
|
||||||
|
writeText(tabstopLeft, yPos, 0, "Gewinn")
|
||||||
|
writeText(tabstopRight, yPos, widthAmount, floatToString(profit, "'"), "TR")
|
||||||
|
pdf.Line(tabstopLeft+dashCorrectionXleft, yPos+dashCorrectionY, tabstopRight+widthAmount+dashCorrectionXright, yPos+dashCorrectionY)
|
||||||
|
total = total + profit
|
||||||
|
yPos = yPos + smallLineSpacing
|
||||||
|
}
|
||||||
|
}
|
||||||
pdf.SetFont("Dejavusans-Bold", "", smallFontSize)
|
pdf.SetFont("Dejavusans-Bold", "", smallFontSize)
|
||||||
writeText(tabstopLeft, yPos, 0, "TOTAL "+title)
|
writeText(tabstopLeft, yPos, 0, "TOTAL "+title)
|
||||||
writeText(tabstopRight, yPos, widthAmount, floatToString(total, "'"), "TR")
|
writeText(tabstopRight, yPos, widthAmount, floatToString(total, "'"), "TR")
|
||||||
yPos = yPos + smallLineSpacing + smallLineSpacing
|
pdf.SetDashPattern([]float64{}, 0)
|
||||||
|
pdf.Line(tabstopLeft+dashCorrectionXleft, yPos+dashCorrectionY, tabstopRight+widthAmount+dashCorrectionXright, yPos+dashCorrectionY)
|
||||||
|
yPos = yPos + smallLineSpacing
|
||||||
|
pdf.SetDashPattern([]float64{0.2, 0.2}, 0)
|
||||||
|
pdf.SetFont("Dejavusans", "", smallFontSize)
|
||||||
|
switch section {
|
||||||
|
case "E":
|
||||||
|
if profit < 0 {
|
||||||
|
writeText(tabstopLeft, yPos, 0, "Verlust")
|
||||||
|
writeText(tabstopRight, yPos, widthAmount, floatToString(0-profit, "'"), "TR")
|
||||||
|
pdf.Line(tabstopLeft+dashCorrectionXleft, yPos+dashCorrectionY, tabstopRight+widthAmount+dashCorrectionXright, yPos+dashCorrectionY)
|
||||||
|
total = total - profit
|
||||||
|
yPos = yPos + smallLineSpacing
|
||||||
|
}
|
||||||
|
case "I":
|
||||||
|
if profit >= 0 {
|
||||||
|
writeText(tabstopLeft, yPos, 0, "Gewinn")
|
||||||
|
writeText(tabstopRight, yPos, widthAmount, floatToString(profit, "'"), "TR")
|
||||||
|
pdf.Line(tabstopLeft+dashCorrectionXleft, yPos+dashCorrectionY, tabstopRight+widthAmount+dashCorrectionXright, yPos+dashCorrectionY)
|
||||||
|
total = total + profit
|
||||||
|
yPos = yPos + smallLineSpacing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yPos = yPos + smallLineSpacing
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,16 +445,36 @@ func createBalanceSheet() {
|
||||||
printPageHeader()
|
printPageHeader()
|
||||||
printSection("A")
|
printSection("A")
|
||||||
printSection("L")
|
printSection("L")
|
||||||
|
printPageHeader()
|
||||||
printSection("E")
|
printSection("E")
|
||||||
printSection("I")
|
printSection("I")
|
||||||
err := pdf.OutputFileAndClose("output.pdf")
|
err := pdf.OutputFileAndClose("output.pdf")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Printf("Successfully created Balance Sheet in file output.pdf\n")
|
fmt.Printf("INFO: Successfully created Balance Sheet in file output.pdf\n")
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Error: %v\n", err)
|
fmt.Printf("ERROR: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func calculateProfit() float64 {
|
||||||
|
var res float64 = 0.0
|
||||||
|
|
||||||
|
for key := range account_balance {
|
||||||
|
if accountType(key) == "I" {
|
||||||
|
res = res + account_balance[key].balance_end
|
||||||
|
}
|
||||||
|
if accountType(key) == "E" {
|
||||||
|
res = res - account_balance[key].balance_end
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
res = roundRappen(res)
|
||||||
|
fmt.Printf("INFO: Calculated Profit: %v\n", res)
|
||||||
|
return res
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func usage() {
|
func usage() {
|
||||||
fmt.Printf("usage: bookkeeper <action> <accounts file> <transactions file>\n")
|
fmt.Printf("usage: bookkeeper <action> <accounts file> <transactions file>\n")
|
||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
|
|
@ -433,10 +489,10 @@ func main() {
|
||||||
|
|
||||||
readAccountData(os.Args[2])
|
readAccountData(os.Args[2])
|
||||||
readTransactionData(os.Args[3])
|
readTransactionData(os.Args[3])
|
||||||
|
profit = calculateProfit()
|
||||||
|
|
||||||
//fmt.Printf("accounts: %#v\n", accounts)
|
//fmt.Printf("accounts: %#v\n", accounts)
|
||||||
//fmt.Printf("transactions: %#v\n", transactions)
|
//fmt.Printf("transactions: %#v\n", transactions)
|
||||||
fmt.Printf("transactions: %#v\n", transactions[18])
|
|
||||||
//fmt.Printf("account_balance: %#v\n", account_balance)
|
//fmt.Printf("account_balance: %#v\n", account_balance)
|
||||||
|
|
||||||
switch action := os.Args[1]; action {
|
switch action := os.Args[1]; action {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue