Running Multi Company Direct Server process Via Function

Hello All,

I’m trying to trigger the Multi Company Direct Server process from a function and not having any luck, my code is a bastardisation of code I’ve found on here TriggerMCD Just FYI I’m NOT great at coding.

//var context = Ice.Services.ContextFactory.CreateContext<ErpContext>();
var context = Ice.Services.ContextFactory.CreateContext();



using(var MultiCompanyDirect = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.MultiCompanyDirectSvcContract>(context))
{
var MDS = MultiCompanyDirect.GetNewParameters();
var paramRow = MDS.MultiCompanyDirectParam[0];


paramRow.LogFilename="MultiCompanyDirect.log";
paramRow.ProcessingDelay=1;
paramRow.TransferMethod="DIRECT";
paramRow.ProcessingBranch="MT";
paramRow.AgentID="SystemTaskAgent";
paramRow.WorkstationID="BPM";
paramRow.Continuous=false;


}

//System.Threading.Thread.Sleep(50000);

I’m not getting a compliing error with this but its not working, I’ve tried using Db instead of using context but i get an "Argument 1: cannot convert from ‘EFx.AddParts.Implementation.ILibraryContext’ to ‘Ice.IceDataContext’
" Error, I’m unsure where to go from here any help would be appreciated.

Just more context if you need this function is triggering when a part is marked as global in the parent company and parts are created throughout the other companies and in all warehouse this code will run Multi Company before linking all the parts in the GlbPart table I have the code that creates these I’m just struggling with the server process.

Thanks in advance!

Just curious, I’m used to seeing the MC Direct Server process running continuously. Why the Function?

1 Like

I’m with Mark. What’s going on?

As for your code, it’s incomplete. (And using an unnecessary and wrong context)


CallService<Erp.Contracts.MultiCompanyDirectSvcContract>(MultiCompanyDirect =>
{
    var MDS = MultiCompanyDirect.GetNewParameters();
    var paramRow = MDS.MultiCompanyDirectParam[0];


    paramRow.LogFilename="MultiCompanyDirect.log";
    paramRow.ProcessingDelay=1;
    paramRow.TransferMethod="DIRECT";
    paramRow.ProcessingBranch="MT";
    paramRow.AgentID="SystemTaskAgent";
    paramRow.WorkstationID="BPM";
    paramRow.Continuous=false;

    //You need something here to actually launch it.
    MultiCompanyDirect.DoSomething(MDS, someStuff);
});

//Not a good idea ->
//System.Threading.Thread.Sleep(50000);

Answer Mark’s question, and then post a trace if the answer makes sense.

1 Like

Ditto,
MC Direct (we have 8 companies) should run on a schedule we run it every 5 minutes on a simple task schedule. Works well and if it fails it is never more than 5 minutes before it tries gain.

We don’t use the continuous run because we’ve had it fail silently before, but the reoccurring 5 minute interval schedule has worked wonders for us for years.

2 Likes

I think our attitude toward running it continuously or on a more regular schedule was it would effect user performance especially with unnecessary processes running in the background.
If this isn’t the case we would be happy to run it more regularly as its currently running every hour at the minute.

Got some code to launch it or do we need to work something up real quick?

Nah it just uses the System Task Agent with a 5 minute interval schedule @klincecum

No this is not the case the footprint of the MCD is negligible.

Yes I assumed. I meant how to properly call it. His code is incomplete and I’m unfamiliar with this BO.

No though it wouldn’t be hard, however I don’t see the need based on what he said it seems is just overly cautious approach.

2 Likes

Yeah I thought you just might have it handy.

Excellent! We tend to lean on the side of caution when implementing processes that would run that often (effecting user performance is always a concern). Thank you we will change the schedule to be more regular.

When creating these global parts do I need to trigger the MCDS some how before adding them to the GblPart table?

I agree with the comments and @josecgomez - and can add that our experience with 12 companies participating in the MCD process, that the overhead/effect is unnoticeable.

We run it on an interval as well, but in v11 it runs well as continuous. We had it fail silently as well and we have some trouble with some items getting into IntQue tables (that I still have to track down) so we’re sticking with interval schedule until then.

Can confirm not a good idea

//Not a good idea ->
//System.Threading.Thread.Sleep(50000);
1 Like

Still struggling with overall problem (I’ll expand, unless you think I should create another post) I’m creating a function that when a part is marked a global in the parent company it creates the part in all companies and adds the part to the companies warehouses ( I have done this and all works well), the next step is to link the part, this was where I wanted to trigger MCDP and then add the parts to the global table but I have changed my approach i was going to create a data directive when MCDP is Complete it invokes a function that creates the links the part but now I’m unsure this is the correct way to achieve this.

Any guidance will be helpful, Thanks in advance.

1 Like

Honestly, I’m not sure the MCD process runs for linking Global Parts. It does run differently for other items like the GL Chart and Currency Exchange rates than it does for inter-company POs & SOs. But the concept is generally the same in so much as it has to run TWICE. Once for the sending company and once for the receiving company, but the initial linking isn’t part of MCD, only the changes afterwards (like description, cost method, etc.).

I’m thinking there is a BO.Method for linking that you should be able to call in the function to get it linked up and then MCD handles changes going forward.

I say that because when you want to link parts, you go into “Link Global Part” screen which works for any part as long as you’re in Part Maint. It shows already linked and available to link (and create if needed). And this happens outside of MCD processing. You might want to back up a step and investigate that process with a client trace.

(There is a chance I might be incorrect)

2 Likes

I’m triggering it in a function using the Invoke BO Method caller for Erp.MultiCompanyDirect.SubmitToAgent rather than using C# code, and it seems to be working fine, but I’m still using it in test only. We have 4 companies involved, and as was mentioned by others, it needs to run in all the participating companies. But using the “TenantMode” = true flag in the parameter set, the system handles that and you only need to run in one company.

(The ExtCompanyList was an attempt to exclude one company, but since I ended up using TenantMode, that list gets ignored.)

Sorry if this is considered hijacking the thread, but the issue I’m running into is that I’m trying to create global customers in all companies after they are created in the parent company. I need to know that the Multi Company Direct process has finished before I can proceed with the linking. (As Josh confirmed, the Sleep is not a good idea.) The SubmitToAgent method returns to the code once submitted, so doing the linking won’t work at that point. The documentation for the API for Erp.PROC.MultiCompanyDirectSvc has a RunDirect method, but when I call it I get an “Object reference not set to an instance of an object” error no matter what I have tried in the parameter set. Epicor Support has informed me that the RunDirect is not actually an option for this, and they have made a note to the development team to remove it from the documentation.

Do I take support at their word that RunDirect will not work, or are there any tips on getting it to work? I have seen other threads that talk about adding something like a comment to the task and checking if it is still active, but I was hoping the RunDirect would just work like it says it does.

1 Like

Do you mean separate Customer records, or globally LINKED records?

Separate records would require the MCD process to be run multiple times (Tennent mode switch now makes this much better) and you might be able to add a short delay in your function or SubmitToAgent at two differnet scheudle times about XX minutes apart to accomplish this.

Records linked back to the parent do not require MCD to work - well, maybe you have to run it once, but not multiple times. The linking is a totally different thing, and it creates the child company customer record as part of the process if you want it to. I suppose you could run MCD multiple times and then figure out how to link them in another function fired by a Data Directive on the Customer record creation… ?? … I’ve never done either programmatically, but I’m sure we can find it somewhere.

Thank you for your reply.

It would create globally linked records. The linking process would occur in the child company where the customer record doesn’t yet exist. The process flow is as follows:

  1. The sales rep creates a new customer in the parent company.
  2. Upon saving the record with the global flag selected: a. The MCD runs, creating records in the GlbCustomer table for all child companies. b. The code then executes the LinkGlbCustomer method to link the customer in each child company.
  3. Appropriate checks are performed where required, similar to those in the manual process.

Currently:

  • I can call the MCD with SubmitToAgent.
  • I can link a new customer in each child company when the record exists in the GlbCustomer table (i.e., create new and link).

The challenge: I haven’t been able to run both processes in the same function because I can’t verify when the MCD process has completed. As a result, the GlbCustomer record may not exist in some or all child companies when the LinkGlbCustomer method is called. While the ‘Sleep’ option has been suggested in various places, it seems like a bad idea.

I have considered displaying a message telling the user to wait 30 seconds before hitting OK, but I would also like to call this function from other sources using API, and I haven’t tested how the API handles message boxes in functions.

Are there alternative methods to either:

  1. Confirm the MCD process has completed before proceeding, or
  2. Implement a more reliable way to wait for MCD to finish before proceeding?

For background, we do run the MCD on a 5 minute schedule, but for the sales rep, that is an eternity. We also want to remove the manual process of linking customers in each of the child companies. This workflow would make new customers available in child companies almost immediately.

Would running MCD in continuous mode solve this problem? I think I would still have the issue of needing to wait until the GlbCustomer records are actually available.

Ok - understood that explanation better than before - apologies for that.

Given all of that - and the limitation you’ve encountered - my suggestion would still be to focus on one of two options:

  • In the initial function, schedule the LinkGlbCustomer method in its own function wrapper for a fixed period of time after the MCD call.
  • Do a Method/Data directive on the GlbCustomer table watching for a record creation, which then calls a function to LinkGlbCustomer. (I’m not sure you can use the GLB tables actually)

Actually - there is a third way - write your DataDirective on the Sysagent tables - whichever one shows the completion of a task - and use that as a trigger for your LinkGlbCustomer.