From 2e5b345daaccfc4ffc73d031a8b2ccb87ede916b Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Fri, 21 Mar 2025 09:46:29 +0100 Subject: [PATCH] add sorting to protocol agenda, decision and votings --- .../club/protocol/protocolAgendaCommand.ts | 1 + .../protocol/protocolAgendaCommandHandler.ts | 5 +++- .../club/protocol/protocolDecisionCommand.ts | 1 + .../protocolDecisionCommandHandler.ts | 5 +++- .../club/protocol/protocolVotingCommand.ts | 1 + .../protocol/protocolVotingCommandHandler.ts | 5 +++- .../admin/club/protocolController.ts | 23 ++++++++------- src/data-source.ts | 2 ++ src/entity/club/protocol/protocolAgenda.ts | 3 ++ src/entity/club/protocol/protocolDecision.ts | 3 ++ src/entity/club/protocol/protocolVoting.ts | 3 ++ .../admin/club/protocol/protocolAgenda.ts | 1 + .../admin/club/protocol/protocolDecision.ts | 1 + .../admin/club/protocol/protocolVoting.ts | 1 + src/helpers/backupHelper.ts | 13 +++++++-- src/migrations/1742544887410-protocolSort.ts | 29 +++++++++++++++++++ .../club/protocol/protocolAgendaService.ts | 18 ++++++++++++ .../club/protocol/protocolDecisionService.ts | 18 ++++++++++++ .../club/protocol/protocolVotingService.ts | 18 ++++++++++++ .../club/protocol/protocolAgenda.models.ts | 1 + .../club/protocol/protocolDecision.models.ts | 1 + .../club/protocol/protocolVoting.models.ts | 1 + 22 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 src/migrations/1742544887410-protocolSort.ts diff --git a/src/command/club/protocol/protocolAgendaCommand.ts b/src/command/club/protocol/protocolAgendaCommand.ts index 749390d..2889122 100644 --- a/src/command/club/protocol/protocolAgendaCommand.ts +++ b/src/command/club/protocol/protocolAgendaCommand.ts @@ -2,5 +2,6 @@ export interface SynchronizeProtocolAgendaCommand { id?: number; topic: string; context: string; + sort?: number; protocolId: number; } diff --git a/src/command/club/protocol/protocolAgendaCommandHandler.ts b/src/command/club/protocol/protocolAgendaCommandHandler.ts index 02fe4f2..96dbc08 100644 --- a/src/command/club/protocol/protocolAgendaCommandHandler.ts +++ b/src/command/club/protocol/protocolAgendaCommandHandler.ts @@ -2,6 +2,7 @@ import { dataSource } from "../../../data-source"; import { protocolAgenda } from "../../../entity/club/protocol/protocolAgenda"; import DatabaseActionException from "../../../exceptions/databaseActionException"; import InternalException from "../../../exceptions/internalException"; +import ProtocolAgendaService from "../../../service/club/protocol/protocolAgendaService"; import { SynchronizeProtocolAgendaCommand } from "./protocolAgendaCommand"; export default abstract class ProtocolAgendaCommandHandler { @@ -11,6 +12,7 @@ export default abstract class ProtocolAgendaCommandHandler { * @returns {Promise} */ static async create(protocolId: number): Promise { + let count = await ProtocolAgendaService.getInstanceCount(protocolId); return await dataSource .createQueryBuilder() .insert() @@ -18,6 +20,7 @@ export default abstract class ProtocolAgendaCommandHandler { .values({ topic: "", context: "", + sort: count, protocolId, }) .execute() @@ -40,7 +43,7 @@ export default abstract class ProtocolAgendaCommandHandler { .insert() .into(protocolAgenda) .values(syncProtocolAgenda) - .orUpdate(["topic", "context"], ["id"]) + .orUpdate(["topic", "context", "sort"], ["id"]) .execute() .then(() => {}) .catch((err) => { diff --git a/src/command/club/protocol/protocolDecisionCommand.ts b/src/command/club/protocol/protocolDecisionCommand.ts index 61eb6f0..aeb2f24 100644 --- a/src/command/club/protocol/protocolDecisionCommand.ts +++ b/src/command/club/protocol/protocolDecisionCommand.ts @@ -2,5 +2,6 @@ export interface SynchronizeProtocolDecisionCommand { id?: number; topic: string; context: string; + sort?: number; protocolId: number; } diff --git a/src/command/club/protocol/protocolDecisionCommandHandler.ts b/src/command/club/protocol/protocolDecisionCommandHandler.ts index 585abf1..9425d38 100644 --- a/src/command/club/protocol/protocolDecisionCommandHandler.ts +++ b/src/command/club/protocol/protocolDecisionCommandHandler.ts @@ -2,6 +2,7 @@ import { dataSource } from "../../../data-source"; import { protocolDecision } from "../../../entity/club/protocol/protocolDecision"; import DatabaseActionException from "../../../exceptions/databaseActionException"; import InternalException from "../../../exceptions/internalException"; +import ProtocolDecisionService from "../../../service/club/protocol/protocolDecisionService"; import { SynchronizeProtocolDecisionCommand } from "./protocolDecisionCommand"; export default abstract class ProtocolDecisionCommandHandler { @@ -11,6 +12,7 @@ export default abstract class ProtocolDecisionCommandHandler { * @returns {Promise} */ static async create(protocolId: number): Promise { + let count = await ProtocolDecisionService.getInstanceCount(protocolId); return await dataSource .createQueryBuilder() .insert() @@ -18,6 +20,7 @@ export default abstract class ProtocolDecisionCommandHandler { .values({ topic: "", context: "", + sort: count, protocolId, }) .execute() @@ -39,7 +42,7 @@ export default abstract class ProtocolDecisionCommandHandler { .insert() .into(protocolDecision) .values(syncProtocolDecisions) - .orUpdate(["topic", "context"], ["id"]) + .orUpdate(["topic", "context", "sort"], ["id"]) .execute() .then(() => {}) .catch((err) => { diff --git a/src/command/club/protocol/protocolVotingCommand.ts b/src/command/club/protocol/protocolVotingCommand.ts index a707b64..617a560 100644 --- a/src/command/club/protocol/protocolVotingCommand.ts +++ b/src/command/club/protocol/protocolVotingCommand.ts @@ -5,5 +5,6 @@ export interface SynchronizeProtocolVotingCommand { favour: number; abstain: number; against: number; + sort?: number; protocolId: number; } diff --git a/src/command/club/protocol/protocolVotingCommandHandler.ts b/src/command/club/protocol/protocolVotingCommandHandler.ts index 45a4642..741c0da 100644 --- a/src/command/club/protocol/protocolVotingCommandHandler.ts +++ b/src/command/club/protocol/protocolVotingCommandHandler.ts @@ -2,6 +2,7 @@ import { dataSource } from "../../../data-source"; import { protocolVoting } from "../../../entity/club/protocol/protocolVoting"; import DatabaseActionException from "../../../exceptions/databaseActionException"; import InternalException from "../../../exceptions/internalException"; +import ProtocolVotingService from "../../../service/club/protocol/protocolVotingService"; import { SynchronizeProtocolVotingCommand } from "./protocolVotingCommand"; export default abstract class ProtocolVotingCommandHandler { @@ -11,6 +12,7 @@ export default abstract class ProtocolVotingCommandHandler { * @returns {Promise} */ static async create(protocolId: number): Promise { + let count = await ProtocolVotingService.getInstanceCount(protocolId); return await dataSource .createQueryBuilder() .insert() @@ -18,6 +20,7 @@ export default abstract class ProtocolVotingCommandHandler { .values({ topic: "", context: "", + sort: count, protocolId, }) .execute() @@ -39,7 +42,7 @@ export default abstract class ProtocolVotingCommandHandler { .insert() .into(protocolVoting) .values(syncProtocolVotings) - .orUpdate(["topic", "context", "favour", "abstain", "against"], ["id"]) + .orUpdate(["topic", "context", "favour", "abstain", "against", "sort"], ["id"]) .execute() .then(() => {}) .catch((err) => { diff --git a/src/controller/admin/club/protocolController.ts b/src/controller/admin/club/protocolController.ts index 868715f..2a6f5fb 100644 --- a/src/controller/admin/club/protocolController.ts +++ b/src/controller/admin/club/protocolController.ts @@ -257,13 +257,13 @@ export async function createProtocolPrintoutById(req: Request, res: Response): P }), start: protocol.starttime, end: protocol.endtime, - agenda, - decisions, + agenda: agenda.sort((a, b) => a.sort - b.sort), + decisions: decisions.sort((a, b) => a.sort - b.sort), presence: presence.filter((p) => !p.absent).map((p) => p.member), absent: presence.filter((p) => p.absent).map((p) => ({ ...p.member, excused: p.excused })), excused_absent: presence.filter((p) => p.absent && p.excused).map((p) => p.member), unexcused_absent: presence.filter((p) => p.absent && !p.excused).map((p) => p.member), - votings, + votings: votings.sort((a, b) => a.sort - b.sort), }, }); @@ -320,6 +320,7 @@ export async function synchronizeProtocolAgendaById(req: Request, res: Response) id: a.id ?? null, topic: a.topic, context: a.context, + sort: a.sort, protocolId, }) ); @@ -343,6 +344,7 @@ export async function synchronizeProtocolDecisonsById(req: Request, res: Respons id: d.id ?? null, topic: d.topic, context: d.context, + sort: d.sort, protocolId, }) ); @@ -362,13 +364,14 @@ export async function synchronizeProtocolVotingsById(req: Request, res: Response let votings = req.body.votings as Array; let syncVoting: Array = votings.map( - (d: ProtocolVotingViewModel): SynchronizeProtocolVotingCommand => ({ - id: d.id ?? null, - topic: d.topic, - context: d.context, - favour: d.favour, - abstain: d.abstain, - against: d.abstain, + (v: ProtocolVotingViewModel): SynchronizeProtocolVotingCommand => ({ + id: v.id ?? null, + topic: v.topic, + context: v.context, + favour: v.favour, + abstain: v.abstain, + against: v.abstain, + sort: v.sort, protocolId, }) ); diff --git a/src/data-source.ts b/src/data-source.ts index ea45dc3..37aebfd 100644 --- a/src/data-source.ts +++ b/src/data-source.ts @@ -49,6 +49,7 @@ import { BackupAndResetDatabase1738166124200 } from "./migrations/1738166124200- import { CreateSchema1738166167472 } from "./migrations/1738166167472-CreateSchema"; import { MemberPrintoutTemplates1742207245862 } from "./migrations/1742207245862-memberPrintoutTemplates"; import { Listprinting1742311486232 } from "./migrations/1742311486232-listprinting"; +import { ProtocolSort1742544887410 } from "./migrations/1742544887410-protocolSort"; const dataSource = new DataSource({ type: DB_TYPE as any, @@ -107,6 +108,7 @@ const dataSource = new DataSource({ CreateSchema1738166167472, MemberPrintoutTemplates1742207245862, Listprinting1742311486232, + ProtocolSort1742544887410, ], migrationsRun: true, migrationsTransactionMode: "each", diff --git a/src/entity/club/protocol/protocolAgenda.ts b/src/entity/club/protocol/protocolAgenda.ts index 7ce7556..a64bf9a 100644 --- a/src/entity/club/protocol/protocolAgenda.ts +++ b/src/entity/club/protocol/protocolAgenda.ts @@ -12,6 +12,9 @@ export class protocolAgenda { @Column({ type: "text", default: "" }) context: string; + @Column({ type: "int", default: 0 }) + sort: number; + @Column() protocolId: number; diff --git a/src/entity/club/protocol/protocolDecision.ts b/src/entity/club/protocol/protocolDecision.ts index 4978d17..e2cc4c1 100644 --- a/src/entity/club/protocol/protocolDecision.ts +++ b/src/entity/club/protocol/protocolDecision.ts @@ -12,6 +12,9 @@ export class protocolDecision { @Column({ type: "text", default: "" }) context: string; + @Column({ type: "int", default: 0 }) + sort: number; + @Column() protocolId: number; diff --git a/src/entity/club/protocol/protocolVoting.ts b/src/entity/club/protocol/protocolVoting.ts index 8e8f7a1..438e8fc 100644 --- a/src/entity/club/protocol/protocolVoting.ts +++ b/src/entity/club/protocol/protocolVoting.ts @@ -21,6 +21,9 @@ export class protocolVoting { @Column({ type: "int", default: 0 }) against: number; + @Column({ type: "int", default: 0 }) + sort: number; + @Column() protocolId: number; diff --git a/src/factory/admin/club/protocol/protocolAgenda.ts b/src/factory/admin/club/protocol/protocolAgenda.ts index aa15b75..65d2334 100644 --- a/src/factory/admin/club/protocol/protocolAgenda.ts +++ b/src/factory/admin/club/protocol/protocolAgenda.ts @@ -12,6 +12,7 @@ export default abstract class ProtocolAgendaFactory { id: record.id, topic: record.topic, context: record.context, + sort: record.sort, protocolId: record.protocolId, }; } diff --git a/src/factory/admin/club/protocol/protocolDecision.ts b/src/factory/admin/club/protocol/protocolDecision.ts index 0fbfff5..608bc2a 100644 --- a/src/factory/admin/club/protocol/protocolDecision.ts +++ b/src/factory/admin/club/protocol/protocolDecision.ts @@ -12,6 +12,7 @@ export default abstract class ProtocolDecisionFactory { id: record.id, topic: record.topic, context: record.context, + sort: record.sort, protocolId: record.protocolId, }; } diff --git a/src/factory/admin/club/protocol/protocolVoting.ts b/src/factory/admin/club/protocol/protocolVoting.ts index 2f4fa4e..49f954c 100644 --- a/src/factory/admin/club/protocol/protocolVoting.ts +++ b/src/factory/admin/club/protocol/protocolVoting.ts @@ -15,6 +15,7 @@ export default abstract class ProtocolVotingFactory { favour: record.favour, abstain: record.abstain, against: record.against, + sort: record.sort, protocolId: record.protocolId, }; } diff --git a/src/helpers/backupHelper.ts b/src/helpers/backupHelper.ts index a60e963..7727527 100644 --- a/src/helpers/backupHelper.ts +++ b/src/helpers/backupHelper.ts @@ -300,8 +300,8 @@ export default abstract class BackupHelper { .leftJoin("protocol.printouts", "printouts") .leftJoin("protocol.votings", "votings") .select(["protocol.title", "protocol.date", "protocol.starttime", "protocol.endtime", "protocol.summary"]) - .addSelect(["agendas.topic", "agendas.context"]) - .addSelect(["decisions.topic", "decisions.context"]) + .addSelect(["agendas.topic", "agendas.context", "agendas.sort"]) + .addSelect(["decisions.topic", "decisions.context", "decisions.sort"]) .addSelect(["presences.absent", "presences.excused"]) .addSelect([ ...(collectIds ? ["member.id"] : []), @@ -312,7 +312,14 @@ export default abstract class BackupHelper { "member.internalId", ]) .addSelect(["printouts.title", "printouts.iteration", "printouts.filename", "printouts.createdAt"]) - .addSelect(["votings.topic", "votings.context", "votings.favour", "votings.abstain", "votings.against"]) + .addSelect([ + "votings.topic", + "votings.context", + "votings.favour", + "votings.abstain", + "votings.against", + "votings.sort", + ]) .getMany(); } private static async getNewsletter(collectIds: boolean): Promise> { diff --git a/src/migrations/1742544887410-protocolSort.ts b/src/migrations/1742544887410-protocolSort.ts new file mode 100644 index 0000000..77f6011 --- /dev/null +++ b/src/migrations/1742544887410-protocolSort.ts @@ -0,0 +1,29 @@ +import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; +import { getDefaultByORM, getTypeByORM } from "./ormHelper"; + +export class ProtocolSort1742544887410 implements MigrationInterface { + name = "ProtocolSort1742544887410"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumn( + "protocol_agenda", + new TableColumn({ name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) }) + ); + + await queryRunner.addColumn( + "protocol_decision", + new TableColumn({ name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) }) + ); + + await queryRunner.addColumn( + "protocol_voting", + new TableColumn({ name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn("protocol_agenda", "sort"); + await queryRunner.dropColumn("protocol_decision", "sort"); + await queryRunner.dropColumn("protocol_voting", "sort"); + } +} diff --git a/src/service/club/protocol/protocolAgendaService.ts b/src/service/club/protocol/protocolAgendaService.ts index fb8ead8..7d54168 100644 --- a/src/service/club/protocol/protocolAgendaService.ts +++ b/src/service/club/protocol/protocolAgendaService.ts @@ -39,4 +39,22 @@ export default abstract class ProtocolAgendaService { throw new DatabaseActionException("SELECT", "protocolAgenda", err); }); } + + /** + * @description get count of exisiting protocolAgenda by protocolId + * @returns {Promise} + */ + static async getInstanceCount(protocolId: number): Promise { + return await dataSource + .getRepository(protocolAgenda) + .createQueryBuilder("protocolAgenda") + .where({ protocolId }) + .getCount() + .then((res) => { + return res; + }) + .catch((err) => { + throw new DatabaseActionException("COUNT", "protocolAgenda", err); + }); + } } diff --git a/src/service/club/protocol/protocolDecisionService.ts b/src/service/club/protocol/protocolDecisionService.ts index 56ac4c6..241dba2 100644 --- a/src/service/club/protocol/protocolDecisionService.ts +++ b/src/service/club/protocol/protocolDecisionService.ts @@ -39,4 +39,22 @@ export default abstract class ProtocolDecisionService { throw new DatabaseActionException("SELECT", "protocolDecision", err); }); } + + /** + * @description get count of exisiting protocolDecision by protocolId + * @returns {Promise} + */ + static async getInstanceCount(protocolId: number): Promise { + return await dataSource + .getRepository(protocolDecision) + .createQueryBuilder("protocolDecisions") + .where({ protocolId }) + .getCount() + .then((res) => { + return res; + }) + .catch((err) => { + throw new DatabaseActionException("COUNT", "protocolDecision", err); + }); + } } diff --git a/src/service/club/protocol/protocolVotingService.ts b/src/service/club/protocol/protocolVotingService.ts index 2000cce..220d29e 100644 --- a/src/service/club/protocol/protocolVotingService.ts +++ b/src/service/club/protocol/protocolVotingService.ts @@ -39,4 +39,22 @@ export default abstract class ProtocolVotingService { throw new DatabaseActionException("SELECT", "protocolVoting", err); }); } + + /** + * @description get count of exisiting protocolVoting by protocolId + * @returns {Promise} + */ + static async getInstanceCount(protocolId: number): Promise { + return await dataSource + .getRepository(protocolVoting) + .createQueryBuilder("protocolVotings") + .where({ protocolId }) + .getCount() + .then((res) => { + return res; + }) + .catch((err) => { + throw new DatabaseActionException("COUNT", "protocolVoting", err); + }); + } } diff --git a/src/viewmodel/admin/club/protocol/protocolAgenda.models.ts b/src/viewmodel/admin/club/protocol/protocolAgenda.models.ts index 3a59327..eed423d 100644 --- a/src/viewmodel/admin/club/protocol/protocolAgenda.models.ts +++ b/src/viewmodel/admin/club/protocol/protocolAgenda.models.ts @@ -2,5 +2,6 @@ export interface ProtocolAgendaViewModel { id: number; topic: string; context: string; + sort: number; protocolId: number; } diff --git a/src/viewmodel/admin/club/protocol/protocolDecision.models.ts b/src/viewmodel/admin/club/protocol/protocolDecision.models.ts index 4a7212c..7de33c4 100644 --- a/src/viewmodel/admin/club/protocol/protocolDecision.models.ts +++ b/src/viewmodel/admin/club/protocol/protocolDecision.models.ts @@ -2,5 +2,6 @@ export interface ProtocolDecisionViewModel { id: number; topic: string; context: string; + sort: number; protocolId: number; } diff --git a/src/viewmodel/admin/club/protocol/protocolVoting.models.ts b/src/viewmodel/admin/club/protocol/protocolVoting.models.ts index 686f423..a5bd723 100644 --- a/src/viewmodel/admin/club/protocol/protocolVoting.models.ts +++ b/src/viewmodel/admin/club/protocol/protocolVoting.models.ts @@ -5,5 +5,6 @@ export interface ProtocolVotingViewModel { favour: number; abstain: number; against: number; + sort: number; protocolId: number; }