Thursday, 1 August 2019

PO LP will be filtered for each User, based on the user’s financial dimensions

Sysadmin>>common>>Users>>Users

Select any current User >> Setup >> Relations . Copy the person, go to HR>> Worker and filter it.  Go to employment tab >> Financial dimensions>> Specify the Department.ex :72

Go to PO and assign the same Department 72 with other dimensions diff.


Code to Filter the PO Listpage Based on User Dimension :

PurchTableListPageInteraction >> InitialQuery  

    container               purchIds;
    DimensionValue          dimvalue;
    DimensionProvider dimensionProvider;
    DimensionAttributeValueSetStorage dimAttrValueSetStorage;
    int i;


   else if (this.getListPageType() == PurchTableListPage::NkwWorkerDimensionView)
    {
         dimensionProvider = new DimensionProvider();
         dimAttrValueSetStorage = DimensionAttributeValueSetStorage::find(HcmWorker::find(DirPersonUser::currentWorker()).getDefaultDimension());

        for (i = 1; i <= dimAttrValueSetStorage.elements(); i++)
        {
            if(DimensionAttribute::find(dimAttrValueSetStorage.getAttributeByIndex(i)).Name == "Department")
            {
                dimvalue = dimAttrValueSetStorage.getDisplayValueByIndex(i);               
            }
        }
        qbds = _query.dataSourceTable(tableNum(PurchTable));
        qbds.clearDynalinks();
        qbds = _query.dataSourceTable(tableNum(PurchTable)).addDataSource(tableNum(PurchLine));
        qbds.relations(true);
        qbds.joinMode(JoinMode::ExistsJoin);
           
        purchIds = this.getPurchIdWithDep(dimvalue);
        if(dimvalue)
            qbds.addRange(fieldNum(PurchLine,PurchId)).value(con2Str(purchIds));
        else
            qbds.addRange(fieldNum(PurchLine,PurchId)).value(sysquery::valueEmptyString());
     
    }
 =================================================================
public container getPurchIdWithDep(DimensionValue _depvalue)
{
    #define.dimAttr("Department")
    #define.dimRangeValue(_depvalue)

    Query query = new Query();
    QueryRun queryRun;
    QueryBuildDataSource queryCustTable;
    QueryBuildRange queryDimRange;

    PurchLine purchline;
    DimensionProvider dimensionProvider;

    DimensionAttributeValueSetStorage dimAttrValueSetStorage;
    int countLine = 1;
    int i;
    container conpurchid;
    queryCustTable = query.addDataSource(tableNum(PurchLine));
    dimensionProvider = new DimensionProvider();

    dimensionProvider.addAttributeRangeToQuery(
        query,
        queryCustTable.name(),
        identifierStr(DefaultDimension),
        DimensionComponent::DimensionAttribute,
        #dimRangeValue,
        #dimAttr,
        true);

    queryRun = new QueryRun(query);

    while (queryRun.next()) {
        purchline = queryRun.get(tableNum(PurchLine));

        dimAttrValueSetStorage = DimensionAttributeValueSetStorage::find(purchline.DefaultDimension);

        for (i = 1; i <= dimAttrValueSetStorage.elements(); i++) {
            if(DimensionAttribute::find(dimAttrValueSetStorage.getAttributeByIndex(i)).Name == "Department")
            {
                if(!confind(conpurchid, purchline.PurchId))
                    conpurchid = conIns(conpurchid,i,purchline.PurchId);
            }
        }
    }
    return conpurchid;
}
==============================================================








Thursday, 27 June 2019

To find the string all files in AOT


To find the string all files in AOT, use below command

K:\AosService\PackagesLocalDirectory\DynaCrane>findstr /i /l /n /s /c:"InternalTask" *.xml

Sunday, 23 June 2019

Filterning List Page

1. Filter ListPage for Created by Current User



At times a client will request that users only view the records they created from a specific table. A good example for this scenario is with purchase Requisition, all users need not see what other employees are requesting for purchase. Fortunately this is catered for out of the box, but for other tables a customization needs to be made.
prforme

