BPM Method on SSRS Email (print) a Sales Order?

Hi Ken, I have it as a Data Directive on OrderHed In-Transaction, with our
EDI855 BPM.

No task is being submitted in the System Monitor, but I’ll try a hard-coded
Email address as I haven’t tried that yet.

Update: hard-coded email addresss didn’t work. :frowning:

Do you know your workstation id?
The ReportStyleNum might need to be tweaked as well.
last the manager password will need to be adjusted as well.

Randy,

Here is the code for a BPM. I went back to the path Jose started us on, vs showing you the data directive.

BPM Execute Custom Code. Code, Using, Reference following: Hard coded for order and email, make sure that works in a stand alone BPM. Then add your order loop.

Code:

var soForm = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.SalesOrderAckSvcContract>(Db);
SalesOrderAckTableset soTS = soForm.GetNewParameters();
SalesOrderAckParamRow r = soTS.SalesOrderAckParam[0];

r.OrderNum = 18738;
r.SysRowID = Guid.Parse("00000000-0000-0000-0000-000000000000");
r.AutoAction = "SSRSPrint";
r.AgentSchedNum = 0;
r.AgentID = "SystemTaskAgent";
r.AgentTaskNum = 0;
r.RecurringTask = false;
r.RptPageSettings = "";
r.RptPrinterSettings = "";
r.RptVersion = "";
r.ReportStyleNum = 2;
r.WorkstationID = "";
r.TaskNote = "";
r.ArchiveCode = 0;
r.DateFormat = "m/d/yyyy";
r.NumericFormat = ",.";
r.AgentCompareString = "";
r.ProcessID = "";
r.ProcessTaskNum = 0;
r.DecimalsGeneral = 0;
r.DecimalsCost = 0;
r.DecimalsPrice = 0;
r.GlbDecimalsGeneral = 0;
r.GlbDecimalsCost = 0;
r.GlbDecimalsPrice = 0;
r.FaxSubject = string.Format("Order: {0} The Sales Ack has been sent to you enjoy reading", 18738); ;
r.FaxTo = "";
r.FaxNumber = "";
r.EMailTo = "email@email.com";
r.EMailBody = "";

r.AttachmentType = "PDF";
r.ReportCurrencyCode = "USD";
r.ReportCultureCode = "en-US";
r.SSRSRenderFormat = "PDF";
r.RowMod = "A";
soForm.RunDirect(soTS);

Using: using Erp.Tablesets;

References Erp.ContractsRptSalesOrderAck

10 Likes

OMG thanks so much @josecgomez and @knash, that code worked.

Ken, I think your first code wasn’t working for me as I always had it in a Data Directive “Execute Custom Code” BPM action-node (or whatever the term is), so --sounds like to this layman-- I had it in the wrong type of node. Plus the WorkstationID I failed to manage.

Jose, it wasn’t working at first as I didn’t have the Using & References set until after I’d messed with your initial code so much it was beyond hope of working.

I owe you both a drink sometime!

2 Likes

Hi,

Looking over this- it appears to be very close to what I’m trying to achieve, when the user clicks to email the sales order acknowledgement via the SSRS Email screen we want to pre-populate the TO field with the users email address (as they always send them to themselves)

The part that I’m struggling to figure out is what Method directive to put the BPM code against- running a trace just shows Erp.Proxy.Rpt.SalesOrderAckImpl and the Submit to agent Method :slightly_frowning_face:

If you don’t mind me asking did you achieve this via a BPM in the end or via APM, or even a screen customisation (which I tried first but I cant seem to get to that screen to customize it)? and if so what directive was this placed against for the sales order ack?

Thanks in advance :slight_smile:

Hi guys (@Randy @josecgomez @knash) , I appreciate the thread. I am also interested to know what method is the code attached to. What I don’t understand is if this code automates the printing or populates the fields and allows the user to push the OK button to activate the send.

I appreciate it if someone could answer that.

It’s not a Method Directive but a Data Directive. In my case it’s OrderHed table as a “standard” directive.

