How to build a PowerApp that generates product labels. Part 3: Adding an embedded PowerApp to a MSDyn365FO page

In the previous post we improved our PowerApp by adding Microsoft Flow to it that extracts data from Finance and Operations based on the information entered to the Item number field.

In this post we will embed PowerApp to MSDyn365FO on the Released products page. In addition, we will pass item number value from the selected record on the Finance and Operations page to the app automatically when it opens.

Before we even open MSDyn365FO we should do one simple change to our PowerApp. For the “OnStart” action we should add following expression:

If(!IsBlank(Param("EntityId")), Set(FlowValues,'PowerApp->Getarecord,RespondtoPowerApps'.Run(Param("EntityId"))))

Where Param(“EntityId”) represents the value passed from MSDyn365FO as an Input for our PowerApp. You can find additional informaiton about Embedded PowerApps in this docs article.

ZPLAPP_AddInputToApp

Then we also should set default value for the Item number to Param(“EntityId”), this will automatically fill in Item number in the app and trigger our flow to extract rest of the data.

ZPLAPP_SetItemDefaultsfromFO

After we did all the changes we should save and publish the app.

Next step would be to open Finance and Operations and insert the PoweApp:

ZPLAPP_InsertPowerAppToD365FO

In the opened dialog enter PowerApp name that you want to display in MSDyn365FO, AppId (you can find it in PowerApps details), Input value that you want to pass to the app (Item number) and application size (Thin, since in the very beginning we choosed Phone layout for our app).

Unfortunately, we can pass only one field to PowerApp, however, now it is not a big deal for us since we can extract additional information with the help from MS Flow.

ZPLAPP_InsertPowerAppDialog

Click Insert and reload the page. Now you can open the app from MSDyn365FO.

ZPLAPP_OpenApp

Once again, our fnal result:

ZLPAPP_FinalApp

That is all. As you can see we can use PowerApps to cover various business requirements without a developer assistance, however, it requires some creativity to combine new tools into one complete solution.

Advertisements

How to build a PowerApp that generates product labels. Part 2: Use Microsoft Flow to get data from MSDyn365FO

In the previous post we created a PowerApp that generates product label based on the information entered manually in the app fields. In this post we will enhance the app to extract Product name and Origin values from MSDyn365FO based on the Item number, i.e. rather than populating all tree fields manually we will enter only Item number. To make this work we will need a help from Microsoft Flow.

Let’s go to https://flow.microsoft.com/ and create a new flow:

ZPLAPP_MSFlow

We will add PowerApp as a trigger and use “Get record” to extract the data from MSDyn365FO. Then we should specify connection to our MSDyn365FO instance and data entity name that we will use to get the data from the system. In this example I will use ReleasedDistincProductV2 to get Product search name and Origin of the item.

Since ReleasedDistincProductV2 entity uses Legal entity and Item number field as a key we should specify it in the “Object Id” property. In this case I have hardcoded Legal entity name and also added Getrecord_Object_Id that represents the value passed from the PowerApp.

