Implement Arrival of Supplier Order.
This commit is contained in:
parent
1590821f64
commit
56f4ec0dda
|
@ -1,7 +0,0 @@
|
||||||
package org.hso.ecommerce.action.warehouse;
|
|
||||||
|
|
||||||
public class StoreSupplierOrderAction {
|
|
||||||
|
|
||||||
//TODO add delivery date and warehouse booking
|
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
package org.hso.ecommerce.controller.intern.suppliers;
|
package org.hso.ecommerce.controller.intern.suppliers;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import org.hso.ecommerce.action.warehouse.SupplierOrderArrivedAction;
|
||||||
import java.util.ArrayList;
|
import org.hso.ecommerce.entities.shop.Article;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.hso.ecommerce.entities.supplier.SupplierOrder;
|
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.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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
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.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
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
|
@Controller
|
||||||
@RequestMapping("/intern/")
|
@RequestMapping("/intern/")
|
||||||
|
@ -24,13 +31,26 @@ public class SupplierOrderController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private final SupplierOrderRepository supplierOrderRepository = null;
|
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")
|
@GetMapping("supplierOrders")
|
||||||
public String listSuppliers(Model model) {
|
public String listSuppliers(Model model) {
|
||||||
|
|
||||||
List<UImodelSupplierOrder> totals = new ArrayList<UImodelSupplierOrder>();
|
List<UImodelSupplierOrder> totals = new ArrayList<UImodelSupplierOrder>();
|
||||||
|
|
||||||
for (SupplierOrder orders : supplierOrderRepository.findAll()) {
|
for (SupplierOrder order : supplierOrderRepository.findAll()) {
|
||||||
totals.add(new UImodelSupplierOrder(orders));
|
final Article article = articleRepository.findArticleByArticleOffer(order.ordered).orElse(null);
|
||||||
|
totals.add(new UImodelSupplierOrder(order, article));
|
||||||
}
|
}
|
||||||
|
|
||||||
model.addAttribute("orders", totals);
|
model.addAttribute("orders", totals);
|
||||||
|
@ -39,20 +59,50 @@ public class SupplierOrderController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/supplierOrders/store/{id}")
|
@PostMapping("/supplierOrders/store/{id}")
|
||||||
public RedirectView storeOrder(@PathVariable(required = true) String id) {
|
public String storeOrder(@PathVariable("id") Long supplierOrderID, Model model, HttpServletResponse response) {
|
||||||
|
SupplierOrder order = supplierOrderRepository.findById(supplierOrderID).orElse(null);
|
||||||
long supplierOrderID = Long.parseLong(id);
|
if (order == null) {
|
||||||
|
model.addAttribute("error", "Die ausgewählte Lieferung konnte nicht gefunden werden.");
|
||||||
Optional<SupplierOrder> order = supplierOrderRepository.findById(supplierOrderID);
|
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
||||||
|
return listSuppliers(model);
|
||||||
if (order.isPresent()) {
|
}
|
||||||
// TODO call action
|
if (order.wasDelivered()) {
|
||||||
|
model.addAttribute("error", "Die ausgewählte Lieferung wurde schon zugestellt.");
|
||||||
System.out.println("Order is present\n");
|
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 {
|
public class UImodelSupplierOrder {
|
||||||
|
@ -66,11 +116,11 @@ public class SupplierOrderController {
|
||||||
public String priceTotal;
|
public String priceTotal;
|
||||||
public boolean arrived;
|
public boolean arrived;
|
||||||
|
|
||||||
public UImodelSupplierOrder(SupplierOrder order) {
|
public UImodelSupplierOrder(SupplierOrder order, Article article) {
|
||||||
this.id = order.id;
|
this.id = order.id;
|
||||||
this.supplierName = order.supplier.name;
|
this.supplierName = order.supplier.name;
|
||||||
this.articleName = order.ordered.title;
|
this.articleName = article != null ? article.title : "error";
|
||||||
this.articleId = order.ordered.id;
|
this.articleId = article != null ? article.id : 0;
|
||||||
this.priceNet = String.format("%.2f", ((float) order.pricePerUnitNetCent / 100));
|
this.priceNet = String.format("%.2f", ((float) order.pricePerUnitNetCent / 100));
|
||||||
this.quantity = String.valueOf(order.numberOfUnits);
|
this.quantity = String.valueOf(order.numberOfUnits);
|
||||||
this.priceTotal = String.format("%.2f", ((float) order.totalPriceNet / 100));
|
this.priceTotal = String.format("%.2f", ((float) order.totalPriceNet / 100));
|
||||||
|
@ -79,11 +129,7 @@ public class SupplierOrderController {
|
||||||
date.setTime(order.created.getTime());
|
date.setTime(order.created.getTime());
|
||||||
this.dateOrder = new SimpleDateFormat("dd.MM.yyyy").format(date);
|
this.dateOrder = new SimpleDateFormat("dd.MM.yyyy").format(date);
|
||||||
|
|
||||||
if (order.delivered != null) {
|
arrived = order.delivered != null;
|
||||||
arrived = true;
|
|
||||||
} else {
|
|
||||||
arrived = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ public class Article {
|
||||||
@Basic
|
@Basic
|
||||||
public long id;
|
public long id;
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
@OneToOne(optional = false)
|
||||||
public ArticleOffer related;
|
public ArticleOffer related;
|
||||||
|
|
||||||
public int shopPricePerUnitNetCent;
|
public int shopPricePerUnitNetCent;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.hso.ecommerce.repos.shop;
|
package org.hso.ecommerce.repos.shop;
|
||||||
|
|
||||||
import org.hso.ecommerce.entities.shop.Article;
|
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.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
@ -12,24 +13,35 @@ import java.util.Optional;
|
||||||
@Repository
|
@Repository
|
||||||
public interface ArticleRepository extends JpaRepository<Article, Long> {
|
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")
|
@Query("SELECT a FROM Article a")
|
||||||
List<Article> findAll();
|
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)
|
@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();
|
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")
|
@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();
|
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")
|
@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);
|
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)
|
@Query(value = "SELECT a.id FROM articles a WHERE a.related_id = :relatedId", nativeQuery = true)
|
||||||
Optional<Integer> findArticleIDByRelatedID(@Param("relatedId") long relatedId);
|
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)
|
@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);
|
List<Article> getArticlesByTermInTitle(String term);
|
||||||
|
|
||||||
|
|
Reference in New Issue