Thursday, December 31, 2020

How to Delete Models in Dynamics 365 F&O

1. Stop the AOS web services (Go to IIS and look for "AOS services" and stop it)

2. Stop Microsoft Dynamics 365 Unified Operations: Batch Management Service [type services.msc into run and search for it]

3. Now go to C:\AOSService\PackagesLocalDirectory

4. Delete your model

5. Now start the AOS web services and Batch Management services

6. Now refresh models

7. Synchronize the database


Monday, December 28, 2020

Error in UAT/Production "Cannot create a record in SysXppAssembly (SysXppAssembly)"

Create a  new job 


static void TTC_AY_SysXppAssembly(Args _args)

{

    SysXppAssembly  SysXppAssembly;

    delete_from SysXppAssembly;

}


Now Run it.


Now run a Full CIL

Tada! Error resolved

Saturday, December 26, 2020

Dynamics 365 F&O Import data from CSV

In this example We will be importing name and id from a csv file in a table.


class TTC_AY_ImportFile

{

    public static void main(Args _args)

    {

        AsciiStreamIo                       file;

        FileUploadTemporaryStorageResult    fileUpload;

        TTC_WorkerTable                     workerTable;

        Counter                             counter = 0;

        str                                 Name;

        #OCCRetryCount


        try

        {

            fileUpload  = File::GetFileFromUser() as FileUploadTemporaryStorageResult;

            file        = AsciiStreamIo::constructForRead(fileUpload.openResult());

            if (file)

            {

                if (file.status())

                {

                    throw error("Unknown problem while importing file");

                }

                file.inFieldDelimiter(';'); //separator

                file.inRecordDelimiter('\r\n');

            }


            //Read a CSV File

            container rec;

            ttsbegin;

            while (!file.status())

            {

                counter++;

                rec = file.read();

                if (conLen(rec))

                {

                    Name = conPeek(rec, 2);

                    workerTable = TTC_WorkerTable::find(Name);

                    

                    if(!workerTable.RecId)

                    {

                        workerTable.clear();

                        workerTable.Id    = conPeek(rec, 1);

                        workerTable.Name  = Name;

                        workerTable.insert();

                    }

                }

            }

            ttscommit;

            info("Operation complete.");

        }

        catch (Exception::Deadlock)

        {

            retry;

        }

        catch (Exception::UpdateConflict)

        {

            if (appl.ttsLevel() == 0)

            {

                if (xSession::currentRetryCount() >= #RetryNum)

                {

                    throw Exception::UpdateConflictNotRecovered;

                }

                else

                {

                    retry;

                }

            }

            else

            {

                throw Exception::UpdateConflict;

            }

        }

    }

}


Sunday, December 20, 2020

Dynamics 365 Chain of commands

In this example We will be showing name and personnel number of worker at Worker creation and automatically deleting the worker


[ExtensionOf(tableStr(HcmWorker))]

final class TTC_HcmWorker_Extension

{

    public void insert()

