diff --git a/src/command/settings/salutation/salutationCommand.ts b/src/command/settings/salutation/salutationCommand.ts new file mode 100644 index 0000000..955f1b8 --- /dev/null +++ b/src/command/settings/salutation/salutationCommand.ts @@ -0,0 +1,12 @@ +export interface CreateSalutationCommand { + salutation: string; +} + +export interface UpdateSalutationCommand { + id: number; + salutation: string; +} + +export interface DeleteSalutationCommand { + id: number; +} diff --git a/src/command/settings/salutation/salutationCommandHandler.ts b/src/command/settings/salutation/salutationCommandHandler.ts new file mode 100644 index 0000000..78f7c69 --- /dev/null +++ b/src/command/settings/salutation/salutationCommandHandler.ts @@ -0,0 +1,69 @@ +import { dataSource } from "../../../data-source"; +import { salutation } from "../../../entity/settings/salutation"; +import InternalException from "../../../exceptions/internalException"; +import { CreateSalutationCommand, DeleteSalutationCommand, UpdateSalutationCommand } from "./salutationCommand"; + +export default abstract class SalutationCommandHandler { + /** + * @description create salutation + * @param {CreateSalutationCommand} createSalutation + * @returns {Promise} + */ + static async create(createSalutation: CreateSalutationCommand): Promise { + return await dataSource + .createQueryBuilder() + .insert() + .into(salutation) + .values({ + salutation: createSalutation.salutation, + }) + .execute() + .then((result) => { + return result.identifiers[0].id; + }) + .catch((err) => { + throw new InternalException("Failed creating salutation", err); + }); + } + + /** + * @description update salutation + * @param {UpdateSalutationCommand} updateSalutation + * @returns {Promise} + */ + static async update(updateSalutation: UpdateSalutationCommand): Promise { + return await dataSource + .createQueryBuilder() + .update(salutation) + .set({ + salutation: updateSalutation.salutation, + }) + .where("id = :id", { id: updateSalutation.id }) + .execute() + .then(() => {}) + .catch((err) => { + throw new InternalException("Failed updating salutation", err); + }); + } + + /** + * @description delete salutation + * @param {DeleteSalutationCommand} deleteSalutation + * @returns {Promise} + */ + static async delete(deleteSalutation: DeleteSalutationCommand): Promise { + return await dataSource + .createQueryBuilder() + .delete() + .from(salutation) + .where("id = :id", { id: deleteSalutation.id }) + .execute() + .then(() => {}) + .catch((err) => { + throw new InternalException( + `Failed deleting salutation ${err.code.includes("ER_ROW_IS_REFERENCED") ? " due to referenced data" : ""}`, + err + ); + }); + } +} diff --git a/src/controller/admin/club/memberController.ts b/src/controller/admin/club/memberController.ts index c313b27..ec99ef3 100644 --- a/src/controller/admin/club/memberController.ts +++ b/src/controller/admin/club/memberController.ts @@ -285,7 +285,7 @@ export async function createMemberPrintoutList(req: Request, res: Response): Pro * @returns {Promise<*>} */ export async function createMember(req: Request, res: Response): Promise { - const salutationId = req.body.salutationId; + const salutationId = parseInt(req.body.salutationId); const firstname = req.body.firstname; const lastname = req.body.lastname; const nameaffix = req.body.nameaffix; @@ -453,7 +453,7 @@ export async function addCommunicationToMember(req: Request, res: Response): Pro */ export async function updateMemberById(req: Request, res: Response): Promise { const memberId = parseInt(req.params.id); - const salutationId = req.body.salutationId; + const salutationId = parseInt(req.body.salutationId); const firstname = req.body.firstname; const lastname = req.body.lastname; const nameaffix = req.body.nameaffix; diff --git a/src/controller/admin/settings/salutationController.ts b/src/controller/admin/settings/salutationController.ts new file mode 100644 index 0000000..d27f4e4 --- /dev/null +++ b/src/controller/admin/settings/salutationController.ts @@ -0,0 +1,87 @@ +import { Request, Response } from "express"; +import SalutationService from "../../../service/settings/salutationService"; +import SalutationFactory from "../../../factory/admin/settings/salutation"; +import { + CreateSalutationCommand, + DeleteSalutationCommand, + UpdateSalutationCommand, +} from "../../../command/settings/salutation/salutationCommand"; +import SalutationCommandHandler from "../../../command/settings/salutation/salutationCommandHandler"; + +/** + * @description get all salutations + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function getAllSalutations(req: Request, res: Response): Promise { + let salutations = await SalutationService.getAll(); + + res.json(SalutationFactory.mapToBase(salutations)); +} + +/** + * @description get salutation by id + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function getSalutationById(req: Request, res: Response): Promise { + const id = parseInt(req.params.id); + let salutation = await SalutationService.getById(id); + + res.json(SalutationFactory.mapToSingle(salutation)); +} + +/** + * @description create new salutation + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function createSalutation(req: Request, res: Response): Promise { + const salutation = req.body.salutation; + + let createSalutation: CreateSalutationCommand = { + salutation: salutation, + }; + await SalutationCommandHandler.create(createSalutation); + + res.sendStatus(204); +} + +/** + * @description update salutation + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function updateSalutation(req: Request, res: Response): Promise { + const id = parseInt(req.params.id); + const salutation = req.body.salutation; + + let updateSalutation: UpdateSalutationCommand = { + id: id, + salutation: salutation, + }; + await SalutationCommandHandler.update(updateSalutation); + + res.sendStatus(204); +} + +/** + * @description delete salutation + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function deleteSalutation(req: Request, res: Response): Promise { + const id = parseInt(req.params.id); + + let deleteSalutation: DeleteSalutationCommand = { + id: id, + }; + await SalutationCommandHandler.delete(deleteSalutation); + + res.sendStatus(204); +} diff --git a/src/factory/admin/club/member/member.ts b/src/factory/admin/club/member/member.ts index 116a0c8..e934025 100644 --- a/src/factory/admin/club/member/member.ts +++ b/src/factory/admin/club/member/member.ts @@ -1,6 +1,7 @@ import { member } from "../../../../entity/club/member/member"; import { MemberStatisticsViewModel, MemberViewModel } from "../../../../viewmodel/admin/club/member/member.models"; import { memberView } from "../../../../views/memberView"; +import SalutationFactory from "../../settings/salutation"; import CommunicationFactory from "./communication"; import MembershipFactory from "./membership"; @@ -13,7 +14,7 @@ export default abstract class MemberFactory { public static mapToSingle(record: member): MemberViewModel { return { id: record?.id, - salutation: record?.salutation, + salutation: SalutationFactory.mapToSingle(record?.salutation), firstname: record?.firstname, lastname: record?.lastname, nameaffix: record?.nameaffix, diff --git a/src/factory/admin/settings/salutation.ts b/src/factory/admin/settings/salutation.ts new file mode 100644 index 0000000..65ac3dd --- /dev/null +++ b/src/factory/admin/settings/salutation.ts @@ -0,0 +1,25 @@ +import { salutation } from "../../../entity/settings/salutation"; +import { SalutationViewModel } from "../../../viewmodel/admin/settings/salutation.models"; + +export default abstract class SalutationFactory { + /** + * @description map record to salutation + * @param {salutation} record + * @returns {SalutationViewModel} + */ + public static mapToSingle(record: salutation): SalutationViewModel { + return { + id: record.id, + salutation: record.salutation, + }; + } + + /** + * @description map records to salutation + * @param {Array} records + * @returns {Array} + */ + public static mapToBase(records: Array): Array { + return records.map((r) => this.mapToSingle(r)); + } +} diff --git a/src/routes/admin/index.ts b/src/routes/admin/index.ts index 9aa24ce..016db3e 100644 --- a/src/routes/admin/index.ts +++ b/src/routes/admin/index.ts @@ -6,6 +6,7 @@ import communicationType from "./settings/communicationType"; import executivePosition from "./settings/executivePosition"; import membershipStatus from "./settings/membershipStatus"; import qualification from "./settings/qualification"; +import salutation from "./settings/salutation"; import calendarType from "./settings/calendarType"; import queryStore from "./settings/queryStore"; import template from "./settings/template"; @@ -43,6 +44,7 @@ router.use( membershipStatus ); router.use("/qualification", PermissionHelper.passCheckMiddleware("read", "settings", "qualification"), qualification); +router.use("/salutation", PermissionHelper.passCheckMiddleware("read", "settings", "salutation"), salutation); router.use("/calendartype", PermissionHelper.passCheckMiddleware("read", "settings", "calendar_type"), calendarType); router.use("/querystore", PermissionHelper.passCheckMiddleware("read", "settings", "query_store"), queryStore); router.use("/template", PermissionHelper.passCheckMiddleware("read", "settings", "template"), template); diff --git a/src/routes/admin/settings/salutation.ts b/src/routes/admin/settings/salutation.ts new file mode 100644 index 0000000..c4c53a0 --- /dev/null +++ b/src/routes/admin/settings/salutation.ts @@ -0,0 +1,45 @@ +import express, { Request, Response } from "express"; +import { + createSalutation, + deleteSalutation, + getAllSalutations, + getSalutationById, + updateSalutation, +} from "../../../controller/admin/settings/salutationController"; +import PermissionHelper from "../../../helpers/permissionHelper"; + +var router = express.Router({ mergeParams: true }); + +router.get("/", async (req: Request, res: Response) => { + await getAllSalutations(req, res); +}); + +router.get("/:id", async (req: Request, res: Response) => { + await getSalutationById(req, res); +}); + +router.post( + "/", + PermissionHelper.passCheckMiddleware("create", "settings", "salutation"), + async (req: Request, res: Response) => { + await createSalutation(req, res); + } +); + +router.patch( + "/:id", + PermissionHelper.passCheckMiddleware("update", "settings", "salutation"), + async (req: Request, res: Response) => { + await updateSalutation(req, res); + } +); + +router.delete( + "/:id", + PermissionHelper.passCheckMiddleware("delete", "settings", "salutation"), + async (req: Request, res: Response) => { + await deleteSalutation(req, res); + } +); + +export default router; diff --git a/src/service/settings/salutationService.ts b/src/service/settings/salutationService.ts new file mode 100644 index 0000000..70a6b4f --- /dev/null +++ b/src/service/settings/salutationService.ts @@ -0,0 +1,41 @@ +import { dataSource } from "../../data-source"; +import { salutation } from "../../entity/settings/salutation"; +import InternalException from "../../exceptions/internalException"; + +export default abstract class SalutationService { + /** + * @description get all salutations + * @returns {Promise>} + */ + static async getAll(): Promise> { + return await dataSource + .getRepository(salutation) + .createQueryBuilder("salutation") + .orderBy("salutation", "ASC") + .getMany() + .then((res) => { + return res; + }) + .catch((err) => { + throw new InternalException("salutations not found", err); + }); + } + + /** + * @description get salutation by id + * @returns {Promise} + */ + static async getById(id: number): Promise { + return await dataSource + .getRepository(salutation) + .createQueryBuilder("salutation") + .where("salutation.id = :id", { id: id }) + .getOneOrFail() + .then((res) => { + return res; + }) + .catch((err) => { + throw new InternalException("salutation not found by id", err); + }); + } +} diff --git a/src/type/permissionTypes.ts b/src/type/permissionTypes.ts index 5ba5cb4..cd37e49 100644 --- a/src/type/permissionTypes.ts +++ b/src/type/permissionTypes.ts @@ -11,6 +11,7 @@ export type PermissionModule = | "executive_position" | "communication_type" | "membership_status" + | "salutation" | "calendar_type" | "user" | "role" @@ -53,6 +54,7 @@ export const permissionModules: Array = [ "executive_position", "communication_type", "membership_status", + "salutation", "calendar_type", "user", "role", @@ -71,6 +73,7 @@ export const sectionsAndModules: SectionsAndModulesObject = { "executive_position", "communication_type", "membership_status", + "salutation", "calendar_type", "query_store", "template",