package services import ( "bytes" "encoding/base64" "errors" "html/template" "image/png" "strconv" "git.odit.services/lfk/document-server/models" "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 { } type ContractTemplateOptions struct { Runners []models.Runner `json:"runners"` CurrencySymbol string `json:"currency_symbol"` Disclaimer string `json:"disclaimer"` ReceiptMinimumAmount int `json:"receipt_minimum_amount"` EventName string `json:"event_name"` SponsoringHeader string `json:"base_url"` BarcodeFormat string `json:"barcode_format"` BarcodePrefix string `json:"barcode_prefix"` } func idToEan13(id int, prefix string) (string, error) { idStr := strconv.Itoa(id) if len(idStr) > 12 { return "", errors.New("id too long") } for len(idStr) < 11 { idStr = "0" + idStr } idStr = prefix + idStr return idStr, nil } func (t *DefaultTemplater) GenerateBarcode(code int, 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 + strconv.Itoa(code)) if err != nil { return "", err } break case "qr": generatedCode, err = qr.Encode(prefix+strconv.Itoa(code), qr.M, qr.Numeric) 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) StringToTemplate(templateString string) (*template.Template, error) { return template.New("template").Funcs(template.FuncMap{ "barcode": t.GenerateBarcode, }).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 }