summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolaus Gotsche <n@softwarefools.com>2018-10-19 12:30:46 +0200
committerNikolaus Gotsche <n@softwarefools.com>2018-10-19 12:30:46 +0200
commit404386194b9492b29b03d4e1e65558c545a70b51 (patch)
tree159b8f61939d7163ba4d63c2cd89ecda4579b1b7
parentae396b0399a9ee4ec8aee4879f0eb36bc7aeb7e8 (diff)
Trys in Auto-Documentation
-rw-r--r--config.go210
-rw-r--r--interact.go1399
-rw-r--r--main.go266
-rw-r--r--sqlite.go2431
-rw-r--r--texify.go395
-rw-r--r--utils.go308
6 files changed, 2536 insertions, 2473 deletions
diff --git a/config.go b/config.go
index 37962ef..a0b3626 100644
--- a/config.go
+++ b/config.go
@@ -1,134 +1,132 @@
package main
import (
- "bytes"
- "fmt"
- //"os"
- "io/ioutil"
- //"strconv"
- "github.com/fatih/color"
- "github.com/BurntSushi/toml"
- "github.com/atrox/homedir"
+ "bytes"
+ "fmt"
+ //"os"
+ "io/ioutil"
+ //"strconv"
+ "github.com/BurntSushi/toml"
+ "github.com/atrox/homedir"
+ "github.com/fatih/color"
)
type Config struct {
- Database string //`toml:"database"`
- Name string //`toml:"name"`
- Street string //`toml:"street"`
- Zip string //`toml:"zip"`
- City string //`toml:"city"`
- Country string //`toml:"country"`
- Telefon string //`toml:"telefon"`
- Mobile string //`toml:"mobile"`
- Mail string //`toml:"mail"`
- Url string //`toml:"url"`
- Taxid string //`toml:"taxid"`
- Bankacc string //`toml:"bankacc"`
- Banklz string //`toml:"banklz"`
- Bankname string //`toml:"bankname"`
- Iban string //`toml:"iban"`
- Bic string //`toml:"bic"`
+ Database string //`toml:"database"`
+ Name string //`toml:"name"`
+ Street string //`toml:"street"`
+ Zip string //`toml:"zip"`
+ City string //`toml:"city"`
+ Country string //`toml:"country"`
+ Telefon string //`toml:"telefon"`
+ Mobile string //`toml:"mobile"`
+ Mail string //`toml:"mail"`
+ Url string //`toml:"url"`
+ Taxid string //`toml:"taxid"`
+ Bankacc string //`toml:"bankacc"`
+ Banklz string //`toml:"banklz"`
+ Bankname string //`toml:"bankname"`
+ Iban string //`toml:"iban"`
+ Bic string //`toml:"bic"`
}
var conffile string
var config Config
func init() {
- conffile,err = homedir.Expand("~/.laboravi.config.toml") //make ~ when finished
- checkErr(err)
+ conffile, err = homedir.Expand("~/.laboravi.config.toml") //make ~ when finished
+ checkErr(err)
}
func editConf() {
- for {
- if _, err := toml.DecodeFile(conffile, &config); err != nil {
- //fmt.Println(err)
- fmt.Println("Configuration file not found")
- makeNewTOML(false)
- }else{
- showConfig()
- if isInterSure("Is this Configuration Correct?") {
- break
- }else{
- //if isSure("Enter new Configuration?"){
- makeNewTOML(true)
- //}else{
- // fmt.Println("I Really Dont think I can Help You then...!")
- //}
- }
- }
- }
+ for {
+ if _, err := toml.DecodeFile(conffile, &config); err != nil {
+ //fmt.Println(err)
+ fmt.Println("Configuration file not found")
+ makeNewTOML(false)
+ } else {
+ showConfig()
+ if isInterSure("Is this Configuration Correct?") {
+ break
+ } else {
+ //if isSure("Enter new Configuration?"){
+ makeNewTOML(true)
+ //}else{
+ // fmt.Println("I Really Dont think I can Help You then...!")
+ //}
+ }
+ }
+ }
}
func initConf() {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- for {
- if _, err := toml.DecodeFile(conffile, &config); err != nil {
- //fmt.Println(err)
- fmt.Println(boldRed("Configuration file not found"))
- makeNewTOML(false)
- }else{
- //fmt.Println(boldGreen("Configuration loaded Successfully"))
- fmt.Println("Config loaded...",boldGreen("Hello ",config.Name))
- break
- }
- }
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ for {
+ if _, err := toml.DecodeFile(conffile, &config); err != nil {
+ //fmt.Println(err)
+ fmt.Println(boldRed("Configuration file not found"))
+ makeNewTOML(false)
+ } else {
+ //fmt.Println(boldGreen("Configuration loaded Successfully"))
+ fmt.Println("Config loaded...", boldGreen("Hello ", config.Name))
+ break
+ }
+ }
}
func makeNewTOML(gibts bool) {
- if gibts {
- fmt.Println("Editing Configuration File\nPress [Enter] to keep the Current setting")
- }else{
- fmt.Println("\nMaking new Configuration File")
- //Examplenames Coming soon
- n := ""
- file,err := homedir.Expand("~/.mywork.db")
- checkErr(err)
- config = Config{file,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n}
- }
- //fmt.Println("Whats Your Namecount\n")
- database := getNewInterInput("DB File Path: ",config.Database)
- name := getNewInterInput("Whats your Name?: ",config.Name)
- street := getNewInterInput("Street: ",config.Street)
- zip := getNewInterInput("Zip Code: ",config.Zip)
- city := getNewInterInput("City: ",config.City)
- country := getNewInterInput("Country: ",config.City)
- telefon := getNewInterInput("Telefone number: ",config.Telefon)
- mobile := getNewInterInput("Mobile number: ",config.Mobile)
- mail := getNewInterInput("Email: ",config.Mail)
- url := getNewInterInput("URL: ",config.Url)
- taxid := getNewInterInput("Tax ID: ",config.Taxid)
- bankname := getNewInterInput("Bank Name: ",config.Bankname)
- bankacc := getNewInterInput("Bank Account: ",config.Bankacc)
- banklz := getNewInterInput("BLZ: ",config.Banklz)
- iban := getNewInterInput("IBAN: ",config.Iban)
- bic := getNewInterInput("BIC: ",config.Bic)
+ if gibts {
+ fmt.Println("Editing Configuration File\nPress [Enter] to keep the Current setting")
+ } else {
+ fmt.Println("\nMaking new Configuration File")
+ //Examplenames Coming soon
+ n := ""
+ file, err := homedir.Expand("~/.mywork.db")
+ checkErr(err)
+ config = Config{file, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n}
+ }
+ //fmt.Println("Whats Your Namecount\n")
+ database := getNewInterInput("DB File Path: ", config.Database)
+ name := getNewInterInput("Whats your Name?: ", config.Name)
+ street := getNewInterInput("Street: ", config.Street)
+ zip := getNewInterInput("Zip Code: ", config.Zip)
+ city := getNewInterInput("City: ", config.City)
+ country := getNewInterInput("Country: ", config.City)
+ telefon := getNewInterInput("Telefone number: ", config.Telefon)
+ mobile := getNewInterInput("Mobile number: ", config.Mobile)
+ mail := getNewInterInput("Email: ", config.Mail)
+ url := getNewInterInput("URL: ", config.Url)
+ taxid := getNewInterInput("Tax ID: ", config.Taxid)
+ bankname := getNewInterInput("Bank Name: ", config.Bankname)
+ bankacc := getNewInterInput("Bank Account: ", config.Bankacc)
+ banklz := getNewInterInput("BLZ: ", config.Banklz)
+ iban := getNewInterInput("IBAN: ", config.Iban)
+ bic := getNewInterInput("BIC: ", config.Bic)
- conf := Config{database,name,street,zip,city,country,telefon,mobile,mail,url,taxid,bankacc,banklz,bankname,iban,bic}
+ conf := Config{database, name, street, zip, city, country, telefon, mobile, mail, url, taxid, bankacc, banklz, bankname, iban, bic}
- buf := new(bytes.Buffer)
- err = toml.NewEncoder(buf).Encode(conf)
- if err != nil {
- panic(err)
- }else{
- //fmt.Println("Conffile:\n",buf.String())
- fmt.Println("\nWriting Configuration File")
- err = ioutil.WriteFile(conffile, buf.Bytes(), 0644)
- checkErr(err)
- }
- fmt.Println(" ")
+ buf := new(bytes.Buffer)
+ err = toml.NewEncoder(buf).Encode(conf)
+ if err != nil {
+ panic(err)
+ } else {
+ //fmt.Println("Conffile:\n",buf.String())
+ fmt.Println("\nWriting Configuration File")
+ err = ioutil.WriteFile(conffile, buf.Bytes(), 0644)
+ checkErr(err)
+ }
+ fmt.Println(" ")
}
func showConfig() {
- buf := new(bytes.Buffer)
- err := toml.NewEncoder(buf).Encode(config)
- if err != nil {
- panic(err)
- }else{
- fmt.Println("Configuration:\n",buf.String())
- //fmt.Println(config)
- }
+ buf := new(bytes.Buffer)
+ err := toml.NewEncoder(buf).Encode(config)
+ if err != nil {
+ panic(err)
+ } else {
+ fmt.Println("Configuration:\n", buf.String())
+ //fmt.Println(config)
+ }
}
-
-
diff --git a/interact.go b/interact.go
index 136e1d2..14e591f 100644
--- a/interact.go
+++ b/interact.go
@@ -1,727 +1,728 @@
package main
import (
- //"os"
- "strings"
- "strconv"
- "fmt"
- "time"
-
- //"github.com/abiosoft/ishell"
- "github.com/EPRparadox82/ishell"
- "github.com/fatih/color"
+ //"os"
+ "fmt"
+ "strconv"
+ "strings"
+ "time"
+
+ //"github.com/abiosoft/ishell"
+ "github.com/EPRparadox82/ishell"
+ "github.com/fatih/color"
)
-
func interact() {
- //stdOut()
- shell := ishell.New()
- shell.SetMultiChoicePrompt(" ->"," - ")
- shell.SetChecklistOptions("[ ] ","[X] ")
-
- //fmt.Println(os.Args)
- //cyan := color.New(color.FgCyan).SprintFunc()
- //yellow := color.New(color.FgYellow).SprintFunc()
- green := color.New(color.FgGreen).SprintFunc()
- boldBlue := color.New(color.FgBlue, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- boldMag := color.New(color.FgMagenta, color.Bold).SprintFunc()
- boldCyan := color.New(color.FgCyan, color.Bold).SprintFunc()
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldYell := color.New(color.FgYellow, color.Bold).SprintFunc()
-
- promptcol := boldBlue
-
- // display info.
- //shell.Println("Starting interactive Shell")
- shell.SetPrompt(promptcol(">>>"))
-
- shell.AddCmd(&ishell.Cmd{
- Name: "new",
- Help: "Start new Project",
- LongHelp: ` Usage: new
+ //stdOut()
+ shell := ishell.New()
+ shell.SetMultiChoicePrompt(" ->", " - ")
+ shell.SetChecklistOptions("[ ] ", "[X] ")
+
+ //fmt.Println(os.Args)
+ //cyan := color.New(color.FgCyan).SprintFunc()
+ //yellow := color.New(color.FgYellow).SprintFunc()
+ green := color.New(color.FgGreen).SprintFunc()
+ boldBlue := color.New(color.FgBlue, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ boldMag := color.New(color.FgMagenta, color.Bold).SprintFunc()
+ boldCyan := color.New(color.FgCyan, color.Bold).SprintFunc()
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldYell := color.New(color.FgYellow, color.Bold).SprintFunc()
+
+ promptcol := boldBlue
+
+ // display info.
+ //shell.Println("Starting interactive Shell")
+ shell.SetPrompt(promptcol(">>>"))
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "new",
+ Help: "Start new Project",
+ LongHelp: ` Usage: new
If no Task is currently running a new project will be added to database and opened.
When there is an open Task the user will be notified to stop it before adding a new Project`,
- Func: func(c *ishell.Context) {
- //c.Print("\033[H\033[2J")
- //c.Println(boldGreen("Start New Project"))
- newProject()
- showLastProject()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "config",
- Help: "View and Edit Configuration",
- LongHelp: ` Usage: config
+ Func: func(c *ishell.Context) {
+ //c.Print("\033[H\033[2J")
+ //c.Println(boldGreen("Start New Project"))
+ newProject()
+ showLastProject()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "config",
+ Help: "View and Edit Configuration",
+ LongHelp: ` Usage: config
Show the current configuration and ask if it should be edited.
Configurations contains the location of the database file and the Personal Data needed for billing
If config is edited press <Enter> on empty line to keep the old entry`,
- Func: func(c *ishell.Context) {
- editConf()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "resume",
- Help: "Resume the Paused Task",
- LongHelp: ` Usage: resume
+ Func: func(c *ishell.Context) {
+ editConf()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "resume",
+ Help: "Resume the Paused Task",
+ LongHelp: ` Usage: resume
Resume the Task that was paused 'now'.`,
- Func: func(c *ishell.Context) {
- newTask(true)
- stdOut()
- setPauseTask(0)
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "pause",
- Help: "Close the Current Task and remember it",
- LongHelp: ` Usage: pause
+ Func: func(c *ishell.Context) {
+ newTask(true)
+ stdOut()
+ setPauseTask(0)
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "pause",
+ Help: "Close the Current Task and remember it",
+ LongHelp: ` Usage: pause
Closes the current task 'now' and remember it to continue later.
The User is not asked to enter a comment.`,
- Func: func(c *ishell.Context) {
- if opentask.id>0 {
- setPauseTask(opentask.id)
- c.Println("Pausing Task",pausetask)
- }
- closeTask(false)
- stdOut()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "status",
- Help: "Show Current Project and Tasks",
- LongHelp: ` Usage: status
+ Func: func(c *ishell.Context) {
+ if opentask.id > 0 {
+ setPauseTask(opentask.id)
+ c.Println("Pausing Task", pausetask)
+ }
+ closeTask(false)
+ stdOut()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "status",
+ Help: "Show Current Project and Tasks",
+ LongHelp: ` Usage: status
Shows the current Project, its last Tasks and if there is a open Task.`,
- Func: func(c *ishell.Context) {
- stdOut()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "add",
- Help: "Add new Customer",
- LongHelp: ` Usage: add
+ Func: func(c *ishell.Context) {
+ stdOut()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "add",
+ Help: "Add new Customer",
+ LongHelp: ` Usage: add
Add a new Customer to Database`,
- Func: func(c *ishell.Context) {
- addCustomer()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "startnow",
- Help: "Start a new Task immediately",
- LongHelp: ` Usage: startnow
+ Func: func(c *ishell.Context) {
+ addCustomer()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "startnow",
+ Help: "Start a new Task immediately",
+ LongHelp: ` Usage: startnow
Start a new Task in the currently open Project with current local time`,
- Func: func(c *ishell.Context) {
- newTask(false)
- stdOut()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "stopnow",
- Help: "Stop the currently Open Task immediately",
- LongHelp: ` Usage: stopnow
+ Func: func(c *ishell.Context) {
+ newTask(false)
+ stdOut()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "stopnow",
+ Help: "Stop the currently Open Task immediately",
+ LongHelp: ` Usage: stopnow
Stop the open Task at the current local time.
If no task is open the user will be notified.`,
- Func: func(c *ishell.Context) {
- closeTask(true)
- stdOut()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "checkbill",
- Help: "<id> check a Bill with the following id as paid",
- LongHelp: ` Usage: checkbill <id>
+ Func: func(c *ishell.Context) {
+ closeTask(true)
+ stdOut()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "checkbill",
+ Help: "<id> check a Bill with the following id as paid",
+ LongHelp: ` Usage: checkbill <id>
Check the bill of the set <id> as paid on the current date`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- argi,err := strconv.Atoi(arg)
- if err == nil{
- checkBill(argi)
- //stdOut()
- }else{
- c.Println(boldRed(arg,"is not a valid id!"))
- }
- }else{
- c.Println(boldRed("checkbill <id> - Please enter an id"))
- showLastBills(0)
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "deletebill",
- Help: "<id> Delete a Bill with the following id",
- LongHelp: ` Usage: deletebill <id>
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ argi, err := strconv.Atoi(arg)
+ if err == nil {
+ checkBill(argi)
+ //stdOut()
+ } else {
+ c.Println(boldRed(arg, "is not a valid id!"))
+ }
+ } else {
+ c.Println(boldRed("checkbill <id> - Please enter an id"))
+ showLastBills(0)
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "deletebill",
+ Help: "<id> Delete a Bill with the following id",
+ LongHelp: ` Usage: deletebill <id>
Delete the bill of the set <id> and set its Task back to unbilled`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- argi,err := strconv.Atoi(arg)
- if err == nil{
- deleteBill(argi)
- stdOut()
- }else{
- c.Println(boldRed(arg,"is not a valid id!"))
- }
- }else{
- c.Println(boldRed("deletebill <id> - Please enter an id"))
- showLastBills(0)
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "deletetask",
- Help: "<id> Delete a Task with the following id",
- LongHelp: ` Usage: deletetask <id>
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ argi, err := strconv.Atoi(arg)
+ if err == nil {
+ deleteBill(argi)
+ stdOut()
+ } else {
+ c.Println(boldRed(arg, "is not a valid id!"))
+ }
+ } else {
+ c.Println(boldRed("deletebill <id> - Please enter an id"))
+ showLastBills(0)
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "deletetask",
+ Help: "<id> Delete a Task with the following id",
+ LongHelp: ` Usage: deletetask <id>
Delete the Task of the set <id>`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- argi,err := strconv.Atoi(arg)
- if err == nil{
- deleteTask(argi)
- stdOut()
- }else{
- c.Println(boldRed(arg,"is not a valid id!"))
- }
- }else{
- tids := getTaskIds()
- selids,lids := getTaskList(tids,false)
- choice := c.MultiChoice(lids,"Select a Task to Edit")
- if choice > -1 {
- deleteTask(selids[choice])
- }
- //c.Println(boldRed("deletetask <id> - Please enter an id"))
- //allProjects()
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "project",
- Help: "<id> Open a Project of the following id",
- LongHelp: ` Usage: project <id>
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ argi, err := strconv.Atoi(arg)
+ if err == nil {
+ deleteTask(argi)
+ stdOut()
+ } else {
+ c.Println(boldRed(arg, "is not a valid id!"))
+ }
+ } else {
+ tids := getTaskIds()
+ selids, lids := getTaskList(tids, false)
+ choice := c.MultiChoice(lids, "Select a Task to Edit")
+ if choice > -1 {
+ deleteTask(selids[choice])
+ }
+ //c.Println(boldRed("deletetask <id> - Please enter an id"))
+ //allProjects()
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "project",
+ Help: "<id> Open a Project of the following id",
+ LongHelp: ` Usage: project <id>
Open the Project with the set <id>
If there is an open Task the user will be notified to close it first.`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- argi,err := strconv.Atoi(arg)
- if err == nil{
- setProject(argi)
- stdOut()
- }else{
- c.Println(boldRed(arg,"is not a valid id!"))
- }
- }else{
- pids := getProjectIds()
- selids,lids := getProjectList(pids)
- choice := c.MultiChoice(lids,"Select a Project to Edit")
- if choice > -1 {
- setProject(selids[choice])
- }
- //c.Println(boldRed("editproject <id> - Please enter an id"))
- //c.Println(boldRed("project <id> - Please enter an id"))
- //allProjects()
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "edittask",
- Help: "<id> Edit a Task of the following id",
- LongHelp: ` Usage: edittask <id>
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ argi, err := strconv.Atoi(arg)
+ if err == nil {
+ setProject(argi)
+ stdOut()
+ } else {
+ c.Println(boldRed(arg, "is not a valid id!"))
+ }
+ } else {
+ pids := getProjectIds()
+ selids, lids := getProjectList(pids)
+ choice := c.MultiChoice(lids, "Select a Project to Edit")
+ if choice > -1 {
+ setProject(selids[choice])
+ }
+ //c.Println(boldRed("editproject <id> - Please enter an id"))
+ //c.Println(boldRed("project <id> - Please enter an id"))
+ //allProjects()
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "edittask",
+ Help: "<id> Edit a Task of the following id",
+ LongHelp: ` Usage: edittask <id>
Edit Task of the set <id>.
Press <Enter> on empty line to keep the old entry`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- argi,err := strconv.Atoi(arg)
- if err == nil{
- editTask(argi)
- }else{
- c.Println(boldRed(arg,"is not a valid id!"))
- }
- }else{
- tids := getTaskIds()
- selids,lids := getTaskList(tids,false)
- choice := c.MultiChoice(lids,"Select a Task to Edit")
- //c.Println(tids)
- //c.Println(selids)
- if choice > -1 {
- editTask(selids[choice])
- //c.Println(choice,selids[choice])
- }
- //c.Println(boldRed("edittask <id> - Please enter an id"))
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "editproject",
- Help: "<id> Edit the Project of the following id",
- LongHelp: ` Usage: editproject <id>
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ argi, err := strconv.Atoi(arg)
+ if err == nil {
+ editTask(argi)
+ } else {
+ c.Println(boldRed(arg, "is not a valid id!"))
+ }
+ } else {
+ tids := getTaskIds()
+ selids, lids := getTaskList(tids, false)
+ choice := c.MultiChoice(lids, "Select a Task to Edit")
+ //c.Println(tids)
+ //c.Println(selids)
+ if choice > -1 {
+ editTask(selids[choice])
+ //c.Println(choice,selids[choice])
+ }
+ //c.Println(boldRed("edittask <id> - Please enter an id"))
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "editproject",
+ Help: "<id> Edit the Project of the following id",
+ LongHelp: ` Usage: editproject <id>
Edit Project of the set <id>.
Press <Enter> on empty line to keep the old entry`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- argi,err := strconv.Atoi(arg)
- if err == nil{
- editProject(argi)
- //allProjects()
- //stdOut()
- }else{
- c.Println(boldRed(arg,"is not a valid id!"))
- }
- }else{
- pids := getProjectIds()
- selids,lids := getProjectList(pids)
- choice := c.MultiChoice(lids,"Select a Project to Edit")
- //c.Println(pids)
- //c.Println(selids)
- if choice > -1 {
- editProject(selids[choice])
- //c.Println(choice,selids[choice])
- }
- //c.Println(boldRed("editproject <id> - Please enter an id"))
- //allProjects()
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "editcustomer",
- Help: "<id> Edit the Customer of the following id",
- LongHelp: ` Usage: editcustomer <id>
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ argi, err := strconv.Atoi(arg)
+ if err == nil {
+ editProject(argi)
+ //allProjects()
+ //stdOut()
+ } else {
+ c.Println(boldRed(arg, "is not a valid id!"))
+ }
+ } else {
+ pids := getProjectIds()
+ selids, lids := getProjectList(pids)
+ choice := c.MultiChoice(lids, "Select a Project to Edit")
+ //c.Println(pids)
+ //c.Println(selids)
+ if choice > -1 {
+ editProject(selids[choice])
+ //c.Println(choice,selids[choice])
+ }
+ //c.Println(boldRed("editproject <id> - Please enter an id"))
+ //allProjects()
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "editcustomer",
+ Help: "<id> Edit the Customer of the following id",
+ LongHelp: ` Usage: editcustomer <id>
Edit Customer of the set <id>.
Press <Enter> on empty line to keep the old entry`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- argi,err := strconv.Atoi(arg)
- if err == nil{
- editCustomer(argi)
- allCustomers()
- //stdOut()
- }else{
- c.Println(boldRed(arg,"is not a valid id!"))
- }
- }else{
- selids,lids := getCustomerList()
- choice := c.MultiChoice(lids,"Select a Customer to Edit")
- if choice > -1 {
- editCustomer(selids[choice])
- }
- //c.Println(boldRed("editcustomer <id> - Please enter an id"))
- //allCustomers()
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "start",
- Help: "<DateTime> - Start Task at a specific Time 'YYYY-MM-DD HH:MM' Or 'HH:MM'",
- LongHelp: ` Usage: start <DateTime>
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ argi, err := strconv.Atoi(arg)
+ if err == nil {
+ editCustomer(argi)
+ allCustomers()
+ //stdOut()
+ } else {
+ c.Println(boldRed(arg, "is not a valid id!"))
+ }
+ } else {
+ selids, lids := getCustomerList()
+ choice := c.MultiChoice(lids, "Select a Customer to Edit")
+ if choice > -1 {
+ editCustomer(selids[choice])
+ }
+ //c.Println(boldRed("editcustomer <id> - Please enter an id"))
+ //allCustomers()
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "start",
+ Help: "<DateTime> - Start Task at a specific Time 'YYYY-MM-DD HH:MM' Or 'HH:MM'",
+ LongHelp: ` Usage: start <DateTime>
Start a new Task in the currently open Project at <DateTime>.
Use Format "YYYY-MM-DD HH:MM" or "HH:MM" for datetime.
If the latter is used the current local Date will be set.`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- newTaskTime(currproject.id,arg)
- stdOut()
- }else{
- c.Println(boldRed("start <DateTime> - Please enter a Datetime"))
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "stop",
- Help: "<DateTime> - Stop Open Task at a specific Time 'YYYY-MM-DD HH:MM' Or 'HH:MM'",
- LongHelp: ` Usage: stop <DateTime>
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ newTaskTime(currproject.id, arg)
+ stdOut()
+ } else {
+ c.Println(boldRed("start <DateTime> - Please enter a Datetime"))
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "stop",
+ Help: "<DateTime> - Stop Open Task at a specific Time 'YYYY-MM-DD HH:MM' Or 'HH:MM'",
+ LongHelp: ` Usage: stop <DateTime>
Stop the active Task at <DateTime>.
Use Format "YYYY-MM-DD HH:MM" or "HH:MM" for datetime.
If the latter is used the current local Date will be set.
In case of a Stop-time before Task start user will be notified.`,
- Func: func(c *ishell.Context) {
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- closeTaskTime(arg)
- stdOut()
- }else{
- c.Println(boldRed("stop <DateTime> - Please enter a Datetime"))
- }
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "all",
- Help: "Show all Projects",
- LongHelp: ` Usage: all
+ Func: func(c *ishell.Context) {
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ closeTaskTime(arg)
+ stdOut()
+ } else {
+ c.Println(boldRed("stop <DateTime> - Please enter a Datetime"))
+ }
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "all",
+ Help: "Show all Projects",
+ LongHelp: ` Usage: all
Show all Projects with small summary sorted by Customer.`,
- Func: func(c *ishell.Context) {
- allProjects()
- stdOut()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "allbills",
- Help: "Show all Bills",
- LongHelp: ` Usage: allbills
+ Func: func(c *ishell.Context) {
+ allProjects()
+ stdOut()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "allbills",
+ Help: "Show all Bills",
+ LongHelp: ` Usage: allbills
Show all previous Bills with small summary.`,
- Func: func(c *ishell.Context) {
- showLastBills(0)
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "allcustomers",
- Help: "Show all Customers",
- LongHelp: ` Usage: allcustomers
+ Func: func(c *ishell.Context) {
+ showLastBills(0)
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "allcustomers",
+ Help: "Show all Customers",
+ LongHelp: ` Usage: allcustomers
Show all Customers.`,
- Func: func(c *ishell.Context) {
- allCustomers()
- c.Println(promptcol("______________________"))
- },
- })
-
- shell.AddCmd(&ishell.Cmd{
- Name: "showbills",
- Help: "<n> - Show the last n bills",
- LongHelp: ` Usage: showbills <n>
+ Func: func(c *ishell.Context) {
+ allCustomers()
+ c.Println(promptcol("______________________"))
+ },
+ })
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "showbills",
+ Help: "<n> - Show the last n bills",
+ LongHelp: ` Usage: showbills <n>
Show the last n Bills with a small summary.`,
- Func: func(c *ishell.Context) {
- //c.ClearScreen()
- arg := "none"
- if len(c.Args) > 0 {
- arg = strings.Join(c.Args, " ")
- argi,err := strconv.Atoi(arg)
- if err == nil{
- showLastBills(argi)
- }else{
- c.Println(boldRed(arg,"is not a valid integer!"))
- }
- }else{
- c.Println(boldRed("showbills <n> - Please enter an integer"))
- }
- //stdOut()
- c.Println(promptcol("______________________"))
- },
- })
-/*
- // multiple choice
- shell.AddCmd(&ishell.Cmd{
- Name: "choice",
- Help: "multiple choice prompt",
- Func: func(c *ishell.Context) {
- choice := c.MultiChoice([]string{
- "Golangers",
- "Go programmers",
- "Gophers",
- "Goers",
- }, "What are Go programmers called ?")
- if choice == 2 {
- c.Println("You got it!")
- } else {
- c.Println("Sorry, you're wrong.")
- }
- },
- })
-
-// multiple choice
- shell.AddCmd(&ishell.Cmd{
- Name: "checklist",
- Help: "checklist prompt",
- Func: func(c *ishell.Context) {
- languages := []string{"Python", "Go", "Haskell", "Rust"}
- choices := c.Checklist(languages,
- "What are your favourite programming languages ?",
- nil)
- out := func() (c []string) {
- for _, v := range choices {
- c = append(c, languages[v])
- }
- return
- }
- c.Println("Your choices are", strings.Join(out(), ", "))
- },
- })
-*/
- //Test stuff in shell
- shell.AddCmd(&ishell.Cmd{
- Name: "test",
- Help: "Test some functions in interactive mode",
- LongHelp: ` Usage: test
+ Func: func(c *ishell.Context) {
+ //c.ClearScreen()
+ arg := "none"
+ if len(c.Args) > 0 {
+ arg = strings.Join(c.Args, " ")
+ argi, err := strconv.Atoi(arg)
+ if err == nil {
+ showLastBills(argi)
+ } else {
+ c.Println(boldRed(arg, "is not a valid integer!"))
+ }
+ } else {
+ c.Println(boldRed("showbills <n> - Please enter an integer"))
+ }
+ //stdOut()
+ c.Println(promptcol("______________________"))
+ },
+ })
+ /*
+ // multiple choice
+ shell.AddCmd(&ishell.Cmd{
+ Name: "choice",
+ Help: "multiple choice prompt",
+ Func: func(c *ishell.Context) {
+ choice := c.MultiChoice([]string{
+ "Golangers",
+ "Go programmers",
+ "Gophers",
+ "Goers",
+ }, "What are Go programmers called ?")
+ if choice == 2 {
+ c.Println("You got it!")
+ } else {
+ c.Println("Sorry, you're wrong.")
+ }
+ },
+ })
+
+ // multiple choice
+ shell.AddCmd(&ishell.Cmd{
+ Name: "checklist",
+ Help: "checklist prompt",
+ Func: func(c *ishell.Context) {
+ languages := []string{"Python", "Go", "Haskell", "Rust"}
+ choices := c.Checklist(languages,
+ "What are your favourite programming languages ?",
+ nil)
+ out := func() (c []string) {
+ for _, v := range choices {
+ c = append(c, languages[v])
+ }
+ return
+ }
+ c.Println("Your choices are", strings.Join(out(), ", "))
+ },
+ })
+ */
+ //Test stuff in shell
+ shell.AddCmd(&ishell.Cmd{
+ Name: "test",
+ Help: "Test some functions in interactive mode",
+ LongHelp: ` Usage: test
Test functions in interactive mode`,
- Func: func(c *ishell.Context) {
- multichoice("Geh scheissn")
+ Func: func(c *ishell.Context) {
+ multichoice("Geh scheissn")
- },
- })
+ },
+ })
- // Prompt Color
- shell.AddCmd(&ishell.Cmd{
- Name: "colorprompt",
- Help: "Select the Color of the prompt",
- LongHelp: ` Usage: colorprompt
+ // Prompt Color
+ shell.AddCmd(&ishell.Cmd{
+ Name: "colorprompt",
+ Help: "Select the Color of the prompt",
+ LongHelp: ` Usage: colorprompt
Select the color of the prompt`,
- Func: func(c *ishell.Context) {
- choice := c.MultiChoice([]string{
- boldMag("Magenta"),
- boldBlue("Blue"),
- boldCyan("Cyan"),
- boldGreen("Green"),
- boldYell("Yellow"),
- boldRed("Red"),
- }, "What Color should the Prompt be?")
- switch choice {
- case 0:
- c.SetPrompt(boldMag(">>>"))
- promptcol=boldMag
- case 1:
- c.SetPrompt(boldBlue(">>>"))
- promptcol=boldBlue
- case 2:
- c.SetPrompt(boldCyan(">>>"))
- promptcol=boldCyan
- case 3:
- c.SetPrompt(boldGreen(">>>"))
- promptcol=boldGreen
- case 4:
- c.SetPrompt(boldYell(">>>"))
- promptcol=boldYell
- case 5:
- c.SetPrompt(boldRed(">>>"))
- promptcol=boldRed
- }
- c.Println(promptcol("As You Wish!"))
-
- c.Println(promptcol("______________________"))
- },
- })
-// Gather Tasks For Bills
- shell.AddCmd(&ishell.Cmd{
- Name: "bill",
- Help: "Select Tasks to be billed",
- LongHelp: ` Usage: bill
+ Func: func(c *ishell.Context) {
+ choice := c.MultiChoice([]string{
+ boldMag("Magenta"),
+ boldBlue("Blue"),
+ boldCyan("Cyan"),
+ boldGreen("Green"),
+ boldYell("Yellow"),
+ boldRed("Red"),
+ }, "What Color should the Prompt be?")
+ switch choice {
+ case 0:
+ c.SetPrompt(boldMag(">>>"))
+ promptcol = boldMag
+ case 1:
+ c.SetPrompt(boldBlue(">>>"))
+ promptcol = boldBlue
+ case 2:
+ c.SetPrompt(boldCyan(">>>"))
+ promptcol = boldCyan
+ case 3:
+ c.SetPrompt(boldGreen(">>>"))
+ promptcol = boldGreen
+ case 4:
+ c.SetPrompt(boldYell(">>>"))
+ promptcol = boldYell
+ case 5:
+ c.SetPrompt(boldRed(">>>"))
+ promptcol = boldRed
+ }
+ c.Println(promptcol("As You Wish!"))
+
+ c.Println(promptcol("______________________"))
+ },
+ })
+ // Gather Tasks For Bills
+ shell.AddCmd(&ishell.Cmd{
+ Name: "bill",
+ Help: "Select Tasks to be billed",
+ LongHelp: ` Usage: bill
Select the tasks that should be merged into a Bill.
The Initial selection cannot be changed afterward. Only the complete
bill can be deleted and a new selection made.`,
- Func: func(c *ishell.Context) {
- nix := []int{0}
- ids,str := getTaskList(nix,true)
- choices := c.Checklist(str,
- "What Tasks do you want to bill ?",
- nil)
- out := func() (c []int) {
- for _, v := range choices {
- if v > -1 {
- c = append(c, ids[v])
- }
- }
- return
- }
- //All selected ids
- selids := out()
- //bids,str2 := getTaskList(selids,false)
- //c.Println(bids,str2)
- c.Println(len(selids),"Tasks Selected")
- //If None Selected end
- if len(selids) == 0 {
- return
- }
- //get if selected tasks have multicustomers, are from multipe projects, and get the ids of the projects
- multicust, multiproj,projids := checkCustomerProjects(selids)
- billprojid := 0
-
- // CHECK IF ONLY ONE CUSTOMER
- if multicust {
- c.Println(boldRed("Cannot Write One Bill to multiple Customers! Please Select different Tasks"))
-
- }else{
- // CHECK IF ONLY ONE PROJECT ELSE CHOOSE ONE
- if multiproj {
- prid,prstr :=getProjectList(projids)
- sel := c.MultiChoice(prstr, "What Project Should be Billed ?")
- if sel > -1 {
- billprojid = prid[sel]
- }
- }else{
- billprojid = projids[0]
- }
-
- seltasks := getSelectedTasks(selids)
- count,hours,dur := analyzeTasks(seltasks)
-
- //c.Printf("%v Tasks Selected. Totaling %.2f (h) - Dates: %s\n",count,hours,dur)
- proj,cust := getProject(billprojid)
- // IF CUSTOMER 0 NO BILL CAN BE CREATED
- if cust.id == 0 {
- c.Println(boldRed("Customer ",cust.company," with id ",cust.id," Cannot be billed. Please move ",proj.name," to a valid Customer"))
- return
- }
-
- //billid,billident := newBill(billprojid)
- //prs,cus := getProjectName(billprojid)
- //c.Println("For",cust.company,"-",cust.name)
- //c.Println("Project:",proj.name,"- ID:",proj.id)
- //c.Println("Projected Income:",hours*cust.satz,"€")
-
- //c.Println("Create New Bill:",billid)
- //c.ReadLine() //Make NEW BILL WITH ID and INV No
- c.ShowPrompt(false)
-
- //fullbillinfo := fmt.Sprintf("For: %s - %s - %.2f(€/h) - Invoice: %s Id:%v\nProject: %s - Id:%v\n%v Tasks Selected. Totaling %.2f (h) - Dates: %s\nProjected Income: %.2f(€)\n",cust.company,cust.name,cust.satz,billident,billid,proj.name,proj.id,count,hours,dur,hours*cust.satz)
- fullbillinfo := fmt.Sprintf("For: %s - %s - %.2f(€/h) \nProject: %s - Id:%v\n%v Tasks Selected. Totaling %.2f (h) - Dates: %s\nProjected Income: %.2f(€)\n",cust.company,cust.name,cust.satz,proj.name,proj.id,count,hours,dur,hours*cust.satz)
- sep := "-------------------------\n"
- restinfo := "Here some Info about the rest"
- restids := selids
- var allitems []billitem
-
- //allaccounted := false
- //resttasks := seltasks
- //SELECT SUBSET AND NAME BILLITEM
- //c.clear()//Println(some,"Str2:",str2)
- for {
- if len(restids) == 0 {
- break
- }
- resttasks := getSelectedTasks(restids)
- rcount,rhours,_ := analyzeTasks(resttasks)
-
- rids,rstr := getTaskList(restids,false)
- qu := "Select Tasks to Group as Billitem"
- restinfo = fmt.Sprintf("%v Tasks Left, Total %.2f(h)\n%s",rcount,rhours,qu)
- pre := fmt.Sprintf("%s%s%s",fullbillinfo,sep,restinfo)
-
- choices2 := c.Checklist(rstr,pre,nil)
- out = func() (c []int) {
- for _, v := range choices2 {
- if v > -1 {
- c = append(c, rids[v])
- }
+ Func: func(c *ishell.Context) {
+ nix := []int{0}
+ ids, str := getTaskList(nix, true)
+ choices := c.Checklist(str,
+ "What Tasks do you want to bill ?",
+ nil)
+ out := func() (c []int) {
+ for _, v := range choices {
+ if v > -1 {
+ c = append(c, ids[v])
+ }
+ }
+ return
+ }
+ //All selected ids
+ selids := out()
+ //bids,str2 := getTaskList(selids,false)
+ //c.Println(bids,str2)
+ c.Println(len(selids), "Tasks Selected")
+ //If None Selected end
+ if len(selids) == 0 {
+ return
}
- return
- }
- taskids := out()
- restids = removeItems(restids,taskids)
-
- if len(taskids)>0 {
- ittasks := getSelectedTasks(taskids)
- itcount,ithours,itdur := analyzeTasks(ittasks)
- c.Printf("\n%v Tasks Selected, Total %.2f(h), Date: %s\n",itcount,ithours,itdur)
- c.ShowPrompt(false)
- c.Print("Name your Task for the Bill: ")
- tsk := c.ReadLine()
- var hrf float64
- for {
- c.Print("How Many Hours: ")
- hr := c.ReadLine()
- hrf,err = strconv.ParseFloat(hr,64)
- if err != nil {
- c.Println(hr,boldRed("can not be Parsed as a Float."),"Try a shape of X.X")
- }else{break}
- }
- c.Printf("%T %v - %T %v\n",tsk,tsk,hrf,hrf)
- allitems = append(allitems,billitem{tsk,itdur,hrf,Round(hrf*cust.satz,5)})
- c.Print("<<Continue>>")
- c.ReadLine()
- //c.ShowPrompt(true)
- }
- }
- billid,billident := newBill(billprojid)
- c.Println(green("Bill Completed"))
- fullbill := bill{billid,billident,dur,proj.id,proj.name,time.Time{},time.Time{},allitems}
- saveBill(fullbill)
- checkTasks(selids,billid)
- c.ProgressBar().Indeterminate(true)
- c.ProgressBar().Start()
- testid := []int{billid}
- testbill := loadBills(testid)
- //c.Println(testbill[0].projectname,testbill[0].items)
- files := billTemplate(testbill[0],cust)
- c.Println(files)
- err = runLatex(files.Main,testbill[0].identity)
- c.ProgressBar().Stop()
- if err== nil {
- c.Println("Finished without Errors")
- }else{
- c.Println("Finished with error:",err)
- }
- c.Print("<<Continue>>")
- c.ReadLine()
- stdOut()
- }
- c.Println(promptcol("______________________"))
- c.ShowPrompt(true)
- },
- })
-
- // Decide if interactive mode should be started
- //args := removeStringFromArray(os.Args[1:],"-file",1)
-
- if len(interArgs) > 0 {
- //args := removeStringFromArray(os.Args[1:],"-file",1)
- //fmt.Println(args)
- shell.Process(interArgs...)
- } else {
- shell.Println("Starting interactive Shell")
- stdOut()
- //start shell
- shell.Run()
- // teardown
- shell.Close()
- }
- //fmt.Println("Laboravi emeritus...")
+ //get if selected tasks have multicustomers, are from multipe projects, and get the ids of the projects
+ multicust, multiproj, projids := checkCustomerProjects(selids)
+ billprojid := 0
+
+ // CHECK IF ONLY ONE CUSTOMER
+ if multicust {
+ c.Println(boldRed("Cannot Write One Bill to multiple Customers! Please Select different Tasks"))
+
+ } else {
+ // CHECK IF ONLY ONE PROJECT ELSE CHOOSE ONE
+ if multiproj {
+ prid, prstr := getProjectList(projids)
+ sel := c.MultiChoice(prstr, "What Project Should be Billed ?")
+ if sel > -1 {
+ billprojid = prid[sel]
+ }
+ } else {
+ billprojid = projids[0]
+ }
+
+ seltasks := getSelectedTasks(selids)
+ count, hours, dur := analyzeTasks(seltasks)
+
+ //c.Printf("%v Tasks Selected. Totaling %.2f (h) - Dates: %s\n",count,hours,dur)
+ proj, cust := getProject(billprojid)
+ // IF CUSTOMER 0 NO BILL CAN BE CREATED
+ if cust.id == 0 {
+ c.Println(boldRed("Customer ", cust.company, " with id ", cust.id, " Cannot be billed. Please move ", proj.name, " to a valid Customer"))
+ return
+ }
+
+ //billid,billident := newBill(billprojid)
+ //prs,cus := getProjectName(billprojid)
+ //c.Println("For",cust.company,"-",cust.name)
+ //c.Println("Project:",proj.name,"- ID:",proj.id)
+ //c.Println("Projected Income:",hours*cust.satz,"€")
+
+ //c.Println("Create New Bill:",billid)
+ //c.ReadLine() //Make NEW BILL WITH ID and INV No
+ c.ShowPrompt(false)
+
+ //fullbillinfo := fmt.Sprintf("For: %s - %s - %.2f(€/h) - Invoice: %s Id:%v\nProject: %s - Id:%v\n%v Tasks Selected. Totaling %.2f (h) - Dates: %s\nProjected Income: %.2f(€)\n",cust.company,cust.name,cust.satz,billident,billid,proj.name,proj.id,count,hours,dur,hours*cust.satz)
+ fullbillinfo := fmt.Sprintf("For: %s - %s - %.2f(€/h) \nProject: %s - Id:%v\n%v Tasks Selected. Totaling %.2f (h) - Dates: %s\nProjected Income: %.2f(€)\n", cust.company, cust.name, cust.satz, proj.name, proj.id, count, hours, dur, hours*cust.satz)
+ sep := "-------------------------\n"
+ restinfo := "Here some Info about the rest"
+ restids := selids
+ var allitems []billitem
+
+ //allaccounted := false
+ //resttasks := seltasks
+ //SELECT SUBSET AND NAME BILLITEM
+ //c.clear()//Println(some,"Str2:",str2)
+ for {
+ if len(restids) == 0 {
+ break
+ }
+ resttasks := getSelectedTasks(restids)
+ rcount, rhours, _ := analyzeTasks(resttasks)
+
+ rids, rstr := getTaskList(restids, false)
+ qu := "Select Tasks to Group as Billitem"
+ restinfo = fmt.Sprintf("%v Tasks Left, Total %.2f(h)\n%s", rcount, rhours, qu)
+ pre := fmt.Sprintf("%s%s%s", fullbillinfo, sep, restinfo)
+
+ choices2 := c.Checklist(rstr, pre, nil)
+ out = func() (c []int) {
+ for _, v := range choices2 {
+ if v > -1 {
+ c = append(c, rids[v])
+ }
+ }
+ return
+ }
+ taskids := out()
+ restids = removeItems(restids, taskids)
+
+ if len(taskids) > 0 {
+ ittasks := getSelectedTasks(taskids)
+ itcount, ithours, itdur := analyzeTasks(ittasks)
+ c.Printf("\n%v Tasks Selected, Total %.2f(h), Date: %s\n", itcount, ithours, itdur)
+ c.ShowPrompt(false)
+ c.Print("Name your Task for the Bill: ")
+ tsk := c.ReadLine()
+ var hrf float64
+ for {
+ c.Print("How Many Hours: ")
+ hr := c.ReadLine()
+ hrf, err = strconv.ParseFloat(hr, 64)
+ if err != nil {
+ c.Println(hr, boldRed("can not be Parsed as a Float."), "Try a shape of X.X")
+ } else {
+ break
+ }
+ }
+ c.Printf("%T %v - %T %v\n", tsk, tsk, hrf, hrf)
+ allitems = append(allitems, billitem{tsk, itdur, hrf, Round(hrf*cust.satz, 5)})
+ c.Print("<<Continue>>")
+ c.ReadLine()
+ //c.ShowPrompt(true)
+ }
+ }
+ billid, billident := newBill(billprojid)
+ c.Println(green("Bill Completed"))
+ fullbill := bill{billid, billident, dur, proj.id, proj.name, time.Time{}, time.Time{}, allitems}
+ saveBill(fullbill)
+ checkTasks(selids, billid)
+ c.ProgressBar().Indeterminate(true)
+ c.ProgressBar().Start()
+ testid := []int{billid}
+ testbill := loadBills(testid)
+ //c.Println(testbill[0].projectname,testbill[0].items)
+ files := billTemplate(testbill[0], cust)
+ c.Println(files)
+ err = runLatex(files.Main, testbill[0].identity)
+ c.ProgressBar().Stop()
+ if err == nil {
+ c.Println("Finished without Errors")
+ } else {
+ c.Println("Finished with error:", err)
+ }
+ c.Print("<<Continue>>")
+ c.ReadLine()
+ stdOut()
+ }
+ c.Println(promptcol("______________________"))
+ c.ShowPrompt(true)
+ },
+ })
+
+ // Decide if interactive mode should be started
+ //args := removeStringFromArray(os.Args[1:],"-file",1)
+
+ if len(interArgs) > 0 {
+ //args := removeStringFromArray(os.Args[1:],"-file",1)
+ //fmt.Println(args)
+ shell.Process(interArgs...)
+ } else {
+ shell.Println("Starting interactive Shell")
+ stdOut()
+ //start shell
+ shell.Run()
+ // teardown
+ shell.Close()
+ }
+ //fmt.Println("Laboravi emeritus...")
}
-func isInterSure(question string) (bool) {
+func isInterSure(question string) bool {
shell := ishell.New()
shell.ShowPrompt(false)
defer shell.ShowPrompt(true)
- shell.Printf("%s (type 'y/Y/yes' to confirm) : ",question)
+ shell.Printf("%s (type 'y/Y/yes' to confirm) : ", question)
line := shell.ReadLine()
- if ( line == "yes" || line == "y" || line == "Y") {
+ if line == "yes" || line == "y" || line == "Y" {
return true
} else {
return false
@@ -739,20 +740,20 @@ func getInterInput(question string) (out string) {
return
}
-func getNewInterInput(question,old string) (string) {
+func getNewInterInput(question, old string) string {
shell := ishell.New()
shell.ShowPrompt(false)
defer shell.ShowPrompt(true)
if old != "" {
- shell.Println("Current:",old)
+ shell.Println("Current:", old)
}
shell.Print(question)
line := shell.ReadLine()
if line == "" {
return old
- }else{
+ } else {
return line
}
}
@@ -762,32 +763,32 @@ func getInterMultiInput(question string) (out string) {
//shell.ShowPrompt(false)
//defer shell.ShowPrompt(true)
- shell.Println(question,"(Multiline input, end with ';')")
+ shell.Println(question, "(Multiline input, end with ';')")
out = shell.ReadMultiLines(";")
shell.Println(" -Done-")
return
}
-func getNewInterMultiInput(question,old string) (out string) {
+func getNewInterMultiInput(question, old string) (out string) {
shell := ishell.New()
//shell.ShowPrompt(false)
//defer shell.ShowPrompt(true)
if old != "" {
- shell.Println("Current:\n",old)
+ shell.Println("Current:\n", old)
}
shell.Println("Should current entry be replaced? A Newline will be added otherwise")
- if isInterSure(" "){
- shell.Println(question,"(Multiline input, end with ';')")
+ if isInterSure(" ") {
+ shell.Println(question, "(Multiline input, end with ';')")
out = shell.ReadMultiLines(";")
shell.Println(" -Done-")
- }else{
+ } else {
shell.Print(question)
txt := shell.ReadLine()
if txt == "" {
out = old
- }else{
+ } else {
out = old + "\n" + txt
}
}
@@ -802,27 +803,27 @@ func getNewInterMultiInput(question,old string) (out string) {
func multichoice(about string) {
- shell := ishell.New()
- shell.SetMultiChoicePrompt(" ->"," - ")
- shell.SetChecklistOptions("[ ] ","[X] ")
-
- shell.AddCmd(&ishell.Cmd{
- Name: "choice",
- Help: "multiple choice prompt",
- Func: func(c *ishell.Context) {
- choice := c.MultiChoice([]string{
- "Golangers",
- "Go programmers",
- "Gophers",
- "Goers",
- }, "What are Go programmers called ?")
- if choice == 2 {
- c.Println("You got it!")
- } else {
- c.Println("Sorry, you're wrong.")
- }
- },
- })
+ shell := ishell.New()
+ shell.SetMultiChoicePrompt(" ->", " - ")
+ shell.SetChecklistOptions("[ ] ", "[X] ")
+
+ shell.AddCmd(&ishell.Cmd{
+ Name: "choice",
+ Help: "multiple choice prompt",
+ Func: func(c *ishell.Context) {
+ choice := c.MultiChoice([]string{
+ "Golangers",
+ "Go programmers",
+ "Gophers",
+ "Goers",
+ }, "What are Go programmers called ?")
+ if choice == 2 {
+ c.Println("You got it!")
+ } else {
+ c.Println("Sorry, you're wrong.")
+ }
+ },
+ })
str := "choice"
shell.Process(str)
shell.Println(about)
diff --git a/main.go b/main.go
index fdc84e7..eda3469 100644
--- a/main.go
+++ b/main.go
@@ -1,22 +1,27 @@
+// Copyright 2018 n@gotsche.at
+// All Rights Reserved
+
+// Laboravi - Timetracker and Bill generator
+//
+// I came, I worked, I Billed
package main
import (
- "fmt"
- //"flag"
- "path/filepath"
- _ "log"
- //"bufio"
- "os"
- //"strings"
- _ "os/exec"
- "github.com/fatih/color"
- "github.com/pborman/getopt/v2"
+ "fmt"
+ _ "log"
+ "os"
+ "path/filepath"
+ //"strings"
+ "github.com/fatih/color"
+ "github.com/pborman/getopt/v2"
+ _ "os/exec"
)
var (
- version string
- compdate string
+ version string
+ compdate string
)
+
//var svar string
//var starttime,stoptime,filename string
//var projectid int
@@ -26,133 +31,148 @@ var (
//var newproject, newtask, stoptask, allproj, allbills, runinter, test, newconfig bool
//var billcount int
-var test,help bool
+var test, help bool
var filename string
var interArgs []string
//var red, green, yellow, cyan color
//var boldRed, boldGreen color
-
func init() {
-
- filename="none"
- //interArgs = removeStringFromArray(os.Args[1:],"-file",1)
-
- getopt.FlagLong(&test, "test", 't', "Test some new Functions")
- getopt.FlagLong(&help, "help", 'h', "Show Program Usage")
- getopt.FlagLong(&filename, "file", 'f', "Load different DB than in config")
- //flag.StringVar(&svar, "svar", "bar", "A String Var")
-
-/* flag.BoolVar(&test,
- "test",
- false,
- "Test Some Functions")
- flag.StringVar(&filename,
- "file",
- "none",
- "Open a different Database than specified in Configuration")
- // CUSTOMIZE USAGE
- flag.Usage = func() {
- //fmt.Fprintf(os.Stderr, "Usage of %s Version %s (%s):\n %s [Options] <Commands>\n\nOptions:\n", os.Args[0],version,compdate,os.Args[0])
- fmt.Fprintf(os.Stdout, "Usage of %s Version %s (%s):\n %s [Options] <Commands>\n\nOptions:\n", os.Args[0],version,compdate,os.Args[0])
- flag.PrintDefaults()
- interArgs = append([]string{"help"},interArgs...)
- }
- //flag.SetOutput(os.Stdout)
- flag.Parse()*/
-}
+ filename = "none"
+ //interArgs = removeStringFromArray(os.Args[1:],"-file",1)
+
+ getopt.FlagLong(&test, "test", 't', "Test some new Functions")
+ getopt.FlagLong(&help, "help", 'h', "Show Program Usage")
+ getopt.FlagLong(&filename, "file", 'f', "Load different DB than in config")
+ //flag.StringVar(&svar, "svar", "bar", "A String Var")
+
+ /* flag.BoolVar(&test,
+ "test",
+ false,
+ "Test Some Functions")
+ flag.StringVar(&filename,
+ "file",
+ "none",
+ "Open a different Database than specified in Configuration")
+ // CUSTOMIZE USAGE
+ flag.Usage = func() {
+ //fmt.Fprintf(os.Stderr, "Usage of %s Version %s (%s):\n %s [Options] <Commands>\n\nOptions:\n", os.Args[0],version,compdate,os.Args[0])
+ fmt.Fprintf(os.Stdout, "Usage of %s Version %s (%s):\n %s [Options] <Commands>\n\nOptions:\n", os.Args[0],version,compdate,os.Args[0])
+ flag.PrintDefaults()
+ interArgs = append([]string{"help"},interArgs...)
+ }
+ //flag.SetOutput(os.Stdout)
+ flag.Parse()*/
+}
+// title prints the colored Laboravi Logo.
+//
+// Argument decides if a Frame shpuld be drawn around it.
func title(frame bool) {
- bR := color.New(color.FgRed, color.Bold).SprintFunc()
- bHiR := color.New(color.FgHiRed, color.Bold).SprintFunc()
- bHiY := color.New(color.FgHiYellow, color.Bold).SprintFunc()
- bHiG := color.New(color.FgHiGreen, color.Bold).SprintFunc()
- bHiC := color.New(color.FgHiCyan, color.Bold).SprintFunc()
- bHiB := color.New(color.FgHiBlue, color.Bold).SprintFunc()
- bHiM := color.New(color.FgHiMagenta, color.Bold).SprintFunc()
- bM := color.New(color.FgMagenta, color.Bold).SprintFunc()
- line := "___"
-
- if frame {
- fmt.Printf("%s%s%s%s%s%s%s%s\n\n",bR(line),bHiR(line),bHiY(line),bHiG(line),bHiC(line),bHiB(line),bHiM(line),bM(line))
- }
- fmt.Println(" ",bR("L"),bHiR("A"),bHiY("B"),bHiG("O"),bHiC("R"),bHiB("A"),bHiM("V"),bM("I"))
- if frame {
- fmt.Printf("%s%s%s%s%s%s%s%s\n",bR(line),bHiR(line),bHiY(line),bHiG(line),bHiC(line),bHiB(line),bHiM(line),bM(line))
- fmt.Printf("Version %s (%s)\n",version,compdate)
- fmt.Println("(c) 2018 - n@gotsche.at\n")
- }
+ bR := color.New(color.FgRed, color.Bold).SprintFunc()
+ bHiR := color.New(color.FgHiRed, color.Bold).SprintFunc()
+ bHiY := color.New(color.FgHiYellow, color.Bold).SprintFunc()
+ bHiG := color.New(color.FgHiGreen, color.Bold).SprintFunc()
+ bHiC := color.New(color.FgHiCyan, color.Bold).SprintFunc()
+ bHiB := color.New(color.FgHiBlue, color.Bold).SprintFunc()
+ bHiM := color.New(color.FgHiMagenta, color.Bold).SprintFunc()
+ bM := color.New(color.FgMagenta, color.Bold).SprintFunc()
+ line := "___"
+
+ if frame {
+ fmt.Printf("%s%s%s%s%s%s%s%s\n\n", bR(line), bHiR(line), bHiY(line), bHiG(line), bHiC(line), bHiB(line), bHiM(line), bM(line))
+ }
+ fmt.Println(" ", bR("L"), bHiR("A"), bHiY("B"), bHiG("O"), bHiC("R"), bHiB("A"), bHiM("V"), bM("I"))
+ if frame {
+ fmt.Printf("%s%s%s%s%s%s%s%s\n", bR(line), bHiR(line), bHiY(line), bHiG(line), bHiC(line), bHiB(line), bHiM(line), bM(line))
+ fmt.Printf("Version %s (%s)\n", version, compdate)
+ fmt.Println("(c) 2018 - n@gotsche.at\n")
+ }
}
+// stdOut shows the standard output the user can determine
+// the state of Laboravi immediately.
func stdOut() {
- showLastProject()
- getClosedTasks(0)
- showOpenTask()
+ showLastProject()
+ getClosedTasks(0)
+ showOpenTask()
}
func main() {
- //boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- //fmt.Println("Laboravi Started")
- getopt.Parse()
- interArgs = getopt.Args()
-
- //fmt.Println(interArgs)
- dbname := "./.mytimes.db"
-
- if len(interArgs) > 0 {
- title(false)
- }else{
- title(true)
- }
-
- if help {
- fmt.Printf("Usage of %s Version %s:\n Use Commands as Parameters\n If Commands or flags other than -f were passed %s exits after execution of command.\n\n", os.Args[0],version,os.Args[0])
- getopt.Usage()
- interArgs = append([]string{"help"},interArgs...)
-
- }else if test {
- //fmt.Println(Round(12.55,0.5),Round(12.55,0.1),Round(12.55,1),Round(12.55,5))
- //fmt.Println(getGitTag())
- multichoice("Fuckoff")
- fmt.Println("Nothing to test")
- //tmpltest()
- //newBill(1)
- //c := []int{2,3}
- //a,b := getUnfinishedList(c)
- //fmt.Println(a,b)
- os.Exit(0)
- }else{
- initConf()
- }
-
-
- haveone := false
- if filename != "none" {
- if haveone {
- fmt.Println("Only One DB Allowed! Will ignore",filename)
- }else{
- haveone = true
- dbname = filename
- if filepath.Ext(filename) != ".db" || filepath.Ext(filename) != ".sql" {
- fmt.Println("Please consider to use a file extension like .db or .sql \n like ~/.<name>.db")
- }
- }
- }else{
- dbname = config.Database
- }
-
- if !help {
- initDB(dbname)
- pausetask = getPauseTask()
- getLastProject()
- getOpenTask()
- }
-
- interact()
-
- fmt.Println("Laboravi finietur...")
+ //boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ //fmt.Println("Laboravi Started")
+ getopt.Parse()
+ interArgs = getopt.Args()
+
+ //fmt.Println(interArgs)
+ dbname := "./.mytimes.db"
+
+ if len(interArgs) > 0 {
+ title(false)
+ } else {
+ title(true)
+ }
+
+ if help {
+ fmt.Printf("Usage of %s Version %s:\n Use Commands as Parameters\n If Commands or flags other than -f were passed %s exits after execution of command.\n\n", os.Args[0], version, os.Args[0])
+ getopt.Usage()
+ interArgs = append([]string{"help"}, interArgs...)
+
+ } else if test {
+ //fmt.Println(Round(12.55,0.5),Round(12.55,0.1),Round(12.55,1),Round(12.55,5))
+ //fmt.Println(getGitTag())
+ //multichoice("Fuckoff")
+ fmt.Println(mli,"halllllllooooo",li,li,li)
+ fmt.Println(nli)
+ fmt.Println(sli,"Something something Something")
+ fmt.Println(nli,"And some more text lalala")
+ fmt.Println(fli,"And some End")
+ fmt.Println("Nothing to test")
+ fmt.Println(frame("HEADLINE",true))
+ fmt.Println(sli,"Something something Something")
+ fmt.Println(nli,"And some more text lalala")
+ fmt.Println(nli)
+ fmt.Println(sli,"More Something Something")
+ fmt.Println(nli,"And even some more text lalala")
+ fmt.Println(nli)
+ fmt.Println(frame("FOOTER",false))
+ //tmpltest()
+ //newBill(1)
+ //c := []int{2,3}
+ //a,b := getUnfinishedList(c)
+ //fmt.Println(a,b)
+ os.Exit(0)
+ } else {
+ initConf()
+ }
+
+ haveone := false
+ if filename != "none" {
+ if haveone {
+ fmt.Println("Only One DB Allowed! Will ignore", filename)
+ } else {
+ haveone = true
+ dbname = filename
+ if filepath.Ext(filename) != ".db" || filepath.Ext(filename) != ".sql" {
+ fmt.Println("Please consider to use a file extension like .db or .sql \n like ~/.<name>.db")
+ }
+ }
+ } else {
+ dbname = config.Database
+ }
+
+ if !help {
+ initDB(dbname)
+ pausetask = getPauseTask()
+ getLastProject()
+ getOpenTask()
+ }
+
+ interact()
+
+ fmt.Println("Laboravi finietur...")
}
diff --git a/sqlite.go b/sqlite.go
index f59d5c5..7da7237 100644
--- a/sqlite.go
+++ b/sqlite.go
@@ -1,65 +1,65 @@
+// sqlite.go contains all database operations
package main
import (
- "database/sql"
- "fmt"
- "time"
- "os"
- //"bufio"
- "strings"
- "regexp"
- "strconv"
- "unicode/utf8"
-
- _ "github.com/mattn/go-sqlite3"
- "github.com/fatih/color"
+ "database/sql"
+ "fmt"
+ "os"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+
+ "github.com/fatih/color"
+ _ "github.com/mattn/go-sqlite3"
)
-type project struct{
- id int
- name string
- comment string
- first time.Time
- last time.Time
- finished int // id of last paid bill
- customer int
+type project struct {
+ id int
+ name string
+ comment string
+ first time.Time
+ last time.Time
+ finished int // id of last paid bill
+ customer int
}
-type task struct{
- id int
- projectid int
- start time.Time
- stop time.Time
- taskname string
- comment string
- checkout int // id of bill
+type task struct {
+ id int
+ projectid int
+ start time.Time
+ stop time.Time
+ taskname string
+ comment string
+ checkout int // id of bill
}
-type customer struct{
- id int
- company string
- name string
- address string
- satz float64
- lastbill time.Time // Last time a bill was paid
+type customer struct {
+ id int
+ company string
+ name string
+ address string
+ satz float64
+ lastbill time.Time // Last time a bill was paid
}
-type billitem struct{
- Task string
- Time string
- Hours float64
- Money float64
+type billitem struct {
+ Task string
+ Time string
+ Hours float64
+ Money float64
}
-type bill struct{
- id int
- identity string //invoice number
- timerange string
- project int
- projectname string
- date time.Time
- paid time.Time
- items []billitem
+type bill struct {
+ id int
+ identity string //invoice number
+ timerange string
+ project int
+ projectname string
+ date time.Time
+ paid time.Time
+ items []billitem
}
var db *sql.DB
@@ -68,12 +68,16 @@ var currproject project
var opentask task
var pausetask int
+// Database Operations
+
+// initDB tries to open an sqlite database of given filename
+// and if it doesnt exit create it in the propper structure.
func initDB(filename string) {
- if _, err := os.Stat(filename); os.IsNotExist(err) {
- db, err = sql.Open("sqlite3", filename)
- checkErr(err)
- fmt.Println("Creating new DB",filename)
- sqlstmt := `
+ if _, err := os.Stat(filename); os.IsNotExist(err) {
+ db, err = sql.Open("sqlite3", filename)
+ checkErr(err)
+ fmt.Println("Creating new DB", filename)
+ sqlstmt := `
CREATE TABLE projects(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(240) NOT NULL,
@@ -121,31 +125,31 @@ func initDB(filename string) {
update vars SET last = datetime('now') WHERE id = 1;
END;
`
- _, err = db.Exec(sqlstmt)
- checkErr(err)
- stmt, err := db.Prepare("INSERT INTO customers(id,company,name) values(?, ?, ?)")
- checkErr(err)
- _, err = stmt.Exec(0,"No one","Specific")
- checkErr(err)
- stmt, err = db.Prepare("INSERT INTO projects(id,name,customer,finished) values(?, ?, ?, ?)")
- checkErr(err)
- _, err = stmt.Exec(0,"None",0,0)
- checkErr(err)
- stmt, err = db.Prepare("INSERT INTO vars(pauseid,last) values(?,datetime('now'))")
- checkErr(err)
- _, err = stmt.Exec(0)
- checkErr(err)
- }else{
- db, err = sql.Open("sqlite3", filename)
- checkErr(err)
- fmt.Println("Opening DB", filename ," - Last Usage:",lastUsage())
- }
+ _, err = db.Exec(sqlstmt)
+ checkErr(err)
+ stmt, err := db.Prepare("INSERT INTO customers(id,company,name) values(?, ?, ?)")
+ checkErr(err)
+ _, err = stmt.Exec(0, "No one", "Specific")
+ checkErr(err)
+ stmt, err = db.Prepare("INSERT INTO projects(id,name,customer,finished) values(?, ?, ?, ?)")
+ checkErr(err)
+ _, err = stmt.Exec(0, "None", 0, 0)
+ checkErr(err)
+ stmt, err = db.Prepare("INSERT INTO vars(pauseid,last) values(?,datetime('now'))")
+ checkErr(err)
+ _, err = stmt.Exec(0)
+ checkErr(err)
+ } else {
+ db, err = sql.Open("sqlite3", filename)
+ checkErr(err)
+ fmt.Println("Opening DB", filename, " - Last Usage:", lastUsage())
+ }
}
func lastUsage() (out string) {
var dat time.Time
- rows,err := db.Query("SELECT last FROM vars WHERE id = 1")
- checkErr(err)
+ rows, err := db.Query("SELECT last FROM vars WHERE id = 1")
+ checkErr(err)
for rows.Next() {
err = rows.Scan(&dat)
checkErr(err)
@@ -155,8 +159,8 @@ func lastUsage() (out string) {
}
func getPauseTask() (id int) {
- rows,err := db.Query("SELECT pauseid FROM vars WHERE id = 1")
- checkErr(err)
+ rows, err := db.Query("SELECT pauseid FROM vars WHERE id = 1")
+ checkErr(err)
for rows.Next() {
err = rows.Scan(&id)
checkErr(err)
@@ -165,1304 +169,1309 @@ func getPauseTask() (id int) {
}
func setPauseTask(id int) {
- stmt, err := db.Prepare("UPDATE vars SET pauseid = ? WHERE id = 1 ")
- checkErr(err)
- _, err = stmt.Exec(id)
- checkErr(err)
+ stmt, err := db.Prepare("UPDATE vars SET pauseid = ? WHERE id = 1 ")
+ checkErr(err)
+ _, err = stmt.Exec(id)
+ checkErr(err)
pausetask = id
}
func newTaskTime(proj int, tim string) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Start Project at ",tim))
- if (opentask.id == 0) {
- timstr := "1791-09-30 19:07"
- //zone, _ := time.Now().Zone()
- if isDateTime(tim) {
- timstr = getDateTime(tim)
- //timst = timstr+" "+zone
- }else if isTime(tim) {
- currdate := time.Now().Local().Format("2006-01-02")
- timstr = currdate+" "+getTime(tim)
- //timst = timstr+" "+zone
- }else {
- fmt.Println(tim,boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM' or 'HH:MM'")
- return
- //os.Exit(0)
- }
- stmt, err := db.Prepare("INSERT INTO timetable(project, start, task, checkout) values(?, datetime(?,'utc'), ?, ?)")
- fmt.Println(timstr)
- task := getInterInput("Specify Task: ")
- checkErr(err)
- if (proj == 0) {
- _, err = stmt.Exec(currproject.id,timstr,task,0)
- }else{
- _, err = stmt.Exec(proj,timstr,task,0)
- }
- checkErr(err)
-
- fmt.Println("...new task inserted into",currproject.name,": ",task)
- getOpenTask()
- updateProject(currproject.id)
- } else {
- fmt.Println(boldRed("Another Task is already Open"))
- showOpenTask()
- }
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Start Project at ", tim))
+ if opentask.id == 0 {
+ timstr := "1791-09-30 19:07"
+ //zone, _ := time.Now().Zone()
+ if isDateTime(tim) {
+ timstr = getDateTime(tim)
+ //timst = timstr+" "+zone
+ } else if isTime(tim) {
+ currdate := time.Now().Local().Format("2006-01-02")
+ timstr = currdate + " " + getTime(tim)
+ //timst = timstr+" "+zone
+ } else {
+ fmt.Println(tim, boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM' or 'HH:MM'")
+ return
+ //os.Exit(0)
+ }
+ stmt, err := db.Prepare("INSERT INTO timetable(project, start, task, checkout) values(?, datetime(?,'utc'), ?, ?)")
+ fmt.Println(timstr)
+ task := getInterInput("Specify Task: ")
+ checkErr(err)
+ if proj == 0 {
+ _, err = stmt.Exec(currproject.id, timstr, task, 0)
+ } else {
+ _, err = stmt.Exec(proj, timstr, task, 0)
+ }
+ checkErr(err)
+
+ fmt.Println("...new task inserted into", currproject.name, ": ", task)
+ getOpenTask()
+ updateProject(currproject.id)
+ } else {
+ fmt.Println(boldRed("Another Task is already Open"))
+ showOpenTask()
+ }
}
func newTask(resume bool) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- task := ""
- if (opentask.id > 0) {
- fmt.Println(boldRed("Another Task is already Open"))
- showOpenTask()
- return
- }
- if resume {
- if pausetask == 0 {
- fmt.Println(boldRed("No Task was Paused"))
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ task := ""
+ if opentask.id > 0 {
+ fmt.Println(boldRed("Another Task is already Open"))
+ showOpenTask()
return
- }else{
- idx := []int{pausetask}
- tsks := getSelectedTasks(idx)
- fulltask := tsks[0]
- fmt.Println(boldGreen("Resuming Task ",pausetask," - ",fulltask.taskname))
- //fmt.Println()
- task = fulltask.taskname
- }
- }else{
- fmt.Println(boldGreen("Starting new Task"))
- task = getInterInput("Specify Task: ")
- }
- stmt, err := db.Prepare("INSERT INTO timetable(project, task, checkout) values(?, ?, ?)")
- checkErr(err)
- _, err = stmt.Exec(currproject.id,task,0)
- checkErr(err)
- if !resume{
- fmt.Println("...New Task inserted into",currproject.name,": ",task)
- }
- getOpenTask()
- updateProject(currproject.id)
+ }
+ if resume {
+ if pausetask == 0 {
+ fmt.Println(boldRed("No Task was Paused"))
+ return
+ } else {
+ idx := []int{pausetask}
+ tsks := getSelectedTasks(idx)
+ fulltask := tsks[0]
+ fmt.Println(boldGreen("Resuming Task ", pausetask, " - ", fulltask.taskname))
+ //fmt.Println()
+ task = fulltask.taskname
+ }
+ } else {
+ fmt.Println(boldGreen("Starting new Task"))
+ task = getInterInput("Specify Task: ")
+ }
+ stmt, err := db.Prepare("INSERT INTO timetable(project, task, checkout) values(?, ?, ?)")
+ checkErr(err)
+ _, err = stmt.Exec(currproject.id, task, 0)
+ checkErr(err)
+ if !resume {
+ fmt.Println("...New Task inserted into", currproject.name, ": ", task)
+ }
+ getOpenTask()
+ updateProject(currproject.id)
}
-func newBill(proj int) (int,string) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- //boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Creating New Bill"))
- //Show 5 recent bills
- showLastBills(5)
- invno := getInterInput("Invoice Number: ")
- stmt, err := db.Prepare("INSERT INTO bills (identity, project, date) values(?, ?, datetime('now'))")
- checkErr(err)
- answ, err := stmt.Exec(invno,proj)
- checkErr(err)
- lid,_ := answ.LastInsertId()
- fmt.Println("Bill",invno,"Created with ID",lid)
- return int(lid), invno
+func newBill(proj int) (int, string) {
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ //boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Creating New Bill"))
+ //Show 5 recent bills
+ showLastBills(5)
+ invno := getInterInput("Invoice Number: ")
+ stmt, err := db.Prepare("INSERT INTO bills (identity, project, date) values(?, ?, datetime('now'))")
+ checkErr(err)
+ answ, err := stmt.Exec(invno, proj)
+ checkErr(err)
+ lid, _ := answ.LastInsertId()
+ fmt.Println("Bill", invno, "Created with ID", lid)
+ return int(lid), invno
}
func saveBill(in bill) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- tasks,times,hours,moneys := items2strings(in.items)
- fmt.Println(boldGreen("Saving Bill"),in.id)
- stmt, err := db.Prepare("UPDATE bills SET identity = ?, timerange = ?, tasks = ?, times = ?, hours = ?, moneys = ? WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(in.identity,in.timerange,tasks,times,hours,moneys,in.id)
- checkErr(err)
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ tasks, times, hours, moneys := items2strings(in.items)
+ fmt.Println(boldGreen("Saving Bill"), in.id)
+ stmt, err := db.Prepare("UPDATE bills SET identity = ?, timerange = ?, tasks = ?, times = ?, hours = ?, moneys = ? WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(in.identity, in.timerange, tasks, times, hours, moneys, in.id)
+ checkErr(err)
}
func showLastBills(count int) {
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- cn := "all"
- if count > 0 {
- cn = fmt.Sprint(count)
- }
- fmt.Printf(boldGreen("Loading %s Bills\n"),cn)
- rows, err := db.Query("SELECT * FROM timetable")
- if count == 0 {
- rows, err = db.Query("SELECT * FROM bills ORDER BY date ASC")
- }else if count > 0 {
- rows, err = db.Query("SELECT * FROM bills ORDER BY date ASC LIMIT ?",count)
- }
- checkErr(err)
- var id,proj int
- var ident,timerange string
- var date,paid time.Time
- var taskstr,timestr,hourstr,moneystr string
- defer rows.Close()
-
- //fmt.Println("___Open Task________________")
- if count == 0 {
- fmt.Print("___All Previous Bills_______\n")
- }else{
- fmt.Printf("___Previous %v Bills________\n",count)
- }
- i := 0
- for rows.Next() {
- i++
- err = rows.Scan(&id,&ident,&timerange,&proj,&taskstr,&timestr,&hourstr,&moneystr,&paid,&date)
- checkErr(err)
- prn,_ := getProjectName(proj)
- hsum := sumFloatArray(string2FloatArray(hourstr,";"))
- msum := sumFloatArray(string2FloatArray(moneystr,";"))
- fmt.Printf(" %v:%s - %s (%v) %.1f[h]: %.2f[€] - ",id,ident,prn,date.Local().Format("2006.01.02"),hsum,msum)
- p := fmt.Sprintf("%v",paid)
- if p == "1791-09-30 19:07:00 +0000 UTC" {
- fmt.Print(boldRed("OPEN\n"))
- }else{
- fmt.Printf(boldGreen("%v\n"),paid.Local().Format("2006.01.02"))
- }
- }
- if i == 0 {
- fmt.Println(boldRed("\n NONE"))
- }
- fmt.Println(" ")
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ cn := "all"
+ if count > 0 {
+ cn = fmt.Sprint(count)
+ }
+ fmt.Printf(boldGreen("Loading %s Bills\n"), cn)
+ rows, err := db.Query("SELECT * FROM timetable")
+ if count == 0 {
+ rows, err = db.Query("SELECT * FROM bills ORDER BY date ASC")
+ } else if count > 0 {
+ rows, err = db.Query("SELECT * FROM bills ORDER BY date ASC LIMIT ?", count)
+ }
+ checkErr(err)
+ var id, proj int
+ var ident, timerange string
+ var date, paid time.Time
+ var taskstr, timestr, hourstr, moneystr string
+ defer rows.Close()
+
+ //fmt.Println("___Open Task________________")
+ if count == 0 {
+ fmt.Print("___All Previous Bills_______\n")
+ } else {
+ fmt.Printf("___Previous %v Bills________\n", count)
+ }
+ i := 0
+ for rows.Next() {
+ i++
+ err = rows.Scan(&id, &ident, &timerange, &proj, &taskstr, &timestr, &hourstr, &moneystr, &paid, &date)
+ checkErr(err)
+ prn, _ := getProjectName(proj)
+ hsum := sumFloatArray(string2FloatArray(hourstr, ";"))
+ msum := sumFloatArray(string2FloatArray(moneystr, ";"))
+ fmt.Printf(" %v:%s - %s (%v) %.1f[h]: %.2f[€] - ", id, ident, prn, date.Local().Format("2006.01.02"), hsum, msum)
+ p := fmt.Sprintf("%v", paid)
+ if p == "1791-09-30 19:07:00 +0000 UTC" {
+ fmt.Print(boldRed("OPEN\n"))
+ } else {
+ fmt.Printf(boldGreen("%v\n"), paid.Local().Format("2006.01.02"))
+ }
+ }
+ if i == 0 {
+ fmt.Println(boldRed("\n NONE"))
+ }
+ fmt.Println(" ")
}
-func loadBills(in []int) (out []bill){
- ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
- que := fmt.Sprintf("SELECT * FROM bills WHERE id IN (%s) ORDER BY project DESC",ins)
- rows,err := db.Query(que)
-
- var id,proj int
- var ident,timerange string
- var date,paid time.Time
- var taskstr,timestr,hourstr,moneystr string
-
- defer rows.Close()
- for rows.Next() {
- err = rows.Scan(&id,&ident,&timerange,&proj,&taskstr,&timestr,&hourstr,&moneystr,&paid,&date)
- checkErr(err)
- itms := strings2items(taskstr,timestr,hourstr,moneystr)
- prname,_ := getProjectName(proj)
- bi := bill{id,ident,timerange,proj,prname,date,paid,itms}
- out = append(out,bi)
- }
- return
+func loadBills(in []int) (out []bill) {
+ ins := strings.Trim(strings.Replace(fmt.Sprint(in), " ", " , ", -1), "[]")
+ que := fmt.Sprintf("SELECT * FROM bills WHERE id IN (%s) ORDER BY project DESC", ins)
+ rows, err := db.Query(que)
+
+ var id, proj int
+ var ident, timerange string
+ var date, paid time.Time
+ var taskstr, timestr, hourstr, moneystr string
+
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&id, &ident, &timerange, &proj, &taskstr, &timestr, &hourstr, &moneystr, &paid, &date)
+ checkErr(err)
+ itms := strings2items(taskstr, timestr, hourstr, moneystr)
+ prname, _ := getProjectName(proj)
+ bi := bill{id, ident, timerange, proj, prname, date, paid, itms}
+ out = append(out, bi)
+ }
+ return
}
func strings2items(tasks, times, hours, moneys string) (out []billitem) {
- ta := string2StringArray(tasks,";")
- ti := string2StringArray(times,";")
- ho := string2FloatArray(hours,";")
- mo := string2FloatArray(moneys,";")
- for i,_ := range ta{
- out = append(out,billitem{ta[i],ti[i],ho[i],mo[i]})
- }
- return
+ ta := string2StringArray(tasks, ";")
+ ti := string2StringArray(times, ";")
+ ho := string2FloatArray(hours, ";")
+ mo := string2FloatArray(moneys, ";")
+ for i, _ := range ta {
+ out = append(out, billitem{ta[i], ti[i], ho[i], mo[i]})
+ }
+ return
}
func items2strings(in []billitem) (tasks, times, hours, moneys string) {
- var tsk,tim []string
- var hrs,mny []float64
- for _,item := range in {
- tsk = append(tsk,item.Task)
- tim = append(tim,item.Time)
- hrs = append(hrs,item.Hours)
- mny = append(mny,item.Money)
- }
- tasks = stringArray2String(tsk,";")
- times = stringArray2String(tim,";")
- hours = strings.Trim(strings.Replace(fmt.Sprint(hrs)," ",";",-1),"[]")
- moneys = strings.Trim(strings.Replace(fmt.Sprint(mny)," ",";",-1),"[]")
- return
+ var tsk, tim []string
+ var hrs, mny []float64
+ for _, item := range in {
+ tsk = append(tsk, item.Task)
+ tim = append(tim, item.Time)
+ hrs = append(hrs, item.Hours)
+ mny = append(mny, item.Money)
+ }
+ tasks = stringArray2String(tsk, ";")
+ times = stringArray2String(tim, ";")
+ hours = strings.Trim(strings.Replace(fmt.Sprint(hrs), " ", ";", -1), "[]")
+ moneys = strings.Trim(strings.Replace(fmt.Sprint(mny), " ", ";", -1), "[]")
+ return
}
func closeTaskTime(tim string) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Stoping Task ",opentask.id,":",opentask.taskname))
- if opentask.id==0 {
- fmt.Println(boldRed("There is no Open Task"))
- return
- }
- //timt,err := time.Parse("2006-01-02 15:04",tim)
- timst,timstr := "1791-09-30 19:07","1791-09-30 19:07"
- zone, _ := time.Now().Zone()
- if isDateTime(tim) {
- timstr = getDateTime(tim)
- timst = timstr+" "+zone
- } else if isTime(tim) {
- timstr = time.Now().Local().Format("2006-01-02")+" "+getTime(tim)
- timst = timstr+" "+zone
- } else {
- fmt.Println(tim,boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM' or 'HH:MM'")
- return
- //os.Exit(0)
-
- }
- timt,err := time.Parse("2006-01-02 15:04 MST",timst)
- checkErr(err)
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Stoping Task ", opentask.id, ":", opentask.taskname))
+ if opentask.id == 0 {
+ fmt.Println(boldRed("There is no Open Task"))
+ return
+ }
+ //timt,err := time.Parse("2006-01-02 15:04",tim)
+ timst, timstr := "1791-09-30 19:07", "1791-09-30 19:07"
+ zone, _ := time.Now().Zone()
+ if isDateTime(tim) {
+ timstr = getDateTime(tim)
+ timst = timstr + " " + zone
+ } else if isTime(tim) {
+ timstr = time.Now().Local().Format("2006-01-02") + " " + getTime(tim)
+ timst = timstr + " " + zone
+ } else {
+ fmt.Println(tim, boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM' or 'HH:MM'")
+ return
+ //os.Exit(0)
- //fmt.Println(timst,timt,opentask.start)
- if (timt.After(opentask.start)) {
- //timstr := timt.UTC().Format("2006-01-02 15:04")
- com := ""
- if isInterSure("Do You Want to enter a Comment?"){
- com = getInterMultiInput("Comment:")
- }
- fmt.Println("...Closing Task",opentask.id,"at",timst)
- stmt, err := db.Prepare("UPDATE timetable SET stop = datetime(?,'utc'), comment = ? WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(timstr,com,opentask.id)
- checkErr(err)
- opentask.id=0
- updateProject(opentask.projectid)
- }else{
- fmt.Println(boldRed("Cannot Stop before the Beginning!"))
- }
- //fmt.Println(tim,timt)
+ }
+ timt, err := time.Parse("2006-01-02 15:04 MST", timst)
+ checkErr(err)
+
+ //fmt.Println(timst,timt,opentask.start)
+ if timt.After(opentask.start) {
+ //timstr := timt.UTC().Format("2006-01-02 15:04")
+ com := ""
+ if isInterSure("Do You Want to enter a Comment?") {
+ com = getInterMultiInput("Comment:")
+ }
+ fmt.Println("...Closing Task", opentask.id, "at", timst)
+ stmt, err := db.Prepare("UPDATE timetable SET stop = datetime(?,'utc'), comment = ? WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(timstr, com, opentask.id)
+ checkErr(err)
+ opentask.id = 0
+ updateProject(opentask.projectid)
+ } else {
+ fmt.Println(boldRed("Cannot Stop before the Beginning!"))
+ }
+ //fmt.Println(tim,timt)
}
func closeTask(loud bool) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- if loud {
- fmt.Println(boldGreen("Stoping Task ",opentask.id,":",opentask.taskname))
- }
- if opentask.id==0 {
- fmt.Println(boldRed("There is no Open Task"))
- return
- }
- if (time.Now().After(opentask.start.Local())) {
- com := ""
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
if loud {
- if isInterSure("Do You Want to enter a Comment?"){
- com = getInterMultiInput("Comment:")
+ fmt.Println(boldGreen("Stoping Task ", opentask.id, ":", opentask.taskname))
+ }
+ if opentask.id == 0 {
+ fmt.Println(boldRed("There is no Open Task"))
+ return
+ }
+ if time.Now().After(opentask.start.Local()) {
+ com := ""
+ if loud {
+ if isInterSure("Do You Want to enter a Comment?") {
+ com = getInterMultiInput("Comment:")
+ }
+ fmt.Println("...Closing Task", opentask.id)
}
- fmt.Println("...Closing Task",opentask.id)
- }
- stmt, err := db.Prepare("UPDATE timetable SET stop = datetime('now'), comment = ? WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(com,opentask.id)
- checkErr(err)
- opentask.id=0
- updateProject(opentask.projectid)
- }else{
- fmt.Println(boldRed("Cannot Stop before the Beginning!"))
- }
+ stmt, err := db.Prepare("UPDATE timetable SET stop = datetime('now'), comment = ? WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(com, opentask.id)
+ checkErr(err)
+ opentask.id = 0
+ updateProject(opentask.projectid)
+ } else {
+ fmt.Println(boldRed("Cannot Stop before the Beginning!"))
+ }
}
func checkBill(bid int) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- var custid int
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ var custid int
- if !isBill(bid) {
- fmt.Println(bid,boldRed("is not a known bill ID"))
- return
- }
+ if !isBill(bid) {
+ fmt.Println(bid, boldRed("is not a known bill ID"))
+ return
+ }
- bar := []int{bid}
- bill := loadBills(bar)
+ bar := []int{bid}
+ bill := loadBills(bar)
- if len(bill)<1 {
- return
- }else{
- pr,cu := getProjectName(bill[0].project)
- custid = getCustomerId(bill[0].project)
- //fmt.Println(bill[0])
- fmt.Println(boldGreen("Checking Bill ",bid," as Paid:\n",bill[0].identity),"\n For",cu," :",pr)
- _,_,ho,ma := items2strings(bill[0].items)
- hsum := sumFloatArray(string2FloatArray(ho,";"))
- msum := sumFloatArray(string2FloatArray(ma,";"))
- fmt.Printf(" Date: %s Hours: %.1f[h] Sum: %.2f[€]\n",bill[0].date.Local().Format("2006-01-02"),hsum,msum)
- //fmt.Println(ta)
- }
+ if len(bill) < 1 {
+ return
+ } else {
+ pr, cu := getProjectName(bill[0].project)
+ custid = getCustomerId(bill[0].project)
+ //fmt.Println(bill[0])
+ fmt.Println(boldGreen("Checking Bill ", bid, " as Paid:\n", bill[0].identity), "\n For", cu, " :", pr)
+ _, _, ho, ma := items2strings(bill[0].items)
+ hsum := sumFloatArray(string2FloatArray(ho, ";"))
+ msum := sumFloatArray(string2FloatArray(ma, ";"))
+ fmt.Printf(" Date: %s Hours: %.1f[h] Sum: %.2f[€]\n", bill[0].date.Local().Format("2006-01-02"), hsum, msum)
+ //fmt.Println(ta)
+ }
- //timst,timstr := "1791-09-30 19:07","1791-09-30 19:07"
- //zone, _ := time.Now().Zone()
- timstr := "1791-09-30 19:07"
+ //timst,timstr := "1791-09-30 19:07","1791-09-30 19:07"
+ //zone, _ := time.Now().Zone()
+ timstr := "1791-09-30 19:07"
- timin := getInterInput("Specify Date (YYYY-MM-DD): ")
+ timin := getInterInput("Specify Date (YYYY-MM-DD): ")
- if isDateTime(timin) {
- timstr = getDateTime(timin)
- }else if isDate(timin) {
- //currdate := time.Now().Local().Format("2006-01-02")
- timstr = getDate(timin)+" 12:00"
- }else {
- fmt.Println(timin,boldRed("is Not a Valid Datestring!"), "use: 'YYYY-MM-DD'")
- return
- }
- fmt.Println(boldGreen(timstr))
- stmt, err := db.Prepare("UPDATE bills SET paid = datetime(?,'utc') WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(timstr,bid)
- checkErr(err)
- stmt, err = db.Prepare("UPDATE customers SET lastbill = datetime(?,'utc') WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(timstr,custid)
- checkErr(err)
+ if isDateTime(timin) {
+ timstr = getDateTime(timin)
+ } else if isDate(timin) {
+ //currdate := time.Now().Local().Format("2006-01-02")
+ timstr = getDate(timin) + " 12:00"
+ } else {
+ fmt.Println(timin, boldRed("is Not a Valid Datestring!"), "use: 'YYYY-MM-DD'")
+ return
+ }
+ fmt.Println(boldGreen(timstr))
+ stmt, err := db.Prepare("UPDATE bills SET paid = datetime(?,'utc') WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(timstr, bid)
+ checkErr(err)
+ stmt, err = db.Prepare("UPDATE customers SET lastbill = datetime(?,'utc') WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(timstr, custid)
+ checkErr(err)
}
-func checkTasks(in []int,billid int) {
- ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
- que := fmt.Sprintf("UPDATE timetable SET checkout = ? WHERE id IN (%s)",ins)
- //rows,err := db.Query(que)
- stmt, err := db.Prepare(que)
- checkErr(err)
- _, err = stmt.Exec(billid)
- checkErr(err)
+func checkTasks(in []int, billid int) {
+ ins := strings.Trim(strings.Replace(fmt.Sprint(in), " ", " , ", -1), "[]")
+ que := fmt.Sprintf("UPDATE timetable SET checkout = ? WHERE id IN (%s)", ins)
+ //rows,err := db.Query(que)
+ stmt, err := db.Prepare(que)
+ checkErr(err)
+ _, err = stmt.Exec(billid)
+ checkErr(err)
}
func uncheckTasks(billid int) {
- //ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
- //que := fmt.Sprintf("UPDATE timetable SET checkout = ? WHERE id IN (%s)",ins)
- //rows,err := db.Query(que)
- //stmt, err := db.Prepare(que)
- stmt, err := db.Prepare("UPDATE timetable SET checkout = 0 WHERE checkout = ?")
- checkErr(err)
- _, err = stmt.Exec(billid)
- checkErr(err)
+ //ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
+ //que := fmt.Sprintf("UPDATE timetable SET checkout = ? WHERE id IN (%s)",ins)
+ //rows,err := db.Query(que)
+ //stmt, err := db.Prepare(que)
+ stmt, err := db.Prepare("UPDATE timetable SET checkout = 0 WHERE checkout = ?")
+ checkErr(err)
+ _, err = stmt.Exec(billid)
+ checkErr(err)
}
func updateProject(id int) {
- stmt, err := db.Prepare("UPDATE projects SET last = datetime('now') WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(id)
- checkErr(err)
+ stmt, err := db.Prepare("UPDATE projects SET last = datetime('now') WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(id)
+ checkErr(err)
}
func getCustomerId(id int) (cust int) {
- rows, err := db.Query("SELECT customer FROM projects WHERE id = ?",id)
- checkErr(err)
- for rows.Next() {
- err = rows.Scan(&cust)
- checkErr(err)
- }
- return
+ rows, err := db.Query("SELECT customer FROM projects WHERE id = ?", id)
+ checkErr(err)
+ for rows.Next() {
+ err = rows.Scan(&cust)
+ checkErr(err)
+ }
+ return
}
func getCustomerName(id int) (cust string) {
- rows, err := db.Query("SELECT company, name FROM customers WHERE id = ?",id)
- checkErr(err)
- var nam,com string
- for rows.Next() {
- err = rows.Scan(&com, &nam)
- checkErr(err)
- }
- cust = fmt.Sprintf("%s: %s",com,nam)
- cust = fmt.Sprintf("%s",com)
- return
+ rows, err := db.Query("SELECT company, name FROM customers WHERE id = ?", id)
+ checkErr(err)
+ var nam, com string
+ for rows.Next() {
+ err = rows.Scan(&com, &nam)
+ checkErr(err)
+ }
+ cust = fmt.Sprintf("%s: %s", com, nam)
+ cust = fmt.Sprintf("%s", com)
+ return
}
-func getProjectName(id int) (pro string,cust string) {
- rows, err := db.Query("SELECT name, customer FROM projects WHERE id = ?",id)
- checkErr(err)
- //rows, err := stmt.Exec(id)
- //checkErr(err)
- cid := 0
- for rows.Next() {
- err = rows.Scan(&pro, &cid)
- checkErr(err)
- }
- cust = getCustomerName(cid)
- return
+func getProjectName(id int) (pro string, cust string) {
+ rows, err := db.Query("SELECT name, customer FROM projects WHERE id = ?", id)
+ checkErr(err)
+ //rows, err := stmt.Exec(id)
+ //checkErr(err)
+ cid := 0
+ for rows.Next() {
+ err = rows.Scan(&pro, &cid)
+ checkErr(err)
+ }
+ cust = getCustomerName(cid)
+ return
}
-func checkCustomerProjects(in []int) (multicust,multiproj bool, projid []int) {
- ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
- que := fmt.Sprintf("SELECT project FROM timetable WHERE id IN (%s) ORDER BY project DESC",ins)
- rows,err := db.Query(que)
- prid, cuid, altprid, altcuid := 0,0,0,0
- multicust, multiproj = false,false
-
- defer rows.Close()
- for rows.Next() {
- err = rows.Scan(&prid)
- checkErr(err)
- if altprid == 0{
- altprid = prid
- projid = append(projid,prid)
- }else{
- if altprid != prid {
- multiproj = true
- altprid = prid
- projid = append(projid,prid)
- }
- }
-
- crows, err := db.Query("SELECT customer FROM projects WHERE id = ?",prid)
- checkErr(err)
- for crows.Next() {
- err = crows.Scan(&cuid)
- checkErr(err)
- if altcuid == 0{
- altcuid = cuid
- }else{
- if altcuid != cuid {
- multicust = true
- altcuid = cuid
- }
- }
- }
- }
- return
+func checkCustomerProjects(in []int) (multicust, multiproj bool, projid []int) {
+ ins := strings.Trim(strings.Replace(fmt.Sprint(in), " ", " , ", -1), "[]")
+ que := fmt.Sprintf("SELECT project FROM timetable WHERE id IN (%s) ORDER BY project DESC", ins)
+ rows, err := db.Query(que)
+ prid, cuid, altprid, altcuid := 0, 0, 0, 0
+ multicust, multiproj = false, false
+
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&prid)
+ checkErr(err)
+ if altprid == 0 {
+ altprid = prid
+ projid = append(projid, prid)
+ } else {
+ if altprid != prid {
+ multiproj = true
+ altprid = prid
+ projid = append(projid, prid)
+ }
+ }
+
+ crows, err := db.Query("SELECT customer FROM projects WHERE id = ?", prid)
+ checkErr(err)
+ for crows.Next() {
+ err = crows.Scan(&cuid)
+ checkErr(err)
+ if altcuid == 0 {
+ altcuid = cuid
+ } else {
+ if altcuid != cuid {
+ multicust = true
+ altcuid = cuid
+ }
+ }
+ }
+ }
+ return
}
-func getProject(id int) (outpr project,outcu customer) {
- rows, err := db.Query("SELECT * FROM projects WHERE id = ?",id)
- checkErr(err)
- var pid,customer,finished int
- var first,last time.Time
- var name,comm string
-
- for rows.Next() {
- err = rows.Scan(&pid, &name, &comm, &first, &last, &finished, &customer)
- checkErr(err)
- outpr.id = pid
- outpr.name = name
- outpr.comment = comm
- outpr.first = first
- outpr.last = last
- outpr.finished = finished
- outpr.customer = customer
- }
- row, err := db.Query("SELECT * FROM customers WHERE id = ?",customer)
- checkErr(err)
- var cid int
- var comp,cuname,addy string
- var satz float64
- var lastb time.Time
-
- for row.Next() {
- err = row.Scan(&cid, &comp, &cuname, &addy, &satz, &lastb)
- checkErr(err)
- outcu.id = cid
- outcu.company = comp
- outcu.name = cuname
- outcu.address = addy
- outcu.satz = satz
- outcu.lastbill = lastb
- }
- return
+func getProject(id int) (outpr project, outcu customer) {
+ rows, err := db.Query("SELECT * FROM projects WHERE id = ?", id)
+ checkErr(err)
+ var pid, customer, finished int
+ var first, last time.Time
+ var name, comm string
+
+ for rows.Next() {
+ err = rows.Scan(&pid, &name, &comm, &first, &last, &finished, &customer)
+ checkErr(err)
+ outpr.id = pid
+ outpr.name = name
+ outpr.comment = comm
+ outpr.first = first
+ outpr.last = last
+ outpr.finished = finished
+ outpr.customer = customer
+ }
+ row, err := db.Query("SELECT * FROM customers WHERE id = ?", customer)
+ checkErr(err)
+ var cid int
+ var comp, cuname, addy string
+ var satz float64
+ var lastb time.Time
+
+ for row.Next() {
+ err = row.Scan(&cid, &comp, &cuname, &addy, &satz, &lastb)
+ checkErr(err)
+ outcu.id = cid
+ outcu.company = comp
+ outcu.name = cuname
+ outcu.address = addy
+ outcu.satz = satz
+ outcu.lastbill = lastb
+ }
+ return
}
func getSelectedTasks(in []int) (outtask []task) {
- ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
- que := fmt.Sprintf("SELECT * FROM timetable WHERE id IN (%s)",ins)
- rows,err := db.Query(que)
- checkErr(err)
+ ins := strings.Trim(strings.Replace(fmt.Sprint(in), " ", " , ", -1), "[]")
+ que := fmt.Sprintf("SELECT * FROM timetable WHERE id IN (%s)", ins)
+ rows, err := db.Query(que)
+ checkErr(err)
- var id,project,checkout int
- var start,stop time.Time
- var tsk,com string
+ var id, project, checkout int
+ var start, stop time.Time
+ var tsk, com string
- defer rows.Close()
- for rows.Next() {
- err = rows.Scan(&id,&project,&start,&stop,&tsk,&com,&checkout)
- outtask = append(outtask,task{id,project,start,stop,tsk,com,checkout})
- }
- return
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&id, &project, &start, &stop, &tsk, &com, &checkout)
+ outtask = append(outtask, task{id, project, start, stop, tsk, com, checkout})
+ }
+ return
}
//Return sum of Hours and Dateranges
func analyzeTasks(in []task) (count int, hours float64, duration string) {
- var lstart,hstop time.Time
- for i,t := range in {
- if i==0 {
- lstart=t.start
- hstop=t.stop
- }
- count++
- dur := float64(t.stop.Sub(t.start))/(1000000000*60*60)
- hours=hours+dur
- if lstart.After(t.start){
- lstart=t.start
- }
- if hstop.Before(t.stop){
- hstop=t.stop
- }
- //txt := fmt.Sprintf("%s - (%v) - %.2f h",task, durstr, dur)
- }
- duration = fmt.Sprintf("%v - %v",lstart.Local().Format("01.02."),hstop.Local().Format("01.02.2006"))
- //duration = fmt.Sprintf("%v - %v",lstart.Local().Format("01.02.2006"),hstop.Local().Format("01.02.2006"))
- return
+ var lstart, hstop time.Time
+ for i, t := range in {
+ if i == 0 {
+ lstart = t.start
+ hstop = t.stop
+ }
+ count++
+ dur := float64(t.stop.Sub(t.start)) / (1000000000 * 60 * 60)
+ hours = hours + dur
+ if lstart.After(t.start) {
+ lstart = t.start
+ }
+ if hstop.Before(t.stop) {
+ hstop = t.stop
+ }
+ //txt := fmt.Sprintf("%s - (%v) - %.2f h",task, durstr, dur)
+ }
+ duration = fmt.Sprintf("%v - %v", lstart.Local().Format("01.02."), hstop.Local().Format("01.02.2006"))
+ //duration = fmt.Sprintf("%v - %v",lstart.Local().Format("01.02.2006"),hstop.Local().Format("01.02.2006"))
+ return
}
-func getProjectList(in []int) ([]int,[]string) {
- var outids []int
- var outstr []string
+func getProjectList(in []int) ([]int, []string) {
+ var outids []int
+ var outstr []string
- ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
- que := fmt.Sprintf("SELECT id, name FROM projects WHERE id IN (%s) ORDER BY last DESC",ins)
- rows,err := db.Query(que)
- checkErr(err)
+ ins := strings.Trim(strings.Replace(fmt.Sprint(in), " ", " , ", -1), "[]")
+ que := fmt.Sprintf("SELECT id, name FROM projects WHERE id IN (%s) ORDER BY last DESC", ins)
+ rows, err := db.Query(que)
+ checkErr(err)
- var id int
- var name string
+ var id int
+ var name string
- defer rows.Close()
- for rows.Next() {
- err = rows.Scan(&id, &name)
- checkErr(err)
- outids = append(outids,id)
- outstr = append(outstr,name)
- }
- return outids,outstr
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&id, &name)
+ checkErr(err)
+ outids = append(outids, id)
+ outstr = append(outstr, name)
+ }
+ return outids, outstr
}
-func getTaskList(in []int,showcust bool) ([]int, []string) {
- var outids []int
- var outstr []string
- lastpr := 0
- pre := ""
- prelen := 0
- ins := strings.Trim(strings.Replace(fmt.Sprint(in)," "," , ",-1),"[]")
- que := fmt.Sprintf("SELECT id, project, start, stop, task FROM timetable WHERE id IN (%s) ORDER BY project DESC, stop DESC",ins)
- rows,err := db.Query(que)
- checkErr(err)
- //rows,err := db.Query("SELECT id, project, start, stop, task FROM timetable WHERE id IN (?) ORDER BY project DESC, stop DESC",ins)
- //rows,err := db.Query("SELECT id, project, start, stop, task FROM timetable WHERE stop != '1791-09-30 19:07' AND checkout = 0 AND id IN ? ORDER BY project DESC, stop DESC",in)
- if (len(in)==1 && in[0]==0){
- rows,err = db.Query("SELECT id, project, start, stop, task FROM timetable WHERE stop != '1791-09-30 19:07' AND checkout = 0 ORDER BY project DESC, stop DESC")
- }//else{
- // rows,err = db.Query("SELECT id, project, start, stop, task FROM timetable WHERE stop != '1791-09-30 19:07' AND checkout = 0 AND id IN ? ORDER BY project DESC, stop DESC",in)
- //}
- var id,project int
- var task string
- var start,stop time.Time
-
- defer rows.Close()
- for rows.Next() {
- err = rows.Scan(&id, &project, &start, &stop, &task)
- checkErr(err)
- if project != lastpr {
- pr,cu := getProjectName(project)
- if showcust {
- pre =fmt.Sprintf("%v| %v: ",cu,pr)
- }else{
- pre =fmt.Sprintf("%v: ",pr)
- }
- prelen = utf8.RuneCountInString(pre)
- lastpr = project
- //outstr[len(outstr)-1]=fmt.Sprintf("%s\n%s - %s",outstr[len(outstr)-1],cu,pr)
- }else{
- pre = strings.Repeat(" ", prelen)
- }
- dur := float64(stop.Sub(start))/(1000000000*60*60)
- durstr := fmt.Sprintf("%v - %v",start.Local().Format("Mon Jan _2 2006 15:04"),stop.Local().Format("15:04"))
- txt := fmt.Sprintf("%s - (%v) - %.2f h",task, durstr, dur)
-
- outids = append(outids,id)
- outstr = append(outstr,fmt.Sprintf("%s%s",pre,txt))
- }
- return outids,outstr
-}
-func getProjectIds() ([]int) {
- var ids []int
- rows,err := db.Query("SELECT id FROM projects WHERE id != 0")// ORDER BY id DESC")
- checkErr(err)
- var id int
+func getTaskList(in []int, showcust bool) ([]int, []string) {
+ var outids []int
+ var outstr []string
+ lastpr := 0
+ pre := ""
+ prelen := 0
+ ins := strings.Trim(strings.Replace(fmt.Sprint(in), " ", " , ", -1), "[]")
+ que := fmt.Sprintf("SELECT id, project, start, stop, task FROM timetable WHERE id IN (%s) ORDER BY project DESC, stop DESC", ins)
+ rows, err := db.Query(que)
+ checkErr(err)
+ //rows,err := db.Query("SELECT id, project, start, stop, task FROM timetable WHERE id IN (?) ORDER BY project DESC, stop DESC",ins)
+ //rows,err := db.Query("SELECT id, project, start, stop, task FROM timetable WHERE stop != '1791-09-30 19:07' AND checkout = 0 AND id IN ? ORDER BY project DESC, stop DESC",in)
+ if len(in) == 1 && in[0] == 0 {
+ rows, err = db.Query("SELECT id, project, start, stop, task FROM timetable WHERE stop != '1791-09-30 19:07' AND checkout = 0 ORDER BY project DESC, stop DESC")
+ } //else{
+ // rows,err = db.Query("SELECT id, project, start, stop, task FROM timetable WHERE stop != '1791-09-30 19:07' AND checkout = 0 AND id IN ? ORDER BY project DESC, stop DESC",in)
+ //}
+ var id, project int
+ var task string
+ var start, stop time.Time
+
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&id, &project, &start, &stop, &task)
+ checkErr(err)
+ if project != lastpr {
+ pr, cu := getProjectName(project)
+ if showcust {
+ pre = fmt.Sprintf("%v| %v: ", cu, pr)
+ } else {
+ pre = fmt.Sprintf("%v: ", pr)
+ }
+ prelen = utf8.RuneCountInString(pre)
+ lastpr = project
+ //outstr[len(outstr)-1]=fmt.Sprintf("%s\n%s - %s",outstr[len(outstr)-1],cu,pr)
+ } else {
+ pre = strings.Repeat(" ", prelen)
+ }
+ dur := float64(stop.Sub(start)) / (1000000000 * 60 * 60)
+ durstr := fmt.Sprintf("%v - %v", start.Local().Format("Mon Jan _2 2006 15:04"), stop.Local().Format("15:04"))
+ txt := fmt.Sprintf("%s - (%v) - %.2f h", task, durstr, dur)
- defer rows.Close()
- for rows.Next() {
- err = rows.Scan(&id)
- checkErr(err)
- ids = append(ids,id)
- }
- return ids
+ outids = append(outids, id)
+ outstr = append(outstr, fmt.Sprintf("%s%s", pre, txt))
+ }
+ return outids, outstr
}
+func getProjectIds() []int {
+ var ids []int
+ rows, err := db.Query("SELECT id FROM projects WHERE id != 0") // ORDER BY id DESC")
+ checkErr(err)
+ var id int
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&id)
+ checkErr(err)
+ ids = append(ids, id)
+ }
+ return ids
+}
-func getTaskIds() ([]int) {
- var ids []int
- rows,err := db.Query("SELECT id FROM timetable WHERE stop != '1791-09-30 19:07'")// ORDER BY id DESC")
- checkErr(err)
- var id int
+func getTaskIds() []int {
+ var ids []int
+ rows, err := db.Query("SELECT id FROM timetable WHERE stop != '1791-09-30 19:07'") // ORDER BY id DESC")
+ checkErr(err)
+ var id int
- defer rows.Close()
- for rows.Next() {
- err = rows.Scan(&id)
- checkErr(err)
- ids = append(ids,id)
- }
- return ids
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&id)
+ checkErr(err)
+ ids = append(ids, id)
+ }
+ return ids
}
func getOpenTask() {
- rows,err := db.Query("SELECT id, project, start, task, checkout FROM timetable WHERE stop = '1791-09-30 19:07'")
- checkErr(err)
- var id,project,checkout int
- var task string
- var start time.Time
-
- defer rows.Close()
- for rows.Next() {
- err = rows.Scan(&id, &project, &start , &task, &checkout)
- checkErr(err)
- //fmt.Println(id, "Open Task:", task, project, start)
- }
- //rows.Close() //good habit to close
- opentask.id = id
- opentask.projectid = project
- opentask.start = start
- opentask.taskname = task
- opentask.checkout = checkout
- //opentask.checkout = checkout != 0
+ rows, err := db.Query("SELECT id, project, start, task, checkout FROM timetable WHERE stop = '1791-09-30 19:07'")
+ checkErr(err)
+ var id, project, checkout int
+ var task string
+ var start time.Time
+
+ defer rows.Close()
+ for rows.Next() {
+ err = rows.Scan(&id, &project, &start, &task, &checkout)
+ checkErr(err)
+ //fmt.Println(id, "Open Task:", task, project, start)
+ }
+ //rows.Close() //good habit to close
+ opentask.id = id
+ opentask.projectid = project
+ opentask.start = start
+ opentask.taskname = task
+ opentask.checkout = checkout
+ //opentask.checkout = checkout != 0
}
func showOpenTask() {
- if (opentask.id==0) {
- if pausetask > 0 {
- fmt.Printf ("___Task %v Paused___________\n",pausetask)
- }else{
- fmt.Println("___No Open Tasks____________")
+ if opentask.id == 0 {
+ if pausetask > 0 {
+ fmt.Printf("___Task %v Paused___________\n", pausetask)
+ } else {
+ fmt.Println("___No Open Tasks____________")
+ }
+ } else {
+ fmt.Println("___Open Task________________")
+ dur := float64(time.Now().Sub(opentask.start)) / (1000000000 * 60 * 60)
+ fmt.Printf(" %v: %v - (%v) - %.2f h\n", opentask.id, opentask.taskname, opentask.start.Local().Format("Mon Jan _2 2006 15:04"), dur)
+ //fmt.Println(opentask.id,":", opentask.taskname,"-", opentask.start.Local().Format("Mon Jan _2 2006 15:04"),dur,"h")
}
- } else {
- fmt.Println("___Open Task________________")
- dur := float64(time.Now().Sub(opentask.start))/(1000000000*60*60)
- fmt.Printf(" %v: %v - (%v) - %.2f h\n",opentask.id, opentask.taskname, opentask.start.Local().Format("Mon Jan _2 2006 15:04"),dur)
- //fmt.Println(opentask.id,":", opentask.taskname,"-", opentask.start.Local().Format("Mon Jan _2 2006 15:04"),dur,"h")
- }
}
func showLastProject() {
- fmt.Println("___Last Project_____________")
- fmt.Println(currproject.id,":", currproject.name,"- Started:",currproject.first.Local().Format("Mon _2 Jan 2006"))
- fmt.Println(" Last Changes",currproject.last.Local().Format("2006 Mon Jan _2 15:04"))
+ fmt.Println("___Last Project_____________")
+ fmt.Println(currproject.id, ":", currproject.name, "- Started:", currproject.first.Local().Format("Mon _2 Jan 2006"))
+ fmt.Println(" Last Changes", currproject.last.Local().Format("2006 Mon Jan _2 15:04"))
}
func addCustomer() {
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Adding new Customer"))
- com := getInterInput("Enter Customer Company: ")
- nam := getInterInput("Enter Customer Name: ")
- add := getInterInput("Enter Address (separate lines by ; [Street;Zip;City;Country]): ")
- sat := 0.0
- for {
- satstr := getInterInput("Hourly Rate: ")
- sat,err = strconv.ParseFloat(satstr,64)
- //checkErr(err)
- if err != nil {
- fmt.Println(satstr,boldRed("can not be Parsed as a Float."), "Try a shape of X.X")
- }else{break}
- }
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Adding new Customer"))
+ com := getInterInput("Enter Customer Company: ")
+ nam := getInterInput("Enter Customer Name: ")
+ add := getInterInput("Enter Address (separate lines by ; [Street;Zip;City;Country]): ")
+ sat := 0.0
+ for {
+ satstr := getInterInput("Hourly Rate: ")
+ sat, err = strconv.ParseFloat(satstr, 64)
+ //checkErr(err)
+ if err != nil {
+ fmt.Println(satstr, boldRed("can not be Parsed as a Float."), "Try a shape of X.X")
+ } else {
+ break
+ }
+ }
- stmt, err := db.Prepare("INSERT INTO customers(company, name, address, satz) values(?, ?, ?, ?)")
- checkErr(err)
- _, err = stmt.Exec(com,nam,add,sat)
- checkErr(err)
- fmt.Println(boldGreen(" Customer Successfully Added:"),com ,nam, add, sat)
+ stmt, err := db.Prepare("INSERT INTO customers(company, name, address, satz) values(?, ?, ?, ?)")
+ checkErr(err)
+ _, err = stmt.Exec(com, nam, add, sat)
+ checkErr(err)
+ fmt.Println(boldGreen(" Customer Successfully Added:"), com, nam, add, sat)
}
func newProject() {
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- if (opentask.id > 0) {
- fmt.Println(boldRed("There is an Open Task"))
- showOpenTask()
- return
- }
- if pausetask > 0 {
- fmt.Println(boldRed("Task ",pausetask," pause status removed"))
- setPauseTask(0)
- }
- fmt.Println(boldGreen("Creating new Project"))
- nam := getInterInput("Enter Project Name: ")
- icust := 0
- allCustomers()
- for{
- cust := getInterInput("Enter Customer id: ")
- icust,err = strconv.Atoi(cust)
- if (err == nil && (isCustomer(icust) || icust == 0)) {
- break
- } else {
- fmt.Println(cust,boldRed("is an invalid ID or Not a known Customer"))
- }
- }
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ if opentask.id > 0 {
+ fmt.Println(boldRed("There is an Open Task"))
+ showOpenTask()
+ return
+ }
+ if pausetask > 0 {
+ fmt.Println(boldRed("Task ", pausetask, " pause status removed"))
+ setPauseTask(0)
+ }
+ fmt.Println(boldGreen("Creating new Project"))
+ nam := getInterInput("Enter Project Name: ")
+ icust := 0
+ allCustomers()
+ for {
+ cust := getInterInput("Enter Customer id: ")
+ icust, err = strconv.Atoi(cust)
+ if err == nil && (isCustomer(icust) || icust == 0) {
+ break
+ } else {
+ fmt.Println(cust, boldRed("is an invalid ID or Not a known Customer"))
+ }
+ }
comm := ""
- if isInterSure("Do you want to Comment the Project?"){
+ if isInterSure("Do you want to Comment the Project?") {
comm = getInterMultiInput("New Comment: ")
- }
+ }
stmt, err := db.Prepare("INSERT INTO projects(name, comment, finished, customer) values(?, ?, ?, ?)")
- checkErr(err)
- _, err = stmt.Exec(nam,comm,0,icust)
- checkErr(err)
- fmt.Println(" Project Created:",nam)
- getLastProject()
+ checkErr(err)
+ _, err = stmt.Exec(nam, comm, 0, icust)
+ checkErr(err)
+ fmt.Println(" Project Created:", nam)
+ getLastProject()
}
func getClosedTasks(num int) {
- rows,err := db.Query("SELECT * FROM timetable WHERE stop != '1791-09-30 19:07' ORDER BY datetime(start)",currproject.id)
- checkErr(err)
- if num > 0 {
- rows,err = db.Query("SELECT * FROM timetable WHERE project = $1 AND checkout > 0 AND stop != '1791-09-30 19:07'ORDER BY datetime(start) DESC LIMIT $2",currproject.id,num)
- checkErr(err)
- } else {
- rows,err = db.Query("SELECT * FROM timetable WHERE project = $1 AND checkout > 0 AND stop != '1791-09-30 19:07'ORDER BY datetime(start)",currproject.id)
- checkErr(err)
- }
- var id, proj,check int
- var sta,sto time.Time
- var tas,com string
- var sum, dur float64 = 0.0, 0.0
- checkErr(err)
- first := true
- //if err != nil && err != sql.ErrNoRows {
- // fmt.Println("___Billed Tasks_______________")
- //}
- for rows.Next() {
- if first {
- fmt.Println("___Billed Tasks_______________")
- first = false
- }
- err = rows.Scan(&id, &proj, &sta, &sto, &tas, &check)
- checkErr(err)
- dur = float64(sto.Sub(sta))/(1000000000*60*60)
- fmt.Printf("%v: %v (%v-%v) - %.2f h\n",id,tas,sta.Local().Format("2006 Mon Jan _2 15:04"),sto.Local().Format("15:04"),dur)
- //fmt.Println(id,tas,sta.Local().Format("2006 Mon Jan _2 15:04"),sto.Local().Format("15:04"),dur,"h")
- sum += dur
- }
- if !first{
- fmt.Println("____________________________")
- fmt.Printf("Billed: %.2f h\n",sum)
- }
- rows.Close()
+ rows, err := db.Query("SELECT * FROM timetable WHERE stop != '1791-09-30 19:07' ORDER BY datetime(start)", currproject.id)
+ checkErr(err)
+ if num > 0 {
+ rows, err = db.Query("SELECT * FROM timetable WHERE project = $1 AND checkout > 0 AND stop != '1791-09-30 19:07'ORDER BY datetime(start) DESC LIMIT $2", currproject.id, num)
+ checkErr(err)
+ } else {
+ rows, err = db.Query("SELECT * FROM timetable WHERE project = $1 AND checkout > 0 AND stop != '1791-09-30 19:07'ORDER BY datetime(start)", currproject.id)
+ checkErr(err)
+ }
+ var id, proj, check int
+ var sta, sto time.Time
+ var tas, com string
+ var sum, dur float64 = 0.0, 0.0
+ checkErr(err)
+ first := true
+ //if err != nil && err != sql.ErrNoRows {
+ // fmt.Println("___Billed Tasks_______________")
+ //}
+ for rows.Next() {
+ if first {
+ fmt.Println("___Billed Tasks_______________")
+ first = false
+ }
+ err = rows.Scan(&id, &proj, &sta, &sto, &tas, &check)
+ checkErr(err)
+ dur = float64(sto.Sub(sta)) / (1000000000 * 60 * 60)
+ fmt.Printf("%v: %v (%v-%v) - %.2f h\n", id, tas, sta.Local().Format("2006 Mon Jan _2 15:04"), sto.Local().Format("15:04"), dur)
+ //fmt.Println(id,tas,sta.Local().Format("2006 Mon Jan _2 15:04"),sto.Local().Format("15:04"),dur,"h")
+ sum += dur
+ }
+ if !first {
+ fmt.Println("____________________________")
+ fmt.Printf("Billed: %.2f h\n", sum)
+ }
+ rows.Close()
- if num > 0 {
- rows,err = db.Query("SELECT * FROM timetable WHERE project = $1 AND checkout = 0 AND stop != '1791-09-30 19:07'ORDER BY datetime(start) DESC LIMIT $2",currproject.id,num)
- checkErr(err)
- } else {
- rows,err = db.Query("SELECT * FROM timetable WHERE project = $1 AND checkout = 0 AND stop != '1791-09-30 19:07'ORDER BY datetime(start)",currproject.id)
- checkErr(err)
- }
- sum2 := 0.0
- first = true
- //if err != nil && err != sql.ErrNoRows{
- // fmt.Println("___Past Tasks_______________")
- //}
- for rows.Next() {
- if first {
- fmt.Println("___Past Tasks_______________")
- first = false
- }
- err = rows.Scan(&id, &proj, &sta, &sto, &tas, &com, &check)
- checkErr(err)
- dur = float64(sto.Sub(sta))/(1000000000*60*60)
- fmt.Printf("%v: %v (%v-%v) - %.2f h\n",id,tas,sta.Local().Format("2006 Mon Jan _2 15:04"),sto.Local().Format("15:04"),dur)
- //fmt.Println(id,tas,sta.Local().Format("2006 Mon Jan _2 15:04"),sto.Local().Format("15:04"),dur,"h")
- sum2 += dur
- }
- //if err != nil && err != sql.ErrNoRows{
- if !first{
- fmt.Println("____________________________")
- fmt.Printf("Unbilled: %.2f[h] Total: %.2f[h]\n",sum2,sum+sum2)
- }
- rows.Close()
+ if num > 0 {
+ rows, err = db.Query("SELECT * FROM timetable WHERE project = $1 AND checkout = 0 AND stop != '1791-09-30 19:07'ORDER BY datetime(start) DESC LIMIT $2", currproject.id, num)
+ checkErr(err)
+ } else {
+ rows, err = db.Query("SELECT * FROM timetable WHERE project = $1 AND checkout = 0 AND stop != '1791-09-30 19:07'ORDER BY datetime(start)", currproject.id)
+ checkErr(err)
+ }
+ sum2 := 0.0
+ first = true
+ //if err != nil && err != sql.ErrNoRows{
+ // fmt.Println("___Past Tasks_______________")
+ //}
+ for rows.Next() {
+ if first {
+ fmt.Println("___Past Tasks_______________")
+ first = false
+ }
+ err = rows.Scan(&id, &proj, &sta, &sto, &tas, &com, &check)
+ checkErr(err)
+ dur = float64(sto.Sub(sta)) / (1000000000 * 60 * 60)
+ fmt.Printf("%v: %v (%v-%v) - %.2f h\n", id, tas, sta.Local().Format("2006 Mon Jan _2 15:04"), sto.Local().Format("15:04"), dur)
+ //fmt.Println(id,tas,sta.Local().Format("2006 Mon Jan _2 15:04"),sto.Local().Format("15:04"),dur,"h")
+ sum2 += dur
+ }
+ //if err != nil && err != sql.ErrNoRows{
+ if !first {
+ fmt.Println("____________________________")
+ fmt.Printf("Unbilled: %.2f[h] Total: %.2f[h]\n", sum2, sum+sum2)
+ }
+ rows.Close()
}
func getLastProject() {
- rows,err := db.Query("SELECT * FROM projects")
- checkErr(err)
+ rows, err := db.Query("SELECT * FROM projects")
+ checkErr(err)
- var uid,nuid int
- var prname,nprname,prcom,nprcom string
- var first,nfirst time.Time
- var last,nlast time.Time
- var finish,nfinish int
- var custom,ncustom int
-
- for rows.Next() {
- err = rows.Scan(&uid, &prname,&prcom, &first, &last, &finish, &custom)
- checkErr(err)
- if (last.After(nlast)){
- nuid=uid
- nprname=prname
- nprcom=prcom
- nfirst=first
- nlast=last
- nfinish=finish
- ncustom=custom
- }
- }
- rows.Close() //good habit to close
-
- currproject.id = nuid
- currproject.name = nprname
- currproject.comment = nprcom
- currproject.first = nfirst
- currproject.last = nlast
- currproject.finished = nfinish
- //currproject.finish = nfinish != 0
- currproject.customer = ncustom
+ var uid, nuid int
+ var prname, nprname, prcom, nprcom string
+ var first, nfirst time.Time
+ var last, nlast time.Time
+ var finish, nfinish int
+ var custom, ncustom int
+
+ for rows.Next() {
+ err = rows.Scan(&uid, &prname, &prcom, &first, &last, &finish, &custom)
+ checkErr(err)
+ if last.After(nlast) {
+ nuid = uid
+ nprname = prname
+ nprcom = prcom
+ nfirst = first
+ nlast = last
+ nfinish = finish
+ ncustom = custom
+ }
+ }
+ rows.Close() //good habit to close
+
+ currproject.id = nuid
+ currproject.name = nprname
+ currproject.comment = nprcom
+ currproject.first = nfirst
+ currproject.last = nlast
+ currproject.finished = nfinish
+ //currproject.finish = nfinish != 0
+ currproject.customer = ncustom
}
-func setProject (nid int) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- if (opentask.id > 0) {
- fmt.Println(boldRed("There is an Open Task"))
- showOpenTask()
- return
- }
- if pausetask > 0 {
- fmt.Println(boldRed("Task ",pausetask," pause status removed"))
- setPauseTask(0)
- }
- if isProject(nid){
- fmt.Println(boldGreen("Opening Project ",nid))
- }else{
- fmt.Println(boldRed("There is no Project"),nid)
- return
- }
+func setProject(nid int) {
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ if opentask.id > 0 {
+ fmt.Println(boldRed("There is an Open Task"))
+ showOpenTask()
+ return
+ }
+ if pausetask > 0 {
+ fmt.Println(boldRed("Task ", pausetask, " pause status removed"))
+ setPauseTask(0)
+ }
+ if isProject(nid) {
+ fmt.Println(boldGreen("Opening Project ", nid))
+ } else {
+ fmt.Println(boldRed("There is no Project"), nid)
+ return
+ }
+
+ rows, err := db.Query("SELECT * FROM projects WHERE id = $1", nid)
+ checkErr(err)
+
+ var uid int
+ var prname, comm string
+ var first time.Time
+ var last time.Time
+ var finish int
+ var custo int
- rows,err := db.Query("SELECT * FROM projects WHERE id = $1",nid)
- checkErr(err)
-
- var uid int
- var prname,comm string
- var first time.Time
- var last time.Time
- var finish int
- var custo int
-
- for rows.Next() {
- err = rows.Scan(&uid, &prname, &comm, &first, &last, &finish, &custo)
- checkErr(err)
- }
- rows.Close() //good habit to close
- currproject.id = uid
- currproject.name = prname
+ for rows.Next() {
+ err = rows.Scan(&uid, &prname, &comm, &first, &last, &finish, &custo)
+ checkErr(err)
+ }
+ rows.Close() //good habit to close
+ currproject.id = uid
+ currproject.name = prname
currproject.comment = comm
- currproject.first = first
- currproject.last = last
- currproject.finished = finish
- //currproject.finish = finish != 0
- currproject.customer = custo
- updateProject(uid)
+ currproject.first = first
+ currproject.last = last
+ currproject.finished = finish
+ //currproject.finish = finish != 0
+ currproject.customer = custo
+ updateProject(uid)
}
func getCustomerList() (outint []int, outstr []string) {
- rows,err := db.Query("SELECT id, company, name FROM customers")
- checkErr(err)
- var id int
- var comp string
- var name string
- for rows.Next() {
- err = rows.Scan(&id, &comp, &name)
- checkErr(err)
- st := fmt.Sprintf("%s: %s",comp,name)
- outint = append(outint,id)
- outstr = append(outstr, st)
- }
- return
+ rows, err := db.Query("SELECT id, company, name FROM customers")
+ checkErr(err)
+ var id int
+ var comp string
+ var name string
+ for rows.Next() {
+ err = rows.Scan(&id, &comp, &name)
+ checkErr(err)
+ st := fmt.Sprintf("%s: %s", comp, name)
+ outint = append(outint, id)
+ outstr = append(outstr, st)
+ }
+ return
}
func allCustomers() {
- rows,err := db.Query("SELECT * FROM customers")
- //rows,err := db.Query("SELECT (id, company, name, address, satz, lastbill) FROM customers")
- checkErr(err)
-
- var uid int
- var comp string
- var name string
- var addr string
- var satz float64
- var last time.Time
-
- fmt.Println("___All Customers________________")
- for rows.Next() {
- err = rows.Scan(&uid, &comp, &name, &addr, &satz, &last)
- checkErr(err)
- lstr := last.Local().Format("2006-01-02 15:04 MST")
- if lstr == "1791-09-30 20:12 LMT"{
- lstr = "Never"
- }
- fmt.Printf(" %v:%s: %s, Rate: %.2f[€/h] , Last Paid Bill: %s\n",uid,comp,name,satz,lstr)
- }
+ rows, err := db.Query("SELECT * FROM customers")
+ //rows,err := db.Query("SELECT (id, company, name, address, satz, lastbill) FROM customers")
+ checkErr(err)
+
+ var uid int
+ var comp string
+ var name string
+ var addr string
+ var satz float64
+ var last time.Time
+
+ fmt.Println("___All Customers________________")
+ for rows.Next() {
+ err = rows.Scan(&uid, &comp, &name, &addr, &satz, &last)
+ checkErr(err)
+ lstr := last.Local().Format("2006-01-02 15:04 MST")
+ if lstr == "1791-09-30 20:12 LMT" {
+ lstr = "Never"
+ }
+ fmt.Printf(" %v:%s: %s, Rate: %.2f[€/h] , Last Paid Bill: %s\n", uid, comp, name, satz, lstr)
+ }
}
func allProjects() {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Loading all customers"))
- fmt.Println("___All Projects________________")
- rows3,err := db.Query("SELECT * FROM customers")
- checkErr(err)
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Loading all customers"))
+ fmt.Println("___All Projects________________")
+ rows3, err := db.Query("SELECT * FROM customers")
+ checkErr(err)
+
+ var cid int
+ var com string
+ var nam string
+ var adr string
+ var sat float64
+ var lst time.Time
+ for rows3.Next() {
+ err = rows3.Scan(&cid, &com, &nam, &adr, &sat, &lst)
+ checkErr(err)
- var cid int
- var com string
- var nam string
- var adr string
- var sat float64
- var lst time.Time
- for rows3.Next() {
- err = rows3.Scan(&cid, &com, &nam, &adr, &sat, &lst)
- checkErr(err)
-
- rows,err := db.Query("SELECT * FROM projects WHERE customer = $1",cid)
- checkErr(err)
-
- var uid int
- var prname,comm string
- var first time.Time
- var last time.Time
- var finish int
- var customer,check int
- var start,stop time.Time
-
- fmt.Println("____For",com,nam)
- for rows.Next() {
- err = rows.Scan(&uid, &prname, &comm, &first, &last, &finish, &customer)
- checkErr(err)
- rows2,err := db.Query("SELECT start, stop, checkout FROM timetable WHERE project = $1 AND stop != '1791-09-30 19:07'",uid)
- checkErr(err)
- sumb,sumo := 0.0,0.0
- for rows2.Next() {
- err = rows2.Scan(&start,&stop,&check)
- checkErr(err)
- if check == 0 {
- sumo += float64(stop.Sub(start))/(1000000000*60*60)
- }else{
- sumb += float64(stop.Sub(start))/(1000000000*60*60)
- }
- }
-
- //fmt.Printf(" %v:%s \n First: %s, Last:%s, Total:%.2f(h) ,Fin:%v, For:%v\n",uid,prname,first.Local().Format("2006-01-02 15:04 MST"),last.Local().Format("2006-01-02 15:04 MST"),sum,finish,customer)
- if (sumo+sumb) > 0 {
- fmt.Printf(" %v:%s \n",uid,prname)
- fmt.Printf(" Unbilled: %.2f[h] Billed: %.2f[h] | Total: %.2f[h]\n",sumo,sumb,sumo+sumb)
- //fmt.Printf(" First: %s, Last:%s, Fin:%v, For:%v\n\n",first.Local().Format("2006-01-02 15:04 MST"),last.Local().Format("2006-01-02 15:04 MST"),finish,customer)
- fmt.Printf(" First: %s, Last:%s, \n\n",first.Local().Format("2006-01-02 15:04 MST"),last.Local().Format("2006-01-02 15:04 MST"))
- }else{
- fmt.Print(" Nothing\n")
- }
- rows2.Close() //good habit to close
- }
- rows.Close() //good habit to close
- }
- rows3.Close() //good habit to close
- fmt.Println("_______________________________\n")
+ rows, err := db.Query("SELECT * FROM projects WHERE customer = $1", cid)
+ checkErr(err)
+
+ var uid int
+ var prname, comm string
+ var first time.Time
+ var last time.Time
+ var finish int
+ var customer, check int
+ var start, stop time.Time
+
+ fmt.Println("____For", com, nam)
+ for rows.Next() {
+ err = rows.Scan(&uid, &prname, &comm, &first, &last, &finish, &customer)
+ checkErr(err)
+ rows2, err := db.Query("SELECT start, stop, checkout FROM timetable WHERE project = $1 AND stop != '1791-09-30 19:07'", uid)
+ checkErr(err)
+ sumb, sumo := 0.0, 0.0
+ for rows2.Next() {
+ err = rows2.Scan(&start, &stop, &check)
+ checkErr(err)
+ if check == 0 {
+ sumo += float64(stop.Sub(start)) / (1000000000 * 60 * 60)
+ } else {
+ sumb += float64(stop.Sub(start)) / (1000000000 * 60 * 60)
+ }
+ }
+
+ //fmt.Printf(" %v:%s \n First: %s, Last:%s, Total:%.2f(h) ,Fin:%v, For:%v\n",uid,prname,first.Local().Format("2006-01-02 15:04 MST"),last.Local().Format("2006-01-02 15:04 MST"),sum,finish,customer)
+ if (sumo + sumb) > 0 {
+ fmt.Printf(" %v:%s \n", uid, prname)
+ fmt.Printf(" Unbilled: %.2f[h] Billed: %.2f[h] | Total: %.2f[h]\n", sumo, sumb, sumo+sumb)
+ //fmt.Printf(" First: %s, Last:%s, Fin:%v, For:%v\n\n",first.Local().Format("2006-01-02 15:04 MST"),last.Local().Format("2006-01-02 15:04 MST"),finish,customer)
+ fmt.Printf(" First: %s, Last:%s, \n\n", first.Local().Format("2006-01-02 15:04 MST"), last.Local().Format("2006-01-02 15:04 MST"))
+ } else {
+ fmt.Print(" Nothing\n")
+ }
+ rows2.Close() //good habit to close
+ }
+ rows.Close() //good habit to close
+ }
+ rows3.Close() //good habit to close
+ fmt.Println("_______________________________\n")
}
func deleteBill(id int) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Deleting Bill ",id))
- var prj int
- var identity,moneys,hours string
- var date time.Time
-
- rows,err := db.Query("SELECT project, date, identity, hours, moneys FROM bills WHERE id = $1",id)
- checkErr(err)
- if rows.Next() {
- err = rows.Scan(&prj, &date, &identity, &hours, &moneys)
- checkErr(err)
- rows.Close() //good habit to close
- prstr,custr := getProjectName(prj)
- hsum := sumFloatArray(string2FloatArray(hours,";"))
- msum := sumFloatArray(string2FloatArray(moneys,";"))
- fmt.Printf("%v: For %v- %v (%v) - %.1f[h] : %.2f[€]\n",identity,custr,prstr,date.Local().Format("2006 Mon Jan _2"),hsum,msum)
- if isInterSure("Are You Sure?") {
- uncheckTasks(id) //Set corresponding Tasks to checkout=0
- stmt, err := db.Prepare("DELETE FROM bills WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(id)
- checkErr(err)
- fmt.Println(boldGreen("Bill ",id," deleted successfully!"))
- } else {
- return
- }
- }else{
- fmt.Println(boldRed(id," is Not a known Bill!"))
- showLastBills(0)
- }
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Deleting Bill ", id))
+ var prj int
+ var identity, moneys, hours string
+ var date time.Time
+
+ rows, err := db.Query("SELECT project, date, identity, hours, moneys FROM bills WHERE id = $1", id)
+ checkErr(err)
+ if rows.Next() {
+ err = rows.Scan(&prj, &date, &identity, &hours, &moneys)
+ checkErr(err)
+ rows.Close() //good habit to close
+ prstr, custr := getProjectName(prj)
+ hsum := sumFloatArray(string2FloatArray(hours, ";"))
+ msum := sumFloatArray(string2FloatArray(moneys, ";"))
+ fmt.Printf("%v: For %v- %v (%v) - %.1f[h] : %.2f[€]\n", identity, custr, prstr, date.Local().Format("2006 Mon Jan _2"), hsum, msum)
+ if isInterSure("Are You Sure?") {
+ uncheckTasks(id) //Set corresponding Tasks to checkout=0
+ stmt, err := db.Prepare("DELETE FROM bills WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(id)
+ checkErr(err)
+ fmt.Println(boldGreen("Bill ", id, " deleted successfully!"))
+ } else {
+ return
+ }
+ } else {
+ fmt.Println(boldRed(id, " is Not a known Bill!"))
+ showLastBills(0)
+ }
}
func deleteTask(id int) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Deleting Task ",id))
- var chk,prj int
- var start,stop time.Time
- var task,comm string
- rows,err := db.Query("SELECT project, start, stop, task, comment, checkout FROM timetable WHERE id = $1",id)
- checkErr(err)
- if rows.Next() {
- err = rows.Scan(&prj, &start, &stop, &task, &comm, &chk)
- checkErr(err)
- rows.Close() //good habit to close
- //fmt.Println(boldGreen("Delete Task", id))
- dur := float64(stop.Sub(start))/(1000000000*60*60)
- fmt.Printf("%v: %v (%v-%v) - %.2f h\n Comments:\n%s\n",prj,task,start.Local().Format("2006 Mon Jan _2 15:04"),stop.Local().Format("15:04"),dur,comm)
- if isInterSure("Are You Sure?") {
- stmt, err := db.Prepare("DELETE FROM timetable WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(id)
- checkErr(err)
- fmt.Println(boldGreen("Task ",id," deleted successfully!"))
- } else {
- return
- }
- }else{
- fmt.Println(boldRed(id," is Not a known Task!"))
- }
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Deleting Task ", id))
+ var chk, prj int
+ var start, stop time.Time
+ var task, comm string
+ rows, err := db.Query("SELECT project, start, stop, task, comment, checkout FROM timetable WHERE id = $1", id)
+ checkErr(err)
+ if rows.Next() {
+ err = rows.Scan(&prj, &start, &stop, &task, &comm, &chk)
+ checkErr(err)
+ rows.Close() //good habit to close
+ //fmt.Println(boldGreen("Delete Task", id))
+ dur := float64(stop.Sub(start)) / (1000000000 * 60 * 60)
+ fmt.Printf("%v: %v (%v-%v) - %.2f h\n Comments:\n%s\n", prj, task, start.Local().Format("2006 Mon Jan _2 15:04"), stop.Local().Format("15:04"), dur, comm)
+ if isInterSure("Are You Sure?") {
+ stmt, err := db.Prepare("DELETE FROM timetable WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(id)
+ checkErr(err)
+ fmt.Println(boldGreen("Task ", id, " deleted successfully!"))
+ } else {
+ return
+ }
+ } else {
+ fmt.Println(boldRed(id, " is Not a known Task!"))
+ }
}
func editCustomer(id int) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Editing Customer ",id))
- var comp,name,addr string
- var satz float64
- rows,err := db.Query("SELECT company, name, address, satz FROM customers WHERE id = $1",id)
- checkErr(err)
- if rows.Next() {
- err = rows.Scan(&comp, &name, &addr, &satz)
- checkErr(err)
- }else{
- fmt.Println(boldRed("There Is No Customer"),id)
- return
- //os.Exit(0)
- }
- rows.Close() //good habit to close
-
- //fmt.Println(boldGreen("Edit Customer",id))
- /*fmt.Println("Old Company Name:",comp)
- in := getInterInput("Enter New:")
- if in!=""{
- comp=in
- }*/
- comp = getNewInterInput("New Company Name: ",comp)
- /*fmt.Println("Old Name:",name)
- in = getInterInput("Enter New:")
- if in!=""{
- name=in
- }*/
- name = getNewInterInput("New Customer Name: ",name)
- /*fmt.Println("Old Adress:",addr)
- in = getInterInput("Enter New:")
- if in!=""{
- addr=in
- }*/
- addr = getNewInterInput("New Adress: ",addr)
- //fmt.Println("Old Hourly Rate:",satz)
- for{
- satzstr := getNewInterInput("New Hourly Rate: ",fmt.Sprintf("%.2f",satz))
- satz,err = strconv.ParseFloat(satzstr,64)
- if err != nil {
- fmt.Println(satzstr,boldRed("can not be Parsed as a Float."), "Try a shape of X.X")
- //os.Exit(0)
- }else{break}
- /*satzstr := getInterInput("Enter New:")
- if satzstr!=""{
- satz,err = strconv.ParseFloat(satzstr,64)
- if err != nil {
- fmt.Println(satzstr,boldRed("can not be Parsed as a Float."), "Try a shape of X.X")
- //os.Exit(0)
- }else{break}
- }else{break}*/
- }
- stmt, err := db.Prepare("UPDATE customers SET company = ?, name = ?, address = ?, satz = ? WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(comp,name,addr,satz,id)
- checkErr(err)
- fmt.Println("...Customer",id,"Updated")
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Editing Customer ", id))
+ var comp, name, addr string
+ var satz float64
+ rows, err := db.Query("SELECT company, name, address, satz FROM customers WHERE id = $1", id)
+ checkErr(err)
+ if rows.Next() {
+ err = rows.Scan(&comp, &name, &addr, &satz)
+ checkErr(err)
+ } else {
+ fmt.Println(boldRed("There Is No Customer"), id)
+ return
+ //os.Exit(0)
+ }
+ rows.Close() //good habit to close
+
+ //fmt.Println(boldGreen("Edit Customer",id))
+ /*fmt.Println("Old Company Name:",comp)
+ in := getInterInput("Enter New:")
+ if in!=""{
+ comp=in
+ }*/
+ comp = getNewInterInput("New Company Name: ", comp)
+ /*fmt.Println("Old Name:",name)
+ in = getInterInput("Enter New:")
+ if in!=""{
+ name=in
+ }*/
+ name = getNewInterInput("New Customer Name: ", name)
+ /*fmt.Println("Old Adress:",addr)
+ in = getInterInput("Enter New:")
+ if in!=""{
+ addr=in
+ }*/
+ addr = getNewInterInput("New Adress: ", addr)
+ //fmt.Println("Old Hourly Rate:",satz)
+ for {
+ satzstr := getNewInterInput("New Hourly Rate: ", fmt.Sprintf("%.2f", satz))
+ satz, err = strconv.ParseFloat(satzstr, 64)
+ if err != nil {
+ fmt.Println(satzstr, boldRed("can not be Parsed as a Float."), "Try a shape of X.X")
+ //os.Exit(0)
+ } else {
+ break
+ }
+ /*satzstr := getInterInput("Enter New:")
+ if satzstr!=""{
+ satz,err = strconv.ParseFloat(satzstr,64)
+ if err != nil {
+ fmt.Println(satzstr,boldRed("can not be Parsed as a Float."), "Try a shape of X.X")
+ //os.Exit(0)
+ }else{break}
+ }else{break}*/
+ }
+ stmt, err := db.Prepare("UPDATE customers SET company = ?, name = ?, address = ?, satz = ? WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(comp, name, addr, satz, id)
+ checkErr(err)
+ fmt.Println("...Customer", id, "Updated")
}
func editTask(id int) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Edit Task ",id))
- var chk,prj int
- var start,stop time.Time
- var task,startstr,stopstr,comm string
- rows,err := db.Query("SELECT project, start, stop, task, comment, checkout FROM timetable WHERE id = $1",id)
- checkErr(err)
- if rows.Next() {
- err = rows.Scan(&prj, &start, &stop, &task, &comm, &chk)
- checkErr(err)
- }else{
- fmt.Println(boldRed("There Is No Task"),id)
- return
- //os.Exit(0)
- }
- rows.Close() //good habit to close
-
-/* fmt.Println("Old Name:",task)
- in := getInterInput("Enter New:")
- if in!=""{
- task=in
- }*/
- task = getNewInterInput("New Task Name: ",task)
-
- startstr=start.Local().Format("2006-01-02 15:04")
- stopstr=stop.Local().Format("2006-01-02 15:04")
- for{
- newstartstr := getNewInterInput("New Start time: ",startstr)
- if !isDateTime(newstartstr) {
- fmt.Println(newstartstr,boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM'")
- }else{
- startstr = newstartstr
- break
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Edit Task ", id))
+ var chk, prj int
+ var start, stop time.Time
+ var task, startstr, stopstr, comm string
+ rows, err := db.Query("SELECT project, start, stop, task, comment, checkout FROM timetable WHERE id = $1", id)
+ checkErr(err)
+ if rows.Next() {
+ err = rows.Scan(&prj, &start, &stop, &task, &comm, &chk)
+ checkErr(err)
+ } else {
+ fmt.Println(boldRed("There Is No Task"), id)
+ return
+ //os.Exit(0)
}
- }
- //fmt.Println("Old End:",stopstr)
- for{
- newend := getNewInterInput("New Stop time: ",stopstr)
- if isDateTime(newend) {
- stopstr=newend
- break
- }else{
- fmt.Println(newend,boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM' or 'HH:MM'")
- }
- }
- //fmt.Println("Old Project:",prj)
- for{
- newprj := getNewInterInput("New Project id: ",fmt.Sprint(prj))
- prj,err = strconv.Atoi(newprj)
- if err != nil {
- fmt.Println(newprj,boldRed("is Not a Valid id."), "Try an Integer instead")
- }
- if !isProject(prj) {
- fmt.Println(boldRed("There is no project"),prj)
- }else{break}
- }
- comm = getNewInterMultiInput("New Comment: ",comm)
-
- stmt, err := db.Prepare("UPDATE timetable SET task = ?, comment = ?, start = datetime(?,'utc'), stop = datetime(?,'utc'), project = ? WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(task,comm,startstr,stopstr,prj,id)
- checkErr(err)
- updateProject(prj)
- fmt.Println("...Task",id,"Updated")
-}
-
-func editProject(id int) {
- boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
- boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
- fmt.Println(boldGreen("Edit Project ",id))
- var fin,cust int
- var first time.Time
- var name,nfirst,comm string
- rows,err := db.Query("SELECT name, comment, first, finished, customer FROM projects WHERE id = $1",id)
- checkErr(err)
- if rows.Next() {
- err = rows.Scan(&name, &comm, &first, &fin, &cust)
- checkErr(err)
-
- name = getNewInterInput("New Name: ",name)
- nfirst=first.Local().Format("2006-01-02 15:04")
- // Get New PRoject Begin Date
- for{
- newfirststr := getNewInterInput("New Begin time: ",nfirst)
- if !isDateTime(newfirststr) {
- fmt.Println(newfirststr,boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM'")
- }else{
- nfirst = newfirststr
+ rows.Close() //good habit to close
+
+ /* fmt.Println("Old Name:",task)
+ in := getInterInput("Enter New:")
+ if in!=""{
+ task=in
+ }*/
+ task = getNewInterInput("New Task Name: ", task)
+
+ startstr = start.Local().Format("2006-01-02 15:04")
+ stopstr = stop.Local().Format("2006-01-02 15:04")
+ for {
+ newstartstr := getNewInterInput("New Start time: ", startstr)
+ if !isDateTime(newstartstr) {
+ fmt.Println(newstartstr, boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM'")
+ } else {
+ startstr = newstartstr
break
}
}
- // Get New Customer
- for{
- newcu := getNewInterInput("New Customer id: ",fmt.Sprint(cust))
- icust,err := strconv.Atoi(newcu)
+ //fmt.Println("Old End:",stopstr)
+ for {
+ newend := getNewInterInput("New Stop time: ", stopstr)
+ if isDateTime(newend) {
+ stopstr = newend
+ break
+ } else {
+ fmt.Println(newend, boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM' or 'HH:MM'")
+ }
+ }
+ //fmt.Println("Old Project:",prj)
+ for {
+ newprj := getNewInterInput("New Project id: ", fmt.Sprint(prj))
+ prj, err = strconv.Atoi(newprj)
if err != nil {
- fmt.Println(newcu,boldRed("is Not a Valid id."), "Try an Integer instead")
- }else if !isCustomer(icust) {
- fmt.Println(boldRed("There is no Customer"),icust)
- }else{
- cust = icust
+ fmt.Println(newprj, boldRed("is Not a Valid id."), "Try an Integer instead")
+ }
+ if !isProject(prj) {
+ fmt.Println(boldRed("There is no project"), prj)
+ } else {
break
}
}
- // Get Comment
- comm = getNewInterMultiInput("New Comment: ",comm)
- }else{
- fmt.Println(boldRed("There Is No Project"),id)
- return
- //os.Exit(0)
- }
- rows.Close() //good habit to close
- stmt, err := db.Prepare("UPDATE projects SET name = ?, comment = ?, last = datetime(?,'utc'), customer = ? WHERE id = ?")
- checkErr(err)
- _, err = stmt.Exec(name,comm,nfirst,cust,id)
- checkErr(err)
- updateProject(id)
- fmt.Println("...Project",id,"Updated")
+ comm = getNewInterMultiInput("New Comment: ", comm)
+
+ stmt, err := db.Prepare("UPDATE timetable SET task = ?, comment = ?, start = datetime(?,'utc'), stop = datetime(?,'utc'), project = ? WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(task, comm, startstr, stopstr, prj, id)
+ checkErr(err)
+ updateProject(prj)
+ fmt.Println("...Task", id, "Updated")
+}
+
+func editProject(id int) {
+ boldGreen := color.New(color.FgGreen, color.Bold).SprintFunc()
+ boldRed := color.New(color.FgRed, color.Bold).SprintFunc()
+ fmt.Println(boldGreen("Edit Project ", id))
+ var fin, cust int
+ var first time.Time
+ var name, nfirst, comm string
+ rows, err := db.Query("SELECT name, comment, first, finished, customer FROM projects WHERE id = $1", id)
+ checkErr(err)
+ if rows.Next() {
+ err = rows.Scan(&name, &comm, &first, &fin, &cust)
+ checkErr(err)
+
+ name = getNewInterInput("New Name: ", name)
+ nfirst = first.Local().Format("2006-01-02 15:04")
+ // Get New PRoject Begin Date
+ for {
+ newfirststr := getNewInterInput("New Begin time: ", nfirst)
+ if !isDateTime(newfirststr) {
+ fmt.Println(newfirststr, boldRed("is Not a Valid Timestring!"), "use: 'YYYY-MM-DD HH:MM'")
+ } else {
+ nfirst = newfirststr
+ break
+ }
+ }
+ // Get New Customer
+ for {
+ newcu := getNewInterInput("New Customer id: ", fmt.Sprint(cust))
+ icust, err := strconv.Atoi(newcu)
+ if err != nil {
+ fmt.Println(newcu, boldRed("is Not a Valid id."), "Try an Integer instead")
+ } else if !isCustomer(icust) {
+ fmt.Println(boldRed("There is no Customer"), icust)
+ } else {
+ cust = icust
+ break
+ }
+ }
+ // Get Comment
+ comm = getNewInterMultiInput("New Comment: ", comm)
+ } else {
+ fmt.Println(boldRed("There Is No Project"), id)
+ return
+ //os.Exit(0)
+ }
+ rows.Close() //good habit to close
+ stmt, err := db.Prepare("UPDATE projects SET name = ?, comment = ?, last = datetime(?,'utc'), customer = ? WHERE id = ?")
+ checkErr(err)
+ _, err = stmt.Exec(name, comm, nfirst, cust, id)
+ checkErr(err)
+ updateProject(id)
+ fmt.Println("...Project", id, "Updated")
}
func isBill(id int) bool {
- rows,err := db.Query("SELECT * FROM bills WHERE id = $1",id)
- checkErr(err)
- defer rows.Close()
- if rows.Next() {
- return true
- } else {
- return false
- }
+ rows, err := db.Query("SELECT * FROM bills WHERE id = $1", id)
+ checkErr(err)
+ defer rows.Close()
+ if rows.Next() {
+ return true
+ } else {
+ return false
+ }
}
func isTask(id int) bool {
- rows,err := db.Query("SELECT * FROM timetable WHERE id = $1",id)
- checkErr(err)
- defer rows.Close()
- if rows.Next() {
- return true
- } else {
- return false
- }
+ rows, err := db.Query("SELECT * FROM timetable WHERE id = $1", id)
+ checkErr(err)
+ defer rows.Close()
+ if rows.Next() {
+ return true
+ } else {
+ return false
+ }
}
func isProject(id int) bool {
- rows,err := db.Query("SELECT * FROM projects WHERE id = $1",id)
- checkErr(err)
- defer rows.Close()
- if rows.Next() {
- return true
- } else {
- return false
- }
+ rows, err := db.Query("SELECT * FROM projects WHERE id = $1", id)
+ checkErr(err)
+ defer rows.Close()
+ if rows.Next() {
+ return true
+ } else {
+ return false
+ }
}
func isCustomer(id int) bool {
- rows,err := db.Query("SELECT * FROM customers WHERE id = $1",id)
- checkErr(err)
- defer rows.Close()
- if rows.Next() {
- return true
- } else {
- return false
- }
+ rows, err := db.Query("SELECT * FROM customers WHERE id = $1", id)
+ checkErr(err)
+ defer rows.Close()
+ if rows.Next() {
+ return true
+ } else {
+ return false
+ }
}
func getDateTime(in string) string {
- r := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})`)
- return r.FindString(in)
+ r := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})`)
+ return r.FindString(in)
}
func getDate(in string) string {
- r := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
- return r.FindString(in)
+ r := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
+ return r.FindString(in)
}
func getTime(in string) string {
- r := regexp.MustCompile(`(\d{2}):(\d{2})`)
- return r.FindString(in)
+ r := regexp.MustCompile(`(\d{2}):(\d{2})`)
+ return r.FindString(in)
}
func isDateTime(in string) bool {
- match, _ := regexp.MatchString(`(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})`,in)
- return match
+ match, _ := regexp.MatchString(`(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})`, in)
+ return match
}
func isDate(in string) bool {
- match, _ := regexp.MatchString(`(\d{4})-(\d{2})-(\d{2})`,in)
- return match
+ match, _ := regexp.MatchString(`(\d{4})-(\d{2})-(\d{2})`, in)
+ return match
}
func isTime(in string) bool {
- match, _ := regexp.MatchString(`(\d{2}):(\d{2})`,in)
- return match
+ match, _ := regexp.MatchString(`(\d{2}):(\d{2})`, in)
+ return match
}
/*
@@ -1490,23 +1499,23 @@ func isSure() bool {
}
}*/
-func isElement(some int, group []int) (bool) {
- for _,e := range group {
- if e == some {
- return true
- }
- }
- return false
+func isElement(some int, group []int) bool {
+ for _, e := range group {
+ if e == some {
+ return true
+ }
+ }
+ return false
}
-func removeItems(master, rem []int) ([]int) {
- var out []int
- for _,v := range master {
- if !isElement(v,rem) {
- out = append(out,v)
- }
- }
- return out
+func removeItems(master, rem []int) []int {
+ var out []int
+ for _, v := range master {
+ if !isElement(v, rem) {
+ out = append(out, v)
+ }
+ }
+ return out
}
/*
diff --git a/texify.go b/texify.go
index 4e9015e..358047a 100644
--- a/texify.go
+++ b/texify.go
@@ -1,217 +1,216 @@
package main
import (
- "fmt"
- "strings"
- "os/exec"
- "os"
- "text/template"
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+ "text/template"
)
-type FeeItem struct{
- Task string
- Timeframe string
- Hours float64
- Price float64
+type FeeItem struct {
+ Task string
+ Timeframe string
+ Hours float64
+ Price float64
}
-type Filenames struct{
- Data string
- Invoice string
- Main string
+type Filenames struct {
+ Data string
+ Invoice string
+ Main string
}
type Data struct {
- InvDate string
- WorkDate string
- InvNo string
- ProjName string
-
- CustComp string
- CustName string
- CustStr string
- CustZip string
- CustCity string
- CustCountry string
-
- TaxID string
- MyName string
- MyStr string
- MyZip string
- MyCity string
- MyCountry string
- MyTel string
- MyMob string
- MyMail string
- MyUrl string
-
- BankNum string
- BankLZ string
- BankName string
- Iban string
- Bic string
+ InvDate string
+ WorkDate string
+ InvNo string
+ ProjName string
+
+ CustComp string
+ CustName string
+ CustStr string
+ CustZip string
+ CustCity string
+ CustCountry string
+
+ TaxID string
+ MyName string
+ MyStr string
+ MyZip string
+ MyCity string
+ MyCountry string
+ MyTel string
+ MyMob string
+ MyMail string
+ MyUrl string
+
+ BankNum string
+ BankLZ string
+ BankName string
+ Iban string
+ Bic string
}
-func billTemplate(billdata bill, cust customer) (Filenames) {
- billid := billdata.id
- custr,cuzip,cucity,cucou := "","","",""
- addr := string2StringArray(cust.address,";")
- for i,a := range addr {
- switch i {
- case 0:
- custr=a
- case 1:
- cuzip=a
- case 2:
- cucity=a
- case 3:
- cucou=a
- default:
- break
- }
- }
- dat := Data{billdata.date.UTC().Format("2006-01-02"),
- billdata.timerange,
- billdata.identity,
- billdata.projectname,
-
- cust.company,
- cust.name,
- custr,
- cuzip,
- cucity,
- cucou,
-
- config.Taxid,
- config.Name,
- config.Street,
- config.Zip,
- config.City,
- config.Country,
- config.Telefon,
- config.Mobile,
- config.Mail,
- config.Url,
-
- config.Bankacc,
- config.Banklz,
- config.Bankname,
- config.Iban,
- config.Bic,
- }
-
- inv := billdata.items
-
- filenamedata := fmt.Sprintf("%v_data",billid)
- filenameinv := fmt.Sprintf("%v_invoice",billid)
- filenamemain := fmt.Sprintf("%v_main.tex",billid)
- fnames := Filenames{filenamedata,filenameinv,filenamemain}
-
- //Parse Templates
- tmpl, err := template.New("invoice").Delims("[[","]]").ParseGlob("templates/*.tex")
- checkErr(err)
- filenamedata = fmt.Sprintf("outtex/%v_data.tex",billid)
- filenameinv = fmt.Sprintf("outtex/%v_invoice.tex",billid)
- filenamemain = fmt.Sprintf("outtex/%v_main.tex",billid)
-
- //Open File
- datf, err := os.Create(filenamedata)
- checkErr(err)
- invf, err := os.Create(filenameinv)
- checkErr(err)
- maif, err := os.Create(filenamemain)
- checkErr(err)
- defer datf.Close()
- defer invf.Close()
- defer maif.Close()
-
- //Execute Template
- //err = tmpl.ExecuteTemplate(os.Stdout, "invoice.tex", td)
- err = tmpl.ExecuteTemplate(datf, "_data.tex", dat)
- checkErr(err)
- err = tmpl.ExecuteTemplate(invf, "_invoice.tex", inv)
- checkErr(err)
- err = tmpl.ExecuteTemplate(maif, "_main.tex", fnames)
- checkErr(err)
-
- return fnames
+func billTemplate(billdata bill, cust customer) Filenames {
+ billid := billdata.id
+ custr, cuzip, cucity, cucou := "", "", "", ""
+ addr := string2StringArray(cust.address, ";")
+ for i, a := range addr {
+ switch i {
+ case 0:
+ custr = a
+ case 1:
+ cuzip = a
+ case 2:
+ cucity = a
+ case 3:
+ cucou = a
+ default:
+ break
+ }
+ }
+ dat := Data{billdata.date.UTC().Format("2006-01-02"),
+ billdata.timerange,
+ billdata.identity,
+ billdata.projectname,
+
+ cust.company,
+ cust.name,
+ custr,
+ cuzip,
+ cucity,
+ cucou,
+
+ config.Taxid,
+ config.Name,
+ config.Street,
+ config.Zip,
+ config.City,
+ config.Country,
+ config.Telefon,
+ config.Mobile,
+ config.Mail,
+ config.Url,
+
+ config.Bankacc,
+ config.Banklz,
+ config.Bankname,
+ config.Iban,
+ config.Bic,
+ }
+
+ inv := billdata.items
+
+ filenamedata := fmt.Sprintf("%v_data", billid)
+ filenameinv := fmt.Sprintf("%v_invoice", billid)
+ filenamemain := fmt.Sprintf("%v_main.tex", billid)
+ fnames := Filenames{filenamedata, filenameinv, filenamemain}
+
+ //Parse Templates
+ tmpl, err := template.New("invoice").Delims("[[", "]]").ParseGlob("templates/*.tex")
+ checkErr(err)
+ filenamedata = fmt.Sprintf("outtex/%v_data.tex", billid)
+ filenameinv = fmt.Sprintf("outtex/%v_invoice.tex", billid)
+ filenamemain = fmt.Sprintf("outtex/%v_main.tex", billid)
+
+ //Open File
+ datf, err := os.Create(filenamedata)
+ checkErr(err)
+ invf, err := os.Create(filenameinv)
+ checkErr(err)
+ maif, err := os.Create(filenamemain)
+ checkErr(err)
+ defer datf.Close()
+ defer invf.Close()
+ defer maif.Close()
+
+ //Execute Template
+ //err = tmpl.ExecuteTemplate(os.Stdout, "invoice.tex", td)
+ err = tmpl.ExecuteTemplate(datf, "_data.tex", dat)
+ checkErr(err)
+ err = tmpl.ExecuteTemplate(invf, "_invoice.tex", inv)
+ checkErr(err)
+ err = tmpl.ExecuteTemplate(maif, "_main.tex", fnames)
+ checkErr(err)
+
+ return fnames
}
-func runLatex(inputfilename,outputfilename string) (error) {
- fmt.Printf("Rendering: %s -> Output File: outpdf/Rechnung%s.pdf\n",inputfilename,cleanString(outputfilename))
- pref := strings.TrimSuffix(inputfilename,"_main.tex")
- //cmdArgs := []string{"-synctex=1", "-interaction=nonstopmode", filename}
-
- binary, err := exec.LookPath("pdflatex")
- checkErr(err)
-
- //env := os.Environ()
- mainpdf := strings.Replace(inputfilename,".tex",".pdf",1)
- cmd := fmt.Sprintf("cd outtex; %v -interaction=nonstopmode -output-directory='../outpdf' %s; cd ../outpdf; cp %s 'Rechnung%s.pdf'; rm %s_*",binary,inputfilename,mainpdf,cleanString(outputfilename),pref)
- //fmt.Println(cmd)
- //docmd := exec.Command(binary,cmdArgs[0], cmdArgs[1],cmdArgs[2])
- docmd := exec.Command("bash","-c",cmd)
- //err = docmd.Run()
- err = docmd.Start()
- //out,err := docmd.Output()
- //checkErr(err)
- err = docmd.Wait()
- //fmt.Println(string(out))
- //fmt.Printf("Finished with Error:%v\n",err)
- return err
+func runLatex(inputfilename, outputfilename string) error {
+ fmt.Printf("Rendering: %s -> Output File: outpdf/Rechnung%s.pdf\n", inputfilename, cleanString(outputfilename))
+ pref := strings.TrimSuffix(inputfilename, "_main.tex")
+ //cmdArgs := []string{"-synctex=1", "-interaction=nonstopmode", filename}
+
+ binary, err := exec.LookPath("pdflatex")
+ checkErr(err)
+
+ //env := os.Environ()
+ mainpdf := strings.Replace(inputfilename, ".tex", ".pdf", 1)
+ cmd := fmt.Sprintf("cd outtex; %v -interaction=nonstopmode -output-directory='../outpdf' %s; cd ../outpdf; cp %s 'Rechnung%s.pdf'; rm %s_*", binary, inputfilename, mainpdf, cleanString(outputfilename), pref)
+ //fmt.Println(cmd)
+ //docmd := exec.Command(binary,cmdArgs[0], cmdArgs[1],cmdArgs[2])
+ docmd := exec.Command("bash", "-c", cmd)
+ //err = docmd.Run()
+ err = docmd.Start()
+ //out,err := docmd.Output()
+ //checkErr(err)
+ err = docmd.Wait()
+ //fmt.Println(string(out))
+ //fmt.Printf("Finished with Error:%v\n",err)
+ return err
}
-
func tmpltest() {
- //Sampledata
- dat := Data{"17.6.18",
- "3.4.-7.6.18",
- "HN 07/18",
- "Testkopfstrasse 132",
- "Somecompany",
- "Jemand Wiadschosei",
- "Fakestreet 123",
- "6996",
- "Busenhausen",
- "Tittania",
- "6575-6544",
- "Meinam Sauluschtig",
- "Saubastrasse 86",
- "1111",
- "Nicetown",
- "Niceland",
- "+43 (1) 655 555 23",
- "+43 (0) 650 555 32",
- "Meinam@sauluscht.ig",
- "www.saulust.com",
- "7272626272",
- "20220",
- "Might Bank Inc.",
- "IB47 2382 4338 2822 1222",
- "BICBICBIC"}
- var inv []FeeItem
-
- inv = append(inv,FeeItem{"Modellierung Dachkonstruktion", "1.4.-27.4.18",13,325})
- inv = append(inv,FeeItem{"Dokument Vorbereitung", "9.4.-5.5.18",15,375})
- inv = append(inv,FeeItem{"Begehungen und Besprechungen", "1.4.-19.4.18",12,300})
- inv = append(inv,FeeItem{"Wichtig aussehen", "5.5.-5.5.18",2,50})
-
- //Parse Templates
- tmpl, err := template.New("invoice").Delims("[[","]]").ParseGlob("templates/*.tex")
- checkErr(err)
- //Open File
- datf, err := os.Create("outtex/1_data.tex")
- checkErr(err)
- invf, err := os.Create("outtex/1_invoice.tex")
- checkErr(err)
- defer datf.Close()
- defer invf.Close()
-
- //Execute Template
- //err = tmpl.ExecuteTemplate(os.Stdout, "invoice.tex", td)
- err = tmpl.ExecuteTemplate(datf, "_data.tex", dat)
- checkErr(err)
- err = tmpl.ExecuteTemplate(invf, "_invoice.tex", inv)
- checkErr(err)
+ //Sampledata
+ dat := Data{"17.6.18",
+ "3.4.-7.6.18",
+ "HN 07/18",
+ "Testkopfstrasse 132",
+ "Somecompany",
+ "Jemand Wiadschosei",
+ "Fakestreet 123",
+ "6996",
+ "Busenhausen",
+ "Tittania",
+ "6575-6544",
+ "Meinam Sauluschtig",
+ "Saubastrasse 86",
+ "1111",
+ "Nicetown",
+ "Niceland",
+ "+43 (1) 655 555 23",
+ "+43 (0) 650 555 32",
+ "Meinam@sauluscht.ig",
+ "www.saulust.com",
+ "7272626272",
+ "20220",
+ "Might Bank Inc.",
+ "IB47 2382 4338 2822 1222",
+ "BICBICBIC"}
+ var inv []FeeItem
+
+ inv = append(inv, FeeItem{"Modellierung Dachkonstruktion", "1.4.-27.4.18", 13, 325})
+ inv = append(inv, FeeItem{"Dokument Vorbereitung", "9.4.-5.5.18", 15, 375})
+ inv = append(inv, FeeItem{"Begehungen und Besprechungen", "1.4.-19.4.18", 12, 300})
+ inv = append(inv, FeeItem{"Wichtig aussehen", "5.5.-5.5.18", 2, 50})
+
+ //Parse Templates
+ tmpl, err := template.New("invoice").Delims("[[", "]]").ParseGlob("templates/*.tex")
+ checkErr(err)
+ //Open File
+ datf, err := os.Create("outtex/1_data.tex")
+ checkErr(err)
+ invf, err := os.Create("outtex/1_invoice.tex")
+ checkErr(err)
+ defer datf.Close()
+ defer invf.Close()
+
+ //Execute Template
+ //err = tmpl.ExecuteTemplate(os.Stdout, "invoice.tex", td)
+ err = tmpl.ExecuteTemplate(datf, "_data.tex", dat)
+ checkErr(err)
+ err = tmpl.ExecuteTemplate(invf, "_invoice.tex", inv)
+ checkErr(err)
}
diff --git a/utils.go b/utils.go
index 0d22813..9d6fc91 100644
--- a/utils.go
+++ b/utils.go
@@ -1,180 +1,216 @@
package main
import (
- "fmt"
- "bufio"
- "os"
- "os/exec"
- "math"
- "strings"
- "strconv"
- "runtime"
+ "bufio"
+ "fmt"
+ "math"
+ "os"
+ "os/exec"
+ "runtime"
+ "strconv"
+ "strings"
+ "unicode/utf8"
)
+const (
+ framewidth int = 40
+ li = "\u2501"
+ mli = "\u2501\u252f\u2501\u2501" //Masterline -T-
+ sli = " \u251c\u2500 " //Slave Line L_
+ nli = " \u2502 " //noone Line |
+ fli = " \u2515\u2501\u2501" //Footer Line L
+)
+
+func frame(text string, head bool) (out string) {
+ if head {
+ out = mli + text
+ }else{
+ out = fli + text
+ }
+ n := utf8.RuneCountInString(out)
+ r := framewidth - n
+ if r < 1 {
+ out = out + li
+ }else{
+ out = out + strings.Repeat(li,r)
+ }
+ if head {
+ out = "\n" + out
+ }else{
+ out = out + "\n"
+ }
+ return
+}
+
func getGitTag() string {
- var (
- cmdOut []byte
- err error
- )
- cmd := "git"
- args := []string{"tag","--points-at","HEAD"}
- if cmdOut,err = exec.Command(cmd,args...).Output(); err != nil {
- panic(err)
- }
- return string(cmdOut)
+ var (
+ cmdOut []byte
+ err error
+ )
+ cmd := "git"
+ args := []string{"tag", "--points-at", "HEAD"}
+ if cmdOut, err = exec.Command(cmd, args...).Output(); err != nil {
+ panic(err)
+ }
+ return string(cmdOut)
}
//Remove a string from a []string and the int number of strings afterwards
-func removeStringFromArray(arr []string,rem string,after int) (out []string) {
- found := false
- i := 0
- for _,st := range arr {
- if found {
- if i < after {
- i++
- }else{
- found = false
- }
- }else{
- if st == rem {
- found = true
- }else{
- out = append(out,st)
- }
- }
- }
- return
+func removeStringFromArray(arr []string, rem string, after int) (out []string) {
+ found := false
+ i := 0
+ for _, st := range arr {
+ if found {
+ if i < after {
+ i++
+ } else {
+ found = false
+ }
+ } else {
+ if st == rem {
+ found = true
+ } else {
+ out = append(out, st)
+ }
+ }
+ }
+ return
}
+//Ask a Question an read the answer
func isSure(quest string) bool {
- fmt.Printf("%s (type 'y/Y/yes' to confirm) : ",quest)
- in := bufio.NewReader(os.Stdin)
- line, err := in.ReadString('\n')
- if(runtime.GOOS == "windows"){
- line = strings.TrimSuffix(line, "\r\n") //for Windows
- }else{
- line = strings.TrimSuffix(line, "\n")
- }
- checkErr(err)
-
- if ( line == "yes" || line == "y" || line == "Y") {
- return true
- } else {
- return false
- }
+ fmt.Printf("%s (type 'y/Y/yes' to confirm) : ", quest)
+ in := bufio.NewReader(os.Stdin)
+ line, err := in.ReadString('\n')
+ if runtime.GOOS == "windows" {
+ line = strings.TrimSuffix(line, "\r\n") //for Windows
+ } else {
+ line = strings.TrimSuffix(line, "\n")
+ }
+ checkErr(err)
+
+ if line == "yes" || line == "y" || line == "Y" {
+ return true
+ } else {
+ return false
+ }
}
+//Test if error is nil and panic if not
+//TODO log seperately
func checkErr(err error) {
- if err != nil {
- panic(err)
- }
+ if err != nil {
+ panic(err)
+ }
}
//make One String with Linebreaks out of an input String Array
-func strLines(in []string) (out string){
+func strLines(in []string) (out string) {
out = ""
- for _,s := range in {
- out = fmt.Sprintf("%s%s\n",out,s)
+ for _, s := range in {
+ out = fmt.Sprintf("%s%s\n", out, s)
}
return
}
+//Ask a question return the Answer
func getInput(quest string) string {
- fmt.Print(quest)
- in := bufio.NewReader(os.Stdin)
- line, err := in.ReadString('\n')
- if(runtime.GOOS == "windows"){
- line = strings.TrimSuffix(line, "\r\n") //for Windows
- }else{
- line = strings.TrimSuffix(line, "\n")
- }
- checkErr(err)
- return line
+ fmt.Print(quest)
+ in := bufio.NewReader(os.Stdin)
+ line, err := in.ReadString('\n')
+ if runtime.GOOS == "windows" {
+ line = strings.TrimSuffix(line, "\r\n") //for Windows
+ } else {
+ line = strings.TrimSuffix(line, "\n")
+ }
+ checkErr(err)
+ return line
}
-func getNewInput(quest,old string) string {
- if old != "" {
- fmt.Println("Current:",old)
- }
- fmt.Print(quest)
- in := bufio.NewReader(os.Stdin)
- line, err := in.ReadString('\n')
- if(runtime.GOOS == "windows"){
- line = strings.TrimSuffix(line, "\r\n") //for Windows
- }else{
- line = strings.TrimSuffix(line, "\n")
- }
- checkErr(err)
- if line == "" {
- return old
- }else{
- return line
- }
+//show Old Value, Ask Question and Return answer
+func getNewInput(quest, old string) string {
+ if old != "" {
+ fmt.Println("Current:", old)
+ }
+ fmt.Print(quest)
+ in := bufio.NewReader(os.Stdin)
+ line, err := in.ReadString('\n')
+ if runtime.GOOS == "windows" {
+ line = strings.TrimSuffix(line, "\r\n") //for Windows
+ } else {
+ line = strings.TrimSuffix(line, "\n")
+ }
+ checkErr(err)
+ if line == "" {
+ return old
+ } else {
+ return line
+ }
}
-func stringArray2String(in []string, delim string) (string) {
- var out string
- for i,a := range in {
- if i==0 {
- out=a
- }else{
- out=fmt.Sprintf("%s%s%s",out,delim,a)
- }
- }
- return out
+func stringArray2String(in []string, delim string) string {
+ var out string
+ for i, a := range in {
+ if i == 0 {
+ out = a
+ } else {
+ out = fmt.Sprintf("%s%s%s", out, delim, a)
+ }
+ }
+ return out
}
-func string2FloatArray(in string,delim string)(out []float64) {
- read := strings.Split(in,delim)
- for _,s := range read{
- fs,err := strconv.ParseFloat(s,64)
- checkErr(err)
- out = append(out,fs)
- }
- return
+func string2FloatArray(in string, delim string) (out []float64) {
+ read := strings.Split(in, delim)
+ for _, s := range read {
+ fs, err := strconv.ParseFloat(s, 64)
+ checkErr(err)
+ out = append(out, fs)
+ }
+ return
}
-func string2StringArray(in string,delim string)(out []string) {
- read := strings.Split(in,delim)
- for _,s := range read{
- out = append(out,s)
- }
- return
+func string2StringArray(in string, delim string) (out []string) {
+ read := strings.Split(in, delim)
+ for _, s := range read {
+ out = append(out, s)
+ }
+ return
}
func RetardRound(x float64) float64 {
- t := math.Trunc(x)
- if math.Abs(x-t) >= 0.5 {
- return t + math.Copysign(1, x)
- }
- return t
+ t := math.Trunc(x)
+ if math.Abs(x-t) >= 0.5 {
+ return t + math.Copysign(1, x)
+ }
+ return t
}
-func Round(x, unit float64) (float64) {
-// return math.Round(x/unit) * unit
- return RetardRound(x/unit) * unit
+func Round(x, unit float64) float64 {
+ // return math.Round(x/unit) * unit
+ return RetardRound(x/unit) * unit
}
func cleanString(in string) (out string) {
- work := strings.Replace(in,"/","-",-1)
- work = strings.Replace(work,"*","-",-1)
- work = strings.Replace(work,":","-",-1)
- work = strings.Replace(work,"<","-",-1)
- work = strings.Replace(work,">","-",-1)
- work = strings.Replace(work,"?","-",-1)
- work = strings.Replace(work,"|","-",-1)
- work = strings.Replace(work,"+","-",-1)
- work = strings.Replace(work,",","-",-1)
- work = strings.Replace(work,";","-",-1)
- work = strings.Replace(work,"=","-",-1)
- work = strings.Replace(work,"[","-",-1)
- out = strings.Replace(work,"]","-",-1)
- return
+ work := strings.Replace(in, "/", "-", -1)
+ work = strings.Replace(work, "*", "-", -1)
+ work = strings.Replace(work, ":", "-", -1)
+ work = strings.Replace(work, "<", "-", -1)
+ work = strings.Replace(work, ">", "-", -1)
+ work = strings.Replace(work, "?", "-", -1)
+ work = strings.Replace(work, "|", "-", -1)
+ work = strings.Replace(work, "+", "-", -1)
+ work = strings.Replace(work, ",", "-", -1)
+ work = strings.Replace(work, ";", "-", -1)
+ work = strings.Replace(work, "=", "-", -1)
+ work = strings.Replace(work, "[", "-", -1)
+ out = strings.Replace(work, "]", "-", -1)
+ return
}
func sumFloatArray(in []float64) (sum float64) {
- for _,e := range in{
- sum += e
- }
- return
+ for _, e := range in {
+ sum += e
+ }
+ return
}