mirror of
https://github.com/st-tu-dresden-praktikum/swt23w23
synced 2024-07-19 21:04:36 +02:00
Make metric variable
This was somehow overlooked, but it should work. This needs to change how the InventoryMutateForm handles quantities, as the amount has to be split from the metric for addition to work.
This commit is contained in:
parent
e37c2506b8
commit
7365b384e3
|
@ -1,5 +1,5 @@
|
||||||
' SPDX-License-Identifier: AGPL-3.0-or-later
|
' SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
' SPDX-FileCopyrightText: 2023 swt23w23
|
' SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
@startuml
|
@startuml
|
||||||
skinparam linetype ortho
|
skinparam linetype ortho
|
||||||
skinparam groupInheritance 2
|
skinparam groupInheritance 2
|
||||||
|
@ -57,7 +57,7 @@ package catering.catalog {
|
||||||
class Consumable {
|
class Consumable {
|
||||||
- promotionPrice : MonetaryAmount
|
- promotionPrice : MonetaryAmount
|
||||||
- wholesalePrice : MonetaryAmount
|
- wholesalePrice : MonetaryAmount
|
||||||
+ Consumable(name : String, retailPrice : MonetaryAmount, wholesalePrice : MonetaryAmount, promotionPrice : Optional<MonetaryAmount>, Set<OrderType> categories) : Consumable
|
+ Consumable(name : String, retailPrice : MonetaryAmount, wholesalePrice : MonetaryAmount, promotionPrice : Optional<MonetaryAmount>, Set<OrderType> categories, metric : Metric) : Consumable
|
||||||
+ getPrice() : MonetaryAmount
|
+ getPrice() : MonetaryAmount
|
||||||
+ getRetailPrice() : MonetaryAmount
|
+ getRetailPrice() : MonetaryAmount
|
||||||
+ setRetailPrice(price : MonetaryAmount) : void
|
+ setRetailPrice(price : MonetaryAmount) : void
|
||||||
|
@ -74,7 +74,7 @@ package catering.catalog {
|
||||||
|
|
||||||
class Rentable {
|
class Rentable {
|
||||||
- wholesalePrice : MonetaryAmount
|
- wholesalePrice : MonetaryAmount
|
||||||
+ Rentable(name : String, pricePerHour : MonetaryAmount, wholesalePrice : MonetaryAmount, Set<OrderType> categories) : Rentable
|
+ Rentable(name : String, pricePerHour : MonetaryAmount, wholesalePrice : MonetaryAmount, Set<OrderType> categories, metric : Metric) : Rentable
|
||||||
+ getWholesalePrice() : MonetaryAmount
|
+ getWholesalePrice() : MonetaryAmount
|
||||||
+ setWholesalePrice(price : MonetaryAmount)
|
+ setWholesalePrice(price : MonetaryAmount)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2023 swt23w23
|
// SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
package catering.catalog;
|
package catering.catalog;
|
||||||
|
|
||||||
import static org.salespointframework.core.Currencies.EURO;
|
import static org.salespointframework.core.Currencies.EURO;
|
||||||
|
@ -9,6 +9,7 @@ import java.util.Optional;
|
||||||
|
|
||||||
import org.javamoney.moneta.Money;
|
import org.javamoney.moneta.Money;
|
||||||
import org.salespointframework.core.DataInitializer;
|
import org.salespointframework.core.DataInitializer;
|
||||||
|
import org.salespointframework.quantity.Metric;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
@ -32,21 +33,32 @@ class CatalogDataInitializer implements DataInitializer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !!! These need to be kept in sync with CatalogUnitTests
|
||||||
cateringCatalog.save(new Consumable(
|
cateringCatalog.save(new Consumable(
|
||||||
"Brötchen Vollkorn",
|
"Brötchen Vollkorn",
|
||||||
Money.of(1, EURO),
|
Money.of(1, EURO),
|
||||||
Money.of(0.5, EURO),
|
Money.of(0.5, EURO),
|
||||||
Optional.of(Money.of(0.75, EURO)),
|
Optional.of(Money.of(0.75, EURO)),
|
||||||
Set.of(OrderType.EVENT_CATERING, OrderType.MOBILE_BREAKFAST)));
|
Set.of(OrderType.EVENT_CATERING, OrderType.MOBILE_BREAKFAST),
|
||||||
|
Metric.UNIT));
|
||||||
|
cateringCatalog.save(new Consumable(
|
||||||
|
"Tafelwasser",
|
||||||
|
Money.of(5, EURO),
|
||||||
|
Money.of(0.01, EURO),
|
||||||
|
Optional.empty(),
|
||||||
|
Set.of(OrderType.PARTY_SERVICE, OrderType.EVENT_CATERING),
|
||||||
|
Metric.LITER));
|
||||||
cateringCatalog.save(new Rentable(
|
cateringCatalog.save(new Rentable(
|
||||||
"Kerze Rot",
|
"Kerze Rot",
|
||||||
Money.of(2, EURO),
|
Money.of(2, EURO),
|
||||||
Money.of(1.5, EURO),
|
Money.of(1.5, EURO),
|
||||||
Set.of(OrderType.EVENT_CATERING, OrderType.MOBILE_BREAKFAST)));
|
Set.of(OrderType.EVENT_CATERING, OrderType.MOBILE_BREAKFAST),
|
||||||
|
Metric.UNIT));
|
||||||
cateringCatalog.save(new Rentable(
|
cateringCatalog.save(new Rentable(
|
||||||
"Brotschneidemaschine Power X 3000",
|
"Brotschneidemaschine Power X 3000",
|
||||||
Money.of(25, EURO),
|
Money.of(25, EURO),
|
||||||
Money.of(10000, EURO),
|
Money.of(10000, EURO),
|
||||||
Set.of(OrderType.EVENT_CATERING, OrderType.MOBILE_BREAKFAST)));
|
Set.of(OrderType.EVENT_CATERING, OrderType.MOBILE_BREAKFAST),
|
||||||
|
Metric.UNIT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Set;
|
||||||
import javax.money.MonetaryAmount;
|
import javax.money.MonetaryAmount;
|
||||||
|
|
||||||
import org.salespointframework.catalog.Product;
|
import org.salespointframework.catalog.Product;
|
||||||
|
import org.salespointframework.quantity.Metric;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -26,8 +27,8 @@ public class Consumable extends Product {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Consumable(String name, MonetaryAmount price, MonetaryAmount wholesalePrice,
|
public Consumable(String name, MonetaryAmount price, MonetaryAmount wholesalePrice,
|
||||||
Optional<MonetaryAmount> promotionPrice, Set<OrderType> categories) {
|
Optional<MonetaryAmount> promotionPrice, Set<OrderType> categories, Metric metric) {
|
||||||
super(name, price);
|
super(name, price, metric);
|
||||||
Assert.notNull(wholesalePrice, "wholesalePrice must not be null!");
|
Assert.notNull(wholesalePrice, "wholesalePrice must not be null!");
|
||||||
Assert.notNull(promotionPrice, "promotionPrice must not be null!");
|
Assert.notNull(promotionPrice, "promotionPrice must not be null!");
|
||||||
this.wholesalePrice = wholesalePrice;
|
this.wholesalePrice = wholesalePrice;
|
||||||
|
|
|
@ -8,6 +8,7 @@ import java.util.Set;
|
||||||
import javax.money.MonetaryAmount;
|
import javax.money.MonetaryAmount;
|
||||||
|
|
||||||
import org.salespointframework.catalog.Product;
|
import org.salespointframework.catalog.Product;
|
||||||
|
import org.salespointframework.quantity.Metric;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -25,8 +26,8 @@ public class Rentable extends Product {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rentable(String name, MonetaryAmount pricePerHour, MonetaryAmount wholesalePrice,
|
public Rentable(String name, MonetaryAmount pricePerHour, MonetaryAmount wholesalePrice,
|
||||||
Set<OrderType> categories) {
|
Set<OrderType> categories, Metric metric) {
|
||||||
super(name, pricePerHour);
|
super(name, pricePerHour, metric);
|
||||||
this.wholesalePrice = wholesalePrice;
|
this.wholesalePrice = wholesalePrice;
|
||||||
Assert.notNull(pricePerHour, "pricePerHour must not be null!");
|
Assert.notNull(pricePerHour, "pricePerHour must not be null!");
|
||||||
Assert.notNull(wholesalePrice, "wholesalePrice must not be null!");
|
Assert.notNull(wholesalePrice, "wholesalePrice must not be null!");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2023 swt23w23
|
// SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
package catering.inventory;
|
package catering.inventory;
|
||||||
|
|
||||||
import static org.salespointframework.core.Currencies.EURO;
|
import static org.salespointframework.core.Currencies.EURO;
|
||||||
|
@ -44,13 +44,15 @@ class ConsumableMutateForm extends InventoryMutateForm {
|
||||||
Money.of(getRetailPrice(), EURO),
|
Money.of(getRetailPrice(), EURO),
|
||||||
Money.of(getWholesalePrice(), EURO),
|
Money.of(getWholesalePrice(), EURO),
|
||||||
getPromotionPrice().map(price -> Money.of(price, EURO)),
|
getPromotionPrice().map(price -> Money.of(price, EURO)),
|
||||||
getOrderTypes());
|
getOrderTypes(),
|
||||||
|
getMetric());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConsumableMutateForm of(Consumable product, UniqueInventoryItem item) {
|
public static ConsumableMutateForm of(Consumable product, UniqueInventoryItem item) {
|
||||||
ConsumableMutateForm form = new ConsumableMutateForm();
|
ConsumableMutateForm form = new ConsumableMutateForm();
|
||||||
form.setName(product.getName());
|
form.setName(product.getName());
|
||||||
form.setQuantity(item.getQuantity());
|
form.setQuantity(item.getQuantity().getAmount().longValueExact());
|
||||||
|
form.setMetric(product.createQuantity(0).getMetric()); // hack
|
||||||
form.setOrderTypes(orderTypesFromCategories(product.getCategories()));
|
form.setOrderTypes(orderTypesFromCategories(product.getCategories()));
|
||||||
form.setWholesalePrice(product.getWholesalePrice().getNumber().doubleValueExact());
|
form.setWholesalePrice(product.getWholesalePrice().getNumber().doubleValueExact());
|
||||||
form.setRetailPrice(product.getRetailPrice().getNumber().doubleValueExact());
|
form.setRetailPrice(product.getRetailPrice().getNumber().doubleValueExact());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2023 swt23w23
|
// SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
package catering.inventory;
|
package catering.inventory;
|
||||||
|
|
||||||
import org.salespointframework.catalog.Product;
|
import org.salespointframework.catalog.Product;
|
||||||
|
@ -163,7 +163,7 @@ class InventoryController {
|
||||||
UniqueInventoryItem item = inventory.findByProduct(product).get();
|
UniqueInventoryItem item = inventory.findByProduct(product).get();
|
||||||
// no setQuantity in enterprise java
|
// no setQuantity in enterprise java
|
||||||
// (though returing a modified object is actually nice)
|
// (though returing a modified object is actually nice)
|
||||||
inventory.save(item.increaseQuantity(form.getQuantity().subtract(item.getQuantity())));
|
inventory.save(item.increaseQuantity(product.createQuantity(form.getQuantity()).subtract(item.getQuantity())));
|
||||||
return "redirect:/inventory";
|
return "redirect:/inventory";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,9 @@ class InventoryController {
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
return add(model, form);
|
return add(model, form);
|
||||||
}
|
}
|
||||||
inventory.save(new UniqueInventoryItem(cateringCatalog.save(form.toProduct()), form.getQuantity()));
|
Product product = form.toProduct();
|
||||||
|
inventory.save(
|
||||||
|
new UniqueInventoryItem(cateringCatalog.save(product), product.createQuantity(form.getQuantity())));
|
||||||
return "redirect:/inventory";
|
return "redirect:/inventory";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2023 swt23w23
|
// SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
package catering.inventory;
|
package catering.inventory;
|
||||||
|
|
||||||
import org.salespointframework.core.DataInitializer;
|
import org.salespointframework.core.DataInitializer;
|
||||||
import org.salespointframework.inventory.UniqueInventory;
|
import org.salespointframework.inventory.UniqueInventory;
|
||||||
import org.salespointframework.inventory.UniqueInventoryItem;
|
import org.salespointframework.inventory.UniqueInventoryItem;
|
||||||
import org.salespointframework.quantity.Quantity;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -28,7 +27,7 @@ class InventoryInitializer implements DataInitializer {
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
cateringCatalog.findAll().forEach(product -> {
|
cateringCatalog.findAll().forEach(product -> {
|
||||||
if (inventory.findByProduct(product).isEmpty()) {
|
if (inventory.findByProduct(product).isEmpty()) {
|
||||||
inventory.save(new UniqueInventoryItem(product, Quantity.of(10)));
|
inventory.save(new UniqueInventoryItem(product, product.createQuantity(10)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2023 swt23w23
|
// SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
package catering.inventory;
|
package catering.inventory;
|
||||||
|
|
||||||
import static org.salespointframework.core.Currencies.EURO;
|
import static org.salespointframework.core.Currencies.EURO;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -12,6 +14,7 @@ import java.util.stream.Stream;
|
||||||
import org.javamoney.moneta.Money;
|
import org.javamoney.moneta.Money;
|
||||||
import org.salespointframework.catalog.Product;
|
import org.salespointframework.catalog.Product;
|
||||||
import org.salespointframework.inventory.UniqueInventoryItem;
|
import org.salespointframework.inventory.UniqueInventoryItem;
|
||||||
|
import org.salespointframework.quantity.Metric;
|
||||||
import org.salespointframework.quantity.Quantity;
|
import org.salespointframework.quantity.Quantity;
|
||||||
import org.springframework.data.util.Streamable;
|
import org.springframework.data.util.Streamable;
|
||||||
|
|
||||||
|
@ -32,9 +35,10 @@ import jakarta.validation.constraints.PositiveOrZero; // NonNegative in enterpri
|
||||||
*/
|
*/
|
||||||
abstract class InventoryMutateForm {
|
abstract class InventoryMutateForm {
|
||||||
private @NotEmpty String name;
|
private @NotEmpty String name;
|
||||||
private @NotNull Quantity quantity;
|
private @NotNull @PositiveOrZero Long quantity;
|
||||||
private @NotNull @PositiveOrZero Double retailPrice;
|
private @NotNull @PositiveOrZero Double retailPrice;
|
||||||
private @NotNull Set<OrderType> orderTypes;
|
private @NotNull Set<OrderType> orderTypes;
|
||||||
|
private @NotNull Metric metric = Metric.UNIT;
|
||||||
|
|
||||||
public InventoryMutateForm() {
|
public InventoryMutateForm() {
|
||||||
}
|
}
|
||||||
|
@ -43,7 +47,7 @@ abstract class InventoryMutateForm {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Quantity getQuantity() {
|
public Long getQuantity() {
|
||||||
return quantity;
|
return quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +55,10 @@ abstract class InventoryMutateForm {
|
||||||
return retailPrice;
|
return retailPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Metric getMetric() {
|
||||||
|
return metric;
|
||||||
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +67,7 @@ abstract class InventoryMutateForm {
|
||||||
return orderTypes;
|
return orderTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setQuantity(Quantity quantity) {
|
public void setQuantity(Long quantity) {
|
||||||
this.quantity = quantity;
|
this.quantity = quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +79,10 @@ abstract class InventoryMutateForm {
|
||||||
this.orderTypes = orderTypes;
|
this.orderTypes = orderTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMetric(Metric metric) {
|
||||||
|
this.metric = metric;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an empty {@link InventoryMutateForm} for {@link Product}s of the given {@link Class}.
|
* Creates an empty {@link InventoryMutateForm} for {@link Product}s of the given {@link Class}.
|
||||||
*
|
*
|
||||||
|
@ -158,4 +170,8 @@ abstract class InventoryMutateForm {
|
||||||
.collect(Collectors.toSet())::contains)
|
.collect(Collectors.toSet())::contains)
|
||||||
.map(OrderType::valueOf).collect(Collectors.toSet());
|
.map(OrderType::valueOf).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<Metric> supportedMetrics() {
|
||||||
|
return List.of(Metric.UNIT, Metric.LITER, Metric.KILOGRAM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2023 swt23w23
|
// SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
package catering.inventory;
|
package catering.inventory;
|
||||||
|
|
||||||
import static org.salespointframework.core.Currencies.EURO;
|
import static org.salespointframework.core.Currencies.EURO;
|
||||||
|
@ -26,7 +26,8 @@ class RentableMutateForm extends InventoryMutateForm {
|
||||||
public static RentableMutateForm of(Rentable product, UniqueInventoryItem item) {
|
public static RentableMutateForm of(Rentable product, UniqueInventoryItem item) {
|
||||||
RentableMutateForm form = new RentableMutateForm();
|
RentableMutateForm form = new RentableMutateForm();
|
||||||
form.setName(product.getName());
|
form.setName(product.getName());
|
||||||
form.setQuantity(item.getQuantity());
|
form.setQuantity(item.getQuantity().getAmount().longValueExact());
|
||||||
|
form.setMetric(product.createQuantity(0).getMetric()); // hack
|
||||||
form.setOrderTypes(orderTypesFromCategories(product.getCategories()));
|
form.setOrderTypes(orderTypesFromCategories(product.getCategories()));
|
||||||
form.setWholesalePrice(product.getWholesalePrice().getNumber().doubleValueExact());
|
form.setWholesalePrice(product.getWholesalePrice().getNumber().doubleValueExact());
|
||||||
form.setRetailPrice(product.getRetailPrice().getNumber().doubleValueExact());
|
form.setRetailPrice(product.getRetailPrice().getNumber().doubleValueExact());
|
||||||
|
@ -39,7 +40,8 @@ class RentableMutateForm extends InventoryMutateForm {
|
||||||
getName(),
|
getName(),
|
||||||
Money.of(getRetailPrice(), EURO),
|
Money.of(getRetailPrice(), EURO),
|
||||||
Money.of(getWholesalePrice(), EURO),
|
Money.of(getWholesalePrice(), EURO),
|
||||||
getOrderTypes());
|
getOrderTypes(),
|
||||||
|
getMetric());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2023 swt23w23
|
// SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
package catering.order;
|
package catering.order;
|
||||||
|
|
||||||
import catering.catalog.CateringCatalog;
|
import catering.catalog.CateringCatalog;
|
||||||
|
@ -178,7 +178,7 @@ public class OrderController {
|
||||||
return "redirect:/event";
|
return "redirect:/event";
|
||||||
}
|
}
|
||||||
|
|
||||||
Quantity amount = Quantity.of(number > 0 ? number : 1);
|
Quantity amount = product.createQuantity(number > 0 ? number : 1);
|
||||||
Quantity cartQuantity = cart.getQuantity(product);
|
Quantity cartQuantity = cart.getQuantity(product);
|
||||||
Quantity available;
|
Quantity available;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!--/*-->
|
<!--/*-->
|
||||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
SPDX-FileCopyrightText: 2023 swt23w23
|
SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
<!--*/-->
|
<!--*/-->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org"
|
<html xmlns:th="http://www.thymeleaf.org"
|
||||||
|
@ -22,9 +22,21 @@ SPDX-FileCopyrightText: 2023 swt23w23
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label" for="quantity">Menge im Bestand</label>
|
<label class="form-label" for="quantity">Menge im Bestand</label>
|
||||||
<input class="form-control" type="number" th:field="*{quantity}" th:errorclass="is-invalid" required/>
|
<div class="input-group" th:classappend="${#fields.hasErrors('quantity') ? 'has-validation' : ''}">
|
||||||
<div th:if="${#fields.hasErrors('quantity')}" class="invalid-feedback">Ungültige Menge.</div>
|
<input class="form-control" type="number" th:field="*{quantity}" th:errorclass="is-invalid" min="0" required/>
|
||||||
|
<span th:if="${!actionIsAdd}" class="input-group-text" th:text="${form.metric.getAbbreviation()}"></span>
|
||||||
|
<div th:if="${#fields.hasErrors('quantity')}" class="invalid-feedback">Ungültige Menge.</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3" th:if="${actionIsAdd}">
|
||||||
|
<label class="form-label" for="metric">Einheit</label>
|
||||||
|
<select class="form-select" th:field="*{metric}" th:errorclass="is-invalid">
|
||||||
|
<option th:each="metric : ${form.supportedMetrics()}" th:value="${metric}" th:text="${metric.getAbbreviation()}"/>
|
||||||
|
</select>
|
||||||
|
<div th:if="${#fields.hasErrors('metric')}" class="invalid-feedback">Ungültige Einheit.</div>
|
||||||
|
</div>
|
||||||
|
<!--/* ensures metric on form is synced (should not be trusted, however) */-->
|
||||||
|
<input th:if="${!actionIsAdd}" class="d-none" type="text" th:field="*{metric}">
|
||||||
<!-- the prices aren’t bound with th:field as they need special formatting -->
|
<!-- the prices aren’t bound with th:field as they need special formatting -->
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label" for="wholesalePrice">Einkaufspreis</label>
|
<label class="form-label" for="wholesalePrice">Einkaufspreis</label>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.*;
|
||||||
import static org.salespointframework.core.Currencies.EURO;
|
import static org.salespointframework.core.Currencies.EURO;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.salespointframework.quantity.Metric;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
@ -23,20 +24,21 @@ class CatalogUnitTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void findByCategories() {
|
void findByCategories() {
|
||||||
|
// !!! These need to be kept in sync with CatalogDataIntializer
|
||||||
assertThat(cateringCatalog.findRentablesByCategoriesContains(OrderType.EVENT_CATERING.toString())).hasSize(2);
|
assertThat(cateringCatalog.findRentablesByCategoriesContains(OrderType.EVENT_CATERING.toString())).hasSize(2);
|
||||||
assertThat(cateringCatalog.findRentablesByCategoriesContains(OrderType.MOBILE_BREAKFAST.toString())).hasSize(2);
|
assertThat(cateringCatalog.findRentablesByCategoriesContains(OrderType.MOBILE_BREAKFAST.toString())).hasSize(2);
|
||||||
assertThat(cateringCatalog.findRentablesByCategoriesContains(OrderType.RENT_A_COOK.toString())).hasSize(0);
|
assertThat(cateringCatalog.findRentablesByCategoriesContains(OrderType.RENT_A_COOK.toString())).hasSize(0);
|
||||||
assertThat(cateringCatalog.findRentablesByCategoriesContains(OrderType.PARTY_SERVICE.toString())).hasSize(0);
|
assertThat(cateringCatalog.findRentablesByCategoriesContains(OrderType.PARTY_SERVICE.toString())).hasSize(0);
|
||||||
|
|
||||||
assertThat(cateringCatalog.findConsumablesByCategoriesContains(OrderType.EVENT_CATERING.toString())).hasSize(1);
|
assertThat(cateringCatalog.findConsumablesByCategoriesContains(OrderType.EVENT_CATERING.toString())).hasSize(2);
|
||||||
assertThat(cateringCatalog.findConsumablesByCategoriesContains(OrderType.MOBILE_BREAKFAST.toString())).hasSize(1);
|
assertThat(cateringCatalog.findConsumablesByCategoriesContains(OrderType.MOBILE_BREAKFAST.toString())).hasSize(1);
|
||||||
assertThat(cateringCatalog.findConsumablesByCategoriesContains(OrderType.RENT_A_COOK.toString())).hasSize(0);
|
assertThat(cateringCatalog.findConsumablesByCategoriesContains(OrderType.RENT_A_COOK.toString())).hasSize(0);
|
||||||
assertThat(cateringCatalog.findConsumablesByCategoriesContains(OrderType.PARTY_SERVICE.toString())).hasSize(0);
|
assertThat(cateringCatalog.findConsumablesByCategoriesContains(OrderType.PARTY_SERVICE.toString())).hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void findConsumables() {
|
void findConsumables() {
|
||||||
assertThat(cateringCatalog.findConsumables()).hasSize(1);
|
assertThat(cateringCatalog.findConsumables()).hasSize(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -56,7 +58,8 @@ class CatalogUnitTests {
|
||||||
Money.of(1.5, EURO),
|
Money.of(1.5, EURO),
|
||||||
Money.of(0.7, EURO),
|
Money.of(0.7, EURO),
|
||||||
Optional.of(Money.of(0.90, EURO)),
|
Optional.of(Money.of(0.90, EURO)),
|
||||||
Set.of(OrderType.MOBILE_BREAKFAST)));
|
Set.of(OrderType.MOBILE_BREAKFAST),
|
||||||
|
Metric.UNIT));
|
||||||
assertThat(cateringCatalog.findAll().stream().count()).isEqualTo(1 + countAllBefore);
|
assertThat(cateringCatalog.findAll().stream().count()).isEqualTo(1 + countAllBefore);
|
||||||
assertThat(cateringCatalog.findConsumables().stream().count()).isEqualTo(1 + countConsumablesBefore);
|
assertThat(cateringCatalog.findConsumables().stream().count()).isEqualTo(1 + countConsumablesBefore);
|
||||||
assertThat(cateringCatalog.findConsumables()).contains(addedConsumable);
|
assertThat(cateringCatalog.findConsumables()).contains(addedConsumable);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
// SPDX-FileCopyrightText: 2023 swt23w23
|
// SPDX-FileCopyrightText: 2023-2024 swt23w23
|
||||||
package catering.inventory;
|
package catering.inventory;
|
||||||
|
|
||||||
import static catering.inventory.InventoryControllerIntegrationTests.PermissionResult.FORBIDDEN;
|
import static catering.inventory.InventoryControllerIntegrationTests.PermissionResult.FORBIDDEN;
|
||||||
|
@ -31,6 +31,7 @@ import org.salespointframework.catalog.Product;
|
||||||
import org.salespointframework.catalog.Product.ProductIdentifier;
|
import org.salespointframework.catalog.Product.ProductIdentifier;
|
||||||
import org.salespointframework.inventory.UniqueInventory;
|
import org.salespointframework.inventory.UniqueInventory;
|
||||||
import org.salespointframework.inventory.UniqueInventoryItem;
|
import org.salespointframework.inventory.UniqueInventoryItem;
|
||||||
|
import org.salespointframework.quantity.Metric;
|
||||||
import org.salespointframework.quantity.Quantity;
|
import org.salespointframework.quantity.Quantity;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
@ -82,11 +83,12 @@ class InventoryControllerIntegrationTests {
|
||||||
anyPid = anyProduct.getId();
|
anyPid = anyProduct.getId();
|
||||||
anyConsumableItem = inventory.save(new UniqueInventoryItem(
|
anyConsumableItem = inventory.save(new UniqueInventoryItem(
|
||||||
catalog.save(new Consumable("Any Consumable", Money.of(1, EURO), Money.of(0.5, EURO),
|
catalog.save(new Consumable("Any Consumable", Money.of(1, EURO), Money.of(0.5, EURO),
|
||||||
Optional.of(Money.of(0.75, EURO)), Set.of(OrderType.EVENT_CATERING, OrderType.PARTY_SERVICE))),
|
Optional.of(Money.of(0.75, EURO)), Set.of(OrderType.EVENT_CATERING, OrderType.PARTY_SERVICE),
|
||||||
|
Metric.UNIT)),
|
||||||
Quantity.of(1)));
|
Quantity.of(1)));
|
||||||
anyRentableItem = inventory.save(new UniqueInventoryItem(
|
anyRentableItem = inventory.save(new UniqueInventoryItem(
|
||||||
catalog.save(new Rentable("Any Rentable", Money.of(1, EURO), Money.of(0.5, EURO),
|
catalog.save(new Rentable("Any Rentable", Money.of(1, EURO), Money.of(0.5, EURO),
|
||||||
Set.of(OrderType.EVENT_CATERING, OrderType.PARTY_SERVICE))),
|
Set.of(OrderType.EVENT_CATERING, OrderType.PARTY_SERVICE), Metric.UNIT)),
|
||||||
Quantity.of(1)));
|
Quantity.of(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +133,8 @@ class InventoryControllerIntegrationTests {
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new UniqueInventoryItem(new Consumable("MOCK Schnitzel Wiener Art (vegan)", Money.of(7.5, EURO),
|
new UniqueInventoryItem(new Consumable("MOCK Schnitzel Wiener Art (vegan)", Money.of(7.5, EURO),
|
||||||
Money.of(3, EURO), Optional.of(Money.of(6.66, EURO)),
|
Money.of(3, EURO), Optional.of(Money.of(6.66, EURO)),
|
||||||
Set.of(OrderType.MOBILE_BREAKFAST, OrderType.PARTY_SERVICE)), Quantity.of(100)));
|
Set.of(OrderType.MOBILE_BREAKFAST, OrderType.PARTY_SERVICE), Metric.UNIT),
|
||||||
|
Quantity.of(100)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in a new issue