Introduction
I want to create a discount according to a product with a specific feature like the color or the dimension. I want something that links the discount and the specific product. How do to it ?
Apex
@RestResource(urlMapping='/quote/commercialaction/')
global without sharing class CommercialActionAPI {
@HttpPost
global static void getCommercialAction() {
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String requestBody = req.requestBody.toString();
// Deserialize the JSON payload to Apex objects
QuoteRequest quoteReq;
Map<String, List<Map<String, Object>>> responseMap = new Map<String, List<Map<String, Object>>>();
try {
quoteReq = (QuoteRequest)JSON.deserialize(requestBody, QuoteRequest.class);
} catch (Exception e) {
res.statusCode = 400; // Bad Request
res.responseBody = Blob.valueOf(JSON.serialize(new ErrorResponse('Invalid request body', e.getMessage())));
return;
}
// Loop through each quote line record
for(QuoteLineRecord qlr : quoteReq.quotelines) {
List<Map<String, Object>> commercialActionsList = new List<Map<String, Object>>();
// Query CommercialAction__c records based on the criteria
List<CommercialAction__c> matchingCommercialActions = [
SELECT Id, Name, Active__c, CommercialActionDiscountAmount__c, CommercialActionDiscountPercentage__c,
Couleur__c, Taille__c, ExternalID__c, Product__c,
Product__r.Name, Product__r.Family, Product__r.ProductCode
FROM CommercialAction__c
WHERE Active__c = true
AND Couleur__c = :qlr.Color
AND Taille__c = :qlr.Size
];
// Add each matching CommercialAction__c record to the list
for(CommercialAction__c ca : matchingCommercialActions) {
Map<String, String> commercialActionMap = new Map<String, String>();
commercialActionMap.put('Id', ca.Id);
commercialActionMap.put('Product', ca.Product__c);
commercialActionsList.add(commercialActionMap);
}
responseMap.put(qlr.Product, commercialActionsList);
}
// Set the HTTP status code and response body
res.statusCode = 200;
res.responseBody = Blob.valueOf(JSON.serialize(responseMap));
}
public class QuoteRequest {
public QuoteRecord quote;
public List<QuoteLineRecord> quotelines;
}
public class QuoteRecord {
public String Id;
}
public class QuoteLineRecord {
public String Id;
public String Quote;
public String Product;
public String CA;
public String Size;
public String Color;
}
public class ErrorResponse {
public String message;
public String debugInfo;
public ErrorResponse(String message, String debugInfo) {
this.message = message;
this.debugInfo = debugInfo;
}
}
}
Custom script
export function onBeforeCalculate(quote, lines, conn) {
return getCommercialAction(quote, lines, conn);
}
function getCommercialAction(quote, lines, conn) {
var quoteRecord = {
Id: quote.record.Id,
}
console.log("quote record : " + quoteRecord);
console.log("quote id record : " + quote.record.Id);
var quoteLineRecords = [];
for (var i = 0; i < lines.length; i++) {
quoteLineRecords.push({
Id: lines[i].record.Id,
Quote: lines[i].record.SBQQ__Quote__c,
Product: lines[i].record.SBQQ__Product__c,
CA: lines[i].record.CommercialAction__c,
Size: lines[i].record.Taille__c,
Color: lines[i].record.Couleur__c
});
}
quoteLineRecords.forEach(function(line){
console.log("------------");
console.log("quote line record Id : " + line.Id);
console.log("------------");
console.log("quote line record quote : " + line.Quote);
console.log("------------");
console.log("quote line record Product : " + line.Product);
console.log("------------");
console.log("quote line record CA : " + line.CA);
console.log("------------");
console.log("quote line record CA : " + line.Size);
console.log("------------");
console.log("quote line record CA : " + line.Color);
});
var body = { quote: quoteRecord, quotelines: quoteLineRecords };
return conn.apex.post("/quote/commercialaction/", body).then(function (res) {
console.log("response: ", res);
var commercialMap = JSON.parse(res);
for (var i = 0; i < lines.length; i++) {
lines[i].record['CommercialAction__c'] = null;
var commercialAction = commercialMap[lines[i].record.SBQQ__Product__c][i];
console.log('------' + commercialAction)
if (commercialAction != null) {
if (commercialAction.Id == null) {
console.log("in if commercial Action")
delete lines[i].record.CommercialAction__c;
delete lines[i].record.CommercialAction__r
}
else {
console.log("in else")
lines[i].record['CommercialAction__c'] = commercialAction.Id;
}
}
}
});
}
let's talk technical
The custom script takes all the product in your quote and calls a apex class. The apex class will return a discount if he finds a discount for this product. If he finds one, he will apply a discount. Else, you don’t have a discount
Price rule
Commercial Action Discount
Commercial Action No Discount
let's talk technical
Here, these price rules is used when the quote has one commercial action. Depending on your commercial action, you can have a discount in amount or in percentage.
Custom object with custom field
fields
Validation rule
Quote line
let's talk technical
I have for example a mug with different color and dimension like you can see above. If you put a discount. You need to specify your product (the mug for example) and select a color, dimension and the start and end date. If today is between the start and end date, the discount will be active and can be selectionnable.
IMPORTANT : if you don’t build the validation rule, be sure, to put a discount in amount or in percentage. Indeed, QLE can show you an error, which indicates, you can’t have a discount in amount and percentage. That’s why to not let this bug open. You need to do the validation rule
Result
the link for the github : https://github.com/AourLegacy/AourFactory/tree/Commercial-action
Comments