Logic App: Converting CSV format table into custom delimiter column separator format

Nowadays logic apps are commonly used for data integration, especially for the Microsoft product. It allows an easy way to transport data from one system to another target system or file storage.

Most systems accept Xls or CSV file to migrate data but so is not the case in all cases. Recently I came across the requirement to separate columns with Tab delimiters. Unfortunately, there is no connector out of the box in the logic app available to convert the table and separate it with a custom delimiter.

Finally, I got a hack to achieve this target: The first step creates a CSV table with the data coming from the data source

As mentioned, we do not have any standard connector to convert with custom delimiter. We will initialize a variable connector. Then we will set a value of variable with following expression:

replace(body('Create_CSV_table'), decodeUriComponent('%2c'), decodeUriComponent('%09'))

or

replace(body('Create_CSV_table'),',','    ')

In replace function I’m taking ‘create CSV table’ as input and then replacing all the “,” with the custom delimiter required.

I hope above information shared is helpful

Do share your feedback with me
Mhq_hassan@hotmail.com

Covid 19 detection from chest x ray using Deep Learning

As part of my MS Computer Science Machine Learning course project, we were asked to read a research paper and then implement that paper. I was more interested in papers related to Covid 19 data. So, I came across with a paper which proposed the idea of predicting Covid 19 from the chest X ray. They consult with medical board which help them in finding some abnormalities on covid19 patients which gave them confidence to build a model that can predict Covid 19 from chest x-ray images.

Data Collection:

Publicly available data was used by the authors. They got 250 samples of Covid-19 chest x-ray and they get 5000 samples of other dieses from publicly available ChesPert dataset. As mention earlier they consult with medical team over the Covid-19 patient chest x ray’s, they remove around 66 chest x-rays because image was not clear. Training set contain 2000 non Covid images and 84 covid images. Covid 19 images sample is very low so data augmentation was applied to increase training sample to 420 on Covid19 images. Testing was done with 100 Covid 19 images and 3000 non Covid.

Classification Methods

Deep transfer learning was used for the predictions. Res18, Res50, SequeezeNet and DenseNet models were trained for the prediction. These models are based Convolution Neural Networks approach which is very much common for the image processing and feature extractions.

Pre trained model were used as we had a very limited data sample available for Covid=19. In which model parameter were fine tuned with new data.

Classification were made on 2 classes one “Covid” and other “Non Covid”.

Models were implemented using Pythorch library that is publicly available.

Results:

Results were good we got accuracy of 98% for all the models. Sensitivity and specificity rates were also promising. Models were evaluated using different parameters like ROC, probability, confusion matrices.

Limitation:

Data available for Covid-19 is very low that’s why we cannot reliable on results.

My contribution:

In adding to the reproduction of work done in research paper, I further trained model on VGG, Inception V3 and alexNet. These are also very good CNN based models and they gave accuracy up to 99%.

Further more I found new dataset with 1200 samples of Covid Chest X ray and use those images as a test on the already trained Res18 model but I got very bad results and accuray was dropped. Then I re train Res18 model with 500 new imagines keep the old images. Then testing was performed in which I was able to achieve accuracy of 98%.

Auther trained the Res18 model with 25 epochs, so changed the size of epochs to 30 again it aslo give good results.  

I hope you like this blog. I’m sharing links for research paper, code and dataset.

Paper:

https://www.sciencedirect.com/science/article/abs/pii/S1361841520301584

Dataset:

Dataset used by paper: https://www.dropbox.com/s/9w8nmj791c9ogsx/data_upload_v3.zip?dl=0

New data link: https://www.kaggle.com/tawsifurrahman/covid19-radiography-database

Code:

https://github.com/shervinmin/DeepCovid.git

Label design and printing, using Zebra Printer on D365 Fin Ops

