add sorting to protocol agenda, decision and votings

This commit is contained in:
Julian Krauser 2025-03-21 09:46:29 +01:00
parent 4b6f0b34df
commit 2e5b345daa
22 changed files with 138 additions and 16 deletions

View file

@ -2,5 +2,6 @@ export interface SynchronizeProtocolAgendaCommand {
id?: number;
topic: string;
context: string;
sort?: number;
protocolId: number;
}

View file

@ -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<number>}
*/
static async create(protocolId: number): Promise<number> {
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) => {

View file

@ -2,5 +2,6 @@ export interface SynchronizeProtocolDecisionCommand {
id?: number;
topic: string;
context: string;
sort?: number;
protocolId: number;
}

View file

@ -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<number>}
*/
static async create(protocolId: number): Promise<number> {
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) => {

View file

@ -5,5 +5,6 @@ export interface SynchronizeProtocolVotingCommand {
favour: number;
abstain: number;
against: number;
sort?: number;
protocolId: number;
}

View file

@ -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<number>}
*/
static async create(protocolId: number): Promise<number> {
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) => {

View file

@ -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<ProtocolVotingViewModel>;
let syncVoting: Array<SynchronizeProtocolVotingCommand> = 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,
})
);

View file

@ -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",

View file

@ -12,6 +12,9 @@ export class protocolAgenda {
@Column({ type: "text", default: "" })
context: string;
@Column({ type: "int", default: 0 })
sort: number;
@Column()
protocolId: number;

View file

@ -12,6 +12,9 @@ export class protocolDecision {
@Column({ type: "text", default: "" })
context: string;
@Column({ type: "int", default: 0 })
sort: number;
@Column()
protocolId: number;

View file

@ -21,6 +21,9 @@ export class protocolVoting {
@Column({ type: "int", default: 0 })
against: number;
@Column({ type: "int", default: 0 })
sort: number;
@Column()
protocolId: number;

View file

@ -12,6 +12,7 @@ export default abstract class ProtocolAgendaFactory {
id: record.id,
topic: record.topic,
context: record.context,
sort: record.sort,
protocolId: record.protocolId,
};
}

View file

@ -12,6 +12,7 @@ export default abstract class ProtocolDecisionFactory {
id: record.id,
topic: record.topic,
context: record.context,
sort: record.sort,
protocolId: record.protocolId,
};
}

View file

@ -15,6 +15,7 @@ export default abstract class ProtocolVotingFactory {
favour: record.favour,
abstain: record.abstain,
against: record.against,
sort: record.sort,
protocolId: record.protocolId,
};
}

View file

@ -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<Array<any>> {

View file

@ -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<void> {
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<void> {
await queryRunner.dropColumn("protocol_agenda", "sort");
await queryRunner.dropColumn("protocol_decision", "sort");
await queryRunner.dropColumn("protocol_voting", "sort");
}
}

View file

@ -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<number>}
*/
static async getInstanceCount(protocolId: number): Promise<number> {
return await dataSource
.getRepository(protocolAgenda)
.createQueryBuilder("protocolAgenda")
.where({ protocolId })
.getCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("COUNT", "protocolAgenda", err);
});
}
}

View file

@ -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<number>}
*/
static async getInstanceCount(protocolId: number): Promise<number> {
return await dataSource
.getRepository(protocolDecision)
.createQueryBuilder("protocolDecisions")
.where({ protocolId })
.getCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("COUNT", "protocolDecision", err);
});
}
}

View file

@ -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<number>}
*/
static async getInstanceCount(protocolId: number): Promise<number> {
return await dataSource
.getRepository(protocolVoting)
.createQueryBuilder("protocolVotings")
.where({ protocolId })
.getCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("COUNT", "protocolVoting", err);
});
}
}

View file

@ -2,5 +2,6 @@ export interface ProtocolAgendaViewModel {
id: number;
topic: string;
context: string;
sort: number;
protocolId: number;
}

View file

@ -2,5 +2,6 @@ export interface ProtocolDecisionViewModel {
id: number;
topic: string;
context: string;
sort: number;
protocolId: number;
}

View file

@ -5,5 +5,6 @@ export interface ProtocolVotingViewModel {
favour: number;
abstain: number;
against: number;
sort: number;
protocolId: number;
}