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;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.compiere.model.MDocType;
|
||||
|
@ -30,7 +29,7 @@ import org.compiere.util.Env;
|
|||
import org.compiere.util.Msg;
|
||||
|
||||
/**
|
||||
* Create (Generate) Invoice from Shipment
|
||||
* Create (Generate) Production from OrderLine
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @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
|
||||
public class OrderLineCreateProduction extends SvrProcess
|
||||
{
|
||||
/** Shipment */
|
||||
/** Order Line */
|
||||
private int p_C_OrderLine_ID = 0;
|
||||
private Timestamp p_MovementDate = null;
|
||||
private boolean ignorePrevProduction = false;
|
||||
|
||||
/**
|
||||
* Prepare - e.g., get Parameters.
|
||||
*/
|
||||
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();
|
||||
} // prepare
|
||||
|
||||
|
@ -97,20 +75,13 @@ 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(),
|
||||
"SELECT max(DocumentNo) " +
|
||||
"FROM M_Production WHERE C_OrderLine_ID = ?",
|
||||
p_C_OrderLine_ID);
|
||||
if (docNo != null)
|
||||
{
|
||||
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "ProductionHasAlreadyBeenCreated", new String[] {docNo}));
|
||||
|
||||
}
|
||||
String docNo = DB.getSQLValueString(get_TrxName(),
|
||||
"SELECT max(DocumentNo) " +
|
||||
"FROM M_Production WHERE C_OrderLine_ID = ?",
|
||||
p_C_OrderLine_ID);
|
||||
if (docNo != null)
|
||||
{
|
||||
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "ProductionHasAlreadyBeenCreated", new String[] {docNo}));
|
||||
}
|
||||
|
||||
MProduction production = new MProduction( line );
|
||||
|
@ -119,8 +90,6 @@ public class OrderLineCreateProduction extends SvrProcess
|
|||
production.setM_Product_ID(line.getM_Product_ID());
|
||||
production.setProductionQty(line.getQtyOrdered().subtract(line.getQtyDelivered()));
|
||||
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);
|
||||
|
||||
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());
|
||||
addLog(production.getM_Production_ID(), null, null, msg, MProduction.Table_ID, production.getM_Production_ID());
|
||||
return "@OK@";
|
||||
} // OrderLineCreateShipment
|
||||
}
|
||||
|
||||
} // OrderLineCreateShipment
|
||||
|
|
|
@ -659,6 +659,9 @@ public class MProduction extends X_M_Production implements DocAction {
|
|||
return reverseCorrectIt();
|
||||
}
|
||||
|
||||
if (getC_OrderLine_ID() > 0)
|
||||
setC_OrderLine_ID(0);
|
||||
|
||||
// After Void
|
||||
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
||||
if (m_processMsg != null)
|
||||
|
@ -716,6 +719,9 @@ public class MProduction extends X_M_Production implements DocAction {
|
|||
reversalDate = new Timestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
if (getC_OrderLine_ID() > 0)
|
||||
setC_OrderLine_ID(0);
|
||||
|
||||
MPeriod.testPeriodOpen(getCtx(), reversalDate, Doc.DOCTYPE_MatProduction, getAD_Org_ID());
|
||||
MProduction reversal = null;
|
||||
reversal = copyFrom (reversalDate);
|
||||
|
|
Loading…
Reference in New Issue