food inherit attributes
This commit is contained in:
parent
4377505b14
commit
fbe748db62
@ -45,8 +45,7 @@ class UserPreferenceForm(forms.ModelForm):
|
|||||||
fields = (
|
fields = (
|
||||||
'default_unit', 'use_fractions', 'use_kj', 'theme', 'nav_color',
|
'default_unit', 'use_fractions', 'use_kj', 'theme', 'nav_color',
|
||||||
'sticky_navbar', 'default_page', 'show_recent', 'search_style',
|
'sticky_navbar', 'default_page', 'show_recent', 'search_style',
|
||||||
'plan_share', 'shopping_share', 'ingredient_decimals', 'shopping_auto_sync',
|
'plan_share', 'ingredient_decimals', 'comments',
|
||||||
'comments'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
@ -93,7 +92,8 @@ class UserPreferenceForm(forms.ModelForm):
|
|||||||
|
|
||||||
widgets = {
|
widgets = {
|
||||||
'plan_share': MultiSelectWidget,
|
'plan_share': MultiSelectWidget,
|
||||||
'shopping_share': MultiSelectWidget
|
'shopping_share': MultiSelectWidget,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
# Generated by Django 3.2.7 on 2021-10-01 22:34
|
# Generated by Django 3.2.7 on 2021-10-01 22:34
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
|
||||||
from django.utils.timezone import utc
|
from django.utils.timezone import utc
|
||||||
|
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
from cookbook.models import ShoppingListEntry
|
|
||||||
|
from cookbook.models import FoodInheritField, ShoppingListEntry
|
||||||
|
|
||||||
|
|
||||||
def delete_orphaned_sle(apps, schema_editor):
|
def delete_orphaned_sle(apps, schema_editor):
|
||||||
@ -16,6 +17,15 @@ def delete_orphaned_sle(apps, schema_editor):
|
|||||||
ShoppingListEntry.objects.filter(shoppinglist=None).delete()
|
ShoppingListEntry.objects.filter(shoppinglist=None).delete()
|
||||||
|
|
||||||
|
|
||||||
|
def create_inheritfields(apps, schema_editor):
|
||||||
|
FoodInheritField.objects.create(name='Supermarket Category', field='supermarket_category')
|
||||||
|
FoodInheritField.objects.create(name='Ignore Shopping', field='ignore_shopping')
|
||||||
|
FoodInheritField.objects.create(name='Diet', field='diet')
|
||||||
|
FoodInheritField.objects.create(name='Substitute', field='substitute')
|
||||||
|
FoodInheritField.objects.create(name='Substitute Children', field='substitute_children')
|
||||||
|
FoodInheritField.objects.create(name='Substitute Siblings', field='substitute_siblings')
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -25,4 +35,5 @@ class Migration(migrations.Migration):
|
|||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RunPython(delete_orphaned_sle),
|
migrations.RunPython(delete_orphaned_sle),
|
||||||
|
migrations.RunPython(create_inheritfields),
|
||||||
]
|
]
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
# Generated by Django 3.2.7 on 2021-10-14 22:36
|
|
||||||
|
|
||||||
import cookbook.models
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('cookbook', '0161_alter_shoppinglistentry_list_recipe'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='FoodParentIgnore',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('field', models.CharField(max_length=32, unique=True)),
|
|
||||||
('name', models.CharField(max_length=64, unique=True)),
|
|
||||||
],
|
|
||||||
bases=(models.Model, cookbook.models.PermissionModelMixin),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='food',
|
|
||||||
name='child_inherit',
|
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='userpreference',
|
|
||||||
name='food_inherit',
|
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='userpreference',
|
|
||||||
name='mealplan_autoinclude_related',
|
|
||||||
field=models.BooleanField(default=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='food',
|
|
||||||
name='ignore_parent',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='ignore_parent', to='cookbook.FoodParentIgnore'),
|
|
||||||
),
|
|
||||||
]
|
|
@ -1,24 +0,0 @@
|
|||||||
from cookbook.models import FoodParentIgnore
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
def create_ignorefields(apps, schema_editor):
|
|
||||||
FoodParentIgnore.objects.create(name='Supermarket Category', field='name')
|
|
||||||
FoodParentIgnore.objects.create(name='Ignore Shopping', field='ignore_shopping')
|
|
||||||
FoodParentIgnore.objects.create(name='Diet', field='diet')
|
|
||||||
FoodParentIgnore.objects.create(name='Substitute', field='substitute')
|
|
||||||
FoodParentIgnore.objects.create(name='Substitute Children', field='substitute_children')
|
|
||||||
FoodParentIgnore.objects.create(name='Substitute Siblings', field='substitute_siblings')
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('cookbook', '0162_food_inherit'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RunPython(
|
|
||||||
create_ignorefields
|
|
||||||
),
|
|
||||||
]
|
|
@ -15,9 +15,7 @@ from django.core.files.uploadedfile import InMemoryUploadedFile, UploadedFile
|
|||||||
from django.core.validators import MinLengthValidator
|
from django.core.validators import MinLengthValidator
|
||||||
from django.db import IntegrityError, models
|
from django.db import IntegrityError, models
|
||||||
from django.db.models import Index, ProtectedError, Q, Subquery
|
from django.db.models import Index, ProtectedError, Q, Subquery
|
||||||
from django.db.models.fields.related import ManyToManyField
|
|
||||||
from django.db.models.functions import Substr
|
from django.db.models.functions import Substr
|
||||||
from django.db.transaction import atomic
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django_prometheus.models import ExportModelOperationsMixin
|
from django_prometheus.models import ExportModelOperationsMixin
|
||||||
@ -329,7 +327,6 @@ class UserPreference(models.Model, PermissionModelMixin):
|
|||||||
mealplan_autoadd_shopping = models.BooleanField(default=False)
|
mealplan_autoadd_shopping = models.BooleanField(default=False)
|
||||||
mealplan_autoexclude_onhand = models.BooleanField(default=True)
|
mealplan_autoexclude_onhand = models.BooleanField(default=True)
|
||||||
mealplan_autoinclude_related = models.BooleanField(default=True)
|
mealplan_autoinclude_related = models.BooleanField(default=True)
|
||||||
food_inherit = models.BooleanField(default=False)
|
|
||||||
|
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
space = models.ForeignKey(Space, on_delete=models.CASCADE, null=True)
|
space = models.ForeignKey(Space, on_delete=models.CASCADE, null=True)
|
||||||
@ -473,18 +470,6 @@ class Unit(ExportModelOperationsMixin('unit'), models.Model, PermissionModelMixi
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class FoodParentIgnore(models.Model, PermissionModelMixin):
|
|
||||||
field = models.CharField(max_length=32, unique=True)
|
|
||||||
name = models.CharField(max_length=64, unique=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return _(self.name)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_name(self):
|
|
||||||
return _(self.name)
|
|
||||||
|
|
||||||
|
|
||||||
class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
|
class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
|
||||||
# exclude fields not implemented yet
|
# exclude fields not implemented yet
|
||||||
inherit_fields = FoodInheritField.objects.exclude(field__in=['diet', 'substitute', 'substitute_children', 'substitute_siblings'])
|
inherit_fields = FoodInheritField.objects.exclude(field__in=['diet', 'substitute', 'substitute_children', 'substitute_siblings'])
|
||||||
@ -498,8 +483,8 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
|
|||||||
ignore_shopping = models.BooleanField(default=False)
|
ignore_shopping = models.BooleanField(default=False)
|
||||||
description = models.TextField(default='', blank=True)
|
description = models.TextField(default='', blank=True)
|
||||||
on_hand = models.BooleanField(default=False)
|
on_hand = models.BooleanField(default=False)
|
||||||
child_inherit = models.BooleanField(default=False)
|
inherit = models.BooleanField(default=False)
|
||||||
ignore_parent = models.ManyToManyField(FoodParentIgnore, related_name="ignore_parent", blank=True)
|
ignore_inherit = models.ManyToManyField(FoodInheritField, blank=True) # is this better as inherit instead of ignore inherit? which is more intuitive?
|
||||||
|
|
||||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||||
objects = ScopedManager(space='space', _manager_class=TreeManager)
|
objects = ScopedManager(space='space', _manager_class=TreeManager)
|
||||||
@ -858,7 +843,16 @@ class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), model
|
|||||||
objects = ScopedManager(space='space')
|
objects = ScopedManager(space='space')
|
||||||
|
|
||||||
@ classmethod
|
@ classmethod
|
||||||
def list_from_recipe(self, recipe=None, mealplan=None, servings=None, ingredients=None, created_by=None, space=None):
|
def list_from_recipe(self, list_recipe=None, recipe=None, mealplan=None, servings=None, ingredients=None, created_by=None, space=None):
|
||||||
|
"""
|
||||||
|
Creates ShoppingListRecipe and associated ShoppingListEntrys from a recipe or a meal plan with a recipe
|
||||||
|
:param list_recipe: Modify an existing ShoppingListRecipe
|
||||||
|
:param recipe: Recipe to use as list of ingredients. One of [recipe, mealplan] are required
|
||||||
|
:param mealplan: alternatively use a mealplan recipe as source of ingredients
|
||||||
|
:param servings: Optional: Number of servings to use to scale shoppinglist. If servings = 0 an existing recipe list will be deleted
|
||||||
|
:param ingredients: Ingredients, list of ingredient IDs to include on the shopping list. When not provided all ingredients will be used
|
||||||
|
"""
|
||||||
|
# TODO cascade to associated recipes
|
||||||
try:
|
try:
|
||||||
r = recipe or mealplan.recipe
|
r = recipe or mealplan.recipe
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -12,12 +12,13 @@ from drf_writable_nested import UniqueFieldsMixin, WritableNestedModelSerializer
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.exceptions import NotFound, ValidationError
|
from rest_framework.exceptions import NotFound, ValidationError
|
||||||
|
|
||||||
from cookbook.models import (Automation, BookmarkletImport, Comment, CookLog, Food, ImportLog,
|
from cookbook.models import (Automation, BookmarkletImport, Comment, CookLog, Food,
|
||||||
Ingredient, Keyword, MealPlan, MealType, NutritionInformation, Recipe,
|
FoodInheritField, ImportLog, Ingredient, Keyword, MealPlan, MealType,
|
||||||
RecipeBook, RecipeBookEntry, RecipeImport, ShareLink, ShoppingList,
|
NutritionInformation, Recipe, RecipeBook, RecipeBookEntry,
|
||||||
ShoppingListEntry, ShoppingListRecipe, Step, Storage, Supermarket,
|
RecipeImport, ShareLink, ShoppingList, ShoppingListEntry,
|
||||||
SupermarketCategory, SupermarketCategoryRelation, Sync, SyncLog, Unit,
|
ShoppingListRecipe, Step, Storage, Supermarket, SupermarketCategory,
|
||||||
UserFile, UserPreference, ViewLog)
|
SupermarketCategoryRelation, Sync, SyncLog, Unit, UserFile,
|
||||||
|
UserPreference, ViewLog)
|
||||||
from cookbook.templatetags.custom_tags import markdown
|
from cookbook.templatetags.custom_tags import markdown
|
||||||
|
|
||||||
|
|
||||||
@ -129,19 +130,12 @@ class UserNameSerializer(WritableNestedModelSerializer):
|
|||||||
fields = ('id', 'username')
|
fields = ('id', 'username')
|
||||||
|
|
||||||
|
|
||||||
class FoodInheritFieldSerializer(UniqueFieldsMixin):
|
class FoodInheritFieldSerializer(UniqueFieldsMixin, serializers.ModelSerializer):
|
||||||
|
|
||||||
def create(self, validated_data):
|
|
||||||
# don't allow writing to FoodInheritField via API
|
|
||||||
return FoodInheritField.objects.get(**validated_data)
|
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
|
||||||
# don't allow writing to FoodInheritField via API
|
|
||||||
return FoodInheritField.objects.get(**validated_data)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = FoodInheritField
|
model = FoodInheritField
|
||||||
fields = ['id', 'name', 'field', ]
|
fields = ['id', 'name', 'field', ]
|
||||||
|
read_only_fields = ('id', 'name', 'field', )
|
||||||
|
|
||||||
|
|
||||||
class UserPreferenceSerializer(serializers.ModelSerializer):
|
class UserPreferenceSerializer(serializers.ModelSerializer):
|
||||||
@ -161,7 +155,7 @@ class UserPreferenceSerializer(serializers.ModelSerializer):
|
|||||||
fields = (
|
fields = (
|
||||||
'user', 'theme', 'nav_color', 'default_unit', 'default_page',
|
'user', 'theme', 'nav_color', 'default_unit', 'default_page',
|
||||||
'search_style', 'show_recent', 'plan_share', 'ingredient_decimals',
|
'search_style', 'show_recent', 'plan_share', 'ingredient_decimals',
|
||||||
'comments', 'shopping_auto_sync', 'mealplan_autoadd_shopping'
|
'comments', 'shopping_auto_sync', 'mealplan_autoadd_shopping', 'food_ignore_default'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -367,7 +361,7 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
|
|||||||
supermarket_category = SupermarketCategorySerializer(allow_null=True, required=False)
|
supermarket_category = SupermarketCategorySerializer(allow_null=True, required=False)
|
||||||
recipe = RecipeSimpleSerializer(allow_null=True, required=False)
|
recipe = RecipeSimpleSerializer(allow_null=True, required=False)
|
||||||
shopping = serializers.SerializerMethodField('get_shopping_status')
|
shopping = serializers.SerializerMethodField('get_shopping_status')
|
||||||
ignore_inherit = FoodInheritFieldSerializer(allow_null=True, many=True, required=False)
|
ignore_inherit = FoodInheritFieldSerializer(allow_null=True, required=False, many=True)
|
||||||
|
|
||||||
recipe_filter = 'steps__ingredients__food'
|
recipe_filter = 'steps__ingredients__food'
|
||||||
|
|
||||||
@ -403,7 +397,7 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
|
|||||||
model = Food
|
model = Food
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'name', 'description', 'shopping', 'recipe', 'ignore_shopping', 'supermarket_category',
|
'id', 'name', 'description', 'shopping', 'recipe', 'ignore_shopping', 'supermarket_category',
|
||||||
'image', 'parent', 'numchild', 'numrecipe', 'on_hand', 'child_inherit', 'ignore_parent'
|
'image', 'parent', 'numchild', 'numrecipe', 'on_hand', 'inherit', 'ignore_inherit'
|
||||||
)
|
)
|
||||||
read_only_fields = ('id', 'numchild', 'parent', 'image', 'numrecipe')
|
read_only_fields = ('id', 'numchild', 'parent', 'image', 'numrecipe')
|
||||||
|
|
||||||
@ -930,13 +924,3 @@ class FoodShoppingUpdateSerializer(serializers.ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Recipe
|
model = Recipe
|
||||||
fields = ['id', 'amount', 'unit', 'delete', ]
|
fields = ['id', 'amount', 'unit', 'delete', ]
|
||||||
|
|
||||||
|
|
||||||
class FoodParentIgnoreSerializer(serializers.ModelSerializer):
|
|
||||||
field = serializers.CharField()
|
|
||||||
name = serializers.CharField()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Recipe
|
|
||||||
fields = ['id', 'name', 'field', ]
|
|
||||||
read_only_fields = ('id', 'name', 'field', )
|
|
||||||
|
@ -48,7 +48,6 @@ def update_step_search_vector(sender, instance=None, created=False, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Food)
|
@receiver(post_save, sender=Food)
|
||||||
@skip_signal
|
|
||||||
def update_food_inheritance(sender, instance=None, created=False, **kwargs):
|
def update_food_inheritance(sender, instance=None, created=False, **kwargs):
|
||||||
if not instance:
|
if not instance:
|
||||||
return
|
return
|
||||||
|
@ -19,7 +19,7 @@ router.register(r'automation', api.AutomationViewSet)
|
|||||||
router.register(r'bookmarklet-import', api.BookmarkletImportViewSet)
|
router.register(r'bookmarklet-import', api.BookmarkletImportViewSet)
|
||||||
router.register(r'cook-log', api.CookLogViewSet)
|
router.register(r'cook-log', api.CookLogViewSet)
|
||||||
router.register(r'food', api.FoodViewSet)
|
router.register(r'food', api.FoodViewSet)
|
||||||
router.register(r'food-inherit-ignore', api.FoodParentIgnoreViewSet)
|
router.register(r'food-inherit-field', api.FoodInheritFieldViewSet)
|
||||||
router.register(r'import-log', api.ImportLogViewSet)
|
router.register(r'import-log', api.ImportLogViewSet)
|
||||||
router.register(r'ingredient', api.IngredientViewSet)
|
router.register(r'ingredient', api.IngredientViewSet)
|
||||||
router.register(r'keyword', api.KeywordViewSet)
|
router.register(r'keyword', api.KeywordViewSet)
|
||||||
|
@ -39,7 +39,7 @@ from cookbook.helper.recipe_html_import import get_recipe_from_source
|
|||||||
from cookbook.helper.recipe_search import get_facet, old_search, search_recipes
|
from cookbook.helper.recipe_search import get_facet, old_search, search_recipes
|
||||||
from cookbook.helper.recipe_url_import import get_from_scraper
|
from cookbook.helper.recipe_url_import import get_from_scraper
|
||||||
from cookbook.helper.shopping_helper import shopping_helper
|
from cookbook.helper.shopping_helper import shopping_helper
|
||||||
from cookbook.models import (Automation, BookmarkletImport, CookLog, Food, FoodParentIgnore,
|
from cookbook.models import (Automation, BookmarkletImport, CookLog, Food, FoodInheritField,
|
||||||
ImportLog, Ingredient, Keyword, MealPlan, MealType, Recipe, RecipeBook,
|
ImportLog, Ingredient, Keyword, MealPlan, MealType, Recipe, RecipeBook,
|
||||||
RecipeBookEntry, ShareLink, ShoppingList, ShoppingListEntry,
|
RecipeBookEntry, ShareLink, ShoppingList, ShoppingListEntry,
|
||||||
ShoppingListRecipe, Step, Storage, Supermarket, SupermarketCategory,
|
ShoppingListRecipe, Step, Storage, Supermarket, SupermarketCategory,
|
||||||
@ -50,7 +50,7 @@ from cookbook.provider.local import Local
|
|||||||
from cookbook.provider.nextcloud import Nextcloud
|
from cookbook.provider.nextcloud import Nextcloud
|
||||||
from cookbook.schemas import FilterSchema, QueryParam, QueryParamAutoSchema, TreeSchema
|
from cookbook.schemas import FilterSchema, QueryParam, QueryParamAutoSchema, TreeSchema
|
||||||
from cookbook.serializer import (AutomationSerializer, BookmarkletImportSerializer,
|
from cookbook.serializer import (AutomationSerializer, BookmarkletImportSerializer,
|
||||||
CookLogSerializer, FoodParentIgnoreSerializer, FoodSerializer,
|
CookLogSerializer, FoodInheritFieldSerializer, FoodSerializer,
|
||||||
FoodShoppingUpdateSerializer, ImportLogSerializer,
|
FoodShoppingUpdateSerializer, ImportLogSerializer,
|
||||||
IngredientSerializer, KeywordSerializer, MealPlanSerializer,
|
IngredientSerializer, KeywordSerializer, MealPlanSerializer,
|
||||||
MealTypeSerializer, RecipeBookEntrySerializer,
|
MealTypeSerializer, RecipeBookEntrySerializer,
|
||||||
@ -393,14 +393,14 @@ class UnitViewSet(viewsets.ModelViewSet, MergeMixin, FuzzyFilterMixin):
|
|||||||
pagination_class = DefaultPagination
|
pagination_class = DefaultPagination
|
||||||
|
|
||||||
|
|
||||||
class FoodParentIgnoreViewSet(viewsets.ReadOnlyModelViewSet):
|
class FoodInheritFieldViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
queryset = FoodParentIgnore.objects
|
queryset = FoodInheritField.objects
|
||||||
serializer_class = FoodParentIgnoreSerializer
|
serializer_class = FoodInheritFieldSerializer
|
||||||
permission_classes = [CustomIsUser]
|
permission_classes = [CustomIsUser]
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
# exclude fields not yet implemented
|
# exclude fields not yet implemented
|
||||||
return self.queryset.exclude(field__in=['diet', 'substitute', 'substitute_children', 'substitute_siblings'])
|
return Food.inherit_fields
|
||||||
|
|
||||||
|
|
||||||
class FoodViewSet(viewsets.ModelViewSet, TreeMixin):
|
class FoodViewSet(viewsets.ModelViewSet, TreeMixin):
|
||||||
|
@ -64,7 +64,7 @@ import { BootstrapVue } from "bootstrap-vue"
|
|||||||
|
|
||||||
import "bootstrap-vue/dist/bootstrap-vue.css"
|
import "bootstrap-vue/dist/bootstrap-vue.css"
|
||||||
|
|
||||||
import { CardMixin, ApiMixin, getConfig, StandardToasts } from "@/utils/utils"
|
import { CardMixin, ApiMixin, getConfig, StandardToasts, getUserPreference } from "@/utils/utils"
|
||||||
|
|
||||||
import GenericInfiniteCards from "@/components/GenericInfiniteCards"
|
import GenericInfiniteCards from "@/components/GenericInfiniteCards"
|
||||||
import GenericHorizontalCard from "@/components/GenericHorizontalCard"
|
import GenericHorizontalCard from "@/components/GenericHorizontalCard"
|
||||||
|
@ -74,7 +74,18 @@ export class Models {
|
|||||||
// REQUIRED: unordered array of fields that can be set during create
|
// REQUIRED: unordered array of fields that can be set during create
|
||||||
create: {
|
create: {
|
||||||
// if not defined partialUpdate will use the same parameters, prepending 'id'
|
// if not defined partialUpdate will use the same parameters, prepending 'id'
|
||||||
params: [["name", "description", "recipe", "ignore_shopping", "supermarket_category", "on_hand", "inherit", "ignore_inherit"]],
|
params: [
|
||||||
|
[
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"recipe",
|
||||||
|
"ignore_shopping",
|
||||||
|
"supermarket_category",
|
||||||
|
"on_hand",
|
||||||
|
"inherit",
|
||||||
|
"ignore_inherit",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
form: {
|
form: {
|
||||||
name: {
|
name: {
|
||||||
@ -404,16 +415,35 @@ export class Models {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static RECIPE = {
|
static RECIPE = {
|
||||||
'name': i18n.t('Recipe'),
|
name: i18n.t("Recipe"),
|
||||||
'apiName': 'Recipe',
|
apiName: "Recipe",
|
||||||
'list': {
|
list: {
|
||||||
'params': ['query', 'keywords', 'foods', 'units', 'rating', 'books', 'keywordsOr', 'foodsOr', 'booksOr', 'internal', 'random', '_new', 'page', 'pageSize', 'options'],
|
params: [
|
||||||
|
"query",
|
||||||
|
"keywords",
|
||||||
|
"foods",
|
||||||
|
"units",
|
||||||
|
"rating",
|
||||||
|
"books",
|
||||||
|
"keywordsOr",
|
||||||
|
"foodsOr",
|
||||||
|
"booksOr",
|
||||||
|
"internal",
|
||||||
|
"random",
|
||||||
|
"_new",
|
||||||
|
"page",
|
||||||
|
"pageSize",
|
||||||
|
"options",
|
||||||
|
],
|
||||||
// 'config': {
|
// 'config': {
|
||||||
// 'foods': {'type': 'string'},
|
// 'foods': {'type': 'string'},
|
||||||
// 'keywords': {'type': 'string'},
|
// 'keywords': {'type': 'string'},
|
||||||
// 'books': {'type': 'string'},
|
// 'books': {'type': 'string'},
|
||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
|
shopping: {
|
||||||
|
params: ["id", ["id", "list_recipe", "ingredients", "servings"]],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
static USER_NAME = {
|
static USER_NAME = {
|
||||||
|
@ -239,6 +239,68 @@ export interface Food {
|
|||||||
* @memberof Food
|
* @memberof Food
|
||||||
*/
|
*/
|
||||||
on_hand?: boolean;
|
on_hand?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof Food
|
||||||
|
*/
|
||||||
|
inherit?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<FoodIgnoreInherit>}
|
||||||
|
* @memberof Food
|
||||||
|
*/
|
||||||
|
ignore_inherit?: Array<FoodIgnoreInherit> | null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface FoodIgnoreInherit
|
||||||
|
*/
|
||||||
|
export interface FoodIgnoreInherit {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof FoodIgnoreInherit
|
||||||
|
*/
|
||||||
|
id?: number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof FoodIgnoreInherit
|
||||||
|
*/
|
||||||
|
name?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof FoodIgnoreInherit
|
||||||
|
*/
|
||||||
|
field?: string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface FoodInheritField
|
||||||
|
*/
|
||||||
|
export interface FoodInheritField {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof FoodInheritField
|
||||||
|
*/
|
||||||
|
id?: number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof FoodInheritField
|
||||||
|
*/
|
||||||
|
name?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof FoodInheritField
|
||||||
|
*/
|
||||||
|
field?: string;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -736,10 +798,10 @@ export interface InlineResponse2004 {
|
|||||||
previous?: string | null;
|
previous?: string | null;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {Array<Step>}
|
* @type {Array<RecipeOverview>}
|
||||||
* @memberof InlineResponse2004
|
* @memberof InlineResponse2004
|
||||||
*/
|
*/
|
||||||
results?: Array<Step>;
|
results?: Array<RecipeOverview>;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -896,6 +958,37 @@ export interface InlineResponse2009 {
|
|||||||
*/
|
*/
|
||||||
results?: Array<ViewLog>;
|
results?: Array<ViewLog>;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface InlineResponse2009
|
||||||
|
*/
|
||||||
|
export interface InlineResponse2009 {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof InlineResponse2009
|
||||||
|
*/
|
||||||
|
count?: number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof InlineResponse2009
|
||||||
|
*/
|
||||||
|
next?: string | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof InlineResponse2009
|
||||||
|
*/
|
||||||
|
previous?: string | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<ViewLog>}
|
||||||
|
* @memberof InlineResponse2009
|
||||||
|
*/
|
||||||
|
results?: Array<ViewLog>;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
@ -1379,10 +1472,10 @@ export interface RecipeBook {
|
|||||||
icon?: string | null;
|
icon?: string | null;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {Array<ShoppingListCreatedBy>}
|
* @type {Array<RecipeBookShared>}
|
||||||
* @memberof RecipeBook
|
* @memberof RecipeBook
|
||||||
*/
|
*/
|
||||||
shared: Array<ShoppingListCreatedBy>;
|
shared: Array<RecipeBookShared>;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -1539,6 +1632,61 @@ export interface RecipeIngredients {
|
|||||||
*/
|
*/
|
||||||
no_amount?: boolean;
|
no_amount?: boolean;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface RecipeKeywords
|
||||||
|
*/
|
||||||
|
export interface RecipeIngredients {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof RecipeIngredients
|
||||||
|
*/
|
||||||
|
id?: number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {IngredientFood}
|
||||||
|
* @memberof RecipeIngredients
|
||||||
|
*/
|
||||||
|
food: IngredientFood | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {FoodSupermarketCategory}
|
||||||
|
* @memberof RecipeIngredients
|
||||||
|
*/
|
||||||
|
unit: FoodSupermarketCategory | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof RecipeIngredients
|
||||||
|
*/
|
||||||
|
amount: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof RecipeIngredients
|
||||||
|
*/
|
||||||
|
note?: string | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof RecipeIngredients
|
||||||
|
*/
|
||||||
|
order?: number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof RecipeIngredients
|
||||||
|
*/
|
||||||
|
is_header?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof RecipeIngredients
|
||||||
|
*/
|
||||||
|
no_amount?: boolean;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
@ -1919,10 +2067,10 @@ export interface ShoppingList {
|
|||||||
entries: Array<ShoppingListEntries> | null;
|
entries: Array<ShoppingListEntries> | null;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {Array<ShoppingListCreatedBy>}
|
* @type {Array<RecipeBookShared>}
|
||||||
* @memberof ShoppingList
|
* @memberof ShoppingList
|
||||||
*/
|
*/
|
||||||
shared: Array<ShoppingListCreatedBy>;
|
shared: Array<RecipeBookShared>;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
@ -2003,18 +2151,6 @@ export interface ShoppingListEntries {
|
|||||||
* @memberof ShoppingListEntries
|
* @memberof ShoppingListEntries
|
||||||
*/
|
*/
|
||||||
ingredient?: number | null;
|
ingredient?: number | null;
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {FoodSupermarketCategory}
|
|
||||||
* @memberof ShoppingListEntries
|
|
||||||
*/
|
|
||||||
unit?: FoodSupermarketCategory | null;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof ShoppingListEntries
|
|
||||||
*/
|
|
||||||
ingredient?: number | null;
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -2326,49 +2462,6 @@ export interface ShoppingListRecipeMealplan {
|
|||||||
*/
|
*/
|
||||||
mealplan_note?: string;
|
mealplan_note?: string;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface ShoppingListRecipes
|
|
||||||
*/
|
|
||||||
export interface ShoppingListRecipes {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof ShoppingListRecipes
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof ShoppingListRecipes
|
|
||||||
*/
|
|
||||||
recipe?: number | null;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof ShoppingListRecipes
|
|
||||||
*/
|
|
||||||
mealplan?: number | null;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof ShoppingListRecipes
|
|
||||||
*/
|
|
||||||
recipe_name?: string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof ShoppingListRecipes
|
|
||||||
*/
|
|
||||||
servings: string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof ShoppingListRecipes
|
|
||||||
*/
|
|
||||||
mealplan_note?: string;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
@ -2559,147 +2652,6 @@ export enum StepTypeEnum {
|
|||||||
Recipe = 'RECIPE'
|
Recipe = 'RECIPE'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface StepFile
|
|
||||||
*/
|
|
||||||
export interface StepFile {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof StepFile
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {any}
|
|
||||||
* @memberof StepFile
|
|
||||||
*/
|
|
||||||
file?: any;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof StepFile
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface StepFood
|
|
||||||
*/
|
|
||||||
export interface StepFood {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
description?: string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {FoodRecipe}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
recipe?: FoodRecipe | null;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
ignore_shopping?: boolean;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {FoodSupermarketCategory}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
supermarket_category?: FoodSupermarketCategory | null;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
parent?: string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
numchild?: number;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
* @memberof StepFood
|
|
||||||
*/
|
|
||||||
on_hand?: boolean;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface StepIngredients
|
|
||||||
*/
|
|
||||||
export interface StepIngredients {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof StepIngredients
|
|
||||||
*/
|
|
||||||
id?: number;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {StepFood}
|
|
||||||
* @memberof StepIngredients
|
|
||||||
*/
|
|
||||||
food: StepFood | null;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {FoodSupermarketCategory}
|
|
||||||
* @memberof StepIngredients
|
|
||||||
*/
|
|
||||||
unit: FoodSupermarketCategory | null;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof StepIngredients
|
|
||||||
*/
|
|
||||||
amount: string;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof StepIngredients
|
|
||||||
*/
|
|
||||||
note?: string | null;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
* @memberof StepIngredients
|
|
||||||
*/
|
|
||||||
order?: number;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
* @memberof StepIngredients
|
|
||||||
*/
|
|
||||||
is_header?: boolean;
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
* @memberof StepIngredients
|
|
||||||
*/
|
|
||||||
no_amount?: boolean;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
|
@ -220,6 +220,11 @@ export const ApiMixin = {
|
|||||||
return {
|
return {
|
||||||
Models: Models,
|
Models: Models,
|
||||||
Actions: Actions,
|
Actions: Actions,
|
||||||
|
FoodCreateDefault: function(form) {
|
||||||
|
form.inherit_ignore = getUserPreference("food_ignore_default")
|
||||||
|
form.inherit = form.supermarket_category.length > 0
|
||||||
|
return form
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -531,3 +536,11 @@ const specialCases = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const formFunctions = {
|
||||||
|
FoodCreateDefault: function(form) {
|
||||||
|
form.fields.filter((x) => x.field === "ignore_inherit")[0].value = getUserPreference("food_ignore_default")
|
||||||
|
form.fields.filter((x) => x.field === "inherit")[0].value = getUserPreference("food_ignore_default").length > 0
|
||||||
|
return form
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user