How to do it...

To create the number sequence definition class, follow these steps:

  1. First, we will need to add an element to the NumberSeqModule base enum; so, locate this enum, right-click on it, and choose Create extension.
  2. Rename the new base enum extension to NumberSeqModule.ConWHS.
  3. Open it in the designer and add a new element. Set the Name property to ConWHSVehicleManagement and the Label property to Vehicle management.
  4. Save and close the designer, and create a new class name: ConWHSNumberSeqModule.
  5. Change the declaration so that it extends NumberSeqApplicationModule and overrides the following methods so that they read as follows:
public NumberSeqModule numberSeqModule() 
{
return NumberSeqModule::ConWHSVehicleManagement;
}
/// <summary>
/// Appends the current class to the map that links
/// modules to number sequence data type generators.
/// </summary>
[SubscribesTo(classstr(NumberSeqGlobal),delegatestr(
NumberSeqGlobal,
buildModulesMapDelegate))]
static void buildModulesMapSubsciber(Map
numberSeqModuleNamesMap)
{
NumberSeqGlobal::addModuleToMap(
classnum(ConWHSNumberSeqModule),
numberSeqModuleNamesMap);
}
protected void loadModule()
{
}
Those migrating from Dynamics AX 2012 may remember the manual job that must be run to initialize the number sequence. This is now done automatically by subscribing to NumberSeqGlobal.buildModulesMapDelegate.
  1. To complete the loadModule method, we will define each number sequence from the EDT, and is done in blocks of code. The following code defines sequences for ConWHSVehicleId and ConWHSVehicleServiceId:
protected void loadModule() 
{
NumberSeqDatatype datatype;
datatype = NumberSeqDatatype::construct();

// Vehicle number
datatype.parmDatatypeId(
extendedtypenum(ConWHSVehicleId));
// Unique key for the identification of vehicles.
// The key is used when creating new vehicles
datatype.parmReferenceHelp(
literalstr("@ConWHS:ConWHS42"));
datatype.parmWizardIsContinuous(false);
datatype.parmWizardIsManual(NoYes::No);
datatype.parmWizardIsChangeDownAllowed(NoYes::No);
datatype.parmWizardIsChangeUpAllowed(NoYes::No);
datatype.parmWizardHighest(999999);
datatype.parmSortField(1);
datatype.addParameterType(
NumberSeqParameterType::DataArea,
true, false);
this.create(datatype);

// Vehicle service order
datatype.parmDatatypeId(
extendedtypenum(ConWHSVehicleServiceId));
// Unique key for the identification of service orders.
// The key is used when creating new services orders
datatype.parmReferenceHelp(
literalstr("@ConWHS:ConWHS43"));
datatype.parmWizardIsContinuous(false);
datatype.parmWizardIsManual(NoYes::No);
datatype.parmWizardIsChangeDownAllowed(NoYes::No);
datatype.parmWizardIsChangeUpAllowed(NoYes::No);
datatype.parmWizardHighest(999999);
datatype.parmSortField(2);
datatype.addParameterType(
NumberSeqParameterType::DataArea,
true, false);
this.create(datatype);
}

The next part is to update the parameters form, so that we can maintain the new sequence:

  1. We will now need to update the parameters form so that we can maintain them. We can save time here with some copying and pasting. Open the design for our ConWHSVehicleParameters form, and then the designer for the InventParameters form from the Application Explorer.
  2. In the form design for InventParameters, expand Data Sources.
  3. Right-click on the NumberSequenceReference data source, and choose Copy.
  4. Change tab to our ConWHSVehicleParameters form designer, right-click on the Data Sources node, and select Paste.
  5. We will need to refactor the code that was brought, but we will need to set up the number sequence handling code. Double-click on the classDeclaration node of the Methods node on the form.
  6. Just after the first brace, enter the following lines:
Boolean                     runExecuteDirect; 
NumberSeqReference numberSeqReference;
NumberSeqScope scope;
ConWHSNumberSeqAppModule numberSeqApplicationModule;
TmpIdRef tmpIdRef;
container numberSequenceModules;
  1. We will now need to create code to initialize the number sequence class, which is done by the following method:
