public static Map<String, Object> decomposeInventoryItem(DispatchContext ctx, Map<String, ? extends Object> context) {
Map<String, Object> result = FastMap.newInstance();
Delegator delegator = ctx.getDelegator();
LocalDispatcher dispatcher = ctx.getDispatcher();
Timestamp now = UtilDateTime.nowTimestamp();
GenericValue userLogin = (GenericValue) context.get("userLogin");
Locale locale = (Locale) context.get("locale");
// Mandatory input fields
String inventoryItemId = (String)context.get("inventoryItemId");
BigDecimal quantity = (BigDecimal)context.get("quantity");
List<String> inventoryItemIds = FastList.newInstance();
try {
GenericValue inventoryItem = delegator.findByPrimaryKey("InventoryItem",
UtilMisc.toMap("inventoryItemId", inventoryItemId));
if (inventoryItem == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunCannotDecomposingInventoryItem", UtilMisc.toMap("inventoryItemId", inventoryItemId), locale));
}
// the work effort (disassemble order) is created
Map<String, Object> serviceContext = UtilMisc.<String, Object>toMap("workEffortTypeId", "TASK",
"workEffortPurposeTypeId", "WEPT_PRODUCTION_RUN",
"currentStatusId", "CAL_COMPLETED");
serviceContext.put("workEffortName", "Decomposing product [" + inventoryItem.getString("productId") + "] inventory item [" + inventoryItem.getString("inventoryItemId") + "]");
serviceContext.put("facilityId", inventoryItem.getString("facilityId"));
serviceContext.put("estimatedStartDate", now);
serviceContext.put("userLogin", userLogin);
Map<String, Object> resultService = dispatcher.runSync("createWorkEffort", serviceContext);
String workEffortId = (String)resultService.get("workEffortId");
// the inventory (marketing package) is issued
serviceContext.clear();
serviceContext = UtilMisc.toMap("inventoryItem", inventoryItem,
"workEffortId", workEffortId, "userLogin", userLogin);
if (quantity != null) {
serviceContext.put("quantity", quantity);
}
resultService = dispatcher.runSync("issueInventoryItemToWorkEffort", serviceContext);
BigDecimal issuedQuantity = (BigDecimal)resultService.get("quantityIssued");
if (issuedQuantity.compareTo(ZERO) == 0) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunCannotDecomposingInventoryItemNoMarketingPackagesFound", UtilMisc.toMap("inventoryItemId", inventoryItem.getString("inventoryItemId")), locale));
}
// get the package's unit cost to compute a cost coefficient ratio which is the marketing package's actual unit cost divided by its standard cost
// this ratio will be used to determine the cost of the marketing package components when they are returned to inventory
serviceContext.clear();
serviceContext = UtilMisc.toMap("productId", inventoryItem.getString("productId"),
"currencyUomId", inventoryItem.getString("currencyUomId"),
"costComponentTypePrefix", "EST_STD",
"userLogin", userLogin);
resultService = dispatcher.runSync("getProductCost", serviceContext);
BigDecimal packageCost = (BigDecimal)resultService.get("productCost");
BigDecimal inventoryItemCost = inventoryItem.getBigDecimal("unitCost");
BigDecimal costCoefficient = null;
if (packageCost == null || packageCost.compareTo(ZERO) == 0 || inventoryItemCost == null) {
// if the actual cost of the item (marketing package) that we are decomposing is not available, or
// if the standard cost of the marketing package is not available then
// the cost coefficient ratio is set to 1.0:
// this means that the unit costs of the inventory items of the components
// will be equal to the components' standard costs
costCoefficient = BigDecimal.ONE;
} else {
costCoefficient = inventoryItemCost.divide(packageCost, 10, rounding);
}
// the components are retrieved
serviceContext.clear();
serviceContext = UtilMisc.toMap("productId", inventoryItem.getString("productId"),
"quantity", issuedQuantity,
"userLogin", userLogin);
resultService = dispatcher.runSync("getManufacturingComponents", serviceContext);
List<Map<String, Object>> components = UtilGenerics.checkList(resultService.get("componentsMap"));
if (UtilValidate.isEmpty(components)) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunCannotDecomposingInventoryItemNoComponentsFound", UtilMisc.toMap("productId", inventoryItem.getString("productId")), locale));
}
for(Map<String, Object> component : components) {
// get the component's standard cost
serviceContext.clear();
serviceContext = UtilMisc.toMap("productId", ((GenericValue)component.get("product")).getString("productId"),
"currencyUomId", inventoryItem.getString("currencyUomId"),
"costComponentTypePrefix", "EST_STD",
"userLogin", userLogin);
resultService = dispatcher.runSync("getProductCost", serviceContext);
BigDecimal componentCost = (BigDecimal)resultService.get("productCost");
// return the component to inventory at its standard cost multiplied by the cost coefficient from above
BigDecimal componentInventoryItemCost = costCoefficient.multiply(componentCost);
serviceContext.clear();
serviceContext = UtilMisc.toMap("productId", ((GenericValue)component.get("product")).getString("productId"),
"quantity", component.get("quantity"),
"facilityId", inventoryItem.getString("facilityId"),
"unitCost", componentInventoryItemCost,
"userLogin", userLogin);
serviceContext.put("workEffortId", workEffortId);
resultService = dispatcher.runSync("productionRunTaskProduce", serviceContext);
List<String> newInventoryItemIds = UtilGenerics.checkList(resultService.get("inventoryItemIds"));