BAQ Export within BPM

,

Edit: New post in a separate thread:
https://www.epiusers.help/t/exporting-baq-data-from-a-function-file-or-no-file-example-library/108641

The original post is archived below:

Old Post

Here is an example of how you use the BOs.
Hope this helps.
This function does the export and returns the data to you as output.

Here is the library with a function: BAQExport1
BAQExport.efxj.txt (4.1 KB) ← Remove .txt

References:
Assemblies:

  • Ice.Contracts.Lib.ServerPath.dll

Services:

  • ICE.Lib.FileTransfer
  • ICE.Proc.DynamicQueryExport

Function Signature:
Input:

Name Type
baqID System.String
outputFormat System.String
textDelim System.String
outputLabels System.Boolean

Output:

Name Type
output System.String

Code:

Guid findGuid = Guid.NewGuid();
string findFilename = $"{baqID}_{findGuid.ToString()}.{outputFormat.ToLower()}";

CallService<DynamicQueryExportSvcContract>(dqe =>
{
    DynamicQueryExportTableset dqeTS = dqe.GetNewParameters();

    DynQueryExpParamRow paramRow = dqeTS.DynQueryExpParam.FirstOrDefault();
    
    paramRow.QueryID = baqID;
    paramRow.ExportFormat = outputFormat.ToUpper();
    paramRow.ExportFilename =  findFilename;
    paramRow.TextDelim = textDelim;
    paramRow.OutputLabels = outputLabels;

    dqe.RunDirect(dqeTS);
   
});


CallService<FileTransferSvcContract>(ft =>
{
    byte[] csvDataBytes = ft.DownloadFile(Epicor.ServiceModel.Utilities.SpecialFolder.CompanyData, $"Processes\\{Session.UserID}\\{findFilename}");
    
    output = System.Text.Encoding.UTF8.GetString(csvDataBytes);
});

Edit: This is just a rough draft. If y’all want it, I can add the proper error checking and share it in the Function sharing thread.

1 Like

Perfect! This works great. Tysm @kve and @klincecum.

FYI for others - need to add the DynamicQueryExport Assembly in Usings & References dialog for it to work. And I ended up using SubmitToAgent as RunDirect was giving the fun " [Network access for Distributed Transaction Manager (MSDTC) has been disabled" error. Could have made a function too but didn’t. Again thanks so much guys!!

CallService<DynamicQueryExportSvcContract>( svc => {
  DynamicQueryExportTableset dqeTS = svc.GetNewParameters();
  DynQueryExpParamRow paramRow = dqeTS.DynQueryExpParam.FirstOrDefault();
  paramRow.QueryID = "BAQID";
  paramRow.ExportFilename = @"\\server\path\filename.csv";
  paramRow.ExportFormat = "CSV"; // "XML";
  paramRow.OutputLabels = true;
  svc.SubmitToAgent(dqeTS, "SystemTaskAgent", 0,0, "Ice.UIProc.BAQExport");
  //svc.RunDirect(dqeTS); //Doesn't work in Part.Update BPM
} );

What took the most time was the server file permissions. Even if the app server account has permission to the folder as a normal user, it needs explicit permission on the share too. Unlike normal users.

1 Like

Very welcome! @klincecum has the right idea that it should probably be done using a Function, and you can invoke the function from the BPM. That way if you want to do the same in another BPM, you can just call the same function with different input parameters.

1 Like

Posted some new examples in a separate thread.
Hope it’s helpful for y’all.

https://www.epiusers.help/t/exporting-baq-data-from-a-function-file-or-no-file-example-library/108641

Thank you @klincecum for the work to make that function with both the BAQ export AND the file transfer. That will make it truly work for me once we are in the cloud.

OK, so I got the Function to create a CSV file in the Cloud server at CompanyDate\Processes\UserID. And I can read that CSV data back into the Function with
FileTransferSvcContract and reformat it with the super helpful code from @klincecum. But, I cannot write that data out to a new file on my local computer or network share. Is that because the function is running on the Cloud server so it will never see my local folders? I have tried with System.IO.File.WriteAllBytes.

The Server File Download menu item does exactly what I want, looks at the Cloud data folders and brings individual files to a local folder.

As mentioned above, yes.

The local PC will have to initiate the request to run the Server File Download or other end point to get the bytes down.

1 Like

It has taken me a while to understand the features and limits of cloud vs. on-prem. But, some of it is slowly sinking in. Thanks for the help and patience @Mark_Wonsil.

So, I did get a my final solution to work. After re-creating the library/functions that @klincecum provided, I use customization code on Customer Shipment Entry to run a REST call to get the data and write it out to a local folder.

	
	// Add usings for Rest Function Call
	using Ice.Lib.RestClient;
	using Ice.BO;
	using Ice.Common;

	
	private static void btnTrack_Click(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **

	//configure REST with AllAccess key
	var restClient = new RestClientBuilder()
	.SetDefaultApiKey("MyAPIKey")
	//	.UseSession(this.oTrans.CoreSession)      
	.SetAppServerUrl("https://company-pilot.epicorsaas.com/server")
	.SetCompanyId("ID")
	.UseBasicAuthentication("user", "password")
	.Build();
	
	using (restClient)
		{
			try
			{
			// Define input parameters
			var FuncParams = new RestContent(new 
				{
				  baqID = "PP-ShipInfoFromPackNum",
				  outputFormat = "CSV",
				  textDelim = ",",
				  outputLabels = true,
				  deleteFile = true,
				  textOrBytes = "TEXT",
				  showHeadersOnCSV = true,
				  showColumnNamesInsteadofLabelsCSV = false
				});
		
			// Call function 
			var getResponse = restClient.Function.Post("PP-BAQExport", "BAQExportToCSVOrXML", FuncParams, published: true);
			// Get Results - output signature has "data" and "message". Only need "data"
			var Results = getResponse.GetAnonymousResult( new { data = (string)null } );
			string ResultText = Results.data;
			//MessageBox.Show(ResultText.Substring(0,350));

			// Write Data to LocalServer
			//string ResultText = "Test";
    		System.IO.File.WriteAllText("\\\\LocalServer\\EpicorData\\Reports\\UPS\\ShipInfoFromPack.csv",ResultText);
			//MessageBox.Show("After Call");
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
			}
		}
	
	}  

One question for you experts: .UseSession(this.oTrans.CoreSession) did not work for me, I had to use the longer form to specify URL, CompanyID, and User/Password form. Is that typical of this kind of customization?

I recreated this in a ShipHead DD Standard directive but getting error when I check it

The type or namespace name ‘DynamicQueryExportSvcContract’ could not be found (are you missing a using directive or an assembly reference?)

The name ‘CallService’ does not exist in the current context

I’m wanting to export BAQ using a BPM as well. Look at your screen where did the Execute Custom option come from? Can I see the command you have in yours?

Thanks
Shanna Frank

Top left, right next to “Call SC Workflow”

Thanks, I just figured it out too. It’s under method directive, I was in Data Directive. I’m new to the BPM world. Thank you for answering.

This should be a data directive. I screencapped Data Directive Maintenance.

I have another quick question. The Execute custom code was on my screen earlier today and now it’s not showing. Would you why?

Hmm I’m really not sure. Does your user account have the “BPM Advanced User” option selected?