We put a checkbox on the SO Entry form, on the Header tab. When the checkbox = True it’ll fire off the email. This keeps it from sending before our CSR have completed the order and allows them to “re-send” by clearing the check box, saving, and check it again. The BPM then sets various variables, ie: Customer Service Rep (CSR) name, and email address. Then it checks for a customized “Entered For” CSR info (used if a CSR enters an order for another CSR). If true, it’ll set those variables as well. Then it goes to the C# code box(es) to send the appropriate SSRS email. (Note screen shot is from our test server that also includes a test email via the email node at the bottom)

The C# code is pretty much what @knash posed and that I marked as the solution. Using variables I mentioned and fields from the OrderHed table. Example: the customer email address is a field on the OrderHed table (copied via BPM from the Customer table during order creation)

1 Like

hi, thanks for the explanation. the code works fine. how could I add an additional attachment?

No idea, sorry. What is it you want to attach?

IE: We made a special SSRS report & report style in Epicor that includes T&Cs that our standard default OrderAck form does not have for these emails.

1 Like

Hmm I am really sad after reading this post. Not going to Insights so I can buy these legends a drink! :sob: I think this will help me solve my 810/invoic issue I have. We have EDI/Demand Management, but not Tie Kinetics :frowning:

So thanks everyone for contributing and posting.

1 Like

Thank you for the code. The email is automatically sent using this code. Any suggestions on how I can display the form (I will set some defaults) and then the user can modify the data in the form and then must click the OK to send?

Here is the code I am using

//GetService<Erp.Contracts.SalesOrderAckSvcContract>(Db)
callContextBpmData.ShortChar02 = “amy.haas@sadiatech.com”;
var soForm = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.SalesOrderAckSvcContract>(Db);
SalesOrderAckTableset soTS = soForm.GetNewParameters();
SalesOrderAckParamRow r = soTS.SalesOrderAckParam[0];

r.OrderNum = 124544;
r.SysRowID = Guid.Parse(“00000000-0000-0000-0000-000000000000”);
r.AutoAction = “SSRSPrint”;
r.AgentSchedNum = 0;
r.AgentID = “SystemTaskAgent”;
r.AgentTaskNum = 0;
r.RecurringTask = false;
r.RptPageSettings = “”;
r.RptPrinterSettings = “”;
r.RptVersion = “”;
r.ReportStyleNum = 1012;
r.WorkstationID = “”;
r.TaskNote = “”;
r.ArchiveCode = 0;
r.DateFormat = “m/d/yyyy”;
r.NumericFormat = “,.”;
r.AgentCompareString = “”;
r.ProcessID = “”;
r.ProcessTaskNum = 0;
r.DecimalsGeneral = 0;
r.DecimalsCost = 0;
r.DecimalsPrice = 0;
r.GlbDecimalsGeneral = 0;
r.GlbDecimalsCost = 0;
r.GlbDecimalsPrice = 0;
r.FaxSubject = string.Format(“Order: {0} The Sales Ack has been sent to you enjoy reading”, 124544); ;
r.FaxTo = “”;
r.FaxNumber = “”;
//r.EMailFrom = “ahaas@elginfasteners.com”;
//r.EMailTo = “ahaas@elginfasteners.com”;
r.EMailTo = callContextBpmData.ShortChar02;
r.EMailBody = “”;

r.AttachmentType = “PDF”;
r.ReportCurrencyCode = “USD”;
r.ReportCultureCode = “en-US”;
r.SSRSRenderFormat = “PDF”;
r.RowMod = “A”;
soForm.RunDirect(soTS);

You can make a BPM from to allow the user to enter data, ie the email body. Then assign that variable to r.EMailBody.

1 Like

I have a method directive using this code that I got working to automatically send out pack slips with some related information (thanks for the code!).

I ran into an issue when I had my shipping manager try to run this; he is getting weird errors on his end; a ‘PRINTER_DOESNT_EXIST’ error and an ‘Object Reference Not Set’ error that points to “Ice.Lib.Reporting.PdfPrintDocument.CreateAndConfigurePdfPrint”. I confirmed that he has no issue manually printing PDF’s on his computer.

I ran a trace on myself, and had him run a trace, and I noticed some differences on the SubmitToAgent method of the SSRS report we’re running. It seems that when I run it, there are no values for the “RptPageSettings” and “RptPrinterSettings” parameters.

