107 lines
4.0 KiB
Java
107 lines
4.0 KiB
Java
package org.hso.ecommerce.supplier;
|
|
|
|
import org.hso.ecommerce.supplier.carrier.Avian;
|
|
import org.hso.ecommerce.supplier.carrier.Carrier;
|
|
import org.hso.ecommerce.supplier.carrier.Posaidon;
|
|
import org.hso.ecommerce.supplier.carrier.Shredder;
|
|
import org.hso.ecommerce.supplier.data.Article;
|
|
import org.hso.ecommerce.supplier.data.Order;
|
|
import org.hso.ecommerce.supplier.data.OrderConfirmation;
|
|
import org.hso.ecommerce.supplier.data.Supplier;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import javax.annotation.PostConstruct;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import java.io.IOException;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
|
|
@RestController
|
|
public class RequestController {
|
|
|
|
private final HashMap<String, Integer> dailySalesVolumeCent = new HashMap<>();
|
|
private final HashMap<String, Supplier> knownSuppliers = new HashMap<>();
|
|
private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
|
private final Carrier[] carriers = new Carrier[]{
|
|
new Avian(), new Posaidon(), new Shredder()
|
|
};
|
|
|
|
@PostConstruct
|
|
public void init() throws IOException {
|
|
for (Supplier s : ConfigurationReader.read()) {
|
|
knownSuppliers.put(s.id, s);
|
|
}
|
|
}
|
|
|
|
|
|
@GetMapping("/")
|
|
public List<Supplier> index() {
|
|
return new ArrayList<>(knownSuppliers.values());
|
|
}
|
|
|
|
@GetMapping("/{supplier}/")
|
|
public Supplier supplier(HttpServletResponse res, @PathVariable("supplier") String supplierName) {
|
|
Supplier s = knownSuppliers.get(supplierName);
|
|
if (s == null) {
|
|
res.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
@PostMapping("/{supplier}/order")
|
|
public OrderConfirmation order(HttpServletResponse res, @PathVariable("supplier") String supplierName, @RequestBody Order order) {
|
|
Supplier s = knownSuppliers.get(supplierName);
|
|
if (s == null) {
|
|
res.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
|
return null;
|
|
}
|
|
|
|
String dateKey = simpleDateFormat.format(new Date());
|
|
int dailyVolume = dailySalesVolumeCent.getOrDefault(dateKey, 0);
|
|
|
|
Article a = s.findArticle(order.manufacturer, order.articleNumber);
|
|
if (a == null) {
|
|
res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
|
return null;
|
|
}
|
|
|
|
int priceNet = a.pricePerUnitNet * order.quantity;
|
|
int discountableNetAmount = 0;
|
|
if (dailyVolume >= s.discount.minimumDailySalesVolumeNetCent) {
|
|
// grant discount on the full price
|
|
discountableNetAmount = priceNet;
|
|
} else if (dailyVolume + priceNet > s.discount.minimumDailySalesVolumeNetCent) {
|
|
// grant partial discount
|
|
discountableNetAmount = dailyVolume + priceNet - s.discount.minimumDailySalesVolumeNetCent;
|
|
}
|
|
int discount = (discountableNetAmount * s.discount.percentDiscount) / 100;
|
|
|
|
Carrier selectedCarrier = carriers[Math.abs((supplierName + java.time.LocalDate.now()).hashCode()) % carriers.length];
|
|
|
|
OrderConfirmation confirmation = new OrderConfirmation();
|
|
confirmation.articleNumber = order.articleNumber;
|
|
confirmation.discountNetCent = discount;
|
|
confirmation.pricePerUnitNetCent = a.pricePerUnitNet;
|
|
confirmation.manufacturer = a.manufacturer;
|
|
confirmation.quantity = order.quantity;
|
|
confirmation.totalPriceNetCharged = priceNet - discount;
|
|
confirmation.carrier = selectedCarrier.getName();
|
|
confirmation.trackingId = selectedCarrier.generateTrackingId();
|
|
confirmation.estimatedArrival = selectedCarrier.arrivalEstimate();
|
|
|
|
if (confirmation.totalPriceNetCharged > order.maxTotalPriceCentNet) {
|
|
res.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
|
|
return null;
|
|
}
|
|
|
|
dailyVolume += confirmation.totalPriceNetCharged;
|
|
dailySalesVolumeCent.put(dateKey, dailyVolume);
|
|
|
|
return confirmation;
|
|
}
|
|
}
|