feat(release): beelloo v0.1

This commit is contained in:
2026-02-11 11:09:45 +01:00
parent 75ad1e7cee
commit 0dc9eda240
26 changed files with 1918 additions and 0 deletions

103
internal/render/render.go Normal file
View File

@ -0,0 +1,103 @@
package render
import (
"bytes"
"embed"
"html/template"
"time"
"github.com/russross/blackfriday/v2"
"beelloo/internal/invoice"
)
//go:embed template.html style.css
var assets embed.FS
type renderItem struct {
Designation template.HTML
UnitPrice string
Quantity string
Amount string
}
type renderData struct {
Seller invoice.Party
Buyer invoice.Party
Invoice invoice.InvoiceInfo
InvoiceDate string
InvoiceDescription template.HTML
Items []renderItem
TotalExclTax string
Payment invoice.PaymentInfo
CSS template.CSS
CSSHref string
}
func RenderHTML(doc invoice.Document) (string, error) {
cssBytes, err := assets.ReadFile("style.css")
if err != nil {
return "", err
}
return RenderHTMLWithCSS(doc, string(cssBytes))
}
func RenderHTMLWithCSS(doc invoice.Document, css string) (string, error) {
return renderHTML(doc, css, "")
}
func RenderHTMLWithCSSLink(doc invoice.Document, href string) (string, error) {
return renderHTML(doc, "", href)
}
func renderHTML(doc invoice.Document, css string, href string) (string, error) {
invoice.ComputeTotals(&doc)
tmplBytes, err := assets.ReadFile("template.html")
if err != nil {
return "", err
}
tmpl, err := template.New("invoice").Parse(string(tmplBytes))
if err != nil {
return "", err
}
data := renderData{
Seller: doc.Seller,
Buyer: doc.Buyer,
Invoice: doc.Invoice,
InvoiceDate: formatDate(doc.Invoice.Date),
InvoiceDescription: markdownHTML(doc.Invoice.Description),
TotalExclTax: invoice.FormatMoney(doc.Totals.TotalExclTax),
Payment: doc.Payment,
CSS: template.CSS(css),
CSSHref: href,
}
for _, item := range doc.Items {
data.Items = append(data.Items, renderItem{
Designation: markdownHTML(item.Designation),
UnitPrice: invoice.FormatMoney(item.UnitPrice),
Quantity: invoice.FormatQuantity(item.Quantity),
Amount: invoice.FormatMoney(invoice.LineAmount(item)),
})
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
return "", err
}
return buf.String(), nil
}
func DefaultCSS() ([]byte, error) {
return assets.ReadFile("style.css")
}
func markdownHTML(input string) template.HTML {
output := blackfriday.Run([]byte(input))
return template.HTML(output)
}
func formatDate(date time.Time) string {
if date.IsZero() {
return ""
}
return date.Format("02/01/2006")
}