I’ve noticed a lot of questions in discussion forums about how to add year to a number sequence in AX2012, e.g. to generate IDs such as 2013-xxxxx and 2014-xxxxx, that would automatically use the current year. Some people understand that number sequence scopes should allow that, but they don’t know how.
Fortunately it’s not only possible but it’s also quite simple. Rather then describing it theoretically or repeating the documentation, let’s walk through a simple end-to-end example.
First of all, we need a new data type that will be associated with the number sequence. Create a new string data type, name it DocuRevisionId, set its Label to Revision ID and StringSize to 20. The type represents a hypothetical document revision ID.
Then we need to register the type with an application module – it’ll be document management in our case. Open loadModule() method of NumberSeqModuleDocument class and add the following code at the end (I intentionally omitted everything that’s not necessary for our example):
datatype.parmDatatypeId(extendedTypeNum(DocuRevisionId)); datatype.addParameterType(NumberSeqParameterType::DataArea, true, false); datatype.addParameterType(NumberSeqParameterType::FiscalCalendarPeriod, true, false); this.create(datatype);
Here we’re creating a new number sequence definition for DocuRevisionId data type. We’re also defining two scope parameter types: company and fiscal calendar period. It’s very important to declare supported scope parameters – you can’t use number sequence scopes without them.
The definition has no effect unless the module is loaded. You can manage that by running the following code in a job:
When it’s done, you can go to Organization administration > Common > Number sequences > Segment configuration and verify that our new type is there and it has both expected segments.
Before configuring number sequences, let’s create fiscal periods that will be used in number sequence scopes. We’ll create periods covering whole years, but you could use anything what makes sense for you.
Open General ledger > Setup > Fiscal calendars and create a new calendar – I’ll call it MyYear. It should cover the whole year:
We’ll need two years for our example, therefore press the New accounting year button and create one more year (for 2014) :
Display generated periods and set a short name for the operating period. The short name will be used automatically in number sequences, if provided. You can also rename the period in this form.
Now we’ll create two number sequences – for years 2013 and 2014. They don’t have to have the same number sequence code, but they can, because the unique identifier is not the code alone, but in conjunction with a scope. We’ll use the same code because it will be needed for one additional scenario.
Go to Organization administration > Common > Number sequences > Number sequences and create a new sequence. Set fields as follows:
|Number sequence code||Revision|
|Scope||Company and Fiscal calendar period|
When you choose a scope, you get additional fields – the sequence will be used only for values that you specify there. Pick your company and the operating period for year 2013 in our new calendar.
By default, the sequence includes segments for all scope parameters, therefore the format is something like DAT2013-######. Because we don’t need the company there, delete the Company segment. The value of Fiscal calendar period segment has been initialized from sequence’s short name and you can change it if needed.
We also need (at least in the typical case) to associate the sequence with a data type. Add a new item on the Reference fast tab, choose Document management area and you’ll get just a single option for Reference: Revision ID. That’s because Revision ID the only type in the selected module that supports Company and Fiscal calendar period.
Now do the same thing once more, just use 2014 instead of 2013.
Everything is ready by now, we just need to have some code that will find the right number sequence and obtain a generated number.
Look at the following implementation. First of all, we find the fiscal period for a given date. Then we use it (together with the current company) to create a scope object. Finally, we find the number sequence for the given data type and scope and get a new number as usual.
date effectiveDate = mkDate(25,05,2013); RefRecId calendarRecId = FiscalCalendar::findByCalendarId("MyYear").RecId; RefRecId periodRecId = FiscalCalendars::findPeriodByPeriodCodeDate(calendarRecId, effectiveDate).RecId; NumberSeqScope scope = NumberSeqScopeFactory::createDataAreaFiscalCalendarPeriodScope( curext(), periodRecId); NumberSequenceReference seqRef = NumberSeqReference::findReference(extendedTypeNum(DocuRevisionId), scope); NumberSeq::newGetNum(seqRef).num();
You should get a number like 2013-000001. If you change the year to 2014, you’ll get 2014-000001, exactly as intended. If you change the year to 2015, you’ll get an error, because no such sequence exists.
There is one more approach – it’s not normally recommended, but it’s good to know about it. We could have omitted the reference to a data type and refer to number sequences just by a common sequence code. These sequences have the same code, but they differ in scope:
This source code is similar to the previous one; we just find a number sequence by its code:
date effectiveDate = mkDate(25,05,2013); RefRecId calendarRecId = FiscalCalendar::findByCalendarId("MyYear").RecId; RefRecId periodRecId = FiscalCalendars::findPeriodByPeriodCodeDate(calendarRecId, effectiveDate).RecId; NumberSeqScope scope = NumberSeqScopeFactory::createDataAreaFiscalCalendarPeriodScope( curext(), periodRecId); info(NumberSeq::newGetNumFromCode("Revision", scope).num());
Number sequence scopes extends abilities of number sequences in quite a straightforward way. Nevertheless if people don’t understand them properly, they often have wrong expectations. For example, they want to use Fiscal calendar period segment for a data type that doesn’t support such a scope parameter. Because the parameter is not supported, there is no code that would provide a specific value for it (for example, AX doesn’t know which date and which calendar to use).
My intention was to show all components in a single place – I hope it will help people to understand how these parts fit together.