From 6bdc0b187e708d9172de186a1cc500308496f68a Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Wed, 14 Nov 2012 09:58:53 +0800 Subject: [PATCH] IDEMPIERE-378 Implement Reverse Accrual --- .../oracle/201211140148_IDEMPIERE-378.sql | 135 ++++++++++++ .../postgresql/201211140148_IDEMPIERE-378.sql | 135 ++++++++++++ .../adempiere/process/MatchInvReverse.java | 63 ++++++ .../org/adempiere/process/MatchPOReverse.java | 61 ++++++ .../org/compiere/model/I_C_AllocationHdr.java | 15 ++ .../src/org/compiere/model/I_M_MatchInv.java | 15 ++ .../src/org/compiere/model/I_M_MatchPO.java | 15 ++ .../org/compiere/model/MAllocationHdr.java | 204 +++++++++++++++--- .../src/org/compiere/model/MInOut.java | 114 +++++++--- .../src/org/compiere/model/MInventory.java | 44 +++- .../src/org/compiere/model/MInvoice.java | 124 ++++++++--- .../src/org/compiere/model/MMatchInv.java | 27 ++- .../src/org/compiere/model/MMatchPO.java | 31 ++- .../src/org/compiere/model/MPayment.java | 46 ++-- .../org/compiere/model/X_C_AllocationHdr.java | 30 ++- .../src/org/compiere/model/X_M_MatchInv.java | 30 ++- .../src/org/compiere/model/X_M_MatchPO.java | 30 ++- .../org/compiere/process/DocumentEngine.java | 34 +++ 18 files changed, 1036 insertions(+), 117 deletions(-) create mode 100644 migration/i1.0a-release/oracle/201211140148_IDEMPIERE-378.sql create mode 100644 migration/i1.0a-release/postgresql/201211140148_IDEMPIERE-378.sql create mode 100644 org.adempiere.base/src/org/adempiere/process/MatchInvReverse.java create mode 100644 org.adempiere.base/src/org/adempiere/process/MatchPOReverse.java diff --git a/migration/i1.0a-release/oracle/201211140148_IDEMPIERE-378.sql b/migration/i1.0a-release/oracle/201211140148_IDEMPIERE-378.sql new file mode 100644 index 0000000000..3357f7e7be --- /dev/null +++ b/migration/i1.0a-release/oracle/201211140148_IDEMPIERE-378.sql @@ -0,0 +1,135 @@ +-- Nov 12, 2012 6:10:19 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Reference (AD_Reference_UU,Name,EntityType,IsOrderByValue,AD_Reference_ID,ValidationType,AD_Org_ID,Created,UpdatedBy,AD_Client_ID,CreatedBy,Updated,IsActive) VALUES ('9a238b56-6113-430b-969d-c72f023d059d','M_MatchPO','D','N',200017,'T',0,TO_DATE('2012-11-12 18:10:15','YYYY-MM-DD HH24:MI:SS'),100,0,100,TO_DATE('2012-11-12 18:10:15','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:10:19 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Reference_Trl (AD_Language,AD_Reference_ID, Help,Name,Description, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Reference_Trl_UU ) SELECT l.AD_Language,t.AD_Reference_ID, t.Help,t.Name,t.Description, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Reference t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Reference_ID=200017 AND NOT EXISTS (SELECT * FROM AD_Reference_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Reference_ID=t.AD_Reference_ID) +; + +-- Nov 12, 2012 6:11:40 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Ref_Table (IsValueDisplayed,OrderByClause,AD_Key,AD_Display,Updated,EntityType,AD_Reference_ID,AD_Client_ID,UpdatedBy,AD_Table_ID,AD_Org_ID,AD_Ref_Table_UU,CreatedBy,Created,IsActive) VALUES ('N','M_MatchPO.DocumentNo',6513,13087,TO_DATE('2012-11-12 18:11:40','YYYY-MM-DD HH24:MI:SS'),'D',200017,0,100,473,0,'f2683800-01e3-47fd-85ea-2a1bb1a8ab48',100,TO_DATE('2012-11-12 18:11:40','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:12:28 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column (IsSyncDatabase,IsEncrypted,Version,AD_Table_ID,EntityType,AD_Reference_Value_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,AD_Element_ID,Created,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,IsAlwaysUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,Updated,AD_Org_ID,UpdatedBy,AD_Client_ID,AD_Column_ID,IsToolbarButton,SeqNoSelection) VALUES ('N','N',1,473,'D',200017,'N','N','N',0,'N',10,'N',18,'N',53457,TO_DATE('2012-11-12 18:12:26','YYYY-MM-DD HH24:MI:SS'),'N','Y','104c1cef-5cc1-436d-aa8a-548e66b2469f','Y','N','Reversal_ID','ID of document reversal','Reversal ID','N','Y',100,TO_DATE('2012-11-12 18:12:26','YYYY-MM-DD HH24:MI:SS'),0,100,0,200880,'N',0) +; + +-- Nov 12, 2012 6:12:28 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Column_Trl_UU ) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=200880 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID) +; + +-- Nov 12, 2012 6:12:36 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +ALTER TABLE M_MatchPO ADD Reversal_ID NUMBER(10) DEFAULT NULL +; + +-- Nov 12, 2012 6:14:15 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Reference (AD_Reference_UU,Name,EntityType,IsOrderByValue,AD_Reference_ID,ValidationType,AD_Org_ID,Created,UpdatedBy,AD_Client_ID,CreatedBy,Updated,IsActive) VALUES ('a8cf3824-9f18-4d6b-802e-3412a8954a00','M_MatchInv','D','N',200018,'T',0,TO_DATE('2012-11-12 18:14:13','YYYY-MM-DD HH24:MI:SS'),100,0,100,TO_DATE('2012-11-12 18:14:13','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:14:15 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Reference_Trl (AD_Language,AD_Reference_ID, Help,Name,Description, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Reference_Trl_UU ) SELECT l.AD_Language,t.AD_Reference_ID, t.Help,t.Name,t.Description, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Reference t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Reference_ID=200018 AND NOT EXISTS (SELECT * FROM AD_Reference_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Reference_ID=t.AD_Reference_ID) +; + +-- Nov 12, 2012 6:14:53 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Ref_Table (IsValueDisplayed,OrderByClause,AD_Key,AD_Display,Updated,EntityType,AD_Reference_ID,AD_Client_ID,UpdatedBy,AD_Table_ID,AD_Org_ID,AD_Ref_Table_UU,CreatedBy,Created,IsActive) VALUES ('N','M_MatchInv.DocumentNo',6497,13086,TO_DATE('2012-11-12 18:14:53','YYYY-MM-DD HH24:MI:SS'),'D',200018,0,100,472,0,'24adae8f-5c79-4cae-b407-3ca6fba3c375',100,TO_DATE('2012-11-12 18:14:53','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:16:04 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column (IsSyncDatabase,IsEncrypted,Version,AD_Table_ID,EntityType,AD_Reference_Value_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,AD_Element_ID,Created,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,IsAlwaysUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,Updated,AD_Org_ID,UpdatedBy,AD_Client_ID,AD_Column_ID,IsToolbarButton,SeqNoSelection) VALUES ('N','N',1,472,'D',200018,'N','N','N',0,'N',10,'N',18,'N',53457,TO_DATE('2012-11-12 18:16:03','YYYY-MM-DD HH24:MI:SS'),'N','Y','62823c9e-b2c1-46e2-9157-80a1338d0b71','Y','N','Reversal_ID','ID of document reversal','Reversal ID','Y','Y',100,TO_DATE('2012-11-12 18:16:03','YYYY-MM-DD HH24:MI:SS'),0,100,0,200881,'N',0) +; + +-- Nov 12, 2012 6:16:04 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Column_Trl_UU ) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=200881 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID) +; + +-- Nov 12, 2012 6:16:10 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +ALTER TABLE M_MatchInv ADD Reversal_ID NUMBER(10) DEFAULT NULL +; + +-- Nov 12, 2012 6:19:34 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column (IsSyncDatabase,IsEncrypted,Version,AD_Table_ID,EntityType,AD_Reference_Value_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,AD_Element_ID,Created,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,IsAlwaysUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,Updated,AD_Org_ID,UpdatedBy,AD_Client_ID,AD_Column_ID,IsToolbarButton,SeqNoSelection) VALUES ('N','N',1,735,'D',323,'N','N','N',0,'N',10,'N',18,'N',53457,TO_DATE('2012-11-12 18:19:33','YYYY-MM-DD HH24:MI:SS'),'N','Y','f8c0678b-cdcc-41b2-8ccf-b7e5bba6c5a1','Y','N','Reversal_ID','ID of document reversal','Reversal ID','Y','Y',100,TO_DATE('2012-11-12 18:19:33','YYYY-MM-DD HH24:MI:SS'),0,100,0,200882,'N',0) +; + +-- Nov 12, 2012 6:19:34 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Column_Trl_UU ) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=200882 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID) +; + +-- Nov 12, 2012 6:19:39 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +ALTER TABLE C_AllocationHdr ADD Reversal_ID NUMBER(10) DEFAULT NULL +; + +-- Nov 12, 2012 6:24:58 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Process (CopyFromProcess,AD_Process_ID,IsDirectPrint,IsReport,AD_Process_UU,AccessLevel,IsBetaFunctionality,IsServerProcess,Statistic_Seconds,Statistic_Count,ShowHelp,EntityType,Classname,Name,AD_Client_ID,UpdatedBy,Updated,CreatedBy,Value,AD_Org_ID,Created,IsActive) VALUES ('N',200016,'N','N','c3c3698b-82ca-4686-9d92-0ffc83c10bf6','3','N','N',0,0,'Y','D','org.adempiere.process.MatchPOReverse','Reverse MatchPO',0,100,TO_DATE('2012-11-12 18:24:56','YYYY-MM-DD HH24:MI:SS'),100,'M_MatchPO_Reversal',0,TO_DATE('2012-11-12 18:24:56','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:24:58 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Process_Trl (AD_Language,AD_Process_ID, Help,Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Process_Trl_UU ) SELECT l.AD_Language,t.AD_Process_ID, t.Help,t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Process t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Process_ID=200016 AND NOT EXISTS (SELECT * FROM AD_Process_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Process_ID=t.AD_Process_ID) +; + +-- Nov 12, 2012 6:26:45 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Process (CopyFromProcess,AD_Process_ID,IsDirectPrint,IsReport,AD_Process_UU,AccessLevel,IsBetaFunctionality,IsServerProcess,Statistic_Seconds,Statistic_Count,ShowHelp,EntityType,Classname,Name,AD_Client_ID,UpdatedBy,Updated,CreatedBy,Value,AD_Org_ID,Created,IsActive) VALUES ('N',200017,'N','N','bbb372e3-138e-4425-9f8c-bfbd1e73a666','3','N','N',0,0,'Y','D','org.adempiere.process.MatchInvReverse','Reverse MatchInv',0,100,TO_DATE('2012-11-12 18:26:44','YYYY-MM-DD HH24:MI:SS'),100,'M_MatchInv_Reversal',0,TO_DATE('2012-11-12 18:26:44','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:26:45 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Process_Trl (AD_Language,AD_Process_ID, Help,Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Process_Trl_UU ) SELECT l.AD_Language,t.AD_Process_ID, t.Help,t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Process t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Process_ID=200017 AND NOT EXISTS (SELECT * FROM AD_Process_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Process_ID=t.AD_Process_ID) +; + +-- Nov 12, 2012 6:30:55 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_ToolBarButton (Action,AD_Tab_ID,SeqNo,AD_Process_ID,AD_ToolBarButton_ID,Updated,IsActive,IsCustomization,Name,AD_Client_ID,AD_ToolBarButton_UU,ComponentName,Created,CreatedBy,UpdatedBy,AD_Org_ID) VALUES ('W',408,10,200017,200069,TO_DATE('2012-11-12 18:30:54','YYYY-MM-DD HH24:MI:SS'),'Y','N','Reverse Invoice Matching',0,'08eda454-bcb1-4c57-83e4-97212206a7bc','ReverseMatchInv',TO_DATE('2012-11-12 18:30:54','YYYY-MM-DD HH24:MI:SS'),100,100,0) +; + +-- Nov 12, 2012 6:31:40 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +UPDATE AD_Process SET Name='Reverse Invoice Matching',Updated=TO_DATE('2012-11-12 18:31:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200017 +; + +-- Nov 12, 2012 6:31:40 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +UPDATE AD_Process_Trl SET IsTranslated='N' WHERE AD_Process_ID=200017 +; + +-- Nov 12, 2012 6:32:43 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_ToolBarButton (Action,AD_Tab_ID,SeqNo,AD_Process_ID,AD_ToolBarButton_ID,Updated,IsActive,IsCustomization,Name,AD_Client_ID,AD_ToolBarButton_UU,ComponentName,Created,CreatedBy,UpdatedBy,AD_Org_ID) VALUES ('W',409,10,200016,200070,TO_DATE('2012-11-12 18:32:42','YYYY-MM-DD HH24:MI:SS'),'Y','N','Reverse PO Matching',0,'1ef6e3e8-8997-4242-9715-58d07afe4e08','ReverseMatchPO',TO_DATE('2012-11-12 18:32:42','YYYY-MM-DD HH24:MI:SS'),100,100,0) +; + +-- Nov 12, 2012 6:34:00 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +UPDATE AD_Process SET Name='Reverse PO Matching',Updated=TO_DATE('2012-11-12 18:34:00','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200016 +; + +-- Nov 12, 2012 6:34:00 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +UPDATE AD_Process_Trl SET IsTranslated='N' WHERE AD_Process_ID=200016 +; + +-- Nov 12, 2012 6:36:32 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_ToolBarButton (Action,AD_Tab_ID,SeqNo,AD_Process_ID,AD_ToolBarButton_ID,Updated,IsActive,IsCustomization,Name,AD_Client_ID,AD_ToolBarButton_UU,ComponentName,Created,CreatedBy,UpdatedBy,AD_Org_ID) VALUES ('W',690,10,200017,200071,TO_DATE('2012-11-12 18:36:31','YYYY-MM-DD HH24:MI:SS'),'Y','N','Reverse Invoice Matching',0,'00811a39-21a6-4c51-b5f1-299bd6f595b1','ReverseMatchInv',TO_DATE('2012-11-12 18:36:31','YYYY-MM-DD HH24:MI:SS'),100,100,0) +; + +-- Nov 12, 2012 6:37:50 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_ToolBarButton (Action,AD_Tab_ID,SeqNo,AD_Process_ID,AD_ToolBarButton_ID,Updated,IsActive,IsCustomization,Name,AD_Client_ID,AD_ToolBarButton_UU,ComponentName,Created,CreatedBy,UpdatedBy,AD_Org_ID) VALUES ('W',692,10,200016,200072,TO_DATE('2012-11-12 18:37:49','YYYY-MM-DD HH24:MI:SS'),'Y','N','Reverse PO Matching',0,'99e7e98d-a600-4174-9b55-923b790d03ba','ReverseMatchPO',TO_DATE('2012-11-12 18:37:49','YYYY-MM-DD HH24:MI:SS'),100,100,0) +; + diff --git a/migration/i1.0a-release/postgresql/201211140148_IDEMPIERE-378.sql b/migration/i1.0a-release/postgresql/201211140148_IDEMPIERE-378.sql new file mode 100644 index 0000000000..08f457d656 --- /dev/null +++ b/migration/i1.0a-release/postgresql/201211140148_IDEMPIERE-378.sql @@ -0,0 +1,135 @@ +-- Nov 12, 2012 6:10:19 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Reference (AD_Reference_UU,Name,EntityType,IsOrderByValue,AD_Reference_ID,ValidationType,AD_Org_ID,Created,UpdatedBy,AD_Client_ID,CreatedBy,Updated,IsActive) VALUES ('9a238b56-6113-430b-969d-c72f023d059d','M_MatchPO','D','N',200017,'T',0,TO_TIMESTAMP('2012-11-12 18:10:15','YYYY-MM-DD HH24:MI:SS'),100,0,100,TO_TIMESTAMP('2012-11-12 18:10:15','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:10:19 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Reference_Trl (AD_Language,AD_Reference_ID, Help,Name,Description, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Reference_Trl_UU ) SELECT l.AD_Language,t.AD_Reference_ID, t.Help,t.Name,t.Description, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Reference t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Reference_ID=200017 AND NOT EXISTS (SELECT * FROM AD_Reference_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Reference_ID=t.AD_Reference_ID) +; + +-- Nov 12, 2012 6:11:40 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Ref_Table (IsValueDisplayed,OrderByClause,AD_Key,AD_Display,Updated,EntityType,AD_Reference_ID,AD_Client_ID,UpdatedBy,AD_Table_ID,AD_Org_ID,AD_Ref_Table_UU,CreatedBy,Created,IsActive) VALUES ('N','M_MatchPO.DocumentNo',6513,13087,TO_TIMESTAMP('2012-11-12 18:11:40','YYYY-MM-DD HH24:MI:SS'),'D',200017,0,100,473,0,'f2683800-01e3-47fd-85ea-2a1bb1a8ab48',100,TO_TIMESTAMP('2012-11-12 18:11:40','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:12:28 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column (IsSyncDatabase,IsEncrypted,Version,AD_Table_ID,EntityType,AD_Reference_Value_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,AD_Element_ID,Created,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,IsAlwaysUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,Updated,AD_Org_ID,UpdatedBy,AD_Client_ID,AD_Column_ID,IsToolbarButton,SeqNoSelection) VALUES ('N','N',1,473,'D',200017,'N','N','N',0,'N',10,'N',18,'N',53457,TO_TIMESTAMP('2012-11-12 18:12:26','YYYY-MM-DD HH24:MI:SS'),'N','Y','104c1cef-5cc1-436d-aa8a-548e66b2469f','Y','N','Reversal_ID','ID of document reversal','Reversal ID','N','Y',100,TO_TIMESTAMP('2012-11-12 18:12:26','YYYY-MM-DD HH24:MI:SS'),0,100,0,200880,'N',0) +; + +-- Nov 12, 2012 6:12:28 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Column_Trl_UU ) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=200880 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID) +; + +-- Nov 12, 2012 6:12:36 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +ALTER TABLE M_MatchPO ADD COLUMN Reversal_ID NUMERIC(10) DEFAULT NULL +; + +-- Nov 12, 2012 6:14:15 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Reference (AD_Reference_UU,Name,EntityType,IsOrderByValue,AD_Reference_ID,ValidationType,AD_Org_ID,Created,UpdatedBy,AD_Client_ID,CreatedBy,Updated,IsActive) VALUES ('a8cf3824-9f18-4d6b-802e-3412a8954a00','M_MatchInv','D','N',200018,'T',0,TO_TIMESTAMP('2012-11-12 18:14:13','YYYY-MM-DD HH24:MI:SS'),100,0,100,TO_TIMESTAMP('2012-11-12 18:14:13','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:14:15 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Reference_Trl (AD_Language,AD_Reference_ID, Help,Name,Description, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Reference_Trl_UU ) SELECT l.AD_Language,t.AD_Reference_ID, t.Help,t.Name,t.Description, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Reference t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Reference_ID=200018 AND NOT EXISTS (SELECT * FROM AD_Reference_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Reference_ID=t.AD_Reference_ID) +; + +-- Nov 12, 2012 6:14:53 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Ref_Table (IsValueDisplayed,OrderByClause,AD_Key,AD_Display,Updated,EntityType,AD_Reference_ID,AD_Client_ID,UpdatedBy,AD_Table_ID,AD_Org_ID,AD_Ref_Table_UU,CreatedBy,Created,IsActive) VALUES ('N','M_MatchInv.DocumentNo',6497,13086,TO_TIMESTAMP('2012-11-12 18:14:53','YYYY-MM-DD HH24:MI:SS'),'D',200018,0,100,472,0,'24adae8f-5c79-4cae-b407-3ca6fba3c375',100,TO_TIMESTAMP('2012-11-12 18:14:53','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:16:04 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column (IsSyncDatabase,IsEncrypted,Version,AD_Table_ID,EntityType,AD_Reference_Value_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,AD_Element_ID,Created,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,IsAlwaysUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,Updated,AD_Org_ID,UpdatedBy,AD_Client_ID,AD_Column_ID,IsToolbarButton,SeqNoSelection) VALUES ('N','N',1,472,'D',200018,'N','N','N',0,'N',10,'N',18,'N',53457,TO_TIMESTAMP('2012-11-12 18:16:03','YYYY-MM-DD HH24:MI:SS'),'N','Y','62823c9e-b2c1-46e2-9157-80a1338d0b71','Y','N','Reversal_ID','ID of document reversal','Reversal ID','Y','Y',100,TO_TIMESTAMP('2012-11-12 18:16:03','YYYY-MM-DD HH24:MI:SS'),0,100,0,200881,'N',0) +; + +-- Nov 12, 2012 6:16:04 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Column_Trl_UU ) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=200881 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID) +; + +-- Nov 12, 2012 6:16:10 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +ALTER TABLE M_MatchInv ADD COLUMN Reversal_ID NUMERIC(10) DEFAULT NULL +; + +-- Nov 12, 2012 6:19:34 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column (IsSyncDatabase,IsEncrypted,Version,AD_Table_ID,EntityType,AD_Reference_Value_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,AD_Element_ID,Created,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,IsAlwaysUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,Updated,AD_Org_ID,UpdatedBy,AD_Client_ID,AD_Column_ID,IsToolbarButton,SeqNoSelection) VALUES ('N','N',1,735,'D',323,'N','N','N',0,'N',10,'N',18,'N',53457,TO_TIMESTAMP('2012-11-12 18:19:33','YYYY-MM-DD HH24:MI:SS'),'N','Y','f8c0678b-cdcc-41b2-8ccf-b7e5bba6c5a1','Y','N','Reversal_ID','ID of document reversal','Reversal ID','Y','Y',100,TO_TIMESTAMP('2012-11-12 18:19:33','YYYY-MM-DD HH24:MI:SS'),0,100,0,200882,'N',0) +; + +-- Nov 12, 2012 6:19:34 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Column_Trl (AD_Language,AD_Column_ID, Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Column_Trl_UU ) SELECT l.AD_Language,t.AD_Column_ID, t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Column t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Column_ID=200882 AND NOT EXISTS (SELECT * FROM AD_Column_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Column_ID=t.AD_Column_ID) +; + +-- Nov 12, 2012 6:19:39 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +ALTER TABLE C_AllocationHdr ADD COLUMN Reversal_ID NUMERIC(10) DEFAULT NULL +; + +-- Nov 12, 2012 6:24:58 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Process (CopyFromProcess,AD_Process_ID,IsDirectPrint,IsReport,AD_Process_UU,AccessLevel,IsBetaFunctionality,IsServerProcess,Statistic_Seconds,Statistic_Count,ShowHelp,EntityType,Classname,Name,AD_Client_ID,UpdatedBy,Updated,CreatedBy,Value,AD_Org_ID,Created,IsActive) VALUES ('N',200016,'N','N','c3c3698b-82ca-4686-9d92-0ffc83c10bf6','3','N','N',0,0,'Y','D','org.adempiere.process.MatchPOReverse','Reverse MatchPO',0,100,TO_TIMESTAMP('2012-11-12 18:24:56','YYYY-MM-DD HH24:MI:SS'),100,'M_MatchPO_Reversal',0,TO_TIMESTAMP('2012-11-12 18:24:56','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:24:58 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Process_Trl (AD_Language,AD_Process_ID, Help,Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Process_Trl_UU ) SELECT l.AD_Language,t.AD_Process_ID, t.Help,t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Process t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Process_ID=200016 AND NOT EXISTS (SELECT * FROM AD_Process_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Process_ID=t.AD_Process_ID) +; + +-- Nov 12, 2012 6:26:45 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Process (CopyFromProcess,AD_Process_ID,IsDirectPrint,IsReport,AD_Process_UU,AccessLevel,IsBetaFunctionality,IsServerProcess,Statistic_Seconds,Statistic_Count,ShowHelp,EntityType,Classname,Name,AD_Client_ID,UpdatedBy,Updated,CreatedBy,Value,AD_Org_ID,Created,IsActive) VALUES ('N',200017,'N','N','bbb372e3-138e-4425-9f8c-bfbd1e73a666','3','N','N',0,0,'Y','D','org.adempiere.process.MatchInvReverse','Reverse MatchInv',0,100,TO_TIMESTAMP('2012-11-12 18:26:44','YYYY-MM-DD HH24:MI:SS'),100,'M_MatchInv_Reversal',0,TO_TIMESTAMP('2012-11-12 18:26:44','YYYY-MM-DD HH24:MI:SS'),'Y') +; + +-- Nov 12, 2012 6:26:45 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_Process_Trl (AD_Language,AD_Process_ID, Help,Description,Name, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Process_Trl_UU ) SELECT l.AD_Language,t.AD_Process_ID, t.Help,t.Description,t.Name, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Process t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Process_ID=200017 AND NOT EXISTS (SELECT * FROM AD_Process_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Process_ID=t.AD_Process_ID) +; + +-- Nov 12, 2012 6:30:55 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_ToolBarButton ("action",AD_Tab_ID,SeqNo,AD_Process_ID,AD_ToolBarButton_ID,Updated,IsActive,IsCustomization,Name,AD_Client_ID,AD_ToolBarButton_UU,ComponentName,Created,CreatedBy,UpdatedBy,AD_Org_ID) VALUES ('W',408,10,200017,200069,TO_TIMESTAMP('2012-11-12 18:30:54','YYYY-MM-DD HH24:MI:SS'),'Y','N','Reverse Invoice Matching',0,'08eda454-bcb1-4c57-83e4-97212206a7bc','ReverseMatchInv',TO_TIMESTAMP('2012-11-12 18:30:54','YYYY-MM-DD HH24:MI:SS'),100,100,0) +; + +-- Nov 12, 2012 6:31:40 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +UPDATE AD_Process SET Name='Reverse Invoice Matching',Updated=TO_TIMESTAMP('2012-11-12 18:31:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200017 +; + +-- Nov 12, 2012 6:31:40 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +UPDATE AD_Process_Trl SET IsTranslated='N' WHERE AD_Process_ID=200017 +; + +-- Nov 12, 2012 6:32:43 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_ToolBarButton ("action",AD_Tab_ID,SeqNo,AD_Process_ID,AD_ToolBarButton_ID,Updated,IsActive,IsCustomization,Name,AD_Client_ID,AD_ToolBarButton_UU,ComponentName,Created,CreatedBy,UpdatedBy,AD_Org_ID) VALUES ('W',409,10,200016,200070,TO_TIMESTAMP('2012-11-12 18:32:42','YYYY-MM-DD HH24:MI:SS'),'Y','N','Reverse PO Matching',0,'1ef6e3e8-8997-4242-9715-58d07afe4e08','ReverseMatchPO',TO_TIMESTAMP('2012-11-12 18:32:42','YYYY-MM-DD HH24:MI:SS'),100,100,0) +; + +-- Nov 12, 2012 6:34:00 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +UPDATE AD_Process SET Name='Reverse PO Matching',Updated=TO_TIMESTAMP('2012-11-12 18:34:00','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200016 +; + +-- Nov 12, 2012 6:34:00 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +UPDATE AD_Process_Trl SET IsTranslated='N' WHERE AD_Process_ID=200016 +; + +-- Nov 12, 2012 6:36:32 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_ToolBarButton ("action",AD_Tab_ID,SeqNo,AD_Process_ID,AD_ToolBarButton_ID,Updated,IsActive,IsCustomization,Name,AD_Client_ID,AD_ToolBarButton_UU,ComponentName,Created,CreatedBy,UpdatedBy,AD_Org_ID) VALUES ('W',690,10,200017,200071,TO_TIMESTAMP('2012-11-12 18:36:31','YYYY-MM-DD HH24:MI:SS'),'Y','N','Reverse Invoice Matching',0,'00811a39-21a6-4c51-b5f1-299bd6f595b1','ReverseMatchInv',TO_TIMESTAMP('2012-11-12 18:36:31','YYYY-MM-DD HH24:MI:SS'),100,100,0) +; + +-- Nov 12, 2012 6:37:50 PM MYT +-- IDEMPIERE-378 Implement Reverse Accrual +INSERT INTO AD_ToolBarButton ("action",AD_Tab_ID,SeqNo,AD_Process_ID,AD_ToolBarButton_ID,Updated,IsActive,IsCustomization,Name,AD_Client_ID,AD_ToolBarButton_UU,ComponentName,Created,CreatedBy,UpdatedBy,AD_Org_ID) VALUES ('W',692,10,200016,200072,TO_TIMESTAMP('2012-11-12 18:37:49','YYYY-MM-DD HH24:MI:SS'),'Y','N','Reverse PO Matching',0,'99e7e98d-a600-4174-9b55-923b790d03ba','ReverseMatchPO',TO_TIMESTAMP('2012-11-12 18:37:49','YYYY-MM-DD HH24:MI:SS'),100,100,0) +; + diff --git a/org.adempiere.base/src/org/adempiere/process/MatchInvReverse.java b/org.adempiere.base/src/org/adempiere/process/MatchInvReverse.java new file mode 100644 index 0000000000..4f37c0882a --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/process/MatchInvReverse.java @@ -0,0 +1,63 @@ +/****************************************************************************** + * Copyright (C) 2012 Heng Sin Low * + * Copyright (C) 2012 Trek Global * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. 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., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + *****************************************************************************/ +package org.adempiere.process; + + +import java.sql.Timestamp; +import java.util.logging.Level; + +import org.adempiere.exceptions.AdempiereException; +import org.compiere.model.MMatchInv; +import org.compiere.process.SvrProcess; +import org.compiere.util.Env; + +/** + * Process to reverse invoice matching + * @author hengsin + * + */ +public class MatchInvReverse extends SvrProcess { + private int p_M_MatchInv_ID = 0; + + @Override + protected void prepare() { + p_M_MatchInv_ID = getRecord_ID(); + } + + /** + * @return message + * @throws Exception + */ + @Override + protected String doIt() throws Exception { + if (log.isLoggable(Level.INFO)) + log.info ("M_MatchInv_ID=" + p_M_MatchInv_ID); + + MMatchInv inv = new MMatchInv (getCtx(), p_M_MatchInv_ID, get_TrxName()); + if (inv.get_ID() != p_M_MatchInv_ID) + throw new AdempiereException("@NotFound@ @M_MatchInv_ID@ " + p_M_MatchInv_ID); + + if (inv.isPosted()) + { + Timestamp reversalDate = Env.getContextAsDate(getCtx(), "#Date"); + if (reversalDate == null) { + reversalDate = new Timestamp(System.currentTimeMillis()); + } + if (!inv.reverse(reversalDate)) + throw new AdempiereException("Failed to reverse invoice matching"); + } + return "@OK@"; + } + +} diff --git a/org.adempiere.base/src/org/adempiere/process/MatchPOReverse.java b/org.adempiere.base/src/org/adempiere/process/MatchPOReverse.java new file mode 100644 index 0000000000..338207de28 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/process/MatchPOReverse.java @@ -0,0 +1,61 @@ +/****************************************************************************** + * Copyright (C) 2012 Heng Sin Low * + * Copyright (C) 2012 Trek Global * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. 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., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + *****************************************************************************/ +package org.adempiere.process; + +import java.sql.Timestamp; +import java.util.logging.Level; + +import org.adempiere.exceptions.AdempiereException; +import org.compiere.model.MMatchPO; +import org.compiere.process.SvrProcess; +import org.compiere.util.Env; + +/** + * Process to reverse PO Matching + * @author hengsin + * + */ +public class MatchPOReverse extends SvrProcess { + private int p_M_MatchPO_ID = 0; + + @Override + protected void prepare() { + p_M_MatchPO_ID = getRecord_ID(); + } + + /** + * @return message + * @throws Exception + */ + @Override + protected String doIt() throws Exception { + if (log.isLoggable(Level.INFO)) + log.info ("M_MatchPO_ID=" + p_M_MatchPO_ID); + + MMatchPO po = new MMatchPO (getCtx(), p_M_MatchPO_ID, get_TrxName()); + if (po.get_ID() != p_M_MatchPO_ID) + throw new AdempiereException("@NotFound@ @M_MatchPO_ID@ " + p_M_MatchPO_ID); + if (po.isPosted()) + { + Timestamp reversalDate = Env.getContextAsDate(getCtx(), "#Date"); + if (reversalDate == null) { + reversalDate = new Timestamp(System.currentTimeMillis()); + } + if (!po.reverse(reversalDate)) + throw new AdempiereException("Failed to reverse matching"); + } + return "@OK@"; + } + +} diff --git a/org.adempiere.base/src/org/compiere/model/I_C_AllocationHdr.java b/org.adempiere.base/src/org/compiere/model/I_C_AllocationHdr.java index 621a4134e5..baca71877b 100644 --- a/org.adempiere.base/src/org/compiere/model/I_C_AllocationHdr.java +++ b/org.adempiere.base/src/org/compiere/model/I_C_AllocationHdr.java @@ -293,6 +293,21 @@ public interface I_C_AllocationHdr /** Get Process Now */ public boolean isProcessing(); + /** Column name Reversal_ID */ + public static final String COLUMNNAME_Reversal_ID = "Reversal_ID"; + + /** Set Reversal ID. + * ID of document reversal + */ + public void setReversal_ID (int Reversal_ID); + + /** Get Reversal ID. + * ID of document reversal + */ + public int getReversal_ID(); + + public org.compiere.model.I_C_AllocationHdr getReversal() throws RuntimeException; + /** Column name Updated */ public static final String COLUMNNAME_Updated = "Updated"; diff --git a/org.adempiere.base/src/org/compiere/model/I_M_MatchInv.java b/org.adempiere.base/src/org/compiere/model/I_M_MatchInv.java index 36d98bb433..799935e995 100644 --- a/org.adempiere.base/src/org/compiere/model/I_M_MatchInv.java +++ b/org.adempiere.base/src/org/compiere/model/I_M_MatchInv.java @@ -286,6 +286,21 @@ public interface I_M_MatchInv */ public BigDecimal getQty(); + /** Column name Reversal_ID */ + public static final String COLUMNNAME_Reversal_ID = "Reversal_ID"; + + /** Set Reversal ID. + * ID of document reversal + */ + public void setReversal_ID (int Reversal_ID); + + /** Get Reversal ID. + * ID of document reversal + */ + public int getReversal_ID(); + + public org.compiere.model.I_M_MatchInv getReversal() throws RuntimeException; + /** Column name Updated */ public static final String COLUMNNAME_Updated = "Updated"; diff --git a/org.adempiere.base/src/org/compiere/model/I_M_MatchPO.java b/org.adempiere.base/src/org/compiere/model/I_M_MatchPO.java index 08d47e32cf..6d01715804 100644 --- a/org.adempiere.base/src/org/compiere/model/I_M_MatchPO.java +++ b/org.adempiere.base/src/org/compiere/model/I_M_MatchPO.java @@ -327,6 +327,21 @@ public interface I_M_MatchPO */ public BigDecimal getQty(); + /** Column name Reversal_ID */ + public static final String COLUMNNAME_Reversal_ID = "Reversal_ID"; + + /** Set Reversal ID. + * ID of document reversal + */ + public void setReversal_ID (int Reversal_ID); + + /** Get Reversal ID. + * ID of document reversal + */ + public int getReversal_ID(); + + public org.compiere.model.I_M_MatchPO getReversal() throws RuntimeException; + /** Column name Updated */ public static final String COLUMNNAME_Updated = "Updated"; diff --git a/org.adempiere.base/src/org/compiere/model/MAllocationHdr.java b/org.adempiere.base/src/org/compiere/model/MAllocationHdr.java index 545de0beff..b562053c6f 100644 --- a/org.adempiere.base/src/org/compiere/model/MAllocationHdr.java +++ b/org.adempiere.base/src/org/compiere/model/MAllocationHdr.java @@ -29,6 +29,7 @@ import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; +import org.adempiere.exceptions.PeriodClosedException; import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; import org.compiere.util.CLogger; @@ -531,7 +532,17 @@ public final class MAllocationHdr extends X_C_AllocationHdr implements DocAction if (m_processMsg != null) return false; - boolean retValue = reverseIt(); + boolean accrual = false; + try + { + MPeriod.testPeriodOpen(getCtx(), getDateTrx(), MPeriodControl.DOCBASETYPE_PaymentAllocation, getAD_Org_ID()); + } + catch (PeriodClosedException e) + { + accrual = true; + } + + boolean retValue = reverseIt(accrual); // After Void m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID); @@ -578,7 +589,7 @@ public final class MAllocationHdr extends X_C_AllocationHdr implements DocAction if (m_processMsg != null) return false; - boolean retValue = reverseIt(); + boolean retValue = reverseIt(false); // After reverseCorrect m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); @@ -601,7 +612,7 @@ public final class MAllocationHdr extends X_C_AllocationHdr implements DocAction if (m_processMsg != null) return false; - boolean retValue = reverseIt(); + boolean retValue = reverseIt(true); // After reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL); @@ -721,43 +732,104 @@ public final class MAllocationHdr extends X_C_AllocationHdr implements DocAction return getCreatedBy(); } // getDoc_User_ID + /** + * Add to Description + * @param description text + */ + public void addDescription (String description) + { + String desc = getDescription(); + if (desc == null) + setDescription(description); + else + setDescription(desc + " | " + description); + } // addDescription /************************************************************************** * Reverse Allocation. * Period needs to be open * @return true if reversed */ - private boolean reverseIt() + private boolean reverseIt(boolean accrual) { if (!isActive()) throw new IllegalStateException("Allocation already reversed (not active)"); - // Can we delete posting - MPeriod.testPeriodOpen(getCtx(), getDateTrx(), MPeriodControl.DOCBASETYPE_PaymentAllocation, getAD_Org_ID()); - - // Set Inactive - setIsActive (false); - if ( !isPosted() ) - setPosted(true); - setDocumentNo(getDocumentNo()+"^"); - setDocStatus(DOCSTATUS_Reversed); // for direct calls - if (!save() || isActive()) - throw new IllegalStateException("Cannot de-activate allocation"); - - // Delete Posting - MFactAcct.deleteEx(MAllocationHdr.Table_ID, getC_AllocationHdr_ID(), get_TrxName()); - - // Unlink Invoices - getLines(true); - HashSet bps = new HashSet(); - for (int i = 0; i < m_lines.length; i++) - { - MAllocationLine line = m_lines[i]; - line.setIsActive(false); - line.saveEx(); - bps.add(new Integer(line.processIt(true))); // reverse + Timestamp reversalDate = accrual ? Env.getContextAsDate(getCtx(), "#Date") : getDateAcct(); + if (reversalDate == null) { + reversalDate = new Timestamp(System.currentTimeMillis()); + } + + // Can we delete posting + MPeriod.testPeriodOpen(getCtx(), reversalDate, MPeriodControl.DOCBASETYPE_PaymentAllocation, getAD_Org_ID()); + + if (accrual) + { + // Deep Copy + MAllocationHdr reversal = copyFrom (this, reversalDate, reversalDate, get_TrxName()); + if (reversal == null) + { + m_processMsg = "Could not create Payment Allocation Reversal"; + return false; + } + reversal.setReversal_ID(getC_AllocationHdr_ID()); + + // Reverse Line Amt + MAllocationLine[] rLines = reversal.getLines(false); + for (MAllocationLine rLine : rLines) { + rLine.setAmount(rLine.getAmount().negate()); + rLine.setDiscountAmt(rLine.getDiscountAmt().negate()); + rLine.setWriteOffAmt(rLine.getWriteOffAmt().negate()); + rLine.setOverUnderAmt(rLine.getOverUnderAmt().negate()); + if (!rLine.save(get_TrxName())) + { + m_processMsg = "Could not correct Payment Allocation Reversal Line"; + return false; + } + } + reversal.addDescription("{->" + getDocumentNo() + ")"); + // + if (!DocumentEngine.processIt(reversal, DocAction.ACTION_Complete)) + { + m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); + return false; + } + + DocumentEngine.processIt(reversal, DocAction.ACTION_Close); + reversal.setProcessing (false); + reversal.setDocStatus(DOCSTATUS_Reversed); + reversal.setDocAction(DOCACTION_None); + reversal.saveEx(); + m_processMsg = reversal.getDocumentNo(); + addDescription("(" + reversal.getDocumentNo() + "<-)"); + + } + else + { + // Set Inactive + setIsActive (false); + if ( !isPosted() ) + setPosted(true); + setDocumentNo(getDocumentNo()+"^"); + setDocStatus(DOCSTATUS_Reversed); // for direct calls + if (!save() || isActive()) + throw new IllegalStateException("Cannot de-activate allocation"); + + // Delete Posting + MFactAcct.deleteEx(MAllocationHdr.Table_ID, getC_AllocationHdr_ID(), get_TrxName()); + + // Unlink Invoices + getLines(true); + HashSet bps = new HashSet(); + for (int i = 0; i < m_lines.length; i++) + { + MAllocationLine line = m_lines[i]; + line.setIsActive(false); + line.saveEx(); + bps.add(new Integer(line.processIt(true))); // reverse + } + updateBP(bps); } - updateBP(bps); return true; } // reverse @@ -794,5 +866,79 @@ public final class MAllocationHdr extends X_C_AllocationHdr implements DocAction || DOCSTATUS_Closed.equals(ds) || DOCSTATUS_Reversed.equals(ds); } // isComplete + + /** + * Create new Allocation by copying + * @param from allocation + * @param dateAcct date of the document accounting date + * @param dateTrx date of the document transaction. + * @param trxName + * @return Allocation + */ + public static MAllocationHdr copyFrom (MAllocationHdr from, Timestamp dateAcct, Timestamp dateTrx, + String trxName) + { + MAllocationHdr to = new MAllocationHdr (from.getCtx(), 0, trxName); + PO.copyValues (from, to, from.getAD_Client_ID(), from.getAD_Org_ID()); + to.set_ValueNoCheck ("DocumentNo", null); + // + to.setDocStatus (DOCSTATUS_Drafted); // Draft + to.setDocAction(DOCACTION_Complete); + // + to.setDateTrx (dateAcct); + to.setDateAcct (dateTrx); + to.setIsManual(false); + // + to.setIsApproved (false); + // + to.setPosted (false); + to.setProcessed (false); + + to.saveEx(); + + // Lines + if (to.copyLinesFrom(from) == 0) + throw new AdempiereException("Could not create Allocation Lines"); + + return to; + } // copyFrom + + /** + * Copy Lines From other Allocation. + * @param otherAllocation allocation + * @return number of lines copied + */ + public int copyLinesFrom (MAllocationHdr otherAllocation) + { + if (isProcessed() || isPosted() || (otherAllocation == null)) + return 0; + MAllocationLine[] fromLines = otherAllocation.getLines(false); + int count = 0; + for (MAllocationLine fromLine : fromLines) { + MAllocationLine line = new MAllocationLine (getCtx(), 0, get_TrxName()); + PO.copyValues (fromLine, line, fromLine.getAD_Client_ID(), fromLine.getAD_Org_ID()); + line.setC_AllocationHdr_ID(getC_AllocationHdr_ID()); + line.setParent(this); + line.set_ValueNoCheck ("C_AllocationLine_ID", I_ZERO); // new + + if (line.getC_Payment_ID() != 0) + { + MPayment payment = new MPayment(getCtx(), line.getC_Payment_ID(), get_TrxName()); + if (DOCSTATUS_Reversed.equals(payment.getDocStatus())) + { + MPayment reversal = (MPayment) payment.getReversal(); + if (reversal != null) + { + line.setPaymentInfo(reversal.getC_Payment_ID(), 0); + } + } + } + + line.saveEx(); + count++; + } + + return count; + } // copyLinesFrom } // MAllocation diff --git a/org.adempiere.base/src/org/compiere/model/MInOut.java b/org.adempiere.base/src/org/compiere/model/MInOut.java index 63a8be4ae5..c67dbd9da9 100644 --- a/org.adempiere.base/src/org/compiere/model/MInOut.java +++ b/org.adempiere.base/src/org/compiere/model/MInOut.java @@ -2040,40 +2040,70 @@ public class MInOut extends X_M_InOut implements DocAction if (m_processMsg != null) return false; + MInOut reversal = reverse(false); + if (reversal == null) + return false; + + // After reverseCorrect + m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); + if (m_processMsg != null) + return false; + + m_processMsg = reversal.getDocumentNo(); + setProcessed(true); + setDocStatus(DOCSTATUS_Reversed); // may come from void + setDocAction(DOCACTION_None); + return true; + } // reverseCorrectionIt + + private MInOut reverse(boolean accrual) { MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); - if (!MPeriod.isOpen(getCtx(), getDateAcct(), dt.getDocBaseType(), getAD_Org_ID())) + Timestamp reversalDate = accrual ? Env.getContextAsDate(getCtx(), "#Date") : getDateAcct(); + if (reversalDate == null) { + reversalDate = new Timestamp(System.currentTimeMillis()); + } + Timestamp reversalMovementDate = accrual ? reversalDate : getMovementDate(); + if (!MPeriod.isOpen(getCtx(), reversalDate, dt.getDocBaseType(), getAD_Org_ID())) { m_processMsg = "@PeriodClosed@"; - return false; + return null; } // Reverse/Delete Matching if (!isSOTrx()) { - MMatchInv[] mInv = MMatchInv.getInOut(getCtx(), getM_InOut_ID(), get_TrxName()); - for (int i = 0; i < mInv.length; i++) - mInv[i].deleteEx(true); - MMatchPO[] mPO = MMatchPO.getInOut(getCtx(), getM_InOut_ID(), get_TrxName()); - for (int i = 0; i < mPO.length; i++) + if (accrual) { - if (mPO[i].getC_InvoiceLine_ID() == 0) - mPO[i].deleteEx(true); - else + if (!reverseMatching(reversalDate)) + return null; + } + else + { + MMatchInv[] mInv = MMatchInv.getInOut(getCtx(), getM_InOut_ID(), get_TrxName()); + for (int i = 0; i < mInv.length; i++) + mInv[i].deleteEx(true); + MMatchPO[] mPO = MMatchPO.getInOut(getCtx(), getM_InOut_ID(), get_TrxName()); + for (int i = 0; i < mPO.length; i++) { - mPO[i].setM_InOutLine_ID(0); - mPO[i].saveEx(); - + if (mPO[i].getC_InvoiceLine_ID() == 0) + mPO[i].deleteEx(true); + else + { + mPO[i].setM_InOutLine_ID(0); + mPO[i].saveEx(); + + } } } } // Deep Copy - MInOut reversal = copyFrom (this, getMovementDate(), getDateAcct(), + MInOut reversal = copyFrom (this, reversalMovementDate, reversalDate, getC_DocType_ID(), isSOTrx(), false, get_TrxName(), true); if (reversal == null) { m_processMsg = "Could not create Ship Reversal"; - return false; + return null; } reversal.setReversal(true); @@ -2091,7 +2121,7 @@ public class MInOut extends X_M_InOut implements DocAction if (!rLine.save(get_TrxName())) { m_processMsg = "Could not correct Ship Reversal Line"; - return false; + return null; } // We need to copy MA if (rLine.getM_AttributeSetInstance_ID() == 0) @@ -2128,7 +2158,7 @@ public class MInOut extends X_M_InOut implements DocAction || !reversal.getDocStatus().equals(DocAction.STATUS_Completed)) { m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); - return false; + return null; } reversal.closeIt(); reversal.setProcessing (false); @@ -2146,18 +2176,38 @@ public class MInOut extends X_M_InOut implements DocAction //FR1948157 this.setReversal_ID(reversal.getM_InOut_ID()); voidConfirmations(); + return reversal; + } - // After reverseCorrect - m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); - if (m_processMsg != null) - return false; - - m_processMsg = reversal.getDocumentNo(); - setProcessed(true); - setDocStatus(DOCSTATUS_Reversed); // may come from void - setDocAction(DOCACTION_None); + private boolean reverseMatching(Timestamp reversalDate) { + MMatchInv[] mInv = MMatchInv.getInOut(getCtx(), getM_InOut_ID(), get_TrxName()); + for (MMatchInv mMatchInv : mInv) + { + String description = mMatchInv.getDescription(); + if (description == null || !description.endsWith("<-)")) + { + if (!mMatchInv.reverse(reversalDate)) + { + log.log(Level.SEVERE, "Failed to create reversal for match invoice " + mMatchInv.getDocumentNo()); + return false; + } + } + } + MMatchPO[] mMatchPOList = MMatchPO.getInOut(getCtx(), getM_InOut_ID(), get_TrxName()); + for (MMatchPO mMatchPO : mMatchPOList) + { + String description = mMatchPO.getDescription(); + if (description == null || !description.endsWith("<-)")) + { + if (!mMatchPO.reverse(reversalDate)) + { + log.log(Level.SEVERE, "Failed to create reversal for match purchase order " + mMatchPO.getDocumentNo()); + return false; + } + } + } return true; - } // reverseCorrectionIt + } /** * Reverse Accrual - none @@ -2171,12 +2221,20 @@ public class MInOut extends X_M_InOut implements DocAction if (m_processMsg != null) return false; + MInOut reversal = reverse(true); + if (reversal == null) + return false; + // After reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL); if (m_processMsg != null) return false; - return false; + m_processMsg = reversal.getDocumentNo(); + setProcessed(true); + setDocStatus(DOCSTATUS_Reversed); // may come from void + setDocAction(DOCACTION_None); + return true; } // reverseAccrualIt /** diff --git a/org.adempiere.base/src/org/compiere/model/MInventory.java b/org.adempiere.base/src/org/compiere/model/MInventory.java index 66718de5e6..17319bdeab 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventory.java +++ b/org.adempiere.base/src/org/compiere/model/MInventory.java @@ -744,12 +744,33 @@ public class MInventory extends X_M_Inventory implements DocAction if (m_processMsg != null) return false; + MInventory reversal = reverse(false); + if (reversal == null) + return false; + + // After reverseCorrect + m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); + if (m_processMsg != null) + return false; + + m_processMsg = reversal.getDocumentNo(); + + return true; + } // reverseCorrectIt + + private MInventory reverse(boolean accrual) { + Timestamp reversalDate = accrual ? Env.getContextAsDate(getCtx(), "#Date") : getMovementDate(); + if (reversalDate == null) { + reversalDate = new Timestamp(System.currentTimeMillis()); + } + MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); - MPeriod.testPeriodOpen(getCtx(), getMovementDate(), dt.getDocBaseType(), getAD_Org_ID()); + MPeriod.testPeriodOpen(getCtx(), reversalDate, dt.getDocBaseType(), getAD_Org_ID()); // Deep Copy MInventory reversal = new MInventory(getCtx(), 0, get_TrxName()); copyValues(this, reversal, getAD_Client_ID(), getAD_Org_ID()); + reversal.setMovementDate(reversalDate); reversal.setDocStatus(DOCSTATUS_Drafted); reversal.setDocAction(DOCACTION_Complete); reversal.setIsApproved (false); @@ -799,29 +820,24 @@ public class MInventory extends X_M_Inventory implements DocAction if (!reversal.processIt(DocAction.ACTION_Complete)) { m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); - return false; + return null; } reversal.closeIt(); reversal.setDocStatus(DOCSTATUS_Reversed); reversal.setDocAction(DOCACTION_None); reversal.saveEx(); - m_processMsg = reversal.getDocumentNo(); - + // Update Reversed (this) msgd = new StringBuilder("(").append(reversal.getDocumentNo()).append("<-)"); addDescription(msgd.toString()); - // After reverseCorrect - m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); - if (m_processMsg != null) - return false; setProcessed(true); //FR1948157 setReversal_ID(reversal.getM_Inventory_ID()); setDocStatus(DOCSTATUS_Reversed); // may come from void setDocAction(DOCACTION_None); - - return true; - } // reverseCorrectIt + + return reversal; + } /** * Reverse Accrual @@ -835,10 +851,16 @@ public class MInventory extends X_M_Inventory implements DocAction if (m_processMsg != null) return false; + MInventory reversal = reverse(true); + if (reversal == null) + return false; + // After reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL); if (m_processMsg != null) return false; + + m_processMsg = reversal.getDocumentNo(); return false; } // reverseAccrualIt diff --git a/org.adempiere.base/src/org/compiere/model/MInvoice.java b/org.adempiere.base/src/org/compiere/model/MInvoice.java index 795d1fbb74..f3cc5bcbea 100644 --- a/org.adempiere.base/src/org/compiere/model/MInvoice.java +++ b/org.adempiere.base/src/org/compiere/model/MInvoice.java @@ -2264,31 +2264,95 @@ public class MInvoice extends X_C_Invoice implements DocAction if (m_processMsg != null) return false; - MPeriod.testPeriodOpen(getCtx(), getDateAcct(), getC_DocType_ID(), getAD_Org_ID()); + MInvoice reversal = reverse(false); + if (reversal == null) + return false; + + // After reverseCorrect + m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); + if (m_processMsg != null) + return false; + + m_processMsg = reversal.getDocumentNo(); + + return true; + } // reverseCorrectIt + + private MInvoice reverse(boolean accrual) { + Timestamp reversalDate = accrual ? Env.getContextAsDate(getCtx(), "#Date") : getDateAcct(); + if (reversalDate == null) { + reversalDate = new Timestamp(System.currentTimeMillis()); + } + Timestamp reversalDateInvoiced = accrual ? reversalDate : getDateInvoiced(); + + MPeriod.testPeriodOpen(getCtx(), reversalDate, getC_DocType_ID(), getAD_Org_ID()); // MAllocationHdr[] allocations = MAllocationHdr.getOfInvoice(getCtx(), getC_Invoice_ID(), get_TrxName()); for (int i = 0; i < allocations.length; i++) { - allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); - allocations[i].reverseCorrectIt(); - allocations[i].saveEx(get_TrxName()); + if (accrual) + { + allocations[i].setDocAction(DocAction.ACTION_Reverse_Accrual); + allocations[i].reverseAccrualIt(); + allocations[i].saveEx(get_TrxName()); + } + else + { + allocations[i].setDocAction(DocAction.ACTION_Reverse_Correct); + allocations[i].reverseCorrectIt(); + allocations[i].saveEx(get_TrxName()); + } } // Reverse/Delete Matching if (!isSOTrx()) { - MMatchInv[] mInv = MMatchInv.getInvoice(getCtx(), getC_Invoice_ID(), get_TrxName()); - for (int i = 0; i < mInv.length; i++) - mInv[i].delete(true); - MMatchPO[] mPO = MMatchPO.getInvoice(getCtx(), getC_Invoice_ID(), get_TrxName()); - for (int i = 0; i < mPO.length; i++) + if (accrual) { - if (mPO[i].getM_InOutLine_ID() == 0) - mPO[i].delete(true); - else + MMatchInv[] mInv = MMatchInv.getInvoice(getCtx(), getC_Invoice_ID(), get_TrxName()); + for (int i = 0; i < mInv.length; i++) { - mPO[i].setC_InvoiceLine_ID(null); - mPO[i].saveEx(get_TrxName()); + if (!mInv[i].reverse(reversalDate)) + { + m_processMsg = "Could not Reverse MatchInv"; + return null; + } + } + MMatchPO[] mPO = MMatchPO.getInvoice(getCtx(), getC_Invoice_ID(), get_TrxName()); + for (int i = 0; i < mPO.length; i++) + { + if (mPO[i].getM_InOutLine_ID() == 0) + { + if (!mPO[i].reverse(reversalDate)) + { + m_processMsg = "Could not Reverse MatchPO"; + return null; + } + } + else + { + mPO[i].setC_InvoiceLine_ID(null); + mPO[i].saveEx(get_TrxName()); + } + } + } + else + { + MMatchInv[] mInv = MMatchInv.getInvoice(getCtx(), getC_Invoice_ID(), get_TrxName()); + for (int i = 0; i < mInv.length; i++) + { + mInv[i].deleteEx(true); + } + MMatchPO[] mPO = MMatchPO.getInvoice(getCtx(), getC_Invoice_ID(), get_TrxName()); + for (int i = 0; i < mPO.length; i++) + { + if (mPO[i].getM_InOutLine_ID() == 0) + mPO[i].deleteEx(true); + else + { + mPO[i].setC_InvoiceLine_ID(null); + mPO[i].saveEx(get_TrxName()); + } } } } @@ -2298,13 +2362,13 @@ public class MInvoice extends X_C_Invoice implements DocAction // Deep Copy MInvoice reversal = null; if (MSysConfig.getBooleanValue(MSysConfig.Invoice_ReverseUseNewNumber, true, getAD_Client_ID())) - reversal = copyFrom (this, getDateInvoiced(), getDateAcct(), getC_DocType_ID(), isSOTrx(), false, get_TrxName(), true); + reversal = copyFrom (this, reversalDateInvoiced, reversalDate, getC_DocType_ID(), isSOTrx(), false, get_TrxName(), true); else - reversal = copyFrom (this, getDateInvoiced(), getDateAcct(), getC_DocType_ID(), isSOTrx(), false, get_TrxName(), true, getDocumentNo()+"^"); + reversal = copyFrom (this, reversalDateInvoiced, reversalDate, getC_DocType_ID(), isSOTrx(), false, get_TrxName(), true, getDocumentNo()+"^"); if (reversal == null) { m_processMsg = "Could not create Invoice Reversal"; - return false; + return null; } reversal.setReversal(true); @@ -2323,7 +2387,7 @@ public class MInvoice extends X_C_Invoice implements DocAction if (!rLine.save(get_TrxName())) { m_processMsg = "Could not correct Invoice Reversal Line"; - return false; + return null; } } reversal.setC_Order_ID(getC_Order_ID()); @@ -2336,7 +2400,7 @@ public class MInvoice extends X_C_Invoice implements DocAction if (!reversal.processIt(DocAction.ACTION_Complete)) { m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); - return false; + return null; } reversal.setC_Payment_ID(0); reversal.setIsPaid(true); @@ -2345,7 +2409,6 @@ public class MInvoice extends X_C_Invoice implements DocAction reversal.setDocStatus(DOCSTATUS_Reversed); reversal.setDocAction(DOCACTION_None); reversal.saveEx(get_TrxName()); - m_processMsg = reversal.getDocumentNo(); // msgadd = new StringBuilder("(").append(reversal.getDocumentNo()).append("<-)"); addDescription(msgadd.toString()); @@ -2375,7 +2438,7 @@ public class MInvoice extends X_C_Invoice implements DocAction // Create Allocation StringBuilder msgall = new StringBuilder().append(Msg.translate(getCtx(), "C_Invoice_ID")).append(": ").append(getDocumentNo()).append("/").append(reversal.getDocumentNo()); - MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, getDateAcct(), + MAllocationHdr alloc = new MAllocationHdr(getCtx(), false, reversalDate, getC_Currency_ID(), msgall.toString(), get_TrxName()); @@ -2402,14 +2465,9 @@ public class MInvoice extends X_C_Invoice implements DocAction // end added alloc.saveEx(); } - - // After reverseCorrect - m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); - if (m_processMsg != null) - return false; - - return true; - } // reverseCorrectIt + + return reversal; + } /** * Reverse Accrual - none @@ -2423,12 +2481,18 @@ public class MInvoice extends X_C_Invoice implements DocAction if (m_processMsg != null) return false; + MInvoice reversal = reverse(true); + if (reversal == null) + return false; + // After reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL); if (m_processMsg != null) return false; - return false; + m_processMsg = reversal.getDocumentNo(); + + return true; } // reverseAccrualIt /** diff --git a/org.adempiere.base/src/org/compiere/model/MMatchInv.java b/org.adempiere.base/src/org/compiere/model/MMatchInv.java index c58537f755..347bd69cf8 100644 --- a/org.adempiere.base/src/org/compiere/model/MMatchInv.java +++ b/org.adempiere.base/src/org/compiere/model/MMatchInv.java @@ -419,5 +419,30 @@ public class MMatchInv extends X_M_MatchInv } // getInOutLine // end Bayu - + /** + * Reverse MatchPO. + * @param reversalDate + * @return message + * @throws Exception + */ + public boolean reverse(Timestamp reversalDate) + { + if (this.isPosted()) + { + MMatchInv reversal = new MMatchInv (getCtx(), 0, get_TrxName()); + PO.copyValues(this, reversal); + reversal.setAD_Org_ID(this.getAD_Org_ID()); + reversal.setDescription("(->" + this.getDocumentNo() + ")"); + reversal.setQty(this.getQty().negate()); + reversal.setDateAcct(reversalDate); + reversal.setDateTrx(reversalDate); + reversal.set_ValueNoCheck ("DocumentNo", null); + reversal.setPosted (false); + reversal.setReversal_ID(getM_MatchInv_ID()); + this.setDescription("(" + this.getDocumentNo() + "<-)"); + if (reversal.save() && this.save()) + return true; + } + return false; + } } // MMatchInv diff --git a/org.adempiere.base/src/org/compiere/model/MMatchPO.java b/org.adempiere.base/src/org/compiere/model/MMatchPO.java index d35723c0ff..8a3405a591 100644 --- a/org.adempiere.base/src/org/compiere/model/MMatchPO.java +++ b/org.adempiere.base/src/org/compiere/model/MMatchPO.java @@ -1165,5 +1165,34 @@ public class MMatchPO extends X_M_MatchPO return ""; } - + + /** + * Reverse MatchPO. + * @param reversalDate + * @return boolean + * @throws Exception + */ + + public boolean reverse(Timestamp reversalDate) + { + if (this.isPosted()) + { + MMatchPO reversal = new MMatchPO (getCtx(), 0, get_TrxName()); + reversal.setC_InvoiceLine_ID(getC_InvoiceLine_ID()); + reversal.setM_InOutLine_ID(getM_InOutLine_ID()); + PO.copyValues(this, reversal); + reversal.setAD_Org_ID(this.getAD_Org_ID()); + reversal.setDescription("(->" + this.getDocumentNo() + ")"); + reversal.setQty(this.getQty().negate()); + reversal.setDateAcct(reversalDate); + reversal.setDateTrx(reversalDate); + reversal.set_ValueNoCheck ("DocumentNo", null); + reversal.setPosted (false); + reversal.setReversal_ID(getM_MatchPO_ID()); + this.setDescription("(" + this.getDocumentNo() + "<-)"); + if (reversal.save() && this.save()) + return true; + } + return false; + } } // MMatchPO diff --git a/org.adempiere.base/src/org/compiere/model/MPayment.java b/org.adempiere.base/src/org/compiere/model/MPayment.java index b1b10f6bcb..26d574cffc 100644 --- a/org.adempiere.base/src/org/compiere/model/MPayment.java +++ b/org.adempiere.base/src/org/compiere/model/MPayment.java @@ -2440,14 +2440,30 @@ public final class MPayment extends X_C_Payment if (m_processMsg != null) return false; - if (!voidOnlinePayment()) + StringBuilder info = reverse(false); + if (info == null) { return false; + } + + // After reverseCorrect + m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); + if (m_processMsg != null) + return false; + + m_processMsg = info.toString(); + return true; + } // reverseCorrectionIt + + private StringBuilder reverse(boolean accrual) { + if (!voidOnlinePayment()) + return null; // Std Period open? - Timestamp dateAcct = getDateAcct(); - if (!MPeriod.isOpen(getCtx(), dateAcct, - isReceipt() ? X_C_DocType.DOCBASETYPE_ARReceipt : X_C_DocType.DOCBASETYPE_APPayment, getAD_Org_ID())) + Timestamp dateAcct = accrual ? Env.getContextAsDate(getCtx(), "#Date") : getDateAcct(); + if (dateAcct == null) { dateAcct = new Timestamp(System.currentTimeMillis()); + } + MPeriod.testPeriodOpen(getCtx(), dateAcct, getC_DocType_ID(), getAD_Org_ID()); // Auto Reconcile if not on Bank Statement boolean reconciled = getC_BankStatementLine_ID() == 0; //AZ Goodwill @@ -2491,7 +2507,7 @@ public final class MPayment extends X_C_Payment if (!reversal.processIt(DocAction.ACTION_Complete)) { m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg(); - return false; + return null; } reversal.closeIt(); reversal.setDocStatus(DOCSTATUS_Reversed); @@ -2540,7 +2556,7 @@ public final class MPayment extends X_C_Payment // end added alloc.saveEx(get_TrxName()); // - StringBuffer info = new StringBuffer (reversal.getDocumentNo()); + StringBuilder info = new StringBuilder(reversal.getDocumentNo()); info.append(" - @C_AllocationHdr_ID@: ").append(alloc.getDocumentNo()); // Update BPartner @@ -2549,15 +2565,11 @@ public final class MPayment extends X_C_Payment MBPartner bp = new MBPartner (getCtx(), getC_BPartner_ID(), get_TrxName()); bp.setTotalOpenBalance(); bp.saveEx(get_TrxName()); - } - // After reverseCorrect - m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); - if (m_processMsg != null) - return false; + } + + return info; + } - m_processMsg = info.toString(); - return true; - } // reverseCorrectionIt /** * Get Bank Statement Line of payment or 0 @@ -2585,11 +2597,17 @@ public final class MPayment extends X_C_Payment if (m_processMsg != null) return false; + StringBuilder info = reverse(true); + if (info == null) { + return false; + } + // After reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL); if (m_processMsg != null) return false; + m_processMsg = info.toString(); return false; } // reverseAccrualIt diff --git a/org.adempiere.base/src/org/compiere/model/X_C_AllocationHdr.java b/org.adempiere.base/src/org/compiere/model/X_C_AllocationHdr.java index 6553b1b320..fa2893aad6 100644 --- a/org.adempiere.base/src/org/compiere/model/X_C_AllocationHdr.java +++ b/org.adempiere.base/src/org/compiere/model/X_C_AllocationHdr.java @@ -33,7 +33,7 @@ public class X_C_AllocationHdr extends PO implements I_C_AllocationHdr, I_Persis /** * */ - private static final long serialVersionUID = 20121031L; + private static final long serialVersionUID = 20121113L; /** Standard Constructor */ public X_C_AllocationHdr (Properties ctx, int C_AllocationHdr_ID, String trxName) @@ -475,4 +475,32 @@ public class X_C_AllocationHdr extends PO implements I_C_AllocationHdr, I_Persis } return false; } + + public org.compiere.model.I_C_AllocationHdr getReversal() throws RuntimeException + { + return (org.compiere.model.I_C_AllocationHdr)MTable.get(getCtx(), org.compiere.model.I_C_AllocationHdr.Table_Name) + .getPO(getReversal_ID(), get_TrxName()); } + + /** Set Reversal ID. + @param Reversal_ID + ID of document reversal + */ + public void setReversal_ID (int Reversal_ID) + { + if (Reversal_ID < 1) + set_Value (COLUMNNAME_Reversal_ID, null); + else + set_Value (COLUMNNAME_Reversal_ID, Integer.valueOf(Reversal_ID)); + } + + /** Get Reversal ID. + @return ID of document reversal + */ + public int getReversal_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_Reversal_ID); + if (ii == null) + return 0; + return ii.intValue(); + } } \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/X_M_MatchInv.java b/org.adempiere.base/src/org/compiere/model/X_M_MatchInv.java index 3e318cf47b..79953f2874 100644 --- a/org.adempiere.base/src/org/compiere/model/X_M_MatchInv.java +++ b/org.adempiere.base/src/org/compiere/model/X_M_MatchInv.java @@ -33,7 +33,7 @@ public class X_M_MatchInv extends PO implements I_M_MatchInv, I_Persistent /** * */ - private static final long serialVersionUID = 20121031L; + private static final long serialVersionUID = 20121113L; /** Standard Constructor */ public X_M_MatchInv (Properties ctx, int M_MatchInv_ID, String trxName) @@ -415,4 +415,32 @@ public class X_M_MatchInv extends PO implements I_M_MatchInv, I_Persistent return Env.ZERO; return bd; } + + public org.compiere.model.I_M_MatchInv getReversal() throws RuntimeException + { + return (org.compiere.model.I_M_MatchInv)MTable.get(getCtx(), org.compiere.model.I_M_MatchInv.Table_Name) + .getPO(getReversal_ID(), get_TrxName()); } + + /** Set Reversal ID. + @param Reversal_ID + ID of document reversal + */ + public void setReversal_ID (int Reversal_ID) + { + if (Reversal_ID < 1) + set_Value (COLUMNNAME_Reversal_ID, null); + else + set_Value (COLUMNNAME_Reversal_ID, Integer.valueOf(Reversal_ID)); + } + + /** Get Reversal ID. + @return ID of document reversal + */ + public int getReversal_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_Reversal_ID); + if (ii == null) + return 0; + return ii.intValue(); + } } \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/X_M_MatchPO.java b/org.adempiere.base/src/org/compiere/model/X_M_MatchPO.java index ceeba9819e..517bc7b4b0 100644 --- a/org.adempiere.base/src/org/compiere/model/X_M_MatchPO.java +++ b/org.adempiere.base/src/org/compiere/model/X_M_MatchPO.java @@ -33,7 +33,7 @@ public class X_M_MatchPO extends PO implements I_M_MatchPO, I_Persistent /** * */ - private static final long serialVersionUID = 20121031L; + private static final long serialVersionUID = 20121113L; /** Standard Constructor */ public X_M_MatchPO (Properties ctx, int M_MatchPO_ID, String trxName) @@ -487,4 +487,32 @@ public class X_M_MatchPO extends PO implements I_M_MatchPO, I_Persistent return Env.ZERO; return bd; } + + public org.compiere.model.I_M_MatchPO getReversal() throws RuntimeException + { + return (org.compiere.model.I_M_MatchPO)MTable.get(getCtx(), org.compiere.model.I_M_MatchPO.Table_Name) + .getPO(getReversal_ID(), get_TrxName()); } + + /** Set Reversal ID. + @param Reversal_ID + ID of document reversal + */ + public void setReversal_ID (int Reversal_ID) + { + if (Reversal_ID < 1) + set_Value (COLUMNNAME_Reversal_ID, null); + else + set_Value (COLUMNNAME_Reversal_ID, Integer.valueOf(Reversal_ID)); + } + + /** Get Reversal ID. + @return ID of document reversal + */ + public int getReversal_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_Reversal_ID); + if (ii == null) + return 0; + return ii.intValue(); + } } \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/process/DocumentEngine.java b/org.adempiere.base/src/org/compiere/process/DocumentEngine.java index bef50b5c82..c7f2497342 100644 --- a/org.adempiere.base/src/org/compiere/process/DocumentEngine.java +++ b/org.adempiere.base/src/org/compiere/process/DocumentEngine.java @@ -976,6 +976,7 @@ public class DocumentEngine implements DocAction { options[index++] = DocumentEngine.ACTION_Void; options[index++] = DocumentEngine.ACTION_Reverse_Correct; + options[index++] = DocumentEngine.ACTION_Reverse_Accrual; } } /******************** @@ -988,6 +989,7 @@ public class DocumentEngine implements DocAction { options[index++] = DocumentEngine.ACTION_Void; options[index++] = DocumentEngine.ACTION_Reverse_Correct; + options[index++] = DocumentEngine.ACTION_Reverse_Accrual; } } /******************** @@ -1000,6 +1002,7 @@ public class DocumentEngine implements DocAction { options[index++] = DocumentEngine.ACTION_Void; options[index++] = DocumentEngine.ACTION_Reverse_Correct; + options[index++] = DocumentEngine.ACTION_Reverse_Accrual; } } /******************** @@ -1025,6 +1028,7 @@ public class DocumentEngine implements DocAction { options[index++] = DocumentEngine.ACTION_Void; options[index++] = DocumentEngine.ACTION_Reverse_Correct; + options[index++] = DocumentEngine.ACTION_Reverse_Accrual; } } //[ 1782412 ] @@ -1061,6 +1065,7 @@ public class DocumentEngine implements DocAction { options[index++] = DocumentEngine.ACTION_Void; options[index++] = DocumentEngine.ACTION_Reverse_Correct; + options[index++] = DocumentEngine.ACTION_Reverse_Accrual; } } /******************** @@ -1244,4 +1249,33 @@ public class DocumentEngine implements DocAction return error; } // postImmediate + /** + * Process document. This replaces DocAction.processIt(). + * @param doc + * @param processAction + * @return true if performed + */ + public static boolean processIt(DocAction doc, String processAction) { + boolean success = false; + + //ensure doc status not change by other session + if (doc instanceof PO) { + PO docPO = (PO) doc; + if (docPO.get_ID() > 0 && docPO.get_TrxName() != null && docPO.get_ValueOld("DocStatus") != null) { + DB.getDatabase().forUpdate(docPO, 30); + String docStatusOriginal = (String) docPO.get_ValueOld("DocStatus"); + String currentStatus = DB.getSQLValueString((String)null, + "SELECT DocStatus FROM " + docPO.get_TableName() + " WHERE " + docPO.get_KeyColumns()[0] + " = ? ", + docPO.get_ID()); + if (!docStatusOriginal.equals(currentStatus) && currentStatus != null) { + throw new IllegalStateException("Document status have been change by other session, please refresh your window and try again. " + docPO.toString()); + } + } + } + + DocumentEngine engine = new DocumentEngine(doc, doc.getDocStatus()); + success = engine.processIt(processAction, doc.getDocAction()); + + return success; + } } // DocumentEnine