calender crud operations

This commit is contained in:
Julian Krauser 2024-10-27 11:47:13 +01:00
parent e7b8257336
commit bf701163d6
18 changed files with 703 additions and 0 deletions

View file

@ -0,0 +1,22 @@
export interface CreateCalendarCommand {
date: Date;
starttime: Date;
endtime: Date;
title: string;
content: string;
typeId: number;
}
export interface UpdateCalendarCommand {
id: number;
date: Date;
starttime: Date;
endtime: Date;
title: string;
content: string;
typeId: number;
}
export interface DeleteCalendarCommand {
id: number;
}

View file

@ -0,0 +1,85 @@
import { dataSource } from "../data-source";
import { calendar } from "../entity/calendar";
import { calendarType } from "../entity/calendarType";
import InternalException from "../exceptions/internalException";
import { CreateCalendarCommand, DeleteCalendarCommand, UpdateCalendarCommand } from "./calendarCommand";
export default abstract class CalendarCommandHandler {
/**
* @description create calendar
* @param CreateCalendarCommand
* @returns {Promise<number>}
*/
static async create(createCalendar: CreateCalendarCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(calendar)
.values({
date: createCalendar.date,
starttime: createCalendar.starttime,
endtime: createCalendar.endtime,
title: createCalendar.title,
content: createCalendar.content,
type: await dataSource
.getRepository(calendarType)
.createQueryBuilder("type")
.where("id = :id", { id: createCalendar.typeId })
.getOneOrFail(),
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new InternalException("Failed creating calendar", err);
});
}
/**
* @description update calendar
* @param UpdateCalendarCommand
* @returns {Promise<void>}
*/
static async update(updateCalendar: UpdateCalendarCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(calendar)
.set({
date: updateCalendar.date,
starttime: updateCalendar.starttime,
endtime: updateCalendar.endtime,
title: updateCalendar.title,
content: updateCalendar.content,
type: await dataSource
.getRepository(calendarType)
.createQueryBuilder("type")
.where("id = :id", { id: updateCalendar.typeId })
.getOneOrFail(),
})
.where("id = :id", { id: updateCalendar.id })
.execute()
.then(() => {})
.catch((err) => {
throw new InternalException("Failed updating award", err);
});
}
/**
* @description delete calendar
* @param DeleteCalendarCommand
* @returns {Promise<void>}
*/
static async delete(deleteCalendar: DeleteCalendarCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(calendar)
.where("id = :id", { id: deleteCalendar.id })
.execute()
.then(() => {})
.catch((err) => {
throw new InternalException("Failed deleting calendar", err);
});
}
}

View file

@ -0,0 +1,16 @@
export interface CreateCalendarTypeCommand {
type: string;
nscdr: boolean;
color: string;
}
export interface UpdateCalendarTypeCommand {
id: number;
type: string;
nscdr: boolean;
color: string;
}
export interface DeleteCalendarTypeCommand {
id: number;
}

View file

@ -0,0 +1,70 @@
import { dataSource } from "../data-source";
import { calendarType } from "../entity/calendarType";
import InternalException from "../exceptions/internalException";
import { CreateCalendarTypeCommand, DeleteCalendarTypeCommand, UpdateCalendarTypeCommand } from "./calendarTypeCommand";
export default abstract class CalendarTypeCommandHandler {
/**
* @description create calendarType
* @param CreateCalendarTypeCommand
* @returns {Promise<number>}
*/
static async create(createCalendarType: CreateCalendarTypeCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(calendarType)
.values({
type: createCalendarType.type,
nscdr: createCalendarType.nscdr,
color: createCalendarType.color,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new InternalException("Failed creating calendarType", err);
});
}
/**
* @description update calendarType
* @param UpdateCalendarTypeCommand
* @returns {Promise<void>}
*/
static async update(updateCalendarType: UpdateCalendarTypeCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(calendarType)
.set({
type: updateCalendarType.type,
nscdr: updateCalendarType.nscdr,
color: updateCalendarType.color,
})
.where("id = :id", { id: updateCalendarType.id })
.execute()
.then(() => {})
.catch((err) => {
throw new InternalException("Failed updating award", err);
});
}
/**
* @description delete calendarType
* @param DeleteCalendarTypeCommand
* @returns {Promise<void>}
*/
static async delete(deleteCalendarType: DeleteCalendarTypeCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(calendarType)
.where("id = :id", { id: deleteCalendarType.id })
.execute()
.then(() => {})
.catch((err) => {
throw new InternalException("Failed deleting calendarType", err);
});
}
}

