food inherit attributes

This commit is contained in:
smilerz 2021-10-19 08:35:33 -05:00
parent 4377505b14
commit fbe748db62
13 changed files with 252 additions and 336 deletions

View File

@ -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,
} }

View File

@ -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),
] ]

View File

@ -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'),
),
]

View File

@ -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
),
]

View File

@ -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:

View File

@ -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', )

View File

@ -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

View File

@ -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)

View File

@ -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):

View File

@ -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"

View File

@ -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 = {

View File

@ -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

View File

@ -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
},
}