package httpinvoce import ( "bytes" "encoding/json" "fmt" "io" "net/http" "time" "git.schreifuchs.ch/lou-taylor/accounting/internal/email" ) const bufSize = 1024 * 1024 // 1Mib func (s Service) createInvoice(w http.ResponseWriter, r *http.Request) { var req invoiceReq err := json.NewDecoder(r.Body).Decode(&req) if err != nil { s.sendErr(w, http.StatusBadRequest, "cannot read body") return } repos, err := req.GetRepos() if err != nil { s.sendErr(w, http.StatusInternalServerError, "cannot get repos") return } invoice, report, err := s.invoice.Generate(req.Creditor, &req.Debtor, time.Duration(req.DurationThreshold), req.HourlyRate, repos) if err != nil { s.sendErr(w, http.StatusInternalServerError, "internal server error") return } // if no time has to be billed aka if bill for 0 CHF if report.Total() <= time.Duration(0) { s.sendErrf(w, http.StatusNotFound, "no suitable issues to be billed") return } w.Header().Set("Content-type", "application/pdf") w.Header().Set( "Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", invoiceName()), ) _, err = io.Copy(w, invoice) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } } 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) return } repos, err := req.Invoice.GetRepos() if err != nil { s.sendErr(w, 500, err.Error()) return } 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 { s.sendErrf(w, http.StatusInternalServerError, "error while creating pdf: %v", err) return } mail := req.ToEMail() mail.Attachments = append(mail.Attachments, email.Attachment{ Name: invoiceName(), MimeType: "application/pdf", Content: bytes.NewReader(invoiceData), }) err = s.mail.Send(mail) if err != nil { s.sendErrf(w, http.StatusInternalServerError, "error while sending mail: %v", err) return } _, err = w.Write(invoiceData) if err != nil { s.sendErr(w, http.StatusInternalServerError, "") } } func invoiceName() string { return fmt.Sprintf("%s_invoice.pdf", time.Now().Format("20060102")) }