mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-02 20:59:28 -05:00
Merge pull request #3048 from smilerz/shoppinglist_fix
Shoppinglist fix
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user