When my Shipping Manager runs it, the trace shows values for both of these parameters.

Anyone have any idea what steps I can try to fix this issue? I have no idea where to even start with printer issues so any help is appreciated. Trace Log snippets from myself (Working) and my Shipping Manager (Not Working) below.

I can post code snippets as well, but the code is pretty much identical to everything else on this thread in terms of setting the parameter row values for printing.

[details="Trace Log - Working"]
<tracePacket>
  <businessObject>Erp.Proxy.Rpt.PackingSlipPrintImpl</businessObject>
  <methodName>SubmitToAgent</methodName>
  <appServerUri>https://centralusdtapp23.epicorsaas.com/SaaS736/</appServerUri>
  <returnType>System.Void</returnType>
  <localTime>1/25/2023 14:39:05:8760716 PM</localTime>
  <threadID>1</threadID>
  <correlationId>3bc2d7a9-40ea-4a63-8606-5b83785c3517</correlationId>
  <executionTime total="760" roundTrip="754" channel="0" bpm="1" bpmDataForm="0" other="5" />
  <retries>0</retries>
  <parameters>
    <parameter name="ds" type="Erp.Rpt.PackingSlipPrintDataSet">
      <PackingSlipPrintDataSet xmlns="http://www.epicor.com/Ice/300/Rpt/PackingSlipPrint/PackingSlipPrint">
        <PackingSlipParam>
          <PackNum>0</PackNum>
          <PrintingOptions>S</PrintingOptions>
          <AssignLegalNumber>false</AssignLegalNumber>
          <EnableAssignLegalNumber>false</EnableAssignLegalNumber>
          <DCHdrList></DCHdrList>
          <PackNumList>102973</PackNumList>
          <StyleNumExt>1001</StyleNumExt>
          <EnableIncludePCID>false</EnableIncludePCID>
          <IncludePCID>false</IncludePCID>
          <DocCopyNum></DocCopyNum>
          <DraftMode>false</DraftMode>
          <DemandContractList></DemandContractList>
          <IncludeInventoryAttributes>false</IncludeInventoryAttributes>
          <SysRowID>00000000-0000-0000-0000-000000000000</SysRowID>
          <AutoAction>SSRSPrint</AutoAction>
          <PrinterName></PrinterName>
          <AgentSchedNum>0</AgentSchedNum>
          <AgentID>SystemTaskAgent</AgentID>
          <AgentTaskNum>0</AgentTaskNum>
          <RecurringTask>false</RecurringTask>
          <RptPageSettings></RptPageSettings>
          <RptPrinterSettings></RptPrinterSettings>
          <RptVersion></RptVersion>
          <ReportStyleNum>1001</ReportStyleNum>
          <WorkstationID>myname</WorkstationID>
          <TaskNote></TaskNote>
          <ArchiveCode>0</ArchiveCode>
          <DateFormat>m/d/yyyy</DateFormat>
          <NumericFormat>,.</NumericFormat>
          <AgentCompareString></AgentCompareString>
          <ProcessID></ProcessID>
          <ProcessCompany></ProcessCompany>
          <ProcessSystemCode></ProcessSystemCode>
          <ProcessTaskNum>0</ProcessTaskNum>
          <DecimalsGeneral>0</DecimalsGeneral>
          <DecimalsCost>0</DecimalsCost>
          <DecimalsPrice>0</DecimalsPrice>
          <GlbDecimalsGeneral>0</GlbDecimalsGeneral>
          <GlbDecimalsCost>0</GlbDecimalsCost>
          <GlbDecimalsPrice>0</GlbDecimalsPrice>
          <FaxSubject>Test Email</FaxSubject>
          <FaxTo></FaxTo>
          <FaxNumber></FaxNumber>
          <EMailTo>myemail@mycompany.com</EMailTo>
          <EMailCC></EMailCC>
          <EMailBCC></EMailBCC>
          <EMailBody>Test Body</EMailBody>
          <AttachmentType>PDF</AttachmentType>
          <ReportCurrencyCode>USD</ReportCurrencyCode>
          <ReportCultureCode>en-US</ReportCultureCode>
          <SSRSRenderFormat>PDF</SSRSRenderFormat>
          <UIXml></UIXml>
          <PrintReportParameters>false</PrintReportParameters>
          <SSRSEnableRouting>false</SSRSEnableRouting>
          <DesignMode>false</DesignMode>
          <RowMod>A</RowMod>
        </PackingSlipParam>
