2020-05-05 22:56:12 +02:00
package org.hso.ecommerce.action.shop ;
import org.hso.ecommerce.action.booking.CreateBookingAction ;
import org.hso.ecommerce.entities.booking.* ;
import org.hso.ecommerce.entities.shop.Address ;
import org.hso.ecommerce.entities.shop.Article ;
import org.hso.ecommerce.entities.shop.CustomerOrder ;
import org.hso.ecommerce.entities.shop.CustomerOrderPosition ;
import org.hso.ecommerce.entities.user.User ;
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 CreateOrderAction {
private User user ;
Address destination ;
private int expectedTotalGrossCent ;
private int totalNetCent ;
private int totalVatCent ;
private PaymentMethod method ;
private BookingAccountEntry latestUserBooking ;
private BookingAccountEntry latestVatBooking ;
private BookingAccountEntry latestMainBooking ;
private List < OrderItem > orderItems = new ArrayList < > ( ) ;
public CreateOrderAction (
User user ,
int expectedTotalGrossCent ,
Address destination ,
PaymentMethod method ,
BookingAccountEntry latestUserBooking ,
BookingAccountEntry latestVatBooking ,
BookingAccountEntry latestMainBooking
) {
this . user = user ;
this . expectedTotalGrossCent = expectedTotalGrossCent ;
this . destination = destination ;
this . method = method ;
this . latestUserBooking = latestUserBooking ;
assert latestUserBooking . userAccount . id = = user . id ;
this . latestVatBooking = latestVatBooking ;
assert latestVatBooking . isVATAccount ;
this . latestMainBooking = latestMainBooking ;
assert latestMainBooking . isMainAccount ;
}
public void addArticle ( Article article , int quantity , List < WarehouseBookingPositionSlotEntry > availableSlots ) {
for ( WarehouseBookingPositionSlotEntry slot : availableSlots ) {
assert slot . article . id = = article . id ;
}
orderItems . add ( new OrderItem ( article , availableSlots , quantity ) ) ;
totalNetCent + = article . shopPricePerUnitNetCent * quantity ;
totalVatCent + = article . getVat ( ) * quantity ;
}
2020-05-10 14:29:08 +02:00
public Result finish ( ) throws ArticleNotInStockException {
2020-05-05 22:56:12 +02:00
CustomerOrder order = createOrder ( ) ;
CustomerPayment payment = createPayment ( ) ;
List < Booking > bookingList = new ArrayList < > ( ) ;
2020-06-13 11:10:20 +02:00
Booking purchaseBooking = new CreateBookingAction (
latestUserBooking , latestMainBooking , new BookingReason ( order ) , order . totalGrossCent ) . finish ( ) ;
Booking paymentBooking = new CreateBookingAction (
null , purchaseBooking . source /* userAccount */ , new BookingReason ( payment ) , order . totalGrossCent ) . finish ( ) ;
Booking vatBooking = new CreateBookingAction (
purchaseBooking . destination /* mainAccount */ , latestVatBooking , new BookingReason ( order ) , order . totalVatCent ) . finish ( ) ;
bookingList . add ( purchaseBooking ) ;
bookingList . add ( paymentBooking ) ;
bookingList . add ( vatBooking ) ;
2020-05-05 22:56:12 +02:00
WarehouseBooking warehouseBooking = createWarehouseBooking ( order ) ;
return new Result (
order ,
warehouseBooking ,
bookingList
) ;
}
2020-05-10 14:29:08 +02:00
private WarehouseBooking createWarehouseBooking ( CustomerOrder order ) throws ArticleNotInStockException {
2020-05-05 22:56:12 +02:00
WarehouseBooking booking = new WarehouseBooking ( ) ;
booking . created = new Timestamp ( new Date ( ) . getTime ( ) ) ;
booking . reason = new BookingReason ( order ) ;
for ( OrderItem item : orderItems ) {
int needed = item . quantity ;
for ( WarehouseBookingPositionSlotEntry slot : item . availableSlots ) {
int remove = Math . min ( slot . newSumSlot , needed ) ;
needed - = remove ;
WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition ( ) ;
bookingPosition . article = item . article ;
bookingPosition . amount = - remove ;
2020-06-12 19:48:21 +02:00
bookingPosition . slotEntry = slot . copyAddAmount ( - remove , item . article ) ;
2020-05-05 22:56:12 +02:00
bookingPosition . booking = booking ;
booking . positions . add ( bookingPosition ) ;
if ( needed = = 0 ) {
break ;
}
}
2020-05-10 14:29:08 +02:00
if ( needed > 0 ) {
throw new ArticleNotInStockException ( item . article ) ;
}
2020-05-05 22:56:12 +02:00
}
return booking ;
}
private CustomerPayment createPayment ( ) {
CustomerPayment payment = new CustomerPayment ( ) ;
payment . amountCent = totalNetCent + totalVatCent ;
payment . payment = method ;
return payment ;
}
private CustomerOrder createOrder ( ) {
assert totalNetCent + totalVatCent = = expectedTotalGrossCent ;
CustomerOrder customerOrder = new CustomerOrder ( ) ;
customerOrder . customer = user ;
customerOrder . destination = destination ;
for ( OrderItem item : orderItems ) {
CustomerOrderPosition position = new CustomerOrderPosition ( ) ;
position . article = item . article ;
position . pricePerUnit = item . article . shopPricePerUnitNetCent ;
position . quantity = item . quantity ;
position . order = customerOrder ;
customerOrder . positions . add ( position ) ;
}
customerOrder . created = new Timestamp ( new Date ( ) . getTime ( ) ) ;
customerOrder . totalNetCent = totalNetCent ;
customerOrder . totalVatCent = totalVatCent ;
customerOrder . totalGrossCent = totalNetCent + totalVatCent ;
return customerOrder ;
}
public static class Result {
public final CustomerOrder customerOrder ;
public final WarehouseBooking warehouseBooking ;
public final List < Booking > bookings ;
Result ( CustomerOrder customerOrder , WarehouseBooking warehouseBooking , List < Booking > bookings ) {
this . customerOrder = customerOrder ;
this . warehouseBooking = warehouseBooking ;
this . bookings = bookings ;
}
}
private static class OrderItem {
List < WarehouseBookingPositionSlotEntry > availableSlots ;
int quantity ;
Article article ;
public OrderItem ( Article article , List < WarehouseBookingPositionSlotEntry > availableSlots , int quantity ) {
this . article = article ;
this . availableSlots = availableSlots ;
this . quantity = quantity ;
}
}
2020-05-10 14:29:08 +02:00
public static class ArticleNotInStockException extends Exception {
private Article article ;
public ArticleNotInStockException ( Article article ) {
super ( " The quantity of article ' " + article . title + " ' is not in stock. " ) ;
this . article = article ;
}
public Article getArticle ( ) {
return article ;
}
}
2020-05-05 22:56:12 +02:00
}