From ce32859d686fb23aae6927d036785f450e8bc4db Mon Sep 17 00:00:00 2001 From: Juan David Arboleda Date: Wed, 16 Jan 2013 16:04:11 -0800 Subject: [PATCH 1/2] IDEMPIERE-379 Reporting wizard for end users / Refactor Sort Tab for print format items --- .../adempiere/webui/adwindow/ADSortTab.java | 153 +++++++++--------- 1 file changed, 79 insertions(+), 74 deletions(-) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java index 2977f7ce57..6100d35095 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADSortTab.java @@ -39,6 +39,7 @@ import org.compiere.model.MRole; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.compiere.util.KeyNamePair; import org.compiere.util.Msg; import org.compiere.util.NamePair; import org.zkoss.zk.au.out.AuFocus; @@ -65,13 +66,14 @@ import org.zkoss.zul.event.ListDataEvent; *
  • https://sourceforge.net/tracker/?func=detail&atid=879335&aid=2826406&group_id=176962 * Zk Port * @author Low Heng Sin + * @author Juan David Arboleda : Refactoring Yes and No List to work with multiple choice. */ public class ADSortTab extends Panel implements IADTabpanel { /** * */ - private static final long serialVersionUID = 4461514427222034848L; + private static final long serialVersionUID = 1775234591903753429L; /** * Sort Tab Constructor @@ -283,8 +285,8 @@ public class ADSortTab extends Panel implements IADTabpanel migrateValueAcrossLists(event); } }; - yesList.setSeltype("multiple"); - noList.setSeltype("multiple"); + yesModel.setMultiple(true); + noModel.setMultiple(true); bAdd.setImage("images/Next24.png"); bAdd.addEventListener(Events.ON_CLICK, actionListener); @@ -298,7 +300,7 @@ public class ADSortTab extends Panel implements IADTabpanel yesList.setItemDraggable(true); noList.setItemDraggable(true); - actionListener = new EventListener() + EventListener actionListener2 = new EventListener() { public void onEvent(Event event) throws Exception { migrateValueWithinYesList(event); @@ -306,40 +308,10 @@ public class ADSortTab extends Panel implements IADTabpanel }; bUp.setImage("images/Parent24.png"); - bUp.addEventListener(Events.ON_CLICK, actionListener); + bUp.addEventListener(Events.ON_CLICK, actionListener2); bDown.setImage("images/Detail24.png"); - bDown.addEventListener(Events.ON_CLICK, actionListener); - - EventListener yesListMouseMotionListener = new EventListener() - { - public void onEvent(Event event) throws Exception { - if (event instanceof DropEvent) - { - DropEvent me = (DropEvent) event; - ListItem startItem = (ListItem) me.getDragged(); - ListItem endItem = (ListItem) me.getTarget(); - if (startItem.getListbox() == endItem.getListbox() && startItem.getListbox() == yesList) - { - int startIndex = yesList.getIndexOfItem(startItem); - int endIndex = yesList.getIndexOfItem(endItem); - Object endElement = yesModel.getElementAt(endIndex); - Object element = yesModel.getElementAt(startIndex); - yesModel.removeElement(element); - endIndex = yesModel.indexOf(endElement); - yesModel.add(endIndex, element); - yesList.setSelectedIndex(endIndex); - if ( yesList.getSelectedItem() != null) - { - AuFocus focus = new AuFocus(yesList.getSelectedItem()); - Clients.response(focus); - } - setIsChanged(true); - } - } - } - }; - yesList.addOnDropListener(yesListMouseMotionListener); + bDown.addEventListener(Events.ON_CLICK, actionListener2); ListHead listHead = new ListHead(); listHead.setParent(yesList); @@ -465,7 +437,7 @@ public class ADSortTab extends Panel implements IADTabpanel yesModel.addElement(pp); else noModel.addElement(pp); - // If the one item from "Yes" list is readonly make entire tab readonly + // If one item from "Yes" list is readonly make entire tab readonly if (isYes && !pp.isUpdateable()) { isReadWrite = false; } @@ -522,40 +494,46 @@ public class ADSortTab extends Panel implements IADTabpanel } Listbox listFrom = (source == bAdd || source == noList) ? noList : yesList; Listbox listTo = (source == bAdd || source == noList) ? yesList : noList; - SimpleListModel lmFrom = (source == bAdd || source == noList) ? - noModel : yesModel; - SimpleListModel lmTo = (lmFrom == yesModel) ? noModel : yesModel; + + int endIndex = yesList.getIndexOfItem(listTo.getSelectedItem()); + //Listto is empty. + if (endIndex<0 ) + endIndex=0; + + migrateLists (listFrom,listTo,endIndex); + } // migrateValueAcrossLists + + void migrateLists (Listbox listFrom , Listbox listTo , int endIndex) + { + int index = 0; + SimpleListModel lmFrom = (listFrom == yesList) ? yesModel:noModel; + SimpleListModel lmTo = (lmFrom == yesModel) ? noModel:yesModel; Set selectedItems = listFrom.getSelectedItems(); List selObjects = new ArrayList(); for (Object obj : selectedItems) { ListItem listItem = (ListItem) obj; - int index = listFrom.getIndexOfItem(listItem); + index = listFrom.getIndexOfItem(listItem); ListElement selObject = (ListElement)lmFrom.getElementAt(index); selObjects.add(selObject); } + index = 0; + Arrays.sort(selObjects.toArray()); for (ListElement selObject : selObjects) { if (selObject == null || !selObject.isUpdateable()) continue; lmFrom.removeElement(selObject); - lmTo.addElement(selObject); - - // Enable explicit Save - setIsChanged(true); - } - - for (ListElement selObject : selObjects) - { - int index = lmTo.indexOf(selObject); - listTo.setSelectedIndex(index); + lmTo.add(endIndex, selObject); } + // Enable explicit Save + setIsChanged(true); if ( listTo.getSelectedItem() != null) { AuFocus focus = new AuFocus(listTo.getSelectedItem()); Clients.response(focus); } - } // migrateValueAcrossLists + } /** * Move within Yes List @@ -622,6 +600,32 @@ public class ADSortTab extends Panel implements IADTabpanel } } // migrateValueWithinYesList + + /** + * Move within Yes List with Drag Event and Multiple Choice + * @param event event + */ + void migrateValueWithinYesList (int endIndex, List selObjects) + { + int iniIndex =0; + Arrays.sort(selObjects.toArray()); + ListElement selObject= null; + ListElement endObject = (ListElement)yesModel.getElementAt(endIndex); + for (ListElement selected : selObjects) { + iniIndex = yesModel.indexOf(selected); + selObject = (ListElement)yesModel.getElementAt(iniIndex); + yesModel.removeElement(selObject); + endIndex = yesModel.indexOf(endObject); + yesModel.add(endIndex, selObject); + } + yesList.removeAllItems(); + for(int i=0 ; i selObjects = new ArrayList(); + endIndex = yesList.getIndexOfItem(endItem); + for (Object obj : yesList.getSelectedItems()) { + ListItem listItem = (ListItem) obj; + int index = yesList.getIndexOfItem(listItem); + ListElement selObject = (ListElement)yesModel.getElementAt(index); + selObjects.add(selObject); + } + migrateValueWithinYesList (endIndex, selObjects); + } + } } } From 0ebc6fab416a787a56a31fda59db4a668a788a28 Mon Sep 17 00:00:00 2001 From: Juan David Arboleda Date: Wed, 16 Jan 2013 16:24:03 -0800 Subject: [PATCH 2/2] IDEMPIERE-454 Easy import / Version 2 - add update capatibility in 1 tab - it requires the key field(s) to be suffixed with /K --- .../oracle/201301161610_IDEMPIERE-454.sql | 43 +++ .../postgresql/201301161610_IDEMPIERE-454.sql | 43 +++ .../org/adempiere/base/IGridTabImporter.java | 2 +- .../adempiere/impexp/GridTabCSVImporter.java | 252 +++++++++++++----- .../webui/panel/action/FileImportAction.java | 32 ++- 5 files changed, 306 insertions(+), 66 deletions(-) create mode 100644 migration/i1.0a-release/oracle/201301161610_IDEMPIERE-454.sql create mode 100644 migration/i1.0a-release/postgresql/201301161610_IDEMPIERE-454.sql diff --git a/migration/i1.0a-release/oracle/201301161610_IDEMPIERE-454.sql b/migration/i1.0a-release/oracle/201301161610_IDEMPIERE-454.sql new file mode 100644 index 0000000000..d8d0b11e04 --- /dev/null +++ b/migration/i1.0a-release/oracle/201301161610_IDEMPIERE-454.sql @@ -0,0 +1,43 @@ +-- Dec 26, 2012 11:13:27 AM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','In order mark a column as a Key,the character ''K'' must be used in capital letter.',' ''K'' must be used in capital letter.',200131,'D','cbb24b89-0807-42c8-a027-98a4d87f0dc1','ColumnKey','Y',TO_DATE('2012-12-26 11:13:26','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-12-26 11:13:26','YYYY-MM-DD HH24:MI:SS')) +; + +-- Dec 26, 2012 11:13:27 AM 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=200131 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) +; + +-- Dec 26, 2012 11:15:03 AM 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','There must be key columns in order to update or merge record(s).',200132,'D','805c64e8-6071-4bc9-821d-f52fe23ac1ad','NoKeyFound','Y',TO_DATE('2012-12-26 11:14:27','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-12-26 11:14:27','YYYY-MM-DD HH24:MI:SS')) +; + +-- Dec 26, 2012 11:15:03 AM 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=200132 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) +; + +-- Dec 26, 2012 11:15:51 AM 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','More than one row has been found and this record cannot be inserted or updated',200133,'D','6386e48b-6055-4f65-87c9-dc42863526cd','TooManyRows','Y',TO_DATE('2012-12-26 11:15:51','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-12-26 11:15:51','YYYY-MM-DD HH24:MI:SS')) +; + +-- Dec 26, 2012 11:15:51 AM 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=200133 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) +; + +-- Dec 26, 2012 11:16:42 AM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('I','Import Mode: ','Import Mode',200134,'D','753fad5d-5b0c-4ec0-8ba1-f748669e85c1','import.mode','Y',TO_DATE('2012-12-26 11:16:42','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-12-26 11:16:42','YYYY-MM-DD HH24:MI:SS')) +; + +-- Dec 26, 2012 11:16:42 AM 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=200134 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) +; + +SELECT register_migration_script('201301161610_IDEMPIERE-454.sql') FROM dual +; + diff --git a/migration/i1.0a-release/postgresql/201301161610_IDEMPIERE-454.sql b/migration/i1.0a-release/postgresql/201301161610_IDEMPIERE-454.sql new file mode 100644 index 0000000000..5716dbf77d --- /dev/null +++ b/migration/i1.0a-release/postgresql/201301161610_IDEMPIERE-454.sql @@ -0,0 +1,43 @@ +-- Dec 26, 2012 11:13:27 AM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','In order mark a column as a Key,the character ''K'' must be used in capital letter.',' ''K'' must be used in capital letter.',200131,'D','cbb24b89-0807-42c8-a027-98a4d87f0dc1','ColumnKey','Y',TO_TIMESTAMP('2012-12-26 11:13:26','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-12-26 11:13:26','YYYY-MM-DD HH24:MI:SS')) +; + +-- Dec 26, 2012 11:13:27 AM 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=200131 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) +; + +-- Dec 26, 2012 11:15:03 AM 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','There must be key columns in order to update or merge record(s).',200132,'D','805c64e8-6071-4bc9-821d-f52fe23ac1ad','NoKeyFound','Y',TO_TIMESTAMP('2012-12-26 11:14:27','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-12-26 11:14:27','YYYY-MM-DD HH24:MI:SS')) +; + +-- Dec 26, 2012 11:15:03 AM 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=200132 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) +; + +-- Dec 26, 2012 11:15:51 AM 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','More than one row has been found and this record cannot be inserted or updated',200133,'D','6386e48b-6055-4f65-87c9-dc42863526cd','TooManyRows','Y',TO_TIMESTAMP('2012-12-26 11:15:51','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-12-26 11:15:51','YYYY-MM-DD HH24:MI:SS')) +; + +-- Dec 26, 2012 11:15:51 AM 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=200133 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) +; + +-- Dec 26, 2012 11:16:42 AM COT +-- IDEMPIERE-454 Easy import +INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('I','Import Mode: ','Import Mode',200134,'D','753fad5d-5b0c-4ec0-8ba1-f748669e85c1','import.mode','Y',TO_TIMESTAMP('2012-12-26 11:16:42','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-12-26 11:16:42','YYYY-MM-DD HH24:MI:SS')) +; + +-- Dec 26, 2012 11:16:42 AM 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=200134 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) +; + +SELECT register_migration_script('201301161610_IDEMPIERE-454.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/adempiere/base/IGridTabImporter.java b/org.adempiere.base/src/org/adempiere/base/IGridTabImporter.java index f927a1024a..58fdeaca4c 100644 --- a/org.adempiere.base/src/org/adempiere/base/IGridTabImporter.java +++ b/org.adempiere.base/src/org/adempiere/base/IGridTabImporter.java @@ -35,7 +35,7 @@ public interface IGridTabImporter { * @param filestream * @param charset */ - public File fileImport(GridTab gridTab, List childs, InputStream filestream, Charset charset); + public File fileImport(GridTab gridTab, List childs, InputStream filestream, Charset charset, String importMode); /** * @return file extension diff --git a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java index ef6370e51e..331b2f8373 100644 --- a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java +++ b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java @@ -35,6 +35,7 @@ import org.adempiere.exceptions.AdempiereException; import org.compiere.model.GridField; import org.compiere.model.GridTab; import org.compiere.model.MColumn; +import org.compiere.model.MQuery; import org.compiere.model.MTable; import org.compiere.model.PO; import org.compiere.tools.FileUtil; @@ -62,17 +63,19 @@ import org.supercsv.prefs.CsvPreference; /** * CSV Importer for GridTab * @author Carlos Ruiz + * @author Juan David Arboleda */ public class GridTabCSVImporter implements IGridTabImporter { private static final String ERROR_HEADER = "_ERROR_"; private static final String LOG_HEADER = "_LOG_"; + private String IMPORT_MODE = null; + /** Logger */ private static CLogger log = CLogger.getCLogger(GridTabCSVImporter.class); boolean m_isError = false; - public File fileImport(GridTab gridTab, List childs, InputStream filestream, Charset charset) { - + public File fileImport(GridTab gridTab, List childs, InputStream filestream, Charset charset , String importMode) { ICsvMapReader mapReader = null; File errFile = null; File logFile = null; @@ -81,6 +84,8 @@ public class GridTabCSVImporter implements IGridTabImporter CsvPreference csvpref = CsvPreference.STANDARD_PREFERENCE; String delimiter = String.valueOf((char) csvpref.getDelimiterChar()); String quoteChar = String.valueOf((char) csvpref.getQuoteChar()); + IMPORT_MODE = importMode; + boolean isThereKey = false; try { String errFileName = FileUtil.getTempMailName("Import_" + gridTab.getTableName(), "_err.csv"); errFile = new File(errFileName); @@ -97,14 +102,27 @@ public class GridTabCSVImporter implements IGridTabImporter continue; } String columnName = headName; - boolean isForeign = headName.indexOf("[") > 0 && headName.endsWith("]"); + boolean isKeyColumn = false; + if ( columnName.indexOf("/") > 0 ){ + if(columnName.endsWith("K")){ + isKeyColumn =true; + columnName = headName.substring(0,headName.length()-2); + }else{ + throw new AdempiereException(Msg.getMsg(Env.getCtx(), "ColumnKey", new Object[] {columnName})); + } + } + + boolean isForeign = columnName.indexOf("[") > 0 && columnName.endsWith("]"); if (isForeign) { - int end = headName.indexOf("["); - columnName = headName.substring(0, end); + int end = columnName.indexOf("["); + columnName = columnName.substring(0, end); } + GridField field = gridTab.getField(columnName); if (field == null) { throw new AdempiereException(Msg.getMsg(Env.getCtx(), "FieldNotFound", new Object[] {columnName})); + }else if(isKeyColumn && !isThereKey){ + isThereKey =true; } MColumn column = MColumn.get(Env.getCtx(), field.getAD_Column_ID()); // TODO: List columns can use RequireSubStr constraint @@ -146,8 +164,10 @@ public class GridTabCSVImporter implements IGridTabImporter } } } - CellProcessor[] processors = readProcArray.toArray(new CellProcessor[readProcArray.size()]); - + if((IMPORT_MODE.equals("U") || IMPORT_MODE.equals("M")) && !isThereKey){ + throw new AdempiereException(Msg.getMsg(Env.getCtx(), "NoKeyFound")); + } + CellProcessor[] processors = readProcArray.toArray(new CellProcessor[readProcArray.size()]); m_isError = false; // write the header String rawHeader = mapReader.getUntokenizedRow(); @@ -178,15 +198,21 @@ public class GridTabCSVImporter implements IGridTabImporter log.fine("Setting " + headName + " to " + value); String columnName = headName; - boolean isForeign = headName.indexOf("[") > 0 && headName.endsWith("]"); + + boolean isKeyColumn = headName.indexOf("/") > 0 && (headName.endsWith("K")); + if (isKeyColumn) + columnName = headName.substring(0,headName.length()-2); + + boolean isForeign = columnName.indexOf("[") > 0 && columnName.endsWith("]"); String foreignColumn = null; if (isForeign) { - int end = headName.indexOf("["); - columnName = headName.substring(0, end); + int end = columnName.indexOf("["); + columnName = columnName.substring(0, end); int startf = headName.indexOf("[")+1; - int endf = headName.length()-1; + int endf = headName.indexOf("]"); foreignColumn = headName.substring(startf, endf); } + GridField field = gridTab.getField(columnName); if (field == null) { lineError.append(Msg.getMsg(Env.getCtx(), "NotAWindowField", new Object[] {headName})); @@ -202,7 +228,7 @@ public class GridTabCSVImporter implements IGridTabImporter } if (!isLineError) { MColumn column = MColumn.get(Env.getCtx(), field.getAD_Column_ID()); - if (isForeign && value != null) { + if (isForeign && value != null){ String foreignTable = column.getReferenceTableName(); String idS = null; int id = -1; @@ -258,66 +284,89 @@ public class GridTabCSVImporter implements IGridTabImporter 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); + + if (isThereKey) + logMsg = areValidKeysAndColumns(gridTab,map,header); - 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 { + if (logMsg == null){ + + if (IMPORT_MODE.equals("I")) + gridTab.dataNew(false); + + for (String headName : header) { + if (headName == null) + continue; + Object value = map.get(headName); + String columnName = headName; + + boolean isKeyColumn = headName.indexOf("/") > 0 && (headName.endsWith("K")); + if (isKeyColumn) { + if(IMPORT_MODE.equals("I")) + columnName = columnName.substring(0,headName.length()-2); + if(IMPORT_MODE.equals("U"))//Key Column never updated + continue; + } + boolean isForeign = columnName.indexOf("[") > 0 && columnName.endsWith("]"); + String foreignColumn = null; + if (isForeign) { + int end = columnName.indexOf("["); + columnName = columnName.substring(0, end); + int startf = headName.indexOf("[")+1; + int endf = headName.indexOf("]"); + foreignColumn = headName.substring(startf, endf); + } + GridField field = gridTab.getField(columnName); + if (field.isParentValue()) + continue; + + if (!field.isEditable(true)) { logMsg = Msg.getMsg(Env.getCtx(), "FieldNotEditable", new Object[] {headName}); error = true; break; } + + 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 (setValue != null) { + gridTab.setValue(field,setValue); + } } + }else { + error =true; } if (! error) { if (gridTab.dataSave(false)) { - PO po = gridTab.getTableModel().getPO(gridTab.getCurrentRow()); - logMsg = Msg.getMsg(Env.getCtx(), "SuccessfullySaved", - new Object[] {po != null ? po.toString() : gridTab.getTableModel().getKeyID(gridTab.getCurrentRow())}); + PO po = gridTab.getTableModel().getPO(gridTab.getCurrentRow()); + if(IMPORT_MODE.equals("I")){ + logMsg = Msg.getMsg(Env.getCtx(), "Inserted") + po.toString(); + }else{ + logMsg = Msg.getMsg(Env.getCtx(), "Updated") + po.toString(); + } } else { error = true; ValueNamePair ppE = CLogger.retrieveWarning(); @@ -346,6 +395,7 @@ public class GridTabCSVImporter implements IGridTabImporter trx = null; } gridTab.getTableModel().setImportingMode(false, null); + IMPORT_MODE =importMode; } // write logMsg = logMsg.replaceAll(delimiter, ""); @@ -378,7 +428,83 @@ public class GridTabCSVImporter implements IGridTabImporter else return errFile; } + + private String areValidKeysAndColumns(GridTab gridTab, Map map,String[] header){ + MQuery pquery = new MQuery(gridTab.getAD_Table_ID()); + String logMsg= null; + Object tmpValue=null; + String columnwithKey=null; + Object setValue = null; + //Process columnKeys + Foreign to add restrictions. + for (int i=0 ; i< header.length; i++){ + boolean isKeyColumn = header[i].indexOf("/") > 0 && header[i].endsWith("K"); + if(isKeyColumn){ + columnwithKey = header[i].substring(0,header[i].length()-2); + boolean isForeign = columnwithKey.indexOf("[") > 0 && columnwithKey.indexOf("]") > 0; + String foreignColumn = null; + if(isForeign) { + int end = columnwithKey.indexOf("["); + columnwithKey = columnwithKey.substring(0, end); + int startf = header[i].indexOf("[")+1; + int endf = header[i].indexOf("]"); + foreignColumn = header[i].substring(startf, endf); + + if (map.get(header[i]) instanceof java.util.Date) + tmpValue = new Timestamp(((java.util.Date)map.get(header[i])).getTime()); + else + tmpValue = map.get(header[i]); + + MColumn column = MColumn.get(Env.getCtx(), gridTab.getField(columnwithKey).getAD_Column_ID()); + String foreignTable = column.getReferenceTableName(); + if ("AD_Ref_List".equals(foreignTable)) { + String idS = resolveForeignList(column, foreignColumn, tmpValue); + setValue = idS; + }else { + int id = resolveForeign(foreignTable, foreignColumn, tmpValue); + setValue = id; + if (gridTab.getField(columnwithKey).isParentValue()) { + int actualId = (Integer) gridTab.getField(columnwithKey).getValue(); + if (actualId != id) { + logMsg = Msg.getMsg(Env.getCtx(), "ParentCannotChange", new Object[] {header[i]}); + break; + } + } + } + }else{ + if (map.get(header[i]) instanceof java.util.Date) + tmpValue = new Timestamp(((java.util.Date)map.get(header[i])).getTime()); + else + tmpValue = map.get(header[i]); + + setValue = tmpValue ; + } + pquery.addRestriction(columnwithKey,MQuery.EQUAL,setValue); + } + } + gridTab.setQuery(pquery); + gridTab.query(false); + if (IMPORT_MODE.equals("I")){ + if(gridTab.getRowCount()>=1) + logMsg = Msg.getMsg(Env.getCtx(), "AlreadyExists", new Object[] {pquery}); + } + if (IMPORT_MODE.equals("U")){ + if(gridTab.getRowCount()<=0) + logMsg = Msg.getMsg(Env.getCtx(), "not.found", new Object[] {pquery}); + else if(gridTab.getRowCount()>1) + logMsg = Msg.getMsg(Env.getCtx(),"SQLErrorNotUnique", new Object[] {pquery}); + } + if (IMPORT_MODE.equals("M")){ + if(gridTab.getRowCount()==1) + IMPORT_MODE = "U"; + else if(gridTab.getRowCount()<=0) + IMPORT_MODE = "I"; + else if(gridTab.getRowCount()>1) + logMsg = Msg.getMsg(Env.getCtx(),"TooManyRows", new Object[] {pquery}); + } + return logMsg; + } + private String resolveForeignList(MColumn column, String foreignColumn, Object value) { String idS = null; StringBuilder select = new StringBuilder("SELECT Value FROM AD_Ref_List WHERE ") 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 index 404ba3fd7d..e27f694e21 100644 --- 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 @@ -74,6 +74,7 @@ public class FileImportAction implements EventListener private Listbox cboType = new Listbox(); private Button bFile = new Button(); private Listbox fCharset = new Listbox(); + private Listbox fImportMode = new Listbox(); private InputStream m_file_istream = null; /** @@ -108,6 +109,11 @@ public class FileImportAction implements EventListener } fCharset.addEventListener(Events.ON_SELECT, this); + fImportMode.appendItem("Insert","I"); + fImportMode.appendItem("Update","U"); + fImportMode.appendItem("Merge","M"); + fImportMode.setSelectedIndex(0); + importerMap = new HashMap(); extensionMap = new HashMap(); List importerList = Service.locator().list(IGridTabImporter.class).getServices(); @@ -155,10 +161,27 @@ public class FileImportAction implements EventListener vb.appendChild(hb); hb = new Hbox(); + Div div2 = new Div(); + div2.setAlign("right"); + div2.appendChild(new Label(Msg.getMsg(Env.getCtx(), "Charset", false))); + hb.appendChild(div2); fCharset.setMold("select"); fCharset.setRows(0); fCharset.setTooltiptext(Msg.getMsg(Env.getCtx(), "Charset", false)); hb.appendChild(fCharset); + fCharset.setWidth("100%"); + vb.appendChild(hb); + + hb = new Hbox(); + Div div3 = new Div(); + div3.setAlign("right"); + div3.appendChild(new Label(Msg.getMsg(Env.getCtx(), "import.mode", true))); + hb.appendChild(div3); + fImportMode.setMold("select"); + fImportMode.setRows(0); + fImportMode.setTooltiptext(Msg.getMsg(Env.getCtx(), "import.mode", false)); + hb.appendChild(fImportMode); + fImportMode.setWidth("100%"); vb.appendChild(hb); hb = new Hbox(); @@ -278,8 +301,13 @@ public class FileImportAction implements EventListener if (listitem == null) return; charset = (Charset)listitem.getValue(); - - File outFile = importer.fileImport(panel.getActiveGridTab(), childs, m_file_istream, charset); + + ListItem importItem = fImportMode.getSelectedItem(); + if (importItem == null) + return; + + String iMode = (String)importItem.getValue(); + File outFile = importer.fileImport(panel.getActiveGridTab(), childs, m_file_istream, charset,iMode); winImportFile.onClose(); winImportFile = null;