Submit multiple invoices to task agent simultaneously

I have been spinning my wheels on this and hope someone might have advice to assist. Long story short, I have an invoice group of about 1000 invoices and it is not an option to create smaller groups. I have been tasked with breaking the group apart into smaller print jobs to increase the speed of output. I have been able to break apart the invoice group using the code below but it appears that the system is attempting to process them too quickly because the majority of them do not print. Here is the code if someone can help out:

        private void btnPrintGroup_ToolClick(object sender, ToolClickEventArgs e)
    {
        EpiDataView myv = (EpiDataView)oTrans.EpiDataViews["InvcHeadList"];
        var session = (Ice.Core.Session)oTrans.Session;
        int totrows = 0;

        List<int> myinvoice = new List<int>();
        foreach (DataRow r in myv.dataView.Table.Rows)
        {
            myinvoice.Add(Convert.ToInt32(r["InvoiceNum"]));
            totrows = totrows + 1;
        }


        int rownum = 0;
        foreach (int invoiceNum in myinvoice)
        {
            rownum = rownum + 1;
            oTrans.PushStatusText(string.Format("Outputting Invoice {0}/{1}", rownum, totrows), true);
            using (var svc = WCFServiceSupport.CreateImpl<Erp.Proxy.Rpt.ARInvFormImpl>(session, Epicor.ServiceModel.Channels.ImplBase<Erp.Contracts.ARInvFormSvcContract>.UriPath))
            {
                Erp.Rpt.ARInvFormDataSet ds = svc.GetNewParameters();
                    //System.Threading.Thread.Sleep(1000); 
                ds.ARInvFormParam[0].InvoiceNum = invoiceNum;
                ds.ARInvFormParam[0].PrintNPost = false;
                ds.ARInvFormParam[0].Vouchering = false;
                ds.ARInvFormParam[0].AssignLegalNumber = false;
                ds.ARInvFormParam[0].AutoAction = "SSRSPrint";
                ds.ARInvFormParam[0].ReportStyleNum = 1004;
                ds.ARInvFormParam[0].WorkstationID = Environment.MachineName + " " + session.GetTerminalID().ToString();
                ds.ARInvFormParam[0].RptPageSettings = @"Color=False,Landscape=False,Margins=[Left=100 Right=100 Top=100 Bottom=0],PaperSize=[Kind=""Custom"" PaperName=""Letter"" Height=1100 Width=850],PaperSource=[SourceName=""FormSource"" Kind=""Custom""],PrinterResolution=[Kind=""Custom"" X=600 Y=600]";
                ds.ARInvFormParam[0].RptPrinterSettings = @"PrinterName=""\\192.168.1.13\Epicor APM Printer"",Copies=1,Collate=False,Duplex=Default,FromPage=1,ToPage=0";
                ds.ARInvFormParam[0].PrinterName = @"\\192.168.1.13\Epicor APM Printer";
                ds.ARInvFormParam[0].SSRSRenderFormat = "EMF";
                ds.ARInvFormParam[0].AttachmentType = "PDF";
                ds.ARInvFormParam[0].ReportCurrencyCode = @"USD";
                ds.ARInvFormParam[0].ReportCultureCode = @"en-US";
                ds.ARInvFormParam[0].DateFormat = @"m/d/yyyy";
                ds.ARInvFormParam[0].NumericFormat = @",.";
                svc.SubmitToAgent(ds, "systemagent", 12345, 0, "Erp.UIRpt.ARInvForm");
            }
            oTrans.PopStatus();
        }

// oTrans.PushStatusText(“Ready”, false);
MessageBox.Show(string.Format(“Submitted {0} Invoices to Task Agent”, totrows));
}

Not sure on the rest of the code, but what appears to be an IP address has a ‘ rather than 1…?

Mark,

