Rok v číselné řadě (AX2012)

Na diskusních fórech jsem zaznamenal hodně otázek o tom, jak přidat rok do číselné řady v AX2012, tedy jak generovat ID jako 2013-xxxxx a 2014-xxxxx, která by automaticky použila aktuální rok. Někteří lidé chápou, že by to měly umožňovat rozsahy (scopes) číselných řad, ale neví jak.

Naštěstí je to nejen možné, ale i celkem jednoduché. Než se snažit o teoretický popis nebo něž opakovat dokumentaci, pojďme si raději projít jeden jednoduchý příklad od začátku do konce.

Datový typ

Nejprve potřebujeme nový datový typ, se kterým bude číselná řada spojena. Vytvořte nový řetězcový datový typ, nazvěte jej DocuRevisionId, nastavte jeho Label na Revision ID a StringSize na 20. Tento datový typ reprezentuje hypotetické ID revize dokumentu.

Pak je třeba zaregistrovat daný typ pro nějaký aplikační modul – v našem případě to bude správa dokumentů. Otevřete metodu loadModule() třídy NumberSeqModuleDocument a přidejte na její konec následující kód (úmyslně jsem vynechal všechno, co není pro náš příklad nezbytné):

datatype.parmDatatypeId(extendedTypeNum(DocuRevisionId));
datatype.addParameterType(NumberSeqParameterType::DataArea, true, false);
datatype.addParameterType(NumberSeqParameterType::FiscalCalendarPeriod, true, false);
this.create(datatype);

Zde vytváříme definici nové číselné řady pro datový typ DocuRevisionId. Také definujeme dva parametry rozsahu: společnost a fiskální kalendářní období. Deklarace podporovaných parametrů rozsahu je velmi důležitá – bez nich nemůžete rozsahy číselných řad používat.

Definice nemá žádný efekt, dokud není modul načten. Můžete to zařídit spuštěním následujícího kódu v jobu:

new NumberSeqModuleDocument().load();

Když je to hotovo, můžete jít do Správa organizace > Společné > Číselné řady > Konfigurace segmentu a ověřit, že tam náš nový typ je a má oba očekávané segmenty.

SegmentConfigurationCZ

Fiskální období

Než začneme konfigurovat číselné řady, vytvořme nejprve fiskální období, která budeme používat v rozsahu číselných řad. Vytvoříme období pokrývající celý rok, ale mohli byste použít cokoli, co dává ve vašem případě smysl.

Otevřete Hlavní kniha > Nastavení > Fiskální kalendáře a vytvořte nový kalendář – já jej nazvu MyYear. Měl by pokrývat celý rok:

NewFiscalCalendarCZ

Pro náš příklad budeme potřebovat dva kalendáře, takže stiskněte tlačítko Nový fiskální rok a vytvořte ještě jeden kalendář (pro rok 2014):

NewFiscalYearCZ

Zobrazte vygenerované období a nastavte Zkrácený název pro aktivní období. Zkrácený název, pokud je zadán, se automaticky použije v číselné řadě. V tomto formuláři můžete také období přejmenovat.

FiscalYearDetailCZ

Číselné řady

Nyní vytvoříme dvě číselné řady – pro roky 2013 a 2014. Nemusí mít stejný kód číselné řady, ale mohou, protože unikátní identifikátor není kód samotný, ale ve spojení s rozsahem. My použijeme stejný kód, protože to bude třeba pro jeden dodatečný případ.

Jděte do Správa organizace > Společné > Číselné řady >Číselné řady a vytvořte novou řadu. Vyplňte pole následovně:

Kód číselné řady Revision
Jméno Revision 2013
Rozsah Společnost a Fiskální období

Jakmile vyberete rozsah, dostanete dodatečná pole – číselná řada bude použita pouze pro hodnoty, které zde určíte. Vyberte vaši společnost a aktivní období pro rok 013 v našem novém kalendáři.

Číselná řada automaticky obsahuje segmenty pro všechny parametry rozsahu, takže formát vypadá nějak jako DAT2013-######. Protože tam společnost nepotřebujeme, smažte segment Společnost. Hodnota segmentu Fiskální kalendářní období se přebírá ze zkráceného názvu období a můžete ji změnit, je-li třeba.

Také potřebujeme (alespoň v typickém případě) asociovat číselnou řadu s datovým typem. Přidejte novou položku na záložce Odkazy, vyberte oblast Správa dokumentů a dostanete jedinou možnost pro Odkaz: Revision ID. To je proto, že Revision ID je jediný typ ve zvoleném modulu, který podporuje Společnost a Fiskální kalendářní období.

Výsledek by měl vypadat takto:

NewSequenceCZ

 

Nyní udělejte to samé ještě jednou, jen použijte rok 2014 místo 2013.

Použití číselných řad

V tuto chvíli je všechno připraveno, potřebujeme jen nějaký kód, který najde správnou číselnou řadu a získá vygenerované číslo.

