aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDiederick de Vries <diederick@diederickdevries.net>2018-09-17 16:21:33 +0200
committerDiederick de Vries <diederick@diederickdevries.net>2018-09-17 16:21:33 +0200
commit8d6cd95fd0f061b976f5d04bdcf63cafb74f0fb7 (patch)
tree9e96689cec62cd1a0d1941096867fb4f4fed0598
parent8365f536062fb249530f963b88c7a7238d4631b0 (diff)
parent338295434a271dadeffb303bf13a5bdbe95f960e (diff)
downloadboodschapi-8d6cd95fd0f061b976f5d04bdcf63cafb74f0fb7.tar.gz
boodschapi-8d6cd95fd0f061b976f5d04bdcf63cafb74f0fb7.tar.bz2
boodschapi-8d6cd95fd0f061b976f5d04bdcf63cafb74f0fb7.zip
Merge branch 'feat-dedouble-groceries'
-rw-r--r--src/main/java/net/diederickdevries/boodschapi/controller/GroceryController.java33
-rw-r--r--src/main/java/net/diederickdevries/boodschapi/controller/ItemController.java2
-rw-r--r--src/main/java/net/diederickdevries/boodschapi/model/Grocery.java9
-rw-r--r--src/main/java/net/diederickdevries/boodschapi/repository/ItemRepository.java2
-rw-r--r--src/main/java/net/diederickdevries/boodschapi/util/ItemUtil.java2
-rw-r--r--src/main/resources/static/js/grocery.js7
-rw-r--r--src/test/java/net/diederickdevries/boodschapi/controller/GroceryControllerIT.java41
-rw-r--r--src/test/java/net/diederickdevries/boodschapi/util/ItemUtilTest.java6
8 files changed, 84 insertions, 18 deletions
diff --git a/src/main/java/net/diederickdevries/boodschapi/controller/GroceryController.java b/src/main/java/net/diederickdevries/boodschapi/controller/GroceryController.java
index a51d2e3..40bc5ad 100644
--- a/src/main/java/net/diederickdevries/boodschapi/controller/GroceryController.java
+++ b/src/main/java/net/diederickdevries/boodschapi/controller/GroceryController.java
@@ -20,11 +20,15 @@ package net.diederickdevries.boodschapi.controller;
20 20
21import java.net.URISyntaxException; 21import java.net.URISyntaxException;
22import java.util.Optional; 22import java.util.Optional;
23import java.util.List;
23import net.diederickdevries.boodschapi.model.Category; 24import net.diederickdevries.boodschapi.model.Category;
24import net.diederickdevries.boodschapi.model.Grocery; 25import net.diederickdevries.boodschapi.model.Grocery;
26import net.diederickdevries.boodschapi.model.Ingredient;
27import net.diederickdevries.boodschapi.model.Item;
25import net.diederickdevries.boodschapi.repository.CategoryRepository; 28import net.diederickdevries.boodschapi.repository.CategoryRepository;
26import net.diederickdevries.boodschapi.repository.GroceryRepository; 29import net.diederickdevries.boodschapi.repository.GroceryRepository;
27import net.diederickdevries.boodschapi.repository.IngredientRepository; 30import net.diederickdevries.boodschapi.repository.IngredientRepository;
31import net.diederickdevries.boodschapi.repository.ItemRepository;
28import net.diederickdevries.boodschapi.util.MessageUtil; 32import net.diederickdevries.boodschapi.util.MessageUtil;
29import net.diederickdevries.boodschapi.util.RequestUtil; 33import net.diederickdevries.boodschapi.util.RequestUtil;
30import org.springframework.beans.factory.annotation.Autowired; 34import org.springframework.beans.factory.annotation.Autowired;
@@ -55,6 +59,7 @@ public class GroceryController
55 @Autowired private GroceryRepository groceryRepository; 59 @Autowired private GroceryRepository groceryRepository;
56 @Autowired private CategoryRepository categoryRepository; 60 @Autowired private CategoryRepository categoryRepository;
57 @Autowired private IngredientRepository ingredientRepository; 61 @Autowired private IngredientRepository ingredientRepository;
62 @Autowired private ItemRepository itemRepository;
58 63
59 /** 64 /**
60 * Adds a new grocery to the category with the id given, unless the category 65 * Adds a new grocery to the category with the id given, unless the category
@@ -116,16 +121,18 @@ public class GroceryController
116 } 121 }
117 122
118 /** 123 /**
119 * Changes the name of the Grocery with the id given into the value given. 124 * Changes the name of the Grocery with the id given into the value
120 * If the name was already in use by another hidden grocery, it is deleted 125 * given. If the name was already in use by another hidden grocery, it is
121 * and the existing grocery is no longer hidden. 126 * deleted and the existing grocery is no longer hidden. Any references to
127 * the deleted grocery (meals, shopping lists) are not pointing to the
128 * existing grocery.
122 * 129 *
123 * @param id The id of the Grocery to change. 130 * @param id The id of the Grocery to change.
124 * @param value The new name of the Grocery. 131 * @param value The new name of the Grocery.
125 * @return The Grocery with the new name. 132 * @return The Grocery with the new name.
126 */ 133 */
127 @RequestMapping(value = "/edit", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) 134 @RequestMapping(value = "/edit", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
128 public ResponseEntity<Object> edit(final Integer id, final String value) 135 public ResponseEntity<Object> edit(final Integer id, final String value) throws URISyntaxException
129 { 136 {
130 final String name = value.trim(); 137 final String name = value.trim();
131 if (name.isEmpty()) 138 if (name.isEmpty())
@@ -148,14 +155,14 @@ public class GroceryController
148 Grocery existing = groceryRepository.findByName(name); 155 Grocery existing = groceryRepository.findByName(name);
149 if (null != existing) 156 if (null != existing)
150 { 157 {
158 moveReferences(grocery, existing);
151 existing.setShow(true); 159 existing.setShow(true);
152 existing.setShowAlways(true);
153 groceryRepository.save(existing); 160 groceryRepository.save(existing);
154 groceryRepository.delete(grocery); 161 groceryRepository.delete(grocery);
155 groceryRepository.flush(); 162 groceryRepository.flush();
156 return ResponseEntity 163 return ResponseEntity
157 .badRequest() 164 .status(HttpStatus.MOVED_PERMANENTLY)
158 .body(MessageUtil.parse(MSG_400_GROCERY_EXISTS, value, existing.getCategory().getName())); 165 .body(RequestUtil.getResourceURI(existing.getId()));
159 } 166 }
160 grocery.setName(name); 167 grocery.setName(name);
161 groceryRepository.saveAndFlush(grocery); 168 groceryRepository.saveAndFlush(grocery);
@@ -251,4 +258,16 @@ public class GroceryController
251 groceryRepository.saveAndFlush(grocery); 258 groceryRepository.saveAndFlush(grocery);
252 return ResponseEntity.ok().body(grocery); 259 return ResponseEntity.ok().body(grocery);
253 } 260 }
261
262 private void moveReferences(Grocery from, Grocery to) {
263 List<Ingredient> ingredients = ingredientRepository.findByGrocery(from);
264 ingredients.forEach(i -> { i.setGrocery(to); });
265 ingredientRepository.saveAll(ingredients);
266 ingredientRepository.flush();
267
268 List<Item> items = itemRepository.findByGrocery(from);
269 items.forEach(i -> { i.setGrocery(to); });
270 itemRepository.saveAll(items);
271 itemRepository.flush();
272 }
254} 273}
diff --git a/src/main/java/net/diederickdevries/boodschapi/controller/ItemController.java b/src/main/java/net/diederickdevries/boodschapi/controller/ItemController.java
index 76c3430..80c374d 100644
--- a/src/main/java/net/diederickdevries/boodschapi/controller/ItemController.java
+++ b/src/main/java/net/diederickdevries/boodschapi/controller/ItemController.java
@@ -64,7 +64,7 @@ public class ItemController
64 * 64 *
65 * @param groceryid The id of the grocery that the item is. 65 * @param groceryid The id of the grocery that the item is.
66 * @param shopid The id of the shop to add the item to. 66 * @param shopid The id of the shop to add the item to.
67 * @param weeknr The weeknr of the week in whose shoppinh list the item should appear. 67 * @param weeknr The weeknr of the week in whose shopping list the item should appear.
68 * @return The added item. 68 * @return The added item.
69 * @throws java.net.URISyntaxException 69 * @throws java.net.URISyntaxException
70 */ 70 */
diff --git a/src/main/java/net/diederickdevries/boodschapi/model/Grocery.java b/src/main/java/net/diederickdevries/boodschapi/model/Grocery.java
index 9ad8a70..472acef 100644
--- a/src/main/java/net/diederickdevries/boodschapi/model/Grocery.java
+++ b/src/main/java/net/diederickdevries/boodschapi/model/Grocery.java
@@ -219,6 +219,13 @@ public class Grocery implements Serializable
219 @Override 219 @Override
220 public String toString() 220 public String toString()
221 { 221 {
222 return "Grocery [ id=" + id + " ] name = " + name; 222 return "Grocery[ id=" + id + " ]"
223 + "bought = " + this.getBought()
224 + ", category = " + (null != this.category ? this.category.getName(): "null")
225 + ", name = " + this.getName()
226 + ", shop = " + (null != this.shop ? this.shop.getName() : "null")
227 + ", show = " + this.getShop()
228 + ", showAlways = " + this.getShowAlways()
229 + ", unit = " + this.getUnit();
223 } 230 }
224} 231}
diff --git a/src/main/java/net/diederickdevries/boodschapi/repository/ItemRepository.java b/src/main/java/net/diederickdevries/boodschapi/repository/ItemRepository.java
index 5cdfadb..43d09d4 100644
--- a/src/main/java/net/diederickdevries/boodschapi/repository/ItemRepository.java
+++ b/src/main/java/net/diederickdevries/boodschapi/repository/ItemRepository.java
@@ -79,5 +79,7 @@ public interface ItemRepository extends JpaRepository<Item, Integer>
79 */ 79 */
80 public Item findByWeekAndGrocery(String week, Grocery grocery); 80 public Item findByWeekAndGrocery(String week, Grocery grocery);
81 81
82 public List<Item> findByGrocery(Grocery grocery);
83
82 public List<Item> findByShop(Shop shop); 84 public List<Item> findByShop(Shop shop);
83} \ No newline at end of file 85} \ No newline at end of file
diff --git a/src/main/java/net/diederickdevries/boodschapi/util/ItemUtil.java b/src/main/java/net/diederickdevries/boodschapi/util/ItemUtil.java
index 40b539c..8362b4a 100644
--- a/src/main/java/net/diederickdevries/boodschapi/util/ItemUtil.java
+++ b/src/main/java/net/diederickdevries/boodschapi/util/ItemUtil.java
@@ -46,7 +46,7 @@ public class ItemUtil
46 46
47 // Find the name of the grocery 47 // Find the name of the grocery
48 int i = 0; 48 int i = 0;
49 while (i < chars.length && (Character.isAlphabetic(chars[i]) || ' ' == chars[i])) 49 while (i < chars.length && (Character.isAlphabetic(chars[i]) || ' ' == chars[i] || '\'' == chars[i]))
50 { 50 {
51 i++; 51 i++;
52 } 52 }
diff --git a/src/main/resources/static/js/grocery.js b/src/main/resources/static/js/grocery.js
index d7cb805..dc278ef 100644
--- a/src/main/resources/static/js/grocery.js
+++ b/src/main/resources/static/js/grocery.js
@@ -107,6 +107,13 @@ function editGrocery(id, value)
107 dataType: "json" 107 dataType: "json"
108 }); 108 });
109 109
110 ajax.always(function (response)
111 {
112 if (response.status === 301) {
113 $("li#" + id + ".grocery").hide();
114 }
115 });
116
110 ajax.fail(function (jqXHR, textStatus, errorThrown) 117 ajax.fail(function (jqXHR, textStatus, errorThrown)
111 { 118 {
112 var origin = 'composer?weeknr=' + getWeekNr(); 119 var origin = 'composer?weeknr=' + getWeekNr();
diff --git a/src/test/java/net/diederickdevries/boodschapi/controller/GroceryControllerIT.java b/src/test/java/net/diederickdevries/boodschapi/controller/GroceryControllerIT.java
index 48cecab..c350a00 100644
--- a/src/test/java/net/diederickdevries/boodschapi/controller/GroceryControllerIT.java
+++ b/src/test/java/net/diederickdevries/boodschapi/controller/GroceryControllerIT.java
@@ -23,11 +23,15 @@ import javax.transaction.Transactional;
23import net.diederickdevries.boodschapi.model.Category; 23import net.diederickdevries.boodschapi.model.Category;
24import net.diederickdevries.boodschapi.model.Grocery; 24import net.diederickdevries.boodschapi.model.Grocery;
25import net.diederickdevries.boodschapi.model.Ingredient; 25import net.diederickdevries.boodschapi.model.Ingredient;
26import net.diederickdevries.boodschapi.model.Item;
26import net.diederickdevries.boodschapi.model.Meal; 27import net.diederickdevries.boodschapi.model.Meal;
28import net.diederickdevries.boodschapi.model.Shop;
27import net.diederickdevries.boodschapi.repository.CategoryRepository; 29import net.diederickdevries.boodschapi.repository.CategoryRepository;
28import net.diederickdevries.boodschapi.repository.GroceryRepository; 30import net.diederickdevries.boodschapi.repository.GroceryRepository;
29import net.diederickdevries.boodschapi.repository.IngredientRepository; 31import net.diederickdevries.boodschapi.repository.IngredientRepository;
32import net.diederickdevries.boodschapi.repository.ItemRepository;
30import net.diederickdevries.boodschapi.repository.MealRepository; 33import net.diederickdevries.boodschapi.repository.MealRepository;
34import net.diederickdevries.boodschapi.repository.ShopRepository;
31import static org.junit.Assert.assertEquals; 35import static org.junit.Assert.assertEquals;
32import static org.junit.Assert.assertNull; 36import static org.junit.Assert.assertNull;
33import static org.junit.Assert.assertTrue; 37import static org.junit.Assert.assertTrue;
@@ -35,6 +39,7 @@ import org.junit.Test;
35import org.junit.runner.RunWith; 39import org.junit.runner.RunWith;
36import org.springframework.beans.factory.annotation.Autowired; 40import org.springframework.beans.factory.annotation.Autowired;
37import org.springframework.boot.test.context.SpringBootTest; 41import org.springframework.boot.test.context.SpringBootTest;
42import org.springframework.http.HttpStatus;
38import org.springframework.http.ResponseEntity; 43import org.springframework.http.ResponseEntity;
39import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 44import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
40 45
@@ -53,6 +58,8 @@ public class GroceryControllerIT
53 @Autowired private CategoryRepository categoryRepository; 58 @Autowired private CategoryRepository categoryRepository;
54 @Autowired private MealRepository mealRepository; 59 @Autowired private MealRepository mealRepository;
55 @Autowired private IngredientRepository ingredientRepository; 60 @Autowired private IngredientRepository ingredientRepository;
61 @Autowired private ItemRepository itemRepository;
62 @Autowired private ShopRepository shopRepository;
56 63
57 @Test 64 @Test
58 public void testAdd() throws Exception 65 public void testAdd() throws Exception
@@ -121,7 +128,7 @@ public class GroceryControllerIT
121 } 128 }
122 129
123 @Test 130 @Test
124 public void testEdit() 131 public void testEdit() throws URISyntaxException
125 { 132 {
126 final String oldName = "testEditGrocery"; 133 final String oldName = "testEditGrocery";
127 final String newName = "newName"; 134 final String newName = "newName";
@@ -139,7 +146,7 @@ public class GroceryControllerIT
139 } 146 }
140 147
141 @Test 148 @Test
142 public void testEditExistingName() 149 public void testEditExistingName() throws URISyntaxException
143 { 150 {
144 final String existingName = "testEditExistingName"; 151 final String existingName = "testEditExistingName";
145 152
@@ -155,18 +162,36 @@ public class GroceryControllerIT
155 grocery.setShow(true); 162 grocery.setShow(true);
156 groceryRepository.saveAndFlush(grocery); 163 groceryRepository.saveAndFlush(grocery);
157 164
165 // Make this grocery part of a meal and of a shopping list. These should
166 // point to the existing grocery afterwards.
167 Meal meal = new Meal();
168 meal.setName("testEditExistingNameMeal");
169 mealRepository.saveAndFlush(meal);
170
171 Ingredient ingredient = new Ingredient(meal, grocery);
172 ingredientRepository.saveAndFlush(ingredient);
173
174 Item item = new Item();
175 item.setGrocery(existing);
176 item.setShop(shopRepository.getOne(Shop.DEFAULT_SHOP));
177 itemRepository.saveAndFlush(item);
178
158 ResponseEntity response = groceryController.edit(grocery.getId(), existingName); 179 ResponseEntity response = groceryController.edit(grocery.getId(), existingName);
159 180
160 Grocery found = groceryRepository.findById(grocery.getId()).orElse(null); 181 Grocery groceryFound = groceryRepository.getOne(grocery.getId());
182 Item itemFound = itemRepository.getOne(item.getId());
183 Ingredient ingredientFound = ingredientRepository.getOne(ingredient.getId());
161 184
162 assertEquals("The response status", 400, response.getStatusCodeValue()); 185 assertEquals("The response status is 301", 301, response.getStatusCodeValue());
163 assertNull("The renamed grocery", found); 186 assertNull("The renamed grocery is not found", groceryFound);
164 assertTrue("The existing grocery", existing.getShow()); 187
165 assertTrue("The existing grocery", existing.alwaysShown()); 188 assertTrue("The existing grocery is shown", existing.getShow());
189 assertEquals("The shopping item", existing.getId(), itemFound.getGrocery().getId());
190 assertEquals("The meal", existing.getId(), ingredientFound.getGrocery().getId());
166 } 191 }
167 192
168 @Test 193 @Test
169 public void testEditEmpty() 194 public void testEditEmpty() throws URISyntaxException
170 { 195 {
171 final String oldName = "testEditGrocery"; 196 final String oldName = "testEditGrocery";
172 197
diff --git a/src/test/java/net/diederickdevries/boodschapi/util/ItemUtilTest.java b/src/test/java/net/diederickdevries/boodschapi/util/ItemUtilTest.java
index 8163856..0a207eb 100644
--- a/src/test/java/net/diederickdevries/boodschapi/util/ItemUtilTest.java
+++ b/src/test/java/net/diederickdevries/boodschapi/util/ItemUtilTest.java
@@ -76,5 +76,11 @@ public class ItemUtilTest
76 grocery.setUnit(null); 76 grocery.setUnit(null);
77 item.setAmount(null); 77 item.setAmount(null);
78 assertEquals(item, ItemUtil.parseItem("Namewithoutspaces")); 78 assertEquals(item, ItemUtil.parseItem("Namewithoutspaces"));
79
80 item.setAmount(1F);
81 grocery.setUnit("x");
82 grocery.setName("Apostrophe's");
83 assertEquals(item, ItemUtil.parseItem("Apostrophe's (1x)"));
84
79 } 85 }
80} 86}