Compare commits

..
11 Commits
Author SHA1 Message Date
philipp f902c61490 feat(certificate): update footer image
Build release images / build-container (push) Successful in 2m13s
Build latest image / build-container (push) Successful in 2m19s
2025-04-23 11:57:44 +02:00
niggl 11e8cc5b1d feat(certificate): Add SepaConfig to certificate generation and CombinedGroupName to runners
Build release images / build-container (push) Successful in 1m57s
Build latest image / build-container (push) Successful in 2m22s
2025-04-17 22:22:50 +02:00
niggl 84155b7404 feat(templater): Add GenerateEPC method for generating EPC QR codes 2025-04-17 22:22:46 +02:00
niggl 45b37197ec feat(models): Add CombinedGroupName to RunnerWithDonations and introduce SepaConfig struct 2025-04-17 22:22:43 +02:00
niggl f65848924c feat(templates): Update donation transfer text and add SEPA support in certificate templates 2025-04-17 22:22:37 +02:00
niggl 98d584867e feat(config): Add SEPA fields to environment configuration 2025-04-17 22:22:29 +02:00
niggl 376e8de1a4 feat(config): Add CurrencyIdentifier to configuration 2025-04-17 22:01:02 +02:00
niggl 2911391fb9 feat(config): Add SEPA fields to configuration 2025-04-17 21:51:27 +02:00
niggl 6d2e0241c9 feat(templates): Added selfservice qr
Build release images / build-container (push) Successful in 2m12s
Build latest image / build-container (push) Successful in 2m26s
2025-04-17 21:44:58 +02:00
niggl afc5b1f0c6 fix(models): Add required SelfServiceLink field to RunnerWithDonations struct 2025-04-17 21:43:54 +02:00
niggl 4a76ee469b fix(barcode): Use auto encoding for QR code generation to support all characters 2025-04-17 21:43:44 +02:00
10 changed files with 108 additions and 11 deletions

No files matched your search

