package services import ( "bytes" "encoding/base64" "errors" "fmt" "html/template" "image/png" "git.odit.services/lfk/document-server/templates" "github.com/boombuler/barcode" "github.com/boombuler/barcode/code128" "github.com/boombuler/barcode/ean" "github.com/boombuler/barcode/qr" ) type Templater interface { Execute(template *template.Template, data interface{}) (string, error) StringToTemplate(templateString string) (*template.Template, error) } type DefaultTemplater struct { } func idToEan13(id string, prefix string) (string, error) { if len(id) > 12 { return "", errors.New("id too long") } for len(id) < 11 { id = "0" + id } id = prefix + id return id, nil } func (t *DefaultTemplater) GenerateBarcode(code string, format string, prefix string) (string, error) { var generatedCode barcode.Barcode var err error switch format { case "ean13": encodedEan, err := idToEan13(code, prefix) if err != nil { return "", err } generatedCode, err = ean.Encode(encodedEan) if err != nil { return "", err } break case "code128": generatedCode, err = code128.Encode(prefix + code) if err != nil { return "", err } break case "qr": generatedCode, err = qr.Encode(prefix+code, qr.M, qr.AlphaNumeric) if err != nil { return "", err } break default: return "", errors.New("unknown barcode format") } scaledCode, err := barcode.Scale(generatedCode, 1000, 500) if err != nil { return "", err } var buf bytes.Buffer err = png.Encode(&buf, scaledCode) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(buf.Bytes()), nil } func (t *DefaultTemplater) SelectSponsorImage(id int) (string, error) { sponsors := []string{ "vrbank", "odit", "sparkasse", } return templates.GetImage(sponsors[id%len(sponsors)]), nil } func FormatUnit(unit string, amount int) (string, error) { switch unit { case "kilometer": return fmt.Sprintf("%.3f", float64(amount)/1000), nil case "euro": return fmt.Sprintf("%.2f", float64(amount)/100), nil default: return "", errors.New("unknown unit") } } func (t *DefaultTemplater) StringToTemplate(templateString string) (*template.Template, error) { return template.New("template").Funcs(template.FuncMap{ "barcode": t.GenerateBarcode, "sponsorLogo": t.SelectSponsorImage, "formatUnit": FormatUnit, }).Parse(templateString) } func (t *DefaultTemplater) Execute(baseTemplate *template.Template, data interface{}) (string, error) { resultBuffer := new(bytes.Buffer) err := baseTemplate.Execute(resultBuffer, data) if err != nil { return "", err } return resultBuffer.String(), nil }