early development...
This commit is contained in:
parent
70fb02847f
commit
fd5b658b1a
141
bookkeeper.go
141
bookkeeper.go
|
|
@ -4,6 +4,8 @@ import (
|
|||
"bufio"
|
||||
"fmt"
|
||||
"github.com/go-pdf/fpdf"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
|
|
@ -27,19 +29,31 @@ type Transaction struct {
|
|||
Items []TransactionItem
|
||||
}
|
||||
|
||||
type Balance struct {
|
||||
balance_start float64
|
||||
balance_end float64
|
||||
}
|
||||
|
||||
/* global variable declaration */
|
||||
var pdf *fpdf.Fpdf
|
||||
var yPos float64
|
||||
var accounts = make(map[string]string)
|
||||
var transactions = make(map[uint16]Transaction)
|
||||
var account_balance = make(map[string]string)
|
||||
var yearEndDate = "YEARENDDATE"
|
||||
var account_balance = make(map[string]Balance)
|
||||
var balanceYear = "UNDEFINED"
|
||||
|
||||
const reportTitle = "Jahresrechnung - nbit Informatik GmbH"
|
||||
const defaultFontSize = 9
|
||||
const smallFontSize = 7
|
||||
const marginTop = 10
|
||||
const smallLineSpacing = 4
|
||||
const lineSpacing = 5
|
||||
const tabstopLeft = 20
|
||||
const tabstopLeft = 25
|
||||
const tabstopRight = 100
|
||||
const widthAmount = 28
|
||||
const dashCorrectionXleft = 1.2
|
||||
const dashCorrectionXright = -1.3
|
||||
const dashCorrectionY = 3
|
||||
|
||||
//func round5rappen(f float64) float64 {
|
||||
// return (math.Round(f*20) / 20)
|
||||
|
|
@ -60,6 +74,16 @@ func addTransaction(document_number string, date string, text string, account_nu
|
|||
return
|
||||
}
|
||||
|
||||
// we use the first transaction to set the year, all transactions not in this year will be invalid
|
||||
if balanceYear == "UNDEFINED" {
|
||||
balanceYear = date[6:10]
|
||||
} else {
|
||||
if date[6:10] != balanceYear {
|
||||
fmt.Printf("WARNING: transaction with Document Number %s is not in same year as first transaction: %s and will be ignored\n", document_number, balanceYear)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var myItem TransactionItem
|
||||
|
||||
document_number_i, err := strconv.ParseInt(document_number, 0, 16)
|
||||
|
|
@ -73,7 +97,8 @@ func addTransaction(document_number string, date string, text string, account_nu
|
|||
if s, err := strconv.ParseFloat(amount, 64); err == nil {
|
||||
myItem.Amount = s
|
||||
} else {
|
||||
fmt.Printf("Cannot convert Amount to Float64: %s\n", amount)
|
||||
fmt.Printf("WARNING: Document %s, cannot convert Amount to Float64: %s and will be ignored\n", document_number, amount)
|
||||
return
|
||||
}
|
||||
myItem.Vat_code = vat_code
|
||||
|
||||
|
|
@ -103,8 +128,8 @@ func readAccountData(filename string) {
|
|||
line := scanner.Text()
|
||||
matched, _ := regexp.MatchString(`^[0-9][0-9][0-9][0-9],.*`, line)
|
||||
if !matched {
|
||||
fmt.Printf("Line %v in Accountfile %s: line not four digits followed by a comma: %s.\n", line_number, filename, line)
|
||||
os.Exit(3)
|
||||
fmt.Printf("WARNING: Line %v in Accountfile %s: line not four digits followed by a comma: %s and will be ignored.\n", line_number, filename, line)
|
||||
continue
|
||||
}
|
||||
|
||||
token := strings.SplitN(line, ",", 2)
|
||||
|
|
@ -112,8 +137,8 @@ func readAccountData(filename string) {
|
|||
account_description := token[1]
|
||||
|
||||
if accountExists(account_number) {
|
||||
fmt.Printf("Line %v in Accountfile %s: Account Number %s already exists\n", line_number, filename, account_number)
|
||||
os.Exit(4)
|
||||
fmt.Printf("WARNING: Line %v in Accountfile %s: Account Number %s already exists and will be ignored\n", line_number, filename, account_number)
|
||||
continue
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -127,6 +152,22 @@ func readAccountData(filename string) {
|
|||
}
|
||||
}
|
||||
|
||||
func floatToString(f float64, sep string) string {
|
||||
p := message.NewPrinter(language.English)
|
||||
s := strings.ReplaceAll(p.Sprintf("%.2f", f), ",", sep)
|
||||
//fmt.Printf("--- s: @%s@\n", s)
|
||||
return s
|
||||
}
|
||||
|
||||
func str2float64(f string) float64 {
|
||||
if s, err := strconv.ParseFloat(f, 64); err == nil {
|
||||
return (s)
|
||||
} else {
|
||||
fmt.Printf("WARNING: cannot convert Amount to Float64: %s and will be ignored\n", f)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func readTransactionData(filename string) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
|
|
@ -150,12 +191,12 @@ func readTransactionData(filename string) {
|
|||
vat_code := token[6]
|
||||
|
||||
if !accountExists(account_number_debit) {
|
||||
fmt.Printf("Line %v in Transactionfile %s: Account Number Debit %s does not exist\n", line_number, filename, account_number_debit)
|
||||
os.Exit(4)
|
||||
fmt.Printf("WARNING: Line %v in Transactionfile %s: Account Number Debit %s does not exist, and will be ignored\n", line_number, filename, account_number_debit)
|
||||
continue
|
||||
}
|
||||
if !accountExists(account_number_credit) {
|
||||
fmt.Printf("Line %v in Transactionfile %s: Account Number Credit %s does not exist\n", line_number, filename, account_number_credit)
|
||||
os.Exit(4)
|
||||
fmt.Printf("WARNING: Line %v in Transactionfile %s: Account Number Credit %s does not exist and will be ignored\n", line_number, filename, account_number_credit)
|
||||
continue
|
||||
}
|
||||
|
||||
addTransaction(document_number, date, text, account_number_debit, account_number_credit, amount, vat_code)
|
||||
|
|
@ -167,15 +208,20 @@ func readTransactionData(filename string) {
|
|||
account_number := token[0]
|
||||
balance := token[1]
|
||||
if !accountExists(account_number) {
|
||||
fmt.Printf("Line %v in Transactionfile %s: Account Number %s does not exist\n", line_number, filename, account_number)
|
||||
os.Exit(4)
|
||||
fmt.Printf("WARNING: Line %v in Transactionfile %s: Account Number %s does not exist and will be ignored\n", line_number, filename, account_number)
|
||||
continue
|
||||
}
|
||||
|
||||
account_balance[account_number] = balance
|
||||
f := str2float64(balance)
|
||||
|
||||
var myBalance Balance
|
||||
myBalance.balance_start = f
|
||||
myBalance.balance_end = f
|
||||
account_balance[account_number] = myBalance
|
||||
|
||||
} else {
|
||||
fmt.Printf("Line %v in Transactionfile %s is not of the form <document number>,<date>,<text>,<account number debit>,<account number credit>,<amount>,<vat code>.\n", line_number, filename, line)
|
||||
os.Exit(3)
|
||||
fmt.Printf("WARNING: Line %v in Transactionfile %s is not of the form <document number>,<date>,<text>,<account number debit>,<account number credit>,<amount>,<vat code> and will be ignored.\n", line_number, filename, line)
|
||||
continue
|
||||
}
|
||||
line_number++
|
||||
}
|
||||
|
|
@ -212,29 +258,62 @@ func printPageHeader() {
|
|||
pdf.SetFont("Dejavusans-Bold", "", defaultFontSize)
|
||||
writeText(tabstopLeft, yPos, 0, reportTitle)
|
||||
yPos = yPos + lineSpacing
|
||||
pdf.SetFont("Dejavusans", "", defaultFontSize)
|
||||
writeText(tabstopLeft, yPos, 0, "per "+yearEndDate)
|
||||
pdf.SetFont("Dejavusans", "", smallFontSize)
|
||||
writeText(tabstopLeft, yPos, 0, "per 31.12."+balanceYear)
|
||||
yPos = yPos + lineSpacing + smallLineSpacing
|
||||
}
|
||||
|
||||
func printAssets() {
|
||||
}
|
||||
func printSection(section string) {
|
||||
var title string
|
||||
var chars string
|
||||
switch section {
|
||||
case "assets":
|
||||
title = "AKTIVEN"
|
||||
chars = "1"
|
||||
case "liabilities":
|
||||
title = "PASSIVEN"
|
||||
chars = "2"
|
||||
case "expense":
|
||||
title = "AUFWAND"
|
||||
chars = "568"
|
||||
case "income":
|
||||
title = "ERTRAG"
|
||||
chars = "4"
|
||||
default:
|
||||
fmt.Printf("WARNING: invalid section: %s\n", section)
|
||||
return
|
||||
}
|
||||
|
||||
func printLiabilities() {
|
||||
}
|
||||
var total float64 = 0.0
|
||||
pdf.SetFont("Dejavusans-Bold", "", smallFontSize)
|
||||
writeText(tabstopLeft, yPos, 0, title)
|
||||
writeText(tabstopRight, yPos, widthAmount, "31.12."+balanceYear, "TR")
|
||||
yPos = yPos + smallLineSpacing
|
||||
pdf.SetFont("Dejavusans", "", smallFontSize)
|
||||
pdf.SetDashPattern([]float64{0.2, 0.2}, 0)
|
||||
for key, element := range account_balance {
|
||||
if strings.Contains(chars, key[0:1]) {
|
||||
writeText(tabstopLeft, yPos, 0, accounts[key])
|
||||
writeText(tabstopRight, yPos, widthAmount, floatToString(element.balance_end, "'"), "TR")
|
||||
pdf.Line(tabstopLeft+dashCorrectionXleft, yPos+dashCorrectionY, tabstopRight+widthAmount+dashCorrectionXright, yPos+dashCorrectionY)
|
||||
total = total + element.balance_end
|
||||
yPos = yPos + smallLineSpacing
|
||||
}
|
||||
}
|
||||
pdf.SetFont("Dejavusans-Bold", "", smallFontSize)
|
||||
writeText(tabstopLeft, yPos, 0, "TOTAL "+title)
|
||||
writeText(tabstopRight, yPos, widthAmount, floatToString(total, "'"), "TR")
|
||||
yPos = yPos + smallLineSpacing + smallLineSpacing
|
||||
|
||||
func printExpenses() {
|
||||
}
|
||||
|
||||
func printIncome() {
|
||||
}
|
||||
|
||||
func createBalanceSheet() {
|
||||
setupBalanceSheet()
|
||||
printPageHeader()
|
||||
printAssets()
|
||||
printLiabilities()
|
||||
printExpenses()
|
||||
printIncome()
|
||||
printSection("assets")
|
||||
printSection("liabilities")
|
||||
printSection("expense")
|
||||
printSection("income")
|
||||
err := pdf.OutputFileAndClose("output.pdf")
|
||||
if err == nil {
|
||||
fmt.Printf("Successfully created Balance Sheet in file output.pdf\n")
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -4,4 +4,5 @@ go 1.20
|
|||
|
||||
require (
|
||||
github.com/go-pdf/fpdf v0.9.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
)
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -12,3 +12,5 @@ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfF
|
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
|
|
|
|||
Loading…
Reference in New Issue