newsletter config CRUD

This commit is contained in:
Julian Krauser 2024-12-26 11:08:48 +01:00
parent 01ce3fdd39
commit 7d36ed3121
14 changed files with 274 additions and 1 deletions

View file

@ -0,0 +1,6 @@
import { NewsletterConfigType } from "../enums/newsletterConfigType";
export interface SetNewsletterConfigCommand {
comTypeId: number;
config: NewsletterConfigType;
}

View file

@ -0,0 +1,30 @@
import { dataSource } from "../data-source";
import { newsletterConfig } from "../entity/newsletterConfig";
import InternalException from "../exceptions/internalException";
import { SetNewsletterConfigCommand } from "./newsletterConfigCommand";
export default abstract class NewsletterConfigCommandHandler {
/**
* @description set newsletterConfig
* @param SetNewsletterConfigCommand
* @returns {Promise<number>}
*/
static async setConfig(setNewsletterConfig: SetNewsletterConfigCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(newsletterConfig)
.values({
comTypeId: setNewsletterConfig.comTypeId,
config: setNewsletterConfig.config,
})
.orUpdate(["config"], "comTypeId")
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new InternalException("Failed setting newsletterConfig", err);
});
}
}

View file

@ -0,0 +1,49 @@
import { Request, Response } from "express";
import NewsletterConfigService from "../../service/newsletterConfigService";
import NewsletterConfigFactory from "../../factory/admin/newsletterConfig";
import NewsletterConfigCommandHandler from "../../command/newsletterConfigCommandHandler";
import { SetNewsletterConfigCommand } from "../../command/newsletterConfigCommand";
/**
* @description get all newsletterConfigs
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllNewsletterConfigs(req: Request, res: Response): Promise<any> {
let newsletterConfigs = await NewsletterConfigService.getAll();
res.json(NewsletterConfigFactory.mapToBase(newsletterConfigs));
}
/**
* @description get newsletterConfig by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getNewsletterConfigById(req: Request, res: Response): Promise<any> {
let comId = parseInt(req.params.comId);
let newsletterConfig = await NewsletterConfigService.getByComId(comId);
res.json(NewsletterConfigFactory.mapToSingle(newsletterConfig));
}
/**
* @description set newsletterConfig
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function setNewsletterConfig(req: Request, res: Response): Promise<any> {
let comTypeId = req.body.comTypeId;
let config = req.body.config;
let createNewsletterConfig: SetNewsletterConfigCommand = {
comTypeId,
config,
};
let id = await NewsletterConfigCommandHandler.setConfig(createNewsletterConfig);
res.send(id);
}

View file

@ -146,6 +146,7 @@ export async function createNewsletterPrintoutById(req: Request, res: Response):
// check if all users have mail or adress
// squash all files to single for printing
// use Helper for Newsletter printing and mail sending
// default template
res.sendStatus(204);
}

View file

@ -59,6 +59,8 @@ import { newsletter } from "./entity/newsletter";
import { newsletterDates } from "./entity/newsletterDates";
import { newsletterRecipients } from "./entity/newsletterRecipients";
import { Newsletter1735118780511 } from "./migrations/1735118780511-newsletter";
import { newsletterConfig } from "./entity/newsletterConfig";
import { NewsletterConfig1735207446910 } from "./migrations/1735207446910-newsletterConfig";
const dataSource = new DataSource({
type: DB_TYPE as any,
@ -103,6 +105,7 @@ const dataSource = new DataSource({
newsletter,
newsletterDates,
newsletterRecipients,
newsletterConfig,
memberView,
memberExecutivePositionsView,
memberQualificationsView,
@ -128,6 +131,7 @@ const dataSource = new DataSource({
Template1734854680201,
TemplateUsage1734949173739,
Newsletter1735118780511,
NewsletterConfig1735207446910,
],
migrationsRun: true,
migrationsTransactionMode: "each",

View file

@ -0,0 +1,30 @@
import { Column, Entity, ManyToOne, PrimaryColumn } from "typeorm";
import { NewsletterConfigType } from "../enums/newsletterConfigType";
import { communicationType } from "./communicationType";
@Entity()
export class newsletterConfig {
@PrimaryColumn({ type: "int" })
comTypeId: number;
@Column({
type: "varchar",
length: "255",
transformer: {
to(value: NewsletterConfigType) {
return value.toString();
},
from(value: string) {
return NewsletterConfigType[value as keyof typeof NewsletterConfigType];
},
},
})
config: NewsletterConfigType;
@ManyToOne(() => communicationType, {
nullable: false,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
comType: communicationType;
}

View file

@ -0,0 +1,4 @@
export enum NewsletterConfigType {
pdf = "pdf",
mail = "mail",
}

View file

@ -0,0 +1,27 @@
import { newsletterConfig } from "../../entity/newsletterConfig";
import { NewsletterConfigViewModel } from "../../viewmodel/admin/newsletterConfig.models";
import CommunicationTypeFactory from "./communicationType";
export default abstract class NewsletterConfigFactory {
/**
* @description map record to newsletterConfig
* @param {newsletterConfig} record
* @returns {NewsletterConfigViewModel}
*/
public static mapToSingle(record: newsletterConfig): NewsletterConfigViewModel {
return {
comTypeId: record.comTypeId,
config: record.config,
comType: record?.comType ? CommunicationTypeFactory.mapToSingle(record.comType) : null,
};
}
/**
* @description map records to newsletterConfig
* @param {Array<newsletterConfig>} records
* @returns {Array<NewsletterConfigViewModel>}
*/
public static mapToBase(records: Array<newsletterConfig>): Array<NewsletterConfigViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,39 @@
import { MigrationInterface, QueryRunner, Table, TableForeignKey } from "typeorm";
import { DB_TYPE } from "../env.defaults";
export class NewsletterConfig1735207446910 implements MigrationInterface {
name = "NewsletterConfig1735207446910";
public async up(queryRunner: QueryRunner): Promise<void> {
const variableType_int = DB_TYPE == "mysql" ? "int" : "integer";
await queryRunner.createTable(
new Table({
name: "newsletter_config",
columns: [
{ name: "comTypeId", type: variableType_int, isPrimary: true, isNullable: false },
{ name: "config", type: "varchar", length: "255", isNullable: false },
],
}),
true
);
await queryRunner.createForeignKey(
"newsletter_config",
new TableForeignKey({
columnNames: ["comTypeId"],
referencedColumnNames: ["id"],
referencedTableName: "communication_type",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const table = await queryRunner.getTable("newsletter_config");
const foreignKey = table.foreignKeys.find((fk) => fk.columnNames.indexOf("comTypeId") !== -1);
await queryRunner.dropForeignKey("newsletter_config", foreignKey);
await queryRunner.dropTable("newsletter_config");
}
}

View file

@ -10,6 +10,7 @@ import calendarType from "./calendarType";
import queryStore from "./queryStore";
import template from "./template";
import templateUsage from "./templateUsage";
import newsletterConfig from "./newsletterConfig";
import member from "./member";
import protocol from "./protocol";
@ -44,6 +45,11 @@ router.use("/calendartype", PermissionHelper.passCheckMiddleware("read", "settin
router.use("/querystore", PermissionHelper.passCheckMiddleware("read", "settings", "query_store"), queryStore);
router.use("/template", PermissionHelper.passCheckMiddleware("read", "settings", "template"), template);
router.use("/templateusage", PermissionHelper.passCheckMiddleware("read", "settings", "template_usage"), templateUsage);
router.use(
"/newsletterconfig",
PermissionHelper.passCheckMiddleware("read", "settings", "newsletter_config"),
newsletterConfig
);
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
router.use("/protocol", PermissionHelper.passCheckMiddleware("read", "club", "protocol"), protocol);

View file

@ -0,0 +1,27 @@
import express, { Request, Response } from "express";
import {
getAllNewsletterConfigs,
getNewsletterConfigById,
setNewsletterConfig,
} from "../../controller/admin/newsletterConfigController";
import PermissionHelper from "../../helpers/permissionHelper";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllNewsletterConfigs(req, res);
});
router.get("/:id", async (req: Request, res: Response) => {
await getNewsletterConfigById(req, res);
});
router.put(
"/",
PermissionHelper.passCheckMiddleware("create", "settings", "newsletter_config"),
async (req: Request, res: Response) => {
await setNewsletterConfig(req, res);
}
);
export default router;

View file

@ -0,0 +1,43 @@
import { dataSource } from "../data-source";
import { newsletterConfig } from "../entity/newsletterConfig";
import { member } from "../entity/member";
import InternalException from "../exceptions/internalException";
export default abstract class NewsletterConfigService {
/**
* @description get all newsletterConfigs
* @returns {Promise<Array<newsletterConfig>>}
*/
static async getAll(): Promise<Array<newsletterConfig>> {
return await dataSource
.getRepository(newsletterConfig)
.createQueryBuilder("newsletterConfig")
.leftJoinAndSelect("newsletterConfig.comType", "comType")
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("newsletterConfigs not found", err);
});
}
/**
* @description get newsletterConfig by id
* @returns {Promise<newsletterConfig>}
*/
static async getByComId(comId: number): Promise<newsletterConfig> {
return await dataSource
.getRepository(newsletterConfig)
.createQueryBuilder("newsletterConfig")
.leftJoinAndSelect("newsletterConfig.comType", "comType")
.where("newsletterConfig.comTypId = :comTypId", { icomTypId: comId })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("newsletterConfig not found by cmId", err);
});
}
}

View file

@ -1,6 +1,5 @@
import { dataSource } from "../data-source";
import { newsletter } from "../entity/newsletter";
import { member } from "../entity/member";
import InternalException from "../exceptions/internalException";
export default abstract class NewsletterService {

View file

@ -0,0 +1,8 @@
import { NewsletterConfigType } from "../../enums/newsletterConfigType";
import { CommunicationTypeViewModel } from "./communicationType.models";
export interface NewsletterConfigViewModel {
comTypeId: number;
config: NewsletterConfigType;
comType: CommunicationTypeViewModel;
}