private void numberSeqPreInit() 
{
runExecuteDirect = false;

numberSequenceModules =
[NumberSeqModule::ConWHSVehicleManagement];
numberSeqApplicationModule = new
ConWHSNumberSeqAppModule();
scope = NumberSeqScopeFactory::createDataAreaScope();
NumberSeqApplicationModule::createReferencesMulti(
numberSequenceModules, scope);
tmpIdRef.setTmpData(
NumberSequenceReference::configurationKeyTableMulti(
numberSequenceModules));
}
  1. We will require a second method that performs some further initialization, but requires that the data source be set up. This must, therefore, run after the super() call in the init method. Write the post init initialization code as follows:
private void numberSeqPostInit() 
{
boolean sameAsActive =
numberSeqApplicationModule.sameAsActive();

numberSequenceReference_ds.object(
fieldNum(NumberSequenceReference,
AllowSameAs)).visible(sameAsActive);
labelSameAs.visible(sameAsActive);
}
  1. The preceding two methods should be placed above and below the super() call in the init method, as demonstrated in the following piece of code:
public void init() 
{
ConWHSVehicleParameters::Find();
NumberSeqApplicationModule::loadAll();
this.numberSeqPreInit();
super();
this.numberSeqPostInit();
}
  1. When we copied the data source from InventParameters, it brought over the code as well. The Active method was overridden in InventParameters for a special case, and it is not required. Delete the Active method.
  2. Let's cheat again and copy the tab page from InventParameters. Select (or open) the form designer for InventParameters.
Normally, I prefer creating everything manually, but adding the number sequence elements to a form saves a lot of time and is relatively risk free from copy and paste errors or omissions.
  1. Right-click on the Tab control and choose Copy.
  2. Next, go back to our form's designer, right-click on the ParameterTab control and choose Paste.
  3. Expand the controls, NumberSeq and NumberSeqBody. Then, delete the ActionPane control.
  4. Within the NumberSeq tab page, expand the Header group control.
  5. Change the Text property of the StaticText10 control to Set up number sequences for vehicle management documents.
  1. For consistency, and to avoid potential naming conflicts, rename the following controls:

Original control name

Correct control name

Header

NumberSeqHeader

StaticText10

NumberSeqHeaderText

GridContainer

NumberSeqQuickFilter

Grid

NumberSeqGrid

  1. Finally, we don't need the tab page to be automatically declared as a global variable: select the NumberSeq tab page control and change the Auto Declaration property to No.
  2. Save and close all designers and code editors.
  3. Open the code editor for the ConWHSVehicleParameters table.
  4. Add a new method that will return the number sequence reference, as shown in the following method:
public static NumberSequenceReference  NumRefServiceId() 
{
return NumberSeqReference::
findReference(
extendedTypeNum(ConWHSVehicleServiceId));
}
It is convention to place a static method per sequence on the parameters table, and other developers will expect to find these helper functions there.
  1. Build the project and look out for compilation errors and correct as required.

The final stage is to integrate the form with the number sequence framework:

  1. Open the code editor for the ConWHSVehicleServiceTableType handler class.
  2. At the top of our class, declare a variable global of type NumberSeqFormHandler, as shown here:
NumberSeqFormHandler      numberSeqFormHandler; 
  1. Next, create a method to construct an instance, if it is not alreadyin stantiated, as per the following code:
protected NumberSeqFormHandler numberSeqFormHandler( 
FormRun _formRun, FormDataSource _serviceTableDS)
{
if (!numberSeqFormHandler)
{
RefRecId localNumSeqId;
RefFieldId serviceIdField;

localNumSeqId =
ConWHSVehicleParameters::
NumRefServiceId().NumberSequenceId;
serviceIdField =
fieldNum(ConWHSVehicleServiceTable,
ServiceId);

numberSeqFormHandler =
NumberSeqFormHandler::newForm(localNumSeqId,
_formRun,
_serviceTableDS,
serviceIdField);
}
return numberSeqFormHandler;
}
  1. Next, we will need to write the methods that control what happens when the various data source event methods are run. Write the methods as shown here:
public void formMethodClose() 
{
if (numberSeqFormHandler)
{
numberSeqFormHandler.formMethodClose();
}
}

public void formMethodDataSourceCreate(
FormRun _element,
FormDataSource _serviceTableDS)
{
this.numberSeqFormHandler(
_element,
_serviceTableDS).formMethodDataSourceCreate();
}

public void formMethodDataSourceDelete(
FormRun _element,
FormDataSource _serviceTableDS,
boolean _forced = false)
{
this.numberSeqFormHandler(
_element,
_serviceTableDS).formMethodDataSourceDelete(
_forced);
}

