added simple entry mode to shopping

This commit is contained in:
vabene1111
2021-02-03 19:38:09 +01:00
parent 3afd18ccdc
commit bcd2e44493
6 changed files with 80 additions and 9 deletions

View File

@ -0,0 +1,8 @@
class Integration:
@staticmethod
def get_recipe(string):
raise Exception('Method not implemented in storage integration')
@staticmethod
def get_export(recipe):
raise Exception('Method not implemented in storage integration')

View File

@ -407,13 +407,9 @@ class ShoppingListRecipe(models.Model):
class ShoppingListEntry(models.Model):
list_recipe = models.ForeignKey(
ShoppingListRecipe, on_delete=models.CASCADE, null=True, blank=True
)
list_recipe = models.ForeignKey(ShoppingListRecipe, on_delete=models.CASCADE, null=True, blank=True)
food = models.ForeignKey(Food, on_delete=models.CASCADE)
unit = models.ForeignKey(
Unit, on_delete=models.CASCADE, null=True, blank=True
)
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, null=True, blank=True)
amount = models.DecimalField(default=0, decimal_places=16, max_digits=32)
order = models.IntegerField(default=0)
checked = models.BooleanField(default=False)

View File

@ -178,7 +178,7 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer):
def create(self, validated_data):
# since multi select tags dont have id's
# duplicate names might be routed to create
obj, created = Food.objects.get_or_create(**validated_data)
obj, created = Food.objects.get_or_create(name=validated_data['name'])
return obj
def update(self, instance, validated_data):

View File

@ -135,6 +135,27 @@
</table>
<div class="row">
<div class="col-12">
<form v-on:submit.prevent="addSimpleEntry()">
<label for="id_simple_entry">{% trans 'Add Entry' %}</label>
<div class="input-group">
<input id="id_simple_entry" class="form-control" v-model="simple_entry">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button"><i class="fa fa-plus"></i>
</button>
</div>
</div>
</form>
</div>
</div>
<br/>
<br/>
<div class="row">
<div class="col-12 col-lg-3">
@ -278,7 +299,8 @@
</td>
<td>[[x.amount]]</td>
<td>[[x.unit.name]]</td>
<td>[[x.food.name]] <span class="text-muted" v-if="x.recipes.length > 0">([[x.recipes.join(', ')]])</span></td>
<td>[[x.food.name]] <span class="text-muted" v-if="x.recipes.length > 0">([[x.recipes.join(', ')]])</span>
</td>
</template>
</tr>
</template>
@ -382,6 +404,7 @@
users: [],
users_loading: false,
onLine: navigator.onLine,
simple_entry: '',
},
directives: {
tabindex: {
@ -444,7 +467,12 @@
let entry = this.findMergeEntry(categories, item)
if (entry !== undefined) {
entry.amount += item.amount * this.servings_cache[item.list_recipe]
let servings = 1
if (item.list_recipe in this.servings_cache) {
servings = this.servings_cache[item.list_recipe]
}
entry.amount += item.amount * servings
if (item.list_recipe !== null && entry.recipes.indexOf(this.recipe_cache[item.list_recipe]) === -1) {
entry.recipes.push(this.recipe_cache[item.list_recipe])
@ -736,6 +764,28 @@
this.makeToast(gettext('Error'), gettext('Please enter a valid food'), 'danger')
}
},
addSimpleEntry: function () {
if (this.simple_entry !== '') {
this.$http.post('{% url 'api_ingredient_from_string' %}', {text: this.simple_entry}, {emulateJSON: true}).then((response) => {
console.log(response)
this.shopping_list.entries.push({
'list_recipe': null,
'food': {'name': response.body.food, supermarket_category: null},
'unit': {'name': response.body.unit},
'amount': response.body.amount,
'order': 0,
'checked': false,
})
this.simple_entry = ''
}).catch((err) => {
console.log(err)
this.makeToast(gettext('Error'), gettext('Something went wrong while trying to add the simple entry.'), 'danger')
})
}
},
getRecipes: function () {
let url = "{% url 'api:recipe-list' %}?limit=5&internal=true"
if (this.recipe_query !== '') {

View File

@ -88,6 +88,7 @@ urlpatterns = [
path('api/plan-ical/<slug:from_date>/<slug:to_date>/', api.get_plan_ical, name='api_get_plan_ical'),
path('api/recipe-from-url/', api.recipe_from_url, name='api_recipe_from_url'),
path('api/backup/', api.get_backup, name='api_backup'),
path('api/ingredient-from-string/', api.ingredient_from_string, name='api_ingredient_from_string'),
path('dal/keyword/', dal.KeywordAutocomplete.as_view(), name='dal_keyword'),
path('dal/food/', dal.IngredientsAutocomplete.as_view(), name='dal_food'),

View File

@ -27,6 +27,7 @@ from rest_framework.parsers import MultiPartParser
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin
from cookbook.helper.ingredient_parser import parse
from cookbook.helper.permission_helper import (CustomIsAdmin, CustomIsGuest,
CustomIsOwner, CustomIsShare,
CustomIsShared, CustomIsUser,
@ -536,3 +537,18 @@ def get_backup(request):
response["Content-Disposition"] = f'attachment; filename=backup{date_format(timezone.now(), format="SHORT_DATETIME_FORMAT", use_l10n=True)}.json' # noqa: E501
return response
@group_required('user')
def ingredient_from_string(request):
text = request.POST['text']
amount, unit, food, note = parse(text)
return JsonResponse(
{
'amount': amount,
'unit': unit,
'food': food,
},
status=200
)