+5 -1
View File
@@ -16,4 +16,8 @@ SPONSORING_DISCLAIMER=Kaya ist cool, aber pass auf, dass du nicht zu viel Geld s
SPONSORING_BARCODEFORMAT=code128
# SPONSORING_BARCODEPREFIX=
CERTIFICATE_FOOTER=Kaya ist cool, danke für deine Unterstützung!
CERTIFICATE_FOOTER=Kaya ist cool, danke für deine Unterstützung!
SEPA_BIC=FNOMDEB2
SEPA_NAME=ODIT.Services
SEPA_IBAN=DE25100180000690238989
+13
View File
@@ -58,6 +58,12 @@ func (h *DefaultHandler) GenerateCertificate(c *fiber.Ctx) error {
Footer: h.Config.CertificateFooter,
CurrencySymbol: h.Config.CurrencySymbol,
Locale: certificateRequest.Locale,
SepaConfig: &models.SepaConfig{
BIC: h.Config.SepaBic,
HolderName: h.Config.SepaName,
IBAN: h.Config.SepaIban,
CurrencyIdentifier: h.Config.CurrencyIdentifier,
},
}
logger.Info("Generating certificate html")
@@ -90,6 +96,13 @@ func addUpRunnerDonations(runners []models.RunnerWithDonations) []models.RunnerW
runners[i].TotalDonations += runners[i].DistanceDonations[j].Amount
runners[i].TotalPerDistance += runners[i].DistanceDonations[j].AmountPerDistance
}
if runners[i].Group.ParentGroup.Name != "" {
runners[i].CombinedGroupName = runners[i].Group.ParentGroup.Name + " - " + runners[i].Group.Name
} else {
runners[i].CombinedGroupName = runners[i].Group.Name
}
}
return runners
}
+4
View File
@@ -44,6 +44,7 @@ func loadEnv() error {
viper.SetDefault("APIKEY", "lfk")
viper.SetDefault("EVENTNAME", "Demo Event")
viper.SetDefault("CURRENCYSYMBOL", "€")
viper.SetDefault("CURRENCYIDENTIFIER", "EUR")
viper.SetDefault("CARD_SUBTITLE", "Runner Card")
viper.SetDefault("CARD_BARCODEFORMAT", "ean13")
viper.SetDefault("CARD_BARCODEPREFIX", "")
@@ -54,6 +55,9 @@ func loadEnv() error {
viper.SetDefault("CERTIFICATE_FOOTER", "Footer")
viper.SetDefault("GOTENBERG_BASEURL", "")
viper.SetDefault("REDIS_ADDR", "")
viper.SetDefault("SEPA_BIC", "")
viper.SetDefault("SEPA_NAME", "")
viper.SetDefault("SEPA_IBAN", "")
// Load .env file
viper.SetConfigFile(".env")
+10
View File
@@ -11,10 +11,12 @@ type RunnerWithDonations struct {
MiddleName string `json:"middle_name" validate:"optional"`
LastName string `json:"last_name" validate:"required"`
Group Group `json:"group" validate:"required"`
CombinedGroupName string `json:"combined_group_name" validate:"optional"`
Distance int `json:"distance" validate:"required"`
DistanceDonations []DistanceDonation `json:"distance_donations" validate:"optional"`
TotalPerDistance int `json:"total_per_distance" validate:"optional"`
TotalDonations int `json:"total_donations" validate:"optional"`
SelfServiceLink string `json:"self_service_link" validate:"required"`
}
type DistanceDonation struct {
@@ -38,4 +40,12 @@ type CertificateTemplateOptions struct {
Footer string `json:"footer"`
CurrencySymbol string `json:"currency_symbol"`
Locale string `json:"locale"`
SepaConfig *SepaConfig `json:"sepa_config"`
}
type SepaConfig struct {
IBAN string `json:"iban" validate:"required"`
HolderName string `json:"holder_name" validate:"required"`
BIC string `json:"bic" validate:"required"`
CurrencyIdentifier string `json:"currency_identifier" validate:"required"`
}
+4
View File
@@ -7,6 +7,7 @@ type Config struct {
APIKey string `mapstructure:"APIKEY"`
EventName string `mapstructure:"EVENTNAME"`
CurrencySymbol string `mapstructure:"CURRENCYSYMBOL"`
CurrencyIdentifier string `mapstructure:"CURRENCYIDENTIFIER"`
CardSubtitle string `mapstructure:"CARD_SUBTITLE"`
CardBarcodeFormat string `mapstructure:"CARD_BARCODEFORMAT"`
CardBarcodePrefix string `mapstructure:"CARD_BARCODEPREFIX"`
@@ -17,4 +18,7 @@ type Config struct {
CertificateFooter string `mapstructure:"CERTIFICATE_FOOTER"`
GotenbergBaseUrl string `mapstructure:"GOTENBERG_BASEURL"`
RedisAddr string `mapstructure:"REDIS_ADDR"`
SepaBic string `mapstructure:"SEPA_BIC"`
SepaName string `mapstructure:"SEPA_NAME"`
SepaIban string `mapstructure:"SEPA_IBAN"`
}
+5 -1
View File
@@ -69,7 +69,11 @@ func (b *DefaultBarcodeService) GenerateBarcode(format string, content string, w
}
break
case "qr":
generatedCode, err = qr.Encode(content, qr.M, qr.AlphaNumeric)
// Always use qr.Auto encoding to support all characters in the content
encoding := qr.Auto
// QR code generation with error correction level M and auto encoding
generatedCode, err = qr.Encode(content, qr.M, encoding)
if err != nil {
return bytes.Buffer{}, err
}
+23
View File
@@ -35,6 +35,28 @@ func idToEan13(id string, prefix string) (string, error) {
return id, nil
}
func (t *DefaultTemplater) GenerateEPC(iban string, bic string, name string, title string, amount int, currency string) (string, error) {
var err error
code := fmt.Sprintf(`
BCD
002
1
SCT
%s
%s
%s
%s%.2f
%s
`, bic, name, iban, currency, float64(amount)/100, title,
)
buf, err := t.BarcodeService.GenerateBarcode("qr", code, 500, 500, 0)
return base64.StdEncoding.EncodeToString(buf.Bytes()), err
}
func (t *DefaultTemplater) GenerateBarcode(code string, format string, prefix string) (string, error) {
var err error
@@ -88,6 +110,7 @@ func (t *DefaultTemplater) StringToTemplate(templateString string) (*template.Te
"sponsorLogo": t.SelectSponsorImage,
"formatUnit": t.FormatUnit,
"loadImage": t.LoadImage,
"epcCode": t.GenerateEPC,
}).Parse(templateString)
}
+1 -1
View File
@@ -1 +1 @@
iVBORw0KGgoAAAANSUhEUgAAApQAAACWCAYAAABgmBgeAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFHGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIxLTAzLTMxVDE0OjEyOjMzKzAyOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMS0wMy0zMVQxNDoxMzozMyswMjowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMS0wMy0zMVQxNDoxMzozMyswMjowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpmZDhjZTFlZi1lMTAy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 truncated
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 truncated
+24 -7
View File
@@ -87,13 +87,30 @@
<td>Gesamt</td>
<td>{{ formatUnit "euro" $.Locale .TotalPerDistance }} {{ $.CurrencySymbol }}</td>
<td>{{ formatUnit "euro" $.Locale .TotalDonations }} {{ $.CurrencySymbol }}</td>
</tfoot>
</table>
</main>
<footer class="certificate-footer">
<p>
{{ $.Footer }}
</p>
</table>
</main>
<footer class="certificate-footer">
<table style="border-collapse: collapse; border: none; width: 17cm;">
<thead>
<tr>
<th style="border: none; width: 50%; text-align: center;">Link zu deinen Rundenzeiten</th>
<th style="border: none; width: 50%; text-align: center;">Spende überweisen</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: none; text-align: center;">
<img src="data:image/png;base64,{{ barcode .SelfServiceLink "qr" "" }}" style="height: 2.5cm; padding: 0.2cm">
</td>
<td style="border: none; text-align: center;">
<img src="data:image/png;base64,{{ epcCode $.SepaConfig.IBAN $.SepaConfig.BIC $.SepaConfig.HolderName (print "Sponsoring für " .FirstName " " .LastName ", " .CombinedGroupName) .TotalDonations $.SepaConfig.CurrencyIdentifier}}" style="height: 2.5cm; padding: 0.2cm">
</td>
</tr>
</tbody>
</table>
<p style="width: 17cm; text-align: center;">
{{ $.Footer }}
</p>
</footer>
</article>
{{ end }}
+19 -1
View File
@@ -91,7 +91,25 @@
</table>
</main>
<footer class="certificate-footer">
<p>
<table style="border-collapse: collapse; border: none; width: 17cm;">
<thead>
<tr>
<th style="border: none; width: 50%; text-align: center;">Link to your lap times</th>
<th style="border: none; width: 50%; text-align: center;">Transfer donation via SEPA</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: none; text-align: center;">
<img src="data:image/png;base64,{{ barcode .SelfServiceLink "qr" "" }}" style="height: 2.5cm; padding: 0.2cm">
</td>
<td style="border: none; text-align: center;">
<img src="data:image/png;base64,{{ epcCode $.SepaConfig.IBAN $.SepaConfig.BIC $.SepaConfig.HolderName (print "Sponsoring for " .FirstName " " .LastName ", " .CombinedGroupName) .TotalDonations $.SepaConfig.CurrencyIdentifier}}" style="height: 2.5cm; padding: 0.2cm">
</td>
</tr>
</tbody>
</table>
<p style="width: 17cm; text-align: center;">
{{ $.Footer }}
</p>
</footer>