From 772ec433686f3b050e23a1c53350965e21ec208a Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 4 Apr 2014 10:19:40 -0500 Subject: [PATCH] IDEMPIERE-1572 Last Run and Saved parameter for process / based on patch from Deepak Pansheriya --- .../oracle/201404040826_IDEMPIERE-1572.sql | 35 ++++ .../201404040826_IDEMPIERE-1572.sql | 32 ++++ .../org/compiere/model/I_AD_PInstance.java | 13 ++ .../src/org/compiere/model/MPInstance.java | 88 ++++++++- .../org/compiere/model/X_AD_PInstance.java | 19 +- .../src/org/compiere/apps/ProcessDialog.java | 144 +++++++++++++- .../compiere/apps/ProcessParameterPanel.java | 61 +++++- .../adempiere/webui/apps/ProcessDialog.java | 180 ++++++++++++++++-- .../webui/apps/ProcessParameterPanel.java | 61 +++++- .../webui/editor/WTableDirEditor.java | 4 +- 10 files changed, 612 insertions(+), 25 deletions(-) create mode 100644 migration/i2.0z/oracle/201404040826_IDEMPIERE-1572.sql create mode 100644 migration/i2.0z/postgresql/201404040826_IDEMPIERE-1572.sql diff --git a/migration/i2.0z/oracle/201404040826_IDEMPIERE-1572.sql b/migration/i2.0z/oracle/201404040826_IDEMPIERE-1572.sql new file mode 100644 index 0000000000..31b97cfb0d --- /dev/null +++ b/migration/i2.0z/oracle/201404040826_IDEMPIERE-1572.sql @@ -0,0 +1,35 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Nov 27, 2013 10:35:14 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Table_ID,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,CreatedBy,Updated,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,EntityType,IsEncrypted,AD_Element_ID,AD_Client_ID,IsSecure) VALUES (0,'N',0,282,210890,'N','N','Y',0,'N',60,'Y',10,'N','N','Y','4f66cceb-27a2-47b8-a1ef-0bc2882bfdef','Y','Name','Alphanumeric identifier of the entity','The name of an entity (record) is used as an default search option in addition to the search key. The name is up to 60 characters in length.','Name','Y',100,TO_DATE('2013-11-27 10:35:12','YYYY-MM-DD HH24:MI:SS'),0,'Y',TO_DATE('2013-11-27 10:35:12','YYYY-MM-DD HH24:MI:SS'),100,'N','N','D','N',469,0,'N') +; + +-- Nov 27, 2013 10:35:20 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +ALTER TABLE AD_PInstance ADD Name NVARCHAR2(60) DEFAULT NULL +; + +-- Nov 27, 2013 10:36:46 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('I','Last Run',200240,'D','fd39a4cd-eb0a-4b35-97ae-cbd4657d8234','LastRun','Y',TO_DATE('2013-11-27 10:36:45','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_DATE('2013-11-27 10:36:45','YYYY-MM-DD HH24:MI:SS'),0) +; + +-- Nov 27, 2013 10:37:01 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('I','Saved Parameters',200241,'D','f1688973-03c3-4af4-9b76-a0cec366ec41','SavedParameter','Y',TO_DATE('2013-11-27 10:37:00','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_DATE('2013-11-27 10:37:00','YYYY-MM-DD HH24:MI:SS'),0) +; + +-- Nov 27, 2013 10:47:53 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('I','Could not save parameters.',200242,'D','d07376af-ab08-4835-a962-9f5addc8dedc','SaveParameterError','Y',TO_DATE('2013-11-27 10:47:52','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_DATE('2013-11-27 10:47:52','YYYY-MM-DD HH24:MI:SS'),0) +; + +-- Mar 28, 2014 12:23:30 PM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Created,Updated,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200046,'C','5','9b2426cb-b513-4199-b835-016cbc34a24f',TO_DATE('2014-03-28 12:23:23','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-03-28 12:23:23','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'LASTRUN_RECORD_COUNT',0,'D') +; + +SELECT register_migration_script('201404040826_IDEMPIERE-1572.sql') FROM dual +; diff --git a/migration/i2.0z/postgresql/201404040826_IDEMPIERE-1572.sql b/migration/i2.0z/postgresql/201404040826_IDEMPIERE-1572.sql new file mode 100644 index 0000000000..9b25763f0d --- /dev/null +++ b/migration/i2.0z/postgresql/201404040826_IDEMPIERE-1572.sql @@ -0,0 +1,32 @@ +-- Nov 27, 2013 10:35:14 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Table_ID,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,AD_Reference_ID,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,CreatedBy,Updated,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,EntityType,IsEncrypted,AD_Element_ID,AD_Client_ID,IsSecure) VALUES (0,'N',0,282,210890,'N','N','Y',0,'N',60,'Y',10,'N','N','Y','4f66cceb-27a2-47b8-a1ef-0bc2882bfdef','Y','Name','Alphanumeric identifier of the entity','The name of an entity (record) is used as an default search option in addition to the search key. The name is up to 60 characters in length.','Name','Y',100,TO_TIMESTAMP('2013-11-27 10:35:12','YYYY-MM-DD HH24:MI:SS'),0,'Y',TO_TIMESTAMP('2013-11-27 10:35:12','YYYY-MM-DD HH24:MI:SS'),100,'N','N','D','N',469,0,'N') +; + +-- Nov 27, 2013 10:35:20 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +ALTER TABLE AD_PInstance ADD COLUMN Name VARCHAR(60) DEFAULT NULL +; + +-- Nov 27, 2013 10:36:46 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('I','Last Run',200240,'D','fd39a4cd-eb0a-4b35-97ae-cbd4657d8234','LastRun','Y',TO_TIMESTAMP('2013-11-27 10:36:45','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_TIMESTAMP('2013-11-27 10:36:45','YYYY-MM-DD HH24:MI:SS'),0) +; + +-- Nov 27, 2013 10:37:01 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('I','Saved Parameters',200241,'D','f1688973-03c3-4af4-9b76-a0cec366ec41','SavedParameter','Y',TO_TIMESTAMP('2013-11-27 10:37:00','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_TIMESTAMP('2013-11-27 10:37:00','YYYY-MM-DD HH24:MI:SS'),0) +; + +-- Nov 27, 2013 10:47:53 AM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Org_ID,Created,AD_Client_ID) VALUES ('I','Could not save parameters.',200242,'D','d07376af-ab08-4835-a962-9f5addc8dedc','SaveParameterError','Y',TO_TIMESTAMP('2013-11-27 10:47:52','YYYY-MM-DD HH24:MI:SS'),100,100,0,TO_TIMESTAMP('2013-11-27 10:47:52','YYYY-MM-DD HH24:MI:SS'),0) +; + +-- Mar 28, 2014 12:23:30 PM IST +-- IDEMPIERE-1572: Last Run and Saved parameter for process +INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Created,Updated,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200046,'C','5','9b2426cb-b513-4199-b835-016cbc34a24f',TO_TIMESTAMP('2014-03-28 12:23:23','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-03-28 12:23:23','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'LASTRUN_RECORD_COUNT',0,'D') +; + +SELECT register_migration_script('201404040826_IDEMPIERE-1572.sql') FROM dual +; diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_PInstance.java b/org.adempiere.base/src/org/compiere/model/I_AD_PInstance.java index cc102e7513..dd041cd8de 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_PInstance.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_PInstance.java @@ -161,6 +161,19 @@ public interface I_AD_PInstance /** Get Processing */ public boolean isProcessing(); + /** Column name Name */ + public static final String COLUMNNAME_Name = "Name"; + + /** Set Name. + * Alphanumeric identifier of the entity + */ + public void setName (String Name); + + /** Get Name. + * Alphanumeric identifier of the entity + */ + public String getName(); + /** Column name Record_ID */ public static final String COLUMNNAME_Record_ID = "Record_ID"; diff --git a/org.adempiere.base/src/org/compiere/model/MPInstance.java b/org.adempiere.base/src/org/compiere/model/MPInstance.java index 6909333f64..6b58195ffc 100644 --- a/org.adempiere.base/src/org/compiere/model/MPInstance.java +++ b/org.adempiere.base/src/org/compiere/model/MPInstance.java @@ -25,8 +25,10 @@ import java.util.List; import java.util.Properties; import java.util.logging.Level; +import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; +import org.compiere.util.Msg; /** * Process Instance Model @@ -40,11 +42,12 @@ import org.compiere.util.Env; */ public class MPInstance extends X_AD_PInstance { + /** + * + */ + private static final long serialVersionUID = -3952972645135787655L; - /** - * - */ - private static final long serialVersionUID = -5848424269552679604L; + private static CLogger s_log = CLogger.getCLogger (MPInstance.class); /** * Standard Constructor @@ -130,6 +133,7 @@ public class MPInstance extends X_AD_PInstance final String whereClause = "AD_PInstance_ID=?"; List list = new Query(getCtx(), I_AD_PInstance_Para.Table_Name, whereClause, null) // @TODO: Review implications of using transaction .setParameters(getAD_PInstance_ID()) + .setOrderBy("SeqNo, ParameterName") .list(); // @@ -349,4 +353,78 @@ public class MPInstance extends X_AD_PInstance ip.saveEx(); return ip; } -} // MPInstance + + public static List get(Properties ctx, int AD_Process_ID, int AD_User_ID) { + List list = new ArrayList(); + List paramsStrAdded = new ArrayList(); + + List namedInstances = new Query(ctx, Table_Name, "AD_Process_ID=? AND AD_User_ID=? AND Name IS NOT NULL", null) + .setClient_ID() + .setOnlyActiveRecords(true) + .setParameters(AD_Process_ID, AD_User_ID) + .setOrderBy("Name") + .list(); + for (MPInstance namedInstance : namedInstances) { + list.add(namedInstance); + paramsStrAdded.add(namedInstance.getParamsStr()); + } + + // unnamed instances + int lastRunCount = MSysConfig.getIntValue("LASTRUN_RECORD_COUNT", 5, Env.getAD_Client_ID(ctx)); + if (lastRunCount > 0) { + // using JDBC instead of Query for performance reasons, AD_PInstance can be huge + String sql = "SELECT * FROM AD_PInstance " + + " WHERE AD_Process_ID=? AND AD_User_ID=? AND IsActive='Y' AND AD_Client_ID=? AND Name IS NULL" + + " ORDER BY Created DESC"; + PreparedStatement pstmt = null; + ResultSet rs = null; + int cnt = 0; + try { + pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, AD_Process_ID); + pstmt.setInt(2, AD_User_ID); + pstmt.setInt(3, Env.getAD_Client_ID(ctx)); + rs = pstmt.executeQuery(); + while (rs.next()) { + MPInstance unnamedInstance = new MPInstance(ctx, rs, null); + String paramsStr = unnamedInstance.getParamsStr(); + if (! paramsStrAdded.contains(paramsStr)) { + unnamedInstance.setName(Msg.getMsg(ctx, "LastRun") + " " + unnamedInstance.getCreated()); + list.add(unnamedInstance); + paramsStrAdded.add(paramsStr); + cnt++; + if (cnt == lastRunCount) + break; + } + } + } catch (Exception e) + { + s_log.log(Level.SEVERE, "Error while Fetching last run records", e); + } finally { + DB.close(rs, pstmt); + rs = null; pstmt = null; + } + } + + return list; + } + + private String getParamsStr() { + StringBuilder cksum = new StringBuilder(); + for (MPInstancePara ip : getParameters()) { + cksum.append("(") + .append(ip.getParameterName()).append("|") + .append(ip.getP_String()).append("|") + .append(ip.getP_String_To()).append("|") + .append(ip.getP_Number()).append("|") + .append(ip.getP_Number_To()).append("|") + .append(ip.getP_Date()).append("|") + .append(ip.getP_Date_To()).append("|") + .append(ip.getInfo()).append("|") + .append(ip.getInfo_To()).append("|") + .append(")"); + } + return cksum.toString(); + } + +} // MPInstance \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_PInstance.java b/org.adempiere.base/src/org/compiere/model/X_AD_PInstance.java index 9d4d7fa535..1dd50b1e0b 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_PInstance.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_PInstance.java @@ -30,7 +30,7 @@ public class X_AD_PInstance extends PO implements I_AD_PInstance, I_Persistent /** * */ - private static final long serialVersionUID = 20131031L; + private static final long serialVersionUID = 20140404L; /** Standard Constructor */ public X_AD_PInstance (Properties ctx, int AD_PInstance_ID, String trxName) @@ -209,6 +209,23 @@ public class X_AD_PInstance extends PO implements I_AD_PInstance, I_Persistent return false; } + /** Set Name. + @param Name + Alphanumeric identifier of the entity + */ + public void setName (String Name) + { + set_Value (COLUMNNAME_Name, Name); + } + + /** Get Name. + @return Alphanumeric identifier of the entity + */ + public String getName () + { + return (String)get_Value(COLUMNNAME_Name); + } + /** Set Record ID. @param Record_ID Direct internal record ID diff --git a/org.adempiere.ui.swing/src/org/compiere/apps/ProcessDialog.java b/org.adempiere.ui.swing/src/org/compiere/apps/ProcessDialog.java index 4feb11029d..86798c21bd 100644 --- a/org.adempiere.ui.swing/src/org/compiere/apps/ProcessDialog.java +++ b/org.adempiere.ui.swing/src/org/compiere/apps/ProcessDialog.java @@ -16,20 +16,27 @@ *****************************************************************************/ package org.compiere.apps; +import static org.compiere.model.SystemIDs.PROCESS_C_INVOICE_GENERATE; +import static org.compiere.model.SystemIDs.PROCESS_M_INOUT_GENERATE; + import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GraphicsConfiguration; +import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.List; import java.util.logging.Level; +import javax.swing.DefaultComboBoxModel; +import javax.swing.ImageIcon; import javax.swing.JEditorPane; import javax.swing.JOptionPane; import javax.swing.JScrollPane; @@ -39,18 +46,23 @@ import org.adempiere.exceptions.AdempiereException; import org.adempiere.exceptions.DBException; import org.adempiere.util.Callback; import org.adempiere.util.IProcessUI; -import static org.compiere.model.SystemIDs.*; +import org.compiere.model.MPInstance; +import org.compiere.model.MPInstancePara; import org.compiere.print.ReportCtl; import org.compiere.print.ReportEngine; import org.compiere.process.ProcessInfo; import org.compiere.process.ProcessInfoUtil; import org.compiere.swing.CButton; +import org.compiere.swing.CComboBox; import org.compiere.swing.CFrame; +import org.compiere.swing.CLabel; import org.compiere.swing.CPanel; +import org.compiere.util.AdempiereSystemError; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.compiere.util.Util; /** * Dialog to Start process. @@ -75,7 +87,7 @@ public class ProcessDialog extends CFrame /** * */ - private static final long serialVersionUID = 7486479305726277406L; + private static final long serialVersionUID = 2435351857958558386L; /** * @deprecated @@ -194,6 +206,11 @@ public class ProcessDialog extends CFrame private ProcessParameterPanel parameterPanel = null; private JSeparator separator = new JSeparator(); private ProcessInfo m_pi = null; + private CComboBox fSavedName = new CComboBox(); + private CButton bSave = new CButton(); + private CButton bDelete = new CButton(); + private List savedParams; + private CLabel lSaved = new CLabel(Msg.getMsg(Env.getCtx(), "SavedParameter")); /** * Static Layout @@ -207,6 +224,19 @@ public class ProcessDialog extends CFrame dialog.setMinimumSize(new Dimension(500, 200)); bOK.addActionListener(this); bPrint.addActionListener(this); + fSavedName.setToolTipText (Msg.getMsg(Env.getCtx(),"SavedParameter")); + fSavedName.setEditable(true); + fSavedName.addActionListener(this); + bSave.setIcon(new ImageIcon(org.compiere.Adempiere.class.getResource("images/Save24.gif"))); + bSave.setMargin(new Insets(2, 2, 2, 2)); + bSave.setToolTipText(Msg.getMsg(Env.getCtx(),"Save")); + bSave.addActionListener(this); + bSave.setEnabled(false); + bDelete.setIcon(new ImageIcon(org.compiere.Adempiere.class.getResource("images/Delete24.gif"))); + bDelete.setMargin(new Insets(2, 2, 2, 2)); + bDelete.setToolTipText(Msg.getMsg(Env.getCtx(),"Delete")); + bDelete.addActionListener(this); + bDelete.setEnabled(false); // southPanel.setLayout(southLayout); southLayout.setAlignment(FlowLayout.RIGHT); @@ -216,7 +246,12 @@ public class ProcessDialog extends CFrame message.setFocusable(true); getContentPane().add(dialog); dialog.add(southPanel, BorderLayout.SOUTH); - southPanel.add(bPrint, null); + + southPanel.add(lSaved,"wrap"); + southPanel.add(fSavedName, "w :200:"); + southPanel.add(bSave, null); + southPanel.add(bDelete, null); + southPanel.add(bPrint, "span, split 2, align right, pushx"); southPanel.add(bOK, null); dialog.add(messagePane, BorderLayout.NORTH); messagePane.setBorder(null); @@ -337,16 +372,39 @@ public class ProcessDialog extends CFrame if(m_ShowHelp != null && m_ShowHelp.equals("S")) bOK.doClick(); + querySaved(); + dialog.revalidate(); return true; } // init + private void querySaved() { + //user query + savedParams = MPInstance.get(Env.getCtx(), m_AD_Process_ID, Env.getContextAsInt(Env.getCtx(), "#AD_User_ID")); + String[] queries = new String[savedParams.size()+1]; + int i = 0; + queries[i++] = ""; + for (MPInstance instance : savedParams) + { + queries[i++] = instance.getName(); + } + fSavedName.setModel(new DefaultComboBoxModel(queries)); + fSavedName.setValue(""); + } + /** * ActionListener (Start) * @param e ActionEvent */ public void actionPerformed (ActionEvent e) { + + String saveName = null; + if (fSavedName.getSelectedItem() != null) + saveName = fSavedName.getSelectedItem().toString(); + + boolean lastRun = ("** " + Msg.getMsg(Env.getCtx(), "LastRun") + " **").equals(saveName); + if (e.getSource() == bOK) { if (bOK.getText().length() == 0) @@ -357,12 +415,92 @@ public class ProcessDialog extends CFrame ProcessCtl.process(this, m_WindowNo, parameterPanel, m_pi, null); } } + else if (e.getSource() == fSavedName) + { + if (savedParams != null && saveName != null) + { + for (int i = 0; i < savedParams.size(); i++) + { + if (savedParams.get(i).getName().equals(saveName)) + { + loadSavedParams(savedParams.get(i)); + } + } + } + boolean enabled = !Util.isEmpty(saveName); + bSave.setEnabled(enabled && !lastRun); + bDelete.setEnabled(enabled && fSavedName.getSelectedIndex() > -1 && !lastRun); + } + else if (e.getSource() == bSave && fSavedName != null && !lastRun) + { + // Update existing + if (fSavedName.getSelectedIndex() > -1 && savedParams != null) + { + for (int i = 0; i < savedParams.size(); i++) + { + if (savedParams.get(i).getName().equals(saveName)) + { + m_pi.setAD_PInstance_ID(savedParams.get(i).getAD_PInstance_ID()); + for (MPInstancePara para : savedParams.get(i).getParameters()) + { + para.deleteEx(true); + } + parameterPanel.saveParameters(); + } + } + } + // create new + else { + MPInstance instance = null; + try + { + instance = new MPInstance(Env.getCtx(), m_pi.getAD_Process_ID(), m_pi.getRecord_ID()); + instance.setName(saveName); + instance.saveEx(); + + m_pi.setAD_PInstance_ID(instance.getAD_PInstance_ID()); + // Get Parameters + if (parameterPanel != null) { + if (!parameterPanel.saveParameters()) + { + throw new AdempiereSystemError(Msg.getMsg(Env.getCtx(), "SaveParameterError")); + } + } + } + catch (Exception ex) + { + ADialog.warn(m_WindowNo, this, ex.getLocalizedMessage()); + } + } + querySaved(); + fSavedName.setSelectedItem(saveName); + } + else if (e.getSource() == bDelete && fSavedName != null && !lastRun ) + { + Object o = fSavedName.getSelectedItem(); + if (savedParams != null && o != null) + { + String selected = o.toString(); + for (int i = 0; i < savedParams.size(); i++) + { + if (savedParams.get(i).getName().equals(selected)) + { + savedParams.get(i).deleteEx(true); + } + } + } + querySaved(); + } else if (e.getSource() == bPrint) printScreen(); } // actionPerformed + private void loadSavedParams(MPInstance instance) { + parameterPanel.loadParameters(instance); + } + /** * Lock User Interface * Called from the Worker before processing diff --git a/org.adempiere.ui.swing/src/org/compiere/apps/ProcessParameterPanel.java b/org.adempiere.ui.swing/src/org/compiere/apps/ProcessParameterPanel.java index 0ae23e3e16..b7f1cd9d77 100644 --- a/org.adempiere.ui.swing/src/org/compiere/apps/ProcessParameterPanel.java +++ b/org.adempiere.ui.swing/src/org/compiere/apps/ProcessParameterPanel.java @@ -40,6 +40,7 @@ import org.compiere.model.GridField; import org.compiere.model.GridFieldVO; import org.compiere.model.MClient; import org.compiere.model.MLookup; +import org.compiere.model.MPInstance; import org.compiere.model.MPInstancePara; import org.compiere.process.ProcessInfo; import org.compiere.swing.CLabel; @@ -65,7 +66,7 @@ public class ProcessParameterPanel extends CPanel implements VetoableChangeListe /** * */ - private static final long serialVersionUID = 3871379020889713432L; + private static final long serialVersionUID = -111202562692738248L; /** * Dynamic generated Parameter panel. @@ -638,6 +639,64 @@ public class ProcessParameterPanel extends CPanel implements VetoableChangeListe return true; } // saveParameters + /* + * load parameters from saved instance + */ + public boolean loadParameters(MPInstance instance) + { + log.config(""); + + MPInstancePara[] params = instance.getParameters(); + for (int j = 0; j < m_mFields.size(); j++) + { + GridField mField = (GridField)m_mFields.get(j); + + // Get Values + VEditor editor = (VEditor)m_vEditors.get(j); + VEditor editor2 = (VEditor)m_vEditors2.get(j); + + editor.setValue(null); + if (editor2 != null) + editor2.setValue(null); + + for ( int i = 0; i, IProc /** * */ - private static final long serialVersionUID = 6316822220179816250L; + private static final long serialVersionUID = -899849696748614034L; private static final String MESSAGE_DIV_STYLE = "max-height: 150pt; overflow: auto; margin: 10px;"; private Div messageDiv; @@ -117,6 +128,10 @@ public class ProcessDialog extends Window implements EventListener, IProc private List downloadFiles; + private boolean showLastRun = false; + + private Grid southRowPanel = GridFactory.newGridLayout(); + /** * Dialog to start a process/report * @param ctx @@ -139,6 +154,11 @@ public class ProcessDialog extends Window implements EventListener, IProc Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", isSOTrx ? "Y" : "N"); try { + MProcess process = new MProcess(m_ctx, m_AD_Process_ID, null); + int count = process.getParameters().length; + if (count > 0) + showLastRun = true; + initComponents(); init(); addEventListener(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, this); @@ -174,26 +194,48 @@ public class ProcessDialog extends Window implements EventListener, IProc center.setAutoscroll(true); center.setStyle("border: none"); - Hlayout hbox = new Hlayout(); + Rows rows = southRowPanel.newRows(); + Row row = rows.newRow(); + + Hbox hBox = new Hbox(); + + hBox.appendChild(lSaved); + fSavedName.addEventListener(Events.ON_CHANGE, this); + hBox.appendChild(fSavedName); + + bSave.setEnabled(false); + bSave.addActionListener(this); + hBox.appendChild(bSave); + + bDelete.setEnabled(false); + bDelete.addActionListener(this); + hBox.appendChild(bDelete); + + row.appendChild(hBox); + + if(!showLastRun) + hBox.setVisible(false); + + Panel confParaPanel =new Panel(); + confParaPanel.setAlign("right"); @SuppressWarnings("unused") String label = Msg.getMsg(Env.getCtx(), "Start"); // Invert - Unify OK/Cancel IDEMPIERE-77 bOK = ButtonFactory.createNamedButton(ConfirmPanel.A_OK, true, true); bOK.setId("Ok"); bOK.addEventListener(Events.ON_CLICK, this); - hbox.appendChild(bOK); + confParaPanel.appendChild(bOK); - Button btn = ButtonFactory.createNamedButton(ConfirmPanel.A_CANCEL, true, true); - btn.setId("Cancel"); - btn.addEventListener(Events.ON_CLICK, this); - hbox.appendChild(btn); - hbox.setStyle("padding: 10px; margin: auto; overflow: visible;"); - hbox.setHflex("min"); + bCancel = ButtonFactory.createNamedButton(ConfirmPanel.A_CANCEL, true, true); + bCancel.setId("Cancel"); + bCancel.addEventListener(Events.ON_CLICK, this); + confParaPanel.appendChild(bCancel); + row.appendChild(confParaPanel); South south = new South(); south.setSclass("dialog-footer"); layout.appendChild(south); - south.appendChild(hbox); + south.appendChild(southRowPanel); this.appendChild(layout); } @@ -209,6 +251,7 @@ public class ProcessDialog extends Window implements EventListener, IProc private Panel centerPanel = null; private Html message = null; private Button bOK = null; + private Button bCancel = null; private boolean valid = true; @@ -229,6 +272,13 @@ public class ProcessDialog extends Window implements EventListener, IProc private static final String ON_STATUS_UPDATE = "onStatusUpdate"; private static final String ON_COMPLETE = "onComplete"; + //saved parameters + private Combobox fSavedName=new Combobox(); + private Button bSave=ButtonFactory.createNamedButton("Save"); + private Button bDelete=ButtonFactory.createNamedButton("Delete"); + private List savedParams; + private Label lSaved=new Label(Msg.getMsg(Env.getCtx(), "SavedParameter")); + /** * Set Visible * (set focus to OK if visible) @@ -330,9 +380,24 @@ public class ProcessDialog extends Window implements EventListener, IProc { startProcess(); } + querySaved(); return true; } // init + private void querySaved() + { + //user query + savedParams = MPInstance.get(Env.getCtx(), m_AD_Process_ID, Env.getContextAsInt(Env.getCtx(), "#AD_User_ID")); + fSavedName.removeAllItems(); + for (MPInstance instance : savedParams) + { + String queries = instance.get_ValueAsString("Name"); + fSavedName.appendItem(queries); + } + + fSavedName.setValue(""); + } + public void startProcess() { m_pi.setPrintPreview(true); @@ -379,6 +444,14 @@ public class ProcessDialog extends Window implements EventListener, IProc public void onEvent(Event event) { Component component = event.getTarget(); + + String saveName = null; + boolean lastRun = false; + if (fSavedName.getRawText() != null) { + saveName = fSavedName.getRawText(); + lastRun = ("** " + Msg.getMsg(Env.getCtx(), "LastRun") + " **") + .equals(saveName); + } if(component instanceof A && event.getName().equals((Events.ON_CLICK))){ doOnClick((A)component); } else if (component instanceof Button) { @@ -393,6 +466,59 @@ public class ProcessDialog extends Window implements EventListener, IProc restart(); } else if ("Cancel".equalsIgnoreCase(element.getId())) { this.dispose(); + } else if (event.getTarget().equals(bSave) && fSavedName != null + && !lastRun) { + + // Update existing + if (fSavedName.getSelectedIndex() > -1 && savedParams != null) { + for (int i = 0; i < savedParams.size(); i++) { + if (savedParams.get(i).getName().equals(saveName)) { + m_pi.setAD_PInstance_ID(savedParams.get(i) + .getAD_PInstance_ID()); + for (MPInstancePara para : savedParams.get(i) + .getParameters()) { + para.deleteEx(true); + } + parameterPanel.saveParameters(); + } + } + } + // create new + else { + MPInstance instance = null; + try { + instance = new MPInstance(Env.getCtx(), + m_pi.getAD_Process_ID(), m_pi.getRecord_ID()); + instance.setName(saveName); + instance.saveEx(); + m_pi.setAD_PInstance_ID(instance.getAD_PInstance_ID()); + // Get Parameters + if (parameterPanel != null) { + if (!parameterPanel.saveParameters()) { + throw new AdempiereSystemError(Msg.getMsg( + Env.getCtx(), "SaveParameterError")); + } + } + } catch (Exception ex) { + log.log(Level.SEVERE, ex.getLocalizedMessage(), ex); + } + } + querySaved(); + fSavedName.setSelectedItem(getComboItem(saveName)); + } + + else if (event.getTarget().equals(bDelete) && fSavedName != null + && !lastRun) { + Object o = fSavedName.getSelectedItem(); + if (savedParams != null && o != null) { + String selected = fSavedName.getSelectedItem().getLabel(); + for (int i = 0; i < savedParams.size(); i++) { + if (savedParams.get(i).getName().equals(selected)) { + savedParams.get(i).deleteEx(true); + } + } + } + querySaved(); } } else if (event.getName().equals(ON_STATUS_UPDATE)) { onStatusUpdate(event); @@ -400,8 +526,36 @@ public class ProcessDialog extends Window implements EventListener, IProc onComplete(); } else if (event.getName().equals(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT)) { SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Process, m_AD_Process_ID); + } else if (event.getTarget().equals(fSavedName)) { + if (savedParams != null && saveName != null) { + for (int i = 0; i < savedParams.size(); i++) { + if (savedParams.get(i).getName().equals(saveName)) { + loadSavedParams(savedParams.get(i)); + } + } + } + boolean enabled = !Util.isEmpty(saveName); + bSave.setEnabled(enabled && !lastRun); + bDelete.setEnabled(enabled && fSavedName.getSelectedIndex() > -1 + && !lastRun); } - + } + + public Comboitem getComboItem( String value) { + Comboitem item = null; + for (int i = 0; i < fSavedName.getItems().size(); i++) { + if (fSavedName.getItems().get(i) != null) { + item = (Comboitem)fSavedName.getItems().get(i); + if (value.equals(item.getLabel().toString())) { + break; + } + } + } + return item; + } + + private void loadSavedParams(MPInstance instance) { + parameterPanel.loadParameters(instance); } private void doOnClick(A btn) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java index a8bf80c11e..164b55975e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java @@ -44,6 +44,7 @@ import org.compiere.model.GridField; import org.compiere.model.GridFieldVO; import org.compiere.model.MClient; import org.compiere.model.MLookup; +import org.compiere.model.MPInstance; import org.compiere.model.MPInstancePara; import org.compiere.process.ProcessInfo; import org.compiere.util.CLogger; @@ -71,7 +72,7 @@ public class ProcessParameterPanel extends Panel implements /** * */ - private static final long serialVersionUID = -5996487688479454715L; + private static final long serialVersionUID = -6089753824709746119L; private String width; @@ -429,6 +430,64 @@ public class ProcessParameterPanel extends Panel implements return true; } // validateParameters + + /* + * load parameters from saved instance + */ + public boolean loadParameters(MPInstance instance) + { + log.config(""); + + MPInstancePara[] params = instance.getParameters(); + for (int j = 0; j < m_mFields.size(); j++) + { + GridField mField = (GridField)m_mFields.get(j); + + // Get Values + WEditor editor = (WEditor)m_wEditors.get(j); + WEditor editor2 = (WEditor)m_wEditors2.get(j); + + editor.setValue(null); + if (editor2 != null) + editor2.setValue(null); + + for ( int i = 0; i