summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolaus Gotsche <n@softwarefools.com>2019-05-14 12:32:45 +0200
committerNikolaus Gotsche <n@softwarefools.com>2019-05-14 12:32:45 +0200
commit0c4c5ac1ba534425716c80d27dc72817718f0367 (patch)
tree109d394c83b48197abaf9a44f88238c8af7283ca
parentbf7dfda3e67f67687109290209c8b09576a417fd (diff)
Payment Debug, Yearly Analysis0.4.4
-rw-r--r--analyze.go95
-rw-r--r--sqlite.go66
-rw-r--r--utils.go10
3 files changed, 140 insertions, 31 deletions
diff --git a/analyze.go b/analyze.go
index fdf2842..b0d15d2 100644
--- a/analyze.go
+++ b/analyze.go
@@ -21,8 +21,23 @@ type Month struct {
Projects []int
}
-var analysis []Month
+// Yearly Data
+type Year struct {
+ Year int
+ Months []int
+ Days []int
+
+ Earnings float64
+ Workvalue float64
+ Workhours float64
+
+ Tasks []int
+ Projects []int
+}
+
+var analysis []Month
+var yearly []Year
//Analyze all tasks and PAyments
func MakeAnalysis() {
@@ -89,13 +104,70 @@ func MakeAnalysis() {
}
}
//fmt.Println("Length:",len(analysis))
- ShowFullAnalysis()
+ for _,mo := range analysis {
+ exist,exid := YearExists(mo.Year)
+
+ if exist{
+ yearly[exid].Months = append(yearly[exid].Months,mo.Month)
+ yearly[exid].Days = append(yearly[exid].Days,mo.Days...)
+ //yearly[exid].Days = AddNewElement(yearly[exid].Days,mo.Days)
+
+ yearly[exid].Earnings += mo.Earnings
+
+ yearly[exid].Workvalue += mo.Workvalue
+ yearly[exid].Workhours += mo.Workhours
+
+ yearly[exid].Tasks = AddNewElement(yearly[exid].Tasks,mo.Tasks)
+ yearly[exid].Projects = AddNewElement(yearly[exid].Projects,mo.Projects)
+ }else{
+ yearly = append(yearly,Year{
+ mo.Year,
+ []int{mo.Month},
+ mo.Days,
+
+ mo.Earnings,
+
+ mo.Workvalue,
+ mo.Workhours,
+
+ mo.Tasks,
+ mo.Projects})
+ }
+ }
+
+ ShowMonthlyAnalysis()
+ ShowYearlyAnalysis()
}
-//Show full analysis
-func ShowFullAnalysis() {
- fmt.Println(frame("Full Analysis",true))
+//Show Yearly analysis
+func ShowYearlyAnalysis() {
+ fmt.Println(frame("Yearly Analysis",true))
+ for _,yr := range yearly {
+ cnt, hr, dur := AnalyzeTasks(GetSelectedTasks(yr.Tasks))
+
+ fmt.Println(sli,yr.Year)
+ fmt.Printf("%s Workhours: %.2f[h]\n",nli,yr.Workhours)
+ fmt.Printf("%s Earnings: %.2f[€]\n",nli,yr.Earnings)
+ fmt.Printf("%s %.2f[€/m]\n",nli,yr.Earnings/float64(len(yr.Months)))
+ fmt.Printf("%s Workvalue: %.2f[€]\n",nli,yr.Workvalue)
+ fmt.Printf("%s %.2f[€/m]\n",nli,yr.Workvalue/float64(len(yr.Months)))
+ fmt.Printf("%s Projects: %v\n",nli,len(yr.Projects))
+ fmt.Printf("%s Days: %v\n",nli,len(yr.Days))
+ fmt.Printf("%s Tasks: %v Hours: %.2f[h]\n",nli,cnt, hr)
+ fmt.Printf("%s %s\n",nli,dur)
+ fmt.Printf("%s Hourly Rate: %.2f[€/h]\n",nli,yr.Earnings/yr.Workhours)
+ fmt.Printf("%s Productivity: %.2f[h/d]\n",nli,yr.Workhours/float64(len(yr.Days)))
+ fmt.Printf("%s %.2f[h/m]\n",nli,yr.Workhours/float64(len(yr.Months)))
+ fmt.Printf("%s %.2f[d/m]\n",nli,float64(len(yr.Days))/float64(len(yr.Months)))
+
+ fmt.Println(nli)
+ }
+ fmt.Println(frame("",false))
+}
+//Show Mothly analysis
+func ShowMonthlyAnalysis() {
+ fmt.Println(frame("Monthly Analysis",true))
for _,mo := range analysis {
cnt, hr, dur := AnalyzeTasks(GetSelectedTasks(mo.Tasks))
@@ -105,12 +177,11 @@ func ShowFullAnalysis() {
fmt.Printf("%s Workvalue: %.2f[€]\n",nli,mo.Workvalue)
fmt.Printf("%s Projects: %v\n",nli,len(mo.Projects))
fmt.Printf("%s Days: %v\n",nli,len(mo.Days))
- fmt.Printf("%s Tasks: %v Hours: %.2f[€]\n",nli,cnt, hr)
+ fmt.Printf("%s Tasks: %v Hours: %.2f[h]\n",nli,cnt, hr)
fmt.Printf("%s %s\n",nli,dur)
fmt.Printf("%s Hourly Rate: %.2f[€/h]\n",nli,mo.Earnings/mo.Workhours)
fmt.Printf("%s Productivity: %.2f[h/d]\n",nli,mo.Workhours/float64(len(mo.Days)))
-
fmt.Println(nli)
}
fmt.Println(frame("",false))
@@ -126,3 +197,13 @@ func MonthExists(year, month int) (exist bool, id int) {
}
return false,-1
}
+
+// Test if yearly slice conatins the year already and return its id if
+func YearExists(year int) (exist bool, id int) {
+ for i,yr := range yearly {
+ if yr.Year == year {
+ return true,i
+ }
+ }
+ return false,-1
+}
diff --git a/sqlite.go b/sqlite.go
index bacb21b..8bfd83e 100644
--- a/sqlite.go
+++ b/sqlite.go
@@ -84,8 +84,9 @@ type IdMap struct {
// Methods
func (t Task) Duration() float64 {
- dur := t.Stop.Sub(t.Start)
- return dur.Hours()
+ //dur := t.Stop.Sub(t.Start)
+ dur := float64(t.Stop.Sub(t.Start)) / (1000000000 * 60 * 60)
+ return dur//.Hours()
}
func (t Task) Money() float64 {
_,cu := GetProject(t.Projectid)
@@ -1362,7 +1363,9 @@ func GetAllPayments() (out []Payment) {
for rows.Next() {
err = rows.Scan(&id,&cuid,&amt,&bistr,&dat)
checkErr(err)
- bi = String2IntArray(bistr,";")
+ if len(bistr)>0 {
+ bi = String2IntArray(bistr,";")
+ }
out = append(out,Payment{id,cuid,amt,dat,bi})
}
return
@@ -1567,7 +1570,6 @@ func AddPayment(dat string) {
if len(selids)>0{
break
}else{
- // TODO allow no bills and ask
fmt.Println(boldRed("At least one Bill should Correspont to a payment!"))
if isInterSure(sli+"Do you want to continue without a selection?") {
//getInterInput("<continue>")
@@ -1596,7 +1598,6 @@ func AddPayment(dat string) {
hsum += it.Hours
}
fmt.Printf("%s %s : %s (%s) %.1f[h] %.2f[€]\n",nli,bi.identity,bi.projectname,bi.date.Format("2006-01-02 15:04"),hsum,bsum)
- //sum += bsum
}
if amtfl != sum {
fmt.Println(sli,boldRed(" The sum of the bills (",sum,"€) does not match Payment amount!"))
@@ -2186,29 +2187,39 @@ func EditPayment(id int) {
}
}
fmt.Println(sub("Bills"))
- biids := String2IntArray(billstr,";")
- mybills := loadBills(biids)
+ var biids []int
+ var mybills []bill
bsum := 0.0
hsum := 0.0
- for _,bi := range mybills{
- bisum := 0.0
- for _,it := range bi.items {
- bisum += it.Money
- hsum += it.Hours
- }
- fmt.Printf("%s %s : %s (%s) %.1f[h] %.2f[€]\n",nli,bi.identity,bi.projectname,bi.date.Format("2006-01-02 15:04"),hsum,bisum)
- bsum += bisum
- }
- if amount != bsum {
- fmt.Println(sub(""))
- fmt.Println(nli,boldRed(" The sum of the bills (",bsum,"€ for",hsum,"h) does not match Payment amount!"))
- if amount > bsum {
- fmt.Printf("%s %.2f € Overpaid\n",nli,(amount-bsum) )
+
+ if len(billstr)>0 {
+ biids = String2IntArray(billstr,";")
+ mybills = loadBills(biids)
+
+ //bsum := 0.0
+ //hsum := 0.0
+ for _,bi := range mybills{
+ bisum := 0.0
+ for _,it := range bi.items {
+ bisum += it.Money
+ hsum += it.Hours
+ }
+ fmt.Printf("%s %s : %s (%s) %.1f[h] %.2f[€]\n",nli,bi.identity,bi.projectname,bi.date.Format("2006-01-02 15:04"),hsum,bisum)
+ bsum += bisum
}
- if amount < bsum {
- fmt.Printf("%s %.2f € Underpaid\n",nli,(amount-bsum) )
+ if amount != bsum {
+ fmt.Println(sub(""))
+ fmt.Println(nli,boldRed(" The sum of the bills (",bsum,"€ for",hsum,"h) does not match Payment amount!"))
+ if amount > bsum {
+ fmt.Printf("%s %.2f € Overpaid\n",nli,(amount-bsum) )
+ }
+ if amount < bsum {
+ fmt.Printf("%s %.2f € Underpaid\n",nli,(amount-bsum) )
+ }
}
+ }else{
+ fmt.Println(nli,boldRed(" None"))
}
if isInterSure(sli+"Do You want to renew Selection?") {
for _,i := range biids {
@@ -2232,8 +2243,13 @@ func EditPayment(id int) {
billstr = IntArray2String(selids,";")
break
}else{
+ billstr = "-1"
fmt.Println(boldRed("At least one Bill should Correspont to a payment!"))
- getInterInput("<continue>")
+ if isInterSure(sli+"Do you want to continue without a selection?") {
+ break
+ }
+ //fmt.Println(boldRed("At least one Bill should Correspont to a payment!"))
+ //getInterInput("<continue>")
}
}
}
@@ -2242,6 +2258,8 @@ func EditPayment(id int) {
_, err = stmt.Exec(cuid, amount, billstr, datstr, id)
checkErr(err)
custr := getCustomerName(cuid)
+ biids = String2IntArray(billstr,";")
+ mybills = loadBills(biids)
fmt.Println(frame(boldGreen("Editing Payment ", id),true))
fmt.Printf("%s From %s Amount %.2f [€]\n",nli,custr,amount)
diff --git a/utils.go b/utils.go
index 9e59d75..5b5be5a 100644
--- a/utils.go
+++ b/utils.go
@@ -309,6 +309,16 @@ func isElement(some int, group []int) bool {
return false
}
+func AddNewElement(base, news []int) (out []int) {
+ out = base
+ for _,e := range news {
+ if !isElement(e,base) {
+ out = append(out,e)
+ }
+ }
+ return
+}
+
func removeItems(master, rem []int) []int {
var out []int
for _, v := range master {