From 976e2d1949c780dc2dc3c0c6a14c65a422447f1b Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Mon, 1 Jun 2020 20:25:51 +0200 Subject: [PATCH 1/4] Implement Warehouse.... Sry, only one commit. No time to make history ;D --- prototype/gradlew | 0 .../CalculateWarehouseStatsAction.java | 73 +++++++++ .../warehouse/CreateManuelBookingAction.java | 92 ++++++++++++ .../hso/ecommerce/app/RequestController.java | 44 ------ .../intern/WarehouseController.java | 19 ++- .../warehouse/ManuelBookingController.java | 138 ++++++++++++++++++ .../intern/warehouse/SlotsController.java | 44 ++++++ .../intern/warehouse/TodoController.java | 102 +++++++++++++ .../entities/booking/BookingReason.java | 5 + .../WarehouseBookingPositionSlotEntry.java | 10 ++ ...useBookingPositionSlotEntryRepository.java | 8 +- .../warehouse/WarehouseBookingRepository.java | 6 + .../templates/intern/warehouse/addManual.html | 25 ++-- .../intern/warehouse/id_progress.html | 67 ++++++--- .../templates/intern/warehouse/index.html | 132 ++++++++--------- .../intern/warehouse/slots/index.html | 63 +++----- .../templates/intern/warehouse/todo.html | 108 +++++++------- 17 files changed, 682 insertions(+), 254 deletions(-) mode change 100644 => 100755 prototype/gradlew create mode 100644 prototype/src/main/java/org/hso/ecommerce/action/warehouse/CalculateWarehouseStatsAction.java create mode 100644 prototype/src/main/java/org/hso/ecommerce/action/warehouse/CreateManuelBookingAction.java create mode 100644 prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/ManuelBookingController.java create mode 100644 prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/SlotsController.java create mode 100644 prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/TodoController.java diff --git a/prototype/gradlew b/prototype/gradlew old mode 100644 new mode 100755 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/app/RequestController.java b/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java index bb0b5d6..9d63f4b 100644 --- a/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java +++ b/prototype/src/main/java/org/hso/ecommerce/app/RequestController.java @@ -119,15 +119,6 @@ public class RequestController { public String internSupplierOrdersId() { return "intern/supplierOrders/id"; } - - /* - - @GetMapping("/intern/suppliersOffers") - public String internSuppliersOffers() { - return "intern/offeredArticles/index"; - } - */ - @GetMapping("/intern/accounting/") public String accounting() { @@ -148,39 +139,4 @@ public class RequestController { public String accountingAddManual() { return "intern/accounting/addManual"; } - - @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/controller/intern/WarehouseController.java b/prototype/src/main/java/org/hso/ecommerce/controller/intern/WarehouseController.java index 9b618f7..1e26c3d 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,25 @@ 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.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( + HttpServletRequest request + ) { + request.setAttribute("bookings", warehouseBookingRepository.findAll()); + return "intern/warehouse/index"; + } } 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..35ab3fc --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/ManuelBookingController.java @@ -0,0 +1,138 @@ +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.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( + HttpServletRequest request + ) { + + request.setAttribute("articles", articleRepository.findAll()); + request.setAttribute("slots", slotRepository.findAll()); + + return "intern/warehouse/addManual"; + } + + @PostMapping("addManual") + public String warehouseAddMaualPost( + 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) { + request.setAttribute("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()) { + request.setAttribute("error", "Der Artikel konnte nicht gefunden werden."); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } else { + article = optionalArticle.get(); + } + + if (amount <= 0) { + request.setAttribute("error", "Eine Anzahl <= 0 kann nicht verbucht werden."); + response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); + return "intern/warehouse/addManual"; + } + + if (sourceIsSlot == false && destinationIsSlot == false) { + request.setAttribute("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) { + request.setAttribute("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) { + request.setAttribute("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..1f6bdd3 --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/SlotsController.java @@ -0,0 +1,44 @@ +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.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( + 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()); + request.setAttribute("entries", entries); + + request.setAttribute("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..48d130a --- /dev/null +++ b/prototype/src/main/java/org/hso/ecommerce/controller/intern/warehouse/TodoController.java @@ -0,0 +1,102 @@ +package org.hso.ecommerce.controller.intern.warehouse; + +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.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( + HttpServletRequest request + ) { + request.setAttribute("bookings", warehouseBookingRepository.findNotDone()); + return "intern/warehouse/todo"; + } + + + @PostMapping("progress/{id}") + public String postProgressId( + HttpServletRequest request, + HttpServletResponse response, + @PathVariable("id") Long id + ) { + Optional booking = warehouseBookingRepository.findById(id); + if (!booking.isPresent()) { + request.setAttribute("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( + HttpServletRequest request, + HttpServletResponse response, + @PathVariable("id") Long id + ) { + Optional booking = warehouseBookingRepository.findById(id); + if (!booking.isPresent()) { + request.setAttribute("error", "Die Buchung wurde nicht gefunden."); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return "error/404"; + } + + booking.get().isInProgress = true; + booking.get().isDone = true; + + warehouseBookingRepository.save(booking.get()); + + return "redirect:/intern/warehouse/todo"; + } + + @GetMapping("progress/{id}") + public String getProgressId(HttpServletRequest request, + HttpServletResponse response, + @PathVariable("id") Long id) { + Optional booking = warehouseBookingRepository.findById(id); + if (!booking.isPresent()) { + request.setAttribute("error", "Die Buchung wurde nicht gefunden."); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return "error/404"; + } + + if (booking.get().isDone) { + request.setAttribute("info", "Die Buchung wurde schon abgeschlossen."); + } + + if (!booking.get().isInProgress) { + // Only reachable if path is manipulated. + request.setAttribute("error", "Die Buchung wurde noch nicht zugewiesen!"); + } + + request.setAttribute("booking", booking.get()); + return "intern/warehouse/id_progress"; + } + + +} 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/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/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/intern/warehouse/addManual.html b/prototype/src/main/resources/templates/intern/warehouse/addManual.html index 774ff56..f4c9f08 100644 --- a/prototype/src/main/resources/templates/intern/warehouse/addManual.html +++ b/prototype/src/main/resources/templates/intern/warehouse/addManual.html @@ -20,14 +20,12 @@
-
+
- + -
@@ -36,20 +34,23 @@
- +
- +
- + - + + +
@@ -58,13 +59,13 @@
- +
- + - +
diff --git a/prototype/src/main/resources/templates/intern/warehouse/id_progress.html b/prototype/src/main/resources/templates/intern/warehouse/id_progress.html index 5e050cd..5d26a1b 100644 --- a/prototype/src/main/resources/templates/intern/warehouse/id_progress.html +++ b/prototype/src/main/resources/templates/intern/warehouse/id_progress.html @@ -21,35 +21,54 @@ - - 2020-01-12 12:18 - - Bestellung 8408 -
- Hans Maier
- Hauptstraße 12
- 74880 Musterstadt
- Deutschland
-
+ + + + Manuell: +

+                
+                
+                    Startbuchung
+                
+                
+                    
+                        Bestellung: 
+                    
+                    

+                
+                
+                    
+                        Lieferung: 
+                    
                 
             
-            
-                
-                Kamera
-                1
-                Lagerplatz 01
-                 -
-            
-            
-                
-                Spielzeugauto
-                2
-                Lagerplatz 02
-                 -
+            
+                
+                
+                
+                    
+                     -
+                    Lagerplatz  
+                
+                
+                    
+                    Lagerplatz  
+                     -
+                
+                
+                    
+                     -
+                     -
+                
             
         
         

- Abschließen + + +
diff --git a/prototype/src/main/resources/templates/intern/warehouse/index.html b/prototype/src/main/resources/templates/intern/warehouse/index.html index 3a6ea70..a4170c6 100644 --- a/prototype/src/main/resources/templates/intern/warehouse/index.html +++ b/prototype/src/main/resources/templates/intern/warehouse/index.html @@ -1,9 +1,9 @@ - + - + Lager @@ -18,7 +18,7 @@

Lagerbuchungen

-
+
@@ -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..e341a99 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 + - - -

From fc239983a7ba0a1be0ffcb9298f634269d930f1f Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Mon, 1 Jun 2020 21:15:27 +0200 Subject: [PATCH 2/4] Fix article links. --- .../main/resources/templates/intern/warehouse/id_progress.html | 2 +- .../src/main/resources/templates/intern/warehouse/index.html | 2 +- .../src/main/resources/templates/intern/warehouse/todo.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/prototype/src/main/resources/templates/intern/warehouse/id_progress.html b/prototype/src/main/resources/templates/intern/warehouse/id_progress.html index 5d26a1b..6aa2302 100644 --- a/prototype/src/main/resources/templates/intern/warehouse/id_progress.html +++ b/prototype/src/main/resources/templates/intern/warehouse/id_progress.html @@ -44,7 +44,7 @@ - diff --git a/prototype/src/main/resources/templates/intern/warehouse/index.html b/prototype/src/main/resources/templates/intern/warehouse/index.html index a4170c6..a91a2b0 100644 --- a/prototype/src/main/resources/templates/intern/warehouse/index.html +++ b/prototype/src/main/resources/templates/intern/warehouse/index.html @@ -78,7 +78,7 @@ - diff --git a/prototype/src/main/resources/templates/intern/warehouse/todo.html b/prototype/src/main/resources/templates/intern/warehouse/todo.html index e341a99..643cad4 100644 --- a/prototype/src/main/resources/templates/intern/warehouse/todo.html +++ b/prototype/src/main/resources/templates/intern/warehouse/todo.html @@ -78,7 +78,7 @@ - From a192f0ac51174bd70a71e4c3fcf04350a1f29d56 Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Wed, 3 Jun 2020 16:55:36 +0200 Subject: [PATCH 3/4] Set Tracing Id in Warehouse/finish not in Checkout. This was wrong. --- .../controller/intern/warehouse/TodoController.java | 6 ++++++ .../ecommerce/controller/shop/ShopCheckoutController.java | 2 -- .../java/org/hso/ecommerce/entities/shop/CustomerOrder.java | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) 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 index 48d130a..d57916c 100644 --- 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 @@ -1,5 +1,6 @@ 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; @@ -69,6 +70,11 @@ public class TodoController { 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"; 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..507b759 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; @@ -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/entities/shop/CustomerOrder.java b/prototype/src/main/java/org/hso/ecommerce/entities/shop/CustomerOrder.java index 1b20bb2..8c80c58 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 @@ -31,7 +31,7 @@ public class CustomerOrder { @NotNull public java.sql.Timestamp created; - @NotNull + @Column(nullable = true) public String trackingId; @Column(nullable = true) From eb82d05f4fe21c4659cc9d12db1b85ef09834b67 Mon Sep 17 00:00:00 2001 From: CodeSteak Date: Mon, 8 Jun 2020 09:14:11 +0200 Subject: [PATCH 4/4] Use Spring model for template attributes --- .../intern/WarehouseController.java | 4 +++- .../warehouse/ManuelBookingController.java | 20 +++++++++-------- .../intern/warehouse/SlotsController.java | 6 +++-- .../intern/warehouse/TodoController.java | 22 +++++++++++-------- 4 files changed, 31 insertions(+), 21 deletions(-) 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 1e26c3d..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 @@ -3,6 +3,7 @@ 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; @@ -17,9 +18,10 @@ public class WarehouseController { @GetMapping("/") public String accountingWarehouse( + Model model, HttpServletRequest request ) { - request.setAttribute("bookings", warehouseBookingRepository.findAll()); + model.addAttribute("bookings", warehouseBookingRepository.findAll()); return "intern/warehouse/index"; } } 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 index 35ab3fc..7ef8e0e 100644 --- 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 @@ -10,6 +10,7 @@ import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryReposi 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; @@ -37,17 +38,18 @@ public class ManuelBookingController { @GetMapping("addManual") public String warehouseAddManual( - HttpServletRequest request + Model model ) { - request.setAttribute("articles", articleRepository.findAll()); - request.setAttribute("slots", slotRepository.findAll()); + 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, @@ -65,7 +67,7 @@ public class ManuelBookingController { try { articleId = Long.parseLong(articleIdText.split(" - ", 2)[0].trim()); } catch (NumberFormatException e) { - request.setAttribute("error", "Die Artikel Id konnte nicht erkannt werden."); + model.addAttribute("error", "Die Artikel Id konnte nicht erkannt werden."); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return "intern/warehouse/addManual"; } @@ -74,7 +76,7 @@ public class ManuelBookingController { Optional
optionalArticle = articleRepository.findById(articleId); Article article = null; if (!optionalArticle.isPresent()) { - request.setAttribute("error", "Der Artikel konnte nicht gefunden werden."); + model.addAttribute("error", "Der Artikel konnte nicht gefunden werden."); response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); return "intern/warehouse/addManual"; } else { @@ -82,13 +84,13 @@ public class ManuelBookingController { } if (amount <= 0) { - request.setAttribute("error", "Eine Anzahl <= 0 kann nicht verbucht werden."); + 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) { - request.setAttribute("error", "Jede Buchung benötigt ein Ziel oder eine Quelle."); + model.addAttribute("error", "Jede Buchung benötigt ein Ziel oder eine Quelle."); response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); return "intern/warehouse/addManual"; } @@ -123,11 +125,11 @@ public class ManuelBookingController { new CreateManuelBookingAction(article, amount, sourceSlot, destinationSlot, reason).finish() ); } catch (CreateManuelBookingAction.ArticleSlotConstraintArticleTypeFailedException e) { - request.setAttribute("error", "Es befindet sich der falsche Artikeltyp in Quell- oder Ziellagerplatz. "); + 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) { - request.setAttribute("error", "Die maximale Anzahl an lagerbaren Artikeln im Ziellagerplatz wurde überschritten."); + model.addAttribute("error", "Die maximale Anzahl an lagerbaren Artikeln im Ziellagerplatz wurde überschritten."); response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED); return "intern/warehouse/addManual"; } 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 index 1f6bdd3..8cc5721 100644 --- 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 @@ -6,6 +6,7 @@ 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; @@ -25,6 +26,7 @@ public class SlotsController { @GetMapping("slots/") public String accountingWarehouseSlots( + Model model, HttpServletRequest request ) { @@ -36,9 +38,9 @@ public class SlotsController { .getBySlotNum(s.slotNum) .orElseGet(() -> WarehouseBookingPositionSlotEntry.empty(null, s)) ).collect(Collectors.toList()); - request.setAttribute("entries", entries); + model.addAttribute("entries", entries); - request.setAttribute("stats", new CalculateWarehouseStatsAction(entries).finish()); + 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 index d57916c..4bed5cd 100644 --- 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 @@ -5,6 +5,7 @@ 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; @@ -23,22 +24,23 @@ public class TodoController { @GetMapping("todo") public String accountingWarehouseTodo( - HttpServletRequest request + Model model ) { - request.setAttribute("bookings", warehouseBookingRepository.findNotDone()); + 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()) { - request.setAttribute("error", "Die Buchung wurde nicht gefunden."); + model.addAttribute("error", "Die Buchung wurde nicht gefunden."); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return "error/404"; } @@ -56,13 +58,14 @@ public class TodoController { @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()) { - request.setAttribute("error", "Die Buchung wurde nicht gefunden."); + model.addAttribute("error", "Die Buchung wurde nicht gefunden."); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return "error/404"; } @@ -81,26 +84,27 @@ public class TodoController { } @GetMapping("progress/{id}") - public String getProgressId(HttpServletRequest request, + public String getProgressId(Model model, + HttpServletRequest request, HttpServletResponse response, @PathVariable("id") Long id) { Optional booking = warehouseBookingRepository.findById(id); if (!booking.isPresent()) { - request.setAttribute("error", "Die Buchung wurde nicht gefunden."); + model.addAttribute("error", "Die Buchung wurde nicht gefunden."); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return "error/404"; } if (booking.get().isDone) { - request.setAttribute("info", "Die Buchung wurde schon abgeschlossen."); + model.addAttribute("info", "Die Buchung wurde schon abgeschlossen."); } if (!booking.get().isInProgress) { // Only reachable if path is manipulated. - request.setAttribute("error", "Die Buchung wurde noch nicht zugewiesen!"); + model.addAttribute("error", "Die Buchung wurde noch nicht zugewiesen!"); } - request.setAttribute("booking", booking.get()); + model.addAttribute("booking", booking.get()); return "intern/warehouse/id_progress"; }