#25-cleanup-&-enhancements #26
17 changed files with 101 additions and 20 deletions
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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[];
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
47
src/migrations/1735822722235-internalId.ts
Normal file
47
src/migrations/1735822722235-internalId.ts
Normal 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");
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -9,6 +9,7 @@ export interface MemberViewModel {
|
|||
lastname: string;
|
||||
nameaffix: string;
|
||||
birthdate: Date;
|
||||
internalId?: string;
|
||||
firstMembershipEntry?: MembershipViewModel;
|
||||
lastMembershipEntry?: MembershipViewModel;
|
||||
sendNewsletter?: CommunicationViewModel;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
export interface MembershipViewModel {
|
||||
id: number;
|
||||
internalId?: string;
|
||||
start: Date;
|
||||
end?: Date;
|
||||
terminationReason?: string;
|
||||
|
|
Loading…
Reference in a new issue