Better Default Number Sequences

Update 22/02/2017: in Dynamics 365 for Operations jobs are a thing of the past. See Mass changes to Number Sequences in Dynamics 365 for Operations for an alternative.

AX 2012 Wizard creates number sequences which contain the company and a dash e.g. “USMF-######”. This adds 5 characters to every number sequence, which is not always desirable.

The following job removes the company and/or the dash from all number sequences and improves the naming of the number sequences.
Use the constants to parameterize the script according to your requirements. If both REMOVECOMPANY and REMOVEDASH are false, then the script still fulfils the purpose of improving the naming of the number sequences.

 

static void numberSequenceTable_Format(Args _args)
{
    #define.REMOVECOMPANY(true) //parameter implemented as constant --> adjust accordingly
    #define.REMOVEDASH(true)    //parameter implemented as constant --> adjust accordingly
    str                     annotatedFormat;
    str                     format;
    container               segments;
    NumberSequenceTable     numberSequenceTable,numberSequenceTableSelect;
    NumberSequenceReference numberSequenceReference, firstReference, numberSequenceReferenceExists;
    NumberSequenceDatatype  numberSequenceDatatype;
    NumberSequenceScope     numberSequenceScope;
    boolean                 companyFound;
    int                     i, j;
    str                     company;
    str                     referencesStr;
    int                     starttime = timeNow();
    int                     pos;
    ;
    setPrefix("numberSequenceTable_Format");
    if(!(infolog.language() like "en*"))
    {
        if(Box::okCancel("It is recommended to use an English login. Continue?",DialogButton::Cancel,"Login language")!=DialogButton::Ok)
        {
            throw error("It is recommended to use an English login.");
        }
    }
    while select RecId from numberSequenceTableSelect
        exists join numberSequenceReferenceExists where numberSequenceReferenceExists.NumberSequenceId == numberSequenceTableSelect.RecId   //avoid renaming of independent sequences (e.g. Serial numbers)
    {
        ttsBegin;
        numberSequenceTable = NumberSequenceTable::find(numberSequenceTableSelect.RecId,true);
        setPrefix(numberSequenceTable.NumberSequence);
        referencesStr = "";
        firstReference.clear();
         
        //0) get reference description (preparation needed for rename and description)
        while select numberSequenceReference where NumberSequenceReference.NumberSequenceId == numberSequenceTable.RecId
        {
            referencesStr += referencesStr?", " : "" + numberSequenceReference.referenceLabel();
            if(!firstReference)
            {
                firstReference = NumberSequenceReference::find(numberSequenceReference.RecId);
            }
        }
        if(!referencesStr)
        {
            referencesStr = numberSequenceTable.Txt;
        }
        
        //1) rename if numbering does not match convention (or language)
        if(firstReference)
        {
            numberSequenceDatatype = numberSequenceDatatype::find(firstReference.NumberSequenceDatatype);
            if(!(numberSequenceTable.NumberSequence like (NumberSequenceTable::autoId(numberSequenceDatatype) + '*')))
            {
                pos=1;
                while(strFind(numberSequenceTable.NumberSequence,'_',pos,999)>1)
                {
                    pos = strFind(numberSequenceTable.NumberSequence,'_',pos,999)+1; //find position of last '_' in ID
                }
                numberSequenceTable.NumberSequence = NumberSequenceTable::autoId(numberSequenceDatatype) + subStr(numberSequenceTable.NumberSequence,pos,999); //new id with old index
                if(NumberSequenceTable::existByNaturalKey(numberSequenceTable.NumberSequence, numberSequenceTable.NumberSequenceScope) || numberSequenceTable.NumberSequence like "*_")
                {
                    numberSequenceTable.NumberSequence = NumberSequenceTable::findNextAutoId(numberSequenceDatatype.DatatypeId);
                }
                if(numberSequenceTable.NumberSequence != numberSequenceTable.orig().NumberSequence)
                {
                    numberSequenceTable.update();
                    j++;
                }
            }
        }
        
        //2) remove segments
        companyFound = false;
        company = "";
        segments = NumberSeq::parseAnnotatedFormat(numberSequenceTable.AnnotatedFormat);
        for(i=1;i<=conLen(segments);i++)
        {
            if(conPeek(conPeek(segments,i),1) == 0)
            {
                company = conPeek(conPeek(segments,i),2);
                if(#REMOVECOMPANY)
                {
                    segments = conDel(segments,i,1); //remove company from number sequence
                    i--;
                }
                companyFound = true;
            }
            else if(companyFound && conPeek(conPeek(segments,i),1) == -1 && conPeek(conPeek(segments,i),2) == "-")
            {
                if(#REMOVEDASH)
                {
                    segments = conDel(segments,i,1); //remove "-" after company from number sequence
                    i--;
                }
                break;
            }
        }
        if(companyFound) //remove company id from segments
        {
            annotatedFormat = NumberSeq::createAnnotatedFormatFromSegments(segments);
            format = NumberSeq::createAnnotatedFormatFromSegments(segments, false);
            numberSequenceTable.AnnotatedFormat = annotatedFormat;
            numberSequenceTable.Format = format;
            numberSequenceTable.update();
            j++;
        }
        
        //3) adjust description to be more human readable
        numberSequenceScope = NumberSequenceScope::find(numberSequenceTable.NumberSequenceScope);
        if(numberSequenceScope.DataArea)
        {
            company = numberSequenceScope.DataArea;
        }
        else if(CompanyInfo::findRecId(numberSequenceScope.LegalEntity))
        {
            company = CompanyInfo::findRecId(numberSequenceScope.LegalEntity).DataArea;
        }
        else if(OMOperatingUnit::find(numberSequenceScope.OperatingUnit,numberSequenceScope.OperatingUnitType))
        {
            company = OMOperatingUnit::find(numberSequenceScope.OperatingUnit,numberSequenceScope.OperatingUnitType).NameAlias;
        }
        else
        {
            company = 'GLOBAL';
        }
        if(strScan(referencesStr,company,1,999)>0)
        {
            numberSequenceTable.Txt = strFmt("%1: %2",strUpr(company),numberSequenceTable.NumberSequence);
        }
        else
        {
            numberSequenceTable.Txt = strFmt("%1: %2",strUpr(company),referencesStr);
        }
        if(strCmp(numberSequenceTable.Txt, numberSequenceTable.orig().Txt)!=0)
        {
            numberSequenceTable.update();
            j++;
        }
        ttsCommit;
    }
    info(strFmt("@SYS74545",j,tableId2pname(tableNum(numberSequenceTable))));
    info(strFmt("@SYS316310",timeNow()-starttime));
}
Advertisements