This blog will cover, how we can design label using Zebra Printer Lable (ZPL) programming. Learning ZPL specifically for Dynamics 365/AX developer from stretch is an addionaly task. When you just want to create/design 1 label. In this article I’ll discuss how we can design label using 3rd party designer available and generate ZPL code.

Zebra printer design and printing require 3 basic things:
1. Setup printer
2. Design label
3. Printing label from AX/D365

Setup printer:
First of install zebra printer driver on system and make sure it also install zebra printer fonts.
Link setup: https://www.zebra.com/us/en/support-downloads/printers.html
After the driver is install configure printer using document routing agent, so we can give printing job/task from D365/AX.
Go to links for configuration:
Configure Printer on D365

In case printer is not available then follow link to configure zebra printer emulator.

Designing Label:

There so many Zebra label designer available, But I’ll use NiceLabel Designer 2019 for designing and generating code.

Download: https://www.nicelabel.com

Open nice label, do label page setup by clicking on create new label

Design your label as according to your requirement through designer tools available.

I have designed a demo label for this article. There are few things that needs to be taken care:

  1. When ever Textbox or barcode is use. Always select Font type starting with “Zebra” these fonts are specially for zebra printer and zebra printer programing is also easy when these special fonts are used.
  2. Set placeholder value for each textbox and barcode. This will be helpful to set values runtime on object/places on label. Placeholder can be defined by so many ways there is no specific instructions. In my case I’m defining placeholder in between “%” for e.g %placeholderName%. Example can be also seen on screenshot.

Once design is complete, we will export designer ZPL code.

Click on print icon

Print dialog will open. Select “Print to file” and click on Print. This will open “Save File” dialog. Save code in your desire folder. File with “.prn” extension will be saved.

Before jumping directly to print, we will verify code on online viewer.

Go to link: http://labelary.com/viewer.html

Open code file on this link.

You can see design is as according code. Let me explain some code objects so this will made easy to make changes directly on code.

^FT: This sets the field position on label. If you want to change position of then change values on ^FT tag.
Format: ^FTx,y,z

“x” and “y” are position on label, it will have numeric values. “Z” is use to define justification but normally we do not use it. 

Example: ^FT89,118

^FB: it is used to define field block. In this you will define width, height, alignment and character spacing.
Format: ^FBa,b,c,d,e

“a” defines width of field box.

“b” defines no of line in box.

“d” defines alignment. Values could be L (left), C (center), R(right), J (justify) and default value is L.

Example: ^FB213,1,0,C

^A: this command is use to set the font size and type in ZPL code.
Format^Afo,h,w
“f” defines font name values range from 0 – 9 or A through Z. Default values is 0

“o” defines orientation. Normally “N” is used.

“h” defines height of font.

“w” defines width of font.

Example: ^A0N,13,12

^BQ: This command is used to show QR code (For different type of bar codes code command is different).

Format: ^BQa,b,c,d,e 

“a” defines field orientation default value is “N”

“b” defines model default value is “2”

“c” defines magnification. You can enlarge your QR code by setting value here. Values range between 1 – 10. Default values are: 1 on 150 dpi printers, 2 on 200 dpi printers, 3 on 300 dpi printers and 6 on 600 dpi printers
Example: ^BQN,2,3

^FS: This command is used to define end of field definition. This will be used when every field is end.

Example: ^FT15,27^A0N,13,12^FB213,1,0,C^FH\^FD%LabelTitle%^FS

Line break:
There is no specific command which can help you in giving line break between the lines in large string. To achieve this, you need to add new Field command between the text at runtime. You have to find the place on string which needs to be on new line then you have to calculate the “Y“ position (position on label, where new line will start otherwise it will overwrite current line). 

For example: I have two lines which I want to print on label. After each sentence I want to give line break. “Hi, my name is Hassan.I’m a dynamics Ax/D365 technical consultant. “

In ZPL code:

