From 040656ba2b1af9c3167cb7607a97d2f8e7417c6c Mon Sep 17 00:00:00 2001 From: AhmedHamed3699 Date: Sun, 24 Dec 2023 21:44:18 +0200 Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=8E=A8=20chore:=20most=20of=20the=20b?= =?UTF-8?q?ackend=20is=20consistent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/controllers/alert.controller.js | 148 +++++++------- server/controllers/auth.controller.js | 4 +- server/controllers/captain.controller.js | 124 ++++++------ server/controllers/scout.controller.js | 245 +++++++++++++++-------- server/routes/alert.route.js | 2 +- server/routes/api.route.js | 2 +- server/routes/captain.route.js | 6 +- server/routes/scout.route.js | 14 +- 8 files changed, 309 insertions(+), 236 deletions(-) diff --git a/server/controllers/alert.controller.js b/server/controllers/alert.controller.js index 55df91db..28b4393a 100644 --- a/server/controllers/alert.controller.js +++ b/server/controllers/alert.controller.js @@ -1,69 +1,83 @@ -import db from "../database/db.js"; +import db from '../database/db.js' const alertController = { - getAlert: async (req, res) => { - console.log(req.params); - const { id } = req.params; //string - - const alert = await db.query( - `SELECT * FROM "Notification" WHERE "NotificationId" = ${Number(id)};` - ); - - if (!alert) return res.status(404).json({ error: "Alert not found" }); - - res - .status(200) - .json({ success: true, message: "Alert successfully found", alert }); - }, - - CreateAlert: async (req, res) => { - console.log(req.body); - const { title, message, type } = req.body; - if (!title || !message || !type) - return res.status(400).json({ error: "Missing input" }); - - const newAlert = await db.query( - `INSERT INTO "Notification" ( "message" ) - VALUES( '${message}' ) RETURNING *;` - ); - - if (!newAlert) return res.status(400).json({ error: "Cannot Post" }); - - res.status(200).json({ success: true, newAlert }); - }, - - DeleteAlert: async (req, res) => { - console.log(req.params); - const { id } = req.params; - - const Alerts = await db.query(`SELECT * FROM "Notification";`); - - const alertsArr = Alerts.rows; - - if (!alertsArr.find((item) => item.NotificationId === Number(id))) - return res.status(404).json({ error: "Alert to be deleted not found" }); - - try { - await db.query( - `DELETE FROM "Notification" WHERE "NotificationId" = ${Number(id)};` - ); - - alertsArr.filter((item) => item.NotificationId !== Number(id)); - return res.status(200).json({ success: true }); - } catch (error) { - console.error(error); - res.status(400).json({ success: false }); - } - }, - - getAllAlerts: async (req, res) => { - const Alerts = await db.query(`SELECT * FROM "Notification";`); - - if (!Alerts.rows.length) - return res.status(400).json({ error: "No alerts found" }); - - res.status(200).json({ status: true, data: Alerts.rows }); - }, -}; - -export default alertController; + getAlert: async (req, res) => { + const { id } = req.params + + const alert = await db.query( + `SELECT * FROM "Notification" WHERE "NotificationId" = $1;`, + [id] + ) + + if (!alert) return res.status(404).json({ error: 'Alert not found' }) + + res.status(200).json({ + message: 'Alert successfully found', + body: alert, + }) + }, + + CreateAlert: async (req, res) => { + const { title, message, type } = req.body + if (!title || !message || !type) + return res.status(400).json({ error: 'Missing input' }) + + const newAlert = await db.query( + `INSERT INTO "Notification" ("message") + VALUES($1) RETURNING *;`, + [message] + ) + + if (!newAlert) return res.status(400).json({ error: 'Cannot Post' }) + + res.status(200).json({ + message: 'Alert successfully created', + body: newAlert, + }) + }, + + DeleteAlert: async (req, res) => { + const { id } = req.params + + const Alerts = await db.query(`SELECT * FROM "Notification";`) + + const alertsArr = Alerts.rows + + if (!alertsArr.find((item) => item.NotificationId === Number(id))) + return res + .status(404) + .json({ error: 'Alert to be deleted not found' }) + + try { + await db.query( + `DELETE FROM "Notification" WHERE "NotificationId" = $1;`, + [id] + ) + + alertsArr.filter((item) => item.NotificationId !== Number(id)) + return res.status(200).json({ + message: 'Alert successfully deleted', + body: alertsArr, + }) + } catch (error) { + console.error(error) + res.status(400).json({ + error: 'An error occured while deleting alert', + }) + } + }, + + getAllAlerts: async (req, res) => { + const Alerts = await db.query(`SELECT * FROM "Notification";`) + + if (!Alerts.rows.length) + return res.status(400).json({ error: 'No alerts found' }) + + res.status(200).json({ + message: 'get Alerts successfully', + body: Alerts.rows, + }) + }, +} + +export default alertController diff --git a/server/controllers/auth.controller.js b/server/controllers/auth.controller.js index f545f7d2..a1c2c0f5 100644 --- a/server/controllers/auth.controller.js +++ b/server/controllers/auth.controller.js @@ -139,7 +139,7 @@ const authController = { // @access Private me: (req, res) => { try { - res.status(200).json({ user: req.captain }) + res.status(200).json({ message: 'You are in', body: req.captain }) } catch (error) { console.log(error) res.status(500).json({ @@ -149,4 +149,4 @@ const authController = { }, } -export default authController \ No newline at end of file +export default authController diff --git a/server/controllers/captain.controller.js b/server/controllers/captain.controller.js index b8863f33..e7618a3b 100644 --- a/server/controllers/captain.controller.js +++ b/server/controllers/captain.controller.js @@ -14,11 +14,11 @@ const captainController = { message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ - error: 'An error occured while retrieving the captains info' + error: 'An error occured while retrieving the captains info', + body: error, }) } }, @@ -28,188 +28,180 @@ const captainController = { const result = await db.query(` SELECT COUNT(*) FROM "Captain" - `); + `) // Respond with the data retrieved and a successful retrieval message res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ - error: 'An error occured while retrieving the captains count' + error: 'An error occured while retrieving the captains count', + body: error, }) } }, captainsInSectorInfo: async (req, res) => { try { // Extract sector base name and suffix name from the request body - const { sectorBaseName, sectorSuffixName } = req.body; + const { rSectorBaseName, rSectorSuffixName } = req.body // Query on the database to get all the captains info in a specific sector - const result = await db.query(` + const result = await db.query( + ` SELECT * FROM "Captain" WHERE "rSectorBaseName" = $1 AND "rSectorSuffixName" = $2`, - [sectorBaseName, sectorSuffixName] - ); - - // If the query returned nothing, return a message that says that - if (!result.rows.length) { - return res.status(200).json({ - message: "Count of rows returned is 0", - }); - } + [rSectorBaseName, rSectorSuffixName] + ) res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, captainsInSectorCount: async (req, res) => { try { // Extract sector base name and suffix name from the request body - const { sectorBaseName, sectorSuffixName } = req.body; + const { rSectorBaseName, rSectorSuffixName } = req.body // Query on the database to get all the captains count in a specific sector - const result = await db.query(` + const result = await db.query( + ` SELECT COUNT(*) FROM "Captain" WHERE "rSectorBaseName" = $1 AND "rSectorSuffixName" = $2`, - [sectorBaseName, sectorSuffixName] - ); + [rSectorBaseName, rSectorSuffixName] + ) res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, captainInfo: async (req, res) => { try { - // Extract the captain ID from the request body - const { captainId } = req.body; + // Extract the captain ID from the request params + const { captainId } = req.params // Query on the database to get that captain info - const result = await db.query(` + const result = await db.query( + ` SELECT * FROM "Captain" WHERE "captainId" = $1`, - [captainId] - ); + [captainId] + ) // If captain doesn't exist return an error message if (!result.rows.length) { return res.status(404).json({ - error: "Captain not found!" + error: 'Captain not found!', }) } // Return the data of the captain res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, allCaptainsInUnitInfo: async (req, res) => { try { - const { unitCaptainId } = req.body; + const { unitCaptainId } = req.params // Make sure that the id is provided (not undefined) - if (!unitCaptainId){ + if (!unitCaptainId) { return res.status(404).json({ - error: "Enter a valid unit captain id" + error: 'Enter a valid unit captain id', }) } // Query to get the id - const result = await db.query(` + const result = await db.query( + ` SELECT C.* FROM "Captain" AS C, "Sector" AS S WHERE S."unitCaptainId" = $1 AND C."rSectorBaseName" = S."baseName" AND C."rSectorSuffixName" = S."suffixName";`, - [unitCaptainId] + [unitCaptainId] ) // If there is no result found, return 404 not found error (This might not be an error) - if (!result.rows.length) - { + if (!result.rows.length) { return res.status(404).json({ - error: "Captains Not Found" + error: 'Captains Not Found', }) } // Return the data res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, - }); - + }) } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, allCaptainsInUnitCount: async (req, res) => { try { - const { unitCaptainId } = req.body; + const { unitCaptainId } = req.params // Make sure that the id is provided (not undefined) - if (!unitCaptainId){ + if (!unitCaptainId) { return res.status(404).json({ - error: "Enter a valid unit captain id" + error: 'Enter a valid unit captain id', }) } // Query to get the id - const result = await db.query(` + const result = await db.query( + ` SELECT COUNT(*) FROM "Captain" AS C, "Sector" AS S WHERE S."unitCaptainId" = $1 AND C."rSectorBaseName" = S."baseName" AND C."rSectorSuffixName" = S."suffixName";`, - [unitCaptainId] + [unitCaptainId] ) // Return the data res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, - }); - + }) } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } - } + }, } -export default captainController \ No newline at end of file +export default captainController diff --git a/server/controllers/scout.controller.js b/server/controllers/scout.controller.js index 10aa5eed..8818dff1 100644 --- a/server/controllers/scout.controller.js +++ b/server/controllers/scout.controller.js @@ -9,15 +9,14 @@ const scoutController = { `) res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, @@ -29,302 +28,370 @@ const scoutController = { `) res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, scoutsInSectorInfo: async (req, res) => { try { - const { sectorBaseName, sectorSuffixName } = req.body; + const { sectorBaseName, sectorSuffixName } = req.body - if (sectorBaseName === undefined && sectorSuffixName === undefined) { + if ( + sectorBaseName === undefined && + sectorSuffixName === undefined + ) { return res.status(400).json({ - error: "Please enter the sector base name and/or suffix name" + error: 'Please enter the sector base name and/or suffix name', }) } - const result = await db.query(` + const result = await db.query( + ` SELECT * FROM "Scout" WHERE "sectorBaseName" = $1 AND "sectorSuffixName" = $2 `, - [sectorBaseName, sectorSuffixName]) + [sectorBaseName, sectorSuffixName] + ) if (!result.rows.length) { return res.status(404).json({ - error: "No scouts found in this sector" + error: 'No scouts found in this sector', }) } res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, scoutsInSectorCount: async (req, res) => { try { - const { sectorBaseName, sectorSuffixName } = req.body; + const { sectorBaseName, sectorSuffixName } = req.body - if (sectorBaseName === undefined && sectorSuffixName === undefined) { + if ( + sectorBaseName === undefined && + sectorSuffixName === undefined + ) { return res.status(400).json({ - error: "Please enter the sector base name and/or suffix name" + error: 'Please enter the sector base name and/or suffix name', }) } - const result = await db.query(` + const result = await db.query( + ` SELECT COUNT(*) FROM "Scout" WHERE "sectorBaseName" = $1 AND "sectorSuffixName" = $2 `, - [sectorBaseName, sectorSuffixName]) + [sectorBaseName, sectorSuffixName] + ) res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, allScoutsInUnitInfo: async (req, res) => { try { - const { unitCaptainId } = req.body; + const { unitCaptainId } = req.params // Make sure that the id is provided (not undefined) - if (!unitCaptainId){ + if (!unitCaptainId) { return res.status(404).json({ - error: "Enter a valid unit captain id" + error: 'Enter a valid unit captain id', }) } - const result = await db.query(` + const result = await db.query( + ` SELECT scout.* FROM "Scout" AS scout, "Sector" AS sector WHERE sector."unitCaptainId" = $1 AND scout."sectorBaseName" = sector."baseName" AND scout."sectorSuffixName" = sector."suffixName"; `, - [unitCaptainId]) + [unitCaptainId] + ) if (!result.rows.length) { return res.status(404).json({ - error: "No scouts found in this unit" + error: 'No scouts found in this unit', }) } res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, allScoutsInUnitCount: async (req, res) => { try { - const { unitCaptainId } = req.body; + const { unitCaptainId } = req.params // Make sure that the id is provided (not undefined) - if (!unitCaptainId){ + if (!unitCaptainId) { return res.status(404).json({ - error: "Enter a valid unit captain id" + error: 'Enter a valid unit captain id', }) } - const result = await db.query(` + const result = await db.query( + ` SELECT Count(*) FROM "Scout" AS scout, "Sector" AS sector WHERE sector."unitCaptainId" = $1 AND scout."sectorBaseName" = sector."baseName" AND scout."sectorSuffixName" = sector."suffixName"; `, - [unitCaptainId]) + [unitCaptainId] + ) if (!result.rows.length) { return res.status(404).json({ - error: "No scouts found in this unit" + error: 'No scouts found in this unit', }) } res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, certainScoutInfo: async (req, res) => { try { - const { scoutId } = req.body; + const { scoutId } = req.params // Make sure that the id is provided (not undefined) - if (!scoutId){ + if (!scoutId) { return res.status(404).json({ - error: "Enter a valid scout id" + error: 'Enter a valid scout id', }) } - const result = await db.query(` + const result = await db.query( + ` SELECT * FROM "Scout" WHERE "scoutId" = $1; `, - [scoutId]) + [scoutId] + ) if (!result.rows.length) { return res.status(404).json({ - error: "No scout found" + error: 'No scout found', }) } res.status(200).json({ - message: "Successful retrieval", + message: 'Successful retrieval', body: result, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while retrieving data', - error + body: error, }) } }, updateScout: async (req, res) => { try { // Destructuring the req.body to get the required info to update a scout - const { scoutId, firstName, middleName, lastName, gender, sectorBaseName, - sectorSuffixName, birthDate, enrollDate, schoolGrade, photo, birthCertificate } = req.body; - + const { scoutId } = req.params + const { + firstName, + middleName, + lastName, + gender, + sectorBaseName, + sectorSuffixName, + birthDate, + enrollDate, + schoolGrade, + photo, + birthCertificate, + } = req.body + // If no scout id is provided give an error if (!scoutId) { return res.status(400).json({ - error: "Please enter a valid scout id" + error: 'Please enter a valid scout id', }) } // Update the scout data - const result1 = await db.query(` + const result1 = await db.query( + ` UPDATE "Scout" SET "firstName" = $1, "middleName" = $2, "lastName" = $3, "gender" = $4, "sectorBaseName" = $5, "sectorSuffixName" = $6 WHERE "scoutId" = $7 RETURNING * `, - [firstName, middleName, lastName, gender, sectorBaseName, sectorSuffixName, scoutId]) + [ + firstName, + middleName, + lastName, + gender, + sectorBaseName, + sectorSuffixName, + scoutId, + ] + ) // If no rows are effected respond with an error status and message if (result1.rowCount == 0) { return res.status(404).json({ - error: "No rows updated for the scout", - body: result1 + error: 'No rows updated for the scout', + body: result1, }) } // Update the scout profile data - const result2 = await db.query(` + const result2 = await db.query( + ` UPDATE "ScoutProfile" SET "birthDate" = $1, "enrollDate" = $2, "schoolGrade" = $3, "photo" = $4, "birthCertificate" = $5 WHERE "scoutId" = $6 RETURNING * `, - [birthDate, enrollDate, schoolGrade, photo, birthCertificate, scoutId]) + [ + birthDate, + enrollDate, + schoolGrade, + photo, + birthCertificate, + scoutId, + ] + ) // Respond with the updated data res.status(200).json({ - message: "Successful update", - body: { result1, result2 } + message: 'Successful update', + body: { result1, result2 }, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while updating the scout', - error + body: error, }) } }, insertScout: async (req, res) => { try { // Destructuring the req.body to get the required info to update a scout - const { firstName, middleName, lastName, gender, sectorBaseName, - sectorSuffixName, birthDate, enrollDate, schoolGrade, photo, birthCertificate } = req.body; + const { + firstName, + middleName, + lastName, + gender, + sectorBaseName, + sectorSuffixName, + birthDate, + enrollDate, + schoolGrade, + photo, + birthCertificate, + } = req.body // Insert a new scout into the database - const result1 = await db.query(` + const result1 = await db.query( + ` INSERT INTO "Scout" ("firstName", "middleName", "lastName", "gender", "sectorBaseName", "sectorSuffixName") VALUES ($1, $2, $3, $4, $5, $6) RETURNING *; `, - [firstName, middleName, lastName, gender, sectorBaseName, sectorSuffixName]) + [ + firstName, + middleName, + lastName, + gender, + sectorBaseName, + sectorSuffixName, + ] + ) // If nothing was inserted return an error if (result1.rowCount == 0) { return res.status(400).json({ - error: "No data was inserted for the scout", - body: result1 + error: 'No data was inserted for the scout', + body: result1, }) } // Insert the scout profile - const result2 = await db.query(` + const result2 = await db.query( + ` INSERT INTO "ScoutProfile" ("birthDate", "enrollDate", "schoolGrade", "photo", "birthCertificate", "scoutId") VALUES ($1, $2, $3, $4, $5, $6) RETURNING *; `, - [birthDate, enrollDate, schoolGrade, photo, birthCertificate, result1.rows[0]["scoutId"]]) + [ + birthDate, + enrollDate, + schoolGrade, + photo, + birthCertificate, + result1.rows[0]['scoutId'], + ] + ) // If nothing was inserted return an error if (result2.rowCount == 0) { return res.status(400).json({ - error: "No data was inserted for the scout profile", - body: result2 + error: 'No data was inserted for the scout profile', + body: result2, }) } // Return the data res.status(200).json({ - message: "Successful insertion", - body: { result1, result2 } + message: 'Successful insertion', + body: { result1, result2 }, }) - } catch (error) { - console.log(error); + console.log(error) res.status(500).json({ message: 'An error occured while inserting a new scout', - error + body: error, }) } - } + }, } -export default scoutController; \ No newline at end of file +export default scoutController diff --git a/server/routes/alert.route.js b/server/routes/alert.route.js index a26b4969..ac001482 100644 --- a/server/routes/alert.route.js +++ b/server/routes/alert.route.js @@ -4,8 +4,8 @@ import alertController from "../controllers/alert.controller.js" const alertRouter = Router(); alertRouter.get("/", alertController.getAllAlerts); +alertRouter.post("/", alertController.CreateAlert); alertRouter.get("/:id", alertController.getAlert); -alertRouter.post("/post", alertController.CreateAlert); alertRouter.delete("/:id", alertController.DeleteAlert); export default alertRouter; diff --git a/server/routes/api.route.js b/server/routes/api.route.js index 79e84b5f..d42aab0a 100644 --- a/server/routes/api.route.js +++ b/server/routes/api.route.js @@ -14,7 +14,7 @@ apiRouter.use('/stats', authMiddleware, statsRouter) apiRouter.use('/finance', authMiddleware, financeRouter) apiRouter.use('/term', authMiddleware, termRouter) apiRouter.use('/captain', authMiddleware, captainRouter) -apiRouter.use('/notifications', alertRouter) +apiRouter.use('/alert', alertRouter) apiRouter.use('/scout', authMiddleware, scoutRouter) export default apiRouter diff --git a/server/routes/captain.route.js b/server/routes/captain.route.js index 202b44b4..b5f14ebf 100644 --- a/server/routes/captain.route.js +++ b/server/routes/captain.route.js @@ -5,13 +5,13 @@ import captainController from "../controllers/captain.controller.js"; const captainRouter = Router(); +captainRouter.get('/:id', captainController.captainInfo) captainRouter.get('/allCaptains/info', captainController.allCaptainsInfo) captainRouter.get('/allCaptains/count', captainController.allCaptainsCount) captainRouter.get('/captainsInSector/info', captainController.captainsInSectorInfo) captainRouter.get('/captainsInSector/count', captainController.captainsInSectorCount) -captainRouter.get('/ceratinCaptain/info', captainController.captainInfo) -captainRouter.get('/allCaptainsInUnit/info', captainController.allCaptainsInUnitInfo) -captainRouter.get('/allCaptainsInUnit/count', captainController.allCaptainsInUnitCount) +captainRouter.get('/allCaptainsInUnit/info/:id', captainController.allCaptainsInUnitInfo) +captainRouter.get('/allCaptainsInUnit/count/:id', captainController.allCaptainsInUnitCount) export default captainRouter \ No newline at end of file diff --git a/server/routes/scout.route.js b/server/routes/scout.route.js index 3985e813..2c9788c1 100644 --- a/server/routes/scout.route.js +++ b/server/routes/scout.route.js @@ -4,14 +4,14 @@ import scoutController from "../controllers/scout.controller.js"; const scoutRouter = Router(); +scoutRouter.post('/', scoutController.insertScout) +scoutRouter.get('/:id', scoutController.certainScoutInfo) +scoutRouter.put('/:id', scoutController.updateScout) scoutRouter.get('/allScouts/count', scoutController.allScoutsCount) scoutRouter.get('/allScouts/info', scoutController.allScoutsInfo) -scoutRouter.get('/scoutsInSector/count', scoutController.scoutsInSectorCount) -scoutRouter.get('/scoutsInSector/info', scoutController.scoutsInSectorInfo) -scoutRouter.get('/allScoutsInUnit/count', scoutController.allScoutsInUnitCount) -scoutRouter.get('/allScoutsInUnit/info', scoutController.allScoutsInUnitInfo) -scoutRouter.get('/certainScout/info', scoutController.certainScoutInfo) -scoutRouter.put('/updateScout', scoutController.updateScout) -scoutRouter.post('/insertScout', scoutController.insertScout) +scoutRouter.get('/allScoutsInSector/count', scoutController.scoutsInSectorCount) +scoutRouter.get('/allScoutsInSector/info', scoutController.scoutsInSectorInfo) +scoutRouter.get('/allScoutsInUnit/count/:id', scoutController.allScoutsInUnitCount) +scoutRouter.get('/allScoutsInUnit/info/:id', scoutController.allScoutsInUnitInfo) export default scoutRouter \ No newline at end of file From f36c97ec9600a4452ae750b5b97e2dd6a876cd9c Mon Sep 17 00:00:00 2001 From: AhmedHamed3699 Date: Sun, 24 Dec 2023 23:03:29 +0200 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=97=83=EF=B8=8F=20chore:=20edited=20d?= =?UTF-8?q?atabase=20scripts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/database/fillDatabase.sql | 23 - server/database/scripts/createDatabase.psql | 1153 ------------------- server/database/scripts/fillDatabase.psql | 154 +-- 3 files changed, 3 insertions(+), 1327 deletions(-) delete mode 100644 server/database/fillDatabase.sql delete mode 100644 server/database/scripts/createDatabase.psql diff --git a/server/database/fillDatabase.sql b/server/database/fillDatabase.sql deleted file mode 100644 index 1609b71f..00000000 --- a/server/database/fillDatabase.sql +++ /dev/null @@ -1,23 +0,0 @@ --- ADD CAPTAINS -INSERT INTO - "Captain"( - "firstName", - "middleName", - "lastName", - "phoneNumber", - "email", - "password", - "gender", - "type" - ) -VALUES - ( - "أمير", - "أنور", - "بخيت", - "01221461992", - "amir.kedis@gmail.com", - "$2a$10$82orQ3yruIoakCWUg/29KuXBwJlZiezJzxUW.8Ek.Jvc/MPLagDYS", - "male", - "general" - ) RETURNING *; \ No newline at end of file diff --git a/server/database/scripts/createDatabase.psql b/server/database/scripts/createDatabase.psql deleted file mode 100644 index 1096d3c6..00000000 --- a/server/database/scripts/createDatabase.psql +++ /dev/null @@ -1,1153 +0,0 @@ --- --- PostgreSQL database dump --- - --- Dumped from database version 16.1 (Ubuntu 16.1-1.pgdg22.04+1) --- Dumped by pg_dump version 16.1 (Ubuntu 16.1-1.pgdg22.04+1) - -SET statement_timeout = 0; -SET lock_timeout = 0; -SET idle_in_transaction_session_timeout = 0; -SET client_encoding = 'UTF8'; -SET standard_conforming_strings = on; -SELECT pg_catalog.set_config('search_path', '', false); -SET check_function_bodies = false; -SET xmloption = content; -SET client_min_messages = warning; -SET row_security = off; - -DROP DATABASE IF EXISTS scoutsManagementSystem; --- --- Name: scoutsManagementSystem; Type: DATABASE; Schema: -; Owner: - --- - -CREATE DATABASE scoutsManagementSystem WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE_PROVIDER = libc LOCALE = 'C'; - - -\connect scoutsManagementSystem - -SET statement_timeout = 0; -SET lock_timeout = 0; -SET idle_in_transaction_session_timeout = 0; -SET client_encoding = 'UTF8'; -SET standard_conforming_strings = on; -SELECT pg_catalog.set_config('search_path', '', false); -SET check_function_bodies = false; -SET xmloption = content; -SET client_min_messages = warning; -SET row_security = off; - --- --- Name: ActivityType; Type: TYPE; Schema: public; Owner: - --- - -CREATE TYPE public."ActivityType" AS ENUM ( - 'entertainment', - 'rowing', - 'camping', - 'wildCooking', - 'scouting', - 'volunteering', - 'other' -); - - --- --- Name: AspectCategory; Type: TYPE; Schema: public; Owner: - --- - -CREATE TYPE public."AspectCategory" AS ENUM ( - 'scoutingSkills', - 'behaviour', - 'participation', - 'exams', - 'other' -); - - --- --- Name: AttendanceStatus; Type: TYPE; Schema: public; Owner: - --- - -CREATE TYPE public."AttendanceStatus" AS ENUM ( - 'absent', - 'execused', - 'termExecused', - 'attended' -); - - --- --- Name: CaptainType; Type: TYPE; Schema: public; Owner: - --- - -CREATE TYPE public."CaptainType" AS ENUM ( - 'general', - 'unit', - 'regular' -); - - --- --- Name: Days; Type: TYPE; Schema: public; Owner: - --- - -CREATE TYPE public."Days" AS ENUM ( - 'sat', - 'sun', - 'mon', - 'tue', - 'wed', - 'thu', - 'fri' -); - - --- --- Name: FinanceItemType; Type: TYPE; Schema: public; Owner: - --- - -CREATE TYPE public."FinanceItemType" AS ENUM ( - 'income', - 'expense' -); - - --- --- Name: Gender; Type: TYPE; Schema: public; Owner: - --- - -CREATE TYPE public."Gender" AS ENUM ( - 'male', - 'female' -); - - --- --- Name: NotificationType; Type: TYPE; Schema: public; Owner: - --- - -CREATE TYPE public."NotificationType" AS ENUM ( - 'attendance', - 'report', - 'financeItemCreated', - 'other' -); - - --- --- Name: Activity; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Activity" ( - "activityId" integer NOT NULL, - place character varying(255), - "weekNumber" integer NOT NULL, - "termNumber" integer NOT NULL, - day public."Days" NOT NULL, - type public."ActivityType" NOT NULL -); - - --- --- Name: ActivityAttendance; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."ActivityAttendance" ( - "scoutId" integer NOT NULL, - "activityId" integer NOT NULL, - score integer, - "attendanceStatus" public."AttendanceStatus" NOT NULL -); - - --- --- Name: ActivityGuidance; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."ActivityGuidance" ( - "activityId" integer NOT NULL, - "captainId" integer NOT NULL -); - - --- --- Name: ActivitySectorParticipation; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."ActivitySectorParticipation" ( - "activityId" integer NOT NULL, - "sectorBaseName" character varying NOT NULL, - "sectorSuffixName" character varying NOT NULL -); - - --- --- Name: Activity_activityId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Activity_activityId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Activity_activityId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Activity_activityId_seq" OWNED BY public."Activity"."activityId"; - - --- --- Name: Aspect; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Aspect" ( - "aspectId" integer NOT NULL, - name character varying(255) NOT NULL, - "sectorBaseName" character varying(255) NOT NULL, - "sectorSuffixName" character varying(255) NOT NULL, - category public."AspectCategory" NOT NULL -); - - --- --- Name: Aspect_aspectId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Aspect_aspectId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Aspect_aspectId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Aspect_aspectId_seq" OWNED BY public."Aspect"."aspectId"; - - --- --- Name: Captain; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Captain" ( - "captainId" integer NOT NULL, - "firstName" character varying(255) NOT NULL, - "middleName" character varying(255) NOT NULL, - "lastName" character varying(255) NOT NULL, - "phoneNumber" character varying(255) NOT NULL, - "email" character varying(255) NOT NULL, - "password" character varying(255) NOT NULL, - "rSectorBaseName" character varying(255), - "rSectorSuffixName" character varying(255), - gender public."Gender" NOT NULL, - type public."CaptainType" NOT NULL -); - - --- --- Name: CaptainAttendance; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."CaptainAttendance" ( - "captainId" integer NOT NULL, - "weekNumber" integer NOT NULL, - "termNumber" integer NOT NULL, - "attendanceStatus" public."AttendanceStatus" NOT NULL -); - - --- --- Name: Captain_captainId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Captain_captainId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Captain_captainId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Captain_captainId_seq" OWNED BY public."Captain"."captainId"; - - --- --- Name: FinanceItem; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."FinanceItem" ( - "itemId" integer NOT NULL, - value double precision NOT NULL, - "timestamp" timestamp(0) without time zone NOT NULL, - type public."FinanceItemType" NOT NULL -); - - --- --- Name: FinanceItem_itemId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."FinanceItem_itemId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: FinanceItem_itemId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."FinanceItem_itemId_seq" OWNED BY public."FinanceItem"."itemId"; - - --- --- Name: Notification; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Notification" ( - "NotificationId" integer NOT NULL, - "timestamp" timestamp(0) without time zone NOT NULL, - message character varying(255) NOT NULL, - "contentType" public."NotificationType" NOT NULL -); - - --- --- Name: Notification_NotificationId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Notification_NotificationId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Notification_NotificationId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Notification_NotificationId_seq" OWNED BY public."Notification"."NotificationId"; - - --- --- Name: OtherItem; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."OtherItem" ( - description text NOT NULL, - "itemId" bigint NOT NULL, - "generalCaptainId" integer -); - - --- --- Name: RecieveNotification; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."RecieveNotification" ( - "notificationId" integer NOT NULL, - "captainId" integer NOT NULL -); - - --- --- Name: Report; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Report" ( - "reportId" integer NOT NULL, - info text NOT NULL, - date date NOT NULL, - "captainId" integer, - "scoutId" integer NOT NULL -); - - --- --- Name: Report_captainId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Report_captainId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Report_captainId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Report_captainId_seq" OWNED BY public."Report"."captainId"; - - --- --- Name: Report_reportId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Report_reportId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Report_reportId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Report_reportId_seq" OWNED BY public."Report"."reportId"; - - --- --- Name: Scout; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Scout" ( - "scoutId" integer NOT NULL, - "firstName" character varying(255) NOT NULL, - "middleName" character varying(255) NOT NULL, - "lastName" character varying(255), - expelled boolean DEFAULT false NOT NULL, - "sectorBaseName" character varying(255), - "sectorSuffixName" character varying(255), - gender public."Gender" -); - - --- --- Name: ScoutAttendance; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."ScoutAttendance" ( - "scoutId" integer NOT NULL, - "weekNumber" integer NOT NULL, - "termNumber" integer NOT NULL, - "attendanceStatus" public."AttendanceStatus" NOT NULL -); - - --- --- Name: ScoutProfile; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."ScoutProfile" ( - "birthCertificate" character varying(255), - "birthDate" date, - "enrollDate" date, - photo character varying(255), - "scoutId" integer NOT NULL, - "schoolGrade" integer -); - - --- --- Name: ScoutScore; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."ScoutScore" ( - "scoutId" integer NOT NULL, - "aspectId" integer NOT NULL, - score integer NOT NULL, - "timestamp" timestamp without time zone NOT NULL -); - - --- --- Name: Scout_scoutId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Scout_scoutId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Scout_scoutId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Scout_scoutId_seq" OWNED BY public."Scout"."scoutId"; - - --- --- Name: Sector; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Sector" ( - "baseName" character varying(255) NOT NULL, - "suffixName" character varying(255) NOT NULL, - "unitCaptainId" integer -); - - --- --- Name: Session; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Session" ( - "sessionId" integer NOT NULL, - title character varying(255) NOT NULL, - "documentURL" character varying(255), - "captainId" integer, - "weekNumber" integer NOT NULL, - "termNumber" integer NOT NULL -); - - --- --- Name: SessionSectorParticipation; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."SessionSectorParticipation" ( - "sessionID" integer NOT NULL, - "sectorBaseName" character varying NOT NULL, - "sectorSuffixName" character varying NOT NULL -); - - --- --- Name: Session_sessionId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Session_sessionId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Session_sessionId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Session_sessionId_seq" OWNED BY public."Session"."sessionId"; - - --- --- Name: Subscription; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Subscription" ( - "itemId" integer NOT NULL, - "sectorBaseName" character varying(255), - "sectorSuffixName" character varying(255), - "weekNumber" integer NOT NULL, - "termNumber" integer NOT NULL -); - - --- --- Name: Subscription_itemId_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Subscription_itemId_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Subscription_itemId_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Subscription_itemId_seq" OWNED BY public."Subscription"."itemId"; - - --- --- Name: Term; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Term" ( - "termNumber" integer NOT NULL, - "termName" character varying(255), - "startDate" date NOT NULL, - "endDate" date NOT NULL -); - - --- --- Name: Term_termNumber_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."Term_termNumber_seq" - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: Term_termNumber_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."Term_termNumber_seq" OWNED BY public."Term"."termNumber"; - - --- --- Name: Week; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public."Week" ( - "weekNumber" integer NOT NULL, - cancelled boolean DEFAULT false NOT NULL, - "startDate" date NOT NULL, - "termNumber" integer NOT NULL -); - - --- --- Name: Activity activityId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Activity" ALTER COLUMN "activityId" SET DEFAULT nextval('public."Activity_activityId_seq"'::regclass); - - --- --- Name: Aspect aspectId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Aspect" ALTER COLUMN "aspectId" SET DEFAULT nextval('public."Aspect_aspectId_seq"'::regclass); - - --- --- Name: Captain captainId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Captain" ALTER COLUMN "captainId" SET DEFAULT nextval('public."Captain_captainId_seq"'::regclass); - - --- --- Name: FinanceItem itemId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."FinanceItem" ALTER COLUMN "itemId" SET DEFAULT nextval('public."FinanceItem_itemId_seq"'::regclass); - - --- --- Name: Notification NotificationId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Notification" ALTER COLUMN "NotificationId" SET DEFAULT nextval('public."Notification_NotificationId_seq"'::regclass); - - --- --- Name: Report reportId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Report" ALTER COLUMN "reportId" SET DEFAULT nextval('public."Report_reportId_seq"'::regclass); - - --- --- Name: Report captainId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Report" ALTER COLUMN "captainId" SET DEFAULT nextval('public."Report_captainId_seq"'::regclass); - - --- --- Name: Scout scoutId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Scout" ALTER COLUMN "scoutId" SET DEFAULT nextval('public."Scout_scoutId_seq"'::regclass); - - --- --- Name: Session sessionId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Session" ALTER COLUMN "sessionId" SET DEFAULT nextval('public."Session_sessionId_seq"'::regclass); - - --- --- Name: Subscription itemId; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Subscription" ALTER COLUMN "itemId" SET DEFAULT nextval('public."Subscription_itemId_seq"'::regclass); - - --- --- Name: Term termNumber; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Term" ALTER COLUMN "termNumber" SET DEFAULT nextval('public."Term_termNumber_seq"'::regclass); - - --- --- Name: ActivityAttendance ActivityAttendance_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivityAttendance" - ADD CONSTRAINT "ActivityAttendance_pkey" PRIMARY KEY ("scoutId", "activityId"); - - --- --- Name: ActivityGuidance ActivityGuidance_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivityGuidance" - ADD CONSTRAINT "ActivityGuidance_pkey" PRIMARY KEY ("activityId", "captainId"); - - --- --- Name: ActivitySectorParticipation ActivitySectorParticipation_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivitySectorParticipation" - ADD CONSTRAINT "ActivitySectorParticipation_pkey" PRIMARY KEY ("activityId", "sectorBaseName", "sectorSuffixName"); - - --- --- Name: Activity Activity_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Activity" - ADD CONSTRAINT "Activity_pkey" PRIMARY KEY ("activityId"); - - --- --- Name: Aspect Aspect_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Aspect" - ADD CONSTRAINT "Aspect_pkey" PRIMARY KEY ("aspectId"); - - --- --- Name: CaptainAttendance CaptainAttendance_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."CaptainAttendance" - ADD CONSTRAINT "CaptainAttendance_pkey" PRIMARY KEY ("captainId", "weekNumber", "termNumber"); - - --- --- Name: Captain Captain_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Captain" - ADD CONSTRAINT "Captain_pkey" PRIMARY KEY ("captainId"); - - --- --- Name: FinanceItem FinanceItem_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."FinanceItem" - ADD CONSTRAINT "FinanceItem_pkey" PRIMARY KEY ("itemId"); - - --- --- Name: Notification Notification_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Notification" - ADD CONSTRAINT "Notification_pkey" PRIMARY KEY ("NotificationId"); - - --- --- Name: OtherItem OtherItem_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."OtherItem" - ADD CONSTRAINT "OtherItem_pkey" PRIMARY KEY ("itemId"); - - --- --- Name: RecieveNotification RecieveNotification_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."RecieveNotification" - ADD CONSTRAINT "RecieveNotification_pkey" PRIMARY KEY ("notificationId", "captainId"); - - --- --- Name: Report Report_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Report" - ADD CONSTRAINT "Report_pkey" PRIMARY KEY ("reportId"); - - --- --- Name: ScoutAttendance ScoutAttendance_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ScoutAttendance" - ADD CONSTRAINT "ScoutAttendance_pkey" PRIMARY KEY ("scoutId", "weekNumber", "termNumber"); - - --- --- Name: ScoutScore ScoutScore_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ScoutScore" - ADD CONSTRAINT "ScoutScore_pkey" PRIMARY KEY ("scoutId", "aspectId"); - - --- --- Name: Scout Scout_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Scout" - ADD CONSTRAINT "Scout_pkey" PRIMARY KEY ("scoutId"); - - --- --- Name: Sector Sector_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Sector" - ADD CONSTRAINT "Sector_pkey" PRIMARY KEY ("baseName", "suffixName"); - - --- --- Name: SessionSectorParticipation SessionSectorParticipation_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."SessionSectorParticipation" - ADD CONSTRAINT "SessionSectorParticipation_pkey" PRIMARY KEY ("sessionID", "sectorBaseName", "sectorSuffixName"); - - --- --- Name: Session Session_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Session" - ADD CONSTRAINT "Session_pkey" PRIMARY KEY ("sessionId"); - - --- --- Name: Subscription Subscription_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Subscription" - ADD CONSTRAINT "Subscription_pkey" PRIMARY KEY ("itemId"); - - --- --- Name: Term Term_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Term" - ADD CONSTRAINT "Term_pkey" PRIMARY KEY ("termNumber"); - - --- --- Name: Week Week_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Week" - ADD CONSTRAINT "Week_pkey" PRIMARY KEY ("weekNumber", "termNumber"); - - --- --- Name: Captain captain_email_unique; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Captain" - ADD CONSTRAINT captain_email_unique UNIQUE (email); - - --- --- Name: Captain captain_phonenumber_unique; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Captain" - ADD CONSTRAINT captain_phonenumber_unique UNIQUE ("phoneNumber"); - - --- --- Name: SessionSectorParticipation SessionParticipation_Sector_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."SessionSectorParticipation" - ADD CONSTRAINT "SessionParticipation_Sector_FK" FOREIGN KEY ("sectorBaseName", "sectorSuffixName") REFERENCES public."Sector"("baseName", "suffixName") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: SessionSectorParticipation SessionParticipation_Session_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."SessionSectorParticipation" - ADD CONSTRAINT "SessionParticipation_Session_FK" FOREIGN KEY ("sessionID") REFERENCES public."Session"("sessionId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ActivityAttendance activityAttendance_activity_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivityAttendance" - ADD CONSTRAINT "activityAttendance_activity_FK" FOREIGN KEY ("activityId") REFERENCES public."Activity"("activityId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ActivityAttendance activityAttendance_scout_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivityAttendance" - ADD CONSTRAINT "activityAttendance_scout_FK" FOREIGN KEY ("scoutId") REFERENCES public."Scout"("scoutId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ActivityGuidance activityGuidance_activity_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivityGuidance" - ADD CONSTRAINT "activityGuidance_activity_FK" FOREIGN KEY ("activityId") REFERENCES public."Activity"("activityId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ActivityGuidance activityGuidance_captain_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivityGuidance" - ADD CONSTRAINT "activityGuidance_captain_FK" FOREIGN KEY ("captainId") REFERENCES public."Captain"("captainId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ActivitySectorParticipation activityParticipation_activity_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivitySectorParticipation" - ADD CONSTRAINT "activityParticipation_activity_FK" FOREIGN KEY ("activityId") REFERENCES public."Activity"("activityId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ActivitySectorParticipation activityParticipation_sector_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ActivitySectorParticipation" - ADD CONSTRAINT "activityParticipation_sector_FK" FOREIGN KEY ("sectorBaseName", "sectorSuffixName") REFERENCES public."Sector"("baseName", "suffixName") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: Activity activity_weeknumber_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Activity" - ADD CONSTRAINT "activity_weeknumber_FK" FOREIGN KEY ("weekNumber", "termNumber") REFERENCES public."Week"("weekNumber", "termNumber") ON UPDATE RESTRICT ON DELETE RESTRICT NOT VALID; - - --- --- Name: Aspect aspect_sectorName_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Aspect" - ADD CONSTRAINT "aspect_sectorName_FK" FOREIGN KEY ("sectorBaseName", "sectorSuffixName") REFERENCES public."Sector"("baseName", "suffixName") ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; - - --- --- Name: ScoutAttendance attendance_scout_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ScoutAttendance" - ADD CONSTRAINT "attendance_scout_FK" FOREIGN KEY ("scoutId") REFERENCES public."Scout"("scoutId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ScoutAttendance attendance_week_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ScoutAttendance" - ADD CONSTRAINT "attendance_week_FK" FOREIGN KEY ("weekNumber", "termNumber") REFERENCES public."Week"("weekNumber", "termNumber") ON UPDATE RESTRICT ON DELETE RESTRICT; - - --- --- Name: CaptainAttendance captainAttendance_regularCaptain_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."CaptainAttendance" - ADD CONSTRAINT "captainAttendance_regularCaptain_FK" FOREIGN KEY ("captainId") REFERENCES public."Captain"("captainId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: CaptainAttendance captainAttendance_week_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."CaptainAttendance" - ADD CONSTRAINT "captainAttendance_week_FK" FOREIGN KEY ("weekNumber", "termNumber") REFERENCES public."Week"("weekNumber", "termNumber") ON UPDATE RESTRICT ON DELETE RESTRICT; - - --- --- Name: Captain captain_sector_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Captain" - ADD CONSTRAINT "captain_sector_FK" FOREIGN KEY ("rSectorBaseName", "rSectorSuffixName") REFERENCES public."Sector"("baseName", "suffixName") ON UPDATE CASCADE ON DELETE SET NULL NOT VALID; - - --- --- Name: OtherItem otherItem_financeItem_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."OtherItem" - ADD CONSTRAINT "otherItem_financeItem_FK" FOREIGN KEY ("itemId") REFERENCES public."FinanceItem"("itemId") ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; - - --- --- Name: OtherItem otherItem_generalCaptain_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."OtherItem" - ADD CONSTRAINT "otherItem_generalCaptain_FK" FOREIGN KEY ("generalCaptainId") REFERENCES public."Captain"("captainId") ON UPDATE RESTRICT ON DELETE SET NULL NOT VALID; - - --- --- Name: RecieveNotification recNot_captain_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."RecieveNotification" - ADD CONSTRAINT "recNot_captain_FK" FOREIGN KEY ("captainId") REFERENCES public."Captain"("captainId") ON UPDATE RESTRICT ON DELETE CASCADE NOT VALID; - - --- --- Name: RecieveNotification recNot_notification_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."RecieveNotification" - ADD CONSTRAINT "recNot_notification_FK" FOREIGN KEY ("notificationId") REFERENCES public."Notification"("NotificationId") ON UPDATE RESTRICT ON DELETE CASCADE NOT VALID; - - --- --- Name: Report report_captain_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Report" - ADD CONSTRAINT "report_captain_FK" FOREIGN KEY ("captainId") REFERENCES public."Captain"("captainId") ON UPDATE RESTRICT ON DELETE SET NULL NOT VALID; - - --- --- Name: Report report_scout_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Report" - ADD CONSTRAINT "report_scout_FK" FOREIGN KEY ("scoutId") REFERENCES public."Scout"("scoutId") ON UPDATE RESTRICT ON DELETE CASCADE NOT VALID; - - --- --- Name: ScoutScore score_aspect_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ScoutScore" - ADD CONSTRAINT "score_aspect_FK" FOREIGN KEY ("aspectId") REFERENCES public."Aspect"("aspectId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ScoutScore score_scout_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ScoutScore" - ADD CONSTRAINT "score_scout_FK" FOREIGN KEY ("scoutId") REFERENCES public."Scout"("scoutId") ON UPDATE RESTRICT ON DELETE CASCADE; - - --- --- Name: ScoutProfile scoutProfile_scout_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."ScoutProfile" - ADD CONSTRAINT "scoutProfile_scout_FK" FOREIGN KEY ("scoutId") REFERENCES public."Scout"("scoutId") ON UPDATE RESTRICT ON DELETE CASCADE NOT VALID; - - --- --- Name: Scout scout_sector_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Scout" - ADD CONSTRAINT "scout_sector_FK" FOREIGN KEY ("sectorSuffixName", "sectorBaseName") REFERENCES public."Sector"("suffixName", "baseName") ON UPDATE CASCADE ON DELETE SET NULL NOT VALID; - - --- --- Name: Sector sector_unitCaptain_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Sector" - ADD CONSTRAINT "sector_unitCaptain_FK" FOREIGN KEY ("unitCaptainId") REFERENCES public."Captain"("captainId") ON UPDATE RESTRICT ON DELETE SET NULL NOT VALID; - - --- --- Name: Session session_captain_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Session" - ADD CONSTRAINT "session_captain_FK" FOREIGN KEY ("captainId") REFERENCES public."Captain"("captainId") ON UPDATE RESTRICT ON DELETE SET NULL NOT VALID; - - --- --- Name: Session session_week_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Session" - ADD CONSTRAINT "session_week_FK" FOREIGN KEY ("weekNumber", "termNumber") REFERENCES public."Week"("weekNumber", "termNumber") ON UPDATE RESTRICT ON DELETE RESTRICT NOT VALID; - - --- --- Name: Subscription subscription_financeItem_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Subscription" - ADD CONSTRAINT "subscription_financeItem_FK" FOREIGN KEY ("itemId") REFERENCES public."FinanceItem"("itemId") ON UPDATE RESTRICT ON DELETE CASCADE NOT VALID; - - --- --- Name: Subscription subscription_sector_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Subscription" - ADD CONSTRAINT "subscription_sector_FK" FOREIGN KEY ("sectorBaseName", "sectorSuffixName") REFERENCES public."Sector"("baseName", "suffixName") ON UPDATE CASCADE ON DELETE SET NULL NOT VALID; - - --- --- Name: Subscription subscription_week_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Subscription" - ADD CONSTRAINT "subscription_week_FK" FOREIGN KEY ("weekNumber", "termNumber") REFERENCES public."Week"("weekNumber", "termNumber") ON UPDATE RESTRICT ON DELETE RESTRICT NOT VALID; - - --- --- Name: Week week_term_FK; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."Week" - ADD CONSTRAINT "week_term_FK" FOREIGN KEY ("termNumber") REFERENCES public."Term"("termNumber") ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; - - --- --- PostgreSQL database dump complete --- \ No newline at end of file diff --git a/server/database/scripts/fillDatabase.psql b/server/database/scripts/fillDatabase.psql index 3af1dfe0..067795be 100644 --- a/server/database/scripts/fillDatabase.psql +++ b/server/database/scripts/fillDatabase.psql @@ -1,153 +1,5 @@ --- Insert dummy data into the "Gender" table -INSERT INTO public."Gender" ("gender") -VALUES - ('ذكر'), - ('أنثى'); - --- Insert dummy data into the "CaptainType" table -INSERT INTO public."CaptainType" ("captainType") -VALUES - ('عام'), - ('وحدة'), - ('عادي'); - --- Insert dummy data into the "Days" table -INSERT INTO public."Days" ("day") -VALUES - ('سبت'), - ('أحد'), - ('اثنين'), - ('ثلاثاء'), - ('أربعاء'), - ('خميس'), - ('جمعة'); - --- Insert dummy data into the "ActivityType" table -INSERT INTO public."ActivityType" ("activityType") -VALUES - ('ترفيه'), - ('تجديف'), - ('تخييم'), - ('طهي بري'), - ('كشافة'), - ('تطوع'), - ('آخر'); - --- Insert dummy data into the "AspectCategory" table -INSERT INTO public."AspectCategory" ("aspectCategory") -VALUES - ('مهارات كشفية'), - ('سلوك'), - ('مشاركة'), - ('امتحانات'), - ('آخر'); - --- Insert dummy data into the "AttendanceStatus" table -INSERT INTO public."AttendanceStatus" ("attendanceStatus") -VALUES - ('غائب'), - ('معذور'), - ('معذور الفصل'), - ('حاضر'); - --- Insert dummy data into the "FinanceItemType" table -INSERT INTO public."FinanceItemType" ("financeItemType") -VALUES - ('إيراد'), - ('مصروف'); - --- Insert dummy data into the "NotificationType" table -INSERT INTO public."NotificationType" ("notificationType") -VALUES - ('حضور'), - ('تقرير'), - ('إنشاء عنصر مالي'), - ('آخر'); - -- Insert dummy data into the "Sector" table -INSERT INTO public."Sector" ("baseName", "suffixName", "unitCaptainId") -SELECT - 'القطاع', - chr(64 + generate_series), - generate_series -FROM generate_series(1, 20); - --- Insert dummy data into the "Term" table -INSERT INTO public."Term" ("termNumber", "termName", "startDate", "endDate") -SELECT - generate_series, - 'الفصل الربيعي', - '2023-01-01'::DATE + generate_series, - '2023-06-30'::DATE + generate_series -FROM generate_series(1, 20); - --- Insert dummy data into the "Week" table -INSERT INTO public."Week" ("weekNumber", "termNumber", "canceled", "startDate") -SELECT - generate_series, - random_int(1, 3), - CASE WHEN random() < 0.5 THEN true ELSE false END, - '2023-01-01'::DATE + generate_series -FROM generate_series(1, 20); - --- Insert dummy data into the "Session" table -INSERT INTO public."Session" ("sessionId", "title", "documentURL", "captainId", "weekNumber", "termNumber") -SELECT - generate_series, - 'جلسة ' || generate_series, - 'https://example.com/document' || generate_series, - generate_series, - random_int(1, 3), - random_int(1, 3) -FROM generate_series(1, 20); - --- Insert dummy data into the "Captain" table -INSERT INTO public."Captain" ("captainId", "firstName", "middleName", "lastName", "phoneNumber", "email", "password", "rSectorBaseName", "rSectorSuffixName", "gender", "type") -SELECT - generate_series, - 'القائد ' || generate_series, - 'الوسيط', - 'العائلة', - '123456789' || generate_series, - 'captain' || generate_series || '@example.com', - 'password' || generate_series, - 'القطاع', - chr(64 + generate_series), - CASE WHEN random() < 0.5 THEN 'ذكر' ELSE 'أنثى' END, - CASE WHEN random() < 0.5 THEN 'عام' ELSE 'وحدة' END -FROM generate_series(1, 20); - --- Insert dummy data into the "Scout" table -INSERT INTO public."Scout" ("scoutId", "firstName", "middleName", "lastName", "expelled", "sectorBaseName", "sectorSuffixName", "gender") -SELECT - generate_series, - 'كشاف ' || generate_series, - 'كشافي', - 'العائلة', - CASE WHEN random() < 0.1 THEN true ELSE false END, - 'القطاع', - chr(64 + generate_series), - CASE WHEN random() < 0.5 THEN 'ذكر' ELSE 'أنثى' END -FROM generate_series(1, 20); - --- Insert dummy data into the "ScoutAttendance" table -INSERT INTO public."ScoutAttendance" ("scoutId", "weekNumber", "termNumber", "attendanceStatus") -SELECT - generate_series, - random_int(1, 20), - random_int(1, 20), - CASE WHEN random() < 0.5 THEN 'حاضر' ELSE 'غائب' END -FROM generate_series(1, 20); +INSERT INTO "Activity" ("place", "weekNumber", "termNumber", "day", "type") +VALUES +('تحرير', 1, 1, 'Monday', 'Lecture'), --- Insert dummy data into the "Activity" table -INSERT INTO public."Activity" ("activityId", "title", "description", "type", "timestamp", "captainId", "weekNumber", "termNumber", "sessionNumber") -SELECT - generate_series, - 'نشاط ' || generate_series, - 'نشاط تجريبي', - 'تجديف', - '2023-01-01 12:00:00'::TIMESTAMP + generate_series, - generate_series, - random_int(1, 3), - random_int(1, 3), - random_int(1, 20); From dd52f4c53b2289f5578c6df863a9f437c463b075 Mon Sep 17 00:00:00 2001 From: AhmedHamed3699 Date: Mon, 25 Dec 2023 01:35:29 +0200 Subject: [PATCH 3/7] =?UTF-8?q?=E2=9C=A8=20feat:=20get=20budget?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/controllers/finance.controller.js | 26 ++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/server/controllers/finance.controller.js b/server/controllers/finance.controller.js index 58677527..c856f3b8 100644 --- a/server/controllers/finance.controller.js +++ b/server/controllers/finance.controller.js @@ -6,10 +6,28 @@ const financeController = { // @access Private getBudget: async (req, res) => { try { - // get subsciptions - return res.status(200) - } catch (err) { - return res.status(500).json({ message: err.message }) + // get income + let result = await db.query( + `SELECT COALESCE(SUM(value), 0) AS sum FROM "FinanceItem" WHERE "type" = 'income'` + ) + const income = result.rows[0].sum + + // get expense + result = await db.query( + `SELECT COALESCE(SUM(value), 0) AS sum FROM "FinanceItem" WHERE "type" = 'expense'` + ) + const expense = result.rows[0].sum + + const budget = income - expense + res.status(200).json({ + message: 'Get budget successfully', + body: budget, + }) + } catch (error) { + console.log(error) + res.status(500).json({ + error: 'An error occurred while getting the budget', + }) } }, } From 5484ccd4666defafd0914077bf2f0ca680f94d23 Mon Sep 17 00:00:00 2001 From: AhmedHamed3699 Date: Mon, 25 Dec 2023 01:36:09 +0200 Subject: [PATCH 4/7] =?UTF-8?q?=E2=9C=A8=20feat:=20get=20absence=20rate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/controllers/stats.controller.js | 61 +++++++++++++++++++++++--- server/routes/stats.route.js | 3 +- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/server/controllers/stats.controller.js b/server/controllers/stats.controller.js index edba0ccb..a2aaec8b 100644 --- a/server/controllers/stats.controller.js +++ b/server/controllers/stats.controller.js @@ -1,18 +1,67 @@ import db from '../database/db.js' const statsController = { - // @desc Get all absence rates + // @desc Get all absence rates from the start of term till now // @route GET /api/stats // @access Private getAbsenceRate: async (req, res) => { try { - if (req.user.type === 'general') { - return res.status(200) + if (req.currentWeek.weekNumber === 0) { + return res.status(400).json({ + error: 'Cannot get absence rate before the term starts', + }) + } + let result + if (req.captain.type === 'general') { + result = await db.query( + `SELECT + COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absenceCount, + COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendanceCount + FROM "ScoutAttendance" + WHERE "termNumber" = $1`, + [req.currentTerm.termNumber] + ) + } else if (req.captain.type === 'unit') { + result = await db.query( + `SELECT + COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absenceCount, + COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendanceCount + FROM "ScoutAttendance" AS SA, "Scout" AS SC, "Sector" AS SE + WHERE SA."termNumber" = $1 AND + SA."scoutId" = SC."scoutId" AND + SC."sectorBaseName" = SE."baseName" AND + SC."sectorSuffixName" = SE."suffixName" AND + SE."unitCaptainId" = $2`, + [req.currentTerm.termNumber, req.captain.captainId] + ) } else { - return res.status(200) + result = await db.query( + `SELECT + COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absenceCount, + COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendanceCount + FROM "ScoutAttendance" AS SA, "Scout" AS SC, "Captain" AS C + WHERE SA."termNumber" = $1 AND + SA."scoutId" = SC."scoutId" AND + SC."sectorBaseName" = C."rSectorBaseName" AND + SC."sectorSuffixName" = C."rSectorSuffixName" AND + C."captainId" = $2`, + [req.currentTerm.termNumber, req.captain.captainId] + ) } - } catch (err) { - return res.status(500).json({ message: err.message }) + const absenceRecordsCount = result.rows[0].absenceCount + const attendanceRecordsCount = result.rows[0].attendanceCount + const absenceRate = + absenceRecordsCount / + (absenceRecordsCount + attendanceRecordsCount) + return res.status(200).json({ + message: 'Get absence rate successfully', + body: absenceRate, + }) + } catch (error) { + console.log(error) + return res + .status(500) + .json({ error: 'An error occurred while getting absence rate' }) } }, } diff --git a/server/routes/stats.route.js b/server/routes/stats.route.js index 73a58c0b..12b04783 100644 --- a/server/routes/stats.route.js +++ b/server/routes/stats.route.js @@ -1,7 +1,8 @@ import { Router } from 'express' import statsController from '../controllers/stats.controller.js' +import { getCurrentTermMiddleware } from '../middlewares/current.middleware.js' const statsRouter = Router() -statsRouter.get('/', statsController.getAbsenceRate) +statsRouter.get('/', getCurrentTermMiddleware, statsController.getAbsenceRate) export default statsRouter From 25d94c928c2dd058d5932d652313e45f7754cb7a Mon Sep 17 00:00:00 2001 From: AhmedHamed3699 Date: Mon, 25 Dec 2023 01:37:26 +0200 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=8E=A8=20chore:=20add=20middleware=20?= =?UTF-8?q?to=20get=20current=20stuff?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/controllers/term.controller.js | 89 ++++++++---------------- server/middlewares/current.middleware.js | 47 +++++++++++++ server/routes/term.route.js | 28 ++++++-- 3 files changed, 99 insertions(+), 65 deletions(-) create mode 100644 server/middlewares/current.middleware.js diff --git a/server/controllers/term.controller.js b/server/controllers/term.controller.js index d972489c..178c2548 100644 --- a/server/controllers/term.controller.js +++ b/server/controllers/term.controller.js @@ -5,29 +5,15 @@ const termController = { // @route GET /api/term/ // @access Private getTerm: async (req, res) => { - try { - const result = await db.query( - `SELECT * FROM "Term" WHERE "termNumber" IN - (SELECT COALESCE(MAX("termNumber"), 0) FROM "Term");` - ) - if (!result.rows.length) { - return res.status(400).json({ - error: 'There is no term in the system', - }) - } - - const currentTerm = result.rows[0] - - res.status(200).json({ - message: 'Current term found successfully', - body: currentTerm, - }) - } catch (error) { - console.log(error) - res.status(500).json({ - error: 'An error occurred while getting the term', + if (req.currentTerm.termNumber === 0) { + return res.status(400).json({ + error: 'There is no terms in the system', }) } + res.status(200).json({ + message: 'Current term found successfully', + body: req.currentTerm, + }) }, // @desc Add a term @@ -43,24 +29,18 @@ const termController = { }) } - const result = await db.query( - `SELECT COALESCE(MAX("termNumber"), 0) AS MAX FROM "Term";` - ) + const termNumber = req.currentTerm.termNumber + 1 - const termNumber = result.rows[0].MAX + 1 - - result = await db.query( - `SELECT * FROM "Term" WHERE "termNumber" = $1;`, - [termNumber - 1] - ) - - if (result.rows.length && result.rows[0].endDate >= startDate) { + if ( + req.currentTerm.termNumber && + req.currentTerm.endDate >= startDate + ) { return res.status(400).json({ error: 'Invalid start date: Overlapping terms', }) } - result = await db.query( + const result = await db.query( `INSERT INTO "Term" VALUES ($1, $2, $3, $4) RETURNING *;`, [termNumber, termName, startDate, endDate] @@ -119,22 +99,14 @@ const termController = { // @access Private getWeek: async (req, res) => { try { - const result = await db.query( - `SELECT * FROM "Week" WHERE "weekNumber" IN - (SELECT COALESCE(MAX("weekNumber"), 0) FROM "Week" WHERE "termNumber" IN - (SELECT COALESCE(MAX("termNumber"), 0) FROM "Term"));` - ) - if (!result.rows.length) { + if (req.currentWeek.weekNumber === 0) { return res.status(400).json({ error: 'There is no weeks or terms in the system', }) } - - const currentWeek = result.rows[0] - res.status(200).json({ message: 'Current week found successfully', - body: currentWeek, + body: req.currentWeek, }) } catch (error) { console.log(error) @@ -149,18 +121,17 @@ const termController = { // @access Private cancelWeek: async (req, res) => { try { - const result = await db.query( - `UPDATE "Week" SET "cancelled" = false - WHERE "weekNumber" IN - (SELECT COALESCE(MAX("weekNumber"), 0) FROM "Week" WHERE "termNumber" IN - (SELECT COALESCE(MAX("termNumber"), 0) FROM "Term")) - RETURNING *;` - ) - if (!result.rows.length) { + if (req.currentWeek.weekNumber === 0) { return res.status(400).json({ - error: 'There is no weeks or terms in the system', + error: 'There is no weeks or terms in the system to be cancelled', }) } + const result = await db.query( + `UPDATE "Week" SET "cancelled" = true + WHERE "termNumber" = $1 AND "weekNumber" = $2 + RETURNING *;`, + [req.currentWeek.termNumber, req.currentWeek.weekNumber] + ) const updatedWeek = result.rows[0] @@ -181,21 +152,19 @@ const termController = { // @access Private getRemainingWeeks: async (req, res) => { try { - const result = await db.query( - `SELECT * FROM "Term" WHERE "termNumber" IN - (SELECT COALESCE(MAX("termNumber"), 0) FROM "Term");` - ) const currentDate = new Date() - if (!result.rows.length || result.rows[0].endDate < currentDate) { + if ( + req.currentTerm.termNumber === 0 || + req.currentTerm.endDate < currentDate + ) { return res.status(400).json({ error: 'There is no running term in the system', }) } - const currentTerm = result.rows[0] - const remainingWeeks = Math.ceil( - (currentTerm.endDate - currentDate) / (1000 * 60 * 60 * 24 * 7) + (req.currentTerm.endDate - currentDate) / + (1000 * 60 * 60 * 24 * 7) ) res.status(200).json({ diff --git a/server/middlewares/current.middleware.js b/server/middlewares/current.middleware.js new file mode 100644 index 00000000..7e6f2bdf --- /dev/null +++ b/server/middlewares/current.middleware.js @@ -0,0 +1,47 @@ +import db from '../database/db.js' + +const getCurrentTermMiddleware = async (req, res, next) => { + try { + const result = await db.query( + `SELECT * FROM "Term" WHERE "termNumber" IN + (SELECT COALESCE(MAX("termNumber"), 0) FROM "Term");` + ) + if (!result.rows.length) { + req.currentTerm = { + termNumber: 0, + } + } else req.currentTerm = result.rows[0] + + next() + } catch (error) { + console.log(error) + res.status(500).json({ + error: 'An error occurred while getting the term', + }) + } +} + +const getCurrentWeekMiddleware = async (req, res, next) => { + try { + const result = await db.query( + `SELECT * FROM "Week" WHERE "weekNumber" IN + (SELECT COALESCE(MAX("weekNumber"), 0) FROM "Week" WHERE "termNumber" IN + (SELECT COALESCE(MAX("termNumber"), 0) FROM "Term"));` + ) + if (!result.rows.length) { + req.currentWeek = { + termNumber: 0, + weekNumber: 0, + } + } else req.currentWeek = result.rows[0] + + next() + } catch (error) { + console.log(error) + res.status(500).json({ + error: 'An error occurred while getting the Week', + }) + } +} + +export { getCurrentTermMiddleware, getCurrentWeekMiddleware } diff --git a/server/routes/term.route.js b/server/routes/term.route.js index 8e499ee3..25cd2443 100644 --- a/server/routes/term.route.js +++ b/server/routes/term.route.js @@ -1,18 +1,36 @@ import { Router } from 'express' import termController from '../controllers/term.controller.js' import checkRankMiddleware from '../middlewares/checkRank.middleware.js' +import { + getCurrentTermMiddleware, + getCurrentWeekMiddleware, +} from '../middlewares/current.middleware.js' const termRouter = Router() // Term routes -termRouter.get('/', termController.getTerm) -termRouter.post('/', checkRankMiddleware('general'), termController.addTerm) +termRouter.get('/', getCurrentTermMiddleware, termController.getTerm) +termRouter.post( + '/', + checkRankMiddleware('general'), + getCurrentTermMiddleware, + termController.addTerm +) termRouter.patch('/', checkRankMiddleware('general'), termController.updateTerm) // Week routes -termRouter.get('/week', termController.getWeek) -termRouter.patch('/week', checkRankMiddleware('general'), termController.cancelWeek) +termRouter.get('/week', getCurrentWeekMiddleware, termController.getWeek) +termRouter.patch( + '/week', + checkRankMiddleware('general'), + getCurrentWeekMiddleware, + termController.cancelWeek +) // Other routes -termRouter.get('/remaining', termController.getRemainingWeeks) +termRouter.get( + '/remaining', + getCurrentTermMiddleware, + termController.getRemainingWeeks +) export default termRouter From 04f764c7a0e8ca7c59a0590ac3307b0146b10b15 Mon Sep 17 00:00:00 2001 From: AhmedHamed3699 Date: Mon, 25 Dec 2023 02:41:07 +0200 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=8E=A8=20chore:=20update=20response?= =?UTF-8?q?=20return=20&=20some=20other=20minor=20adjusments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/controllers/alert.controller.js | 17 ++- server/controllers/captain.controller.js | 66 +++------- server/controllers/finance.controller.js | 6 +- server/controllers/scout.controller.js | 148 +++++------------------ server/controllers/stats.controller.js | 18 ++- server/routes/stats.route.js | 11 +- 6 files changed, 85 insertions(+), 181 deletions(-) diff --git a/server/controllers/alert.controller.js b/server/controllers/alert.controller.js index 28b4393a..4ecb1510 100644 --- a/server/controllers/alert.controller.js +++ b/server/controllers/alert.controller.js @@ -9,18 +9,17 @@ const alertController = { [id] ) - if (!alert) return res.status(404).json({ error: 'Alert not found' }) + if (!alert.rowCount) + return res.status(404).json({ error: 'Alert not found' }) res.status(200).json({ message: 'Alert successfully found', - body: alert, + body: alert.rows[0], }) }, CreateAlert: async (req, res) => { - const { title, message, type } = req.body - if (!title || !message || !type) - return res.status(400).json({ error: 'Missing input' }) + const { message, type } = req.body const newAlert = await db.query( `INSERT INTO "Notification" ("message") @@ -28,11 +27,12 @@ const alertController = { [message] ) - if (!newAlert) return res.status(400).json({ error: 'Cannot Post' }) + if (!newAlert.rowCount) + return res.status(400).json({ error: 'Cannot Post' }) res.status(200).json({ message: 'Alert successfully created', - body: newAlert, + body: newAlert.rows[0], }) }, @@ -70,9 +70,6 @@ const alertController = { getAllAlerts: async (req, res) => { const Alerts = await db.query(`SELECT * FROM "Notification";`) - if (!Alerts.rows.length) - return res.status(400).json({ error: 'No alerts found' }) - res.status(200).json({ message: 'get Alerts successfully', body: Alerts.rows, diff --git a/server/controllers/captain.controller.js b/server/controllers/captain.controller.js index e7618a3b..a8f3bfe3 100644 --- a/server/controllers/captain.controller.js +++ b/server/controllers/captain.controller.js @@ -4,15 +4,12 @@ const captainController = { allCaptainsInfo: async (req, res) => { try { // Query on the database to get the captains info - const result = await db.query(` - SELECT * - FROM "Captain" - `) + const result = await db.query(`SELECT * FROM "Captain"`) // Respond with the data retrieved and a successful retrieval message res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows, }) } catch (error) { console.log(error) @@ -25,15 +22,14 @@ const captainController = { allCaptainsCount: async (req, res) => { try { // Query on the database to get the captains info - const result = await db.query(` - SELECT COUNT(*) - FROM "Captain" - `) + const result = await db.query( + `SELECT COUNT(*) AS count FROM "Captain"` + ) // Respond with the data retrieved and a successful retrieval message res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows[0].count, }) } catch (error) { console.log(error) @@ -50,8 +46,7 @@ const captainController = { // Query on the database to get all the captains info in a specific sector const result = await db.query( - ` - SELECT * + `SELECT * FROM "Captain" WHERE "rSectorBaseName" = $1 AND "rSectorSuffixName" = $2`, [rSectorBaseName, rSectorSuffixName] @@ -59,7 +54,7 @@ const captainController = { res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows, }) } catch (error) { console.log(error) @@ -76,8 +71,7 @@ const captainController = { // Query on the database to get all the captains count in a specific sector const result = await db.query( - ` - SELECT COUNT(*) + `SELECT COUNT(*) AS count FROM "Captain" WHERE "rSectorBaseName" = $1 AND "rSectorSuffixName" = $2`, [rSectorBaseName, rSectorSuffixName] @@ -85,7 +79,7 @@ const captainController = { res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows[0].count, }) } catch (error) { console.log(error) @@ -102,8 +96,7 @@ const captainController = { // Query on the database to get that captain info const result = await db.query( - ` - SELECT * + `SELECT * FROM "Captain" WHERE "captainId" = $1`, [captainId] @@ -119,7 +112,7 @@ const captainController = { // Return the data of the captain res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows[0], }) } catch (error) { console.log(error) @@ -133,33 +126,20 @@ const captainController = { try { const { unitCaptainId } = req.params - // Make sure that the id is provided (not undefined) - if (!unitCaptainId) { - return res.status(404).json({ - error: 'Enter a valid unit captain id', - }) - } - // Query to get the id const result = await db.query( - ` - SELECT C.* + `SELECT C.* FROM "Captain" AS C, "Sector" AS S - WHERE S."unitCaptainId" = $1 AND C."rSectorBaseName" = S."baseName" AND C."rSectorSuffixName" = S."suffixName";`, + WHERE S."unitCaptainId" = $1 AND + C."rSectorBaseName" = S."baseName" AND + C."rSectorSuffixName" = S."suffixName";`, [unitCaptainId] ) - // If there is no result found, return 404 not found error (This might not be an error) - if (!result.rows.length) { - return res.status(404).json({ - error: 'Captains Not Found', - }) - } - // Return the data res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows, }) } catch (error) { console.log(error) @@ -173,17 +153,9 @@ const captainController = { try { const { unitCaptainId } = req.params - // Make sure that the id is provided (not undefined) - if (!unitCaptainId) { - return res.status(404).json({ - error: 'Enter a valid unit captain id', - }) - } - // Query to get the id const result = await db.query( - ` - SELECT COUNT(*) + `SELECT COUNT(*) AS count FROM "Captain" AS C, "Sector" AS S WHERE S."unitCaptainId" = $1 AND C."rSectorBaseName" = S."baseName" AND C."rSectorSuffixName" = S."suffixName";`, [unitCaptainId] @@ -192,7 +164,7 @@ const captainController = { // Return the data res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows[0].count, }) } catch (error) { console.log(error) diff --git a/server/controllers/finance.controller.js b/server/controllers/finance.controller.js index c856f3b8..bf06c9eb 100644 --- a/server/controllers/finance.controller.js +++ b/server/controllers/finance.controller.js @@ -8,13 +8,15 @@ const financeController = { try { // get income let result = await db.query( - `SELECT COALESCE(SUM(value), 0) AS sum FROM "FinanceItem" WHERE "type" = 'income'` + `SELECT COALESCE(SUM(value), 0) AS sum FROM "FinanceItem" + WHERE "type" = 'income';` ) const income = result.rows[0].sum // get expense result = await db.query( - `SELECT COALESCE(SUM(value), 0) AS sum FROM "FinanceItem" WHERE "type" = 'expense'` + `SELECT COALESCE(SUM(value), 0) AS sum FROM "FinanceItem" + WHERE "type" = 'expense';` ) const expense = result.rows[0].sum diff --git a/server/controllers/scout.controller.js b/server/controllers/scout.controller.js index 8818dff1..582e6fa1 100644 --- a/server/controllers/scout.controller.js +++ b/server/controllers/scout.controller.js @@ -3,14 +3,13 @@ import db from '../database/db.js' const scoutController = { allScoutsCount: async (req, res) => { try { - const result = await db.query(` - SELECT COUNT(*) - FROM "Scout" - `) + const result = await db.query( + `SELECT COUNT(*) AS count FROM "Scout";` + ) res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows[0].count, }) } catch (error) { console.log(error) @@ -22,14 +21,11 @@ const scoutController = { }, allScoutsInfo: async (req, res) => { try { - const result = await db.query(` - SELECT * - FROM "Scout" - `) + const result = await db.query(`SELECT * FROM "Scout";`) res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows, }) } catch (error) { console.log(error) @@ -43,33 +39,16 @@ const scoutController = { try { const { sectorBaseName, sectorSuffixName } = req.body - if ( - sectorBaseName === undefined && - sectorSuffixName === undefined - ) { - return res.status(400).json({ - error: 'Please enter the sector base name and/or suffix name', - }) - } - const result = await db.query( - ` - SELECT * + `SELECT * FROM "Scout" - WHERE "sectorBaseName" = $1 AND "sectorSuffixName" = $2 - `, + WHERE "sectorBaseName" = $1 AND "sectorSuffixName" = $2;`, [sectorBaseName, sectorSuffixName] ) - if (!result.rows.length) { - return res.status(404).json({ - error: 'No scouts found in this sector', - }) - } - res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows, }) } catch (error) { console.log(error) @@ -83,27 +62,16 @@ const scoutController = { try { const { sectorBaseName, sectorSuffixName } = req.body - if ( - sectorBaseName === undefined && - sectorSuffixName === undefined - ) { - return res.status(400).json({ - error: 'Please enter the sector base name and/or suffix name', - }) - } - const result = await db.query( - ` - SELECT COUNT(*) + `SELECT COUNT(*) AS count FROM "Scout" - WHERE "sectorBaseName" = $1 AND "sectorSuffixName" = $2 - `, + WHERE "sectorBaseName" = $1 AND "sectorSuffixName" = $2;`, [sectorBaseName, sectorSuffixName] ) res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows[0].count, }) } catch (error) { console.log(error) @@ -117,31 +85,18 @@ const scoutController = { try { const { unitCaptainId } = req.params - // Make sure that the id is provided (not undefined) - if (!unitCaptainId) { - return res.status(404).json({ - error: 'Enter a valid unit captain id', - }) - } - const result = await db.query( - ` - SELECT scout.* + `SELECT scout.* FROM "Scout" AS scout, "Sector" AS sector - WHERE sector."unitCaptainId" = $1 AND scout."sectorBaseName" = sector."baseName" AND scout."sectorSuffixName" = sector."suffixName"; - `, + WHERE sector."unitCaptainId" = $1 AND + scout."sectorBaseName" = sector."baseName" AND + scout."sectorSuffixName" = sector."suffixName";`, [unitCaptainId] ) - if (!result.rows.length) { - return res.status(404).json({ - error: 'No scouts found in this unit', - }) - } - res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows, }) } catch (error) { console.log(error) @@ -155,31 +110,18 @@ const scoutController = { try { const { unitCaptainId } = req.params - // Make sure that the id is provided (not undefined) - if (!unitCaptainId) { - return res.status(404).json({ - error: 'Enter a valid unit captain id', - }) - } - const result = await db.query( - ` - SELECT Count(*) + `SELECT Count(*) FROM "Scout" AS scout, "Sector" AS sector - WHERE sector."unitCaptainId" = $1 AND scout."sectorBaseName" = sector."baseName" AND scout."sectorSuffixName" = sector."suffixName"; - `, + WHERE sector."unitCaptainId" = $1 AND + scout."sectorBaseName" = sector."baseName" AND + scout."sectorSuffixName" = sector."suffixName";`, [unitCaptainId] ) - if (!result.rows.length) { - return res.status(404).json({ - error: 'No scouts found in this unit', - }) - } - res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows[0].count, }) } catch (error) { console.log(error) @@ -193,19 +135,10 @@ const scoutController = { try { const { scoutId } = req.params - // Make sure that the id is provided (not undefined) - if (!scoutId) { - return res.status(404).json({ - error: 'Enter a valid scout id', - }) - } - const result = await db.query( - ` - SELECT * + `SELECT * FROM "Scout" - WHERE "scoutId" = $1; - `, + WHERE "scoutId" = $1;`, [scoutId] ) @@ -217,7 +150,7 @@ const scoutController = { res.status(200).json({ message: 'Successful retrieval', - body: result, + body: result.rows[0], }) } catch (error) { console.log(error) @@ -245,22 +178,13 @@ const scoutController = { birthCertificate, } = req.body - // If no scout id is provided give an error - if (!scoutId) { - return res.status(400).json({ - error: 'Please enter a valid scout id', - }) - } - // Update the scout data const result1 = await db.query( - ` - UPDATE "Scout" + `UPDATE "Scout" SET "firstName" = $1, "middleName" = $2, "lastName" = $3, "gender" = $4, "sectorBaseName" = $5, "sectorSuffixName" = $6 WHERE "scoutId" = $7 - RETURNING * - `, + RETURNING *;`, [ firstName, middleName, @@ -282,13 +206,11 @@ const scoutController = { // Update the scout profile data const result2 = await db.query( - ` - UPDATE "ScoutProfile" + `UPDATE "ScoutProfile" SET "birthDate" = $1, "enrollDate" = $2, "schoolGrade" = $3, "photo" = $4, "birthCertificate" = $5 WHERE "scoutId" = $6 - RETURNING * - `, + RETURNING *;`, [ birthDate, enrollDate, @@ -331,11 +253,9 @@ const scoutController = { // Insert a new scout into the database const result1 = await db.query( - ` - INSERT INTO "Scout" ("firstName", "middleName", "lastName", "gender", "sectorBaseName", "sectorSuffixName") + `INSERT INTO "Scout" ("firstName", "middleName", "lastName", "gender", "sectorBaseName", "sectorSuffixName") VALUES ($1, $2, $3, $4, $5, $6) - RETURNING *; - `, + RETURNING *;`, [ firstName, middleName, @@ -356,11 +276,9 @@ const scoutController = { // Insert the scout profile const result2 = await db.query( - ` - INSERT INTO "ScoutProfile" ("birthDate", "enrollDate", "schoolGrade", "photo", "birthCertificate", "scoutId") + `INSERT INTO "ScoutProfile" ("birthDate", "enrollDate", "schoolGrade", "photo", "birthCertificate", "scoutId") VALUES ($1, $2, $3, $4, $5, $6) - RETURNING *; - `, + RETURNING *;`, [ birthDate, enrollDate, diff --git a/server/controllers/stats.controller.js b/server/controllers/stats.controller.js index a2aaec8b..d5f50f32 100644 --- a/server/controllers/stats.controller.js +++ b/server/controllers/stats.controller.js @@ -1,10 +1,10 @@ import db from '../database/db.js' const statsController = { - // @desc Get all absence rates from the start of term till now - // @route GET /api/stats + // @desc Get absence rates for scouts from the start of term till now + // @route GET /api/stats/scouts // @access Private - getAbsenceRate: async (req, res) => { + getScoutsAbsenceRate: async (req, res) => { try { if (req.currentWeek.weekNumber === 0) { return res.status(400).json({ @@ -18,7 +18,7 @@ const statsController = { COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absenceCount, COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendanceCount FROM "ScoutAttendance" - WHERE "termNumber" = $1`, + WHERE "termNumber" = $1;`, [req.currentTerm.termNumber] ) } else if (req.captain.type === 'unit') { @@ -31,7 +31,7 @@ const statsController = { SA."scoutId" = SC."scoutId" AND SC."sectorBaseName" = SE."baseName" AND SC."sectorSuffixName" = SE."suffixName" AND - SE."unitCaptainId" = $2`, + SE."unitCaptainId" = $2;`, [req.currentTerm.termNumber, req.captain.captainId] ) } else { @@ -44,7 +44,7 @@ const statsController = { SA."scoutId" = SC."scoutId" AND SC."sectorBaseName" = C."rSectorBaseName" AND SC."sectorSuffixName" = C."rSectorSuffixName" AND - C."captainId" = $2`, + C."captainId" = $2;`, [req.currentTerm.termNumber, req.captain.captainId] ) } @@ -64,6 +64,12 @@ const statsController = { .json({ error: 'An error occurred while getting absence rate' }) } }, + + // @desc Get all absence rates from the start of term till now + // @route GET /api/stats/captains + // @access Private + getCaptainsAbsenceRate: async (req, res) => { + }, } export default statsController diff --git a/server/routes/stats.route.js b/server/routes/stats.route.js index 12b04783..600007f5 100644 --- a/server/routes/stats.route.js +++ b/server/routes/stats.route.js @@ -3,6 +3,15 @@ import statsController from '../controllers/stats.controller.js' import { getCurrentTermMiddleware } from '../middlewares/current.middleware.js' const statsRouter = Router() -statsRouter.get('/', getCurrentTermMiddleware, statsController.getAbsenceRate) +statsRouter.get( + '/scouts', + getCurrentTermMiddleware, + statsController.getScoutsAbsenceRate +) +statsRouter.get( + '/captains', + getCurrentTermMiddleware, + statsController.getCaptainsAbsenceRate +) export default statsRouter From 07428c8ffeeabd3684bea2a6eaf752c08c1a5a5a Mon Sep 17 00:00:00 2001 From: AhmedHamed3699 Date: Mon, 25 Dec 2023 04:13:56 +0200 Subject: [PATCH 7/7] =?UTF-8?q?=E2=9C=85=20fix:=20pass=20tests,=20to=20be?= =?UTF-8?q?=20continued=20later?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/controllers/stats.controller.js | 50 ++++++++++++++-------- server/controllers/term.controller.js | 9 +++- server/database/db.js | 19 +++++--- server/middlewares/checkRank.middleware.js | 2 +- 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/server/controllers/stats.controller.js b/server/controllers/stats.controller.js index d5f50f32..00c666f4 100644 --- a/server/controllers/stats.controller.js +++ b/server/controllers/stats.controller.js @@ -6,7 +6,7 @@ const statsController = { // @access Private getScoutsAbsenceRate: async (req, res) => { try { - if (req.currentWeek.weekNumber === 0) { + if (req.currentTerm.termNumber === 0) { return res.status(400).json({ error: 'Cannot get absence rate before the term starts', }) @@ -15,41 +15,58 @@ const statsController = { if (req.captain.type === 'general') { result = await db.query( `SELECT - COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absenceCount, - COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendanceCount - FROM "ScoutAttendance" - WHERE "termNumber" = $1;`, + COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absence_count, + COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendance_count + FROM "ScoutAttendance" AS S, "Week" AS W + WHERE + S."weekNumber" = W."weekNumber" AND + S."termNumber" = W."termNumber" AND + W."cancelled" = false AND + S."termNumber" = $1;`, [req.currentTerm.termNumber] ) } else if (req.captain.type === 'unit') { result = await db.query( `SELECT - COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absenceCount, - COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendanceCount - FROM "ScoutAttendance" AS SA, "Scout" AS SC, "Sector" AS SE - WHERE SA."termNumber" = $1 AND + COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absence_count, + COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendance_count + FROM "ScoutAttendance" AS SA, "Scout" AS SC, "Sector" AS SE, "Week" AS W + WHERE + SA."weekNumber" = W."weekNumber" AND + SA."termNumber" = W."termNumber" AND SA."scoutId" = SC."scoutId" AND SC."sectorBaseName" = SE."baseName" AND SC."sectorSuffixName" = SE."suffixName" AND + W."cancelled" = false AND + SA."termNumber" = $1 AND SE."unitCaptainId" = $2;`, [req.currentTerm.termNumber, req.captain.captainId] ) } else { result = await db.query( `SELECT - COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absenceCount, - COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendanceCount - FROM "ScoutAttendance" AS SA, "Scout" AS SC, "Captain" AS C - WHERE SA."termNumber" = $1 AND + COUNT(*) FILTER (WHERE "attendanceStatus" = 'absent') AS absence_count, + COUNT(*) FILTER (WHERE "attendanceStatus" = 'attended') AS attendance_count + FROM "ScoutAttendance" AS SA, "Scout" AS SC, "Captain" AS C , "Week" AS W + WHERE + SA."weekNumber" = W."weekNumber" AND + SA."termNumber" = W."termNumber" AND SA."scoutId" = SC."scoutId" AND SC."sectorBaseName" = C."rSectorBaseName" AND SC."sectorSuffixName" = C."rSectorSuffixName" AND + W."cancelled" = false AND + SA."termNumber" = $1 AND C."captainId" = $2;`, [req.currentTerm.termNumber, req.captain.captainId] ) } - const absenceRecordsCount = result.rows[0].absenceCount - const attendanceRecordsCount = result.rows[0].attendanceCount + const absenceRecordsCount = Number(result.rows[0].absence_count) + const attendanceRecordsCount = Number(result.rows[0].attendance_count) + if (absenceRecordsCount + attendanceRecordsCount === 0) { + return res.status(400).json({ + error: 'There is no attendance records', + }) + } const absenceRate = absenceRecordsCount / (absenceRecordsCount + attendanceRecordsCount) @@ -68,8 +85,7 @@ const statsController = { // @desc Get all absence rates from the start of term till now // @route GET /api/stats/captains // @access Private - getCaptainsAbsenceRate: async (req, res) => { - }, + getCaptainsAbsenceRate: async (req, res) => {}, } export default statsController diff --git a/server/controllers/term.controller.js b/server/controllers/term.controller.js index 178c2548..7f853d42 100644 --- a/server/controllers/term.controller.js +++ b/server/controllers/term.controller.js @@ -23,7 +23,12 @@ const termController = { try { const { termName, startDate, endDate } = req.body - if (startDate >= endDate) { + const currentDate = new Date() + const startDateObj = new Date(startDate) + const endDateObj = new Date(endDate) + console.log(currentDate) + console.log(endDateObj) + if (startDateObj >= endDateObj || endDateObj < currentDate) { return res.status(400).json({ error: 'Invalid dates', }) @@ -33,7 +38,7 @@ const termController = { if ( req.currentTerm.termNumber && - req.currentTerm.endDate >= startDate + req.currentTerm.endDate >= startDateObj ) { return res.status(400).json({ error: 'Invalid start date: Overlapping terms', diff --git a/server/database/db.js b/server/database/db.js index 0abb16e5..c4c65bb6 100644 --- a/server/database/db.js +++ b/server/database/db.js @@ -12,8 +12,7 @@ if (process.env.DB === 'online') { rejectUnauthorized: false, }, }) -} -else { +} else { _db = new pg.Pool({ host: process.env.DB_HOST, port: process.env.DB_PORT, @@ -32,25 +31,31 @@ cron.schedule('0 0 * * 0', async () => { const currentDate = new Date() // Get the current term - const result = await db.query( + let result = await db.query( `SELECT * FROM "Term" WHERE "termNumber" IN (SELECT COALESCE(MAX("termNumber"), 0) FROM "Term");` ) - if (!result.rows.length || result.rows[0].endDate <= currentDate) return + if ( + !result.rows.length || + result.rows[0].endDate <= currentDate || + result.rows[0].startDate > currentDate + ) + return const currentTermNumber = result.rows[0].termNumber // Get the current week result = await db.query( - `SELECT COALESCE(MAX("weekNumber"), 0) FROM "Week" WHERE "termNumber" = $1;`, + `SELECT COALESCE(MAX("weekNumber"), 0) AS max FROM "Week" WHERE "termNumber" = $1;`, [currentTermNumber] ) - const { currentWeekNumber } = result.rows[0] + const currentWeekNumber = result.rows[0].max + console.log('Add a new week', currentWeekNumber + 1) // Add a new week result = await db.query( `INSERT INTO "Week" - VALUES ($1, $2, $3) + VALUES ($1, $2, $3, $4) RETURNING *;`, [currentWeekNumber + 1, false, currentDate, currentTermNumber] ) diff --git a/server/middlewares/checkRank.middleware.js b/server/middlewares/checkRank.middleware.js index d8ff3fbe..bdf571af 100644 --- a/server/middlewares/checkRank.middleware.js +++ b/server/middlewares/checkRank.middleware.js @@ -1,7 +1,7 @@ const checkRankMiddleware = (rank) => { return async (req, res, next) => { - const captainRank = req.user.type + const captainRank = req.captain.type if (captainRank === rank) { next() } else {