From d291cf0d1bf375e96fda822543d5ceb29dc67010 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 30 Jan 2021 18:32:01 +0100 Subject: [PATCH 01/20] Added address class and errors ref #1 --- src/errors/AddressErrors.ts | 57 ++++++++++++++++++++++++++ src/models/Address.ts | 80 +++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 src/errors/AddressErrors.ts create mode 100644 src/models/Address.ts diff --git a/src/errors/AddressErrors.ts b/src/errors/AddressErrors.ts new file mode 100644 index 0000000..300bb31 --- /dev/null +++ b/src/errors/AddressErrors.ts @@ -0,0 +1,57 @@ +import { IsString } from 'class-validator'; +import { BadRequestError } from 'routing-controllers'; + +/** + * Error to throw when an address's postal code fails validation. + */ +export class AddressPostalCodeInvalidError extends BadRequestError { + @IsString() + name = "AddressPostalCodeInvalidError" + + @IsString() + message = "The postal code you provided is invalid. \n Please check if your postal code follows the postal code validation guidelines." +} + +/** + * Error to throw when an non-empty address's first line isn't set. + */ +export class AddressFirstLineEmptyError extends BadRequestError { + @IsString() + name = "AddressFirstLineEmptyError" + + @IsString() + message = "You provided a empty first address line. \n If you want an empty address please set all propertys to null. \n For non-empty addresses the following fields have to be set: address1, postalcode, city, country" +} + +/** + * Error to throw when an non-empty address's postal code isn't set. + */ +export class AddressPostalCodeEmptyError extends BadRequestError { + @IsString() + name = "AddressPostalCodeEmptyError" + + @IsString() + message = "You provided a empty postal code. \n If you want an empty address please set all propertys to null. \n For non-empty addresses the following fields have to be set: address1, postalcode, city, country" +} + +/** + * Error to throw when an non-empty address's city isn't set. + */ +export class AddressCityEmptyError extends BadRequestError { + @IsString() + name = "AddressCityEmptyError" + + @IsString() + message = "You provided a empty city. \n If you want an empty address please set all propertys to null. \n For non-empty addresses the following fields have to be set: address1, postalcode, city, country" +} + +/** + * Error to throw when an non-empty address's country isn't set. + */ +export class AddressCountryEmptyError extends BadRequestError { + @IsString() + name = "AddressCountryEmptyError" + + @IsString() + message = "You provided a empty country. \n If you want an empty address please set all propertys to null. \n For non-empty addresses the following fields have to be set: address1, postalcode, city, country" +} \ No newline at end of file diff --git a/src/models/Address.ts b/src/models/Address.ts new file mode 100644 index 0000000..dc66f10 --- /dev/null +++ b/src/models/Address.ts @@ -0,0 +1,80 @@ +import { + IsPostalCode, + IsString +} from "class-validator"; +import ValidatorJS from 'validator'; +import { config } from '../../config'; +import { AddressCityEmptyError, AddressCountryEmptyError, AddressFirstLineEmptyError, AddressPostalCodeEmptyError, AddressPostalCodeInvalidError } from '../../errors/AddressErrors'; + +/** + * Defines the Address class. + * Implemented this way to prevent any formatting differences. +*/ +export class Address { + /** + * The address's first line. + * Containing the street and house number. + */ + @IsString() + address1?: string; + + /** + * The address's second line. + * Containing optional information. + */ + @IsString() + address2?: string; + + /** + * The address's postal code. + * This will get checked against the postal code syntax for the configured country. + */ + @IsString() + @IsPostalCode(config.postalcode_validation_countrycode) + postalcode: string; + + /** + * The address's city. + */ + @IsString() + city: string; + + /** + * The address's country. + */ + @IsString() + country: string; + + public reset() { + this.address1 = null; + this.address2 = null; + this.city = null; + this.country = null; + this.postalcode = null; + } + + /** + * Checks if this is a valid address + */ + public static isValidAddress(address: Address): Boolean { + if (address == null) { return false; } + if (address.address1 == null || address.city == null || address.country == null || address.postalcode == null) { return false; } + if (ValidatorJS.isPostalCode(address.postalcode, config.postalcode_validation_countrycode) == false) { return false; } + return true; + } + + /** + * This function validates addresses. + * This is a workaround for non-existant class validation for embedded entities. + * @param address The address that shall get validated. + */ + public static validate(address: Address) { + if (address == null) { return; } + if (address.address1 == null && address.city == null && address.country == null && address.postalcode == null) { return; } + if (address.address1 == null) { throw new AddressFirstLineEmptyError(); } + if (address.postalcode == null) { throw new AddressPostalCodeEmptyError(); } + if (address.city == null) { throw new AddressCityEmptyError(); } + if (address.country == null) { throw new AddressCountryEmptyError(); } + if (ValidatorJS.isPostalCode(address.postalcode.toString(), config.postalcode_validation_countrycode) == false) { throw new AddressPostalCodeInvalidError(); } + } +} From 63f952376698c3561754bfb206a64c58c1ae86f1 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sat, 30 Jan 2021 18:32:28 +0100 Subject: [PATCH 02/20] Added input class for contract generation ref #1 --- src/models/ContractRunner.ts | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/models/ContractRunner.ts diff --git a/src/models/ContractRunner.ts b/src/models/ContractRunner.ts new file mode 100644 index 0000000..eda52f7 --- /dev/null +++ b/src/models/ContractRunner.ts @@ -0,0 +1,39 @@ +import { + IsInt, + IsString +} from "class-validator"; + +/** + * Defines the contract runner class (from which the runner sponsoring contracts get generated). +*/ +export class ContractRunner { + /** + * The runner's id. + */ + @IsInt() + id: number; + + /** + * The runner's first name. + */ + @IsString() + firstname: string; + + /** + * The runner's middle name. + */ + @IsString() + middlename?: string; + + /** + * The runner's last name. + */ + @IsString() + lastname: string; + + /** + * The runner's group. + */ + @IsString() + group: string; +} From e29c17a29a6ee84944f8d67d7b6f3c4292763c10 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 08:49:18 +0100 Subject: [PATCH 03/20] Added a simplified runnergroup class ref #1 --- src/models/RunnerGroup.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/models/RunnerGroup.ts diff --git a/src/models/RunnerGroup.ts b/src/models/RunnerGroup.ts new file mode 100644 index 0000000..f50a179 --- /dev/null +++ b/src/models/RunnerGroup.ts @@ -0,0 +1,36 @@ +import { IsInt, IsNotEmpty, IsObject, IsOptional, IsString } from "class-validator"; + +/** + * Defines the runner group class - a simplified version of the backend's ResponseRunnerTeam/-Organization +*/ +export abstract class RunnerGroup { + /** + * The group's id. + */ + @IsInt() + @IsNotEmpty() + id: number;; + + /** + * The group's name. + */ + @IsString() + @IsNotEmpty() + name: string; + + /** + * The group's parent group. + * If it is set this implies that the object is a team. + */ + @IsObject() + @IsOptional() + parentGroup?: RunnerGroup + + /** + * Returns the groups full name in the format: org.name/team.name (or just org). + */ + public get fullName(): string { + if (!this.parentGroup) { return this.name; } + return `${this.name}/${this.parentGroup.fullName}`; + } +} From cb7325bbf906b405955bd81e199abae5edc27d91 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 08:49:41 +0100 Subject: [PATCH 04/20] Added a runnercard class ref #1 --- src/models/RunnerCard.ts | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/models/RunnerCard.ts diff --git a/src/models/RunnerCard.ts b/src/models/RunnerCard.ts new file mode 100644 index 0000000..89f2687 --- /dev/null +++ b/src/models/RunnerCard.ts @@ -0,0 +1,33 @@ +import { + IsEAN, + IsInt, + IsNotEmpty, + IsObject, + IsString +} from "class-validator"; +import { ContractRunner } from './ContractRunner'; + +/** + * Defines the runner card class (used to create runner card pdfs). +*/ +export class RunnerCard { + /** + * The cards's id. + */ + @IsInt() + id: number; + + /** + * The card's associated runner. + */ + @IsObject() + runner: ContractRunner | null; + + /** + * The card's code. + */ + @IsEAN() + @IsString() + @IsNotEmpty() + code: string; +} From aae4f507eafbfd51cd9972cf0fac4c5afafbb45a Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 08:50:31 +0100 Subject: [PATCH 05/20] Runners now use the runnergroup class instead of strings ref #1 --- src/models/{ContractRunner.ts => Runner.ts} | 8 +++++--- src/models/RunnerCard.ts | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) rename src/models/{ContractRunner.ts => Runner.ts} (81%) diff --git a/src/models/ContractRunner.ts b/src/models/Runner.ts similarity index 81% rename from src/models/ContractRunner.ts rename to src/models/Runner.ts index eda52f7..fec6235 100644 --- a/src/models/ContractRunner.ts +++ b/src/models/Runner.ts @@ -1,12 +1,14 @@ import { IsInt, + IsObject, IsString } from "class-validator"; +import { RunnerGroup } from './RunnerGroup'; /** * Defines the contract runner class (from which the runner sponsoring contracts get generated). */ -export class ContractRunner { +export class Runner { /** * The runner's id. */ @@ -34,6 +36,6 @@ export class ContractRunner { /** * The runner's group. */ - @IsString() - group: string; + @IsObject() + group: RunnerGroup; } diff --git a/src/models/RunnerCard.ts b/src/models/RunnerCard.ts index 89f2687..3a4cffb 100644 --- a/src/models/RunnerCard.ts +++ b/src/models/RunnerCard.ts @@ -5,7 +5,7 @@ import { IsObject, IsString } from "class-validator"; -import { ContractRunner } from './ContractRunner'; +import { Runner } from './Runner'; /** * Defines the runner card class (used to create runner card pdfs). @@ -21,7 +21,7 @@ export class RunnerCard { * The card's associated runner. */ @IsObject() - runner: ContractRunner | null; + runner: Runner | null; /** * The card's code. From d08bdfd961f4128981b969cf149df7397a257193 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 08:59:30 +0100 Subject: [PATCH 06/20] Added a certificaterunner class ref #1 --- src/models/CertificateRunner.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/models/CertificateRunner.ts diff --git a/src/models/CertificateRunner.ts b/src/models/CertificateRunner.ts new file mode 100644 index 0000000..937536e --- /dev/null +++ b/src/models/CertificateRunner.ts @@ -0,0 +1,23 @@ +import { + IsArray, + IsInt +} from "class-validator"; +import { Runner } from './Runner'; + +/** + * Defines the certificate runner class (from which the runner certificates get generated). +*/ +export class CertificateRunner extends Runner { + + /** + * The total distance ran by the runner. + */ + @IsInt() + distance: number; + + /** + * Array containing all distance donations associated with the runner. + */ + @IsArray() + distanceDonations: any[]; +} From 1d1fa50327927328ce77af33c1abbf994df9ac8b Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 09:05:02 +0100 Subject: [PATCH 07/20] Moved distance to the main runner object ref #1 --- src/models/CertificateRunner.ts | 13 +++---------- src/models/Runner.ts | 6 ++++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/models/CertificateRunner.ts b/src/models/CertificateRunner.ts index 937536e..a30b356 100644 --- a/src/models/CertificateRunner.ts +++ b/src/models/CertificateRunner.ts @@ -1,23 +1,16 @@ import { - IsArray, - IsInt + IsArray } from "class-validator"; +import { DistanceDonation } from './DistanceDonation'; import { Runner } from './Runner'; /** * Defines the certificate runner class (from which the runner certificates get generated). */ export class CertificateRunner extends Runner { - - /** - * The total distance ran by the runner. - */ - @IsInt() - distance: number; - /** * Array containing all distance donations associated with the runner. */ @IsArray() - distanceDonations: any[]; + distanceDonations: DistanceDonation[]; } diff --git a/src/models/Runner.ts b/src/models/Runner.ts index fec6235..826941a 100644 --- a/src/models/Runner.ts +++ b/src/models/Runner.ts @@ -38,4 +38,10 @@ export class Runner { */ @IsObject() group: RunnerGroup; + + /** + * The total distance ran by the runner. + */ + @IsInt() + distance: number; } From 1d73e4ed9ccb3dfb7709cb89957ed5bbcefad870 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 09:05:21 +0100 Subject: [PATCH 08/20] Added the donation classes ref #1 --- src/models/DistanceDonation.ts | 40 ++++++++++++++++++++++++++++++++++ src/models/Donation.ts | 32 +++++++++++++++++++++++++++ src/models/FixedDonation.ts | 16 ++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 src/models/DistanceDonation.ts create mode 100644 src/models/Donation.ts create mode 100644 src/models/FixedDonation.ts diff --git a/src/models/DistanceDonation.ts b/src/models/DistanceDonation.ts new file mode 100644 index 0000000..a4e35e1 --- /dev/null +++ b/src/models/DistanceDonation.ts @@ -0,0 +1,40 @@ +import { IsInt, IsNotEmpty, IsObject, IsPositive } from "class-validator"; +import { Donation } from "./Donation"; +import { Runner } from "./Runner"; + +/** + * Defines the DistanceDonation class. + * For distanceDonations a donor pledges to donate a certain amount for each kilometer ran by a runner. +*/ +export class DistanceDonation extends Donation { + /** + * The donation's associated runner. + * Used as the source of the donation's distance. + */ + @IsObject() + @IsNotEmpty() + runner: Runner; + + /** + * The donation's amount donated per distance. + * The amount the donor set to be donated per kilometer that the runner ran. + */ + @IsInt() + @IsPositive() + amountPerDistance: number; + + /** + * The donation's amount in cents (or whatever your currency's smallest unit is.). + * Get's calculated from the runner's distance ran and the amount donated per kilometer. + */ + public get amount(): number { + let calculatedAmount = 0; + try { + calculatedAmount = this.amountPerDistance * (this.runner.distance / 1000); + } catch (error) { + throw error; + } + return calculatedAmount; + } + +} diff --git a/src/models/Donation.ts b/src/models/Donation.ts new file mode 100644 index 0000000..1beaf0c --- /dev/null +++ b/src/models/Donation.ts @@ -0,0 +1,32 @@ +import { + IsInt, + IsNotEmpty, + IsObject +} from "class-validator"; +import { Donor } from './Donor'; + +/** + * Defines the Donation base calss. + * A donation just associates a donor with a donation amount. + * The specifics of the amoun's determination has to be implemented in child classes. +*/ +export abstract class Donation { + /** + * Autogenerated unique id (primary key). + */ + @IsInt() + id: number; + + /** + * The donations's donor. + */ + @IsNotEmpty() + @IsObject() + donor: Donor; + + /** + * The donation's amount in cents (or whatever your currency's smallest unit is.). + * The exact implementation may differ for each type of donation. + */ + public abstract get amount(): number; +} \ No newline at end of file diff --git a/src/models/FixedDonation.ts b/src/models/FixedDonation.ts new file mode 100644 index 0000000..18c8a23 --- /dev/null +++ b/src/models/FixedDonation.ts @@ -0,0 +1,16 @@ +import { IsInt, IsPositive } from "class-validator"; +import { Donation } from "./Donation"; + +/** + * Defines the FixedDonation entity. + * In the past there was no easy way to track fixed donations (eg. for creating donation receipts). +*/ +export class FixedDonation extends Donation { + + /** + * The donation's amount in cents (or whatever your currency's smallest unit is.). + */ + @IsInt() + @IsPositive() + amount: number; +} \ No newline at end of file From cfa65e83cafcefbd6261a99ab7a4eaf099665a81 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 09:09:10 +0100 Subject: [PATCH 09/20] Added a basic donor class ref #1 --- src/models/Donor.ts | 37 +++++++++++++++++++++++++++++++++++++ src/models/Runner.ts | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/models/Donor.ts diff --git a/src/models/Donor.ts b/src/models/Donor.ts new file mode 100644 index 0000000..cb9d9df --- /dev/null +++ b/src/models/Donor.ts @@ -0,0 +1,37 @@ +import { + + IsInt, + + + + IsString +} from "class-validator"; + +/** + * Defines the Donor class. +*/ +export class Donor { + /** + * The donor's id. + */ + @IsInt() + id: number; + + /** + * The donor's first name. + */ + @IsString() + firstname: string; + + /** + * The donor's middle name. + */ + @IsString() + middlename?: string; + + /** + * The donor's last name. + */ + @IsString() + lastname: string; +} diff --git a/src/models/Runner.ts b/src/models/Runner.ts index 826941a..f7968a8 100644 --- a/src/models/Runner.ts +++ b/src/models/Runner.ts @@ -6,7 +6,7 @@ import { import { RunnerGroup } from './RunnerGroup'; /** - * Defines the contract runner class (from which the runner sponsoring contracts get generated). + * Defines the runner class (from which the runner sponsoring contracts get generated). */ export class Runner { /** From 9f3758de39ef1d5b591a24868eb683caa742f694 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 09:59:34 +0100 Subject: [PATCH 10/20] Added PDFs to gitignore ref #3 --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 37345c3..72aa169 100644 --- a/.gitignore +++ b/.gitignore @@ -136,4 +136,5 @@ build /docs lib /oss-attribution -*.tmp \ No newline at end of file +*.tmp +*.pdf \ No newline at end of file From 8a30265fc600dad17f584f95dd51db976945d4c5 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 09:59:48 +0100 Subject: [PATCH 11/20] Added templates folder ref #3 --- src/templates/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/templates/.gitkeep diff --git a/src/templates/.gitkeep b/src/templates/.gitkeep new file mode 100644 index 0000000..e69de29 From 557cc26f281da0b47621dff667435a788c42c103 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 10:01:31 +0100 Subject: [PATCH 12/20] Added Barebones pdf creator class ref #3 --- src/PdfCreator.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/PdfCreator.ts diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts new file mode 100644 index 0000000..1650c79 --- /dev/null +++ b/src/PdfCreator.ts @@ -0,0 +1,14 @@ +import fs from "fs"; +import path from 'path'; + +/** + * This class is responsible for all things pdf creation. + * This uses the html templates from src/templates. + */ +export class PdFCreator { + private templateDir = path.join(__dirname, '/templates'); + + public generateSponsoringContract() { + const template = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8'); + } +} From 4617f2c5bdcb29534b46865ebe21d15e2b1cd72f Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 11:02:23 +0100 Subject: [PATCH 13/20] Resolved fun issues with promises ref #3 --- src/PdfCreator.ts | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index 1650c79..3fa95a8 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -1,14 +1,42 @@ import fs from "fs"; +import pdf_converter from "html-pdf"; import path from 'path'; - /** * This class is responsible for all things pdf creation. * This uses the html templates from src/templates. */ -export class PdFCreator { +export class PdfCreator { private templateDir = path.join(__dirname, '/templates'); - public generateSponsoringContract() { + public async generateSponsoringContract(): Promise { const template = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8'); + let pdf = await pdf_converter.create(template, { format: "A5", orientation: "landscape" }); + return await this.toBuffer(pdf); + } + + /** + * Promise wrapper function that resolves the toBuffer promise for pdf generation. + * @param pdf The pdf object that shall be turned into a buffer. + */ + public async toBuffer(pdf): Promise { + let promise = await new Promise((resolve, reject) => { + pdf.toBuffer(function (err, buffer) { + resolve(buffer); + }); + }); + return await promise; + } + + /** + * Promise wrapper function that resolves the toStream promise for pdf generation. + * @param pdf The pdf object that shall be turned into a stream. + */ + public async toStream(pdf): Promise { + let promise = await new Promise((resolve, reject) => { + pdf.toStream(function (err, stream) { + resolve(stream); + }); + }); + return await promise; } } From a7d4001ad992d60e2af69e9bbed53366bc0a46d3 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 11:03:06 +0100 Subject: [PATCH 14/20] Added html-pdf package ref #3 --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f2e080c..eb1477f 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "cors": "^2.8.5", "dotenv": "^8.2.0", "express": "^4.17.1", + "html-pdf": "^2.2.0", "reflect-metadata": "^0.1.13", "routing-controllers": "^0.9.0-alpha.6", "routing-controllers-openapi": "^2.2.0" @@ -72,4 +73,4 @@ "publish": false } } -} \ No newline at end of file +} From f726a6e699575b839d332c15e61c9008fe996fa9 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 11:20:47 +0100 Subject: [PATCH 15/20] Added a bs example template ref #3 --- src/templates/sponsoring_contract.html | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/templates/sponsoring_contract.html diff --git a/src/templates/sponsoring_contract.html b/src/templates/sponsoring_contract.html new file mode 100644 index 0000000..a1b7707 --- /dev/null +++ b/src/templates/sponsoring_contract.html @@ -0,0 +1,46 @@ + + + + Sponsoring contract + + + +
+

