IDEMPIERE-5624 Implement export data as SQL insert statement (#1721)

This commit is contained in:
hengsin 2023-03-13 22:57:45 +08:00 committed by GitHub
parent efe0e14e57
commit b188775e9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 467 additions and 122 deletions

View File

@ -0,0 +1,14 @@
-- IDEMPIERE-5624 Implement export data as SQL insert statement
SELECT register_migration_script('202303111206_IDEMPIERE-5624.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Mar 11, 2023, 12:06:48 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','zip - SQL zip file','Zip archive of Oracle and PostgreSQL Insert SQL scripts',0,0,'Y',TO_TIMESTAMP('2023-03-11 12:06:46','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-03-11 12:06:46','YYYY-MM-DD HH24:MI:SS'),100,200825,'FileSQLInsertZip','D','9308f542-5ab1-4462-90a3-c0d70b2eb009')
;
-- Mar 11, 2023, 12:11:29 PM MYT
UPDATE AD_Message SET MsgText='zip - SQL Insert scripts zip archive', MsgTip=NULL,Updated=TO_TIMESTAMP('2023-03-11 12:11:29','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200825
;

View File

@ -0,0 +1,11 @@
-- IDEMPIERE-5624 Implement export data as SQL insert statement
SELECT register_migration_script('202303111206_IDEMPIERE-5624.sql') FROM dual;
-- Mar 11, 2023, 12:06:48 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','zip - SQL zip file','Zip archive of Oracle and PostgreSQL Insert SQL scripts',0,0,'Y',TO_TIMESTAMP('2023-03-11 12:06:46','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-03-11 12:06:46','YYYY-MM-DD HH24:MI:SS'),100,200825,'FileSQLInsertZip','D','9308f542-5ab1-4462-90a3-c0d70b2eb009')
;
-- Mar 11, 2023, 12:11:29 PM MYT
UPDATE AD_Message SET MsgText='zip - SQL Insert scripts zip archive', MsgTip=NULL,Updated=TO_TIMESTAMP('2023-03-11 12:11:29','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200825
;

View File

@ -119,4 +119,13 @@
priority="0">
</exporter>
</extension>
<extension
id="org.adempiere.impexp.GridTabSQLInsertExporter"
name="Export data as SQL insert statement"
point="org.adempiere.base.IGridTabExporter">
<exporter
class="org.adempiere.impexp.GridTabSQLInsertExporter"
priority="0">
</exporter>
</extension>
</plugin>

View File

@ -19,9 +19,8 @@ import java.util.List;
import org.compiere.model.GridTab;
/**
*
* Interface to export data from {@link GridTab}
* @author hengsin
*
*/
public interface IGridTabExporter {
@ -31,21 +30,22 @@ public interface IGridTabExporter {
* @param childs
* @param isCurrentRowOnly
* @param file
* @param indxDetailSelected index of selected child tab
*/
public void export(GridTab gridTab, List<GridTab> childs, boolean isCurrentRowOnly, File file, int indxDetailSelected);
/**
* @return file extension
* @return file extension (csv, zip, ect)
*/
public String getFileExtension();
/**
* @return description for file extension
* @return label for file extension
*/
public String getFileExtensionLabel();
/**
* @return mime type
* @return mime content type
*/
public String getContentType();
@ -55,9 +55,31 @@ public interface IGridTabExporter {
public String getSuggestedFileName(GridTab gridTab);
/**
* Check a tab (detail tab) is support to export in this exporter
* @param gridTab
* @return
* Check if exported support the export of a child tab
* @param childTab
* @return true if export is supported, false otherwise
*/
public boolean isExportableTab (GridTab gridTab);
public boolean isExportableTab (GridTab childTab);
/**
* @return true if exporter is available to role with advanced access only
*/
default boolean isAdvanced() {
return false;
}
/**
* @return true if export of child tabs is supported only when current row only is on.
*/
default boolean isExportChildTabsForCurrentRowOnly() {
return false;
}
/**
* Maximum deep of child tab supported by the exporter
* @return > 0 for maximum level of deep, <= 0 for unlimited level of deep
*/
default int maxDeepOfChildTab() {
return 0;
}
}

View File

@ -0,0 +1,207 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* 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., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - hengsin *
**********************************************************************/
package org.adempiere.impexp;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.adempiere.base.IGridTabExporter;
import org.adempiere.exceptions.AdempiereException;
import org.compiere.db.Database;
import org.compiere.model.GridTab;
import org.compiere.model.MTable;
import org.compiere.model.PO;
import org.compiere.util.Env;
import org.compiere.util.Msg;
/**
* Export data as SQL insert statement
* @author hengsin
*/
public class GridTabSQLInsertExporter implements IGridTabExporter {
/**
* Default constructor
*/
public GridTabSQLInsertExporter() {
}
@Override
public void export(GridTab gridTab, List<GridTab> childs, boolean isCurrentRowOnly, File file,
int indxDetailSelected) {
try (FileOutputStream fos = new FileOutputStream (file); ZipOutputStream zos = new ZipOutputStream(fos);){
// create directory "oracle"
ZipEntry directoryEntry = new ZipEntry("oracle/");
zos.putNextEntry(directoryEntry);
zos.closeEntry();
// create directory "postgresql"
directoryEntry = new ZipEntry("postgresql/");
zos.putNextEntry(directoryEntry);
zos.closeEntry();
//export header tab
MTable table = MTable.get(gridTab.getAD_Table_ID());
List<String> oracles = new ArrayList<>();
List<String> pgs = new ArrayList<>();
if (isCurrentRowOnly) {
PO po = getPO(gridTab, table, gridTab.getCurrentRow());
if (po != null)
addSQLInsert(po, oracles, pgs);
} else {
for(int i = 0; i < gridTab.getRowCount(); i++) {
PO po = getPO(gridTab, table, i);
if (po != null)
addSQLInsert(po, oracles, pgs);
}
}
ZipEntry fileEntry = new ZipEntry("oracle/" + table.getTableName() + ".sql");
zos.putNextEntry(fileEntry);
for(String oracle : oracles)
zos.write((oracle+"\n;\n").getBytes());
zos.closeEntry();
fileEntry = new ZipEntry("postgresql/" + table.getTableName() + ".sql");
zos.putNextEntry(fileEntry);
for(String pg : pgs)
zos.write((pg+"\n;\n").getBytes());
zos.closeEntry();
//export child tabs
if (isCurrentRowOnly) {
for(GridTab childTab : childs) {
if (!childTab.isLoadComplete()){
childTab.initTab(false);
childTab.query(false, 0, 0);
}
if (childTab.getRowCount() == 0)
continue;
table = MTable.get(childTab.getAD_Table_ID());
oracles = new ArrayList<>();
pgs = new ArrayList<>();
for(int i = 0; i < childTab.getRowCount(); i++) {
PO po = getPO(childTab, table, i);
if (po != null)
addSQLInsert(po, oracles, pgs);
}
fileEntry = new ZipEntry("oracle/" + table.getTableName() + ".sql");
zos.putNextEntry(fileEntry);
for(String oracle : oracles)
zos.write((oracle+"\n;\n").getBytes());
zos.closeEntry();
fileEntry = new ZipEntry("postgresql/" + table.getTableName() + ".sql");
zos.putNextEntry(fileEntry);
for(String pg : pgs)
zos.write((pg+"\n;\n").getBytes());
zos.closeEntry();
}
}
} catch (Exception e) {
throw new AdempiereException(e);
}
}
/**
* Create SQL insert script for po
* @param po
* @param oracles list to add oracle insert script
* @param pgs list to add postgresql insert script
*/
protected void addSQLInsert(PO po, List<String> oracles, List<String> pgs) {
String sql = po.toInsertSQL();
String oracle = Database.getDatabase(Database.DB_ORACLE).convertStatement(sql);
String pg = Database.getDatabase(Database.DB_POSTGRESQL).convertStatement(sql);
oracles.add(oracle);
pgs.add(pg);
}
/**
* Load PO by record ID or UUID
* @param gridTab
* @param table
* @param row
* @return PO
*/
protected PO getPO(GridTab gridTab, MTable table, int row) {
int recordId = gridTab.getKeyID(row);
if (recordId >= 0) {
return table.getPO(gridTab.getKeyID(row), null);
} else {
UUID uuid = gridTab.getTableModel().getUUID(row);
if (uuid != null)
return table.getPOByUU(uuid.toString(), null);
}
return null;
}
@Override
public String getFileExtension() {
return "zip";
}
@Override
public String getFileExtensionLabel() {
return Msg.getMsg(Env.getCtx(), "FileSQLInsertZip");
}
@Override
public String getContentType() {
return "application/zip";
}
@Override
public String getSuggestedFileName(GridTab gridTab) {
return gridTab.getName() + "." + getFileExtension();
}
@Override
public boolean isExportableTab(GridTab gridTab) {
if (!gridTab.isDisplayed())
return false;
return true;
}
@Override
public boolean isAdvanced() {
return true;
}
@Override
public boolean isExportChildTabsForCurrentRowOnly() {
return true;
}
@Override
public int maxDeepOfChildTab() {
return 1;
}
}

View File

@ -1579,9 +1579,6 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
return true;
// ** dynamic content **
String parsed = Env.parseContext (m_vo.ctx, 0, dl, false, false).trim();
if (parsed.length() == 0)
return true;
boolean retValue = Evaluator.evaluateLogic(this, dl);
if (log.isLoggable(Level.CONFIG)) log.config(m_vo.Name + " (" + dl + ") => " + retValue);
return retValue;

View File

@ -3177,7 +3177,6 @@ public abstract class PO
} // saveNew
private boolean doInsert(boolean withValues) {
int index;
lobReset();
// Change Log
@ -3190,7 +3189,92 @@ public abstract class PO
List<Object> params = new ArrayList<Object>();
// SQL
StringBuilder sqlInsert = new StringBuilder("INSERT INTO ");
StringBuilder sqlInsert = new StringBuilder();
AD_ChangeLog_ID = buildInsertSQL(sqlInsert, withValues, params, session, AD_ChangeLog_ID, false);
//
int no = withValues ? DB.executeUpdate(sqlInsert.toString(), m_trxName)
: DB.executeUpdate(sqlInsert.toString(), params.toArray(), false, m_trxName);
boolean ok = no == 1;
if (ok)
{
if (withValues && m_IDs.length == 1 && p_info.hasKeyColumn()
&& m_KeyColumns[0].endsWith("_ID") && !Env.isUseCentralizedId(p_info.getTableName()))
{
int id = DB.getSQLValueEx(get_TrxName(), "SELECT " + m_KeyColumns[0] + " FROM "
+ p_info.getTableName() + " WHERE " + getUUIDColumnName() + "=?", get_ValueAsString(getUUIDColumnName()));
m_IDs[0] = Integer.valueOf(id);
set_ValueNoCheck(m_KeyColumns[0], m_IDs[0]);
int ki = p_info.getColumnIndex(m_KeyColumns[0]);
// Change Log - Only
String insertLog = MSysConfig.getValue(MSysConfig.SYSTEM_INSERT_CHANGELOG, "Y", getAD_Client_ID());
if ( session != null
&& m_IDs.length == 1
&& p_info.isAllowLogging(ki) // logging allowed
&& !p_info.isEncrypted(ki) // not encrypted
&& !p_info.isVirtualColumn(ki) // no virtual column
&& !"Password".equals(p_info.getColumnName(ki))
&& (insertLog.equalsIgnoreCase("Y")
|| (insertLog.equalsIgnoreCase("K") && p_info.getColumn(ki).IsKey))
)
{
// change log on new
MChangeLog cLog = session.changeLog (
m_trxName, AD_ChangeLog_ID,
p_info.getAD_Table_ID(), p_info.getColumn(ki).AD_Column_ID,
get_ID(), getAD_Client_ID(), getAD_Org_ID(), null, id, MChangeLog.EVENTCHANGELOG_Insert);
if (cLog != null)
AD_ChangeLog_ID = cLog.getAD_ChangeLog_ID();
}
}
ok = lobSave();
if (!load(m_trxName)) // re-read Info
{
if (m_trxName == null)
log.log(Level.SEVERE, "reloading");
else
log.log(Level.SEVERE, "[" + m_trxName + "] - reloading");
ok = false;;
}
}
else
{
String msg = "Not inserted - ";
if (CLogMgt.isLevelFiner())
msg += sqlInsert.toString();
else
msg += get_TableName();
if (m_trxName == null)
log.log(Level.WARNING, msg);
else
log.log(Level.WARNING, "[" + m_trxName + "]" + msg);
}
return ok;
}
/**
* Export data as insert SQL statement
*/
public String toInsertSQL()
{
StringBuilder sqlInsert = new StringBuilder();
buildInsertSQL(sqlInsert, true, null, null, 0, true);
return sqlInsert.toString();
}
/**
* Build insert SQL statement and capture change log
* @param sqlInsert
* @param withValues true to create statement with column values, false to use parameter binding (i.e with ?)
* @param params statement parameters when withValues is false
* @param session to capture change log. null when call from toInsertSQL (i.e to build sql only, not for real insert to DB)
* @param AD_ChangeLog_ID initial change log id
* @param generateScriptOnly true if it is to generate sql script only, false for real DB insert
* @return last AD_ChangeLog_ID
*/
protected int buildInsertSQL(StringBuilder sqlInsert, boolean withValues, List<Object> params, MSession session,
int AD_ChangeLog_ID, boolean generateScriptOnly) {
sqlInsert.append("INSERT INTO ");
sqlInsert.append(p_info.getTableName()).append(" (");
StringBuilder sqlValues = new StringBuilder(") VALUES (");
int size = get_ColumnCount();
@ -3212,6 +3296,13 @@ public abstract class PO
continue;
}
//do not export secure column
if (generateScriptOnly)
{
if (p_info.isEncrypted(i) || p_info.isSecure(i) || "Password".equalsIgnoreCase(p_info.getColumnName(i)))
continue;
}
// ** add column **
if (doComma)
{
@ -3229,11 +3320,18 @@ public abstract class PO
try
{
if (m_IDs.length == 1 && p_info.hasKeyColumn()
&& m_KeyColumns[0].endsWith("_ID") && m_KeyColumns[0].equals(p_info.getColumnName(i)) && !Env.isUseCentralizedId(p_info.getTableName()))
&& m_KeyColumns[0].endsWith("_ID") && m_KeyColumns[0].equals(p_info.getColumnName(i)) && (generateScriptOnly || !Env.isUseCentralizedId(p_info.getTableName())))
{
if (generateScriptOnly && get_ID() > 0 && get_ID() <= MTable.MAX_OFFICIAL_ID)
{
sqlValues.append(value);
}
else
{
MSequence sequence = MSequence.get(Env.getCtx(), p_info.getTableName(), get_TrxName(), true);
sqlValues.append("nextidfunc("+sequence.getAD_Sequence_ID()+",'N')");
}
}
else if (c == Object.class) // may have need to deal with null values differently
sqlValues.append (saveNewSpecial (value, i));
else if (value == null || value.equals (Null.NULL))
@ -3379,11 +3477,11 @@ public abstract class PO
}
}
if (!withValues || Env.isUseCentralizedId(p_info.getTableName()))
if (session != null && (!withValues || Env.isUseCentralizedId(p_info.getTableName())))
{
// Change Log - Only
String insertLog = MSysConfig.getValue(MSysConfig.SYSTEM_INSERT_CHANGELOG, "Y", getAD_Client_ID());
if ( session != null
if (!generateScriptOnly && session != null
&& m_IDs.length == 1
&& p_info.isAllowLogging(i) // logging allowed
&& !p_info.isEncrypted(i) // not encrypted
@ -3410,7 +3508,7 @@ public abstract class PO
while (it.hasNext())
{
String column = (String)it.next();
index = p_info.getColumnIndex(column);
int index = p_info.getColumnIndex(column);
String value = (String)m_custom.get(column);
if (value == null)
continue;
@ -3443,65 +3541,7 @@ public abstract class PO
}
sqlInsert.append(sqlValues)
.append(")");
//
int no = withValues ? DB.executeUpdate(sqlInsert.toString(), m_trxName)
: DB.executeUpdate(sqlInsert.toString(), params.toArray(), false, m_trxName);
boolean ok = no == 1;
if (ok)
{
if (withValues && m_IDs.length == 1 && p_info.hasKeyColumn()
&& m_KeyColumns[0].endsWith("_ID") && !Env.isUseCentralizedId(p_info.getTableName()))
{
int id = DB.getSQLValueEx(get_TrxName(), "SELECT " + m_KeyColumns[0] + " FROM "
+ p_info.getTableName() + " WHERE " + getUUIDColumnName() + "=?", get_ValueAsString(getUUIDColumnName()));
m_IDs[0] = Integer.valueOf(id);
set_ValueNoCheck(m_KeyColumns[0], m_IDs[0]);
int ki = p_info.getColumnIndex(m_KeyColumns[0]);
// Change Log - Only
String insertLog = MSysConfig.getValue(MSysConfig.SYSTEM_INSERT_CHANGELOG, "Y", getAD_Client_ID());
if ( session != null
&& m_IDs.length == 1
&& p_info.isAllowLogging(ki) // logging allowed
&& !p_info.isEncrypted(ki) // not encrypted
&& !p_info.isVirtualColumn(ki) // no virtual column
&& !"Password".equals(p_info.getColumnName(ki))
&& (insertLog.equalsIgnoreCase("Y")
|| (insertLog.equalsIgnoreCase("K") && p_info.getColumn(ki).IsKey))
)
{
// change log on new
MChangeLog cLog = session.changeLog (
m_trxName, AD_ChangeLog_ID,
p_info.getAD_Table_ID(), p_info.getColumn(ki).AD_Column_ID,
get_ID(), getAD_Client_ID(), getAD_Org_ID(), null, id, MChangeLog.EVENTCHANGELOG_Insert);
if (cLog != null)
AD_ChangeLog_ID = cLog.getAD_ChangeLog_ID();
}
}
ok = lobSave();
if (!load(m_trxName)) // re-read Info
{
if (m_trxName == null)
log.log(Level.SEVERE, "reloading");
else
log.log(Level.SEVERE, "[" + m_trxName + "] - reloading");
ok = false;;
}
}
else
{
String msg = "Not inserted - ";
if (CLogMgt.isLevelFiner())
msg += sqlInsert.toString();
else
msg += get_TableName();
if (m_trxName == null)
log.log(Level.WARNING, msg);
else
log.log(Level.WARNING, "[" + m_trxName + "]" + msg);
}
return ok;
return AD_ChangeLog_ID;
}
/**

View File

@ -657,6 +657,17 @@ public class POInfo implements Serializable
return m_columns[index].IsEncrypted;
} // isEncrypted
/**
* @param index
* @return true if column is secure
*/
public boolean isSecure(int index)
{
if (index < 0 || index >= m_columns.length)
return false;
return MColumn.get(m_columns[index].AD_Column_ID).isSecure();
}
/**
* Is allowed logging on this column
*

View File

@ -15,6 +15,7 @@ package org.adempiere.webui.panel.action;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -44,6 +45,7 @@ import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.Dialog;
import org.compiere.model.GridTab;
import org.compiere.model.MRole;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.util.media.AMedia;
@ -56,26 +58,30 @@ import org.zkoss.zul.Vbox;
import org.zkoss.zul.Vlayout;
/**
*
* Action to export data from {@link GridTab}
* @author hengsin
*
*/
public class ExportAction implements EventListener<Event>
{
private AbstractADWindowContent panel;
/** Exporter Label:IGridTabExporter */
private Map<String, IGridTabExporter> exporterMap = null;
/** Exporter Label:Exporter File Extension */
private Map<String, String> extensionMap = null;
/** Export file dialog */
private Window winExportFile = null;
private ConfirmPanel confirmPanel = new ConfirmPanel(true);
/** List of exporters */
private Listbox cboType = new Listbox();
private Checkbox chkCurrentRow = new Checkbox();
private int indxDetailSelected = 0;
private List<GridTab> childs;
private Row selectionTabRow = null;
private List<Checkbox> chkSelectionTabForExport = null;
private int selectedChildTabIndex = 0;
private List<GridTab> childTabs;
private Row childTabSelectionRow = null;
private List<Checkbox> chkSelectChildTabs = null;
private IGridTabExporter exporter;
/**
* @param panel
*/
@ -92,13 +98,17 @@ public class ExportAction implements EventListener<Event>
exporterMap = new HashMap<String, IGridTabExporter>();
extensionMap = new HashMap<String, String>();
List<IGridTabExporter> exporterList = EquinoxExtensionLocator.instance().list(IGridTabExporter.class).getExtensions();
MRole role = MRole.getDefault();
for(IGridTabExporter exporter : exporterList)
{
if (exporter.isAdvanced() && !role.isAccessAdvanced())
continue;
String extension = exporter.getFileExtension();
if (!extensionMap.containsKey(extension))
if (!extensionMap.containsKey(exporter.getFileExtensionLabel()))
{
extensionMap.put(extension, exporter.getFileExtensionLabel());
exporterMap.put(extension, exporter);
extensionMap.put(exporter.getFileExtensionLabel(), extension);
exporterMap.put(exporter.getFileExtensionLabel(), exporter);
}
}
@ -116,9 +126,11 @@ public class ExportAction implements EventListener<Event>
cboType.setMold("select");
cboType.getItems().clear();
for(Map.Entry<String, String> entry : extensionMap.entrySet())
List<String> keys = new ArrayList<>(extensionMap.keySet());
Collections.sort(keys);
for(String key : keys)
{
cboType.appendItem(entry.getKey() + " - " + entry.getValue(), entry.getKey());
cboType.appendItem(key, key);
}
cboType.setSelectedIndex(0);
@ -159,9 +171,10 @@ public class ExportAction implements EventListener<Event>
chkCurrentRow.setLabel(Msg.getMsg(Env.getCtx(), "ExportCurrentRowOnly"));
chkCurrentRow.setSelected(true);
row.appendChild(chkCurrentRow);
chkCurrentRow.addActionListener(this);
selectionTabRow = new Row();
rows.appendChild(selectionTabRow);
childTabSelectionRow = new Row();
rows.appendChild(childTabSelectionRow);
LayoutUtils.addSclass("dialog-footer", confirmPanel);
vb.appendChild(confirmPanel);
@ -179,51 +192,61 @@ public class ExportAction implements EventListener<Event>
}
/**
* Show list tab can export for user selection
* Show child tabs for user selection
*/
protected void displayExportTabSelection() {
initTabInfo ();
int tabLevel = panel.getActiveGridTab().getTabLevel();
exporter = getExporter ();
if (exporter == null){
Events.echoEvent("onExporterException", winExportFile, null);
}
// clear list checkbox selection to recreate with new reporter
selectionTabRow.getChildren().clear();
childTabSelectionRow.getChildren().clear();
if (exporter.isExportChildTabsForCurrentRowOnly() && !chkCurrentRow.isChecked())
return;
Vlayout vlayout = new Vlayout();
selectionTabRow.appendChild(new Space());
selectionTabRow.appendChild(vlayout);
childTabSelectionRow.appendChild(new Space());
childTabSelectionRow.appendChild(vlayout);
vlayout.appendChild(new Label(Msg.getMsg(Env.getCtx(), "SelectTabToExport")));
chkSelectionTabForExport = new ArrayList<Checkbox> ();
chkSelectChildTabs = new ArrayList<Checkbox> ();
boolean isHasSelectionTab = false;
boolean isSelectTabDefault = false;
boolean selectAllChildTabs = false;
// with 2Pack, default is export all child tab
if (exporter.getClass().getName().equals("org.adempiere.pipo2.GridTab2PackExporter")){
isSelectTabDefault = true;
selectAllChildTabs = true;
}
// for to make each export tab with one checkbox
for (GridTab child : childs){
for (GridTab child : childTabs){
Checkbox chkSelectionTab = new Checkbox();
chkSelectionTab.setLabel(child.getName());
// just allow selection tab can export
// check with exporter
if (!exporter.isExportableTab(child)){
continue;
}
if (child.getTabNo() == indxDetailSelected || isSelectTabDefault){
if (exporter.maxDeepOfChildTab() > 0) {
int deep = child.getTabLevel() - tabLevel;
if (deep > exporter.maxDeepOfChildTab())
continue;
}
if (child.getTabNo() == selectedChildTabIndex || selectAllChildTabs){
chkSelectionTab.setSelected(true);
}
chkSelectionTab.setAttribute("tabBinding", child);
vlayout.appendChild(chkSelectionTab);
chkSelectionTabForExport.add(chkSelectionTab);
chkSelectChildTabs.add(chkSelectionTab);
chkSelectionTab.addEventListener(Events.ON_CHECK, this);
isHasSelectionTab = true;
}
// in case no child tab can export. clear selection area
if (isHasSelectionTab == false){
selectionTabRow.getChildren().clear();
childTabSelectionRow.getChildren().clear();
}
}
@ -238,12 +261,17 @@ public class ExportAction implements EventListener<Event>
panel.focusToLastFocusEditor();
} else if (event.getTarget().equals(cboType) && event.getName().equals(Events.ON_SELECT)) {
displayExportTabSelection();
} else if (event.getTarget() == chkCurrentRow) {
exporter = getExporter();
if (exporter != null && exporter.isExportChildTabsForCurrentRowOnly()) {
displayExportTabSelection();
}
} else if (event.getTarget() instanceof Checkbox) {
// A child is not exportable without its parent
Checkbox cbSel = (Checkbox) event.getTarget();
GridTab gtSel = (GridTab)cbSel.getAttribute("tabBinding");
boolean found = false;
for (Checkbox cb : chkSelectionTabForExport) {
for (Checkbox cb : chkSelectChildTabs) {
if (cb == cbSel) {
found = true;
continue;
@ -264,20 +292,23 @@ public class ExportAction implements EventListener<Event>
}
}
/**
* Close export file dialog
*/
private void onCancel() {
winExportFile.onClose();
}
/**
* get info of window export,
* index of active tab, list child tab
* Get GridTabs info from calling AD window,
* index of active detail tab, child tabs
*/
protected void initTabInfo() {
IADTabbox adTab = panel.getADTab();
int selected = adTab.getSelectedIndex();
int tabLevel = panel.getActiveGridTab().getTabLevel();
Set<String> tables = new HashSet<String>();
childs = new ArrayList<GridTab>();
childTabs = new ArrayList<GridTab>();
List<GridTab> includedList = panel.getActiveGridTab().getIncludedTabs();
for(GridTab included : includedList)
{
@ -285,7 +316,7 @@ public class ExportAction implements EventListener<Event>
if (tables.contains(tableName))
continue;
tables.add(tableName);
childs.add(included);
childTabs.add(included);
}
for(int i = selected+1; i < adTab.getTabCount(); i++)
{
@ -298,18 +329,18 @@ public class ExportAction implements EventListener<Event>
if (tables.contains(tableName))
continue;
tables.add(tableName);
childs.add(adTabPanel.getGridTab());
childTabs.add(adTabPanel.getGridTab());
}
indxDetailSelected = 0;
selectedChildTabIndex = 0;
if( adTab.getSelectedDetailADTabpanel()!=null )
indxDetailSelected = adTab.getSelectedDetailADTabpanel().getGridTab().getTabNo();
selectedChildTabIndex = adTab.getSelectedDetailADTabpanel().getGridTab().getTabNo();
}
/**
* Get selected exporter
* @return
* @return IGridTabExporter
*/
protected IGridTabExporter getExporter() {
ListItem li = cboType.getSelectedItem();
@ -323,18 +354,21 @@ public class ExportAction implements EventListener<Event>
return exporter;
}
/**
* Invoke exporter and prompt user to download exported data file
*/
private void exportFile() {
try {
boolean currentRowOnly = chkCurrentRow.isSelected();
File file = File.createTempFile("Export", "."+cboType.getSelectedItem().getValue().toString());
childs.clear();
for (Checkbox chkSeletionTab : chkSelectionTabForExport){
List<GridTab> selectedChildTabs = new ArrayList<>();
for (Checkbox chkSeletionTab : chkSelectChildTabs){
if (chkSeletionTab.isChecked()){
childs.add((GridTab)chkSeletionTab.getAttribute("tabBinding"));
selectedChildTabs.add((GridTab)chkSeletionTab.getAttribute("tabBinding"));
}
}
exporter.export(panel.getActiveGridTab(), childs, currentRowOnly,file,indxDetailSelected);
exporter.export(panel.getActiveGridTab(), selectedChildTabs, currentRowOnly, file, selectedChildTabIndex);
winExportFile.onClose();
winExportFile = null;