Podívejte se na následující implementaci. Nejdříve ze všeho najdeme fiskální období pro dané datum. Pak jej použijeme (společně s aktuální společností) k vytvoření objektu reprezentující rozsah. Nakonec najdeme číselnou řady pro daný typ a rozsah a získáme nové číslo obvyklým způsobem.

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();

Měli byste dostat číslo jako 2013-000001. Pokud změníte rok na 2014, dostanete 2014-000001, přesně jak bylo zamýšleno. Pokud změníte rok na 2015, dostanete chybu, protože žádná takové řada neexistuje.

Existuje ještě jeden přístup – normálně se nedoporučuje, ale je dobré o něm vědět. Mohli jsme vynechat referenci na datový typ a odkazovat se na číslené řady jen společným kódem. Tyto řady mají stejný kód, ale liší se rozsahem:
SequencesCZ
Tento zdrojový kód je podobný tomu předchozímu, jen hledáme číselnou řadu pomocí jejího kódu:

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());

Závěr

Rozsahy číslených řad rozšiřují schopnosti číselných řad vcelku přímočarým způsobem. Nicméně pokud jim lidé dostatečně nerozumí, mají často nesprávná očekávání. Například chtějí použít segment Fiskální kalendářní období pro datový typ, který takový parametr rozsahu nepodporuje. Protože parametr není podporován, neexistuje žádný kód, který by pro něj poskytl konkrétní hodnotu (AX například neví, jaké datum a jaký kalendář by měla použít).

Můj záměr byl ukázat všechny komponenty na jednom místě – doufám, že to lidem pomůže pochopit, jak do sebe jednotlivé části zapadají.

Zpracování výjimek s X++ and .NET Interop

Nedávná diskuze na komunitním fóru o zprávách ve výjimkách mě přiměla danou situaci důkladně otestovat a myslím, že výsledky stojí za zveřejnění. Tento příspěvek také zmiňuje něco, co jsem už zjistil dříve – že v kódu, který používá .NET Interop a který může být spouštěný jak jako X++ tak i CIL, může být zpracování výjimek celkem složité.

Pojďme si představit problém. Máme metodu třídy v X++ (AX2012), která vyhazuje výjimku:

public class XppClass
{
    public static void run()
    {
        throw error("It failed!");
    }
}

Je použita v .NET knihovně (za pomoci proxy třídy):