{{Runner Name}}

+
+ + \ No newline at end of file From 2c7b0254ec7e49c31f8f33eed334ab4156052fb6 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 11:27:14 +0100 Subject: [PATCH 16/20] Adjusted template font styleing ref #3 --- src/templates/sponsoring_contract.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/templates/sponsoring_contract.html b/src/templates/sponsoring_contract.html index a1b7707..1597b2c 100644 --- a/src/templates/sponsoring_contract.html +++ b/src/templates/sponsoring_contract.html @@ -8,7 +8,6 @@ padding: 0; font-family: 'Sackers Gothic Std'; font-weight: 500; - font-size: 70px; background: rgb(241,241,241); -webkit-print-color-adjust: exact; box-sizing: border-box; @@ -40,7 +39,7 @@
-

{{Runner Name}}

+

{{Runner Name}}

\ No newline at end of file From 3ca38abe9359e436fe0f80400ad0308ad9d64a4f Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 11:28:07 +0100 Subject: [PATCH 17/20] Switched to the splitted functions ref #3 --- src/PdfCreator.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index 3fa95a8..4ccd919 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -8,10 +8,11 @@ import path from 'path'; export class PdfCreator { private templateDir = path.join(__dirname, '/templates'); + //TODO: Accept the runner class public async generateSponsoringContract(): Promise { - const template = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8'); - let pdf = await pdf_converter.create(template, { format: "A5", orientation: "landscape" }); - return await this.toBuffer(pdf); + let template = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8'); + template = template.replace("{{Runner Name}}", "lelele"); + return await pdf_converter.create(template, { format: "A5", orientation: "landscape" }); } /** From 64bd1ffc3ad8459c13154e2cd9a568f27baa2bf2 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 11:28:24 +0100 Subject: [PATCH 18/20] Created a barebones pdf controller ref #3 --- src/controllers/PdfController.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/controllers/PdfController.ts diff --git a/src/controllers/PdfController.ts b/src/controllers/PdfController.ts new file mode 100644 index 0000000..9770b11 --- /dev/null +++ b/src/controllers/PdfController.ts @@ -0,0 +1,20 @@ +import { ContentType, Controller, Get } from 'routing-controllers'; +import { OpenAPI } from 'routing-controllers-openapi'; +import { PdfCreator } from '../PdfCreator'; + +@Controller() +export class PdfController { + private pdf: PdfCreator; + constructor() { + this.pdf = new PdfCreator(); + } + + @Get('/contracts') + @ContentType("application/pdf") + @OpenAPI({ description: "Generate Sponsoring contract pdfs from runner objects." }) + async generateContracts() { + //TODO: Accept the real classes + const contracts = await this.pdf.generateSponsoringContract(); + return await this.pdf.toBuffer(contracts); + } +} \ No newline at end of file From 7d5b5750ad78fd979cb1b647d8b318a84513532a Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 11:30:51 +0100 Subject: [PATCH 19/20] Created a pdf class that takes care of the pdf wrapping ref #3 --- src/PdfCreator.ts | 25 ++++++++++++++++--------- src/controllers/PdfController.ts | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index 4ccd919..8e547b2 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -9,19 +9,27 @@ export class PdfCreator { private templateDir = path.join(__dirname, '/templates'); //TODO: Accept the runner class - public async generateSponsoringContract(): Promise { + public async generateSponsoringContract(): Promise { let template = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8'); template = template.replace("{{Runner Name}}", "lelele"); - return await pdf_converter.create(template, { format: "A5", orientation: "landscape" }); + return new Pdf(await pdf_converter.create(template, { format: "A5", orientation: "landscape" })); + } + +} + +export class Pdf { + content: any; + + constructor(pdf: any) { + this.content = pdf; } /** * Promise wrapper function that resolves the toBuffer promise for pdf generation. - * @param pdf The pdf object that shall be turned into a buffer. */ - public async toBuffer(pdf): Promise { + public async toBuffer(): Promise { let promise = await new Promise((resolve, reject) => { - pdf.toBuffer(function (err, buffer) { + this.content.toBuffer(function (err, buffer) { resolve(buffer); }); }); @@ -30,14 +38,13 @@ export class PdfCreator { /** * Promise wrapper function that resolves the toStream promise for pdf generation. - * @param pdf The pdf object that shall be turned into a stream. */ - public async toStream(pdf): Promise { + public async toStream(): Promise { let promise = await new Promise((resolve, reject) => { - pdf.toStream(function (err, stream) { + this.content.toStream(function (err, stream) { resolve(stream); }); }); return await promise; } -} +} \ No newline at end of file diff --git a/src/controllers/PdfController.ts b/src/controllers/PdfController.ts index 9770b11..0ec9581 100644 --- a/src/controllers/PdfController.ts +++ b/src/controllers/PdfController.ts @@ -15,6 +15,6 @@ export class PdfController { async generateContracts() { //TODO: Accept the real classes const contracts = await this.pdf.generateSponsoringContract(); - return await this.pdf.toBuffer(contracts); + return await contracts.toBuffer(); } } \ No newline at end of file From 3fb8be22b74204accabed8a8c8fb5161c5ad7504 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 2 Feb 2021 11:34:01 +0100 Subject: [PATCH 20/20] Added typeing to the buffer and stream conversion ref #3 --- src/PdfCreator.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/PdfCreator.ts b/src/PdfCreator.ts index 8e547b2..2345c8c 100644 --- a/src/PdfCreator.ts +++ b/src/PdfCreator.ts @@ -1,6 +1,8 @@ import fs from "fs"; import pdf_converter from "html-pdf"; import path from 'path'; +import { Stream } from 'stream'; + /** * This class is responsible for all things pdf creation. * This uses the html templates from src/templates. @@ -17,6 +19,10 @@ export class PdfCreator { } +/** + * This class is a wrapper for the pdf objects created by html-pdf. + * It offers typed conversion to Buffer and Stream. + */ export class Pdf { content: any; @@ -27,9 +33,9 @@ export class Pdf { /** * Promise wrapper function that resolves the toBuffer promise for pdf generation. */ - public async toBuffer(): Promise { - let promise = await new Promise((resolve, reject) => { - this.content.toBuffer(function (err, buffer) { + public async toBuffer(): Promise { + let promise = await new Promise((resolve, reject) => { + this.content.toBuffer(function (err, buffer: Buffer) { resolve(buffer); }); }); @@ -39,9 +45,9 @@ export class Pdf { /** * Promise wrapper function that resolves the toStream promise for pdf generation. */ - public async toStream(): Promise { - let promise = await new Promise((resolve, reject) => { - this.content.toStream(function (err, stream) { + public async toStream(): Promise { + let promise = await new Promise((resolve, reject) => { + this.content.toStream(function (err, stream: Stream) { resolve(stream); }); });