BPM with dynamic email receipient

I would do a custom 4GL program on a BAM alert that looks up the buyer for a given PO watching the fields that you are interested in.

I've included an e-mail describing a much more elaborate solution for PO approval notification below. The point is that your BAM 4GL program can call set the values of Email-To, Email-Subject, etc. and you'll get what you want.

I don't have time to connect all the dots here, but maybe this is enough to get you started. The Vantage 8.03 Tools Guide section on Business Activity Manager has a good section on this.

-bws

--
Brian W. Spolarich ~ Manager, Information Services ~ Advanced Photonix / Picometrix
    bspolarich@... ~ 734-864-5618 ~ www.advancedphotonix.com


-----Original Message-----
From: vantage@yahoogroups.com [mailto:vantage@yahoogroups.com] On Behalf Of vanb1950
Sent: Tuesday, March 16, 2010 11:46 AM
To: vantage@yahoogroups.com
Subject: [Vantage] BPM with dynamic email receipient

I am trying to send an email to a user when certain fields change on a Purchase Order. I need the recipient to be the buyer that entered the Purchase Order. Can anyone offer adice on how to do this?
Thanks,
Van Backeris

-----

[Resending this from early September in case this is useful to you. -bws]

Here's what I wound up doing:

1. Save the below 4GL code API-POApprovalNotification.p as a .P file under mfgsys803\server\ud\ with whatever name you want.

2. Create a BAM on POHeader watching for changes in ApprovalStatus and ShortChar01. Add rules, For Alert, where ApprovalStatus <> U or ShortChar01 <> "".

3. Create a BPM as follows:
- POApvMsg.Update, Post-Processing
- Condition: Number of Rows in 'GetApvMsg' query is not lets than one
- Query: for each ttPOApvMsg where ttPOApvMsg.MsgType = '1' no-lock
- Action: Synchronously execute 4GL Action with code below, record nothing
- Code:

find ttPOApvMsg.
for each ttPOApvMsg no-lock:
message "ttPOApvMsg.PONum: " + string(ttPOApvMsg.PONum) + "~n".
find first POHeader where POHeader.Company = ttPOApvMsg.Company and POHeader.PONum = ttPOApvMsg.PONum no-lock.
define variable ApprovalChain as character no-undo.
ApprovalChain = POHeader.ShortChar01 + "/" + ttPOApvMsg.MsgTo.
run lib\UpdateTableBuffer.p(input BUFFER POHeader:HANDLE, 'ShortChar01',ApprovalChain).
end.

That's it.

The point here is that without the BPM you have no way that I could figure out how to detect when the up-level approval notification has been generated, so you'd only get an e-mail from the BAM from the initial PO approval request, not the subsequent ones. With the BPM I modify a ShortChar field in the POHeader table appending the next approver. The data is irrelevant, as long as the field changes, and thus the BAM gets triggered. This notification program sends e-mail to each approver in series (assuming their Buyer record has an e-mail address), and the requestor Buyer indicating the final disposition (approve or reject) of the PO approval request.

I needed to use a BAM because I didn't think one could use a BPM 4GL action to send e-mail. However I saw something about this come across the list recently (although I apparently didn't save it and given how badly the search works in this Yahoo! Group not sure if I can find it again), so I think you could do this entirely as a BPM if you wanted to keep it cleaner. It seems to me that one should be able to do everything in a BPM that one can do in a BAM.

-bws

-----Begin API-POApprovalNotification.p-----

{ud/GlbAlert.i &TableName = "POHeader"}

DEFINE VARIABLE POAmount AS DECIMAL NO-UNDO.
DEFINE VARIABLE PONumber AS DECIMAL NO-UNDO.
DEFINE VARIABLE Company AS CHARACTER NO-UNDO.
DEFINE VARIABLE ApprovalStatus AS CHARACTER NO-UNDO.
DEFINE VARIABLE ApproverEmail AS CHARACTER NO-UNDO.
DEFINE VARIABLE ApproverName AS CHARACTER NO-UNDO.
DEFINE VARIABLE ApproverCode AS CHARACTER NO-UNDO.
DEFINE VARIABLE RequestorEmail AS CHARACTER NO-UNDO.
DEFINE VARIABLE RequestorName AS CHARACTER NO-UNDO.
DEFINE VARIABLE RequestorCode AS CHARACTER NO-UNDO.
DEFINE VARIABLE StatusText AS CHARACTER NO-UNDO.
DEFINE VARIABLE ApprovalStatusDesc AS CHARACTER NO-UNDO.

