import { Request, Response } from "express"; import BoatType from "../db/models/BoatType"; import Boat from "../db/models/Boat"; import Sport from "../db/models/Sport"; //create boat const createBoat = async (req: Request, res: Response) => { try { if (!(res.locals.user.role == "coordinator")) { return res .status(403) .json({ success: false, error: "MustBeCoordinator" }); } const newBoatInput = req.body; //check if boattype exists const boatType = await BoatType.findByPk(newBoatInput.boattype); if (!boatType) { return res .status(404) .json({ success: false, error: "boattypeNotFound" }); } //check if name of boat already exists const checkBoatName = await Boat.findOne({ where: { name: newBoatInput.name, }, }); if (!(checkBoatName === null)) { return res .status(409) .json({ success: false, error: "boatNameAlreadyExists" }); } //check if given sport-ids can be found const sportsArray = newBoatInput.sports; var check = true; //if sports provided in the request body if (!(sportsArray === undefined)) { //define empty array, where we store founded/not founded names of sports assigned to boat's id var listIfNotFound = new Array(); var listIfFound = new Array(); //check wether each new given id exists or not for (let i = 0; i < sportsArray.length; i++) { const found = await Sport.findByPk(sportsArray[i]); if (!found) { listIfNotFound.push(sportsArray[i]); var check = false; } if (found) { const showSportName = await ( await Sport.findByPk(sportsArray[i]) ).name; listIfFound.push(showSportName); } } } //if there is a sport, which isn't in the database, we return an array with the names of the missing sports if (check === false) { return res.status(404).json({ success: false, sports: listIfNotFound }); } //create the boat const newBoat = await Boat.create(newBoatInput); //another check if sports array was provided and it's with valid sport ids => create entry in BoatHasSport table with the new created boat id and corresponding sport is if (!(sportsArray == undefined)) { if (listIfFound.length === sportsArray.length) { const boatid = newBoat.id; //create entry (boatid, each id of given sportIds) for (let i = 0; i < sportsArray.length; i++) { const sportid = sportsArray[i]; const entry = { boatid, sportid }; //create new entry in boatHasBoatType //TODO: Replace //await BoatTypeHasSport.create(entry); } } } //return created boat + the assigned sports if (newBoat) { return res.status(201).json({ success: true, result: { id: newBoat.id, name: newBoat.name, status: newBoat.status, sports: listIfFound, }, }); } } catch (error) { console.error(error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; //show all boats const showAllBoatsController = async (req: Request, res: Response) => { try { const allBoats = await Boat.findAll(); return res.status(200).send({ success: true, result: allBoats.map((boat) => { return { id: boat.id, name: boat.name, status: boat.status, }; }), }); } catch (error) { console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; //show specific boat using given id const showBoatById = async (req: Request, res: Response) => { try { const givenId = req.params.id; const boat = await Boat.findByPk(givenId); if (boat) { return res.status(200).json({ success: true, result: { id: boat.id, name: boat.name, status: boat.status, }, }); } 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" }); } }; //delete specific boat using given id const deleteBoatById = async (req: Request, res: Response) => { try { const givenId = req.params.id; //first we need to destroy entries where the to-be-deleted boat is connected with sport in BoatHasSport table, because it violates the foreign constraint //TODO: Replace /*await BoatTypeHasSport.destroy({ where: { boattypeid: givenId, }, });*/ const boatToDelete = await Boat.destroy({ where: { id: givenId, }, }); if (boatToDelete == 0) { return res .status(404) .json({ success: false, error: "BoatIdDoesNotExist" }); } return res.status(200).json({ success: true }); } catch (error) { console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; //update boat by given id const updateBoatById = async (req: Request, res: Response) => { try { //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 boat can be found using givenId const foundBoat = await Boat.findByPk(givenId); if (!foundBoat) { return res.status(404).json({ success: false, error: "boatIdNotFound" }); } //check if name of boat already exists if (!(input.name === undefined)) { const checkBoatName = await Boat.findOne({ where: { name: input.name, }, }); if (!(checkBoatName === null)) { return res .status(409) .json({ success: false, error: "boatNameAlreadyExists" }); } } //we need to check if boattype is not null(wasn't provided in body), otherwise we have server error: Cannot read properties of undefined if (!(input.boattype === undefined)) { //check if new boattype can be found const checkBoatTypeId = await BoatType.findByPk(input.boattype); if (!checkBoatTypeId) { return res .status(404) .json({ success: false, error: "givenBoatTypeIdNotFound" }); } } //try to update the attributes, which are in Boat table const updatedBoat = await Boat.update(input, { where: { id: givenId, }, returning: true, }); //check if new given sport-ids can be found const newSportsArray = input.sports; if (!(newSportsArray === undefined)) { //define empty array, where we store founded/not founded id's of sports assigned to boat's id var listIfNotFound = new Array(); var listIfFound = new Array(); //help variable in order to return the Array with the sport ids, which weren't founded var check = true; //check wether each new given id exists or not for (let i = 0; i < newSportsArray.length; i++) { const found = await Sport.findByPk(newSportsArray[i]); // if not founded, push id's into listIfNotFound Array if (!found) { listIfNotFound.push(newSportsArray[i]); var check = false; } if (found) { //check if sport already assigned to boat, if yes continue, no need for error message //TODO: Replace /*const getBoatIdInBoatHasSport = await BoatTypeHasSport.findOne({ where: { boattypeid: givenId, sportid: newSportsArray[i], }, }); //if boat is not already assigned to existing sport id => put id into listIfFound if (getBoatIdInBoatHasSport === null) { listIfFound.push(newSportsArray[i]); }*/ } } //if the updated-to-be sportid(sportids) doesn't exist if (check === false) { return res.status(404).json({ success: false, sports: listIfNotFound }); } //if sports Array is with valid id's, assign them to boat; create entry (boatid, each id of given sportIds) inf BoatHasSport table for (let i = 0; i < listIfFound.length; i++) { const boatid = givenId; const sportid = listIfFound[i]; const entry = { boatid, sportid }; //create new entry in boatHasBoatType //TODO: Replace //await BoatTypeHasSport.create(entry); } } //get names of assigned sports to boat for the response message // help Array in order to print as response the name of the updated + previously added new sports to boat var listOfNames = new Array(); //TODO: Replace /*const findAllSportsAssignedToBoat = await BoatTypeHasSport.findAll({ where: { boattypeid: givenId, }, }); for (let i = 0; i < findAllSportsAssignedToBoat.length; i++) { const foundedSportName = await Sport.findByPk( findAllSportsAssignedToBoat[i].sportid ); listOfNames.push(foundedSportName.name); }*/ //we need this special case res, because sports is not an attribute assigned to Boat table, and if only sports provided as request body error happens // check if in the requested body only values for sports were provided if (Object.keys(input).length === 1 && !(input.sports === undefined)) { //return after updating return res.status(200).json({ success: true, result: { id: givenId, name: foundBoat.name, status: foundBoat.status, sports: listOfNames, }, }); } //case where in request body attributes from Boat provided + sports which is an attribute in Sport table and connection between Boat and Sport is saved in BoatHasSport table const boatDataAfterUpdate = updatedBoat[1][0]; return res.status(200).json({ success: true, result: { id: boatDataAfterUpdate.id, name: boatDataAfterUpdate.name, status: boatDataAfterUpdate.status, sports: listOfNames, }, }); } catch (error) { console.error("server error: ", error.message); return res.status(500).json({ success: false, error: "serverError" }); } }; const boatControllers = { showAllBoatsController, showBoatById, deleteBoatById, createBoat, updateBoatById, }; export default boatControllers;