Merge pull request #3048 from smilerz/shoppinglist_fix

Shoppinglist fix
This commit is contained in:
vabene1111
2024-03-21 14:08:23 +01:00
committed by GitHub
3 changed files with 49 additions and 26 deletions

View File

@@ -1168,12 +1168,24 @@ class ShoppingListEntryViewSet(viewsets.ModelViewSet):
@decorators.action(detail=False, methods=['POST'], serializer_class=ShoppingListEntryBulkSerializer, permission_classes=[CustomIsUser]) @decorators.action(detail=False, methods=['POST'], serializer_class=ShoppingListEntryBulkSerializer, permission_classes=[CustomIsUser])
def bulk(self, request): def bulk(self, request):
serializer = self.serializer_class(data=request.data) serializer = self.serializer_class(data=request.data)
if serializer.is_valid(): if serializer.is_valid():
ShoppingListEntry.objects.filter(Q(created_by=self.request.user) print(serializer.validated_data)
| Q(created_by__in=list(self.request.user.get_shopping_share()))).filter(space=request.space, id__in=serializer.validated_data['ids'] bulk_entries = ShoppingListEntry.objects.filter(
).update(checked=serializer.validated_data['checked'], Q(created_by=self.request.user) | Q(created_by__in=list(self.request.user.get_shopping_share()))
updated_at=timezone.now(), ).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) return Response(serializer.data)
else: else:
return Response(serializer.errors, 400) return Response(serializer.errors, 400)

View File

@@ -75,26 +75,25 @@
<!-- --------------------------------------- shopping list table --> <!-- --------------------------------------- shopping list table -->
<b-row v-for="c in shopping_list_store.get_entries_by_group" v-bind:key="c.id"> <b-row v-for="c in shopping_list_store.get_entries_by_group" v-bind:key="c.id">
<b-col cols="12" <b-col cols="12"
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 )"> v-if="(c.count_unchecked > 0 || user_preference_store.device_settings.shopping_show_checked_entries)
<b-button-group class="w-100 mt-1" && (c.count_unchecked + c.count_checked) > 0
:class="{'flex-row-reverse': useUserPreferenceStore().user_settings.left_handed}"> && (c.count_delayed_unchecked < c.count_unchecked || user_preference_store.device_settings.shopping_show_delayed_entries)"
>
<b-button-group class="w-100 mt-1" :class="{'flex-row-reverse': useUserPreferenceStore().user_settings.left_handed}">
<b-button variant="info" block class="btn btn-block text-left"> <b-button variant="info" block class="btn btn-block text-left">
<span v-if="c.name === shopping_list_store.UNDEFINED_CATEGORY">{{ <span v-if="c.name === shopping_list_store.UNDEFINED_CATEGORY">{{$t('Undefined')}}</span>
$t('Undefined')
}}</span>
<span v-else>{{ c.name }}</span> <span v-else>{{ c.name }}</span>
</b-button> </b-button>
<b-button class="d-print-none " <b-button class="d-print-none "
:class="{'btn-success':(c.count_unchecked > 0), 'btn-warning': (c.count_unchecked <= 0)}" :class="{'btn-success':(c.count_unchecked > 0), 'btn-warning': (c.count_unchecked <= 0)}"
@click="checkGroup(c, (c.count_unchecked > 0))"> @click="checkGroup(c, (c.count_unchecked > 0))">
<i class="fas fa-fw" <i class="fas fa-fw" :class="{'fa-check':(c.count_unchecked > 0), 'fa-cart-plus':(c.count_unchecked <= 0) }"></i>
:class="{'fa-check':(c.count_unchecked > 0), 'fa-cart-plus':(c.count_unchecked <= 0) }"></i>
</b-button> </b-button>
</b-button-group> </b-button-group>
<span v-for="f in c.foods" v-bind:key="f.id"> <span v-for="f in c.foods" v-bind:key="f.id">
<shopping-line-item :entries="f['entries']" class="mt-1"/> <shopping-line-item :entries="f['entries']" class="mt-1"/>
</span> </span>
</b-col> </b-col>
</b-row> </b-row>

View File

@@ -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 {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
import {ApiApiFactory} from "@/utils/openapi/api";
import {StandardToasts} from "@/utils/utils";
import _ from 'lodash';
import moment from "moment/moment"; import moment from "moment/moment";
import {defineStore} from "pinia";
import Vue from "vue";
const _STORE_ID = "shopping_list_store" const _STORE_ID = "shopping_list_store"
/* /*
@@ -60,6 +60,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
let total_checked = 0 let total_checked = 0
let total_unchecked_food = 0 let total_unchecked_food = 0
let total_checked_food = 0 let total_checked_food = 0
for (let i in structure) { for (let i in structure) {
let count_unchecked = 0 let count_unchecked = 0
let count_checked = 0 let count_checked = 0
@@ -75,7 +76,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
} else { } else {
food_checked = false food_checked = false
count_unchecked++ 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++ count_delayed_unchecked++
} }
} }
@@ -171,7 +172,8 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
} }
} }
return false return false
} },
}, },
actions: { actions: {
/** /**
@@ -222,8 +224,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
this.last_autosync = new Date().getTime(); this.last_autosync = new Date().getTime();
let apiClient = new ApiApiFactory() let apiClient = new ApiApiFactory()
apiClient.listShoppingListEntrys(undefined, undefined, undefined, { apiClient.listShoppingListEntrys(undefined, undefined, undefined, {'query': {'last_autosync': previous_autosync}
'query': {'last_autosync': previous_autosync}
}).then((r) => { }).then((r) => {
r.data.forEach((e) => { r.data.forEach((e) => {
// dont update stale client data // dont update stale client data
@@ -491,6 +492,17 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
// can use localization in store // can use localization in store
//StandardToasts.makeStandardToast(this, this.$t('NoMoreUndo')) //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
} }
}, },
}) })