114 lines
2.5 KiB
Go
114 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"time"
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
"git.schreifuchs.ch/lou-taylor/accounting/internal/email"
|
|
"git.schreifuchs.ch/lou-taylor/accounting/pkg/invoice"
|
|
)
|
|
|
|
type createFlags struct {
|
|
Email bool `flag:"email" help:"send invoice by email"`
|
|
Output string `flag:"o" help:"output file"`
|
|
Label string `flag:"l" help:"filters for issues with the label"`
|
|
}
|
|
|
|
func create(arguments []string, c any) {
|
|
flags, ok := c.(*createFlags)
|
|
if !ok {
|
|
panic("invalid config injected")
|
|
}
|
|
req := parseRequest(arguments)
|
|
|
|
cfg, log, invoicer, mailer := inject()
|
|
|
|
repos, err := req.GetRepos()
|
|
if err != nil {
|
|
fmt.Printf("could not get repos: %v", err)
|
|
return
|
|
}
|
|
|
|
opts := invoice.DefaultOptions
|
|
|
|
if flags.Label != "" {
|
|
opts.IssueState = gitea.StateAll
|
|
opts.IssueFilter = func(i *gitea.Issue) bool {
|
|
for _, l := range i.Labels {
|
|
if l.Name == flags.Label {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
}
|
|
opts.Since = time.Now().AddDate(-1, 0, 0)
|
|
|
|
opts.Mindur = time.Duration(req.DurationThreshold)
|
|
invoice, report, err := invoicer.Generate(req.Creditor, req.Debtor, req.HourlyRate, repos, &opts)
|
|
if err != nil {
|
|
log.Error(fmt.Sprintf("Error while creating invoice: %v", err))
|
|
}
|
|
|
|
// if no time has to be billed aka if bill for 0 CHF
|
|
if report.Total() <= time.Duration(0) {
|
|
log.Info("no suitable issues to be billed")
|
|
return
|
|
}
|
|
|
|
if flags.Email {
|
|
mail := email.Mail{
|
|
To: []string{req.MailTo},
|
|
Subject: fmt.Sprintf("Invoice from %s", cfg.Email.From),
|
|
Attachments: []email.Attachment{{Name: "invoice.pdf", MimeType: "application/pdf", Content: invoice}},
|
|
}
|
|
err := mailer.Send(mail)
|
|
if err != nil {
|
|
log.Error(fmt.Sprintf("Error while sending mail: %v", err))
|
|
os.Exit(1)
|
|
}
|
|
return
|
|
}
|
|
if len(flags.Output) > 0 {
|
|
file, err := os.Create(flags.Output)
|
|
if err != nil {
|
|
log.Error(fmt.Sprintf("Error opening output file: %v", err))
|
|
os.Exit(1)
|
|
}
|
|
defer file.Close()
|
|
|
|
_, err = io.Copy(file, invoice)
|
|
if err != nil {
|
|
log.Error(fmt.Sprintf("Error while writing to output file: %v", err))
|
|
os.Exit(1)
|
|
}
|
|
return
|
|
}
|
|
io.Copy(os.Stdout, invoice)
|
|
}
|
|
|
|
func parseRequest(arguments []string) *invoiceRequest {
|
|
if len(arguments) < 1 {
|
|
fmt.Println("please specify request file")
|
|
os.Exit(1)
|
|
}
|
|
|
|
file, err := os.Open(arguments[0])
|
|
if err != nil {
|
|
log.Fatalf("can't open file: %s %v", arguments[0], err)
|
|
}
|
|
|
|
defer file.Close()
|
|
req := &invoiceRequest{}
|
|
|
|
json.NewDecoder(file).Decode(req)
|
|
|
|
return req
|
|
}
|