Implement Arrival of Supplier Order.

This commit is contained in:
CodeSteak 2020-06-12 19:22:36 +02:00
parent 1590821f64
commit 56f4ec0dda
5 changed files with 198 additions and 44 deletions

View File

@ -1,7 +0,0 @@
package org.hso.ecommerce.action.warehouse;
public class StoreSupplierOrderAction {
//TODO add delivery date and warehouse booking
}

View File

@ -0,0 +1,103 @@
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.supplier.SupplierOrder;
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.ArrayList;
import java.util.Date;
import java.util.List;
public class SupplierOrderArrivedAction {
private final Article article;
private final ArrayList<WarehouseBookingPositionSlotEntry> warehouseCandidates;
private final SupplierOrder order;
public SupplierOrderArrivedAction(List<WarehouseBookingPositionSlotEntry> warehouseCandidates, SupplierOrder order, Article article) {
this.warehouseCandidates = new ArrayList<>(warehouseCandidates);
this.order = order;
this.article = article;
}
public Result finish() throws NoSpaceInWarehouseException {
// Sort for most filled slot first;
warehouseCandidates.sort((b, a) -> Integer.compare(a.newSumSlot, b.newSumSlot));
int needed = order.numberOfUnits;
WarehouseBooking booking = new WarehouseBooking();
booking.created = new Timestamp(new Date().getTime());
booking.reason = new BookingReason(order);
for (WarehouseBookingPositionSlotEntry entry : warehouseCandidates) {
int canBeAdded = article.warehouseUnitsPerSlot - entry.newSumSlot;
if (canBeAdded == 0) {
// this slot is full, skip
continue;
}
int willBeAdded = Math.min(canBeAdded, needed);
needed -= willBeAdded;
WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition();
bookingPosition.article = article;
bookingPosition.amount = willBeAdded;
bookingPosition.slotEntry = entry.copyAddAmount(willBeAdded);
bookingPosition.booking = booking;
booking.positions.add(bookingPosition);
if (needed == 0) {
break;
}
}
if (needed > 0) {
throw new NoSpaceInWarehouseException(article);
}
order.delivered = new Timestamp(new Date().getTime());
return new Result(order, booking);
}
public static class Result extends Exception {
private final SupplierOrder order;
private final WarehouseBooking booking;
public Result(SupplierOrder order, WarehouseBooking booking) {
this.order = order;
this.booking = booking;
}
public SupplierOrder getOrder() {
return order;
}
public WarehouseBooking getBooking() {
return booking;
}
}
public static class NoSpaceInWarehouseException extends Exception {
private Article article;
public NoSpaceInWarehouseException(Article article) {
super("The quantity of article '" + article.title + "' does not fit in warehouse.");
this.article = article;
}
public Article getArticle() {
return article;
}
}
}

View File