public void formMethodDataSourceLinkActive(
FormRun _element,
FormDataSource _serviceTableDS)
{
this.numberSeqFormHandler(
_element,
_serviceTableDS).formMethodDataSourceLinkActive();
}

public boolean formMethodDataSourceValidateWrite(
FormRun _element,
FormDataSource _serviceTableDS)
{
boolean ret = true;

if (!this.numberSeqFormHandler(
_element, _serviceTableDS).
formMethodDataSourceValidateWrite())
{
ret = false;
}

return ret;
}

public void formMethodDataSourceWrite(
FormRun _element,
FormDataSource _serviceTableDS)
{
this.numberSeqFormHandler(
_element,
_serviceTableDS).formMethodDataSourceWrite();
}
This code does seem a lot, but it is largely the same in most implementations and, with some refactoring, it can simply be copied. The SalesTableType class uses this pattern.
  1. The next task is to override certain methods on the ConWHSVehicleServiceTable table in order to call the methods we have just written.
When reading the following steps, it may seem quicker and easier to call ConWHSVehicleServiceTable.type().formMethodDataSourceWrite(). This would carry a significant performance overhead, as the handler would be constructed whenever a method was called.
  1. Create a global variable to the form by opening the classDeclaration node of the form and typing the following, just after the first opening brace:
ConWHSVehicleServiceTableType serviceTableType; 
  1. We now need to hook up the data source event methods to our handler class. The naming scheme for the number sequence methods tells us which to use on each data source event method. The first is formMethodClose, so we will need to override the Close method at form level. Do so, and enter the following code:
public void close() 
{
if (!serviceTableType)
{
serviceTableType =
ConWHSVehicleServiceTable.type();
}
serviceTableType.formMethodClose();
super();
}
  1. The rest override methods on the ConWHSVehicleServiceTable data source. To save time, override the following methods:
    • Create
    • Delete
    • LinkActive
    • ValidateWrite
    • Write
  2. These methods should be written as follows:
public void create(boolean _append = false) 
{
super(_append);
if (!serviceTableType)
{
serviceTableType =
ConWHSVehicleServiceTable.type();
}
serviceTableType.formMethodDataSourceCreate(
element, this);
}

public void delete()
{
if (!serviceTableType)
{
serviceTableType =
ConWHSVehicleServiceTable.type();
}
serviceTableType.formMethodDataSourceDelete(
element, this);

super();
}

public void linkActive()
{
if (!serviceTableType)
{
serviceTableType =
ConWHSVehicleServiceTable.type();
}
serviceTableType.formMethodDataSourceLinkActive(
element, this);
super();
}

public boolean validateWrite()
{
boolean ret;

ret = super();

if (!serviceTableType)
{
serviceTableType =
ConWHSVehicleServiceTable.type();
}
ret = ret &&
serviceTableType.formMethodDataSourceValidateWrite(
element, this);

return ret;
}

public void write()
{
if (!serviceTableType)
{
serviceTableType =
ConWHSVehicleServiceTable.type();
}
serviceTableType.formMethodDataSourceWrite(
element, this);
super();
}
  1. Save and close all designers, and build the package.
  2. Although we should test at each stage, this requires setting up a number sequence. The following steps are a rough guide, just so we can test the form's behavior.
  3. In the web client, open the Vehicle management workspace, and click on parameters.
This is to trigger the NumberSeqApplicationModule::loadAll() method.
  1. Once open, check that the two records appear in the grid in the Number sequences tab.
If they do not, we either missed adding the call to NumberSeqApplicationModule::loadAll() in our init method or the delegate subscription in our ConWHSNumberSeqModule class is incorrect.
  1. Navigate to Organizational administration | Number sequences | Number sequences.
  2. Click on New.
  3. Enter ConWHSServ in the Number sequent code field (the prefix helps group sequence together) and Vehicle service id as Name.
  4. Set Scope to Company, and enter the current company ID as Company.
  5. Configure the Segments grid as shown in the following screenshot:
  1. Change the value for Largest to 999999 in the General tab.
  2. The next part is the first test; expand References and click on Add.
  3. Select the module from the Area tab; in our case, Vehicle management, and then Service Id. Click on OK.
  4. Next, open Vehicle management workspace and create a new service order record to test that the various events work correctly.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.50.244