diff --git a/go.mod b/go.mod index 2cc0cdd..ef24c89 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/andybalholm/brotli v1.1.1 // indirect + github.com/boombuler/barcode v1.0.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/spec v0.21.0 // indirect @@ -21,6 +22,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/makiuchi-d/gozxing v0.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect @@ -32,5 +34,6 @@ require ( github.com/valyala/tcplisten v1.0.0 // indirect golang.org/x/sys v0.27.0 // indirect golang.org/x/tools v0.27.0 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0a11074..3505c93 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= +github.com/boombuler/barcode v1.0.2 h1:79yrbttoZrLGkL/oOI8hBrUKucwOL0oOjUgEguGMcJ4= +github.com/boombuler/barcode v1.0.2/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -28,6 +30,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/makiuchi-d/gozxing v0.1.1 h1:xxqijhoedi+/lZlhINteGbywIrewVdVv2wl9r5O9S1I= +github.com/makiuchi-d/gozxing v0.1.1/go.mod h1:eRIHbOjX7QWxLIDJoQuMLhuXg9LAuw6znsUtRkNw9DU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -68,6 +72,8 @@ golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/handlers/contract.go b/handlers/contract.go index f522919..4485194 100644 --- a/handlers/contract.go +++ b/handlers/contract.go @@ -41,13 +41,20 @@ func GenerateContract(c *fiber.Ctx) error { contract.Runners = duplicatedRunners generator := services.DefaultTemplater{} - template, err := templates.GetTemplate(contract.Locale, "contract") + templateString, err := templates.GetTemplate(contract.Locale, "contract") if err != nil { log.Println(err) return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Template not found", }) } + template, err := generator.StringToTemplate(templateString) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": err.Error(), + }) + } + result, err := generator.Execute(template, &services.ContractTemplateOptions{ Runners: contract.Runners, CurrencySymbol: "€", diff --git a/services/templater.go b/services/templater.go index 6fd9688..c0a7cdf 100644 --- a/services/templater.go +++ b/services/templater.go @@ -2,13 +2,21 @@ package services import ( "bytes" + "encoding/base64" + "errors" "html/template" + "image/png" + "math" + "strconv" "git.odit.services/lfk/document-server/models" + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/ean" ) type Templater interface { Execute(template *template.Template, data interface{}) (string, error) + StringToTemplate(templateString string) (*template.Template, error) } type DefaultTemplater struct { @@ -23,10 +31,59 @@ type ContractTemplateOptions struct { SponsoringHeader string `json:"base_url"` } -func (t *DefaultTemplater) Execute(template *template.Template, data interface{}) (string, error) { +func idToEan13(id int) (string, error) { + multiply := [2]int{1, 3} + idStr := strconv.Itoa(id) + + if len(idStr) > 12 { + return "", errors.New("id too long") + } + for len(idStr) < 12 { + idStr = "0" + idStr + } + + total := 0 + for i, char := range idStr { + num, err := strconv.Atoi(string(char)) + if err != nil { + return "", err + } + total += num * multiply[i%2] + } + checkSum := (int(math.Ceil(float64(total)/10)) * 10) - total + return idStr + strconv.Itoa(checkSum), nil +} + +func (t *DefaultTemplater) GenerateBarcode(code int) (string, error) { + encodedEan, err := idToEan13(code) + eanCode, err := ean.Encode(encodedEan) + if err != nil { + return "", err + } + scaledCode, err := barcode.Scale(eanCode, 100, 50) + 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 := template.Execute(resultBuffer, data) + err := baseTemplate.Execute(resultBuffer, data) if err != nil { return "", err } diff --git a/templates/contract/de.html b/templates/contract/de.html index 2a67633..f8bd4ec 100644 --- a/templates/contract/de.html +++ b/templates/contract/de.html @@ -56,7 +56,7 @@