--- /dev/null
+package main
+
+import (
+ "encoding/xml"
+ "fmt"
+ "io/ioutil"
+ "os"
+)
+
+type Account struct {
+ XMLName xml.Name `xml:"account"`
+ Name string `xml:"name"`
+ AccountId string `xml:"id"`
+ ParentId string `xml:"parent"`
+}
+
+type Split struct {
+ XMLName xml.Name `xml:"split"`
+ Id string `xml:"id"`
+ Value string `xml:"value"`
+ Quantity string `xml:"quantity"`
+ AccountId string `xml:"account"`
+}
+
+type Transaction struct {
+ XMLName xml.Name `xml:"transaction"`
+ Id string `xml:"id"`
+ Date string `xml:"date-posted>date"`
+ Description string `xml:"description"`
+ Spl []Split `xml:"splits>split"`
+}
+
+type ParsedData struct {
+ XMLName xml.Name `xml:"gnc-v2"`
+ DataCnt []string `xml:"count-data"`
+ Accnt []Account `xml:"book>account"`
+ Trn []Transaction `xml:"book>transaction"`
+}
+
+// 'global' data
+var data ParsedData
+
+func main() {
+
+ // open xml file
+ file, err := os.Open("c13_skr03.gnucash")
+ if err != nil {
+ fmt.Println("Error opening file:", err)
+ return
+ }
+ defer file.Close()
+
+ // read xml file
+ xmldata, err := ioutil.ReadAll(file)
+ if err != nil {
+ fmt.Println("Error reading file:", err)
+ return
+ }
+
+ // unmarshal xml data
+ err = xml.Unmarshal(xmldata,&data)
+ if err != nil {
+ fmt.Println("Error unmarshaling xml data:", err)
+ return
+ }
+
+ // whooha, this is our data!
+ fmt.Println("Parsed accounts:",len(data.Accnt))
+ fmt.Println("Parsed transactions:",len(data.Trn))
+
+ //
+ // hardcoded account ids we have to look at
+ //
+ // wareneingang 19% and 7%
+ pid_buy_n := string("8e3b7c42e3173ed85f3d4736e82afb4d")
+ pid_buy_s := string("0cfd2ceb45fff89b9d1b7ce3af66cdf3")
+ // abziehbare vst 19% and 7%
+ aid_vst_n := string("7c449e13125d6b93043f963628106db2")
+ aid_vst_s := string("006643c1c0a91f2b40614c75a49c6295")
+
+ // account maps
+ type amap struct {
+ pid string
+ num int
+ taxval int
+ buy bool
+ tax bool
+ }
+ accnt := make(map[string]amap)
+
+ for ac := range data.Accnt {
+ aid := data.Accnt[ac].AccountId
+ pid := data.Accnt[ac].ParentId
+ // general map
+ accnt[aid]=amap{
+ pid,ac,0,false,false,
+ }
+ tmp := accnt[aid]
+ switch {
+ case pid == pid_buy_n:
+ tmp.taxval=19
+ tmp.buy=true
+ accnt[aid]=tmp
+ //accnt[aid].taxval=19
+ //accnt[aid].buy=true
+ case pid == pid_buy_s:
+ //accnt[aid].tax=7
+ //accnt[aid].buy=true
+ case aid == aid_vst_n:
+ //accnt[aid].taxval=19
+ //accnt[aid].buy=true
+ //accnt[aid].tax=true
+ case aid == aid_vst_s:
+ //accnt[aid].tax=7
+ //accnt[aid].buy=true
+ //accnt[aid].tax=true
+ // there will be more assignments later on!
+ }
+ }
+
+ // check transactions
+ for tc := range data.Trn {
+ for tsc := range data.Trn[tc].Spl {
+ aid := data.Trn[tc].Spl[tsc].AccountId
+ switch {
+ case accnt[aid].buy:
+ var ret bool
+ switch accnt[aid].taxval {
+ case 19:
+ ret=check_buy(&data.Trn[tc],aid_vst_n)
+ case 7:
+ ret=check_buy(&data.Trn[tc],aid_vst_s)
+ }
+ anum := accnt[aid].num
+ if ret == false {
+ fmt.Println("Problem:", data.Accnt[anum].Name)
+ }
+ }
+ }
+ }
+
+}
+
+func check_buy(ta *Transaction,id string) bool {
+ for sc := range ta.Spl {
+ if ta.Spl[sc].AccountId == id {
+ return true
+ }
+ }
+ return false
+}
+