Method Directive to Data Directive for Quote Closing

,

Goal: Close any quote that is expired.

Success so far: Used DMT to close all old quotes by updating the Task List to LOSE. Closed 6500 quotes in a few minutes.

Still to Do: Add a BPM that closes quotes when they become Expired. Expiration Process runs every day at 2:00 am, but it does not close quotes. I have an existing Standard Data Directive on AlertQue that triggers on Quote Expirations and sends emails to SalesReps.

I created a widget based Method Directive that can be manually triggered on the Quote Form to call the Task.UpdateExt and successfully close the quote. But, I need to make that happen automatically when quotes expire.

Data Directives do not have Fill-Table-By-Query or Invoke-BO-Method widgets, so I can’t just copy my working Method Directive to Data Directive.

I started to reverse engineer the widget source code that I find on the server for my BPM, but that is slightly beyond my current programming capabilities.

Is custom code in a Data Directive on the AlertQue table the right approach, or is there some other way to get these quotes to automatically close when the Expiration process marks them Expired?

10.2.200.20 (no functions yet).

1 Like

At your version, you have a couple of options, none of them are amazing, but I would offer that you make an In-Transaction Data Directive on the SysTask table. When the Quote Expiration process has an End Date, then your BPM would loop through all Expired Quotes that are still open and use BO Methods to close them.

2 Likes

BO Methods in Data Directive always means custom code, not widgets, right?

Unfortunately, yes. If you were on a newer version I would suggest functions.

1 Like

I’m struggling with converting a widget based method directive to a code based data directive to close a Quote. I want to use GetByID to fill a Task tableset, then change the Task fields in that tableset to complete the Task, then pass that tableset to UpdateExt to complete the task and close the quote.

Problem is that GetByID returns a TaskTableset, and UpdateExt requires a UpdExtTaskTableset. Is there another approach I should be using?

Code so far:

var MyTaskTS = new Erp.Tablesets.UpdExtTaskTableset();
bool ErrorOccurred;

Erp.Contracts.TaskSvcContract hTask =null; 
hTask = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.TaskSvcContract>(Db);

var ttQuoteHed_xRow = (from ttQuoteHed_Row in ttQuoteHed 
                       select ttQuoteHed_Row).FirstOrDefault();
                       
MyTaskTS = hTask.GetByID("QuoteHed",ttQuoteHed_xRow.QuoteNum.ToString(),"" ,"", 10);

//ToDo: set Conclusion = LOSE, ReasonCode = EXP, Complete = true, CompleteDate = today()  

hTask.UpdateExt(ref MyTaskTS, true, true, out ErrorOccurred);

GetByID and UpdateExt are mutually exclusive. Try just using Update instead.

1 Like

Well, I tried and tried to get a Data Directive to work like the widget based Method Directive, but never got it. I tried various versions of UpdateExt trying to piece together the appropriate dataset and that didn’t work for me. At your suggestion, I also tried to use GetByID and Update on the ‘regular’ dataset, and programmed each method and paramter I saw in the trace of setting the Task to LOSE, and that didn’t work for me either. It was nearly there, the Task got marked Complete, and Lost, the Quote even got marked Closed, but the big red “LOST” text box that normally shows up on the Summary tab didn’t show up. So, I must have been leaving something out that UpdateExt knows about.

I ended up using DMT to accomplish my goal. I used the command line processing capabilities of DMT in a PowerShell script. It runs DMT first to extract a list of Quotes in a BAQ, that are then formatted into a CSV file formatted for DMT. then another call to DMT processes that file that completes and losses the Task for each quote.

So far so good. But, I found 1 out of 10 quotes that have their Tasks completed, don’t get the quote closed. For those quotes I ended up running DMT another time to force the quote closed by updating Quote Header.

Now I have the PowerShell script running in Windows Task Scheduler every day at 2:15 am (after the Epicor Quote Expiration process runs at 2:00 am). All is good.

ProcessCloseR1.txt (5.0 KB)

Here’s my PowerShell script. The BAQ is simple - all Quotes with Expired=true and QuoteClosed=false.

1 Like

Jason-- I know this is an old post but I am attempting to currently implement a solution along this line of thinking.

The problem I am having is that my directive does not seem to trigger based on the following conditions in the SysTask table:

ttSysTask.TaskDescription field of the Changed Row is equal to “Quote Expiration”
and ttSysTask.TaskStatus field of the Changed Row is equal to “COMPLETE”

I have tried using “added row”, “updated row”, and “changed row”-- none seem to trigger under these conditions. Am I missing anything you can think of?

I would verify the two text values are exactly correct. Also, check that each condition works individually.

1 Like

Thank you so much for the quick response. I have verified the text values, and I am attempting to test by using the “Show Message” widget as the only execution after the conditions. I have not yet been able to get a message to pop up no matter the conditions. I am wondering if the SysTask table works with data directives the way the erp tables do.

I don’t think I was able to get a message, but that could be wrong. I updated the TaskNotes field and appended some text to see if it worked.

1 Like

Awesome idea, I’ll give that a shot as well. Thanks again.

EDIT: That worked. I am getting the TaskNote based on my conditions… So my issue must be in my custom code. Oh Joy!!! Thanks Jason.

I’ve created something for this need here if you are interested. Validate before blindly implementing but it has been working well for us so far.

1 Like

Chance, thank you for the response and for your help. Are you using this updatable BAQ within a BPM basically?

Yeah that’s the gist. I scheduled a BAQ export for the companies I want it to run in.

1 Like

Chance,

May I ask why you are scheduling an Export? What exactly are you accomplishing with this customization?

A little backstory on my situation:
I am attempting to scan all expired quotes that are not LOST (ReasonType = ‘’) and lose them. I was able to accomplish this with a data directive on the QuoteHed table and it worked when I expired the quotes one by one with the DMT tool, and my eventual plan was to schedule the Quote Expiration Process for a nightly run. However, the Quote Expiration Process seems to bypass the data directives for some reason and it does not trigger the code to run.

So now I am working on a data directive in the SysTask table with conditions checking for the Quote Expiration process complete, which triggers based on the conditions well. But, in my code I am grabbing all QuoteHed records where Expired == true and ReasonType == “”, but my code to LOSE the active task on the quote one by one (with a foreach loop) no longer works.

I am curious how/why you are closing or losing quotes by exporting a BAQ on a schedule.

Essentially I am replacing the Epicor out of the box quote expiration process. AND on top of that losing the actually quotes that are marked expired. In the current version of Epicor we are on we could have used a scheduled function to do this same thing, but a BAQ BPM was the fastest way for me to deploy. The “Export” of the BAQ essentially fires the GetList method of the UBAQ. This is the method where all my code to accomplish the above tasks lie.

1 Like

Chance, thank you SO much for explaining the process in detail for me.

1 Like