[/details]
[details="Trace Log - Not Working"]
<tracePacket>
  <businessObject>Erp.Proxy.Rpt.PackingSlipPrintImpl</businessObject>
  <methodName>SubmitToAgent</methodName>
  <appServerUri>https://centralusdtapp23.epicorsaas.com/SaaS736/</appServerUri>
  <returnType>System.Void</returnType>
  <localTime>1/25/2023 09:56:22:2359559 AM</localTime>
  <threadID>1</threadID>
  <correlationId>1ec422d9-53c2-47cd-977d-c35baffd60b4</correlationId>
  <executionTime total="193" roundTrip="186" channel="0" bpm="0" bpmDataForm="0" other="7" />
  <retries>0</retries>
  <parameters>
    <parameter name="ds" type="Erp.Rpt.PackingSlipPrintDataSet">
      <PackingSlipPrintDataSet xmlns="http://www.epicor.com/Ice/300/Rpt/PackingSlipPrint/PackingSlipPrint">
        <PackingSlipParam>
          <PackNum>102973</PackNum>
          <PrintingOptions>S</PrintingOptions>
          <AssignLegalNumber>false</AssignLegalNumber>
          <EnableAssignLegalNumber>false</EnableAssignLegalNumber>
          <DCHdrList></DCHdrList>
          <PackNumList>102996</PackNumList>
          <StyleNumExt>2</StyleNumExt>
          <EnableIncludePCID>false</EnableIncludePCID>
          <IncludePCID>false</IncludePCID>
          <DocCopyNum></DocCopyNum>
          <DraftMode>false</DraftMode>
          <DemandContractList></DemandContractList>
          <IncludeInventoryAttributes>false</IncludeInventoryAttributes>
          <SysRowID>00000000-0000-0000-0000-000000000000</SysRowID>
          <AutoAction>SSRSPrint</AutoAction>
          <PrinterName></PrinterName>
          <AgentSchedNum>0</AgentSchedNum>
          <AgentID>SystemTaskAgent</AgentID>
          <AgentTaskNum>0</AgentTaskNum>
          <RecurringTask>false</RecurringTask>
          <RptPageSettings>Color=True,Landscape=False,AutoRotate=False,PaperSize=[Kind="Letter" PaperName="Letter" Height=1100 Width=850],PaperSource=[SourceName="Automatically Select" Kind="FormSource"],PrinterResolution=[]</RptPageSettings>
          <RptPrinterSettings>PrinterName="PrinterWyomingShippingMgr (HP LaserJet MFP M426fdw)",Copies=2,Collate=True,Duplex=Simplex,FromPage=1,ToPage=0</RptPrinterSettings>
          <RptVersion></RptVersion>
          <ReportStyleNum>1001</ReportStyleNum>
          <WorkstationID>hisname</WorkstationID>
          <TaskNote></TaskNote>
          <ArchiveCode>0</ArchiveCode>
          <DateFormat>m/d/yyyy</DateFormat>
          <NumericFormat>,.</NumericFormat>
          <AgentCompareString></AgentCompareString>
          <ProcessID></ProcessID>
          <ProcessCompany></ProcessCompany>
          <ProcessSystemCode></ProcessSystemCode>
          <ProcessTaskNum>0</ProcessTaskNum>
          <DecimalsGeneral>0</DecimalsGeneral>
          <DecimalsCost>0</DecimalsCost>
          <DecimalsPrice>0</DecimalsPrice>
          <GlbDecimalsGeneral>0</GlbDecimalsGeneral>
          <GlbDecimalsCost>0</GlbDecimalsCost>
          <GlbDecimalsPrice>0</GlbDecimalsPrice>
          <FaxSubject>test</FaxSubject>
          <FaxTo></FaxTo>
          <FaxNumber></FaxNumber>
          <EMailTo>myemail@mycompany.com</EMailTo>
          <EMailCC></EMailCC>
          <EMailBCC></EMailBCC>
          <EMailBody>test</EMailBody>
          <AttachmentType>PDF</AttachmentType>
          <ReportCurrencyCode>USD</ReportCurrencyCode>
          <ReportCultureCode>en-US</ReportCultureCode>
          <SSRSRenderFormat>PDF</SSRSRenderFormat>
          <UIXml></UIXml>
          <PrintReportParameters>false</PrintReportParameters>
          <SSRSEnableRouting>false</SSRSEnableRouting>
          <DesignMode>false</DesignMode>
          <RowMod>A</RowMod>
        </PackingSlipParam>
