Discounted Products
- abhyash
- Nov 1, 2022
- 3 min read
Updated: Nov 5, 2022
V1 Prepared By: Abhyash Timsina – 1 November 2022
Motivation: Do a REST callout via APEX to two separate API endpoints that stores products and discounts. Combine the data, determine what type of discount, apply the discount to the product and display it in a LWC Datatable. Note - This is a personal project and not intended for financial gain.
My Technical Components

Lightning Web Component:

Source Code for DiscountedProducts Apex Class (with annotation starting with //)
/**
* Created by Abhyash Timsina on 1/11/2022.
*/
public with sharing class DiscountedProducts {
// Create wrapper class to use product variables from API JSON
public class productsListClass
{
@AuraEnabled public Integer id;
@AuraEnabled public String name;
@AuraEnabled public Integer price;
@AuraEnabled public Integer discountedPrice;
@AuraEnabled public String currency_x;
@AuraEnabled public Integer discount;
@AuraEnabled public String discountType;
}
// Another wrapper class to store discount variables from API JSON
public class discountsListClass
{
@AuraEnabled public Integer productId;
@AuraEnabled public Integer discountPercentage;
@AuraEnabled public Integer discountAmount;
}
// Allow apex to communicate with LWC
@AuraEnabled(Cacheable=true)
public static List<productsListClass> getProductsAndDiscounts() {
// Create an empty list of product wrapper class
List<productsListClass> productsResponse = new List<productsListClass>();
// Get Products details from product API endpoint via REST callout
try {
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setHeader('Content-Type', 'application/json');
req.setHeader('X-Accept-Version', '2.0.0');
req.setEndpoint('https://developer-assignment.web.app/products');
req.setMethod('GET');
res = http.send(req);
// Store REST response into product list variable. Also since 'currency' is a reserved name, we replace it with currency_x
productsResponse = (List<productsListClass>) JSON.deserialize(res.getBody().replace('currency','currency_x'), List<productsListClass>.class);
} catch (Exception e) {
System.debug('Error:' + e.getMessage() + 'LN:' + e.getLineNumber());
}
// Create an empty list of discount wrapper class
List<discountsListClass> discountsResponse = new List<discountsListClass>();
// Get Discount details from discount API endpoint via REST callout
try {
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setHeader('Content-Type', 'application/json');
req.setHeader('X-Accept-Version', '2.0.0');
req.setEndpoint('https://developer-assignment.web.app/discounts');
req.setMethod('GET');
res = http.send(req);
// Store REST response into discount list variable.
discountsResponse = (List<discountsListClass>) JSON.deserialize(res.getBody(), List<discountsListClass>.class);
} catch (Exception e) {
System.debug('Error:' + e.getMessage() + 'LN:' + e.getLineNumber());
}
// Apply the discount using applyDiscount method using the list of products and discounts wrappers as parameters
List<productsListClass> discountedProductResponse = applyDiscount(productsResponse, discountsResponse);
// Return the values to LWC
return discountedProductResponse;
}
// Method to apply the discount
public static List<productsListClass> applyDiscount(List<productsListClass> productsResponse, List<discountsListClass> discountsResponse) {
// Create an empty list of product wrapper class to store the products and discounts table
List<productsListClass> discountedProductsResponse = new List<productsListClass>();
// Logic to apply the discount. If product list product id matches the discount list product id, do the calculation
for (productsListClass pl : productsResponse) {
for (discountsListClass dl : discountsResponse) {
if (pl.id == dl.productId) {
// Logic for Discount Type of 'Percentage'
if (dl.discountPercentage != null) {
pl.discountedPrice = pl.price - (pl.price * (dl.discountPercentage) / 100);
pl.discount = (pl.discountedPrice * (dl.discountPercentage) / 100);
pl.discountType = 'Percentage';
discountedProductsResponse.add(pl);
}
// Logic for Discount Type of 'Amount'
if (dl.discountAmount != null) {
pl.discountedPrice = pl.price - (pl.price * (dl.discountAmount) / 100);
pl.discount = dl.discountAmount;
pl.discountType = 'Amount';
discountedProductsResponse.add(pl);
}
}
}
}
return discountedProductsResponse;
}
}
Source Code for discountedProductsLWC (with annotation starting with //)
HTML
<!--
- Created by Abhyash Timsina on 1/11/2022.
-->
<template>
<lightning-card title="Discounted Products LWC">
// Uses Lightning Datatable to store productList data. Columns have already been defined in Javascript
<lightning-datatable
key-field="id"
data={productList}
hide-checkbox-column
columns={columns}>
</lightning-datatable>
</lightning-card>
</template>
Javascript
/**
* Created by Abhyash Timsina on 1/11/2022.
*/
import {LightningElement, track} from 'lwc';
// Reference APEX class and method in LWC
import getProductsAndDiscounts from'@salesforce/apex/DiscountedProducts.getProductsAndDiscounts';
// Define columns for Datatable - Name, Discounted Price, Discount and Discount Type.
const columns = [
{ label: 'Name', fieldName: 'name', type: 'text'},
{ label: 'Discounted Price', fieldName: 'discountedPrice', type: 'currency', typeAttributes: {
'currencyCode': {
'fieldName': "currency_x"
},
currencyDisplayAs: "symbol"
} },
// Note the currencyCode type attribute which matches the currency_x from the JSON from the API. And the currencyDisplayAs as symbol
{ label: 'Discount', fieldName: 'discount', type: 'currency', typeAttributes: {
'currencyCode': {
'fieldName': "currency_x"
},
currencyDisplayAs: "symbol"
}},
{ label: 'Discount Type', fieldName: 'discountType', type: 'text'},
];
export default class DeveloperAssignmentLwc extends LightningElement {
// Tracking variables for columns and data - required for Datatable
@track columns = columns;
@track data = [];
@track error;
// Lifecycle Hook - happens when page is refreshed and uses APEX to get the latest products and discounts from the API
connectedCallback() {
getProductsAndDiscounts()
.then(result => {
this.data = result;
})
.catch(error => {
this.error = error;
});
}
// Getter to parse the product list data and stringify it for the datatable. This is what is used as a variable in the HTML
get productList() {
return JSON.parse(JSON.stringify(this.data));
}
}
Metadata
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>56.0</apiVersion>
<description>Discounted Products Lwc</description>
<isExposed>true</isExposed>
<masterLabel>Discounted Products Lwc</masterLabel>
// Expose LWC to AppPage, RecordPage and HomePage
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Package Link:
If you need help in installing and getting this working – please contact me on LinkedIn
Kommentarer