Skip to content

Commit

Permalink
Merge pull request #27 from advanced-computer-lab-2023/task_42_43
Browse files Browse the repository at this point in the history
Task 42 43
  • Loading branch information
3laaHisham authored Nov 10, 2023
2 parents 3824f6b + 9520100 commit 746606d
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 23 deletions.
1 change: 1 addition & 0 deletions client/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"import/prefer-default-export": 0,
"react/function-component-definition": 0,
"jsx-a11y/control-has-associated-label": 0,
"import/no-unresolved": 0,
"react/jsx-no-useless-fragment": [
1,
{
Expand Down
2 changes: 1 addition & 1 deletion server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"stripe": "^8.174.0",
"ts-node": "^10.9.1",
"typescript": "^5.2.2",
"uuid": "^9.0.1",
"validator": "^13.9.0"
},
"devDependencies": {
Expand Down
5 changes: 0 additions & 5 deletions server/src/models/doctor.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const options = { discriminatorKey: 'role' };
interface DailySchedule {
from: { hours: number; minutes: number };
to: { hours: number; minutes: number };
maxPatients: number;
}

interface IDoctor extends ICommonUser {
Expand Down Expand Up @@ -49,10 +48,6 @@ const dailyScheduleSchema = {
minutes: { type: Number, required: false, default: 0, min: 0, max: 59 }
},
required: true
},
maxPatients: {
type: Number,
required: true
}
};

Expand Down
12 changes: 11 additions & 1 deletion server/src/routes/doctor.route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import express, { Request, Response } from 'express';

import controller from '../controllers';
import { getDoctors } from '../services';
import { createAppointment, getDoctors, viewAvailableAppointments } from '../services';
import { isAuthenticated, isAuthorized } from '../middlewares';

const router = express.Router();
router.use(isAuthenticated);

router.get('/:id/availableAppointments', isAuthorized('Patient'), (req: Request, res: Response) => {
controller(res)(viewAvailableAppointments)(req.params.id);
});

router.post('/:id/appointments', isAuthorized('Patient'), (req: Request, res: Response) => {
controller(res)(createAppointment)(req.decoded.id, req.params.id, req.body);
});

router.get('/:id', (req: Request, res: Response) => {
controller(res)(getDoctors)({ _id: req.params.id });
Expand Down
15 changes: 12 additions & 3 deletions server/src/routes/me.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ import express, { Request, Response } from 'express';

import controller from '../controllers';
import { isAuthenticated, isAuthorized } from '../middlewares';
import { getUsers, updateInfo, getAppointments, getPrescriptions, addFamilyMember, getFamily } from '../services';
import {
getUsers,
updateInfo,
getAppointments,
getPrescriptions,
addFamilyMember,
getFamily,
getHealthRecords
} from '../services';

const router = express.Router();

Expand Down Expand Up @@ -58,9 +66,10 @@ router.get('/prescriptions', (req: Request, res: Response) => {
controller(res)(getPrescriptions)(req.query);
});

router.get('/medicalhistory', (req: Request, res: Response) => {
// controller(res)()();
router.get('/medicalhistory', isAuthorized('Patient'), (req: Request, res: Response) => {
controller(res)(getHealthRecords)(req.decoded.id);
});

router.post('/medicalhistory', (req: Request, res: Response) => {
// controller(res)()();
});
Expand Down
16 changes: 7 additions & 9 deletions server/src/routes/patient.route.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
import express, { Request, Response } from 'express';

import controller from '../controllers';
import { getMyPatients } from '../services';
import { addHealthRecord, getHealthRecords, getMyPatients } from '../services';
import { isAuthenticated, isAuthorized } from '../middlewares';

const router = express.Router();

router.use(isAuthenticated);
router.use(isAuthorized('Doctor'));

router.get('/:id/medicalhistory', (req: Request, res: Response) => {
// controller(res)()();
});

router.get('/:id', (req: Request, res: Response) => {
controller(res)(getMyPatients)({ doctorID: req.decoded.id, patientID: req.params.id });
});
router.get('/', (req: Request, res: Response) => {
controller(res)(getMyPatients)({ doctorID: req.decoded.id });
});

router.post('/:id/medicalhistory', (req: Request, res: Response) => {
// Handle medical history update logic here
// notice that doctors can update patients medical history
// controller(res)()();
router.get('/:id/medicalhistory', isAuthorized('Doctor'), (req: Request, res: Response) => {
controller(res)(getHealthRecords)(req.params.id);
});

router.post('/:id/medicalhistory', isAuthorized('Doctor'), (req: Request, res: Response) => {
controller(res)(addHealthRecord)(req.params.id, req.body);
});

export default router;
19 changes: 17 additions & 2 deletions server/src/services/appointment.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Appointment } from '../models';
import { Appointment, Doctor } from '../models';
import { StatusCodes } from 'http-status-codes';
import mongoose from 'mongoose';
import { HttpError } from '../utils';
Expand All @@ -18,4 +18,19 @@ const getAppointments = async (query: any) => {
};
};

export { getAppointments };
const createAppointment = async (patientID: String, doctorID: String, body: any) => {
const doctor = await Doctor.findById(doctorID);
if (!doctor) throw new HttpError(StatusCodes.NOT_FOUND, 'Doctor not found');

body.patientID = patientID;
body.doctorID = doctorID;
const newAppointment = await Appointment.create(body);

return {
status: StatusCodes.CREATED,
message: 'Appointment created successfully',
result: newAppointment
};
};

export { getAppointments, createAppointment };
107 changes: 106 additions & 1 deletion server/src/services/doctor.service.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { v4: uuidv4 } = require('uuid');
import { HttpError } from '../utils';
import StatusCodes from 'http-status-codes';
import { User, Contract, Appointment, IPatient, IDoctor, Doctor } from '../models';
Expand Down Expand Up @@ -44,4 +45,108 @@ const getDoctors = async (query: any) => {
return { result: doctors, status: StatusCodes.OK };
};

export { getDoctors, getMyPatients };
const viewAvailableAppointments = async (doctorID: string) => {
const doctor = await Doctor.findById(doctorID);
if (!doctor) throw new HttpError(StatusCodes.NOT_FOUND, 'Doctor not found');

const weeklySlots = doctor.weeklySlots;
if (!weeklySlots) throw new HttpError(StatusCodes.NOT_FOUND, 'No available appointments for this doctor');

let availableAppointments = {};

const thisDay = new Date();
const currentYear = thisDay.getUTCFullYear();
const currentMonth = thisDay.getUTCMonth();
const currentDate = thisDay.getUTCDate();
const currentDay = thisDay.getUTCDay();
const lastDay = currentDay + 6;

// Get all doctor's appointments
const appointments = await Appointment.find({
doctorID: doctorID
});

for (let i = currentDay; i <= lastDay; i++) {
const dayOfWeek = i % 7;
const day = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayOfWeek];
const dailySlots = weeklySlots[day as keyof typeof weeklySlots];

for (const slot of dailySlots) {
const slotHour = slot.from.hours;
const slotMinute = slot.from.minutes;
const slotHourEnd = slot.to.hours;
const slotMinuteEnd = slot.to.minutes;
let isSlotAvailable = true;

for (const appointment of appointments) {
const appointmentStartDate = appointment.startDate;
const appointmentYear = appointmentStartDate.getUTCFullYear();
const appointmentMonth = appointmentStartDate.getUTCMonth();
const appointmentDate = appointmentStartDate.getUTCDate();
const appointmentDay = appointmentStartDate.getUTCDay();
const appointmentHour = appointmentStartDate.getUTCHours();
const appointmentMinute = appointmentStartDate.getUTCMinutes();

if (
appointmentYear === currentYear &&
appointmentMonth === currentMonth &&
appointmentDate >= currentDate &&
appointmentDate <= currentDate + 6 &&
appointmentDay % 7 === dayOfWeek &&
slotHour === appointmentHour &&
slotMinute === appointmentMinute
) {
isSlotAvailable = false;
break;
}
}

if (isSlotAvailable) {
const startDate = new Date(
currentYear,
currentMonth,
currentDate + i - currentDay,
slotHour + 2,
slotMinute,
0,
0
);
const endDate = new Date(
currentYear,
currentMonth,
currentDate + i - currentDay,
slotHourEnd + 2,
slotMinuteEnd,
0,
0
);

const price = Math.floor(doctor.hourRate * (slotHourEnd - slotHour + (slotMinuteEnd - slotMinute) / 60));

const id = uuidv4();

const slot = {
status: 'Upcoming',
sessionPrice: price,
startDate: startDate.toISOString(),
endDate: endDate.toISOString(),
isFollowUp: false,
_id: id
};

if (!(availableAppointments as any)[day]) {
(availableAppointments as any)[day] = []; // Initialize the day as an array if it doesn't exist
}
(availableAppointments as any)[day].push(slot);
}
}
}

return {
status: StatusCodes.OK,
message: 'Available Appointments retrieved successfully',
result: availableAppointments
};
};

export { getDoctors, getMyPatients, viewAvailableAppointments };
44 changes: 43 additions & 1 deletion server/src/services/patient.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,46 @@ const viewDoctorsForPatient = async (patientId: string, query: any) => {
};
};

export { viewDoctorsForPatient as viewAllDoctorsForPatient, getFamily, addFamilyMember };
const addHealthRecord = async (patientID: String, body: any) => {
const { name, medicalRecord } = body;
if (!name || !medicalRecord) throw new HttpError(StatusCodes.BAD_REQUEST, 'Please provide name, medicalRecord');

const update = {
$push: {
medicalHistory: {
name,
medicalRecord
}
}
};
const updatedUser = await Patient.findByIdAndUpdate(patientID, update, { new: true });
if (!updatedUser) throw new HttpError(StatusCodes.NOT_FOUND, 'User not found');

return {
result: updatedUser,
status: StatusCodes.OK,
message: 'Health record added successfully'
};
};

const getHealthRecords = async (patientID: String) => {
const user: any = await Patient.findById(patientID).select('medicalHistory');
if (!user) throw new HttpError(StatusCodes.NOT_FOUND, 'patient not found');

const healthRecords = user.medicalHistory;
if (!healthRecords) throw new HttpError(StatusCodes.NOT_FOUND, 'health records not found');

return {
result: healthRecords,
status: StatusCodes.OK,
message: 'Health records retrieved successfully'
};
};

export {
viewDoctorsForPatient as viewAllDoctorsForPatient,
getFamily,
addFamilyMember,
addHealthRecord,
getHealthRecords
};

0 comments on commit 746606d

Please sign in to comment.