IDEMPIERE-5331 Create Production from Order (all Lines) (#1375)
* IDEMPIERE-5331 Create Production from Order (all Lines) * Refactoring to remove redundant or unused code and parameters * Clear the order line reference on production when voiding and reversing
This commit is contained in:
parent
ddaf0d6af3
commit
7246c56266
|
@ -0,0 +1,22 @@
|
||||||
|
-- IDEMPIERE-5331 Create Production from Order Lines
|
||||||
|
SELECT register_migration_script('202206271645_IDEMPIERE-5331.sql') FROM dual;
|
||||||
|
|
||||||
|
SET SQLBLANKLINES ON
|
||||||
|
SET DEFINE OFF
|
||||||
|
|
||||||
|
-- Jun 27, 2022, 4:45:47 PM CEST
|
||||||
|
UPDATE AD_Process SET Name='Create Production from Order Line', Description='Create Production for single ordered product',Updated=TO_TIMESTAMP('2022-06-27 16:45:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200006
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jun 27, 2022, 4:46:09 PM CEST
|
||||||
|
UPDATE AD_Process SET Name='Create Shipment from Order Line',Updated=TO_TIMESTAMP('2022-06-27 16:46:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200007
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jun 27, 2022, 4:46:53 PM CEST
|
||||||
|
INSERT INTO AD_Process (AD_Process_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,IsReport,Value,IsDirectPrint,Classname,AccessLevel,EntityType,Statistic_Count,Statistic_Seconds,IsBetaFunctionality,ShowHelp,CopyFromProcess,AD_Process_UU) VALUES (200138,0,0,'Y',TO_TIMESTAMP('2022-06-27 16:46:53','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-06-27 16:46:53','YYYY-MM-DD HH24:MI:SS'),100,'Create Production from Order','Create Production for BOM ordered products','N','C_Order_CreateProduction','N','org.compiere.process.OrderCreateProduction','3','D',0,0,'N','S','N','4d1322d4-df18-4cab-a280-82b1c14f35fd')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jun 27, 2022, 4:51:04 PM CEST
|
||||||
|
INSERT INTO AD_ToolBarButton (AD_Client_ID,AD_Org_ID,Created,CreatedBy,ComponentName,IsActive,AD_ToolBarButton_ID,Name,Updated,UpdatedBy,IsCustomization,AD_ToolBarButton_UU,Action,AD_Tab_ID,AD_Process_ID,DisplayLogic,SeqNo,EntityType) VALUES (0,0,TO_TIMESTAMP('2022-06-27 16:51:04','YYYY-MM-DD HH24:MI:SS'),100,'C_Order_CreateProduction','Y',200122,'C_Order_CreateProduction',TO_TIMESTAMP('2022-06-27 16:51:04','YYYY-MM-DD HH24:MI:SS'),100,'N','9ffb3433-7c04-4d35-bd31-681fa70feb29','W',186,200138,'@SQL=SELECT 1 FROM C_OrderLine ol JOIN M_Product p ON (ol.M_Product_ID=p.M_Product_ID) WHERE ol.C_Order_ID=@C_Order_ID:0@ AND ol.Processed=''Y'' AND p.IsBOM=''Y''',10,'D')
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
-- IDEMPIERE-5331 Create Production from Order Lines
|
||||||
|
SELECT register_migration_script('202206271645_IDEMPIERE-5331.sql') FROM dual;
|
||||||
|
|
||||||
|
-- Jun 27, 2022, 4:45:47 PM CEST
|
||||||
|
UPDATE AD_Process SET Name='Create Production from Order Line', Description='Create Production for single ordered product',Updated=TO_TIMESTAMP('2022-06-27 16:45:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200006
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jun 27, 2022, 4:46:09 PM CEST
|
||||||
|
UPDATE AD_Process SET Name='Create Shipment from Order Line',Updated=TO_TIMESTAMP('2022-06-27 16:46:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200007
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jun 27, 2022, 4:46:53 PM CEST
|
||||||
|
INSERT INTO AD_Process (AD_Process_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,IsReport,Value,IsDirectPrint,Classname,AccessLevel,EntityType,Statistic_Count,Statistic_Seconds,IsBetaFunctionality,ShowHelp,CopyFromProcess,AD_Process_UU) VALUES (200138,0,0,'Y',TO_TIMESTAMP('2022-06-27 16:46:53','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2022-06-27 16:46:53','YYYY-MM-DD HH24:MI:SS'),100,'Create Production from Order','Create Production for BOM ordered products','N','C_Order_CreateProduction','N','org.compiere.process.OrderCreateProduction','3','D',0,0,'N','S','N','4d1322d4-df18-4cab-a280-82b1c14f35fd')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Jun 27, 2022, 4:51:04 PM CEST
|
||||||
|
INSERT INTO AD_ToolBarButton (AD_Client_ID,AD_Org_ID,Created,CreatedBy,ComponentName,IsActive,AD_ToolBarButton_ID,Name,Updated,UpdatedBy,IsCustomization,AD_ToolBarButton_UU,"action",AD_Tab_ID,AD_Process_ID,DisplayLogic,SeqNo,EntityType) VALUES (0,0,TO_TIMESTAMP('2022-06-27 16:51:04','YYYY-MM-DD HH24:MI:SS'),100,'C_Order_CreateProduction','Y',200122,'C_Order_CreateProduction',TO_TIMESTAMP('2022-06-27 16:51:04','YYYY-MM-DD HH24:MI:SS'),100,'N','9ffb3433-7c04-4d35-bd31-681fa70feb29','W',186,200138,'@SQL=SELECT 1 FROM C_OrderLine ol JOIN M_Product p ON (ol.M_Product_ID=p.M_Product_ID) WHERE ol.C_Order_ID=@C_Order_ID:0@ AND ol.Processed=''Y'' AND p.IsBOM=''Y''',10,'D')
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
/***********************************************************************
|
||||||
|
* This file is part of iDempiere ERP Open Source *
|
||||||
|
* http://www.idempiere.org *
|
||||||
|
* *
|
||||||
|
* Copyright (C) Contributors *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU General Public License *
|
||||||
|
* as published by the Free Software Foundation; either version 2 *
|
||||||
|
* of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the Free Software *
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||||
|
* MA 02110-1301, USA. *
|
||||||
|
* *
|
||||||
|
* Contributors: *
|
||||||
|
* - Carlos Ruiz - globalqss - bxservice *
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
package org.compiere.process;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.model.MDocType;
|
||||||
|
import org.compiere.model.MOrder;
|
||||||
|
import org.compiere.model.MOrderLine;
|
||||||
|
import org.compiere.model.MProduct;
|
||||||
|
import org.compiere.model.MProduction;
|
||||||
|
import org.compiere.model.MWarehouse;
|
||||||
|
import org.compiere.model.Query;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Msg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Carlos Ruiz - globalqss - bxservice
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@org.adempiere.base.annotation.Process
|
||||||
|
public class OrderCreateProduction extends SvrProcess {
|
||||||
|
/** Order */
|
||||||
|
private int p_C_Order_ID = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare - e.g., get Parameters.
|
||||||
|
*/
|
||||||
|
protected void prepare() {
|
||||||
|
p_C_Order_ID = getRecord_ID();
|
||||||
|
} // prepare
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Production for BOM products of an order
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected String doIt() throws Exception {
|
||||||
|
if (log.isLoggable(Level.INFO))
|
||||||
|
log.info("C_Order_ID=" + p_C_Order_ID);
|
||||||
|
if (p_C_Order_ID == 0)
|
||||||
|
throw new IllegalArgumentException("No Order");
|
||||||
|
//
|
||||||
|
MOrder order = new MOrder(getCtx(), p_C_Order_ID, get_TrxName());
|
||||||
|
if (order.get_ID() == 0)
|
||||||
|
throw new IllegalArgumentException("Order not found");
|
||||||
|
if (!MOrder.DOCSTATUS_Completed.equals(order.getDocStatus()))
|
||||||
|
throw new IllegalArgumentException("Order not completed");
|
||||||
|
|
||||||
|
final String where = "C_OrderLine.C_Order_ID=?"
|
||||||
|
+ " AND C_OrderLine.Processed='Y'"
|
||||||
|
+ " AND p.IsBOM='Y'"
|
||||||
|
+ " AND p.IsVerified='Y'"
|
||||||
|
+ " AND NOT EXISTS (SELECT 1 FROM M_Production pr WHERE pr.C_OrderLine_ID=C_OrderLine.C_OrderLine_ID)";
|
||||||
|
List<MOrderLine> lines = new Query(getCtx(), MOrderLine.Table_Name, where, get_TrxName())
|
||||||
|
.addJoinClause("JOIN M_Product p ON (C_OrderLine.M_Product_ID=p.M_Product_ID)")
|
||||||
|
.setOnlyActiveRecords(true)
|
||||||
|
.setParameters(p_C_Order_ID)
|
||||||
|
.list();
|
||||||
|
|
||||||
|
MDocType doc = new MDocType(getCtx(), order.getC_DocType_ID(), get_TrxName());
|
||||||
|
int cnt = 0;
|
||||||
|
for (MOrderLine line : lines) {
|
||||||
|
if ((line.getQtyOrdered().subtract(line.getQtyDelivered())).compareTo(Env.ZERO) <= 0) {
|
||||||
|
if (!doc.getDocSubTypeSO().equals("ON")) { // Consignment and stock orders both have subtype of ON
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MProduction production = new MProduction(line);
|
||||||
|
MProduct product = new MProduct(getCtx(), line.getM_Product_ID(), get_TrxName());
|
||||||
|
|
||||||
|
production.setM_Product_ID(line.getM_Product_ID());
|
||||||
|
production.setProductionQty(line.getQtyOrdered().subtract(line.getQtyDelivered()));
|
||||||
|
production.setDatePromised(line.getDatePromised());
|
||||||
|
production.setC_OrderLine_ID(line.getC_OrderLine_ID());
|
||||||
|
|
||||||
|
int locator = product.getM_Locator_ID();
|
||||||
|
if (locator == 0)
|
||||||
|
locator = MWarehouse.get(getCtx(), line.getM_Warehouse_ID()).getDefaultLocator().get_ID();
|
||||||
|
production.setM_Locator_ID(locator);
|
||||||
|
|
||||||
|
if (line.getC_BPartner_ID() > 0) {
|
||||||
|
production.setC_BPartner_ID(order.getC_BPartner_ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.getC_Project_ID() > 0) {
|
||||||
|
production.setC_Project_ID(line.getC_Project_ID());
|
||||||
|
} else {
|
||||||
|
production.setC_Project_ID(order.getC_Project_ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.getC_Campaign_ID() > 0) {
|
||||||
|
production.setC_Campaign_ID(line.getC_Campaign_ID());
|
||||||
|
} else {
|
||||||
|
production.setC_Campaign_ID(order.getC_Campaign_ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.getC_Activity_ID() > 0) {
|
||||||
|
production.setC_Activity_ID(line.getC_Activity_ID());
|
||||||
|
} else {
|
||||||
|
production.setC_Activity_ID(order.getC_Activity_ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.getUser1_ID() > 0) {
|
||||||
|
production.setUser1_ID(line.getUser1_ID());
|
||||||
|
} else {
|
||||||
|
production.setUser1_ID(order.getUser1_ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.getUser2_ID() > 0) {
|
||||||
|
production.setUser2_ID(line.getUser2_ID());
|
||||||
|
} else {
|
||||||
|
production.setUser2_ID(order.getUser2_ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.getAD_OrgTrx_ID() > 0) {
|
||||||
|
production.setAD_OrgTrx_ID(line.getAD_OrgTrx_ID());
|
||||||
|
} else {
|
||||||
|
production.setAD_OrgTrx_ID(order.getAD_OrgTrx_ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
production.saveEx();
|
||||||
|
|
||||||
|
production.createLines(false);
|
||||||
|
production.setIsCreated("Y");
|
||||||
|
production.saveEx();
|
||||||
|
|
||||||
|
String msg = Msg.parseTranslation(getCtx(), "@M_Production_ID@ @Created@ " + production.getDocumentNo());
|
||||||
|
addBufferLog(production.getM_Production_ID(), null, null, msg, MProduction.Table_ID, production.getM_Production_ID());
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "@Created@ " + cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // OrderCreateShipment
|
|
@ -16,7 +16,6 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.compiere.process;
|
package org.compiere.process;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.compiere.model.MDocType;
|
import org.compiere.model.MDocType;
|
||||||
|
@ -30,7 +29,7 @@ import org.compiere.util.Env;
|
||||||
import org.compiere.util.Msg;
|
import org.compiere.util.Msg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create (Generate) Invoice from Shipment
|
* Create (Generate) Production from OrderLine
|
||||||
*
|
*
|
||||||
* @author Jorg Janke
|
* @author Jorg Janke
|
||||||
* @version $Id: OrderLineCreateProduction.java,v 1.1 2007/07/23 05:34:35 mfuggle Exp $
|
* @version $Id: OrderLineCreateProduction.java,v 1.1 2007/07/23 05:34:35 mfuggle Exp $
|
||||||
|
@ -38,35 +37,14 @@ import org.compiere.util.Msg;
|
||||||
@org.adempiere.base.annotation.Process
|
@org.adempiere.base.annotation.Process
|
||||||
public class OrderLineCreateProduction extends SvrProcess
|
public class OrderLineCreateProduction extends SvrProcess
|
||||||
{
|
{
|
||||||
/** Shipment */
|
/** Order Line */
|
||||||
private int p_C_OrderLine_ID = 0;
|
private int p_C_OrderLine_ID = 0;
|
||||||
private Timestamp p_MovementDate = null;
|
|
||||||
private boolean ignorePrevProduction = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare - e.g., get Parameters.
|
* Prepare - e.g., get Parameters.
|
||||||
*/
|
*/
|
||||||
protected void prepare()
|
protected void prepare()
|
||||||
{
|
{
|
||||||
ProcessInfoParameter[] para = getParameter();
|
|
||||||
for (int i = 0; i < para.length; i++)
|
|
||||||
{
|
|
||||||
String name = para[i].getParameterName();
|
|
||||||
if (para[i].getParameter() == null)
|
|
||||||
;
|
|
||||||
if (name.equals("MovementDate"))
|
|
||||||
p_MovementDate = (Timestamp) para[i].getParameter();
|
|
||||||
else if (name.equals("IgnorePrevProduction"))
|
|
||||||
ignorePrevProduction = "Y".equals(para[i].getParameter());
|
|
||||||
else
|
|
||||||
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_MovementDate == null)
|
|
||||||
p_MovementDate = Env.getContextAsDate(getCtx(), Env.DATE);
|
|
||||||
if ( p_MovementDate==null)
|
|
||||||
p_MovementDate = new Timestamp(System.currentTimeMillis());
|
|
||||||
|
|
||||||
p_C_OrderLine_ID = getRecord_ID();
|
p_C_OrderLine_ID = getRecord_ID();
|
||||||
} // prepare
|
} // prepare
|
||||||
|
|
||||||
|
@ -97,11 +75,6 @@ public class OrderLineCreateProduction extends SvrProcess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If we don't ignore previous production, and there has been a previous one,
|
|
||||||
//throw an exception
|
|
||||||
if (!ignorePrevProduction)
|
|
||||||
{
|
|
||||||
String docNo = DB.getSQLValueString(get_TrxName(),
|
String docNo = DB.getSQLValueString(get_TrxName(),
|
||||||
"SELECT max(DocumentNo) " +
|
"SELECT max(DocumentNo) " +
|
||||||
"FROM M_Production WHERE C_OrderLine_ID = ?",
|
"FROM M_Production WHERE C_OrderLine_ID = ?",
|
||||||
|
@ -109,8 +82,6 @@ public class OrderLineCreateProduction extends SvrProcess
|
||||||
if (docNo != null)
|
if (docNo != null)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "ProductionHasAlreadyBeenCreated", new String[] {docNo}));
|
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "ProductionHasAlreadyBeenCreated", new String[] {docNo}));
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MProduction production = new MProduction( line );
|
MProduction production = new MProduction( line );
|
||||||
|
@ -119,8 +90,6 @@ public class OrderLineCreateProduction extends SvrProcess
|
||||||
production.setM_Product_ID(line.getM_Product_ID());
|
production.setM_Product_ID(line.getM_Product_ID());
|
||||||
production.setProductionQty(line.getQtyOrdered().subtract(line.getQtyDelivered()));
|
production.setProductionQty(line.getQtyOrdered().subtract(line.getQtyDelivered()));
|
||||||
production.setDatePromised(line.getDatePromised());
|
production.setDatePromised(line.getDatePromised());
|
||||||
if ( product.getM_Locator_ID() > 0 )
|
|
||||||
production.setM_Locator_ID(product.getM_Locator_ID());
|
|
||||||
production.setC_OrderLine_ID(p_C_OrderLine_ID);
|
production.setC_OrderLine_ID(p_C_OrderLine_ID);
|
||||||
|
|
||||||
int locator = product.getM_Locator_ID();
|
int locator = product.getM_Locator_ID();
|
||||||
|
@ -177,6 +146,6 @@ public class OrderLineCreateProduction extends SvrProcess
|
||||||
String msg = Msg.parseTranslation(getCtx(), "@M_Production_ID@ @Created@ " + production.getDocumentNo());
|
String msg = Msg.parseTranslation(getCtx(), "@M_Production_ID@ @Created@ " + production.getDocumentNo());
|
||||||
addLog(production.getM_Production_ID(), null, null, msg, MProduction.Table_ID, production.getM_Production_ID());
|
addLog(production.getM_Production_ID(), null, null, msg, MProduction.Table_ID, production.getM_Production_ID());
|
||||||
return "@OK@";
|
return "@OK@";
|
||||||
} // OrderLineCreateShipment
|
}
|
||||||
|
|
||||||
} // OrderLineCreateShipment
|
} // OrderLineCreateShipment
|
||||||
|
|
|
@ -659,6 +659,9 @@ public class MProduction extends X_M_Production implements DocAction {
|
||||||
return reverseCorrectIt();
|
return reverseCorrectIt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getC_OrderLine_ID() > 0)
|
||||||
|
setC_OrderLine_ID(0);
|
||||||
|
|
||||||
// After Void
|
// After Void
|
||||||
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
||||||
if (m_processMsg != null)
|
if (m_processMsg != null)
|
||||||
|
@ -716,6 +719,9 @@ public class MProduction extends X_M_Production implements DocAction {
|
||||||
reversalDate = new Timestamp(System.currentTimeMillis());
|
reversalDate = new Timestamp(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getC_OrderLine_ID() > 0)
|
||||||
|
setC_OrderLine_ID(0);
|
||||||
|
|
||||||
MPeriod.testPeriodOpen(getCtx(), reversalDate, Doc.DOCTYPE_MatProduction, getAD_Org_ID());
|
MPeriod.testPeriodOpen(getCtx(), reversalDate, Doc.DOCTYPE_MatProduction, getAD_Org_ID());
|
||||||
MProduction reversal = null;
|
MProduction reversal = null;
|
||||||
reversal = copyFrom (reversalDate);
|
reversal = copyFrom (reversalDate);
|
||||||
|
|
Loading…
Reference in New Issue