IDEMPIERE-5029 User can make Shipment/Receipt Line Product different … (#968)

* IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product

* IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product

Merge patch from Carlos

* IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product

Make consistent with previous patch - always use oLine.M_Product_ID for
reservation

* IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product

add safe guard against oLine is Charge and sLine is Product.

* IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product

- need to apply the oLine.getM_Product_ID changes to reservation log
too.

* IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product

More fix for update of qtyreserved not using product id from oLine.

* IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product

update of qtyreserved: should use warehouse and issotrx from order too
This commit is contained in:
hengsin 2021-11-12 01:48:27 +08:00 committed by GitHub
parent 5469bddbda
commit f937cdbf35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 16 deletions

View File

@ -0,0 +1,15 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product
-- Nov 5, 2021, 7:31:15 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Shipment/Receipt Line Product is different from Order Line Product',0,0,'Y',TO_DATE('2021-11-05 19:31:14','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-11-05 19:31:14','YYYY-MM-DD HH24:MI:SS'),100,200720,'MInOutLineAndOrderLineProductDifferent','D','2e24aa42-6a8e-4ff1-b236-43d16e543389')
;
-- Nov 8, 2021, 5:28:35 PM CET
INSERT INTO AD_SysConfig (AD_SysConfig_ID,AD_Client_ID,AD_Org_ID,Created,Updated,CreatedBy,UpdatedBy,IsActive,Name,Value,Description,EntityType,ConfigurationLevel,AD_SysConfig_UU) VALUES (200187,0,0,TO_DATE('2021-11-08 17:28:34','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2021-11-08 17:28:34','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','VALIDATE_MATCHING_PRODUCT_ON_SHIPMENT','Y','Validate if the product on shipment line must match the same product on order line (Y/N)','D','C','f8eb3b4b-a267-409a-ab83-fccdb11c8c88')
;
SELECT register_migration_script('202111051150_IDEMPIERE-5029.sql') FROM dual
;

View File

@ -0,0 +1,12 @@
-- IDEMPIERE-5029 User can make Shipment/Receipt Line Product different from Order Line Product
-- Nov 5, 2021, 7:31:15 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Shipment/Receipt Line Product is different from Order Line Product',0,0,'Y',TO_TIMESTAMP('2021-11-05 19:31:14','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-11-05 19:31:14','YYYY-MM-DD HH24:MI:SS'),100,200720,'MInOutLineAndOrderLineProductDifferent','D','2e24aa42-6a8e-4ff1-b236-43d16e543389')
;
-- Nov 8, 2021, 5:28:35 PM CET
INSERT INTO AD_SysConfig (AD_SysConfig_ID,AD_Client_ID,AD_Org_ID,Created,Updated,CreatedBy,UpdatedBy,IsActive,Name,Value,Description,EntityType,ConfigurationLevel,AD_SysConfig_UU) VALUES (200187,0,0,TO_TIMESTAMP('2021-11-08 17:28:34','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2021-11-08 17:28:34','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','VALIDATE_MATCHING_PRODUCT_ON_SHIPMENT','Y','Validate if the product on shipment line must match the same product on order line (Y/N)','D','C','f8eb3b4b-a267-409a-ab83-fccdb11c8c88')
;
SELECT register_migration_script('202111051150_IDEMPIERE-5029.sql') FROM dual
;

View File

@ -1423,18 +1423,18 @@ public class MInOut extends X_M_InOut implements DocAction
if (oLine!=null && mtrx!=null && oLine.getQtyOrdered().signum() >= 0)
{
if (sLine.getC_OrderLine_ID() != 0)
if (sLine.getC_OrderLine_ID() != 0 && oLine.getM_Product_ID() > 0)
{
IReservationTracer tracer = null;
IReservationTracerFactory factory = Core.getReservationTracerFactory();
if (factory != null) {
tracer = factory.newTracer(getC_DocType_ID(), getDocumentNo(), sLine.getLine(),
sLine.get_Table_ID(), sLine.get_ID(), oLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(), oLine.getM_AttributeSetInstance_ID(), isSOTrx(),
oLine.getM_Product_ID(), oLine.getM_AttributeSetInstance_ID(), isSOTrx(),
get_TrxName());
}
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(),
oLine.getM_Product_ID(),
oLine.getM_AttributeSetInstance_ID(),
orderedQtyToUpdate.negate(),
isSOTrx(),
@ -1510,18 +1510,18 @@ public class MInOut extends X_M_InOut implements DocAction
m_processMsg = "Cannot correct Inventory OnHand [" + product.getValue() + "] - " + lastError;
return DocAction.STATUS_Invalid;
}
if (oLine!=null && oLine.getQtyOrdered().signum() >= 0)
if (oLine!=null && oLine.getQtyOrdered().signum() >= 0 && oLine.getM_Product_ID() > 0)
{
IReservationTracer tracer = null;
IReservationTracerFactory factory = Core.getReservationTracerFactory();
if (factory != null) {
tracer = factory.newTracer(getC_DocType_ID(), getDocumentNo(), sLine.getLine(),
sLine.get_Table_ID(), sLine.get_ID(), oLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(), oLine.getM_AttributeSetInstance_ID(), isSOTrx(),
oLine.getM_Product_ID(), oLine.getM_AttributeSetInstance_ID(), isSOTrx(),
get_TrxName());
}
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(),
oLine.getM_Product_ID(),
oLine.getM_AttributeSetInstance_ID(),
orderedQtyToUpdate.negate(), isSOTrx(), get_TrxName(), tracer))
{

View File

@ -575,7 +575,7 @@ public class MInOutLine extends X_M_InOutLine
{
if (getParent().isSOTrx())
{
log.saveError("FillMandatory", Msg.translate(getCtx(), "C_Order_ID"));
log.saveError("FillMandatory", Msg.translate(getCtx(), "C_OrderLine_ID"));
return false;
}
}
@ -626,7 +626,19 @@ public class MInOutLine extends X_M_InOutLine
return false;
}
}
if (MSysConfig.getBooleanValue(MSysConfig.VALIDATE_MATCHING_PRODUCT_ON_SHIPMENT, true, Env.getAD_Client_ID(getCtx()))) {
if (getC_OrderLine_ID() > 0) {
MOrderLine orderLine = new MOrderLine(getCtx(), getC_OrderLine_ID(), get_TrxName());
if (orderLine.getM_Product_ID() != getM_Product_ID()) {
log.saveError("MInOutLineAndOrderLineProductDifferent", (getM_Product_ID() > 0 ? MProduct.get(getM_Product_ID()).getValue() : "")
+ " <> " + (orderLine.getM_Product_ID() > 0 ? MProduct.get(orderLine.getM_Product_ID()).getValue() : ""));
return false;
}
}
}
return true;
} // beforeSave

View File

@ -44,7 +44,7 @@ public class MSysConfig extends X_AD_SysConfig
/**
*
*/
private static final long serialVersionUID = -2487508787436200753L;
private static final long serialVersionUID = 4071371201535378277L;
public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION";
public static final String ALERT_SEND_ATTACHMENT_AS_XLS = "ALERT_SEND_ATTACHMENT_AS_XLS";
@ -168,6 +168,7 @@ public class MSysConfig extends X_AD_SysConfig
public static final String USER_LOCKING_MAX_PASSWORD_AGE_DAY = "USER_LOCKING_MAX_PASSWORD_AGE_DAY";
public static final String USER_LOCKING_PASSWORD_NOTIFY_DAY = "USER_LOCKING_PASSWORD_NOTIFY_DAY";
public static final String USER_PASSWORD_HASH = "USER_PASSWORD_HASH";
public static final String VALIDATE_MATCHING_PRODUCT_ON_SHIPMENT = "VALIDATE_MATCHING_PRODUCT_ON_SHIPMENT";
public static final String VALIDATE_MATCHING_TO_ORDERED_QTY = "VALIDATE_MATCHING_TO_ORDERED_QTY";
public static final String WEBUI_LOGOURL = "WEBUI_LOGOURL";
public static final String ZK_ADVANCE_FIND_FILTER_COLUMN_LIST = "ZK_ADVANCE_FIND_FILTER_COLUMN_LIST";

View File

@ -525,19 +525,19 @@ public class Match
{
success = true;
// Correct Ordered Qty for Stocked Products (see MOrder.reserveStock / MInOut.processIt)
if (sLine.getProduct() != null && sLine.getProduct().isStocked()) {
if (oLine.get_ID() > 0 && oLine.getM_Product_ID() > 0 && oLine.getProduct().isStocked()) {
IReservationTracer tracer = null;
IReservationTracerFactory factory = Core.getReservationTracerFactory();
if (factory != null) {
tracer = factory.newTracer(sLine.getParent().getC_DocType_ID(), sLine.getParent().getDocumentNo(), sLine.getLine(),
sLine.get_Table_ID(), sLine.get_ID(), sLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(), oLine.getM_AttributeSetInstance_ID(), sLine.getParent().isSOTrx(),
sLine.get_Table_ID(), sLine.get_ID(), oLine.getM_Warehouse_ID(),
oLine.getM_Product_ID(), oLine.getM_AttributeSetInstance_ID(), oLine.getParent().isSOTrx(),
trxName);
}
success = MStorageReservation.add (Env.getCtx(), sLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(),
sLine.getM_AttributeSetInstance_ID(),
qty.negate(), false, trxName, tracer);
success = MStorageReservation.add (Env.getCtx(), oLine.getM_Warehouse_ID(),
oLine.getM_Product_ID(),
oLine.getM_AttributeSetInstance_ID(),
qty.negate(), oLine.getParent().isSOTrx(), trxName, tracer);
}
}
}