add food substitutions
This commit is contained in:
parent
5e3f94fcf7
commit
6ef25b604b
@ -419,12 +419,47 @@ class RecipeSearch():
|
|||||||
if not self._makenow:
|
if not self._makenow:
|
||||||
return
|
return
|
||||||
shopping_users = [*self._request.user.get_shopping_share(), self._request.user]
|
shopping_users = [*self._request.user.get_shopping_share(), self._request.user]
|
||||||
|
|
||||||
|
onhand_filter = (
|
||||||
|
Q(steps__ingredients__food__onhand_users__in=shopping_users, steps__ingredients__food__ignore_shopping=False) # food onhand
|
||||||
|
| Q(steps__ingredients__food__substitute__onhand_users__in=shopping_users, steps__ingredients__food__substitute__ignore_shopping=False) # or substitute food onhand
|
||||||
|
| Q(steps__ingredients__food__in=self.__children_substitute_filter(shopping_users))
|
||||||
|
| Q(steps__ingredients__food__in=self.__sibling_substitute_filter(shopping_users))
|
||||||
|
)
|
||||||
self._queryset = self._queryset.annotate(
|
self._queryset = self._queryset.annotate(
|
||||||
count_food=Count('steps__ingredients__food'),
|
count_food=Count('steps__ingredients__food'),
|
||||||
count_onhand=Count('pk', filter=Q(steps__ingredients__food__onhand_users__in=shopping_users, steps__ingredients__food__ignore_shopping=False)),
|
count_onhand=Count('pk', filter=Q(onhand_filter)),
|
||||||
count_ignore=Count('pk', filter=Q(steps__ingredients__food__ignore_shopping=True))
|
count_ignore=Count('pk', filter=Q(steps__ingredients__food__ignore_shopping=True))
|
||||||
).annotate(missingfood=F('count_food')-F('count_onhand')-F('count_ignore')).filter(missingfood=0)
|
).annotate(missingfood=F('count_food')-F('count_onhand')-F('count_ignore')).filter(missingfood=0)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __children_substitute_filter(shopping_users=None):
|
||||||
|
children_onhand_subquery = Food.objects.filter(
|
||||||
|
path__startswith=Substr(OuterRef('path'), 1, Food.steplen*OuterRef('depth')),
|
||||||
|
depth__gt=OuterRef('depth'),
|
||||||
|
onhand_users__in=shopping_users
|
||||||
|
).annotate(child_onhand=Count((Substr(OuterRef('path'), 1, Food.steplen*OuterRef('depth'))), distinct=True)).values('child_onhand')
|
||||||
|
return Food.objects.exclude( # list of foods that are onhand and children of: foods that are not onhand and are set to use children as substitutes
|
||||||
|
Q(onhand_users__in=shopping_users)
|
||||||
|
| Q(ignore_shopping=True)
|
||||||
|
| Q(substitute__onhand_users__in=shopping_users)
|
||||||
|
).exclude(depth=1, numchild=0).filter(substitute_children=True
|
||||||
|
).annotate(child_onhand=Coalesce(Subquery(children_onhand_subquery), 0))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __sibling_substitute_filter(shopping_users=None):
|
||||||
|
sibling_onhand_subquery = Food.objects.filter(
|
||||||
|
path__startswith=Substr(OuterRef('path'), 1, Food.steplen*(OuterRef('depth')-1)),
|
||||||
|
depth=OuterRef('depth'),
|
||||||
|
onhand_users__in=shopping_users
|
||||||
|
).annotate(sibling_onhand=Count(Substr(OuterRef('path'), 1, Food.steplen*(OuterRef('depth')-1)), distinct=True)).values('sibling_onhand')
|
||||||
|
return Food.objects.exclude( # list of foods that are onhand and siblings of: foods that are not onhand and are set to use siblings as substitutes
|
||||||
|
Q(onhand_users__in=shopping_users)
|
||||||
|
| Q(ignore_shopping=True)
|
||||||
|
| Q(substitute__onhand_users__in=shopping_users)
|
||||||
|
).exclude(depth=1, numchild=0).filter(substitute_siblings=True
|
||||||
|
).annotate(sibling_onhand=Coalesce(Subquery(sibling_onhand_subquery), 0))
|
||||||
|
|
||||||
|
|
||||||
class RecipeFacet():
|
class RecipeFacet():
|
||||||
class CacheEmpty(Exception):
|
class CacheEmpty(Exception):
|
||||||
@ -605,7 +640,7 @@ class RecipeFacet():
|
|||||||
|
|
||||||
def _recipe_count_queryset(self, field, depth=1, steplen=4):
|
def _recipe_count_queryset(self, field, depth=1, steplen=4):
|
||||||
return Recipe.objects.filter(**{f'{field}__path__startswith': OuterRef('path')}, id__in=self._recipe_list, space=self._request.space
|
return Recipe.objects.filter(**{f'{field}__path__startswith': OuterRef('path')}, id__in=self._recipe_list, space=self._request.space
|
||||||
).values(child=Substr(f'{field}__path', 1, steplen)
|
).values(child=Substr(f'{field}__path', 1, steplen*depth)
|
||||||
).annotate(count=Count('pk', distinct=True)).values('count')
|
).annotate(count=Count('pk', distinct=True)).values('count')
|
||||||
|
|
||||||
def _keyword_queryset(self, queryset, keyword=None):
|
def _keyword_queryset(self, queryset, keyword=None):
|
||||||
|
19
cookbook/migrations/0170_alter_ingredient_unit.py
Normal file
19
cookbook/migrations/0170_alter_ingredient_unit.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 3.2.11 on 2022-02-02 19:36
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('cookbook', '0169_auto_20220121_1427'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ingredient',
|
||||||
|
name='unit',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.unit'),
|
||||||
|
),
|
||||||
|
]
|
34
cookbook/migrations/0171_auto_20220202_1340.py
Normal file
34
cookbook/migrations/0171_auto_20220202_1340.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Generated by Django 3.2.11 on 2022-02-02 19:40
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('cookbook', '0170_alter_ingredient_unit'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='food',
|
||||||
|
name='substitute',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='_cookbook_food_substitute_+', to='cookbook.Food'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='food',
|
||||||
|
name='substitute_children',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='food',
|
||||||
|
name='substitute_siblings',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ingredient',
|
||||||
|
name='unit',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cookbook.unit'),
|
||||||
|
),
|
||||||
|
]
|
@ -488,6 +488,7 @@ class Unit(ExportModelOperationsMixin('unit'), models.Model, PermissionModelMixi
|
|||||||
|
|
||||||
|
|
||||||
class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
|
class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
|
||||||
|
# TODO when savings a food as substitute children - assume children and descednats are also substitutes for siblings
|
||||||
# exclude fields not implemented yet
|
# exclude fields not implemented yet
|
||||||
inheritable_fields = FoodInheritField.objects.exclude(field__in=['diet', 'substitute', 'substitute_children', 'substitute_siblings'])
|
inheritable_fields = FoodInheritField.objects.exclude(field__in=['diet', 'substitute', 'substitute_children', 'substitute_siblings'])
|
||||||
|
|
||||||
@ -501,6 +502,9 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
|
|||||||
onhand_users = models.ManyToManyField(User, blank=True)
|
onhand_users = models.ManyToManyField(User, blank=True)
|
||||||
description = models.TextField(default='', blank=True)
|
description = models.TextField(default='', blank=True)
|
||||||
inherit_fields = models.ManyToManyField(FoodInheritField, blank=True)
|
inherit_fields = models.ManyToManyField(FoodInheritField, blank=True)
|
||||||
|
substitute = models.ManyToManyField("self", blank=True)
|
||||||
|
substitute_siblings = models.BooleanField(default=False)
|
||||||
|
substitute_children = models.BooleanField(default=False)
|
||||||
|
|
||||||
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)
|
||||||
@ -560,9 +564,9 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
|
|||||||
|
|
||||||
|
|
||||||
class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, PermissionModelMixin):
|
class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, PermissionModelMixin):
|
||||||
# a pre-delete signal on Food checks if the Ingredient is part of a Step, if it is raises a ProtectedError instead of cascading the delete
|
# delete method on Food and Unit checks if they are part of a Recipe, if it is raises a ProtectedError instead of cascading the delete
|
||||||
food = models.ForeignKey(Food, on_delete=models.CASCADE, null=True, blank=True)
|
food = models.ForeignKey(Food, on_delete=models.CASCADE, null=True, blank=True)
|
||||||
unit = models.ForeignKey(Unit, on_delete=models.PROTECT, null=True, blank=True)
|
unit = models.ForeignKey(Unit, on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
amount = models.DecimalField(default=0, decimal_places=16, max_digits=32)
|
amount = models.DecimalField(default=0, decimal_places=16, max_digits=32)
|
||||||
note = models.CharField(max_length=256, null=True, blank=True)
|
note = models.CharField(max_length=256, null=True, blank=True)
|
||||||
is_header = models.BooleanField(default=False)
|
is_header = models.BooleanField(default=False)
|
||||||
|
@ -4,7 +4,8 @@ from decimal import Decimal
|
|||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db.models import Avg, QuerySet, Sum
|
from django.db.models import Avg, Q, QuerySet, Sum, Value
|
||||||
|
from django.db.models.functions import Substr
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from drf_writable_nested import UniqueFieldsMixin, WritableNestedModelSerializer
|
from drf_writable_nested import UniqueFieldsMixin, WritableNestedModelSerializer
|
||||||
@ -375,6 +376,13 @@ class RecipeSimpleSerializer(serializers.ModelSerializer):
|
|||||||
read_only_fields = ['id', 'name', 'url']
|
read_only_fields = ['id', 'name', 'url']
|
||||||
|
|
||||||
|
|
||||||
|
class FoodSimpleSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Food
|
||||||
|
fields = ('id', 'name')
|
||||||
|
read_only_fields = ['id', 'name']
|
||||||
|
|
||||||
|
|
||||||
class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedRecipeMixin):
|
class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedRecipeMixin):
|
||||||
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)
|
||||||
@ -382,10 +390,25 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
|
|||||||
shopping = serializers.ReadOnlyField(source='shopping_status')
|
shopping = serializers.ReadOnlyField(source='shopping_status')
|
||||||
inherit_fields = FoodInheritFieldSerializer(many=True, allow_null=True, required=False)
|
inherit_fields = FoodInheritFieldSerializer(many=True, allow_null=True, required=False)
|
||||||
food_onhand = CustomOnHandField(required=False, allow_null=True)
|
food_onhand = CustomOnHandField(required=False, allow_null=True)
|
||||||
|
substitute_onhand = serializers.SerializerMethodField('get_substitute_onhand')
|
||||||
|
substitute = FoodSimpleSerializer(many=True, allow_null=True, required=False)
|
||||||
|
|
||||||
recipe_filter = 'steps__ingredients__food'
|
recipe_filter = 'steps__ingredients__food'
|
||||||
images = ['recipe__image']
|
images = ['recipe__image']
|
||||||
|
|
||||||
|
def get_substitute_onhand(self, obj):
|
||||||
|
shared_users = None
|
||||||
|
if request := self.context.get('request', None):
|
||||||
|
shared_users = getattr(request, '_shared_users', None)
|
||||||
|
if shared_users is None:
|
||||||
|
shared_users = [x.id for x in list(self.context['request'].user.get_shopping_share())] + [self.context['request'].user.id]
|
||||||
|
filter = Q(id__in=obj.substitute.all())
|
||||||
|
if obj.substitute_siblings:
|
||||||
|
filter |= Q(path__startswith=obj.path[:Food.steplen*(obj.depth-1)], depth=obj.depth)
|
||||||
|
if obj.substitute_children:
|
||||||
|
filter |= Q(path__startswith=obj.path, depth__gt=obj.depth)
|
||||||
|
return Food.objects.filter(filter).filter(onhand_users__id__in=shared_users).exists()
|
||||||
|
|
||||||
# def get_shopping_status(self, obj):
|
# def get_shopping_status(self, obj):
|
||||||
# return ShoppingListEntry.objects.filter(space=obj.space, food=obj, checked=False).count() > 0
|
# return ShoppingListEntry.objects.filter(space=obj.space, food=obj, checked=False).count() > 0
|
||||||
|
|
||||||
@ -437,7 +460,8 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
|
|||||||
model = Food
|
model = Food
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'name', 'description', 'shopping', 'recipe', 'food_onhand', 'supermarket_category',
|
'id', 'name', 'description', 'shopping', 'recipe', 'food_onhand', 'supermarket_category',
|
||||||
'image', 'parent', 'numchild', 'numrecipe', 'inherit_fields', 'full_name', 'ignore_shopping'
|
'image', 'parent', 'numchild', 'numrecipe', 'inherit_fields', 'full_name', 'ignore_shopping',
|
||||||
|
'substitute', 'substitute_siblings', 'substitute_children', 'substitute_onhand'
|
||||||
)
|
)
|
||||||
read_only_fields = ('id', 'numchild', 'parent', 'image', 'numrecipe')
|
read_only_fields = ('id', 'numchild', 'parent', 'image', 'numrecipe')
|
||||||
|
|
||||||
|
@ -90,7 +90,10 @@ def test_add(arg, request, obj_1):
|
|||||||
c = request.getfixturevalue(arg[0])
|
c = request.getfixturevalue(arg[0])
|
||||||
r = c.post(
|
r = c.post(
|
||||||
reverse(LIST_URL),
|
reverse(LIST_URL),
|
||||||
{'food': model_to_dict(obj_1.food), 'amount': 1},
|
{'food': {
|
||||||
|
'id': obj_1.food.__dict__['id'],
|
||||||
|
'name': obj_1.food.__dict__['name'],
|
||||||
|
}, 'amount': 1},
|
||||||
content_type='application/json'
|
content_type='application/json'
|
||||||
)
|
)
|
||||||
response = json.loads(r.content)
|
response = json.loads(r.content)
|
||||||
|
@ -103,7 +103,10 @@ def test_add(arg, request, sle):
|
|||||||
c = request.getfixturevalue(arg[0])
|
c = request.getfixturevalue(arg[0])
|
||||||
r = c.post(
|
r = c.post(
|
||||||
reverse(LIST_URL),
|
reverse(LIST_URL),
|
||||||
{'food': model_to_dict(sle[0].food), 'amount': 1},
|
{'food': {
|
||||||
|
'id': sle[0].food.__dict__['id'],
|
||||||
|
'name': sle[0].food.__dict__['name'],
|
||||||
|
}, 'amount': 1},
|
||||||
content_type='application/json'
|
content_type='application/json'
|
||||||
)
|
)
|
||||||
response = json.loads(r.content)
|
response = json.loads(r.content)
|
||||||
|
@ -655,7 +655,7 @@ class RecipeViewSet(viewsets.ModelViewSet):
|
|||||||
QueryParam(name='new', description=_('Returns new results first in search results. [''true''/''<b>false</b>'']')),
|
QueryParam(name='new', description=_('Returns new results first in search results. [''true''/''<b>false</b>'']')),
|
||||||
QueryParam(name='timescooked', description=_('Filter recipes cooked X times or more. Negative values returns cooked less than X times'), qtype='int'),
|
QueryParam(name='timescooked', description=_('Filter recipes cooked X times or more. Negative values returns cooked less than X times'), qtype='int'),
|
||||||
QueryParam(name='lastcooked', description=_('Filter recipes last cooked on or after YYYY-MM-DD. Prepending ''-'' filters on or before date.')),
|
QueryParam(name='lastcooked', description=_('Filter recipes last cooked on or after YYYY-MM-DD. Prepending ''-'' filters on or before date.')),
|
||||||
QueryParam(name='makenow', description=_('Filter recipes that can be made with OnHand food. [''true''/''<b>false</b>'']'), qtype='int'),
|
QueryParam(name='makenow', description=_('Filter recipes that can be made with OnHand food. [''true''/''<b>false</b>'']')),
|
||||||
]
|
]
|
||||||
schema = QueryParamAutoSchema()
|
schema = QueryParamAutoSchema()
|
||||||
|
|
||||||
|
@ -417,7 +417,6 @@ export default {
|
|||||||
// TODO: make this generic
|
// TODO: make this generic
|
||||||
let params = { pageSize: 50, random: true }
|
let params = { pageSize: 50, random: true }
|
||||||
params[this.this_recipe_param] = item.id
|
params[this.this_recipe_param] = item.id
|
||||||
console.log("RECIPE PARAM", this.this_recipe_param, params, item.id)
|
|
||||||
this.genericAPI(this.Models.RECIPE, this.Actions.LIST, params)
|
this.genericAPI(this.Models.RECIPE, this.Actions.LIST, params)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
parent = this.findCard(item.id, this["items_" + col])
|
parent = this.findCard(item.id, this["items_" + col])
|
||||||
|
@ -915,7 +915,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
console.log(screen.height)
|
|
||||||
this.getShoppingList()
|
this.getShoppingList()
|
||||||
this.getSupermarkets()
|
this.getSupermarkets()
|
||||||
this.getShoppingCategories()
|
this.getShoppingCategories()
|
||||||
@ -1406,7 +1405,6 @@ export default {
|
|||||||
window.removeEventListener("offline", this.updateOnlineStatus)
|
window.removeEventListener("offline", this.updateOnlineStatus)
|
||||||
},
|
},
|
||||||
addRecipeToShopping() {
|
addRecipeToShopping() {
|
||||||
console.log(this.new_recipe)
|
|
||||||
this.$bvModal.show(`shopping_${this.new_recipe.id}`)
|
this.$bvModal.show(`shopping_${this.new_recipe.id}`)
|
||||||
},
|
},
|
||||||
finishShopping() {
|
finishShopping() {
|
||||||
|
@ -100,7 +100,7 @@ export default {
|
|||||||
this.loadInitial()
|
this.loadInitial()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadInitial: function() {
|
loadInitial: function () {
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
apiClient.listSupermarkets().then((results) => {
|
apiClient.listSupermarkets().then((results) => {
|
||||||
this.supermarkets = results.data
|
this.supermarkets = results.data
|
||||||
@ -110,7 +110,7 @@ export default {
|
|||||||
this.selectable_categories = this.categories
|
this.selectable_categories = this.categories
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
selectedCategoriesChanged: function(data) {
|
selectedCategoriesChanged: function (data) {
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
|
|
||||||
if ("removed" in data) {
|
if ("removed" in data) {
|
||||||
@ -133,23 +133,22 @@ export default {
|
|||||||
if ("moved" in data || "added" in data) {
|
if ("moved" in data || "added" in data) {
|
||||||
this.supermarket_categories.forEach((element, index) => {
|
this.supermarket_categories.forEach((element, index) => {
|
||||||
let relation = this.selected_supermarket.category_to_supermarket.filter((el) => el.category.id === element.id)[0]
|
let relation = this.selected_supermarket.category_to_supermarket.filter((el) => el.category.id === element.id)[0]
|
||||||
console.log(relation)
|
|
||||||
apiClient.partialUpdateSupermarketCategoryRelation(relation.id, { order: index })
|
apiClient.partialUpdateSupermarketCategoryRelation(relation.id, { order: index })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectedSupermarketChanged: function(supermarket, id) {
|
selectedSupermarketChanged: function (supermarket, id) {
|
||||||
this.supermarket_categories = []
|
this.supermarket_categories = []
|
||||||
this.selectable_categories = this.categories
|
this.selectable_categories = this.categories
|
||||||
|
|
||||||
for (let i of supermarket.category_to_supermarket) {
|
for (let i of supermarket.category_to_supermarket) {
|
||||||
this.supermarket_categories.push(i.category)
|
this.supermarket_categories.push(i.category)
|
||||||
this.selectable_categories = this.selectable_categories.filter(function(el) {
|
this.selectable_categories = this.selectable_categories.filter(function (el) {
|
||||||
return el.id !== i.category.id
|
return el.id !== i.category.id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
supermarketModalOk: function() {
|
supermarketModalOk: function () {
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
if (this.selected_supermarket.new) {
|
if (this.selected_supermarket.new) {
|
||||||
apiClient.createSupermarket({ name: this.selected_supermarket.name }).then((results) => {
|
apiClient.createSupermarket({ name: this.selected_supermarket.name }).then((results) => {
|
||||||
@ -160,7 +159,7 @@ export default {
|
|||||||
apiClient.partialUpdateSupermarket(this.selected_supermarket.id, { name: this.selected_supermarket.name })
|
apiClient.partialUpdateSupermarket(this.selected_supermarket.id, { name: this.selected_supermarket.name })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
categoryModalOk: function() {
|
categoryModalOk: function () {
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
if (this.selected_category.new) {
|
if (this.selected_category.new) {
|
||||||
apiClient.createSupermarketCategory({ name: this.selected_category.name }).then((results) => {
|
apiClient.createSupermarketCategory({ name: this.selected_category.name }).then((results) => {
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<span>
|
<span>
|
||||||
<b-button
|
<b-button v-if="!item.ignore_shopping" class="btn text-decoration-none fas px-1 py-0 border-0" variant="link" v-b-popover.hover.html :title="Title" :class="IconClass" @click="toggleOnHand" />
|
||||||
class="btn text-decoration-none fas px-1 py-0 border-0"
|
|
||||||
variant="link"
|
|
||||||
v-b-popover.hover.html
|
|
||||||
:title="[onhand ? $t('FoodOnHand', { food: item.name }) : $t('FoodNotOnHand', { food: item.name })]"
|
|
||||||
:class="[onhand ? 'text-success fa-clipboard-check' : 'text-muted fa-clipboard']"
|
|
||||||
@click="toggleOnHand"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -25,6 +18,26 @@ export default {
|
|||||||
onhand: false,
|
onhand: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
Title: function () {
|
||||||
|
if (this.onhand) {
|
||||||
|
return this.$t("FoodOnHand", { food: this.item.name })
|
||||||
|
} else if (this.item.substitute_onhand) {
|
||||||
|
return this.$t("SubstituteOnHand")
|
||||||
|
} else {
|
||||||
|
return this.$t("FoodNotOnHand", { food: this.item.name })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
IconClass: function () {
|
||||||
|
if (this.onhand) {
|
||||||
|
return "text-success fa-clipboard-check"
|
||||||
|
} else if (this.item.substitute_onhand) {
|
||||||
|
return "text-warning fa-clipboard-check"
|
||||||
|
} else {
|
||||||
|
return "text-muted fa-clipboard"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.onhand = this.item.food_onhand
|
this.onhand = this.item.food_onhand
|
||||||
},
|
},
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td v-else-if="show_shopping" class="text-right text-nowrap">
|
<td v-else-if="show_shopping" class="text-right text-nowrap">
|
||||||
|
<shopping-badge v-if="ingredient.food.ignore_shopping" :item="shoppingBadgeFood" />
|
||||||
<b-button
|
<b-button
|
||||||
v-if="!ingredient.food.ignore_shopping"
|
v-if="!ingredient.food.ignore_shopping"
|
||||||
class="btn text-decoration-none fas fa-shopping-cart px-2 user-select-none"
|
class="btn text-decoration-none fas fa-shopping-cart px-2 user-select-none"
|
||||||
@ -56,10 +57,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { calculateAmount, ResolveUrlMixin, ApiMixin } from "@/utils/utils"
|
import { calculateAmount, ResolveUrlMixin, ApiMixin } from "@/utils/utils"
|
||||||
import OnHandBadge from "@/components/Badges/OnHand"
|
import OnHandBadge from "@/components/Badges/OnHand"
|
||||||
|
import ShoppingBadge from "@/components/Badges/Shopping"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "IngredientComponent",
|
name: "IngredientComponent",
|
||||||
components: { OnHandBadge },
|
components: { OnHandBadge, ShoppingBadge },
|
||||||
props: {
|
props: {
|
||||||
ingredient: Object,
|
ingredient: Object,
|
||||||
ingredient_factor: { type: Number, default: 1 },
|
ingredient_factor: { type: Number, default: 1 },
|
||||||
@ -87,6 +89,11 @@ export default {
|
|||||||
this.shop = this.ingredient?.shop
|
this.shop = this.ingredient?.shop
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
shoppingBadgeFood() {
|
||||||
|
// shopping badge is hidden when ignore_shopping=true.
|
||||||
|
// force true in this context to allow adding to shopping list from recipe view
|
||||||
|
return { ...this.ingredient.food, ignore_shopping: false }
|
||||||
|
},
|
||||||
ShoppingPopover() {
|
ShoppingPopover() {
|
||||||
if (this.ingredient?.shopping_status == false) {
|
if (this.ingredient?.shopping_status == false) {
|
||||||
return this.$t("NotInShopping", { food: this.ingredient.food.name })
|
return this.$t("NotInShopping", { food: this.ingredient.food.name })
|
||||||
|
@ -56,7 +56,6 @@ import "bootstrap-vue/dist/bootstrap-vue.css"
|
|||||||
|
|
||||||
import IngredientComponent from "@/components/IngredientComponent"
|
import IngredientComponent from "@/components/IngredientComponent"
|
||||||
import { ApiMixin, StandardToasts } from "@/utils/utils"
|
import { ApiMixin, StandardToasts } from "@/utils/utils"
|
||||||
import ShoppingListViewVue from "../apps/ShoppingListView/ShoppingListView.vue"
|
|
||||||
|
|
||||||
Vue.use(BootstrapVue)
|
Vue.use(BootstrapVue)
|
||||||
|
|
||||||
|
@ -16,8 +16,11 @@
|
|||||||
<small-text v-if="visibleCondition(f, 'smalltext')" :value="f.value" />
|
<small-text v-if="visibleCondition(f, 'smalltext')" :value="f.value" />
|
||||||
</div>
|
</div>
|
||||||
<template v-slot:modal-footer>
|
<template v-slot:modal-footer>
|
||||||
<div class="row w-100 justify-content-end">
|
<div class="row w-100">
|
||||||
<div class="col-auto">
|
<div class="col-6 align-self-end">
|
||||||
|
<b-form-checkbox v-if="advancedForm" sm switch v-model="show_advanced">{{ $t("Advanced") }}</b-form-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto justify-content-end">
|
||||||
<b-button class="mx-1" variant="secondary" v-on:click="cancelAction">{{ $t("Cancel") }}</b-button>
|
<b-button class="mx-1" variant="secondary" v-on:click="cancelAction">{{ $t("Cancel") }}</b-button>
|
||||||
<b-button class="mx-1" variant="primary" v-on:click="doAction">{{ form.ok_label }}</b-button>
|
<b-button class="mx-1" variant="primary" v-on:click="doAction">{{ form.ok_label }}</b-button>
|
||||||
</div>
|
</div>
|
||||||
@ -78,7 +81,8 @@ export default {
|
|||||||
form: {},
|
form: {},
|
||||||
dirty: false,
|
dirty: false,
|
||||||
special_handling: false,
|
special_handling: false,
|
||||||
show_help: true,
|
show_help: false,
|
||||||
|
show_advanced: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -86,6 +90,13 @@ export default {
|
|||||||
this.$root.$on("change", this.storeValue) // bootstrap modal placed at document so have to listen at root of component
|
this.$root.$on("change", this.storeValue) // bootstrap modal placed at document so have to listen at root of component
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
advancedForm() {
|
||||||
|
return this.form.fields
|
||||||
|
.map((x) => {
|
||||||
|
return x?.advanced ?? false
|
||||||
|
})
|
||||||
|
.includes(true)
|
||||||
|
},
|
||||||
buttonLabel() {
|
buttonLabel() {
|
||||||
return this.buttons[this.action].label
|
return this.buttons[this.action].label
|
||||||
},
|
},
|
||||||
@ -268,6 +279,11 @@ export default {
|
|||||||
visibleCondition(field, field_type) {
|
visibleCondition(field, field_type) {
|
||||||
let type_match = field?.type == field_type
|
let type_match = field?.type == field_type
|
||||||
let checks = true
|
let checks = true
|
||||||
|
let show_advanced = true
|
||||||
|
if (field?.advanced) {
|
||||||
|
show_advanced = this.show_advanced
|
||||||
|
}
|
||||||
|
|
||||||
if (type_match && field?.condition) {
|
if (type_match && field?.condition) {
|
||||||
const value = this.item1[field?.condition?.field]
|
const value = this.item1[field?.condition?.field]
|
||||||
const preference = getUserPreference(field?.condition?.field)
|
const preference = getUserPreference(field?.condition?.field)
|
||||||
@ -294,7 +310,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return type_match && checks
|
return type_match && checks && show_advanced
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
</b-input-group-prepend>
|
</b-input-group-prepend>
|
||||||
|
|
||||||
<b-form-spinbutton min="1" v-model="recipe_servings" inline style="height: 3em"></b-form-spinbutton>
|
<b-form-spinbutton min="1" v-model="recipe_servings" inline style="height: 3em"></b-form-spinbutton>
|
||||||
<CustomInputSpinButton v-model.number="recipe_servings" style="height: 3em" />
|
<!-- <CustomInputSpinButton v-model.number="recipe_servings" style="height: 3em" /> -->
|
||||||
|
|
||||||
<b-input-group-append>
|
<b-input-group-append>
|
||||||
<b-button variant="secondary" @click="$bvModal.hide(`shopping_${modal_id}`)">{{ $t("Cancel") }} </b-button>
|
<b-button variant="secondary" @click="$bvModal.hide(`shopping_${modal_id}`)">{{ $t("Cancel") }} </b-button>
|
||||||
@ -76,11 +76,11 @@ const { ApiApiFactory } = require("@/utils/openapi/api")
|
|||||||
import { StandardToasts } from "@/utils/utils"
|
import { StandardToasts } from "@/utils/utils"
|
||||||
import IngredientsCard from "@/components/IngredientsCard"
|
import IngredientsCard from "@/components/IngredientsCard"
|
||||||
import LoadingSpinner from "@/components/LoadingSpinner"
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
import CustomInputSpinButton from "@/components/CustomInputSpinButton"
|
// import CustomInputSpinButton from "@/components/CustomInputSpinButton"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ShoppingModal",
|
name: "ShoppingModal",
|
||||||
components: { IngredientsCard, LoadingSpinner, CustomInputSpinButton },
|
components: { IngredientsCard, LoadingSpinner },
|
||||||
mixins: [],
|
mixins: [],
|
||||||
props: {
|
props: {
|
||||||
recipe: { required: true, type: Object },
|
recipe: { required: true, type: Object },
|
||||||
|
@ -289,13 +289,11 @@
|
|||||||
"remember_search": "Remember Search",
|
"remember_search": "Remember Search",
|
||||||
"remember_hours": "Hours to Remember",
|
"remember_hours": "Hours to Remember",
|
||||||
"tree_select": "Use Tree Selection",
|
"tree_select": "Use Tree Selection",
|
||||||
"OnHand_help": "Food is in inventory and will not be automatically added to a shopping list.",
|
"OnHand_help": "Food is in inventory and will not be automatically added to a shopping list. Onhand status is shared with shopping users.",
|
||||||
"ignore_shopping_help": "Never add food to the shopping list (e.g. water)",
|
"ignore_shopping_help": "Never add food to the shopping list (e.g. water)",
|
||||||
"shopping_category_help": "Supermarkets can be ordered and filtered by Shopping Category according to the layout of the aisles.",
|
"shopping_category_help": "Supermarkets can be ordered and filtered by Shopping Category according to the layout of the aisles.",
|
||||||
"food_recipe_help": "Linking a recipe here will include the linked recipe in any other recipe that use this food",
|
"food_recipe_help": "Linking a recipe here will include the linked recipe in any other recipe that use this food",
|
||||||
"Foods": "Foods",
|
"Foods": "Foods",
|
||||||
"review_shopping": "Review shopping entries before saving",
|
|
||||||
"view_recipe": "View Recipe",
|
|
||||||
"enable_expert": "Enable Expert Mode",
|
"enable_expert": "Enable Expert Mode",
|
||||||
"expert_mode": "Expert Mode",
|
"expert_mode": "Expert Mode",
|
||||||
"simple_mode": "Simple Mode",
|
"simple_mode": "Simple Mode",
|
||||||
@ -326,6 +324,15 @@
|
|||||||
"make_now": "Make Now",
|
"make_now": "Make Now",
|
||||||
"recipe_filter": "Recipe Filter",
|
"recipe_filter": "Recipe Filter",
|
||||||
"book_filter_help": "Include recipes from recipe filter instead of assigning each recipe",
|
"book_filter_help": "Include recipes from recipe filter instead of assigning each recipe",
|
||||||
|
"review_shopping": "Review shopping entries before saving",
|
||||||
|
"view_recipe": "View Recipe",
|
||||||
|
"filter": "Filter",
|
||||||
"reset_children": "Reset Child Inheritance",
|
"reset_children": "Reset Child Inheritance",
|
||||||
"reset_children_help": "Overwrite all children with values from inherited fields."
|
"reset_children_help": "Overwrite all children with values from inherited fields.",
|
||||||
|
"substitute_help": "Substitutes are considered when searching for recipes that can be made with onhand ingredients.",
|
||||||
|
"substitute_siblings_help": "All food that share a parent of this food are considered substitutes.",
|
||||||
|
"substitute_children_help": "All food that are children of this food are considered substitutes.",
|
||||||
|
"substitute_siblings": "Substitute Siblings",
|
||||||
|
"substitute_children": "Substitute Children",
|
||||||
|
"SubstituteOnHand": "You have a substitute on hand."
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,22 @@ 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", "food_onhand", "supermarket_category", "inherit", "inherit_fields", "ignore_shopping", "reset_inherit"]],
|
params: [
|
||||||
|
[
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"recipe",
|
||||||
|
"food_onhand",
|
||||||
|
"supermarket_category",
|
||||||
|
"inherit",
|
||||||
|
"inherit_fields",
|
||||||
|
"ignore_shopping",
|
||||||
|
"substitute",
|
||||||
|
"substitute_siblings",
|
||||||
|
"substitute_children",
|
||||||
|
"reset_inherit",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
form: {
|
form: {
|
||||||
show_help: true,
|
show_help: true,
|
||||||
@ -126,8 +141,38 @@ export class Models {
|
|||||||
allow_create: true,
|
allow_create: true,
|
||||||
help_text: i18n.t("shopping_category_help"),
|
help_text: i18n.t("shopping_category_help"),
|
||||||
},
|
},
|
||||||
|
substitute: {
|
||||||
|
form_field: true,
|
||||||
|
advanced: true,
|
||||||
|
type: "lookup",
|
||||||
|
multiple: true,
|
||||||
|
field: "substitute",
|
||||||
|
list: "FOOD",
|
||||||
|
label: i18n.t("Substitutes"),
|
||||||
|
allow_create: false,
|
||||||
|
help_text: i18n.t("substitute_help"),
|
||||||
|
},
|
||||||
|
substitute_siblings: {
|
||||||
|
form_field: true,
|
||||||
|
advanced: true,
|
||||||
|
type: "checkbox",
|
||||||
|
field: "substitute_siblings",
|
||||||
|
label: i18n.t("substitute_siblings"),
|
||||||
|
help_text: i18n.t("substitute_siblings_help"),
|
||||||
|
condition: { field: "parent", value: true, condition: "field_exists" },
|
||||||
|
},
|
||||||
|
substitute_children: {
|
||||||
|
form_field: true,
|
||||||
|
advanced: true,
|
||||||
|
type: "checkbox",
|
||||||
|
field: "substitute_children",
|
||||||
|
label: i18n.t("substitute_children"),
|
||||||
|
help_text: i18n.t("substitute_children_help"),
|
||||||
|
condition: { field: "numchild", value: 0, condition: "gt" },
|
||||||
|
},
|
||||||
inherit_fields: {
|
inherit_fields: {
|
||||||
form_field: true,
|
form_field: true,
|
||||||
|
advanced: true,
|
||||||
type: "lookup",
|
type: "lookup",
|
||||||
multiple: true,
|
multiple: true,
|
||||||
field: "inherit_fields",
|
field: "inherit_fields",
|
||||||
@ -137,6 +182,7 @@ export class Models {
|
|||||||
},
|
},
|
||||||
reset_inherit: {
|
reset_inherit: {
|
||||||
form_field: true,
|
form_field: true,
|
||||||
|
advanced: true,
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
field: "reset_inherit",
|
field: "reset_inherit",
|
||||||
label: i18n.t("reset_children"),
|
label: i18n.t("reset_children"),
|
||||||
|
@ -307,6 +307,30 @@ export interface Food {
|
|||||||
* @memberof Food
|
* @memberof Food
|
||||||
*/
|
*/
|
||||||
ignore_shopping?: boolean;
|
ignore_shopping?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<FoodSubstitute>}
|
||||||
|
* @memberof Food
|
||||||
|
*/
|
||||||
|
substitute?: Array<FoodSubstitute> | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof Food
|
||||||
|
*/
|
||||||
|
substitute_siblings?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof Food
|
||||||
|
*/
|
||||||
|
substitute_children?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof Food
|
||||||
|
*/
|
||||||
|
substitute_onhand?: string;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -423,6 +447,25 @@ export enum FoodShoppingUpdateDeleteEnum {
|
|||||||
True = 'true'
|
True = 'true'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface FoodSubstitute
|
||||||
|
*/
|
||||||
|
export interface FoodSubstitute {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof FoodSubstitute
|
||||||
|
*/
|
||||||
|
id?: number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof FoodSubstitute
|
||||||
|
*/
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
@ -709,6 +752,30 @@ export interface IngredientFood {
|
|||||||
* @memberof IngredientFood
|
* @memberof IngredientFood
|
||||||
*/
|
*/
|
||||||
ignore_shopping?: boolean;
|
ignore_shopping?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<FoodSubstitute>}
|
||||||
|
* @memberof IngredientFood
|
||||||
|
*/
|
||||||
|
substitute?: Array<FoodSubstitute> | null;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof IngredientFood
|
||||||
|
*/
|
||||||
|
substitute_siblings?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof IngredientFood
|
||||||
|
*/
|
||||||
|
substitute_children?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof IngredientFood
|
||||||
|
*/
|
||||||
|
substitute_onhand?: string;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -5482,13 +5549,13 @@ export const ApiApiAxiosParamCreator = function (configuration?: Configuration)
|
|||||||
* @param {string} [_new] Returns new results first in search results. [true/<b>false</b>]
|
* @param {string} [_new] Returns new results first in search results. [true/<b>false</b>]
|
||||||
* @param {number} [timescooked] Filter recipes cooked X times or more. Negative values returns cooked less than X times
|
* @param {number} [timescooked] Filter recipes cooked X times or more. Negative values returns cooked less than X times
|
||||||
* @param {string} [lastcooked] Filter recipes last cooked on or after YYYY-MM-DD. Prepending - filters on or before date.
|
* @param {string} [lastcooked] Filter recipes last cooked on or after YYYY-MM-DD. Prepending - filters on or before date.
|
||||||
* @param {number} [makenow] Filter recipes that can be made with OnHand food. [true/<b>false</b>]
|
* @param {string} [makenow] Filter recipes that can be made with OnHand food. [true/<b>false</b>]
|
||||||
* @param {number} [page] A page number within the paginated result set.
|
* @param {number} [page] A page number within the paginated result set.
|
||||||
* @param {number} [pageSize] Number of results to return per page.
|
* @param {number} [pageSize] Number of results to return per page.
|
||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
listRecipes: async (query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, foodsOr?: number, foodsAnd?: number, foodsOrNot?: number, foodsAndNot?: number, units?: number, rating?: number, books?: string, booksOr?: number, booksAnd?: number, booksOrNot?: number, booksAndNot?: number, internal?: string, random?: string, _new?: string, timescooked?: number, lastcooked?: string, makenow?: number, page?: number, pageSize?: number, options: any = {}): Promise<RequestArgs> => {
|
listRecipes: async (query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, foodsOr?: number, foodsAnd?: number, foodsOrNot?: number, foodsAndNot?: number, units?: number, rating?: number, books?: string, booksOr?: number, booksAnd?: number, booksOrNot?: number, booksAndNot?: number, internal?: string, random?: string, _new?: string, timescooked?: number, lastcooked?: string, makenow?: string, page?: number, pageSize?: number, options: any = {}): Promise<RequestArgs> => {
|
||||||
const localVarPath = `/api/recipe/`;
|
const localVarPath = `/api/recipe/`;
|
||||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||||
@ -10068,13 +10135,13 @@ export const ApiApiFp = function(configuration?: Configuration) {
|
|||||||
* @param {string} [_new] Returns new results first in search results. [true/<b>false</b>]
|
* @param {string} [_new] Returns new results first in search results. [true/<b>false</b>]
|
||||||
* @param {number} [timescooked] Filter recipes cooked X times or more. Negative values returns cooked less than X times
|
* @param {number} [timescooked] Filter recipes cooked X times or more. Negative values returns cooked less than X times
|
||||||
* @param {string} [lastcooked] Filter recipes last cooked on or after YYYY-MM-DD. Prepending - filters on or before date.
|
* @param {string} [lastcooked] Filter recipes last cooked on or after YYYY-MM-DD. Prepending - filters on or before date.
|
||||||
* @param {number} [makenow] Filter recipes that can be made with OnHand food. [true/<b>false</b>]
|
* @param {string} [makenow] Filter recipes that can be made with OnHand food. [true/<b>false</b>]
|
||||||
* @param {number} [page] A page number within the paginated result set.
|
* @param {number} [page] A page number within the paginated result set.
|
||||||
* @param {number} [pageSize] Number of results to return per page.
|
* @param {number} [pageSize] Number of results to return per page.
|
||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
async listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, foodsOr?: number, foodsAnd?: number, foodsOrNot?: number, foodsAndNot?: number, units?: number, rating?: number, books?: string, booksOr?: number, booksAnd?: number, booksOrNot?: number, booksAndNot?: number, internal?: string, random?: string, _new?: string, timescooked?: number, lastcooked?: string, makenow?: number, page?: number, pageSize?: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<InlineResponse2004>> {
|
async listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, foodsOr?: number, foodsAnd?: number, foodsOrNot?: number, foodsAndNot?: number, units?: number, rating?: number, books?: string, booksOr?: number, booksAnd?: number, booksOrNot?: number, booksAndNot?: number, internal?: string, random?: string, _new?: string, timescooked?: number, lastcooked?: string, makenow?: string, page?: number, pageSize?: number, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<InlineResponse2004>> {
|
||||||
const localVarAxiosArgs = await localVarAxiosParamCreator.listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, foodsOr, foodsAnd, foodsOrNot, foodsAndNot, units, rating, books, booksOr, booksAnd, booksOrNot, booksAndNot, internal, random, _new, timescooked, lastcooked, makenow, page, pageSize, options);
|
const localVarAxiosArgs = await localVarAxiosParamCreator.listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, foodsOr, foodsAnd, foodsOrNot, foodsAndNot, units, rating, books, booksOr, booksAnd, booksOrNot, booksAndNot, internal, random, _new, timescooked, lastcooked, makenow, page, pageSize, options);
|
||||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||||
},
|
},
|
||||||
@ -11823,13 +11890,13 @@ export const ApiApiFactory = function (configuration?: Configuration, basePath?:
|
|||||||
* @param {string} [_new] Returns new results first in search results. [true/<b>false</b>]
|
* @param {string} [_new] Returns new results first in search results. [true/<b>false</b>]
|
||||||
* @param {number} [timescooked] Filter recipes cooked X times or more. Negative values returns cooked less than X times
|
* @param {number} [timescooked] Filter recipes cooked X times or more. Negative values returns cooked less than X times
|
||||||
* @param {string} [lastcooked] Filter recipes last cooked on or after YYYY-MM-DD. Prepending - filters on or before date.
|
* @param {string} [lastcooked] Filter recipes last cooked on or after YYYY-MM-DD. Prepending - filters on or before date.
|
||||||
* @param {number} [makenow] Filter recipes that can be made with OnHand food. [true/<b>false</b>]
|
* @param {string} [makenow] Filter recipes that can be made with OnHand food. [true/<b>false</b>]
|
||||||
* @param {number} [page] A page number within the paginated result set.
|
* @param {number} [page] A page number within the paginated result set.
|
||||||
* @param {number} [pageSize] Number of results to return per page.
|
* @param {number} [pageSize] Number of results to return per page.
|
||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, foodsOr?: number, foodsAnd?: number, foodsOrNot?: number, foodsAndNot?: number, units?: number, rating?: number, books?: string, booksOr?: number, booksAnd?: number, booksOrNot?: number, booksAndNot?: number, internal?: string, random?: string, _new?: string, timescooked?: number, lastcooked?: string, makenow?: number, page?: number, pageSize?: number, options?: any): AxiosPromise<InlineResponse2004> {
|
listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, foodsOr?: number, foodsAnd?: number, foodsOrNot?: number, foodsAndNot?: number, units?: number, rating?: number, books?: string, booksOr?: number, booksAnd?: number, booksOrNot?: number, booksAndNot?: number, internal?: string, random?: string, _new?: string, timescooked?: number, lastcooked?: string, makenow?: string, page?: number, pageSize?: number, options?: any): AxiosPromise<InlineResponse2004> {
|
||||||
return localVarFp.listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, foodsOr, foodsAnd, foodsOrNot, foodsAndNot, units, rating, books, booksOr, booksAnd, booksOrNot, booksAndNot, internal, random, _new, timescooked, lastcooked, makenow, page, pageSize, options).then((request) => request(axios, basePath));
|
return localVarFp.listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, foodsOr, foodsAnd, foodsOrNot, foodsAndNot, units, rating, books, booksOr, booksAnd, booksOrNot, booksAndNot, internal, random, _new, timescooked, lastcooked, makenow, page, pageSize, options).then((request) => request(axios, basePath));
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -13605,14 +13672,14 @@ export class ApiApi extends BaseAPI {
|
|||||||
* @param {string} [_new] Returns new results first in search results. [true/<b>false</b>]
|
* @param {string} [_new] Returns new results first in search results. [true/<b>false</b>]
|
||||||
* @param {number} [timescooked] Filter recipes cooked X times or more. Negative values returns cooked less than X times
|
* @param {number} [timescooked] Filter recipes cooked X times or more. Negative values returns cooked less than X times
|
||||||
* @param {string} [lastcooked] Filter recipes last cooked on or after YYYY-MM-DD. Prepending - filters on or before date.
|
* @param {string} [lastcooked] Filter recipes last cooked on or after YYYY-MM-DD. Prepending - filters on or before date.
|
||||||
* @param {number} [makenow] Filter recipes that can be made with OnHand food. [true/<b>false</b>]
|
* @param {string} [makenow] Filter recipes that can be made with OnHand food. [true/<b>false</b>]
|
||||||
* @param {number} [page] A page number within the paginated result set.
|
* @param {number} [page] A page number within the paginated result set.
|
||||||
* @param {number} [pageSize] Number of results to return per page.
|
* @param {number} [pageSize] Number of results to return per page.
|
||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
* @memberof ApiApi
|
* @memberof ApiApi
|
||||||
*/
|
*/
|
||||||
public listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, foodsOr?: number, foodsAnd?: number, foodsOrNot?: number, foodsAndNot?: number, units?: number, rating?: number, books?: string, booksOr?: number, booksAnd?: number, booksOrNot?: number, booksAndNot?: number, internal?: string, random?: string, _new?: string, timescooked?: number, lastcooked?: string, makenow?: number, page?: number, pageSize?: number, options?: any) {
|
public listRecipes(query?: string, keywords?: number, keywordsOr?: number, keywordsAnd?: number, keywordsOrNot?: number, keywordsAndNot?: number, foods?: number, foodsOr?: number, foodsAnd?: number, foodsOrNot?: number, foodsAndNot?: number, units?: number, rating?: number, books?: string, booksOr?: number, booksAnd?: number, booksOrNot?: number, booksAndNot?: number, internal?: string, random?: string, _new?: string, timescooked?: number, lastcooked?: string, makenow?: string, page?: number, pageSize?: number, options?: any) {
|
||||||
return ApiApiFp(this.configuration).listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, foodsOr, foodsAnd, foodsOrNot, foodsAndNot, units, rating, books, booksOr, booksAnd, booksOrNot, booksAndNot, internal, random, _new, timescooked, lastcooked, makenow, page, pageSize, options).then((request) => request(this.axios, this.basePath));
|
return ApiApiFp(this.configuration).listRecipes(query, keywords, keywordsOr, keywordsAnd, keywordsOrNot, keywordsAndNot, foods, foodsOr, foodsAnd, foodsOrNot, foodsAndNot, units, rating, books, booksOr, booksAnd, booksOrNot, booksAndNot, internal, random, _new, timescooked, lastcooked, makenow, page, pageSize, options).then((request) => request(this.axios, this.basePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user