/** * ─────────────────────────────────────────────────────────────────────────────────────────────────┐ * This class is use for upsert Salesforce Records, Send Notificaion Email and upsert Error Message if any. * Shopify API Documentation: https://shopify.dev/docs/admin-api/rest/reference * Create Shopify Store: https://www.shopify.com/signup?itcat=identity&itterm=create-new-store * Shopify API Release 2020: https://www.shopify.in/partners/blog/shopify-api-release-january-2020 * What is Person Account in Salesforce ? https://help.salesforce.com/articleView?id=account_person.htm&type=5 * ────────────────────────────────────────────────────────────────────────────────────────────────── * @author Sumit * ────────────────────────────────────────────────────────────────────────────────────────────────── */ public with sharing class EmailErrorCSV { //private static Integer fpAcc = 0; private static Integer fpOrd = 0; private static Integer fpOrdItem = 0; //private static Integer fpProd = 0; public static List configListToCheckObjects = new List (); public static map Shopifyididvsbody = new map(); //Shopify Id vs JSON Response body /**************************************makeCsvAndSendInEmail*************************************************/ /** * ─────────────────────────────────────────────────────────────────────────────────────────────┐ * Upsert Records into the Salesforce * Upsert Error Messages into Salesforce If any catch * ────────────────────────────────────────────────────────────────────────────────────────────── * @param String jSONRequestBody - JOSN Response of all records * @param String ObjectName - Shopify Entity's Name * @param List objectList - list of object define in JSONResponse * @param Schema.SobjectField externalIdField - Shopify External ID * @param boolean IsWebhook - Define is webhook record or process for batch records * ─────────────────────────────────────────────────────────────────────────────────────────────┘ */ public static void makeCsvAndSendInEmail( String jSONRequestBody, String objectName, List objectList, Schema.SobjectField externalIdField, boolean IsWebhook, String store){ try{ //use for add in shopify External Id to make it unique String isbatch = 'F'; if(Iswebhook){ isbatch = 'T'; } Boolean isPerson = Schema.sObjectType.Account.fields.getMap().containsKey( 'isPersonAccount' ); if(Schema.sObjectType.HIC_ShopifySync__HIC_Configuration__c.isAccessible() && Schema.sObjectType.HIC_ShopifySync__HIC_Configuration__c.isCreateable()){ String query = 'Select '+ CheckAccessibility.isAccessible('id,HIC_ShopifySync__AccountFilter__c,HIC_ShopifySync__Dynamic_prevent_duplicate__c,HIC_ShopifySync__ContactFilter__c,HIC_ShopifySync__Update_Identified_Contact_Records__c, HIC_ShopifySync__Update_Identified_Account_Records__c, HIC_ShopifySync__Upsert_Account_basis_on_Customer_Company__c, HIC_ShopifySync__Collection__c,HIC_ShopifySync__Batch_Is_Processing__c,HIC_ShopifySync__Shopify_URL__c, HIC_ShopifySync__Private_Key_Password__c,HIC_ShopifySync__Inventory_Location__c, HIC_ShopifySync__Enable_Draft_Order__c,HIC_ShopifySync__API_Key__c, name, HIC_ShopifySync__Opportunity__c, HIC_ShopifySync__Order__c, HIC_ShopifySync__Opportunity_Line_Item__c, HIC_ShopifySync__Order_Line_Item__c,HIC_ShopifySync__Upsert_Lead_basis_on_Email__c,HIC_ShopifySync__Update_Identified_Lead_Records__c, HIC_ShopifySync__Order_Fulfillment__c, HIC_ShopifySync__Person_Account__c,HIC_ShopifySync__Upsert_Customer_basis_on_Email__c','HIC_ShopifySync__HIC_Configuration__c')+' from HIC_ShopifySync__HIC_Configuration__c Where '+CheckAccessibility.isAccessible('HIC_ShopifySync__Store__c', 'HIC_ShopifySync__HIC_Configuration__c')+' = \''+store+'\' LIMIT 49999'; configListToCheckObjects = Database.query(query); } Schema.SObjectType SObjectType = Schema.getGlobalDescribe().get(objectName); Schema.DescribeSObjectResult objResult = SObjectType.getDescribe(); string ObjectLabelName = String.valueof(objResult.getLabel()); //Get Error mapping records list listofErrormailfield = new List(); String ErrorfieldMappingquery = 'select ' +CheckAccessibility.isAccessible('name,HIC_ShopifySync__Shopify_Field__c','HIC_ShopifySync__Error_Mapping__c') +' from HIC_ShopifySync__Error_Mapping__c where '+ CheckAccessibility.isAccessible('name','HIC_ShopifySync__Error_Mapping__c') + ' = \''+ ObjectLabelName +'\' limit 1'; listofErrormailfield = Database.query(ErrorfieldMappingquery); Schema.SObjectType ObjectType = Schema.getGlobalDescribe().get(objectName); Map fieldMap = ObjectType.getDescribe().fields.getmap(); Schema.SobjectField theField = null; //use for add in shopify External Id to make it unique if(!listofErrormailfield.isEmpty()){ theField = fieldMap.get(String.ValueOf(listofErrormailfield[0].HIC_ShopifySync__Shopify_Field__c)); } /************* Upsert sObject records into Salesforce ****************/ List updateResult = new List (); //Product if (objectName == 'Product2') { List prodListToUpsert = (List) objectList; List updateProductList = new List(); if (configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c != null) { String jsonString = configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c; Object deserializedObject = JSON.deserializeUntyped(jsonString); List> jsonList = new List>(); if (deserializedObject instanceof List) { for (Object obj : (List) deserializedObject) { if (obj instanceof Map) { jsonList.add((Map) obj); } } } else { System.debug('Invalid JSON structure detected.'); } List> filteredList = new List>(); for (Map jsonObj : jsonList) { if (jsonObj.containsKey('SalesforceObject') && jsonObj.get('SalesforceObject') == 'Product2') { filteredList.add(jsonObj); } } if (!filteredList.isEmpty()) { SObject sobjectRecord = Schema.getGlobalDescribe().get('Product2').newSObject(); Set excludedFields = new Set{'Id', 'HIC_ShopifySync__Shopify_Id__c'}; String filteredJsonString = JSON.serialize(filteredList); String soqlQuery = generateSOQL(filteredJsonString, sobjectRecord, jsonRequestBody); List existingProducts = Database.query(soqlQuery); Set alreadyHandledIds = new Set(); for (Product2 incoming : prodListToUpsert) { for (Product2 existing : existingProducts) { if (existing == null || alreadyHandledIds.contains(existing.Id)) continue; Boolean matched = false; for (Map rule : filteredList) { String sfField = (String) rule.get('SalesforceFieldApiName'); String operator = ((String) rule.get('MatchingOperator')).toLowerCase(); Boolean caseSensitive = rule.containsKey('caseSensitive') && (Boolean) rule.get('caseSensitive'); String existingValue = existing.get(sfField) != null ? String.valueOf(existing.get(sfField)) : ''; String incomingValue = incoming.get(sfField) != null ? String.valueOf(incoming.get(sfField)) : ''; if (operator == 'equals' && existingValue.equals(incomingValue) && caseSensitive) { matched = true; break; } else if (operator == 'contains') { matched = true; break; } else if (operator == 'equals' && !caseSensitive && existingValue.equalsIgnoreCase(incomingValue)) { matched = true; break; } } if (matched) { String incomingShopifyId = incoming.HIC_ShopifySync__Shopify_Id__c; String existingShopifyId = existing.HIC_ShopifySync__Shopify_Id__c; if (incomingShopifyId != existingShopifyId) { Product2 toUpdate = new Product2(Id = existing.Id); toUpdate.HIC_ShopifySync__Shopify_Id__c = incomingShopifyId; updateProductList.add(toUpdate); alreadyHandledIds.add(existing.Id); System.debug('Product2 match found with different Shopify ID. Added to update list: ' + toUpdate); } break; } } } if (!updateProductList.isEmpty()) { System.debug('Performing update on existing Product2 records...'); Database.update(updateProductList, false); } } } if (CheckAccessibility.isUpsertable(String.valueOf(externalIdField), 'Product2')) { if (!updateProductList.isEmpty()) { Set updatedIds = new Set(); for (Product2 prod : updateProductList) { updatedIds.add(prod.Id); } List remainingProductsToUpsert = new List(); for (Product2 prod : prodListToUpsert) { if (!updatedIds.contains(prod.Id)) { remainingProductsToUpsert.add(prod); } } prodListToUpsert = remainingProductsToUpsert; } System.debug('Upserting Product2 records: ' + prodListToUpsert); List upsertResults = Database.upsert(prodListToUpsert, externalIdField, false); for (Integer i = 0; i < upsertResults.size(); i++) { Database.UpsertResult sr = upsertResults[i]; Product2 prod = prodListToUpsert[i]; if (sr.isSuccess()) { if (sr.isCreated()) { //fpProd++; System.debug('INSERTED Product2 Id=' + sr.getId() + ' ShopifyId=' + prod.HIC_ShopifySync__Shopify_Id__c); } else { System.debug('UPDATED Product2 Id=' + sr.getId() + ' ShopifyId=' + prod.HIC_ShopifySync__Shopify_Id__c); } } else { System.debug('FAILED Product2 ShopifyIad=' + prod.HIC_ShopifySync__Shopify_Id__c + ' Errors: ' + sr.getErrors()); } } } } //Account else if(objectName == 'Account'){ system.debug('***AccountObjectName'+objectName); List accListToUpsert = new List (); accListToUpsert = (List ) objectList; System.debug('accListToUpsert****'+accListToUpsert); Map accEmailVsAccountMap = new Map(); Map companyVsAccountMap = new Map(); Map companyVsExistingRecMap = new Map(); List identifiedAccountList = new List(); List updateAccountList = new List(); if(configListToCheckObjects[0].HIC_ShopifySync__Upsert_Customer_basis_on_Email__c && Schema.sObjectType.Account.fields.getMap().containsKey( 'ispersonaccount') && configListToCheckObjects[0].HIC_ShopifySync__Person_Account__c){ Map emailVsExistingRecMap = new Map(); for(Account acc : accListToUpsert){ if(acc.get('PersonEmail') != null){ accEmailVsAccountMap.put(String.valueOf(acc.get('PersonEmail')),acc); } } Set emailSet = accEmailVsAccountMap.keySet(); if (!emailSet.isEmpty()) { for (Account acc : Database.query('SELECT Id, PersonEmail, HIC_ShopifySync__Shopify_Id__c, HIC_ShopifySync__Is_identified__c FROM Account WHERE PersonEmail IN :emailSet' + (configListToCheckObjects[0].HIC_ShopifySync__AccountFilter__c != null ? ' ' + configListToCheckObjects[0].HIC_ShopifySync__AccountFilter__c : ''))) { emailVsExistingRecMap.put(String.valueOf(acc.get('PersonEmail')), acc); } } for(string email : emailVsExistingRecMap.keyset()){ if(accEmailVsAccountMap.containsKey(email)){ //Account existAccount = accEmailVsAccountMap.get(email); Account existAccount = new Account(); existAccount.Id = emailVsExistingRecMap.get(email).Id; existAccount.HIC_ShopifySync__Shopify_Id__c = accEmailVsAccountMap.get(email).HIC_ShopifySync__Shopify_Id__c; existAccount.HIC_ShopifySync__Is_identified__c = true; if(emailVsExistingRecMap.get(email).HIC_ShopifySync__Shopify_Id__c != accEmailVsAccountMap.get(email).HIC_ShopifySync__Shopify_Id__c){ accEmailVsAccountMap.remove(email); identifiedAccountList.add(existAccount); updateAccountList.add(existAccount); } else if(emailVsExistingRecMap.get(email).HIC_ShopifySync__Is_identified__c) identifiedAccountList.add(existAccount); accEmailVsAccountMap.remove(email); } } if(!updateAccountList.isEmpty()) Database.update(updateAccountList, false); //fpAcc++; }else if(configListToCheckObjects[0].HIC_ShopifySync__Upsert_Account_basis_on_Customer_Company__c && !configListToCheckObjects[0].HIC_ShopifySync__Person_Account__c){ for(Account acc : accListToUpsert){ if(acc.get('Name') != null){ companyVsAccountMap.put(String.valueOf(acc.get('Name')).trim().toLowerCase(), acc); } } Set companySet = companyVsAccountMap.keySet(); if (!companySet.isEmpty()) { for (Account acc : Database.query('SELECT Id, HIC_ShopifySync__Shopify_Id__c, Name, HIC_ShopifySync__Is_identified__c FROM Account WHERE Name IN :companySet' + (configListToCheckObjects[0].HIC_ShopifySync__AccountFilter__c != null ? ' ' + configListToCheckObjects[0].HIC_ShopifySync__AccountFilter__c : ''))) { system.debug('acc-->'+acc); companyVsExistingRecMap.put(String.valueOf(acc.get('Name')).trim().toLowerCase(), acc); } } for(string company : companyVsExistingRecMap.keyset()){ if(companyVsAccountMap.containsKey(company)){ //Account existAccount = companyVsAccountMap.get(company); Account existAccount = new Account(); existAccount.Id = companyVsExistingRecMap.get(company).Id; existAccount.HIC_ShopifySync__Shopify_Id__c = companyVsAccountMap.get(company).HIC_ShopifySync__Shopify_Id__c; existAccount.HIC_ShopifySync__Is_identified__c = true; if(companyVsExistingRecMap.get(company).HIC_ShopifySync__Shopify_Id__c != companyVsAccountMap.get(company).HIC_ShopifySync__Shopify_Id__c){ companyVsAccountMap.remove(company); identifiedAccountList.add(existAccount); updateAccountList.add(existAccount); } else if(companyVsExistingRecMap.get(company).HIC_ShopifySync__Is_identified__c) identifiedAccountList.add(existAccount); companyVsAccountMap.remove(company); } } if(!updateAccountList.isEmpty()) Database.update(updateAccountList, false); } else if (configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c != null) { String jsonString = configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c; Object deserializedObject = JSON.deserializeUntyped(jsonString); List> jsonList = new List>(); if (deserializedObject instanceof List) { List tempList = (List) deserializedObject; for (Object obj : tempList) { if (obj instanceof Map) { jsonList.add((Map) obj); } } } else { System.debug('Invalid JSON structure detected.'); } List> filteredList = new List>(); for (Map jsonObj : jsonList) { if (jsonObj.containsKey('SalesforceObject') && jsonObj.get('SalesforceObject') == 'account') { filteredList.add(jsonObj); } } if (!filteredList.isEmpty()) { SObject sobjectRecord = Schema.getGlobalDescribe().get('Account').newSObject(); Set excludedFields = new Set{'Id', 'HIC_ShopifySync__Is_identified__c', 'HIC_ShopifySync__Shopify_Id__c'}; for (Account acc : accListToUpsert) { for (String fieldName : acc.getPopulatedFieldsAsMap().keySet()) { if (!excludedFields.contains(fieldName)) { Object value = acc.get(fieldName); if (value != null) { String key = String.valueOf(value).trim().toLowerCase(); companyVsAccountMap.put(key, acc); } } } } system.debug('filteredList--->'+filteredList); String filteredJsonString = JSON.serialize(filteredList); system.debug('filteredJsonString--->'+filteredJsonString); String soqlQuery = generateSOQL(filteredJsonString, sobjectRecord, jsonRequestBody); System.debug('Generated SOQL query: ' + soqlQuery); if (String.isNotBlank(soqlQuery)) { for (Account acc : Database.query(soqlQuery)) { for (String fieldName : acc.getPopulatedFieldsAsMap().keySet()) { if (!excludedFields.contains(fieldName)) { Object value = acc.get(fieldName); if (value != null) { String key = String.valueOf(value).trim().toLowerCase(); companyVsExistingRecMap.put(key, acc); } } } } } else { System.debug('SOQL query is null or empty. Skipping execution.'); } System.debug('companyVsExistingRecMap --->>> ' + companyVsExistingRecMap); System.debug('companyVsAccountMap --->>> ' + companyVsAccountMap); Set alreadyHandledIds = new Set(); if (companyVsExistingRecMap != null && !companyVsExistingRecMap.isEmpty()) { for (Account existingAcc : companyVsExistingRecMap.values()) { if (existingAcc == null || alreadyHandledIds.contains(existingAcc.Id)) continue; for (Account incomingAcc : companyVsAccountMap.values()) { if (incomingAcc == null) continue; Boolean matched = false; for (Map rule : filteredList) { String sfField = (String) rule.get('SalesforceFieldApiName'); String operator = ((String) rule.get('MatchingOperator')).toLowerCase(); Boolean caseSensitive = rule.containsKey('caseSensitive') && (Boolean) rule.get('caseSensitive'); String existingValue = existingAcc.get(sfField) != null ? String.valueOf(existingAcc.get(sfField)) : ''; String incomingValue = incomingAcc.get(sfField) != null ? String.valueOf(incomingAcc.get(sfField)) : ''; if (operator == 'equals' && existingValue.equals(incomingValue) && caseSensitive) { matched = true; break; } else if (operator == 'contains') { matched = true; break; } else if (operator == 'equals' && !caseSensitive && existingValue.equalsIgnoreCase(incomingValue)) { matched = true; break; } } if (matched) { Account accToUpdate = new Account(Id = existingAcc.Id); accToUpdate.HIC_ShopifySync__Shopify_Id__c = incomingAcc.HIC_ShopifySync__Shopify_Id__c; accToUpdate.HIC_ShopifySync__Is_identified__c = true; if (incomingAcc.HIC_ShopifySync__Shopify_Id__c != existingAcc.HIC_ShopifySync__Shopify_Id__c) { updateAccountList.add(accToUpdate); identifiedAccountList.add(accToUpdate); alreadyHandledIds.add(existingAcc.Id); } else if (existingAcc.HIC_ShopifySync__Is_identified__c) { identifiedAccountList.add(accToUpdate); } break; // matched once, no need to check other incoming } } } } if (!updateAccountList.isEmpty()) { Database.update(updateAccountList, false); System.debug('Updated Account records: ' + updateAccountList); } else { System.debug('No Account records to update.'); } } } if (CheckAccessibility.isUpsertable(String.valueOf(externalIdField), 'Account')) { if ((companyVsExistingRecMap.isEmpty() && accEmailVsAccountMap.isEmpty() && identifiedAccountList.isEmpty()) || configListToCheckObjects[0].HIC_ShopifySync__Update_Identified_Account_Records__c) { System.debug('Running upsert with accListToUpsert'); updateResult = Database.upsert(accListToUpsert, externalIdField, false); } else if (!companyVsAccountMap.isEmpty() && configListToCheckObjects[0].HIC_ShopifySync__Update_Identified_Account_Records__c) { System.debug('Running upsert with companyVsAccountMap values'); Set uniqueAccounts = new Set(companyVsAccountMap.values()); updateResult = Database.upsert(new List(uniqueAccounts), externalIdField, false); } else if (!accEmailVsAccountMap.isEmpty()) { System.debug('Running upsert with accEmailVsAccountMap values'); Set uniqueAccounts = new Set(accEmailVsAccountMap.values()); updateResult = Database.upsert(new List(uniqueAccounts), externalIdField, false); } else if (!companyVsAccountMap.isEmpty()) { System.debug('Running upsert with companyVsAccountMap values'); Set uniqueAccounts = new Set(companyVsAccountMap.values()); updateResult = Database.upsert(new List(uniqueAccounts), externalIdField, false); } if (!updateResult.isEmpty()) { for (Integer i = 0; i < updateResult.size(); i++) { Database.UpsertResult sr = updateResult[i]; if (sr.isSuccess()) { if (sr.isCreated()) { //fpAcc++; System.debug('INSERTED Account Id=' + sr.getId()); } else { System.debug('UPDATED Account Id=' + sr.getId()); } } else { System.debug('FAILED Account Errors=' + sr.getErrors()); } } } } else { System.debug('Field not upsertable: ' + externalIdField); } System.debug('updateResult****'+updateResult); } //Contact else if (objectName == 'Contact') { System.debug('--- Entered Contact Block ---'); List conListToUpsert = (List) objectList; System.debug('conListToUpsert size: ' + conListToUpsert.size()); Map conEmailVsContactMap = new Map(); Map conFieldVsContactMap = new Map(); List updateContactList = new List(); List identifiedContactList = new List(); Set deleteContactIdSet = new Set(); Map emailVsIdMap = new Map(); List> filteredList = new List>(); Boolean useDynamic = configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c != null; Boolean useEmailMatching = configListToCheckObjects[0].HIC_ShopifySync__Upsert_Customer_basis_on_Email__c; if (useEmailMatching) { // Collect all emails from incoming contacts for (Contact con : conListToUpsert) { if (String.isNotBlank(con.Email)) { conFieldVsContactMap.put(con.Email.trim().toLowerCase(), con); } } Set conEmailSet = conFieldVsContactMap.keySet(); // Query for existing contacts in Salesforce based on emails String query; if (isPerson) { query = 'SELECT Id, Email, AccountId, HIC_ShopifySync__Shopify_Id__c, HIC_ShopifySync__Is_identified__c FROM Contact WHERE Email IN :conEmailSet AND IsPersonAccount = false' + (configListToCheckObjects[0].HIC_ShopifySync__ContactFilter__c != null ? ' ' + configListToCheckObjects[0].HIC_ShopifySync__ContactFilter__c : ''); } else { query = 'SELECT Id, Email, AccountId, HIC_ShopifySync__Shopify_Id__c, HIC_ShopifySync__Is_identified__c FROM Contact WHERE Email IN :conEmailSet' + (configListToCheckObjects[0].HIC_ShopifySync__ContactFilter__c != null ? ' ' + configListToCheckObjects[0].HIC_ShopifySync__ContactFilter__c : ''); } // Store existing contacts in a map based on email for (Contact con : Database.query(query)) { if (String.isNotBlank(con.Email)) { emailVsIdMap.put(con.Email.trim().toLowerCase(), con); } } } // Handle logic for dynamic matching else if (useDynamic) { String jsonString = configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c; Object parsedJson = JSON.deserializeUntyped(jsonString); List> jsonList = new List>(); if (parsedJson instanceof List) { for (Object entry : (List) parsedJson) { if (entry instanceof Map) { jsonList.add((Map) entry); } } } for (Map jsonObj : jsonList) { if (jsonObj.containsKey('SalesforceObject') && jsonObj.get('SalesforceObject') == 'Contact') { filteredList.add(jsonObj); } } if (!filteredList.isEmpty()) { SObject sobjectRecord = Schema.getGlobalDescribe().get('Contact').newSObject(); Set excludedFields = new Set{'Id','AccountId','HIC_ShopifySync__Is_identified__c','HIC_ShopifySync__Shopify_Id__c'}; Map fieldMaps = Schema.SObjectType.Contact.fields.getMap(); // Populate conFieldVsContactMap using the dynamic logic for (Contact con : conListToUpsert) { for (String fieldName : con.getPopulatedFieldsAsMap().keySet()) { try { // First, check if the field actually exists in the schema if (!fieldMaps.containsKey(fieldName)) { System.debug('Skipping field due to missing schema definition: ' + fieldName); continue; } // Get field describe to determine if it's a reference (lookup) Schema.DescribeFieldResult describe = fieldMaps.get(fieldName).getDescribe(); Schema.DisplayType fieldType = describe.getType(); // Skip if it's a reference (lookup) field if (fieldType == Schema.DisplayType.REFERENCE) { System.debug('Skipped lookup field: ' + fieldName); continue; } Object fieldValue = con.get(fieldName); System.debug('Checking field: ' + fieldName + ' | Value: ' + fieldValue); if (!excludedFields.contains(fieldName) && fieldValue != null) { System.debug('Valid non-lookup field found for mapping: ' + fieldName + ' = ' + fieldValue); conFieldVsContactMap.put(String.valueOf(fieldValue), con); } } catch (Exception e) { System.debug('Skipping field due to error: ' + fieldName + ' | Error: ' + e.getMessage()); } } } // Generate the dynamic SOQL query for filtering String filteredJsonString = JSON.serialize(filteredList); String soqlQuery = generateSOQL(filteredJsonString, sobjectRecord, jsonRequestBody); // Query and map dynamic contacts to the emailVsIdMap for (Contact con : Database.query(soqlQuery)) { for (String fieldName : con.getPopulatedFieldsAsMap().keySet()) { if (!excludedFields.contains(fieldName) && con.get(fieldName) != null) { String key = String.valueOf(con.get(fieldName)).trim().toLowerCase(); emailVsIdMap.put(key, con); } } } } } Set alreadyHandledIds = new Set(); if (emailVsIdMap != null && !emailVsIdMap.isEmpty()) { for (Contact existingCon : emailVsIdMap.values()) { if (existingCon == null || alreadyHandledIds.contains(existingCon.Id)) continue; for (Contact incomingCon : conFieldVsContactMap.values()) { if (incomingCon == null) continue; Boolean matched = false; if (useEmailMatching) { String existingEmail = existingCon.Email != null ? existingCon.Email.trim().toLowerCase() : ''; String incomingEmail = incomingCon.Email != null ? incomingCon.Email.trim().toLowerCase() : ''; matched = existingEmail == incomingEmail; } else { for (Map rule : filteredList) { String sfField = (String) rule.get('SalesforceFieldApiName'); String operator = ((String) rule.get('MatchingOperator')).toLowerCase(); Boolean caseSensitive = rule.containsKey('caseSensitive') && (Boolean) rule.get('caseSensitive'); String existingValue = (getFieldValue(existingCon, sfField) != null) ? String.valueOf(getFieldValue(existingCon, sfField)) : ''; String incomingValue = (getFieldValue(incomingCon, sfField) != null) ? String.valueOf(getFieldValue(incomingCon, sfField)) : ''; if (operator == 'equals' && existingValue.equals(incomingValue) && caseSensitive) { matched = true; break; } else if (operator == 'contains') { matched = true; break; } else if (operator == 'equals' && !caseSensitive && existingValue.equalsIgnoreCase(incomingValue)) { matched = true; break; } } } if (matched) { System.debug('Matched Contact: existingCon.Id = ' + existingCon.Id + ', incomingCon.Id = ' + incomingCon.Id); Contact conToUpdate = new Contact(Id = existingCon.Id); conToUpdate.HIC_ShopifySync__Shopify_Id__c = incomingCon.HIC_ShopifySync__Shopify_Id__c; conToUpdate.HIC_ShopifySync__Is_identified__c = true; conToUpdate.AccountId = existingCon.AccountId; System.debug('Prepared conToUpdate: ' + conToUpdate); if (incomingCon.HIC_ShopifySync__Shopify_Id__c != existingCon.HIC_ShopifySync__Shopify_Id__c) { updateContactList.add(conToUpdate); identifiedContactList.add(conToUpdate); if (existingCon.HIC_ShopifySync__Shopify_Id__c != null) { deleteContactIdSet.add(existingCon.HIC_ShopifySync__Shopify_Id__c); System.debug('Marked for deletion from deleteContactIdSet: ' + existingCon.HIC_ShopifySync__Shopify_Id__c); } alreadyHandledIds.add(existingCon.Id); System.debug('Contact added to updateContactList and identifiedContactList'); System.debug('Marked for deletion from deleteContactIdSet: ' + existingCon.HIC_ShopifySync__Shopify_Id__c); System.debug('Added to alreadyHandledIds: ' + existingCon.Id); } else if (existingCon.HIC_ShopifySync__Is_identified__c) { identifiedContactList.add(conToUpdate); System.debug('Contact already identified; added to identifiedContactList: ' + existingCon.Id); } break; // once matched, move to next existingCon } } } } // Perform updates and deletions if necessary if (!updateContactList.isEmpty()) { Database.update(updateContactList, false); } if (!deleteContactIdSet.isEmpty()) { List conListToDelete = [ SELECT Id FROM Contact WHERE HIC_ShopifySync__Shopify_Id__c IN :deleteContactIdSet AND CreatedDate = TODAY ]; Database.delete(conListToDelete, false); } if (CheckAccessibility.isUpsertable(String.valueOf(externalIdField), 'Contact')) { if ((emailVsIdMap.isEmpty() && identifiedContactList.isEmpty()) || configListToCheckObjects[0].HIC_ShopifySync__Update_Identified_Contact_Records__c) { updateResult = Database.upsert(conListToUpsert, externalIdField, false); } else if (!conFieldVsContactMap.isEmpty() && configListToCheckObjects[0].HIC_ShopifySync__Update_Identified_Contact_Records__c) { Set uniqueContacts = new Set(conFieldVsContactMap.values()); updateResult = Database.upsert(new List(uniqueContacts), externalIdField, false); } } else { System.debug('Field not upsertable: ' + externalIdField); } System.debug('updateResult****' + updateResult); } //Lead else if (objectName == 'Lead') { List leadListToUpsert = (List) objectList; Map conEmailVsLeadMap = new Map(); List updateLeadList = new List(); List identifiedLeadList = new List(); Set deleteLeadIdSet = new Set(); Map fieldVsExistingRecMap = new Map(); Map emailVsIdMap = new Map(); Boolean updateIdentified = configListToCheckObjects[0].HIC_ShopifySync__Update_Identified_Lead_Records__c; if (configListToCheckObjects[0].HIC_ShopifySync__Upsert_Lead_basis_on_Email__c) { for (Lead con : leadListToUpsert) { if (con.Email != null) { conEmailVsLeadMap.put(con.Email, con); } } Set conEmailSet = conEmailVsLeadMap.keySet(); List conList = [SELECT Id, Email, HIC_ShopifySync__Shopify_Id__c, HIC_ShopifySync__Is_identified__c FROM Lead WHERE Email IN :conEmailSet]; for (Lead existingLead : conList) { emailVsIdMap.put(existingLead.Email, existingLead); } for (String email : emailVsIdMap.keySet()) { if (conEmailVsLeadMap.containsKey(email)) { Lead incoming = conEmailVsLeadMap.get(email); Lead existing = emailVsIdMap.get(email); if (String.isBlank(existing.HIC_ShopifySync__Shopify_Id__c) && existing.HIC_ShopifySync__Shopify_Id__c != incoming.HIC_ShopifySync__Shopify_Id__c) { Lead toUpdate = new Lead(Id = existing.Id); toUpdate.HIC_ShopifySync__Shopify_Id__c = incoming.HIC_ShopifySync__Shopify_Id__c; toUpdate.HIC_ShopifySync__Is_identified__c = true; updateLeadList.add(toUpdate); deleteLeadIdSet.add(incoming.HIC_ShopifySync__Shopify_Id__c); identifiedLeadList.add(toUpdate); conEmailVsLeadMap.remove(email); } else if (String.isNotBlank(existing.HIC_ShopifySync__Shopify_Id__c) && existing.HIC_ShopifySync__Shopify_Id__c != incoming.HIC_ShopifySync__Shopify_Id__c) { System.debug('Skipping email-match update: existing lead already has Shopify ID ' + existing.HIC_ShopifySync__Shopify_Id__c + ' (incoming: ' + incoming.HIC_ShopifySync__Shopify_Id__c + ')'); } else if (existing.HIC_ShopifySync__Is_identified__c) { identifiedLeadList.add(existing); conEmailVsLeadMap.remove(email); } else { conEmailVsLeadMap.remove(email); } } } if (!deleteLeadIdSet.isEmpty()) { List conListToDelete = [SELECT Id FROM Lead WHERE HIC_ShopifySync__Shopify_Id__c IN :deleteLeadIdSet AND CreatedDate = TODAY]; Database.delete(conListToDelete, false); } if (!updateLeadList.isEmpty()) { Database.update(updateLeadList, false); } } else if (configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c != null) { String jsonString = configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c; Object deserializedObject = JSON.deserializeUntyped(jsonString); List> jsonList = new List>(); if (deserializedObject instanceof List) { for (Object obj : (List) deserializedObject) { if (obj instanceof Map) { Map entry = (Map) obj; if (entry.containsKey('SalesforceObject') && entry.get('SalesforceObject') == 'Lead') { jsonList.add(entry); } } } } if (!jsonList.isEmpty()) { SObject sobjectRecord = Schema.getGlobalDescribe().get('Lead').newSObject(); String filteredJsonString = JSON.serialize(jsonList); String soqlQuery = generateSOQL(filteredJsonString, sobjectRecord, jsonRequestBody); Map alreadyHandledIds = new Map(); if (String.isNotBlank(soqlQuery)) { List existingLeads = Database.query(soqlQuery); for (Lead incoming : leadListToUpsert) { for (Lead existing : existingLeads) { if (existing == null || alreadyHandledIds.containsKey(existing.Id)) continue; Boolean matched = false; for (Map rule : jsonList) { String sfField = (String) rule.get('SalesforceFieldApiName'); String operator = ((String) rule.get('MatchingOperator')).toLowerCase(); Boolean caseSensitive = rule.containsKey('caseSensitive') && (Boolean) rule.get('caseSensitive'); String existingValue = existing.get(sfField) != null ? String.valueOf(existing.get(sfField)) : ''; String incomingValue = incoming.get(sfField) != null ? String.valueOf(incoming.get(sfField)) : ''; if (operator == 'equals' && existingValue.equals(incomingValue) && caseSensitive) { matched = true; break; } else if (operator == 'contains' && existingValue.contains(incomingValue)) { matched = true; break; } else if (operator == 'equals' && !caseSensitive && existingValue.equalsIgnoreCase(incomingValue)) { matched = true; break; } } if (matched) { String incomingShopifyId = incoming.HIC_ShopifySync__Shopify_Id__c; String existingShopifyId = existing.HIC_ShopifySync__Shopify_Id__c; if (incomingShopifyId != existingShopifyId) { Lead toUpdate = new Lead(Id = existing.Id); toUpdate.HIC_ShopifySync__Shopify_Id__c = incomingShopifyId; updateLeadList.add(toUpdate); alreadyHandledIds.put(existing.Id, existing); } identifiedLeadList.add(existing); break; } } } } if (!updateLeadList.isEmpty()) { Database.update(updateLeadList, false); } } } // FINAL UPSERT SECTION if (CheckAccessibility.isUpsertable(String.valueOf(externalIdField), 'Lead')) { if ((emailVsIdMap.isEmpty() && identifiedLeadList.isEmpty()) || updateIdentified) { updateResult = Database.upsert(leadListToUpsert, externalIdField, false); } else if (!conEmailVsLeadMap.isEmpty() && updateIdentified) { Set uniqueLeads = new Set(conEmailVsLeadMap.values()); updateResult = Database.upsert(new List(uniqueLeads), externalIdField, false); } if (!updateResult.isEmpty()) { for (Integer i = 0; i < updateResult.size(); i++) { Database.UpsertResult sr = updateResult[i]; if (sr.isSuccess()) { if (sr.isCreated()) { //fpAcc++; System.debug('INSERTED Account Id=' + sr.getId()); } else { System.debug('UPDATED Account Id=' + sr.getId()); } } else { System.debug('FAILED Account Errors=' + sr.getErrors()); } } } } } //Opportunity else if (objectName == 'Opportunity') { List oppListToUpsert = (List) objectList; List updateOpportunityList = new List(); if (configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c != null) { String jsonString = configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c; Object deserializedObject = JSON.deserializeUntyped(jsonString); List> jsonList = new List>(); if (deserializedObject instanceof List) { for (Object obj : (List) deserializedObject) { if (obj instanceof Map) { jsonList.add((Map) obj); } } } else { System.debug('--- [OPP] Invalid JSON structure detected.'); } List> filteredList = new List>(); for (Map jsonObj : jsonList) { if (jsonObj.containsKey('SalesforceObject') && jsonObj.get('SalesforceObject') == 'Opportunity') { filteredList.add(jsonObj); } } System.debug('--- [OPP] Filtered JSON Configs: ' + filteredList); if (!filteredList.isEmpty()) { SObject sobjectRecord = Schema.getGlobalDescribe().get('Opportunity').newSObject(); Set excludedFields = new Set{'Id', 'HIC_ShopifySync__Shopify_Id__c'}; String filteredJsonString = JSON.serialize(filteredList); String soqlQuery = generateSOQL(filteredJsonString, sobjectRecord, jsonRequestBody); System.debug('--- [OPP] Generated SOQL: ' + soqlQuery); List existingOpportunities = new List(); if (soqlQuery != null) { existingOpportunities = Database.query(soqlQuery); } Set alreadyHandledIds = new Set(); for (Opportunity incoming : oppListToUpsert) { for (Opportunity existing : existingOpportunities) { if (existing == null || alreadyHandledIds.contains(existing.Id)) continue; Boolean matched = false; for (Map rule : filteredList) { String sfField = (String) rule.get('SalesforceFieldApiName'); String operator = ((String) rule.get('MatchingOperator')).toLowerCase(); Boolean caseSensitive = rule.containsKey('caseSensitive') && (Boolean) rule.get('caseSensitive'); String existingValue = existing.get(sfField) != null ? String.valueOf(existing.get(sfField)) : ''; String incomingValue = incoming.get(sfField) != null ? String.valueOf(incoming.get(sfField)) : ''; if (operator == 'equals' && existingValue.equals(incomingValue) && caseSensitive) { matched = true; break; } else if (operator == 'contains') { matched = true; break; } else if (operator == 'equals' && !caseSensitive && existingValue.equalsIgnoreCase(incomingValue)) { matched = true; break; } } if (matched) { String incomingShopifyId = incoming.HIC_ShopifySync__Shopify_Id__c; String existingShopifyId = existing.HIC_ShopifySync__Shopify_Id__c; if (incomingShopifyId != existingShopifyId) { Opportunity oppToUpdate = new Opportunity(Id = existing.Id); oppToUpdate.HIC_ShopifySync__Shopify_Id__c = incomingShopifyId; updateOpportunityList.add(oppToUpdate); alreadyHandledIds.add(existing.Id); } break; } } } if (!updateOpportunityList.isEmpty()) { Database.update(updateOpportunityList, false); } // Remove already handled records if (!alreadyHandledIds.isEmpty()) { List filteredOppList = new List(); for (Opportunity opp : oppListToUpsert) { if (!alreadyHandledIds.contains(opp.Id)) { filteredOppList.add(opp); } } oppListToUpsert = filteredOppList; } } } if (CheckAccessibility.isUpsertable(String.valueOf(externalIdField), 'Opportunity')) { if (!oppListToUpsert.isEmpty()) { updateResult = Database.upsert(oppListToUpsert, externalIdField, false); System.debug('oppListToUpsert-->>'+JSON.serializePretty(oppListToUpsert)); if (!updateResult.isEmpty()) { for (Integer i = 0; i < updateResult.size(); i++) { Database.UpsertResult sr = updateResult[i]; if (sr.isSuccess()) { if (sr.isCreated() && fpOrd == 0) { Opportunity ord = oppListToUpsert[i]; String paymentStatus = null; if (ord.getSObjectType() .getDescribe() .fields .getMap() .containsKey('HIC_ShopifySync__Payment_Status__c')) { paymentStatus = (String) ord.get('HIC_ShopifySync__Payment_Status__c'); } if (!String.isBlank(paymentStatus)) { fpOrd++; System.debug('INSERTED Opportunity Id=' + sr.getId()); } else { System.debug( 'Skipped fpOrd increment (Payment Status missing or null)' ); } } else { System.debug('UPDATED Opportunity Id=' + sr.getId()); } } else { System.debug('FAILED Opportunity Errors=' + sr.getErrors()); } } } } } } //OpportunityLineItem else if (objectName == 'OpportunityLineItem') { List prodListToUpsert = new List(); prodListToUpsert = (List) objectList; Opportunity opp; if (!prodListToUpsert.isEmpty()) { String shopifyOppId = prodListToUpsert[0].Opportunity.HIC_ShopifySync__Shopify_Id__c; List oppList = [ SELECT Id, HIC_ShopifySync__Payment_Status__c FROM Opportunity WHERE HIC_ShopifySync__Shopify_Id__c = :shopifyOppId WITH USER_MODE LIMIT 1 ]; if (!oppList.isEmpty()) { opp = oppList[0]; } } if (CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'OpportunityLineItem')) { updateResult = Database.upsert(prodListToUpsert,externalIdField,false); System.debug('prodListToUpsert-->>' +JSON.serializePretty(prodListToUpsert)); Integer oppLineItemCreated = 0; for (Database.UpsertResult sr : updateResult) { if (sr.isSuccess()) { if (sr.isCreated()) { if (opp != null && String.isNotBlank( opp.HIC_ShopifySync__Payment_Status__c )) { oppLineItemCreated++; } System.debug('INSERTED opplineitem Id=' + sr.getId()); } else { System.debug('UPDATED opplineitem Id=' + sr.getId()); } } else { System.debug('FAILED opplineitem Errors=' + sr.getErrors()); } } if (oppLineItemCreated > 0) { System.debug('oppLineItemCreated-->>' + oppLineItemCreated); fpOrdItem = oppLineItemCreated; } } if (!IsWebhook) { nestedRecordsJSONBody(jSONRequestBody); } } //Order else if (objectName == 'Order') { List orderListToUpsert = (List) objectList; List updateOrderList = new List(); Map fieldVsOrderMap = new Map(); Map fieldVsExistingRecMap = new Map(); if (configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c != null) { String jsonString = configListToCheckObjects[0].HIC_ShopifySync__Dynamic_prevent_duplicate__c; Object deserializedObject = JSON.deserializeUntyped(jsonString); List> jsonList = new List>(); if (deserializedObject instanceof List) { for (Object obj : (List) deserializedObject) { if (obj instanceof Map) { jsonList.add((Map) obj); } } } else { System.debug('--- [ORDER] Invalid JSON structure detected.'); } List> filteredList = new List>(); for (Map jsonObj : jsonList) { if (jsonObj.containsKey('SalesforceObject') && jsonObj.get('SalesforceObject') == 'Order') { filteredList.add(jsonObj); } } if (!filteredList.isEmpty()) { SObject sobjectRecord = Schema.getGlobalDescribe().get('Order').newSObject(); Set excludedFields = new Set{'Id', 'HIC_ShopifySync__Shopify_Id__c','Account'}; Map fieldMaps = Schema.SObjectType.Order.fields.getMap(); for (Order ord : orderListToUpsert) { for (String fieldName : ord.getPopulatedFieldsAsMap().keySet()) { try { // First, check if the field actually exists in the schema if (!fieldMaps.containsKey(fieldName)) { continue; } // Get field describe to determine if it's a reference (lookup) Schema.DescribeFieldResult describe = fieldMaps.get(fieldName).getDescribe(); Schema.DisplayType fieldType = describe.getType(); // Skip if it's a reference (lookup) field if (fieldType == Schema.DisplayType.REFERENCE) { continue; } Object fieldValue = ord.get(fieldName); if (!excludedFields.contains(fieldName) && fieldValue != null) { fieldVsOrderMap.put(String.valueOf(fieldValue), ord); } } catch (Exception e) { System.debug('Skipping field due to error: ' + fieldName + ' | Error: ' + e.getMessage()); } } } String filteredJsonString = JSON.serialize(filteredList); String soqlQuery = generateSOQL(filteredJsonString, sobjectRecord, jsonRequestBody); System.debug('--- [ORDER] Generated SOQL: ' + soqlQuery); if(soqlQuery!=null){ for (Order ord : Database.query(soqlQuery)) { for (String fieldName : ord.getPopulatedFieldsAsMap().keySet()) { if (!excludedFields.contains(fieldName) && ord.get(fieldName) != null) { fieldVsExistingRecMap.put(String.valueOf(ord.get(fieldName)), ord); } } } } Set alreadyHandledIds = new Set(); if (!fieldVsExistingRecMap.isEmpty() && !fieldVsOrderMap.isEmpty()) { for (Order existingOrd : fieldVsExistingRecMap.values()) { if (existingOrd == null || alreadyHandledIds.contains(existingOrd.Id)) continue; for (Order incomingOrd : fieldVsOrderMap.values()) { if (incomingOrd == null) continue; Boolean matched = false; for (Map rule : filteredList) { String sfField = (String) rule.get('SalesforceFieldApiName'); String operator = ((String) rule.get('MatchingOperator')).toLowerCase(); Boolean caseSensitive = rule.containsKey('caseSensitive') && (Boolean) rule.get('caseSensitive'); String existingValue = existingOrd.get(sfField) != null ? String.valueOf(existingOrd.get(sfField)) : ''; String incomingValue = incomingOrd.get(sfField) != null ? String.valueOf(incomingOrd.get(sfField)) : ''; if (operator == 'equals' && existingValue.equals(incomingValue) && caseSensitive) { matched = true; break; } else if (operator == 'contains') { matched = true; break; } else if (operator == 'equals' && !caseSensitive && existingValue.equalsIgnoreCase(incomingValue)) { matched = true; break; } } if (matched) { String incomingShopifyId = incomingOrd.HIC_ShopifySync__Shopify_Id__c; String existingShopifyId = existingOrd.HIC_ShopifySync__Shopify_Id__c; if (incomingShopifyId != existingShopifyId) { Order ordToUpdate = new Order(Id = existingOrd.Id); ordToUpdate.HIC_ShopifySync__Shopify_Id__c = incomingShopifyId; updateOrderList.add(ordToUpdate); alreadyHandledIds.add(existingOrd.Id); System.debug('--- [ORDER] Shopify ID mismatch: updating Order - ' + ordToUpdate); } break; // no need to check other incoming once matched } } } } if (!updateOrderList.isEmpty()) { Database.update(updateOrderList, false); } } } if (CheckAccessibility.isUpsertable(String.valueOf(externalIdField), 'Order')) { if (fieldVsExistingRecMap.isEmpty()) { updateResult = Database.upsert(orderListToUpsert, externalIdField, false); System.debug('orderListToUpsert-->>'+JSON.serializePretty(orderListToUpsert)); if (!updateResult.isEmpty()) { for (Integer i = 0; i < updateResult.size(); i++) { Database.UpsertResult sr = updateResult[i]; if (sr.isSuccess()) { if (sr.isCreated() && fpOrd == 0) { Order ord = orderListToUpsert[i]; String paymentStatus = null; if (ord.getSObjectType() .getDescribe() .fields .getMap() .containsKey('HIC_ShopifySync__Payment_Status__c')) { paymentStatus = (String) ord.get('HIC_ShopifySync__Payment_Status__c'); } if (!String.isBlank(paymentStatus)) { fpOrd++; System.debug('INSERTED Order Id=' + sr.getId()); } else { System.debug( 'Skipped fpOrd increment (Payment Status missing or null)' ); } } else { System.debug('UPDATED Order Id=' + sr.getId()); } } else { System.debug('FAILED Order Errors=' + sr.getErrors()); } } } } else { Map dedupedByExternalId = new Map(); for (Order ord : fieldVsOrderMap.values()) { String externalId = ord.HIC_ShopifySync__Shopify_Id__c; if (String.isNotBlank(externalId)) { dedupedByExternalId.put(externalId, ord); } } List uniqueOrders = new List(dedupedByExternalId.values()); if (!uniqueOrders.isEmpty()) { updateResult = Database.upsert(uniqueOrders, externalIdField, false); if (!updateResult.isEmpty()) { for (Integer i = 0; i < updateResult.size(); i++) { Database.UpsertResult sr = updateResult[i]; if (sr.isSuccess()) { if (sr.isCreated()) { fpOrd++; System.debug('INSERTED Account Id=' + sr.getId()); } else { System.debug('UPDATED Account Id=' + sr.getId()); } } else { System.debug('FAILED Account Errors=' + sr.getErrors()); } } } } } } } //OrderItem else if(objectName == 'OrderItem'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; Order ord; if (!prodListToUpsert.isEmpty()) { String shopifyOppId = prodListToUpsert[0].Order.HIC_ShopifySync__Shopify_Id__c; List OrdList = [ SELECT Id, HIC_ShopifySync__Payment_Status__c FROM Order WHERE HIC_ShopifySync__Shopify_Id__c = :shopifyOppId WITH USER_MODE LIMIT 1 ]; if (!OrdList.isEmpty()) { ord = OrdList[0]; } } if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'OrderItem')){ updateResult = Database.upsert(prodListToUpsert, externalIdField, false); System.debug('OrderprodListToUpsert-->>'+JSON.serializePretty(prodListToUpsert)); Integer ordLineItemCreated = 0; for (Database.UpsertResult sr : updateResult) { if (sr.isSuccess()) { if (sr.isCreated()) { if (ord != null && String.isNotBlank( ord.HIC_ShopifySync__Payment_Status__c )) { ordLineItemCreated++; } System.debug('INSERTED ordlineitem Id=' + sr.getId()); } else { System.debug('UPDATED ordlineitem Id=' + sr.getId()); } } else { System.debug('FAILED ordlineitem Errors=' + sr.getErrors()); } } if (ordLineItemCreated > 0) { System.debug('ordLineItemCreated-->>' + ordLineItemCreated); fpOrdItem = ordLineItemCreated; } } if(!IsWebhook){ //get Record's JSON based on their External ID. nestedRecordsJSONBody(jSONRequestBody); } } //Collects else if(objectName == 'HIC_ShopifySync__Collect__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Collect__c')) updateResult = Database.upsert(prodListToUpsert, externalIdField, false); } //Collections else if(objectName == 'HIC_ShopifySync__Collection__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Collection__c')) updateResult = Database.upsert(prodListToUpsert, externalIdField, false); System.debug('prodListToUpsert-----'+prodListToUpsert); System.debug('updateResult---'+updateResult); } //Inventory Item else if(objectName == 'HIC_ShopifySync__Inventory__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Inventory__c')){ updateResult = Database.upsert(prodListToUpsert, externalIdField, false); } // if(!IsWebhook){ // nestedRecordsJSONBody(jSONRequestBody); // } } //Inventory Level else if(objectName == 'HIC_ShopifySync__Inventory_Level__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Inventory_Level__c')) updateResult = Database.upsert(prodListToUpsert, externalIdField, false); } //Location else if(objectName == 'HIC_ShopifySync__Location__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Location__c')) updateResult = Database.upsert(prodListToUpsert, externalIdField, false); } //Depreceated else if(objectName == 'HIC_ShopifySync__Missing_Order__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Missing_Order__c')) updateResult = Database.upsert(prodListToUpsert, externalIdField, false); } //Order Fulfillment else if(objectName == 'HIC_ShopifySync__Order_Fulfillment__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Order_Fulfillment__c')) updateResult = Database.upsert(prodListToUpsert, externalIdField, false); } //Order Fulfillment Item else if(objectName == 'HIC_ShopifySync__Order_Fulfillment_Item__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Order_Fulfillment_Item__c')){ updateResult = Database.upsert(prodListToUpsert, externalIdField, false); } nestedRecordsJSONBody(jSONRequestBody); } //Product's Variant else if(objectName == 'HIC_ShopifySync__Variant__c'){ List prodListToUpsert = new List (); prodListToUpsert = (List ) objectList; if(CheckAccessibility.isUpsertable(String.valueOf(externalIdField),'HIC_ShopifySync__Variant__c')){ updateResult = Database.upsert(prodListToUpsert, externalIdField, false); //Integer variantsCreated = 0; for (Database.UpsertResult sr : updateResult) { if (sr.isSuccess()) { if (sr.isCreated()) { //variantsCreated++; System.debug('INSERTED Variant Id=' + sr.getId()); } else { System.debug('UPDATED Variant Id=' + sr.getId()); } } else { System.debug('FAILED Variant Errors=' + sr.getErrors()); } } //if (variantsCreated > 0) { // fpProd += variantsCreated; //} } nestedRecordsJSONBody(jSONRequestBody); } else { updateResult = Database.upsert(objectList, externalIdField, false); //nestedRecordsJSONBody(jSONRequestBody); } //Get configurations list listofConfiguration = new list(); String query = 'Select '+CheckAccessibility.isAccessible('id,name, HIC_ShopifySync__Account_Contact__c, HIC_ShopifySync__Person_Account__c, HIC_ShopifySync__Default_Account__c, HIC_ShopifySync__Shopify_URL__c, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Opportunity__c, HIC_ShopifySync__Order__c, HIC_ShopifySync__Opportunity_Line_Item__c, HIC_ShopifySync__Order_Line_Item__c, HIC_ShopifySync__Order_Fulfillment__c','HIC_ShopifySync__HIC_Configuration__c')+' from HIC_ShopifySync__HIC_Configuration__c where '+CheckAccessibility.isAccessible('HIC_ShopifySync__Store__c', 'HIC_ShopifySync__HIC_Configuration__c')+' = \''+store+'\' LIMIT 49999'; listofConfiguration = database.query(query); list listoferrors = new list(); //List of errors message list listofsuccesslog = new list(); //List of Shopify logs String sObjectName = 'HIC_ShopifySync__Error_Message__c'.trim(); DescribeSObjectResult schemaTypes = Schema.getGlobalDescribe().get(sObjectName).getDescribe(); Map fieldsMaps = schemaTypes.fields.getMap(); for(Integer index = 0 ; index < updateResult.size() ; index ++){ //If record successfully upsert if( !updateResult[index].isSuccess() ){ if(schemaTypes.isAccessible() && (schemaTypes.isCreateable()||schemaTypes.isUpdateable()) ){ // Error Message Object HIC_ShopifySync__Error_Message__c errorobj = new HIC_ShopifySync__Error_Message__c(); errorobj.HIC_ShopifySync__Store__c = store; if(CheckAccessibility.isUpdateable('name',fieldsMaps) && schemaTypes.isCreateable()){ errorobj.name = objectName; } //Object Contact then modified Shopify's External ID if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Shopify_id__c,HIC_ShopifySync__Error_id__c',fieldsMaps) && objectName == 'Contact'){ if(string.valueof(objectList[index].get(externalIdField)).contains('Busines')){ errorobj.HIC_ShopifySync__Shopify_id__c = string.valueof(objectList[index].get(externalIdField)+isbatch).remove('Business'); errorobj.HIC_ShopifySync__Error_id__c = string.valueof(objectName+objectList[index].get(externalIdField)+isbatch).remove('Business'); }else if(string.valueof(objectList[index].get(externalIdField)).contains('Person')){ errorobj.HIC_ShopifySync__Shopify_id__c = string.valueof(objectList[index].get(externalIdField)+isbatch).remove('Person'); errorobj.HIC_ShopifySync__Error_id__c = string.valueof(objectName+objectList[index].get(externalIdField)+isbatch).remove('Person'); } if(theField != null ){ if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Important_Field__c',fieldsMaps)) errorobj.HIC_ShopifySync__Important_Field__c = String.valueOf(objectList[index].get(theField)); } }else{ if(theField != null ){ if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Important_Field__c',fieldsMaps)) errorobj.HIC_ShopifySync__Important_Field__c = String.valueOf(objectList[index].get(theField)); } if(CheckAccessibility.isUpdateable('HIC_ShopifySync__shopify_id__c',fieldsMaps) && schemaTypes.isCreateable()){ errorobj.HIC_ShopifySync__shopify_id__c = string.valueof(objectList[index].get(externalIdField)+isbatch); } if(CheckAccessibility.isUpdateable('HIC_ShopifySync__error_id__c',fieldsMaps) && schemaTypes.isCreateable()){ errorobj.HIC_ShopifySync__error_id__c = string.valueof(objectName+objectList[index].get(externalIdField)+isbatch); } } if(CheckAccessibility.isUpdateable('HIC_ShopifySync__delivered__c',fieldsMaps) && schemaTypes.isCreateable()) { errorobj.HIC_ShopifySync__delivered__c = false; } //Get Error message string errorMsg = ''; for(Database.Error error : updateResult[index].getErrors()){ if(error.getFields() != null && !error.getFields().isEmpty()){ errorMsg += String.join(error.getFields(), ' ') + ' | ' + error.getMessage() + ','; }else{ errorMsg += error.getMessage() + ','; } } if(CheckAccessibility.isUpdateable('HIC_ShopifySync__message__c',fieldsMaps) && schemaTypes.isCreateable()){ errorobj.HIC_ShopifySync__message__c = errorMsg.removeEnd(','); } errorobj.HIC_ShopifySync__Iswebhook__c = Iswebhook; if(!errorobj.HIC_ShopifySync__message__c.containsIgnoreCase('duplicate value found: HIC_ShopifySync__Shopify_Id__c duplicates value on record with id') && !errorobj.HIC_ShopifySync__message__c.containsIgnoreCase('unable to obtain exclusive access to this record')){ listoferrors.add(errorobj); } } }else{ String sObjectNames = 'HIC_ShopifySync__Shopify_Log__c'.trim(); sObjectType schemaType = Schema.getGlobalDescribe().get(sObjectNames) ; Map fieldsMap = schemaType.getDescribe().fields.getMap(); HIC_ShopifySync__Shopify_Log__c SuccessLog = new HIC_ShopifySync__Shopify_Log__c(); SuccessLog.HIC_ShopifySync__Store__c = store; SuccessLog.HIC_ShopifySync__Is_Webhook__c = Iswebhook ; SuccessLog.name = Objectname; //Update Shopify's external Id before upsert Shopify logs if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Shopify_id__c,HIC_ShopifySync__Error_id__c',fieldsMap) && objectName == 'Contact'){ if(string.valueof(objectList[index].get(externalIdField)).contains('Busines')){ SuccessLog.HIC_ShopifySync__Error_id__c = string.valueof(objectList[index].get(externalIdField)+isbatch+Objectname).remove('Business'); SuccessLog.HIC_ShopifySync__Shopify_id__c = string.valueof(objectList[index].get(externalIdField)).remove('Business'); }else if(string.valueof(objectList[index].get(externalIdField)).contains('Person')){ SuccessLog.HIC_ShopifySync__Error_id__c = string.valueof(objectList[index].get(externalIdField)+isbatch+Objectname).remove('Person'); SuccessLog.HIC_ShopifySync__Shopify_id__c = string.valueof(objectList[index].get(externalIdField)).remove('Person'); } }else{ if(CheckAccessibility.isUpdateable('HIC_ShopifySync__shopify_id__c,HIC_ShopifySync__Error_id__c',fieldsMaps) && schemaType.getDescribe().isCreateable()){ SuccessLog.HIC_ShopifySync__Error_id__c = string.valueof(objectList[index].get(externalIdField)+isbatch+Objectname); SuccessLog.HIC_ShopifySync__shopify_id__c = string.valueof(objectList[index].get(externalIdField)); } } //Get JSON Response based on Shopify's external Id if(!Shopifyididvsbody.isEmpty() && Shopifyididvsbody.containsKey(string.valueof(objectList[index].get(externalIdField)))){ jSONRequestBody = Shopifyididvsbody.get(string.valueof(objectList[index].get(externalIdField))); } //Split JSON Response into the Salesforce field (If get very large JSON Response) if(jSONRequestBody!= null && jSONRequestBody != ''){ Integer lengthofjSONRequestBody = jSONRequestBody.length(); if(lengthofjSONRequestBody != null && lengthofjSONRequestBody != 0 && lengthofjSONRequestBody <= 131072){ SuccessLog.HIC_ShopifySync__Info__c = jSONRequestBody; }else if(lengthofjSONRequestBody > 131072 && lengthofjSONRequestBody <= 262144){ SuccessLog.HIC_ShopifySync__Info__c = jSONRequestBody.substring(0,131072); SuccessLog.HIC_ShopifySync__Second_Info__c =jSONRequestBody.substring(131072,lengthofjSONRequestBody); }else if(lengthofjSONRequestBody > 262144 && lengthofjSONRequestBody <= 393216){ SuccessLog.HIC_ShopifySync__Info__c = jSONRequestBody.substring(0,131072); SuccessLog.HIC_ShopifySync__Second_Info__c =jSONRequestBody.substring(131072,262144); SuccessLog.HIC_ShopifySync__Third_Info__c = jSONRequestBody.substring(262144,lengthofjSONRequestBody); }else if(lengthofjSONRequestBody > 393216){ SuccessLog.HIC_ShopifySync__Info__c = jSONRequestBody.substring(0,131072); SuccessLog.HIC_ShopifySync__Second_Info__c =jSONRequestBody.substring(131072,262144); SuccessLog.HIC_ShopifySync__Third_Info__c = jSONRequestBody.substring(262144,393216); } } // Shopify Log added listofsuccesslog.add(SuccessLog); } } //Upsert Error Messagge records if(!listoferrors.isEmpty()){ if(schemaTypes.isAccessible() && schemaTypes.isCreateable()){ Schema.SObjectType objectType1 = Schema.getGlobalDescribe().get('HIC_ShopifySync__Error_Message__c'); Map fieldMap1 = objectType1.getDescribe().fields.getMap(); Schema.SobjectField theField1 = fieldMap1.get('HIC_ShopifySync__Error_id__c'); if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Error_id__c','HIC_ShopifySync__Error_Message__c') && schemaTypes.isCreateable()){ database.upsert(listoferrors, theField1); } } } //Upsert Success logs records if(!listofsuccesslog.isEmpty()){ if(Schema.sObjectType.HIC_ShopifySync__Shopify_Log__c.isAccessible() && Schema.sObjectType.HIC_ShopifySync__Shopify_Log__c.isCreateable()){ Schema.SObjectType objectType1 = Schema.getGlobalDescribe().get('HIC_ShopifySync__Shopify_Log__c'); Map fieldMap1 = objectType1.getDescribe().fields.getMap(); Schema.SobjectField theField1 = fieldMap1.get('HIC_ShopifySync__Error_id__c'); if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Error_id__c','HIC_ShopifySync__Shopify_Log__c') && Schema.getGlobalDescribe().get('HIC_ShopifySync__Shopify_Log__c').getDescribe().isCreateable()){ database.upsert(listofsuccesslog, theField1); } } } }catch(Exception e){ } } //Deprecated public static void makeCsvAndSendInEmail( String jSONRequestBody, String objectName, List objectList, Schema.SobjectField externalIdField, boolean IsWebhook){ } /**************************************nestedRecordsJSONBody*************************************************/ /** * ─────────────────────────────────────────────────────────────────────────────────────────────┐ * Use for get map of Shopify external Id Vs JSON Response of the record - Map: Shopifyididvsbody * ────────────────────────────────────────────────────────────────────────────────────────────── * @param String jsonbody - list of Shopify JSON response * ─────────────────────────────────────────────────────────────────────────────────────────────┘ */ public static void nestedRecordsJSONBody(String jsonbody){ list listofmain = (list) JSON.deserializeUntyped(jsonbody); map> Orderidvslistofvarintobject = new map>(); List listofallProductVarients = new List(); for(object obj :listofmain ){ Map mainmap = (Map) obj; if(mainmap.isEmpty()) return; listofallProductVarients.add(obj); } for(Object obj : listofallProductVarients){ map mapvariants = (map) obj; Shopifyididvsbody.put(String.valueof(mapvariants.get('id')),JSON.serialize(obj)); } } /**************************************DeleteRecords*************************************************/ /** * ─────────────────────────────────────────────────────────────────────────────────────────────┐ * Use for track deleted records in Salesforce * Upsert Error message if any * Upsert Shopify Log records for deleted records * ────────────────────────────────────────────────────────────────────────────────────────────── * @param String Objectname - Salesforce Object Name * @param String jSONRequestBody - JSON Repose of the Shopify Records * @param list deleteresult - deleted records details * @param list objectList - List of Object list for upsert * ─────────────────────────────────────────────────────────────────────────────────────────────┘ */ public static void DeleteRecords(String Objectname, String jSONRequestBody, list deleteresult, list objectList, String store ){ if(jSONRequestBody == '' || jSONRequestBody == null) return; Map recordidvsShopifyid = new map(); if(!objectList.isEmpty() && objectList.size() >0){ for(SObject obj : objectList ){ recordidvsShopifyid.put(String.valueof(obj.get('id')),String.valueof(obj.get('HIC_ShopifySync__Shopify_Id__c'))); } } Schema.SObjectType SObjectType = Schema.getGlobalDescribe().get(objectName); Schema.DescribeSObjectResult objResult = SObjectType.getDescribe(); string ObjectLabelName = String.valueof(objResult.getLabel()); list listofErrormailfield = new List(); String ErrorfieldMappingquery = 'select ' +CheckAccessibility.isAccessible('name,HIC_ShopifySync__Shopify_Field__c','HIC_ShopifySync__Error_Mapping__c') +' from HIC_ShopifySync__Error_Mapping__c where '+ CheckAccessibility.isAccessible('name','HIC_ShopifySync__Error_Mapping__c') + ' = \''+ ObjectLabelName +'\' limit 1'; listofErrormailfield = Database.query(ErrorfieldMappingquery); Schema.SObjectType ObjectType = Schema.getGlobalDescribe().get(objectName); Map fieldMap = ObjectType.getDescribe().fields.getmap(); Schema.SobjectField theField = null; list listofsuccesslog = new list(); list listoferrors = new list(); String sObjectName = 'HIC_ShopifySync__Error_Message__c'.trim(); DescribeSObjectResult schemaType = Schema.getGlobalDescribe().get(sObjectName).getDescribe(); Map fieldsMap = schemaType.fields.getMap(); for(Database.DeleteResult result : deleteresult){ if(result.isSuccess()){ HIC_ShopifySync__Shopify_Log__c SuccessLog = new HIC_ShopifySync__Shopify_Log__c(); SuccessLog.HIC_ShopifySync__Store__c = store; SuccessLog.HIC_ShopifySync__Is_Webhook__c = true; SuccessLog.name = Objectname ; SuccessLog.HIC_ShopifySync__Error_id__c = recordidvsShopifyid.get(String.valueOf(result.getId()))+'T'+Objectname+ '-Delete'; SuccessLog.HIC_ShopifySync__Shopify_Id__c = recordidvsShopifyid.get(String.valueOf(result.getId())); if(jSONRequestBody!= null && jSONRequestBody != ''){ Integer lengthofjSONRequestBody = jSONRequestBody.length(); if(lengthofjSONRequestBody != null && lengthofjSONRequestBody != 0 && lengthofjSONRequestBody <= 131072){ SuccessLog.HIC_ShopifySync__Info__c = jSONRequestBody; }else if(lengthofjSONRequestBody > 131072 && lengthofjSONRequestBody <= 262144){ SuccessLog.HIC_ShopifySync__Info__c = jSONRequestBody.substring(0,131072); SuccessLog.HIC_ShopifySync__Second_Info__c =jSONRequestBody.substring(131072,lengthofjSONRequestBody); }else if(lengthofjSONRequestBody > 262144 && lengthofjSONRequestBody <= 393216){ SuccessLog.HIC_ShopifySync__Info__c = jSONRequestBody.substring(0,131072); SuccessLog.HIC_ShopifySync__Second_Info__c =jSONRequestBody.substring(131072,262144); SuccessLog.HIC_ShopifySync__Third_Info__c = jSONRequestBody.substring(262144,lengthofjSONRequestBody); }else if(lengthofjSONRequestBody > 393216){ SuccessLog.HIC_ShopifySync__Info__c = jSONRequestBody.substring(0,131072); SuccessLog.HIC_ShopifySync__Second_Info__c =jSONRequestBody.substring(131072,262144); SuccessLog.HIC_ShopifySync__Third_Info__c = jSONRequestBody.substring(262144,393216); } } listofsuccesslog.add(SuccessLog); }else{ HIC_ShopifySync__Error_Message__c errorobj = new HIC_ShopifySync__Error_Message__c(); errorobj.HIC_ShopifySync__Store__c = store; if(CheckAccessibility.isUpdateable('name',fieldsMap) && schemaType.isCreateable()){ errorobj.name = Objectname; } if(!listofErrormailfield.isEmpty() && fieldMap.containsKey(String.ValueOf(listofErrormailfield[0].HIC_ShopifySync__Shopify_Field__c))){ theField = fieldMap.get(String.ValueOf(listofErrormailfield[0].HIC_ShopifySync__Shopify_Field__c)); } if(theField != null ){ if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Important_Field__c',fieldsMap) && !objectList.isEmpty()) errorobj.HIC_ShopifySync__Important_Field__c = String.valueOf(objectList[0].get(theField)); } if(CheckAccessibility.isUpdateable('HIC_ShopifySync__shopify_id__c',fieldsMap) && schemaType.isCreateable()){ errorobj.HIC_ShopifySync__Shopify_id__c = recordidvsShopifyid.get(String.valueof(result.getId())); } if(CheckAccessibility.isUpdateable('HIC_ShopifySync__error_id__c',fieldsMap) && schemaType.isCreateable()){ errorobj.HIC_ShopifySync__Error_id__c = 'Delete '+Objectname+recordidvsShopifyid.get(String.valueof(result.getId())); } if(CheckAccessibility.isUpdateable('HIC_ShopifySync__delivered__c',fieldsMap) && schemaType.isCreateable()) { errorobj.HIC_ShopifySync__delivered__c = false; } string errorMsg = ''; for(Database.Error error : result.getErrors()){ if(error.getFields() != null && !error.getFields().isEmpty()){ errorMsg += String.join(error.getFields(), ' ') + ' | ' + error.getMessage() + ','; }else{ errorMsg += error.getMessage() + ','; } } if(CheckAccessibility.isUpdateable('HIC_ShopifySync__message__c',fieldsMap) && schemaType.isCreateable()){ errorobj.HIC_ShopifySync__message__c = errorMsg.removeEnd(','); } errorobj.HIC_ShopifySync__Iswebhook__c = true; if(!errorobj.HIC_ShopifySync__message__c.containsIgnoreCase('duplicate value found: HIC_ShopifySync__Shopify_Id__c duplicates value on record with id') && !errorobj.HIC_ShopifySync__message__c.containsIgnoreCase('unable to obtain exclusive access to this record')){ listoferrors.add(errorobj); } } } if(!listoferrors.isEmpty()){ if(Schema.sObjectType.HIC_ShopifySync__Error_Message__c.isAccessible() && Schema.sObjectType.HIC_ShopifySync__Error_Message__c.isCreateable()){ Schema.SObjectType objectType1 = Schema.getGlobalDescribe().get('HIC_ShopifySync__Error_Message__c'); Map fieldMap1 = objectType1.getDescribe().fields.getMap(); Schema.SobjectField theField1 = fieldMap1.get('HIC_ShopifySync__Error_id__c'); if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Error_id__c','HIC_ShopifySync__Error_Message__c') && Schema.getGlobalDescribe().get('HIC_ShopifySync__Error_Message__c').getDescribe().isCreateable()){ database.upsert(listoferrors, theField1); } } } if(!listofsuccesslog.isEmpty()){ if(Schema.sObjectType.HIC_ShopifySync__Shopify_Log__c.isAccessible() && Schema.sObjectType.HIC_ShopifySync__Shopify_Log__c.isCreateable()){ Schema.SObjectType objectType1 = Schema.getGlobalDescribe().get('HIC_ShopifySync__Shopify_Log__c'); Map fieldMap1 = objectType1.getDescribe().fields.getMap(); Schema.SobjectField theField1 = fieldMap1.get('HIC_ShopifySync__Error_id__c'); if(CheckAccessibility.isUpsertable('HIC_ShopifySync__Error_id__c','HIC_ShopifySync__Shopify_Log__c') && Schema.getGlobalDescribe().get('HIC_ShopifySync__Shopify_Log__c').getDescribe().isCreateable()){ database.upsert(listofsuccesslog, theField1); } } } } //Deprecated public static void DeleteRecords(String Objectname, String jSONRequestBody, list deleteresult, list objectList ){ } /**************************************SendErrormail*************************************************/ /** * ─────────────────────────────────────────────────────────────────────────────────────────────┐ * Use for send email notification * ────────────────────────────────────────────────────────────────────────────────────────────── * @param String Objectname - Salesforce Object Name * ─────────────────────────────────────────────────────────────────────────────────────────────┘ */ public static void SendErrormail(String objapiname){ Schema.SObjectType SObjectType = Schema.getGlobalDescribe().get(objapiname); Schema.DescribeSObjectResult objResult = SObjectType.getDescribe(); string ObjectLabelName = String.valueof(objResult.getLabel()); list listoferrors = new list(); String query = 'Select '+CheckAccessibility.isAccessible('name,HIC_ShopifySync__Delivered__c,HIC_ShopifySync__Error_id__c,HIC_ShopifySync__Message__c,HIC_ShopifySync__Shopify_id__c,HIC_ShopifySync__Important_Field__c','HIC_ShopifySync__Error_Message__c')+' from HIC_ShopifySync__Error_Message__c where '+CheckAccessibility.isAccessible('HIC_ShopifySync__Delivered__c','HIC_ShopifySync__Error_Message__c')+' = false and '+CheckAccessibility.isAccessible('name','HIC_ShopifySync__Error_Message__c')+' = \''+ objapiname +'\''; system.debug('EmailErrorCSV--> '+query); listoferrors = database.query(query); system.debug('listoferrors--> '+listoferrors); if(listoferrors.isempty()) return; List toAddresses = new List (); List getEmailIdsToSendErrorEmails = new List (); String getEmailIds = 'Select '+CheckAccessibility.isAccessible('id,name ','HIC_ShopifySync__Email_Addresses_to_send_error_CSV__c') +' from HIC_ShopifySync__Email_Addresses_to_send_error_CSV__c Limit 49000'; getEmailIdsToSendErrorEmails = database.query(getEmailIds); system.debug('***Emailidlist---*'+getEmailIdsToSendErrorEmails); if(getEmailIdsToSendErrorEmails.isempty()) return; list listofErrormailfield = new List(); String ErrorfieldMappingquery = 'select ' +CheckAccessibility.isAccessible('name,HIC_ShopifySync__Shopify_Field__c','HIC_ShopifySync__Error_Mapping__c') +' from HIC_ShopifySync__Error_Mapping__c where '+ CheckAccessibility.isAccessible('name','HIC_ShopifySync__Error_Mapping__c') + ' = \''+ objapiname +'\' limit 1'; listofErrormailfield = Database.query(ErrorfieldMappingquery); for(HIC_ShopifySync__Email_Addresses_to_send_error_CSV__c emailIds : getEmailIdsToSendErrorEmails){ if(emailIds.name != null && emailIds.name != '') toAddresses.add(emailIds.name); } String finalCsv = ''; String csvBody = ''; String headerValue = 'shopify ID, Error Message, '+ (listofErrormailfield[0].HIC_ShopifySync__Shopify_Field__c == null ? '' : listofErrormailfield[0].HIC_ShopifySync__Shopify_Field__c) +' \n'; string errorMsg = ''; finalCsv = headerValue; for(HIC_ShopifySync__Error_Message__c err : listoferrors){ if(err.HIC_ShopifySync__Shopify_id__c != null && err.HIC_ShopifySync__Shopify_id__c != '' && (err.HIC_ShopifySync__Shopify_id__c).containsIgnoreCase('T')) { err.HIC_ShopifySync__Shopify_id__c = (err.HIC_ShopifySync__Shopify_id__c).removeEnd('T'); } if(err.HIC_ShopifySync__Shopify_id__c != null && err.HIC_ShopifySync__Shopify_id__c != '' && (err.HIC_ShopifySync__Shopify_id__c).containsIgnoreCase('F')) { err.HIC_ShopifySync__Shopify_id__c = (err.HIC_ShopifySync__Shopify_id__c).removeEnd('F'); } string recordString = err.HIC_ShopifySync__Shopify_id__c+','+err.HIC_ShopifySync__Message__c+','+(err.HIC_ShopifySync__Important_Field__c == null ? '' : err.HIC_ShopifySync__Important_Field__c ) +'\n'; finalCsv = finalCsv + recordString; } if( finalCsv != null && finalCsv != ''){ system.debug('**finalCsv*-->'+finalCsv); String csvname = ObjectLabelName + 'Error File.csv'; Messaging.EmailFileAttachment csvAttc = new Messaging.EmailFileAttachment(); csvAttc.setFileName(csvname); csvAttc.setBody(Blob.valueOf(finalCsv)); String subject ='Shopify'+' '+ObjectLabelName+' '+'Sync Error'; Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage(); email.setSubject(subject); if(!toAddresses.isEmpty() ){ System.debug('addrress****_-'+toAddresses); email.setToAddresses(toAddresses ); email.setPlainTextBody('Please find error file attached.'); email.setFileAttachments(new Messaging.EmailFileAttachment[]{csvAttc}); try{ Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email}); system.debug('***SendEmailResult'+r); }catch(Exception e){ // system.debug('Error: '+ e.getMessage() +'at Line '+e.getLineNumber()+' Cause '+e.getCause()); Messaging.SingleEmailMessage emailtoCurrentUser =new Messaging.SingleEmailMessage(); emailtoCurrentUser.setSubject(subject); emailtoCurrentUser.setPlainTextBody('Please find error file attached.'); emailtoCurrentUser.setTargetObjectId(UserInfo.getUserId()); emailtoCurrentUser.saveAsActivity = false; emailtoCurrentUser.setFileAttachments(new Messaging.EmailFileAttachment[]{csvAttc}); try{ Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {emailtoCurrentUser}); }catch(Exception err){ System.debug('Email failled'); } } } } } /**************************************SuccessMailSend*************************************************/ /** * ─────────────────────────────────────────────────────────────────────────────────────────────┐ * Use for send email notification * ────────────────────────────────────────────────────────────────────────────────────────────── * @param String Objectname - Salesforce Object Name * ─────────────────────────────────────────────────────────────────────────────────────────────┘ */ public static void SuccessMailSend(){ String syncResult; Map> objNameVsListOfObjMap = new Map>(); Map nameVsShopifyFieldMap = new Map(); List errorObjListTemp; List listoferrors = new List(); list listofErrormailfield = new List(); List csvAttachmentList = new List(); List toAddresses; List getEmailIdsToSendErrorEmails = new List (); String getEmailIds = 'Select '+CheckAccessibility.isAccessible('id,name ','HIC_ShopifySync__Email_Addresses_to_send_error_CSV__c') +' from HIC_ShopifySync__Email_Addresses_to_send_error_CSV__c Limit 49000'; getEmailIdsToSendErrorEmails = database.query(getEmailIds); system.debug('getEmailIdsToSendErrorEmails ----->'+getEmailIdsToSendErrorEmails); if(getEmailIdsToSendErrorEmails.isEmpty()){ return; } String query = 'Select '+CheckAccessibility.isAccessible('name,HIC_ShopifySync__IsWebhook__c,HIC_ShopifySync__Error_id__c,HIC_ShopifySync__Message__c,HIC_ShopifySync__Shopify_id__c,HIC_ShopifySync__Important_Field__c','HIC_ShopifySync__Error_Message__c')+' from HIC_ShopifySync__Error_Message__c where '+CheckAccessibility.isAccessible('HIC_ShopifySync__IsWebhook__c','HIC_ShopifySync__Error_Message__c')+' = false and createdDate = today limit 40000'; system.debug('error obj query string----> '+query); listoferrors = database.query(query); system.debug('listOfAllErrors----> '+listoferrors); if(listoferrors.isEmpty()){ syncResult = 'success'; toAddresses = new List(); for(HIC_ShopifySync__Email_Addresses_to_send_error_CSV__c emailIds : getEmailIdsToSendErrorEmails){ if(emailIds.name != null && emailIds.name != '') toAddresses.add(emailIds.name); } String subject ='Hurray! You are now synced!'; Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage(); email.setSubject(subject); if(!toAddresses.isEmpty() ){ System.debug('toAddrress here**** '+toAddresses); email.setToAddresses(toAddresses ); PageReference pageRef = new PageReference('/apex/ShopifyConfigurationResultTemplate?result='+syncResult); if(!Test.isRunningTest()){ email.setHtmlBody(pageRef.getContent().toString().UnescapeHTML4()); } email.setPlainTextBody(''); try{ system.debug('email here ---->'+email); Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email}); system.debug('success send email result ---->'+r); }catch(Exception e){ Messaging.SingleEmailMessage emailtoCurrentUser =new Messaging.SingleEmailMessage(); emailtoCurrentUser.setSubject(subject); PageReference pageRefnew = new PageReference('/apex/ShopifyConfigurationResultTemplate?result='+syncResult); if(!Test.isRunningTest()){ emailtoCurrentUser.setHtmlBody(pageRefnew.getContent().toString().UnescapeHTML4()); } emailtoCurrentUser.setPlainTextBody(''); emailtoCurrentUser.setTargetObjectId(UserInfo.getUserId()); emailtoCurrentUser.saveAsActivity = false; try{ Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {emailtoCurrentUser}); }catch(Exception err){ System.debug('Email failled'); } } } } else { syncResult = 'failure'; for(HIC_ShopifySync__Error_Message__c errorObj : listoferrors){ system.debug('errorObj here inside if ------->'+errorObj); if(errorObj.HIC_ShopifySync__Shopify_id__c != null && errorObj.HIC_ShopifySync__Shopify_id__c != '' && (errorObj.HIC_ShopifySync__Shopify_id__c).containsIgnoreCase('T')) { errorObj.HIC_ShopifySync__Shopify_id__c = (errorObj.HIC_ShopifySync__Shopify_id__c).removeEnd('T'); } if(errorObj.HIC_ShopifySync__Shopify_id__c != null && errorObj.HIC_ShopifySync__Shopify_id__c != '' && (errorObj.HIC_ShopifySync__Shopify_id__c).containsIgnoreCase('F')) { errorObj.HIC_ShopifySync__Shopify_id__c = (errorObj.HIC_ShopifySync__Shopify_id__c).removeEnd('F'); } if( errorObj != null && String.isNotBlank(errorObj.Name) && !objNameVsListOfObjMap.isEmpty() && objNameVsListOfObjMap.containsKey(errorObj.Name)){ errorObjListTemp = new List(); errorObjListTemp = objNameVsListOfObjMap.get(errorObj.Name); errorObjListTemp.add(errorObj); objNameVsListOfObjMap.put(errorObj.Name, errorObjListTemp); system.debug('inside objNameVsListOfObjMap if ----->'+objNameVsListOfObjMap); } else { if( errorObj != null && String.isNotBlank(errorObj.Name)){ system.debug('errorObj here inside else------->'+errorObj); objNameVsListOfObjMap.put(errorObj.Name, new List{errorObj}); } } } system.debug('objNameVsListOfObjMap final ----->'+objNameVsListOfObjMap); String ErrorfieldMappingquery = 'select ' +CheckAccessibility.isAccessible('name,HIC_ShopifySync__Shopify_Field__c','HIC_ShopifySync__Error_Mapping__c') +' from HIC_ShopifySync__Error_Mapping__c'; system.debug('ErrorfieldMappingquery ----->'+ErrorfieldMappingquery); listofErrormailfield = Database.query(ErrorfieldMappingquery); system.debug('listofErrormailfield ----->'+listofErrormailfield); if( !listofErrormailfield.isEmpty() ){ for( HIC_ShopifySync__Error_Mapping__c errorMapping : listofErrormailfield){ if(String.isNotBlank(errorMapping.Name) && String.isNotBlank(errorMapping.HIC_ShopifySync__Shopify_Field__c) ){ nameVsShopifyFieldMap.put(errorMapping.Name, errorMapping); } } } else { return; } system.debug('nameVsShopifyFieldMap from error mapping obj-->'+nameVsShopifyFieldMap); if(!objNameVsListOfObjMap.isEmpty()){ for(String objName : new List(objNameVsListOfObjMap.keySet() ) ){ String finalCsv = ''; String csvBody = ''; String headerValue = ''; if( !nameVsShopifyFieldMap.isEmpty() && nameVsShopifyFieldMap.containsKey(objName)){ headerValue = 'Shopify ID, Error Message, '+ (nameVsShopifyFieldMap.get(objName).HIC_ShopifySync__Shopify_Field__c == null ? '' : nameVsShopifyFieldMap.get(objName).HIC_ShopifySync__Shopify_Field__c) +' \n'; } string errorMsg = ''; finalCsv = headerValue; List templist = objNameVsListOfObjMap.get(objName); if(templist.size() < 5000){ for(Integer i = 0; i < templist.size(); i++){ //for(HIC_ShopifySync__Error_Message__c err : objNameVsListOfObjMap.get(objName)){ string recordString = templist[i].HIC_ShopifySync__Shopify_id__c+','+templist[i].HIC_ShopifySync__Message__c+','+(templist[i].HIC_ShopifySync__Important_Field__c == null ? '' : templist[i].HIC_ShopifySync__Important_Field__c ) +'\n'; finalCsv = finalCsv + recordString; } }else{ for(Integer i = 0; i < 5000; i++){ //for(HIC_ShopifySync__Error_Message__c err : objNameVsListOfObjMap.get(objName)){ string recordString = templist[i].HIC_ShopifySync__Shopify_id__c+','+templist[i].HIC_ShopifySync__Message__c+','+(templist[i].HIC_ShopifySync__Important_Field__c == null ? '' : templist[i].HIC_ShopifySync__Important_Field__c ) +'\n'; finalCsv = finalCsv + recordString+'\n\n\n\n\nTotal error found on'+objName +','+templist.size(); } } system.debug('final CSV inside for ----->'+finalCsv); if( finalCsv != null && finalCsv != ''){ system.debug('**finalCsv*-->'+finalCsv); String csvname = objName + ' Error File.csv'; Messaging.EmailFileAttachment csvAttc = new Messaging.EmailFileAttachment(); csvAttc.setFileName(csvname); csvAttc.setBody(Blob.valueOf(finalCsv)); system.debug('csvAttc inside for if --->'+csvAttc); csvAttachmentList.add(csvAttc); } } } system.debug('csvAttachmentList final ---->'+csvAttachmentList); toAddresses = new List(); for(HIC_ShopifySync__Email_Addresses_to_send_error_CSV__c emailIds : getEmailIdsToSendErrorEmails){ if(emailIds.name != null && emailIds.name != '') toAddresses.add(emailIds.name); } String subject ='Something did not go quite right'; Messaging.SingleEmailMessage email =new Messaging.SingleEmailMessage(); email.setSubject(subject); if(!toAddresses.isEmpty() ){ System.debug('toAddrress here**** '+toAddresses); email.setToAddresses(toAddresses ); PageReference pageRef = new PageReference('/apex/ShopifyConfigurationResultTemplate?result='+syncResult); if(!Test.isRunningTest()){ email.setHtmlBody(pageRef.getContent().toString().UnescapeHTML4()); } email.setPlainTextBody(''); email.setFileAttachments(csvAttachmentList); system.debug('final email ---->'+email); try{ Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email}); system.debug('error send email result ---->'+r); }catch(Exception e){ Messaging.SingleEmailMessage emailtoCurrentUser =new Messaging.SingleEmailMessage(); emailtoCurrentUser.setSubject(subject); PageReference pageRefnew = new PageReference('/apex/ShopifyConfigurationResultTemplate?result='+syncResult); if(!Test.isRunningTest()){ emailtoCurrentUser.setHtmlBody(pageRefnew.getContent().toString().UnescapeHTML4()); } emailtoCurrentUser.setPlainTextBody(''); emailtoCurrentUser.setTargetObjectId(UserInfo.getUserId()); emailtoCurrentUser.saveAsActivity = false; emailtoCurrentUser.setFileAttachments(csvAttachmentList); try{ Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {emailtoCurrentUser}); }catch(Exception err){ System.debug('Email failled'); } } } } } public static String generateSOQL(String jsonString, SObject sobjectRecord, String jsonRequestBody) { System.debug('DEBUG: Entering generateSOQL method'); if (String.isBlank(jsonString) || String.isBlank(jsonRequestBody)) { System.debug('DEBUG: jsonString or jsonRequestBody is blank'); return null; } System.debug('DEBUG: Deserializing input JSONs'); List conditions = (List) JSON.deserializeUntyped(jsonString); Map shopifyJson = (Map) JSON.deserializeUntyped(jsonRequestBody); List whereClauses = new List(); Set fieldsToRetrieve = new Set(); String salesforceObject = null; System.debug('DEBUG: Starting to iterate over conditions'); for (Object conditionObj : conditions) { System.debug('DEBUG: Condition Object - ' + conditionObj); Map condition = (Map) conditionObj; String shopifyField = (String) condition.get('ShopifyApiName'); String sfField = (String) condition.get('SalesforceFieldApiName'); String matchingOperator = (String) condition.get('MatchingOperator'); salesforceObject = (String) condition.get('SalesforceObject'); Boolean caseSensitive = condition.containsKey('caseSensitive') && (Boolean) condition.get('caseSensitive'); // Get Shopify value Object shopifyValue = getValueFromShopifyJson(shopifyField, shopifyJson); System.debug('DEBUG: Shopify Value - ' + shopifyValue); if (shopifyValue == null) { System.debug('DEBUG: Shopify value is null, skipping this condition'); continue; } // Escape and normalize Shopify value String shvalue = String.escapeSingleQuotes(String.valueOf(shopifyValue)); System.debug('DEBUG: Escaped Shopify Value - ' + shvalue); // Trim and lowercase if not case-sensitive String normalizedShopifyValue = shvalue.trim(); if (!caseSensitive) { normalizedShopifyValue = normalizedShopifyValue.toLowerCase(); } // Build the where clause String fieldExpr = sfField; String whereClause = ''; if (matchingOperator == 'equals') { if (caseSensitive) { whereClause = sfField + ' = \'' + shvalue + '\''; } else { whereClause = sfField + ' LIKE \'' + shvalue.trim() + '\''; } } else if (matchingOperator == 'startsWith') { whereClause = fieldExpr + ' LIKE \'' + normalizedShopifyValue + '%\''; } else if (matchingOperator == 'endsWith') { whereClause = fieldExpr + ' LIKE \'%' + normalizedShopifyValue + '\''; } else if (matchingOperator == 'contains') { whereClause = fieldExpr + ' LIKE \'%' + normalizedShopifyValue + '%\''; } System.debug('DEBUG: Where Clause - ' + whereClause); if (String.isNotEmpty(whereClause)) { whereClauses.add(whereClause); } fieldsToRetrieve.add(sfField); } // Add standard fields if (salesforceObject == 'Account' || salesforceObject == 'Lead') { fieldsToRetrieve.add('Id'); fieldsToRetrieve.add('HIC_ShopifySync__Is_identified__c'); fieldsToRetrieve.add('HIC_ShopifySync__Shopify_Id__c'); } else if (salesforceObject == 'Contact') { fieldsToRetrieve.add('Id'); fieldsToRetrieve.add('HIC_ShopifySync__Is_identified__c'); fieldsToRetrieve.add('HIC_ShopifySync__Shopify_Id__c'); fieldsToRetrieve.add('AccountId'); } else { fieldsToRetrieve.add('Id'); fieldsToRetrieve.add('HIC_ShopifySync__Shopify_Id__c'); } // Final query build whereClauses.add('HIC_ShopifySync__Shopify_Id__c = null'); if (!whereClauses.isEmpty()) { String query = 'SELECT ' + String.join(new List(fieldsToRetrieve), ', ') + ' FROM ' + salesforceObject + ' WHERE ' + String.join(whereClauses, ' AND ') + ' ORDER BY CreatedDate DESC LIMIT 1'; System.debug('DEBUG: Final SOQL Query - ' + query); return query; } System.debug('DEBUG: No where clauses generated, returning null'); return null; } public static Object getValueFromShopifyJson(String shopifyApiName, Map shopifyJson) { if (String.isBlank(shopifyApiName) || shopifyJson == null) { return null; } if (shopifyApiName.contains('.')) { String[] pathParts = shopifyApiName.split('\\.'); Object currentObject = shopifyJson; for (String part : pathParts) { if (!(currentObject instanceof Map)) { return null; } currentObject = ((Map) currentObject).get(part); if (currentObject == null) { return null; } } return currentObject; } else { return shopifyJson.get(shopifyApiName); } } public static Object getFieldValue(SObject sObj, String fieldPath) { List parts = fieldPath.split('\\.'); SObject currentObj = sObj; for (Integer i = 0; i < parts.size(); i++) { String part = parts[i]; Object val = currentObj.get(part); if (val == null) return null; if (i == parts.size() - 1) return val; if (!(val instanceof SObject)) return null; currentObj = (SObject) val; } return null; } public static void flushFeatureParameters(){ Map m = new Map(); //if(fpAcc >0) m.put('HIC_ShopifySync__Customer_Count', fpAcc); if(fpOrd >0) m.put('HIC_ShopifySync__Active_Order_Count', fpOrd); if(fpOrdItem >0) m.put('HIC_ShopifySync__Active_Order_Product_Count',fpOrdItem); //if(fpProd >0) m.put('HIC_ShopifySync__Product_Count', fpProd); if(!m.isEmpty()){ FeatureParameter.incrementAsync(m); } fpOrd = fpOrdItem = 0; } }