return result;
}
public static Map<String, Object> changeProductionRunTaskStatus(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");
String productionRunId = (String) context.get("productionRunId");
String taskId = (String) context.get("workEffortId");
String statusId = (String) context.get("statusId");
Boolean issueAllComponents = (Boolean) context.get("issueAllComponents");
if (issueAllComponents == null) {
issueAllComponents = Boolean.FALSE;
}
ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
if (!productionRun.exist()) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunNotExists", locale));
}
List<GenericValue> tasks = productionRun.getProductionRunRoutingTasks();
GenericValue theTask = null;
GenericValue oneTask = null;
boolean allTaskCompleted = true;
boolean allPrecTaskCompletedOrRunning = true;
for (int i = 0; i < tasks.size(); i++) {
oneTask = tasks.get(i);
if (oneTask.getString("workEffortId").equals(taskId)) {
theTask = oneTask;
} else {
if (theTask == null && allPrecTaskCompletedOrRunning && (!oneTask.getString("currentStatusId").equals("PRUN_COMPLETED") && !oneTask.getString("currentStatusId").equals("PRUN_RUNNING"))) {
allPrecTaskCompletedOrRunning = false;
}
if (allTaskCompleted && !oneTask.getString("currentStatusId").equals("PRUN_COMPLETED")) {
allTaskCompleted = false;
}
}
}
if (theTask == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskNotExists", locale));
}
String currentStatusId = theTask.getString("currentStatusId");
String oldStatusId = theTask.getString("currentStatusId"); // pass back old status for secas to check
if (statusId != null && currentStatusId.equals(statusId)) {
result.put("oldStatusId", oldStatusId);
result.put("newStatusId", currentStatusId);
result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskStatusChanged",UtilMisc.toMap("newStatusId", currentStatusId), locale));
return result;
}
// PRUN_CREATED or PRUN_SCHEDULED or PRUN_DOC_PRINTED --> PRUN_RUNNING
// this should be called only when the first task is started
if ((currentStatusId.equals("PRUN_CREATED") || currentStatusId.equals("PRUN_SCHEDULED") || currentStatusId.equals("PRUN_DOC_PRINTED")) && (statusId == null || statusId.equals("PRUN_RUNNING"))) {
// change the production run task status to PRUN_RUNNING
// if necessary change the production run (header) status to PRUN_RUNNING
if (!allPrecTaskCompletedOrRunning) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskCannotStartPrevTasksNotCompleted", locale));
}
if (productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_CREATED")) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunTaskCannotStartDocsNotPrinted", locale));
}
Map<String, Object> serviceContext = FastMap.newInstance();
serviceContext.clear();
serviceContext.put("workEffortId", taskId);
serviceContext.put("currentStatusId", "PRUN_RUNNING");
serviceContext.put("actualStartDate", UtilDateTime.nowTimestamp());
serviceContext.put("userLogin", userLogin);
try {
dispatcher.runSync("updateWorkEffort", serviceContext);
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the updateWorkEffort service", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
}
if (!productionRun.getGenericValue().getString("currentStatusId").equals("PRUN_RUNNING")) {
serviceContext.clear();
serviceContext.put("productionRunId", productionRunId);
serviceContext.put("statusId", "PRUN_RUNNING");
serviceContext.put("userLogin", userLogin);
try {
dispatcher.runSync("changeProductionRunStatus", serviceContext);
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the changeProductionRunStatus service", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
}
}
result.put("oldStatusId", oldStatusId);
result.put("newStatusId", "PRUN_RUNNING");
result.put(ModelService.SUCCESS_MESSAGE, UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", "PRUN_DOC_PRINTED"), locale));
return result;
}
// PRUN_RUNNING --> PRUN_COMPLETED
// this should be called only when the last task is completed
if (currentStatusId.equals("PRUN_RUNNING") && (statusId == null || statusId.equals("PRUN_COMPLETED"))) {
Map<String, Object> serviceContext = FastMap.newInstance();
if (issueAllComponents.booleanValue()) {
// Issue all the components, if this task needs components and they still need to be issued
try {
List<GenericValue> inventoryAssigned = delegator.findByAnd("WorkEffortInventoryAssign", UtilMisc.toMap("workEffortId", taskId));
if (UtilValidate.isEmpty(inventoryAssigned)) {
serviceContext.clear();
serviceContext.put("workEffortId", taskId);
serviceContext.put("userLogin", userLogin);
dispatcher.runSync("issueProductionRunTask", serviceContext);
}
} catch (Exception e) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
}
}
// change only the production run task status to PRUN_COMPLETED
serviceContext.clear();
serviceContext.put("workEffortId", taskId);
serviceContext.put("currentStatusId", "PRUN_COMPLETED");
serviceContext.put("actualCompletionDate", UtilDateTime.nowTimestamp());
BigDecimal quantityToProduce = theTask.getBigDecimal("quantityToProduce");
if (quantityToProduce == null) {
quantityToProduce = BigDecimal.ZERO;
}
BigDecimal quantityProduced = theTask.getBigDecimal("quantityProduced");
if (quantityProduced == null) {
quantityProduced = BigDecimal.ZERO;
}
BigDecimal quantityRejected = theTask.getBigDecimal("quantityRejected");
if (quantityRejected == null) {
quantityRejected = BigDecimal.ZERO;
}
BigDecimal totalQuantity = quantityProduced.add(quantityRejected);
BigDecimal diffQuantity = quantityToProduce.subtract(totalQuantity);
if (diffQuantity.compareTo(BigDecimal.ZERO) > 0) {
quantityProduced = quantityProduced.add(diffQuantity);
}
serviceContext.put("quantityProduced", quantityProduced);
if (theTask.get("actualSetupMillis") == null) {
serviceContext.put("actualSetupMillis", theTask.get("estimatedSetupMillis"));
}
if (theTask.get("actualMilliSeconds") == null) {
Double autoMillis = null;
if (theTask.get("estimatedMilliSeconds") != null) {
autoMillis = Double.valueOf(quantityProduced.doubleValue() * theTask.getDouble("estimatedMilliSeconds"));
}
serviceContext.put("actualMilliSeconds", autoMillis);
}
serviceContext.put("userLogin", userLogin);
try {
dispatcher.runSync("updateWorkEffort", serviceContext);
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the updateWorkEffort service", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
}
// Calculate and store the production run task actual costs
serviceContext.clear();
serviceContext.put("productionRunTaskId", taskId);
serviceContext.put("userLogin", userLogin);
try {
dispatcher.runSync("createProductionRunTaskCosts", serviceContext);
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the createProductionRunTaskCosts service", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
}
// If this is the last task, then the production run is marked as 'completed'
if (allTaskCompleted) {
serviceContext.clear();
serviceContext.put("productionRunId", productionRunId);
serviceContext.put("statusId", "PRUN_COMPLETED");
serviceContext.put("userLogin", userLogin);
try {
dispatcher.runSync("changeProductionRunStatus", serviceContext);
} catch (GenericServiceException e) {
Debug.logError(e, "Problem calling the updateWorkEffort service", module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunStatusNotChanged", locale));
}
// and compute the overhead costs associated to the finished product
try {
// get the currency
GenericValue facility = productionRun.getGenericValue().getRelatedOne("Facility");
Map<String, Object> outputMap = dispatcher.runSync("getPartyAccountingPreferences",
UtilMisc.<String, Object>toMap("userLogin", userLogin,
"organizationPartyId", facility.getString("ownerPartyId")));
GenericValue partyAccountingPreference = (GenericValue)outputMap.get("partyAccountingPreference");
if (partyAccountingPreference == null) {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ManufacturingProductionRunUnableToFindCosts", locale));
}
outputMap = dispatcher.runSync("getProductionRunCost", UtilMisc.<String, Object>toMap("userLogin", userLogin, "workEffortId", productionRunId));
BigDecimal totalCost = (BigDecimal)outputMap.get("totalCost");
if (totalCost == null) {
totalCost = ZERO;
}
List<GenericValue> productCostComponentCalcs = delegator.findByAnd("ProductCostComponentCalc",
UtilMisc.toMap("productId", productionRun.getProductProduced().getString("productId")),
UtilMisc.toList("sequenceNum"));
for (int i = 0; i < productCostComponentCalcs.size(); i++) {
GenericValue productCostComponentCalc = productCostComponentCalcs.get(i);
GenericValue costComponentCalc = productCostComponentCalc.getRelatedOne("CostComponentCalc");