blob: 831226e6671745d75823315c54306a0295fa3174 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// The only required parameter is "productionRunId".
// The "actionForm" parameter triggers actions (see "ProductionRunSimpleEvents.xml").
import org.ofbiz.entity.util.EntityUtil;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.widget.html.HtmlFormWrapper;
import org.ofbiz.manufacturing.jobshopmgt.ProductionRun;
import javolution.util.FastList;
productionRunId = parameters.productionRunId ?: parameters.workEffortId;
if (productionRunId) {
ProductionRun productionRun = new ProductionRun(productionRunId, delegator, dispatcher);
if (productionRun.exist()){
productionRunId = productionRun.getGenericValue().workEffortId;
context.productionRunId = productionRunId;
context.productionRun = productionRun.getGenericValue();
// Find all the order items to which this production run is linked.
orderItems = delegator.findByAnd("WorkOrderItemFulfillment", [workEffortId : productionRunId]);
if (orderItems) {
context.orderItems = orderItems;
}
// Find all the work efforts that must be completed before this one.
mandatoryWorkEfforts = EntityUtil.filterByDate(delegator.findByAnd("WorkEffortAssoc", [workEffortIdTo : productionRunId, workEffortAssocTypeId : "WORK_EFF_PRECEDENCY"]));
if (mandatoryWorkEfforts) {
context.mandatoryWorkEfforts = mandatoryWorkEfforts;
}
// Find all the work efforts that can start after this one.
dependentWorkEfforts = EntityUtil.filterByDate(delegator.findByAnd("WorkEffortAssoc", [workEffortIdFrom : productionRunId, workEffortAssocTypeId : "WORK_EFF_PRECEDENCY"]));
if (dependentWorkEfforts) {
context.dependentWorkEfforts = dependentWorkEfforts;
}
quantityToProduce = productionRun.getGenericValue().get("quantityToProduce") ?: 0.0;
// Find the inventory items produced
inventoryItems = delegator.findByAnd("WorkEffortInventoryProduced", [workEffortId : productionRunId]);
context.inventoryItems = inventoryItems;
if (inventoryItems) {
lastWorkEffortInventoryProduced = (GenericValue)inventoryItems.get(inventoryItems.size() - 1);
lastInventoryItem = lastWorkEffortInventoryProduced.getRelatedOne("InventoryItem");
context.lastLotId = lastInventoryItem.lotId;
}
// Find if the production run can produce inventory.
quantityProduced = productionRun.getGenericValue().quantityProduced ?: 0.0;
quantityRejected = productionRun.getGenericValue().quantityRejected ?: 0.0;
lastTask = productionRun.getLastProductionRunRoutingTask();
quantityDeclared = (lastTask ? (lastTask.quantityProduced ?: 0.0) : 0.0 ;
if (lastTask && ("PRUN_RUNNING".equals(lastTask.currentStatusId) || "PRUN_COMPLETED".equals(lastTask.currentStatusId))) {
context.canDeclareAndProduce = "Y";
}
maxQuantity = quantityDeclared - quantityProduced;
productionRunData = [:];
productionRunData.workEffortId = productionRunId;
productionRunData.productId = productionRun.getProductProduced().productId;
if (maxQuantity > 0 && !"WIP".equals(productionRun.getProductProduced().productTypeId)) {
productionRunData.quantity = maxQuantity;
context.canProduce = "Y";
}
productionRunData.quantityToProduce = quantityToProduce;
productionRunData.quantityProduced = quantityProduced;
productionRunData.quantityRejected = quantityRejected;
productionRunData.quantityRemaining = quantityToProduce - quantityProduced;
productionRunData.estimatedCompletionDate = productionRun.getEstimatedCompletionDate();
productionRunData.productionRunName = productionRun.getProductionRunName();
productionRunData.description = productionRun.getDescription();
productionRunData.estimatedStartDate = productionRun.getEstimatedStartDate();
productionRunData.actualStartDate = productionRun.getGenericValue().getTimestamp("actualStartDate");
productionRunData.actualCompletionDate = productionRun.getGenericValue().getTimestamp("actualCompletionDate");
productionRunData.currentStatusId = productionRun.getGenericValue().currentStatusId;
context.productionRunData = productionRunData;
actionForm = parameters.actionForm ?: "beforeActionProductionRun";
context.actionForm = actionForm;
//---------------
// Routing tasks
//---------------
// routingTask update sub-screen
routingTaskId = parameters.routingTaskId;
if (routingTaskId && (actionForm.equals("UpdateRoutingTask") || actionForm.equals("EditRoutingTask"))){
routingTask = delegator.findByPrimaryKey("WorkEffort", [workEffortId : routingTaskId]);
Map routingTaskData = routingTask.getAllFields();
routingTaskData.estimatedSetupMillis = routingTask.getDouble("estimatedSetupMillis");
routingTaskData.estimatedMilliSeconds = routingTask.getDouble("estimatedMilliSeconds");
HtmlFormWrapper editPrRoutingTaskWrapper = new HtmlFormWrapper("component://manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml", "EditProductionRunDeclRoutingTask", request, response);
editPrRoutingTaskWrapper.putInContext("routingTaskData", routingTaskData);
editPrRoutingTaskWrapper.putInContext("actionForm", "UpdateRoutingTask");
routingTaskData.partyId = userLogin.partyId;
context.editPrRoutingTaskWrapper = editPrRoutingTaskWrapper;
context.routingTaskId = routingTaskId;
// Get the list of deliverable products, i.e. the WorkEffortGoodStandard entries
// with workEffortGoodStdTypeId = "PRUNT_PROD_DELIV":
// first of all we get the template task (the routing task)
templateTaskAssoc = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("WorkEffortAssoc", [workEffortIdTo : routingTask.workEffortId, workEffortAssocTypeId : "WORK_EFF_TEMPLATE"])));
templateTask = [:];
if (templateTaskAssoc) {
templateTask = templateTaskAssoc.getRelatedOne("FromWorkEffort");
}
delivProducts = [];
if (templateTask) {
delivProducts = EntityUtil.filterByDate(templateTask.getRelatedByAnd("WorkEffortGoodStandard", [workEffortGoodStdTypeId : "PRUNT_PROD_DELIV"]));
}
HtmlFormWrapper createRoutingTaskDelivProductForm = new HtmlFormWrapper("component://manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml", "CreateRoutingTaskDelivProduct", request, response);
createRoutingTaskDelivProductForm.putInContext("formData", [productionRunId : productionRunId, workEffortId : routingTaskId]);
context.createRoutingTaskDelivProductForm = createRoutingTaskDelivProductForm;
context.delivProducts = delivProducts;
// Get the list of delivered products, i.e. inventory items
prunInventoryProduced = delegator.findByAnd("WorkEffortAndInventoryProduced", [workEffortId : routingTaskId]);
context.prunInventoryProduced = prunInventoryProduced;
HtmlFormWrapper prunInventoryProducedForm = new HtmlFormWrapper("component://manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml", "ProductionRunTaskInventoryProducedList", request, response);
prunInventoryProducedForm.putInContext("prunInventoryProduced", prunInventoryProduced);
context.prunInventoryProducedForm = prunInventoryProducedForm;
}
// RoutingTasks list
List productionRunRoutingTasks = productionRun.getProductionRunRoutingTasks();
String startTaskId = null; // which production run task is ready to start and has the [Start] buton next to it
String issueTaskId = null; // which production run task is ready to have products issued with [Issue Components] button
String completeTaskId = null; // which task has the [Complete] button next to it
productionRunRoutingTasks.each { task ->
// only PRUN_RUNNING tasks can have items issued or production run completed
if ("PRUN_RUNNING".equals(task.currentStatusId)) {
// Use WorkEffortGoodStandard to figure out if there are products which are needed for this task (PRUNT_PRODNEEDED) and which have not been issued (ie, WEGS_CREATED).
// If so this task should have products issued
components = delegator.findByAnd("WorkEffortGoodStandard", [workEffortId : task.workEffortId, workEffortGoodStdTypeId : "PRUNT_PROD_NEEDED"]);
List notIssued = EntityUtil.filterByAnd(components, [statusId : "WEGS_CREATED"]);
if (components && notIssued) {
issueTaskId = task.workEffortId;
}
if (!issueTaskId) {
completeTaskId = task.workEffortId;
}
}
// the first CREATED and SCHEDULED task will be the startTaskId. As the issue and complete tasks are filled out this condition will no longer be true
if (!startTaskId &&
!issueTaskId &&
!completeTaskId &&
("PRUN_CREATED".equals(task.currentStatusId) ||
"PRUN_SCHEDULED".equals(task.currentStatusId))) {
startTaskId = task.workEffortId;
}
}
context.productionRunRoutingTasks = productionRunRoutingTasks;
context.startTaskId = (startTaskId ? startTaskId: "null");
context.issueTaskId = (issueTaskId? issueTaskId: "null");
context.completeTaskId = (completeTaskId != null? completeTaskId: "null");
// Product components list
productionRunComponents = productionRun.getProductionRunComponents();
productionRunComponentsData = FastList.newInstance();
productionRunComponentsDataReadyForIssuance = FastList.newInstance();
productionRunComponentsAlreadyIssued = FastList.newInstance();
if (productionRunComponents){
productionRunComponents.each { component ->
product = component.getRelatedOne("Product");
componentName = product.getString("internalName");
productionRunTask = component.getRelatedOne("WorkEffort");
workEffortName = productionRunTask.getString("workEffortName");
Map componentData = component.getAllFields();
componentData.internalName = componentName;
componentData.workEffortName = workEffortName;
componentData.facilityId = productionRunTask.facilityId;
issuances = delegator.findByAnd("WorkEffortAndInventoryAssign", [workEffortId : component.workEffortId, productId : product.productId]);
totalIssued = 0.0;
issuances.each { issuance ->
issued = issuance.quantity;
if (issued) {
totalIssued += issued;
}
}
returns = delegator.findByAnd("WorkEffortAndInventoryProduced", [workEffortId : component.workEffortId , productId : product.productId]);
totalReturned = 0.0;
returns.each { returned ->
returnDetail = EntityUtil.getFirst(delegator.findByAnd("InventoryItemDetail", [inventoryItemId : returned.inventoryItemId], ["inventoryItemDetailSeqId"]));
if (returnDetail) {
qtyReturned = returnDetail.quantityOnHandDiff;
if (qtyReturned) {
totalReturned += qtyReturned;
}
}
}
componentData.issuedQuantity = totalIssued;
componentData.returnedQuantity = totalReturned;
componentData.currentStatusId = productionRunTask.currentStatusId;
if ("PRUN_RUNNING".equals(productionRunTask.currentStatusId)) {
componentData.isRunning = "Y";
} else {
componentData.isRunning = "null";
}
productionRunComponentsData.add(componentData);
if ("PRUN_RUNNING".equals(productionRunTask.currentStatusId) && "WEGS_CREATED".equals(component.getString("statusId"))) {
productionRunComponentsDataReadyForIssuance.add(componentData);
} else if (totalIssued > 0.0) {
productionRunComponentsAlreadyIssued.add(componentData);
}
}
}
context.productionRunComponentsData = productionRunComponentsData;
context.productionRunComponentsDataReadyForIssuance = productionRunComponentsDataReadyForIssuance;
context.productionRunComponentsAlreadyIssued = productionRunComponentsAlreadyIssued;
}
}