Mittwoch, 17. Dezember 2014

Dynamics AX 2012 SSRS Reports


Create a new SSRS Report:


1. Create the temporary table for the Report 
 -> ReportTableTMP, ReportLineTMP
-> Set the Parameter TableType to InMemory or TempDB


2. Create the classes for Controller, Contract and Dataprovider


The Controller-Class
public class Report_Controller extends SrsReportRunController
{
}
public static void main(Args _args)
{
    Report_Controller controller;
    CustInvoiceTrans   CustInvoiceTrans;
    ;
Report_Contract    contract = new Report_Contract();
Controller = new Report_controller();
Controller.parmReportName(SSRSReportSTr(ReportNAME),DESIGNName));
Controller.parmArgs(_args);
controller.parmLoadFromSysLastValue(false);
controller.parmShowDialog(false);  //No Dialog
CustInvoiceTrans   = _args.record();

contract.parmCustInvoiceTrans(CustInvoiceTrans);
Controller.parmReportContract().parmRdpContract(contract);
Controller.startOperation();
}





The Contract-Class
[DataContractAttribute]
public class Report_Contract
{
   CustInvoiceTrans    CustInvoiceTrans;
}
and the parmMethode for CustInvoiceTrans...


The Dataprovider -Class


[SRSReportParameterAttribute(classStr(Report_Contract))] <-- These Parameter are necessary


public class ReportDP extends SRSReportDataProviderBase
{
       ReportTableTmp    TableTMP;
       REportLineTmp     LineTmp;
}


[SRSReportDataSetAttribute(tableStr(ReportTableTmp))]


public ReportTableTmp getReportTableTmp()  <-- you Need this for every temporary table you want to use in the Report
{
       select * from ReportTableTmp ;


       return ReportTableTmp ;
}

[SRSReportDataSetAttribute(tableStr(ReportLineTmp))]


public ReportLineTmp getReportLineTmp()
{
       select * from ReportLineTmp;


       return ReportLineTmp;
}

 

[SysEntryPointAttribute]
public void processReport()
{
    REportContract contract;
    ;
    contract = this.parmDataContract();
    CustInvoiceTrans = contract.parmCustInvoiceTrans();
   
    //Fill the ReportTableTMP
    //Fill the ReportLineTMP
}



The MenuItem parameter for the Report





How to call the Report from Code


private void printReport()
{
    SRSPrintDestinationSettings printSettings;
    Report_contract contract = new Report_contract();
    Report_controller controller = new Report_controller();
    ;
    // set Report Name
    controller.parmReportName(ssrsReportStr(ReportNAme,DesignName));

    // set contract
    contract.parmCustInvoiceTrans(CustInvoiceTrans);
    controller.parmReportContract().parmRdpContract(contract);

    // get Print settings from contract
    printSettings = controller.parmReportContract().parmPrintSettings();

    // set print medium
    printSettings.printMediumType(SRSPrintMediumType::Screen);

    // supress dialog
    controller.parmShowDialog(false);

    // run report
    controller.startoperation();

}


And now only the Report is missing.



Dienstag, 2. Dezember 2014

Dynamics AX 2012


Aus einem Nummernkreis der in Parametern als Referenz hinterlegt ist, bekommt man so am schnellsten die nächsten Nummer:


this.ListID = NumberSeq::newGetNum(NumberSeqReference::findReference(ExtendedTypeNum(ListID))).num();

Mittwoch, 19. November 2014

AX2012: Eine einzelne Finanzdimension aus den Finanzdimensionen raus lösen und in ein Set von Finanzdimensionen hinzufügen. Hier am Beispiel der ProdTable und der Finanzdimension JobID




static void IAXfindLedgerDimension(Args _args)
{
    DimensionAttribute  DimensionAttribute;
    DimensionAttributeValue DimensionAttributeValue;
    DimensionAttributeValueSetItem    DimensionAttributeValueSetITem,DimensionAttributeValueSetITem2;
    DimensionAttributeValueSet  DimensionAttributeValueSEt;
    ProdTable           ProdTable,ProdTable2;
    DimensionDefault                defaultDimension;               
    ;
    ProdTable = ProdTable::find('000585');
    ProdTable2 = ProdTable::find('000584');

    DimensionAttributeValueSetITem  = DimensionAttributeValueSetItem::find(ProdTable.DefaultDimension);

    DimensionAttribute = DimensionAttribute::findByName('jobID');

    DimensionAttributeValueSet = DimensionAttributeValueSet::find(ProdTable.DefaultDimension);

    defaultDimension = DimensionDefaultingService::serviceReplaceAttributeValue(ProdTable2.DefaultDimension, DimensionAttributeValueSet.RecId, DimensionAttribute.RecId);
  
    ttsBegin;
        ProdTable2.selectForUpdate(true);
    ProdTable2.DefaultDimension = defaultDimension;
    ProdTable2.update();
    ttsCommit;
}
AX2012
Finanzdimensionen bei einem Debitoren per Code setzen


