Compare commits
No commits in common. "main" and "1.3.0" have entirely different histories.
8
.env
8
.env
@ -11,13 +11,9 @@ CARD_SUBTITLE=Kaya ist cool
|
||||
CARD_BARCODEFORMAT=ean13
|
||||
# CARD_BARCODEPREFIX=
|
||||
|
||||
SPONSORING_RECEIPTMINIMUM=40
|
||||
SPONSOING_RECEIPTMINIMUM=10
|
||||
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!
|
||||
|
||||
SEPA_BIC=FNOMDEB2
|
||||
SEPA_NAME=ODIT.Services
|
||||
SEPA_IBAN=DE25100180000690238989
|
||||
CERTIFICATE_FOOTER=Kaya ist cool, danke für deine Unterstützung!
|
@ -1,27 +0,0 @@
|
||||
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
|
@ -1,27 +0,0 @@
|
||||
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
|
18
.woodpecker/build.yml
Normal file
18
.woodpecker/build.yml
Normal file
@ -0,0 +1,18 @@
|
||||
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
|
17
.woodpecker/release.yml
Normal file
17
.woodpecker/release.yml
Normal file
@ -0,0 +1,17 @@
|
||||
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
|
@ -8,9 +8,8 @@ RUN go mod download
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -o server
|
||||
|
||||
FROM alpine:3.18
|
||||
RUN mkdir -p /tmp && chmod 1777 /tmp
|
||||
|
||||
FROM scratch
|
||||
COPY --from=builder /app/server /server
|
||||
COPY static /static
|
||||
ADD https://curl.haxx.se/ca/cacert.pem /etc/ssl/certs/ca-certificates.crt
|
||||
ENTRYPOINT [ "/server" ]
|
11
docs/docs.go
11
docs/docs.go
@ -326,17 +326,6 @@ const docTemplate = `{
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parent_group": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -317,17 +317,6 @@
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parent_group": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -96,13 +96,6 @@ definitions:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
parent_group:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
|
16
go.mod
16
go.mod
@ -23,11 +23,8 @@ require (
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hhrutter/lzw v1.0.0 // indirect
|
||||
github.com/hhrutter/pkcs7 v0.2.0 // indirect
|
||||
github.com/hhrutter/tiff v1.0.2 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/makiuchi-d/gozxing v0.1.1 // indirect
|
||||
@ -36,9 +33,7 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/oxplot/papersizes v0.0.0-20181201065918-90a3a5ae1915 // indirect
|
||||
github.com/pdfcpu/pdfcpu v0.10.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.7.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
@ -51,19 +46,16 @@ require (
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/swaggo/files/v2 v2.0.1 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.61.0 // indirect
|
||||
github.com/valyala/fasthttp v1.57.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.37.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/image v0.26.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
golang.org/x/tools v0.27.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
24
go.sum
24
go.sum
@ -29,18 +29,10 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hhrutter/lzw v1.0.0 h1:laL89Llp86W3rRs83LvKbwYRx6INE8gDn0XNb1oXtm0=
|
||||
github.com/hhrutter/lzw v1.0.0/go.mod h1:2HC6DJSn/n6iAZfgM3Pg+cP1KxeWc3ezG8bBqW5+WEo=
|
||||
github.com/hhrutter/pkcs7 v0.2.0 h1:i4HN2XMbGQpZRnKBLsUwO3dSckzgX142TNqY/KfXg+I=
|
||||
github.com/hhrutter/pkcs7 v0.2.0/go.mod h1:aEzKz0+ZAlz7YaEMY47jDHL14hVWD6iXt0AgqgAvWgE=
|
||||
github.com/hhrutter/tiff v1.0.2 h1:7H3FQQpKu/i5WaSChoD1nnJbGx4MxU5TlNqqpxw55z8=
|
||||
github.com/hhrutter/tiff v1.0.2/go.mod h1:pcOeuK5loFUE7Y/WnzGw20YxUdnqjY1P0Jlcieb/cCw=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@ -62,12 +54,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/oxplot/papersizes v0.0.0-20181201065918-90a3a5ae1915 h1:4WzMzgExTgBfuUQ/HegMf+jcHtH+c3fl7eySUQUbfzg=
|
||||
github.com/oxplot/papersizes v0.0.0-20181201065918-90a3a5ae1915/go.mod h1:LJRTnhoARxQgMyT7T9L+ZzwR4OrmyHTy5LPxZEzE1CM=
|
||||
github.com/pdfcpu/pdfcpu v0.10.2 h1:DB2dWuoq0eF0QwHjgyLirYKLTCzFOoZdmmIUSu72aL0=
|
||||
github.com/pdfcpu/pdfcpu v0.10.2/go.mod h1:Q2Z3sqdRqHTdIq1mPAUl8nfAoim8p3c1ASOaQ10mCpE=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||
@ -111,8 +99,6 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.57.0 h1:Xw8SjWGEP/+wAAgyy5XTvgrWlOD1+TxbbvNADYCm1Tg=
|
||||
github.com/valyala/fasthttp v1.57.0/go.mod h1:h6ZBaPRlzpZ6O3H5t2gEk1Qi33+TmLvfwgLLp0t9CpE=
|
||||
github.com/valyala/fasthttp v1.61.0 h1:VV08V0AfoRaFurP1EWKvQQdPTZHiUzaVoulX1aBDgzU=
|
||||
github.com/valyala/fasthttp v1.61.0/go.mod h1:wRIV/4cMwUPWnRcDno9hGnYZGh78QzODFfo1LTUhBog=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
@ -125,12 +111,8 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY=
|
||||
golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
@ -139,12 +121,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
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=
|
||||
@ -155,8 +133,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
112
handlers/card.go
112
handlers/card.go
@ -1,14 +1,10 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
|
||||
"git.odit.services/lfk/document-server/models"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/pdfcpu/pdfcpu/pkg/api"
|
||||
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
|
||||
)
|
||||
|
||||
// GenerateCard godoc
|
||||
@ -22,6 +18,7 @@ import (
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /v1/pdfs/cards [post]
|
||||
func (h *DefaultHandler) GenerateCard(c *fiber.Ctx) error {
|
||||
|
||||
logger := h.Logger.Named("GenerateCard")
|
||||
|
||||
cardRequest := new(models.CardRequest)
|
||||
@ -55,115 +52,38 @@ func (h *DefaultHandler) GenerateCard(c *fiber.Ctx) error {
|
||||
})
|
||||
}
|
||||
|
||||
segmentLength := calculateOptimalSegmentSize(len(cardRequest.Cards))
|
||||
pdfs := []string{}
|
||||
for i := 0; i < len(cardRequest.Cards); i += segmentLength {
|
||||
|
||||
segment := cardRequest.Cards[i:]
|
||||
if len(segment) > segmentLength {
|
||||
segment = cardRequest.Cards[i : i+segmentLength]
|
||||
}
|
||||
|
||||
genConfig := &models.CardTemplateOptions{
|
||||
CardSegments: splitCardSegments(segment),
|
||||
EventName: h.Config.EventName,
|
||||
CardSubtitle: h.Config.CardSubtitle,
|
||||
BarcodeFormat: h.Config.CardBarcodeFormat,
|
||||
BarcodePrefix: h.Config.CardBarcodePrefix,
|
||||
}
|
||||
|
||||
logger.Info("Generating card html")
|
||||
result, err := h.Templater.Execute(template, genConfig)
|
||||
if err != nil {
|
||||
logger.Errorw("Error executing template", "error", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
logger.Info("Generated card html")
|
||||
c.Set(fiber.HeaderContentType, "text/html")
|
||||
|
||||
logger.Info("Converting html to pdf")
|
||||
pdf, err := h.Converter.ToPdf(result, "a4", false)
|
||||
if err != nil {
|
||||
logger.Errorw("Error converting html to pdf", "error", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
tempFile, err := os.CreateTemp("", fmt.Sprintf("cards-%d-*.pdf", i/segmentLength))
|
||||
if err != nil {
|
||||
logger.Errorw("Error creating temp file", "error", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
defer os.Remove(tempFile.Name()) // Ensure cleanup even on error paths
|
||||
|
||||
if _, err := tempFile.Write(pdf); err != nil {
|
||||
logger.Errorw("Error writing pdf to temp file", "error", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
tempFile.Close()
|
||||
pdfs = append(pdfs, tempFile.Name())
|
||||
genConfig := &models.CardTemplateOptions{
|
||||
CardSegments: splitCardSegments(cardRequest.Cards),
|
||||
EventName: h.Config.EventName,
|
||||
CardSubtitle: h.Config.CardSubtitle,
|
||||
BarcodeFormat: h.Config.CardBarcodeFormat,
|
||||
BarcodePrefix: h.Config.CardBarcodePrefix,
|
||||
}
|
||||
|
||||
outputFile := "./output.pdf"
|
||||
conf := model.NewDefaultConfiguration()
|
||||
err = api.MergeCreateFile(pdfs, outputFile, false, conf)
|
||||
logger.Info("Generating card html")
|
||||
result, err := h.Templater.Execute(template, genConfig)
|
||||
if err != nil {
|
||||
logger.Errorw("Failed to merge PDFs", "error", err)
|
||||
logger.Errorw("Error executing template", "error", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
logger.Info("Generated card html")
|
||||
c.Set(fiber.HeaderContentType, "text/html")
|
||||
|
||||
// Clean up individual PDF files
|
||||
for _, file := range pdfs {
|
||||
if err := os.Remove(file); err != nil {
|
||||
logger.Warnw("Failed to remove temporary PDF file", "file", file, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Set headers and return the merged PDF
|
||||
c.Set(fiber.HeaderContentType, "application/pdf")
|
||||
c.Set(fiber.HeaderContentDisposition, "attachment; filename=runner-cards.pdf")
|
||||
pdfBytes, err := os.ReadFile(outputFile)
|
||||
logger.Info("Converting html to pdf")
|
||||
pdf, err := h.Converter.ToPdf(result, "a4", false)
|
||||
if err != nil {
|
||||
logger.Errorw("Failed to read merged PDF", "error", err)
|
||||
logger.Errorw("Error converting html to pdf", "error", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
os.Remove(outputFile) // Clean up the merged file
|
||||
|
||||
logger.Info("Converted html to pdf")
|
||||
|
||||
c.Set(fiber.HeaderContentType, "application/pdf")
|
||||
c.Set(fiber.HeaderContentDisposition, "attachment; filename=runner-cards.pdf")
|
||||
return c.Send(pdfBytes)
|
||||
}
|
||||
|
||||
func calculateOptimalSegmentSize(totalCards int) int {
|
||||
if totalCards < 30 {
|
||||
return 25 // Reduces overhead for really small batches
|
||||
}
|
||||
|
||||
// Base size for small batches
|
||||
if totalCards < 100 {
|
||||
return 50
|
||||
}
|
||||
|
||||
// For medium batches
|
||||
if totalCards < 500 {
|
||||
return 75
|
||||
}
|
||||
|
||||
// For large batches, be more conservative
|
||||
return 100
|
||||
return c.Send(pdf)
|
||||
}
|
||||
|
||||
func invertCardArrayItemPairs(cards []models.Card) []models.Card {
|
||||
|
@ -58,12 +58,6 @@ 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")
|
||||
@ -96,13 +90,6 @@ 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
main.go
4
main.go
@ -44,7 +44,6 @@ 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", "")
|
||||
@ -55,9 +54,6 @@ 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,12 +11,10 @@ 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 {
|
||||
@ -40,12 +38,4 @@ 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"`
|
||||
}
|
||||
|
@ -7,18 +7,14 @@ 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 string `mapstructure:"SPONSORING_RECEIPTMINIMUM"`
|
||||
SponsoringReceiptMinimum int `mapstructure:"SPONSOING_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"`
|
||||
}
|
||||
|
@ -14,17 +14,14 @@ type Runner struct {
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
ParentGroup struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
} `json:"parent_group" validate:"optional"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type ContractTemplateOptions struct {
|
||||
Runners []Runner `json:"runners"`
|
||||
CurrencySymbol string `json:"currency_symbol"`
|
||||
Disclaimer string `json:"disclaimer"`
|
||||
ReceiptMinimumAmount string `json:"receipt_minimum_amount"`
|
||||
ReceiptMinimumAmount int `json:"receipt_minimum_amount"`
|
||||
EventName string `json:"event_name"`
|
||||
BarcodeFormat string `json:"barcode_format"`
|
||||
BarcodePrefix string `json:"barcode_prefix"`
|
||||
|
@ -69,11 +69,7 @@ func (b *DefaultBarcodeService) GenerateBarcode(format string, content string, w
|
||||
}
|
||||
break
|
||||
case "qr":
|
||||
// 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)
|
||||
generatedCode, err = qr.Encode(content, qr.M, qr.AlphaNumeric)
|
||||
if err != nil {
|
||||
return bytes.Buffer{}, err
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@ -36,28 +35,6 @@ 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
|
||||
|
||||
@ -90,24 +67,9 @@ func (t *DefaultTemplater) LoadImage(name string) (string, error) {
|
||||
|
||||
func (t *DefaultTemplater) FormatUnit(unit string, locale string, amount int) (string, error) {
|
||||
var formatted string
|
||||
var seperator string
|
||||
switch locale {
|
||||
case "de":
|
||||
seperator = " "
|
||||
default:
|
||||
seperator = ""
|
||||
}
|
||||
switch unit {
|
||||
case "kilometer":
|
||||
if amount < 1000 {
|
||||
formatted = fmt.Sprintf("%d%sm", amount, seperator)
|
||||
} else if (amount % 1000) == 0 {
|
||||
formatted = fmt.Sprintf("%d%skm", amount/1000, seperator)
|
||||
} else {
|
||||
kilometers := math.Floor(float64(amount) / 1000)
|
||||
meters := amount - int(kilometers)*1000
|
||||
formatted = fmt.Sprintf("%d%skm %d%sm", int(kilometers), seperator, meters, seperator)
|
||||
}
|
||||
formatted = fmt.Sprintf("%.3f", float64(amount)/1000)
|
||||
case "euro":
|
||||
formatted = fmt.Sprintf("%.2f", float64(amount)/100)
|
||||
default:
|
||||
@ -126,7 +88,6 @@ 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>Läuferkarten</title>
|
||||
<title>Sponsoring contract</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<style>
|
||||
.sheet {
|
||||
@ -50,12 +50,8 @@
|
||||
<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>{{ if ne .Runner.Group.ParentGroup.Name "" -}}{{ .Runner.Group.ParentGroup.Name }}/{{end -}}{{ .Runner.Group.Name }}</p>
|
||||
{{ else }}
|
||||
<p>Läufer:in</p>
|
||||
{{ end}}
|
||||
<p>{{ .Runner.Group.Name }}</p>
|
||||
{{ end}}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Runner cards</title>
|
||||
<title>Sponsoring contract</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<style>
|
||||
.sheet {
|
||||
@ -49,12 +49,8 @@
|
||||
<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>{{ if ne .Runner.Group.ParentGroup.Name "" -}}{{ .Runner.Group.ParentGroup.Name }}/{{end -}}{{ .Runner.Group.Name }}</p>
|
||||
{{ else }}
|
||||
<p>Runner</p>
|
||||
{{ end}}
|
||||
<p>{{ .Runner.Group.Name }}</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Läuferurkunde</title>
|
||||
<title>Sponsoring contract</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<style>
|
||||
.sheet {
|
||||
@ -56,8 +56,8 @@
|
||||
{{ .MiddleName }} {{ .LastName }}
|
||||
</p>
|
||||
<p style="font-size: 1cm; margin-bottom: 0;">hat beim {{ $.EventName }}</p>
|
||||
<p style="font-size: 2cm; font-weight: bold; margin-bottom: 0;">{{formatUnit "kilometer" $.Locale .Distance}}</p>
|
||||
<p style="font-size: 1cm;">für den guten Zweck zurückgelegt.</p>
|
||||
<p style="font-size: 2cm; font-weight: bold; margin-bottom: 0;">{{formatUnit "kilometer" $.Locale .Distance}}km</p>
|
||||
<p style="font-size: 1cm;">für den guten Zweck zurückgelegt</p>
|
||||
</main>
|
||||
<footer class="certificate-footer">
|
||||
<img src="data:image/png;base64,{{ loadImage "certificate_footer" }}">
|
||||
@ -87,30 +87,13 @@
|
||||
<td>Gesamt</td>
|
||||
<td>{{ formatUnit "euro" $.Locale .TotalPerDistance }} {{ $.CurrencySymbol }}</td>
|
||||
<td>{{ formatUnit "euro" $.Locale .TotalDonations }} {{ $.CurrencySymbol }}</td>
|
||||
</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 "Spende LfK " .ID ", " .FirstName " " .LastName ", " .CombinedGroupName) .TotalDonations $.SepaConfig.CurrencyIdentifier}}" style="height: 2.5cm; padding: 0.2cm">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p style="width: 17cm; text-align: center;">
|
||||
Sponsoren überweisen ihre Beträge bitte auf unser Konto: {{ $.SepaConfig.HolderName }} | IBAN: {{ $.SepaConfig.IBAN }} | BIC: {{ $.SepaConfig.BIC }} | Vz: "Spende LfK {{.ID}}, {{ .FirstName }} {{ .LastName }}, {{.CombinedGroupName}}"
|
||||
</p>
|
||||
</tfoot>
|
||||
</table>
|
||||
</main>
|
||||
<footer class="certificate-footer">
|
||||
<p>
|
||||
{{ $.Footer }}
|
||||
</p>
|
||||
</footer>
|
||||
</article>
|
||||
{{ end }}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Runner certificate</title>
|
||||
<title>Sponsoring contract</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
|
||||
<style>
|
||||
.sheet {
|
||||
@ -56,8 +56,8 @@
|
||||
{{ .MiddleName }} {{ .LastName }}
|
||||
</p>
|
||||
<p style="font-size: 1cm; margin-bottom: 0;">Ran</p>
|
||||
<p style="font-size: 2cm; font-weight: bold; margin-bottom: 0;">{{formatUnit "kilometer" $.Locale .Distance}}</p>
|
||||
<p style="font-size: 1cm;">for our good cause at the {{ $.EventName }}.</p>
|
||||
<p style="font-size: 2cm; font-weight: bold; margin-bottom: 0;">{{formatUnit "kilometer" $.Locale .Distance}}km</p>
|
||||
<p style="font-size: 1cm;">for our good cause at the {{ $.EventName }}</p>
|
||||
</main>
|
||||
<footer class="certificate-footer">
|
||||
<img src="data:image/png;base64,{{ loadImage "certificate_footer" }}">
|
||||
@ -91,26 +91,8 @@
|
||||
</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 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 "Spende LfK " .ID ", " .FirstName " " .LastName ", " .CombinedGroupName) .TotalDonations $.SepaConfig.CurrencyIdentifier}}" style="height: 2.5cm; padding: 0.2cm">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p style="width: 17cm; text-align: center;">
|
||||
Donors, please transfer your donation to our account: {{ $.SepaConfig.HolderName }} | IBAN: {{ $.SepaConfig.IBAN }} | BIC: {{ $.SepaConfig.BIC }} | Ref: "Spende LfK {{.ID}}, {{ .FirstName }} {{ .LastName }}, {{.CombinedGroupName}}"
|
||||
<p>
|
||||
{{ $.Footer }}
|
||||
</p>
|
||||
</footer>
|
||||
</article>
|
||||
|
@ -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;"><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>
|
||||
<span style="border-bottom: 1px solid; width: 100%; display: block;">{{ .Group.Name }}</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;"><p>{{ if ne .Group.ParentGroup.Name "" -}}{{ .Group.ParentGroup.Name }}/ {{end -}}{{ .Group.Name }}</p></span>
|
||||
<span style="border-bottom: 1px solid; width: 100%; display: block;">{{ .Group.Name}}</span>
|
||||
<p style="font-size: x-small; display: block;">Team/class</p>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user