public static Map<String, Object> createProductionRunForMktgPkg(DispatchContext ctx, Map<String, ? extends Object> context) {
Map<String, Object> result = FastMap.newInstance();
Delegator delegator = ctx.getDelegator();
LocalDispatcher dispatcher = ctx.getDispatcher();
Locale locale = (Locale) context.get("locale");
GenericValue userLogin = (GenericValue) context.get("userLogin");
// Mandatory input fields
String facilityId = (String)context.get("facilityId");
String orderId = (String)context.get("orderId");
String orderItemSeqId = (String)context.get("orderItemSeqId");
// Check if the order is to be immediately fulfilled, in which case the inventory
// hasn't been reserved and ATP not yet decreased
boolean isImmediatelyFulfilled = false;
try {
GenericValue order = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
GenericValue productStore = delegator.getRelatedOne("ProductStore", order);
isImmediatelyFulfilled = "Y".equals(productStore.getString("isImmediatelyFulfilled"));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunForMarketingPackagesCreationError", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "errorString", e.getMessage()), locale));
}
GenericValue orderItem = null;
try {
orderItem = delegator.findByPrimaryKey("OrderItem", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunForMarketingPackagesCreationError", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "errorString", e.getMessage()), locale));
}
if (orderItem == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunForMarketingPackagesOrderItemNotFound", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId), locale));
}
if (orderItem.get("quantity") == null) {
Debug.logWarning("No quantity found for orderItem [" + orderItem +"], skipping production run of this marketing package", module);
return ServiceUtil.returnSuccess();
}
try {
// first figure out how much of this product we already have in stock (ATP)
BigDecimal existingAtp = BigDecimal.ZERO;
Map<String, Object> tmpResults = dispatcher.runSync("getInventoryAvailableByFacility",
UtilMisc.<String, Object>toMap("productId", orderItem.getString("productId"),
"facilityId", facilityId, "userLogin", userLogin));
if (tmpResults.get("availableToPromiseTotal") != null) {
existingAtp = (BigDecimal) tmpResults.get("availableToPromiseTotal");
}
// if the order is immediately fulfilled, adjust the atp to compensate for it not reserved
if (isImmediatelyFulfilled) {
existingAtp = existingAtp.subtract(orderItem.getBigDecimal("quantity"));
}
if (Debug.verboseOn()) { Debug.logVerbose("Order item [" + orderItem + "] Existing ATP = [" + existingAtp + "]", module); }
// we only need to produce more marketing packages if there isn't enough in stock.
if (existingAtp.compareTo(ZERO) < 0) {
// how many should we produce? If there already is some inventory, then just produce enough to bring ATP back up to zero.
BigDecimal qtyRequired = BigDecimal.ZERO.subtract(existingAtp);
// ok so that's how many we WANT to produce, but let's check how many we can actually produce based on the available components
Map<String, Object> serviceContext = FastMap.newInstance();
serviceContext.put("productId", orderItem.getString("productId"));
serviceContext.put("facilityId", facilityId);
serviceContext.put("userLogin", userLogin);
Map<String, Object> resultService = dispatcher.runSync("getMktgPackagesAvailable", serviceContext);
BigDecimal mktgPackagesAvailable = (BigDecimal) resultService.get("availableToPromiseTotal");
BigDecimal qtyToProduce = qtyRequired.min(mktgPackagesAvailable);
if (qtyToProduce.compareTo(ZERO) > 0) {
if (Debug.verboseOn()) { Debug.logVerbose("Required quantity (all orders) = [" + qtyRequired + "] quantity to produce = [" + qtyToProduce + "]", module); }
serviceContext.put("pRQuantity", qtyToProduce);
serviceContext.put("startDate", UtilDateTime.nowTimestamp());
//serviceContext.put("workEffortName", "");
resultService = dispatcher.runSync("createProductionRun", serviceContext);
String productionRunId = (String)resultService.get("productionRunId");
result.put("productionRunId", productionRunId);
try {
delegator.create("WorkOrderItemFulfillment", UtilMisc.toMap("workEffortId", productionRunId, "orderId", orderId, "orderItemSeqId", orderItemSeqId));
} catch (GenericEntityException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunForMarketingPackagesCreationError", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId, "errorString", e.getMessage()), locale));
}
try {
serviceContext.clear();
serviceContext.put("productionRunId", productionRunId);
serviceContext.put("statusId", "PRUN_COMPLETED");
serviceContext.put("userLogin", userLogin);
resultService = dispatcher.runSync("quickChangeProductionRunStatus", serviceContext);
serviceContext.clear();
serviceContext.put("workEffortId", productionRunId);
serviceContext.put("userLogin", userLogin);
resultService = dispatcher.runSync("productionRunProduce", serviceContext);
} catch (GenericServiceException e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotCreated", locale));
}
result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunCreated", UtilMisc.toMap("productionRunId", productionRunId), locale));
return result;
} else {
if (Debug.verboseOn()) { Debug.logVerbose("There are not enough components available to produce any marketing packages [" + orderItem.getString("productId") + "]", module); }
return ServiceUtil.returnSuccess();
}
} else {
if (Debug.verboseOn()) { Debug.logVerbose("No marketing packages need to be produced - ATP is [" + existingAtp + "]", module); }
return ServiceUtil.returnSuccess();