diff --git a/README.md b/README.md index b077e4d..04ed462 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,16 @@ - ##### **location** - ##### **type**: _String_ (enum: ["Point"], required) - ##### **coordinates**: [Number] required + - ##### **placesId**: _String_ - ##### **imgUrl**: _String_ (required) - - ##### **workingHours**: _String_ (required) + - ##### **workingHours**: + - ##### **pn**: String + - ##### **wt**: String + - ##### **sr**: String + - ##### **cz**: String + - ##### **pt**: String + - ##### **sb**: String + - ##### **nd**: String - ##### **description**: _String_ - ##### **tags** - ##### **cardPayments**: _Boolean_ @@ -32,7 +40,6 @@ - ##### **delivery**: _Boolean_ - ##### **links** - ##### **facebook**: _String_ - - ##### **twitter**: _String_ - ##### **instagram**: _String_ - ##### **www**: _String_ - ##### **phone**: _Number_ @@ -40,6 +47,8 @@ - ##### **subscriptionActive**: _Boolean_ - ##### **subscriptionStarted**: _String_ - ##### **subscriptionDue**: _String_ + - ##### **categories**: [String] + - ##### **lunchMenu**: [*mongoose.Types.ObjectId*] - ##### **dishes**: [*mongoose.Types.ObjectId*]
@@ -63,6 +72,8 @@ - ##### **peanuts**: _Boolean_ - ##### **sesame**: _Boolean_ - ##### **ingredients**: [*String*] + - ##### **glicemicIndex**: String + - ##### **kCal**: String - ##### **vegan**: _Boolean_ - ##### **vegetarian**: _Boolean_
@@ -94,9 +105,18 @@ - #### **PUT** Takes in **dishId**, **restaurantId**, **dish** document, and a JWT **token (header)** and tries to update specified document in a database. Returns **304** on success. Else returns **204** on bad document, or **401** on bad token. - #### **DELETE** + Takes in **dishId**, and JWT **token (header)** and tries to remove specified dish from database. If everything goes OK, it returns **200**. +
+* ### **/dish/hidden** + + - #### **POST** + Takes a **dishId, visible(bool)** parameters, and JWT **token (header)**, tries to set dish visibility. Returns **200** on success. + +
+ * ### **/restaurant** - #### **GET** @@ -108,6 +128,20 @@
+ - ### **/restaurant/category** + + * #### **POST** + Takes a **restaurantId, category, action (add / delete)** parameters, and JWT **token (header)**, tries to create or remove a supplied category. + +
+ + - ### **/restaurant/lunch** + + * #### **POST** + Takes a **restaurantId, dishId, action (add / delete)** parameters, and JWT **token (header)**, tries to create or remove a supplied dish from/to the lunch menu. + +
+ - ### **/restaurant/dishes** - #### **GET** @@ -120,7 +154,7 @@ - #### **POST** - Takes a **restaurantId** parameter and a **JWT token(header)**, and tries to remove the restaurant from the database and from user. If successfull returns **200**, if failed returns error with a code. + Takes a **restaurantId** parameter **!!!should also check password!!!** and a **JWT token(header)**, and tries to remove the restaurant from the database and from user. If successfull returns **200**, if failed returns error with a code.
@@ -164,6 +198,14 @@
+* ### **/user/changepass** + + - #### **POST** + + Takes **token, email, newPass, pass** parameters and if everything checks out, changes user password to the supplied **newPass**. + +
+ - ### **/search** - #### **GET** diff --git a/models/restaurant.js b/models/restaurant.js index 7e50186..96eb84b 100644 --- a/models/restaurant.js +++ b/models/restaurant.js @@ -33,8 +33,13 @@ const restaurantSchema = mongoose.Schema({ type: String, }, workingHours: { - type: String, - required: true, + pn: String, + wt: String, + sr: String, + cz: String, + pt: String, + sb: String, + nd: String, }, description: { type: String, @@ -58,6 +63,8 @@ const restaurantSchema = mongoose.Schema({ subscriptionActive: Boolean, subscriptionStarted: Date, subscriptionDue: Date, + categories: [String], + lunchMenu: [mongoose.Types.ObjectId], dishes: [mongoose.Types.ObjectId], }); diff --git a/models/users.js b/models/users.js index 7ac5546..07f72b2 100644 --- a/models/users.js +++ b/models/users.js @@ -38,6 +38,7 @@ const userSchema = mongoose.Schema({ }, }, restaurants: [mongoose.Types.ObjectId], + trialUsed: Boolean, }); export default mongoose.model("User", userSchema); diff --git a/routes/routeDish.js b/routes/routeDish.js index 567c54b..0491c91 100644 --- a/routes/routeDish.js +++ b/routes/routeDish.js @@ -3,8 +3,15 @@ import { createDish } from "../services/dataPrepServices.js"; import { removeDish, addDishToRestaurant, + setDishVisibility, } from "../services/databaseServices.js"; -import * as services from "../services/services.js"; +import { + validateRestaurant, + validateUserToken, + validateDishId, + handleError, + verifyDishAccess, +} from "../services/services.js"; import Dish from "../models/dish.js"; var router = express.Router(); @@ -23,15 +30,29 @@ router.get("/", (req, res) => { router.post("/", async (req, res) => { try { - await services.validateRestaurant(req.body.restaurantId); + await validateRestaurant(req.body.restaurantId); const token = req.headers["x-auth-token"]; - services.validateUserToken(token); + validateUserToken(token); const dish = createDish(req.body.dish, req.body.restaurantId, true); await dish.save(); await addDishToRestaurant(req.body.restaurantId, dish._id); res.status(201).send(dish._id); } catch (error) { - services.handleError(error, res); + handleError(error, res); + } +}); + +// HIDE, UNHIDE DISH + +router.post("/hidden", async (req, res) => { + try { + await validateDishId(req.body.dishId); + const token = req.headers["x-auth-token"]; + validateUserToken(token); + await setDishVisibility(req.body.dishId, req.body.visible); + res.sendStatus(200); + } catch (error) { + handleError(error, res); } }); @@ -39,14 +60,14 @@ router.post("/", async (req, res) => { router.delete("/", async (req, res) => { try { - await services.validateDishId(req.body.dishId); + await validateDishId(req.body.dishId); const token = req.headers["x-auth-token"]; - const decodedToken = services.validateUserToken(token); - await services.verifyDishAccess(req.body.dishId, decodedToken); + const decodedToken = validateUserToken(token); + await verifyDishAccess(req.body.dishId, decodedToken); await removeDish(req.body.dishId); res.sendStatus(200); } catch (error) { - services.handleError(error, res); + handleError(error, res); } }); @@ -54,14 +75,14 @@ router.delete("/", async (req, res) => { router.put("/", async (req, res) => { try { - await services.validateDishId(req.body.dishId); + await validateDishId(req.body.dishId); const token = req.headers["x-auth-token"]; - services.validateUserToken(token); + validateUserToken(token); const dish = createDish(req.body.dish, req.body.restaurantId, false); await Dish.replaceOne({ _id: req.body.dishId }, dish); res.sendStatus(200); } catch (error) { - services.handleError(error, res); + handleError(error, res); } }); diff --git a/routes/routeRestaurant.js b/routes/routeRestaurant.js index 94a17a5..abd4535 100644 --- a/routes/routeRestaurant.js +++ b/routes/routeRestaurant.js @@ -5,6 +5,8 @@ import { fetchRestaurant, fetchAllDishesForRestaurant, removeRestaurant, + changeCategory, + changeLunchMenu, } from "../services/databaseServices.js"; import { decodeAndSanitize, @@ -76,6 +78,44 @@ router.get("/dishes", async (req, res) => { } }); +// CHANGE CATEGORY + +router.post("/category", async (req, res) => { + try { + const token = req.headers["x-auth-token"]; + const user = validateUserToken(token); + await validateRestaurant(req.body.restaurantId); + await verifyRestaurantAccess(req.body.restaurantId, user); + await changeCategory( + req.body.restaurantId, + req.body.category, + req.body.action + ); + res.send("Kategoria zmieniona pomyślnie"); + } catch (error) { + handleError(error, res); + } +}); + +// CHANGE LUNCH MENU + +router.post("/lunch", async (req, res) => { + try { + const token = req.headers["x-auth-token"]; + const user = validateUserToken(token); + await validateRestaurant(req.body.restaurantId); + await verifyRestaurantAccess(req.body.restaurantId, user); + await changeLunchMenu( + req.body.restaurantId, + req.body.dishId, + req.body.action + ); + res.send("Lunch menu zmienione pomyślnie."); + } catch (error) { + handleError(error, res); + } +}); + // DELETE RESTAURANT router.post("/delete", async (req, res) => { diff --git a/routes/routeTest.js b/routes/routeTest.js index 7fd27f0..6b38e9f 100644 --- a/routes/routeTest.js +++ b/routes/routeTest.js @@ -1,16 +1,10 @@ import express from "express"; -import * as services from "../services/services.js"; -import * as databaseServices from "../services/databaseServices.js"; var router = express.Router(); router.post("/", async (req, res) => { try { - const newDate = await databaseServices.renewSubscription( - req.body.restaurantId, - 1 - ); - res.send(`Subskrypcja przedłużona do: ${newDate}`); + console.log("test"); } catch (error) { services.handleError(error, res); } diff --git a/services/databaseServices.js b/services/databaseServices.js index b917282..48c7c2e 100644 --- a/services/databaseServices.js +++ b/services/databaseServices.js @@ -104,6 +104,72 @@ export async function renewSubscription(restaurantId, monthsToAdd) { return dueDateBasedOnSubscription(restaurant, monthsToAdd); } +async function checkIfCategoryExists(restaurant, category) { + const categories = restaurant.categories; + if (categories.includes(category)) { + throw newError("Podana kategoria już istnieje", 200); + } +} + +async function checkIfAlreadyInLunchMenu(restaurant, dishId) { + const lunchMenu = restaurant.lunchMenu; + if (lunchMenu.includes(dishId)) { + throw newError("Podane danie jest już w lunch menu", 200); + } +} + +export async function changeCategory(restaurantId, categoryName, action) { + if (action === "add") { + const restaurant = await Restaurant.findById(restaurantId).catch((err) => { + throw newError("Nie udało się pobrać restauracji.", 404); + }); + await checkIfCategoryExists(restaurant, categoryName); + await Restaurant.findByIdAndUpdate(restaurantId, { + $push: { categories: categoryName }, + }).catch((e) => { + throw newError("Nie udało się dodać kategorii.", 500); + }); + } else if (action === "delete") { + await Restaurant.findByIdAndUpdate(restaurantId, { + $pull: { categories: categoryName }, + }).catch((e) => { + throw newError("Nie udało się usunąć kategorii.", 500); + }); + } else { + throw newError("Nieznany błąd.", 500); + } +} + +export async function setDishVisibility(dishId, visible) { + await Dish.findByIdAndUpdate(dishId, { $set: { hidden: !visible } }).catch( + (e) => { + throw newError("Nie udało się zmienić dania.", 500); + } + ); +} + +export async function changeLunchMenu(restaurantId, dishId, action) { + if (action === "add") { + const restaurant = await Restaurant.findById(restaurantId).catch((err) => { + throw newError("Nie udało się pobrać restauracji.", 404); + }); + await checkIfAlreadyInLunchMenu(restaurant, dishId); + await Restaurant.findByIdAndUpdate(restaurantId, { + $push: { lunchMenu: dishId }, + }).catch((e) => { + throw newError("Nie udało się dodać dania do lunch menu.", 500); + }); + } else if (action === "delete") { + await Restaurant.findByIdAndUpdate(restaurantId, { + $pull: { lunchMenu: dishId }, + }).catch((e) => { + throw newError("Nie udało się usunąć dania.", 500); + }); + } else { + throw newError("Nie sprecyzowano akcji", 500); + } +} + export async function fetchRestaurant(id) { const data = await Restaurant.findById(id).catch((e) => { throw newError("Nie udało się pobrać restauracji.", 500);