/*
01/22/21 CB@IC Initial Creation(00189679)
Test class: OrderAndReturnCtrlTest
*/
public class OrderAndReturnCtrl {
public OrderAndReturnCtrl(){}
public static final String PO_BOX_EXPR = '(?i)[\\s\\S]*p[\\.\\s]{0,2}(o[\\.\\s]{0,2})? ?b((ox)|o|x)[\\s\\S]*'; //String contains some variant of P.O. Box
public static final Id REFUND_REQUEST_PRODUCT_ID = ApexCodeSettings__c.getOrgDefaults().Refund_Request_Id__c;
@AuraEnabled
public static string init(String caseId){
system.debug('caseId-->'+caseId);
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeObjectField('order', createOrderWrapper(caseId));
gen.writeObjectField('recordTypes', getRecordTypes());
//gen.writeObjectField('countries', getCountries());
gen.writeObjectField('countries', getCountry());
gen.writeObjectField('states', getStates());
gen.close();
return gen.getAsString();
}
@AuraEnabled(cacheable=true)
public static string searchProducts(String searchTerm, String[] productFilters, String returnType){
System.debug('searchTerm: ' + searchTerm);
System.debug('productFilters: ' + productFilters);
System.debug('returnType: ' + returnType);
if(!String.isNotEmpty(searchTerm)) {
System.debug('returning');
return '';
}
String term = searchTerm.replace('*', '%') + '%';
Set<Id> partsAlreadyListed = new Set<Id>();
String query = 'SELECT Orderable__c, Case_Creation__c, IsActive, Name, Description, Product_Image__c, RecordType.Name, RecordType.DeveloperName, Family, Available_Balance__c, In_Transit__c, On_Order__c, Stockroom__c, Physical_Stock__c, Has_Replacement__c, Recall_Count__c, Order_Override__c, Canada_Stock_Available__c, Part_Type__c,Preferred_Return_Carrier__c, Product_Region__c ' +
'FROM Product2 ' +
'WHERE (Orderable__c = true OR Case_Creation__c = true) AND Name LIKE :term AND RecordType.DeveloperName = \'Amer_Products\' AND Stockroom__c != \'None\' AND Family = \'First Alert\'' + ' AND Id != :REFUND_REQUEST_PRODUCT_ID ';//FABase Migration : Updated record type from product to Amer_Products
if(productFilters != null && !productFilters.isEmpty()){
query += 'AND FAMILY IN :productFilters ';
}
query += 'ORDER BY Name LIMIT 100';
system.debug('query: ' + query);
//Matching Products
Product2[] prods = Database.query(query);
system.debug('prods: ' + JSON.serialize(prods));
Set<Id> addedIds = new Map<Id, SObject>(prods).keySet().clone();
system.debug('addedIds: ' + JSON.serialize(addedIds));
Replacement__c[] replacements = [
SELECT Replacement_Product__r.Orderable__c, Replacement_Product__r.IsActive, Replacement_Product__r.Stockroom__c, Replacement_Product__r.Physical_Stock__c, Replacement_Product__r.Name, Replacement_Product__r.Description, Replacement_Product__r.Product_Image__c, Replacement_Product__r.RecordType.Name, Replacement_Product__r.RecordType.DeveloperName, Replacement_Product__r.Family, Replacement_Product__r.Available_Balance__c, Replacement_Product__r.In_Transit__c, Replacement_Product__r.On_Order__c, Replacement_Product__r.Recall_Count__c, Replacement_Product__r.Order_Override__c, Replacement_Product__r.Has_Replacement__c, Replacement_Product__r.Canada_Stock_Available__c, Replacement_Product__r.Part_Type__c, Replacement_Product__r.Preferred_Return_Carrier__c, Replacement_Product__r.Product_Region__c
FROM Replacement__c
WHERE Replacement_Product__r.Orderable__c = TRUE AND Obsolete_Product__c = :prods AND Replacement_Product__c != :prods
ORDER BY Replacement_Product__r.Name ASC
];
system.debug('replacements: ' + JSON.serialize(replacements));
for(Replacement__c replacement : replacements) {
if(!addedIds.contains(replacement.Replacement_Product__c)) {
System.debug('66');
addedIds.add(replacement.Replacement_Product__c);
prods.add(replacement.Replacement_Product__r);
} else {
System.debug('70');
}
}
//Bill - Need to show active replacements for inactive products. ->
//Monica - Updated to abide by Orderable__c and/or Case_Creation__c checkbox instead of IsActive and using below
/*
for(Integer i = 0; i < prods.size(); i++)
if(prods[i].Orderable__c != true)
prods.remove(i);
*/
//All parts for matching products
//TODO: fix to use order wrapper once we pass it
Set<Id> prodIds = (new Map<Id, SObject>(prods)).keySet();
Map<Id, Part[]> productParts = getParts(prodIds, false);
List<Part> parts = new List<Part>();
system.debug('productParts: ' + JSON.serialize(productParts));
system.debug('prods: ' + JSON.serialize(prods));
for(Product2 prod : prods) {
//MG added orderable condition
if(prod.Orderable__c) {
parts.add(new Part(prod, false));
for(Part p : productParts.get(prod.Id)) {
parts.add(p);
partsAlreadyListed.add(p.p.Id);
}
}
}
List<Part> returnParts = new List<Part>();
for(Product2 prod : prods) {
if(prod.RecordType.DeveloperName == 'Amer_Products') {
returnParts.add(new Part(prod, false));
for(Part rp : productParts.get(prod.Id)) {
if(rp.p.RecordType.DeveloperName == 'Amer_Products') {
returnParts.add(rp);
partsAlreadyListed.add(rp.p.Id);
}
}
}
}
for(Product2 p : Database.query(
'SELECT Name, Description, Product_Image__c, RecordType.Name, RecordType.DeveloperName, Family, Available_Balance__c, In_Transit__c, On_Order__c, Stockroom__c, Physical_Stock__c, Has_Replacement__c, Recall_Count__c, Order_Override__c, Canada_Stock_Available__c, Part_Type__c, Preferred_Return_Carrier__c, Orderable__c, Product_Region__c ' +
'FROM Product2 ' +
'WHERE (Orderable__c = true OR Case_Creation__c = true) AND Name LIKE :term AND RecordType.DeveloperName = \'Part\' AND Stockroom__c != \'None\' AND Id != :partsAlreadyListed ')) {
//if(step == 1 && p.Orderable__c == true) {
parts.add(new Part(p, false));
if(p.RecordType.DeveloperName == 'Part') {
returnParts.add(new Part(p, false));
}
}
loadPriceData(parts);
system.debug('parts: ' + JSON.serialize(parts));
system.debug('returnParts: ' + JSON.serialize(returnParts));
if((parts == null || parts.isEmpty()) && returnType.equals('Disposal')){
parts = searchDisposalParts(term);
}
system.debug('parts: ' + JSON.serialize(parts));
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeObjectField('parts', parts);
gen.close();
return gen.getAsString();
}
@AuraEnabled
public static string getDisposalParts(){
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeObjectField('parts', loadDisposalParts());
gen.close();
return gen.getAsString();
}
@AuraEnabled
public static string populateCityState(String postalCode){
String ShippingCity;
String ShippingStateCode;
String ShippingCountryCode;
System.debug('postalCode: ' + postalCode);
try {
Map<String, String> cityStateInfo = lookupCityState(postalCode, false);
System.debug('cityStateInfo: ' + cityStateInfo);
if(!String.isBlank(cityStateInfo.get('city')))
ShippingCity = cityStateInfo.get('city');
if(!String.isBlank(cityStateInfo.get('state')))
ShippingStateCode = cityStateInfo.get('state').trim().toUpperCase();
if(postalCode != null && Pattern.matches('\\d{5}', postalCode) && (!String.isBlank(cityStateInfo.get('city')) || !String.isBlank(cityStateInfo.get('state'))))
ShippingCountryCode = 'US';
if(postalCode != null && Pattern.matches('^[ABCEGHJKLMNPRSTVXY]\\d[A-Z] ?\\d[A-Z]\\d$', postalCode.toUpperCase()) && (!String.isBlank(cityStateInfo.get('city')) || !String.isBlank(cityStateInfo.get('state'))))
ShippingCountryCode = 'CA';
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeObjectField('city', ShippingCity);
gen.writeObjectField('state', ShippingStateCode);
gen.writeObjectField('country', ShippingCountryCode);
gen.close();
return gen.getAsString();
}
@AuraEnabled
public static String completeOrder(String orderWrapper)
{
System.debug('orderWrapper--> '+orderWrapper);
OrderWrapper ow = (OrderWrapper)JSON.deserialize(orderWrapper, OrderWrapper.class);
savePoint sp = Database.setSavePoint();
System.debug('ow--> '+JSON.serialize(ow));
System.debug('ow.UpdateShippingAddress: ' + ow.UpdateShippingAddress);
//FA Migration- Commnted the below code and updating the Contact fields after completing the order
/*if(ow.UpdateShippingAddress){
Account acct = new Account (
Id = ow.AccountId,
ShippingStreet = ow.ShippingStreet,
ShippingCity = ow.ShippingCity,
ShippingState = ow.ShippingState ,
ShippingPostalCode = ow.ShippingPostalCode,
ShippingCountry = ow.ShippingCountry,
Email__c = ow.Email
);
Database.DMLOptions dml = new Database.DMLOptions();
dml.DuplicateRuleHeader.allowSave = true;
dml.DuplicateRuleHeader.runAsCurrentUser = true;
Database.SaveResult sr = Database.update(acct, dml);
Contact c = new Contact(
Id = ow.AccountContactId,
Phone = ow.Phone
);
sr = Database.update(c, dml);
}*/
if(ow.UpdateShippingAddress){
Contact con = new Contact (
Id = ow.AccountContactId,
MailingStreet = ow.ShippingStreet,
MailingCity = ow.ShippingCity,
MailingState = ow.ShippingState,
MailingPostalCode = ow.ShippingPostalCode,
MailingCountry = ow.ShippingCountry,
Email = ow.Email,
Phone = ow.Phone
);
Database.DMLOptions dml = new Database.DMLOptions();
dml.DuplicateRuleHeader.allowSave = true;
dml.DuplicateRuleHeader.runAsCurrentUser = true;
Database.SaveResult sr = Database.update(con, dml);
}
// logic to update mailing address?
Boolean hasReturn = ow.ReturnLineItems.size() > 0 && ow.ReturnNeeded == 'true';
Boolean advancedExchange = ow.ReturnType == 'Advanced Exchange' && ow.ReturnNeeded == 'true';
Boolean hasOrderParts = !ow.OrderLineItems.isEmpty() || ow.Type == 'Refund';
String message = '';
String orderId = '';
String returnId = '';
try{
Order o = new Order();
if(hasReturn){
system.debug('has return');
if(hasOrderParts){
system.debug('has order parts');
o = createOrder(ow);
if(o.Id != null){
System.debug('order created, trying return');
orderId = o.Id;
message = 'ok';
createReturn(o, ow);
} else {
message = 'not ok';
}
} else {
system.debug('no order parts');
String woId = createReturn(o, ow);
message = 'ok';
orderId = woId;
}
} else {
system.debug('no return');
o = createOrder(ow);
if(o.Id != null){
message = 'ok';
orderId = o.Id;
} else {
message = 'not ok';
}
}
if(ow.SendPaymentRequest){
createChargentRequest(o);
}
} catch(DmlException ex){
Database.rollback(sp);
System.debug('there was an error');
System.debug('message: ' + ex.getMessage());
message = 'not okay';
}
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeObjectField('status', message);
gen.writeObjectField('orderId', orderId);
gen.close();
return gen.getAsString();
}
private static Boolean createChargentRequest(Order o){
try{
ChargentBase__Gateway__c gateway = [SELECT Id FROM ChargentBase__Gateway__c WHERE ChargentBase__Active__c = true LIMIT 1];
Account personContact = [SELECT Id FROM Account WHERE Id =:o.AccountId]; //FABase Migration: Removed 'PersonContactId' from Query
ChargentOrders__ChargentOrder__c chargentOrder = new ChargentOrders__ChargentOrder__c();
Order ord = [SELECT Id, TotalAmount FROM Order WHERE Id =:o.Id LIMIT 1];
system.debug('total amount: ' + o.TotalAmount);
chargentOrder.Order__c = o.Id;
chargentOrder.ChargentOrders__Account__c = o.AccountId;
chargentOrder.ChargentOrders__Gateway__c = gateway.Id;
chargentOrder.ChargentOrders__Subtotal__c = ord.TotalAmount;
system.debug('inserting charget order');
insert chargentOrder;
system.debug('chargent order inserted');
ChargentOrders__Payment_Request__c paymentRequest = new ChargentOrders__Payment_Request__c();
paymentRequest.ChargentOrders__ChargentOrder__c = chargentOrder.Id;
paymentRequest.Order__c = o.Id;
//FABase Migration commented the below line
paymentRequest.ChargentOrders__Billing_Contact__c = o.ShipToContactId;
paymentRequest.ChargentOrders__Send_Payment_Request_Email__c = true;
system.debug('insert payment request');
insert paymentRequest;
system.debug('payment request inserted');
return true;
} catch (Exception ex){
system.debug('there was an issue creating charget orders');
system.debug(ex.getMessage());
return false;
}
}
private static Order createOrder(OrderWrapper ow){
Order ord = new Order(
AccountId = ow.AccountId,
ShipToContactId = ow.AccountContactId,
EffectiveDate = Date.Today(),
Case__c = ow.Id,
PriceBook2Id = ow.PriceBookId,
ShippingStreet = ow.ShippingStreet,
ShippingCity = ow.ShippingCity,
ShippingState = ow.ShippingState ,
ShippingPostalCode = ow.ShippingPostalCode,
ShippingCountry = ow.ShippingCountry,
Type = ow.Type,
Status = 'Draft',
RMA_Type__c = 'None',
Billing_Email__c = ow.Email,
Waive_Shipping_Fee__c = ow.WaiveShipping
);
if(ord.ShippingCountry != 'CA' && ord.ShippingCountry != 'MX' && ord.ShippingCountry != 'US') {
ord.Expedited_Shipping__c = 'FedEx International';
} else if(IsPOBox(ord.ShippingStreet)) {
ord.Expedited_Shipping__c = 'USPS';
} else if(ow.ExpediteShipping) {
ord.Expedited_Shipping__c = 'Expedited';
} else if(ord.ShippingCountry == 'CA'){
ord.Expedited_Shipping__c = 'Standard CA';
} else {
Boolean containsKey = false;
for(Part p : ow.OrderLineItems) {
if(p.p.Part_Type__c == 'Key') {
containsKey = true;
break;
}
}
if(containsKey) {
ord.Expedited_Shipping__c = 'USPS';
}
else {
ord.Expedited_Shipping__c = 'Standard';
}
}
ord.International__c = ord.ShippingCountry != 'US';
if(ow.ReturnNeeded != 'true') {
ord.RMA_Type__c = 'None';
} else {
ord.RMA_Type__c = ow.ReturnType;
}
if(ow.ReturnType == 'Advanced Exchange' && ow.ReturnNeeded == 'true'){
ord.Advanced_Exchange_Accepted__c = false;
ord.Advanced_Exchange_Date__c = null;
}
try{
insert ord;
Boolean itemsCreated = createOrderItems(ord, ow);
if(itemsCreated){
ord.Status = 'Activated';
update ord;
} else {
System.debug('could not create order items)');
}
} catch(DmlException ex){
System.debug('there was a problem: ' + ex.getMessage());
}
return ord;
}
private static Boolean createOrderItems(Order ord, OrderWrapper ow) {
try {
List<Part> partsToProcess = ow.OrderLineItems;
if(ord.Type == 'Refund') {
List<Product2> p = [SELECT IsActive, Orderable__c, Name, Description, Product_Image__c, RecordType.Name, RecordType.DeveloperName, Family, Available_Balance__c, In_Transit__c, On_Order__c, Stockroom__c, Physical_Stock__c, Has_Replacement__c, Recall_Count__c, Order_Override__c, Canada_Stock_Available__c, Part_Type__c,Preferred_Return_Carrier__c, Product_Region__c FROM Product2 WHERE Id = :REFUND_REQUEST_PRODUCT_ID LIMIT 1];
if(!p.isEmpty()) {
Part aPart = new Part(p[0], ow.isCanadian);
aPart.price = 0;
partsToProcess.add(aPart);
} else {
return false;
}
}
PriceBookEntry[] pbes;
if(Test.isRunningTest()) {
pbes = [SELECT Product2Id FROM PriceBookEntry WHERE Pricebook2Id = :(Test.getStandardPricebookId()) AND isDeleted = FALSE LIMIT 50000];
}
else {
//pbes = [SELECT Product2Id FROM PriceBookEntry WHERE PriceBook2.isStandard = TRUE AND isDeleted = FALSE AND IsActive = True LIMIT 50000];
pbes = [SELECT Product2Id FROM PriceBookEntry WHERE PriceBook2.Name = 'Standard Price Book' AND isDeleted = FALSE AND IsActive = True and Product2.Family = 'First Alert'];
}
Map<Id, PriceBookEntry> pbeByProdId = new Map<Id, PriceBookEntry>();
for(PriceBookEntry pbe : pbes) {
pbeByProdId.put(pbe.Product2Id, pbe);
}
OrderItem[] ois = new OrderItem[]{};
system.debug('pbes-->'+JSON.serialize(pbes));
system.debug('partsToProcess-->'+JSON.serialize(partsToProcess));
system.debug('pbeByProdId-->'+JSON.serialize(pbeByProdId));
for(Part p : partsToProcess) {
/* if(!pbeByProdId.containsKey(p.p.Id)) {
throw new AuraHandledException('No Standard price defined for order item' + p.p.Name);
}*/
if(pbeByProdId.get(p.p.Id) == null) {
string errorMessage = 'No Standard price defined for order item';
AuraHandledException msg = new AuraHandledException(errorMessage);
msg.setMessage(errorMessage);
throw msg;
// throw new AuraHandledException('No Standard price defined for order item' + p.p.Name);
}
System.debug(p);
OrderItem oi = new OrderItem(
OrderId = ord.Id,
PricebookEntryId = pbeByProdId.get(p.p.Id).Id,
Quantity = p.qty,
UnitPrice = p.price,
//Stockroom__c = p.stockroom,
Notes_Line_1__c = p.getNotesField(0),
Notes_Line_2__c = p.getNotesField(1),
Notes_Line_3__c = p.getNotesField(2),
Notes_Line_4__c = p.getNotesField(3),
PreAuth_Qty__c = (getIsAdvancedExchange(ow)) ? p.preAuthQty : 0,
PreAuth_Unit_Price__c = (getIsAdvancedExchange(ow)) ? p.preAuthPrice : 0,
PreAuth_Total_Price__c = (getIsAdvancedExchange(ow)) ? p.preAuthQty * p.preAuthPrice : 0,
Batteries_Or_Wire_Harness__c = p.batteriesOrWireHarness == 'Yes'
);
ois.add(oi);
}
Boolean canadaOrder = false;
system.debug('ord-->'+JSON.serialize(ord));
Order[] ordType = [SELECT RecordType.DeveloperName FROM Order WHERE Id = :ord.Id];
system.debug('ordType-->'+JSON.serialize(ordType));
if(!ordType.isEmpty() && ordType[0].RecordTypeId != null && ordType[0].RecordType.DeveloperName == 'Canada_Order')
canadaOrder = true;
system.debug('canadaOrder-->'+canadaOrder);
if(ord.Waive_Shipping_Fee__c != true && canadaOrder == false) {
PriceBookEntry[] shPbe = [SELECT Id FROM PriceBookEntry WHERE Product2.Name = 'Shipping and Handling' LIMIT 1];
system.debug('shPbe-->'+JSON.serialize(shPbe));
if(!shPbe.isEmpty()) {
OrderItem sh = new OrderItem(
OrderId = ord.Id,
PricebookEntryId = shPbe[0].Id,
Quantity = 1,
UnitPrice = ow.Shipping
);
ois.add(sh);
}
}
system.debug('ois-->'+JSON.serialize(ois));
insert ois;
return true;
}
catch(Exception e) {
System.debug(e);
throw new AuraHandledException(e.getMessage());
}
}
private static string createReturn(Order ord, OrderWrapper ow) {
WorkOrder workOrd = new WorkOrder();
try {
workOrd.AccountId = ow.AccountId;
workOrd.CaseId = ow.Id;
workOrd.ContactId = ow.AccountContactId;
if(ord.Id != null) {
workOrd.Order__c = ord.Id;
}
if(ord.Id != null) {
workOrd.OwnerId = [SELECT Id,OwnerId FROM Order Where ID = :ord.Id LIMIT 1][0].OwnerId;
}
workOrd.Street = ow.ShippingStreet;
workOrd.City = ow.ShippingCity;
workOrd.State = ow.ShippingState;
workOrd.PostalCode = ow.ShippingPostalCode;
workOrd.Country = ow.ShippingCountry;
workOrd.Return_Needed__c = ow.ReturnNeeded == 'true' ? 'yes' : 'no';
workOrd.Return_Type__c = ow.ReturnNeeded == 'true' ? ow.ReturnType : 'None';
workOrd.Return_Only__c = ow.ReturnType == 'Return Only';
workOrd.Pricebook2Id = ow.PriceBookId;
workOrd.CaseId = ow.Id;
if(String.isBlank(ow.CompanyName)) {
workOrd.Company_Person_Name__c = ow.ContactName;
}
else {
workOrd.Contact_Attention__c = ow.CompanyName;
workOrd.Company_Person_Name__c = ow.ContactName;
}
workOrd.Contact_Email__c = ow.Email;
Account a = [SELECT Id, Phone FROM Account WHERE Id =:ow.AccountId LIMIT 1];
workOrd.Contact_Phone__c = ow.Phone;
if(String.isBlank(workOrd.Contact_Phone__c)) {
workOrd.Contact_Phone__c =a.Phone ;
//FABASE Migration Change
/*if(String.isBlank(workOrd.Contact_Phone__c)) {
workOrd.Contact_Phone__c = a.PersonHomePhone;
}*/
}
insert workOrd;
WorkOrderLineItem[] wolis = new WorkOrderLineItem[]{};
for(Part p : ow.ReturnLineItems) {
if(p.qty > 0) {
WorkOrderLineItem woli = new WorkOrderLineItem(
WorkOrderId = workOrd.Id,
Case__c = workOrd.CaseId,
Qty_Expected__c = p.qty,
Product2__c = p.p.Id,
Preferred_Return_Carrier__c = p.p.Preferred_Return_Carrier__c,
Contact_Email__c = ord.Billing_Email__c,
Street = workOrd.Street,
City = workOrd.City,
State = workOrd.State,
PostalCode = workOrd.PostalCode,
Country = workOrd.Country,
Description = p.notes
);
if(ord.Id != null) {
woli.OrderId = ord.Id;
}
if(!p.p.Disposal_Product__c)
woli.PricebookEntryId = p.pbe.Id;
wolis.add(woli);
}
}
insert wolis;
System.debug('return created: ' + workOrd.Id);
return workOrd.Id;
}
catch(Exception e){
system.debug('return not created. see error.');
System.debug(e.getMessage());
return '';
}
}
private static LightningSelect[] getRecordTypes(){
LightningSelect[] results = new LightningSelect[]{};
Map<String,Schema.RecordTypeInfo> rts = new Map<String,Schema.RecordTypeInfo>();
rts = SObjectType.Case.getRecordTypeInfosByDeveloperName();
for(String rt: rts.keySet()) {
if(rts.get(rt).getName() != 'Misdirected/Unknown' && rts.get(rt).getName() != 'Master' && rts.get(rt).getName() != 'Other' && rts.get(rt).getName() != 'Interaction')
results.add(new LightningSelect(rts.get(rt).getRecordTypeId(), rts.get(rt).getName()));
}
System.debug('returning record types' );
return results;
}
@TestVisible
private static OrderWrapper createOrderWrapper(String caseId){
OrderWrapper ow = new OrderWrapper(caseId);
Case c;
Id productId;
if(String.isNotEmpty(caseId)){
c = [SELECT Id, CaseNumber, AccountId, RecordType.DeveloperName, Account.Name, Contact.Name, Contact.Email , Contact.Phone, Contact.MailingStreet, Contact.MailingCity,
Contact.MailingState, Contact.MailingPostalCode, Contact.MailingCountry ,Contact.Id, Asset.Product2.Stockroom__c, Asset.Product2.Physical_Stock__c, Asset.Product2.Orderable__c,
Asset.Product2.Case_Creation__c,Asset.Product2.IsActive, Asset.Product2.Name, Asset.Product2.Description, Asset.Product2.Product_Image__c, Asset.Product2.RecordType.Name,
Asset.Product2.RecordType.DeveloperName, Asset.Product2.Family, Asset.Product2.Available_Balance__c, Asset.Product2.In_Transit__c, Asset.Product2.On_Order__c, Asset.Product2.Recall_Count__c,
Asset.Product2.Order_Override__c, Asset.Product2.Has_Replacement__c, Asset.Product2.Canada_Stock_Available__c, Asset.Product2.Part_Type__c, Asset.Product2.Preferred_Return_Carrier__c, Asset.Product2.Product_Region__c, Type
FROM Case Where Id =:caseId LIMIT 1]; //FABase Migration- Removed 'Account.PersonContact.Id' from Query and All PersonAccount related fields replaced with Contact fields
system.debug('CaseRecord--> '+JSON.serialize(c));
if(c != null){
// Fill out case info
ow.Id = caseId;
ow.AccountId = c.AccountId;
//FABase Migration- Commented the below line as PersonAccount is not being used and replaced Account with Contact fields to be displayed in UI
ow.AccountContactId = c.Contact.Id;
ow.PriceBookId = (Test.isRunningTest()) ? Test.getStandardPricebookId() : [SELECT Id FROM PriceBook2 WHERE isStandard = TRUE LIMIT 1][0].Id;
ow.CaseNumber = c.CaseNumber;
ow.CompanyName = c.Account.Name;
ow.ContactName = c.Contact.Name;
ow.Phone = c.Contact.Phone;
ow.Email = c.Contact.Email;
ow.ShippingStreet = c.Contact.MailingStreet;
ow.ShippingCity = c.Contact.MailingCity;
ow.ShippingState = c.Contact.MailingState;
ow.ShippingPostalCode = c.Contact.MailingPostalCode;
ow.ShippingCountry = c.Contact.MailingCountry ;
if(c.Type != null)
ow.isSpecialHandling = c.Type.equals('Special Handling');
System.debug('isSpecialHandling: ' + ow.isSpecialHandling);
if(c.Account != null && (String.isBlank(c.Contact.MailingCountry ) || c.Contact.MailingCountry == 'CA'))
ow.isCanadian = true;
if(c.Asset.Product2Id != null)
productId = c.Asset.Product2Id;
system.debug('ow--> '+JSON.serialize(ow));
loadProduct(ow, c);
} else {
System.debug('There was no case associated with the passed Id: ' + caseId);
}
}
User u = [SELECT Id, LID_Code__c FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1];
String bypassAV = ApexCodeSettings__c.getOrgDefaults().Bypass_Address_Validation__c;
System.debug('bypassAV: ' + byPassAv);
System.debug('userId: ' + u.Id);
if(String.isNotEmpty(bypassAV)){
if(bypassAv.contains(u.Id.to15())){
System.debug('user can bypass av');
ow.CanBypassAddressValidation = true;
}
}
ow.UserLocation = u.LID_Code__c;
return ow;
}
private static Map<String, LightningSelect[]> getStates(){
Map<String, LightningSelect[]> stateOptionsMap = new Map<String, LightningSelect[]>();
for(PicklistEntry entry : SObjectType.Contact.fields.StateOption__c.getPicklistValues()){
stateOptionsMap.put(entry.getValue(), new LightningSelect[]{new LightningSelect('', '--Select State--')});
}
return stateOptionsMap;
}
private static LightningSelect[] getCountries(){
LightningSelect[] results = new LightningSelect[]{};
LightningSelect[] orderedResults = new LightningSelect[]{new LightningSelect('', '--Select Country--')};
for(PicklistEntry entry : SObjectType.Contact.fields.CountryOption__c.getPicklistValues()) {
if(entry.getLabel() == 'United States') {
orderedResults.add(new LightningSelect(entry.getValue(), entry.getLabel()));
} else {
results.add(new LightningSelect(entry.getValue(), entry.getLabel()));
}
}
for(LightningSelect ls : results) {
orderedResults.add(ls);
}
return orderedResults;
}
private static LightningSelect[] getCountry(){
LightningSelect[] orderedResults = new LightningSelect[]{new LightningSelect('', '--Select Country--')};
//orderedResults.add(new LightningSelect('United States', 'United States'));
//orderedResults.add(new LightningSelect('Canada', 'Canada'));
List<CountryList__c> mcs = CountryList__c.getall().values();
for(CountryList__c c : mcs){
orderedResults.add(new LightningSelect(c.Name, c.Country_Name__c));
}
return orderedResults;
}
private static void loadProduct(OrderWrapper ow, Case c) {
Part[] products = new Part[]{};
//add case asset and related products to returns page
if(c.Asset.Product2.Orderable__c || c.Asset.Product2.Case_Creation__c) {
ow.ReturnParts = new list<Part>();
//asset
Part retProduct = new Part(c.Asset.Product2, ow.isCanadian);
if(retProduct.p.RecordType.DeveloperName == 'Amer_Products') {
ow.ReturnParts.add(retProduct.clone());
//parts
for(Part p : getParts(new Set<Id>{retProduct.p.Id}, ow.isCanadian).get(retProduct.p.Id)) {
system.debug('689');
if(p.p.RecordType.DeveloperName == 'Amer_Products') {
ow.ReturnParts.add(p);
}
}
}
}
system.debug(' ow.ReturnParts--> '+JSON.serialize(ow.ReturnParts));
if((c.Asset.Product2.Orderable__c || c.Asset.Product2.Case_Creation__c) && c.Asset.Product2.Stockroom__c != 'None' /* && cs.Asset.Product2.Has_Replacement__c == false */) {
ow.Product = new Part(c.Asset.Product2, ow.isCanadian);
products = new Part[] { ow.Product };
}
if(c.Asset != null){
Replacement__c[] replacements = [
SELECT Replacement_Product__r.Stockroom__c, Replacement_Product__r.Orderable__c, Replacement_Product__r.Physical_Stock__c, Replacement_Product__r.Name, Replacement_Product__r.Description, Replacement_Product__r.Product_Image__c, Replacement_Product__r.RecordType.Name, Replacement_Product__r.RecordType.DeveloperName, Replacement_Product__r.Family, Replacement_Product__r.Available_Balance__c, Replacement_Product__r.In_Transit__c, Replacement_Product__r.On_Order__c, Replacement_Product__r.Recall_Count__c, Replacement_Product__r.Order_Override__c, Replacement_Product__r.Has_Replacement__c, Replacement_Product__r.Canada_Stock_Available__c, Replacement_Product__r.Part_Type__c, Replacement_Product__r.Preferred_Return_Carrier__c, Replacement_Product__r.Product_Region__c
FROM Replacement__c
WHERE Replacement_Product__r.Orderable__c = TRUE AND Obsolete_Product__c = :c.Asset.Product2Id /* AND Replacement_Product__r.Has_Replacement__c = FALSE */
ORDER BY Replacement_Product__r.Name ASC
];
system.debug(' replacements--> '+JSON.serialize(replacements));
for(Replacement__c replacement : replacements){
System.debug('708');
products.add(new Part(replacement.Replacement_Product__r, ow.isCanadian));
}
}
system.debug(' products--> '+JSON.serialize(products));
Set<Id> prodIds = new Set<Id>{};
for(Part p : products)
prodIds.add(p.p.Id);
//Get parts
Map<Id, Part[]> productParts = getParts(prodIds, ow.isCanadian);
system.debug(' productParts--> '+JSON.serialize(productParts));
//Group parts under each product
ow.Parts = new Part[]{};
for(Part prod : products) {
ow.Parts.add(prod);
for(Part p : productParts.get(prod.p.Id))
ow.Parts.add(p);
}
system.debug(' ow.Parts--> '+JSON.serialize(ow.Parts));
loadPriceData(ow.Parts);
}
private static void loadPriceData(Part[] parts) {
Set<Id> pIds = new Set<Id>();
system.debug('parts-->'+JSON.serialize(parts));
for(Part p : parts) {
pIds.add(p.p.Id);
}
system.debug('pIds-->'+JSON.serialize(pIds));
PricebookEntry[] pbes;
if(Test.isRunningTest()) {
pbes = [SELECT Pricebook2Id, Product2Id, UnitPrice, PreAuth_Needed__c, PreAuth_List_Price__c FROM PricebookEntry WHERE Product2Id IN :pIds AND PriceBook2Id = :(Test.getStandardPricebookId()) LIMIT 10000];
}
else {
pbes = [SELECT Pricebook2Id, Product2Id, UnitPrice, PreAuth_Needed__c, PreAuth_List_Price__c FROM PricebookEntry WHERE Product2Id IN :pIds AND PriceBook2.isStandard = TRUE LIMIT 10000];
}
system.debug('pbes-->'+JSON.serialize(pbes));
Map<Id, PricebookEntry> productToPbEntryMap = new Map<Id, PricebookEntry>();
for(PricebookEntry pbe : pbes) {
productToPbEntryMap.put(pbe.Product2Id, pbe);
}
system.debug('productToPbEntryMap-->'+JSON.serialize(productToPbEntryMap));
for(Part p : parts) {
if(productToPbEntryMap.containsKey(p.p.Id)){
PricebookEntry e = productToPbEntryMap.get(p.p.Id);
p.preAuthNeeded = e.PreAuth_Needed__c;
p.preAuthPrice = (p.preAuthNeeded && e.PreAuth_List_Price__c != null) ? e.PreAuth_List_Price__c : 0;
p.preAuthQty = (p.preAuthNeeded) ? 1 : 0;
p.price = e.UnitPrice;
p.pbe = e;
System.debug(e);
}
}
}
//FABASE Migration change
/*private static void loadReplacements(List<Part> parts){
Set<Id> productIds = new Set<Id>();
for(Part p : parts){
if(p.p.RecordType.Name == 'Product'){
productIds.add(p.p.Id);
}
}
Map<Id, List<Alternative__c>> replacementsByProdId = new Map<Id, List<Alternative__c>>();
Date today = Date.today();
for(Alternative__c a : [SELECT Id, Original_Product__c, Alternative_Product__c FROM Alternative__c WHERE Alternative_Expiration_Date__c > :today AND Original_Product__c IN :productIds]){
List<Alternative__c> alts = new List<Alternative__c>();
if(replacementsByProdId.containsKey(a.Original_Product__c)){
alts = replacementsByProdId.get(a.Original_Product__c);
}
alts.add(a);
replacementsByProdId.put(a.Original_Product__c, alts);
}
}*/
@TestVisible
private static List<Part> loadDisposalParts() {
Part[] products = new Part[]{};
for(Product2 p : [SELECT Id, Physical_Stock__c, Orderable__c, Stockroom__c,
Case_Creation__c,IsActive, Name, Description, Product_Image__c, RecordType.Name,
RecordType.DeveloperName, Family, Available_Balance__c, In_Transit__c, On_Order__c, Recall_Count__c,
Order_Override__c, Has_Replacement__c, Canada_Stock_Available__c, Part_Type__c, Preferred_Return_Carrier__c, Product_Region__c, Disposal_Product__c
FROM Product2
WHERE Disposal_Product__c = true]){
products.add(new Part(p, false));
}
return products;
}
private static List<Part> searchDisposalParts(String searchTerm) {
Part[] products = new Part[]{};
for(Product2 p : [SELECT Id, Physical_Stock__c, Orderable__c, Stockroom__c,
Case_Creation__c,IsActive, Name, Description, Product_Image__c, RecordType.Name,
RecordType.DeveloperName, Family, Available_Balance__c, In_Transit__c, On_Order__c, Recall_Count__c,
Order_Override__c, Has_Replacement__c, Canada_Stock_Available__c, Part_Type__c, Preferred_Return_Carrier__c, Product_Region__c, Disposal_Product__c
FROM Product2
WHERE Disposal_Product__c = true AND Name LIKE :searchTerm]){
products.add(new Part(p, false));
}
return products;
}
private static Boolean isPOBox(String street){
return String.isNotBlank(street) && Pattern.matches(PO_BOX_EXPR, street);
}
public static Boolean getIsAdvancedExchange(OrderWrapper ow) {
return ow.ReturnType == 'Advanced Exchange' && getIsReturn(ow);
}
public static Boolean getIsReturn(OrderWrapper ow) {
return ow.ReturnNeeded == 'true';
}
private static Map<Id, Part[]> getParts(Set<Id> productIds, Boolean isCanadian) {
Product_Part__c[] prodParts = [
SELECT Product__c,
Product_Part__r.Name,
Product_Part__r.Description,
Product_Part__r.Product_Image__c,
Product_Part__r.RecordType.Name,
Product_Part__r.RecordType.DeveloperName,
Product_Part__r.Family,
Product_Part__r.Available_Balance__c,
Product_Part__r.In_Transit__c,
Product_Part__r.On_Order__c,
Product_Part__r.Stockroom__c,
Product_Part__r.Physical_Stock__c,
Product_Part__r.Has_Replacement__c,
Product_Part__r.Recall_Count__c,
Product_Part__r.Order_Override__c,
Product_Part__r.Canada_Stock_Available__c,
Product_Part__r.Orderable__c,
Product_Part__r.Part_Type__c,
Product_Part__r.Product_Region__c
FROM Product_Part__c
WHERE Product_Part__r.Orderable__c = TRUE AND Product__c IN :productIds AND Product_Part__c != null /*AND (Product_Part__r.Recall_Count__c = NULL OR Product_Part__r.Recall_Count__c = 0)*/ AND Product_Part__r.Stockroom__c != 'None' /*AND (Product_Part__r.Replacement__c = null OR Product_Part__r.Replacement__r.Stockroom__c = 'None')*/
ORDER BY Product_Part__r.Name
];
system.debug('prodParts--> '+JSON.serialize(prodParts));
Map<Id, Part[]> partsByProductId = new Map<Id, Part[]>();
for(Id pid : productIds)
partsByProductId.put(pid, new Part[]{});
Set<Id> partsAdded = new Set<Id>(); //Used to prevent same part from being listed twice
for(Product_Part__c part : prodParts) {
if(!partsAdded.contains(part.Product_Part__c)) {
partsByProductId.get(part.Product__c).add(new Part(part.Product_Part__r, isCanadian));
partsAdded.add(part.Product_Part__c);
}
}
system.debug('partsByProductId--> '+JSON.serialize(partsByProductId));
return partsByProductId;
}
public class OrderWrapper{
public String Id { get; set; }
public String AccountId { get; set; }
public String AccountContactId { get; set; }
public String PriceBookId { get; set; }
public String CaseNumber { get; set; }
public String ContactName { get; set; }
public String Phone { get; set; }
public String CompanyName { get; set; }
public String Email { get; set; }
public String ShippingStreet { get; set; }
public String ShippingCity { get; set; }
public String ShippingState { get; set; }
public String ShippingPostalCode { get; set; }
public String ShippingCountry { get; set; }
public Boolean isCanadian { get; set; }
public Part Product { get; set; }
public Part refundProduct { get; set; }
public String UserLocation { get; set; }
public String Type { get; set; }
public String ReturnNeeded { get; set; }
public String ReturnType { get; set; }
public String SearchTerm { get; set; }
public Boolean SendPaymentRequest { get; set; }
public Boolean isSpecialHandling { get; set; }
public Boolean CreateShippingLabel { get; set; }
public Boolean ExpediteShipping { get; set; }
public Boolean WaiveShipping { get; set; }
public Boolean UpdateShippingAddress { get; set; }
public Boolean CanBypassAddressValidation { get; set; }
public List<Part> OrderLineItems { get; set; }
public List<Part> ReturnLineItems { get; set; }
public List<Part> Parts { get; set; }
public List<Part> ReturnParts { get; set; }
public Decimal Shipping { get; set; }
public OrderWrapper(String caseId){
this.Id = caseId;
this.Type = '';
this.ReturnType = '';
this.ReturnNeeded = '';
this.isCanadian = false;
this.SendPaymentRequest = false;
this.CreateShippingLabel = false;
this.ExpediteShipping = false;
this.WaiveShipping = false;
this.UpdateShippingAddress = true;
this.OrderLineItems = new List<Part>();
this.ReturnLineItems = new List<Part>();
this.Shipping = 0.00;
this.CanBypassAddressValidation = false;
this.isSpecialHandling = false;
List<Product2> p = [SELECT IsActive, Orderable__c, Name, Description, Product_Image__c, RecordType.Name, RecordType.DeveloperName, Family, Available_Balance__c, In_Transit__c, On_Order__c, Stockroom__c, Physical_Stock__c, Has_Replacement__c, Recall_Count__c, Order_Override__c, Canada_Stock_Available__c, Part_Type__c,Preferred_Return_Carrier__c, Product_Region__c FROM Product2 WHERE Id = :REFUND_REQUEST_PRODUCT_ID LIMIT 1];
if(!p.isEmpty()) {
Part aPart = new Part(p[0], false);
aPart.price = 0;
this.refundProduct = aPart;
}
else {
System.debug('refund part could not be found');
this.refundProduct = null;
}
}
}
public class Part {
private Boolean isCanadian { get; set; }
public Product2 p {get; set;}
public Purchase_Order__c[] pos {get; set;}
public Decimal price {get; set;}
public Integer qty {get; set;}
//public String stockroom { get; set; }
public Decimal total { get; set; }
public String notes {get; set;}
public Boolean preAuthNeeded {get;set;}
public Integer preAuthQty {get;set;}
public Decimal preAuthPrice {get;set;}
public Boolean isUniversalPart {get;set;}
public String batteriesOrWireHarness {get;set;}
public PricebookEntry pbe {get;set;}
public Boolean isSelected { get; set; }
public Boolean canSelect { get; set; }
public String unavailableReason { get; set; }
public String region { get; set; }
public List<Part> replacements { get; set; }
@TestVisible
Part(Product2 prod, Boolean isCanadian) {
this.isCanadian = isCanadian;
this.p = prod;
this.price = price;
this.qty = 1;
//this.stockroom = prod.Stockroom__c;
//total = qty * price;
this.preAuthNeeded = false;
this.preAuthQty = 0;
this.preAuthPrice = 0;
this.isUniversalPart = prod.Name.toLowerCase().contains('universal');
this.batteriesOrWireHarness = '';
this.isSelected = false;
this.canSelect = this.getCanSelect(prod);
this.unavailableReason = this.getUnavailableReason(prod);
this.region = prod.Product_Region__c;
}
public String getNotesField(Integer row) {
if(this.notes == null)
return null;
String[] lines = this.notes.split('\n');
if(row >= lines.size())
return null;
return lines[row].left(35);
}
public Boolean getCanSelect(Product2 p) {
if(!p.Orderable__c)
return false;
if(p.Order_Override__c)
return true;
if(p.Physical_Stock__c > 0)
return true;
if(p.Available_Balance__c <= 0 && p.Physical_Stock__c <= 0 && !p.Order_Override__c)
return false;
if(p.Recall_Count__c != null && p.Recall_Count__c > 0)
return false;
if(p.Available_Balance__c <= 0 && p.Has_Replacement__c == true)
return false;
/*
if(p.Available_Balance__c <= 0)
return false;
*/
if(p.Stockroom__c != 'en' || ApexCodeSettings__c.getOrgDefaults().NewOrderValidateAvailableBalance__c != true)
return true;
return (p.Available_Balance__c != null && p.Available_Balance__c > 0) || (p.In_Transit__c != null && p.In_Transit__c > 0) ||
(p.On_Order__c != null && p.On_Order__c > 0) || (isCanadian && p.Canada_Stock_Available__c);
}
public String getUnavailableReason(Product2 p) {
if(p.Recall_Count__c != null && p.Recall_Count__c > 0)
return 'recalled';
if(p.Has_Replacement__c == true)
return 'obsolete';
return 'not in stock';
}
}
private static final Map<String, String> STATE_MAP = new Map<String, String> {
'AL' => 'Alabama',
'AK' => 'Alaska',
'AZ' => 'Arizona',
'AR' => 'Arkansas',
'CA' => 'California',
'CO' => 'Colorado',
'CT' => 'Connecticut',
'DE' => 'Delaware',
'FL' => 'Florida',
'GA' => 'Georgia',
'HI' => 'Hawaii',
'ID' => 'Idaho',
'IL' => 'Illinois',
'IN' => 'Indiana',
'IA' => 'Iowa',
'KS' => 'Kansas',
'KY' => 'Kentucky',
'LA' => 'Louisiana',
'ME' => 'Maine',
'MD' => 'Maryland',
'MA' => 'Massachusetts',
'MI' => 'Michigan',
'MN' => 'Minnesota',
'MS' => 'Mississippi',
'MO' => 'Missouri',
'MT' => 'Montana',
'NE' => 'Nebraska',
'NV' => 'Nevada',
'NH' => 'New Hampshire',
'NJ' => 'New Jersey',
'NM' => 'New Mexico',
'NY' => 'New York',
'NC' => 'North Carolina',
'ND' => 'North Dakota',
'OH' => 'Ohio',
'OK' => 'Oklahoma',
'OR' => 'Oregon',
'PA' => 'Pennsylvania',
'RI' => 'Rhode Island',
'SC' => 'South Carolina',
'SD' => 'South Dakota',
'TN' => 'Tennessee',
'TX' => 'Texas',
'UT' => 'Utah',
'VT' => 'Vermont',
'VA' => 'Virginia',
'WA' => 'Washington',
'WV' => 'West Virginia',
'WI' => 'Wisconsin',
'WY' => 'Wyoming'
};
public static Map<String, String> lookupCityState(String zip, Boolean fullStateName) {
Map<String, String> info = new Map<String, String> {'city' => '', 'state' => ''};
if(zip == null)
return info;
//Canada Postal Code
if(Pattern.matches('^[ABCEGHJKLMNPRSTVXY]\\d[A-Z] ?\\d[A-Z]\\d$', zip.toUpperCase())) {
//curl -X GET -H "Accept: application/vnd.cpc.postoffice+xml" -H "Authorization: Basic NjgzZmVjMmIzNGM0YjI4NDozMmIwMzg5ZWIyNmVlNWE0YmM2ZmI2" "https://soa-gw.canadapost.ca/rs/postoffice?postalCode=M6C3Y1&maximum=1"
zip = zip.toUpperCase().replace(' ', '');
try {
String url = 'https://soa-gw.canadapost.ca/rs/postoffice?maximum=1&postalCode=' + zip;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setHeader('Authorization', 'Basic NjgzZmVjMmIzNGM0YjI4NDozMmIwMzg5ZWIyNmVlNWE0YmM2ZmI2');
req.setHeader('Accept', 'application/vnd.cpc.postoffice+xml');
req.setEndpoint(url);
String xml;
if(!Test.isRunningTest())
xml = h.send(req).getBody();
else
xml = ' <CITY>TORONTO</CITY><PROVINCE>ON</PROVINCE>';
Integer cs = xml.toUpperCase().indexOf('<CITY>');
Integer ce = xml.toUpperCase().indexOf('</CITY>');
Integer ss = xml.toUpperCase().indexOf('<PROVINCE>');
Integer se = xml.toUpperCase().indexOf('</PROVINCE>');
if(cs > 0 && ce > cs && ss > 0 && se > ss) {
info.put('city', TitleCaseUtil.toTitleCase(xml.substring(cs + 6, ce).trim(), false));
info.put('state', xml.substring(ss + 10, se).trim());
if(fullStateName == true && STATE_MAP.containsKey(info.get('state').trim().toUpperCase()))
info.put('state', STATE_MAP.get(info.get('state').trim().toUpperCase()));
}
System.debug(info);
return info;
}
catch(Exception e) {
String message = 'QuickCreateController.lookupCityState() threw: ' + e.getMessage() + ' @ ' + e.getStackTraceString();
System.debug(message);
sendErrorReport(message);
return info;
}
//return null;
}
else { //US Zip Code
zip = zip.replaceAll('[^0-9]', '');
zip = zip.left(5);
if(zip.length() != 5)
return info;
try {
String url = 'http://production.shippingapis.com/ShippingAPI.dll';
url += '?API=CityStateLookup&XML=' + EncodingUtil.urlEncode('<CityStateLookupRequest USERID="844JARDE1026"><ZipCode ID="0"><Zip5>' + String.escapeSingleQuotes(zip) + '</Zip5></ZipCode></CityStateLookupRequest>', 'UTF-8');
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint(url);
String xml;
if(!Test.isRunningTest())
xml = h.send(req).getBody();
else
xml = ' <City>TRENTON</City><State>NJ</State>';
Integer cs = xml.toUpperCase().indexOf('<CITY>');
Integer ce = xml.toUpperCase().indexOf('</CITY>');
Integer ss = xml.toUpperCase().indexOf('<STATE>');
Integer se = xml.toUpperCase().indexOf('</STATE>');
if(cs > 0 && ce > cs && ss > 0 && se > ss) {
info.put('city', TitleCaseUtil.toTitleCase(xml.substring(cs + 6, ce).trim(), false));
info.put('state', xml.substring(ss + 7, se).trim());
if(fullStateName == true && STATE_MAP.containsKey(info.get('state').trim().toUpperCase()))
info.put('state', STATE_MAP.get(info.get('state').trim().toUpperCase()));
}
System.debug(info);
return info;
}
catch(Exception e) {
String message = 'QuickCreateController.lookupCityState() threw: ' + e.getMessage() + ' @ ' + e.getStackTraceString();
System.debug(message);
sendErrorReport(message);
return info;
}
}
}
private static void sendErrorReport(String details) {
try {
ApexCodeSettings__c setting = ApexCodeSettings__c.getOrgDefaults();
if(String.isBlank(details) || String.isBlank(setting.QuickCreateErrorEmailUserId__c))
return;
if(String.isNotBlank(setting.QuickCreateErrorEmailExclusions__c))
for(String exclusion : setting.QuickCreateErrorEmailExclusions__c.trim().split('\n'))
if(String.isNotBlank(exclusion))
if(details.contains(exclusion.trim()))
return;
Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
msg.setPlainTextBody(details);
msg.setTargetObjectId(setting.QuickCreateErrorEmailUserId__c.trim());
msg.setSaveAsActivity(false);
for(Messaging.SendEmailResult result : messaging.sendEmail(new Messaging.Email[]{msg}, false))
if(!result.isSuccess())
for(Messaging.SendEmailError err : result.getErrors())
System.debug(err.getMessage());
}
catch(Exception e) {
System.debug('OrderAndReturnCtrl.sendErrorReport threw: ' + e.getMessage() + ' @ ' + e.getStackTraceString());
}
}
//FOR PICKLISTS
public class LightningSelect{
public String value{get;set;}
public String label{get;set;}
public String icon{get;set;}
public LightningSelect(String value, String label){
this.value = value;
this.label = label;
}
public LightningSelect(String value, String label, String icon){
this.value = value;
this.label = label;
this.icon = icon;
}
}
}