BPM Custom Code Email - Help Needed

I’ve been asked to create a BPM that would email Requestors when their requisitions PO has been approved. I have a BPM in place to that messages PO approvers when approval is needed and sends an email back to the buyer once the highest level approver has approved or rejected the purchase order. My thought was to add a section in custom C# that would check each release on each line for a requisition and email the requestor that the corresponding requisition line had been fulfilled. What I would like to accomplish is something similar to whats listed in this post:

And have the c# code compile like requestor numbers into a single email and send it off. Has anyone else done something similar or know of a better way of accomplishing the same thing?

Thanks for the help!

HI @dgreenEA
You could do this using custom code on change approval,
The PoRel Table has the PO + request number and line numbers.
You could iterate through the Req lines, appending the data to a string.

If you use the string builder class you can format it very nicely for emailing in html formatting.

1 Like

@Joseph_Davies,

Just recently got back to working on this and I got it working pretty well. I do however have a single issue with the code I’ve written and attached below. I am receiving duplicate emails for each req line associated with the PO.

For example, I made a requisition with 4 lines, 2 lines to one supplier, 2 lines to another. When the PO’s show approved I should get a total of 4 emails, 1 for each line on a requisition. However, I get 2 emails for each line totaling 8 emails. I believe it has to do with the last part of my iterating process, but am unsure how to remedy this issue.

Thanks for the help!

var POHed = (from r in ttPOHeader where r.Added() || r.Updated() select r).FirstOrDefault();

if (POHed != null)
{
  foreach (var PODtl_iterator in (from r in Db.PODetail where r.Company == Session.CompanyID && r.PONUM == POHed.PONum select r))
  { 
    if (PODtl_iterator != null)
    {
      foreach (var PORel_iterator in (from r in Db.PORel where r.Company == Session.CompanyID && r.PONum == POHed.PONum select r))
      {  
        if (PORel_iterator != null)
        {
          foreach (var Requisition_iterator in (from r in Db.ReqDetail where r.Company == Session.CompanyID && r.ReqNum == PORel_iterator.ReqNum && r.ReqLine == PORel_iterator.ReqLine select r))
          { 
            if (PORel_iterator != null)
            {
              var Req = Requisition_iterator;
                
              var PONum = Req.PONUM;
              var POLine = Req.POLine;
              var PORel = Req.PORelNum;
              var ReqNum = Req.ReqNum;
              var ReqLine = Req.ReqLine;
              var PartNum = Req.PartNum;
              var OrderQty = Req.OrderQty;
              var email = "Recievers email goes here";
              var sender = "Senders email goes here";
              var emailMessage = ("PO: "+PONum+" PO Line: "+ POLine + " PO Rel: "+PORel+" Req#: "+ReqNum+ " Req Line: "+ ReqLine+" Part#: "+PartNum+" Order Qty: "+OrderQty);
              Message = ("PO: "+PONum+" PO Line: "+ POLine + " PO Rel: "+PORel+" Req#: "+ReqNum+ " Req Line: "+ ReqLine+" Part#: "+PartNum+" Order Qty: "+OrderQty); 
             
             

              var body = emailMessage;
            
              var mailer = this.GetMailer(async: true);
              var messages = new Ice.Mail.SmtpMail();
              messages.SetFrom(sender);
              messages.SetTo(email);
              //message.SetCC()
              //message.SetBcc() 
              messages.SetBody(body);
             
             mailer.Send(messages);

          
         }
        }
      }
    }
  }
 }
}

My first guess would be that the BPM that runs the code is firing multiple times.

At the very beginning of your code, generate a random number. Then include that in the email message as a debugging tool. If all 8 emails have the same number in them then the BPM is only firing once.

3 Likes

You may want to add the POline to this otherwise you will get all release for all lines multiple times.

2 Likes

@knash,

