Compare commits
23 Commits
1.3.0
..
bc17f7256b
| Author | SHA1 | Date | |
|---|---|---|---|
|
bc17f7256b
|
|||
|
d2f3eea8a5
|
|||
|
f902c61490
|
|||
|
11e8cc5b1d
|
|||
|
84155b7404
|
|||
|
45b37197ec
|
|||
|
f65848924c
|
|||
|
98d584867e
|
|||
|
376e8de1a4
|
|||
|
2911391fb9
|
|||
|
6d2e0241c9
|
|||
|
afc5b1f0c6
|
|||
|
4a76ee469b
|
|||
|
b58bf700df
|
|||
|
efd3a35802
|
|||
|
0f7e44a42a
|
|||
|
f90e5d75fa
|
|||
|
31d4ec5f27
|
|||
|
d61d4d6e7e
|
|||
|
606ce6b940
|
|||
|
750fa70332
|
|||
|
7d503edbc9
|
|||
|
5c9235df8d
|
@@ -11,9 +11,13 @@ CARD_SUBTITLE=Kaya ist cool
|
||||
CARD_BARCODEFORMAT=ean13
|
||||
# CARD_BARCODEPREFIX=
|
||||
|
||||
SPONSOING_RECEIPTMINIMUM=10
|
||||
SPONSORING_RECEIPTMINIMUM=40
|
||||
SPONSORING_DISCLAIMER=Kaya ist cool, aber pass auf, dass du nicht zu viel Geld sammelst!
|
||||
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
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Build latest image
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-container:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Login to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: registry.odit.services
|
||||
username: ${{ vars.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
tags: |
|
||||
${{ vars.REGISTRY }}/lfk/document-server:latest
|
||||
platforms: linux/amd64,linux/arm64
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Build release images
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*.*.*"
|
||||
|
||||
jobs:
|
||||
build-container:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Login to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: registry.odit.services
|
||||
username: ${{ vars.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
tags: |
|
||||
${{ vars.REGISTRY }}/lfk/document-server:${{ github.ref_name }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
@@ -1,18 +0,0 @@
|
||||
steps:
|
||||
- name: build latest
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
repo: registry.odit.services/lfk/document-server
|
||||
tags:
|
||||
- latest
|
||||
registry: registry.odit.services
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache_from: registry.odit.services/lfk/document-server:latest
|
||||
username:
|
||||
from_secret: odit-registry-builder-username
|
||||
password:
|
||||
from_secret: odit-registry-builder-password
|
||||
when:
|
||||
branch: main
|
||||
when:
|
||||
event: push
|
||||
@@ -1,17 +0,0 @@
|
||||
steps:
|
||||
- name: build tag
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
repo: registry.odit.services/lfk/document-server
|
||||
tags:
|
||||
- "${CI_COMMIT_TAG}"
|
||||
registry: registry.odit.services
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache_from: registry.odit.services/lfk/document-server:latest
|
||||
username:
|
||||
from_secret: odit-registry-builder-username
|
||||
password:
|
||||
from_secret: odit-registry-builder-password
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
@@ -326,6 +326,17 @@ const docTemplate = `{
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parent_group": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -317,6 +317,17 @@
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parent_group": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -96,6 +96,13 @@ definitions:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
parent_group:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
+5
-1
@@ -7,14 +7,18 @@ 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"`
|
||||
SponsoringReceiptMinimum int `mapstructure:"SPONSOING_RECEIPTMINIMUM"`
|
||||
SponsoringReceiptMinimum string `mapstructure:"SPONSORING_RECEIPTMINIMUM"`
|
||||
SponosringDisclaimer string `mapstructure:"SPONSORING_DISCLAIMER"`
|
||||
SponsoringBarcodeFormat string `mapstructure:"SPONSORING_BARCODEFORMAT"`
|
||||
SponsoringBarcodePrefix string `mapstructure:"SPONSORING_BARCODEPREFIX"`
|
||||
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
-2
@@ -14,14 +14,17 @@ type Runner struct {
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
ParentGroup struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
} `json:"parent_group" validate:"optional"`
|
||||
}
|
||||
|
||||
type ContractTemplateOptions struct {
|
||||
Runners []Runner `json:"runners"`
|
||||
CurrencySymbol string `json:"currency_symbol"`
|
||||
Disclaimer string `json:"disclaimer"`
|
||||
ReceiptMinimumAmount int `json:"receipt_minimum_amount"`
|
||||
ReceiptMinimumAmount string `json:"receipt_minimum_amount"`
|
||||
EventName string `json:"event_name"`
|
||||
BarcodeFormat string `json:"barcode_format"`
|
||||
BarcodePrefix string `json:"barcode_prefix"`
|
||||
|
||||
+5
-1
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
INST
|
||||
%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)
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Sponsoring contract</title>
|
||||
<title>Läuferkarten</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<style>
|
||||
.sheet {
|
||||
@@ -50,8 +50,12 @@
|
||||
<p style="font-size: 0.6rem; text-align: center; margin: 0; padding: 0;">{{ .Code }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{{ if ne .Runner.FirstName "" }}
|
||||
<p>{{ .Runner.LastName }}, {{ .Runner.FirstName }} {{ .Runner.MiddleName }}</p>
|
||||
<p>{{ .Runner.Group.Name }}</p>
|
||||
<p>{{ if ne .Runner.Group.ParentGroup.Name "" -}}{{ .Runner.Group.ParentGroup.Name }}/{{end -}}{{ .Runner.Group.Name }}</p>
|
||||
{{ else }}
|
||||
<p>Kein Läufer zugewiesen</p>
|
||||
{{ end}}
|
||||
{{ end}}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Sponsoring contract</title>
|
||||
<title>Runner cards</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<style>
|
||||
.sheet {
|
||||
@@ -49,8 +49,12 @@
|
||||
<p style="font-size: 0.6rem; text-align: center; margin: 0; padding: 0;">{{ .Code }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{{ if ne .Runner.FirstName ""}}
|
||||
<p>{{ .Runner.LastName }}, {{ .Runner.FirstName }} {{ .Runner.MiddleName }}</p>
|
||||
<p>{{ .Runner.Group.Name }}</p>
|
||||
<p>{{ if ne .Runner.Group.ParentGroup.Name "" -}}{{ .Runner.Group.ParentGroup.Name }}/{{end -}}{{ .Runner.Group.Name }}</p>
|
||||
{{ else }}
|
||||
<p>Blank card</p>
|
||||
{{ end}}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Sponsoring contract</title>
|
||||
<title>Läuferurkunde</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<style>
|
||||
.sheet {
|
||||
@@ -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 }}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Sponsoring contract</title>
|
||||
<title>Runner certificate</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<style>
|
||||
.sheet {
|
||||
@@ -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>
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
<p style="font-size: x-small; display: block;">Nachname</p>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<span style="border-bottom: 1px solid; width: 100%; display: block;">{{ .Group.Name }}</span>
|
||||
<p style="font-size: x-small; display: block;">Team/ Klasse</p>
|
||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"><p>{{ if ne .Group.ParentGroup.Name "" -}}{{ .Group.ParentGroup.Name }}/ {{end -}}{{ .Group.Name }}</p></span>
|
||||
<p style="font-size: x-small; display: block;">Team/Klasse</p>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin-top: -0.5rem">mit einem Betrag von _____ {{ $.CurrencySymbol }} pro gelaufenem Kilometer zu
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<p style="font-size: x-small; display: block;">Last Name</p>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<span style="border-bottom: 1px solid; width: 100%; display: block;">{{ .Group.Name}}</span>
|
||||
<span style="border-bottom: 1px solid; width: 100%; display: block;"><p>{{ if ne .Group.ParentGroup.Name "" -}}{{ .Group.ParentGroup.Name }}/ {{end -}}{{ .Group.Name }}</p></span>
|
||||
<p style="font-size: x-small; display: block;">Team/class</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user