Printing from a uBAQ called via REST fails

Head scratcher here… I have code in an updateable BAQ Advanced BPM Update only that calls a BAQReport. This works perfectly if i execute it inside the Epicor client (say the BAQ Designer etc). I can even place this on a standard data directive and trigger it from a field change, again, anywhere inside the client it works fine. Soon as i attempt to execute the BAQ via REST or swagger i get the following error in the task monitor:

Query execution failed for dataset ‘BAQReportParameter’. —> System.Data.SqlClient.SqlException: Invalid column name ‘Cur-TaskClientID’.

Running the BAQReport and tracing it, that column isn’t even in there, nor can i see it as a property of the BAQReportParamRow or the callContextClient. I do see it in the SysTaskParam table however. Anyone ever try to execute a DynamicReportQuery from rest and encounter this?

Got a list of methods called in the trace? Or even post the trace itself if it isn’t too long or filled with confidential data.

It’s just SubmitToAgent, it’s incredibly long however.

Bruce,

I know the TaskClientID shows up in Session.TaskClientID and its Computer Name + Epicor Username for example “HP-PC manager”.

I wonder if Epicor automatically fills this in when there is an actual Client Session, but it doesn’t do that for REST, or does something different with Rest.

I assume you have a BPM where you specify BAQ Report Parameters:

  1. BAQID
  2. WorkstationID
  3. PrinterID
    etc…

I wonder if you need to add some logic to populate these additional parameters, just to make REST happy (These are acceptable BAQReport Params):

  • Cur-Comp
  • CUR-LANGID
  • Cur-Plant
  • Cur-TaskClientID
  • DCD-USERID

Perhaps when it detects the Client Type to be REST it doesn’t populate all of the vars, so maybe you need to explicitly define them… I wonder if you can just get it from Session.TaskClientID or if it will be happy if you use WorkStationID for it.

If I look at the SSRS BAQReportParameter table, this is what it has when I run it through the Client…

I wonder what REST would be doing diff.

1 Like

Mark,

Correct, i had specified all the other goodies, as it was working inside the client as expected.

Genious…thanks, i was definitely stuck in my thinking, never occurred to me to look in Session variables! Soon as i set this.Session.TaskClientID to the expected one, it worked like a charm. Thanks!

Maybe @Bart_Elia would be kind enough to weigh in on how the REST headers might include this information if we need to pass it in or how that all works from the outside.

1 Like

Awesome! Good to know as well, because more than likely more and more folks will use REST to Submit Reports. #gold

Correct, it’s actually the ClientComputer name plus the session #… so if you were logged in twice it might be 1 or 2? Per your example, and mine followed this as well it’s L4093 + 1 or 2 etc… I’ll need to dig into that a bit further.

This is configurable note that the session ID is actually the session you see in windows image
This is such that on a terminal server the same named user (say with MES) does not get others print outs.
However it is configurable and you can hence tweak how things work for your needs
image image

1 Like

So in the rest call we have to add those fields as parameters? @hkeric.wci

You probably don’t use those in REST. I assume in REST you would have a Service Account for API Calls, with Session Impersonation.

First of all Recommendation from @aidacra

Basically what that setting does is when you Submit a Queued Job to the Agent, it knows where to send the ex PDF Preview too. Imagine if you have a Terminal Server (Citrix, RDS) you probably have 30-50 Users Connected, it determines where to send the result to. Have you ever been connected to 2-3 PCs with the same UserID and you Print Preview something, it doesn’t show up, later you login and they all popup.

You can Run Reports Directly (example one)

api/help/v1/methods/Erp.RPT.GlBookReportSvc/index#!/Custom_methods/RunDirect

Then there is a GetReportBytes API Call you can get the bytes and write to ex .pdf

The Equivalent in LINQ (perhaps its easier to understand) is:

var SysRptRow =
(from sr in Db.SysRptLst.With(LockHint.NoLock)
  where
    sr.Company == Session.CompanyID
    && sr.UserID == Session.UserID
    && sr.RptDescription.Contains("Process Payments")
    && sr.PrintProgram.Contains("MICRChkPrint")
    && sr.RptData != null
  orderby sr.SysTaskNum descending
  select sr
).FirstOrDefault();


if (SysRptRow != null) {
  System.IO.File.WriteAllBytes(@"\\UNC\Path\file.pdf", SysRptRow.RptData);
}
1 Like