@ -1,13 +1,14 @@
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.action.warehouse.SupplierOrderArrivedAction;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.supplier.SupplierOrder;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
import org.hso.ecommerce.repos.shop.ArticleRepository;
import org.hso.ecommerce.repos.supplier.SupplierOrderRepository;
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;
@ -15,7 +16,13 @@ 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;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Controller
@RequestMapping("/intern/")
@ -24,13 +31,26 @@ public class SupplierOrderController {
@Autowired
private final SupplierOrderRepository supplierOrderRepository = null;
@Autowired
private final ArticleRepository articleRepository = null;
@Autowired
private final WarehouseBookingPositionSlotEntryRepository warehouseBookingPositionSlotEntryRepository = null;
@Autowired
private final WarehouseBookingRepository warehouseBookingRepository = null;
@Autowired
private final SlotRepository slotRepository = null;
@GetMapping("supplierOrders")
public String listSuppliers(Model model) {
List<UImodelSupplierOrder> totals = new ArrayList<UImodelSupplierOrder>();
for (SupplierOrder orders : supplierOrderRepository.findAll()) {
totals.add(new UImodelSupplierOrder(orders));
for (SupplierOrder order : supplierOrderRepository.findAll()) {
final Article article = articleRepository.findArticleByArticleOffer(order.ordered).orElse(null);
totals.add(new UImodelSupplierOrder(order, article));
}
model.addAttribute("orders", totals);
@ -39,20 +59,50 @@ public class SupplierOrderController {
}
@PostMapping("/supplierOrders/store/{id}")
public RedirectView storeOrder(@PathVariable(required = true) String id) {
long supplierOrderID = Long.parseLong(id);
Optional<SupplierOrder> order = supplierOrderRepository.findById(supplierOrderID);
if (order.isPresent()) {
// TODO call action
System.out.println("Order is present\n");
public String storeOrder(@PathVariable("id") Long supplierOrderID, Model model, HttpServletResponse response) {
SupplierOrder order = supplierOrderRepository.findById(supplierOrderID).orElse(null);
if (order == null) {
model.addAttribute("error", "Die ausgewählte Lieferung konnte nicht gefunden werden.");
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
return listSuppliers(model);
}
if (order.wasDelivered()) {
model.addAttribute("error", "Die ausgewählte Lieferung wurde schon zugestellt.");
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
return listSuppliers(model);
}
return new RedirectView("../../supplierOrders/");
final Article article = articleRepository.findArticleByArticleOffer(order.ordered).orElse(null);
if (order == null) {
model.addAttribute("error", "Der bestellte Artikel wurde nicht angelegt, er hätte nicht bestellt werden dürfen.");
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
return listSuppliers(model);
}
// Hard to do efficiently, this should be fine.
List<WarehouseBookingPositionSlotEntry> candidates = slotRepository
.findAll()
.stream()
.map(slot ->
warehouseBookingPositionSlotEntryRepository.getBySlotNum(slot.slotNum).orElseGet(() ->
WarehouseBookingPositionSlotEntry.empty(article, slot)
)
)
.filter(entry -> entry.article.id == article.id)
.collect(Collectors.toList());
SupplierOrderArrivedAction action = new SupplierOrderArrivedAction(candidates, order, article);
try {
SupplierOrderArrivedAction.Result result = action.finish();
supplierOrderRepository.save(result.getOrder());
warehouseBookingRepository.save(result.getBooking());
} catch (SupplierOrderArrivedAction.NoSpaceInWarehouseException e) {
e.printStackTrace();
}
return "redirect:/intern/warehouse/todo";
}
public class UImodelSupplierOrder {
@ -66,11 +116,11 @@ public class SupplierOrderController {
public String priceTotal;
public boolean arrived;
public UImodelSupplierOrder(SupplierOrder order) {
public UImodelSupplierOrder(SupplierOrder order, Article article) {
this.id = order.id;
this.supplierName = order.supplier.name;
this.articleName = order.ordered.title;
this.articleId = order.ordered.id;
this.articleName = article != null ? article.title : "error";
this.articleId = article != null ? article.id : 0;
this.priceNet = String.format("%.2f", ((float) order.pricePerUnitNetCent / 100));
this.quantity = String.valueOf(order.numberOfUnits);
this.priceTotal = String.format("%.2f", ((float) order.totalPriceNet / 100));
@ -79,11 +129,7 @@ public class SupplierOrderController {
date.setTime(order.created.getTime());
this.dateOrder = new SimpleDateFormat("dd.MM.yyyy").format(date);
if (order.delivered != null) {
arrived = true;
} else {
arrived = false;
}
arrived = order.delivered != null;
}
}
}

View File

@ -16,7 +16,7 @@ public class Article {
@Basic
public long id;
@ManyToOne(optional = false)
@OneToOne(optional = false)
public ArticleOffer related;
public int shopPricePerUnitNetCent;

View File

@ -1,6 +1,7 @@
package org.hso.ecommerce.repos.shop;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.supplier.ArticleOffer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
@ -12,24 +13,35 @@ import java.util.Optional;
@Repository
public interface ArticleRepository extends JpaRepository<Article, Long> {
@Query("SELECT a FROM Article a WHERE a.id = :articleId")
Article findArticleById(@Param("articleId") long articleId);
/***
* use findById instead.
*/
@Deprecated
@Query("SELECT a FROM Article a WHERE a.id = :articleId")
Article findArticleById(@Param("articleId") long articleId);
@Query("SELECT a FROM Article a")
List<Article> findAll();
@Query("SELECT a FROM Article a")
List<Article> findAll();
@Query(value = "Select a.* from articles as a, article_offers as ao, warehouse_booking_position_entries as wbpe where a.related_id = ao.id and wbpe.article_id = a.id and ao.should_be_advertised = true group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
List<Article> getAdvertisedArticles();
@Query("SELECT a FROM CustomerOrderPosition cop JOIN cop.order co JOIN co.customer c JOIN cop.article a ORDER BY co.id DESC")
List<Article> getOrderedArticles();
@Query("SELECT a FROM CustomerOrderPosition cop JOIN cop.order co JOIN co.customer c JOIN cop.article a ORDER BY co.id DESC")
List<Article> getOrderedArticles();
@Query("SELECT a FROM CustomerOrderPosition cop JOIN cop.order co JOIN co.customer c JOIN cop.article a WHERE c.id = :customerId ORDER BY co.id DESC")
List<Article> getOrderedArticles(long customerId);
/***
* use type safe findArticleByArticleOffer instead.
*/
@Deprecated
@Query(value = "SELECT a.id FROM articles a WHERE a.related_id = :relatedId", nativeQuery = true)
Optional<Integer> findArticleIDByRelatedID(@Param("relatedId") long relatedId);
@Query(value = "SELECT a FROM Article a Where a.related = :related")
Optional<Article> findArticleByArticleOffer(ArticleOffer related);
@Query(value = "Select a.* from articles as a, warehouse_booking_position_entries as wbpe where wbpe.article_id = a.id and a.title LIKE %:term% group by wbpe.slot_id having max(wbpe.id) and wbpe.new_sum_slot != 0", nativeQuery = true)
List<Article> getArticlesByTermInTitle(String term);