View file

@ -0,0 +1,197 @@
import { Request, Response } from "express";
import CalendarService from "../../service/calendarService";
import CalendarFactory from "../../factory/admin/calendar";
import CalendarTypeService from "../../service/calendarTypeService";
import CalendarTypeFactory from "../../factory/admin/calendarType";
import { CreateCalendarCommand, DeleteCalendarCommand, UpdateCalendarCommand } from "../../command/calendarCommand";
import CalendarCommandHandler from "../../command/calendarCommandHandler";
import {
CreateCalendarTypeCommand,
DeleteCalendarTypeCommand,
UpdateCalendarTypeCommand,
} from "../../command/calendarTypeCommand";
import CalendarTypeCommandHandler from "../../command/calendarTypeCommandHandler";
/**
* @description get all calendar items
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllCalendarItems(req: Request, res: Response): Promise<any> {
let items = await CalendarService.getAll();
res.json(CalendarFactory.mapToBase(items));
}
/**
* @description get calendar item by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getCalendarItemById(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id);
let item = await CalendarService.getById(id);
res.json(CalendarFactory.mapToSingle(item));
}
/**
* @description get all calendar types
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllCalendarTypes(req: Request, res: Response): Promise<any> {
let types = await CalendarTypeService.getAll();
res.json(CalendarTypeFactory.mapToBase(types));
}
/**
* @description get calendar type by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getCalendarTypeById(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id);
let type = await CalendarTypeService.getById(id);
res.json(CalendarTypeFactory.mapToSingle(type));
}
/**
* @description create calendar item
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createCalendarItem(req: Request, res: Response): Promise<any> {
const date = req.body.date;
const starttime = req.body.starttime;
const endtime = req.body.endtime;
const title = req.body.title;
const content = req.body.content;
const typeId = req.body.typeId;
let createItem: CreateCalendarCommand = {
date,
starttime,
endtime,
title,
content,
typeId,
};
let id = await CalendarCommandHandler.create(createItem);
res.send(id);
}
/**
* @description create calendar type
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createCalendarType(req: Request, res: Response): Promise<any> {
const type = req.body.type;
const nscdr = req.body.nscdr;
const color = req.body.color;
let createType: CreateCalendarTypeCommand = {
type,
nscdr,
color,
};
let id = await CalendarTypeCommandHandler.create(createType);
res.send(id);
}
/**
* @description update calendar item
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateCalendarItem(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id);
const date = req.body.date;
const starttime = req.body.starttime;
const endtime = req.body.endtime;
const title = req.body.title;
const content = req.body.content;
const typeId = req.body.typeId;
let updateItem: UpdateCalendarCommand = {
id,
date,
starttime,
endtime,
title,
content,
typeId,
};
await CalendarCommandHandler.update(updateItem);
res.sendStatus(204);
}
/**
* @description update calendar type
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateCalendarType(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id);
const type = req.body.type;
const nscdr = req.body.nscdr;
const color = req.body.color;
let updateType: UpdateCalendarTypeCommand = {
id,
type,
nscdr,
color,
};
await CalendarTypeCommandHandler.update(updateType);
res.sendStatus(204);
}
/**
* @description delete calendar item
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteCalendarItem(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id);
let deleteItem: DeleteCalendarCommand = {
id,
};
await CalendarCommandHandler.delete(deleteItem);
res.sendStatus(204);
}
/**
* @description delete calendar type
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteCalendarType(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id);
let deleteType: DeleteCalendarTypeCommand = {
id,
};
await CalendarTypeCommandHandler.delete(deleteType);
res.sendStatus(204);
}

View file

@ -0,0 +1,25 @@
import { Request, Response } from "express";
import CalendarFactory from "../factory/admin/calendar";
import CalendarService from "../service/calendarService";
import CalendarTypeService from "../service/calendarTypeService";
import { calendar } from "../entity/calendar";
/**
* @description get all calendar items by types or nscdr
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getCalendarItemsByTypes(req: Request, res: Response): Promise<any> {
let types = Array.isArray(req.query.types) ? req.query.types : [req.query.types];
let items: Array<calendar> = [];
if (types.length == 0) {
let typeIds = await CalendarTypeService.getByTypes(types as Array<string>);
items = await CalendarService.getByTypes(typeIds.map((t) => t.id));
} else {
items = await CalendarService.getByTypeNSCDR();
}
res.json(CalendarFactory.mapToBase(items));
}

View file

@ -12,6 +12,9 @@ export class calendarType {
@Column({ type: "boolean" }) // none specified cal dav request @Column({ type: "boolean" }) // none specified cal dav request
nscdr: boolean; nscdr: boolean;
@Column({ type: "varchar", length: 255 })
color: string;
@OneToMany(() => calendar, (c) => c.type, { @OneToMany(() => calendar, (c) => c.type, {
nullable: false, nullable: false,
onDelete: "RESTRICT", onDelete: "RESTRICT",

View file

@ -0,0 +1,31 @@
import { calendar } from "../../entity/calendar";
import { CalendarViewModel } from "../../viewmodel/admin/calendar.models";
import CalendarTypeFactory from "./calendarType";
export default abstract class CalendarFactory {
/**
* @description map record to calendar
* @param {calendar} record
* @returns {CalendarViewModel}
*/
public static mapToSingle(record: calendar): CalendarViewModel {
return {
id: record.id,
date: record.date,
starttime: record.starttime,
endtime: record.endtime,
title: record.title,
content: record.content,
type: CalendarTypeFactory.mapToSingle(record.type),
};
}
/**
* @description map records to calendar
* @param {Array<calendar>} records
* @returns {Array<CalendarViewModel>}
*/
public static mapToBase(records: Array<calendar>): Array<CalendarViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,27 @@
import { calendarType } from "../../entity/calendarType";
import { CalendarTypeViewModel } from "../../viewmodel/admin/calendarType.models";
export default abstract class CalendarTypeFactory {
/**
* @description map record to calendarType
* @param {calendarType} record
* @returns {CalendarTypeViewModel}
*/
public static mapToSingle(record: calendarType): CalendarTypeViewModel {
return {
id: record.id,
type: record.type,
nscdr: record.nscdr,
color: record.color,
};
}
/**
* @description map records to calendarType
* @param {Array<calendarType>} records
* @returns {Array<CalendarTypeViewModel>}
*/
public static mapToBase(records: Array<calendarType>): Array<CalendarTypeViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -14,6 +14,7 @@ export class Calendar1729947763295 implements MigrationInterface {
{ name: "id", type: variableType_int, isPrimary: true, isGenerated: true, generationStrategy: "increment" }, { name: "id", type: variableType_int, isPrimary: true, isGenerated: true, generationStrategy: "increment" },
{ name: "type", type: "varchar", length: "255", isNullable: false }, { name: "type", type: "varchar", length: "255", isNullable: false },
{ name: "nscdr", type: "tinyint", isNullable: false }, { name: "nscdr", type: "tinyint", isNullable: false },
{ name: "color", type: "varchar", length: "255", isNullable: false },
], ],
}) })
); );