    {

        next insert();

        Info(strFmt("%1",this.PersonnelNumber));

        Info(strFmt("%1",this.name()));

        this.delete();

    }

}

Export data to CSV file - JOB AX 2012

static void JobExportWorker(Args _args)

{

    HcmWorker                               hcmWorker;

    CommaTextIo                           file;

    container                                   line;

    #define.filename(@'C:\Worker.csv')

    #File

    file = new CommaTextIo(#filename, #io_write);

    if (!file || file.status() != IO_Status::Ok)

    {

        throw error("File cannot be opened.");

    }

    file.outRecordDelimiter('\r\n');

    file.outFieldDelimiter('\t');


    while select hcmWorker

    {

            line = [hcmWorker.personnelnumber,hcmWorker.Name()];

            file.writeExp(line);

    }

    info(strFmt("File %1 created.", #filename));

}


Friday, November 20, 2020

Import data from CSV file - JOB AX 2012

 static void ImportfromCSV(Args _args)

{

    TTC_AppOfPF     appOfPF;

    Dialog          dialog  = new Dialog();

    DialogField     dialogField;

    AsciiIo         importFile;

    str             filePath,fileNameOnly;

    filetype        type;

    container       record;

    str             Delimiter = ",";

    int             totalRecords;


    dialogField=dialog.addField(extendedTypeStr(FilenameOpen),"Select File","Select file to import");

    dialog.caption("Import Worker's File");

    dialog.filenameLookupFilter(['csv','*.csv']);

    if(!dialog.run())

        return;

    [filePath, fileNameOnly, type] = fileNameSplit(dialogField.value());

    importFile = new AsciiIo(dialogField.value(), 'R');

    if((!importFile) || (importFile.status() != IO_Status::Ok))

    {

        warning("Error in opening import file");

        throw(Exception::Error);

    }

    importFile.inFieldDelimiter(Delimiter);

    if((!importFile) || (importFile.status() != IO_Status::Ok))

    {

        warning("Error in opening log file");

        throw(Exception::Error);

    }

    try

    {

        ttsbegin;

        record = importFile.read();

        while(importFile.status() ==  IO_Status::Ok)

        {

            record = importFile.read();

            if(!record)

                break;

            totalRecords = totalRecords + 1;

            appOfPF.clear();

            appOfPF.Worker                  = conPeek(record,1);

            appOfPF.PersonnelNumber         = conPeek(record,2);

            appOfPF.PFAccountNum            = conPeek(record,3);

            appOfPF.insert();

        }

        ttscommit;

    }

    catch(Exception::Error)

    {

        Throw(Exception::Error);

    }

    info(strFmt("Total read records = %1",totalRecords));

}

Wednesday, November 18, 2020

Common table in Ax 2012

Common : The system table Common is the base for all tables. The table contains no data, and the table can be compared with a temporary application table. Common is used like the base type anytype. You can set any table equal to the table Common. This is useful if you need to transfer a table as a parameter and not knowing the exact table before execution time

static void DataDic_Common(Args _args)

{

Common common;

CustTable custTable;

;

common = custTable;

if (common.tableId == tablenum(custTable))

{

while select common

{

info(common.(fieldnum(custTable, name)));

}

}

}

The example above is initializing Common with CustTable. A check is made to assure that Common is now equal to CustTable. All records from CustTable are looped, and the customer name is printed in the InfoLog. Notice, the system function fieldnum() is used to get the field name printed. If you do not know the fieldname at runtime, you can enter the field id in parentheses instead.

Wednesday, July 8, 2020

Container in Ax 2012

A container is an abstract data type (ADT) whose instances are collections of other objects.
In other words, they store objects in an organized way that follows specific access rules. The size of the container depends on the number of objects (elements) it contains.

Declare a container :
container cr3;

Assign a literal container to a container variable :
cr3 = [22, "blue"];

Declare and assign a container :
container cr2 = [1, "blue", true];

Mimic container modification (implicitly creates a copy) :
cr3 += [16, strMyColorString];
cr3 = conIns(cr3, 1, 3.14);
cr3 = conPoke(cr3, 2, "violet");

Assignment of a container (implicitly creates a copy) : 
cr2 = cr3;

Read a value from the container : 
myStr = conPeek(cr2, 1);

One statement that does multiple assignments from a container
str myStr;
int myInt;
container cr4 = ["Hello", 22, 20\07\1988];
[myStr, myInt] = cr4; // "Hello", 22


condel   :- Use condel to delete one or more items from a container.
confind :- Use confind to locate a sequence of items in a container. 
conins   :- Use conins to insert some items into a container.
conlen   :- Use conlen to find out how many items there are in a container.
connull  :- Use connull to explicitly dispose of the contents of a container.
conpeek :- Use conpeek to extract an item from a container, and to convert it into another data type  
conpoke :- Use conpoke to replace (poke) an item in a container.

Difference between temp table and container.
1. Data in containers are stored and retrieved sequentially, but a temporary table enables you to define indexes to speed up data retrieval.
2. Containers provide slower data access if you are working with many records. However, if you are working with only a few records, use a container.
3. Another important difference between temporary tables and containers is how they are used in method calls. 
When you pass a temporary table into a method call, it is passed by reference. Containers are passed by value. When a variable is passed by reference, only a pointer to the object is passed into the method. When a variable is passed by value, a new copy of the variable is passed into the method. If the computer has a limited amount of memory, it might start swapping memory to disk, slowing down application execution. When you pass a variable into a method, a temporary table may provide better performance than a container

Saturday, June 6, 2020

update_recordset in Ax 2012

The X++ SQL statement update_recordset enables you to update multiple rows in a single trip to the server

update_recordset generalJournalAccountEntryUpdateRecSet
                setting
                  TTC_EOMCheckField=NoYes::Yes
                    join generalJournalEntryUpdateRecSet
                        where generalJournalAccountEntryUpdateRecSet.GeneralJournalEntry                           ==  generalJournalEntryUpdateRecSet.RecId
                        &&    generalJournalEntryUpdateRecSet.AccountingDate                                       >=  fromDate
                        &&    generalJournalEntryUpdateRecSet.AccountingDate                                       <=  toDate
                        &&    generalJournalEntryUpdateRecSet.Ledger                                               ==  fromLedger.RecId
                        &&    generalJournalEntryUpdateRecSet.PostingLayer                                         ==  CurrentOperationsTax::Current
                    join DimensionAttributeLevelValueAllViewUpdateRecSet
                        where generalJournalAccountEntryUpdateRecSet.LedgerDimension                               ==  DimensionAttributeLevelValueAllViewUpdateRecSet.ValueCombinationRecId
                        &&    DimensionAttributeLevelValueAllViewUpdateRecSet.DisplayValue                         ==  division
                        &&    DimensionAttributeLevelValueAllViewUpdateRecSet.DimensionAttribute                   ==  DimensionAttribute::findByName("Division").RecId
                    join DimensionAttributeLevelValueAllViewUpdateRecSet2
                        where DimensionAttributeLevelValueAllViewUpdateRecSet2.ValueCombinationRecId               ==  DimensionAttributeLevelValueAllViewUpdateRecSet.ValueCombinationRecId
                        &&    DimensionAttributeLevelValueAllViewUpdateRecSet2.DisplayValue                        ==  selectedMainAccount
                        &&    DimensionAttributeLevelValueAllViewUpdateRecSet2.DimensionAttribute                  ==  DimensionAttribute::findByName("MainAccount").RecId;
        }


Picture of same code with indentation :-

Creating custom lookup in dialog form in Ax 2012

1. write following in class declaration

MainAccount                             mainAccount;





2. Write a new method "accountLookup"

public void accountLookup(FormStringControl _control2)
{
    Query                   query = new Query();
    QueryBuildDataSource    queryBuildDataSource;
    QueryBuildRange         queryBuildRange;
    SysTableLookup          sysTableLookup = SysTableLookup::newParameters(tableNum(mainAccount),_control2);

    sysTableLookup.addLookupField(fieldNum(mainAccount, mainaccountid));
    sysTableLookup.addLookupField(fieldNum(mainAccount, Name));

    queryBuildDataSource = query.addDataSource(tableNum(mainAccount));

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}







3. now go to "dialog" method and after taking the input for account write the following code

    dialog.addTabPage("Account");
    dialog.addGroup("Account Parameters").columns(2);
    dlgMainAccounts         = dialog.addFieldValue(extendedTypeStr(String255),mainAccounts,"Accounts");
    control2 = dlgMainAccounts.control();
    control2.registerOverrideMethod(methodStr(FormStringControl, lookup),methodStr(TTC_EOM,accountLookup), this);
    dlgMainAccounts.mcrReplaceOnLookup(false); //this is for entering multiple account values in the field
    controlMainAccounts    = dlgMainAccounts.control();

Applying validation on fields (methods) in dialog form in Ax 2012

1. go to class declaration and make the following "FormBulidStringControl"

FormBuildStringControl                  controlFromDataAreaId,controlToDataAreaId,controlGeneralType,controlMainAccounts,controlDivision;





2. now in the "dialog" method write the following method,below the field where we enter value

controlFromDataAreaId = dlgFromDataAreaId.control();





3. now in the ""dialogPostRun" method write the following code

controlFromDataAreaId.registerOverrideMethod(methodStr(FormStringControl,Validate),
                                            methodStr(TTC_EOM,fromtoEntity_Validate),
                                            this);





4. now make a new method, in this case ""fromtoEntity_Validate

public boolean fromtoEntity_Validate(FormStringControl  _control)
{
    boolean ret         = _control.validate();

    select DataArea from companyInfo
        where companyInfo.DataArea  == _control.valueStr();

    if(companyInfo)
    {
        ret = true;
    }
    else
    {
        ret = ret && checkFailed("Entity does not exist");
    }
    return ret;
}

Sunday, May 24, 2020

Making all fields mandatory/necessary in dialog form in Ax 2012

Write this code in the validate form
(accordingly)


public boolean validate(Object calledFrom = null)
{
    boolean ret;

    ret = super(calledFrom);

    if(!fromDate)
    {
        ret =   checkFailed("From Date must be entered");
    }
    else if(!toDate)
    {
        ret =   checkFailed("To Date must be entered");
    }
    else if(!fromDataAreaId)
    {
        ret =   checkFailed("From company must be entered");
    }
    else if(!toDataAreaId)
    {
        ret =   checkFailed("To company must be entered");
    }
    else if(!generalType)
    {
        ret =   checkFailed("General Type must be entered");
    }
    else if(!mainAccounts)
    {
        ret =   checkFailed("Accounts must be entered");
    }
    else if(!division)
    {
        ret =   checkFailed("Division must be entered");
    }

    return ret;
}

Sunday, April 12, 2020

Construct Method in Ax 2012

class ClassTest
{

}




public void show()
{
    info("Atul");
}




public static ClassTest construct()
{
    return new ClassTest();
}




public static void main(Args _args)
{
    ClassTest obj = ClassTest::construct();
    obj.show();
}

Pack UnPack in Dialog Form in Ax 2012

In class declaration write this

//in the start
#define.CurrentVersion(2)



//in the end
#localMacro.CurrentList
        fromDate,
        toDate,
        fromDataAreaId,
        toDataAreaId,
        generalType,
        mainAccounts,
        division
#endMacro







Make this method in the dialog form

container pack()
{
    return [fromDate,toDate,fromDataAreaId,toDataAreaId,generalType,mainAccounts,division];

}


Make this method in the dialog form
boolean unpack(container _packedValues)
{
    [fromDate,toDate,fromDataAreaId,toDataAreaId,generalType,mainAccounts,division] = _packedValues;
    return true;
}

Basic Dialog Form in Ax 2012

class TTC_AY extends RunBase
{
    DialogField fieldName,fieldId;
    TTC_CustomerTable   custTable;
    TTC_CustomerTable2  custTable2;
    TTC_CustID custId;
    TTC_Name custName;
}




protected Object Dialog()
{
    Dialog dialog;
    ;
    dialog = super();
    dialog.caption('Atul Dialog');
    fieldId   =  dialog.addField(extendedTypeStr(TTC_CustID), 'Customer Id');
    fieldName     =  dialog.addField(extendedTypeStr(TTC_Name),'Customer Name');
    return dialog;
}




public boolean getFromDialog()
{
    custId     = fieldId.value();
    custName   = fieldName.value();
    return super();
}




public void run()
{
    while select * from custTable
        where custTable.Name == custName
            && custTable.Id == custId

    if (custTable)
    {
        info( strFmt('%1 -- %2',custTable.Id, custTable.Name));
        custTable2.Id           = custTable.Id;
        custTable2.Name         = custTable.Name;
        custTable2.Email        = custTable.Email;
        custTable2.Phone        = custTable.Phone;
        custTable2.Gender       = custTable.Gender;
        custTable2.CustomerType = custTable.CustomerType;
        custTable2.Balance      = custTable.Balance;
        custTable2.Age          = custTable.Age;
        custTable2.Address      = custTable.Address;
        custtable2.insert();
    }
    else
    {
        error( 'Customer not found!');
    }
}




public static void main(Args _args)
{
    TTC_AY custCreate = new TTC_AY();
    if (custCreate.prompt())
    {
        custCreate.run();
    }
}

Display Methods in Ax 2012

Add the field(Int this case int type) in the form that you want to show(Total in this case) or do the operations on  (display method is used to show the name with id also)

Put the following properties of the field that you added in the Form
datasource   : whatever you want to add
datamethod : name of the method that you will create

now go to the table and create a method (display method is made on table methods)

display public TTC_Dis AmountOrder()
{
    TTC_OrderTable orderTable;

    select sum(Dis) from orderTable;

    return orderTable.Dis;
}

Roles and Security in Ax 2012

System administrator -> common -> users-> users

Create new role for Form display methods
Go to Menuitems and create new menu items

1. Go to security->privilage and create new privilages
go to properties of the privilege and put the name of form and label accordingly
open the privilege -> Entry point
right click on it and create new entry point
name the entry point and put the object type as "MenuItemDisplay"
and put object name as required(i.e the Display MenuItem that is required)
and put access level as "Delete"

2. Go to security->duty and create new duty
go to properties of the duty and put the name of the duty and label accordingly
go to security->duties->DutyThatYouCreated->privileges
right click on it and create new privilege
go to properties and put the name of the privilege

3. Go to Security->Roles
create new role and put the name and label it as you require
open the role and go to duties create new duty and name it accordingly
now go to privileges and create new privilege and name it accordingly
now save it
now you can see your role for assigning to users

NOTE:-
ye grouping hai basically,menuitem ki grouping kar ke privilege banate hai
jaise 5 privilege bana liye,uss mei se ek duty bna li usmein 3 ko privilege de diya
phir dusra duty bna liya uss ko 5 ka privilege de diya
phir roles assign hote hai user ko

Monday, April 6, 2020

Form Datasource Methods in Ax 2012


Active : The user selects a new record.Retrieves data from joined datasource when a user moves to a new record.

Create : The user creates a new record in the datasource.If you use this method to specify field valuues,the new value are saved to the database when you leave the form.

Delete : the user deletes a record in the datasource.Deletes the current reord from the datasource.

ExecuteQuery : The form is opened for data display.Executes the datasource query and displays the retrieved records.

Filter : The user starts one of the filter commands on the form shortcut menu.Filter records in the datasource.

FindRecord : Activated by the find value method.Finds the specified record in the database and makes it the current one.

InIt : The form is opened.Creates a datasource query based on the datasource properties.

InItValue : A new record is created.The purpose is to fill in initial values in the record.Initializes field values in a new record.If you use this method to specify field values,the new values are not automatically saved to the database when you leave the form.To specify values that you want to save when you leave the form,use the created method.

LinkActive : The user selects a new record in a form that has a datasourcelinked to another datasource.Calls the FormDataSource.executeQuery method on data sources that are linked to the current data source.

Refresh : Not sgtarted by the system.Updates the form by refreshing the view of all records in the datasource.WILL NOT REREAD THE RECORD FROM THE DATASOURCE.IT BASICALLY JUST REFRESHES THE SCREEN WITH WHATEVER IS STORED IN THE FORM FROM THE CACHE.

Reread : Not started by the system.Rereads the current record from the datasource.WILL ONLY REREAD THE CURRENT RECORD FROM THE DATABASE SO YOU SHOULD NOT USE IT TO REFRESH THE FORM DATA IF YOU HAVE ADDED/REMOVED RECORDS.

Research : Not started by the system.Refreshes the database search defined by the query , specified by the FormDataSource.init method.WILL RETURN THE EXISTING FORM QUERY AGAINST THE DATASOURCE,THEREFORE UPDATING THE LIST WITH NEW /REMOVED RECORDS AS WELL AS UPDATING EXISTING ONES.THIS WILL HONOUR ANY EXISTING FILTERS AND SORTING ON THE FORM.

SelectionChanged() : The user selects or unselects one or morerecords in the datasource.Enables youo to change the property values of control when the selected record changes.

ValidateWrite() : A new or updated record is to be written determines whether data is valid and ready to be written.

Write() : The user inserts a new record or updates an existing one.Calls the FormDataSource.validateWrite method and manages the database write operation.

Form Control Methods in Ax 2012


Validate : The user exists a control after entering data.

Lookup : The user uses the lookup facility.

Modified : The user exits an edit field after changing it.The user changes a value in a checkbox,combobox,listbox or radio button control.The super call manages the table update.

Form Methods in Ax 2012


Activate : When a form receives focus.Returns boolean data type that specifies whether a form has focus.

CanClose : When aform is closed.specifies whether you can close the form.The call to the super in the method checks whether closing the form is a valid action.

Closed : The form is closed.use this method to check whether the form has been closed.

Close : The form is closed.the call to the super in this method closes the form window,manages database updates and sets the closed method to true.

CloseCancel : Use this method to check whether the form has been closed by a cancel action.the method is set to true if the form is closed by a cancel action.

CloseOk : The user presses an ok button.specifies whether the form wasa closed by clicking the ok button.the call to the super method sets the boolean flag closedok and calls the close method.

InIt : The form is opened.use the method to initialize a form.the init method I started immediately after the new method and creates the run time image of the form.you must call the super method if you override this methpd and you should add your code before the super call.

Run : The form is opened.Call the run method immediately after the init method.The call to the super method makes the form window appear on the screen and performs a database search for the data to be displayed in the form.

Method Flow                                     Init->Run

How to create Inventory Ax 2012

How to create Inventory

Process Inventory Adjustment -> New -> Lines -> Validate -> Post

1.New:
                           Form name                   : InventJournalTable
                           Table(Datasource) : InventJournalTable

2.Lines:
                           Form name                   : InventJournalLossProfit
                           Table(Datasource) : InventJournalTrans


How to create a Sales order Ax 2012

How to create a SO(Sales Order)

Process SO -> PickList -> PickingListRegistration -> PackingList -> Invoice -> Post

1.SO:
                           Form name         : SalesTable
                           Table(Datasource) : SalesTable,
                                                                        SalesLine
                           Relation         :
                           SalesLine.SalesId == SalesTable.SalesId
                           Class                 : SalesTableForm

2.PickingList:
                           Form name         : WMSPickingRoutesJournal
                           Table(Datasource) : WMSPickingRoute,
                                            WMSOrderTrans
                           Relation         :       
                           WMSOrderTrans.routeId == WMSPickingRoute.pickingRouteID
                           Class                 : SalesPickingListJournalCreate

3.PickingListRegistration:
                           Form name                  : WMSPickingRegistration
                           Table(Datasource) : WMSPickingRoute,
                                                                WMSOrderTrans
                           Relation         :         
                           WMSOrderTrans.routeId == WMSPickingRoute.pickingRouteID
                           Class                 : No Classs was hit by debugger

4.PackingSlip:
                           Form name         : CustPackingSlipJournal
                           Table(Datasource) : CustPackingSlipJour,
                                                    CustPackingSlipTrans
                           Relation           
                                  CustPackingSlipTrans.SalesId == CustPackingSlipJour.SalesId
                                  CustPackingSlipTrans.PackingSlipId == CustPackingSlipJour. PackingSlipId
                                  CustPackingSlipTrans.DeliveryDate == CustPackingSlipJour.DeliveryDate
                           Class                         : SalesPackingSlipJournalCreate

5.Invoice:
                           Form name         : CustInvoiceJournal
                           Table(Datasource) : CustInvoiceJour,
                                            CustInvoiceTrans
                           Relation         :
                           CustInvoiceTrans.SalesId         == CustInvoiceJour.SalesId
                           CustInvoiceTrans.InvoiceId      == CustInvoiceJour.InvoiceId
                           CustInvoiceTrans.InvoiceDate  == CustInvoiceJour.InvoiceDate
         CustInvoiceTrans.numberSequenceGroup  == CustInvoiceJour.numberSequenceGroup
                           Class                :  SalesInvoiceJournalCreateBase

How to create a Purchase order Ax 2012

How to create a PO(Purchase Order) 

Process PO -> Confirm -> Receive -> Invoice -> Post

1.PO Main Form:
                           Form name         :       PurchTable
                           Table(Datasource) : PurchTable,
                                                                        PurchLine
                           Relation         :
                           PurchLine.PurchId == PurchTable.PurchId
                           Class                 : PurchCreateOrderForm

2.Create PO Form:
                           Form name         : PurchCreateOrder
                           Table(Datasource) : PurchTable,
                                                                        PurchTable_W
                           Class                 : PurchCreateOrderForm

3.Purchase Order Confirmations:
                           Form name         : VendPurchOrderJournal
                           Table(Datasource) : VendPurchOrderJour
                           Class                 : PurchPurchOrderJournalCreate

4.Receive(Receipt list):
                           Form name         : VendReceiptsListJournal
                           Table(Datasource) : VendReceiptsListJour,
                                            VendReceiptsListTrans
                           Relation         :
        VendReceiptsListTrans.PurchId                 == VendReceiptsListJour.PurchId
        VendReceiptsListTrans.ReceiptsListId      == VendReceiptsListJour. ReceiptsListId
        VendReceiptsListTrans. ReceiptsListDate == VendReceiptsListJour. ReceiptsListDate

5.Receive(Product receipt):
                           Form name         :   VendPackingSlipJournal
                           Table(Datasource) : VendPackingSlipJour
                           Class                 : FormLetterVersionableJournalCreate,
                                                    FormLetterJournalCreate

6.Invoice:
                           Form name         : VendInvoiceJournal
                           Table(Datasource) : VendInvoiceJour,
                                               VendInvoiceTrans
                           Relation         :
                VendInvoiceTrans.PurchId                 == VendInvoiceJour.PurchId
        VendInvoiceTrans.InvoiceId              == VendInvoiceJour. InvoiceId
        VendInvoiceTrans.InvoiceDate         == VendInvoiceJour. InvoiceDate
        VendInvoiceTrans.numberSequenceGroup == VendInvoiceJour. numberSequenceGroup
        VendInvoiceTrans.InternalInvoiceId == VendInvoiceJour. InternalInvoiceId
                           Class                : PurchInvoiceJournalCreate,
                                              FormLetterJournalCreate

Tuesday, March 31, 2020

Custom Form Dynamics 365

Right click on project -> Add -> New Item
select Form from the dialog box opened
put the name of the form and press Add
Now form will open automatically
Now drag the table that you want to add in the "Data Sources"
Now right click on "Design" -> Apply pattern -> select "Custom"
Now right click on "Design" -> New -> Grid
a new grid will be created
open the properties of the grid
put the name "Grid" and select the table in Data source
now drag the required fields into the grid from the datasource->tableName->Fields
now right click on project from solution explorer and rebuild your project
now to add the form on front end make a display menu item for the form
now create extension of required module in your project(AccountsReceivable in my case)
drag and drop the display menu item in the module

Monday, March 30, 2020

SSRS with ID filter Dynamics 365

Create a temporary table,in this case "CustReportTmp"
set table type property to "InMemory"
add the fields that you want to add in the report from the table you want to add
Now create a new RDP class,Best practice to suffix the rdp class name with DP
Now write the following code:

[SRSReportParameterAttribute(classStr(CustReportFilterContract))]
class CustReportFilterDP extends SRSReportDataProviderBase
{
    CustReportTmp   custReportTmp;
    TTC_CustID        ID;

    [SRSReportDataSetAttribute(tableStr('CustReportTmp'))]
    public custReportTmp getCustReportRDPDemoTmp()
    {
        select * from custReportTmp;
        return custReportTmp;
    }

    [SysEntryPointAttribute]
    public void processReport()
    {
        CustReportFilterContract    contract;
        TTC_Customer                customer;

        contract    = this.parmDataContract() as CustReportFilterContract;
        ID             = contract.parmID();

        while select * from customer where customer.ID  ==  ID
        {
            custReportTmp.clear();
            custReportTmp.ID              =   customer.ID;
            custReportTmp.Name        =   customer.Name;
            custReportTmp.Age           =   customer.Age;
            custReportTmp.Phone        =   customer.Phone;
            custReportTmp.EmailID     =   customer.EmailID;
            custReportTmp.Balance     =   customer.Balance;
            custReportTmp.insert();
        }
    }

}


now add a contract class

[DataContractAttribute]
class CustReportFilterContract
{
    TTC_CustID ID;

    [DataMemberAttribute("ID")]
    public TTC_CustID parmID(str _ID = ID)
    {
        ID  =   _ID;
        return ID;
    }

}

now right click on project -> add -> new item ->
than select "Report"
rename the report accordingly,in this case "ReportFilterRDP"
right click on dataset and add a dataset,name it accordingly
now go to properties of the dataset created
and put data source type to "Report Data Provider"
and select the query that we created (in this case we will select the class that we created)
now right click on design and create a new design
go to properties and give the name of the design and style template to "table style alternating rows"
now right click on design and click on "edit using designer"
now add a table from the ToolBox and and add the necessary fields that you want to add in the report
or you can make the report as per your requirements
now from the solution explorer right click on your report and click deploy report
now right click on project area and rebuild your project
add an output menu item for your report and place it in "Menu Extension" as per your requirement

Modified Field (Table Method) Dynamics 365

public class TTC_Order extends common
{
    public void modifiedField(FieldId _fieldId)
    {
        TTC_Customer        customer;
        TTC_WomenWear   womenwear;
        TTC_MenWear        menwear;
        TTC_KidWear         kidwear;
        super(_fieldId);
        if(_fieldId ==  fieldNum(TTC_Order,CustomerID))
        {
            select customer
                where customer.ID   ==  this.CustomerID;
            this.CustomerName   =   customer.Name;
            this.AccountType       =   customer.CustomerType;
        }

        if(_fieldId ==  fieldNum(TTC_Order,ItemId))
        {
            if(this.Category    ==  TTC_Category::Kid)
            {
                select kidwear
                    where kidwear.ID    ==  this.ItemId;
                this.ItemType   =   kidwear.Type;
            }
            if(this.Category    ==  TTC_Category::Men)
            {
                select menwear
                    where menwear.ID    ==  this.ItemId;
                this.ItemType   =   menwear.Type;
            }
            if(this.Category    ==  TTC_Category::Women)
            {
                select womenwear
                    where womenwear.ID  ==  this.ItemId;
                this.ItemType   =   womenwear.Type;
            }
        }

        if(_fieldId ==  fieldNum(TTC_Order,Quantity))
        {
            if(this.Category    ==  TTC_Category::Kid)
            {
                select kidwear
                    where kidwear.ID    ==  this.ItemID;
                this.Amount =   this.Quantity * kidwear.Price;
            }
            if(this.Category    ==  TTC_Category::Men)
            {
                select menwear
                    where menwear.ID    ==  this.ItemID;
                this.Amount =   this.Quantity * menwear.Price;
            }
            if(this.Category    ==  TTC_Category::Women)
            {
                select womenwear
                    where womenwear.ID  ==  this.ItemID;
                this.Amount =   this.Quantity * womenwear.Price;
            }
        }
    }

}

Starting a project Dynamics 365

Make your project
now click on "Dynamics 365" in action pane
select "Model Management"
select "Create Model"
a popup menu will appear
Name the model "TTC_CustomModel"
Model publisher "Tectree"
Model Description "This model contains all custom customizations"
click next
select "Create new package"
click next
select
application common,application foundation,application platform,application suite,calendar,contact person,currency,dimensions,directory,electronic reporting,
fiscal books,general ledger,ledger,personnel,policy,retail,subledger,tax,unit of measure
click next

go to the properties of the project
select the right model
syncronise database on build  -  false (so that building project won't take much time)


go to dynamics 365 -> options
now select project
now tick "organise projects by element type"
and click ok