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