Thanks for the quick response. Unfortunately, that appears to be a copy / paste issue on the forum (double backslash 192 in lieu of `92).

Thanks,
Tanner

Tanner,

In your SubmitToAgent line, you use 12345 for your AgentShedNumber and 0 for your AgentTaskNumber. Have you considered changing those to be unique? Perhaps the task number could be your invoice number.

Jim

I don’t know that printing 1000 individual invoices will be much faster than just printing the group…
However I recommend that you use the Adapter instead of the WCF Directly and for your Task number pass 0 instead of 12345… let the System agent handle what numbers are what.

For your workstation ID you should use the function below

Ice.Lib.Report.EpiReportFunctions.GetWorkStationID((Session)oTrans.Session);

For the RPT Page settings use this function

Ice.Lib.Report.EpiPageAndPrinterSettings.CreatePageSettingsAsString(printDialog.PrinterSettings.DefaultPageSettings
);

And for the RPtPrinterSettings use this function

Ice.Lib.Report.EpiPageAndPrinterSettings.CreatePrinterSettingsAsString(printDialog.PrinterSettings);

Report Culture

Ice.Lib.Report.EpiReportFunctions.GetRptCultureCode(session);
1 Like

Jim,

Thanks for the idea. I tried that but it did not work. It appears they didn’t even see them reach the task agent when I use the invoice number for the agentTaskNum. I also ran a test with agentSchedNum = 0 which did not work.

Thanks,
Tanner

Jose,

Thanks for your suggestion. I tried your suggestion but having issues using the syntax / using the adapter. The updated code is:

    private void btnPrintGroup_ToolClick(object sender, ToolClickEventArgs e)
{
    EpiDataView myv = (EpiDataView)oTrans.EpiDataViews["InvcHeadList"];
    var session = (Ice.Core.Session)oTrans.Session;

    var workstationid = Ice.Lib.Report.EpiReportFunctions.GetWorkStationID(session);
    var rptculturecode = Ice.Lib.Report.EpiReportFunctions.GetRptCultureCode(session);

    int totrows = 0;

    List<int> myinvoice = new List<int>();
    foreach (DataRow r in myv.dataView.Table.Rows)
    {
        myinvoice.Add(Convert.ToInt32(r["InvoiceNum"]));
        totrows = totrows + 1;
    }

    int rownum = 0;

    foreach (int invoiceNum in myinvoice)
    {

        var myAdapter = new ARInvFormAdapter(ARInvoiceForm);
        rownum = rownum + 1;
        oTrans.PushStatusText(string.Format("Outputting Invoice {0}/{1}", rownum, totrows), true);

        myAdapter.GetNewParameters();
        myAdapter.ReportData.ARInvFormParam[0].InvoiceNum = invoiceNum;
        myAdapter.ReportData.ARInvFormParam[0].PrintNPost = false;
        myAdapter.ReportData.ARInvFormParam[0].Vouchering = false;
        myAdapter.ReportData.ARInvFormParam[0].AssignLegalNumber = false;
        myAdapter.ReportData.ARInvFormParam[0].AutoAction = "SSRSPrint";
        myAdapter.ReportData.ARInvFormParam[0].ReportStyleNum = 1004;
        myAdapter.ReportData.ARInvFormParam[0].WorkstationID = workstationid;
        myAdapter.ReportData.ARInvFormParam[0].RptPageSettings = @"Color=False,Landscape=False,Margins=[Left=100 Right=100 Top=100 Bottom=0],PaperSize=[Kind=""Custom"" PaperName=""Letter"" Height=1100 Width=850],PaperSource=[SourceName=""FormSource"" Kind=""Custom""],PrinterResolution=[Kind=""Custom"" X=600 Y=600]";
        myAdapter.ReportData.ARInvFormParam[0].RptPrinterSettings = @"PrinterName=""\\192.168.1.13\Epicor APM Printer"",Copies=1,Collate=False,Duplex=Default,FromPage=1,ToPage=0";
        myAdapter.ReportData.ARInvFormParam[0].PrinterName = @"\\192.168.1.13\Epicor APM Printer";
        myAdapter.ReportData.ARInvFormParam[0].SSRSRenderFormat = "EMF";
        myAdapter.ReportData.ARInvFormParam[0].AttachmentType = "PDF";
        myAdapter.ReportData.ARInvFormParam[0].ReportCurrencyCode = @"USD";
        myAdapter.ReportData.ARInvFormParam[0].ReportCultureCode = rptculturecode;
        myAdapter.ReportData.ARInvFormParam[0].DateFormat = @"m/d/yyyy";
        myAdapter.ReportData.ARInvFormParam[0].NumericFormat = @",.";
        myAdapter.SubmitToAgent("systemagent", 0, 0);

        oTrans.PopStatus();
        myAdapter = null;
    }
    oTrans.PushStatusText("Ready", false);
    MessageBox.Show(string.Format("Submitted {0} Invoices to Task Agent", totrows));
}   

However, when running the updated code, I receive the following error message:

    See the end of this message for details on invoking 

just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
at Erp.Adapters.ARInvFormAdapter.GetNewParameters()
at Script.btnPrintGroup_ToolClick(Object sender, ToolClickEventArgs e)
at Infragistics.Win.UltraWinToolbars.ToolBase.OnToolClick(ToolClickEventArgs e)
at Infragistics.Win.UltraWinToolbars.UltraToolbarsManager.OnToolClick(ToolClickEventArgs e)
at Infragistics.Win.UltraWinToolbars.UltraToolbarsManager.FireEvent(ToolbarEventIds id, EventArgs e)
at Infragistics.Win.UltraWinToolbars.ToolBase.OnToolClick()
at Infragistics.Win.UltraWinToolbars.ToolMenuItem.OnClick()
at Infragistics.Win.UltraWinToolbars.PopupMenuItemUIElement.DoClickProcessing(MouseEventArgs e)
at Infragistics.Win.UltraWinToolbars.PopupMenuItemUIElement.OnMouseUp(MouseEventArgs e)
at Infragistics.Win.TextUIElementBase.OnMouseUp(MouseEventArgs e)
at Infragistics.Win.ControlUIElementBase.ProcessMouseUpHelper(Object sender, MouseEventArgs e)
at Infragistics.Win.ControlUIElementBase.ProcessMouseUp(Object sender, MouseEventArgs e)
at Infragistics.Win.Utilities.ProcessEvent(Control control, ProcessEvent eventToProcess, EventArgs e)
at Infragistics.Win.UltraWinToolbars.PopupControlBase.OnMouseUp(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

I assume it is something simple. Any help you with syntax would be greatly appreciated!

1 Like

You need to BOConnect() the adapter before you can use it.

1 Like

Cool… That appeared the BOConnect() fixed the adapter syntax issue. However, it appears the first 10 print jobs err out and then 2 complete which is similar to behavior I was seeing with using WCF. Perhaps it is due to the missing settings on the RptPrinterSettings. Any ideas if the errors below are related to this or do I need to slow down the print job submissions?

Thanks,
Tanner

Err#1 ->
Program Ice.Services.Lib.RunTask raised an unexpected exception with the following message: RunTask: Object reference not set to an instance of an object.
at System.Drawing.Printing.PageSettings.CopyToHdevmode(IntPtr hdevmode)
at System.Drawing.Printing.PrinterSettings.GetHdevmode(PageSettings pageSettings)
at System.Drawing.Printing.PrintController.OnStartPrint(PrintDocument document, PrintEventArgs e)
at System.Drawing.Printing.StandardPrintController.OnStartPrint(PrintDocument document, PrintEventArgs e)
at System.Windows.Forms.PrintControllerWithStatusDialog.OnStartPrint(PrintDocument document, PrintEventArgs e)
at System.Drawing.Printing.PrintController.Print(PrintDocument document)
at System.Drawing.Printing.PrintDocument.Print()
at Ice.Core.SsrsReporting.EmfReportPrinter.Print(Byte[] reportBytes, String printerNameParameter, EpiPrinterSettings printerSettings, EpiPageSettings pageSettings)
at Ice.Core.SsrsReporting.ReportProcessorBase1.RenderReportForPrintFaxOrEmailReport(SysRptLst sysRptLstRow) at Ice.Core.SsrsReporting.ReportProcessorBase1.ProcessReportPart(String reportLocation, Action1 modifySysRptLstRow) at Ice.Core.RptBase.ReportDatabaseBuilder1.XMLClose()
at Erp.Internal.AR.ARInvForm.RunProcess(Int32 instanceTaskNum, String outputFileName)
at Ice.Hosting.TaskCaller.ExecuteTask()
at Ice.Services.Lib.RunTaskSvc.RunTask(Int32 ipTaskNum)

Err#2–>
Program Ice.Services.Lib.RunTask raised an unexpected exception with the following message: RunTask: Settings to access printer ‘\192.168.1.13\Epicor APM Printer’ are not valid.
at System.Drawing.Printing.PrinterSettings.GetHdevmodeInternal(String printer)
at System.Drawing.Printing.PrinterSettings.GetHdevmode(PageSettings pageSettings)
at System.Drawing.Printing.PrintController.OnStartPrint(PrintDocument document, PrintEventArgs e)
at System.Windows.Forms.PrintControllerWithStatusDialog.OnStartPrint(PrintDocument document, PrintEventArgs e)
at System.Drawing.Printing.PrintController.Print(PrintDocument document)
at System.Drawing.Printing.PrintDocument.Print()
at Ice.Core.SsrsReporting.EmfReportPrinter.Print(Byte[] reportBytes, String printerNameParameter, EpiPrinterSettings printerSettings, EpiPageSettings pageSettings)
at Ice.Core.SsrsReporting.ReportProcessorBase1.RenderReportForPrintFaxOrEmailReport(SysRptLst sysRptLstRow) at Ice.Core.SsrsReporting.ReportProcessorBase1.ProcessReportPart(String reportLocation, Action1 modifySysRptLstRow) at Ice.Core.RptBase.ReportDatabaseBuilder1.XMLClose()
at Erp.Internal.AR.ARInvForm.RunProcess(Int32 instanceTaskNum, String outputFileName)
at Ice.Hosting.TaskCaller.ExecuteTask()
at Ice.Services.Lib.RunTaskSvc.RunTask(Int32 ipTaskNum)

Err#3–>
Program Ice.Services.Lib.RunTask raised an unexpected exception with the following message: RunTask: AtomicComposition encountered an unexpected Exception, review InnerException for details.
at System.ComponentModel.Composition.Hosting.AtomicComposition.FinalComplete()
at System.ComponentModel.Composition.Hosting.AtomicComposition.Complete()
at System.ComponentModel.Composition.Hosting.CatalogExportProvider.DetermineRejection(ComposablePartDefinition definition, AtomicComposition parentAtomicComposition)
at System.ComponentModel.Composition.Hosting.CatalogExportProvider.IsRejected(ComposablePartDefinition definition, AtomicComposition atomicComposition)
at System.ComponentModel.Composition.Hosting.CatalogExportProvider.InternalGetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
at System.ComponentModel.Composition.Hosting.ExportProvider.TryGetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition, IEnumerable1& exports) at System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.AggregateExportProvider.GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition) at System.ComponentModel.Composition.Hosting.ExportProvider.TryGetExports(ImportDefinition definition, AtomicComposition atomicComposition, IEnumerable1& exports)
at System.ComponentModel.Composition.Hosting.CompositionContainer.GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition)
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExportsCore[T,TMetadataView](String contractName)
at Ice.Core.SsrsReporting.SsrsRenderInformationFactory.Create(String documentType, Func1 serviceCreator) at Ice.Core.SsrsReporting.ReportProcessorBase1.RenderReport(String ssrsRenderFormat, String printProgram, Boolean ignorePageSettings, Boolean ignoreMargins, Action2 beforeRenderAction) at Ice.Core.SsrsReporting.ReportProcessorBase1.RenderReportForPrintFaxOrEmailReport(SysRptLst sysRptLstRow)
at Ice.Core.SsrsReporting.ReportProcessorBase1.ProcessReportPart(String reportLocation, Action1 modifySysRptLstRow)
at Ice.Core.RptBase.ReportDatabaseBuilder`1.XMLClose()
at Erp.Internal.AR.ARInvForm.RunProcess(Int32 instanceTaskNum, String outputFileName)
at Ice.Hosting.TaskCaller.ExecuteTask()
at Ice.Services.Lib.RunTaskSvc.RunTask(Int32 ipTaskNum)

Inner Trace:
One or more errors occurred.
:

An item with the same key has already been added.
: at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.ComponentModel.Composition.Hosting.CatalogExportProvider.<>c__DisplayClass11.b__c()
at System.ComponentModel.Composition.Hosting.AtomicComposition.FinalComplete()

There appears to have been an issue with my task agent which contributed to the issue at the end. The adapter technique appears to have resolved the issue. Thanks for your help! Out of curiosity, do you know which dll contains Ice.Lib.Report.EpiPageAndPrinterSettings?

Thanks,
Tanner

Although the jobs are submitted to the task agent and 1000 invoices take 1 hour to send (instead of 10 hours+), it appears that a percentage of them error out. My tests seem to indicate either an issue with creating the printer or the task agent cannot handle them (although most invoices are handled properly). Does something need to be set up for a printer object to be created or sent to the task agent to use a server printer in the background process? The error I am seeing is below, any help is greatly appreciated.

Thanks,
Tanner

   Program Ice.Services.Lib.RunTask raised an unexpected exception with the following message: RunTask: Settings to access printer '\\192.168.1.13\Epicor APM Printer' are not valid.

at System.Drawing.Printing.PrinterSettings.GetHdevmodeInternal(String printer)
at System.Drawing.Printing.PrinterSettings.GetHdevmode(PageSettings pageSettings)
at System.Drawing.Printing.PrintController.OnStartPrint(PrintDocument document, PrintEventArgs e)
at System.Windows.Forms.PrintControllerWithStatusDialog.OnStartPrint(PrintDocument document, PrintEventArgs e)
at System.Drawing.Printing.PrintController.Print(PrintDocument document)
at System.Drawing.Printing.PrintDocument.Print()
at Ice.Core.SsrsReporting.EmfReportPrinter.Print(Byte[] reportBytes, String printerNameParameter, EpiPrinterSettings printerSettings, EpiPageSettings pageSettings)
at Ice.Core.SsrsReporting.ReportProcessorBase1.RenderReportForPrintFaxOrEmailReport(SysRptLst sysRptLstRow) at Ice.Core.SsrsReporting.ReportProcessorBase1.ProcessReportPart(String reportLocation, Action1 modifySysRptLstRow) at Ice.Core.RptBase.ReportDatabaseBuilder1.XMLClose()
at Erp.Internal.AR.ARInvForm.RunProcess(Int32 instanceTaskNum, String outputFileName)
at Ice.Hosting.TaskCaller.ExecuteTask()
at Ice.Services.Lib.RunTaskSvc.RunTask(Int32 ipTaskNum)

Tanner,

You’re probably not going to like my answer.

I’ve dealt with a similar situation, only with using AUTOPRINT in a data directive to send invoices to EDI. Since we’re basically using the same process to generate EDI (it calls a report, only difference is it uses the “EDI” type versus “SSRS”) - I think it’s pretty much the same thing. The autoprint from the data directive should be doing about the same code that you’re calling out from your button.

It’d gotten to the point where it seems as if the system agent just can’t handle that much stuff hitting at the same time. If I generated 100 invoices, then I could almost guarantee 3-5 of them would “fail”, and I’d get 95-97 EDI files in my output folder. If I reset those invoices and did it again, I’d get another 3-5 that would fail, but it wouldn’t always be the same ones. We worked with Epicor Tech Support pretty extensive, and was able to PROVE that it was a system agent issue - but it never really got resolved.

I eventually developed a system where I would write the invoices that were supposed to be sent via EDI to a UD table, and then I had a windows script that reads through the output generated and extracts the invoices that actually made it, and submits that to Service Connect to “match” to what was expected. The user has a dashboard they check about 30 minutes after generating invoices, and they pull up the invoices manually that “didn’t make it”, and reprint them using the EDI report style.

At one point, I actually had a tech support agent say something along the lines of “autoprint isn’t designed to handle large batches”. That was a quote that went on my “quote wall”. Doesn’t matter that I’m not autoprinting 100 invoices at once, it’s actually autoprinting one invoice at a time, it’s just doing 100 of them within a matter of a couple seconds.

I know it’s probably not the answer you wanted to hear. A lot of focus got put on this through Tech Support, but it was never resolved.

Kevin Simon
SimsTrak Consulting, LLC

Kevin,

Thanks for the information, I really appreciate it. Do you happen to have a call number or something that I could reference to work with Epicor to help get the issue resolved or submit an enhancement request to fix the task agent? I would rather see this fixed than have to write another custom process that bypasses what an enterprise system should be able to handle out of the box.

Thanks,
Tanner

though late response, hope it helps someone in the future.
you have to slow down the loop.
we done something in past like this…
after
oTrans.PopStatus();
//call the ud method
PauseForMilliSeconds(3000);

//copy the below ud method.

public static DateTime PauseForMilliSeconds( int MilliSecondsToPauseFor )
{

        System.DateTime ThisMoment  = System.DateTime.Now                                       ;
        System.TimeSpan duration    = new System.TimeSpan( 0, 0, 0, 0, MilliSecondsToPauseFor ) ;
        System.DateTime AfterWards  = ThisMoment.Add( duration )                                ;
        
        
        while ( AfterWards >= ThisMoment  )
        {
                System.Windows.Forms.Application.DoEvents() ;
                ThisMoment = System.DateTime.Now            ;
        }
        
        
        return System.DateTime.Now ;
    }

/between, is the PopStatus works for you??/

1 Like

Couldn’t find this information through any search so here it is for search posterity:
Ice.Lib.RoutingBreakingRules.dll

2 Likes