Skip to content

Instantly share code, notes, and snippets.

@ashkohli
Created January 13, 2022 09:33
Show Gist options
  • Select an option

  • Save ashkohli/fd1ca0a6234316d960445fb1576ce455 to your computer and use it in GitHub Desktop.

Select an option

Save ashkohli/fd1ca0a6234316d960445fb1576ce455 to your computer and use it in GitHub Desktop.
public class MultiQuotePDFController {
public Opportunity OpportunityRecord { get; private set; }
public OpportunityLineItem OpportunityLineItem {get; private set; }
public Map<String, Integer> ProductNameToNoOfPriceUnitsMap { get; private set; }
public Map<String, String> ProductNameToCurrencyMap { get; private set; }
public Integer NoOfUnitsForBeaconReference { get; private set; }
public List<String> OverallListOfUnits { get; private set; }
Public List<String>OverallListOfCurrenciesAndUnits {get; private set;}
Public List<String> quoteTotals {get; private set; }
public Map<String, Set<String>> ProductNameToListOfUnits { get; private set; }
public Map<String, Set<String>> CurrencytoPriceUnits { get; private set; }
public List<OpportunityLineItem> OpportunityProductsList { get; private set; }
public Multi_Quote_Groupings__mdt MultiQuoteConfigurations { get; private set; }
public List<Item> ConvertedOpportunityProductsList { get; private set; }
public Boolean IsError { get; private set; }
String OpportunityId = '';
//Above are declaring variables to be used in this class
public MultiQuotePDFController() {
IsError = false;
OverallListOfUnits = new List<String>();
ProductNameToListOfUnits = new Map<String, Set<String>>();
OpportunityId = ApexPages.currentPage().getParameters().get('id');
//if there is no error, create new list and map to pull the opportunity id from the page URL
OpportunityProductsList = getOpportunityLineItems(OpportunityId);
OpportunityRecord = getOpportunityDate(OpportunityProductsList);
MultiQuoteConfigurations = getMultiQuoteConfiguration(OpportunityRecord.Mode_of_Transport__c, OpportunityRecord.Shipment_Type__c);
if (MultiQuoteConfigurations != null) {
populateRelatedData();
//
List<AggregateResult> aggreageted_line_items = Database.query(queryConstructorAgg());
ConvertedOpportunityProductsList = convertItems(aggreageted_line_items);
getPricesAndReferences(ConvertedOpportunityProductsList);
} else {
IsError = true;
}
}
private List<OpportunityLineItem> getOpportunityLineItems(String opportunity_id) {
return
[SELECT Beacon_Reference_Id__c, Price_Unit__c,Equipment_Type_Pull__c,Opportunity.Requested_Valid_From_Date__c,Opportunity.Requested_Valid_To_Date__c, Starting_Point_Seaport__r.Name,
Ending_Point_Seaport__r.Name, Ending_Point_City__c, Ending_Point_Postcode__c, Ending_Point_Country__c,
Starting_Point_City__c, Starting_Point_Postcode__c, Starting_Point_Country__c, Ending_Point_Airport__r.Name,
Starting_Point_Airport__r.Name, Price_Currency__c,Cost_Currency__c, Product2.Name, Price_Amount__c,
Opportunity.Account.Name, Opportunity.Quoted_Date__c, Opportunity.Pricing_Notes__c,Unit_Cost__c,Opportunity.Quote_Total__c,Unit_Price__c,
Opportunity.Mode_of_Transport__c, Opportunity.Shipment_Type__c, Opportunity.Quote_Expiration_Date__c,Valid_From__c,Valid_To__c,Unit_Price_Quote_Currency__c, quote_currency__c
FROM OpportunityLineItem
WHERE OpportunityID = :opportunity_id
ORDER BY Product2.Name, Equipment_Type_Lookup__c];
}
// return a list of opportunity line items using the parameter of opportunity ID and return all the field items in the above SOQL statement
private Opportunity getOpportunityDate(List<OpportunityLineItem> opportunity_line_items) {
if (!opportunity_line_items.isEmpty()) {
OpportunityLineItem opportunity_line_item = opportunity_line_items.get(0);
return opportunity_line_item.Opportunity;
}
return new Opportunity();
}
private Multi_Quote_Groupings__mdt getMultiQuoteConfiguration(String mode_of_transport, String shipment_type) {
List<Multi_Quote_Groupings__mdt> configs = [SELECT Single_Reference__c, Mode_of_Transport__c, Shipment_Type__c, Display_Arr_Airport__c, Display_Delivery__c,
Display_Dep_Airport__c, Display_POD__c, Display_POL__c, Display_Pickup__c, Group_by_Arr_Airport__c,
Group_by_Delivery__c, Group_by_Dep_Airport__c, Group_by_POD__c, Group_by_POL__c, Group_by_Pickup__c
FROM Multi_Quote_Groupings__mdt
WHERE Mode_of_Transport__c =: mode_of_transport
AND Shipment_Type__c =: shipment_type
LIMIT 1];
if (configs.isEmpty()) {
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR, 'Multi-Quote PDF is not available for this type of Opportunity'));
return null;
}
return configs.get(0);
}
//create a list with the items in the SOQL statement if the mode and shipment type given in the metadata is present. Group by the POL, POD, Arrival Airport, Delivery, Pickup, and Depar Airport
//if the shipment type and mode of transport do not match throw up an error message
private void populateRelatedData() {
ProductNameToListOfUnits = new Map<String, Set<String>>();
CurrencytoPriceUnits = new map<String, set<String>>();
ProductNameToNoOfPriceUnitsMap = new Map<String, Integer>();
ProductNameToCurrencyMap = new Map<String, String>();
String Quote_Currency;
//the above method populateRelatedData creates new maps
//ProductNameToListOfUnits is where the key, value (product, unit (equipment type))
//ProductNameToNoOfPriceUnitsMap is where the key, value (Product, number of price units)
//ProductNameToCurrencyMap is where the key, value (Product, Currency (cost_currency))
Set<String> units_set = new Set<String>();
for (OpportunityLineItem opportunity_line_item : OpportunityProductsList) {
String price_unit = (String.isNotBlank(opportunity_line_item.Equipment_Type_Pull__c)) ? opportunity_line_item.Equipment_Type_Pull__c : '-';
units_set.add(price_unit);
if (!ProductNameToListOfUnits.containsKey(opportunity_line_item.Product2.Name)) {
ProductNameToListOfUnits.put(opportunity_line_item.Product2.Name, new Set<String>());
}
ProductNameToListOfUnits.get(opportunity_line_item.Product2.Name).add(price_unit);
String cost_currency = String.isNotBlank(opportunity_line_item.Cost_Currency__c) ? opportunity_line_item.Cost_Currency__c : '-';
ProductNameToCurrencyMap.put(opportunity_line_item.Product2.Name, cost_currency);
}
//Create a set called units_set and go through all the opportunity products in the opportunitylineitem
//if the Equipment Type Pull is not blank add the Equipment Type, otherwise put '-'
//Add the responses to the string price_unit and add the string price_unit to the set units_Set
//if the map ProductNameToListOfUnits contains the same product name,match the product name to the equipment type in the unit_set string
//
// In the map of ProductnameToListOfUnits get the product name and the equipment type from the opportunitylineitem
// Create a string where if the cost_currency is not blank in the opportunitylineitem, pull the cost currency, otherwise '-'
// Add the key and value to the ProductNameToCurrencyMap
OverallListOfUnits.addAll(units_set);
NoOfUnitsForBeaconReference = OverallListOfUnits.size();
//Add all the values in the units_set set to the variable OverallListOfUnits
//The variable NoOfUnitsForBeaconReference will be the number of values in the OverallListOfUnits variable
for (String key : ProductNameToListOfUnits.keySet()) {
ProductNameToNoOfPriceUnitsMap.put(key, ProductNameToListOfUnits.get(key).size());
}
}
// for the ProductNameToListOfUnits map, get all the values and put the value (number of equipment types) in the map ProductNameToNoOfPriceUnitsMap
private String queryConstructorAgg() {
String query_string = 'SELECT MIN (Beacon_Reference_ID__c) beaconReference, ';
//create a string and select the min Beacon Reference ID and call it beaconReference
List<String> query_fields = new List<String>();
if (MultiQuoteConfigurations.Group_by_Arr_Airport__c) query_fields.add('Ending_Point_Airport__r.Name endingPointAirportName');
if (MultiQuoteConfigurations.Group_by_Delivery__c) query_fields.add('Ending_Point_City__c, Ending_Point_Postcode__c, Ending_Point_Country__c');
if (MultiQuoteConfigurations.Group_by_Dep_Airport__c) query_fields.add('Starting_Point_Airport__r.Name startingPointAirportName');
if (MultiQuoteConfigurations.Group_by_Pickup__c) query_fields.add('Starting_Point_City__c, Starting_Point_Postcode__c, Starting_Point_Country__c');
if (MultiQuoteConfigurations.Group_by_POD__c) query_fields.add('Ending_Point_Seaport__r.Name endingPointSeaportName');
if (MultiQuoteConfigurations.Group_by_POL__c) query_fields.add('Starting_Point_Seaport__r.Name startingPointSeaportName');
//create a new string called query fields
//If the checkbox for the grouping = true, then add the field following it. For example, if Group By Airport is true, then add the Ending Airport name to the string
query_string += String.join(query_fields, ', ');
query_string += ' FROM OpportunityLineItem WHERE OpportunityID = :OpportunityId';
// concatenate the list with commas
// concatenate the list with the following parameter of FROM OpportunityLineITem where OpportunityID = :OpportunityID
query_string += ' GROUP BY ';
List<String> group_fields = new List<String>();
if (MultiQuoteConfigurations.Group_by_Arr_Airport__c) group_fields.add('Ending_Point_Airport__r.Name');
if (MultiQuoteConfigurations.Group_by_Delivery__c) group_fields.add('Ending_Point_City__c, Ending_Point_Postcode__c, Ending_Point_Country__c');
if (MultiQuoteConfigurations.Group_by_Dep_Airport__c) group_fields.add('Starting_Point_Airport__r.Name');
if (MultiQuoteConfigurations.Group_by_Pickup__c) group_fields.add('Starting_Point_City__c, Starting_Point_Postcode__c, Starting_Point_Country__c');
if (MultiQuoteConfigurations.Group_by_POD__c) group_fields.add('Ending_Point_Seaport__r.Name');
if (MultiQuoteConfigurations.Group_by_POL__c) group_fields.add('Starting_Point_Seaport__r.Name');
query_string += String.join(group_fields, ', ');
//take the final query string we created before and concatenate with GROUP BY
//If the Group By checkbox is true, then add the following field
return query_string;
}
//return the final string which would be something like this SELECT Min (Beacon_Reference_ID)... from OpportunityLineItem WHERE OpportunityID = :OpportunityID GROUP BY ...
private List<Item> convertItems(List<AggregateResult> aggregate_line_items) {
//create a list called convertItems and pass through a list called aggregate_line_items
List<Item> line_items = new List<Item>();
//create a list called line_items
for (AggregateResult item : aggregate_line_items) {
//loop through the list of aggregate_line_items
Item single_line_item = new Item();
//create a new items called single_line_item
single_line_item.beaconReference = (String)item.get('beaconReference');
//Add the beaconReference to the single_line_item
if (MultiQuoteConfigurations.Group_by_POL__c) {
single_line_item.Starting_Point_Seaport_Name = (String)item.get('startingPointSeaportName');
//if checkbox GROUP by POL is marked then pull the starting Point Seaport name into the single_line_item item
}
if (MultiQuoteConfigurations.Group_by_POD__c) {
single_line_item.Ending_Point_Seaport_Name = (String)item.get('endingPointSeaportName');
//if checkbox GROUP by POL is marked then pull the ending Point Seaport name into the single_line_item item
}
if (MultiQuoteConfigurations.Group_by_Dep_Airport__c) {
single_line_item.Starting_Point_Airport_Name = (String)item.get('startingPointAirportName');
//if checkbox GROUP by POL is marked then pull the starting Point Airport name into the single_line_item item
}
if (MultiQuoteConfigurations.Group_by_Arr_Airport__c) {
single_line_item.Ending_Point_Airport_Name = (String)item.get('endingPointAirportName');
//if checkbox GROUP by POL is marked then pull the Ending Point Airport name into the single_line_item item
}
if (MultiQuoteConfigurations.Group_by_Delivery__c) {
single_line_item.Ending_Point_City = (String)item.get('Ending_Point_City__c');
single_line_item.Ending_Point_Postcode = (String)item.get('Ending_Point_Postcode__c');
single_line_item.Ending_Point_Country = (String)item.get('Ending_Point_Country__c');
populateDelivery(single_line_item);
//if GROUP by Delivery is marked, then add ending point city, postcode and country
}
if (MultiQuoteConfigurations.Group_by_Pickup__c) {
single_line_item.Starting_Point_City = (String)item.get('Starting_Point_City__c');
single_line_item.Starting_Point_Postcode = (String)item.get('Starting_Point_Postcode__c');
single_line_item.Starting_Point_Country = (String)item.get('Starting_Point_Country__c');
populatePickup(single_line_item);
//if GROUP by Pickup is marked, then add ending point city, postcode and country
}
line_items.add(single_line_item);
//Add all the above to the line_items list created befiore
}
return line_items;
//return all the items in the line items list
}
private void populatePickup(Item single_line_item) {
List<String> pickup_list = new List<String>();
if(String.isNotBlank(single_line_item.Starting_Point_City)) pickup_list.add(single_line_item.Starting_Point_City);
if(String.isNotBlank(single_line_item.Starting_Point_Postcode)) pickup_list.add(single_line_item.Starting_Point_Postcode);
if(String.isNotBlank(single_line_item.Starting_Point_Country)) pickup_list.add(single_line_item.Starting_Point_Country);
single_line_item.Pickup = String.join(pickup_list, ', ');
}
// populatePickup method passing through the item single_line_item
// create a list called pickup_list
// if single_line_item item has a Starting Point city, add the Starting Point city to the list
// if single_line_item item has a postcode, add the postcode to the list
// if single_line_item item has a starting point country, add it to the list
// the pickup value in the single_line_item = the string created before and is concatenated by a comma
private void populateDelivery(Item single_line_item) {
List<String> delivery_list = new List<String>();
if(String.isNotBlank(single_line_item.Ending_Point_City)) delivery_list.add(single_line_item.Ending_Point_City);
if(String.isNotBlank(single_line_item.Ending_Point_Postcode)) delivery_list.add(single_line_item.Ending_Point_Postcode);
if(String.isNotBlank(single_line_item.Ending_Point_Country)) delivery_list.add(single_line_item.Ending_Point_Country);
single_line_item.Delivery = String.join(delivery_list, ', ');
}
// populateDelivery method passing through the item single_line_item
// create a list called delivery_list
// if single_line_item item has a Ending Point city, add the Ending Point city to the list
// if single_line_item item has a postcode, add the postcode to the list
// if single_line_item item has a Ending point country, add it to the list
// the delivery value in the single_line_item = the string created before and is concatenated by a comma
public void getPricesAndReferences(List<Item> items) {
for (Item i : items) {
i.pricesMap = new Map<String, Double>();
i.referencesMap = new Map<String, String>();
i.totalsMap = new Map <String,Double>();
i.quoteCurrencyTotal = new map <String, Double>();
i.costCurrencyTotal = new map <String, Double>();
i.currToTotalMap = new map <String,Double>();
if (MultiQuoteConfigurations.Single_Reference__c) {
NoOfUnitsForBeaconReference = 1;
}
for (OpportunityLineItem opportunity_line_item : OpportunityProductsList) {
String price_unit = (String.isNotBlank(opportunity_line_item.Equipment_Type_Pull__c)) ? opportunity_line_item.Equipment_Type_Pull__c : '-';
String quote_currency = (String.isNotBlank(opportunity_line_item.Quote_Currency__c)) ? opportunity_line_item.Quote_Currency__c : '-';
String cost_currency = (String.isNotBlank(opportunity_line_item.Cost_Currency__c)) ? opportunity_line_item.Cost_Currency__c : '-';
if (i.isRelatedRecord(opportunity_line_item, MultiQuoteConfigurations)) {
i.pricesMap.put(opportunity_line_item.Product2.Name + ' ' + price_unit, opportunity_line_item.Unit_Price__c != null ? opportunity_line_item.Unit_Price__c : null);
i.referencesMap.put(price_unit, opportunity_line_item.Beacon_Reference_ID__c !=null ? opportunity_line_item.Beacon_Reference_ID__c : '-');
i.totalsMap.put(price_unit, opportunity_line_item.unit_price_quote_currency__c !=null ? opportunity_line_item.unit_price_quote_currency__c : null);
i.quoteCurrencyTotal.put(quote_currency + ' ' + price_unit, opportunity_line_item.Unit_Price_Quote_Currency__c !=null ? opportunity_line_item.Unit_Price_Quote_Currency__c: null);
i.costCurrencyTotal.put(cost_currency + ' ' + price_unit, opportunity_line_item.Unit_Price__c !=null ? opportunity_line_item.Unit_Price__c: null);
} else {
i.pricesMap.put(opportunity_line_item.Product2.Name + ' ' + price_unit, null);
i.referencesMap.put(price_unit, '-');
i.totalsMap.put(price_unit, null);
i.quoteCurrencyTotal.put(quote_currency + ' ' +price_unit,null);
i.costCurrencyTotal.put(cost_currency + ' ' + price_unit,null);
}
map<String,Double>costCurrencyTotal;
map<String, Double> currToTotalMap = new map<String,Integer>();
for(String key : costCurrencyTotal.keyset()){
list<String> strList = key.split(' ');
if(currToTotalMap.containsKey(strList[1])){
Double tempTotal = currToTotalMap.get(strList[1]);
currToTotalMap.put(strList[1], (tempTotal+ costCurrencyTotal.get(key)));
}else{
currToTotalMap.put(strList[1], costCurrencyTotal.get(key));
}
}
}
}
}
// Public static Map<String,Double>sumMaps(Map<String,Double>quoteCurrencyTotal, Map<String,Double>costCurrencyTotal) {
// Set<String> keys1 = quoteCurrencyTotal.keySet();
//Set<String> keys2 = costCurrencyTotal.keySet();
// keys1.retainAll(keys2);
//Map<String,Double>summedMap = new Map<String,Double>();
//for(String k : keys1) {
// summedMap.put(k, quoteCurrencyTotal.get(k) + costCurrencyTotal.get(k));
// }
//return summedMap;
//loop through the opportunityLineItems in the OpportunityProductsList
//for the string price_units if the equipment type is not blank, pull the equipment type, otherwise put '-'
// if the opportunitylineitem and the MultiQuoteConfigurations are related records, then pull the Product Name + equipment type, the unit price in the PricesMap
// if the opportunitylineitem and the MultiQuoteConfigurations are related records, the put the equipment type, beacon reference id into the ReferencesMap
// Otherwise put Product Name and Equipment Type, and 0 in the PricesMap
// Otherwise put equipment type and '-' in the referencesMap
public class Item {
public Decimal quoteTotal {get;set;}
public String beaconReference {get;set;}
public String Starting_Point_Seaport_Name {get;set;}
public String Ending_Point_Seaport_Name {get;set;}
public String Starting_Point_Airport_Name {get;set;}
public String Ending_Point_Airport_Name {get;set;}
public String Ending_Point_City {get;set;}
public String Ending_Point_Postcode {get;set;}
public String Ending_Point_Country {get;set;}
public String Starting_Point_City {get;set;}
public String Starting_Point_Postcode {get;set;}
public String Starting_Point_Country {get;set;}
public String Pickup {get;set;}
public String Delivery {get;set;}
public Map<String, Decimal> pricesMap {get;set;}
public Map<String, String> referencesMap {get;set;}
public Map<String, Decimal> totalsMap {get;set;}
public Map<String, Decimal>quoteCurrencyTotal {get;set;}
public Map<String, Decimal>costCurrencyTotal {get;set;}
public Map<String, Decimal>currToTotalMap {get;set;}
//create new variables in a class
public Boolean isRelatedRecord(OpportunityLineItem record_to_compare, Multi_Quote_Groupings__mdt multi_quote_configurations) {
//public method that passes through the record to compare from the OpportunityLineItem and multi quote configurations from the MQG mdt
Set<Boolean> configuration_check_list = new Set<Boolean>();
//Create a new boolean set called configuration check list
if (multi_quote_configurations.Group_by_POL__c) {
configuration_check_list.add(record_to_compare.Starting_Point_Seaport__r.Name == this.Starting_Point_Seaport_Name);
//if Group by POL is marked, then add the Starting Seaport Name to the set
}
if (multi_quote_configurations.Group_by_POD__c) {
configuration_check_list.add(record_to_compare.Ending_Point_Seaport__r.Name == this.Ending_Point_Seaport_Name);
//if Group by POD is marked, then add the Ending Seaport Name to the set
}
if (multi_quote_configurations.Group_by_Dep_Airport__c) {
configuration_check_list.add(record_to_compare.Starting_Point_Airport__r.Name == this.Starting_Point_Airport_Name);
//if Group by Dep Airport is marked, then add the Ending Seaport Name to the set
}
if (multi_quote_configurations.Group_by_Arr_Airport__c) {
configuration_check_list.add(record_to_compare.Ending_Point_Airport__r.Name == this.Ending_Point_Airport_Name);
//if Group by Arr Airport is marked, then add the Ending Seaport Name to the set
}
if (multi_quote_configurations.Group_by_Pickup__c) {
configuration_check_list.add(record_to_compare.Starting_Point_City__c == this.Starting_Point_City);
configuration_check_list.add(record_to_compare.Starting_Point_Postcode__c == this.Starting_Point_Postcode);
configuration_check_list.add(record_to_compare.Starting_Point_Country__c == this.Starting_Point_Country);
//if group by Pickup is selected, then add starting point city, starting point postcode, and starting point country
}
if (multi_quote_configurations.Group_by_Delivery__c) {
configuration_check_list.add(record_to_compare.Ending_Point_City__c == this.Ending_Point_City);
configuration_check_list.add(record_to_compare.Ending_Point_Postcode__c == this.Ending_Point_Postcode);
configuration_check_list.add(record_to_compare.Ending_Point_Country__c == this.Ending_Point_Country);
//if group by delivery is selected, then add ending point city, ending point postcode, and ending point country
}
return !configuration_check_list.contains(false);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment