如何在 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 调用或某些组合来执行此过程以上。

但是,这些选项似乎对我不可用:

创建快照后,我想我需要能够将其下载到本地,以便通过 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);
        }
    }
}