#25-cleanup-&-enhancements #26

Merged
jkeffects merged 4 commits from #25-cleanup-&-enhancements into main 2025-01-02 17:37:19 +00:00
17 changed files with 101 additions and 20 deletions
Showing only changes of commit 0d2c7dd7f1 - Show all commits

View file

@ -6,6 +6,7 @@ export interface CreateMemberCommand {
lastname: string;
nameaffix: string;
birthdate: Date;
internalId?: string;
}
export interface UpdateMemberCommand {
@ -15,6 +16,7 @@ export interface UpdateMemberCommand {
lastname: string;
nameaffix: string;
birthdate: Date;
internalId?: string;
}
export interface UpdateMemberNewsletterCommand {

View file

@ -27,6 +27,7 @@ export default abstract class MemberCommandHandler {
lastname: createMember.lastname,
nameaffix: createMember.nameaffix,
birthdate: createMember.birthdate,
internalId: createMember.internalId,
})
.execute()
.then((result) => {
@ -53,6 +54,7 @@ export default abstract class MemberCommandHandler {
lastname: updateMember.lastname,
nameaffix: updateMember.nameaffix,
birthdate: updateMember.birthdate,
internalId: updateMember.internalId,
})
.where("id = :id", { id: updateMember.id })
.execute()

View file

@ -1,5 +1,4 @@
export interface CreateMembershipCommand {
internalId?: string;
start: Date;
memberId: number;
statusId: number;
@ -7,7 +6,6 @@ export interface CreateMembershipCommand {
export interface UpdateMembershipCommand {
id: number;
internalId?: string;
start: Date;
end?: Date;
terminationReason?: string;

View file

@ -8,11 +8,11 @@ import { CreateMembershipCommand, DeleteMembershipCommand, UpdateMembershipComma
export default abstract class MembershipCommandHandler {
/**
* @description create membership
* @param CreateMembershipCommand
* @param {CreateMembershipCommand} createMembership
* @returns {Promise<number>}
*/
static async create(createMembership: CreateMembershipCommand): Promise<number> {
let insertid = -1;
let insertId = -1;
return await dataSource
.transaction(async (manager) => {
await manager
@ -20,7 +20,6 @@ export default abstract class MembershipCommandHandler {
.insert()
.into(membership)
.values({
internalId: createMembership.internalId,
start: createMembership.start,
member: await dataSource
.getRepository(member)
@ -35,7 +34,7 @@ export default abstract class MembershipCommandHandler {
})
.execute()
.then((result) => {
insertid = result.identifiers[0].id;
insertId = result.identifiers[0].id;
});
await manager
@ -43,14 +42,15 @@ export default abstract class MembershipCommandHandler {
.update(membership)
.set({
end: createMembership.start,
terminationReason: "beendet durch neuen Eintrag.",
})
.where("end IS NULL")
.andWhere("memberId = :memberId", { memberId: createMembership.memberId })
.andWhere("id <> :id", { id: insertid })
.andWhere("id <> :id", { id: insertId })
.execute();
})
.then(() => {
return insertid;
return insertId;
})
.catch((err) => {
throw new InternalException("Failed creating membership", err);
@ -59,7 +59,7 @@ export default abstract class MembershipCommandHandler {
/**
* @description update membership
* @param UpdateMembershipCommand
* @param {UpdateMembershipCommand} updateMembership
* @returns {Promise<void>}
*/
static async update(updateMembership: UpdateMembershipCommand): Promise<void> {
@ -67,7 +67,6 @@ export default abstract class MembershipCommandHandler {
.createQueryBuilder()
.update(membership)
.set({
internalId: updateMembership.internalId,
start: updateMembership.start,
end: updateMembership.end,
terminationReason: updateMembership.terminationReason,
@ -88,16 +87,16 @@ export default abstract class MembershipCommandHandler {
/**
* @description delete membership
* @param DeleteMembershipCommand
* @param {DeleteMembershipCommand} deleteMembership
* @returns {Promise<void>}
*/
static async delete(deletMembership: DeleteMembershipCommand): Promise<void> {
static async delete(deleteMembership: DeleteMembershipCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(membership)
.where("id = :id", { id: deletMembership.id })
.andWhere("memberId = :memberId", { memberId: deletMembership.memberId })
.where("id = :id", { id: deleteMembership.id })
.andWhere("memberId = :memberId", { memberId: deleteMembership.memberId })
.execute()
.then(() => {})
.catch((err) => {

View file

@ -228,6 +228,7 @@ export async function createMember(req: Request, res: Response): Promise<any> {
const lastname = req.body.lastname;
const nameaffix = req.body.nameaffix;
const birthdate = req.body.birthdate;
const internalId = req.body.internalId;
let createMember: CreateMemberCommand = {
salutation,
@ -235,6 +236,7 @@ export async function createMember(req: Request, res: Response): Promise<any> {
lastname,
nameaffix,
birthdate,
internalId,
};
let memberId = await MemberCommandHandler.create(createMember);
@ -249,12 +251,10 @@ export async function createMember(req: Request, res: Response): Promise<any> {
*/
export async function addMembershipToMember(req: Request, res: Response): Promise<any> {
const memberId = parseInt(req.params.memberId);
const internalId = req.body.internalId;
const start = req.body.start;
const statusId = req.body.statusId;
let createMembership: CreateMembershipCommand = {
internalId,
start,
memberId,
statusId,
@ -394,6 +394,7 @@ export async function updateMemberById(req: Request, res: Response): Promise<any
const lastname = req.body.lastname;
const nameaffix = req.body.nameaffix;
const birthdate = req.body.birthdate;
const internalId = req.body.internalId;
let updateMember: UpdateMemberCommand = {
id: memberId,
@ -402,6 +403,7 @@ export async function updateMemberById(req: Request, res: Response): Promise<any
lastname,
nameaffix,
birthdate,
internalId,
};
await MemberCommandHandler.update(updateMember);
@ -417,7 +419,6 @@ export async function updateMemberById(req: Request, res: Response): Promise<any
export async function updateMembershipOfMember(req: Request, res: Response): Promise<any> {
const memberId = parseInt(req.params.memberId);
const recordId = parseInt(req.params.recordId);
const internalId = req.body.internalId;
const start = req.body.start;
const end = req.body.end || null;
const terminationReason = req.body.terminationReason;
@ -425,7 +426,6 @@ export async function updateMembershipOfMember(req: Request, res: Response): Pro
let updateMembership: UpdateMembershipCommand = {
id: recordId,
internalId,
start,
end,
terminationReason,

View file

@ -62,6 +62,7 @@ import { Newsletter1735118780511 } from "./migrations/1735118780511-newsletter";
import { newsletterConfig } from "./entity/newsletterConfig";
import { NewsletterConfig1735207446910 } from "./migrations/1735207446910-newsletterConfig";
import { TemplateMargins1735733514043 } from "./migrations/1735733514043-templateMargins";
import { InternalId1735822722235 } from "./migrations/1735822722235-internalId";
const dataSource = new DataSource({
type: DB_TYPE as any,
@ -134,6 +135,7 @@ const dataSource = new DataSource({
Newsletter1735118780511,
NewsletterConfig1735207446910,
TemplateMargins1735733514043,
InternalId1735822722235,
],
migrationsRun: true,
migrationsTransactionMode: "each",

View file

@ -39,6 +39,9 @@ export class member {
@Column({ type: "date" })
birthdate: Date;
@Column({ type: "varchar", length: 255, unique: true, nullable: true })
internalId?: string;
@OneToMany(() => communication, (communications) => communications.member)
communications: communication[];

View file

@ -16,6 +16,12 @@ export class memberAwards {
@Column({ type: "date" })
date: Date;
@Column()
memberId: number;
@Column()
awardId: number;
@ManyToOne(() => member, (member) => member.awards, {
nullable: false,
onDelete: "CASCADE",

View file

@ -16,6 +16,12 @@ export class memberExecutivePositions {
@Column({ type: "date", nullable: true })
end?: Date;
@Column()
memberId: number;
@Column()
executivePositionId: number;
@ManyToOne(() => member, (member) => member.awards, {
nullable: false,
onDelete: "CASCADE",

View file

@ -19,6 +19,12 @@ export class memberQualifications {
@Column({ type: "varchar", length: 255, nullable: true })
terminationReason?: string;
@Column()
memberId: number;
@Column()
qualificationId: number;
@ManyToOne(() => member, (member) => member.awards, {
nullable: false,
onDelete: "CASCADE",

View file

@ -7,6 +7,9 @@ export class membership {
@PrimaryColumn({ generated: "increment", type: "int" })
id: number;
/**
* @deprecated
*/
@Column({ type: "varchar", length: 255, unique: true, nullable: true })
internalId?: string;
@ -19,6 +22,12 @@ export class membership {
@Column({ type: "varchar", length: 255, nullable: true })
terminationReason?: string;
@Column()
memberId: number;
@Column()
statusId: number;
@ManyToOne(() => member, (member) => member.memberships, {
nullable: false,
onDelete: "CASCADE",

View file

@ -17,6 +17,7 @@ export default abstract class MemberFactory {
lastname: record?.lastname,
nameaffix: record?.nameaffix,
birthdate: record?.birthdate,
internalId: record.internalId,
firstMembershipEntry: record?.firstMembershipEntry
? MembershipFactory.mapToSingle(record.firstMembershipEntry)
: null,

View file

@ -10,7 +10,6 @@ export default abstract class MembershipFactory {
public static mapToSingle(record: membership): MembershipViewModel {
return {
id: record.id,
internalId: record.internalId,
start: record.start,
end: record.end,
terminationReason: record.terminationReason,

View file

@ -0,0 +1,47 @@
import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
import { membership } from "../entity/membership";
import { member } from "../entity/member";
export class InternalId1735822722235 implements MigrationInterface {
name = "InternalId1735822722235";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.addColumn(
"member",
new TableColumn({
name: "internalId",
type: "varchar",
length: "255",
default: null,
isNullable: true,
isUnique: true,
})
);
let memberships = await queryRunner.manager.getRepository(membership).find();
console.log(memberships);
let internalIds = memberships.reduce<{ [key: number]: Array<string> }>((acc, cur) => {
let memberId = cur.memberId;
let setIds = acc[memberId] ?? [];
if (cur?.internalId) {
setIds.push(cur.internalId);
}
acc[memberId] = setIds;
return acc;
}, {});
console.log(internalIds);
for (const [id, value] of Object.entries(internalIds)) {
const ids = value.filter((v) => v != null).join(", ");
if (ids) {
let m = await queryRunner.manager.getRepository(member).findOneByOrFail({ id: parseInt(id) });
m.internalId = ids;
await queryRunner.manager.getRepository(member).save(m);
}
}
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropColumn("member", "internalId");
}
}

View file

@ -14,6 +14,7 @@ export default abstract class MembershipService {
.createQueryBuilder("membership")
.leftJoinAndSelect("membership.status", "membershipStatus")
.where("membership.memberId = :memberId", { memberId: memberId })
.orderBy("membership.start", "DESC")
.getMany()
.then((res) => {
return res;

View file

@ -9,6 +9,7 @@ export interface MemberViewModel {
lastname: string;
nameaffix: string;
birthdate: Date;
internalId?: string;
firstMembershipEntry?: MembershipViewModel;
lastMembershipEntry?: MembershipViewModel;
sendNewsletter?: CommunicationViewModel;

View file

@ -1,6 +1,5 @@
export interface MembershipViewModel {
id: number;
internalId?: string;
start: Date;
end?: Date;
terminationReason?: string;