API to pull in PDF of report

I have been asked if it was possible to get an API to pull in a custom report and have it viewable in PDF. Anyone done this before?

2 Likes

I am back at this now! I was reading and you said that in 10.2.500 or above to use Functions instead of uBAQ. I’ve used both not quite sure I am following how to write a BAQ in functions. I get that you can update a table with a function very easily, but not fully following how it would be used in a function. Can you elaborate or give an example for me to see?

Would you mind re-stating your original question with more depth. Then we could answer you better.

Not sure exactly what you are wanting to do.

We are creating a website for our company that will allow our external reps to access invoices with a click. We want this to bring up the invoice in pdf format.

My thought was the external rep can click a button that is tied to the customer, and we have the basic customer info already available behind the scenes. When the rep clicks the link, it then fires the API to process a BAQ to get all the open Invoice data. Afterward, I would need to figure out how to get it to populate a pdf document.

However, I saw that functions may be a slicker way to do this and that led me to this point.

Sure, it is pretty easy

Write an epicor function that takes in as parameters a unique identifier for the invoice in our case we use SysRowID
image

Then you simply run the report with the right report style and return back the report bytes

this.Success=true;
try
{
  this.CallService<Erp.Contracts.ARInvFormSvcContract>(arInvFrm => {
    Guid newTask = Guid.NewGuid();
    String noteStr= newTask.ToString();
    var invcRow = Guid.Parse(this.SysRowID);
    var invoiceNum = (from ih in Db.InvcHead where ih.SysRowID==invcRow select ih.InvoiceNum).FirstOrDefault();
    if(invoiceNum!=null && invoiceNum !=0)
    {
      var arInvFrmTs = arInvFrm.GetNewParameters();
      arInvFrmTs.ARInvFormParam[0].AgentID="SystemTaskAgent";
      arInvFrmTs.ARInvFormParam[0].AutoAction="SSRSGenerate";
      arInvFrmTs.ARInvFormParam[0].CalledFrom="Erp.UI.ARInvoiceTracker";
      arInvFrmTs.ARInvFormParam[0].ReportStyleNum=1005;
      arInvFrmTs.ARInvFormParam[0].SSRSRenderFormat="PDF";
      arInvFrmTs.ARInvFormParam[0].SSRSEnableRouting=false;
      arInvFrmTs.ARInvFormParam[0].TaskNote =noteStr;
      arInvFrmTs.ARInvFormParam[0].InvoiceNum= invoiceNum;
      this.TaskNoteGuid = noteStr;
      this.InvoiceNum = invoiceNum;
      arInvFrm.RunDirect(arInvFrmTs);
      var getReportBytes = (from b in Db.SysRptLst join st in Db.SysTask on b.SysTaskNum equals st.SysTaskNum
                            where st.TaskNote ==noteStr select new {b.RptDescription, b.RptData}).FirstOrDefault();
      
      this.InvoiceDocument = Convert.ToBase64String(getReportBytes.RptData);
     }
     else
     {
      this.Success=false;
      this.ErrorMessage="Invoice not Found";
     }
    
  });
}
catch(Exception ex)
{
  this.Success=false;
  this.ErrorMessage=ex.Message;
}

Then you can turn those report bytes back into a document in your web app. If you are using a JavaScript front end this will do it

 let byteString= window.atob(response.InvoiceDocument);
                  let arrayBuffer = new ArrayBuffer(byteString.length);
                  let int8Array = new Uint8Array(arrayBuffer);
                  for(let i=0;i<byteString.length;i++)
                  {
                    int8Array[i]=byteString.charCodeAt(i);
                  }
                  let documentBlob = new Blob([int8Array], {type: 'application/pdf'});
                  let fileURL = URL.createObjectURL(documentBlob);
                  window.open(fileURL,'_blank');
                
2 Likes

Just noticed your company, @Will79

Say hello to Sean for me :stuck_out_tongue: it’s been a few years but I did some stuff for you guys back in my consulting days that I’m not sure I could do again :sweat_smile::sweat_smile::sweat_smile: that was a wild project!

1 Like

Thanks! Yeah, Sean asked me to figure this out. He’s amazing at coding and other things, but I am so far behind I can barely keep up sometimes.

One quick but prob simple question, where do I get the SysRowID? Do we fire the API to the BAQ, get the SysRowID, then fire the Function?

You don’t have to use the SysRowID you can just use the invoice number then you don’t have to look anything up. The SysRowID is in the InvcHead table and yes you can get it with a BAQ.

We used it because this is a generic functionn that does more than just print invoices ir prints orders, quotes etc. So Instead of having a bunch of different parameters we use the SysRowID as a “generic” input.

2 Likes

Much appreciate the info! This helps me out tremendously.

Are you using a JavaScript front end of some sort? Node , Angular , React? If you aren’t you can still use this same function you will just have to turn those Base64Encoded Bytes into a PDF some other way I may have an example of this in C# if that’s more your flavor.

That part is all Sean! :rofl: :joy: I will pass the info to him on this one. However, I do think he will be using Java. If you have the C#, that would be great as well.

That was a much better explanation, @Mark_Wonsil would be proud :rofl:

1 Like

@josecgomez Sean said he’s using .NET Blazor which has the JS interop functionality.

I’m getting several errors and am curious if I have all the services and assemblies for the function or if I need to look elsewhere. I am currently using the services ERP:BO:ARInvoice and ERP:BO:ARInvForm and assemblies ERP.Contracts.BO.ArInvoice.

THANK YOU for not automatically emailing them! :face_holding_back_tears:

Do you have M365 and do you use it to collaborate with your outside reps, via Teams for example?

1 Like

Sadly no. Everything is email.

No 365 or no collaboration?

No to both. GSuite

Most of those are inputs and output variables from the signature of the function.

The other two are Table references you need to add.