^FO16,100^A0N,20,19^FB530,12,0,J,0^FDHi, my name is hassan.^FS^FO16,120^A0N,20,19^FB530,12,0,J,0^FDI’m a dynamics Ax/D365 technical consultant^FS

before 2nd sentence there is a code/command “.^FS^FO16,120^A0N,20,19^FB530,12,0,J,0^FD”
In which ^FO16,120: 120 is Y position, where for first sentence Y position was 100
This thing can be manage through x++ coding, write a logic which iterate string and add new line command where it is need and calculate Y position based on number of lines. In my case 1 line take 20 points.

Printing label from AX/D365

Last thing is calling printing job from AX/D365 because end user will perform printing activity on from Dynamics. Zebra printing task require runtime resolution over the internet. On FinOps out of the box it only works for advance warehouse module. But you don’t need to care about this because we just need to call one method.

Code:

str labelLayout = "CT~~CD,~CC^~CT~^XA~TA000~JSN^LT0^MNW^PON^PMN^LH0,0^JMA^PR5,5~SD15^JUS^LRN^CI^XZ^XA^MMT^PW240^LL0240^LS0^FO8,4^GB225,141,2^FS^FO9,40^GB221,0,2^FS^FT89,118^BQN,2,3^FH\^FDLA,%barCode%^FS^FT15,27^A0N,13,12^FB213,1,0,C^FH\^FD%LabelTitle%^FS^FO9,114^GB221,0,2^FS^FT15,133^A0N,13,12^FB213,1,0,C^FH\^FD%Instructions%^FS^PQ1,0,1,Y^XZ";

labelLayout = strreplace(labelLayout, "%LabelTitle%", "Test Label");
labelLayout = strreplace(labelLayout, "%barCode%", "123456");
labelLayout = strreplace(labelLayout, "%Instructions%", "My label printing blog");
WHSDocumentRouting::printLabelToPrinter("Zebra Test Emulator", labelLayout);

I initialize string variable with ZPL code. Then replace placeholder set on printing objects with the actual values that need to be print on label. In last we call print label task by calling “printLabelToPrinter” in WHSDocumentRouting framework class. It takes two parameter first printer name and second label code.

I hope this blog will be helpful.

Do give your feedback and feel free to contact me on:
Email: mhq_hassan@hotmail.com
LinkedIn: https://www.linkedin.com/in/muhammadhassannaviwala/

Special thanks to my colleagues
Muhammad Usama Yameen (Usama.Yameen@mazikglobal.com)
Mustafa Ali Asghar (mustafa.ali@mazikglobal.com)

Configuration of Zebra Printer emulator on D365 – FinOps

This blog is beneficial for both developers and functional consultant. Who have development or testing task related to zebra printer but printer physically not available.
Google chrome has the Zebra printer emulator extension available, which require very simple steps to configure.
Open google and search “ZPL printer chrome app” and select very first link.

Click on Install, in screenshot it’s showing “launch app” because its already install.

After the installation complete, open emulator 

On emulator “On” and “Off” button is used to enable and disable printer and Hamp button opens setting.

Now open printer settings. And note down Network Ip and Port.

Now we will configure emulator as printer.
Click start button on windows and search “Printer and Scanner” and open the setting

Now click on “Add a printer or scanner”, it will find all the printer available on your network.

We do not have emulator available over the network, so we will click on “The printer that I want isn’t availabale”.

Dialog box will open, now select “Add a printer or scanner with manual settings”

Now select printer port. Select “Create new port” and under the “type” select “Standard TCP Ip port”.

In Host Name or Ip Address field we will give Ip address that was on emulator settings, in my case that is 127.0.0.1

Press next, now this will take some time to scan setting.

Select “custom” and go to settings.

Verify port name and printer name.

Now select “Replace the current driver”. Click next

Under printer sharing select do not share this printer. Click Next

Give name to your printer.

Click Finish to complete setup.

Once Printer installation is complete on system. We will configure emulator on FinOps through document routing agent. (Go to this link if you don’t know how to install and configure document routing agent.)

