initial go code to examine gnucash data
authorhackbard <hackbard@hackdaworld.org>
Sat, 11 Oct 2014 18:39:21 +0000 (20:39 +0200)
committerhackbard <hackbard@hackdaworld.org>
Sat, 11 Oct 2014 18:39:21 +0000 (20:39 +0200)
gocash.go [new file with mode: 0644]

diff --git a/gocash.go b/gocash.go
new file mode 100644 (file)
index 0000000..88b84d9
--- /dev/null
+++ b/gocash.go
@@ -0,0 +1,152 @@
+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
+}
+