How to Extend Product Detail View in Microsoft Dynamics 365 Retail & Commerce POS

 

Microsoft Dynamics 365

Retail & Commerce

POS (Point of Sales)

How to Extend Product Detail View

Link: https://learn.microsoft.com/en-us/dynamics365/commerce/dev-itpro/pos-control-non-screen

Pre-Requisite

1.    Visual Studio 19

2.    SQL Server

3.    Scale Unit project from GitHub repository

https://github.com/microsoft/Dynamics365Commerce.ScaleUnit

Verify you version and download as per match.                    

 


 


4.    SDK’s and runtime

sdk-2.1.513-windows-x64-installer

runtime-2.1.17-windows-x64-installer

.NET Core 3.1 SDK

Windows SDK (10.0.10586.0)

.NET 6.0 Runtime

.NET Core 6.0 Runtime

 

5.    After installation of sdk and runtime

Copy you scaleunit project from download to Service Volume (k)



  

Development

Open Scale Unit Project from Service Volume (K) and build it.

After successful build add folder SimpleProductDetails

Add ProductAvailabilityPanel.html, ProductAvailabilityPanel.ts

 


ProductAvailabilityPanel.html



ProductAvailabilityPanel.html- Code

<!DOCTYPE html>

 

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

<head>

    <meta charset="utf-8" />

    <title></title>

</head>

<body>

    <div id="Contoso_Pos_Extensibility_Samples_ProductAvailabilityPanel" class="height100Percent">

        <h2 class="marginTop8 marginBottom8" id="Contoso_Pos_Extensibility_Samples_ProductAvailabilityPanel_TitleElement"></h2>

        <div id="Contoso_Pos_Extensibility_Samples_ProductAvailabilityPanel_DataList" class="width400 grow col"></div>

    </div>

</body>

</html>

ProductAvailabilityPanel.ts



   


















ProductAvailabilityPanel.ts – Code

import {

    SimpleProductDetailsCustomControlBase,

    ISimpleProductDetailsCustomControlState,

    ISimpleProductDetailsCustomControlContext

} from "PosApi/Extend/Views/SimpleProductDetailsView";

import { InventoryLookupOperationRequest, InventoryLookupOperationResponse } from "PosApi/Consume/OrgUnits";

import { ClientEntities, ProxyEntities } from "PosApi/Entities";

import { ArrayExtensions } from "PosApi/TypeExtensions";

import * as Controls from "PosApi/Consume/Controls";

 

export default class ProductAvailabilityPanel extends SimpleProductDetailsCustomControlBase {

  

    public dataList: Controls.IDataList<ProxyEntities.OrgUnitAvailability>;

    public readonly title: string;

 

    private static readonly TEMPLATE_ID: string = "Contoso_Pos_Extensibility_Samples_ProductAvailabilityPanel";

    private _state: ISimpleProductDetailsCustomControlState;

    private _orgUnitAvailabilities: ProxyEntities.OrgUnitAvailability[] = [];

 

    constructor(id: string, context: ISimpleProductDetailsCustomControlContext) {

        super(id, context);

 

        this.title = "Product Availability";

    }

 

    /**

     * Binds the control to the specified element.

     * @param {HTMLElement} element The element to which the control should be bound.

     */

