Add New Parameters to Business function


Reputable Poster
Is it a standard JDE function or a custom function? If it is a standard function then the first answer is it is generally to be avoided. If that is not an option (or the pain of changing the function is less than the alternative) then basically you need to find everywhere the data structure is used (generally one to one) and also everywhere the function is called and update. If the function is called from forms, NER's or UBE's then you need to open them in the designer and update. If it is called from other C BSFN's then you'll need to edit the source code directly to accommodate the new DS element. Also be aware new elements will always be appended to the DS, irrespective of what the designer shows.

Just remember that if you do add an element to a standard DS that your name will be used in vain everytime someone has to apply and ESU or perform an upgrade. Make sure you've got a well maintained change log if you're going to be making those sorts of mods in JDE.


Legendary Poster
I'll just tag on with what Russell said. If you do decide to add elements to a pristine BSFN DS try to make the new parameters optional or have default values so callers of the BSFN that don't implement your mods are not effected. Then all you really need to do is a full build to make sure all the C code gets recompiled with the new struct - namely BSFNs that call the modded BSFN.

Having said that I have never found a need to modify a pristine BSFN DS... and we are very heavily modified including many BSFNs. You can often find other ways to "pass" information to a BSFN without modifying the DS directly. If the BSFN you intend to modify makes use of jdeCache the easiest way is to add your own extension or tag cache. This is what we have done with things like the sales order MBF. For example we call AcmeF4211EditLine along with F4211FSEditLine and AcmeF4211EditLine will write to custom jdeCache the additional data that we want passed to F4211FSEditLine and then that custom jdeCache is read by B4200310/311.

Another way, (and this is a little bit of a hack but it works, and if done correctly is safe and doesn't effect callers that DONT implement the mods), is to store your custom parameters in memory (jdeCache or just plain old jdeAlloc) and then pass a handle to the memory location through an existing BSFN DS member in such a way that flags the BSFN that there is custom params to be picked up. I do this by picking a numeric DS member that is allways a positive value and then pass the handle to the memory location as a negative number. The negative number is the indication to the BSFN that the caller is passing custom params. The handle is used by the modded BSFN to pick up the values out of memory, including the originally intended value for the parameter that the handle was passed in.

Say you have the following pristine DS:
JCHAR                 szCompany[11];
MATH_NUMERIC    mnOrderNumber;
JCHAR                 szOrderType[3];

And you want to pass URAB (mnUserDefinedNumber) for order 01000-12345-SO to the modified BSFN.

Calling BSFN stores the following in memory:
mnOrderNumber = 12345
mnUserDefinedNumber = 88899

Uses jdeStoreDataPtr to get a handle to the memory location which returns a value of 1.

This is what is passed to the modified BSFN
szCompany = "01000"
mnOrderNumber = -1
szOrderType= "SO"

The pseudo code in the modified BSFN looks like this:
if(mnOrderNumber < 0)
   ID handle = mnOrderNumber * -1;
   myCustParams = jdeRemoveDataPtr(hUser, handle)
   MathCopy(&lpDS->mnOrderNumber, &myCustParams.mnOrderNumber); //restore the originally intended order number back in the lpDS parameter
   //you now have access to the value stored in myCustParams.mnUserDefinedNumber 
//If mnOrderNumber  is >= 0 then it just means an actual order number was passed and the caller didn't implement the mods.
   jdeFree(myCustParams);  //or destroy jdeCache, or what ever free action is appropriate

I usually build a BSFN to set the custom params for the caller so that the ugliness of the implementation is hidden. So from the caller perspective all they do is this:

  -> mnOrderNumber = 12345
  -> mnUserDefineNumber = 88899
  <- mnOrderNumberHandle = -1

   -> szCompany = "01000"
   -> mnOrderNumber = mnOrderNumberHandle 
   -> szOrderType = "SO"

And then in ModifiedFunction
if(mnOrderNumber < 0)
     <> lpDS->mnOrderNumber;  // passes -1, gets set to 12345
     <- mnUserReservedNumber;

I also use this technique so I can pass custom Form/Report Interconnects. Keeps the public interface pristine and easier to retrofit during ESU/upgrades but still allows for callers to optionally invoke custom functionality.