From f8878b8e01b86a836ad8d6d06dbce8cb82a2ccef Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Mon, 17 Jun 2019 12:24:47 +0200 Subject: [PATCH 1/5] IDEMPIERE-3439 IDEMPIERE-3936 - foreign constraints --- .../oracle/201906171220_IDEMPIERE-3439.sql | 71 +++++++++++++++++++ .../201906171220_IDEMPIERE-3439.sql | 68 ++++++++++++++++++ .../src/org/compiere/model/MColumn.java | 7 ++ .../src/org/compiere/model/MTable.java | 1 + 4 files changed, 147 insertions(+) create mode 100644 migration/i6.2/oracle/201906171220_IDEMPIERE-3439.sql create mode 100644 migration/i6.2/postgresql/201906171220_IDEMPIERE-3439.sql diff --git a/migration/i6.2/oracle/201906171220_IDEMPIERE-3439.sql b/migration/i6.2/oracle/201906171220_IDEMPIERE-3439.sql new file mode 100644 index 0000000000..cbc34223c3 --- /dev/null +++ b/migration/i6.2/oracle/201906171220_IDEMPIERE-3439.sql @@ -0,0 +1,71 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-3439-3936 +-- Jun 17, 2019, 12:19:10 PM CEST +UPDATE AD_Column SET FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:19:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212804 +; + +-- Jun 17, 2019, 12:19:20 PM CEST +UPDATE AD_Column SET FKConstraintName='ADUserClient_ADCtxHelpSuggesti', FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:19:20','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212804 +; + +-- Jun 17, 2019, 12:19:20 PM CEST +ALTER TABLE AD_CtxHelpSuggestion MODIFY AD_UserClient_ID NUMBER(10) +; + +-- Jun 17, 2019, 12:19:20 PM CEST +ALTER TABLE AD_CtxHelpSuggestion ADD CONSTRAINT ADUserClient_ADCtxHelpSuggesti FOREIGN KEY (AD_UserClient_ID) REFERENCES ad_client(ad_client_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 17, 2019, 12:19:40 PM CEST +UPDATE AD_Column SET FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:19:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212805 +; + +-- Jun 17, 2019, 12:19:42 PM CEST +UPDATE AD_Column SET FKConstraintName='ADUser_ADCtxHelpSuggestion', FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:19:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212805 +; + +-- Jun 17, 2019, 12:19:42 PM CEST +ALTER TABLE AD_CtxHelpSuggestion MODIFY AD_User_ID NUMBER(10) +; + +-- Jun 17, 2019, 12:19:42 PM CEST +ALTER TABLE AD_CtxHelpSuggestion ADD CONSTRAINT ADUser_ADCtxHelpSuggestion FOREIGN KEY (AD_User_ID) REFERENCES ad_user(ad_user_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 17, 2019, 12:20:02 PM CEST +UPDATE AD_Column SET FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:20:02','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212779 +; + +-- Jun 17, 2019, 12:20:04 PM CEST +UPDATE AD_Column SET FKConstraintName='ADUserClient_ADFieldSuggestion', FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:20:04','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212779 +; + +-- Jun 17, 2019, 12:20:04 PM CEST +ALTER TABLE AD_FieldSuggestion MODIFY AD_UserClient_ID NUMBER(10) +; + +-- Jun 17, 2019, 12:20:04 PM CEST +ALTER TABLE AD_FieldSuggestion ADD CONSTRAINT ADUserClient_ADFieldSuggestion FOREIGN KEY (AD_UserClient_ID) REFERENCES ad_client(ad_client_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 17, 2019, 12:20:12 PM CEST +UPDATE AD_Column SET FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:20:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212780 +; + +-- Jun 17, 2019, 12:20:13 PM CEST +UPDATE AD_Column SET FKConstraintName='ADUser_ADFieldSuggestion', FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:20:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212780 +; + +-- Jun 17, 2019, 12:20:13 PM CEST +ALTER TABLE AD_FieldSuggestion MODIFY AD_User_ID NUMBER(10) +; + +-- Jun 17, 2019, 12:20:13 PM CEST +ALTER TABLE AD_FieldSuggestion ADD CONSTRAINT ADUser_ADFieldSuggestion FOREIGN KEY (AD_User_ID) REFERENCES ad_user(ad_user_id) DEFERRABLE INITIALLY DEFERRED +; + +SELECT register_migration_script('201906171220_IDEMPIERE-3439.sql') FROM dual +; + diff --git a/migration/i6.2/postgresql/201906171220_IDEMPIERE-3439.sql b/migration/i6.2/postgresql/201906171220_IDEMPIERE-3439.sql new file mode 100644 index 0000000000..a81b72c7df --- /dev/null +++ b/migration/i6.2/postgresql/201906171220_IDEMPIERE-3439.sql @@ -0,0 +1,68 @@ +-- IDEMPIERE-3439-3936 +-- Jun 17, 2019, 12:19:10 PM CEST +UPDATE AD_Column SET FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:19:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212804 +; + +-- Jun 17, 2019, 12:19:20 PM CEST +UPDATE AD_Column SET FKConstraintName='ADUserClient_ADCtxHelpSuggesti', FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:19:20','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212804 +; + +-- Jun 17, 2019, 12:19:20 PM CEST +INSERT INTO t_alter_column values('ad_ctxhelpsuggestion','AD_UserClient_ID','NUMERIC(10)',null,null) +; + +-- Jun 17, 2019, 12:19:20 PM CEST +ALTER TABLE AD_CtxHelpSuggestion ADD CONSTRAINT ADUserClient_ADCtxHelpSuggesti FOREIGN KEY (AD_UserClient_ID) REFERENCES ad_client(ad_client_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 17, 2019, 12:19:40 PM CEST +UPDATE AD_Column SET FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:19:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212805 +; + +-- Jun 17, 2019, 12:19:42 PM CEST +UPDATE AD_Column SET FKConstraintName='ADUser_ADCtxHelpSuggestion', FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:19:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212805 +; + +-- Jun 17, 2019, 12:19:42 PM CEST +INSERT INTO t_alter_column values('ad_ctxhelpsuggestion','AD_User_ID','NUMERIC(10)',null,null) +; + +-- Jun 17, 2019, 12:19:42 PM CEST +ALTER TABLE AD_CtxHelpSuggestion ADD CONSTRAINT ADUser_ADCtxHelpSuggestion FOREIGN KEY (AD_User_ID) REFERENCES ad_user(ad_user_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 17, 2019, 12:20:02 PM CEST +UPDATE AD_Column SET FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:20:02','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212779 +; + +-- Jun 17, 2019, 12:20:04 PM CEST +UPDATE AD_Column SET FKConstraintName='ADUserClient_ADFieldSuggestion', FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:20:04','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212779 +; + +-- Jun 17, 2019, 12:20:04 PM CEST +INSERT INTO t_alter_column values('ad_fieldsuggestion','AD_UserClient_ID','NUMERIC(10)',null,null) +; + +-- Jun 17, 2019, 12:20:04 PM CEST +ALTER TABLE AD_FieldSuggestion ADD CONSTRAINT ADUserClient_ADFieldSuggestion FOREIGN KEY (AD_UserClient_ID) REFERENCES ad_client(ad_client_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 17, 2019, 12:20:12 PM CEST +UPDATE AD_Column SET FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:20:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212780 +; + +-- Jun 17, 2019, 12:20:13 PM CEST +UPDATE AD_Column SET FKConstraintName='ADUser_ADFieldSuggestion', FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:20:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212780 +; + +-- Jun 17, 2019, 12:20:13 PM CEST +INSERT INTO t_alter_column values('ad_fieldsuggestion','AD_User_ID','NUMERIC(10)',null,null) +; + +-- Jun 17, 2019, 12:20:13 PM CEST +ALTER TABLE AD_FieldSuggestion ADD CONSTRAINT ADUser_ADFieldSuggestion FOREIGN KEY (AD_User_ID) REFERENCES ad_user(ad_user_id) DEFERRABLE INITIALLY DEFERRED +; + +SELECT register_migration_script('201906171220_IDEMPIERE-3439.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/compiere/model/MColumn.java b/org.adempiere.base/src/org/compiere/model/MColumn.java index 4d29a2d258..0f147a83fc 100644 --- a/org.adempiere.base/src/org/compiere/model/MColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MColumn.java @@ -809,6 +809,13 @@ public class MColumn extends X_AD_Column foreignTable = "AD_Chart"; } + if (foreignTable.equals("AD_AllClients_V")) + foreignTable = "AD_Client"; + else if (foreignTable.equals("AD_AllUsers_V")) + foreignTable = "AD_User"; + else if (foreignTable.equals("AD_AllRoles_V")) + foreignTable = "AD_Role"; + return foreignTable; } diff --git a/org.adempiere.base/src/org/compiere/model/MTable.java b/org.adempiere.base/src/org/compiere/model/MTable.java index c2e7980d79..486ddb18b3 100644 --- a/org.adempiere.base/src/org/compiere/model/MTable.java +++ b/org.adempiere.base/src/org/compiere/model/MTable.java @@ -705,6 +705,7 @@ public class MTable extends X_AD_Table tablename.equals("AD_AllClients_V") || tablename.equals("AD_ReportView") || tablename.equals("AD_Role") || + tablename.equals("AD_AllRoles_V") || tablename.equals("AD_System") || tablename.equals("AD_User") || tablename.equals("AD_AllUsers_V") || From ed6a4133e082ca00d65acab7dfa83f9c3b8422f8 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Mon, 17 Jun 2019 12:33:04 +0200 Subject: [PATCH 2/5] IDEMPIERE-2389 - foreign key --- .../oracle/201906171230_IDEMPIERE-2389.sql | 27 +++++++++++++++++++ .../201906171230_IDEMPIERE-2389.sql | 24 +++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 migration/i6.2/oracle/201906171230_IDEMPIERE-2389.sql create mode 100644 migration/i6.2/postgresql/201906171230_IDEMPIERE-2389.sql diff --git a/migration/i6.2/oracle/201906171230_IDEMPIERE-2389.sql b/migration/i6.2/oracle/201906171230_IDEMPIERE-2389.sql new file mode 100644 index 0000000000..e8c2f3c620 --- /dev/null +++ b/migration/i6.2/oracle/201906171230_IDEMPIERE-2389.sql @@ -0,0 +1,27 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-2389 +-- Jun 17, 2019, 12:28:14 PM CEST +INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201072,'abd39a4e-0ebf-4708-bfe1-415abfc22bcd',TO_DATE('2019-06-17 12:28:14','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','ad_language_id_idx',TO_DATE('2019-06-17 12:28:14','YYYY-MM-DD HH24:MI:SS'),100,111,'Y','Y','N','N','N') +; + +-- Jun 17, 2019, 12:28:29 PM CEST +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201387,'0be76e53-2809-420c-bb7a-8c4b48edcc74',TO_DATE('2019-06-17 12:28:29','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_DATE('2019-06-17 12:28:29','YYYY-MM-DD HH24:MI:SS'),100,9622,201072,10) +; + +-- Jun 17, 2019, 12:28:32 PM CEST +ALTER TABLE AD_Language ADD CONSTRAINT ad_language_id_idx UNIQUE (AD_Language_ID) +; + +-- Jun 17, 2019, 12:29:47 PM CEST +UPDATE AD_Column SET FKConstraintName='ADLanguage_ADPInstance', FKConstraintType='N',Updated=TO_DATE('2019-06-17 12:29:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211868 +; + +-- Jun 17, 2019, 12:30:06 PM CEST +ALTER TABLE AD_PInstance ADD CONSTRAINT ADLanguage_ADPInstance FOREIGN KEY (AD_Language_ID) REFERENCES AD_Language (AD_Language_ID) DEFERRABLE INITIALLY DEFERRED +; + +SELECT register_migration_script('201906171230_IDEMPIERE-2389.sql') FROM dual +; + diff --git a/migration/i6.2/postgresql/201906171230_IDEMPIERE-2389.sql b/migration/i6.2/postgresql/201906171230_IDEMPIERE-2389.sql new file mode 100644 index 0000000000..a2e0fbc93f --- /dev/null +++ b/migration/i6.2/postgresql/201906171230_IDEMPIERE-2389.sql @@ -0,0 +1,24 @@ +-- IDEMPIERE-2389 +-- Jun 17, 2019, 12:28:14 PM CEST +INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201072,'abd39a4e-0ebf-4708-bfe1-415abfc22bcd',TO_TIMESTAMP('2019-06-17 12:28:14','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','ad_language_id_idx',TO_TIMESTAMP('2019-06-17 12:28:14','YYYY-MM-DD HH24:MI:SS'),100,111,'Y','Y','N','N','N') +; + +-- Jun 17, 2019, 12:28:29 PM CEST +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201387,'0be76e53-2809-420c-bb7a-8c4b48edcc74',TO_TIMESTAMP('2019-06-17 12:28:29','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2019-06-17 12:28:29','YYYY-MM-DD HH24:MI:SS'),100,9622,201072,10) +; + +-- Jun 17, 2019, 12:28:32 PM CEST +ALTER TABLE AD_Language ADD CONSTRAINT ad_language_id_idx UNIQUE (AD_Language_ID) +; + +-- Jun 17, 2019, 12:29:47 PM CEST +UPDATE AD_Column SET FKConstraintName='ADLanguage_ADPInstance', FKConstraintType='N',Updated=TO_TIMESTAMP('2019-06-17 12:29:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211868 +; + +-- Jun 17, 2019, 12:30:06 PM CEST +ALTER TABLE AD_PInstance ADD CONSTRAINT ADLanguage_ADPInstance FOREIGN KEY (AD_Language_ID) REFERENCES AD_Language (AD_Language_ID) DEFERRABLE INITIALLY DEFERRED +; + +SELECT register_migration_script('201906171230_IDEMPIERE-2389.sql') FROM dual +; + From 429d0d47b3daa73b9e09420eb74aba19641e51c6 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Mon, 17 Jun 2019 17:28:51 +0200 Subject: [PATCH 3/5] IDEMPIERE-3439 IDEMPIERE-3936 - foreign constraints - fix NPE --- .../src/org/compiere/model/MColumn.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/model/MColumn.java b/org.adempiere.base/src/org/compiere/model/MColumn.java index 0f147a83fc..5e67a8922e 100644 --- a/org.adempiere.base/src/org/compiere/model/MColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MColumn.java @@ -809,12 +809,15 @@ public class MColumn extends X_AD_Column foreignTable = "AD_Chart"; } - if (foreignTable.equals("AD_AllClients_V")) - foreignTable = "AD_Client"; - else if (foreignTable.equals("AD_AllUsers_V")) - foreignTable = "AD_User"; - else if (foreignTable.equals("AD_AllRoles_V")) - foreignTable = "AD_Role"; + if (foreignTable != null) { + if (foreignTable.equals("AD_AllClients_V")) { + foreignTable = "AD_Client"; + } else if (foreignTable.equals("AD_AllUsers_V")) { + foreignTable = "AD_User"; + } else if (foreignTable.equals("AD_AllRoles_V")) { + foreignTable = "AD_Role"; + } + } return foreignTable; } From a4ab94895d9a02ab6428cc8aaf8ff576ae3026a2 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Tue, 18 Jun 2019 21:09:12 +0800 Subject: [PATCH 4/5] IDEMPIERE-3983 Matched PO posting status "Deferred" never transitions to "Posted" if no matching MR is assigned --- .../src/org/compiere/acct/Doc_MatchPO.java | 4 +- .../src/org/compiere/model/MMatchPO.java | 154 ++++++++++++++++++ 2 files changed, 156 insertions(+), 2 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/acct/Doc_MatchPO.java b/org.adempiere.base/src/org/compiere/acct/Doc_MatchPO.java index 3f8bf82640..4f97269f07 100644 --- a/org.adempiere.base/src/org/compiere/acct/Doc_MatchPO.java +++ b/org.adempiere.base/src/org/compiere/acct/Doc_MatchPO.java @@ -117,14 +117,14 @@ public class Doc_MatchPO extends Doc MMatchPO[] matchPOs = MMatchPO.getOrderLine(getCtx(), m_oLine.getC_OrderLine_ID(), getTrxName()); for (MMatchPO matchPO : matchPOs) { - if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getC_InvoiceLine_ID() == 0) + if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getC_InvoiceLine_ID() == 0 && matchPO.getReversal_ID()==0) { String docStatus = matchPO.getM_InOutLine().getM_InOut().getDocStatus(); if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) { noInvoiceLines.add(matchPO); } } - else if (matchPO.getM_InOutLine_ID() == 0) + else if (matchPO.getM_InOutLine_ID() == 0 && matchPO.getReversal_ID()==0) { String docStatus = matchPO.getC_InvoiceLine().getC_Invoice().getDocStatus(); if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) { diff --git a/org.adempiere.base/src/org/compiere/model/MMatchPO.java b/org.adempiere.base/src/org/compiere/model/MMatchPO.java index 038573c7f1..9e1502ace9 100644 --- a/org.adempiere.base/src/org/compiere/model/MMatchPO.java +++ b/org.adempiere.base/src/org/compiere/model/MMatchPO.java @@ -23,9 +23,15 @@ import java.sql.ResultSet; import java.sql.Savepoint; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.logging.Level; +import org.compiere.process.DocAction; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; @@ -626,6 +632,154 @@ public class MMatchPO extends X_M_MatchPO } throw new RuntimeException(msg); } + + //auto create m_matchinv if not created yet + int cnt = DB.getSQLValue(iLine.get_TrxName(), "SELECT Count(*) FROM M_MatchInv WHERE C_InvoiceLine_ID="+iLine.getC_InvoiceLine_ID()); + if (cnt == 0) + { + Map noInvoiceLines = new HashMap<>(); + Map> invoiceMatched = new HashMap>(); + List noInvoiceList = new ArrayList(); + MMatchPO[] matchPOs = MMatchPO.getOrderLine(iLine.getCtx(), C_OrderLine_ID, iLine.get_TrxName()); + for (MMatchPO matchPO : matchPOs) + { + if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getReversal_ID() == 0) + { + if (matchPO.getC_InvoiceLine_ID() == 0) + { + String docStatus = matchPO.getM_InOutLine().getM_InOut().getDocStatus(); + if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) + { + noInvoiceLines.put(matchPO.getM_MatchPO_ID(), new BigDecimal[]{matchPO.getQty()}); + noInvoiceList.add(matchPO); + } + } + else + { + List invoices = invoiceMatched.get(matchPO.getM_InOutLine_ID()); + if (invoices == null) + { + invoices = new ArrayList(); + invoiceMatched.put(matchPO.getM_InOutLine_ID(), invoices); + } + invoices.add(matchPO); + } + } + } + + Collections.sort(noInvoiceList, new Comparator() { + @Override + public int compare(MMatchPO arg0, MMatchPO arg1) { + return arg0.getM_MatchPO_ID() > arg1.getM_MatchPO_ID() + ? 1 + : (arg0.getM_MatchPO_ID()==arg1.getM_MatchPO_ID() ? 0 : -1); + } + }); + for (MMatchPO matchPO : noInvoiceList) + { + BigDecimal[] qtyHolder = noInvoiceLines.get(matchPO.getM_MatchPO_ID()); + List matchedInvoices = invoiceMatched.get(matchPO.getM_InOutLine_ID()); + MMatchInv[] matchInvoices = MMatchInv.getInOutLine(iLine.getCtx(), matchPO.getM_InOutLine_ID(), iLine.get_TrxName()); + for (MMatchInv matchInv : matchInvoices) + { + if (matchInv.getReversal_ID() > 0) + continue; + BigDecimal alreadyMatch = BigDecimal.ZERO; + if (matchedInvoices != null) + { + for(MMatchPO matchedInvoice : matchedInvoices) + { + if (matchedInvoice.getC_InvoiceLine_ID()==matchInv.getC_InvoiceLine_ID()) + alreadyMatch = alreadyMatch.add(matchedInvoice.getQty()); + } + } + BigDecimal balance = matchInv.getQty().subtract(alreadyMatch); + if (balance.signum() > 0) + { + String docStatus = matchInv.getC_InvoiceLine().getC_Invoice().getDocStatus(); + if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) + { + qtyHolder[0] = qtyHolder[0].subtract(balance); + } + } + } + } + + BigDecimal toMatch = retValue.getQty(); + for (MMatchPO matchPO : noInvoiceList) + { + BigDecimal[] qtyHolder = noInvoiceLines.get(matchPO.getM_MatchPO_ID()); + if (qtyHolder[0].signum() > 0) + { + BigDecimal autoMatchQty = null; + if (qtyHolder[0].compareTo(toMatch) >= 0) + { + autoMatchQty = toMatch; + toMatch = BigDecimal.ZERO; + } + else + { + autoMatchQty = qtyHolder[0]; + toMatch = toMatch.subtract(autoMatchQty); + } + if (autoMatchQty != null && autoMatchQty.signum() > 0) + { + Savepoint savepoint = null; + Trx trx = null; + MMatchInv matchInv = null; + try + { + trx = trxName != null ? Trx.get(trxName, false) : null; + savepoint = trx != null ? trx.getConnection().setSavepoint() : null; + matchInv = new MMatchInv(retValue.getCtx(), 0, retValue.get_TrxName()); + matchInv.setC_InvoiceLine_ID(retValue.getC_InvoiceLine_ID()); + matchInv.setM_Product_ID(retValue.getM_Product_ID()); + matchInv.setM_InOutLine_ID(matchPO.getM_InOutLine_ID()); + matchInv.setAD_Client_ID(retValue.getAD_Client_ID()); + matchInv.setAD_Org_ID(retValue.getAD_Org_ID()); + matchInv.setM_AttributeSetInstance_ID(retValue.getM_AttributeSetInstance_ID()); + matchInv.setQty(autoMatchQty); + matchInv.setDateTrx(dateTrx); + matchInv.setProcessed(true); + if (!matchInv.save()) + { + if (savepoint != null) + { + trx.getConnection().rollback(savepoint); + savepoint = null; + } + else + { + matchInv.delete(true); + } + String msg = "Failed to auto match invoice."; + ValueNamePair error = CLogger.retrieveError(); + if (error != null) + { + msg = msg + " " + error.getName(); + } + s_log.severe(msg); + matchInv = null; + } + } catch (Exception e) { + s_log.log(Level.SEVERE, "Failed to auto match Invoice.", e); + matchInv = null; + } finally { + if (savepoint != null) + { + try { + trx.getConnection().releaseSavepoint(savepoint); + } catch (Exception e) {} + } + } + if (matchInv == null) + break; + } + } + if (toMatch.signum() <= 0) + break; + } + } } } } From 3a6f8f08e264b83754f940d2e6cd1639e726ec31 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Wed, 19 Jun 2019 18:21:55 +0800 Subject: [PATCH 5/5] IDEMPIERE-3983 Matched PO posting status "Deferred" never transitions to "Posted" if no matching MR is assigned --- .../src/org/compiere/model/MMatchPO.java | 269 +++++++++--------- 1 file changed, 141 insertions(+), 128 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/model/MMatchPO.java b/org.adempiere.base/src/org/compiere/model/MMatchPO.java index 9e1502ace9..7e8580c1eb 100644 --- a/org.adempiere.base/src/org/compiere/model/MMatchPO.java +++ b/org.adempiere.base/src/org/compiere/model/MMatchPO.java @@ -398,12 +398,20 @@ public class MMatchPO extends X_M_MatchPO else if (mpo.getM_AttributeSetInstance_ID() != sLine.getM_AttributeSetInstance_ID()) continue; } - } + } else continue; if (iLine == null && mpo.isPosted()) continue; } + if (iLine != null && sLine == null && mpo.getC_InvoiceLine_ID() == 0) + { + //verify m_matchinv not created for other invoice + int cnt = DB.getSQLValue(iLine.get_TrxName(), "SELECT Count(*) FROM M_MatchInv WHERE M_InOutLine_ID="+mpo.getM_InOutLine_ID() + +" AND C_InvoiceLine_ID != "+iLine.getC_InvoiceLine_ID()); + if (cnt > 0) + continue; + } if ((iLine != null || mpo.getC_InvoiceLine_ID() > 0) && (sLine != null || mpo.getM_InOutLine_ID() > 0)) { int M_InOutLine_ID = sLine != null ? sLine.getM_InOutLine_ID() : mpo.getM_InOutLine_ID(); @@ -485,12 +493,12 @@ public class MMatchPO extends X_M_MatchPO qty = qty.subtract(toMatch); if (qty.signum() <= 0) { - retValue = mpo; - break; + retValue = mpo; + break; + } } } } - } catch (Exception e) { s_log.log(Level.SEVERE, sql, e); @@ -633,152 +641,157 @@ public class MMatchPO extends X_M_MatchPO throw new RuntimeException(msg); } - //auto create m_matchinv if not created yet - int cnt = DB.getSQLValue(iLine.get_TrxName(), "SELECT Count(*) FROM M_MatchInv WHERE C_InvoiceLine_ID="+iLine.getC_InvoiceLine_ID()); - if (cnt == 0) + //auto create m_matchinv + Map noInvoiceLines = new HashMap<>(); + Map> invoiceMatched = new HashMap>(); + List noInvoiceList = new ArrayList(); + //get all matchpo with inoutline for C_OrderLine_ID + MMatchPO[] matchPOs = MMatchPO.getOrderLine(iLine.getCtx(), C_OrderLine_ID, iLine.get_TrxName()); + for (MMatchPO matchPO : matchPOs) { - Map noInvoiceLines = new HashMap<>(); - Map> invoiceMatched = new HashMap>(); - List noInvoiceList = new ArrayList(); - MMatchPO[] matchPOs = MMatchPO.getOrderLine(iLine.getCtx(), C_OrderLine_ID, iLine.get_TrxName()); - for (MMatchPO matchPO : matchPOs) - { - if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getReversal_ID() == 0) - { - if (matchPO.getC_InvoiceLine_ID() == 0) - { - String docStatus = matchPO.getM_InOutLine().getM_InOut().getDocStatus(); - if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) - { - noInvoiceLines.put(matchPO.getM_MatchPO_ID(), new BigDecimal[]{matchPO.getQty()}); - noInvoiceList.add(matchPO); - } - } - else - { - List invoices = invoiceMatched.get(matchPO.getM_InOutLine_ID()); - if (invoices == null) - { - invoices = new ArrayList(); - invoiceMatched.put(matchPO.getM_InOutLine_ID(), invoices); - } - invoices.add(matchPO); - } - } - } + if (matchPO.getM_MatchPO_ID() == retValue.getM_MatchPO_ID()) + continue; - Collections.sort(noInvoiceList, new Comparator() { - @Override - public int compare(MMatchPO arg0, MMatchPO arg1) { - return arg0.getM_MatchPO_ID() > arg1.getM_MatchPO_ID() - ? 1 - : (arg0.getM_MatchPO_ID()==arg1.getM_MatchPO_ID() ? 0 : -1); + if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getReversal_ID() == 0) + { + if (matchPO.getC_InvoiceLine_ID() == 0) + { + String docStatus = matchPO.getM_InOutLine().getM_InOut().getDocStatus(); + if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) + { + noInvoiceLines.put(matchPO.getM_MatchPO_ID(), new BigDecimal[]{matchPO.getQty()}); + noInvoiceList.add(matchPO); + } } - }); - for (MMatchPO matchPO : noInvoiceList) - { - BigDecimal[] qtyHolder = noInvoiceLines.get(matchPO.getM_MatchPO_ID()); - List matchedInvoices = invoiceMatched.get(matchPO.getM_InOutLine_ID()); - MMatchInv[] matchInvoices = MMatchInv.getInOutLine(iLine.getCtx(), matchPO.getM_InOutLine_ID(), iLine.get_TrxName()); - for (MMatchInv matchInv : matchInvoices) + else { - if (matchInv.getReversal_ID() > 0) - continue; - BigDecimal alreadyMatch = BigDecimal.ZERO; - if (matchedInvoices != null) + List invoices = invoiceMatched.get(matchPO.getM_InOutLine_ID()); + if (invoices == null) { - for(MMatchPO matchedInvoice : matchedInvoices) - { - if (matchedInvoice.getC_InvoiceLine_ID()==matchInv.getC_InvoiceLine_ID()) - alreadyMatch = alreadyMatch.add(matchedInvoice.getQty()); - } + invoices = new ArrayList(); + invoiceMatched.put(matchPO.getM_InOutLine_ID(), invoices); } - BigDecimal balance = matchInv.getQty().subtract(alreadyMatch); - if (balance.signum() > 0) - { - String docStatus = matchInv.getC_InvoiceLine().getC_Invoice().getDocStatus(); - if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) - { - qtyHolder[0] = qtyHolder[0].subtract(balance); - } - } - } + invoices.add(matchPO); + } + } + } + + //sort in created sequence + Collections.sort(noInvoiceList, new Comparator() { + @Override + public int compare(MMatchPO arg0, MMatchPO arg1) { + return arg0.getM_MatchPO_ID() > arg1.getM_MatchPO_ID() + ? 1 + : (arg0.getM_MatchPO_ID()==arg1.getM_MatchPO_ID() ? 0 : -1); } - - BigDecimal toMatch = retValue.getQty(); - for (MMatchPO matchPO : noInvoiceList) + }); + + //goes through all matchpo that potentially have not been matched to any invoice yet + //calculate balance that have not been matched to invoice line + for (MMatchPO matchPO : noInvoiceList) + { + BigDecimal[] qtyHolder = noInvoiceLines.get(matchPO.getM_MatchPO_ID()); + List matchedInvoices = invoiceMatched.get(matchPO.getM_InOutLine_ID()); + MMatchInv[] matchInvoices = MMatchInv.getInOutLine(iLine.getCtx(), matchPO.getM_InOutLine_ID(), iLine.get_TrxName()); + for (MMatchInv matchInv : matchInvoices) { - BigDecimal[] qtyHolder = noInvoiceLines.get(matchPO.getM_MatchPO_ID()); - if (qtyHolder[0].signum() > 0) + if (matchInv.getReversal_ID() > 0) + continue; + BigDecimal alreadyMatch = BigDecimal.ZERO; + if (matchedInvoices != null) { - BigDecimal autoMatchQty = null; - if (qtyHolder[0].compareTo(toMatch) >= 0) + for(MMatchPO matchedInvoice : matchedInvoices) { - autoMatchQty = toMatch; - toMatch = BigDecimal.ZERO; + if (matchedInvoice.getC_InvoiceLine_ID()==matchInv.getC_InvoiceLine_ID()) + alreadyMatch = alreadyMatch.add(matchedInvoice.getQty()); } - else + } + BigDecimal balance = matchInv.getQty().subtract(alreadyMatch); + if (balance.signum() > 0) + { + String docStatus = matchInv.getC_InvoiceLine().getC_Invoice().getDocStatus(); + if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) { - autoMatchQty = qtyHolder[0]; - toMatch = toMatch.subtract(autoMatchQty); + qtyHolder[0] = qtyHolder[0].subtract(balance); } - if (autoMatchQty != null && autoMatchQty.signum() > 0) + } + } + } + + //do matching + BigDecimal toMatch = retValue.getQty(); + for (MMatchPO matchPO : noInvoiceList) + { + BigDecimal[] qtyHolder = noInvoiceLines.get(matchPO.getM_MatchPO_ID()); + if (qtyHolder[0].signum() > 0) + { + BigDecimal autoMatchQty = null; + if (qtyHolder[0].compareTo(toMatch) >= 0) + { + autoMatchQty = toMatch; + toMatch = BigDecimal.ZERO; + } + else + { + autoMatchQty = qtyHolder[0]; + toMatch = toMatch.subtract(autoMatchQty); + } + if (autoMatchQty != null && autoMatchQty.signum() > 0) + { + Savepoint savepoint = null; + Trx trx = null; + MMatchInv matchInv = null; + try { - Savepoint savepoint = null; - Trx trx = null; - MMatchInv matchInv = null; - try + trx = trxName != null ? Trx.get(trxName, false) : null; + savepoint = trx != null ? trx.getConnection().setSavepoint() : null; + matchInv = new MMatchInv(retValue.getCtx(), 0, retValue.get_TrxName()); + matchInv.setC_InvoiceLine_ID(retValue.getC_InvoiceLine_ID()); + matchInv.setM_Product_ID(retValue.getM_Product_ID()); + matchInv.setM_InOutLine_ID(matchPO.getM_InOutLine_ID()); + matchInv.setAD_Client_ID(retValue.getAD_Client_ID()); + matchInv.setAD_Org_ID(retValue.getAD_Org_ID()); + matchInv.setM_AttributeSetInstance_ID(retValue.getM_AttributeSetInstance_ID()); + matchInv.setQty(autoMatchQty); + matchInv.setDateTrx(dateTrx); + matchInv.setProcessed(true); + if (!matchInv.save()) { - trx = trxName != null ? Trx.get(trxName, false) : null; - savepoint = trx != null ? trx.getConnection().setSavepoint() : null; - matchInv = new MMatchInv(retValue.getCtx(), 0, retValue.get_TrxName()); - matchInv.setC_InvoiceLine_ID(retValue.getC_InvoiceLine_ID()); - matchInv.setM_Product_ID(retValue.getM_Product_ID()); - matchInv.setM_InOutLine_ID(matchPO.getM_InOutLine_ID()); - matchInv.setAD_Client_ID(retValue.getAD_Client_ID()); - matchInv.setAD_Org_ID(retValue.getAD_Org_ID()); - matchInv.setM_AttributeSetInstance_ID(retValue.getM_AttributeSetInstance_ID()); - matchInv.setQty(autoMatchQty); - matchInv.setDateTrx(dateTrx); - matchInv.setProcessed(true); - if (!matchInv.save()) + if (savepoint != null) { - if (savepoint != null) - { - trx.getConnection().rollback(savepoint); - savepoint = null; - } - else - { - matchInv.delete(true); - } - String msg = "Failed to auto match invoice."; - ValueNamePair error = CLogger.retrieveError(); - if (error != null) - { - msg = msg + " " + error.getName(); - } - s_log.severe(msg); - matchInv = null; + trx.getConnection().rollback(savepoint); + savepoint = null; } - } catch (Exception e) { - s_log.log(Level.SEVERE, "Failed to auto match Invoice.", e); - matchInv = null; - } finally { - if (savepoint != null) + else { - try { - trx.getConnection().releaseSavepoint(savepoint); - } catch (Exception e) {} - } + matchInv.delete(true); + } + String msg = "Failed to auto match invoice."; + ValueNamePair error = CLogger.retrieveError(); + if (error != null) + { + msg = msg + " " + error.getName(); + } + s_log.severe(msg); + matchInv = null; } - if (matchInv == null) - break; + } catch (Exception e) { + s_log.log(Level.SEVERE, "Failed to auto match Invoice.", e); + matchInv = null; + } finally { + if (savepoint != null) + { + try { + trx.getConnection().releaseSavepoint(savepoint); + } catch (Exception e) {} + } } + if (matchInv == null) + break; } - if (toMatch.signum() <= 0) - break; } + if (toMatch.signum() <= 0) + break; } } }