fix mealplan

This commit is contained in:
hay-kot 2021-03-13 21:50:01 -09:00
commit 746d39815a
16 changed files with 121 additions and 85 deletions

View file

@ -79,6 +79,7 @@ export default {
this.$store.dispatch("requestHomePageSettings");
this.$store.dispatch("requestSiteSettings");
this.$store.dispatch("refreshToken");
this.$store.dispatch("requestCurrentGroup");
this.darkModeSystemCheck();
this.darkModeAddEventListener();
},

View file

@ -82,6 +82,7 @@
</template>
<script>
const CREATE_EVENT = "created";
import api from "@/api";
import utils from "@/utils";
import MealPlanCard from "./MealPlanCard";
@ -116,9 +117,8 @@ export default {
},
},
async mounted() {
let settings = await api.settings.requestAll();
this.items = await api.recipes.getAllByCategory(settings.planCategories);
console.log(this.items);
let categories = Array.from(this.groupSettings, x => x.name);
this.items = await api.recipes.getAllByCategory(categories);
if (this.items.length === 0) {
const keys = [
@ -134,6 +134,9 @@ export default {
},
computed: {
groupSettings() {
return this.$store.getters.getCurrentGroup;
},
actualStartDate() {
return Date.parse(this.startDate);
},
@ -146,7 +149,6 @@ export default {
let dateDif = (endDate - startDate) / (1000 * 3600 * 24) + 1;
if (dateDif < 1) {
return null;
}
@ -190,12 +192,13 @@ export default {
async save() {
const mealBody = {
group: this.groupSettings.name,
startDate: this.startDate,
endDate: this.endDate,
meals: this.meals,
};
await api.mealPlans.create(mealBody);
this.$emit("created");
this.$emit(CREATE_EVENT);
this.meals = [];
this.startDate = null;
this.endDate = null;

View file

@ -28,7 +28,7 @@ const actions = {
const getters = {
getGroups: state => state.groups,
getGroupNames: state => Array.from(state.groups, x => x.name),
getCurrentGroup: state => state.currentGroup
getCurrentGroup: state => state.currentGroup,
};
export default {

View file

@ -9,12 +9,12 @@ from db.init_db import init_db
from routes import (
backup_routes,
debug_routes,
meal_routes,
migration_routes,
setting_routes,
theme_routes,
)
from routes.groups import groups
from routes.mealplans import mealplans
from routes.recipe import (
all_recipe_routes,
category_routes,
@ -51,7 +51,7 @@ def api_routers():
app.include_router(recipe_crud_routes.router)
# Meal Routes
app.include_router(meal_routes.router)
app.include_router(mealplans.router)
# Settings Routes
app.include_router(setting_routes.router)
app.include_router(theme_routes.router)

View file

@ -3,6 +3,9 @@ from pathlib import Path
import dotenv
APP_VERSION = "v0.3.0"
DB_VERSION = "v0.3.0"
CWD = Path(__file__).parent
@ -19,8 +22,6 @@ dotenv.load_dotenv(ENV)
SECRET = "super-secret-key"
# General
APP_VERSION = "v0.3.0"
DB_VERSION = "v0.3.0"
PRODUCTION = os.environ.get("ENV")
PORT = int(os.getenv("mealie_port", 9000))
API = os.getenv("api_docs", True)
@ -83,7 +84,7 @@ else:
# Mongo Database
MEALIE_DB_NAME = os.getenv("mealie_db_name", "mealie")
DEFAULT_GROUP = os.getenv("default_group", "home")
DEFAULT_GROUP = os.getenv("default_group", "Home")
DB_USERNAME = os.getenv("db_username", "root")
DB_PASSWORD = os.getenv("db_password", "example")
DB_HOST = os.getenv("db_host", "mongo")

View file

@ -60,6 +60,10 @@ class Group(SqlAlchemyBase, BaseMixins):
self.__init__(session=session, *args, **kwargs)
@staticmethod
def get_ref(session: Session, name: str):
return session.query(Group).filter(Group.name == name).one()
@staticmethod
def create_if_not_exist(session, name: str = DEFAULT_GROUP):
try:

View file

@ -1,8 +1,8 @@
import uuid
from typing import List
import sqlalchemy as sa
import sqlalchemy.orm as orm
from db.models.group import Group
from db.models.model_base import BaseMixins, SqlAlchemyBase
@ -29,16 +29,25 @@ class MealPlanModel(SqlAlchemyBase, BaseMixins):
uid = sa.Column(sa.Integer, primary_key=True, unique=True) #! Probably Bad?
startDate = sa.Column(sa.Date)
endDate = sa.Column(sa.Date)
meals: List[Meal] = orm.relation(Meal)
meals: List[Meal] = orm.relationship(Meal, cascade="all, delete")
group_id = sa.Column(sa.String, sa.ForeignKey("groups.id"))
group = orm.relationship("Group", back_populates="mealplans")
def __init__(self, startDate, endDate, meals, uid=None, session=None) -> None:
def __init__(
self, startDate, endDate, meals, group: str, uid=None, session=None
) -> None:
self.startDate = startDate
self.endDate = endDate
self.group = Group.get_ref(session, group)
self.meals = [Meal(**meal) for meal in meals]
def update(self, session, startDate, endDate, meals, uid) -> None:
def update(self, session, startDate, endDate, meals, uid, group) -> None:
MealPlanModel._sql_remove_list(session, [Meal], uid)
self.__init__(startDate, endDate, meals)
self.__init__(
startDate=startDate,
endDate=endDate,
meals=meals,
group=group,
session=session,
)

View file

@ -1,44 +1,33 @@
from datetime import date
from typing import List
from db.database import db
from db.db_setup import generate_session
from fastapi import APIRouter, Depends
from schema.meal import MealPlanBase, MealPlanInDB
from schema.recipe import Recipe
from routes.deps import manager
from schema.meal import MealPlanIn, MealPlanInDB
from schema.snackbar import SnackResponse
from schema.user import GroupInDB, UserInDB
from services.meal_services import get_todays_meal, process_meals
from sqlalchemy.orm.session import Session
router = APIRouter(prefix="/api/meal-plans", tags=["Meal Plan"])
@router.get("/all", response_model=List[MealPlanInDB])
def get_all_meals(session: Session = Depends(generate_session)):
@router.get("/all", response_model=list[MealPlanInDB])
def get_all_meals(
current_user: UserInDB = Depends(manager),
session: Session = Depends(generate_session),
):
""" Returns a list of all available Meal Plan """
return db.meals.get_all(session)
@router.get("/{id}/shopping-list")
def get_shopping_list(id: str, session: Session = Depends(generate_session)):
#! Refactor into Single Database Call
mealplan = db.meals.get(session, id)
mealplan: MealPlanInDB
slugs = [x.slug for x in mealplan.meals]
recipes: list[Recipe] = [db.recipes.get(session, x) for x in slugs]
ingredients = [
{"name": x.name, "recipeIngredient": x.recipeIngredient}
for x in recipes
if x
]
return ingredients
print(current_user.group)
group_entry: GroupInDB = db.groups.get(session, current_user.group, "name")
return group_entry.mealplans
@router.post("/create")
def create_meal_plan(data: MealPlanBase, session: Session = Depends(generate_session)):
def create_meal_plan(
data: MealPlanIn,
session: Session = Depends(generate_session),
current_user=Depends(manager),
):
""" Creates a meal plan database entry """
processed_plan = process_meals(session, data)
db.meals.create(session, processed_plan.dict())
@ -46,16 +35,9 @@ def create_meal_plan(data: MealPlanBase, session: Session = Depends(generate_ses
return SnackResponse.success("Mealplan Created")
@router.get("/this-week", response_model=MealPlanInDB)
def get_this_week(session: Session = Depends(generate_session)):
""" Returns the meal plan data for this week """
return db.meals.get_all(session, limit=1, order_by="startDate")
@router.put("/{plan_id}")
def update_meal_plan(
plan_id: str, meal_plan: MealPlanBase, session: Session = Depends(generate_session)
plan_id: str, meal_plan: MealPlanIn, session: Session = Depends(generate_session)
):
""" Updates a meal plan based off ID """
processed_plan = process_meals(session, meal_plan)
@ -74,6 +56,13 @@ def delete_meal_plan(plan_id, session: Session = Depends(generate_session)):
return SnackResponse.error("Mealplan Deleted")
@router.get("/this-week", response_model=MealPlanInDB)
def get_this_week(session: Session = Depends(generate_session)):
""" Returns the meal plan data for this week """
return db.meals.get_all(session, limit=1, order_by="startDate")
@router.get("/today", tags=["Meal Plan"])
def get_today(session: Session = Depends(generate_session)):
"""

View file

@ -0,0 +1,23 @@
from db.database import db
from db.db_setup import generate_session
from fastapi import APIRouter, Depends
from schema.meal import MealPlanInDB
from schema.recipe import Recipe
from sqlalchemy.orm.session import Session
router = APIRouter(prefix="/api/meal-plans", tags=["Meal Plan"])
@router.get("/{id}/shopping-list")
def get_shopping_list(id: str, session: Session = Depends(generate_session)):
#! Refactor into Single Database Call
mealplan = db.meals.get(session, id)
mealplan: MealPlanInDB
slugs = [x.slug for x in mealplan.meals]
recipes: list[Recipe] = [db.recipes.get(session, x) for x in slugs]
ingredients = [
{"name": x.name, "recipeIngredient": x.recipeIngredient} for x in recipes if x
]
return ingredients

View file

@ -0,0 +1,7 @@
from fastapi import APIRouter
from routes.mealplans import crud, helpers
router = APIRouter()
router.include_router(crud.router)
router.include_router(helpers.router)

View file

@ -1,6 +1,5 @@
import shutil
from datetime import timedelta
from os import access
from core.config import USER_DIR
from core.security import get_password_hash, verify_password

View file

@ -1,7 +1,9 @@
from datetime import date
from typing import List, Optional
from db.models.mealplan import MealPlanModel
from pydantic import BaseModel, validator
from pydantic.utils import GetterDict
class MealIn(BaseModel):
@ -18,7 +20,8 @@ class MealOut(MealIn):
orm_mode = True
class MealPlanBase(BaseModel):
class MealPlanIn(BaseModel):
group: str
startDate: date
endDate: date
meals: List[MealIn]
@ -30,7 +33,7 @@ class MealPlanBase(BaseModel):
return v
class MealPlanProcessed(MealPlanBase):
class MealPlanProcessed(MealPlanIn):
meals: list[MealOut]
@ -40,18 +43,9 @@ class MealPlanInDB(MealPlanProcessed):
class Config:
orm_mode = True
class MealPlan(BaseModel):
uid: Optional[str]
class Config:
schema_extra = {
"example": {
"startDate": date.today(),
"endDate": date.today(),
"meals": [
{"slug": "Packed Mac and Cheese", "date": date.today()},
{"slug": "Eggs and Toast", "date": date.today()},
],
@classmethod
def getter_dict(_cls, name_orm: MealPlanModel):
return {
**GetterDict(name_orm),
"group": name_orm.group.name,
}
}

View file

@ -1,12 +1,12 @@
from datetime import date, timedelta
from db.database import db
from schema.meal import MealIn, MealOut, MealPlanBase, MealPlanProcessed
from schema.meal import MealIn, MealOut, MealPlanIn, MealPlanProcessed
from schema.recipe import Recipe
from sqlalchemy.orm.session import Session
def process_meals(session: Session, meal_plan_base: MealPlanBase) -> MealPlanProcessed:
def process_meals(session: Session, meal_plan_base: MealPlanIn) -> MealPlanProcessed:
meals = []
for x, meal in enumerate(meal_plan_base.meals):
meal: MealIn
@ -30,7 +30,10 @@ def process_meals(session: Session, meal_plan_base: MealPlanBase) -> MealPlanPro
meals.append(meal_data)
return MealPlanProcessed(
meals=meals, startDate=meal_plan_base.startDate, endDate=meal_plan_base.endDate
group=meal_plan_base.group,
meals=meals,
startDate=meal_plan_base.startDate,
endDate=meal_plan_base.endDate,
)

View file

@ -13,6 +13,7 @@ from tests.utils.routes import (
def get_meal_plan_template(first=None, second=None):
return {
"group": "Home",
"startDate": "2021-01-18",
"endDate": "2021-01-19",
"meals": [
@ -54,17 +55,17 @@ def slug_2(api_client):
api_client.delete(RECIPES_PREFIX + "/" + slug_2)
def test_create_mealplan(api_client, slug_1, slug_2):
def test_create_mealplan(api_client, slug_1, slug_2, token):
meal_plan = get_meal_plan_template()
meal_plan["meals"][0]["slug"] = slug_1
meal_plan["meals"][1]["slug"] = slug_2
response = api_client.post(MEALPLAN_CREATE, json=meal_plan)
response = api_client.post(MEALPLAN_CREATE, json=meal_plan, headers=token)
assert response.status_code == 200
def test_read_mealplan(api_client, slug_1, slug_2):
response = api_client.get(MEALPLAN_ALL)
def test_read_mealplan(api_client, slug_1, slug_2, token):
response = api_client.get(MEALPLAN_ALL, headers=token)
assert response.status_code == 200
@ -77,9 +78,9 @@ def test_read_mealplan(api_client, slug_1, slug_2):
assert meals[1]["slug"] == meal_plan["meals"][1]["slug"]
def test_update_mealplan(api_client, slug_1, slug_2):
def test_update_mealplan(api_client, slug_1, slug_2, token):
response = api_client.get(MEALPLAN_ALL)
response = api_client.get(MEALPLAN_ALL, headers=token)
existing_mealplan = json.loads(response.text)
existing_mealplan = existing_mealplan[0]
@ -89,11 +90,13 @@ def test_update_mealplan(api_client, slug_1, slug_2):
existing_mealplan["meals"][0]["slug"] = slug_2
existing_mealplan["meals"][1]["slug"] = slug_1
response = api_client.put(f"{MEALPLAN_PREFIX}/{plan_uid}", json=existing_mealplan)
response = api_client.put(
f"{MEALPLAN_PREFIX}/{plan_uid}", json=existing_mealplan, headers=token
)
assert response.status_code == 200
response = api_client.get(MEALPLAN_ALL)
response = api_client.get(MEALPLAN_ALL, headers=token)
existing_mealplan = json.loads(response.text)
existing_mealplan = existing_mealplan[0]
@ -101,8 +104,8 @@ def test_update_mealplan(api_client, slug_1, slug_2):
assert existing_mealplan["meals"][1]["slug"] == slug_1
def test_delete_mealplan(api_client):
response = api_client.get(MEALPLAN_ALL)
def test_delete_mealplan(api_client, token):
response = api_client.get(MEALPLAN_ALL, headers=token)
assert response.status_code == 200
existing_mealplan = json.loads(response.text)

View file

@ -16,7 +16,7 @@ def default_user():
"id": 1,
"fullName": "Change Me",
"email": "changeme@email.com",
"group": "home",
"group": "Home",
"admin": True
}
@ -27,7 +27,7 @@ def new_user():
"id": 2,
"fullName": "My New User",
"email": "newuser@email.com",
"group": "home",
"group": "Home",
"admin": False
}
@ -54,7 +54,7 @@ def test_create_user(api_client: requests, token, new_user):
"fullName": "My New User",
"email": "newuser@email.com",
"password": "MyStrongPassword",
"group": "home",
"group": "Home",
"admin": False
}
@ -78,7 +78,7 @@ def test_update_user(api_client: requests, token):
"id": 1,
"fullName": "Updated Name",
"email": "updated@email.com",
"group": "home",
"group": "Home",
"admin": True
}
response = api_client.put(f"{BASE}/1", headers=token, json=update_data)