Friday, October 26, 2018

Accessing global cache value and changing logic in same scope based on cache captured in Dynamics 365 for finance and operations

Scope:
Accessing global cache value in one scope (Alternate way for context instance)

Requirement: Without overlay
End user wants to print purchase order confirmation report with new menu item in PO confirmation journal, when user printing report from new menu item it has to print data for particular fields from different ISV solution.

Solution:
There are some possibility in dynamics 365 for finance and operations
1. Context
2. SysGlobalObjectCache
3. Duplicate SSRS report, DP class and controller class (Time consuming task)

2. SysGlobalObjectCache
/// <summary>
/// PurchPurchaseOrderController - Extension cls
/// </summary>
[ExtensionOf(classStr(PurchPurchaseOrderController))]
final class PurchPurchaseOrderController_Extension
{
    /// <summary>
    /// PurchPurchaseOrderController Method Main COC- Extension cLS
    /// </summary>
    /// <param name = "_args">
    /// caller args record
    /// </param>
    public static void main(Args _args)
    {
        SysGlobalObjectCache    PurchGlobalCache =  new SysGlobalObjectCache();

        PurchGlobalCache.remove("PurchPurchaseOrderController",["Report_GlobalParm"]);
        if (_args.menuItemName() == menuItemOutputStr(Cls_PurchPurchaseOrder))
        {
            PurchGlobalCache.insert("PurchPurchaseOrderController",["Report_GlobalParm"], ["Cls_PurchPurchaseOrder"]);
        }
        next main(_args);       
    }

}

//Note: Adding global cache, when its get call from new menu item.

//Note: In DP class, when system having cache in global for the particular transaction scope. then we can differentiate business logic according to that

/// <summary>
/// PurchPurchaseOrderDP - Extension cls
/// </summary>
[extensionof(classstr(PurchPurchaseOrderDP))]
final class PurchPurchaseOrderDP_Extension
{
    /// <summary>
    /// Insert the order header - COC method
    /// </summary>
    /// <param name = "_purchaseOrderHeader">
    /// A <c>PurchPurchaseOrderHeader</c> record to insert.
    /// </param>
    protected void insertOrderHeader(PurchPurchaseOrderHeader _purchaseOrderHeader)
    {
        SysGlobalObjectCache    PurchGlobalCache =  new SysGlobalObjectCache();
        container callerPurchMenu = PurchGlobalCache.find("PurchPurchaseOrderController",["Report_GlobalParm"]);
        if(callerPurchMenu)
        {
            //TODO- Your business logic
        }
        next insertOrderHeader(_purchaseOrderHeader);

        PurchGlobalCache.remove("PurchPurchaseOrderController",["Report_GlobalParm"]); // it should be remove
    }

}

Python for data science