public class CSharpClass
{
    public static void Run()
    {
        try
        {
            XppClass.run();
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

Tato .NET knihovna je opět volána z X++:

public static void main(Args args)
{
    try
    {
        CSharpClass::Run();
    }
    catch (Exception::CLRError)
    {
        info(AifUtil::getClrErrorMessage());
    }
    catch (Exception::Error)
    {
        info("Exception::Error zachycena");
    }
}

Zcela identický kód použijeme v různém kontextu – a uvidíme, že se nebude chovat stejně.

X++ kód na klientu

Pokud spustíme kódu na klientu, můžeme odchytit výjimku v X++ jako obvykle (tzn. infolog zobrazí „Exception::Error zachycena“). Výjimka v .NET kódu je typu Microsoft.Dynamics.AX.ManagedInterop.ErrorException a zpráva z infologu je obsažena ve vlastnosti Message:

ErrorException

To je to chování, které je popsáno v Proxies and Exception Mapping [AX 2012].

X++ kód na serveru

Nyní spusťme ten samý kód na serveru. Výjimku v X++ můžeme zachytit stejně jako předtím. Ale situace v .NET třídě je jiná – ačkoli typ je stále ErrorException, vlastnost Message obsahuje text „Exception of type ‚Microsoft.Dynamics.AX.ManagedInterop.ErrorException‘ was thrown“ namísto sktečné zprávy z infologu (a vnitřní výjimka je prázdná).

CIL

Když spustíme daný kód v CIL (například v dávkové úloze), situace je ještě odlišnější. Výjimka zachycená v .NET třídě je System.Reflection.TargetInvocationException (s obecnou zprávou „Exception has been thrown by the target of an invocation“). Její vnitřní výjimka je Microsoft.Dynamics.Ax.Xpp.ErrorException se stejně nicneříkající zprávou „Exception of type ‚Microsoft.Dynamics.Ax.Xpp.ErrorException‘ was thrown“.

Výjimka v X++ je také TargetInvocationException a její vnitřní výjimka je ta, kterou jsme viděli v .NET. Protože je to .NETová výjimka, nemůžeme ji odchytnout pomocí catch (Exception::Error) (což je, mimochodem, přeloženo do CIL jako catch (ErrorException)), musíme použít catch (Exception::CLRError). To je velmi důležitý postřeh – pokud takový X++ kód spustíte v CIL, váš kód pro zpracování výjimek nemusí fungovat tak, jak očekáváte.

Závěr

Jak můžete vidět, kombinování .NET Interopu z X++ a .NET Interopu do X++ vám snadno může způsobit bolest hlavy, protože chování závisí na vrstvě (klient/server) a na tom, jestli kód běží jako X++ nebo CIL). V mnoha případech také nedostanete detaily o X++ výjimkách.

Měli byste to vzít v úvahu, když navrhujete vaše řešení – možná nepotřebujete používat .NET Interop z X++ a .NET Interop do X++ zároveň.

AX2012 R2 Demo V3.0

Microsoft nedávno uvolnil nové virtuální stroje s předkonfigurovanou AX2012 R2 (a spoustou dalších věcí): Microsoft Dynamics AX 2012 R2 Solution Demo Package V3.0.

Hlavní virtuální stroj jsem už nainstaloval a  chtěl bych se podělit o dvě varování:

  1. Pokud používáte Hyper-V 2.o (Windows Server 2008), nemůžete virtuální stroj naimportovat – musíte vytvořit nový a použít poskytnutý virtuální disk. Podrobnosti najdete v dokumentu Setup Instructions.
  2. Vyžaduje spoustu zdrojů. S předchozí jsem na svém počítači žádné potíže neměl, ale tato verze okamžitě zabrala veškeré zdroje, včetně kompletní kapacity 4 procesorů (2.4 GHz). Naštěstí sestřelení SharePointu mi pomohlo dostat se na nějaká normální čísla.
    Je také zřejmé, že 6 GB RAM (které jsem úspěšně používal pro předchozí verzi) už rozhodně nestačí – Microsoft doporučuje 16 GB.

Dynamics AX Solutions Excellence Certification Program

Aktualizace (2014-08-06): Podle zpráv z Microsoftu je Solutions Excellence Certification Program momentálně pozastaven a není jasné, jestli bude někdy obnoven.


Možná už jste zaslechli o Microsoft Dynamics AX Solutions Excellence Certification Programu – nové úrovni certifikací pro Dynamics AX. Microsoft už dříve udělal jisté změny v Partner Programu, aby trochu ztížil získání vyšších úrovní kompetencí. Toto je další krok ve stejném směru – nové požadavky nejsou triviální.

Jednotlivci budou moci získat Solutions Excellence certifikaci v těchto třech směrech:

  • Vývojový (Development)
  • Technický (Technical)
  • Aplikační (Functional)

Detaily o aplikační dráze nejsou zatím k dispozici, ale o zbylých dvou něco málo uvolněno bylo.

Jak vývojový tak i technický směr budou obsahovat dvě zkoušky – jednu znalostní a jednu praktickou (lab exam). Ještě než půjdete na Solutions Excellence certifikaci, budete navíc muset mít několik dalších zkoušek (jsou stejné pro oba směry):

To pravděpodobně není kombinace zkoušek, kterou by v současné době mělo moc lidí – budeme muset prokázat trochu snahy. Ale to je účel, ne?

Je důležité pochopit, že tyto certifikace neexistují jen proto, aby pár lidí dostalo další certifikační logo. Partneři Microsoftu budou nuceni zaměstnávat lidi s těmito certifikacemi, pokud chtějí získat (nebo udržet) pokročilou úroveň kompetence. MPN: Gold Competency bude vyžadovat jednoho zaměstnance s technickou a jednoho s vývojovou Excellence certifikací a Certified Software Advisors bude vyžadovat dokonce dva certifikované zaměstnance v každém směru.

S určitou dávkou zjednodušení lze říct, že tyto nové zkoušky budou k dispozici příští rok (2014) a nové požadavky na partnery se budou vyžadovat od roku 2015.

Více podrobností najdete na stránce Introducing the Microsoft Dynamics AX Solutions Excellence Certification Program na Partnersource.

Přednášky o AX v ČR

Ačkoli už pár let pracuji v zahraničí, několikrát do roka jezdím do Čech a jsem stále v kontaktu s mnoha bývalými kolegy. Občas dostávám dotazy ohledně Dynamics AX a žádosti, abych detailněji ukázal něco, co jsem třeba zmínil na blogu.

Protože řada věcí by mohla zajímat více lidí, napadlo mě, že bych mohl některé z nich probrat veřejně. A pokud by i někdo další měl podobné tendence, mohli bychom zajít ještě o krok dál a třeba zorganizovat nějaká pravidelná setkání, kde by každý mohl prezentovat své nápady, diskutovat problémy a podobně.

Z mé strany by se dalo čekat hlavně povídání o programování, integraci AX a .NETu a o správě životního cyklu aplikací (ALM). Konkrétně jsem v poslední době dostal několik otázek o využití Powershellu ke správě Dynamics AX a o Team Foundation Serveru – to by pravděpodobně byla má první témata.

Protože nejvíce potenciálních zájemců je v Praze, a protože přes Prahu jezdím, udělal bych to tam. V budoucnu by se dalo uvažovat i o jiných místech, ale v tuto chvíli by to byla zbytečná debata.

Pokud byste se chtěli něčeho takového zúčastnit a/nebo máte jakýkoli související nápad, tak se mi prosím ozvěte (můžete zde nechat komentář nebo mi napsat e-mail na  goshoom na goshoom tečka net). Podle zájmu se uvidí, co dál.