So big ooof on my part. Noticed that that section of the iterator was also referencing the POHeader and not the PODetail_Iterator as it should have been. After making that swap and adding in the POLine as stated the code is working flawlessly. Thank you for the solution!

@ckrusen,
That debugging tip is going in my notebook! That idea would have saved me hours worth of troubleshooting in the past!

Corrected code below for those interested. Thank you all for the quick responses and help!

var POHed = (from r in ttPOHeader where r.Added() || r.Updated() select r).FirstOrDefault();

if (POHed != null)
{
  foreach (var PODtl_iterator in (from r in Db.PODetail where r.Company == Session.CompanyID && r.PONUM == POHed.PONum select r))
  { 
    if (PODtl_iterator != null)
    {
      foreach (var PORel_iterator in (from r in Db.PORel where r.Company == Session.CompanyID && r.PONum == PODtl_iterator.PONUM && r.POLine == PODtl_iterator.POLine select r))
      {  
        if (PORel_iterator != null)
        {
          foreach (var Requisition_iterator in (from r in Db.ReqDetail where r.Company == Session.CompanyID && r.ReqNum == PORel_iterator.ReqNum && r.ReqLine == PORel_iterator.ReqLine select r))
          { 
            if (PORel_iterator != null)
            {
              var Req = Requisition_iterator;
                
              var PONum = Req.PONUM;
              var POLine = Req.POLine;
              var PORel = Req.PORelNum;
              var ReqNum = Req.ReqNum;
              var ReqLine = Req.ReqLine;
              var PartNum = Req.PartNum;
              var OrderQty = Req.OrderQty;
              var email = "Receivers email Here";
              var sender = "Senders email Here";
              var emailMessage = ("PO: "+PONum+" PO Line: "+ POLine + " PO Rel: "+PORel+" Req#: "+ReqNum+ " Req Line: "+ ReqLine+" Part#: "+PartNum+" Order Qty: "+OrderQty);
              Message = ("PO: "+PONum+" PO Line: "+ POLine + " PO Rel: "+PORel+" Req#: "+ReqNum+ " Req Line: "+ ReqLine+" Part#: "+PartNum+" Order Qty: "+OrderQty); 
             
             

              var body = emailMessage;
            
              var mailer = this.GetMailer(async: true);
              var messages = new Ice.Mail.SmtpMail();
              messages.SetFrom(sender);
              messages.SetTo(email);
              //message.SetCC()
              //message.SetBcc() 
              messages.SetBody(body);
             
             mailer.Send(messages);

          
         }
        }
      }
    }
  }
 }
}

You could also remove the foreach line loop as you don’t really need to do that based on your code not using the return item.

Saves a few request back to the server.

1 Like

@ckrusen and @knash,

Just noticed my emails are not receiving a subject line. How do I add one through my custom code?

messages.Subject = “this is the subject line”;

1 Like

@knash ,

Do you also know a way to round a decimal to no decimal places?

myDecimal.Floor().ToString;
Math.Floor(myDecimal).ToString();

edit

whoops… that give you the integer part. If you want to round (up and down) use
Math.Round(myDecimal).ToString();

1 Like

there are many ways…i convert to int

int thisNum = Convert.ToInt32( value );

1 Like

@ckrusen and @knash,
You guys are awesome! Thanks again!

What version are you on? Have you thought about using Epicor Functions (which you can schedule) so you can send a consolidated email periodically through the day rather than on each action?

From experience users soon get sick of individual notifications for each line/item they order etc. As an example i use Functions to send emails out twice a day letting approvers know what POs they have o/s to approve with a hyperlink to the PO approvals form (in EWA) and then kick off a standard BPM to let the individual buyers know that things have been approved

3 Likes

And multiple copies due to corrections…

User: “I’m getting too many emails.”

Me: “I could make it just send one email at the end of the day, with all the approvals that happened that day”

User: “I can’t wait until the end of the day. Can you have it email first thing in the morning, with all the approvals that will happen later that day?”

1 Like