From 382b9695ff297935a9ef16c216498c23dc036180 Mon Sep 17 00:00:00 2001
From: elit04 <elit04@fu-berlin.de>
Date: Thu, 20 Jan 2022 13:47:47 -0500
Subject: [PATCH] sport routes + controllers

---
 server/src/controllers/sport.controllers.ts | 171 ++++++++++++++++++--
 server/src/routes/sport.routes.ts           |  32 +++-
 server/src/server.ts                        |   3 +
 3 files changed, 190 insertions(+), 16 deletions(-)

diff --git a/server/src/controllers/sport.controllers.ts b/server/src/controllers/sport.controllers.ts
index 74483c0..3af89ab 100644
--- a/server/src/controllers/sport.controllers.ts
+++ b/server/src/controllers/sport.controllers.ts
@@ -1,9 +1,9 @@
-/*import { Request, Response } from "express";
-import sport from "../db/models/Sport";
+import { Request, Response } from "express";
 import Boat from "../db/models/Boat";
-import BoatType from "../db/models/BoatType";
+import BoatHasSport from "../db/models/BoatHasSport";
+import Sport from "../db/models/Sport";
 
-//createSportController
+//create SportController
 const createSportController = async (req: Request, res: Response) => {
     try {
       if (!(res.locals.user.role == "coordinator")) {
@@ -13,8 +13,17 @@ const createSportController = async (req: Request, res: Response) => {
       }
   
       const newSportInput = req.body;
+
+      //check if Sport already exists in DB to avoid duplicates
+      const findIfSportExists = await Sport.findOne({
+        where: {name: newSportInput.name}
+      })
+
+      if(findIfSportExists) {
+        return res.status(404).json({ success: false, error: "sportAlreadyExists" });
+      }
   
-      const newSport = await sport.create(newSportInput);
+      const newSport = await Sport.create(newSportInput);
   
       if (newSport) {
         return res.status(201).json({
@@ -31,7 +40,7 @@ const createSportController = async (req: Request, res: Response) => {
     }
   };
 
-  //show all Sports
+//show all Sports
 const showAllSports = async (req: Request, res: Response) => {
     try {
       if (!(res.locals.user.role === "coordinator")) {
@@ -39,11 +48,11 @@ const showAllSports = async (req: Request, res: Response) => {
           .status(403)
           .json({ success: false, error: "MustBeCoordinator" });
       }
-      const allSports = await sport.findAll();
+      const allSports = await Sport.findAll();
       return res.status(200).send({
         success: true,
-        result: allSports.map((sport) => {
-          return { id: sport.id, name: sport.name };
+        result: allSports.map((Sport) => {
+          return { id: Sport.id, name: Sport.name };
         }),
       });
     } catch (error) {
@@ -52,10 +61,148 @@ const showAllSports = async (req: Request, res: Response) => {
     }
   };
 
+// delete a Sport by using given sport ID
+const deleteSportById = async (req: Request, res: Response) => {
+  try {
+    //check authority
+    if (!(res.locals.user.role === "coordinator")) {
+      return res
+        .status(403)
+        .json({ success: false, error: "MustBeCoordinator" });
+    }
+    //delete using given id
+    const givenId = req.params.id;
+
+    //first we need to destroy entries where the to-be-deleted sport is assigned to boat in BoatHasSport table, otherwise it violates the foreign key constraint
+    await BoatHasSport.destroy(
+      {
+        where: {
+          sportid: givenId,
+        }
+      }
+    )
+
+    const sportToDelete = await Sport.destroy({
+      where: {
+        id: givenId,
+      },
+    });
+
+    if (sportToDelete == 0) {
+      return res
+        .status(404)
+        .json({ success: false, error: "accountIdDoesNotExist" });
+    }
+
+    return res.status(204).json({ success: true });
+  } catch (error) {
+    console.error("server error: ", error.message);
+    return res.status(500).json({ success: false, error: "serverError" });
+  }
+};
+
+//update boat by given sport id
+const updateSportById = async (req: Request, res: Response) => {
+  try {
+    //check authority
+    if (!(res.locals.user.role === "coordinator")) {
+      return res
+        .status(403)
+        .json({ success: false, error: "MustBeCoordinator" });
+    }
+
+    //get new input
+    const input = req.body;
+
+    //return 200 with empty response if no data was given
+    if (Object.keys(input).length === 0) {
+      return res
+        .status(200)
+        .json({ success: true, result: {}, message: "noInputFound" });
+    }
+
+    //get id
+    const givenId = req.params.id;
+
+    //check if sport can be found using givenId
+    const foundSport= await Sport.findByPk(givenId);
+
+    if (!foundSport) {
+      return res.status(404).json({ success: false, error: "sportIdNotFound" });
+    }
+
+    //try to update
+    const updatedSport = await Sport.update(input, {
+      where: {
+        id: givenId,
+      },
+      returning: true,
+    });
+
+    //return after updating
+    const sportDataAfterUpdate = updatedSport[1][0];
+    return res.status(200).json({
+      success: true,
+      result: {
+        id: sportDataAfterUpdate.id,
+        name: sportDataAfterUpdate.name,
+        color: sportDataAfterUpdate.color,
+      },
+    });
+  } catch (error) {
+    console.error("server error: ", error.message);
+    return res.status(500).json({ success: false, error: "serverError" });
+  }
+};
+
+//show all sports assigned to boat by given boatid
+const showSportByBoatId = async (req: Request, res: Response) => {
+  try {
+    if (!(res.locals.user.role === "coordinator")) {
+      return res
+        .status(403)
+        .json({ success: false, error: "MustBeCoordinator" });
+    }
+    const givenId = req.params.id;
+    const boat = await Boat.findByPk(givenId);
+    if (boat) {
+
+      //if boat exists check in BoatHasSport table if there are any sports assigned to Boat
+      const boatIdInBoatHasSport = await BoatHasSport.findByPk(givenId);
+
+      if (!boatIdInBoatHasSport) {
+        return res.status(404).json({ success: false, error: "noAssignedSportToBoatId" });
+      }
+      
+      const findAllBoatId = await BoatHasSport.findAll({
+        where: {
+          boatid: givenId,
+        }
+      });
+
+      for (let i =0; i < findAllBoatId.length; i++) {
+        const found = await Sport.findByPk(findAllBoatId[i].sportid)
+        return res
+        .status(200)
+        .json({ success: true, result: { sport: found.name } });
+
+      }
+    }
+    return res.status(404).json({ success: false, error: "boatIdNotFound" });
+  } catch (error) {
+    console.error("server error: ", error.message);
+    return res.status(500).json({ success: false, error: "serverError" });
+  }
+};
+
+
   const sportControllers = {
     createSportController,
-    showAllSports
-  };
+    showAllSports,
+    deleteSportById,
+    updateSportById,
+    showSportByBoatId
+};
   
   export default sportControllers;
-  */
\ No newline at end of file
+  
\ No newline at end of file
diff --git a/server/src/routes/sport.routes.ts b/server/src/routes/sport.routes.ts
index 4e1bdec..ffc011d 100644
--- a/server/src/routes/sport.routes.ts
+++ b/server/src/routes/sport.routes.ts
@@ -1,4 +1,4 @@
-/* import { Router } from "express";
+import { Router } from "express";
 import { body } from "express-validator";
 import sportControllers from "../controllers/sport.controllers";
 import handleValidationResult from "../middleware/handleValidationResult";
@@ -13,14 +13,38 @@ sportRouter.get(
   sportControllers.showAllSports
 );
 
-//create sport
+//create a sport
 sportRouter.post(
   "/api/sport/",
   body("name").not().isEmpty(),
+  body("color").if(body("color").exists()).not().isEmpty(), //optional tags field
   handleValidationResult,
   validateToken,
   sportControllers.createSportController
 );
 
-export default sportRouter;
-*/
\ No newline at end of file
+//delete Sport by given id
+sportRouter.delete(
+  "/api/sport/:id",
+  validateToken,
+  sportControllers.deleteSportById,
+);
+
+//update a sport
+sportRouter.patch(
+  "/api/sport/:id/",
+  body("name").if(body("color").exists()).not().isEmpty(),
+  body("color").if(body("color").exists()).not().isEmpty(),
+  handleValidationResult,
+  validateToken,
+  sportControllers.updateSportById
+);
+
+//show sports assigned to boat id
+sportRouter.get(
+  "/api/sport/:id/",
+  validateToken,
+  sportControllers.showSportByBoatId
+);
+
+export default sportRouter;
\ No newline at end of file
diff --git a/server/src/server.ts b/server/src/server.ts
index 5616f3d..8d0120a 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -12,6 +12,7 @@ import boatsRouter from "./routes/boat.routes";
 import userRouter from "./routes/user.routes";
 import boatTypeRouter from "./routes/boatType.routes";
 import entryRouter from "./routes/createLogEntry.routes";
+import sportRouter from "./routes/sport.routes";
 
 let init = async () => {
   //DB
@@ -30,6 +31,8 @@ let init = async () => {
   app.use("/", userRouter);
   app.use("/", boatTypeRouter);
   app.use("/", entryRouter);
+  app.use("/", sportRouter);
+
   //DB-information section
   await showAllDBs(sequelize);
   await showTables(sequelize);
-- 
GitLab