Operations:
Output: Sample prints
print(5 + 5) #Addition
print(5 - 5) # subtraction
print(3 * 5) # Multiplication
print(10 / 2) #Division
print(18 % 7) #Modulo
print(4 ** 2) #exponentiation
# How much is your INR 100 worth after 7 years at the rate of interest per year is 10%?
print(100 * 1.1 ** 7)
Variables:
Str -  “sangeeth”, ‘gowtham’
Bool - True /False
Int – 1, 9
Float – 1.98, 8.78
Function: Type() - //to find unknown type of variables
List:
My_list = []
Ex:
= [1, 3, 4, 2]
= [[1, 2, 3], [4, 5, 7]]
= [1 + 2, "a" * 5, 3] = [3,aaa,3]
= ["room1", 11.2478, "room2", 8.459, "room3", 74.56, "room4", 74.698, "room5", 10.25]
Subset listing:
List Index get:  [0,1,2,3…] (Asc),  [….-3,-2,-1] [Desc]
List Slicing:  [Start (inclusive) : End (exclusive)]
My_list = ["room1", 11.2478, "room2", 8.459, "room3", 74.56, "room4", 74.698, "room5", 10.25]
Get_First_6list = My_list [:6] or Get_First_6list = My_list [1:6] or Get_last_list = My_list[6:]
Sub setting lists of lists:
My_list = [["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]
My_list[2][0]
My_list[2][:2]
List Manipulation:
My_list = ["room1", 11.2478, "room2", 8.459, "room3", 74.56, "room4", 74.698, "room5", 10.25]
To update list
My_list[<index position>] = “room5” or 9.897
Adding to new list by amending
My_list_1 = My_list + [“room6”, 24.5896]
Delete list
del(My_list [10]); del(My_list [11])
del(My_list [10:11])
del(My_list [-4:-2])
del(My_list [-3]); del(My_list [-4])
                Assigning one list to another
                                My_list _Copy = My_list (Note: while update My_list_copy it will affect My_list)
My_list_copy1 = My_list [:] (Note: This will copy all list values from My_list, but while update My_list_copy1 it will affect My_list)
Functions:
Max
Min
Sorted
len
Complex
Help(<functionName>) – to get details for function and arguments
Methods:
Upper (Ex: <StrVariables>.upper()), Count (Ex: <Variables>.count(..))
print(<list>.index(20.0)) – Index position finding
print(<list>.count(9.50)) – getting count of repeated times in list values
append(), that adds an element to the list it is called on,
remove(), that removes the first element of a list that matches the input, and
reverse(), that reverses the order of the elements in the list it is called on.
Packages:
import math
import numpy
from math import radians (Note: To import radians function from math package)
from scipy.linalg import inv as my_inv (Note: Suppose you want to use the function inv(), which is in the linalg subpackage of the scipy package)
Numpy: (Numeric Python)
Adv:
Powerful
Collection of values
Hold different types
Change add remove
Data Science
                Mathematical operation over collection
                Speed
NumPy array:
                Calculation over entire arrays
                Easy and fast for complex calculation
Syntax: Example
import numpy as np
np_array1 = np.array(array1)
Manipulation with np array = np_array1 + np_array2 (+, _ ,*, /, **)


Ex:
height = [180, 175, 165, 168, 189, 195]
weight = [74, 52, 42, 85, 96, 53]
import numpy as np
np_height = np.array(height)
print(np_height)
np_height_m = np_height * 0.0254
print(np_height_m)
np_height_m = np.array(height) * 0.0254
np_weight_kg = np.array(weight) * 0.453592
bmi = np_weight_kg / np_height_m ** 2
print(bmi[light])
2D – NumPy Array
N dimensional array
My_list = [[180, 78.4],           
           [215, 102.7],           
           [210, 98.5],           
           [188, 75.2]]
import numpy as np
np_ My_list = np.array(My_list)
print(type(np_My_list))
print(np_My_list.shape)
Output:
<class 'numpy.ndarray'>
(4, 2) (Shape will return total size of array (row, column))
               



Ex:
# Print out the 4th row of np_My_list
print(np_My_list [4,:])
# Select the entire second column of np_My_list
np_array1 np_My_list [:,1]
# Print out value of 3th player
print(np_baseball[2, 0])
Output:
[ 70 195]
75
Basic statistics:
Data Analysis:



Wednesday, October 17, 2018

Range/Formula/Style/Format in Excel cell through Code using OfficeOpenXML Dynamics 365 finance and operation


//Dynamics 365 for finance and operation

//Setting Up range for collection of cells to do style/format
            OfficeOpenXml.ExcelRange cellRange;
            cellRange = Worksheet.get_Cells().get_Item("A4:D5");

            Style.ExcelFont lisStyle = cell.Style.Font;
            lisStyle.Bold = true;
            lisStyle.Size = 12;
            lisStyle.UnderLineType = true;

//Setting Up formula in excel cell
           OfficeOpenXml.ExcelRange  cellRange;
           cellRange =  Worksheet.get_Cells().get_Item(currentRow, 4);
           cellRange.formula = "=SUM(D2:D10)";

//Setting Up format in excel cell
var column = cell.get_Worksheet().Column(cell.get_Start().get_Column());
var columnStyle = column.get_Style();
var columnNumberFormat = columnStyle.get_Numberformat();
columnNumberFormat.set_Format(DateFormatString);
columnStyle.set_HorizontalAlignment(ExcelHorizontalAlignment::Right);


Tuesday, October 16, 2018

Passing values between PreHandler & PostHandler method in Dynamics 365 FO


    /// <summary>
    /// method -getNum - pre event hanlder
    /// </summary>
    /// <param name="args">Event args</param>
    [PreHandlerFor(tableStr(DevCustomTable),tableMethodStr(DevCustomTable, getNum))]
    public static void DevCustomTable_Pre_getNum(XppPrePostArgs args)
    {
        args.addArg("parmPreArgs""Value 1234567890");
    }

    /// <summary>
    /// method - getNum- Post event hanlder
    /// </summary>
    /// <param name="args">Event args</param>
    [PostHandlerFor(tableStr(DevCustomTable),tableMethodStr(DevCustomTable, getNum))]
    public static void DevCustomTable_Post_ getNum (XppPrePostArgs args)
    {
        if (args.existsArg("parmPreArgs"))
        {
           Info(args.getArg("parmPreArgs"));
        }
    }

Friday, October 5, 2018

Get Method parameters in Event Handler class Dynamics 365 FO

/// <summary>
    /// Event handler for initFromLedgerPostingTransaction method
    /// </summary>
    /// <param name="args"></param>
    [PostHandlerFor(classStr(LedgerVoucherTransObject), methodStr(LedgerVoucherTransObject, initFromLedgerPostingTransaction))]
    public static void LedgerVoucherTransObject_Post_initFromLedgerPostingTransaction(XppPrePostArgs args)
    {
        LedgerPostingTransactionTmp     _ledgerPostingTransaction = args.getArg(identifierStr(_ledgerPostingTransaction));
    }

Convert Call stack to readable format in D365FO X++

//Input --container _xppCallStack = xSession::xppCallStack();  Public static str POL_formatXppCallStack(container _xppCallStack, int _skipFr...