package invoice import ( "archive/zip" "bytes" "errors" "fmt" "io" "log" "net/http" "os" "os/exec" "dev.tandem.ws/tandem/camper/pkg/auth" "dev.tandem.ws/tandem/camper/pkg/database" "dev.tandem.ws/tandem/camper/pkg/template" ) func mustWriteInvoicesPdf(r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, slugs []string) []byte { buf := new(bytes.Buffer) w := zip.NewWriter(buf) for _, slug := range slugs { inv := mustGetInvoice(r.Context(), conn, company, slug) if inv == nil { continue } f, err := w.Create(fmt.Sprintf("%s-%s.pdf", inv.Number, template.Slugify(inv.Invoicee.Name))) if err != nil { panic(err) } mustWriteInvoicePdf(f, r, user, company, inv) } mustClose(w) return buf.Bytes() } func mustWriteInvoicePdf(w io.Writer, r *http.Request, user *auth.User, company *auth.Company, inv *invoice) { cmd := exec.Command("weasyprint", "--stylesheet", "web/static/invoice.css", "-", "-") var stderr bytes.Buffer cmd.Stderr = &stderr stdin, err := cmd.StdinPipe() if err != nil { panic(err) } stdout, err := cmd.StdoutPipe() if err != nil { panic(err) } defer func() { err := stdout.Close() if !errors.Is(err, os.ErrClosed) { panic(err) } }() if err = cmd.Start(); err != nil { panic(err) } go func() { defer mustClose(stdin) template.MustRenderAdmin(stdin, r, user, company, "invoice/view.gohtml", inv) }() if _, err = io.Copy(w, stdout); err != nil { panic(err) } if err := cmd.Wait(); err != nil { log.Printf("ERR - %v\n", stderr.String()) panic(err) } } func mustClose(closer io.Closer) { if err := closer.Close(); err != nil { panic(err) } }