From 066f24162e245674d78aa02c649e5bf8fa841665 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 26 Oct 2012 00:03:39 -0500 Subject: [PATCH] IDEMPIERE-454 Easy import / v1 -> Exporter - export data from 1 tab / Importer - allow insert in 1 tab --- .../oracle/928_IDEMPIERE-454.sql | 93 ++++ .../postgresql/928_IDEMPIERE-454.sql | 93 ++++ org.adempiere.base/plugin.xml | 10 + .../org.adempiere.base.IGridTabImporter.exsd | 141 ++++++ .../org/adempiere/base/IGridTabExporter.java | 5 + .../org/adempiere/base/IGridTabImporter.java | 59 +++ .../adempiere/impexp/GridTabCSVExporter.java | 44 +- .../adempiere/impexp/GridTabCSVImporter.java | 433 ++++++++++++++++++ .../impexp/GridTabExcelExporter.java | 5 + .../src/org/compiere/model/GridTable.java | 25 +- .../adempiere/pipo2/GridTab2PackExporter.java | 5 + .../webui/adwindow/ADWindowToolbar.java | 14 +- .../adwindow/AbstractADWindowContent.java | 21 +- .../webui/event/ToolbarListener.java | 5 + .../webui/panel/action/ExportAction.java | 4 +- .../webui/panel/action/FileImportAction.java | 277 +++++++++++ org.adempiere.ui.zk/images/FileImport16.png | Bin 0 -> 3343 bytes org.adempiere.ui.zk/images/FileImport24.png | Bin 0 -> 3919 bytes 18 files changed, 1196 insertions(+), 38 deletions(-) create mode 100644 migration/360lts-release/oracle/928_IDEMPIERE-454.sql create mode 100644 migration/360lts-release/postgresql/928_IDEMPIERE-454.sql create mode 100644 org.adempiere.base/schema/org.adempiere.base.IGridTabImporter.exsd create mode 100644 org.adempiere.base/src/org/adempiere/base/IGridTabImporter.java create mode 100644 org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/FileImportAction.java create mode 100644 org.adempiere.ui.zk/images/FileImport16.png create mode 100644 org.adempiere.ui.zk/images/FileImport24.png diff --git a/migration/360lts-release/oracle/928_IDEMPIERE-454.sql b/migration/360lts-release/oracle/928_IDEMPIERE-454.sql new file mode 100644 index 0000000000..97272a59a5 --- /dev/null +++ b/migration/360lts-release/oracle/928_IDEMPIERE-454.sql @@ -0,0 +1,93 @@ +-- Oct 7, 2012 7:15:57 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_ToolBarButton (Name,ComponentName,Classname,IsCustomization,KeyStroke_KeyCode,KeyStroke_Modifiers,AD_Client_ID,AD_Org_ID,Created,CreatedBy,AD_ToolBarButton_ID,Updated,UpdatedBy,IsActive,AD_ToolBarButton_UU) VALUES ('zk Window - File Import','FileImport','org.idempiere.ui.window','N',0,0,0,0,TO_DATE('2012-10-07 19:15:57','YYYY-MM-DD HH24:MI:SS'),100,1000007,TO_DATE('2012-10-07 19:15:57','YYYY-MM-DD HH24:MI:SS'),100,'Y','afdd17a6-5fd1-411e-8596-5310aa68785f') +; + +-- Oct 25, 2012 11:42:24 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','Field {0} not found',200082,'D','a41866df-ebaf-4ea4-a5be-694b21d076c6','FieldNotFound','Y',TO_DATE('2012-10-25 23:42:22','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-10-25 23:42:22','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:42:24 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200082 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:43:32 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','{0} not a window field',200083,'D','ff2e000e-330e-40d7-8da2-37c558c02fae','NotAWindowField','Y',TO_DATE('2012-10-25 23:43:31','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-10-25 23:43:31','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:43:32 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200083 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:45:01 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','{0} is readonly',200084,'D','914303a5-b1b7-46db-9d3d-953258f1815c','FieldIsReadOnly','Y',TO_DATE('2012-10-25 23:45:00','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-10-25 23:45:00','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:45:01 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200084 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:45:50 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','{0} is not displayed',200085,'D','6406807b-ead4-4bbe-9221-8d3936e77f22','FieldNotDisplayed','Y',TO_DATE('2012-10-25 23:45:49','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-10-25 23:45:49','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:45:50 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200085 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:46:55 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','{0} not resolved = ({1})',200086,'D','bbaa12b8-df37-4a2a-812f-144bbfdef1a9','ForeignNotResolved','Y',TO_DATE('2012-10-25 23:46:53','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-10-25 23:46:53','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:46:55 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200086 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:48:44 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','ERROR: {0} parent cannot be changed',200087,'D','a47623df-6f91-42ad-9172-2459a680c3cf','ParentCannotChange','Y',TO_DATE('2012-10-25 23:48:43','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-10-25 23:48:43','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:48:44 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200087 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:49:42 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','ERROR: {0} not editable',200088,'D','78a73537-7dee-44cc-b66d-76cfba2fb199','FieldNotEditable','Y',TO_DATE('2012-10-25 23:49:40','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-10-25 23:49:40','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:49:42 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200088 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:50:46 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','Successfully saved [{0}]',200089,'D','9d255a1a-e4ea-402b-98ee-ad168603b4c5','SuccessfullySaved','Y',TO_DATE('2012-10-25 23:50:45','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-10-25 23:50:45','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:50:46 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200089 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:50:57 PM COT +-- IDEMPIERE-454 Easy import +UPDATE AD_Message SET MsgType='I',Updated=TO_DATE('2012-10-25 23:50:57','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200089 +; + +SELECT register_migration_script('928_IDEMPIERE-454.sql') FROM dual +; + diff --git a/migration/360lts-release/postgresql/928_IDEMPIERE-454.sql b/migration/360lts-release/postgresql/928_IDEMPIERE-454.sql new file mode 100644 index 0000000000..cda2b6664e --- /dev/null +++ b/migration/360lts-release/postgresql/928_IDEMPIERE-454.sql @@ -0,0 +1,93 @@ +-- Oct 7, 2012 7:15:57 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_ToolBarButton (Name,ComponentName,Classname,IsCustomization,KeyStroke_KeyCode,KeyStroke_Modifiers,AD_Client_ID,AD_Org_ID,Created,CreatedBy,AD_ToolBarButton_ID,Updated,UpdatedBy,IsActive,AD_ToolBarButton_UU) VALUES ('zk Window - File Import','FileImport','org.idempiere.ui.window','N',0,0,0,0,TO_TIMESTAMP('2012-10-07 19:15:57','YYYY-MM-DD HH24:MI:SS'),100,1000007,TO_TIMESTAMP('2012-10-07 19:15:57','YYYY-MM-DD HH24:MI:SS'),100,'Y','afdd17a6-5fd1-411e-8596-5310aa68785f') +; + +-- Oct 25, 2012 11:42:24 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','Field {0} not found',200082,'D','a41866df-ebaf-4ea4-a5be-694b21d076c6','FieldNotFound','Y',TO_TIMESTAMP('2012-10-25 23:42:22','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-10-25 23:42:22','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:42:24 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200082 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:43:32 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','{0} not a window field',200083,'D','ff2e000e-330e-40d7-8da2-37c558c02fae','NotAWindowField','Y',TO_TIMESTAMP('2012-10-25 23:43:31','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-10-25 23:43:31','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:43:32 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200083 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:45:01 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','{0} is readonly',200084,'D','914303a5-b1b7-46db-9d3d-953258f1815c','FieldIsReadOnly','Y',TO_TIMESTAMP('2012-10-25 23:45:00','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-10-25 23:45:00','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:45:01 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200084 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:45:50 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','{0} is not displayed',200085,'D','6406807b-ead4-4bbe-9221-8d3936e77f22','FieldNotDisplayed','Y',TO_TIMESTAMP('2012-10-25 23:45:49','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-10-25 23:45:49','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:45:50 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200085 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:46:55 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','{0} not resolved = ({1})',200086,'D','bbaa12b8-df37-4a2a-812f-144bbfdef1a9','ForeignNotResolved','Y',TO_TIMESTAMP('2012-10-25 23:46:53','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-10-25 23:46:53','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:46:55 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200086 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:48:44 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','ERROR: {0} parent cannot be changed',200087,'D','a47623df-6f91-42ad-9172-2459a680c3cf','ParentCannotChange','Y',TO_TIMESTAMP('2012-10-25 23:48:43','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-10-25 23:48:43','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:48:44 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200087 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:49:42 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','ERROR: {0} not editable',200088,'D','78a73537-7dee-44cc-b66d-76cfba2fb199','FieldNotEditable','Y',TO_TIMESTAMP('2012-10-25 23:49:40','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-10-25 23:49:40','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:49:42 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200088 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:50:46 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','Successfully saved [{0}]',200089,'D','9d255a1a-e4ea-402b-98ee-ad168603b4c5','SuccessfullySaved','Y',TO_TIMESTAMP('2012-10-25 23:50:45','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-10-25 23:50:45','YYYY-MM-DD HH24:MI:SS')) +; + +-- Oct 25, 2012 11:50:46 PM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200089 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) +; + +-- Oct 25, 2012 11:50:57 PM COT +-- IDEMPIERE-454 Easy import +UPDATE AD_Message SET MsgType='I',Updated=TO_TIMESTAMP('2012-10-25 23:50:57','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200089 +; + +SELECT register_migration_script('928_IDEMPIERE-454.sql') FROM dual +; + diff --git a/org.adempiere.base/plugin.xml b/org.adempiere.base/plugin.xml index 79aa4c8727..a6535ada32 100644 --- a/org.adempiere.base/plugin.xml +++ b/org.adempiere.base/plugin.xml @@ -12,6 +12,7 @@ + + + + + + + + + + + + + Extension point to provide import service for data from that is generated from the AD_Window definition. The client in use ( swing or zk ) is responsible to present all available import extension to user to pick the one to use. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + numeric priority value, higher value is of higher priority. + + + + + + + Implementation class name for the org.adempiere.base.IGridTabImporter interface + + + + + + + + + + + + + + + 1.0.0 + + + + + + + + + <pre> +<extension + id="org.adempiere.impexp.GridTabCSVImporter" + name="Grid data CSV importer" + point="org.adempiere.base.IGridTabImporter"> + <importer + class="org.adempiere.impexp.GridTabCSVImporter" + priority="0"> + </importer> +</extension> +</pre> + + + + + + + + + The class attribute must represent an implementor of org.adempiere.base.IGridTabImporter + + + + + + + + + CSV import in org.adempiere.base + + + + + + + + + This file is part of iDempiere ERP http://www.idempiere.org. + + Copyright (C) Carlos Ruiz + Copyright (C) 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. + + + + + diff --git a/org.adempiere.base/src/org/adempiere/base/IGridTabExporter.java b/org.adempiere.base/src/org/adempiere/base/IGridTabExporter.java index 80403c8d28..cfcfef6647 100644 --- a/org.adempiere.base/src/org/adempiere/base/IGridTabExporter.java +++ b/org.adempiere.base/src/org/adempiere/base/IGridTabExporter.java @@ -48,4 +48,9 @@ public interface IGridTabExporter { * @return mime type */ public String getContentType(); + + /** + * @return suggested file name + */ + public String getSuggestedFileName(GridTab gridTab); } diff --git a/org.adempiere.base/src/org/adempiere/base/IGridTabImporter.java b/org.adempiere.base/src/org/adempiere/base/IGridTabImporter.java new file mode 100644 index 0000000000..f927a1024a --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/IGridTabImporter.java @@ -0,0 +1,59 @@ +/****************************************************************************** + * Product: iDempiere ERP & CRM Smart Business Solution * + * Copyright (C) 2012 Trek Global * + * Copyright (C) 2012 Carlos Ruiz * + * 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.base; + +import java.io.File; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.List; + +import org.compiere.model.GridTab; + +/** + * + * @author Carlos Ruiz + * + */ +public interface IGridTabImporter { + + /** + * export gridTab data to file + * @param gridTab + * @param childs + * @param filestream + * @param charset + */ + public File fileImport(GridTab gridTab, List childs, InputStream filestream, Charset charset); + + /** + * @return file extension + */ + public String getFileExtension(); + + /** + * @return description for file extension + */ + public String getFileExtensionLabel(); + + /** + * @return mime type + */ + public String getContentType(); + + /** + * @return suggested file name + */ + public String getSuggestedFileName(GridTab gridTab); +} diff --git a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVExporter.java b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVExporter.java index e3a4cf6fa2..16442a8289 100644 --- a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVExporter.java +++ b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVExporter.java @@ -17,6 +17,7 @@ package org.adempiere.impexp; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -25,6 +26,7 @@ import java.util.List; import java.util.Map; import org.adempiere.base.IGridTabExporter; +import org.adempiere.exceptions.AdempiereException; import org.adempiere.model.MTabCustomization; import org.compiere.model.GridField; import org.compiere.model.GridTab; @@ -77,7 +79,9 @@ public class GridTabCSVExporter implements IGridTabExporter } else if (DisplayType.Time == column.getAD_Reference_ID()) { procArray.add(new Optional(new FmtDate("DisplayType.DEFAULT_TIME_FORMAT"))); } else if (DisplayType.Integer == column.getAD_Reference_ID() || DisplayType.isNumeric(column.getAD_Reference_ID())) { - procArray.add(new Optional(new FmtNumber(DisplayType.getNumberFormat(column.getAD_Reference_ID())))); + DecimalFormat nf = DisplayType.getNumberFormat(column.getAD_Reference_ID()); + nf.setGroupingUsed(false); + procArray.add(new Optional(new FmtNumber(nf))); } else if (DisplayType.YesNo == column.getAD_Reference_ID()) { procArray.add(new Optional(new FmtBool("Y", "N"))); } else { // lookups and text @@ -110,7 +114,7 @@ public class GridTabCSVExporter implements IGridTabExporter mapWriter.write(row, header, processors); } } catch (IOException e) { - e.printStackTrace(); + throw new AdempiereException(e); } finally { if (mapWriter != null) { try { @@ -125,7 +129,7 @@ public class GridTabCSVExporter implements IGridTabExporter private Object resolveValue(GridTab gridTab, MTable table, MColumn column, int i, String headName) { Object value = null; - if (headName.contains("[") && headName.endsWith("]")) { + if (headName.indexOf("[") >= 0 && headName.endsWith("]")) { String foreignTable = column.getReferenceTableName(); Object idO = gridTab.getValue(i, column.getColumnName()); if (idO != null) { @@ -157,12 +161,14 @@ public class GridTabCSVExporter implements IGridTabExporter String foreignTable = column.getReferenceTableName(); if ( ! ("AD_Language".equals(foreignTable) || "AD_EntityType".equals(foreignTable))) { MTable fTable = MTable.get(Env.getCtx(), foreignTable); - // Hardcoded / do not check for Value on AD_Org and AD_User, must use name for these two tables - if (! ("AD_Org".equals(foreignTable) || "AD_User".equals(foreignTable)) + // Hardcoded / do not check for Value on AD_Org, AD_User and AD_Ref_List, must use name for these two tables + if (! ("AD_Org".equals(foreignTable) || "AD_User".equals(foreignTable) || "AD_Ref_List".equals(foreignTable)) && fTable.getColumn("Value") != null) { name.append("[Value]"); // fully qualified } else if (fTable.getColumn("Name") != null) { name.append("[Name]"); + } else if (fTable.getColumn("DocumentNo") != null) { + name.append("[DocumentNo]"); } } } @@ -197,16 +203,16 @@ public class GridTabCSVExporter implements IGridTabExporter String[] customComponent = custom.split(";"); String[] fieldIds = customComponent[0].split("[,]"); List fieldList = new ArrayList(); - for(String fieldIdStr : fieldIds) + for (String fieldIdStr : fieldIds) { fieldIdStr = fieldIdStr.trim(); if (fieldIdStr.length() == 0) continue; int AD_Field_ID = Integer.parseInt(fieldIdStr); - for(GridField gridField : tmpFields) + for (GridField gridField : tmpFields) { if (gridField.getAD_Field_ID() == AD_Field_ID) { - if(gridField.isDisplayedGrid()) + if (!gridField.isReadOnly() && gridField.isDisplayedGrid()) fieldList.add(gridField); break; @@ -219,9 +225,11 @@ public class GridTabCSVExporter implements IGridTabExporter { ArrayList gridFieldList = new ArrayList(); - for(GridField field:tmpFields) + for (GridField field:tmpFields) { - if(field.isDisplayedGrid()) + if ("AD_Client_ID".equals(field.getColumnName())) + continue; + if (field.isParentValue() || (!field.isReadOnly() && field.isDisplayedGrid())) gridFieldList.add(field); } @@ -238,19 +246,9 @@ public class GridTabCSVExporter implements IGridTabExporter return gridFields; } - public boolean isColumnPrinted(GridTab tab, int col) - { - GridField field = tab.getField(col); - // field not displayed - if (!field.isDisplayed()) - return false; - // field encrypted - if (field.isEncrypted()) - return false; - // button without a reference value - if (field.getDisplayType() == DisplayType.Button && field.getAD_Reference_Value_ID() == 0) - return false; - return true; + @Override + public String getSuggestedFileName(GridTab gridTab) { + return "Export_" + gridTab.getTableName() + "." + getFileExtension(); } } diff --git a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java new file mode 100644 index 0000000000..1bc5affbc5 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java @@ -0,0 +1,433 @@ +/****************************************************************************** + * Product: iDempiere ERP & CRM Smart Business Solution * + * Copyright (C) 2012 Carlos Ruiz * + * 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.impexp; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.sql.Timestamp; +import java.text.DecimalFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import org.adempiere.base.IGridTabImporter; +import org.adempiere.exceptions.AdempiereException; +import org.compiere.model.GridField; +import org.compiere.model.GridTab; +import org.compiere.model.MColumn; +import org.compiere.model.MTable; +import org.compiere.tools.FileUtil; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.Language; +import org.compiere.util.Msg; +import org.compiere.util.Trx; +import org.compiere.util.ValueNamePair; +import org.supercsv.cellprocessor.Optional; +import org.supercsv.cellprocessor.ParseBigDecimal; +import org.supercsv.cellprocessor.ParseBool; +import org.supercsv.cellprocessor.ParseDate; +import org.supercsv.cellprocessor.ParseInt; +import org.supercsv.cellprocessor.constraint.StrMinMax; +import org.supercsv.cellprocessor.constraint.StrNotNullOrEmpty; +import org.supercsv.cellprocessor.ift.CellProcessor; +import org.supercsv.exception.SuperCsvCellProcessorException; +import org.supercsv.io.CsvMapReader; +import org.supercsv.io.ICsvMapReader; +import org.supercsv.prefs.CsvPreference; + +/** + * CSV Importer for GridTab + * @author Carlos Ruiz + */ +public class GridTabCSVImporter implements IGridTabImporter +{ + private static final String ERROR_HEADER = "_ERROR_"; + private static final String LOG_HEADER = "_LOG_"; + /** Logger */ + private static CLogger log = CLogger.getCLogger(GridTabCSVImporter.class); + boolean m_isError = false; + + public File fileImport(GridTab gridTab, List childs, InputStream filestream, Charset charset) { + + ICsvMapReader mapReader = null; + File errFile = null; + File logFile = null; + FileWriter errFileW = null; + FileWriter logFileW = null; + CsvPreference csvpref = CsvPreference.STANDARD_PREFERENCE; + String delimiter = String.valueOf((char) csvpref.getDelimiterChar()); + String quoteChar = String.valueOf((char) csvpref.getQuoteChar()); + try { + String errFileName = FileUtil.getTempMailName("Import_" + gridTab.getTableName(), "_err.csv"); + errFile = new File(errFileName); + errFileW = new FileWriter(errFile, false); + mapReader = new CsvMapReader(new InputStreamReader(filestream), csvpref); + + String[] header = mapReader.getHeader(true); + List readProcArray = new ArrayList(); + for (int idx = 0; idx < header.length; idx++) { + String headName = header[idx]; + if (headName.equals(ERROR_HEADER) || headName.equals(LOG_HEADER)) { + header[idx] = null; + readProcArray.add(null); + continue; + } + String columnName = headName; + boolean isForeign = headName.indexOf("[") > 0 && headName.endsWith("]"); + if (isForeign) { + int end = headName.indexOf("["); + columnName = headName.substring(0, end); + } + GridField field = gridTab.getField(columnName); + if (field == null) { + throw new AdempiereException(Msg.getMsg(Env.getCtx(), "FieldNotFound", new Object[] {columnName})); + } + MColumn column = MColumn.get(Env.getCtx(), field.getAD_Column_ID()); + // TODO: List columns can use RequireSubStr constraint + if (column.isMandatory()) { + if (DisplayType.Date == column.getAD_Reference_ID()) { + readProcArray.add(new ParseDate(DisplayType.DEFAULT_DATE_FORMAT)); + } else if (DisplayType.DateTime == column.getAD_Reference_ID()) { + readProcArray.add(new ParseDate(DisplayType.DEFAULT_TIMESTAMP_FORMAT)); + } else if (DisplayType.Time == column.getAD_Reference_ID()) { + readProcArray.add(new ParseDate("DisplayType.DEFAULT_TIME_FORMAT")); + } else if (DisplayType.Integer == column.getAD_Reference_ID()) { + readProcArray.add(new ParseInt()); + } else if (DisplayType.isNumeric(column.getAD_Reference_ID())) { + readProcArray.add(new ParseBigDecimal(new DecimalFormatSymbols(Language.getLoginLanguage().getLocale()))); + } else if (DisplayType.YesNo == column.getAD_Reference_ID()) { + readProcArray.add(new ParseBool("y", "n")); + } else if (DisplayType.isText(column.getAD_Reference_ID())) { + readProcArray.add(new StrMinMax(1, column.getFieldLength())); + } else { // mandatory lookups + readProcArray.add(new StrNotNullOrEmpty()); + } + } else { + if (DisplayType.Date == column.getAD_Reference_ID()) { + readProcArray.add(new Optional(new ParseDate(DisplayType.DEFAULT_DATE_FORMAT))); + } else if (DisplayType.DateTime == column.getAD_Reference_ID()) { + readProcArray.add(new Optional(new ParseDate(DisplayType.DEFAULT_TIMESTAMP_FORMAT))); + } else if (DisplayType.Time == column.getAD_Reference_ID()) { + readProcArray.add(new Optional(new ParseDate("DisplayType.DEFAULT_TIME_FORMAT"))); + } else if (DisplayType.Integer == column.getAD_Reference_ID()) { + readProcArray.add(new Optional(new ParseInt())); + } else if (DisplayType.isNumeric(column.getAD_Reference_ID())) { + readProcArray.add(new Optional(new ParseBigDecimal(new DecimalFormatSymbols(Language.getLoginLanguage().getLocale())))); + } else if (DisplayType.YesNo == column.getAD_Reference_ID()) { + readProcArray.add(new Optional(new ParseBool("y", "n"))); + } else if (DisplayType.isText(column.getAD_Reference_ID())) { + readProcArray.add(new Optional(new StrMinMax(1, column.getFieldLength()))); + } else { // optional lookups and text + readProcArray.add(null); + } + } + } + CellProcessor[] processors = readProcArray.toArray(new CellProcessor[readProcArray.size()]); + + m_isError = false; + // write the header + String rawHeader = mapReader.getUntokenizedRow(); + errFileW.write(rawHeader + delimiter + ERROR_HEADER + "\n"); + + List> data = new ArrayList>(); + List rawData = new ArrayList(); + // pre-process to check for errors + while (true) { + Map map = null; + boolean isLineError = false; + StringBuilder errMsg = new StringBuilder(); + try { + map = mapReader.read(header, processors); + } catch (SuperCsvCellProcessorException e) { + int idx = e.getCsvContext().getColumnNumber() - 1; + errMsg.append(header[idx]).append(": ").append(e.getMessage()); + isLineError = true; + } + String rawLine = mapReader.getUntokenizedRow(); + if (! isLineError) { + if (map == null) + break; + for (Entry set : map.entrySet()) { + StringBuilder lineError = new StringBuilder(); + String headName = set.getKey(); + Object value = set.getValue(); + log.fine("Setting " + headName + " to " + value); + + String columnName = headName; + boolean isForeign = headName.indexOf("[") > 0 && headName.endsWith("]"); + String foreignColumn = null; + if (isForeign) { + int end = headName.indexOf("["); + columnName = headName.substring(0, end); + int startf = headName.indexOf("[")+1; + int endf = headName.length()-1; + foreignColumn = headName.substring(startf, endf); + } + GridField field = gridTab.getField(columnName); + if (field == null) { + lineError.append(Msg.getMsg(Env.getCtx(), "NotAWindowField", new Object[] {headName})); + isLineError = true; + } + if (!isLineError && field.isReadOnly() && !field.isParentValue()) { + lineError.append(Msg.getMsg(Env.getCtx(), "FieldIsReadOnly", new Object[] {headName})); + isLineError = true; + } + if (!isLineError && ! ( field.isDisplayed() || field.isDisplayedGrid() )) { + lineError.append(Msg.getMsg(Env.getCtx(), "FieldNotDisplayed", new Object[] {headName})); + isLineError = true; + } + if (!isLineError) { + MColumn column = MColumn.get(Env.getCtx(), field.getAD_Column_ID()); + if (isForeign) { + String foreignTable = column.getReferenceTableName(); + String idS = null; + int id = -1; + if ("AD_Ref_List".equals(foreignTable)) { + idS = resolveForeignList(column, foreignColumn, value); + } else { + id = resolveForeign(foreignTable, foreignColumn, value); + } + if (idS == null && id < 0) { + lineError.append(Msg.getMsg(Env.getCtx(), "ForeignNotResolved", new Object[] {headName, value.toString()})); + isLineError = true; + } + } else { + // no validation here + // TODO: we could validate length of string or min/max + } + } + if (isLineError && lineError.length() > 0) { + if (errMsg.length() > 0) + errMsg.append(" / "); + errMsg.append(lineError); + } + } + } + if (isLineError && ! m_isError) + m_isError = true; + if (!m_isError) { + data.add(map); + rawData.add(rawLine); + } + // write + rawLine = rawLine + delimiter + quoteChar + errMsg.toString().replaceAll(quoteChar, "") + quoteChar + "\n"; + errFileW.write(rawLine); + } + + if (!m_isError) { + String logFileName = FileUtil.getTempMailName("Import_" + gridTab.getTableName(), "_log.csv"); + logFile = new File(logFileName); + logFileW = new FileWriter(logFile, false); + + // write the header + logFileW.write(rawHeader + delimiter + LOG_HEADER + "\n"); + + // no errors found - then process + for (int idx = 0; idx < data.size(); idx++) { + String rawLine = rawData.get(idx); + String trxName = null; + String logMsg = null; + Trx trx = null; + boolean error = false; + try { + trxName = "Import_" + gridTab.getTableName() + "_" + UUID.randomUUID(); + trx = Trx.get(trxName, true); + Map map = data.get(idx); + gridTab.getTableModel().setImportingMode(true, trxName); + gridTab.dataNew(false); + for (String headName : header) { + if (headName == null) + continue; + Object value = map.get(headName); + + String columnName = headName; + boolean isForeign = headName.indexOf("[") > 0 && headName.endsWith("]"); + String foreignColumn = null; + if (isForeign) { + int end = headName.indexOf("["); + columnName = headName.substring(0, end); + int startf = headName.indexOf("[")+1; + int endf = headName.length()-1; + foreignColumn = headName.substring(startf, endf); + } + GridField field = gridTab.getField(columnName); + if (field.isParentValue()) + continue; + MColumn column = MColumn.get(Env.getCtx(), field.getAD_Column_ID()); + Object setValue = null; + if (isForeign) { + String foreignTable = column.getReferenceTableName(); + if ("AD_Ref_List".equals(foreignTable)) { + String idS = resolveForeignList(column, foreignColumn, value); + setValue = idS; + } else { + int id = resolveForeign(foreignTable, foreignColumn, value); + setValue = id; + if (field.isParentValue()) { + int actualId = (Integer) field.getValue(); + if (actualId != id) { + logMsg = Msg.getMsg(Env.getCtx(), "ParentCannotChange", new Object[] {headName}); + error = true; + break; + } + } + } + } else { + if (value != null) { + if (value != null && value instanceof java.util.Date) + value = new Timestamp(((java.util.Date)value).getTime()); + setValue = value; + } + } + if (value != null) { + if (field.isEditable(true)) { + gridTab.setValue(columnName, setValue); + } else { + logMsg = Msg.getMsg(Env.getCtx(), "FieldNotEditable", new Object[] {headName}); + error = true; + break; + } + } + } + if (! error) { + if (gridTab.dataSave(false)) { + logMsg = Msg.getMsg(Env.getCtx(), "SuccessfullySaved", new Object[] {gridTab.getTableModel().getKeyID(gridTab.getCurrentRow())}); + } else { + error = true; + ValueNamePair ppE = CLogger.retrieveWarning(); + String info = null; + if (ppE != null) + info = ppE.getName(); + if (info == null) + info = ""; + logMsg = Msg.getMsg(Env.getCtx(), "Error") + " " + Msg.getMsg(Env.getCtx(), "SaveError") + " (" + info + ")"; + gridTab.dataIgnore(); + } + } else { + gridTab.dataIgnore(); + } + } catch (Exception e) { + logMsg = Msg.getMsg(Env.getCtx(), "Error") + " " + e.getLocalizedMessage(); + error = true; + } finally { + if (trx != null) { + if (error) { + trx.rollback(); + } else { + trx.commit(); + } + trx.close(); + trx = null; + } + gridTab.getTableModel().setImportingMode(false, null); + } + // write + logMsg = logMsg.replaceAll(delimiter, ""); + rawLine = rawLine + delimiter + quoteChar + logMsg + quoteChar + "\n"; + logFileW.write(rawLine); + } + } + + } catch (IOException e) { + throw new AdempiereException(e); + } + finally { + try { + if (mapReader != null) + mapReader.close(); + if (errFileW != null) { + errFileW.flush(); + errFileW.close(); + } + if (logFileW != null) { + logFileW.flush(); + logFileW.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if (logFile != null) + return logFile; + else + return errFile; + } + + private String resolveForeignList(MColumn column, String foreignColumn, Object value) { + String idS = null; + StringBuilder select = new StringBuilder("SELECT Value FROM AD_Ref_List WHERE ") + .append(foreignColumn).append("=? AND AD_Reference_ID=? AND IsActive='Y'"); + idS = DB.getSQLValueStringEx(null, select.toString(), value, column.getAD_Reference_Value_ID()); + return idS; + } + + private int resolveForeign(String foreignTable, String foreignColumn, Object value) { + int id = -1; + StringBuilder select = new StringBuilder("SELECT ") + .append(foreignTable).append("_ID FROM ") + .append(foreignTable).append(" WHERE ") + .append(foreignColumn).append("=? AND IsActive='Y' AND AD_Client_ID=?"); + id = DB.getSQLValueEx(null, select.toString(), value, Env.getAD_Client_ID(Env.getCtx())); + if (id == -1 && !"AD_Client".equals(foreignTable)) { + MTable ft = MTable.get(Env.getCtx(), foreignTable); + String accessLevel = ft.getAccessLevel(); + if ( MTable.ACCESSLEVEL_All.equals(accessLevel) + || MTable.ACCESSLEVEL_SystemOnly.equals(accessLevel) + || MTable.ACCESSLEVEL_SystemPlusClient.equals(accessLevel)) { + // try System client if the table has System access + id = DB.getSQLValueEx(null, select.toString(), value, 0); + } + } + return id; + } + + @Override + public String getFileExtension() { + return "csv"; + } + + @Override + public String getFileExtensionLabel() { + return Msg.getMsg(Env.getCtx(), "FileCSV"); + } + + @Override + public String getContentType() { + return "application/csv"; + } + + @Override + public String getSuggestedFileName(GridTab gridTab) { + Calendar cal = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + String dt = sdf.format(cal.getTime()); + String localFile = "Import_" + gridTab.getTableName() + "_" + dt + + (m_isError ? "_err" : "_log") + + "." + getFileExtension(); + return localFile; + } + +} diff --git a/org.adempiere.base/src/org/adempiere/impexp/GridTabExcelExporter.java b/org.adempiere.base/src/org/adempiere/impexp/GridTabExcelExporter.java index 22ab472a0f..e8ffe79949 100644 --- a/org.adempiere.base/src/org/adempiere/impexp/GridTabExcelExporter.java +++ b/org.adempiere.base/src/org/adempiere/impexp/GridTabExcelExporter.java @@ -177,4 +177,9 @@ public class GridTabExcelExporter extends AbstractExcelExporter implements IGrid public String getContentType() { return "application/vnd.ms-excel"; } + + @Override + public String getSuggestedFileName(GridTab gridTab) { + return gridTab.getName() + "." + getFileExtension(); + } } diff --git a/org.adempiere.base/src/org/compiere/model/GridTable.java b/org.adempiere.base/src/org/compiere/model/GridTable.java index f086aef7bd..b25465508e 100644 --- a/org.adempiere.base/src/org/compiere/model/GridTable.java +++ b/org.adempiere.base/src/org/compiere/model/GridTable.java @@ -94,7 +94,7 @@ public class GridTable extends AbstractTableModel /** * */ - private static final long serialVersionUID = 4648364477309024202L; + private static final long serialVersionUID = 2328810326636468776L; public static final String DATA_REFRESH_MESSAGE = "Refreshed"; @@ -2040,10 +2040,12 @@ public class GridTable extends AbstractTableModel // MTable table = MTable.get (m_ctx, m_AD_Table_ID); PO po = null; + if (! m_importing) // Just use trx when importing + m_trxName = null; if (Record_ID != -1) - po = table.getPO(Record_ID, null); + po = table.getPO(Record_ID, m_trxName); else // Multi - Key - po = table.getPO(getWhereClause(rowData), null); + po = table.getPO(getWhereClause(rowData), m_trxName); // No Persistent Object if (po == null) throw new ClassNotFoundException ("No Persistent Object"); @@ -2374,6 +2376,10 @@ public class GridTable extends AbstractTableModel /** LOB Info */ private ArrayList m_lobInfo = null; + // IDEMPIERE-454 Easy import + private boolean m_importing = false; + private String m_trxName = null; + /** * Reset LOB info */ @@ -3707,10 +3713,19 @@ public class GridTable extends AbstractTableModel PO po = null; int Record_ID = getKeyID(row); if (Record_ID != -1) - po = table.getPO(Record_ID, null); + po = table.getPO(Record_ID, m_trxName); else // Multi - Key - po = table.getPO(getWhereClause(getDataAtRow(row)), null); + po = table.getPO(getWhereClause(getDataAtRow(row)), m_trxName); return po; } + + public void setImportingMode(boolean importing, String trxName) { + m_importing = importing; + m_trxName = trxName; + } + + public boolean isImporting() { + return m_importing; + } } diff --git a/org.adempiere.pipo/src/org/adempiere/pipo2/GridTab2PackExporter.java b/org.adempiere.pipo/src/org/adempiere/pipo2/GridTab2PackExporter.java index 7d2cfd20cf..86f4515cce 100644 --- a/org.adempiere.pipo/src/org/adempiere/pipo2/GridTab2PackExporter.java +++ b/org.adempiere.pipo/src/org/adempiere/pipo2/GridTab2PackExporter.java @@ -145,4 +145,9 @@ public class GridTab2PackExporter implements IGridTabExporter { public String getContentType() { return "application/zip"; } + + @Override + public String getSuggestedFileName(GridTab gridTab) { + return gridTab.getName() + "." + getFileExtension(); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java index 123b9d9bee..94b04bf7c4 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java @@ -59,7 +59,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener /** * */ - private static final long serialVersionUID = 904447827065380369L; + private static final long serialVersionUID = 3390505814516682801L; private static final String BTNPREFIX = "Btn"; @@ -85,7 +85,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener private ToolBarButton btnCustomize; - private ToolBarButton btnExport; + private ToolBarButton btnExport, btnFileImport; private ToolBarButton btnProcess; @@ -186,6 +186,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener { btnExport = createButton("Export", "Export", "Export"); } + btnFileImport = createButton("FileImport", "FileImport", "FileImport"); configureKeyMap(); @@ -548,6 +549,15 @@ public class ADWindowToolbar extends FToolbar implements EventListener btnExport.setDisabled(!b); } + /** + * Enable/disable file import button + * @param b + */ + public void enableFileImport(boolean b) { + if (btnFileImport != null) + btnFileImport.setDisabled(!b); + } + private boolean ToolBarMenuRestictionLoaded = false; public void updateToolBarAndMenuWithRestriction(int AD_Window_ID) { if (ToolBarMenuRestictionLoaded) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index d1bc076de0..19e09dde16 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -58,6 +58,7 @@ import org.adempiere.webui.panel.InfoPanel; import org.adempiere.webui.panel.WAttachment; import org.adempiere.webui.panel.WDocActionPanel; import org.adempiere.webui.panel.action.ExportAction; +import org.adempiere.webui.panel.action.FileImportAction; import org.adempiere.webui.panel.action.ReportAction; import org.adempiere.webui.part.AbstractUIPart; import org.adempiere.webui.session.SessionManager; @@ -1202,12 +1203,14 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements // Confirm Warning else if (e.isWarning() && !e.isConfirmed()) { - FDialog.warn(curWindowNo, null, e.getAD_Message(), e.getInfo()); - e.setConfirmed(true); // show just once - if MTable.setCurrentRow is involved the status event is re-issued + if (! adTabbox.getSelectedGridTab().getTableModel().isImporting()) { + FDialog.warn(curWindowNo, null, e.getAD_Message(), e.getInfo()); + e.setConfirmed(true); // show just once - if MTable.setCurrentRow is involved the status event is re-issued + } } boolean changed = e.isChanged() || e.isInserting(); - boolean readOnly = tabPanel.getGridTab().isReadOnly(); + boolean readOnly = adTabbox.getSelectedGridTab().isReadOnly(); boolean insertRecord = !readOnly; if (!detailTab) { @@ -1337,10 +1340,10 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted()); toolbar.enableReport(true); toolbar.enableExport(!adTabbox.getSelectedGridTab().isSortTab()); - + toolbar.enableFileImport(!changed && !adTabbox.getSelectedGridTab().isSortTab() && adTabbox.getSelectedGridTab().isInsertRecord()); + //Deepak-Enabling customize button IDEMPIERE-364 - if(!(adTabbox.getSelectedTabpanel() instanceof ADSortTab)) - toolbar.enableCustomize(((ADTabpanel)adTabbox.getSelectedTabpanel()).isGridView()); + toolbar.enableCustomize(((ADTabpanel)adTabbox.getSelectedTabpanel()).isGridView() && !adTabbox.getSelectedGridTab().isSortTab()); toolbar.updateToolBarAndMenuWithRestriction(gridWindow.getAD_Window_ID()); } @@ -2155,6 +2158,12 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements action.export(); } + @Override + public void onFileImport() { + FileImportAction action = new FileImportAction(this); + action.fileImport(); + } + /************************************************************************** * Start Button Process * @param vButton button diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/ToolbarListener.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/ToolbarListener.java index cbb0d30787..1ac65c4009 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/ToolbarListener.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/event/ToolbarListener.java @@ -165,6 +165,11 @@ public interface ToolbarListener */ public void onExport(); + /** + * File import data + */ + public void onFileImport(); + /** * Customize grid view. */ diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ExportAction.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ExportAction.java index cdbd771e0e..6cd0a5724a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ExportAction.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ExportAction.java @@ -115,7 +115,7 @@ public class ExportAction implements EventListener Hbox hb = new Hbox(); Div div = new Div(); div.setAlign("right"); - div.appendChild(new Label("Files of Type: ")); + div.appendChild(new Label(Msg.getMsg(Env.getCtx(), "FilesOfType"))); hb.appendChild(div); hb.appendChild(cboType); cboType.setWidth("100%"); @@ -195,7 +195,7 @@ public class ExportAction implements EventListener winExportFile.onClose(); winExportFile = null; AMedia media = null; - media = new AMedia(panel.getActiveGridTab().getName() + "." + ext, null, exporter.getContentType(), file, true); + media = new AMedia(exporter.getSuggestedFileName(panel.getActiveGridTab()), null, exporter.getContentType(), file, true); Filedownload.save(media, panel.getActiveGridTab().getName() + "." + ext); } catch (Exception e) { throw new AdempiereException(e); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/FileImportAction.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/FileImportAction.java new file mode 100644 index 0000000000..d8fd6aad1d --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/FileImportAction.java @@ -0,0 +1,277 @@ +/****************************************************************************** + * Product: iDempiere ERP & CRM Smart Business Solution * + * Copyright (C) 2012 Trek Global * + * Copyright (C) 2012 Carlos Ruiz * + * 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.webui.panel.action; + +import java.io.File; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.adempiere.base.IGridTabImporter; +import org.adempiere.base.Service; +import org.adempiere.exceptions.AdempiereException; +import org.adempiere.webui.adwindow.AbstractADWindowContent; +import org.adempiere.webui.adwindow.IADTabbox; +import org.adempiere.webui.adwindow.IADTabpanel; +import org.adempiere.webui.apps.AEnv; +import org.adempiere.webui.component.Button; +import org.adempiere.webui.component.ConfirmPanel; +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.ListItem; +import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.util.ReaderInputStream; +import org.adempiere.webui.window.FDialog; +import org.compiere.model.GridTab; +import org.compiere.util.Env; +import org.compiere.util.Ini; +import org.compiere.util.Msg; +import org.zkoss.util.media.AMedia; +import org.zkoss.util.media.Media; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.UploadEvent; +import org.zkoss.zul.Div; +import org.zkoss.zul.Filedownload; +import org.zkoss.zul.Hbox; +import org.zkoss.zul.Vbox; + +/** + * + * @author Carlos Ruiz + * + */ +public class FileImportAction implements EventListener +{ + private AbstractADWindowContent panel; + + private Map importerMap = null; + private Map extensionMap = null; + + private Window winImportFile = null; + private ConfirmPanel confirmPanel = new ConfirmPanel(true); + private Listbox cboType = new Listbox(); + private Button bFile = new Button(); + private Listbox fCharset = new Listbox(); + private InputStream m_file_istream = null; + + /** + * @param panel + */ + public FileImportAction(AbstractADWindowContent panel) + { + this.panel = panel; + } + + /** + * execute import action + */ + public void fileImport() + { + // charset + Charset[] charsets = Ini.getAvailableCharsets(); + for (int i = 0; i < charsets.length; i++) + fCharset.appendItem(charsets[i].displayName(), charsets[i]); + Charset charset = Ini.getCharset(); + for (int i = 0; i < fCharset.getItemCount(); i++) + { + ListItem listitem = fCharset.getItemAtIndex(i); + Charset compare = (Charset)listitem.getValue(); + + if (charset == compare) + { + fCharset.setSelectedIndex(i); + break; + } + } + // TODO: change the streamreader when changing the charset + // fCharset.addEventListener(Events.ON_SELECT, this); + + importerMap = new HashMap(); + extensionMap = new HashMap(); + List importerList = Service.list(IGridTabImporter.class); + for(IGridTabImporter importer : importerList) + { + String extension = importer.getFileExtension(); + if (!extensionMap.containsKey(extension)) + { + extensionMap.put(extension, importer.getFileExtensionLabel()); + importerMap.put(extension, importer); + } + } + + if (winImportFile == null) + { + winImportFile = new Window(); + winImportFile.setTitle(Msg.getMsg(Env.getCtx(), "FileImport") + ": " + panel.getActiveGridTab().getName()); + winImportFile.setWidth("450px"); + winImportFile.setClosable(true); + winImportFile.setBorder("normal"); + winImportFile.setStyle("position:absolute"); + + cboType.setMold("select"); + + cboType.getItems().clear(); + for(Map.Entry entry : extensionMap.entrySet()) + { + cboType.appendItem(entry.getKey() + " - " + entry.getValue(), entry.getKey()); + } + + cboType.setSelectedIndex(0); + + Vbox vb = new Vbox(); + vb.setWidth("100%"); + winImportFile.appendChild(vb); + + Hbox hb = new Hbox(); + Div div = new Div(); + div.setAlign("right"); + div.appendChild(new Label(Msg.getMsg(Env.getCtx(), "FilesOfType"))); + hb.appendChild(div); + hb.appendChild(cboType); + cboType.setWidth("100%"); + vb.appendChild(hb); + + hb = new Hbox(); + bFile.setLabel(Msg.getMsg(Env.getCtx(), "FileImportFile")); + bFile.setTooltiptext(Msg.getMsg(Env.getCtx(), "FileImportFileInfo")); + bFile.setUpload("true"); + bFile.addEventListener(Events.ON_UPLOAD, this); + hb.appendChild(bFile); + vb.appendChild(hb); + + hb = new Hbox(); + fCharset.setMold("select"); + fCharset.setRows(0); + fCharset.setTooltiptext(Msg.getMsg(Env.getCtx(), "Charset", false)); + hb.appendChild(fCharset); + vb.appendChild(hb); + + vb.appendChild(confirmPanel); + confirmPanel.addActionListener(this); + } + + winImportFile.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); + AEnv.showWindow(winImportFile); + } + + @Override + public void onEvent(Event event) throws Exception { + if (event instanceof UploadEvent) + { + UploadEvent ue = (UploadEvent) event; + processUploadMedia(ue.getMedia()); + } else if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) { + winImportFile.onClose(); + } + else if (event.getTarget().getId().equals(ConfirmPanel.A_OK)) { + // TODO: Verify that file and charset are mandatory + importFile(); + } + } + + private void processUploadMedia(Media media) { + if (media == null) + return; + + if (media.isBinary()) { + m_file_istream = media.getStreamData(); + } + else { + ListItem listitem = fCharset.getSelectedItem(); + if (listitem == null) { + m_file_istream = new ReaderInputStream(media.getReaderData()); + } else { + Charset charset = (Charset)listitem.getValue(); + m_file_istream = new ReaderInputStream(media.getReaderData(), charset.name()); + } + } + + bFile.setLabel(media.getName()); + } + + private void importFile() { + try { + ListItem li = cboType.getSelectedItem(); + if(li == null || li.getValue() == null) + { + FDialog.error(0, winImportFile, "FileInvalidExtension"); + return; + } + + String ext = li.getValue().toString(); + IGridTabImporter importer = importerMap.get(ext); + if (importer == null) + { + FDialog.error(0, winImportFile, "FileInvalidExtension"); + return; + } + + IADTabbox adTab = panel.getADTab(); + int selected = adTab.getSelectedIndex(); + int tabLevel = panel.getActiveGridTab().getTabLevel(); + Set tables = new HashSet(); + List childs = new ArrayList(); + List includedList = panel.getActiveGridTab().getIncludedTabs(); + for(GridTab included : includedList) + { + String tableName = included.getTableName(); + if (tables.contains(tableName)) + continue; + tables.add(tableName); + childs.add(included); + } + for(int i = selected+1; i < adTab.getTabCount(); i++) + { + IADTabpanel adTabPanel = adTab.getADTabpanel(i); + if (adTabPanel.getGridTab().isSortTab()) + continue; + if (adTabPanel.getGridTab().getTabLevel() <= tabLevel) + break; + String tableName = adTabPanel.getGridTab().getTableName(); + if (tables.contains(tableName)) + continue; + tables.add(tableName); + childs.add(adTabPanel.getGridTab()); + } + + ListItem listitem = fCharset.getSelectedItem(); + Charset charset = null; + if (listitem == null) + return; + charset = (Charset)listitem.getValue(); + + File outFile = importer.fileImport(panel.getActiveGridTab(), childs, m_file_istream, charset); + winImportFile.onClose(); + winImportFile = null; + + AMedia media = null; + media = new AMedia(importer.getSuggestedFileName(panel.getActiveGridTab()), null, importer.getContentType(), outFile, true); + Filedownload.save(media, panel.getActiveGridTab().getName() + "." + ext); + + } catch (Exception e) { + throw new AdempiereException(e); + } finally { + if (winImportFile != null) + winImportFile.onClose(); + } + } +} diff --git a/org.adempiere.ui.zk/images/FileImport16.png b/org.adempiere.ui.zk/images/FileImport16.png new file mode 100644 index 0000000000000000000000000000000000000000..f8fde8390d3e67e822a0442af6fb99447b4583a1 GIT binary patch literal 3343 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 ZKL8l$Kg>GebAbQ=002ovPDHLkV1kl!L{R_$ literal 0 HcmV?d00001 diff --git a/org.adempiere.ui.zk/images/FileImport24.png b/org.adempiere.ui.zk/images/FileImport24.png new file mode 100644 index 0000000000000000000000000000000000000000..432727a744ab93ee7009ee8c2006f6535086976d GIT binary patch literal 3919 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 literal 0 HcmV?d00001