diff --git a/src/data-source.ts b/src/data-source.ts index 8f5b1f4..21c23a2 100644 --- a/src/data-source.ts +++ b/src/data-source.ts @@ -22,6 +22,12 @@ import { Invite1724579024939 } from "./migrations/1724579024939-invite"; import { Permissions1724661484664 } from "./migrations/1724661484664-permissions"; import { RolePermission1724771491085 } from "./migrations/1724771491085-role_permission"; import { MemberBaseData1725435669492 } from "./migrations/1725435669492-member_base_data"; +import { member } from "./entity/member"; +import { memberAwards } from "./entity/memberAwards"; +import { memberExecutivePositions } from "./entity/memberExecutivePositions"; +import { memberQualifications } from "./entity/memberQualifications"; +import { membership } from "./entity/membership"; +import { Memberdata1726301836849 } from "./migrations/1726301836849-memberdata"; const dataSource = new DataSource({ type: DB_TYPE as any, @@ -46,6 +52,11 @@ const dataSource = new DataSource({ executivePosition, membershipStatus, qualification, + member, + memberAwards, + memberExecutivePositions, + memberQualifications, + membership, ], migrations: [ Initial1724317398939, @@ -54,6 +65,7 @@ const dataSource = new DataSource({ Permissions1724661484664, RolePermission1724771491085, MemberBaseData1725435669492, + Memberdata1726301836849, ], migrationsRun: true, migrationsTransactionMode: "each", diff --git a/src/entity/award.ts b/src/entity/award.ts index e5b8d38..cf26689 100644 --- a/src/entity/award.ts +++ b/src/entity/award.ts @@ -1,5 +1,5 @@ import { Column, Entity, OneToMany, PrimaryColumn } from "typeorm"; -//import { memberAwards } from "./memberAwards"; +import { memberAwards } from "./memberAwards"; @Entity() export class award { @@ -9,8 +9,6 @@ export class award { @Column({ type: "varchar", length: 255 }) award: string; - // @OneToMany(() => memberAwards, (member) => member.award, { - // onDelete: "RESTRICT", - // }) - // members: memberAwards[]; + @OneToMany(() => memberAwards, (member) => member.award) + members: memberAwards[]; } diff --git a/src/entity/communication.ts b/src/entity/communication.ts index 78164d8..fc9aa79 100644 --- a/src/entity/communication.ts +++ b/src/entity/communication.ts @@ -1,5 +1,5 @@ import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm"; -//import { member } from "./member"; +import { member } from "./member"; import { communicationType } from "./communicationType"; @Entity() @@ -33,8 +33,10 @@ export class communication { }) type: communicationType; - // @ManyToOne(() => member, (member) => member.awards, { - // onDelete: "RESTRICT", - // }) - // member: member; + @ManyToOne(() => member, (member) => member.awards, { + nullable: false, + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + member: member; } diff --git a/src/entity/communicationType.ts b/src/entity/communicationType.ts index 90da06f..6ff867d 100644 --- a/src/entity/communicationType.ts +++ b/src/entity/communicationType.ts @@ -24,8 +24,6 @@ export class communicationType { }) useColumns: Array; - @OneToMany(() => communication, (communication) => communication.type, { - onDelete: "RESTRICT", - }) + @OneToMany(() => communication, (communication) => communication.type) communications: communication[]; } diff --git a/src/entity/executivePosition.ts b/src/entity/executivePosition.ts index 1b11e7e..e88cea2 100644 --- a/src/entity/executivePosition.ts +++ b/src/entity/executivePosition.ts @@ -1,5 +1,5 @@ import { Column, Entity, OneToMany, PrimaryColumn } from "typeorm"; -//import { memberExecutivePositions } from "./memberExecutivePositions"; +import { memberExecutivePositions } from "./memberExecutivePositions"; @Entity() export class executivePosition { @@ -9,8 +9,6 @@ export class executivePosition { @Column({ type: "varchar", length: 255 }) position: string; - // @OneToMany(() => memberExecutivePositions, (memberExecutivePositions) => memberExecutivePositions.executivePosition, { - // onDelete: "RESTRICT", - // }) - // members: memberExecutivePositions[]; + @OneToMany(() => memberExecutivePositions, (memberExecutivePositions) => memberExecutivePositions.executivePosition) + members: memberExecutivePositions[]; } diff --git a/src/entity/member.ts b/src/entity/member.ts new file mode 100644 index 0000000..855b54d --- /dev/null +++ b/src/entity/member.ts @@ -0,0 +1,51 @@ +import { Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne, PrimaryColumn } from "typeorm"; +import { Salutation } from "../enums/salutation"; +import { membership } from "./membership"; +import { memberAwards } from "./memberAwards"; +import { memberQualifications } from "./memberQualifications"; +import { memberExecutivePositions } from "./memberExecutivePositions"; +import { communication } from "./communication"; + +@Entity() +export class member { + @PrimaryColumn({ generated: "increment", type: "int" }) + id: number; + + @Column({ type: "enum", enum: Salutation, default: Salutation.none }) + salutation: Salutation; + + @Column({ type: "varchar", length: 255 }) + firstname: string; + + @Column({ type: "varchar", length: 255 }) + lastname: string; + + @Column({ type: "varchar", length: 255 }) + nameaffix: string; + + @Column({ type: "date" }) + birthdate: Date; + + @OneToMany(() => communication, (communications) => communications.member) + communications: communication; + + @OneToOne(() => communication, { + nullable: true, + onDelete: "SET NULL", + onUpdate: "RESTRICT", + }) + @JoinColumn() + sendNewsletter?: communication; + + @OneToMany(() => membership, (membership) => membership.member) + memberships: membership[]; + + @OneToMany(() => memberAwards, (awards) => awards.member) + awards: memberAwards[]; + + @OneToMany(() => memberExecutivePositions, (executivePositions) => executivePositions.member) + positions: memberExecutivePositions[]; + + @OneToMany(() => memberQualifications, (qualifications) => qualifications.member) + qualifications: memberQualifications[]; +} diff --git a/src/entity/memberAwards.ts b/src/entity/memberAwards.ts new file mode 100644 index 0000000..47ea86a --- /dev/null +++ b/src/entity/memberAwards.ts @@ -0,0 +1,32 @@ +import { Column, Entity, ManyToOne, PrimaryColumn } from "typeorm"; +import { member } from "./member"; +import { award } from "./award"; + +@Entity() +export class memberAwards { + @PrimaryColumn({ generated: "increment", type: "int" }) + id: number; + + @Column({ type: "boolean", default: true }) + given: boolean; + + @Column({ type: "varchar", length: 255, nullable: true }) + note?: string; + + @Column({ type: "date" }) + date: Date; + + @ManyToOne(() => member, (member) => member.awards, { + nullable: false, + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + member: member; + + @ManyToOne(() => award, (award) => award.members, { + nullable: false, + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + award: award; +} diff --git a/src/entity/memberExecutivePositions.ts b/src/entity/memberExecutivePositions.ts new file mode 100644 index 0000000..0f68729 --- /dev/null +++ b/src/entity/memberExecutivePositions.ts @@ -0,0 +1,32 @@ +import { Column, Entity, ManyToOne, PrimaryColumn } from "typeorm"; +import { member } from "./member"; +import { executivePosition } from "./executivePosition"; + +@Entity() +export class memberExecutivePositions { + @PrimaryColumn({ generated: "increment", type: "int" }) + id: number; + + @Column({ type: "varchar", length: 255, nullable: true }) + note?: string; + + @Column({ type: "date" }) + start: Date; + + @Column({ type: "date", nullable: true }) + end?: Date; + + @ManyToOne(() => member, (member) => member.awards, { + nullable: false, + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + member: member; + + @ManyToOne(() => executivePosition, (executivePosition) => executivePosition.members, { + nullable: false, + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + executivePosition: executivePosition; +} diff --git a/src/entity/memberQualifications.ts b/src/entity/memberQualifications.ts new file mode 100644 index 0000000..c2d4026 --- /dev/null +++ b/src/entity/memberQualifications.ts @@ -0,0 +1,35 @@ +import { Column, Entity, ManyToOne, PrimaryColumn } from "typeorm"; +import { member } from "./member"; +import { qualification } from "./qualification"; + +@Entity() +export class memberQualifications { + @PrimaryColumn({ generated: "increment", type: "int" }) + id: number; + + @Column({ type: "varchar", length: 255, nullable: true }) + note?: string; + + @Column({ type: "date" }) + start: Date; + + @Column({ type: "date", nullable: true }) + end?: Date; + + @Column({ type: "varchar", length: 255, nullable: true }) + terminationReason?: string; + + @ManyToOne(() => member, (member) => member.awards, { + nullable: false, + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + member: member; + + @ManyToOne(() => qualification, (qualification) => qualification.members, { + nullable: false, + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + qualification: qualification; +} diff --git a/src/entity/membership.ts b/src/entity/membership.ts new file mode 100644 index 0000000..dd8d1ac --- /dev/null +++ b/src/entity/membership.ts @@ -0,0 +1,37 @@ +import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm"; +import { member } from "./member"; +import { membershipStatus } from "./membershipStatus"; + +@Entity() +export class membership { + @PrimaryColumn({ generated: "increment", type: "int" }) + id: number; + + @Column({ type: "varchar", length: 255, unique: true, nullable: true }) + internalId?: string; + + @Column({ type: "date" }) + start: Date; + + @Column({ type: "date", nullable: true }) + end?: Date; + + @Column({ type: "varchar", length: 255, nullable: true }) + terminationReason?: string; + + @ManyToOne(() => member, (member) => member.memberships, { + nullable: false, + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + @JoinColumn() + member: member; + + @ManyToOne(() => membershipStatus, (membershipStatus) => membershipStatus.memberships, { + nullable: false, + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + @JoinColumn() + status: membershipStatus; +} diff --git a/src/entity/membershipStatus.ts b/src/entity/membershipStatus.ts index 640836b..980d88b 100644 --- a/src/entity/membershipStatus.ts +++ b/src/entity/membershipStatus.ts @@ -1,5 +1,5 @@ import { Column, Entity, OneToMany, PrimaryColumn } from "typeorm"; -//import { membership } from "./membership"; +import { membership } from "./membership"; @Entity() export class membershipStatus { @@ -9,6 +9,6 @@ export class membershipStatus { @Column({ type: "varchar", length: 255 }) status: string; - // @OneToMany(() => membership, (membership) => membership.status) - // memberships: membership[]; + @OneToMany(() => membership, (membership) => membership.status) + memberships: membership[]; } diff --git a/src/entity/qualification.ts b/src/entity/qualification.ts index 2f4652d..59a657c 100644 --- a/src/entity/qualification.ts +++ b/src/entity/qualification.ts @@ -1,5 +1,5 @@ import { Column, Entity, OneToMany, PrimaryColumn } from "typeorm"; -//import { memberQualifications } from "./memberQualifications"; +import { memberQualifications } from "./memberQualifications"; @Entity() export class qualification { @@ -12,8 +12,6 @@ export class qualification { @Column({ type: "varchar", length: 255, nullable: true, default: null }) description?: string; - // @OneToMany(() => memberQualifications, (memberQualifications) => memberQualifications.qualification, { - // onDelete: "RESTRICT", - // }) - // members: memberQualifications[]; + @OneToMany(() => memberQualifications, (memberQualifications) => memberQualifications.qualification) + members: memberQualifications[]; } diff --git a/src/enums/salutation.ts b/src/enums/salutation.ts new file mode 100644 index 0000000..214bb85 --- /dev/null +++ b/src/enums/salutation.ts @@ -0,0 +1,6 @@ +export enum Salutation { + Sir = "sir", + Madam = "madam", + other = "other", + none = "none", +} diff --git a/src/migrations/1726301836849-memberdata.ts b/src/migrations/1726301836849-memberdata.ts new file mode 100644 index 0000000..c62696a --- /dev/null +++ b/src/migrations/1726301836849-memberdata.ts @@ -0,0 +1,258 @@ +import { MigrationInterface, QueryRunner, Table, TableColumn, TableForeignKey } from "typeorm"; + +export class Memberdata1726301836849 implements MigrationInterface { + name = "Memberdata1726301836849"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: "membership", + columns: [ + { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" }, + { name: "internalId", type: "varchar", length: "255", isNullable: true }, + { name: "start", type: "date", isNullable: false }, + { name: "end", type: "date", isNullable: true }, + { name: "terminationReason", type: "varchar", length: "255", isNullable: true }, + { name: "memberId", type: "int", isNullable: false }, + { name: "statusId", type: "int", isNullable: false }, + ], + uniques: [{ name: "IDX_703f499fe3a9892e3a8790cdfc", columnNames: ["internalId"] }], + }), + true + ); + + await queryRunner.createTable( + new Table({ + name: "member_qualifications", + columns: [ + { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" }, + { name: "note", type: "varchar", length: "255", isNullable: true }, + { name: "start", type: "date", isNullable: false }, + { name: "end", type: "date", isNullable: true }, + { name: "terminationReason", type: "varchar", length: "255", isNullable: true }, + { name: "memberId", type: "int", isNullable: false }, + { name: "qualificationId", type: "int", isNullable: false }, + ], + }), + true + ); + + await queryRunner.createTable( + new Table({ + name: "member_executive_positions", + columns: [ + { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" }, + { name: "note", type: "varchar", length: "255", isNullable: true }, + { name: "start", type: "date", isNullable: false }, + { name: "end", type: "date", isNullable: true }, + { name: "memberId", type: "int", isNullable: false }, + { name: "executivePositionId", type: "int", isNullable: false }, + ], + }), + true + ); + + await queryRunner.createTable( + new Table({ + name: "member", + columns: [ + { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" }, + { + name: "salutation", + type: "enum", + enum: ["sir", "madam", "other", "none"], + default: "'none'", + isNullable: false, + }, + { name: "firstname", type: "varchar", length: "255", isNullable: false }, + { name: "lastname", type: "varchar", length: "255", isNullable: false }, + { name: "nameaffix", type: "varchar", length: "255", isNullable: false }, + { name: "birthdate", type: "date", isNullable: false }, + { name: "sendNewsletterId", type: "int", isNullable: true }, + ], + uniques: [{ name: "REL_d57e160c4513cd949159217281", columnNames: ["sendNewsletterId"] }], + }), + true + ); + + await queryRunner.createTable( + new Table({ + name: "member_awards", + columns: [ + { name: "id", type: "int", isPrimary: true, isGenerated: true, generationStrategy: "increment" }, + { name: "given", type: "tinyint", default: 1, isNullable: false }, + { name: "note", type: "varchar", length: "255", isNullable: true }, + { name: "date", type: "date", isNullable: false }, + { name: "memberId", type: "int", isNullable: false }, + { name: "awardId", type: "int", isNullable: false }, + ], + }), + true + ); + + await queryRunner.addColumn("communication", new TableColumn({ name: "memberId", type: "int", isNullable: false })); + + await queryRunner.createForeignKey( + "membership", + new TableForeignKey({ + columnNames: ["memberId"], + referencedTableName: "member", + referencedColumnNames: ["id"], + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "membership", + new TableForeignKey({ + columnNames: ["statusId"], + referencedTableName: "membership_status", + referencedColumnNames: ["id"], + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "member_qualifications", + new TableForeignKey({ + columnNames: ["memberId"], + referencedTableName: "member", + referencedColumnNames: ["id"], + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "member_qualifications", + new TableForeignKey({ + columnNames: ["qualificationId"], + referencedTableName: "qualification", + referencedColumnNames: ["id"], + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "member_executive_positions", + new TableForeignKey({ + columnNames: ["memberId"], + referencedTableName: "member", + referencedColumnNames: ["id"], + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "member_executive_positions", + new TableForeignKey({ + columnNames: ["executivePositionId"], + referencedTableName: "executive_position", + referencedColumnNames: ["id"], + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "communication", + new TableForeignKey({ + columnNames: ["memberId"], + referencedTableName: "member", + referencedColumnNames: ["id"], + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "member", + new TableForeignKey({ + columnNames: ["sendNewsletterId"], + referencedTableName: "communication", + referencedColumnNames: ["id"], + onDelete: "SET NULL", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "member_awards", + new TableForeignKey({ + columnNames: ["memberId"], + referencedTableName: "member", + referencedColumnNames: ["id"], + onDelete: "CASCADE", + onUpdate: "RESTRICT", + }) + ); + + await queryRunner.createForeignKey( + "member_awards", + new TableForeignKey({ + columnNames: ["awardId"], + referencedTableName: "award", + referencedColumnNames: ["id"], + onDelete: "RESTRICT", + onUpdate: "RESTRICT", + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + const member = await queryRunner.getTable("member"); + const memeberForeignKey = member.foreignKeys.find((fk) => fk.columnNames.indexOf("sendNewsletterId") !== -1); + await queryRunner.dropForeignKey("member", memeberForeignKey); + + const member_awards = await queryRunner.getTable("member_awards"); + const memeberAwardsForeignKeyMember = member_awards.foreignKeys.find( + (fk) => fk.columnNames.indexOf("memberId") !== -1 + ); + const memeberAwardsForeignKeyAward = member_awards.foreignKeys.find( + (fk) => fk.columnNames.indexOf("awardId") !== -1 + ); + await queryRunner.dropForeignKey("member_awards", memeberAwardsForeignKeyMember); + await queryRunner.dropForeignKey("member_awards", memeberAwardsForeignKeyAward); + + const communication = await queryRunner.getTable("communication"); + const communicationForeignKey = communication.foreignKeys.find((fk) => fk.columnNames.indexOf("memberId") !== -1); + await queryRunner.dropForeignKey("communication", communicationForeignKey); + + const member_executive_positions = await queryRunner.getTable("member_executive_positions"); + const memeberExecutivePositionForeignKeyMember = member_executive_positions.foreignKeys.find( + (fk) => fk.columnNames.indexOf("memberId") !== -1 + ); + const memeberExecutivePositionForeignKeyPosition = member_executive_positions.foreignKeys.find( + (fk) => fk.columnNames.indexOf("executivePositionId") !== -1 + ); + await queryRunner.dropForeignKey("member_executive_positions", memeberExecutivePositionForeignKeyMember); + await queryRunner.dropForeignKey("member_executive_positions", memeberExecutivePositionForeignKeyPosition); + + const member_qualifications = await queryRunner.getTable("member_qualifications"); + const memeberQualificationForeignKeyMember = member_qualifications.foreignKeys.find( + (fk) => fk.columnNames.indexOf("memberId") !== -1 + ); + const memeberQualificationForeignKeyQualification = member_qualifications.foreignKeys.find( + (fk) => fk.columnNames.indexOf("qualificationId") !== -1 + ); + await queryRunner.dropForeignKey("member_qualifications", memeberQualificationForeignKeyMember); + await queryRunner.dropForeignKey("member_qualifications", memeberQualificationForeignKeyQualification); + + const membership = await queryRunner.getTable("membership"); + const membershipForeignKeyMember = membership.foreignKeys.find((fk) => fk.columnNames.indexOf("memberId") !== -1); + const membershipForeignKeyStatus = membership.foreignKeys.find((fk) => fk.columnNames.indexOf("statusId") !== -1); + await queryRunner.dropForeignKey("membership", membershipForeignKeyMember); + await queryRunner.dropForeignKey("membership", membershipForeignKeyStatus); + + await queryRunner.dropColumn("communication", "memberId"); + await queryRunner.dropTable("member_awards"); + await queryRunner.dropTable("member"); + await queryRunner.dropTable("member_executive_positions"); + await queryRunner.dropTable("member_qualifications"); + await queryRunner.dropTable("membership"); + } +}