After registration of printer gets complete, go to FinOps and

Navigate to Organization Administration -> Setup -> Network Printer

You will find printer that was selected from routing agent. Now select your printer and change value of “Active” column to “Yes”. This will enable the printer on FinOps.

Zebra printer is configured now try printer something from your FinOps.

Do share your feedback:
mhq_hassan@hotmail.com

Printer configuration on D365 – FinOps

In this blog we will discuss about how to configure on premises printer to the Microsoft dynamics 365 FinOps. This feature enables you to connect your printer with finOps and perform printing task.

In my case I connect Zebra printer with FinOps to perform some label printing task (How to design and print label using Zebra printer will cover in other blog in the series).

Let’s begin..!!

At first step you must install “Document Routing Agent” on your system. We will get setup from FinOps.

Navigate to Organization Administration -> Setup -> Network Printer -> Download document routing agent installer (Application Action Pane)

This will automatically download “Document Routing Agent” setup.

Open wizard and install routing agent.

After installation gets complete. Open routing agent and click on settings. Then provide

FinOps Url: https://xxxxxxx-xxx-xx.cloudax.dynamics.com

Azure AD Tenant: This is AD domain name like: [organizationDomainName].com. Contact your IT team to provide AD tenant.

After settings, sign in with your FinOps account.

Click to printer. It will bring all the printer install on the system. So, select the printers from list and click on register

After registration of printer gets complete, go to FinOps and

Navigate to Organization Administration -> Setup -> Network Printer

You will find printer that was selected from routing agent. Now select your printer and change value of “Active” column to “Yes”. This will enable the printer on FinOps.

I hope this blog would be helpful.

Do share your feedback with me
Mhq_hassan@hotmail.com

Employee clock-in and clock-out in D365 / x++

This blog will help you to clock in and clock out employee in d365 programmatically. Following method is dual purpose, it can clock in clock out employee. First it check if employee has any activity, if activity found then it clock out other wise it clock in.

public boolean clockInClockOutRegistration(
        JmgTermLoginCardNo _badgeId)
    {
        JmgEmployee                 jmgEmployee;
        JmgJobBundle                jmgJobBundle;
        HcmWorker                   hcmWorker;
        JmgRegistrationSetup        jmgRegistrationSetup;
        JmgRegistrationSetup        employeeSetup;
        boolean                     isSuccessful = false;
        utcdatetime                 registrationTime = DateTimeUtil::newDateTime(JmgProfileSeconds::getSysDate(), JmgProfileSeconds::getSysTime());
        str                         returnMessage;
        
        try
        {
        
            jmgEmployee = JmgEmployee::findCardNo(_badgeId);
            hcmWorker = jmgEmployee.HcmWorker();
            jmgRegistrationSetup = JmgRegistrationSetup::find('');
            employeeSetup = JmgRegistrationSetup::find(JmgEmployee::find(jmgEmployee.Worker).RegistrationSetupId);

            ttsBegin;
            jmgJobBundle = new JmgJobBundle(jmgEmployee.Worker, false, false, false, employeeSetup ? employeeSetup : jmgRegistrationSetup);
        
            // Checking if employee is already clocked in or not
            if (jmgJobBundle.emplClockedIn())
            {
                if(!MzkMESHelper::activeDirectJobRegistration(jmgEmployee.Worker))
                {
                    // Performing clock-out
                    jmgJobBundle.addJob(JmgJobTable::find(JmgIpcActivity::findSignOutJobId()));
                    isSuccessful = jmgJobBundle.makeRegistrations(DateTimeUtil::date(registrationTime), DateTimeUtil::time(registrationTime));

                    if (isSuccessful)
                    {
                        info ("Sucessful clock out "+time2Str(DateTimeUtil::time(registrationTime),-1,-1));
                    }
                    else
                    {
                        error("Operation failed");
                    }
                }
                else
                {
                    error("@SYS302293");
                }
            }
            else
            {
                // Performing clock-in
                jmgJobBundle.addJob(JmgJobTable::find(JmgIpcActivity::findSignInJobId()));
                isSuccessful = jmgJobBundle.makeRegistrations(DateTimeUtil::date(registrationTime), DateTimeUtil::time(registrationTime));
            
                if (isSuccessful)
                {
                    info ("Sucessful clock "+time2Str(DateTimeUtil::time(registrationTime),-1,-1));
                }
                else
                {
                    error("Operation failed");
                }
            }
            ttscommit;

        }
        catch (Exception::Error)
        {
            error("Operation failed");
        }

        return isSuccessful;
    }

