Merge branch 'milestone/ff-admin-unit' into unit/#102-base-management

# Conflicts:
#	src/data-source.ts
This commit is contained in:
Julian Krauser 2025-06-08 07:55:20 +02:00
commit e056db053b
68 changed files with 1807 additions and 1521 deletions

View file

@ -8,6 +8,7 @@ import DatabaseActionException from "../exceptions/databaseActionException";
import { availableTemplates } from "../type/templateTypes";
import SettingHelper from "./settingsHelper";
import { LoginRoutineEnum } from "../enums/loginRoutineEnum";
import { education } from "../entity/configuration/education";
export type BackupSection =
| "member"
@ -55,6 +56,7 @@ export default abstract class BackupHelper {
"member_executive_positions",
"membership",
"communication",
"member_educations",
],
memberBase: [
"award",
@ -63,6 +65,7 @@ export default abstract class BackupHelper {
"membership_status",
"communication_type",
"salutation",
"education",
],
protocol: [
"protocol",
@ -246,6 +249,8 @@ export default abstract class BackupHelper {
.leftJoin("positions.executivePosition", "executivePosition")
.leftJoin("member.qualifications", "qualifications")
.leftJoin("qualifications.qualification", "qualification")
.leftJoin("member.educations", "educations")
.leftJoin("educations.education", "education")
.select([
...(collectIds ? ["member.id"] : []),
"member.firstname",
@ -253,6 +258,7 @@ export default abstract class BackupHelper {
"member.nameaffix",
"member.birthdate",
"member.internalId",
"member.note",
])
.addSelect(["salutation.salutation"])
.addSelect([
@ -280,6 +286,14 @@ export default abstract class BackupHelper {
"qualification.qualification",
"qualification.description",
])
.addSelect([
"educations.start",
"educations.end",
"educations.place",
"educations.note",
"education.education",
"education.description",
])
.getMany();
}
private static async getMemberBase(): Promise<{ [key: string]: Array<any> }> {
@ -294,6 +308,7 @@ export default abstract class BackupHelper {
qualification: await dataSource
.getRepository("qualification")
.find({ select: { qualification: true, description: true } }),
education: await dataSource.getRepository("education").find({ select: { education: true, description: true } }),
};
}
private static async getProtocol(collectIds: boolean): Promise<Array<any>> {
@ -344,6 +359,7 @@ export default abstract class BackupHelper {
"newsletter.newsletterText",
"newsletter.newsletterSignatur",
"newsletter.isSent",
"newsletter.createdAt",
])
.addSelect(["dates.calendarId", "dates.diffTitle", "dates.diffDescription"])
.addSelect(["recipients.memberId"])
@ -534,6 +550,13 @@ export default abstract class BackupHelper {
.map((d) => ({ ...d, id: undefined })),
"qualification"
),
education: uniqBy(
data
.map((d) => (d.education ?? []).map((c: any) => c.education))
.flat()
.map((d) => ({ ...d, id: undefined })),
"education"
),
});
let salutation = await this.transactionManager.getRepository("salutation").find();
@ -541,6 +564,7 @@ export default abstract class BackupHelper {
let membership = await this.transactionManager.getRepository("membership_status").find();
let award = await this.transactionManager.getRepository("award").find();
let qualification = await this.transactionManager.getRepository("qualification").find();
let education = await this.transactionManager.getRepository("education").find();
let position = await this.transactionManager.getRepository("executive_position").find();
let dataWithMappedIds = data.map((d) => ({
...d,
@ -583,6 +607,13 @@ export default abstract class BackupHelper {
id: qualification.find((iq) => iq.qualification == q.qualification.qualification)?.id ?? undefined,
},
})),
educations: (d.educations ?? []).map((e: any) => ({
...e,
education: {
...e.education,
id: education.find((id) => id.education == e.education.education)?.id ?? undefined,
},
})),
}));
await this.transactionManager.getRepository("member").save(dataWithMappedIds);
}
@ -593,6 +624,7 @@ export default abstract class BackupHelper {
let award = await this.transactionManager.getRepository("award").find();
let qualification = await this.transactionManager.getRepository("qualification").find();
let position = await this.transactionManager.getRepository("executive_position").find();
let education = await this.transactionManager.getRepository("education").find();
await this.transactionManager
.createQueryBuilder()
@ -634,10 +666,19 @@ export default abstract class BackupHelper {
.insert()
.into("qualification")
.values(
(data?.["qualification"] ?? []).filter((d) => !qualification.map((q) => q.award).includes(d.qualification))
(data?.["qualification"] ?? []).filter(
(d) => !qualification.map((q) => q.qualification).includes(d.qualification)
)
)
.orIgnore()
.execute();
await this.transactionManager
.createQueryBuilder()
.insert()
.into("education")
.values((data?.["education"] ?? []).filter((d) => !education.map((q) => q.education).includes(d.education)))
.orIgnore()
.execute();
}
private static async setProtocol(data: Array<any>, collectedIds: boolean): Promise<void> {
let members = await this.transactionManager.getRepository("member").find();

View file

@ -12,6 +12,16 @@ export abstract class DemoDataHelper {
return newsletterDemoData;
case "member":
return memberDemoData;
case "listprint":
return {
today: new Date(),
list: [memberDemoData.memberships],
};
case "listprint.member":
return {
today: new Date(),
list: [memberDemoData.member],
};
default:
return {};
}

View file

@ -17,11 +17,13 @@ export default abstract class DynamicQueryBuilder {
"memberAwards",
"memberExecutivePositions",
"memberQualifications",
"memberEducations",
"membership",
"memberView",
"memberExecutivePositionsView",
"memberQualificationsView",
"membershipView",
"membershipTotalView",
];
public static getTableMeta(tableName: string): TableMeta {
@ -226,19 +228,19 @@ export default abstract class DynamicQueryBuilder {
query += ` IS NOT NULL`;
break;
case "contains":
query += ` LIKE :${parameterKey}`;
query += ` ILIKE :${parameterKey}`;
parameters[parameterKey] = `%${condition.value}%`;
break;
case "notContains":
query += ` NOT LIKE :${parameterKey}`;
query += ` NOT ILIKE :${parameterKey}`;
parameters[parameterKey] = `%${condition.value}%`;
break;
case "startsWith":
query += ` LIKE :${parameterKey}`;
query += ` ILIKE :${parameterKey}`;
parameters[parameterKey] = `${condition.value}%`;
break;
case "endsWith":
query += ` LIKE :${parameterKey}`;
query += ` ILIKE :${parameterKey}`;
parameters[parameterKey] = `%${condition.value}`;
break;
case "timespanEq":
@ -292,7 +294,12 @@ export default abstract class DynamicQueryBuilder {
results.forEach((res) => {
if (typeof value === "object" && value instanceof Date) {
res[newKey] = new Date(value).toISOString();
} else if (typeof value === "object" && !Array.isArray(value) && !(value instanceof Buffer)) {
} else if (
typeof value === "object" &&
!Array.isArray(value) &&
!(value instanceof Buffer) &&
value !== null
) {
let string = "";
for (const key of Object.keys(value)) {
string += `${value[key]} ${key} `;
@ -301,7 +308,7 @@ export default abstract class DynamicQueryBuilder {
// JSON.stringify(value).replace(/["\\{}]/g, "").replaceAll(",", ", ");
} else if (String(value) != "undefined") {
res[newKey] = String(value);
res[newKey] = value !== null ? String(value) : "";
}
});
}

View file

@ -76,7 +76,7 @@ export default abstract class SettingHelper {
* @param value The value to set
*/
public static async setSetting<K extends SettingString>(key: K, value: SettingValueMapping[K]): Promise<void> {
if (value === undefined || value === null || value == "") {
if (value === undefined || value === null || value === "") {
if (key != "mail.password") this.resetSetting(key);
return;
}