diff --git a/internal/api/httpinvoce/controller.go b/internal/api/httpinvoce/controller.go index 6d84c31..93cbdc4 100644 --- a/internal/api/httpinvoce/controller.go +++ b/internal/api/httpinvoce/controller.go @@ -29,13 +29,19 @@ func (s Service) createInvoice(w http.ResponseWriter, r *http.Request) { return } - invoice, err := s.invoice.Generate(req.Creditor, req.Debtor, time.Duration(req.DurationThreshold), req.HourlyRate, repos) + invoice, report, err := s.invoice.Generate(req.Creditor, req.Debtor, time.Duration(req.DurationThreshold), req.HourlyRate, repos) if err != nil { log.Println("error while processing invoice:", err) fmt.Fprint(w, "internal server error") w.WriteHeader(http.StatusInternalServerError) return } + // if no time has to be billed aka if bill for 0 CHF + if report.Total() <= time.Duration(0) { + s.sendErr(w, http.StatusNotFound, "no suitable issues to be billed") + return + } + w.Header().Set("Content-type", "application/pdf") w.Header().Set( "Content-Disposition", @@ -51,7 +57,6 @@ func (s Service) createInvoice(w http.ResponseWriter, r *http.Request) { func (s Service) sendInvoice(w http.ResponseWriter, r *http.Request) { var req sendReq - err := json.NewDecoder(r.Body).Decode(&req) if err != nil { s.sendErrf(w, http.StatusBadRequest, "cannot read body: %v", err) @@ -63,11 +68,16 @@ func (s Service) sendInvoice(w http.ResponseWriter, r *http.Request) { s.sendErr(w, 500, err.Error()) return } - invoice, err := s.invoice.Generate(req.Invoice.Creditor, req.Invoice.Debtor, time.Duration(req.Invoice.DurationThreshold), req.Invoice.HourlyRate, repos) + invoice, report, err := s.invoice.Generate(req.Invoice.Creditor, req.Invoice.Debtor, time.Duration(req.Invoice.DurationThreshold), req.Invoice.HourlyRate, repos) if err != nil { s.sendErr(w, http.StatusInternalServerError, "error while processing invoice:", err) return } + // if no time has to be billed aka if bill for 0 CHF + if report.Total() <= time.Duration(0) { + s.sendErr(w, http.StatusNotFound, "no suitable issues to be billed") + return + } invoiceData, err := io.ReadAll(invoice) if err != nil { diff --git a/internal/api/httpinvoce/resource.go b/internal/api/httpinvoce/resource.go index f8a0e13..952de50 100644 --- a/internal/api/httpinvoce/resource.go +++ b/internal/api/httpinvoce/resource.go @@ -8,6 +8,7 @@ import ( "git.schreifuchs.ch/lou-taylor/accounting/internal/email" "git.schreifuchs.ch/lou-taylor/accounting/pkg/invoice" "git.schreifuchs.ch/lou-taylor/accounting/pkg/invoice/model" + "git.schreifuchs.ch/lou-taylor/accounting/pkg/invoice/report" ) type Service struct { @@ -21,7 +22,7 @@ func New(log *slog.Logger, invoice invoicer, mail mailer) *Service { } type invoicer interface { - Generate(creditor, deptor model.Entity, mindur time.Duration, rate float64, repos []invoice.Repo) (document io.ReadCloser, err error) + Generate(creditor, deptor model.Entity, mindur time.Duration, rate float64, repos []invoice.Repo) (document io.ReadCloser, report report.Report, err error) } type mailer interface { diff --git a/pkg/invoice/invoice.go b/pkg/invoice/invoice.go index 46aab6a..bb5e43c 100644 --- a/pkg/invoice/invoice.go +++ b/pkg/invoice/invoice.go @@ -10,7 +10,7 @@ import ( "git.schreifuchs.ch/lou-taylor/accounting/pkg/invoice/report" ) -func (s *Service) Generate(creditor, deptor model.Entity, mindur time.Duration, rate float64, repos []Repo) (document io.ReadCloser, err error) { +func (s *Service) Generate(creditor, deptor model.Entity, mindur time.Duration, rate float64, repos []Repo) (document io.ReadCloser, r *report.Report, err error) { var is []*gitea.Issue for _, repo := range repos { iss, _, err := s.gitea.ListRepoIssues( @@ -24,7 +24,7 @@ func (s *Service) Generate(creditor, deptor model.Entity, mindur time.Duration, }, ) if err != nil { - return nil, err + return nil, nil, err } is = append(is, iss...) @@ -37,7 +37,7 @@ func (s *Service) Generate(creditor, deptor model.Entity, mindur time.Duration, }, ) issues := issue.FromGiteas(is, mindur) - r := report.New( + r = report.New( issues, creditor, deptor,