[/details]

I get the same error on kinetic, @svandenberg did you solve your issue ?

Never got a real solution, had to work around it by making a new user account for our shipping manager. It seems the error is tied to the user account but I don’t have the knowledge to dig any deeper than that.

At a guess I’m thinking these values come from the users’ Workstation. Shipping needs to be logged into a workstation for label printing, etc.

@svandenberg, if possible I’d look into getting APR and doing this via Report Style. It’s a much better way to do it.

can you share the code of your bpm ? i’m trying send out pack slips in a method directive too but isn’t working on my side

Here’s the custom code in the post processing method directive I have on the Erp.BO.CustShip.Update Method. This collects all relevant information I want from a customer shipment and sends an email out to the concerned parties.

I have a pre-processing directive to trigger this whenever a customer shipment is checked as “Shipped”.

//Erp.BO.CustShip.Update

//See Using and Reference
//using Erp.Tablesets;
//Reference Assemblies:
//Erp.Contracts.Rpt.PackingSlipPrint

//Declare Variables
string nl = "\n";
string pmPersonID = "";
string HTMLnl = "<br>";
string trackingNum = "";
decimal totShipQty = 0;
decimal totLineQty = 0;
List<string> shipinfoList = new List<string>();
List<string> orderinfoList = new List<string>();
HashSet<int> ordernumList = new HashSet<int>();
HashSet<string> pmEmailList = new HashSet<string>();
HashSet<string> designReleaseList = new HashSet<string>();
int packNum = Convert.ToInt32(callContextBpmData.Number01);
var psForm = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.PackingSlipPrintSvcContract>(Db);
PackingSlipPrintTableset psTS = psForm.GetNewParameters();
PackingSlipParamRow psR = psTS.PackingSlipParam[0];

//Find the selected pack
var packHead = (from r in Db.ShipHead where r.Company == CompanyID
  && r.PackNum == packNum
  select r).FirstOrDefault();

//Find the list of pack lines for the selected pack
if(packHead != null)
{
  var packLines = (from r in Db.ShipDtl where r.Company == CompanyID
    && r.PackNum == packNum
    select r);
  
  //Iterate through all pack lines and add shipping info to shipinfoList
  //Add unique order numbers to the ordernumList Hash Set
  if(packLines != null)
  {
    foreach(var line in packLines)
    {
      totShipQty = decimal.Round(line.OurInventoryShipQty + line.OurJobShipQty, 2, MidpointRounding.AwayFromZero);
      
      shipinfoList.Add("Order: " + line.OrderNum + "   Line: " + line.OrderLine + "   Part: " + line.PartNum + "   Description: " + line.LineDesc + "   Qty: " + totShipQty);
    
      ordernumList.Add(line.OrderNum);
    }
  }
}