static void setFinancialDimensionToCustomer(CustAccount _custAccount) 
 { 
  CustTable custTable; 
  Struct struct = new Struct(); 
  container ledgerDimension; 
  DimensionDefault DimensionDefault; 
  ; 
  struct.add('BookingChannel', '30'); 
  struct.add('Carrier', '01'); 
  struct.add('Department', '30'); 
  struct.add('Destination', '01'); 
  struct.add('Division', '30'); 
  struct.add('Origin', '01'); 
  struct.add('Product', '30'); 
  ledgerDimension += struct.fields(); 
  ledgerDimension += struct.fieldName(1); 
  ledgerDimension += struct.valueIndex(1); 
  ledgerDimension += struct.fieldName(2); 
  ledgerDimension += struct.valueIndex(2); 
  ledgerDimension += struct.fieldName(3); 
  ledgerDimension += struct.valueIndex(3); 
  ledgerDimension += struct.fieldName(4); 
  ledgerDimension += struct.valueIndex(4); 
  ledgerDimension += struct.fieldName(5); 
  ledgerDimension += struct.valueIndex(5); 
  ledgerDimension += struct.fieldName(6); 
  ledgerDimension += struct.valueIndex(6); 
  ledgerDimension += struct.fieldName(7); 
  ledgerDimension += struct.valueIndex(7); 
  ttsBegin; 
  DimensionDefault = AxdDimensionUtil::getDimensionAttributeValueSetId(ledgerDimension); 
  custTable = CustTable::find(_custAccount, true); 
  custTable.DefaultDimension = DimensionDefault; 
  custTable.update(); 
  ttsCommit; 
 } 

Dienstag, 18. November 2014


AX2012 Reservierungen über Code ändern/setzen


Die folgenden beiden Zeilen funktionieren auch für die Salesline dazu einfach im construct die Salesline übergeben.


Eine negative Menge (hier -5) heißt, dass diese SalesLine 5 mehr reserviert, eine positive Menge reduziert die reservierte Menge


reservation = InventUpd_Reservation::newMovement(InventMovement::construct(WMSOrderTrans),-5,true);
reservation.updateNow();
AX2012


Dimensionsanzeige Formular in einem Formular hinzufügen




Today I will post about how to display only the inventory dimensions selected by the user.
This post is rather long because I decided show it step-by-step but I hope you guys enjoy it.