In the response we map output variables with entity fields that “Get record” returns (i.e. ProductSeachName and Country/Region of Origin.

Flow templte looks as follows:

ZPLAPP_MSFlowTemplate

Let’s test the Flow to verify that it returns correct information:

ZPLAPP_TestMSFlowTemplate

Click “Save & Test” and enter Item number that exists in MSDyn365FO:

ZPLAPP_RunMSFlow

Click “Run flow” gives:

ZPLAPP_FlowStarted

After MS Flow configuration is completed we need to modify PowerApp to use it. As you remember, we are going to trigger MS Flow when the Item number field value is changed. Therefore, we should select Item number text input field and for the “OnChange” action click on the “Flows” button:

ZPLAPP_AddFlowtoPowerApp

In the Opened form select the Flow that we previously created:

ZPLAPP_AssosiateFlowDialog

After that you will notice that “OnChange” expression has been prepopulated automatically to call the Flow selected. Now, we need to modify it to pass the value from Item number text input field to the Flow and save the result returned by the Flow to the variable. The final expression looks like:

Set(FlowValues,'PowerApp->Getarecord,RespondtoPowerApps'.Run(ItemId.Text))

Where ‘PowerApp->Getarecord,RespondtoPowerApps’.Run(ItemId.Text) executes the Flow. Function “Run” accepts parameter value that is passed to the Flow (value from Item number text box). Function “Set” is used to set “FlowValues” variable with the result of Flow execution. More information on set function could be found here.

ZPLAPP_SetFlowVariable

Next step is to set Product name and Origin fields with the values returned by the Flow:

ZPLAPP_SetValuesFromFlowVariableProductSearchName

ZPLAPP_SetValuesFromFlowVariable_COO

Done. If we run the app we would get the following result:

ZPLAPP_Part2Final

To summarize: In this post we have created Microsoft Flow that gets the data from MSDyn365FO, then we have modified the app to pass Item number information to the Flow and automatically populates Product name and Origin with the data from the system.

In the next post we will embed our PowerApp in Dyamics 365 for Finance and Operations to the Released products form and will pass Item number from the record selected in the grid to the app.

How to build a PowerApp that generates product labels. Part 1: Create an app

Have you ever had a requirement to preprint a label for the product beforehand? Warehouse management module has a lot of powerful features. However, out of the box you can only print labels as a part of mobile device flow, for example, when you receive a purchase order, report as finish a production order or perform inventory movement.

The scenario I had as follows: manufacturing company produces bags of seeds. In the production, on the bagging line, every bag is filled with the seed and the label is attached to the bag when its closed. Once the bag gets off the bagging line it is placed on the pallet. When the pallet is full, it is wrapped and labelled with the pallet label. Here how it looks like:

ZPLAPP_BagLabel

Therefore, we need to produce two different labels: bag label and pallet label. The pallet label can be printed when we RAF on the mobile device, but bag label should be ready when we start production.

On our project we did a modification that prints a label from MSDyn365FO, but when PU14 was released and we got the ability to embed PowerApps to MSDyn365FO I wondered, if we could create a PowerApp that generates product label. In this series of posts, I will try to show you what could be done when we use Microsoft Flow, PowerApps and MSDyn365FO together.

If you want to see end result, here you go:

ZLPAPP_FinalApp

If you are interested to know how it was done keep reading!

Design a label

Firstly, you need to design your label layout. You can use any software that does this, I’ve installed 30 days trial version of NiceLabel Designer Pro. Next step would be to get our label in ZPL language as a text format.

I’ve decided to create a simple label with size 50 mm x 25 mm, that has Item number as a text and QR code, Product name and Country of origin on it:

ZPLAPP_LabelDesign

As you see, in the label I used placeholders like $[Name]$, I did it as it was easier for me to identify what information I should replace with the actual data later on. So, the label in ZPL language looks as follows:

CT~~CD,~CC^~CT~
^XA~TA000~JSN^LT0^MNW^MTD^PON^PMN^LH0,0^JMA^PR4,4~SD15^JUS^LRN^CI0^XZ
^XA
^MMT
^PW400
^LL0200
^LS0
^FT14,38^A0N,28,28^FH\^FDProduct number:^FS
^FT14,126^A0N,28,28^FH\^FDName: ^FS
^FT14,176^A0N,28,28^FH\^FDOrigin:^FS
^FT302,106^BQN,2,4
^FDLA,$ItemId$^FS
^FT111,84^A0N,28,28^FH\^FD$ItemId$^FS
^FT114,126^A0N,28,28^FH\^FD$ProductName$^FS
^FT114,176^A0N,28,28^FH\^FD$CountryOfOrigin$^FS
^PQ1,0,1,Y^XZ

Create a PowerApp

After the label is designed we can start building our PowerApp. Login to https://powerapps.microsoft.com and create new blank PowerApp with Phone layout:

ZPLAPP_CreatePowerApp

Our PowerApp will have one main screen with tree fields on it, where we can enter product information (manually for now) and preview label as an image:

ZPLAPP_DesignPowerApp

ZPLAPP_Table

To be able to display a label in the PowerApp we will use Labelary API that returns label image in png format. I’m using this service because it is free. Also, it has some limitations regarding to the label size and number of requests per second, so you may consider to licence this API for private use or use another API. The format of the request as follows:

http://api.labelary.com/v1/printers/dpmm/labels/widthxheight/index/zpl

The parameters we replace in this request are:

  • dpmm: the value is picked based on the printer characteristics, we will set it to 8dpmm.
  • width, height: label dimensions. Since our label is 50mmx25mm we will set it to 1,9685 and 0,984252 inches respectively.
  • Index: set to 0 by default.
  • ZPL: set it to ZPL label that we designed above.

However, as you remember in the beginning we have used placeholders in the label design, therefore, before using it we should replace those placeholders in the request with the values from respective Text inputs values, for example:

$ItemId$ =  " & EncodeUrl(ItemId.Text) & "

Our final request will look like:

http://api.labelary.com/v1/printers/8dpmm/labels/1.9685x0.984252/0/%10CT~~CD,~CC%5E~CT~%20%5EXA~TA000~JSN%5ELT0%5EMNW%5EMTD%5EPON%5EPMN%5ELH0,0%5EJMA%5EPR4,4~SD15%5EJUS%5ELRN%5ECI0%5EXZ%20%5EXA%20%5EMMT%20%5EPW400%20%5ELL0200%20%5ELS0%20%5EFT14,38%5EA0N,28,28%5EFH/%5EFDProduct%20number:%5EFS%20%5EFT14,126%5EA0N,28,28%5EFH/%5EFDName:%20%5EFS%20%5EFT14,176%5EA0N,28,28%5EFH/%5EFDOrigin:%5EFS%20%5EFT302,106%5EBQN,2,4%20%5EFDLA," & EncodeUrl(ItemId.Text) & "%5EFS%20%5EFT111,84%5EA0N,28,28%5EFH/%5EFD" & EncodeUrl(ItemId.Text) & "%5EFS%20%5EFT114,126%5EA0N,28,28%5EFH/%5EFD" & EncodeUrl(ProductSearchName.Text) & "%5EFS%20%5EFT114,176%5EA0N,28,28%5EFH/%5EFD" & EncodeUrl(COO.Text) & "%5EFS%20%5EPQ1,0,1,Y%5EXZ

Once we built our request we can set it as Image property for the Image control:

ZPLAPP_ImagePropertyZPLAPP_ImageLink

Now, if we enter the data in the input boxes of PowerApp screen we would see below result:

ZPLAPP_FinalApp

One more thing, that we can do, is to add a “Get label” button to the app that opens label in the separate tab of the browser. To do this we should set “On select” action for the button to Launch(Image_ZPLLabel.Image). More info on what Launch function does is here.

ZPLAPP_AddLaunchButton

Rather than opening label in a new tab you can sent it to a network printer, but that is a topic for a different blog post.

To summarize, in this post we have designed ZPL label and have built a PowerApp that accepts product information entered manually, draws the label and generates image file in png format in the separate tab in the browser.

In the next post we will enhance our app to extract Product name and Origin information from the MSDyn365FO by using Microsoft Flow. Stay tuned.

Split of transfer order registration and receiving by using a warehouse app

Those of you who have worked with advanced warehouse functionality already know that when you receive a transfer order on a warehouse app the system posts transfer receipt immediately after you process a line on the mobile device. This behavior differs from the purchase receive where we register the stock before product receipt posting.

Guess what? We can now split registration and receiving for the transfer order and have similar process to the PO receipt. This feature was introduced in 8.0 release. If you go to the warehouse management parameters you could see new parameter there named “Transfer order receiving process” that has 2 options: “Split the registration and receiving” and “Combine the registration and receiving”.

TOReceivingProcess_WHSParameters

Let’s check how it works. I am using standard demo data and I’ve set parameter mentioned above to “Split the registration and receiving”.

Then I have created a transfer order between two warehouses that are using advanced warehouse management processes. I have shipped (posted transfer order shipment) inventory from the “From warehouse”. At that stage the status of the transfer order is Shipped.

TOReceivingProcess_TransferOrderShipped

After that, by using License plate receiving and put away menu item (setup is below), I will receive the stock to the “To warehouse”.

TOReceivingProcess_ManuItem

To do this, I will log in to the mobile device and start LP receiving process:

Enter License plate number (target LP number that was shipped from the “From warehouse”), confirm Items and quantity by clicking OK.

TOReceivingProcess_WHSAPPReceive

Since we are using License plate receiving and put away menu item we also need to complete put away work on the mobile device as a part of this flow. Complete pick and put steps by clicking OK.

TOReceivingProcess_WHSAPPPutaway

Done. Now we are ready to check what had happened in the system.

The Transfer receipt work was completed on mobile device and as expected, it is in “Closed” status.

TOReceivingProcess_WHSWork

The transfer order itself still has status “Shipped”. Furthermore, if we check inventory transactions for the transfer order line that was received with the warehouse app, we could see following information:

Transfer order shipment:

  • Warehouse 24, Sold – TO shipment from the “From warehouse”
  • Warehouse 27, Purchased – TO receipt to “In transit” warehouse

Transfer order receive:

  • Warehouse 27, Picked – TO issue from “In transit” warehouse
  • Warehouse 61, Registered – TO registration to the “To warehouse”

TOReceivingProcess_InventTrans

Now, to complete this transfer order we should post transfer order receive. This can be done from the transfer order form:

TOReceivingProcess_TOReceive

Set Update to “Registered” to pick up only registered lines:

TOReceivingProcess_TOReceivePosting

Note: you can also setup TO receiving posting as a batch job that runs periodically and updates all registered transfer lines.

As a result, we have a transfer order in received status:

TOReceivingProcess_TransferOrderReceived

One more important thing to know and pay attention to: this feature supports only License plate receiving process, i.e. it does not work with Transfer order receiving or Load item receiving mobile device flows, at least for now😊.

Call center: Fraud check to put sales orders on hold automatically

Fraud check functionality allows to define criteria which help to identify fraudulent sales orders. The orders that do not comply to the fraud check rules can be placed on-hold automatically and be reviewed later by responsible person. Orders that are On-hold are locked for further processing and cannot be processed (released, shipped, etc.) until the hold code is cleared.

There are couple of settings and key configurations that should be in place to use fraud check functionality. First of all, it works only with sales orders that are created through Retail call center channel. In addition, call center channel should have “Enable order completion” parameter activated:

MRCAutoHold_CallCenter

In Call center parameters form on the Holds tab the “Fraud check” parameter should be enabled and Manual fraud hold code, Fraud hold code, Minimum score values should be set.

To understand why do we need to set it all up we should know how fraud check logic works in the system. We setup scores for static fraud data like phone, email, zip code, extended zip code and for all fraud rules. When the user completes the order, its information is evaluated against those fraud rules, the system sums up scores for all “matched” conditions and calculates the total score. If total score of the sales order exceeds Minimum score defined in parameters – sales order is automatically placed on hold with respective fraud hold code.

MRCAutoHold_CallCenterParameters

Going back to the setup, there are two fraud criteria types: Static fraud data and Fraud rules.

Static fraud data

Static fraud data is the fixed list of values like: phone, email, zip code and extended zip code. In this table we can store information known from previous fraudulent orders and every record in this table is scored separately.

On the below form we see that phone number 555555555 can be considered as fraudulent and it has value 50 as a score:

MRCAutoHold_StaticFraudData

Fraud rules

Fraud rules are flexible rules configured by the user. To configure fraud rule we should setup following information:

  • Variables, as a variable you can set any field in any table, for example customer group of the customer:

MRCAutoHold_Variables

  • Conditions, can be any criteria that you would like to validate, for example:

Condition 1:  Sales order for Mode of delivery = 10 (Truck).

MRCAutoHold_Conditions1

Condition 2: Sales order totals exceeds 500.

MRCAutoHold_Conditions2

  • Fraud rule, uses variables and conditions to build evaluation rules, it can be created for the order or lines level.

Let’s say that all orders with total amount greater than 500 (in any currency) and delivery mode “10” (Truck) should be placed on hold automatically.

We will score it as 150 and apply the rule on the header level. As you may notice in the conditions area I have listed both conditions created above with logical relation “AND”, meaning that both criteria should be met.

MRCAutoHold_Rules

To see it in action we will create a sales order and complete it:

MRCAutoHold_SalesOrder

Right after we click submit button below dialog pops up to inform us that order was placed on hold:

MRCAutoHold_OrderComplete

Now, from the sales order we can open Order holds form where we can review the list of fraud rules that were triggered for this order:

MRCAutoHold_OrderHolds

That is all, to clear a hold code you can click Clear hold button on the order holds form.

I have been asked couple of times whether it is possible to put orders on hold automatically, and the answer is yes, however we have some restrictions that I mentioned before, i.e.:

  • We should use call center functionality
  • We should have “Enable order completion” activated for the call center channel

In addition to the that, you always need keep in mind that any additional validation can cause performance decrease. Therefore, if you setup a lot fraud rules in the system, do not be surprised that order completion function works slower than it was before, since every time you complete the order the system should go through all those conditions and evaluate them.

WHS: Partial load shipment

Partial shipment of a transport load is a new functionality added in 8.0 release. By setting this up we can now handle partial shipment of the same load or perform picking of an outbound work attached to different loads in MsDyn365FO and ship them together.

To be able to use this functionality, firstly you need to “mark” loads that should handle partial shipments. This can be done manually by setting up Loading strategy to “Partial shipping allowed”:

WHSTransportLoad_StrategyEnum

Note: you cannot change Load strategy for the load if you already completed at least one work that referes to it.

Secondly, to use transport loads functionality you should create separate mobile device menu item for Transport loading:

WHSTransportLoad_TransportLoadingMenuItem

Note: This menu item has a parameter “Allowed ship confirmation type”, do not mix it up with WHS Shipment confirmation, since Transport loading menu creates new “Transport load” that contains reference to the WHS Load and Shipment. You can find the list of transport loads under: Warehouse management > Loads > Transport loads.

Transport loading mobile device menu item accepts only works created for loads with “Partial load shipping allowed” loading strategy, i.e. if you scan a work for load with “Full load shipping only” strategy you will get next error:

WHSTransportLoad_LoadStrategyError

Another thing is that you can process only work with put away location that has the same type as final shipping location from Warehouse management parameters:

WHSTransportLoad_WHSParameters

For example, if you try to complete first pick and put pair steps of the work below, by using Transport loading menu item on a mobile device, you will get an error:

WHSTransportLoad_WHSWorkPutawayError

WHSTransportLoad_WHSWorkPutawayErrorMessage

However, after you complete first pick and put pair with User or System directed mobile device menu item, you can proceed with completing of another pick and put pair by using Transport loading.

Let’s review couple of scenarios that we can cover with this functionality.

Scenario 1. Partial shipment of the sales order load

We have received a sales order for high-volume items and we know that we need more than 1 truck to deliver it. We have picked all stock to staging area and when the transport comes on site we can load the stock to it. Considering that we need multiple trucks for this delivery and depending upon trucks availability we can either load both trucks in parallel or sequentially after each other.

So I have created a sales order and released in to the warehouse, then I have changed loading strategy to partial shipping allowed for this load.

WHSTransportLoad_Sc1Load

The load has 2 works attached to it:

WHSTransportLoad_Sc1LoadAndWork

I have completed pick to staging for one work and now ready to load items to the Truck 1. To do this I will use Transport loading menu item on the mobile device:

WHSTransportLoad_TransportLoadMenu

First thing that you need to do, when you use Transport loading menu item, is to specify Transport load id. It is not the same number as WHS load id, the system accepts any value entered to this field as it creates new Transport load record. Therefore, you should define what information you would like to capture, whether it is an existing transport load number or something else.

Note: make sure that you use unique identifier since you won’t be able to use same number after the load is shipped and you’ll get an error like: “Transport load no longer eligible for transport loading. “

I will set transport load id to Truck-1, then Scan work id and complete the pick:

WHSTransportLoad_Sc1TransportLoadProcess1

WHSTransportLoad_Sc1TransportLoadProcess2

When work is completed we can go to Transport loads form and find there “Truck-1” transport load. At that stage it has “In progress” status since we have not confirmed it yet.

WHSTransportLoad_Sc1TransportLoadForm

At the same time WHS load is also “In process” because we have not completed another work attached to it:

WHSTransportLoad_Sc1WHSLoadProcess1

Further steps to process Transport load are similar to the WHS load flow, i.e.:

  • Confirm transport load by clicking on the Transport button of the Transport loads form, this will change the status to shipped (do not forget that you can so it as a part of mobile device flow if required).

WHSTransportLoad_Sc1TransportLoadFormShipped

  • Generate packing slip for the transport load. This will create a packing slip and will change WHS load status to “Partially shipped”.

WHSTransportLoad_Sc1WHSLoadPartial

When you complete picking and loading for another work, WHS Load status will changes to “Shipped” automatically.

Scenario 2. Ship multiple loads together on one transport load.

We have received multiple orders for the same customer and we can ship them all together. We cannot determine load capacity beforehand. Therefore, we will release sales orders separately and pick the stock to staging area and then to truck itself. We do not need to consolidate loads since we can use transport loading menu item to combine multiple shipments.

We have 2 loads with Loading strategy to “Partial shipping allowed”:

WHSTransportLoad_Sc2WHSLoads

Every load has an open sales order picking work generated:

WHSTransportLoad_Sc2Work

On the mobile device we perform picking by using Transport loading menu item. We specify Transport Load id as TRP-001 and perform picking of works related to our sales orders.

WHSTransportLoad_Sc2TransportLoadProcess1WHSTransportLoad_Sc2TransportLoadProcess2

Repeat same steps for the second work.

After we finished, we have transport load that contains stock picked for multiple sales orders and loads.

WHSTransportLoad_Sc2TransportLoadForm

Then we confirm transport load and post packing slip for it. On the packing slip posting screen you can choose whether you want to produce 1 packing slip document or 2 separate for the Transport load by changing summary update parameter.

After it is done, since both loads were fully shipped, the WHS load status automatically changes to “Shipped”:

WHSTransportLoad_Sc2WHSLoadsShipped

That is all, I think it is a really good feature of new release that gives us more opportunities to manage picking process and do something that was not possible before. Worth to mention that it supports Transfer orders too!

Update inventory batch attributes with a quality test result

Inventory batch attributes allow to capture any additional characteristics against the batch number. The attribute value can be assigned manually, inherited from a component to a finished item or automatically updated on a quality order validation step.

In this post we will review the scenario when we update batch attribute information with the quality test result.

The setup and precondition steps that should be taken are:

1. Create a batch attribute (Product information management > Setup > Categories and attributes > Batch attributes)

PdsBatchAttrib_BatchAttributes

2. Assign the batch attribute to an item (Product information management > Products > Released products, Product specific button on the manage inventory tab)

NOTE: the button is enabled if Batch number is active in tracking dimension group assigned to the item.

PdsBatchAttrib_ReleasedProductsPdsBatchAttrib_ProductSpecific

3. In the Quality test group for the test line select required batch attribute that applies to the test (“Attribute” field) and activate “Update inventory batch attribute” to flag that inventory batch attribute should be updated with result value.

PdsBatchAttrib_TestGroups

NOTE: Update inventory batch attribute field value is defaulted from an Inventory management parameter (Inventory management > Setup > Inventory and warehouse management), but you can always override the value for a particular test group on header on line level.

When all prerequisites are met the next steps for us would be:

4. Create a quality order (manually or automatically by using quality associations). In this example a quality order is automatically created when we posted Product receipt.

PdsBatchAttrib_CreateQO

5. Enter quality test results. Open quality orders form and populate quality test results by clicking on the results button:

PdsBatchAttrib_QOPdsBatchAttrib_QOResults

6. Validate the quality order. Click on the Validate button to validate quality order and quality order test result will be inherited to the inventory batch attribute of the batch number:

PdsBatchAttrib_QOValidate

To check it, open Batches form (Right click > View details or Inventory management > Inquiries and reports > Tracking dimensions > Batches) and click on the Inventory batch attribute button:

PdsBatchAttrib_InventBatchPdsBatchAttrib_InventBatchAttrib

As you can see, system captured not only Attribute value but a quality order number from where the result was inherited which is really handy since it gives us ability to go and check additional test details if required.