PONumber = POHeader.PONum.
Company = POHeader.Company.
ApprovalStatus = POHeader.ApprovalStatus.

message "In API-POApprovalNotification.p: Company: " + Company + " PONumber: " + string(PONumber) + " ApprovalStatus: " + ApprovalStatus + "~r~n".

find PODetail where (PODetail.Company = POHeader.Company) and (PODetail.PONum = POHeader.PONum) no-lock no-error.
for each PODetail of POHeader:
POAmount = POAmount + (PODetail.DocUnitCost * PODetail.OrderQty).
end.

find POApvMsg where (POApvMsg.Company = POHeader.Company) and (POApvMsg.PONum = POHeader.PONum) no-lock no-error.

if available POApvMsg then do:

case POApvMsg.MsgType:
when "1" then do:
find PurAgent where (PurAgent.Company = POHeader.Company) and (PurAgent.BuyerId = POApvMsg.MsgTo) no-lock no-error.
ApproverName = PurAgent.Name.
ApproverEmail = PurAgent.EmailAddress.
ApproverCode = PurAgent.BuyerID.
find PurAgent where (PurAgent.Company = POHeader.Company) and (PurAgent.BuyerID = POApvMsg.MsgFrom) no-lock no-error.
RequestorName = PurAgent.Name.
RequestorEmail = PurAgent.EmailAddress.
RequestorCode = PurAgent.BuyerID.
end.
when "2" then do:
find PurAgent where (PurAgent.Company = POHeader.Company) and (PurAgent.BuyerId = POApvMsg.MsgTo) no-lock no-error.
RequestorName = PurAgent.Name.
RequestorEmail = PurAgent.EmailAddress.
RequestorCode = PurAgent.BuyerID.
find PurAgent where (PurAgent.Company = POHeader.Company) and (PurAgent.BuyerID = POApvMsg.MsgFrom) no-lock no-error.
ApproverName = PurAgent.Name.
ApproverEmail = PurAgent.EmailAddress.
ApproverCode = PurAgent.BuyerID.
end.
end case.


case ApprovalStatus:
when "A" then do:
StatusText = "Has Been Approved!".
ApprovalStatusDesc = "Approved".
Assign Email-To = RequestorEmail.
end.
when "R" then do:
StatusText = "Has Been Denied!".
ApprovalStatusDesc = "Rejected".
Assign Email-To = RequestorEmail.
end.
when "P" then do:
StatusText = "Requires Approval...".
ApprovalStatusDesc = "Pending Approval".
Assign Email-To = ApproverEmail.
Assign Email-CC = RequestorEmail.
end.
when "U" then do:
message "Not sending e-mail for ApprovalStatus = U".
Assign SendEmail = False.
end.
end case.

message "Email-To: " + Email-To + "~nEmail-CC: " + Email-CC.

/*
Assign Email-To = "bspolarich@...".
Assign Email-CC = "bspolarich@...".
*/

find Vendor where (Vendor.Company = POHeader.Company) and (Vendor.VendorNum = POHeader.VendorNum) no-lock no-error.
Assign Email-From = "vantage-alerts@...".
Assign Email-Subject = POHeader.Company + " Purchase Order Approval Status Notification".
Assign Email-Text = "Purchase Order " + string(POHeader.PONum) + " " + StatusText + "~r~n"
+ "----------~r~n"
+ "Company: " + POHeader.Company + "~r~n"
+ "Vendor: " + Vendor.Name + " (" + Vendor.VendorID + ")~r~n"
+ "PO Amount: " + TRIM(string(POAmount, "$>>>,>>>,>>9.99")) + "~r~n"
+ "Approval Status: " + ApprovalStatusDesc + "~r~n"
+ "Buyer: " + RequestorName + " (" + RequestorCode + ") <" + RequestorEmail + ">~r~n"
+ "PO Date: " + string(POHeader.OrderDate) + "~r~n"
+ "Approver: " + ApproverName + " (" + ApproverCode + ") <" + ApproverEmail + ">~r~n"
+ "Comments: ~r~n" + POHeader.CommentText + "~r~n".

if (POApvMsg.MsgText <> "") then do:
Assign Email-Text = Email-Text + "Approval Message Log: ~r~n" + POApvMsg.MsgText + "~r~n".
end.
message "Email-Text: ~n" + Email-Text.
end.
else do:
message "Not sending e-mail.~r~n".
Assign SendEmail = False.
return "Cancel Send".
end.
-----End API-POApprovalNotification.p-----