Warranty Extension

One stop shop to extend all Server Warranties for Azure

Cole Russell
April 1, 2022

Solution Description

The Warranty Extension Application enables the Spares & Warranty Operations (SWOPs) Team to manage the annual Warranty Extension Process supporting 150 engineering groups, 500 users across around the world, and over 3.5 Million servers in Azure.

E2E Diagram

Warranty_Extension_Figma

Warranty Extension Canvas App

Warranty Extension App Warranty_Extension_App

Impact

This design allows for more rapid development of future enhancements adhering to the tenants of hyperautomation by both improving security & reducing maintenance costs. This continues the path to ~$1.8M in savings from ~10,800 hours of toil reduction over the next 3 years, while adding enhancements that increase the overall savings to ~$2M from ~12,000 hours of toil reduction.

Interesting Aspect of this Solution #1

This application was a herculean undertaking and really pushed the Power Platform to its limits. For starters, there are very few use cases where someone is managing 1M records in Dataverse, let alone 3.5M, that can be updated by 100s of Users, with full data updates weekly, all through a Canvas Power App!

As a result of the size of this data there were numerous considerations but arguably the most difficult was in how this data was represented in the UI for Users to select for extensions. It was determined early on that we would need a lookup table to pre-filter the application data based on the AAD of the User logged into the application. This allowed us to only load assets that were pertinent to the User rather than filtering after the fact which would have significantly increased load times. Furthermore, in order to provide additional filtering capabilities, such as the use case when a User manages 100k or more assets, it was then important to make sure that all functions were Delegable to Dataverse. As a result the most difficult bit of code written was the code which populates the Gallery in the Canvas App. It was constant guess and check to make sure that every function could be delegated.

This is the code that is currentl in production:

If(chkboxDecommDateWarr,
Filter(
   'Warranty Assets Inscopes',
    IsBlank(drpCurrentDecision.Selected.Value) || IsEmpty(drpCurrentDecision.Selected.Value)|| 'Decision Current' = drpCurrentDecision.Selected.Value,
    IsBlank(drpPreviousDecisions.Selected.Value) || IsEmpty(drpPreviousDecisions.Selected.Value) || 'Decision Previous' = drpPreviousDecisions.Selected.Value,
    EOB in colEOBNames && EOB = cbEOB.Selected.EOB,
    IsBlank(cbRegion.SelectedItems) || IsEmpty(cbRegion.SelectedItems) || ROCRegion = cbRegion.Selected.Result,
    IsBlank(cbPropertyGroup.SelectedItems) || IsEmpty(cbPropertyGroup.SelectedItems) || PropertyGroup = cbPropertyGroup.Selected.Result,
    IsBlank(cbCountry.SelectedItems) || IsEmpty(cbCountry.SelectedItems) || Country = cbCountry.Selected.Result,
    IsBlank(cbPropertyDimension.SelectedItems) || IsEmpty(cbPropertyDimension.SelectedItems) || PropertyDimension = cbPropertyDimension.Selected.Result,
    IsBlank(cbDatacenter.SelectedItems) || IsEmpty(cbDatacenter.SelectedItems) || DataCenterCode = cbDatacenter.Selected.Result,
    IsBlank(txtClusterName)|| IsEmpty(txtClusterName) || StartsWith(ClusterName,txtClusterName.Text),
    IsBlank(txtAssetTag) || IsEmpty(txtAssetTag) || StartsWith(
        AssetTag,
        txtAssetTag.Text
    ),
    IsBlank(txtRackName)|| IsEmpty(txtRackName) || StartsWith(Rack,txtRackName.Text),
    IsBlank(cbGenMapping.SelectedItems) || IsEmpty(cbGenMapping.SelectedItems) || GEN = cbGenMapping.Selected.Result,
    'Decision Admin' = Blank(),
    'Extension End Date' = Blank() && (MaxWarrantyDate < DecommLDDate) && (DecommLDDate < Date(varFY,6,30)) && (DecommLDDate > Date(varFY-1,6,30)),
    Status='Status (Warranty Assets Inscopes)'.Active,MaxWarrantyDate < Date(varFY,6,30)
),
Filter(
   'Warranty Assets Inscopes',
    IsBlank(drpCurrentDecision.Selected.Value) || IsEmpty(drpCurrentDecision.Selected.Value)|| 'Decision Current' = drpCurrentDecision.Selected.Value,
    IsBlank(drpPreviousDecisions.Selected.Value) || IsEmpty(drpPreviousDecisions.Selected.Value) || 'Decision Previous' = drpPreviousDecisions.Selected.Value,
    EOB in colEOBNames && EOB = cbEOB.Selected.EOB,
    IsBlank(cbRegion.SelectedItems) || IsEmpty(cbRegion.SelectedItems) || ROCRegion = cbRegion.Selected.Result,
    IsBlank(cbPropertyGroup.SelectedItems) || IsEmpty(cbPropertyGroup.SelectedItems) || PropertyGroup = cbPropertyGroup.Selected.Result,
    IsBlank(cbCountry.SelectedItems) || IsEmpty(cbCountry.SelectedItems) || Country = cbCountry.Selected.Result,
    IsBlank(cbPropertyDimension.SelectedItems) || IsEmpty(cbPropertyDimension.SelectedItems) || PropertyDimension = cbPropertyDimension.Selected.Result,
    IsBlank(cbDatacenter.SelectedItems) || IsEmpty(cbDatacenter.SelectedItems) || DataCenterCode = cbDatacenter.Selected.Result,
    IsBlank(txtClusterName)|| IsEmpty(txtClusterName) || StartsWith(ClusterName,txtClusterName.Text),
    IsBlank(txtAssetTag) || IsEmpty(txtAssetTag) || StartsWith(
        AssetTag,
        txtAssetTag.Text
    ),
    IsBlank(txtRackName)|| IsEmpty(txtRackName) || StartsWith(Rack,txtRackName.Text),
    IsBlank(cbGenMapping.SelectedItems) || IsEmpty(cbGenMapping.SelectedItems) || GEN = cbGenMapping.Selected.Result,
    'Decision Admin' = Blank(),
    Status='Status (Warranty Assets Inscopes)'.Active,MaxWarrantyDate < Date(varFY,6,30)
))