As a consultant you may be tasked to do the customization in another module,
To demonstrate i will use the Purchase Requisition form so that you can refer from your system ;
Go to AOT Tables and navigate to the PurchReqTable Table, the first thing to note is the Table property created by set to yes which is the field we will use to filter,
createdby

Next navigate to the queries group, Navigate to the PurchReqTableCreatedByMe query  and on the add a filter for the created by field to only show records created by the current user.
querycb

On AOT now navigate to menu Items group, display menu items. On the PurchReqPreparedByMe menu item go to the Query property. add the  PurchReqTableCreatedByMe query and save all.
menuitemq

Now going back to the Area Page and clicking the menu item link Purchase Requisitions Created by me, will show a filtered list of only Purchase Requisitions created by the current user.
============================================================

2. Adding Custome filter on Listpage


magine you want a filter on a list page say planned orders list page. Filter works on the order date and shows order due today or all. It has two values in the selection Today/All. Its not that straightforward as it may seem as it is a list page. On a normal AX form, its much easier.
A number of steps required to achieve this.
1. Add the custom filter to the list page. Note the filterExpression, its a call to method we create in next step. Also you need an enum and an EDT based off the enum, EDT is selected in the properties as well.
2. SysQueryRangeUtil
Add a method to the SysQueryRangeUtil.
3. Interaction class
List pages use the interaction classes for logic. We need to customize 2 methods in the ReqTransPOListPageInteraction.
In method initializing, after super(), add this
   customFilter = SysEPCustomFilter::construct(formStr(ReqTransPOListPage));  
   customFilter.load();  
   customFilter.setInitialFilterControlValue(formControlStr(ReqTransPOListPage, yourFilter), 0);  
Note: customFilter.load() will reload the last saved selection in your filter. In case, you want a specific enum selection everytime, comment out this line.
In method initializeQuery, before super(), add this
Note the call to method in SysQueryRangeUtil
   if (this.listPage().listPageArgs().parameters())  
   {  
     reqPOFilterEnum = customFilter.getFilterControlValue(formControlStr(ReqTransPOListPage, yourFilter));  
     SysQuery::findOrCreateRange(_query.dataSourceTable(tableNum(ReqPO)), fieldNum(ReqPO, ReqDateOrder)).value(SysQueryRangeUtil::xxxReqPOFilter(reqPOFilterEnum));  
   }  
4. Your list page

=================================================

3. Filter Purchtable listpage based on Dimension assigned to worker for current user id

i) Add one enum item -'WorkerDimensions' to Enum - 'PurchTableListPage'
ii) Create new menu item -PurchTableListPage_WorkeDimensions pass  Enum type parameter -'PurchTableListPage', Enum parameter- 'WorkerDimensions'
iii) Modify method PurchTableListPageInteraction\initializeQuery
 //bju
     else if (this.getListPageType() == PurchTableListPage::WorkerDimensions)
    {
         qbds = _query.dataSourceTable(tableNum(PurchTable));
        qbds.clearDynalinks();
        qbds = _query.dataSourceTable(tableNum(PurchTable)).addDataSource(tableNum(PurchLine));
        qbds.relations(true);
        qbds.joinMode(JoinMode::ExistsJoin);
       
        qbds.addRange(fieldNum(PurchLine,DefaultDimension)).value(queryValue(HcmWorker::find(DirPersonUser::currentWorker()).getDefaultDimension()));
    }
    //bju

iv) Add new menu item at required position in ax.

Friday, 21 June 2019

Get Purchase Order Financial Dimensions Using X++