View file

@ -0,0 +1,57 @@
import express, { Request, Response } from "express";
import {
getCalendarItemById,
getAllCalendarItems,
getAllCalendarTypes,
getCalendarTypeById,
createCalendarItem,
createCalendarType,
updateCalendarItem,
updateCalendarType,
deleteCalendarItem,
deleteCalendarType,
} from "../../controller/admin/calendarController";
var router = express.Router({ mergeParams: true });
router.get("/items", async (req: Request, res: Response) => {
await getAllCalendarItems(req, res);
});
router.get("/item/:id", async (req: Request, res: Response) => {
await getCalendarItemById(req, res);
});
router.get("/types", async (req: Request, res: Response) => {
await getAllCalendarTypes(req, res);
});
router.get("/type/:id", async (req: Request, res: Response) => {
await getCalendarTypeById(req, res);
});
router.post("/item", async (req: Request, res: Response) => {
await createCalendarItem(req, res);
});
router.post("/type", async (req: Request, res: Response) => {
await createCalendarType(req, res);
});
router.patch("/item/:id", async (req: Request, res: Response) => {
await updateCalendarItem(req, res);
});
router.patch("/type/:id", async (req: Request, res: Response) => {
await updateCalendarType(req, res);
});
router.delete("/item/:id", async (req: Request, res: Response) => {
await deleteCalendarItem(req, res);
});
router.delete("/type/:id", async (req: Request, res: Response) => {
await deleteCalendarType(req, res);
});
export default router;

View file

@ -9,6 +9,8 @@ import qualification from "./qualification";
import member from "./member"; import member from "./member";
import calendar from "./calendar";
import role from "./role"; import role from "./role";
import user from "./user"; import user from "./user";
@ -34,6 +36,8 @@ router.use("/qualification", PermissionHelper.passCheckMiddleware("read", "setti
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member); router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
router.use("/calendar", PermissionHelper.passCheckMiddleware("read", "club", "calendar"), calendar);
router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role); router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role);
router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user); router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user);

