diff --git a/migration/iD10/oracle/202310271330_IDEMPIERE-5893.sql b/migration/iD10/oracle/202310271330_IDEMPIERE-5893.sql new file mode 100644 index 0000000000..aee70cdeaf --- /dev/null +++ b/migration/iD10/oracle/202310271330_IDEMPIERE-5893.sql @@ -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') +; + diff --git a/migration/iD10/postgresql/202310271330_IDEMPIERE-5893.sql b/migration/iD10/postgresql/202310271330_IDEMPIERE-5893.sql new file mode 100644 index 0000000000..278fcfe741 --- /dev/null +++ b/migration/iD10/postgresql/202310271330_IDEMPIERE-5893.sql @@ -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') +; + diff --git a/org.adempiere.base/src/org/compiere/model/MOrder.java b/org.adempiere.base/src/org/compiere/model/MOrder.java index 5c783ef77e..febe737099 100644 --- a/org.adempiere.base/src/org/compiere/model/MOrder.java +++ b/org.adempiere.base/src/org/compiere/model/MOrder.java @@ -1406,49 +1406,42 @@ public class MOrder extends X_C_Order implements DocAction { if (!success || newRecord) return success; - - // TODO: The changes here with UPDATE are not being saved on change log - audit problem - - // Propagate Description changes - if (is_ValueChanged("Description") || is_ValueChanged("POReference")) - { - String sql = "UPDATE C_Invoice i" - + " SET (Description,POReference)=" - + "(SELECT Description,POReference " - + "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(); - int no = DB.executeUpdateEx(sql, get_TrxName()); - if (log.isLoggable(Level.FINE)) log.fine("Description -> #" + no); + + // Propagate changes to not-completed/reversed/closed invoices + String propagateColsSysCfg = MSysConfig.getValue(MSysConfig.ORDER_COLUMNS_TO_COPY_TO_NOT_COMPLETED_INVOICES, + "Description,POReference,PaymentRule,C_PaymentTerm_ID,DateAcct", getAD_Client_ID(), getAD_Org_ID()); + if (!Util.isEmpty(propagateColsSysCfg, true)) { + String[] propagateCols = propagateColsSysCfg.split(","); + boolean propagateColChanged = false; + for (String propagateCol : propagateCols) { + String trimmedCol = propagateCol.trim(); + if (get_ColumnIndex(trimmedCol) >= 0 && is_ValueChanged(trimmedCol)) { + propagateColChanged = true; + break; + } + } + if (propagateColChanged) { + List 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 if ( is_ValueChanged("AD_Org_ID") || is_ValueChanged(MOrder.COLUMNNAME_C_BPartner_ID) diff --git a/org.adempiere.base/src/org/compiere/model/MSysConfig.java b/org.adempiere.base/src/org/compiere/model/MSysConfig.java index 6c3f30864c..e9fe2d6651 100644 --- a/org.adempiere.base/src/org/compiere/model/MSysConfig.java +++ b/org.adempiere.base/src/org/compiere/model/MSysConfig.java @@ -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 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_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 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_RECEIPT = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CHECK_ON_RECEIPT"; public static final String PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CREDIT_CARD = "PAYMENT_OVERWRITE_DOCUMENTNO_WITH_CREDIT_CARD";