diff --git a/cookbook/views/api.py b/cookbook/views/api.py
index a35ac1ce25..c2f78d72f6 100644
--- a/cookbook/views/api.py
+++ b/cookbook/views/api.py
@@ -612,10 +612,14 @@ def fdc(self, request, pk):
data = json.loads(response.content)
food_property_list = []
- food_property_types = food.foodproperty_set.values_list('property__property_type_id', flat=True)
- for pt in PropertyType.objects.filter(space=request.space).all():
- if pt.fdc_id and pt.id not in food_property_types:
+ # delete all properties where the property type has a fdc_id as these should be overridden
+ for fp in food.properties.all():
+ if fp.property_type.fdc_id:
+ fp.delete()
+
+ for pt in PropertyType.objects.filter(space=request.space, fdc_id__gte=0).all():
+ if pt.fdc_id:
for fn in data['foodNutrients']:
if fn['nutrient']['id'] == pt.fdc_id:
food_property_list.append(Property(
diff --git a/vue/src/apps/TestView/TestView.vue b/vue/src/apps/TestView/TestView.vue
index 25a4dd0fe1..31ec9087e4 100644
--- a/vue/src/apps/TestView/TestView.vue
+++ b/vue/src/apps/TestView/TestView.vue
@@ -4,48 +4,46 @@
{{ recipe.name }}
-
+
{{ $t('Name') }} |
FDC |
{{ $t('Properties_Food_Amount') }} |
{{ $t('Properties_Food_Unit') }} |
-
-
-
+ |
{{ pt.name }} ({{ pt.unit }})
|
-
+
- {{ f.food.name }}
+ {{ f.name }}
|
-
+ |
-
+
-
+
|
-
-
+ |
+
|
-
+ |
+ :disabled="f.loading"/>
|
-
+
|
@@ -57,7 +55,7 @@
:model="Models.PROPERTY_TYPE"
:action="Actions.UPDATE"
:item1="editing_property_type"
- @finish-action="editing_property_type = null; loadPropertyTypes()">
+ @finish-action="editing_property_type = null; loadData()">
@@ -86,32 +84,7 @@ export default {
mixins: [ApiMixin],
components: {GenericModalForm, GenericMultiselect},
computed: {
- foods: function () {
- let foods = {}
- if (this.recipe !== null && this.property_types !== []) {
- this.recipe.steps.forEach(s => {
- s.ingredients.forEach(i => {
- let food = {food: i.food, properties: {}, loading: false}
-
- this.property_types.forEach(pt => {
- food.properties[pt.id] = {changed: false, property_amount: 0, property_type: pt}
- })
- i.food.properties.forEach(fp => {
- food.properties[fp.property_type.id] = {changed: false, property_amount: fp.property_amount, property_type: fp.property_type}
- })
- foods[food.food.id] = food
- })
- })
- }
- return foods
- },
- properties: function () {
- let properties = {}
- this.property_types.forEach(pt => {
- properties[pt.id] = pt
- })
- return properties
- }
+
},
data() {
return {
@@ -119,51 +92,95 @@ export default {
property_types: [],
editing_property_type: null,
loading: false,
+ foods: [],
}
},
mounted() {
this.$i18n.locale = window.CUSTOM_LOCALE
- this.loadRecipe();
- this.loadPropertyTypes();
+ this.loadData();
},
methods: {
- loadRecipe: function () {
+ loadData: function () {
let apiClient = new ApiApiFactory()
- apiClient.retrieveRecipe("112").then(result => {
- this.recipe = result.data
- this.loading = false;
- }).catch((err) => {
- StandardToasts.makeStandardToast(this, StandardToasts.FAIL_FETCH, err)
- })
- },
- loadPropertyTypes: function () {
- let apiClient = new ApiApiFactory()
apiClient.listPropertyTypes().then(result => {
this.property_types = result.data
+
+ apiClient.retrieveRecipe("112").then(result => { //TODO get recipe id
+ this.recipe = result.data
+
+ this.foods = []
+
+ this.recipe.steps.forEach(s => {
+ s.ingredients.forEach(i => {
+ if (this.foods.filter(x => (x.id === i.food.id)).length === 0) {
+ this.foods.push(this.buildFood(i.food))
+ }
+ })
+ })
+ this.loading = false;
+ }).catch((err) => {
+ StandardToasts.makeStandardToast(this, StandardToasts.FAIL_FETCH, err)
+ })
}).catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_FETCH, err)
})
},
+ buildFood: function (food) {
+ /**
+ * Prepare food for display in grid by making sure the food properties are in the same order as property_types and that no types are missing
+ * */
+
+ let existing_properties = {}
+ food.properties.forEach(fp => {
+ existing_properties[fp.property_type.id] = fp
+ })
+
+ let food_properties = []
+ this.property_types.forEach(pt => {
+ let new_food_property = {
+ property_type: pt,
+ property_amount: 0,
+ }
+ if (pt.id in existing_properties) {
+ new_food_property = existing_properties[pt.id]
+ }
+ food_properties.push(new_food_property)
+ })
+
+ this.$set(food, 'loading', false)
+
+ food.properties = food_properties
+
+ return food
+ },
+ spliceInFood: function (food){
+ /**
+ * replace food in foods list, for example after updates from the server
+ */
+ this.foods = this.foods.map(f => (f.id === food.id) ? food : f)
+
+ },
updateFood: function (food) {
let apiClient = new ApiApiFactory()
apiClient.partialUpdateFood(food.id, food).then(result => {
+ this.spliceInFood(this.buildFood(result.data))
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE)
}).catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
})
},
updateFoodFromFDC: function (food) {
- this.loading = true;
+ food.loading = true;
let apiClient = new ApiApiFactory()
apiClient.fdcFood(food.id).then(result => {
StandardToasts.makeStandardToast(this, StandardToasts.SUCCESS_UPDATE)
- this.loadRecipe()
+ this.spliceInFood(this.buildFood(result.data))
}).catch((err) => {
StandardToasts.makeStandardToast(this, StandardToasts.FAIL_UPDATE, err)
- this.loading = false;
+ food.loading = false;
})
}
},