Files
004_comission/_resources/_tecky/party-planner/backend/routes/scheduleRoutes.ts
louiscklaw 6c60a73f30 update,
2025-01-31 19:15:17 +08:00

628 lines
14 KiB
TypeScript

import express, { Request, Response } from 'express';
import { client } from '../app';
import { isLoggedInAPI } from '../util/guard';
import { logger } from '../util/logger';
export const scheduleRoutes = express.Router();
scheduleRoutes.get('/', isLoggedInAPI, getEventSchedule);
scheduleRoutes.post('/activity', isLoggedInAPI, postEventSchedule);
scheduleRoutes.put('/description/edit', isLoggedInAPI, editDescription);
scheduleRoutes.put('/remark/edit', isLoggedInAPI, editRemark);
scheduleRoutes.put('/timeName/edit', isLoggedInAPI, editTimeName);
scheduleRoutes.post('/item', isLoggedInAPI, postItem);
scheduleRoutes.delete('/timeBlock/', isLoggedInAPI, deleteTimeBlock);
// select * from time_blocks where start_time
// between '2022-10-12T10:00:00' and '2022-10-12T12:00:00'
// or end_time between '2022-10-12T10:00:00' and '2022-10-12T12:00:00';
// Date <- Birthday , no need to do comparison , Time is not useful
// Time <- only if it is not a moment, but a periodic time. "Every day 3pm"
// Datetime <- everything else
async function postItem(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const creator = req.query['is-creator'];
const timeBlockId = req.query['id'];
const itemList = req.body;
const eventId = req.query['event-id'];
const event = (
await client.query(
`
SELECT start_datetime, end_datetime, deleted FROM events
WHERE id = $1
`,
[eventId]
)
).rows[0];
const isDeleted = event.deleted;
const eventStartTimeInMin = event.start_datetime.getTime();
const eventEndTimeInMin = event.end_datetime.getTime();
const now = new Date().getTime();
let isProcessing = true;
if (eventStartTimeInMin < now && eventEndTimeInMin < now) {
isProcessing = false;
//event is finished
}
if (isDeleted) {
isProcessing = false;
//event was deleted by creator
}
if (creator === '1' && isProcessing) {
// delete existing list
await client.query(
`
DELETE FROM time_block_item
WHERE time_block_item.time_block_id = $1
`,
[timeBlockId]
);
itemList.forEach(async (item: any) => {
await client.query(
`
INSERT INTO time_block_item (time_block_id, item_id, created_at, updated_at)
VALUES ($1, $2, $3, $4)
`,
[timeBlockId, `${item}`, 'now()', 'now()']
);
});
res.json({
status: true,
msg: 'Items Added'
});
} else {
res.status(400).json({
msg: '[EER001]: Unauthorized Request'
});
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[ITM003]: Failed to Add Show Item'
});
}
}
async function editTimeName(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const eventId = req.query['event-id'];
const creator = req.query['is-creator'];
const timeBlockId = parseInt(req.query['id'] as string);
const date = req.query.date;
const title = req.body.title;
const startTime = req.body.editStartTime;
const endTime = req.body.editEndTime;
const color = req.body.editColor;
const event = (
await client.query(
`
SELECT start_datetime, end_datetime, deleted FROM events
WHERE id = $1
`,
[eventId]
)
).rows[0];
const isDeleted = event.deleted;
const eventStartTimeInMin = event.start_datetime.getTime();
const eventEndTimeInMin = event.end_datetime.getTime();
const now = new Date().getTime();
let isProcessing = true;
if (eventStartTimeInMin < now && eventEndTimeInMin < now) {
isProcessing = false;
//event is finished
}
if (isDeleted) {
isProcessing = false;
//event was deleted by creator
}
if (creator === '1' && isProcessing) {
//check time collision with existing time-blocks
//bug: correct end time = 00:00 problem
const existingActivities = (
await client.query(
`
SELECT start_time, end_time, id FROM time_blocks
WHERE event_id = $1
AND date = $2
AND id != $3
ORDER BY start_time ASC;
`,
[eventId, date, timeBlockId]
)
).rows;
let reject = false;
const newStartTimeInMin = toMin(req.body.editStartTime);
const newEndTimeInMin = toMin(req.body.editEndTime);
existingActivities.forEach((activity) => {
const startTimeInMin = toMin(activity.start_time);
const endTimeInMin = toMin(activity.end_time);
if (newStartTimeInMin > startTimeInMin && newStartTimeInMin < endTimeInMin) {
reject = true;
console.log('1');
}
if (newEndTimeInMin > startTimeInMin && newEndTimeInMin < endTimeInMin) {
reject = true;
console.log('2');
}
if (newStartTimeInMin <= startTimeInMin && newEndTimeInMin >= endTimeInMin) {
reject = true;
console.log('3');
}
});
//writing update to DB
if (reject) {
res.status(400).json({
msg: '[EER002]: Activity Start Time or End Time Overlapped with Existing Activity'
});
} else {
await client.query(
`
UPDATE time_blocks
SET title = $1,
start_time = $2,
end_time = $3,
color = $4,
updated_at = $5
WHERE event_id = $6
AND id = $7
AND date = $8
`,
[title, startTime, endTime, color, 'now()', eventId, timeBlockId, date]
);
res.json({
status: true,
msg: 'Edit success'
});
}
} else {
res.json({
status: false,
msg: '[EER001]: Unauthorized Request'
});
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[TBE002]: Failed to Edit Time & Name'
});
}
}
async function editRemark(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const eventId = req.query['event-id'];
const creator = req.query['is-creator'];
const timeBlockId = req.query['id'];
const date = req.query.date;
const remark = req.body.remark;
const event = (
await client.query(
`
SELECT start_datetime, end_datetime, deleted FROM events
WHERE id = $1
`,
[eventId]
)
).rows[0];
const isDeleted = event.deleted;
const eventStartTimeInMin = event.start_datetime.getTime();
const eventEndTimeInMin = event.end_datetime.getTime();
const now = new Date().getTime();
let isProcessing = true;
if (eventStartTimeInMin < now && eventEndTimeInMin < now) {
isProcessing = false;
//event is finished
}
if (isDeleted) {
isProcessing = false;
//event was deleted by creator
}
if (creator === '1' && isProcessing) {
await client.query(
`
UPDATE time_blocks
SET remark = $1,
updated_at = $2
WHERE event_id = $3
AND id = $4
AND date = $5
`,
[remark, 'now()', eventId, timeBlockId, date]
);
res.json({
status: true,
msg: 'Edit success'
});
} else {
res.json({
status: false,
msg: '[EER001]: Unauthorized Request'
});
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[TBE001]: Failed to Edit Remark'
});
}
}
async function editDescription(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const eventId = req.query['event-id'];
const creator = req.query['is-creator'];
const timeBlockId = req.query['id'];
const date = req.query.date;
const description = req.body.description;
const event = (
await client.query(
`
SELECT start_datetime, end_datetime, deleted FROM events
WHERE id = $1
`,
[eventId]
)
).rows[0];
const isDeleted = event.deleted;
const eventStartTimeInMin = event.start_datetime.getTime();
const eventEndTimeInMin = event.end_datetime.getTime();
const now = new Date().getTime();
let isProcessing = true;
if (eventStartTimeInMin < now && eventEndTimeInMin < now) {
isProcessing = false;
//event is finished
}
if (isDeleted) {
isProcessing = false;
//event was deleted by creator
}
if (creator === '1' && isProcessing) {
await client.query(
`
UPDATE time_blocks
SET description = $1,
updated_at = $2
WHERE event_id = $3
AND id = $4
AND date = $5
`,
[description, 'now()', eventId, timeBlockId, date]
);
res.json({
status: true,
msg: 'Edit success'
});
} else {
res.json({
status: false,
msg: '[EER001]: Unauthorized Request'
});
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[TBE003]: Failed to Edit Description'
});
}
}
async function deleteTimeBlock(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const eventId = req.query['event-id'];
const creator = req.query['is-creator'];
const timeBlockId = req.query['id'];
const date = req.query.date;
const event = (
await client.query(
`
SELECT start_datetime, end_datetime, deleted FROM events
WHERE id = $1
`,
[eventId]
)
).rows[0];
const isDeleted = event.deleted;
const eventStartTimeInMin = event.start_datetime.getTime();
const eventEndTimeInMin = event.end_datetime.getTime();
const now = new Date().getTime();
let isProcessing = true;
if (eventStartTimeInMin < now && eventEndTimeInMin < now) {
isProcessing = false;
//event is finished
}
if (isDeleted) {
isProcessing = false;
//event was deleted by creator
}
if (creator === '1' && isProcessing) {
await client.query(
`
DELETE FROM time_block_item
WHERE time_block_id = $1
`,
[timeBlockId]
);
await client.query(
`
DELETE FROM time_blocks
WHERE id = $1
AND event_id = $2
AND date = $3
`,
[timeBlockId, eventId, date]
);
res.json({
status: true,
msg: 'Delete success'
});
} else {
res.status(400).json({
status: false,
msg: '[EER001]: Unauthorized Request'
});
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[TBD001]: Failed to Delete Time Block'
});
}
}
async function getEventSchedule(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const eventId = req.query['event-id'];
const creator = req.query['is-creator'];
let date = req.query.date;
let event;
if (creator === '1') {
event = (
await client.query(
`
SELECT * FROM events
WHERE events.id = $1
AND events.creator_id = $2
`,
[eventId, req.session.user]
)
).rows[0];
} else {
event = (
await client.query(
`
SELECT * FROM events
INNER JOIN participants ON participants.event_id = events.id
WHERE events.id = $1
AND participants.user_id = $2;
`,
[eventId, req.session.user]
)
).rows[0];
}
if (event.start_datetime) {
if (date === 'null' || 'undefined') {
const option = {
hour12: false,
year: 'numeric',
month: '2-digit',
day: '2-digit'
};
let placeholder = event.start_datetime.toLocaleString('en-GB', option).split('/');
date = `${placeholder[2]}${placeholder[1]}${placeholder[0]}`;
}
const activitiesArr = (
await client.query(
`
SELECT * FROM time_blocks
WHERE event_id = $1
AND date = $2
`,
[eventId, date]
)
).rows;
const itemList = (
await client.query(
`
SELECT * FROM items
WHERE items.event_id = $1
`,
[eventId]
)
).rows;
const savedItemList = (
await client.query(
`
SELECT * FROM items
JOIN time_block_item ON items.id = time_block_item.item_id
JOIN time_blocks ON time_block_item.time_block_id = time_blocks.id
WHERE time_blocks.event_id = $1
AND time_blocks.date = $2
`,
[eventId, date]
)
).rows;
res.json({
status: true,
detail: event,
activities: activitiesArr,
items: itemList,
savedItems: savedItemList
});
} else {
res.json({ status: false });
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[ETS001]: Failed to get Event Schedule'
});
}
}
function toMin(timeInput: String) {
const hourInMin = parseInt(timeInput.slice(0, 2)) * 60;
const min = parseInt(timeInput.slice(3, 5));
return hourInMin + min;
}
async function postEventSchedule(req: Request, res: Response) {
try {
logger.debug('Before reading DB');
const eventId = req.query['event-id'];
const creator = req.query['is-creator'];
const date = req.query.date;
const event = (
await client.query(
`
SELECT start_datetime, end_datetime, deleted FROM events
WHERE id = $1
`,
[eventId]
)
).rows[0];
const isDeleted = event.deleted;
const eventStartTimeInMin = event.start_datetime.getTime();
const eventEndTimeInMin = event.end_datetime.getTime();
const now = new Date().getTime();
let isProcessing = true;
if (eventStartTimeInMin < now && eventEndTimeInMin < now) {
isProcessing = false;
//event is finished
}
if (isDeleted) {
isProcessing = false;
//event was deleted by creator
}
if (creator === '1' && isProcessing) {
//check if start time and end time collided with existing activities
const existingActivities = (
await client.query(
`
SELECT start_time, end_time FROM time_blocks
WHERE event_id = $1
AND date = $2
ORDER BY start_time ASC;
`,
[eventId, date]
)
).rows;
let reject = false;
existingActivities.forEach((activity) => {
const startTimeInMin = toMin(activity.start_time);
const endTimeInMin = toMin(activity.end_time);
const newStartTimeInMin = toMin(req.body.startTime);
const newEndTimeInMin = toMin(req.body.endTime);
if (newStartTimeInMin > startTimeInMin && newStartTimeInMin < endTimeInMin) {
reject = true;
} else if (newEndTimeInMin > startTimeInMin && newEndTimeInMin < endTimeInMin) {
reject = true;
}
});
//writing request to DB
if (reject) {
res.status(400).json({
msg: '[EER002]: Activity Start Time or End Time Overlapped with Existing Activity'
});
} else {
await client.query(
`
INSERT INTO time_blocks
(title, description, event_id, user_id, start_time,
end_time, remark, date, color, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`,
[
req.body.title,
req.body.description,
eventId,
req.session.user,
req.body.startTime,
req.body.endTime,
req.body.remark,
date,
req.body.color,
'now()',
'now()'
]
);
res.json({
status: true,
msg: 'save success'
});
}
} else {
res.status(400).json({
msg: '[EER001]: Unauthorized Request'
});
}
} catch (e) {
logger.error(e);
res.status(500).json({
msg: '[ETS002]: Failed to Post Event Schedule'
});
}
}