1. The table must have the field InventDimId and it must have a relation with InventDim.
Image
2. Create a new Form. My form has two data sources, InventDimDisplay and InventDim (required) and a grid.
Image
3. Set the InventDim data source properties to:
Image
4. On form Design, create a new Grid and move the ItemId to your grid and then create a new Group and then set the properties below:
Image
5. On class declaration add the following piece of code:
public class FormRun extends ObjectRun
{
    // Declare the class InventDimCtrl_Frm_EditDimensions
    InventDimCtrl_Frm_EditDimensions        inventDimFormSetup;
}
6. Now, create a new method in form.
public InventDimCtrl_Frm_EditDimensions inventDimSetupObject()
{
    return inventDimFormSetup;
}
7. Override the form’s method Init.
public void init()
{
    super();
    // This method will be used to show default fields at form startup
    element.updateDesign(InventDimFormDesignUpdate::Init);
}
8. Create a new method, this method is responsible to show the Inventory Controls.
void updateDesign(InventDimFormDesignUpdate mode)
{
    InventDimParm inventDimParmVisible;

    switch (mode)
    {
        // Form Init
        case InventDimFormDesignUpdate::Init    :
            if (!inventDimFormSetup)
                inventDimFormSetup  = InventDimCtrl_Frm_EditDimensions::newFromForm(element);
                inventDimFormSetup.parmSkipOnHandLookUp( true);

                // Use the methods on InventDimParm
                // to set which dimensions to show when form is initialized
                inventdimparmvisible.inventsiteidflag       = true;
                inventdimparmvisible.InventLocationIdFlag   = true;
                inventDimFormSetup.parmDimParmVisibleGrid(inventDimParmVisible);

        // Datasource Active
        case InventDimFormDesignUpdate::Active  :
            inventDimFormSetup.formActiveSetup(InventDimGroupSetup::newItemId(InventDimDisplay.ItemId)); //InventDimDisplay is the datasource name.
            inventDimFormSetup.formSetControls( true);
            break;

        // Datasource Field change
        case InventDimFormDesignUpdate::FieldChange :
            inventDimFormSetup.formActiveSetup(InventDimGroupSetup::newItemId(InventDimDisplay.ItemId)); //InventDimDisplay is the datasource name.
            InventDim.clearNotSelectedDim(inventDimFormSetup.parmDimParmEnabled()); // InventDim is referring to datasource name
            inventDimFormSetup.formSetControls( true);
            break;

        default :
            throw error(strFmt ("@SYS54195", funcName()));
    }
}
9. We have to create a method on data source to update our table InventDimId and use the method Active to refresh the controls.
Override Data source’s method Active.
public int active()
{
    int ret;
    ret = super();
    element.updateDesign(InventDimFormDesignUpdate::Active);
    return ret;
}
10. Now, override the method Modified for ItemId field in your data source.
public void modified()
{
    super();
   
    element.updateDesign(InventDimFormDesignUpdate::FieldChange);
    InventDim.clearNotSelectedDim(element.inventDimSetupObject().parmDimParmEnabled());
}
11. We have to create a MenuItemButton to call the Display Dimension form where the user can select which dimensions he want to display.
Set the following properties:
MenuItemType: Display
MenuItemName: InventDimParmFixed
12. By the end of this tutorial, your form should look like this.
Image
13. The results:
Image
AX2012
Klasse mit Query im Dialog


CLASS syncVendDlvTime Extends   RunBaseBatch
   
    METHODS
      SOURCE classDeclaration
        public class syncVendDlvTime extends RunBaseBatch
        {
            DialogRunbase   dialog;
       
            DialogField     dialogLocationspezific; //STandortspezifische Auftragseinstellungen
            DialogField     dialogItem; //Artikeldeckung
       
            NoYesId          Locationspecific;
            NoYesId         Item;
       
            QueryRun        QueryRun;
            Query                   query;
       
            DEFINE.CurrentVersion(1)
            LOCALMACRO.CurrentList
                Locationspecific,
                Item
            ENDMACRO
        }
      ENDSOURCE
      SOURCE dialog
        protected Object dialog()
        {
            Object ret;
            ;
            dialog = super();
            //ret = super();
       
            dialogLocationspezific = dialog.addFieldValue(extendedTypeStr(NoYesId),Locationspecific,"");
            dialogItem = dialog.addFieldValue(extendedTypeStr(NoYesId),Item,"");
            return dialog;
        }
      ENDSOURCE
      SOURCE getFromDialog
        public boolean getFromDialog()
        {
            boolean ret;
            ;
       
            ret = super();
            Locationspecific = dialogLocationspezific.value();
            Item = dialogItem.value();
       
            return ret;
        }
      ENDSOURCE
      SOURCE initQuery
    
        protected void initQuery()
        {          
            QueryBuildDataSource    qbds2;
       
            QueryBuildRange         qr_Item;
            QueryBuildRange         qr_vend;
            ;
            query = new Query();
            qbds2 = query.addDataSource(tableNum(VendTable));

            qbds2 = qbds2.addDataSource(tableNum(InventTable));
            qbds2.relations(false);
            qbds2.addLink(fieldNum(VendTable,AccountNum),fieldNum(InventTable,PrimaryVEndorId));
            queryRun = new QueryRun(query);
        }
      ENDSOURCE
      SOURCE queryRun
   
        QueryRun queryRun()
        {
            queryRun = new QueryRun(query);
            return queryRun;
        }
      ENDSOURCE
      SOURCE run
        public void run()
        {
            InventTable InventTable;
            VendTable   VendTable;
            InventItemPurchSetup    InventItemPurchSetup;
            ReqItemTable        ReqItemTable;
            ;
            ttsBegin;
            while(QueryRun.next())
            {
                InventTAble = QueryRun.get(tableNum(InventTable));
                VendTable = QueryRun.get(tableNum(VendTable));
       
                //Sync Standardauftragseinstellungen
                inventItemPurchSetup = InventItemPurchSetup::findDefault(InventTable.ItemId,true);
                InventItemPurchSetup.LeadTime = VendTable.DlvdaysPurch;
                InventItemPurchSetup.CalendarDays = VendTable.Workingdays;
                InventItemPurchSetup.update();
                //sync STandortspezifische Auftragseinstellungen
                if(Locationspecific == NoYes::Yes)
                {
                    while select forUpdate * from InventItemPurchSetup
                        where InventItemPurchSetup.ItemId == InventTable.ItemId
                    {
                        InventItemPurchSetup.LeadTime = VendTable.DlvdaysPurch;
                        InventItemPurchSetup.CalendarDays = VendTable.Workingdays;
                        InventItemPurchSetup.update();
                    }
                }
                //Sync Artikeldeckung
                if(Item == NoYes::Yes)
                {
                    while select forupdate * from ReqItemTable
                        where ReqItemTable.ItemCovFieldsActive == NoYes::Yes
                        && ReqItemTable.VendId == VendTable.AccountNum
                        && ReqItemTable.LeadTimePurchaseActive == NoYes::Yes
                    {
                        ReqItemTable.LeadTimePurchase = VendTable.DlvdaysPurch;
                        ReqItemTable.CalendarDaysPurchase = VendTable.Workingdays;
                        ReqItemTable.update();
                    }
                }
                info(literalStr(""));
       
            }
            ttsCommit;
        }
      ENDSOURCE
      SOURCE showQueryValues
   
        boolean showQueryValues()
        {
            return true;
        }
      ENDSOURCE
      SOURCE main
        public static void main(Args args)
        {
                syncVendDlvTime syncVendDlvTime;
            ;
            syncVendDlvTime = new syncVendDlvTime();
            syncVendDlvTime.initQuery();
       
            if(syncVendDlvTime.prompt())
            {
                syncVendDlvTime.run();
            }
        }
      ENDSOURCE
    ENDMETHODS
  ENDCLASS