Generate invent batch Id programmatically in d365/x++

Following code can be used to create invent batch id for production order.

static InventBatchId generateActiveInventBatch(
        ProdTable     _prodTable)
    {
        InventBatchId  inventBatchId;
        InventBatch    inventBatch;
        NoYes          isBatchActive;
        InventNumGroup inventNumGroup;

        FieldId checkInventBatch = fieldNum(InventDim, InventBatchId);

        try
        {
            isBatchActive   = ecoResTrackingDimensionGroupFldSetup::findByDimensionGroupFieldId(InventTable::find(_prodTable.ItemId).trackingDimensionGroup(), checkInventBatch).IsActive;

            if (isBatchActive)
            {
                inventNumGroup = InventNumGroup::find(InventTable::find(_prodTable.ItemId).BatchNumGroupId);

                inventbatchId  = inventNumGroup.buildNumberParameters(DateTimeUtil::date(_prodTable.CreatedDateTime), _prodTable.ProdId, _prodTable.InventTransId, extendedTypeNum(InventBatchId));

                inventBatch    = InventBatch::findOrCreate(inventbatchId, _prodTable.ItemId);
            }
        }
        catch (Exception::Error)
        {
            inventBatchId = "";
        }

        return inventBatchId;
    }

Generate licence plate number for production order in D365

License plate can be generated by following code for production job and production order.

static WHSLicensePlateId generateActiveLicensePlate(
        ItemId            _itemId,
        WrkCtrId          _workCellId,
        JmgJobId          _jobId,
        WHSLicensePlateId _licensePlateId = '')
    {
        WHSLicensePlateId licensePlateId;
        NoYes             isLicenseActive;
        WHSLicensePlate   wHSLicensePlate;

        try
        {
            FieldId checkLicensePlate = fieldNum(InventDim, LicensePlateId);
            // check if item is license plate enable.
            isLicenseActive = 
 EcoResStorageDimensionGroupFldSetup::findByDimensionGroupFieldId(InventTable::find(_itemId).storageDimensionGroup(),checkLicensePlate).IsActive;

            if (isLicenseActive)
            {
                // Generating new license plate id
                licensePlateId =  NumberSeq::newGetNum(WHSParameters::numRefWHSLicensePlateId()).num();
                whsLicensePlate.clear();
                whsLicensePlate.initValue();
                whsLicensePlate.LicensePlateId = licensePlateId ;
                whsLicensePlate.insert();
            }
             
        }
        catch (Exception::Error)
        {
            licensePlateId = "";
        }

        return licensePlateId;
    } 

Get Sales Price and Sales Trade Agreement Price in pragmatically D365 / x++

When we create sales line, sales price value will default on basis of following hierarchy:

  • First system will check if there is sales agreement for item.
  • If sales agreement not found, then it checks item sales price define on item setup (Release product).
  • If sales price not found on item setup then field will remain blank, user will enter sales price.

Price can be changed even if its default from sales agreement or item setup. If you want to get sales price programmatically according to above mention hierarchy, then following code is useful:

