BPM to send email to PO ApprovalPerson when buyer limit exceeded - custom code

Thanks to a kind fellow EpiUser, I found a very helpful post on creating a BPM to send a notification email to the relevant approval person when a PO approval is needed.

This Was done on POHeader Update, with a pre-processing method directive to check a condition and then enable a post processing method directive.

previous example

How ever, on the post processing custom C# code, I get the error “name ttPOheader does not exist in the current context” Is this because this solution was for an older version? and somehow now we cannot use ttPOHeader in post processing? (I’m on Kinetic 23.2)

Any help would be much appreciated!!

Could possibly be due to the capitalisation. Looks like there’s a reference to ttPOheader where it should be ttPOHeader?

Hopefully it’s that simple anyway!

Thanks,

Nathan

Hi
Try replacing tt with ds in the code, this was a change in later versions

Erp.Tables.PurAgent PurAgent;
string vapprov = string.Empty;

// Iterate over ttPOHeader where ApprovalStatus is 'P'
foreach (var ttPOHeader_iterator in (from ttPOHeader_Row in ttPOHeader where string.Compare(ttPOHeader_Row.ApprovalStatus, "P", true)==0 select ttPOHeader_Row))

{ 

  var ttPOHeaderRow = ttPOHeader_iterator;
  if (ttPOHeader_iterator != null)
  
  {
    PurAgent = (from PurAgent_Row in Db.PurAgent where PurAgent_Row.Company == ttPOHeaderRow.Company && PurAgent_Row.BuyerID == ttPOHeaderRow.BuyerID select PurAgent_Row).FirstOrDefault();
  
    vapprov = PurAgent.ApprovalPerson;

    PurAgent = (from PurAgent_Row in Db.PurAgent where PurAgent_Row.Company == ttPOHeaderRow.Company && PurAgent_Row.BuyerID == vapprov select PurAgent_Row).FirstOrDefault();
    
    vapprov = PurAgent.EMailAddress;
    
    PurAgent = (from PurAgent_Row in Db.PurAgent where PurAgent_Row.Company == ttPOHeaderRow.Comapny && PurAgent_Row.BuyerID == ttPOHeaderRow.BuyerID select PurAgent_Row).FirstOrDefault();
  
      if(!string.IsNullOrEmpty(vapprov))  
      {
        string vFrom = string.Empty; // Set if needed
        string vTo = string.Empty;
        string vCC = string.Empty;
        string vSubject = string.Empty;
        string vBody = string.Empty;
        vFrom = "no-reply@xx.com";
        vTo = vapprov;
        vCC = "";
        vSubject = vSubject + "Purchase Order" + System.Convert.ToString(ttPOHeaderRow.PONum) + "Needs Approval";
        vBody = vBody + "The Above PO Needs Approval";
        var mailer = this.GetMailer(async: false);
        var message = new Ice.Mail.SmtpMail(); 
        message.SetTo(vTo); 
        message.SetFrom(vFrom); 
        message.SetCC(vCC); 
        message.SetSubject(vSubject); 
        message.SetBody(vBody); 
        mailer.Send(message);
    break;             
    }
  
  }
} 

thanks for the suggestion Nathan, I tried this and still no luck.

Tried this too, then I get that error same error for dsPOHeader … :cry:

I tried popping this code into a new Post-Processing BPM on PurchaseOrder.Update and the only error was down to a typo on Company in the PurAgent line. Once I corrected it, the code compiled fine.

If you start typing ‘tt’ into your custom code editor then hit Control + space does intellisense show you anything? Here’s what I get:

image

If you’re not seeing this then you’re probably on a more recent version and will need to swap to the ds variables as @SueLowden suggested.

Many thanks,

Nathan

1 Like

Try this code to gather the information and populate to call context fields then use the send email widget to use the data afterwards:
string vapprov = string.Empty;
string vbuyer = string.Empty;
Erp.Tables.PurAgent PurAgent;

foreach (var ttPOHeader_xRow in ds.POHeader)
{

foreach (var ttPOHeader_iterator in (from ttPOHeader_Row in ds.POHeader
where string.Compare(ttPOHeader_Row.ApprovalStatus, “P”, true) == 0
select ttPOHeader_Row))
{
var ttPOHeaderRow = ttPOHeader_iterator;
if (ttPOHeader_xRow != null)
{
PurAgent = (from PurAgent_Row in Db.PurAgent
where string.Compare(PurAgent_Row.Company, ttPOHeaderRow.Company, true) == 0 && string.Compare(PurAgent_Row.BuyerID, ttPOHeaderRow.BuyerID, true) == 0
select PurAgent_Row).FirstOrDefault();
vapprov = PurAgent.ApprovalPerson;
PurAgent = (from PurAgent_Row in Db.PurAgent
where string.Compare(PurAgent_Row.Company, ttPOHeaderRow.Company, true) == 0 && string.Compare(PurAgent_Row.BuyerID, vapprov, true) == 0
select PurAgent_Row).FirstOrDefault();
vapprov = PurAgent.EMailAddress;
PurAgent = (from PurAgent_Row in Db.PurAgent
where string.Compare(PurAgent_Row.Company, ttPOHeaderRow.Company, true) == 0 && string.Compare(PurAgent_Row.BuyerID, ttPOHeaderRow.BuyerID, true) == 0
select PurAgent_Row).FirstOrDefault();
vbuyer = PurAgent.EMailAddress;
if (!String.IsNullOrEmpty(vapprov))
{
callContextBpmData.Character01 = vbuyer;
callContextBpmData.Character02 = vapprov;
}
}
}
}

2 Likes

Good pickup on the Typo!! I corrected it. I Am on kinetic 23.2, I just tried your suggestion and this is what i get. I will try the next suggestion by Sue now. thanks Nathan!

That’ll be it. You’ll need to replace your lookup in the foreach loop to something like ds.POHeader, I don’t have a 23.2 instance in front of me to test, unfortunately.

Thanks,

Nathan

Hi
FYI - I have changed my approach to letting people know they have PO’s to approve, rather than “spamming” them each time a PO is submitted for approval, I have moved this into a Function that I can schedule.

The function gives them a list of PO’s awaiting their approval in a pretty SMTP table format and a hyperlink to the browser approval form so they can just action them.

Generally we schedule this function to run before the working day, mid-morning and mid-afternoon

The data comes from a BAQ and user codes

3 Likes

The code compiles with no errors with this solution! thanks a lot.

I really like this idea, Thanks a lot for sharing.

I will definitely look into functions once I become confident with my BPM Skills.