feat(services): Support for multiple barcode formats 🥳

This commit is contained in:
Nicolai Ort 2024-12-03 18:02:15 +01:00
parent 8812bf2410
commit 62f04f7d1c
Signed by: niggl
GPG Key ID: 13AFA55AF62F269F
4 changed files with 42 additions and 20 deletions

View File

@ -62,6 +62,8 @@ func GenerateContract(c *fiber.Ctx) error {
ReceiptMinimumAmount: 10, ReceiptMinimumAmount: 10,
EventName: "Event name", EventName: "Event name",
SponsoringHeader: templates.ImageSponsoringHeaderBase64, SponsoringHeader: templates.ImageSponsoringHeaderBase64,
BarcodeFormat: "ean13",
BarcodePrefix: "1",
}) })
if err != nil { if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{

View File

@ -6,12 +6,13 @@ import (
"errors" "errors"
"html/template" "html/template"
"image/png" "image/png"
"math"
"strconv" "strconv"
"git.odit.services/lfk/document-server/models" "git.odit.services/lfk/document-server/models"
"github.com/boombuler/barcode" "github.com/boombuler/barcode"
"github.com/boombuler/barcode/code128"
"github.com/boombuler/barcode/ean" "github.com/boombuler/barcode/ean"
"github.com/boombuler/barcode/qr"
) )
type Templater interface { type Templater interface {
@ -29,38 +30,57 @@ type ContractTemplateOptions struct {
ReceiptMinimumAmount int `json:"receipt_minimum_amount"` ReceiptMinimumAmount int `json:"receipt_minimum_amount"`
EventName string `json:"event_name"` EventName string `json:"event_name"`
SponsoringHeader string `json:"base_url"` SponsoringHeader string `json:"base_url"`
BarcodeFormat string `json:"barcode_format"`
BarcodePrefix string `json:"barcode_prefix"`
} }
func idToEan13(id int) (string, error) { func idToEan13(id int, prefix string) (string, error) {
multiply := [2]int{1, 3}
idStr := strconv.Itoa(id) idStr := strconv.Itoa(id)
if len(idStr) > 12 { if len(idStr) > 12 {
return "", errors.New("id too long") return "", errors.New("id too long")
} }
for len(idStr) < 12 {
for len(idStr) < 11 {
idStr = "0" + idStr idStr = "0" + idStr
} }
idStr = prefix + idStr
total := 0 return idStr, nil
for i, char := range idStr { }
num, err := strconv.Atoi(string(char))
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 { if err != nil {
return "", err return "", err
} }
total += num * multiply[i%2] 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")
} }
checkSum := (int(math.Ceil(float64(total)/10)) * 10) - total
return idStr + strconv.Itoa(checkSum), nil
}
func (t *DefaultTemplater) GenerateBarcode(code int) (string, error) { scaledCode, err := barcode.Scale(generatedCode, 1000, 500)
encodedEan, err := idToEan13(code)
eanCode, err := ean.Encode(encodedEan)
if err != nil {
return "", err
}
scaledCode, err := barcode.Scale(eanCode, 100, 50)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -56,7 +56,7 @@
</div> </div>
<div class="column"> <div class="column">
<img style="vertical-align: revert; margin-top: auto; object-fit: cover; max-height: 2cm;" <img style="vertical-align: revert; margin-top: auto; object-fit: cover; max-height: 2cm;"
src="data:image/png;base64,{{ barcode .ID }}" /> src="data:image/png;base64,{{ barcode .ID $.BarcodeFormat $.BarcodePrefix }}" />
</div> </div>
</div> </div>
<div class="columns" style="padding-top: 1rem;"> <div class="columns" style="padding-top: 1rem;">

View File

@ -55,7 +55,7 @@
</div> </div>
<div class="column"> <div class="column">
<img style="vertical-align: revert; margin-top: auto; object-fit: cover; max-height: 2cm;" <img style="vertical-align: revert; margin-top: auto; object-fit: cover; max-height: 2cm;"
src="data:image/png;base64,{{ barcode .ID}}" /> src="data:image/png;base64,{{ barcode .ID $.BarcodeFormat $.BarcodePrefix }}"/>
</div> </div>
</div> </div>
<div class="columns" style="padding-top: 1rem;"> <div class="columns" style="padding-top: 1rem;">