diff --git a/prototype/gradlew b/prototype/gradlew old mode 100644 new mode 100755 diff --git a/prototype/scripts/addsupplierorders.sql b/prototype/scripts/addsupplierorders.sql new file mode 100644 index 0000000..6c19af3 --- /dev/null +++ b/prototype/scripts/addsupplierorders.sql @@ -0,0 +1,3 @@ + +INSERT INTO supplier_orders ("created", "delivered", "number_of_units", "price_per_unit_net_cent", "total_price_net", "ordered_id", "supplier_id") +VALUES ('0', '0', '42', '42', '42', '1', '1'); diff --git a/prototype/src/main/java/org/hso/ecommerce/action/user/UpdateUserSettingsAction.java b/prototype/src/main/java/org/hso/ecommerce/action/user/UpdateUserSettingsAction.java new file mode 100644 index 0000000..ba17181 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/action/user/UpdateUserSettingsAction.java @@ -0,0 +1,83 @@ +package org.hso.ecommerce.action.user; + +import org.hso.ecommerce.entities.booking.PaymentMethod; +import org.hso.ecommerce.entities.user.User; +import org.hso.ecommerce.repos.user.UserRepository; + +public class UpdateUserSettingsAction { + + private User user; + private UserRepository repository; + + public UpdateUserSettingsAction(User user, UserRepository repository) { + this.user = user; + this.repository = repository; + } + + public UpdateResult updateEmail(String newMail) { + UpdateResult result = new UpdateResult(false); + if (!newMail.contains("@")) { + result.errorString = "Ändern der Email-Addresse nicht möglich. Bitte versuchen Sie es erneut."; + } else { + this.user.email = newMail; + this.repository.save(this.user); + result.updated = true; + } + return result; + } + + public UpdateResult updatePassword(String oldPassword, String password1, String password2) { + UpdateResult result = new UpdateResult(false); + if (this.user.validatePassword(oldPassword)) { + if (password1.equals(password2)) { + if (!password1.equals(oldPassword)) { + this.user.setPassword(password1); + this.repository.save(this.user); + result.updated = true; + } else { + result.errorString = "Das neue Passwort entspricht dem alten Passwort."; + } + } else { + result.errorString = "Die beiden neuen Passwörter stimmen nicht überein. Bitte versuchen Sie es erneut."; + } + } else { + result.errorString = "Das eingegebene alte Passwort stimmt nicht mit dem momentan gespeicherten Passwort überein. Bitte versuchen Sie es erneut."; + } + return result; + } + + public UpdateResult updateShippingInfo(String salutation, String name, String address) { + this.user.salutation = salutation; + this.user.name = name; + this.user.defaultDeliveryAddress.addressString = address; + this.repository.save(this.user); + return new UpdateResult(true); + } + + public UpdateResult updatePaymentInfo(String creditCardNumber) { + UpdateResult result = new UpdateResult(false); + if (creditCardNumber.matches("[0-9]+")) { + this.user.defaultPayment = PaymentMethod.fromCreditCardNumber(creditCardNumber); + this.repository.save(this.user); + result.updated = true; + } else { + result.errorString = "Kreditkartennummer darf nur Zahlen enthalten. Bitte versuchen Sie es erneut."; + } + return result; + } + + public class UpdateResult { + public boolean updated; //if true worked, if false not worked + public String errorString; + + public UpdateResult(boolean updated, String errorString) { + this.updated = updated; + this.errorString = errorString; + } + + public UpdateResult(boolean updated) { + this.updated = updated; + this.errorString = ""; + } + } +} diff --git a/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CalculateWarehouseStatsAction.java b/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CalculateWarehouseStatsAction.java new file mode 100644 index 0000000..ca5c5dc --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CalculateWarehouseStatsAction.java @@ -0,0 +1,73 @@ +package org.hso.ecommerce.action.warehouse; + +import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry; + +import java.util.HashSet; +import java.util.List; + +public class CalculateWarehouseStatsAction { + + private List entryList; + + public CalculateWarehouseStatsAction(List everyCurrentEntry) { + this.entryList = everyCurrentEntry; + } + + public WarehouseStats finish() { + int numArticles = calculateNumArticles(); + double efficiency = calculateEfficiency(); + double ratioUsedSlots = calculateRatioSlotsUsed(); + + return new WarehouseStats(numArticles, efficiency, ratioUsedSlots); + } + + private double calculateRatioSlotsUsed() { + int used = 0; + + for (WarehouseBookingPositionSlotEntry entry : entryList) { + if (entry.newSumSlot > 0) { + used++; + } + } + + return ((double) used) / entryList.size(); + } + + private double calculateEfficiency() { + double e = 0; + + for (WarehouseBookingPositionSlotEntry entry : entryList) { + if (entry.newSumSlot > 0) { + e += entry.newSumSlot / (double) entry.article.warehouseUnitsPerSlot; + } else { + e += 0; + } + } + + return e / entryList.size(); + } + + private int calculateNumArticles() { + HashSet articleIds = new HashSet<>(); + + for (WarehouseBookingPositionSlotEntry entry : entryList) { + if (entry.newSumSlot > 0) { + articleIds.add(entry.article.id); + } + } + + return articleIds.size(); + } + + private static class WarehouseStats { + public int numArticles; + public double efficiency; + public double ratioUsedSlots; + + WarehouseStats(int numArticles, double efficiency, double ratioUsedSlots) { + this.numArticles = numArticles; + this.efficiency = efficiency; + this.ratioUsedSlots = ratioUsedSlots; + } + } +} diff --git a/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CreateManuelBookingAction.java b/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CreateManuelBookingAction.java new file mode 100644 index 0000000..4d35e63 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/action/warehouse/CreateManuelBookingAction.java @@ -0,0 +1,92 @@ +package org.hso.ecommerce.action.warehouse; + +import org.hso.ecommerce.entities.booking.BookingReason; +import org.hso.ecommerce.entities.shop.Article; +import org.hso.ecommerce.entities.warehouse.WarehouseBooking; +import org.hso.ecommerce.entities.warehouse.WarehouseBookingPosition; +import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry; + +import java.sql.Timestamp; +import java.util.Date; +import java.util.Optional; + +public class CreateManuelBookingAction { + + private Article article; + private int amount; + private Optional source; + private Optional destination; + private String reason; + + public CreateManuelBookingAction(Article article, int amount, Optional source, Optional destination, String reason) { + this.article = article; + this.amount = amount; + this.source = source; + this.destination = destination; + this.reason = reason; + } + + public WarehouseBooking finish() throws ArticleSlotConstraintFailedException { + WarehouseBooking booking = new WarehouseBooking(); + booking.created = new Timestamp(new Date().getTime()); + booking.reason = new BookingReason(reason); + + if (source.isPresent()) { + + if (source.get().article.id != article.id) { + throw new ArticleSlotConstraintArticleTypeFailedException(); + } + + WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition(); + bookingPosition.booking = booking; + + bookingPosition.article = article; + bookingPosition.amount = -amount; + bookingPosition.slotEntry = source.get().copyAddAmount(-amount); + + if (bookingPosition.slotEntry.newSumSlot < 0 || bookingPosition.slotEntry.newSumSlot > article.warehouseUnitsPerSlot) { + throw new ArticleSlotConstraintFailedException("The quantity of article can only be set in bounds."); + } + + booking.positions.add(bookingPosition); + } + + if (destination.isPresent()) { + + if (destination.get().article.id != article.id) { + throw new ArticleSlotConstraintArticleTypeFailedException(); + } + + WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition(); + bookingPosition.booking = booking; + + bookingPosition.article = article; + bookingPosition.amount = amount; + bookingPosition.slotEntry = destination.get().copyAddAmount(amount); + + if (bookingPosition.slotEntry.newSumSlot < 0 || bookingPosition.slotEntry.newSumSlot > article.warehouseUnitsPerSlot) { + throw new ArticleSlotConstraintFailedException("The quantity of article can only be set in bounds."); + } + + booking.positions.add(bookingPosition); + } + + return booking; + } + + public static class ArticleSlotConstraintFailedException extends Exception { + public ArticleSlotConstraintFailedException(String s) { + super(s); + } + + public ArticleSlotConstraintFailedException() { + super("The quantity of article can only be set in bounds."); + } + } + + public static class ArticleSlotConstraintArticleTypeFailedException extends ArticleSlotConstraintFailedException { + public ArticleSlotConstraintArticleTypeFailedException() { + super("The Article in the slot entry does not match."); + } + } +} diff --git a/prototype/src/main/java/org/hso/ecommerce/action/warehouse/StoreSupplierOrderAction.java b/prototype/src/main/java/org/hso/ecommerce/action/warehouse/StoreSupplierOrderAction.java new file mode 100644 index 0000000..9bc413d --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/action/warehouse/StoreSupplierOrderAction.java @@ -0,0 +1,7 @@ +package org.hso.ecommerce.action.warehouse; + +public class StoreSupplierOrderAction { + + //TODO add delivery date and warehouse booking + +} diff --git a/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java b/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java index 8373179..3039bb9 100644 --- a/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java +++ b/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java @@ -85,57 +85,4 @@ public class RequestController { return "intern/customerOrders/id"; } - @GetMapping("/intern/supplierOrders/") - public String internSupplierOrders() { - return "intern/supplierOrders/index"; - } - - @GetMapping("/intern/supplierOrders/{id}") - public String internSupplierOrdersId() { - return "intern/supplierOrders/id"; - } - - /* - - @GetMapping("/intern/suppliersOffers") - public String internSuppliersOffers() { - return "intern/offeredArticles/index"; - } - */ - - - @GetMapping("/intern/warehouse/") - public String accountingWarehouse() { - return "intern/warehouse/index"; - } - - @GetMapping("/intern/warehouse/todo") - public String accountingWarehouseTodo() { - return "intern/warehouse/todo"; - } - - @GetMapping("/intern/warehouse/addManual") - public String accountingWarehouseAddManual() { - return "intern/warehouse/addManual"; - } - - @PostMapping("/intern/warehouse/progress/{id}") - public String accountingWarehouseProgressIdPost(HttpServletResponse response) { - if ((notSoRandom++) % 2 == 1) { - return "redirect:/intern/warehouse/progress/450"; - } else { - response.setStatus(409); - return "intern/warehouse/error_progress_failed"; - } - } - - @GetMapping("/intern/warehouse/progress/{id}") - public String accountingWarehouseProgressId() { - return "intern/warehouse/id_progress"; - } - - @GetMapping("/intern/warehouse/slots/") - public String accountingWarehouseSlots() { - return "intern/warehouse/slots/index"; - } } diff --git a/prototype/src/main/java/org/hso/ecommerce/app/UserRequestController.java b/prototype/src/main/java/org/hso/ecommerce/app/UserRequestController.java deleted file mode 100644 index c4f6301..0000000 --- a/prototype/src/main/java/org/hso/ecommerce/app/UserRequestController.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.hso.ecommerce.app; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -@RequestMapping("user") -public class UserRequestController { - - @GetMapping("/") - public String user() { - return "redirect:/user/settings"; - } - - @GetMapping("/settings") - public String userSettings() { - return "user/settings"; - } - - @GetMapping("/orders/") - public String userOrdeers() { - return "user/orders/index"; - } - - @GetMapping("/bonuspoints") - public String userBonuspoints() { - return "user/bonuspoints"; - } - - @GetMapping("/notifications/") - public String userNotifications() { - return "user/notifications/index"; - } -} - diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/RegisterController.java b/prototype/src/main/java/org/hso/ecommerce/controller/RegisterController.java index 15acf9f..19f81b7 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/RegisterController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/RegisterController.java @@ -1,5 +1,6 @@ package org.hso.ecommerce.controller; +import org.hso.ecommerce.entities.booking.PaymentMethod; import org.hso.ecommerce.entities.shop.Address; import org.hso.ecommerce.entities.user.User; import org.hso.ecommerce.repos.user.UserRepository; @@ -54,7 +55,8 @@ public class RegisterController { newUser.setPassword(password); newUser.email = username; newUser.isEmployee = false; - //TODO for salutation, type, ad are no attributes/fields in the class/database. Add when they are there. + newUser.salutation = salutation; + newUser.defaultPayment = PaymentMethod.fromCreditCardNumber(""); newUser.isActive = true; newUser.created = new java.sql.Timestamp(System.currentTimeMillis()); diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/UserController.java b/prototype/src/main/java/org/hso/ecommerce/controller/UserController.java index 523bf2e..8a90d43 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/UserController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/UserController.java @@ -1,8 +1,127 @@ package org.hso.ecommerce.controller; +import org.hso.ecommerce.action.user.UpdateUserSettingsAction; +import org.hso.ecommerce.entities.shop.CustomerOrder; +import org.hso.ecommerce.entities.user.User; +import org.hso.ecommerce.repos.shop.CustomerOrderRepository; +import org.hso.ecommerce.repos.user.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.List; @Controller -//@RequestMapping("...") +@RequestMapping("/user") public class UserController { + + @Autowired + private final UserRepository userRepository = null; + + @Autowired + private final CustomerOrderRepository customerOrderRepository = null; + + @GetMapping("/") + public String user() { + return "redirect:/user/settings"; + } + + @GetMapping("/settings") + public String userSettings(Model model, + HttpSession session + ) { + long userId = (long) session.getAttribute("userId"); + User user = userRepository.findById(userId).get(); + model.addAttribute("user", user); + + return "user/settings"; + } + + @GetMapping("/orders/") + public String userOrdeers(HttpSession session, + Model model + ) { + List orders = customerOrderRepository.getOrdersByUserId((long) session.getAttribute("userId")); + model.addAttribute("orders", orders); + + return "user/orders/index"; + } + + @PostMapping("/settings/changeMail") + public String changeMail(HttpSession session, + @RequestParam("email") String email, + HttpServletRequest request + ) { + User user = userRepository.findById((long) session.getAttribute("userId")).get(); + + UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository); + UpdateUserSettingsAction.UpdateResult result = cusa.updateEmail(email); + if (result.updated == false) { + request.setAttribute("error", result.errorString); + return "user/settings"; + } + + return "redirect:/user/settings"; + } + + @PostMapping("/settings/changePwd") + public String changePwd(HttpSession session, + @RequestParam("old-password") String oldPassword, + @RequestParam("password1") String password1, + @RequestParam("password2") String password2, + HttpServletRequest request + ) { + User user = userRepository.findById((long) session.getAttribute("userId")).get(); + + UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository); + UpdateUserSettingsAction.UpdateResult result = cusa.updatePassword(oldPassword, password1, password2); + if (result.updated == false) { + request.setAttribute("error", result.errorString); + return "user/settings"; + } + + return "redirect:/user/settings"; + } + + @PostMapping("/settings/changeAddress") + public String changeAddress(HttpSession session, + @RequestParam("salutation") String salutation, + @RequestParam("name") String name, + @RequestParam("address") String address, + HttpServletRequest request + ) { + User user = userRepository.findById((long) session.getAttribute("userId")).get(); + + UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository); + UpdateUserSettingsAction.UpdateResult result = cusa.updateShippingInfo(salutation, name, address); + if (result.updated == false) { + request.setAttribute("error", result.errorString); + return "user/settings"; + } + + return "redirect:/user/settings"; + } + + @PostMapping("/settings/changePaymentInfo") + public String changePaymentInfo(HttpSession session, + @RequestParam("creditCardNumber") String creditCardNumber, + HttpServletRequest request + ) { + User user = userRepository.findById((long) session.getAttribute("userId")).get(); + + UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository); + UpdateUserSettingsAction.UpdateResult result = cusa.updatePaymentInfo(creditCardNumber); + if (result.updated == false) { + request.setAttribute("error", result.errorString); + return "user/settings"; + } + + return "redirect:/user/settings"; + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java b/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java index e2bad65..0f54221 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/cronjob/CronjobController.java @@ -28,7 +28,7 @@ import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository; import org.hso.ecommerce.repos.booking.BookingRepository; import org.hso.ecommerce.repos.cronjob.BackgroundJobRepository; import org.hso.ecommerce.repos.shop.ArticleRepository; -import org.hso.ecommerce.repos.shop.CustomerOderRepository; +import org.hso.ecommerce.repos.shop.CustomerOrderRepository; import org.hso.ecommerce.repos.supplier.ArticleOfferRepository; import org.hso.ecommerce.repos.supplier.SupplierOrderRepository; import org.hso.ecommerce.repos.supplier.SupplierRepository; @@ -230,7 +230,7 @@ class CronjobController { final ArticleOfferRepository articleOfferRepository = null; @Autowired - final CustomerOderRepository customerOrderRepository = null; + final CustomerOrderRepository customerOrderRepository = null; @Autowired final BookingRepository bookingRepository = null; diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternArticleController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternArticleController.java index e011f71..e799210 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternArticleController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/InternArticleController.java @@ -62,16 +62,12 @@ public class InternArticleController { @GetMapping("/{id}") public String internListedArticlesId(Model model, @PathVariable String id) { - int articleid = Integer.parseInt(id); - UImodelArticle total = new UImodelArticle(); - total.addArticle(articleRepository.findArticleById(articleid), warehouseEntryRepository.getArticleStock(articleid).orElse(0)); model.addAttribute("ArticleID", total); - return "intern/listedArticles/id"; } @@ -80,7 +76,7 @@ public class InternArticleController { @RequestParam(value = "title", required = true) String title, @RequestParam(value = "description", required = true) String description, @RequestParam(value = "units-per-slot", required = true) String warehouseUnitsPerSlot, - @RequestParam(value = "price_netto", required = true) String pricenetto, + @RequestParam(value = "priceNet", required = true) String pricenetto, @RequestParam(value = "reorderMaxPrice", required = true) String reorderMaxPrice, @RequestParam(value = "autobuy", required = true) Boolean shouldReorder, @RequestParam(value = "categorie", required = true) String categories, @@ -192,19 +188,12 @@ public class InternArticleController { public static class UImodelArticles { public String imgPath; - public String title; - public String price; - - public String price_netto; - + public String priceNet; public String categorie; - public int stock; - - public long offer_id; - + public long offerID; public long id; void addListedArticle(Article article, int stock) { @@ -213,7 +202,7 @@ public class InternArticleController { this.imgPath = article.image.path; } this.title = article.title; - this.price_netto = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100)); + this.priceNet = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100)); this.price = String.format("%.2f", ((float) article.getPriceGross() / 100)); StringBuilder result = new StringBuilder(); @@ -224,7 +213,7 @@ public class InternArticleController { this.categorie = result.toString(); this.stock = stock; - this.offer_id = article.related.id; + this.offerID = article.related.id; this.id = article.id; } } @@ -234,123 +223,31 @@ public class InternArticleController { public String imgPath; public String title; public String price; - public String price_netto; + public String priceNet; public String reorderMaxPrice; public String categorie; public int stock; - public long offer_id; + public long offerID; public long id; public boolean shouldReorder; public String warehouseUnitsPerSlot; public String description; public int vatPercent; - public String getImgPath() { - return imgPath; - } - - public void setImgPath(String imgPath) { - this.imgPath = imgPath; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getPrice() { - return price; - } - - public void setPrice(String price) { - this.price = price; - } - - public int getVatPercent() { - return vatPercent; - } - - public String getPrice_netto() { - return price_netto; - } - - public void setPrice_netto(String price_netto) { - this.price_netto = price_netto; - } - - public String getReorderMaxPrice() { - return reorderMaxPrice; - } - - public void setReorderMaxPrice(String reorderMaxPrice) { - this.reorderMaxPrice = reorderMaxPrice; - } - public String getCategorie() { return categorie; } - public void setCategorie(String categorie) { - this.categorie = categorie; - } - - public int getStock() { - return stock; - } - - public void setStock(int stock) { - this.stock = stock; - } - - public long getOffer_id() { - return offer_id; - } - - public void setOffer_id(long offer_id) { - this.offer_id = offer_id; - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public boolean isShouldReorder() { - return shouldReorder; - } - - public void setShouldReorder(boolean shouldReorder) { - this.shouldReorder = shouldReorder; - } - - public String getWarehouseUnitsPerSlot() { - return warehouseUnitsPerSlot; - } - - public void setWarehouseUnitsPerSlot(String warehouseUnitsPerSlot) { - this.warehouseUnitsPerSlot = warehouseUnitsPerSlot; - } - public String getDescription() { return description; } - public void setDescription(String description) { - this.description = description; - } - void addArticle(Article article, int stock) { if (article.image != null) { this.imgPath = article.image.path; } this.title = article.title; - this.price_netto = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100)); + this.priceNet = String.format("%.2f", ((float) article.shopPricePerUnitNetCent / 100)); this.price = String.format("%.2f", ((float) article.getPriceGross() / 100)); StringBuilder result = new StringBuilder(); @@ -362,7 +259,7 @@ public class InternArticleController { this.categorie = result.toString(); this.stock = stock; - this.offer_id = article.related.id; + this.offerID = article.related.id; this.id = article.id; this.reorderMaxPrice = String.format("%.2f", ((float) article.reorderMaxPrice / 100)); this.shouldReorder = article.shouldReorder; diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/WarehouseController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/WarehouseController.java index 9b618f7..4a0258e 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/WarehouseController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/WarehouseController.java @@ -1,8 +1,27 @@ package org.hso.ecommerce.controller.intern; +import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; @Controller -//@RequestMapping("...") +@RequestMapping("/intern/warehouse/") public class WarehouseController { + + @Autowired + private final WarehouseBookingRepository warehouseBookingRepository = null; + + @GetMapping("/") + public String accountingWarehouse( + Model model, + HttpServletRequest request + ) { + model.addAttribute("bookings", warehouseBookingRepository.findAll()); + return "intern/warehouse/index"; + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/AccountingController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/AccountingController.java index 4ca0acf..92f08f3 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/AccountingController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/accounting/AccountingController.java @@ -40,7 +40,7 @@ public class AccountingController { /** * A description used to render the html template for bookings on a specific account */ - static class ShortTemplateBooking { + public static class ShortTemplateBooking { public String datetime; public String amount; public String source; diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierIndexController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierIndexController.java index 500843f..61f14f6 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierIndexController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierIndexController.java @@ -1,45 +1,157 @@ package org.hso.ecommerce.controller.intern.suppliers; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; import java.util.List; -import javax.servlet.http.HttpServletRequest; - import org.hso.ecommerce.controller.intern.accounting.AccountingController; +import org.hso.ecommerce.controller.intern.accounting.AccountingController.ShortTemplateBooking; import org.hso.ecommerce.controller.intern.accounting.AccountingController.ShortTemplateBookingResult; import org.hso.ecommerce.entities.booking.Booking; +import org.hso.ecommerce.entities.supplier.Supplier; +import org.hso.ecommerce.entities.supplier.SupplierOrder; import org.hso.ecommerce.repos.booking.BookingRepository; +import org.hso.ecommerce.repos.supplier.SupplierOrderRepository; +import org.hso.ecommerce.repos.supplier.SupplierRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @Controller -@RequestMapping("/intern/suppliers") +@RequestMapping("/intern/") public class SupplierIndexController { - @Autowired - private BookingRepository bookingRepository = null; + @Autowired + private final SupplierRepository supplierRepository = null; - @Autowired - private AccountingController accountingController = null; + @Autowired + private final SupplierOrderRepository supplierOrderRepository = null; - @GetMapping("/") - public String internSuppliers() { - return "intern/suppliers/index"; - } + @Autowired + private final BookingRepository bookingRepository = null; - @GetMapping("/{supplierId}") - public String internSuppliersId(HttpServletRequest request, @PathVariable(required = true) long supplierId) { + @Autowired + private AccountingController accountingController = null; - // Table of bookings - List bookings = bookingRepository.supplierBookingsReverseChronologically(supplierId); - ShortTemplateBookingResult result = accountingController.buildShortTemplate(bookings, - account -> account.supplierAccount != null && account.supplierAccount.id == supplierId); - request.setAttribute("balance", result.balance); - request.setAttribute("bookings", result.bookings); + @GetMapping("suppliers") + public String listSuppliers(Model model) { - return "intern/suppliers/id"; - } + List totals = new ArrayList(); + for (Supplier supplier : supplierRepository.findAll()) { + UImodelSuppliers tmp = new UImodelSuppliers(supplier.id, supplier.name); + totals.add(tmp); + } + + model.addAttribute("suppliers", totals); + return "intern/suppliers/index"; + } + + @GetMapping("/suppliers/{id}") + public String supplierDetail(Model model, @PathVariable String id) { + + long supplierId = Long.parseLong(id); + + // add orders from supplier to UImodel + List orders = new ArrayList(); + for (SupplierOrder supplierOrder : supplierOrderRepository.findOrderBySupplierID(supplierId)) { + orders.add(new UImodelSupplierDetailOrders(supplierOrder)); + } + + // Table of bookings + List bookings = bookingRepository.supplierBookingsReverseChronologically(supplierId); + ShortTemplateBookingResult bookingResult = accountingController.buildShortTemplate(bookings, + account -> account.supplierAccount != null && account.supplierAccount.id == supplierId); + + UImodelSupplierDetail total = new UImodelSupplierDetail(supplierRepository.findSupplierById(supplierId).name, + bookingResult.balance, orders, bookingResult.bookings); + + model.addAttribute("SupplierDetail", total); + + return "intern/suppliers/id"; + } + + public class UImodelSuppliers { + public long id; + public String name; + + public UImodelSuppliers(long id, String name) { + this.id = id; + this.name = name; + } + + } + + public class UImodelSupplierDetail { + + public String name; + public String balance; + public List orders; + public List bookings; + + public UImodelSupplierDetail(String name, String balance, List orders, + List bookings + ) { + this.name = name; + this.balance = balance; + this.orders = orders; + this.bookings = bookings; + } + + } + + public class UImodelSupplierDetailOrders { + public long id; + public String dateOrder; + public String articleName; + public long articleId; + public String priceNet; + public String quantity; + public String priceTotal; + public boolean arrived; + + public UImodelSupplierDetailOrders(SupplierOrder order) { + this.id = order.id; + this.articleName = order.ordered.title; + this.articleId = order.ordered.id; + this.priceNet = String.format("%.2f", ((float) order.pricePerUnitNetCent / 100)); + this.quantity = String.valueOf(order.numberOfUnits); + this.priceTotal = String.format("%.2f", ((float) order.totalPriceNet / 100)); + + Date date = new Date(); + date.setTime(order.created.getTime()); + this.dateOrder = new SimpleDateFormat("dd.MM.yyyy").format(date); + + if (order.delivered != null) { + arrived = true; + } else { + arrived = false; + } + } + } + + public class UImodelSupplierDetailBookings { + + public String dateBooking; + public String price; + public String srcName; + public String balance; + public String reason; + public long orderID; + + public UImodelSupplierDetailBookings(Booking booking) { + Date date = new Date(); + date.setTime(booking.reason.supplierOrder.created.getTime()); + this.dateBooking = new SimpleDateFormat("dd.MM.yyyy").format(date); + this.price = String.format("%.2f", ((float) booking.amountCent / 100)); + this.srcName = ((booking.source.isMainAccount) ? "Hauptkonto" : booking.source.supplierAccount.name); + this.balance = String.format("%.2f", ((float) booking.destination.newSumCent / 100)); + this.reason = booking.reason.comment; + this.orderID = booking.reason.supplierOrder.id; + } + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierOfferController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierOfferController.java index edc7bc2..979f967 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierOfferController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierOfferController.java @@ -40,94 +40,22 @@ public class SupplierOfferController { public class UImodelOfferedArticle { - long offer_id; - String title; - String manufacturer; - String articlenumber; - String supplierName; - String price; - String ads; - int listedArticleId; - boolean offerIsListed; // true --> offered article is listed - - public long getOffer_id() { - return offer_id; - } - - public void setOffer_id(long offer_id) { - this.offer_id = offer_id; - } - - public boolean isOfferIsListed() { - return offerIsListed; - } - - public void setOfferIsListed(boolean offerIsListed) { - this.offerIsListed = offerIsListed; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getManufacturer() { - return manufacturer; - } - - public void setManufacturer(String manufacturer) { - this.manufacturer = manufacturer; - } - - public String getArticlenumber() { - return articlenumber; - } - - public void setArticlenumber(String articlenumber) { - this.articlenumber = articlenumber; - } - - public String getSupplierName() { - return supplierName; - } - - public void setSupplierName(String supplierName) { - this.supplierName = supplierName; - } - - public String getPrice() { - return price; - } - - public void setPrice(String price) { - this.price = price; - } - - public String getAds() { - return ads; - } - - public void setAds(String ads) { - this.ads = ads; - } - - public int getListedArticleId() { - return listedArticleId; - } - - public void setListedArticleId(int listedArticleId) { - this.listedArticleId = listedArticleId; - } + public long offerId; + public String title; + public String manufacturer; + public String articleNumber; + public String supplierName; + public String price; + public String ads; + public int listedArticleId; + public boolean offerIsListed; // true --> offered article is listed public void addData(ArticleOffer article, Optional listedArticleId) { - this.offer_id = article.id; + this.offerId = article.id; this.title = article.title; this.manufacturer = article.manufacturer; - this.articlenumber = article.articleNumber; + this.articleNumber = article.articleNumber; this.supplierName = article.cheapestSupplier.name; this.price = String.format("%.2f", ((float) article.pricePerUnitNet / 100)); this.ads = (article.shouldBeAdvertised) ? "Ja" : "Nein"; diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierOrderController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierOrderController.java index ef3acb4..1485c92 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierOrderController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/suppliers/SupplierOrderController.java @@ -1,8 +1,89 @@ package org.hso.ecommerce.controller.intern.suppliers; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.hso.ecommerce.entities.supplier.SupplierOrder; +import org.hso.ecommerce.repos.supplier.SupplierOrderRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.view.RedirectView; @Controller -//@RequestMapping("...") +@RequestMapping("/intern/") public class SupplierOrderController { + + @Autowired + private final SupplierOrderRepository supplierOrderRepository = null; + + @GetMapping("supplierOrders") + public String listSuppliers(Model model) { + + List totals = new ArrayList(); + + for (SupplierOrder orders : supplierOrderRepository.findAll()) { + totals.add(new UImodelSupplierOrder(orders)); + } + + model.addAttribute("orders", totals); + + return "intern/supplierOrders/index"; + } + + @PostMapping("/supplierOrders/store/{id}") + public RedirectView storeOrder(@PathVariable(required = true) String id) { + + long supplierOrderID = Long.parseLong(id); + + Optional order = supplierOrderRepository.findById(supplierOrderID); + + if (order.isPresent()) { + // TODO call action + + System.out.println("Order is present\n"); + + } + + return new RedirectView("../../supplierOrders/"); + } + + public class UImodelSupplierOrder { + public long id; + public String dateOrder; + public String supplierName; + public String articleName; + public long articleId; + public String priceNet; + public String quantity; + public String priceTotal; + public boolean arrived; + + public UImodelSupplierOrder(SupplierOrder order) { + this.id = order.id; + this.supplierName = order.supplier.name; + this.articleName = order.ordered.title; + this.articleId = order.ordered.id; + this.priceNet = String.format("%.2f", ((float) order.pricePerUnitNetCent / 100)); + this.quantity = String.valueOf(order.numberOfUnits); + this.priceTotal = String.format("%.2f", ((float) order.totalPriceNet / 100)); + + Date date = new Date(); + date.setTime(order.created.getTime()); + this.dateOrder = new SimpleDateFormat("dd.MM.yyyy").format(date); + + if (order.delivered != null) { + arrived = true; + } else { + arrived = false; + } + } + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/ManuelBookingController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/ManuelBookingController.java new file mode 100644 index 0000000..7ef8e0e --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/ManuelBookingController.java @@ -0,0 +1,140 @@ +package org.hso.ecommerce.controller.intern.warehouse; + +import org.hso.ecommerce.action.warehouse.CreateManuelBookingAction; +import org.hso.ecommerce.entities.shop.Article; +import org.hso.ecommerce.entities.warehouse.Slot; +import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry; +import org.hso.ecommerce.repos.shop.ArticleRepository; +import org.hso.ecommerce.repos.warehouse.SlotRepository; +import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository; +import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Optional; + +@Controller +@RequestMapping("/intern/warehouse/") +public class ManuelBookingController { + + @Autowired + private final ArticleRepository articleRepository = null; + + @Autowired + private final SlotRepository slotRepository = null; + + @Autowired + private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null; + + @Autowired + private final WarehouseBookingRepository warehouseBookingRepository = null; + + @GetMapping("addManual") + public String warehouseAddManual( + Model model + ) { + + model.addAttribute("articles", articleRepository.findAll()); + model.addAttribute("slots", slotRepository.findAll()); + + return "intern/warehouse/addManual"; + } + + @PostMapping("addManual") + public String warehouseAddMaualPost( + Model model, + HttpServletRequest request, + HttpServletResponse response, + @RequestParam("articleId") String articleIdText, + @RequestParam("amount") Integer amount, + @RequestParam("reason") String reason, + @RequestParam("sourceIsSlot") Boolean sourceIsSlot, + @RequestParam("sourceSlot") Integer sourceSlotNum, + @RequestParam("destinationIsSlot") Boolean destinationIsSlot, + @RequestParam("destinationSlot") Integer destinationSlotNum + ) { + + // The suggestions for articleId in the UI show articles names, seperated by a " - ". + // The Number must be extracted first. + long articleId = -1; + try { + articleId = Long.parseLong(articleIdText.split(" - ", 2)[0].trim()); + } catch (NumberFormatException e) { + model.addAttribute("error", "Die Artikel Id konnte nicht erkannt werden."); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return "intern/warehouse/addManual"; + } + + + Optional
optionalArticle = articleRepository.findById(articleId); + Article article = null; + if (!optionalArticle.isPresent()) { + model.addAttribute("error", "Der Artikel konnte nicht gefunden werden."); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } else { + article = optionalArticle.get(); + } + + if (amount <= 0) { + model.addAttribute("error", "Eine Anzahl <= 0 kann nicht verbucht werden."); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } + + if (sourceIsSlot == false && destinationIsSlot == false) { + model.addAttribute("error", "Jede Buchung benötigt ein Ziel oder eine Quelle."); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } + + Optional sourceSlot = Optional.empty(); + if (sourceIsSlot == true) { + sourceSlot = warehouseBookingPositionSlotEntryRepository.getBySlotNum(sourceSlotNum); + if (!sourceSlot.isPresent()) { + request.setAttribute("error", "Quelllagerplatz wurde nicht gefunden oder ist leer."); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } + } + + Optional destinationSlot = Optional.empty(); + if (destinationIsSlot == true) { + Optional slot = slotRepository.findBySlotNum(destinationSlotNum); + if (!slot.isPresent()) { + request.setAttribute("error", "Ziellagerplatz wurde nicht gefunden."); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } + + Article finalArticle = article; + destinationSlot = Optional.of(warehouseBookingPositionSlotEntryRepository.getBySlotNum(destinationSlotNum).orElseGet( + () -> WarehouseBookingPositionSlotEntry.empty(finalArticle, slot.get()) + )); + } + + try { + warehouseBookingRepository.save( + new CreateManuelBookingAction(article, amount, sourceSlot, destinationSlot, reason).finish() + ); + } catch (CreateManuelBookingAction.ArticleSlotConstraintArticleTypeFailedException e) { + model.addAttribute("error", "Es befindet sich der falsche Artikeltyp in Quell- oder Ziellagerplatz. "); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } catch (CreateManuelBookingAction.ArticleSlotConstraintFailedException e) { + model.addAttribute("error", "Die maximale Anzahl an lagerbaren Artikeln im Ziellagerplatz wurde überschritten."); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } + + return "redirect:/intern/warehouse/todo"; + } + +} diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/SlotsController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/SlotsController.java new file mode 100644 index 0000000..8cc5721 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/SlotsController.java @@ -0,0 +1,46 @@ +package org.hso.ecommerce.controller.intern.warehouse; + +import org.hso.ecommerce.action.warehouse.CalculateWarehouseStatsAction; +import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry; +import org.hso.ecommerce.repos.warehouse.SlotRepository; +import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.stream.Collectors; + +@Controller +@RequestMapping("/intern/warehouse/") +public class SlotsController { + + @Autowired + private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null; + + @Autowired + private final SlotRepository slotRepository = null; + + @GetMapping("slots/") + public String accountingWarehouseSlots( + Model model, + HttpServletRequest request + ) { + + // Doing this in a single would be hard and error prone. + // Writing native queries should be minimized. + // Therefore this method was prefered + List entries = slotRepository.findAll().stream().map( + s -> warehouseBookingPositionSlotEntryRepository + .getBySlotNum(s.slotNum) + .orElseGet(() -> WarehouseBookingPositionSlotEntry.empty(null, s)) + ).collect(Collectors.toList()); + model.addAttribute("entries", entries); + + model.addAttribute("stats", new CalculateWarehouseStatsAction(entries).finish()); + return "intern/warehouse/slots/index"; + } +} diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/TodoController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/TodoController.java new file mode 100644 index 0000000..4bed5cd --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/TodoController.java @@ -0,0 +1,112 @@ +package org.hso.ecommerce.controller.intern.warehouse; + +import org.hso.ecommerce.action.shop.EnableTrackingAction; +import org.hso.ecommerce.entities.warehouse.WarehouseBooking; +import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Optional; + +@Controller +@RequestMapping("/intern/warehouse/") +public class TodoController { + + @Autowired + private final WarehouseBookingRepository warehouseBookingRepository = null; + + @GetMapping("todo") + public String accountingWarehouseTodo( + Model model + ) { + model.addAttribute("bookings", warehouseBookingRepository.findNotDone()); + return "intern/warehouse/todo"; + } + + + @PostMapping("progress/{id}") + public String postProgressId( + Model model, + HttpServletRequest request, + HttpServletResponse response, + @PathVariable("id") Long id + ) { + Optional booking = warehouseBookingRepository.findById(id); + if (!booking.isPresent()) { + model.addAttribute("error", "Die Buchung wurde nicht gefunden."); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return "error/404"; + } + + if (booking.get().isInProgress) { + response.setStatus(409); + return "intern/warehouse/error_progress_failed"; + } + + booking.get().isInProgress = true; + warehouseBookingRepository.save(booking.get()); + + return "redirect:/intern/warehouse/progress/" + id; + } + + @PostMapping("progress/{id}/finish") + public String postProgressIdFinish( + Model model, + HttpServletRequest request, + HttpServletResponse response, + @PathVariable("id") Long id + ) { + Optional booking = warehouseBookingRepository.findById(id); + if (!booking.isPresent()) { + model.addAttribute("error", "Die Buchung wurde nicht gefunden."); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return "error/404"; + } + + booking.get().isInProgress = true; + booking.get().isDone = true; + + // Update Delivery Date + if (booking.get().reason.customerOrder != null) { + EnableTrackingAction.addTrackingInfo(booking.get().reason.customerOrder); + } + + warehouseBookingRepository.save(booking.get()); + + return "redirect:/intern/warehouse/todo"; + } + + @GetMapping("progress/{id}") + public String getProgressId(Model model, + HttpServletRequest request, + HttpServletResponse response, + @PathVariable("id") Long id) { + Optional booking = warehouseBookingRepository.findById(id); + if (!booking.isPresent()) { + model.addAttribute("error", "Die Buchung wurde nicht gefunden."); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return "error/404"; + } + + if (booking.get().isDone) { + model.addAttribute("info", "Die Buchung wurde schon abgeschlossen."); + } + + if (!booking.get().isInProgress) { + // Only reachable if path is manipulated. + model.addAttribute("error", "Die Buchung wurde noch nicht zugewiesen!"); + } + + model.addAttribute("booking", booking.get()); + return "intern/warehouse/id_progress"; + } + + +} diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopCheckoutController.java b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopCheckoutController.java index c2c1c3a..8b0b1ba 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopCheckoutController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopCheckoutController.java @@ -1,7 +1,6 @@ package org.hso.ecommerce.controller.shop; import org.hso.ecommerce.action.shop.CreateOrderAction; -import org.hso.ecommerce.action.shop.EnableTrackingAction; import org.hso.ecommerce.entities.booking.BookingAccountEntry; import org.hso.ecommerce.entities.booking.PaymentMethod; import org.hso.ecommerce.entities.shop.Address; @@ -11,7 +10,7 @@ import org.hso.ecommerce.entities.user.User; import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository; import org.hso.ecommerce.repos.booking.BookingRepository; import org.hso.ecommerce.repos.shop.ArticleRepository; -import org.hso.ecommerce.repos.shop.CustomerOderRepository; +import org.hso.ecommerce.repos.shop.CustomerOrderRepository; import org.hso.ecommerce.repos.user.UserRepository; import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository; import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository; @@ -45,7 +44,7 @@ public class ShopCheckoutController { private final WarehouseBookingRepository warehouseBookingRepository = null; @Autowired - private final CustomerOderRepository customerOderRepository = null; + private final CustomerOrderRepository customerOderRepository = null; @Autowired private final WarehouseBookingPositionSlotEntryRepository wbeseRepo = null; @@ -122,7 +121,7 @@ public class ShopCheckoutController { user, expectedPrice, Address.fromString(address), - PaymentMethod.fromCreditCarNumber(cardnumber), + PaymentMethod.fromCreditCardNumber(cardnumber), bookingEntryRepository.getByUser(user.id).orElse(BookingAccountEntry.newUser(user)), bookingEntryRepository.getByVat().orElse(BookingAccountEntry.newVat()), bookingEntryRepository.getByMain().orElse(BookingAccountEntry.newMain()) @@ -136,7 +135,6 @@ public class ShopCheckoutController { CreateOrderAction.Result result = null; try { result = action.finish(); - EnableTrackingAction.addTrackingInfo(result.customerOrder); customerOderRepository.save(result.customerOrder); bookingRepository.saveAll(result.bookings); diff --git a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java index cacdafe..47b8acf 100644 --- a/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java +++ b/prototype/src/main/java/org/hso/ecommerce/controller/shop/ShopSearchController.java @@ -32,9 +32,8 @@ public class ShopSearchController { ) { model.addAttribute("categories", categoryRepository.getCategories()); //for sidebar - term = term.trim(); - if (term != null) { //if search by Term + term = term.trim(); List
articles = SearchByTermAction.searchByTerm(term, articleRepository); model.addAttribute("articles", articles); } else if (category != null) { //if search by Category diff --git a/prototype/src/main/java/org/hso/ecommerce/entities/booking/BookingReason.java b/prototype/src/main/java/org/hso/ecommerce/entities/booking/BookingReason.java index 3b93517..8d6572f 100644 --- a/prototype/src/main/java/org/hso/ecommerce/entities/booking/BookingReason.java +++ b/prototype/src/main/java/org/hso/ecommerce/entities/booking/BookingReason.java @@ -43,4 +43,9 @@ public class BookingReason { public BookingReason(SupplierOrder supplierOrder) { this.supplierOrder = supplierOrder; } + + public BookingReason(String comment) { + this.isManuel = true; + this.comment = comment; + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/entities/booking/PaymentMethod.java b/prototype/src/main/java/org/hso/ecommerce/entities/booking/PaymentMethod.java index af0a9c0..fa9fe62 100644 --- a/prototype/src/main/java/org/hso/ecommerce/entities/booking/PaymentMethod.java +++ b/prototype/src/main/java/org/hso/ecommerce/entities/booking/PaymentMethod.java @@ -7,7 +7,7 @@ public class PaymentMethod { public String creditCardNumber; - public static PaymentMethod fromCreditCarNumber(String cardnumber) { + public static PaymentMethod fromCreditCardNumber(String cardnumber) { PaymentMethod m = new PaymentMethod(); m.creditCardNumber = cardnumber; diff --git a/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrder.java b/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrder.java index 1b20bb2..853b885 100644 --- a/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrder.java +++ b/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrder.java @@ -4,6 +4,7 @@ import org.hso.ecommerce.entities.user.User; import javax.persistence.*; import javax.validation.constraints.NotNull; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; @@ -31,7 +32,7 @@ public class CustomerOrder { @NotNull public java.sql.Timestamp created; - @NotNull + @Column(nullable = true) public String trackingId; @Column(nullable = true) @@ -43,4 +44,21 @@ public class CustomerOrder { public int totalNetCent; public int totalGrossCent; public int totalVatCent; + + public String formatInDeliverySince(){ + return new SimpleDateFormat("dd.MM.yyyy HH:mm").format(inDeliverySince); + } + + public String formatCreated(){ + return new SimpleDateFormat("dd.MM.yyyy HH:mm").format(created); + } + + public String formatDeliveredAt(){ + return new SimpleDateFormat("dd.MM.yyyy HH:mm").format(deliveredAt); + } + + public String getEstimatedArrival() { + //TODO: get estimated arrival from api + return "TODO TODO TODO"; + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrderPosition.java b/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrderPosition.java index dbe53f7..2569158 100644 --- a/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrderPosition.java +++ b/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrderPosition.java @@ -19,4 +19,8 @@ public class CustomerOrderPosition { public int pricePerUnit; public int quantity; + + public int getSumPrice(){ + return article.getPriceGross() * quantity; + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/entities/user/User.java b/prototype/src/main/java/org/hso/ecommerce/entities/user/User.java index 784d89a..e08c2ee 100644 --- a/prototype/src/main/java/org/hso/ecommerce/entities/user/User.java +++ b/prototype/src/main/java/org/hso/ecommerce/entities/user/User.java @@ -24,6 +24,11 @@ public class User { @Column(unique = true) public String email; + @Column(insertable = false, updatable = false) + public String name; + + public String salutation; + public String passwordHash; public boolean isActive; diff --git a/prototype/src/main/java/org/hso/ecommerce/entities/warehouse/WarehouseBookingPositionSlotEntry.java b/prototype/src/main/java/org/hso/ecommerce/entities/warehouse/WarehouseBookingPositionSlotEntry.java index 444b921..5c7d909 100644 --- a/prototype/src/main/java/org/hso/ecommerce/entities/warehouse/WarehouseBookingPositionSlotEntry.java +++ b/prototype/src/main/java/org/hso/ecommerce/entities/warehouse/WarehouseBookingPositionSlotEntry.java @@ -38,4 +38,14 @@ public class WarehouseBookingPositionSlotEntry { return e; } + + public static WarehouseBookingPositionSlotEntry empty(Article article, Slot slot) { + WarehouseBookingPositionSlotEntry e = new WarehouseBookingPositionSlotEntry(); + + e.article = article; + e.slot = slot; + e.newSumSlot = 0; + + return e; + } } diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/booking/BookingRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/booking/BookingRepository.java index 9847f4a..e72ae6a 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/booking/BookingRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/booking/BookingRepository.java @@ -26,5 +26,3 @@ public interface BookingRepository extends JpaRepository { List supplierBookingsReverseChronologically(long supplierId); } - - diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOderRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOrderRepository.java similarity index 68% rename from prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOderRepository.java rename to prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOrderRepository.java index 2c332f5..86c88e6 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOderRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/shop/CustomerOrderRepository.java @@ -5,13 +5,17 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository -public interface CustomerOderRepository extends JpaRepository { +public interface CustomerOrderRepository extends JpaRepository { @Query("SELECT SUM(cop.quantity) FROM CustomerOrderPosition cop JOIN cop.order co WHERE cop.article.id = :articleId AND co.created >= :begin AND co.created < :end") Integer countOrdersOfArticleInTimespan( long articleId, java.sql.Timestamp begin, java.sql.Timestamp end ); -} + @Query("SELECT co FROM CustomerOrder co WHERE co.customer.id = :userId ORDER BY co.id DESC") + List getOrdersByUserId(long userId); +} \ No newline at end of file diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/supplier/SupplierOrderRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/supplier/SupplierOrderRepository.java index 9d15e02..06ad249 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/supplier/SupplierOrderRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/supplier/SupplierOrderRepository.java @@ -1,8 +1,11 @@ package org.hso.ecommerce.repos.supplier; +import java.util.List; + import org.hso.ecommerce.entities.supplier.SupplierOrder; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository @@ -11,4 +14,9 @@ public interface SupplierOrderRepository extends JpaRepository findOrderBySupplierID(@Param("supplierId") long supplierId); + + @Query("SELECT a FROM SupplierOrder a") + List findAll(); } diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/supplier/SupplierRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/supplier/SupplierRepository.java index 2b81659..14b3a75 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/supplier/SupplierRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/supplier/SupplierRepository.java @@ -1,10 +1,19 @@ package org.hso.ecommerce.repos.supplier; +import java.util.List; + import org.hso.ecommerce.entities.supplier.Supplier; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface SupplierRepository extends JpaRepository { - -} + + @Query("SELECT a FROM Supplier a") + List findAll(); + + @Query("SELECT a FROM Supplier a WHERE a.id = :supplierId") + Supplier findSupplierById(@Param("supplierId") long supplierId); +} \ No newline at end of file diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/warehouse/WarehouseBookingPositionSlotEntryRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/warehouse/WarehouseBookingPositionSlotEntryRepository.java index cb9902e..804e8b7 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/warehouse/WarehouseBookingPositionSlotEntryRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/warehouse/WarehouseBookingPositionSlotEntryRepository.java @@ -13,10 +13,12 @@ public interface WarehouseBookingPositionSlotEntryRepository extends JpaReposito @Query(value = "Select e.id, e.article_id, e.new_sum_slot, e.slot_id from warehouse_booking_position_entries as e, warehouse_slots as s where e.slot_id = s.id AND e.article_id = :article GROUP BY s.slot_num HAVING max(e.id)", nativeQuery = true) List getByArticle(long article); - - + @Query(value = "SELECT SUM(w.new_sum_slot) FROM warehouse_booking_position_entries as w WHERE w.article_id = :articleid", nativeQuery = true) Optional getArticleStock(long articleid); - + + @Query(value = "Select e.id, e.article_id, e.new_sum_slot, e.slot_id from warehouse_booking_position_entries as e, warehouse_slots as s where e.slot_id = s.id AND s.slot_num = :slotnum GROUP BY s.slot_num HAVING max(e.id)", nativeQuery = true) + Optional getBySlotNum(long slotnum); + } diff --git a/prototype/src/main/java/org/hso/ecommerce/repos/warehouse/WarehouseBookingRepository.java b/prototype/src/main/java/org/hso/ecommerce/repos/warehouse/WarehouseBookingRepository.java index 8d01092..08434c4 100644 --- a/prototype/src/main/java/org/hso/ecommerce/repos/warehouse/WarehouseBookingRepository.java +++ b/prototype/src/main/java/org/hso/ecommerce/repos/warehouse/WarehouseBookingRepository.java @@ -2,10 +2,16 @@ package org.hso.ecommerce.repos.warehouse; import org.hso.ecommerce.entities.warehouse.WarehouseBooking; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface WarehouseBookingRepository extends JpaRepository { + @Query("Select b FROM WarehouseBooking b WHERE b.isDone = 0") + List findNotDone(); + } diff --git a/prototype/src/main/resources/templates/fragments/customer.html b/prototype/src/main/resources/templates/fragments/customer.html index d47a06a..f8ba1ff 100644 --- a/prototype/src/main/resources/templates/fragments/customer.html +++ b/prototype/src/main/resources/templates/fragments/customer.html @@ -12,8 +12,6 @@ diff --git a/prototype/src/main/resources/templates/fragments/header.html b/prototype/src/main/resources/templates/fragments/header.html index 054c332..349f72c 100644 --- a/prototype/src/main/resources/templates/fragments/header.html +++ b/prototype/src/main/resources/templates/fragments/header.html @@ -18,7 +18,6 @@
@@ -32,8 +32,8 @@ @@ -45,77 +45,61 @@ + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + +
- +
Status
+ Manuell: + + Startbuchung + + + Bestellung: + + + + Lieferung: + +
2020-01-12 12:18 - Bestellung 8408 - Auf Warteliste
-
Kamera1Lagerplatz 01 -
Spielzeugauto2Lagerplatz 02 -
+ Auf Warteliste + + Wird bearbeitet + + Fertig +
2020-01-12 12:15 - Manuell: Ware war defekt. - In Arbeit
-
Kamera1Lagerplatz 01 -
2020-01-12 12:11 - Lieferung 4545 - Fertig
Kamera10 -Lagerplatz 01 - -
Kamera1 -Lagerplatz 04
-Lagerplatz + Lagerplatz + - - -

diff --git a/prototype/src/main/resources/templates/intern/warehouse/slots/index.html b/prototype/src/main/resources/templates/intern/warehouse/slots/index.html index 29de644..3d52f6b 100644 --- a/prototype/src/main/resources/templates/intern/warehouse/slots/index.html +++ b/prototype/src/main/resources/templates/intern/warehouse/slots/index.html @@ -27,15 +27,16 @@

Plätze in Verwendung

-

67%

+

% +

Lagereffizienz

-

43%

+

%

Lagerdiversität

-

3

+

@@ -52,47 +53,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + +
Anzahl Max.

#1

Kamera2020

#2

Kamera120

#3

0

#4

0

#5

Usb-Ding110

#6

Stativ35

#

- .

diff --git a/prototype/src/main/resources/templates/intern/warehouse/todo.html b/prototype/src/main/resources/templates/intern/warehouse/todo.html index 4ff484e..643cad4 100644 --- a/prototype/src/main/resources/templates/intern/warehouse/todo.html +++ b/prototype/src/main/resources/templates/intern/warehouse/todo.html @@ -24,6 +24,7 @@
+

Es gibt keine offenen Lagerbuchungen!

@@ -41,60 +42,63 @@ + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + +
Status
+ Manuell: +

+                    
+ Startbuchung + + + Bestellung: + +

+                    
+ + Lieferung: + +
2020-01-12 12:18 - Bestellung 8408 -
- Hans Maier
- Hauptstraße 12
- 74880 Musterstadt
- Deutschland
-
-
-
- -
-
Kamera1Lagerplatz 01 -
Spielzeugauto2Lagerplatz 02 -
2020-01-12 12:15 - Manuell: Ware war defekt. - Abschließen -
Kamera1Lagerplatz 01 -
+
+ +
+
+
+ +
+
-Lagerplatz + Lagerplatz + - - -

diff --git a/prototype/src/main/resources/templates/register.html b/prototype/src/main/resources/templates/register.html index 078191f..fccb016 100644 --- a/prototype/src/main/resources/templates/register.html +++ b/prototype/src/main/resources/templates/register.html @@ -63,25 +63,6 @@ -
- -
- -
-
- -
-

Werbung

-
-
-
- -
- -
-
-
-
diff --git a/prototype/src/main/resources/templates/user/orders/index.html b/prototype/src/main/resources/templates/user/orders/index.html index a60e623..023910d 100644 --- a/prototype/src/main/resources/templates/user/orders/index.html +++ b/prototype/src/main/resources/templates/user/orders/index.html @@ -21,30 +21,22 @@
-
-

Bestellung vom 27.01.2020

+
-
-

Bestellung vom 01.01.2020

-
- - - - - - - - - - - - - - - - - -
LieferstatusAngekommen
03.01.2020
SendeverfolgungsnummerXE5140684351DE
- Hans Maier
- Hauptstraße 12
- 74880 Musterstadt
- Deutschland
-
Gutgeschriebene Bonuspunkte5
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BildNameMengePreis pro Artikel (Brutto)
Billige Kamera 140,50 EUR
Apfel 51,00 EUR
PositionPreis
Artikel (Netto) 20,00 EUR
Umsatzsteuer (19%) 5,00 EUR
Umsatzsteuer (7%) 2,00 EUR
-

Gesammtpreis

-
-

50,79 EUR

+

diff --git a/prototype/src/main/resources/templates/user/settings.html b/prototype/src/main/resources/templates/user/settings.html index 29f6ec4..80bd60e 100644 --- a/prototype/src/main/resources/templates/user/settings.html +++ b/prototype/src/main/resources/templates/user/settings.html @@ -21,19 +21,19 @@
-
+

Login Daten

- +
-
+

Sicherheit

@@ -42,8 +42,8 @@ - - + + @@ -51,7 +51,7 @@
-
+

Rechungs- und Lieferinformation

@@ -59,7 +59,7 @@
-
-
- +