in applications/manufacturing/src/main/java/org/apache/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java [185:443]
public static Map<String, Object> createProductionRun(DispatchContext ctx, Map<String, ? extends Object> context) {
Map<String, Object> result = new HashMap<>();
Delegator delegator = ctx.getDelegator();
LocalDispatcher dispatcher = ctx.getDispatcher();
Locale locale = (Locale) context.get("locale");
GenericValue userLogin = (GenericValue) context.get("userLogin");
// TODO: security management and finishing cleaning (ex copy from PartyServices.java)
// Mandatory input fields
String productId = (String) context.get("productId");
Timestamp startDate = (Timestamp) context.get("startDate");
BigDecimal pRQuantity = (BigDecimal) context.get("pRQuantity");
String facilityId = (String) context.get("facilityId");
// Optional input fields
String workEffortId = (String) context.get("routingId");
String workEffortName = (String) context.get("workEffortName");
String description = (String) context.get("description");
GenericValue routing = null;
GenericValue product = null;
List<GenericValue> routingTaskAssocs = null;
try {
// Find the product
product = EntityQuery.use(delegator).from("Product").where("productId", productId).queryOne();
if (product == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingProductNotExist", locale));
}
} catch (GenericEntityException e) {
Debug.logWarning(e.getMessage(), MODULE);
return ServiceUtil.returnError(e.getMessage());
}
// -------------------
// Routing and routing tasks
// -------------------
// Select the product's routing
try {
Map<String, Object> routingInMap = UtilMisc.toMap("productId", productId, "applicableDate", startDate, "userLogin", userLogin);
if (workEffortId != null) {
routingInMap.put("workEffortId", workEffortId);
}
Map<String, Object> routingOutMap = dispatcher.runSync("getProductRouting", routingInMap);
if (ServiceUtil.isError(routingOutMap)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(routingOutMap));
}
routing = (GenericValue) routingOutMap.get("routing");
routingTaskAssocs = UtilGenerics.cast(routingOutMap.get("tasks"));
} catch (GenericServiceException gse) {
Debug.logWarning(gse.getMessage(), MODULE);
}
if (routing == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingProductRoutingNotExist", locale));
}
if (UtilValidate.isEmpty(routingTaskAssocs)) {
return ServiceUtil.returnError(UtilProperties.getMessage(RESOURCE, "ManufacturingRoutingHasNoRoutingTask", locale));
}
// -------------------
// Components
// -------------------
// The components are retrieved using the getManufacturingComponents service
// (that performs a bom breakdown and if needed runs the configurator).
List<BOMNode> components = null;
Map<String, Object> serviceContext = new HashMap<>();
serviceContext.put("productId", productId); // the product that we want to manufacture
serviceContext.put("quantity", pRQuantity); // the quantity that we want to manufacture
serviceContext.put("userLogin", userLogin);
Map<String, Object> serviceResult = null;
try {
serviceResult = dispatcher.runSync("getManufacturingComponents", serviceContext);
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
components = UtilGenerics.cast(serviceResult.get("components")); // a list of objects representing the product's components
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the getManufacturingComponents service", MODULE);
return ServiceUtil.returnError(e.getMessage());
}
// ProductionRun header creation,
if (workEffortName == null) {
String prdName = UtilValidate.isNotEmpty(product.getString("productName")) ? product.getString("productName") : product.getString(
"productId");
String wefName = UtilValidate.isNotEmpty(routing.getString("workEffortName")) ? routing.getString("workEffortName")
: routing.getString("workEffortId");
workEffortName = prdName + "-" + wefName;
}
serviceContext.clear();
serviceContext.put("workEffortTypeId", "PROD_ORDER_HEADER");
serviceContext.put("workEffortPurposeTypeId", "WEPT_PRODUCTION_RUN");
serviceContext.put("currentStatusId", "PRUN_CREATED");
serviceContext.put("workEffortName", workEffortName);
serviceContext.put("description", description);
serviceContext.put("facilityId", facilityId);
serviceContext.put("estimatedStartDate", startDate);
serviceContext.put("quantityToProduce", pRQuantity);
serviceContext.put("userLogin", userLogin);
try {
serviceResult = dispatcher.runSync("createWorkEffort", serviceContext);
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the createWorkEffort service", MODULE);
return ServiceUtil.returnError(e.getMessage());
}
String productionRunId = (String) serviceResult.get("workEffortId");
if (Debug.infoOn()) {
Debug.logInfo("ProductionRun created: " + productionRunId, MODULE);
}
// ProductionRun, product will be produce creation = WorkEffortGoodStandard for the productId
serviceContext.clear();
serviceContext.put("workEffortId", productionRunId);
serviceContext.put("productId", productId);
serviceContext.put("workEffortGoodStdTypeId", "PRUN_PROD_DELIV");
serviceContext.put("statusId", "WEGS_CREATED");
serviceContext.put("estimatedQuantity", pRQuantity);
serviceContext.put("fromDate", startDate);
serviceContext.put("userLogin", userLogin);
try {
serviceResult = dispatcher.runSync("createWorkEffortGoodStandard", serviceContext);
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the createWorkEffortGoodStandard service", MODULE);
return ServiceUtil.returnError(e.getMessage());
}
// Multi creation (like clone) ProductionRunTask and GoodAssoc
boolean first = true;
for (GenericValue routingTaskAssoc : routingTaskAssocs) {
if (EntityUtil.isValueActive(routingTaskAssoc, startDate)) {
GenericValue routingTask = null;
try {
routingTask = routingTaskAssoc.getRelatedOne("ToWorkEffort", false);
} catch (GenericEntityException e) {
Debug.logError(e.getMessage(), MODULE);
}
// Calculate the estimatedCompletionDate
long totalTime = ProductionRun.getEstimatedTaskTime(routingTask, pRQuantity, dispatcher);
Timestamp endDate = TechDataServices.addForward(TechDataServices.getTechDataCalendar(routingTask), startDate, totalTime);
serviceContext.clear();
serviceContext.put("priority", routingTaskAssoc.get("sequenceNum"));
serviceContext.put("workEffortPurposeTypeId", "WEPT_PRODUCTION_RUN");
serviceContext.put("workEffortName", routingTask.get("workEffortName"));
serviceContext.put("description", routingTask.get("description"));
serviceContext.put("fixedAssetId", routingTask.get("fixedAssetId"));
serviceContext.put("workEffortTypeId", "PROD_ORDER_TASK");
serviceContext.put("currentStatusId", "PRUN_CREATED");
serviceContext.put("workEffortParentId", productionRunId);
serviceContext.put("facilityId", facilityId);
serviceContext.put("reservPersons", routingTask.get("reservPersons"));
serviceContext.put("estimatedStartDate", startDate);
serviceContext.put("estimatedCompletionDate", endDate);
serviceContext.put("estimatedSetupMillis", routingTask.get("estimatedSetupMillis"));
serviceContext.put("estimatedMilliSeconds", routingTask.get("estimatedMilliSeconds"));
serviceContext.put("quantityToProduce", pRQuantity);
serviceContext.put("userLogin", userLogin);
serviceResult = null;
try {
serviceResult = dispatcher.runSync("createWorkEffort", serviceContext);
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the createWorkEffort service", MODULE);
}
String productionRunTaskId = (String) serviceResult.get("workEffortId");
if (Debug.infoOn()) {
Debug.logInfo("ProductionRunTaskId created: " + productionRunTaskId, MODULE);
}
// The newly created production run task is associated to the routing task
// to keep track of the template used to generate it.
serviceContext.clear();
serviceContext.put("userLogin", userLogin);
serviceContext.put("workEffortIdFrom", routingTask.getString("workEffortId"));
serviceContext.put("workEffortIdTo", productionRunTaskId);
serviceContext.put("workEffortAssocTypeId", "WORK_EFF_TEMPLATE");
try {
serviceResult = dispatcher.runSync("createWorkEffortAssoc", serviceContext);
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the createWorkEffortAssoc service", MODULE);
}
// clone associated objects from the routing task to the run task
String routingTaskId = routingTaskAssoc.getString("workEffortIdTo");
try {
cloneWorkEffortPartyAssignments(ctx, userLogin, routingTaskId, productionRunTaskId);
cloneWorkEffortCostCalcs(ctx, userLogin, routingTaskId, productionRunTaskId);
} catch (GeneralException e) {
return ServiceUtil.returnError(e.getMessage());
}
// Now we iterate thru the components returned by the getManufacturingComponents service
// TODO: if in the BOM a routingWorkEffortId is specified, but the task is not in the routing
// the component is not added to the production run.
for (BOMNode node : components) {
// The components variable contains a list of BOMNodes:
// each node represents a product (component).
GenericValue productBom = node.getProductAssoc();
if ((productBom.getString("routingWorkEffortId") == null && first) || (productBom.getString("routingWorkEffortId") != null
&& productBom.getString("routingWorkEffortId").equals(routingTask.getString("workEffortId")))) {
serviceContext.clear();
serviceContext.put("workEffortId", productionRunTaskId);
// Here we get the ProductAssoc record from the BOMNode
// object to be sure to use the
// right component (possibly configured).
serviceContext.put("productId", node.getProduct().get("productId"));
serviceContext.put("workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED");
serviceContext.put("statusId", "WEGS_CREATED");
serviceContext.put("fromDate", productBom.get("fromDate"));
// Here we use the getQuantity method to get the quantity already
// computed by the getManufacturingComponents service
serviceContext.put("estimatedQuantity", node.getQuantity());
serviceContext.put("userLogin", userLogin);
serviceResult = null;
try {
serviceResult = dispatcher.runSync("createWorkEffortGoodStandard", serviceContext);
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the createWorkEffortGoodStandard service", MODULE);
}
if (Debug.infoOn()) {
Debug.logInfo("ProductLink created for productId: " + productBom.getString("productIdTo"), MODULE);
}
}
}
first = false;
startDate = endDate;
}
}
// update the estimatedCompletionDate field for the productionRun
serviceContext.clear();
serviceContext.put("workEffortId", productionRunId);
serviceContext.put("estimatedCompletionDate", startDate);
serviceContext.put("userLogin", userLogin);
serviceResult = null;
try {
serviceResult = dispatcher.runSync("updateWorkEffort", serviceContext);
if (ServiceUtil.isError(serviceResult)) {
return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult));
}
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the updateWorkEffort service", MODULE);
}
result.put("productionRunId", productionRunId);
result.put("estimatedCompletionDate", startDate);
result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(RESOURCE, "ManufacturingProductionRunCreated", UtilMisc.toMap(
"productionRunId", productionRunId), locale));
return result;
}