IDEMPIERE-5893 Completed invoices are being updated in MOrder.afterSave (#2075)

* IDEMPIERE-5893 Completed invoices are being updated in MOrder.afterSave

* - refactor
- test for date and ID

* - implement SysConfig ORDER_COLUMNS_TO_COPY_TO_NOT_COMPLETED_INVOICES as suggested by Heng Sin
This commit is contained in:
Carlos Ruiz 2023-10-27 14:21:02 +02:00 committed by GitHub
parent b8379d15be
commit 9ac87d3c9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 42 deletions

View File

@ -0,0 +1,10 @@
-- IDEMPIERE-5893 Completed invoices are being updated in MOrder.afterSave
SELECT register_migration_script('202310271330_IDEMPIERE-5893.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Oct 27, 2023, 1:30:33 PM CEST
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 (200239,0,0,TO_TIMESTAMP('2023-10-27 13:30:32','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-10-27 13:30:32','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','ORDER_COLUMNS_TO_COPY_TO_NOT_COMPLETED_INVOICES','Description,POReference,PaymentRule,C_PaymentTerm_ID,DateAcct','Comma separated list of columns to be copied when changing an order to not completed invoices','D','O','afb62005-a8e6-446a-99d1-d268e59ec255')
;

View File

@ -0,0 +1,7 @@
-- IDEMPIERE-5893 Completed invoices are being updated in MOrder.afterSave
SELECT register_migration_script('202310271330_IDEMPIERE-5893.sql') FROM dual;
-- Oct 27, 2023, 1:30:33 PM CEST
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 (200239,0,0,TO_TIMESTAMP('2023-10-27 13:30:32','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-10-27 13:30:32','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','ORDER_COLUMNS_TO_COPY_TO_NOT_COMPLETED_INVOICES','Description,POReference,PaymentRule,C_PaymentTerm_ID,DateAcct','Comma separated list of columns to be copied when changing an order to not completed invoices','D','O','afb62005-a8e6-446a-99d1-d268e59ec255')
;

View File

@ -1406,49 +1406,42 @@ public class MOrder extends X_C_Order implements DocAction
{ {
if (!success || newRecord) if (!success || newRecord)
return success; return success;
// TODO: The changes here with UPDATE are not being saved on change log - audit problem // Propagate changes to not-completed/reversed/closed invoices
String propagateColsSysCfg = MSysConfig.getValue(MSysConfig.ORDER_COLUMNS_TO_COPY_TO_NOT_COMPLETED_INVOICES,
// Propagate Description changes "Description,POReference,PaymentRule,C_PaymentTerm_ID,DateAcct", getAD_Client_ID(), getAD_Org_ID());
if (is_ValueChanged("Description") || is_ValueChanged("POReference")) if (!Util.isEmpty(propagateColsSysCfg, true)) {
{ String[] propagateCols = propagateColsSysCfg.split(",");
String sql = "UPDATE C_Invoice i" boolean propagateColChanged = false;
+ " SET (Description,POReference)=" for (String propagateCol : propagateCols) {
+ "(SELECT Description,POReference " String trimmedCol = propagateCol.trim();
+ "FROM C_Order o WHERE i.C_Order_ID=o.C_Order_ID) " if (get_ColumnIndex(trimmedCol) >= 0 && is_ValueChanged(trimmedCol)) {
+ "WHERE DocStatus NOT IN ('RE','CL') AND C_Order_ID=" + getC_Order_ID(); propagateColChanged = true;
int no = DB.executeUpdateEx(sql, get_TrxName()); break;
if (log.isLoggable(Level.FINE)) log.fine("Description -> #" + no); }
}
if (propagateColChanged) {
List<MInvoice> relatedInvoices = new Query(getCtx(), MInvoice.Table_Name,
"C_Order_ID=? AND Processed='N' AND DocStatus NOT IN ('CO','RE','CL')", get_TrxName())
.setParameters(getC_Order_ID())
.list();
if (relatedInvoices.size() > 0) {
for (String propagateCol : propagateCols) {
String trimmedCol = propagateCol.trim();
if (get_ColumnIndex(trimmedCol) >= 0 && is_ValueChanged(trimmedCol)) {
Object newValue = get_Value(trimmedCol);
for (MInvoice relatedInvoice : relatedInvoices) {
relatedInvoice.set_Value(trimmedCol, newValue);
}
}
}
for (MInvoice relatedInvoice : relatedInvoices) {
relatedInvoice.saveEx();
}
}
}
} }
// Propagate Changes of Payment Info to existing (not reversed/closed) invoices
if (is_ValueChanged("PaymentRule") || is_ValueChanged("C_PaymentTerm_ID")
|| is_ValueChanged("C_Payment_ID")
|| is_ValueChanged("C_CashLine_ID"))
{
String sql = "UPDATE C_Invoice i "
+ "SET (PaymentRule,C_PaymentTerm_ID,C_Payment_ID,C_CashLine_ID)="
+ "(SELECT PaymentRule,C_PaymentTerm_ID,C_Payment_ID,C_CashLine_ID "
+ "FROM C_Order o WHERE i.C_Order_ID=o.C_Order_ID)"
+ "WHERE DocStatus NOT IN ('RE','CL') AND C_Order_ID=" + getC_Order_ID();
// Don't touch Closed/Reversed entries
int no = DB.executeUpdate(sql, get_TrxName());
if (log.isLoggable(Level.FINE)) log.fine("Payment -> #" + no);
}
// Propagate Changes of Date Account to existing (not completed/reversed/closed) invoices
if (is_ValueChanged("DateAcct"))
{
String sql = "UPDATE C_Invoice i "
+ "SET (DateAcct)="
+ "(SELECT DateAcct "
+ "FROM C_Order o WHERE i.C_Order_ID=o.C_Order_ID)"
+ "WHERE DocStatus NOT IN ('CO','RE','CL') AND Processed='N' AND C_Order_ID=" + getC_Order_ID();
// Don't touch Completed/Closed/Reversed entries
int no = DB.executeUpdate(sql, get_TrxName());
if (log.isLoggable(Level.FINE)) log.fine("DateAcct -> #" + no);
}
// Sync Lines // Sync Lines
if ( is_ValueChanged("AD_Org_ID") if ( is_ValueChanged("AD_Org_ID")
|| is_ValueChanged(MOrder.COLUMNNAME_C_BPartner_ID) || is_ValueChanged(MOrder.COLUMNNAME_C_BPartner_ID)

View File

@ -44,7 +44,7 @@ public class MSysConfig extends X_AD_SysConfig
/** /**
* *
*/ */
private static final long serialVersionUID = -2055659961699848343L; private static final long serialVersionUID = -8121703411463724745L;
public static final String AD_CHANGELOG_SAVE_UUID = "AD_CHANGELOG_SAVE_UUID"; public static final String AD_CHANGELOG_SAVE_UUID = "AD_CHANGELOG_SAVE_UUID";
public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION"; public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION";
@ -154,6 +154,7 @@ public class MSysConfig extends X_AD_SysConfig
public static final String MONITOR_INITIAL_WAIT_FOR_CLUSTER_IN_SECONDS = "MONITOR_INITIAL_WAIT_FOR_CLUSTER_IN_SECONDS"; public static final String MONITOR_INITIAL_WAIT_FOR_CLUSTER_IN_SECONDS = "MONITOR_INITIAL_WAIT_FOR_CLUSTER_IN_SECONDS";
public static final String MONITOR_MAX_WAIT_FOR_CLUSTER_IN_SECONDS = "MONITOR_MAX_WAIT_FOR_CLUSTER_IN_SECONDS"; public static final String MONITOR_MAX_WAIT_FOR_CLUSTER_IN_SECONDS = "MONITOR_MAX_WAIT_FOR_CLUSTER_IN_SECONDS";
public static final String MSEQUENCE_GETNEXT_TIMEOUT = "MSEQUENCE_GETNEXT_TIMEOUT"; public static final String MSEQUENCE_GETNEXT_TIMEOUT = "MSEQUENCE_GETNEXT_TIMEOUT";
public static final String ORDER_COLUMNS_TO_COPY_TO_NOT_COMPLETED_INVOICES = "ORDER_COLUMNS_TO_COPY_TO_NOT_COMPLETED_INVOICES";
public static final String PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_PAYMENT = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_PAYMENT"; public static final String PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_PAYMENT = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_PAYMENT";
public static final String PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_RECEIPT = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_RECEIPT"; public static final String PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_RECEIPT = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_RECEIPT";
public static final String PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CREDIT_CARD = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CREDIT_CARD"; public static final String PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CREDIT_CARD = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CREDIT_CARD";