diff --git a/cookbook/views/api.py b/cookbook/views/api.py index 670bd9cbf9..a0ceada127 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -1168,12 +1168,24 @@ def get_queryset(self): @decorators.action(detail=False, methods=['POST'], serializer_class=ShoppingListEntryBulkSerializer, permission_classes=[CustomIsUser]) def bulk(self, request): serializer = self.serializer_class(data=request.data) + if serializer.is_valid(): - ShoppingListEntry.objects.filter(Q(created_by=self.request.user) - | Q(created_by__in=list(self.request.user.get_shopping_share()))).filter(space=request.space, id__in=serializer.validated_data['ids'] - ).update(checked=serializer.validated_data['checked'], - updated_at=timezone.now(), - ) + print(serializer.validated_data) + bulk_entries = ShoppingListEntry.objects.filter( + Q(created_by=self.request.user) | Q(created_by__in=list(self.request.user.get_shopping_share())) + ).filter(space=request.space, id__in=serializer.validated_data['ids']) + bulk_entries.update(checked=(checked := serializer.validated_data['checked']), updated_at=timezone.now(), ) + + # update the onhand for food if shopping_add_onhand is True + if request.user.userpreference.shopping_add_onhand: + foods = Food.objects.filter(id__in=bulk_entries.values('food')) + if checked: + for f in foods: + f.onhand_users.add(*request.user.userpreference.shopping_share.all(), request.user) + elif checked == False: + for f in foods: + f.onhand_users.remove(*request.user.userpreference.shopping_share.all(), request.user) + return Response(serializer.data) else: return Response(serializer.errors, 400) diff --git a/vue/src/apps/ShoppingListView/ShoppingListView.vue b/vue/src/apps/ShoppingListView/ShoppingListView.vue index f5a22a316e..3a6f09ccf6 100644 --- a/vue/src/apps/ShoppingListView/ShoppingListView.vue +++ b/vue/src/apps/ShoppingListView/ShoppingListView.vue @@ -75,26 +75,25 @@ - + v-if="(c.count_unchecked > 0 || user_preference_store.device_settings.shopping_show_checked_entries) + && (c.count_unchecked + c.count_checked) > 0 + && (c.count_delayed_unchecked < c.count_unchecked || user_preference_store.device_settings.shopping_show_delayed_entries)" + > + - {{ - $t('Undefined') - }} + {{$t('Undefined')}} {{ c.name }} - + :class="{'btn-success':(c.count_unchecked > 0), 'btn-warning': (c.count_unchecked <= 0)}" + @click="checkGroup(c, (c.count_unchecked > 0))"> + - - + + diff --git a/vue/src/stores/ShoppingListStore.js b/vue/src/stores/ShoppingListStore.js index bacaf86abb..a5169e97e7 100644 --- a/vue/src/stores/ShoppingListStore.js +++ b/vue/src/stores/ShoppingListStore.js @@ -1,10 +1,10 @@ -import {ApiApiFactory} from "@/utils/openapi/api" -import {StandardToasts} from "@/utils/utils" -import {defineStore} from "pinia" -import Vue from "vue" -import _ from 'lodash'; import {useUserPreferenceStore} from "@/stores/UserPreferenceStore"; +import {ApiApiFactory} from "@/utils/openapi/api"; +import {StandardToasts} from "@/utils/utils"; +import _ from 'lodash'; import moment from "moment/moment"; +import {defineStore} from "pinia"; +import Vue from "vue"; const _STORE_ID = "shopping_list_store" /* @@ -60,6 +60,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, { let total_checked = 0 let total_unchecked_food = 0 let total_checked_food = 0 + for (let i in structure) { let count_unchecked = 0 let count_checked = 0 @@ -75,7 +76,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, { } else { food_checked = false count_unchecked++ - if (structure[i]['foods'][fi]['entries'][ei].delay_until != null){ + if (this.is_delayed(structure[i]['foods'][fi]['entries'][ei])){ count_delayed_unchecked++ } } @@ -171,7 +172,8 @@ export const useShoppingListStore = defineStore(_STORE_ID, { } } return false - } + }, + }, actions: { /** @@ -222,8 +224,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, { this.last_autosync = new Date().getTime(); let apiClient = new ApiApiFactory() - apiClient.listShoppingListEntrys(undefined, undefined, undefined, { - 'query': {'last_autosync': previous_autosync} + apiClient.listShoppingListEntrys(undefined, undefined, undefined, {'query': {'last_autosync': previous_autosync} }).then((r) => { r.data.forEach((e) => { // dont update stale client data @@ -491,6 +492,17 @@ export const useShoppingListStore = defineStore(_STORE_ID, { // can use localization in store //StandardToasts.makeStandardToast(this, this.$t('NoMoreUndo')) } + }, + /** + * checks if the delay_until is in the future. If it is, the item is delayed + */ + is_delayed: function(entry) { + let delayed = false + if (entry.delay_until != null) { + const delay_until = new Date(entry.delay_until) + delayed = delay_until.getTime() > Date.now() + } + return delayed } }, })