Public void run()
{
    Di_FinancialDimensionsTmp         Di_FinancialDimensionsTmp;
    PurchLine                                        purchLine;
    PurchTable                                      purchTable;
    DimensionAttribute                        dimensionAttribute;
    DimensionAttributeValue               dimensionAttributeValue;
    Dimensionattributevalueset            dimensionattributevalueset;
    DimensionAttributeValueSetItem   dimensionAttributeValueSetItem;


    while select PurchLine
    {
     while select dimensionAttributeValueSetItem
        where dimensionAttributeValueSetItem.DimensionAttributeValueSet == purchLine.DefaultDimension
          join dimensionAttributeValue
            where dimensionAttributeValue.RecId == dimensionAttributeValueSetItem.DimensionAttributeValue
              join  dimensionAttribute
                where dimensionAttribute.RecId == dimensionAttributeValue.DimensionAttribute
     {
        switch (DimensionAttribute.Name)
        {
            case BusinessUnit     :
            Di_FinancialDimensionsTmp.BusinessUnit = dimensionAttributeValueSetItem.DisplayValue;
            break;
            case CostCenter :
            Di_FinancialDimensionsTmp.CostCenter    = dimensionAttributeValueSetItem.DisplayValue;
            break;
            case Department :
            Di_FinancialDimensionsTmp.Department    = dimensionAttributeValueSetItem.DisplayValue;
            break;
            case ItemGroup :
            Di_FinancialDimensionsTmp.ItemGroup     = dimensionAttributeValueSetItem.DisplayValue;
            break;
            case Project:
            Di_FinancialDimensionsTmp.Project         = dimensionAttributeValueSetItem.DisplayValue;
            break;
        }
        Di_FinancialDimensionsTmp.LineNumber = PurchLine.LineNumber;
     }
    Di_FinancialDimensionsTmp.Purchid = purchLine.PurchId;
    Di_FinancialDimensionsTmp.insert();
}

Refresh called form once button clicked is executed.

class WHSContainerTableFormEventHandler
{
   
    [FormControlEventHandler(formControlStr(WHSContainerTable, CreateNewCarrierLabel), FormControlEventType::Clicked)]
    public static void CreateNewCarrierLabel_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        sender.formRun().dataSource().research(true);

    }

}

Wednesday, 29 May 2019

SysOperation-Framework: Initalize parameters of a data contract

If you include the SysOperationInitializable class in a data contract using the implements command, the method initialize() gets available and can be overwritten.
This method can be used to initialize variables within the data contract. However, this method is only called as long as no usage data is found or it is not activated.
[DataContractAttribute]
class TutorialSysOperationDataContract
    implements SysOperationInitializable
{
    date dialogDate;
}

[DataMemberAttribute]
public TransDate parmDialogDate(TransDate _dialogDate = dialogDate)
{
    dialogDate = _dialogDate;
    return dialogDate;
}

public void initialize()
{
    dialogDate = systemDateGet() - 365;
}

If you want the initalize() to always be called, you must extend the DataContract with the attribute SysOperationAlwaysInitializeAttribute.
[DataContractAttribute, SysOperationAlwaysInitializeAttribute]
class TutorialSysOperationDataContract
    implements SysOperationInitializable
{
    date dialogDate;
}

Tuesday, 21 May 2019

Cheque report Customization

Today we will learn how to customise standard cheque report and add a new cheque design.


1) Make a new Output type MenuItem for your cheque report.



2) Make changes in the standard enum for cheque report and add your cheque name.


3) Make changes in chequeController Class. Add your report name in declaration section.

Call your report according to the Enum specified. The Enum will be the one you created above.


4) Make a method in Global class for converting numerals to Indian format

/// <summary>
/// Convert numerals to Hindi format text.
/// </summary
/// <param name="_num">
/// The numeral to be converted.
/// </param>
/// <returns>
/// The converted string.
/// </returns>

