Implement Arrival of Supplier Order. #62
@ -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;
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ public class Article {
 | 
			
		||||
    @Basic
 | 
			
		||||
    public long id;
 | 
			
		||||
 | 
			
		||||
    @ManyToOne(optional = false)
 | 
			
		||||
    @OneToOne(optional = false)
 | 
			
		||||
    public ArticleOffer related;
 | 
			
		||||
 | 
			
		||||
    public int shopPricePerUnitNetCent;
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user
	
In Zeile 64 gibt es doch schon ein
if (order == null)mit einem return. Hab ich da was übersehen oder wird die Abfrage nie erfüllt?