AX2012


Rest liefern z. B. der Auftragsposition über Code setzen


static void Test_resetRestLiefern(Args _args)
{
SalesLine Salesline2;
boolean updated;
Qty tqy = -6,sqty;
;
ttsBegin;
Salesline2 = SalesLine::findinventtransid('007136',true);
sqty = Salesline2.unitConvertInvent2Sales(Salesline2.RemainInventPhysical+tqy);
updated = SalesUpdateRemain::updateDeliveryRemainder(Salesline2,sqty,Salesline2.RemainInventPhysical+tqy);
info('test');
ttsCommit;
}

AX2009
Barcode auf Bericht drucken




Initialisieren des Barcodes:


Barcode initReportBarcodeControl(ReportStringControl _barcodeStringControl)
{
   BarCodeSetup                barcodeSetup;
   ;
    barcodeSetup    = BarcodeSetup::find(ProdParameters::find().swsBarcodeSetupId);
    if (barcodeSetup && barcodeSetup.barcodeType != BarcodeType::NoBarcode)
    {
         // set Font-Name and-Size for ReportStringControl
        _barcodeStringControl.font(barcodeSetup.fontName);
        _barcodeStringControl.fontSize(barcodeSetup.fontSize);
        return Barcode::construct(barcodeSetup.barcodeType == BarcodeType::EAN128 ?     BarcodeType::Code128 : barcodeSetup.barcodeType);


    }
    else
    {
        _barcodeStringControl.visible(false);
        return null;
    }
}


Im Init nach super()
barCode = this.initReportBarcodeControl(BarcodeNumber);
display Methode für Reportfield
display str BarcodeNumber()
{
    if (Barcode == null)
        return '';


    if(isCollectiveDocument)
    {
       if(isPEReport)
        {
            Barcode.string(true, int2str(curProdTable.swsProductionId));
        }
        else
        {
            Barcode.string(true, int2str(prodTable.swsProductionId));
        }
    }
    else
    {
        if(isPEReport)
        {
            Barcode.string(true, curProdTable.ProdId);
        }
        else
        {
            Barcode.string(true, prodTable.ProdId);
        }
    }
    return Barcode.barcodeStr();
}


Das Feld am Report selbst ist ein String: