UD GetByID across multiple companies

We have several Companies set up in our E10 DB. I’m developing a custom form that is to be used by multiple Companies. I’ve got no problem putting the data into the UD table I’m using, no problem updating it when my current company matches the company that entered the data. But how do I edit data that has been entered in one company, while working within a different company? This one has me stumped.

The following code works within the same company, but it won’t find data entered by Company2 while I’m working in Company1:

UD30Adapter adUD30 = new UD30Adapter(UD30Form);
adUD30.BOConnect();

UD30DataSet dsUD30 =(UD30DataSet)adUD30.GetCurrentDataSet(DataSetMode.RowsDataSet);

bool bFound = adUD30.GetByID(sID, sJobNum, sJobLine, string.Empty, string.Empty);

I can see that my data exists in SQL Server but can’t work out how to make it accessible cross-company in my customization. Any pointers?

Thanks in advance.

The adapter is probably being instantiated with the context of the user who is running the form including the company specific data that the adapter returns.
I might suggest utilizing a cross company BAQ to drive your data retrieval instead of an adapter

2 Likes

Hi Aaron,

Thanks for the reply. I’ve had time to play around with the idea of using a BAQ instead of adapters. While I have no problem retrieving the data with a BAQ like this, how can I then modify this data and use it to update my UD table? I’ve tried casting it as a UDXXDataset and feeding back in via the adapter but I can’t cast as an Ice.BO.UDXXDataset. I’ve also tried using a select statement using a System.Data.SQLClient but I get the same result - I get the data but can’t cast it to anything I can use with an adapter.update. Would it be possible to use an updateable BAQ in this manner? If so, does anyone have an example of doing this in C#? Thanks for the help!

A few things to know. If you use Adapter, BO or UBAQ it will only be limited to the companies the User has access to.

You have a few options.

  1. You can do it via BPM (UD Table)
  2. UBAQ (Manual Code)
  3. UBAQ w/ BAQDataView (search the forums there are many BAQDataView examples)
  4. BO / Adapter using a Service Account to Impersonate New Session.
  5. Service Connect (kind of meant for cross-company updates)
  6. REST

Search the forums for BAQDataView, sounds a bit like that would be your canidate, because you can Bind it to a Grid if I recall.

Thanks for your replies and sorry about the delay in responding. It’s taken me a little while to get the opportunity to test this out. @hkeric.wci I’ve gone down the path of your option 2 as I don’t need to feed this back to a grid (though I’ll definitely keep that idea in mind for another couple of projects I can foresee after this one.)

So I’ve set up my UBAQ but I’m having a bit of trouble with the Update. After doing a bit of research on this idea I’ve set up my UBAQ with “Advanced BPM Update Only” and set the Base Processing of my UD30.Update method. I’m having a bit of trouble with my BPM though, hoping someone might point me in the right direction.

Here’s what I’ve got (this is in an “Execute Custom Code” caller) :

using (Ice.Contracts.UD30SvcContract UD30Svc = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.UD30SvcContract>(Db))
{
var sKey1 = (string)ttResults[0][“Key1”];
var sKey2 = (string)ttResults[0][“Key2”];
var sKey3 = (string)ttResults[0][“Key3”];
var sKey4 = (string)ttResults[0][“Key4”];
var sKey5 = (string)ttResults[0][“Key5”];
var sProdRange = (string)ttResults[0][“Character02”];

Ice.Tablesets.UD30Tableset UD30TS = new Ice.Tablesets.UD30Tableset();

UD30Svc.GetByID(sKey1,sKey2,sKey3,sKey4,sKey5);
UD30TS.UD30[0]["Character02"] = sProdRange;

UD30Svc.Update(ref UD30TS);

}

The above fails with the error that the UD30Svc.GetByID requires a @Key1 parameter which has not been passed in. How was I supposed to pass these parameters in as opposed to what I’ve done?

Thanks in advance once again!

Ok, I feel like I’m going round in circles with this. I’m sure my problem is something small, I just can’t put a finger on it. Any help appreciated!

Here’s what I have so far. I have a BPM that fires on SalesOrder.MasterUpdate to populate our UD30 table with some data. This is being used from two of our companies. This works fine, I can see all the correct data is being entered when I look at the db with a BAQ or through SQL Server. No problem.

The data for each company needs to be updated by either company. Following the above advice I’ve set up a UBAQ that returns a single row from UD30:
image

The update for this UBAQ is Advanced BPM Update Only. My BPM looks like this:

(The Show Messages are only there for debugging and will be removed).
Each of the Set Vars takes a value from queryResultDatasetRow and stores as a variable.
image

If I link to the Show Message 7 node in my BPM I can see that I get all data that I need from either company. So far so good. When I link to the custom code, then things start to break. Custom Code is:

Ice.Contracts.UD30SvcContract UD30svc = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.UD30SvcContract>(Db);

UD30Tableset ds = UD30svc.GetByID(sKey1,sKey2,sKey3,sKey4,sKey5);    

ds.UD30[0].Character02 = sProdGroup;
ds.UD30[0].RowMod = IceRow.ROWSTATE_UPDATED;
UD30svc.Update(ref ds);

That all works fine when the data comes from the same company as my current session, but when I try to update cross-company data I get an error stating the row could not be found. I would assume the ServiceRenderer.GetService defaults to the current company only?

How can I change the above so it will update across companies? Please help while I still have hair!

Still scratching my head on this one - can anyone tell me is what I’m trying to do possible?
@josecgomez?
@Aaron_Moreng?
@hkeric.wci?

i’d like to help but I don’t have a multi-company environment to play with. But to clarify for my understanding, you’re not talking about simply finding data cross company and displaying it. You’re wanting to find, modify, and save that data back to it’s source company, correct?

I’d have to dig a little deeper to see how a cross company uBAQ is actually performing the update in the other company. But a row not found issue tells me that the record you are trying to find with the UD30 service doesn’t exist with the key configurations you’re passing. Are you definitely sure that the record exists in that company with those 5 keys?

Your best bet is to just change the company you are in in code during your process.
Gist of it is,
Get your Data
Check if the company you are in matches the one you need to get
If it doesn’t
Modify the company in your Session
Instanciate the Adapter
Make the Changes
Put the Company back in the session and repeat

There are ways to do this on the server side too via creating a Temporary company Session like this
This would run on a BAQ or a UBAQ

using (CallContext.Current.TemporarySessionCreator.SetCompanyID(childCompanyID).Create())
{
}
1 Like

That did the trick. Works like a charm! Thanks @josecgomez.

And thanks @Aaron_Moreng and @hkeric.wci for the time you spent helping me too.

1 Like

Glad it worked!

One thing to note, whomever is running this code needs to have permissions on all those companies or this won’t work either.
So be mindful of that, it works for you, but if your users don’t have cross company access this will not work for them

I’ll keep that in mind. Thanks again for your help on this one.