Compare commits
36 Commits
v0.4.0
...
7fea1ca78f
| Author | SHA1 | Date | |
|---|---|---|---|
| 7fea1ca78f | |||
| 64fce5bd01 | |||
| 5ba26c4cbf | |||
| b82a32ae3e | |||
| 0af9b81b38 | |||
| 955e11846b | |||
| d1577cd08d | |||
| 6767c3b2d1 | |||
| 2b2195727b | |||
| 3ca2237953 | |||
| 8d6ea4dbf9 | |||
| 8b71608792 | |||
| f1084b59a7 | |||
| c8dc998ecd | |||
| 3df3d26708 | |||
| 922e762aa2 | |||
| c3beb3e103 | |||
| 457ea26cf8 | |||
| c2d2b66f2f | |||
| 289a0d8671 | |||
| ce3053c0ba | |||
| 6608456c68 | |||
| 1cbe5a1614 | |||
| 9584bfed8b | |||
| 0839ff6359 | |||
| 4739193709 | |||
| 0ade57536e | |||
| d17108f4b9 | |||
| 3c42ca3042 | |||
| 073433f308 | |||
| 8bac1fadd6 | |||
| a478081727 | |||
| b1978e796f | |||
| c51ec74d30 | |||
| b8f0d1fa60 | |||
| 96886c74bc |
@@ -44,6 +44,7 @@ steps:
|
||||
tags:
|
||||
- dev
|
||||
registry: registry.odit.services
|
||||
mtu: 1000
|
||||
- name: run changelog export
|
||||
depends_on: ["clone"]
|
||||
image: node:latest
|
||||
@@ -112,6 +113,7 @@ steps:
|
||||
tags:
|
||||
- latest
|
||||
registry: registry.odit.services
|
||||
mtu: 1000
|
||||
- name: push merge to repo
|
||||
depends_on: ["clone"]
|
||||
image: appleboy/drone-git-push
|
||||
@@ -146,6 +148,7 @@ steps:
|
||||
tags:
|
||||
- '${DRONE_TAG}'
|
||||
registry: registry.odit.services
|
||||
mtu: 1000
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
47
CHANGELOG.md
47
CHANGELOG.md
@@ -2,13 +2,56 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [v0.3.3](https://git.odit.services/lfk/document-server/compare/v0.3.3...v0.3.3)
|
||||
#### [v0.4.3](https://git.odit.services/lfk/document-server/compare/v0.4.3...v0.4.3)
|
||||
|
||||
- Merge pull request 'Configurable sponsoring disclaimer feature/33-disclaimer' (#34) from feature/33-disclaimer into dev [`e9d3574`](https://git.odit.services/lfk/document-server/commit/e9d35745997a9e948509ea67b59f5a7658f9d652)
|
||||
#### [v0.4.3](https://git.odit.services/lfk/document-server/compare/v0.4.2...v0.4.3)
|
||||
|
||||
> 30 March 2021
|
||||
|
||||
- Merge pull request 'Release 0.4.3' (#40) from dev into main [`c8dc998`](https://git.odit.services/lfk/document-server/commit/c8dc998ecdccc7fc4348ecc0db552a3d7bc2eb52)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`289a0d8`](https://git.odit.services/lfk/document-server/commit/289a0d8671575dda911c64f79d24726d3bbee071)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`3df3d26`](https://git.odit.services/lfk/document-server/commit/3df3d26708aab12590cd9c1f697cfdea8017ace4)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`457ea26`](https://git.odit.services/lfk/document-server/commit/457ea26cf8124009084415d12c7a0e31912a3eb1)
|
||||
- 🚀Bumped version to v0.4.3 [`c3beb3e`](https://git.odit.services/lfk/document-server/commit/c3beb3e1032492f9a8304c4b099a700ad0d1d2cf)
|
||||
- Pipeline mtu fix [`c2d2b66`](https://git.odit.services/lfk/document-server/commit/c2d2b66f2f6fbd30c2027fd3dab393db5219eb44)
|
||||
|
||||
#### [v0.4.2](https://git.odit.services/lfk/document-server/compare/v0.4.0...v0.4.2)
|
||||
|
||||
> 29 March 2021
|
||||
|
||||
- Merge pull request 'Release 0.4.2' (#39) from dev into main [`ce3053c`](https://git.odit.services/lfk/document-server/commit/ce3053c0ba5404ebd8d4cbd5386c454d8cd8c4d2)
|
||||
- 🚀Bumped version to v0.4.1 [`d17108f`](https://git.odit.services/lfk/document-server/commit/d17108f4b9f041727afcee5c171d5d8f9a3c677c)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`0ade575`](https://git.odit.services/lfk/document-server/commit/0ade57536e372a62356fe2f329f6cfe04bcfc397)
|
||||
- Fixed faulty object mapping [`9584bfe`](https://git.odit.services/lfk/document-server/commit/9584bfed8ba5b8c856b55aa90969874d4d6751ff)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`8bac1fa`](https://git.odit.services/lfk/document-server/commit/8bac1fadd6b4257e5062a1b1673e122c5b535046)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`b8f0d1f`](https://git.odit.services/lfk/document-server/commit/b8f0d1fa60da4e3262623cecf4a78c8a9a322f8c)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`073433f`](https://git.odit.services/lfk/document-server/commit/073433f308f2f8e7ada97dd0b3896fb541e85711)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`a478081`](https://git.odit.services/lfk/document-server/commit/a47808172797e12800c46d17ccf4b458f4a506de)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`6608456`](https://git.odit.services/lfk/document-server/commit/6608456c686e51d3aa16e630ba72c7c29e428b2a)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`0839ff6`](https://git.odit.services/lfk/document-server/commit/0839ff63593cfb9e8339b2b2a86dbe7e2afb5dcb)
|
||||
- Now using our own images to build stuff 🚀 [`96886c7`](https://git.odit.services/lfk/document-server/commit/96886c74bc397e1ee793e83e0d01a6bbaa953da3)
|
||||
- 🚀Bumped version to v0.4.2 [`1cbe5a1`](https://git.odit.services/lfk/document-server/commit/1cbe5a1614c40fbf23f032be60039ddb1472ca94)
|
||||
- Emergency bugfixes 🐞 [`3c42ca3`](https://git.odit.services/lfk/document-server/commit/3c42ca30427174c21e0db6426d8f0d91a1ebc501)
|
||||
- Let's try the mtu fix [`c51ec74`](https://git.odit.services/lfk/document-server/commit/c51ec74d30334b156668de4719c77f2e9c6d023f)
|
||||
|
||||
#### [v0.4.0](https://git.odit.services/lfk/document-server/compare/v0.3.3...v0.4.0)
|
||||
|
||||
> 14 March 2021
|
||||
|
||||
- Merge pull request 'Alpha Release 0.4.0' (#38) from dev into main [`8d3cc34`](https://git.odit.services/lfk/document-server/commit/8d3cc34395922a271da1032310da6ec6f7a164f7)
|
||||
- Updated ci with new kubernetes secrets 🚀🚀🚀 [`b180e04`](https://git.odit.services/lfk/document-server/commit/b180e0404537404d0564453fde5976f4de672a8b)
|
||||
- Updated styleing [`03ed6d5`](https://git.odit.services/lfk/document-server/commit/03ed6d5bc18c5b26edd7b1d698c9de936e008f32)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`b612562`](https://git.odit.services/lfk/document-server/commit/b612562d347f5fafcf4ce94a4508b7c0bb9370c6)
|
||||
- 🚀Bumped version to v0.4.0 [`85519bc`](https://git.odit.services/lfk/document-server/commit/85519bc2e4e8906732dc5f99e417014a14bad7d0)
|
||||
- Merge pull request 'Configureable contracts amount feature/35-contracts_per_runner' (#37) from feature/35-contracts_per_runner into dev [`ed02306`](https://git.odit.services/lfk/document-server/commit/ed023067386551dc92d60ba63dff8bc4cc44ce00)
|
||||
- Added disclaimer to template [`4e1e124`](https://git.odit.services/lfk/document-server/commit/4e1e124d0dc08f96aeb05dd1c975064fe785b80f)
|
||||
- Changed ci pipeline type to kubernetes [`677bd86`](https://git.odit.services/lfk/document-server/commit/677bd861335302269baec96a59916475bbdd405f)
|
||||
- Added config for amount of contracts per runner [`d01b4a0`](https://git.odit.services/lfk/document-server/commit/d01b4a0b99f3c1aa088b02d766d21bfb6b9e3a29)
|
||||
- Added logic for generateing multiple contracts per runner [`d991940`](https://git.odit.services/lfk/document-server/commit/d9919404b5b90151318d20258a273ca6c7640393)
|
||||
- MAde disclaimer configurable via env [`5e4d6f4`](https://git.odit.services/lfk/document-server/commit/5e4d6f44dab581483135594432bd8c8d65ba74ef)
|
||||
- MAde disclaimer configurable via env [`885765a`](https://git.odit.services/lfk/document-server/commit/885765ac71b6a65c869ee841c383667f4947dcde)
|
||||
- Documented the new config var [`31a5950`](https://git.odit.services/lfk/document-server/commit/31a59500fa77f1ad7c54fa297d00c8707ae6db9c)
|
||||
- Merge pull request 'Configurable sponsoring disclaimer feature/33-disclaimer' (#34) from feature/33-disclaimer into dev [`e9d3574`](https://git.odit.services/lfk/document-server/commit/e9d35745997a9e948509ea67b59f5a7658f9d652)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`19fbf50`](https://git.odit.services/lfk/document-server/commit/19fbf50f6f6057c5321a999b6551d05db32b5fd8)
|
||||
- Added reamde entry for the new env var [`9dd62ce`](https://git.odit.services/lfk/document-server/commit/9dd62cefa94bf3f0bf8e77fd25e7ca1ec4b30e2b)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Typescript Build
|
||||
FROM registry.odit.services/mirror/node:14.15.1-alpine3.12
|
||||
FROM registry.odit.services/hub/library/node:14.15.1-alpine3.12
|
||||
WORKDIR /app
|
||||
COPY package.json ./
|
||||
RUN npm i -g pnpm
|
||||
@@ -8,7 +8,7 @@ COPY tsconfig.json ./
|
||||
COPY src ./src
|
||||
RUN pnpm run build
|
||||
# final image
|
||||
FROM registry.odit.services/mirror/alpine:3.13.1
|
||||
FROM registry.odit.services/hub/library/alpine:3.13.1
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache \
|
||||
chromium \
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
version: "3"
|
||||
services:
|
||||
document_server:
|
||||
build: .
|
||||
ports:
|
||||
- 4010:4010
|
||||
environment:
|
||||
APP_PORT: 4010
|
||||
NODE_ENV: production
|
||||
version: "3"
|
||||
services:
|
||||
document_server:
|
||||
build: .
|
||||
ports:
|
||||
- 4010:4010
|
||||
environment:
|
||||
APP_PORT: 4010
|
||||
NODE_ENV: production
|
||||
EVENT_NAME: "Lauf für Kaya! 2021"
|
||||
CURRENCY_SYMBOL: "€"
|
||||
API_KEY: RYRccAJ4SKZnZaEci6Nyk9Z6mw3sD94fyKJ74WNzi6hLkxGNyJDrKPkxBmPwvR4f
|
||||
CONTRACTS_PER_RUNNER: 2
|
||||
SPONSORING_RECEIPT_MINIMUM_AMOUNT: 50
|
||||
DISCLAIMER_TEXT: "Rechtsgrundlage unserer Datenverarbeitung aufgrund freiwilliger Einwilligung ist Art. 6 Abs. 1 e), Abs. 3 DSGVO i.V.m. Art. 85 BayEUG. Mit Ihrer Unterschrift willigen Sie in unsere Datennutzung zum Zwecke des Lauf für Kaya! ein. Die Daten für Spendenquittungen"
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@odit/lfk-document-server",
|
||||
"version": "0.4.0",
|
||||
"version": "0.4.3",
|
||||
"description": "The document generation server for the LfK! runner system. This generates certificates, sponsoring aggreements and more",
|
||||
"main": "src/app.ts",
|
||||
"scripts": {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { PDFDocument } from 'pdf-lib';
|
||||
import puppeteer from "puppeteer";
|
||||
import { awaitAsyncHandlebarHelpers, helpers } from './asyncHelpers';
|
||||
import { config } from './config';
|
||||
import { CertificateRunner } from './models/CertificateRunner';
|
||||
import { Runner } from './models/Runner';
|
||||
import { RunnerCard } from './models/RunnerCard';
|
||||
import { RunnerGroup } from './models/RunnerGroup';
|
||||
@@ -153,13 +154,37 @@ export class PdfCreator {
|
||||
await i18next.changeLanguage(locale);
|
||||
const template_source = fs.readFileSync(`${this.templateDir}/runner_card.html`, 'utf8');
|
||||
const template = Handlebars.compile(template_source);
|
||||
let result = template({ cards, cards_swapped, eventname: "LfK! 2069", codeformat: "qrcode" })
|
||||
let result = template({ cards, cards_swapped, eventname: config.eventname, codeformat: codeformat })
|
||||
result = await awaitAsyncHandlebarHelpers(result);
|
||||
fs.writeFileSync("lelelelele.tmp", result);
|
||||
const pdf = await this.renderPdf(result, { format: "A4", landscape: false });
|
||||
return pdf
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate sponsoring contract pdfs.
|
||||
* @param runner The runner you want to generate the contracts for.
|
||||
* @param locale The locale used for the contracts (default:en)
|
||||
*/
|
||||
public async generateRunnerCertficates(runners: CertificateRunner[], locale: string = "en"): Promise<Buffer> {
|
||||
if (runners.length > 50) {
|
||||
let pdf_promises = new Array<Promise<Buffer>>();
|
||||
let i, j;
|
||||
for (i = 0, j = runners.length; i < j; i += 50) {
|
||||
let chunk = runners.slice(i, i + 50);
|
||||
pdf_promises.push(this.generateRunnerCertficates(chunk, locale));
|
||||
}
|
||||
const pdfs = await Promise.all(pdf_promises);
|
||||
return await this.mergePdfs(pdfs);
|
||||
}
|
||||
await i18next.changeLanguage(locale);
|
||||
const template_source = fs.readFileSync(`${this.templateDir}/runner_certificate.html`, 'utf8');
|
||||
const template = Handlebars.compile(template_source);
|
||||
let result = template({ runners, eventname: config.eventname });
|
||||
result = await awaitAsyncHandlebarHelpers(result);
|
||||
const pdf = await this.renderPdf(result, { format: "A4", landscape: false, printBackground: true });
|
||||
return pdf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all images in html to base64.
|
||||
* Works with image files in the template directory or images from urls.
|
||||
@@ -167,6 +192,7 @@ export class PdfCreator {
|
||||
*/
|
||||
public async imgToBase64(html): Promise<string> {
|
||||
const $ = cheerio.load(html)
|
||||
|
||||
$('img').each(async (index, element) => {
|
||||
let imgsrc = $(element).attr("src");
|
||||
if (imgsrc.startsWith("data:image")) {
|
||||
@@ -192,7 +218,7 @@ export class PdfCreator {
|
||||
|
||||
image = `data:${img_type};base64,${image}`
|
||||
$(element).attr("src", image)
|
||||
})
|
||||
});
|
||||
|
||||
return $.html();
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export const config = {
|
||||
sponor_logos: getSponsorLogos(),
|
||||
api_key: getApiKey(),
|
||||
disclaimer_text: process.env.DISCLAIMER_TEXT || "",
|
||||
contracts_per_runner: process.env.CONTRACTS_PER_RUNNER || 1,
|
||||
contracts_per_runner: parseInt(process.env.CONTRACTS_PER_RUNNER) || 1,
|
||||
}
|
||||
let errors = 0
|
||||
if (typeof config.internal_port !== "number") {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Authorized, Body, JsonController, Post, QueryParam, Res } from 'routing-controllers';
|
||||
import { OpenAPI } from 'routing-controllers-openapi';
|
||||
import { CertificateRunner } from '../models/CertificateRunner';
|
||||
import { Runner } from '../models/Runner';
|
||||
import { RunnerCard } from '../models/RunnerCard';
|
||||
import { PdfCreator } from '../PdfCreator';
|
||||
@@ -54,6 +55,25 @@ export class PdfController {
|
||||
return contracts;
|
||||
}
|
||||
|
||||
@Post('/certificates')
|
||||
@OpenAPI({ description: "Generate runner certificate pdfs from certificate runner objects.<br>You can choose your prefered locale by passing the 'locale' query-param.<br> If you provide more than 100 runenrs this could take a moment or two (we tested up to 1000 runners in about 70sec so far)." })
|
||||
async generateCertificates(@Body({ validate: true, options: { limit: "500mb" } }) runners: CertificateRunner[], @Res() res: any, @QueryParam("locale") locale: string, @QueryParam("download") download: boolean) {
|
||||
if (!this.initialized) {
|
||||
await this.pdf.init();
|
||||
this.initialized = true;
|
||||
}
|
||||
if (!Array.isArray(runners)) {
|
||||
runners = [runners];
|
||||
}
|
||||
runners = this.mapCertificatRunnersGroupNames(runners)
|
||||
const certificates = await this.pdf.generateRunnerCertficates(runners, locale);
|
||||
res.setHeader('content-type', 'application/pdf');
|
||||
if (download) {
|
||||
res.setHeader('Content-Disposition', 'attachment; filename="certificates.pdf"')
|
||||
}
|
||||
return certificates;
|
||||
}
|
||||
|
||||
private mapRunnerGroupNames(runners: Runner[]): Runner[] {
|
||||
let response = new Array<Runner>();
|
||||
for (let runner of runners) {
|
||||
@@ -68,10 +88,37 @@ export class PdfController {
|
||||
return response;
|
||||
}
|
||||
|
||||
private mapCertificatRunnersGroupNames(runners: CertificateRunner[]): CertificateRunner[] {
|
||||
let response = new Array<CertificateRunner>();
|
||||
for (let runner of runners) {
|
||||
if (!runner.group.parentGroup) {
|
||||
runner.group.fullName = runner.group.name;
|
||||
}
|
||||
else {
|
||||
runner.group.fullName = `${runner.group.parentGroup.name}/${runner.group.name}`;
|
||||
}
|
||||
response.push(runner)
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private mapCardGroupNames(cards: RunnerCard[]): RunnerCard[] {
|
||||
let response = new Array<RunnerCard>();
|
||||
for (let card of cards) {
|
||||
if (!card.runner.group.parentGroup) {
|
||||
if (!card.runner) {
|
||||
card.runner = {
|
||||
id: 0,
|
||||
firstname: "Blank",
|
||||
lastname: "Blank",
|
||||
distance: 0,
|
||||
group: {
|
||||
id: 0,
|
||||
name: "Blank",
|
||||
fullName: "Blank"
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!card.runner.group.parentGroup) {
|
||||
card.runner.group.fullName = card.runner.group.name;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
{
|
||||
"address": "Adresse",
|
||||
"city": "Stadt",
|
||||
"date": "Datum",
|
||||
"firstname": "Vorname",
|
||||
"group": "Team/Klasse",
|
||||
"house_number": "Hausnummer",
|
||||
"id": "ID",
|
||||
"lastname": "Nachname",
|
||||
"location": "Ort",
|
||||
"please_use_blockletters": "Bitte in DRUCKBUCHSTABEN schreiben",
|
||||
"postalcode": "Postleitzahl",
|
||||
"signature": "Unterschrift",
|
||||
"sponsor": "Sponsor",
|
||||
"sponsoring_address_condition": "Muss ausgefüllt werden, wenn Sie eine Spendenquittung benötigen - Spendenquittungen können erst ab einem Gesamtbetrag von {{sponsoring_receipt_minimum_amount}}{{currency_symbol}} ausgestellt werden",
|
||||
"sponsoring_amount_per_distance": "mit einem Betrag von _____{{currency_symbol}} pro gelaufenem Kilometer zu unterstützen.",
|
||||
"sponsoring_subtitle": "Ich/Wir sind bereit anlässlich des {{eventname}}",
|
||||
"sponsoring_title": "Sponsoringerklärung",
|
||||
"street": "Straße"
|
||||
}
|
||||
"address": "Adresse",
|
||||
"city": "Stadt",
|
||||
"date": "Datum",
|
||||
"firstname": "Vorname",
|
||||
"group": "Team/Klasse",
|
||||
"house_number": "Hausnummer",
|
||||
"id": "ID",
|
||||
"lastname": "Nachname",
|
||||
"location": "Ort",
|
||||
"please_use_blockletters": "Bitte in DRUCKBUCHSTABEN schreiben",
|
||||
"postalcode": "Postleitzahl",
|
||||
"signature": "Unterschrift",
|
||||
"sponsor": "Sponsor",
|
||||
"sponsoring_address_condition": "Muss ausgefüllt werden, wenn Sie eine Spendenquittung benötigen - Spendenquittungen können erst ab einem Gesamtbetrag von {{sponsoring_receipt_minimum_amount}}{{currency_symbol}} ausgestellt werden",
|
||||
"sponsoring_amount_per_distance": "mit einem Betrag von _____{{currency_symbol}} pro gelaufenem Kilometer zu unterstützen.",
|
||||
"sponsoring_subtitle": "Ich/Wir sind bereit anlässlich des {{eventname}}",
|
||||
"sponsoring_title": "Sponsoringerklärung",
|
||||
"street": "Straße",
|
||||
"urkunde": "Urkunde",
|
||||
"hat-beim-eventname": "Hat beim {{../eventname}}",
|
||||
"fuer-den-guten-zweck-zurueckgelegt": "für den guten Zweck zurückgelegt",
|
||||
"sponsorings": "Sponsorings",
|
||||
"sponsor-in": "Sponsor:in",
|
||||
"betrag-km": "Betrag/KM",
|
||||
"gesamtbetrag": "Gesamtbetrag",
|
||||
"gesamt": "Gesamt"
|
||||
}
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
{
|
||||
"address": "Address",
|
||||
"city": "City",
|
||||
"date": "date",
|
||||
"firstname": "First name",
|
||||
"group": "Team/class",
|
||||
"house_number": "House number",
|
||||
"lastname": "Last name",
|
||||
"location": "Location",
|
||||
"please_use_blockletters": "Please write in BLOCK LETTERS.",
|
||||
"postalcode": "Postal code",
|
||||
"signature": "Signature",
|
||||
"sponsor": "sponsor",
|
||||
"sponsoring_address_condition": "You have to provide an address if you want a donation receipt - Donation receipts can't be issued for total donation amounts under {{sponsoring_receipt_minimum_amount}}{{currency_symbol}}",
|
||||
"sponsoring_amount_per_distance": "with the amount of _____{{currency_symbol}} per kilometer run.",
|
||||
"sponsoring_subtitle": "On the ocation of the {{eventname}} I/We want to support",
|
||||
"sponsoring_title": "Sponsoring contract",
|
||||
"street": "Street"
|
||||
}
|
||||
"address": "Address",
|
||||
"city": "City",
|
||||
"date": "date",
|
||||
"firstname": "First name",
|
||||
"group": "Team/class",
|
||||
"house_number": "House number",
|
||||
"lastname": "Last name",
|
||||
"location": "Location",
|
||||
"please_use_blockletters": "Please write in BLOCK LETTERS.",
|
||||
"postalcode": "Postal code",
|
||||
"signature": "Signature",
|
||||
"sponsor": "sponsor",
|
||||
"sponsoring_address_condition": "You have to provide an address if you want a donation receipt - Donation receipts can't be issued for total donation amounts under {{sponsoring_receipt_minimum_amount}}{{currency_symbol}}",
|
||||
"sponsoring_amount_per_distance": "with the amount of _____{{currency_symbol}} per kilometer run.",
|
||||
"sponsoring_subtitle": "On the ocation of the {{eventname}} I/We want to support",
|
||||
"sponsoring_title": "Sponsoring contract",
|
||||
"street": "Street",
|
||||
"urkunde": "Certifcate",
|
||||
"fuer-den-guten-zweck-zurueckgelegt": "for our good cuse at the {eventname}",
|
||||
"hat-beim-eventname": "Ran",
|
||||
"id": "ID",
|
||||
"sponsorings": "Donations",
|
||||
"sponsor-in": "Donor",
|
||||
"betrag-km": "Amount/KM",
|
||||
"gesamtbetrag": "Total",
|
||||
"gesamt": "Combined"
|
||||
}
|
||||
|
||||
BIN
src/templates/certficate_background.png
Normal file
BIN
src/templates/certficate_background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
BIN
src/templates/certificate_footer.png
Normal file
BIN
src/templates/certificate_footer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
98
src/templates/runner_certificate.html
Normal file
98
src/templates/runner_certificate.html
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user