Files
accounting/internal/api/httpinvoce/controller.go

100 lines
2.3 KiB
Go

package httpinvoce
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"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.sendErrf(w, http.StatusBadRequest, "cannot read body: %v", err)
return
}
repos, err := req.GetRepos()
if err != nil {
s.sendErr(w, 500, err.Error())
return
}
invoice, 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
}
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, 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
}
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"))
}