如何在 Acumatica 中自动创建和 SFTP 传输快照?
How can I automate the creation and SFTP transfer of a snapshot in Acumatica?
我想在我的 SAAS 托管的 Acumatica 实例中创建某些表的夜间快照,并将生成的 XML 文件通过 SFTP 传输到给定位置。 (我已经为感兴趣的表创建了自定义导出模式选项。)
我想通过 Acumatica Automation Schedule、我可以通过 API 调用的自定义操作或对现有 Acumatica 操作的 API 调用或某些组合来执行此过程以上。
但是,这些选项似乎对我不可用:
- Automation Scheduling 不支持创建快照(https://feedback.acumatica.com/ideas/ACU-I-570)
- 我尝试添加操作以创建 Web 服务端点的快照,但我似乎无法传递管理弹出窗口所需的参数
- 试图创建一个自定义的 Acumatica 按钮,我也在努力弄清楚如何引发和管理弹出窗口。
创建快照后,我想我需要能够将其下载到本地,以便通过 SFTP 将其传输到我想要的位置;我还没有深入了解我是否通过 API 调用下载快照按钮,结果文件将转到哪里。
六月,
当我遇到无法使用 ReST 或其他集成技术触发的问题时,我通常会转向 Selenium 作为阻力最小的途径。我确实想指出,我总是错误地选择使用 selenium 作为最后的手段。
我通常喜欢使用 PowerShell selenium 模块来做这样的事情。
一旦你的脚本开始工作,你就可以很容易地将它连接到一个标准的 Windows 调度程序中。
这可能不是最优雅的方式,但它肯定会完成工作。
如果你有兴趣,你可以开始使用这个
https://github.com/adamdriscoll/selenium-powershell/blob/master/README.md
一旦您熟悉了它,您就可以使用 chrome 检查工具来挖掘您需要定位的元素。您所关注的对话框通常在页面中以 iframe 的形式出现。
如果你想尝试这条路线,我可以分享我的一些脚本来帮助你入门。
希望对您有所帮助。
罗伯特
我最终创建了一个简单的控制台应用程序,因为它更符合我们的其他应用程序,而且我对 C# 比对 PowerShell 更熟悉。罗伯特,你的项目对于弄清楚如何引用更棘手的元素非常宝贵。
我希望设置计划任务,使用每个步骤的方法名称调用我的应用程序,每个步骤之间有适当的延迟——例如,创建快照大约需要 25 分钟。有不同的方法来创建快照、下载快照、删除快照,接下来我将使用 SFTP 将下载的快照传输到其最终目的地。我睡了一会儿,让网站有时间赶上进度;有可用的 Waits 和 WaitForExpectedCondition 方法,但我没有在这个快速而肮脏的版本中使用它们。
这是我的代码的内容。 (我通过 Nuget 将 WebDriver 和 ChromeDriver 添加到应用程序中。)
using System;
using System.Collections.Generic;
using System.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Threading;
namespace InfiniteExport
{
class Program
{
static string connectorInfo;
static void Main(string[] args)
{
string method = "";
if (args.Count() >= 1)
{
method = args[0].ToLower();
}
IWebDriver driver = new ChromeDriver();
try
{
switch (method)
{
case "createsnapshot":
Login(driver);
CreateSnapshot(driver);
break;
case "downloadsnapshot":
Login(driver);
DownloadSnapshot(driver);
break;
case "deletesnapshot":
Login(driver);
DeleteSnapshot(driver);
break;
default:
break;
}
}
catch (Exception e)
{
throw e;
}
finally
{
driver.Quit();
}
}
static void Login(IWebDriver driver)
{
//This login actually results in a 404 error because there's no redirect embedded in it, but the login itself is successful and creates the session used by the next method navigation
driver.Navigate().GoToUrl(InfiniteExport.Properties.Settings.Default.BaseAcumaticaURL + "/Frames/Login.aspx");
driver.FindElement(By.Id("form1")).Click();
driver.FindElement(By.Id("txtUser")).SendKeys(InfiniteExport.Properties.Settings.Default.AcumaticaUserName);
driver.FindElement(By.Id("txtPass")).SendKeys(InfiniteExport.Properties.Settings.Default.AcumaticaPassword);
driver.FindElement(By.Id("btnLogin")).Click();
driver.Manage().Window.Maximize();
Thread.Sleep(5000);
}
static void CreateSnapshot(IWebDriver driver)
{
driver.Navigate().GoToUrl(@InfiniteExport.Properties.Settings.Default.BaseAcumaticaURL + "/Main?ScreenId=SM203520&_CompanyID=2");
Thread.Sleep(2000);
driver.SwitchTo().Frame("main");
//Click the @$@#%*! unnamed create snapshot button
driver.FindElement(By.CssSelector(".toolsBtn[data-cmd=exportSnapshotCommand]")).Click();
Thread.Sleep(2000);
//Switch to the modal popup to start clicking items on it (this is the "Warning not in maintenance mode" popup)
driver.SwitchTo().ActiveElement();
driver.FindElement(By.Id("messageBox_0")).Click();
Thread.Sleep(2000);
//Switch to the modal popup with the export options
driver.SwitchTo().ActiveElement();
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edDescription")).SendKeys("InfiniteExport");
//Select the dropdown option for the InfiniteExport
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edExportMode_text")).Click();
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edExportMode_text")).SendKeys("InfiniteExport");
Thread.Sleep(2000);
driver.FindElement(By.ClassName("ddSelection")).Click();
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_chkPrepare")).Click();
//Select the dropdown option for XML
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edPrepareMode")).Click();
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edPrepareMode_text")).SendKeys("XML");
Thread.Sleep(2000);
driver.FindElement(By.ClassName("ddSelection")).Click();
Thread.Sleep(2000);
//Click the OK button to start the export
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_btnExportSnapshotOK")).Click();
//Wait long enough for the process to start, then quit and come back later to download
Thread.Sleep(10000);
}
static void DownloadSnapshot(IWebDriver driver)
{
driver.Navigate().GoToUrl(@InfiniteExport.Properties.Settings.Default.BaseAcumaticaURL + "/Main?ScreenId=SM203520&_CompanyID=2");
Thread.Sleep(2000);
driver.SwitchTo().Frame("main");
//Unless this is made fancier, it will download the active grid row, which is the most recent snapshot created
driver.FindElement(By.CssSelector(".toolsBtn[data-cmd=downloadSnapshotCommand]")).Click();
Thread.Sleep(10000);
}
static void DeleteSnapshot(IWebDriver driver)
{
driver.Navigate().GoToUrl(@InfiniteExport.Properties.Settings.Default.BaseAcumaticaURL + "/Main?ScreenId=SM203520&_CompanyID=2");
Thread.Sleep(2000);
driver.SwitchTo().Frame("main");
//Unless this is made fancier, it will delete the active grid row, which is the most recent snapshot created
driver.FindElement(By.CssSelector(".toolsBtn[data-cmd=Delete]")).Click();
Thread.Sleep(2000);
driver.FindElement(By.CssSelector(".toolsBtn[data-cmd=saveCompanyCommand]")).Click();
Thread.Sleep(10000);
}
}
}
我想在我的 SAAS 托管的 Acumatica 实例中创建某些表的夜间快照,并将生成的 XML 文件通过 SFTP 传输到给定位置。 (我已经为感兴趣的表创建了自定义导出模式选项。)
我想通过 Acumatica Automation Schedule、我可以通过 API 调用的自定义操作或对现有 Acumatica 操作的 API 调用或某些组合来执行此过程以上。
但是,这些选项似乎对我不可用:
- Automation Scheduling 不支持创建快照(https://feedback.acumatica.com/ideas/ACU-I-570)
- 我尝试添加操作以创建 Web 服务端点的快照,但我似乎无法传递管理弹出窗口所需的参数
- 试图创建一个自定义的 Acumatica 按钮,我也在努力弄清楚如何引发和管理弹出窗口。
创建快照后,我想我需要能够将其下载到本地,以便通过 SFTP 将其传输到我想要的位置;我还没有深入了解我是否通过 API 调用下载快照按钮,结果文件将转到哪里。
六月, 当我遇到无法使用 ReST 或其他集成技术触发的问题时,我通常会转向 Selenium 作为阻力最小的途径。我确实想指出,我总是错误地选择使用 selenium 作为最后的手段。 我通常喜欢使用 PowerShell selenium 模块来做这样的事情。 一旦你的脚本开始工作,你就可以很容易地将它连接到一个标准的 Windows 调度程序中。 这可能不是最优雅的方式,但它肯定会完成工作。 如果你有兴趣,你可以开始使用这个
https://github.com/adamdriscoll/selenium-powershell/blob/master/README.md
一旦您熟悉了它,您就可以使用 chrome 检查工具来挖掘您需要定位的元素。您所关注的对话框通常在页面中以 iframe 的形式出现。
如果你想尝试这条路线,我可以分享我的一些脚本来帮助你入门。
希望对您有所帮助。 罗伯特
我最终创建了一个简单的控制台应用程序,因为它更符合我们的其他应用程序,而且我对 C# 比对 PowerShell 更熟悉。罗伯特,你的项目对于弄清楚如何引用更棘手的元素非常宝贵。
我希望设置计划任务,使用每个步骤的方法名称调用我的应用程序,每个步骤之间有适当的延迟——例如,创建快照大约需要 25 分钟。有不同的方法来创建快照、下载快照、删除快照,接下来我将使用 SFTP 将下载的快照传输到其最终目的地。我睡了一会儿,让网站有时间赶上进度;有可用的 Waits 和 WaitForExpectedCondition 方法,但我没有在这个快速而肮脏的版本中使用它们。
这是我的代码的内容。 (我通过 Nuget 将 WebDriver 和 ChromeDriver 添加到应用程序中。)
using System;
using System.Collections.Generic;
using System.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Threading;
namespace InfiniteExport
{
class Program
{
static string connectorInfo;
static void Main(string[] args)
{
string method = "";
if (args.Count() >= 1)
{
method = args[0].ToLower();
}
IWebDriver driver = new ChromeDriver();
try
{
switch (method)
{
case "createsnapshot":
Login(driver);
CreateSnapshot(driver);
break;
case "downloadsnapshot":
Login(driver);
DownloadSnapshot(driver);
break;
case "deletesnapshot":
Login(driver);
DeleteSnapshot(driver);
break;
default:
break;
}
}
catch (Exception e)
{
throw e;
}
finally
{
driver.Quit();
}
}
static void Login(IWebDriver driver)
{
//This login actually results in a 404 error because there's no redirect embedded in it, but the login itself is successful and creates the session used by the next method navigation
driver.Navigate().GoToUrl(InfiniteExport.Properties.Settings.Default.BaseAcumaticaURL + "/Frames/Login.aspx");
driver.FindElement(By.Id("form1")).Click();
driver.FindElement(By.Id("txtUser")).SendKeys(InfiniteExport.Properties.Settings.Default.AcumaticaUserName);
driver.FindElement(By.Id("txtPass")).SendKeys(InfiniteExport.Properties.Settings.Default.AcumaticaPassword);
driver.FindElement(By.Id("btnLogin")).Click();
driver.Manage().Window.Maximize();
Thread.Sleep(5000);
}
static void CreateSnapshot(IWebDriver driver)
{
driver.Navigate().GoToUrl(@InfiniteExport.Properties.Settings.Default.BaseAcumaticaURL + "/Main?ScreenId=SM203520&_CompanyID=2");
Thread.Sleep(2000);
driver.SwitchTo().Frame("main");
//Click the @$@#%*! unnamed create snapshot button
driver.FindElement(By.CssSelector(".toolsBtn[data-cmd=exportSnapshotCommand]")).Click();
Thread.Sleep(2000);
//Switch to the modal popup to start clicking items on it (this is the "Warning not in maintenance mode" popup)
driver.SwitchTo().ActiveElement();
driver.FindElement(By.Id("messageBox_0")).Click();
Thread.Sleep(2000);
//Switch to the modal popup with the export options
driver.SwitchTo().ActiveElement();
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edDescription")).SendKeys("InfiniteExport");
//Select the dropdown option for the InfiniteExport
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edExportMode_text")).Click();
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edExportMode_text")).SendKeys("InfiniteExport");
Thread.Sleep(2000);
driver.FindElement(By.ClassName("ddSelection")).Click();
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_chkPrepare")).Click();
//Select the dropdown option for XML
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edPrepareMode")).Click();
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_frmExportSnapshot_edPrepareMode_text")).SendKeys("XML");
Thread.Sleep(2000);
driver.FindElement(By.ClassName("ddSelection")).Click();
Thread.Sleep(2000);
//Click the OK button to start the export
driver.FindElement(By.Id("ctl00_phF_pnlExportSnapshot_btnExportSnapshotOK")).Click();
//Wait long enough for the process to start, then quit and come back later to download
Thread.Sleep(10000);
}
static void DownloadSnapshot(IWebDriver driver)
{
driver.Navigate().GoToUrl(@InfiniteExport.Properties.Settings.Default.BaseAcumaticaURL + "/Main?ScreenId=SM203520&_CompanyID=2");
Thread.Sleep(2000);
driver.SwitchTo().Frame("main");
//Unless this is made fancier, it will download the active grid row, which is the most recent snapshot created
driver.FindElement(By.CssSelector(".toolsBtn[data-cmd=downloadSnapshotCommand]")).Click();
Thread.Sleep(10000);
}
static void DeleteSnapshot(IWebDriver driver)
{
driver.Navigate().GoToUrl(@InfiniteExport.Properties.Settings.Default.BaseAcumaticaURL + "/Main?ScreenId=SM203520&_CompanyID=2");
Thread.Sleep(2000);
driver.SwitchTo().Frame("main");
//Unless this is made fancier, it will delete the active grid row, which is the most recent snapshot created
driver.FindElement(By.CssSelector(".toolsBtn[data-cmd=Delete]")).Click();
Thread.Sleep(2000);
driver.FindElement(By.CssSelector(".toolsBtn[data-cmd=saveCompanyCommand]")).Click();
Thread.Sleep(10000);
}
}
}