View file

@ -6,6 +6,7 @@ import allowSetup from "../middleware/allowSetup";
import authenticate from "../middleware/authenticate"; import authenticate from "../middleware/authenticate";
import errorHandler from "../middleware/errorHandler"; import errorHandler from "../middleware/errorHandler";
import publicAvailable from "./public";
import setup from "./setup"; import setup from "./setup";
import auth from "./auth"; import auth from "./auth";
import admin from "./admin/index"; import admin from "./admin/index";
@ -21,6 +22,7 @@ export default (app: Express) => {
app.use(cors()); app.use(cors());
app.options("*", cors()); app.options("*", cors());
app.use("/public", publicAvailable);
app.use("/setup", allowSetup, setup); app.use("/setup", allowSetup, setup);
app.use("/auth", auth); app.use("/auth", auth);
app.use(authenticate); app.use(authenticate);

10
src/routes/public.ts Normal file
View file

@ -0,0 +1,10 @@
import express from "express";
import { getCalendarItemsByTypes } from "../controller/publicController";
var router = express.Router({ mergeParams: true });
router.get("/calendar", async (req, res) => {
await getCalendarItemsByTypes(req, res);
});
export default router;

View file

@ -0,0 +1,78 @@
import { dataSource } from "../data-source";
import { calendar } from "../entity/calendar";
import InternalException from "../exceptions/internalException";
export default abstract class CalendarService {
/**
* @description get all calendars
* @returns {Promise<Array<calendar>>}
*/
static async getAll(): Promise<Array<calendar>> {
return await dataSource
.getRepository(calendar)
.createQueryBuilder("calendar")
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("calendars not found", err);
});
}
/**
* @description get calendar by id
* @returns {Promise<calendar>}
*/
static async getById(id: number): Promise<calendar> {
return await dataSource
.getRepository(calendar)
.createQueryBuilder("calendar")
.where("calendar.id = :id", { id: id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("calendar not found by id", err);
});
}
/**
* @description get calendar by types
* @returns {Promise<Array<calendar>>}
*/
static async getByTypes(types: Array<number>): Promise<Array<calendar>> {
return await dataSource
.getRepository(calendar)
.createQueryBuilder("calendar")
.leftJoinAndSelect("calendar.type", "type")
.where("type.id IN (:...types)", { types: types })
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("calendars not found by types", err);
});
}
/**
* @description get calendar by types nscdr
* @returns {Promise<Array<calendar>>}
*/
static async getByTypeNSCDR(): Promise<Array<calendar>> {
return await dataSource
.getRepository(calendar)
.createQueryBuilder("calendar")
.leftJoinAndSelect("calendar.type", "type")
.where("type.nscdr = :nscdr)", { nscdr: true })
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("calendars not found by type nscdr", err);
});
}
}

View file

@ -0,0 +1,58 @@
import { dataSource } from "../data-source";
import { calendarType } from "../entity/calendarType";
import InternalException from "../exceptions/internalException";
export default abstract class CalendarTypeService {
/**
* @description get all calendar types
* @returns {Promise<Array<calendarType>>}
*/
static async getAll(): Promise<Array<calendarType>> {
return await dataSource
.getRepository(calendarType)
.createQueryBuilder("calendarType")
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("calendarTypes not found", err);
});
}
/**
* @description get calendar type by id
* @returns {Promise<calendarType>}
*/
static async getById(id: number): Promise<calendarType> {
return await dataSource
.getRepository(calendarType)
.createQueryBuilder("calendarType")
.where("calendarType.id = :id", { id: id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("calendarType not found by id", err);
});
}
/**
* @description get calendar by names
* @returns {Promise<Array<calendarType>>}
*/
static async getByTypes(names: Array<string>): Promise<Array<calendarType>> {
return await dataSource
.getRepository(calendarType)
.createQueryBuilder("calendarType")
.where("calendarType.type IN (:...names)", { names: names })
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("calendarTypes not found by names", err);
});
}
}

View file

@ -0,0 +1,11 @@
import { CalendarTypeViewModel } from "./calendarType.models";
export interface CalendarViewModel {
id: number;
date: Date;
starttime: Date;
endtime: Date;
title: string;
content: string;
type: CalendarTypeViewModel;
}

View file

@ -0,0 +1,6 @@
export interface CalendarTypeViewModel {
id: number;
type: string;
nscdr: boolean;
color: string;
}