public static Price findSalesPrice(SalesLine _salesLine)
    {
        Price               retPrice;
        PriceDisc           priceDisc;
        CustTable           custTable = custTable::find(_salesLine.CustAccoun);
        PriceDiscParameters priceDiscParameters = PriceDiscParameters::construct();

        priceDiscParameters.parmModuleType(ModuleInventPurchSales::Sales);
        priceDiscParameters.parmItemId(_salesLine.ItemId);
        priceDiscParameters.parmInventDim(_salesLine.inventDim());
        priceDiscParameters.parmPriceDiscDate(_salesLine.ShippingDateRequested);
        priceDiscParameters.parmQty(_salesLine.QtyOrdered);
        priceDiscParameters.parmAccountNum(_salesLine.CustAccount);
        priceDiscParameters.parmCurrencyCode(_salesLine.CurrencyCode);
        priceDiscParameters.parmUnitID(_salesLine.SalesUnit);
       
        priceDisc = PriceDisc::newFromPriceDiscParameters(priceDiscParameters);

        if (priceDisc.findPrice(custTable.PriceGroup))
            retPrice = priceDisc.price();
        else if (priceDisc.findItemPrice())
            retPrice = priceDisc.price();

        return retPrice;
    }

    If trade agreement sale price is required for sales item, then following code will work   

public static Price findTradeAgreementPrice(SalesLine _salesLine)
    {
        Price               retPrice;
        PriceDisc           priceDisc;
        CustTable           custTable = custTable::find(_salesLine.CustAccoun);
        PriceDiscParameters priceDiscParameters = PriceDiscParameters::construct();

        priceDiscParameters.parmModuleType(ModuleInventPurchSales::Sales);
        priceDiscParameters.parmItemId(_salesLine.ItemId);
        priceDiscParameters.parmInventDim(_salesLine.inventDim());
        priceDiscParameters.parmPriceDiscDate(_salesLine.ShippingDateRequested);
        priceDiscParameters.parmQty(_salesLine.QtyOrdered);
        priceDiscParameters.parmAccountNum(_salesLine.CustAccount);
        priceDiscParameters.parmCurrencyCode(_salesLine.CurrencyCode);
        priceDiscParameters.parmUnitID(_salesLine.SalesUnit);
       
        priceDisc = PriceDisc::newFromPriceDiscParameters(priceDiscParameters);

        if (_priceDisc.findPriceAgreement(custTable.PriceGroup,InventDim::inventDimIdBlank()))
        {
            retPrice = _priceDisc.price();
        }

        return retPrice;
    }

Hello World

I’m Muhammad Hassan Naviwala, I have completed my BS Computer Science from FAST-NU. Beside being a technical person I enjoy doing public speaking. I believe in contributing and giving back to society that’s why I have start doing blogs to share what I have learned in Microsoft Dynamics.

I started my career as a software engineer in 2017 at The Kidney Center Hospital where we do in-house development of HMS on .NET technology. For the love of management system I join Mazik Global in 2019 and got introduced to Microsoft Dynamics AX and D365. Since then I’m working on Dynamics and getting hands on experience of customization, migration, iterations and custom services.

As mentioned above I love doing public speaking. I have experienced hosting and share stage as “Master of ceremony”. Large crowd i faced as a host was 1500. I also enjoy giving training sessions and I love speaking on entrepreneurship, career and education ,problem solving skills and technical topics.

I start teaching in 2018 as visiting faculty at Scepter College where i teach “Computer Coding and Programming” course was design teach basic blocks of computer programming. Topics i love teaching are computer programming, databases and algorithm design.

Inspired from “God loves those who love their fellow beings” I’m engaged in numerous social activities. I’m a part of Rotaract Club where we conduct events regarding medical and professional awareness. I believe you are worthy if you are contributing to society in a positive. If you are not contributing then your being and not being is same.

In fact purpose writing blog is that i want to contribute to dynamics community. I want to share my experience and problems which i solved with others.

Design a site like this with WordPress.com
Get started