    public onReady(element: HTMLElement): void {

        let templateElement: HTMLElement = document.getElementById(ProductAvailabilityPanel.TEMPLATE_ID);

        let templateClone: Node = templateElement.cloneNode(true);

        element.appendChild(templateClone);

 

        let titleElement: HTMLElement = element.querySelector("#Contoso_Pos_Extensibility_Samples_ProductAvailabilityPanel_TitleElement");

        titleElement.innerText = this.title;

 

        let dataListOptions: Readonly<Controls.IDataListOptions<ProxyEntities.OrgUnitAvailability>> = {

            columns: [

                {

                    title: "Location",

                    ratio: 31,

                    collapseOrder: 4,

                    minWidth: 100,

                    computeValue: (value: ProxyEntities.OrgUnitAvailability): string => {

                        return value.OrgUnitLocation.OrgUnitName;

                    }

                },

                {

                    title: "Inventory",

                    ratio: 23,

                    collapseOrder: 3,

                    minWidth: 60,

                    computeValue: (value: ProxyEntities.OrgUnitAvailability): string => {

                        return ArrayExtensions.hasElements(value.ItemAvailabilities) ? value.ItemAvailabilities[0].AvailableQuantity.toString() : "0";

                    }

                },

                {

                    title: "Reserved",

                    ratio: 23,

                    collapseOrder: 1,

                    minWidth: 60,

                    computeValue: (value: ProxyEntities.OrgUnitAvailability): string => {

                        return ArrayExtensions.hasElements(value.ItemAvailabilities) ? value.ItemAvailabilities[0].PhysicalReserved.toString() : "0";

                    }

                },

                {

                    title: "Ordered",

                    ratio: 23,

                    collapseOrder: 2,

                    minWidth: 60,

                    computeValue: (value: ProxyEntities.OrgUnitAvailability): string => {

                        return ArrayExtensions.hasElements(value.ItemAvailabilities) ? value.ItemAvailabilities[0].OrderedSum.toString() : "0";

                    }

                }

            ],

            data: this._orgUnitAvailabilities,

            interactionMode: Controls.DataListInteractionMode.None,

        };

 

        let dataListRootElem: HTMLDivElement = element.querySelector("#Contoso_Pos_Extensibility_Samples_ProductAvailabilityPanel_DataList") as HTMLDivElement;

        this.dataList = this.context.controlFactory.create(this.context.logger.getNewCorrelationId(), "DataList", dataListOptions, dataListRootElem);

 

    }

 

    /**

     * Initializes the control.

     * @param {ISimpleProductDetailsCustomControlState} state The initial state of the page used to initialize the control.

     */

    public init(state: ISimpleProductDetailsCustomControlState): void {

        this._state = state;

        let correlationId: string = this.context.logger.getNewCorrelationId();

 

        if (!this._state.isSelectionMode)

        {

            this.isVisible = true;

            let request: InventoryLookupOperationRequest<InventoryLookupOperationResponse> =

                new InventoryLookupOperationRequest<InventoryLookupOperationResponse>(this._state.product.RecordId, correlationId);

 

            this.context.runtime.executeAsync(request).then((result: ClientEntities.ICancelableDataResult<InventoryLookupOperationResponse>) =>

            {

                if (!result.canceled)

                {

                        this._orgUnitAvailabilities = result.data.orgUnitAvailability;

                        this.dataList.data = this._orgUnitAvailabilities;

                }

 

            }).catch((reason: any) =>

            {

                   this.context.logger.logError(JSON.stringify(reason), correlationId);

            });

        }

    }

}

Register class in manifest.json



"SimpleProductDetailsView": {

          "controlsConfig": {

            "customControls": [

              {

                "controlName": "ProductAvailabilityPanel",

                "htmlPath": "ViewExtensions/SimpleProductDetails/ProductAvailabilityPanel.html",

                "modulePath": "ViewExtensions/SimpleProductDetails/ProductAvailabilityPanel"

              }

            ]

          }

        },

 

Rebuild the whole solution.

Once the build is compiled successfully Now copy the commerce runtime library.

CommerceRuntime.dll

From: “..\..\CommerceRuntime\bin\Debug\netstandard2.0”

To: “K:\RetailServer\WebRoot\bin\Ext”




Open CommerceRuntime.Ext.config file and add the following line in the composition tag.
<add source="assembly" value="CommerceRuntime" />



Now deploy the extension on the dev machine by copying the code.
From:..\..\ ScaleUnit\bin\Debug\netstandard2.0\CloudScaleUnitExtensionPackage\RetailCloudPOS\Code\Extensions”
To: “K:\RetailCloudPos\WebRoot\Extensions”


 

Now login to pos and go to setting to check package


 



Now go to product and select any one





    


The End




Comments

Popular posts from this blog

How to Add Custom Control in Customer with Custom Field & Add/Update Data in D365 Commerce POS

How to Extend Customer List View adding Custom Field on Dynamics 365 Retail & Commerce POS

How to Search Custom Field from Customer and Num Pad in Dynamics 365 Retail & Commerce POS