static TempStr TEC_numeralsToTxt_IN(real _num)
{
    int     numOfPennies = frac(_num)*100 mod 100;
     int     test         = real2int(round(_num,0));
     int     paise;
     int     numOfTenths;
     str 20  ones[19], tenths[9], hundreds, thousands, lakhs, crores, millions, billions;
     str 40  textpaise;
     int     tmpnumofpennies;
     int     temp;
     str 200 returntxt;

     int checkPower(int  _test, int _power)
     {
         int     numOfPower;

         if (_test >= _power)
         {
             numOfPower = _test DIV _power;
             if (numOfPower >= 100)
             {
                 temp = numOfPower DIV 100;
                 returntxt = returntxt + ' ' + ones[temp] + ' ' + hundreds;
                 numOfPower = numOfPower MOD 100;
             }
             if (numOfPower >= 20)
             {
                 temp = numOfPower DIV 10;
                 returntxt = returntxt + ' ' + tenths[temp];
                 numOfPower = numOfPower MOD 10;
             }

             if (numOfPower >= 1)
             {
                 returntxt = returntxt + ' ' + ones[numOfPower];
                 numOfPower = numOfPower MOD 10;
             }

             switch(_power)
             {
                 case 1000000000 :
                 {
                     returntxt = returntxt + ' ' + billions;
                     _test = _test MOD 1000000000;
                     break;
                 }
                 case 10000000 :
                 {
                     returntxt = returntxt + ' ' + crores;
                     _test = _test MOD 10000000;
                     break;
                 }
                case 100000 :
                 {
                     returntxt = returntxt + ' ' + lakhs;
                     _test = _test MOD 100000;
                     break;
                 }
                 case 1000 :
                 {
                     returntxt = returntxt + ' ' + thousands;
                     _test = _test MOD 1000;
                     break;
                 }
                 case 100 :
                 {
                     returntxt = returntxt + ' ' + hundreds;
                     _test = _test MOD 100;
                     break;
                 }
             }
         }
         return _test;
     }
     ones[1] = "@SYS26620";
     ones[2] = "@SYS26621";
     ones[3] = "@SYS26622";
     ones[4] = "@SYS26626";
     ones[5] = "@SYS26627";
     ones[6] = "@SYS26628";
     ones[7] = "@SYS26629";
     ones[8] = "@SYS26630";
     ones[9] = "@SYS26631";
     ones[10] = "@SYS26632";
     ones[11] = "@SYS26633";
     ones[12] = "@SYS26634";
     ones[13] = "@SYS26635";
     ones[14] = "@SYS26636";
     ones[15] = "@SYS26637";
     ones[16] = "@SYS26638";
     ones[17] = "@SYS26639";
     ones[18] = "@SYS26640";
     ones[19] = "@SYS26641";
     tenths[1] = 'Not used';
     tenths[2] = "@SYS26643";
     tenths[3] = "@SYS26644";
     tenths[4] = "@SYS26645";
     tenths[5] = "@SYS26646";
     tenths[6] = "@SYS26647";
     tenths[7] = "@SYS26648";
     tenths[8] = "@SYS26649";
     tenths[9] = "@SYS26650";
     hundreds    = "@SYS26651";
     thousands   = "@SYS26652";
     lakhs       = "Lakh";
     crores      = "Crore";
       millions    = "@SYS26653";
      billions    = "@SYS26654";

      test = checkPower(test, 1000000000);
     test = checkPower(test, 10000000);
     test = checkPower(test, 100000);
     test = checkPower(test, 1000);
     test = checkPower(test, 100);

     if (test >= 20)
     {
         numOfTenths = test DIV 10;
         returntxt = returntxt + ' ' + tenths[numofTenths];
         numOfTenths = numOfTenths MOD 10;
         test = test MOD 10;
     }
     if (test >= 1)
     {
         numOfTenths = test;
         returntxt = returntxt + ' ' + ones[numOfTenths];
     }
      if (numOfPennies)
     {
         returntxt = returntxt + ' ' + "@SYS5534" + "\n\n";
     }
     paise=numofPennies;
     if(paise)
     {
      if(paise >=20)
      {
       numofTenths= paise DIV 10;
       returntxt=returntxt + ' '+tenths[numofTenths];
       numofTenths = numofTenths MOD 10;
       paise=paise MOD 10;
      }
      if(paise >=1)
      {
       numOfTenths=paise;
       returntxt=returntxt+ ' '+ones[numOfTenths];
      }
      returntxt=returntxt+" Paise";

     }
    return   returntxt + "  Only";
}

5) Next is CustVendCheque class. Initialize your Enum.

Here we converted the amount to Indian format.







6) Make Change in BankPrintTestCheque Class



7) Make Changes in BankChequePrint Class


8) Make a new report project in visual studio and add report and add dataset selecting ChequeDp class.

9) Add new design.


10) size should be the same as of your cheque. Here it is 8 X 4. Set accordingly.