diff --git a/src/main/java/catering/inventory/InventoryController.java b/src/main/java/catering/inventory/InventoryController.java new file mode 100644 index 0000000..d87c5aa --- /dev/null +++ b/src/main/java/catering/inventory/InventoryController.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2023 Simon Bruder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package catering.inventory; + +import org.salespointframework.catalog.Product; +import org.salespointframework.inventory.UniqueInventory; +import org.salespointframework.inventory.UniqueInventoryItem; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.util.Assert; +import org.springframework.validation.Errors; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; + +import catering.catalog.CatalogDummy; +import catering.catalog.CateringCatalog; +import jakarta.validation.Valid; + +@Controller +class InventoryController { + private final UniqueInventory inventory; + private final CateringCatalog cateringCatalog; + + InventoryController(UniqueInventory inventory, CateringCatalog cateringCatalog) { + Assert.notNull(inventory, "Inventory must not be null!"); + Assert.notNull(inventory, "CateringCatalog must not be null!"); + this.inventory = inventory; + this.cateringCatalog = cateringCatalog; + } + + @GetMapping("/inventory") + String list(Model model) { + model.addAttribute("inventory", inventory.findAll()); + + return "inventory"; + } + + @GetMapping("/inventory/edit/{pid}") + String edit(Model model, @PathVariable Product pid) { + model.addAttribute("product", pid); + model.addAttribute("item", inventory.findByProduct(pid).get()); + + return "inventory-mutate"; + } + + @PostMapping("/inventory/edit/{pid}") + String edit(@Valid InventoryMutateForm form, Errors result, @PathVariable Product pid) { + if (result.hasErrors()) { + return "redirect:/inventory/edit/" + pid.getId(); + } + CatalogDummy product = (CatalogDummy) pid; + UniqueInventoryItem item = inventory.findByProduct(pid).get(); + + product.setName(form.getName()); + product.setType(form.getType()); + product.setPrice(form.getRetailPrice()); + product.setWholesalePrice(form.getWholesalePrice()); + product.setPromotionPrice(form.getPromotionPrice().orElse(null)); + + product = cateringCatalog.save(product); + + // no setQuantity in enterprise java + // (though returing a modified object is actually nice) + inventory.save(item.increaseQuantity(form.getQuantity().subtract(item.getQuantity()))); + return "redirect:/inventory"; + } + + @GetMapping("/inventory/add") + String add() { + return "inventory-mutate"; + } + + @PostMapping("/inventory/add") + String add(@Valid InventoryMutateForm form, Errors result) { + if (result.hasErrors()) { + return "inventory-mutate"; + } + inventory.save(new UniqueInventoryItem( + cateringCatalog.save(new CatalogDummy(form.getName(), form.getType(), form.getRetailPrice(), + form.getWholesalePrice(), form.getPromotionPrice().orElse(null))), + form.getQuantity())); + return "redirect:/inventory"; + } + + @GetMapping("/inventory/delete/{pid}") + String delete(@PathVariable Product pid) { + UniqueInventoryItem item = inventory.findByProduct(pid).get(); + inventory.delete(item); + cateringCatalog.delete((CatalogDummy) pid); + return "redirect:/inventory"; + } +} diff --git a/src/main/java/catering/inventory/InventoryInizializer.java b/src/main/java/catering/inventory/InventoryInizializer.java new file mode 100644 index 0000000..217c957 --- /dev/null +++ b/src/main/java/catering/inventory/InventoryInizializer.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 Simon Bruder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package catering.inventory; + +import org.salespointframework.core.DataInitializer; +import org.salespointframework.inventory.UniqueInventory; +import org.salespointframework.inventory.UniqueInventoryItem; +import org.salespointframework.quantity.Quantity; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +import catering.catalog.CateringCatalog; + +@Component +class InventoryInitializer implements DataInitializer { + private final UniqueInventory inventory; + private final CateringCatalog cateringCatalog; + + InventoryInitializer(UniqueInventory inventory, CateringCatalog cateringCatalog) { + Assert.notNull(inventory, "Inventory must not be null!"); + Assert.notNull(cateringCatalog, "CateringCatalog must not be null!"); + + this.inventory = inventory; + this.cateringCatalog = cateringCatalog; + } + + @Override + public void initialize() { + cateringCatalog.findAll().forEach(product -> { + if (inventory.findByProduct(product).isEmpty()) { + inventory.save(new UniqueInventoryItem(product, Quantity.of(10))); + } + }); + } +} diff --git a/src/main/java/catering/inventory/InventoryMutateForm.java b/src/main/java/catering/inventory/InventoryMutateForm.java new file mode 100644 index 0000000..dcdf99f --- /dev/null +++ b/src/main/java/catering/inventory/InventoryMutateForm.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2023 Simon Bruder + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package catering.inventory; + +import static org.salespointframework.core.Currencies.EURO; + +import java.util.Optional; + +import javax.money.MonetaryAmount; + +import org.javamoney.moneta.Money; +import org.salespointframework.quantity.Quantity; + +import catering.catalog.CatalogDummyType; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.PositiveOrZero; // NonNegative in enterprise java + +class InventoryMutateForm { + private final @NotNull CatalogDummyType type; + private final @NotEmpty String name; + private final @NotNull Quantity quantity; + private final @NotNull MonetaryAmount wholesalePrice, retailPrice; + private final @NotNull Optional promotionPrice; + + public InventoryMutateForm(@NotNull CatalogDummyType type, @NotEmpty String name, + @NotNull Quantity quantity, @PositiveOrZero double wholesalePrice, @PositiveOrZero double retailPrice, + @PositiveOrZero Optional promotionPrice) { + this.type = type; + this.name = name; + this.quantity = quantity; + this.wholesalePrice = Money.of(wholesalePrice, EURO); + this.retailPrice = Money.of(retailPrice, EURO); + this.promotionPrice = promotionPrice.map(price -> (MonetaryAmount) Money.of(price, EURO)); + } + + public CatalogDummyType getType() { + return type; + } + + public String getName() { + return name; + } + + public Quantity getQuantity() { + return quantity; + } + + public MonetaryAmount getWholesalePrice() { + return wholesalePrice; + } + + public MonetaryAmount getRetailPrice() { + return retailPrice; + } + + public Optional getPromotionPrice() { + return promotionPrice; + } +} diff --git a/src/main/resources/templates/inventory-mutate.html b/src/main/resources/templates/inventory-mutate.html new file mode 100644 index 0000000..354f801 --- /dev/null +++ b/src/main/resources/templates/inventory-mutate.html @@ -0,0 +1,42 @@ + + + + +

Lagerverwaltung

+

+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + +
+
+ +
+ +
+ + diff --git a/src/main/resources/templates/inventory.html b/src/main/resources/templates/inventory.html new file mode 100644 index 0000000..8d78cee --- /dev/null +++ b/src/main/resources/templates/inventory.html @@ -0,0 +1,44 @@ + + + + +

Lagerverwaltung

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID ProduktnameMengeEinkaufspreisUVPGesamtwert
+ +