//Iterate through all unique orders and get order information
if(ordernumList != null)
{
  foreach(int order in ordernumList)
  {
    //Get the order table related to the pack
    var orderHead = (from r in Db.OrderHed where r.Company == CompanyID
    && r.OrderNum == order
    select r).FirstOrDefault();
    
    //Find the Design Release, PM and PM Email address for the order
    if(orderHead != null)
    {
      designReleaseList.Add(orderHead.DesignRelease_c);
    
      var personTable = (from r in Db.Person where r.Company == CompanyID
        && r.PersonID == orderHead.SalesRepCode_c
        select r).FirstOrDefault();
      
      try
      {
        var addr = new System.Net.Mail.MailAddress (personTable.EMailAddress);
        pmEmailList.Add (personTable.EMailAddress);
      }
      catch
      {
        // bad address we skip
      }
      
      //Find the list of order lines for the selected order
      var orderLines = (from r in Db.OrderDtl where r.Company == CompanyID
        && r.OrderNum == order
        select r);
      
      //Iterate through all order lines and add line info of open lines to orderinfoList
      if(orderLines != null)
      {
        foreach(var orderLine in orderLines)
        {
        if(orderLine.OpenLine == true)
          {
            totLineQty = decimal.Round(orderLine.SellingQuantity, 2, MidpointRounding.AwayFromZero);
            
            orderinfoList.Add("Order: " + orderLine.OrderNum + "  Line: " + orderLine.OrderLine + " Part: " + orderLine.PartNum + " Description: " + orderLine.LineDesc + " Qty: " + totLineQty + nl);
          }
        }
      }
    }
  }
}

//Packlist Print Parameters
psR.PackNumList = packNum.ToString();
psR.SysRowID = Guid.Parse("00000000-0000-0000-0000-000000000000");
psR.AutoAction = "SSRSPrint";
psR.AgentSchedNum = 0;
psR.AgentID = "SystemTaskAgent";
psR.AgentTaskNum = 0;
psR.RecurringTask = false;
psR.RptPageSettings = "";
psR.RptPrinterSettings = "";
psR.RptVersion = "";
psR.ReportStyleNum = 1001;
psR.WorkstationID = "";
psR.TaskNote = "";
psR.ArchiveCode = 0;
psR.DateFormat = "m/d/yyyy";
psR.NumericFormat = ",.";
psR.AgentCompareString = "";
psR.ProcessID = "";
psR.ProcessTaskNum = 0;
psR.DecimalsGeneral = 0;
psR.DecimalsCost = 0;
psR.DecimalsPrice = 0;
psR.GlbDecimalsGeneral = 0;
psR.GlbDecimalsCost = 0;
psR.GlbDecimalsPrice = 0;
psR.AssignLegalNumber = false;
psR.EnableAssignLegalNumber = false;
psR.IncludePCID = false;
psR.EnableIncludePCID = false;
psR.AttachmentType = "PDF";
psR.SSRSRenderFormat = "PDF";
psR.FaxTo = "";
psR.FaxNumber = "";

if(ordernumList != null && shipinfoList != null && pmEmailList != null)
{

  //Try to get the tracking number from the selected pack
  try
  {
    trackingNum = packHead.TrackingNumber;
  }
  catch
  {
  }
  
  //Add person1 to email list for billing info
  pmEmailList.Add("person1@company.com");
  
  //Add person2 to email list for shipping info
  pmEmailList.Add("person2@company.com");
  
  string orderNums = String.Join(", ", ordernumList.ToArray());
  
  string designReleases = String.Join(", ", designReleaseList.ToArray());
  
  string shipInfo = String.Join(nl, shipinfoList.ToArray());
  
  string orderInfo = String.Join(nl, orderinfoList.ToArray());
  
  string emailAddress = String.Join(";", pmEmailList.ToArray());
  
  string Subject = String.Format("Epicor Shipment Notice: Order(s): {0}   Design Release(s): {1}", orderNums, designReleases);
  
  string Body = String.Format("*Pack Number*{0}{1}{0}{0}*Tracking Number*{0}{2}{0}{0}*Shipped Lines*{0}{3}{0}{0}*Open Lines*{0}{4}",
  Environment.NewLine,
  packNum,
  trackingNum,
  shipInfo,
  orderInfo);
  
  //Debug Message - Show all order info collected
  //PublishInfoMessage(Subject + nl + nl + Body + nl + nl + emailAddress, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", "");
  
  psR.EMailTo = emailAddress;
  psR.FaxSubject = Subject;
  psR.EMailBody = Body;
  psR.RowMod = "A";
  psForm.RunDirect(psTS);
}

We do have APR but I’m not sure how to use that for the request I was given: “Have Epicor automatically send an email out when a customer shipment is checked as ‘Shipped’. The email must include all pertinent information from all order lines that are shipped.”

I mostly use APR for automatically sending BAQ Reports out on a weekly or monthly schedule.