Untitled

 avatar
unknown
plain_text
2 months ago
112 kB
2
Indexable
Fullc folder
OpportunityOfferingSaveEditAllController.cls

public without sharing class OpportunityOfferingSaveEditAllController {
    public static Map<String,String> statusMessage = new Map<String,String>();
    @AuraEnabled
    public static List<OpportunityOfferingWrapper> getOfferings(Id recordId){
        List<Opportunity_Offering__c> drLinesList = new List<Opportunity_Offering__c>();
        List<OpportunityOfferingWrapper> drLinesWrapperList = new List<OpportunityOfferingWrapper>();
        drLinesList = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                       from Opportunity_Offering__c where Opportunity_Name__c = :recordId ];
        for(Opportunity_Offering__c drRec : drLinesList){
            drLinesWrapperList.add(new OpportunityOfferingWrapper(drRec));
        }
        return drLinesWrapperList;
    }
    
    @AuraEnabled
    public static OppOfferWrapper getOppDetails(Id recordId){
        Opportunity opp = [select id,name,stagename from opportunity where id = :recordId];
        User userRecord = [select id,Name from User where id = :UserInfo.getUserId()];
        return new OppOfferWrapper(userRecord.Id, userRecord.Name, opp.Id, opp.Name, opp.stagename);
    }
    
    @AuraEnabled
    public static Map<String,String> saveDRList(String oppId, String dealType, List<OpportunityOfferingWrapper> drLinesList){
        system.debug(dealType + '  dealType');
        Set<Id> oppIds = new Set<Id>();
        Savepoint sp = Database.setSavepoint();
        statusMessage.put('status','Success');
        statusMessage.put('message','Records saved successfully');
        statusMessage.put('url',URL.getOrgDomainUrl().toExternalForm());
        List<Opportunity_Offering__c> oppOfferingToUpdate = new List<Opportunity_Offering__c>();
        List<Opportunity_Offering__c> oppOfferingToInsert = new List<Opportunity_Offering__c>();
        Map<Id,String> idVsDealType = new Map<Id,String>();
        for(OpportunityOfferingWrapper drLine : drLinesList){
            idVsDealType.put(drLine.VirtusaOffering,drLine.VirtusaOfferingDealType);
        }
        List<Virtusa_Offering__c> virtusaLis = [select id,Offering_Deal_Type__c from Virtusa_Offering__c where id IN :idVsDealType.keySet()];
        for(Virtusa_Offering__c offer : virtusaLis){
            idVsDealType.put(offer.id,offer.Offering_Deal_Type__c);
        }
        Decimal consultingSum = 0;
        Decimal nonConsultingSum = 0;
        for(OpportunityOfferingWrapper drLine : drLinesList){
            String virtusaOffDealType = drLine.VirtusaOfferingDealType != null && drLine.VirtusaOfferingDealType != '' ? drLine.VirtusaOfferingDealType :
            idVsDealType.get(drLine.VirtusaOffering);
            if(virtusaOffDealType == 'Consulting'){
                consultingSum = consultingSum + Decimal.valueOf(drLine.OfferingSplit);
            }
            if(virtusaOffDealType == 'Non Consulting'){
                nonConsultingSum = nonConsultingSum + Decimal.valueOf(drLine.OfferingSplit);
            }
        }
        if(dealType == 'Consulting'){
            if(consultingSum != 100 || nonConsultingSum > 50){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For Consulting Deals it is mandatory to select one or more consulting offering with split% totaling to 100% and optional to have non consulting Offerings with up to 50% split');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        if(dealType == 'Non Consulting'){
            if(nonConsultingSum < 5 || nonConsultingSum > 100 || consultingSum > 50){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For Non-Consulting Deals Offering Sum of Split% can vary between 5% to max 100% and optionally Consulting Offerings Split % sum can be up to 50%');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        system.debug(nonConsultingSum + '  nonConsultingSum');
        system.debug(consultingSum + '  consultingSum');
        if(dealType == 'No Offerings Required'){
            system.debug('inside if block  no offering....');
            if(nonConsultingSum != 0 || consultingSum != 0){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For "No Offerings Required" Deals tagging No Offerings is only allowed');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        
        try{
            Boolean isNoOfferingExist = false;
            String virId = '';
            if(dealType == 'No Offerings Required'){
                List<Opportunity_Offering__c> drLinesListNoOff = new List<Opportunity_Offering__c>();
                drLinesListNoOff = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                                    from Opportunity_Offering__c where Opportunity_Name__c = :oppId and Virtu_Offering_Split_p__c = 0];
                if(drLinesListNoOff.size() != 0 ) isNoOfferingExist = true;
                List<Virtusa_Offering__c> vir = [select id,name from Virtusa_Offering__c where name = 'No Offerings'];
                virId = vir[0].Id;
            }
            for(OpportunityOfferingWrapper drLine : drLinesList){
                oppIds.add(drLine.opportunityId);
                Opportunity_Offering__c drlineRec = new Opportunity_Offering__c();
                drlineRec.Virtusa_Offering__c = drLine.VirtusaOffering;
                if(drLine.OfferingSplit != null && drLine.OfferingSplit != '' ) drlineRec.Virtu_Offering_Split_p__c = Decimal.valueOf(drLine.OfferingSplit);
                drlineRec.Opportunity_Name__c = drLine.opportunityId;
                drlineRec.Deal_Led_By__c = dealType;
                if(virId == drLine.VirtusaOffering) isNoOfferingExist = true;
                //drLineRecordToInsert.add(drlineRec);
                if(drLine.Id != null && drLine.Id != ''){
                    drlineRec.Id = drLine.Id;
                    oppOfferingToUpdate.add(drlineRec);//if(Decimal.valueOf(drLine.OfferingSplit) != 0)  removed logic as not able to update offering to zero
                }
                else{
                    oppOfferingToInsert.add(drlineRec);
                }
            }
            if(dealType == 'No Offerings Required' && !isNoOfferingExist){
                List<Opportunity_Offering__c> drLinesListNoOff = new List<Opportunity_Offering__c>();
                drLinesListNoOff = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                               from Opportunity_Offering__c where Opportunity_Name__c = :oppId and Virtu_Offering_Split_p__c != 0];
                Opportunity_Offering__c drlineRec = new Opportunity_Offering__c();
                
                drlineRec.Virtusa_Offering__c = virId;
                drlineRec.Virtu_Offering_Split_p__c = 0;
                drlineRec.Opportunity_Name__c = oppId;
                drlineRec.Deal_Led_By__c = dealType;
                if(drLinesListNoOff.size() == 0 ) oppOfferingToInsert.add(drlineRec);
                
            }
            Set<Id> newOfferingIds = new Set<Id>();
            if(oppOfferingToInsert.size() > 0){
                insert oppOfferingToInsert;
                for(Opportunity_Offering__c offers : oppOfferingToInsert){
                    newOfferingIds.add(offers.Id);
                }
            }
            if(oppOfferingToUpdate.size() > 0){
                update oppOfferingToUpdate;
            }
            if(oppIds.size() > 0 && (oppOfferingToUpdate.size() > 0 || oppOfferingToInsert.size() > 0)){
                initiateEmailNotification(oppIds,newOfferingIds);
            }
            
        }
        catch(Exception ex){
            statusMessage.put('status','Fail');
            String errorMsg = ex.getMessage();//Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, You cannot add or edit the offerings of this opportunity: []
            if(errorMsg.contains('FIELD_CUSTOM_VALIDATION_EXCEPTION')) errorMsg = errorMsg.substringAfter('FIELD_CUSTOM_VALIDATION_EXCEPTION,');
            if(errorMsg.contains(': []')) errorMsg = errorMsg.substringBefore(': []').trim();
            statusMessage.put('message',errorMsg);
            Database.rollback(sp);
        }
        return statusMessage;
    }
    @Future
    public static void initiateEmailNotification(Set<Id> oppIds,Set<Id> newOfferings){
        Map<Id,List<Opportunity_Offering__c>> oppIdVsOfferingList = new Map<Id,List<Opportunity_Offering__c>>();
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name,
                                                                   Group_SBU__c,
                                                                   Account.Customer_Name__r.Client__r.Name,
                                                                   Account.Customer_Name__r.name,
                                                                   Account.name,
                                                                   Opportunity_ID__c,
                                                                   Deal_Type__c,
                                                                   StageName,
                                                                   Amount,
                                                                   CurrencyIsoCode,
                                                                   Opportunity_Amount_Converted_New__c,
                                                                   Opportunity_CS_Owner__r.Name,
                                                                   Owner.name,
                                                                   OwnerId,
                                                                   Owner.Email,
                                                                   Account.owner.name,
                                                                   Account.CSM__r.Name
                                                                   from Opportunity where id In :oppIds]);
        Map<Id,Opportunity_Offering__c> idVsRelOfferingRecord = new Map<Id,Opportunity_Offering__c>([select id,Name,
                                                                                                  Opportunity_Name__c,Virtusa_Offering__c,
                                                                                                     Virtusa_Offering__r.Offering_Squad__c,
                                                                                                     Virtu_Offering_Split_p__c,
                                                                                                     Old_Offering_Split__c,
                                                                                                     Deal_Led_By__c,
                                                                                                     Owner.name,
                                                                                                     Virtusa_Offering__r.Name
                                                                                                  from Opportunity_Offering__c 
                                                                                                  where Opportunity_Name__c IN :oppIds]);
        Set<String> squadTeam = new Set<String>();
        Map<Id,String> virtusaIdVsSquad = new Map<Id,String>();
        for(Opportunity_Offering__c offer : idVsRelOfferingRecord.values()){
            if(offer.Virtusa_Offering__c != null && offer.Virtusa_Offering__r.Offering_Squad__c != null){
                if(offer.Virtu_Offering_Split_p__c != 0 || (offer.Virtu_Offering_Split_p__c == 0 && offer.Virtu_Offering_Split_p__c != offer.Old_Offering_Split__c))
                   squadTeam.add(offer.Virtusa_Offering__r.Offering_Squad__c);
                virtusaIdVsSquad.put(offer.Virtusa_Offering__c,offer.Virtusa_Offering__r.Offering_Squad__c);
            }
            if(oppIdVsOfferingList.containsKey(offer.Opportunity_Name__c)){
                oppIdVsOfferingList.get(offer.Opportunity_Name__c).add(offer);
            }else{
                oppIdVsOfferingList.put(offer.Opportunity_Name__c,new List<Opportunity_Offering__c>{offer});
            }
        }
        Map<String,String> emailVsName = new Map<String,String>();
        String slist = '';
        for (String s: squadTeam) {
            slist += '\'' + s + '\',';
        }
        system.debug(',slist' + slist);
        slist = slist.removeEnd(',');
        String value = '(\'' + String.join(squadTeam, '\',\'') + '\')';
        String queryString = 'select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c'+
                                                           ' from contact' + 
                                                           ' where email != null and ' + 
                                                           ' Offering_squad_Leader__c = true and ' +
                                                           ' Off_Squad_Team_del__c includes' + value;
        List<Contact> contactList = DataBase.query(queryString);
        system.debug('List of records: '+contactList);
        /*Map<Id,Contact> contactList = new Map<Id,Contact>([select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c
                                                           from contact 
                                                           where email != null and 
                                                           Offering_squad_Leader__c = true and 
                                                           Off_Squad_Team_del__c includes (:slist)]);*/
        system.debug(',contactList' + contactList);
        Map<Id,List<String>> virOffIdVsEmail = new Map<Id,List<String>>();
        Map<String,Set<Id>> emailVsVirtusaId = new Map<String,Set<Id>>();
        for(Id virId : virtusaIdVsSquad.keySet()){
            for(Contact con : contactList){
                emailVsName.put(con.email,con.name);
                if(virtusaIdVsSquad.get(virId) != null && con.Off_Squad_Team_del__c.contains(virtusaIdVsSquad.get(virId))){
                    if(!virOffIdVsEmail.containskey(virId))virOffIdVsEmail.put(virId,new List<String>{con.email});
                    else{
                        virOffIdVsEmail.get(virId).add(con.email);
                    }
                }
            }
        }
        for(Id oppId : oppIdVsOfferingList.keySet()){
            Set<String> to = new Set<String>();
            Opportunity opp = offeringOpp.get(oppId);
            if(opp.owner.email != null){
                to.add(opp.owner.email);
                emailVsName.put(opp.owner.email,opp.owner.name);
            }
            for(Opportunity_Offering__c oppOffer : oppIdVsOfferingList.get(oppId)){
                Id relatedOffId = oppOffer.Id;
                if(virOffIdVsEmail != null && idVsRelOfferingRecord != null && idVsRelOfferingRecord.get(relatedOffId) != null 
                   && virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c) != null)
                    to.addAll(virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c));
                if(virOffIdVsEmail != null && virOffIdVsEmail.get(oppOffer.Virtusa_Offering__c) != null){
                    to.addAll(virOffIdVsEmail.get(oppOffer.Virtusa_Offering__c));
                }
            }
            

            String subject = 'Virtusa Offering Notification';
            String body = '';
            body = 'Hi All,<br/><br/> Following offerings have tagged to the opportunity.<br/><br/>';
            String dealLeadBy = oppIdVsOfferingList.get(oppId).size() > 1 ? 
                oppIdVsOfferingList.get(oppId)[1].Deal_Led_By__c : oppIdVsOfferingList.get(oppId)[0].Deal_Led_By__c;
            body = body + 
                '<b><u>Opportunity Details</b></u><br/><br/>'+
                '<li>Deal Lead By - '+dealLeadBy + '</li>'+
                '<li>Group SBU - '+offeringOpp.get(oppId).Group_SBU__c+'</li>'+
                '<li>Account - '+offeringOpp.get(oppId).Account.name+'</li>'+
                '<li>Opportunity ID - <a href="'+ URL.getOrgDomainUrl().toExternalForm() +'/'+oppId+'">'+offeringOpp.get(oppId).Opportunity_ID__c+'</a></li>'+
                '<li>Opportunity Name - '+offeringOpp.get(oppId).name + '</li>'+
                '<li>Stage - '+offeringOpp.get(oppId).StageName+'</li>'+
                '<li>Amount (converted) - '+'USD'+' '+offeringOpp.get(oppId).Opportunity_Amount_Converted_New__c+'</li>'+
                '<li>Opportunity Owner - '+offeringOpp.get(oppId).Owner.name + '</li>'+
                '<br/><br/>';
            
            body = body + '<b><u>Offering Details</b></u><br/><br/>';
            String tableHtml = '<table style="border-collapse: collapse;">';
            tableHtml += '<thead>';
            tableHtml += '<tr>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">SR. No</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Virtusa Offering Name</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Old Split%</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">New Split%</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Is Modified</th>';
            tableHtml += '</tr>';
            tableHtml += '</thead>';
            tableHtml += '<tbody>';
            Integer count = 1;
            List<Opportunity_Offering__c> offerList = oppIdVsOfferingList.get(oppId);
            for(Opportunity_Offering__c oppOffer : offerList){
                if(offerList.size() == 1 || 
                   (offerList.size() > 1 && oppOffer.Virtusa_Offering__r.Name != 'No Offerings')){
                    tableHtml += '<tr>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + count + '</td>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Virtusa_Offering__r.Name + '</td>';
                    String oldSplit = oppOffer.Old_Offering_Split__c == null ? '-' : oppOffer.Old_Offering_Split__c.setScale(2) + '';
                    if(newOfferings.contains(oppOffer.Id)) oldSplit = '-';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oldSplit + '</td>';
                    //else tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Old_Offering_Split__c + '</td>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Virtu_Offering_Split_p__c + '</td>';
                    Boolean isNotChange = oppOffer.Old_Offering_Split__c == null || oppOffer.Virtu_Offering_Split_p__c == oppOffer.Old_Offering_Split__c;
                    String isChanged = !isNotChange == true ? 'Yes' : 'No';
                    
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + isChanged + '</td>';
                    tableHtml += '</tr>';
                    count++;
                }
            }
            tableHtml += '</tbody>';
            tableHtml += '</table>';
            body = body + tableHtml + '<br/><br/>';
            body = body + 'Thanks,<br/> System Administrator';
            String repmail = '';
            SingleEmailUtility seu = new SingleEmailUtility();
            List<String> ccAddress = new List<String>();
            seu.sendMail(new List<String>(to), ccAddress, '', subject, body);
        }
    }
    
    public class OppOfferWrapper{
        @auraEnabled public string currentUserId{get;set;}
        @auraEnabled public string currentName{get;set;}
        @auraEnabled public string OpportunityName{get;set;}
        @auraEnabled public string OpportunityId{get;set;}
        @auraEnabled public string opportunityStageName{get;set;} 
        public OppOfferWrapper(String userId, String userName, String oppId, String oppName, String oppStage){
            this.currentUserId = userId;
            this.currentName = userName;
            this.OpportunityName = oppName;
            this.OpportunityId = oppId;
            this.opportunityStageName = oppStage;
        }
    }
}



----------------------

OpportunityOfferingTriggerHelper.cls

public without sharing class OpportunityOfferingTriggerHelper {
    @future
    public static void createShareRecordsFutureContext(Set<Id> offeringIds){
        if(offeringIds != null)createShareRecords(offeringIds);
    }
    
    public static void createShareRecords(Set<Id> offeringIds){
        Map<Id,Id> oppOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Id> virOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Set<Id>> oppIdVsOfferingIdSet = new Map<Id,Set<Id>>();
        
        List<Opportunity_Offering__c> opOfferingList = new List<Opportunity_Offering__c>();
        opOfferingList = [select id,Opportunity_Name__c,Virtusa_Offering__c from
                          Opportunity_Offering__c where id IN :offeringIds];
        for(Opportunity_Offering__c opOffering : opOfferingList){
            oppOfferIdVsOppId.put(opOffering.Id,opOffering.Opportunity_Name__c);
            virOfferIdVsOppId.put(opOffering.Id,opOffering.Virtusa_Offering__c);
            if(!oppIdVsOfferingIdSet.containsKey(opOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(opOffering.Opportunity_Name__c,new Set<Id>{opOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c).add(opOffering.Id);
            }
        }
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name
                                                                   from Opportunity where id In :oppOfferIdVsOppId.values() ]);
        Map<Id,Opportunity_Offering__c> idVsRelOfferingRecord = new Map<Id,Opportunity_Offering__c>([select id,
                                                                                                     Opportunity_Name__c,Virtusa_Offering__c
                                                                                                     from Opportunity_Offering__c 
                                                                                                     where Opportunity_Name__c IN :offeringOpp.keySet()
                                                                                                     and ID Not In :oppOfferIdVsOppId.keySet()]);
        for(Opportunity_Offering__c opOffering : idVsRelOfferingRecord.values()){
            oppOfferIdVsOppId.put(opOffering.Id,opOffering.Opportunity_Name__c);
            virOfferIdVsOppId.put(opOffering.Id,opOffering.Virtusa_Offering__c);
            if(!oppIdVsOfferingIdSet.containsKey(opOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(opOffering.Opportunity_Name__c,new Set<Id>{opOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c).add(opOffering.Id);
            }
        }
        Map<Id,Virtusa_Offering__c> vOfferingList = new Map<Id,Virtusa_Offering__c>([Select id,
                                                                                     Offering_Squad__c,
                                                                                     Virtu_Squad_Email_Address__c
                                                                                     from Virtusa_Offering__c
                                                                                     where    id In :virOfferIdVsOppId.values() ]);
        Set<String> squadTeam = new Set<String>();        
        for(Virtusa_Offering__c vr : vOfferingList.values()){
            if(vr.Offering_Squad__c != null) squadTeam.add(vr.Offering_Squad__c);
        }
        Map<Id,List<String>> virOffIdVsEmail = new Map<Id,List<String>>();
        Map<String,Set<Id>> emailVsVirtusaId = new Map<String,Set<Id>>();
        String slist = '';
        for (String s: squadTeam) {
            slist += '\'' + s + '\',';
        }
            String value = '(\'' + String.join(squadTeam, '\',\'') + '\')';
            String queryString = 'select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c'+
                                                               ' from contact' + 
                                                               ' where email != null and ' + 
                                                               ' Offering_squad_Leader__c = true and ' +
                                                               ' Off_Squad_Team_del__c includes' + value;
            List<Contact> contactList = DataBase.query(queryString);
        
        for(Virtusa_Offering__c vr : vOfferingList.values()){
            if(vr.Offering_Squad__c != null){
                for(Contact con : contactList){
                    if(con.Off_Squad_Team_del__c.contains(vr.Offering_Squad__c)){
                        //emailVsName.put(con.email,con.name);
                        if(!emailVsVirtusaId.containskey(con.email)){
                            emailVsVirtusaId.put(con.email,new Set<Id>{vr.Id});
                        }
                        else{
                            emailVsVirtusaId.get(con.email).add(vr.Id);
                        }
                        if(!virOffIdVsEmail.containskey(vr.Id)){
                            
                            virOffIdVsEmail.put(vr.Id,new List<String>{con.email});
                        }
                        else{
                            virOffIdVsEmail.get(vr.Id).add(con.email);
                        }
                    }
                }
            }
        }
        Set<String> toAddresses = new Set<String>();
        for(Opportunity_Offering__c opOffering : opOfferingList){
            Set<String> to = new Set<String>();
            if(offeringOpp.get(opOffering.Opportunity_Name__c) != null){
                Set<Id> relatedOfferingIds = oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c);
                if(relatedOfferingIds != null && relatedOfferingIds.size() > 0){
                    for(Id relatedOffId : relatedOfferingIds){
                        if(virOffIdVsEmail != null && idVsRelOfferingRecord != null && idVsRelOfferingRecord.get(relatedOffId) != null
                           && idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c != null )
                            to.addAll(virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c));
                        
                    }
                }
            }
            if(virOffIdVsEmail != null && virOffIdVsEmail.get(opOffering.Virtusa_Offering__c) != null){
                to.addAll(virOffIdVsEmail.get(opOffering.Virtusa_Offering__c));
            }
            if(to.size() > 0) toAddresses.addAll(to);
        }
        List<User> userRecords = [select id,email from User where email IN :toAddresses];
        Map<String,Opportunity_Offering__share> oppOffList = new Map<String,Opportunity_Offering__share>();
        for(User userRec : userRecords){
            if(emailVsVirtusaId != null && emailVsVirtusaId.get(userRec.email) != null){
                Set<Id> virtusaIds = emailVsVirtusaId.get(userRec.email);
                for(Id oppOfferId : virOfferIdVsOppId.keySet()){
                    Set<Id> offerIds = oppIdVsOfferingIdSet.get(oppOfferIdVsOppId.get(oppOfferId));
                    if(virtusaIds.contains(virOfferIdVsOppId.get(oppOfferId))){
                        for(Id offerId : offerIds){
                            Opportunity_Offering__share oppOfferShare = new Opportunity_Offering__share();
                            oppOfferShare.ParentId = offerId;
                            oppOfferShare.UserOrGroupId = userRec.Id;
                            oppOfferShare.AccessLevel = 'edit';
                            oppOfferShare.RowCause = 'Manual';
                            if(offerId != null && userRec != null)
                                oppOffList.put(offerId+'-'+userRec.Id,oppOfferShare);
                        }
                    }
                }
            }
        }
        if(oppOffList.size() > 0) Database.upsert(oppOffList.values(),false);
        
    }
    
    //Author    - Viji
    //Arguments - opOfferingList -> list of opportunity offering record
    //Purpose   - called from after update,after insert
    //Date      - 21/03/2023
    @future
    public static void updateOffOwnerAccessToOppOwnerHelper(Set<Id> offeringIds){
        createShareRecordsForOppOwner(offeringIds);
    }
    
    public static void createShareRecordsForOppOwner(Set<Id> offeringIds){
        Map<Id,Id> oppOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Set<Id>> oppIdVsOfferingIdSet = new Map<Id,Set<Id>>();
        Map<Id,Id> offOwner = new Map<Id,Id>();
        List<Opportunity_Offering__c> opOfferingList = new List<Opportunity_Offering__c>();
        opOfferingList = [select id,Opportunity_Name__c,Virtusa_Offering__c,OwnerId from
                          Opportunity_Offering__c where id IN :offeringIds];
        
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppOfferIdVsOppId.put(oppOffering.id,oppOffering.Opportunity_Name__c);
            if(!oppIdVsOfferingIdSet.containsKey(oppOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(oppOffering.Opportunity_Name__c,new Set<Id>{oppOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(oppOffering.Opportunity_Name__c).add(oppOffering.Id);
            }
        }
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name,stagename,ownerid
                                                                   from Opportunity where id In :oppOfferIdVsOppId.values() ]);
        for(Opportunity_Offering__c opOffering : opOfferingList){
            Opportunity oppRec = offeringOpp.get(opOffering.Opportunity_Name__c);
            Id offeringOwner = opOffering.ownerId;
            if(oppRec != null){
                Set<Id> relatedOfferingIds = oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c);
                if(relatedOfferingIds != null && relatedOfferingIds.size() > 0){
                    for(Id relatedOffId : relatedOfferingIds){
                        if(oppRec.OwnerId != null && offeringOwner != null && oppRec.OwnerId != offeringOwner){
                            offOwner.put(oppRec.Id, oppRec.OwnerId);
                        }
                    }
                }
            }
        }
        
        List<User> ownerUserRecords = [select id from User where Id =: offOwner.values()];
        Map<String,Opportunity_Offering__share> oppOffList = new Map<String,Opportunity_Offering__share>();
        List<Opportunity_Offering__c> oppOwnerOffList= [select id,Opportunity_Name__c,ownerId from
                                                        Opportunity_Offering__c where ownerId NOT IN :ownerUserRecords 
                                                        AND Opportunity_Name__c =: offOwner.keySet()];    
        for(User userRec : ownerUserRecords){
            if(userRec!=null){
                for(Opportunity_Offering__c offering : oppOwnerOffList){
                    Opportunity_Offering__share oppOfferShare = new Opportunity_Offering__share();
                    oppOfferShare.ParentId = offering.Id;
                    oppOfferShare.UserOrGroupId = userRec.Id;
                    oppOfferShare.AccessLevel = 'edit';
                    oppOfferShare.RowCause = 'Manual';
                    if(offering!=null && userRec != null){
                        oppOffList.put(offering.Id+'-'+userRec.Id,oppOfferShare);
                    }
                }
                if(oppOffList.size() > 0) upsert oppOffList.values();         
                
            }
        }    
    }        
    
    public static void deleteNoOffering(List<Opportunity_Offering__c> opOfferingList,Boolean isUpdate){
        Set<Id> oppIds = new Set<Id>();
        Set<Id> curroppIds = new Set<Id>();
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppIds.add(oppOffering.Opportunity_Name__c);
            if(!isUpdate) curroppIds.add(oppOffering.Id);
        }
		deletNoOfferingFuture(oppIds,curroppIds);
    }
    @future
    public static void deletNoOfferingFuture(Set<Id> oppIds,Set<Id> curroppIds){
        List<Opportunity_Offering__c> oppList = [SELECT Id, OwnerId, Name, Opportunity_Name__c, Opportunity_Id__c, Virtusa_Offering__c,Virtusa_Offering__r.name 
                                                 FROM Opportunity_Offering__c where Opportunity_Name__c IN :oppIds AND Virtusa_Offering__r.name = 'No Offerings' AND id NOT IN :curroppIds];
        if(oppList != null && oppList.size() > 0){
            delete oppList;
        }
    }
    public static void stampOldPec(Map<Id, Opportunity_Offering__c > mapOldRecord,Map<Id, Opportunity_Offering__c > mapNewRecord){
        for(Opportunity_Offering__c opOffering : mapNewRecord.values()){
            if(mapOldRecord.get(opOffering.Id).Virtu_Offering_Split_p__c != null){
                   opOffering.Old_Offering_Split__c = mapOldRecord.get(opOffering.Id).Virtu_Offering_Split_p__c;
               }
        }
    }
    
    public static void validateNoOffering(List<Opportunity_Offering__c> opOfferingList){
        Set<Id> oppIds = new Set<Id>();
        Set<Id> virIds = new Set<Id>();
        Map<Id,Boolean> oppIdToRes = new Map<Id,Boolean>();
        //Boolean noOffering;
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppIds.add(oppOffering.Opportunity_Name__c);
            virIds.add(oppOffering.Virtusa_Offering__c);
        }
        Map<Id,Virtusa_Offering__c> vOfferingList = new Map<Id,Virtusa_Offering__c>([Select id,Name,
                                                                                     Offering_Squad__c,
                                                                                     Virtu_Squad_Email_Address__c
                                                                                     from Virtusa_Offering__c
                                                                                     where    id In :virIds]);
        List<Opportunity_Offering__c> oppList = [SELECT Id, OwnerId, Name, Opportunity_Name__c, Opportunity_Id__c, Virtusa_Offering__c,Virtusa_Offering__r.name, Virtu_Offering_Split_p__c 
                                                 FROM Opportunity_Offering__c where Opportunity_Name__c IN :oppIds];
        oppList.addAll(opOfferingList);
        for(Opportunity_Offering__c opp : oppList){
            if(oppList.size()>0){
                oppIdToRes.put(opp.Opportunity_Name__c,false);
                if(opp.Virtu_Offering_Split_p__c == 0){
                    //noOffering = true;
                }else{
                    //noOffering = false;
                    oppIdToRes.put(opp.Opportunity_Name__c,true);
                }
            }
        }
        for(Opportunity_Offering__c opp : opOfferingList){
            if(oppList.size()>0){
            //if(vOfferingList.get(opp.Virtusa_Offering__c).name == 'No Offerings' && !noOffering && oppIdToRes.contains(opp.Opportunity_Name__c)){
            if(vOfferingList.get(opp.Virtusa_Offering__c).name == 'No Offerings' && oppIdToRes.containsKey(opp.Opportunity_Name__c) && oppIdToRes.get(opp.Opportunity_Name__c)){
                opp.addError('"No Offerings" Cannot Be Tagged If Opportunity has Offerings');
            }
            }
        }
    }
}



---------------------

OpportunityOfferingSaveEditAllController.cls
public without sharing class OpportunityOfferingSaveEditAllController {
    public static Map<String,String> statusMessage = new Map<String,String>();
    @AuraEnabled
    public static List<OpportunityOfferingWrapper> getOfferings(Id recordId){
        List<Opportunity_Offering__c> drLinesList = new List<Opportunity_Offering__c>();
        List<OpportunityOfferingWrapper> drLinesWrapperList = new List<OpportunityOfferingWrapper>();
        drLinesList = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                       from Opportunity_Offering__c where Opportunity_Name__c = :recordId ];
        for(Opportunity_Offering__c drRec : drLinesList){
            drLinesWrapperList.add(new OpportunityOfferingWrapper(drRec));
        }
        return drLinesWrapperList;
    }
    
    @AuraEnabled
    public static OppOfferWrapper getOppDetails(Id recordId){
        Opportunity opp = [select id,name,stagename from opportunity where id = :recordId];
        User userRecord = [select id,Name from User where id = :UserInfo.getUserId()];
        return new OppOfferWrapper(userRecord.Id, userRecord.Name, opp.Id, opp.Name, opp.stagename);
    }
    
    @AuraEnabled
    public static Map<String,String> saveDRList(String oppId, String dealType, List<OpportunityOfferingWrapper> drLinesList){
        system.debug(dealType + '  dealType');
        Set<Id> oppIds = new Set<Id>();
        Savepoint sp = Database.setSavepoint();
        statusMessage.put('status','Success');
        statusMessage.put('message','Records saved successfully');
        statusMessage.put('url',URL.getOrgDomainUrl().toExternalForm());
        List<Opportunity_Offering__c> oppOfferingToUpdate = new List<Opportunity_Offering__c>();
        List<Opportunity_Offering__c> oppOfferingToInsert = new List<Opportunity_Offering__c>();
        Map<Id,String> idVsDealType = new Map<Id,String>();
        for(OpportunityOfferingWrapper drLine : drLinesList){
            idVsDealType.put(drLine.VirtusaOffering,drLine.VirtusaOfferingDealType);
        }
        List<Virtusa_Offering__c> virtusaLis = [select id,Offering_Deal_Type__c from Virtusa_Offering__c where id IN :idVsDealType.keySet()];
        for(Virtusa_Offering__c offer : virtusaLis){
            idVsDealType.put(offer.id,offer.Offering_Deal_Type__c);
        }
        Decimal consultingSum = 0;
        Decimal nonConsultingSum = 0;
        for(OpportunityOfferingWrapper drLine : drLinesList){
            String virtusaOffDealType = drLine.VirtusaOfferingDealType != null && drLine.VirtusaOfferingDealType != '' ? drLine.VirtusaOfferingDealType :
            idVsDealType.get(drLine.VirtusaOffering);
            if(virtusaOffDealType == 'Consulting'){
                consultingSum = consultingSum + Decimal.valueOf(drLine.OfferingSplit);
            }
            if(virtusaOffDealType == 'Non Consulting'){
                nonConsultingSum = nonConsultingSum + Decimal.valueOf(drLine.OfferingSplit);
            }
        }
        if(dealType == 'Consulting'){
            if(consultingSum != 100 || nonConsultingSum > 50){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For Consulting Deals it is mandatory to select one or more consulting offering with split% totaling to 100% and optional to have non consulting Offerings with up to 50% split');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        if(dealType == 'Non Consulting'){
            if(nonConsultingSum < 5 || nonConsultingSum > 100 || consultingSum > 50){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For Non-Consulting Deals Offering Sum of Split% can vary between 5% to max 100% and optionally Consulting Offerings Split % sum can be up to 50%');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        system.debug(nonConsultingSum + '  nonConsultingSum');
        system.debug(consultingSum + '  consultingSum');
        if(dealType == 'No Offerings Required'){
            system.debug('inside if block  no offering....');
            if(nonConsultingSum != 0 || consultingSum != 0){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For "No Offerings Required" Deals tagging No Offerings is only allowed');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        
        try{
            Boolean isNoOfferingExist = false;
            String virId = '';
            if(dealType == 'No Offerings Required'){
                List<Opportunity_Offering__c> drLinesListNoOff = new List<Opportunity_Offering__c>();
                drLinesListNoOff = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                                    from Opportunity_Offering__c where Opportunity_Name__c = :oppId and Virtu_Offering_Split_p__c = 0];
                if(drLinesListNoOff.size() != 0 ) isNoOfferingExist = true;
                List<Virtusa_Offering__c> vir = [select id,name from Virtusa_Offering__c where name = 'No Offerings'];
                virId = vir[0].Id;
            }
            for(OpportunityOfferingWrapper drLine : drLinesList){
                oppIds.add(drLine.opportunityId);
                Opportunity_Offering__c drlineRec = new Opportunity_Offering__c();
                drlineRec.Virtusa_Offering__c = drLine.VirtusaOffering;
                if(drLine.OfferingSplit != null && drLine.OfferingSplit != '' ) drlineRec.Virtu_Offering_Split_p__c = Decimal.valueOf(drLine.OfferingSplit);
                drlineRec.Opportunity_Name__c = drLine.opportunityId;
                drlineRec.Deal_Led_By__c = dealType;
                if(virId == drLine.VirtusaOffering) isNoOfferingExist = true;
                //drLineRecordToInsert.add(drlineRec);
                if(drLine.Id != null && drLine.Id != ''){
                    drlineRec.Id = drLine.Id;
                    oppOfferingToUpdate.add(drlineRec);//if(Decimal.valueOf(drLine.OfferingSplit) != 0)  removed logic as not able to update offering to zero
                }
                else{
                    oppOfferingToInsert.add(drlineRec);
                }
            }
            if(dealType == 'No Offerings Required' && !isNoOfferingExist){
                List<Opportunity_Offering__c> drLinesListNoOff = new List<Opportunity_Offering__c>();
                drLinesListNoOff = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                               from Opportunity_Offering__c where Opportunity_Name__c = :oppId and Virtu_Offering_Split_p__c != 0];
                Opportunity_Offering__c drlineRec = new Opportunity_Offering__c();
                
                drlineRec.Virtusa_Offering__c = virId;
                drlineRec.Virtu_Offering_Split_p__c = 0;
                drlineRec.Opportunity_Name__c = oppId;
                drlineRec.Deal_Led_By__c = dealType;
                if(drLinesListNoOff.size() == 0 ) oppOfferingToInsert.add(drlineRec);
                
            }
            Set<Id> newOfferingIds = new Set<Id>();
            if(oppOfferingToInsert.size() > 0){
                insert oppOfferingToInsert;
                for(Opportunity_Offering__c offers : oppOfferingToInsert){
                    newOfferingIds.add(offers.Id);
                }
            }
            if(oppOfferingToUpdate.size() > 0){
                update oppOfferingToUpdate;
            }
            if(oppIds.size() > 0 && (oppOfferingToUpdate.size() > 0 || oppOfferingToInsert.size() > 0)){
                initiateEmailNotification(oppIds,newOfferingIds);
            }
            
        }
        catch(Exception ex){
            statusMessage.put('status','Fail');
            String errorMsg = ex.getMessage();//Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, You cannot add or edit the offerings of this opportunity: []
            if(errorMsg.contains('FIELD_CUSTOM_VALIDATION_EXCEPTION')) errorMsg = errorMsg.substringAfter('FIELD_CUSTOM_VALIDATION_EXCEPTION,');
            if(errorMsg.contains(': []')) errorMsg = errorMsg.substringBefore(': []').trim();
            statusMessage.put('message',errorMsg);
            Database.rollback(sp);
        }
        return statusMessage;
    }
    @Future
    public static void initiateEmailNotification(Set<Id> oppIds,Set<Id> newOfferings){
        Map<Id,List<Opportunity_Offering__c>> oppIdVsOfferingList = new Map<Id,List<Opportunity_Offering__c>>();
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name,
                                                                   Group_SBU__c,
                                                                   Account.Customer_Name__r.Client__r.Name,
                                                                   Account.Customer_Name__r.name,
                                                                   Account.name,
                                                                   Opportunity_ID__c,
                                                                   Deal_Type__c,
                                                                   StageName,
                                                                   Amount,
                                                                   CurrencyIsoCode,
                                                                   Opportunity_Amount_Converted_New__c,
                                                                   Opportunity_CS_Owner__r.Name,
                                                                   Owner.name,
                                                                   OwnerId,
                                                                   Owner.Email,
                                                                   Account.owner.name,
                                                                   Account.CSM__r.Name
                                                                   from Opportunity where id In :oppIds]);
        Map<Id,Opportunity_Offering__c> idVsRelOfferingRecord = new Map<Id,Opportunity_Offering__c>([select id,Name,
                                                                                                  Opportunity_Name__c,Virtusa_Offering__c,
                                                                                                     Virtusa_Offering__r.Offering_Squad__c,
                                                                                                     Virtu_Offering_Split_p__c,
                                                                                                     Old_Offering_Split__c,
                                                                                                     Deal_Led_By__c,
                                                                                                     Owner.name,
                                                                                                     Virtusa_Offering__r.Name
                                                                                                  from Opportunity_Offering__c 
                                                                                                  where Opportunity_Name__c IN :oppIds]);
        Set<String> squadTeam = new Set<String>();
        Map<Id,String> virtusaIdVsSquad = new Map<Id,String>();
        for(Opportunity_Offering__c offer : idVsRelOfferingRecord.values()){
            if(offer.Virtusa_Offering__c != null && offer.Virtusa_Offering__r.Offering_Squad__c != null){
                if(offer.Virtu_Offering_Split_p__c != 0 || (offer.Virtu_Offering_Split_p__c == 0 && offer.Virtu_Offering_Split_p__c != offer.Old_Offering_Split__c))
                   squadTeam.add(offer.Virtusa_Offering__r.Offering_Squad__c);
                virtusaIdVsSquad.put(offer.Virtusa_Offering__c,offer.Virtusa_Offering__r.Offering_Squad__c);
            }
            if(oppIdVsOfferingList.containsKey(offer.Opportunity_Name__c)){
                oppIdVsOfferingList.get(offer.Opportunity_Name__c).add(offer);
            }else{
                oppIdVsOfferingList.put(offer.Opportunity_Name__c,new List<Opportunity_Offering__c>{offer});
            }
        }
        Map<String,String> emailVsName = new Map<String,String>();
        String slist = '';
        for (String s: squadTeam) {
            slist += '\'' + s + '\',';
        }
        system.debug(',slist' + slist);
        slist = slist.removeEnd(',');
        String value = '(\'' + String.join(squadTeam, '\',\'') + '\')';
        String queryString = 'select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c'+
                                                           ' from contact' + 
                                                           ' where email != null and ' + 
                                                           ' Offering_squad_Leader__c = true and ' +
                                                           ' Off_Squad_Team_del__c includes' + value;
        List<Contact> contactList = DataBase.query(queryString);
        system.debug('List of records: '+contactList);
        /*Map<Id,Contact> contactList = new Map<Id,Contact>([select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c
                                                           from contact 
                                                           where email != null and 
                                                           Offering_squad_Leader__c = true and 
                                                           Off_Squad_Team_del__c includes (:slist)]);*/
        system.debug(',contactList' + contactList);
        Map<Id,List<String>> virOffIdVsEmail = new Map<Id,List<String>>();
        Map<String,Set<Id>> emailVsVirtusaId = new Map<String,Set<Id>>();
        for(Id virId : virtusaIdVsSquad.keySet()){
            for(Contact con : contactList){
                emailVsName.put(con.email,con.name);
                if(virtusaIdVsSquad.get(virId) != null && con.Off_Squad_Team_del__c.contains(virtusaIdVsSquad.get(virId))){
                    if(!virOffIdVsEmail.containskey(virId))virOffIdVsEmail.put(virId,new List<String>{con.email});
                    else{
                        virOffIdVsEmail.get(virId).add(con.email);
                    }
                }
            }
        }
        for(Id oppId : oppIdVsOfferingList.keySet()){
            Set<String> to = new Set<String>();
            Opportunity opp = offeringOpp.get(oppId);
            if(opp.owner.email != null){
                to.add(opp.owner.email);
                emailVsName.put(opp.owner.email,opp.owner.name);
            }
            for(Opportunity_Offering__c oppOffer : oppIdVsOfferingList.get(oppId)){
                Id relatedOffId = oppOffer.Id;
                if(virOffIdVsEmail != null && idVsRelOfferingRecord != null && idVsRelOfferingRecord.get(relatedOffId) != null 
                   && virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c) != null)
                    to.addAll(virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c));
                if(virOffIdVsEmail != null && virOffIdVsEmail.get(oppOffer.Virtusa_Offering__c) != null){
                    to.addAll(virOffIdVsEmail.get(oppOffer.Virtusa_Offering__c));
                }
            }
            

            String subject = 'Virtusa Offering Notification';
            String body = '';
            body = 'Hi All,<br/><br/> Following offerings have tagged to the opportunity.<br/><br/>';
            String dealLeadBy = oppIdVsOfferingList.get(oppId).size() > 1 ? 
                oppIdVsOfferingList.get(oppId)[1].Deal_Led_By__c : oppIdVsOfferingList.get(oppId)[0].Deal_Led_By__c;
            body = body + 
                '<b><u>Opportunity Details</b></u><br/><br/>'+
                '<li>Deal Lead By - '+dealLeadBy + '</li>'+
                '<li>Group SBU - '+offeringOpp.get(oppId).Group_SBU__c+'</li>'+
                '<li>Account - '+offeringOpp.get(oppId).Account.name+'</li>'+
                '<li>Opportunity ID - <a href="'+ URL.getOrgDomainUrl().toExternalForm() +'/'+oppId+'">'+offeringOpp.get(oppId).Opportunity_ID__c+'</a></li>'+
                '<li>Opportunity Name - '+offeringOpp.get(oppId).name + '</li>'+
                '<li>Stage - '+offeringOpp.get(oppId).StageName+'</li>'+
                '<li>Amount (converted) - '+'USD'+' '+offeringOpp.get(oppId).Opportunity_Amount_Converted_New__c+'</li>'+
                '<li>Opportunity Owner - '+offeringOpp.get(oppId).Owner.name + '</li>'+
                '<br/><br/>';
            
            body = body + '<b><u>Offering Details</b></u><br/><br/>';
            String tableHtml = '<table style="border-collapse: collapse;">';
            tableHtml += '<thead>';
            tableHtml += '<tr>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">SR. No</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Virtusa Offering Name</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Old Split%</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">New Split%</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Is Modified</th>';
            tableHtml += '</tr>';
            tableHtml += '</thead>';
            tableHtml += '<tbody>';
            Integer count = 1;
            List<Opportunity_Offering__c> offerList = oppIdVsOfferingList.get(oppId);
            for(Opportunity_Offering__c oppOffer : offerList){
                if(offerList.size() == 1 || 
                   (offerList.size() > 1 && oppOffer.Virtusa_Offering__r.Name != 'No Offerings')){
                    tableHtml += '<tr>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + count + '</td>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Virtusa_Offering__r.Name + '</td>';
                    String oldSplit = oppOffer.Old_Offering_Split__c == null ? '-' : oppOffer.Old_Offering_Split__c.setScale(2) + '';
                    if(newOfferings.contains(oppOffer.Id)) oldSplit = '-';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oldSplit + '</td>';
                    //else tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Old_Offering_Split__c + '</td>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Virtu_Offering_Split_p__c + '</td>';
                    Boolean isNotChange = oppOffer.Old_Offering_Split__c == null || oppOffer.Virtu_Offering_Split_p__c == oppOffer.Old_Offering_Split__c;
                    String isChanged = !isNotChange == true ? 'Yes' : 'No';
                    
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + isChanged + '</td>';
                    tableHtml += '</tr>';
                    count++;
                }
            }
            tableHtml += '</tbody>';
            tableHtml += '</table>';
            body = body + tableHtml + '<br/><br/>';
            body = body + 'Thanks,<br/> System Administrator';
            String repmail = '';
            SingleEmailUtility seu = new SingleEmailUtility();
            List<String> ccAddress = new List<String>();
            seu.sendMail(new List<String>(to), ccAddress, '', subject, body);
        }
    }
    
    public class OppOfferWrapper{
        @auraEnabled public string currentUserId{get;set;}
        @auraEnabled public string currentName{get;set;}
        @auraEnabled public string OpportunityName{get;set;}
        @auraEnabled public string OpportunityId{get;set;}
        @auraEnabled public string opportunityStageName{get;set;} 
        public OppOfferWrapper(String userId, String userName, String oppId, String oppName, String oppStage){
            this.currentUserId = userId;
            this.currentName = userName;
            this.OpportunityName = oppName;
            this.OpportunityId = oppId;
            this.opportunityStageName = oppStage;
        }
    }
}



------------------------

OpportunityOfferingTriggerHelper.cls

public without sharing class OpportunityOfferingTriggerHelper {
    @future
    public static void createShareRecordsFutureContext(Set<Id> offeringIds){
        if(offeringIds != null)createShareRecords(offeringIds);
    }
    
    public static void createShareRecords(Set<Id> offeringIds){
        Map<Id,Id> oppOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Id> virOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Set<Id>> oppIdVsOfferingIdSet = new Map<Id,Set<Id>>();
        
        List<Opportunity_Offering__c> opOfferingList = new List<Opportunity_Offering__c>();
        opOfferingList = [select id,Opportunity_Name__c,Virtusa_Offering__c from
                          Opportunity_Offering__c where id IN :offeringIds];
        for(Opportunity_Offering__c opOffering : opOfferingList){
            oppOfferIdVsOppId.put(opOffering.Id,opOffering.Opportunity_Name__c);
            virOfferIdVsOppId.put(opOffering.Id,opOffering.Virtusa_Offering__c);
            if(!oppIdVsOfferingIdSet.containsKey(opOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(opOffering.Opportunity_Name__c,new Set<Id>{opOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c).add(opOffering.Id);
            }
        }
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name
                                                                   from Opportunity where id In :oppOfferIdVsOppId.values() ]);
        Map<Id,Opportunity_Offering__c> idVsRelOfferingRecord = new Map<Id,Opportunity_Offering__c>([select id,
                                                                                                     Opportunity_Name__c,Virtusa_Offering__c
                                                                                                     from Opportunity_Offering__c 
                                                                                                     where Opportunity_Name__c IN :offeringOpp.keySet()
                                                                                                     and ID Not In :oppOfferIdVsOppId.keySet()]);
        for(Opportunity_Offering__c opOffering : idVsRelOfferingRecord.values()){
            oppOfferIdVsOppId.put(opOffering.Id,opOffering.Opportunity_Name__c);
            virOfferIdVsOppId.put(opOffering.Id,opOffering.Virtusa_Offering__c);
            if(!oppIdVsOfferingIdSet.containsKey(opOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(opOffering.Opportunity_Name__c,new Set<Id>{opOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c).add(opOffering.Id);
            }
        }
        Map<Id,Virtusa_Offering__c> vOfferingList = new Map<Id,Virtusa_Offering__c>([Select id,
                                                                                     Offering_Squad__c,
                                                                                     Virtu_Squad_Email_Address__c
                                                                                     from Virtusa_Offering__c
                                                                                     where    id In :virOfferIdVsOppId.values() ]);
        Set<String> squadTeam = new Set<String>();        
        for(Virtusa_Offering__c vr : vOfferingList.values()){
            if(vr.Offering_Squad__c != null) squadTeam.add(vr.Offering_Squad__c);
        }
        Map<Id,List<String>> virOffIdVsEmail = new Map<Id,List<String>>();
        Map<String,Set<Id>> emailVsVirtusaId = new Map<String,Set<Id>>();
        String slist = '';
        for (String s: squadTeam) {
            slist += '\'' + s + '\',';
        }
            String value = '(\'' + String.join(squadTeam, '\',\'') + '\')';
            String queryString = 'select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c'+
                                                               ' from contact' + 
                                                               ' where email != null and ' + 
                                                               ' Offering_squad_Leader__c = true and ' +
                                                               ' Off_Squad_Team_del__c includes' + value;
            List<Contact> contactList = DataBase.query(queryString);
        
        for(Virtusa_Offering__c vr : vOfferingList.values()){
            if(vr.Offering_Squad__c != null){
                for(Contact con : contactList){
                    if(con.Off_Squad_Team_del__c.contains(vr.Offering_Squad__c)){
                        //emailVsName.put(con.email,con.name);
                        if(!emailVsVirtusaId.containskey(con.email)){
                            emailVsVirtusaId.put(con.email,new Set<Id>{vr.Id});
                        }
                        else{
                            emailVsVirtusaId.get(con.email).add(vr.Id);
                        }
                        if(!virOffIdVsEmail.containskey(vr.Id)){
                            
                            virOffIdVsEmail.put(vr.Id,new List<String>{con.email});
                        }
                        else{
                            virOffIdVsEmail.get(vr.Id).add(con.email);
                        }
                    }
                }
            }
        }
        Set<String> toAddresses = new Set<String>();
        for(Opportunity_Offering__c opOffering : opOfferingList){
            Set<String> to = new Set<String>();
            if(offeringOpp.get(opOffering.Opportunity_Name__c) != null){
                Set<Id> relatedOfferingIds = oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c);
                if(relatedOfferingIds != null && relatedOfferingIds.size() > 0){
                    for(Id relatedOffId : relatedOfferingIds){
                        if(virOffIdVsEmail != null && idVsRelOfferingRecord != null && idVsRelOfferingRecord.get(relatedOffId) != null
                           && idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c != null )
                            to.addAll(virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c));
                        
                    }
                }
            }
            if(virOffIdVsEmail != null && virOffIdVsEmail.get(opOffering.Virtusa_Offering__c) != null){
                to.addAll(virOffIdVsEmail.get(opOffering.Virtusa_Offering__c));
            }
            if(to.size() > 0) toAddresses.addAll(to);
        }
        List<User> userRecords = [select id,email from User where email IN :toAddresses];
        Map<String,Opportunity_Offering__share> oppOffList = new Map<String,Opportunity_Offering__share>();
        for(User userRec : userRecords){
            if(emailVsVirtusaId != null && emailVsVirtusaId.get(userRec.email) != null){
                Set<Id> virtusaIds = emailVsVirtusaId.get(userRec.email);
                for(Id oppOfferId : virOfferIdVsOppId.keySet()){
                    Set<Id> offerIds = oppIdVsOfferingIdSet.get(oppOfferIdVsOppId.get(oppOfferId));
                    if(virtusaIds.contains(virOfferIdVsOppId.get(oppOfferId))){
                        for(Id offerId : offerIds){
                            Opportunity_Offering__share oppOfferShare = new Opportunity_Offering__share();
                            oppOfferShare.ParentId = offerId;
                            oppOfferShare.UserOrGroupId = userRec.Id;
                            oppOfferShare.AccessLevel = 'edit';
                            oppOfferShare.RowCause = 'Manual';
                            if(offerId != null && userRec != null)
                                oppOffList.put(offerId+'-'+userRec.Id,oppOfferShare);
                        }
                    }
                }
            }
        }
        if(oppOffList.size() > 0) Database.upsert(oppOffList.values(),false);
        
    }
    
    //Author    - Viji
    //Arguments - opOfferingList -> list of opportunity offering record
    //Purpose   - called from after update,after insert
    //Date      - 21/03/2023
    @future
    public static void updateOffOwnerAccessToOppOwnerHelper(Set<Id> offeringIds){
        createShareRecordsForOppOwner(offeringIds);
    }
    
    public static void createShareRecordsForOppOwner(Set<Id> offeringIds){
        Map<Id,Id> oppOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Set<Id>> oppIdVsOfferingIdSet = new Map<Id,Set<Id>>();
        Map<Id,Id> offOwner = new Map<Id,Id>();
        List<Opportunity_Offering__c> opOfferingList = new List<Opportunity_Offering__c>();
        opOfferingList = [select id,Opportunity_Name__c,Virtusa_Offering__c,OwnerId from
                          Opportunity_Offering__c where id IN :offeringIds];
        
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppOfferIdVsOppId.put(oppOffering.id,oppOffering.Opportunity_Name__c);
            if(!oppIdVsOfferingIdSet.containsKey(oppOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(oppOffering.Opportunity_Name__c,new Set<Id>{oppOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(oppOffering.Opportunity_Name__c).add(oppOffering.Id);
            }
        }
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name,stagename,ownerid
                                                                   from Opportunity where id In :oppOfferIdVsOppId.values() ]);
        for(Opportunity_Offering__c opOffering : opOfferingList){
            Opportunity oppRec = offeringOpp.get(opOffering.Opportunity_Name__c);
            Id offeringOwner = opOffering.ownerId;
            if(oppRec != null){
                Set<Id> relatedOfferingIds = oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c);
                if(relatedOfferingIds != null && relatedOfferingIds.size() > 0){
                    for(Id relatedOffId : relatedOfferingIds){
                        if(oppRec.OwnerId != null && offeringOwner != null && oppRec.OwnerId != offeringOwner){
                            offOwner.put(oppRec.Id, oppRec.OwnerId);
                        }
                    }
                }
            }
        }
        
        List<User> ownerUserRecords = [select id from User where Id =: offOwner.values()];
        Map<String,Opportunity_Offering__share> oppOffList = new Map<String,Opportunity_Offering__share>();
        List<Opportunity_Offering__c> oppOwnerOffList= [select id,Opportunity_Name__c,ownerId from
                                                        Opportunity_Offering__c where ownerId NOT IN :ownerUserRecords 
                                                        AND Opportunity_Name__c =: offOwner.keySet()];    
        for(User userRec : ownerUserRecords){
            if(userRec!=null){
                for(Opportunity_Offering__c offering : oppOwnerOffList){
                    Opportunity_Offering__share oppOfferShare = new Opportunity_Offering__share();
                    oppOfferShare.ParentId = offering.Id;
                    oppOfferShare.UserOrGroupId = userRec.Id;
                    oppOfferShare.AccessLevel = 'edit';
                    oppOfferShare.RowCause = 'Manual';
                    if(offering!=null && userRec != null){
                        oppOffList.put(offering.Id+'-'+userRec.Id,oppOfferShare);
                    }
                }
                if(oppOffList.size() > 0) upsert oppOffList.values();         
                
            }
        }    
    }        
    
    public static void deleteNoOffering(List<Opportunity_Offering__c> opOfferingList,Boolean isUpdate){
        Set<Id> oppIds = new Set<Id>();
        Set<Id> curroppIds = new Set<Id>();
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppIds.add(oppOffering.Opportunity_Name__c);
            if(!isUpdate) curroppIds.add(oppOffering.Id);
        }
		deletNoOfferingFuture(oppIds,curroppIds);
    }
    @future
    public static void deletNoOfferingFuture(Set<Id> oppIds,Set<Id> curroppIds){
        List<Opportunity_Offering__c> oppList = [SELECT Id, OwnerId, Name, Opportunity_Name__c, Opportunity_Id__c, Virtusa_Offering__c,Virtusa_Offering__r.name 
                                                 FROM Opportunity_Offering__c where Opportunity_Name__c IN :oppIds AND Virtusa_Offering__r.name = 'No Offerings' AND id NOT IN :curroppIds];
        if(oppList != null && oppList.size() > 0){
            delete oppList;
        }
    }
    public static void stampOldPec(Map<Id, Opportunity_Offering__c > mapOldRecord,Map<Id, Opportunity_Offering__c > mapNewRecord){
        for(Opportunity_Offering__c opOffering : mapNewRecord.values()){
            if(mapOldRecord.get(opOffering.Id).Virtu_Offering_Split_p__c != null){
                   opOffering.Old_Offering_Split__c = mapOldRecord.get(opOffering.Id).Virtu_Offering_Split_p__c;
               }
        }
    }
    
    public static void validateNoOffering(List<Opportunity_Offering__c> opOfferingList){
        Set<Id> oppIds = new Set<Id>();
        Set<Id> virIds = new Set<Id>();
        Map<Id,Boolean> oppIdToRes = new Map<Id,Boolean>();
        //Boolean noOffering;
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppIds.add(oppOffering.Opportunity_Name__c);
            virIds.add(oppOffering.Virtusa_Offering__c);
        }
        Map<Id,Virtusa_Offering__c> vOfferingList = new Map<Id,Virtusa_Offering__c>([Select id,Name,
                                                                                     Offering_Squad__c,
                                                                                     Virtu_Squad_Email_Address__c
                                                                                     from Virtusa_Offering__c
                                                                                     where    id In :virIds]);
        List<Opportunity_Offering__c> oppList = [SELECT Id, OwnerId, Name, Opportunity_Name__c, Opportunity_Id__c, Virtusa_Offering__c,Virtusa_Offering__r.name, Virtu_Offering_Split_p__c 
                                                 FROM Opportunity_Offering__c where Opportunity_Name__c IN :oppIds];
        oppList.addAll(opOfferingList);
        for(Opportunity_Offering__c opp : oppList){
            if(oppList.size()>0){
                oppIdToRes.put(opp.Opportunity_Name__c,false);
                if(opp.Virtu_Offering_Split_p__c == 0){
                    //noOffering = true;
                }else{
                    //noOffering = false;
                    oppIdToRes.put(opp.Opportunity_Name__c,true);
                }
            }
        }
        for(Opportunity_Offering__c opp : opOfferingList){
            if(oppList.size()>0){
            //if(vOfferingList.get(opp.Virtusa_Offering__c).name == 'No Offerings' && !noOffering && oppIdToRes.contains(opp.Opportunity_Name__c)){
            if(vOfferingList.get(opp.Virtusa_Offering__c).name == 'No Offerings' && oppIdToRes.containsKey(opp.Opportunity_Name__c) && oppIdToRes.get(opp.Opportunity_Name__c)){
                opp.addError('"No Offerings" Cannot Be Tagged If Opportunity has Offerings');
            }
            }
        }
    }
}


-------------------FULLC REAL--------------

OpportunityOfferingSaveEditAllController
public without sharing class OpportunityOfferingSaveEditAllController {
    public static Map<String,String> statusMessage = new Map<String,String>();
    @AuraEnabled
    public static List<OpportunityOfferingWrapper> getOfferings(Id recordId){
        List<Opportunity_Offering__c> drLinesList = new List<Opportunity_Offering__c>();
        List<OpportunityOfferingWrapper> drLinesWrapperList = new List<OpportunityOfferingWrapper>();
        drLinesList = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                       from Opportunity_Offering__c where Opportunity_Name__c = :recordId ];
        for(Opportunity_Offering__c drRec : drLinesList){
            drLinesWrapperList.add(new OpportunityOfferingWrapper(drRec));
        }
        return drLinesWrapperList;
    }
    
    @AuraEnabled
    public static OppOfferWrapper getOppDetails(Id recordId){
        Opportunity opp = [select id,name,stagename from opportunity where id = :recordId];
        User userRecord = [select id,Name from User where id = :UserInfo.getUserId()];
        return new OppOfferWrapper(userRecord.Id, userRecord.Name, opp.Id, opp.Name, opp.stagename);
    }
    
    @AuraEnabled
    public static Map<String,String> saveDRList(String oppId, String dealType, List<OpportunityOfferingWrapper> drLinesList){
        system.debug(dealType + '  dealType');
        Set<Id> oppIds = new Set<Id>();
        Savepoint sp = Database.setSavepoint();
        statusMessage.put('status','Success');
        statusMessage.put('message','Records saved successfully');
        statusMessage.put('url',URL.getOrgDomainUrl().toExternalForm());
        List<Opportunity_Offering__c> oppOfferingToUpdate = new List<Opportunity_Offering__c>();
        List<Opportunity_Offering__c> oppOfferingToInsert = new List<Opportunity_Offering__c>();
        Map<Id,String> idVsDealType = new Map<Id,String>();
        for(OpportunityOfferingWrapper drLine : drLinesList){
            idVsDealType.put(drLine.VirtusaOffering,drLine.VirtusaOfferingDealType);
        }
        List<Virtusa_Offering__c> virtusaLis = [select id,Offering_Deal_Type__c from Virtusa_Offering__c where id IN :idVsDealType.keySet()];
        for(Virtusa_Offering__c offer : virtusaLis){
            idVsDealType.put(offer.id,offer.Offering_Deal_Type__c);
        }
        Decimal consultingSum = 0;
        Decimal nonConsultingSum = 0;
        for(OpportunityOfferingWrapper drLine : drLinesList){
            String virtusaOffDealType = drLine.VirtusaOfferingDealType != null && drLine.VirtusaOfferingDealType != '' ? drLine.VirtusaOfferingDealType :
            idVsDealType.get(drLine.VirtusaOffering);
            if(virtusaOffDealType == 'Consulting'){
                consultingSum = consultingSum + Decimal.valueOf(drLine.OfferingSplit);
            }
            if(virtusaOffDealType == 'Non Consulting'){
                nonConsultingSum = nonConsultingSum + Decimal.valueOf(drLine.OfferingSplit);
            }
        }
        if(dealType == 'Consulting'){
            if(consultingSum != 100 || nonConsultingSum > 50){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For Consulting Deals it is mandatory to select one or more consulting offering with split% totaling to 100% and optional to have non consulting Offerings with up to 50% split');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        if(dealType == 'Non Consulting'){
            if(nonConsultingSum < 5 || nonConsultingSum > 100 || consultingSum > 50){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For Non-Consulting Deals Offering Sum of Split% can vary between 5% to max 100% and optionally Consulting Offerings Split % sum can be up to 50%');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        system.debug(nonConsultingSum + '  nonConsultingSum');
        system.debug(consultingSum + '  consultingSum');
        if(dealType == 'No Offerings Required'){
            system.debug('inside if block  no offering....');
            if(nonConsultingSum != 0 || consultingSum != 0){
                statusMessage.put('status','Fail');
                statusMessage.put('message','For "No Offerings Required" Deals tagging No Offerings is only allowed');
                if(!Test.isRunningTest()) return statusMessage;
            }
        }
        
        try{
            Boolean isNoOfferingExist = false;
            String virId = '';
            if(dealType == 'No Offerings Required'){
                List<Opportunity_Offering__c> drLinesListNoOff = new List<Opportunity_Offering__c>();
                drLinesListNoOff = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                                    from Opportunity_Offering__c where Opportunity_Name__c = :oppId and Virtu_Offering_Split_p__c = 0];
                if(drLinesListNoOff.size() != 0 ) isNoOfferingExist = true;
                List<Virtusa_Offering__c> vir = [select id,name from Virtusa_Offering__c where name = 'No Offerings'];
                virId = vir[0].Id;
            }
            for(OpportunityOfferingWrapper drLine : drLinesList){
                oppIds.add(drLine.opportunityId);
                Opportunity_Offering__c drlineRec = new Opportunity_Offering__c();
                drlineRec.Virtusa_Offering__c = drLine.VirtusaOffering;
                if(drLine.OfferingSplit != null && drLine.OfferingSplit != '' ) drlineRec.Virtu_Offering_Split_p__c = Decimal.valueOf(drLine.OfferingSplit);
                drlineRec.Opportunity_Name__c = drLine.opportunityId;
                drlineRec.Deal_Led_By__c = dealType;
                if(virId == drLine.VirtusaOffering) isNoOfferingExist = true;
                //drLineRecordToInsert.add(drlineRec);
                if(drLine.Id != null && drLine.Id != ''){
                    drlineRec.Id = drLine.Id;
                    oppOfferingToUpdate.add(drlineRec);//if(Decimal.valueOf(drLine.OfferingSplit) != 0)  removed logic as not able to update offering to zero
                }
                else{
                    oppOfferingToInsert.add(drlineRec);
                }
            }
            if(dealType == 'No Offerings Required' && !isNoOfferingExist){
                List<Opportunity_Offering__c> drLinesListNoOff = new List<Opportunity_Offering__c>();
                drLinesListNoOff = [select Id,Virtusa_Offering__c,Deal_Led_By__c,Virtusa_Offering__r.Name,Virtusa_Offering__r.Offering_Deal_Type__c,Virtu_Offering_Split_p__c,Opportunity_Name__c,OwnerId,Owner.Name,Opportunity_Name__r.name
                               from Opportunity_Offering__c where Opportunity_Name__c = :oppId and Virtu_Offering_Split_p__c != 0];
                Opportunity_Offering__c drlineRec = new Opportunity_Offering__c();
                
                drlineRec.Virtusa_Offering__c = virId;
                drlineRec.Virtu_Offering_Split_p__c = 0;
                drlineRec.Opportunity_Name__c = oppId;
                drlineRec.Deal_Led_By__c = dealType;
                if(drLinesListNoOff.size() == 0 ) oppOfferingToInsert.add(drlineRec);
                
            }
            Set<Id> newOfferingIds = new Set<Id>();
            if(oppOfferingToInsert.size() > 0){
                insert oppOfferingToInsert;
                for(Opportunity_Offering__c offers : oppOfferingToInsert){
                    newOfferingIds.add(offers.Id);
                }
            }
            if(oppOfferingToUpdate.size() > 0){
                update oppOfferingToUpdate;
            }
            if(oppIds.size() > 0 && (oppOfferingToUpdate.size() > 0 || oppOfferingToInsert.size() > 0)){
                initiateEmailNotification(oppIds,newOfferingIds);
            }
            
        }
        catch(Exception ex){
            statusMessage.put('status','Fail');
            String errorMsg = ex.getMessage();//Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, You cannot add or edit the offerings of this opportunity: []
            if(errorMsg.contains('FIELD_CUSTOM_VALIDATION_EXCEPTION')) errorMsg = errorMsg.substringAfter('FIELD_CUSTOM_VALIDATION_EXCEPTION,');
            if(errorMsg.contains(': []')) errorMsg = errorMsg.substringBefore(': []').trim();
            statusMessage.put('message',errorMsg);
            Database.rollback(sp);
        }
        return statusMessage;
    }
    @Future
    public static void initiateEmailNotification(Set<Id> oppIds,Set<Id> newOfferings){
        Map<Id,List<Opportunity_Offering__c>> oppIdVsOfferingList = new Map<Id,List<Opportunity_Offering__c>>();
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name,
                                                                   Group_SBU__c,
                                                                   Account.Customer_Name__r.Client__r.Name,
                                                                   Account.Customer_Name__r.name,
                                                                   Account.name,
                                                                   Opportunity_ID__c,
                                                                   Deal_Type__c,
                                                                   StageName,
                                                                   Amount,
                                                                   CurrencyIsoCode,
                                                                   Opportunity_Amount_Converted_New__c,
                                                                   Opportunity_CS_Owner__r.Name,
                                                                   Owner.name,
                                                                   OwnerId,
                                                                   Owner.Email,
                                                                   Account.owner.name,
                                                                   Account.CSM__r.Name
                                                                   from Opportunity where id In :oppIds]);
        Map<Id,Opportunity_Offering__c> idVsRelOfferingRecord = new Map<Id,Opportunity_Offering__c>([select id,Name,
                                                                                                  Opportunity_Name__c,Virtusa_Offering__c,
                                                                                                     Virtusa_Offering__r.Offering_Squad__c,
                                                                                                     Virtu_Offering_Split_p__c,
                                                                                                     Old_Offering_Split__c,
                                                                                                     Deal_Led_By__c,
                                                                                                     Owner.name,
                                                                                                     Virtusa_Offering__r.Name
                                                                                                  from Opportunity_Offering__c 
                                                                                                  where Opportunity_Name__c IN :oppIds]);
        Set<String> squadTeam = new Set<String>();
        Map<Id,String> virtusaIdVsSquad = new Map<Id,String>();
        for(Opportunity_Offering__c offer : idVsRelOfferingRecord.values()){
            if(offer.Virtusa_Offering__c != null && offer.Virtusa_Offering__r.Offering_Squad__c != null){
                if(offer.Virtu_Offering_Split_p__c != 0 || (offer.Virtu_Offering_Split_p__c == 0 && offer.Virtu_Offering_Split_p__c != offer.Old_Offering_Split__c))
                   squadTeam.add(offer.Virtusa_Offering__r.Offering_Squad__c);
                virtusaIdVsSquad.put(offer.Virtusa_Offering__c,offer.Virtusa_Offering__r.Offering_Squad__c);
            }
            if(oppIdVsOfferingList.containsKey(offer.Opportunity_Name__c)){
                oppIdVsOfferingList.get(offer.Opportunity_Name__c).add(offer);
            }else{
                oppIdVsOfferingList.put(offer.Opportunity_Name__c,new List<Opportunity_Offering__c>{offer});
            }
        }
        Map<String,String> emailVsName = new Map<String,String>();
        String slist = '';
        for (String s: squadTeam) {
            slist += '\'' + s + '\',';
        }
        system.debug(',slist' + slist);
        slist = slist.removeEnd(',');
        String value = '(\'' + String.join(squadTeam, '\',\'') + '\')';
        String queryString = 'select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c'+
                                                           ' from contact' + 
                                                           ' where email != null and ' + 
                                                           ' Offering_squad_Leader__c = true and ' +
                                                           ' Off_Squad_Team_del__c includes' + value;
        List<Contact> contactList = DataBase.query(queryString);
        system.debug('List of records: '+contactList);
        /*Map<Id,Contact> contactList = new Map<Id,Contact>([select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c
                                                           from contact 
                                                           where email != null and 
                                                           Offering_squad_Leader__c = true and 
                                                           Off_Squad_Team_del__c includes (:slist)]);*/
        system.debug(',contactList' + contactList);
        Map<Id,List<String>> virOffIdVsEmail = new Map<Id,List<String>>();
        Map<String,Set<Id>> emailVsVirtusaId = new Map<String,Set<Id>>();
        for(Id virId : virtusaIdVsSquad.keySet()){
            for(Contact con : contactList){
                emailVsName.put(con.email,con.name);
                if(virtusaIdVsSquad.get(virId) != null && con.Off_Squad_Team_del__c.contains(virtusaIdVsSquad.get(virId))){
                    if(!virOffIdVsEmail.containskey(virId))virOffIdVsEmail.put(virId,new List<String>{con.email});
                    else{
                        virOffIdVsEmail.get(virId).add(con.email);
                    }
                }
            }
        }
        for(Id oppId : oppIdVsOfferingList.keySet()){
            Set<String> to = new Set<String>();
            Opportunity opp = offeringOpp.get(oppId);
            if(opp.owner.email != null){
                to.add(opp.owner.email);
                emailVsName.put(opp.owner.email,opp.owner.name);
            }
            for(Opportunity_Offering__c oppOffer : oppIdVsOfferingList.get(oppId)){
                Id relatedOffId = oppOffer.Id;
                if(virOffIdVsEmail != null && idVsRelOfferingRecord != null && idVsRelOfferingRecord.get(relatedOffId) != null 
                   && virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c) != null)
                    to.addAll(virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c));
                if(virOffIdVsEmail != null && virOffIdVsEmail.get(oppOffer.Virtusa_Offering__c) != null){
                    to.addAll(virOffIdVsEmail.get(oppOffer.Virtusa_Offering__c));
                }
            }
            

            String subject = 'Virtusa Offering Notification';
            String body = '';
            body = 'Hi All,<br/><br/> Following offerings have tagged to the opportunity.<br/><br/>';
            String dealLeadBy = oppIdVsOfferingList.get(oppId).size() > 1 ? 
                oppIdVsOfferingList.get(oppId)[1].Deal_Led_By__c : oppIdVsOfferingList.get(oppId)[0].Deal_Led_By__c;
            body = body + 
                '<b><u>Opportunity Details</b></u><br/><br/>'+
                '<li>Deal Lead By - '+dealLeadBy + '</li>'+
                '<li>Group SBU - '+offeringOpp.get(oppId).Group_SBU__c+'</li>'+
                '<li>Account - '+offeringOpp.get(oppId).Account.name+'</li>'+
                '<li>Opportunity ID - <a href="'+ URL.getOrgDomainUrl().toExternalForm() +'/'+oppId+'">'+offeringOpp.get(oppId).Opportunity_ID__c+'</a></li>'+
                '<li>Opportunity Name - '+offeringOpp.get(oppId).name + '</li>'+
                '<li>Stage - '+offeringOpp.get(oppId).StageName+'</li>'+
                '<li>Amount (converted) - '+'USD'+' '+offeringOpp.get(oppId).Opportunity_Amount_Converted_New__c+'</li>'+
                '<li>Opportunity Owner - '+offeringOpp.get(oppId).Owner.name + '</li>'+
                '<br/><br/>';
            
            body = body + '<b><u>Offering Details</b></u><br/><br/>';
            String tableHtml = '<table style="border-collapse: collapse;">';
            tableHtml += '<thead>';
            tableHtml += '<tr>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">SR. No</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Virtusa Offering Name</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Old Split%</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">New Split%</th>';
            tableHtml += '<th style="font-weight: bold;  border: 1px solid black; padding: 8px;">Is Modified</th>';
            tableHtml += '</tr>';
            tableHtml += '</thead>';
            tableHtml += '<tbody>';
            Integer count = 1;
            List<Opportunity_Offering__c> offerList = oppIdVsOfferingList.get(oppId);
            for(Opportunity_Offering__c oppOffer : offerList){
                if(offerList.size() == 1 || 
                   (offerList.size() > 1 && oppOffer.Virtusa_Offering__r.Name != 'No Offerings')){
                    tableHtml += '<tr>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + count + '</td>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Virtusa_Offering__r.Name + '</td>';
                    String oldSplit = oppOffer.Old_Offering_Split__c == null ? '-' : oppOffer.Old_Offering_Split__c.setScale(2) + '';
                    if(newOfferings.contains(oppOffer.Id)) oldSplit = '-';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oldSplit + '</td>';
                    //else tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Old_Offering_Split__c + '</td>';
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + oppOffer.Virtu_Offering_Split_p__c + '</td>';
                    Boolean isNotChange = oppOffer.Old_Offering_Split__c == null || oppOffer.Virtu_Offering_Split_p__c == oppOffer.Old_Offering_Split__c;
                    String isChanged = !isNotChange == true ? 'Yes' : 'No';
                    
                    tableHtml += '<td style="border: 1px solid black; padding: 8px;">' + isChanged + '</td>';
                    tableHtml += '</tr>';
                    count++;
                }
            }
            tableHtml += '</tbody>';
            tableHtml += '</table>';
            body = body + tableHtml + '<br/><br/>';
            body = body + 'Thanks,<br/> System Administrator';
            String repmail = '';
            SingleEmailUtility seu = new SingleEmailUtility();
            List<String> ccAddress = new List<String>();
            seu.sendMail(new List<String>(to), ccAddress, '', subject, body);
        }
    }
    
    public class OppOfferWrapper{
        @auraEnabled public string currentUserId{get;set;}
        @auraEnabled public string currentName{get;set;}
        @auraEnabled public string OpportunityName{get;set;}
        @auraEnabled public string OpportunityId{get;set;}
        @auraEnabled public string opportunityStageName{get;set;} 
        public OppOfferWrapper(String userId, String userName, String oppId, String oppName, String oppStage){
            this.currentUserId = userId;
            this.currentName = userName;
            this.OpportunityName = oppName;
            this.OpportunityId = oppId;
            this.opportunityStageName = oppStage;
        }
    }
}



-------------------------
OpportunityOfferingTriggerHelper.cls
public without sharing class OpportunityOfferingTriggerHelper {
    @future
    public static void createShareRecordsFutureContext(Set<Id> offeringIds){
        if(offeringIds != null)createShareRecords(offeringIds);
    }
    
    public static void createShareRecords(Set<Id> offeringIds){
        Map<Id,Id> oppOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Id> virOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Set<Id>> oppIdVsOfferingIdSet = new Map<Id,Set<Id>>();
        
        List<Opportunity_Offering__c> opOfferingList = new List<Opportunity_Offering__c>();
        opOfferingList = [select id,Opportunity_Name__c,Virtusa_Offering__c from
                          Opportunity_Offering__c where id IN :offeringIds];
        for(Opportunity_Offering__c opOffering : opOfferingList){
            oppOfferIdVsOppId.put(opOffering.Id,opOffering.Opportunity_Name__c);
            virOfferIdVsOppId.put(opOffering.Id,opOffering.Virtusa_Offering__c);
            if(!oppIdVsOfferingIdSet.containsKey(opOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(opOffering.Opportunity_Name__c,new Set<Id>{opOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c).add(opOffering.Id);
            }
        }
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name
                                                                   from Opportunity where id In :oppOfferIdVsOppId.values() ]);
        Map<Id,Opportunity_Offering__c> idVsRelOfferingRecord = new Map<Id,Opportunity_Offering__c>([select id,
                                                                                                     Opportunity_Name__c,Virtusa_Offering__c
                                                                                                     from Opportunity_Offering__c 
                                                                                                     where Opportunity_Name__c IN :offeringOpp.keySet()
                                                                                                     and ID Not In :oppOfferIdVsOppId.keySet()]);
        for(Opportunity_Offering__c opOffering : idVsRelOfferingRecord.values()){
            oppOfferIdVsOppId.put(opOffering.Id,opOffering.Opportunity_Name__c);
            virOfferIdVsOppId.put(opOffering.Id,opOffering.Virtusa_Offering__c);
            if(!oppIdVsOfferingIdSet.containsKey(opOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(opOffering.Opportunity_Name__c,new Set<Id>{opOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c).add(opOffering.Id);
            }
        }
        Map<Id,Virtusa_Offering__c> vOfferingList = new Map<Id,Virtusa_Offering__c>([Select id,
                                                                                     Offering_Squad__c,
                                                                                     Virtu_Squad_Email_Address__c
                                                                                     from Virtusa_Offering__c
                                                                                     where    id In :virOfferIdVsOppId.values() ]);
        Set<String> squadTeam = new Set<String>();        
        for(Virtusa_Offering__c vr : vOfferingList.values()){
            if(vr.Offering_Squad__c != null) squadTeam.add(vr.Offering_Squad__c);
        }
        Map<Id,List<String>> virOffIdVsEmail = new Map<Id,List<String>>();
        Map<String,Set<Id>> emailVsVirtusaId = new Map<String,Set<Id>>();
        String slist = '';
        for (String s: squadTeam) {
            slist += '\'' + s + '\',';
        }
            String value = '(\'' + String.join(squadTeam, '\',\'') + '\')';
            String queryString = 'select id,email,name,Offering_squad_Leader__c,Off_Squad_Team_del__c'+
                                                               ' from contact' + 
                                                               ' where email != null and ' + 
                                                               ' Offering_squad_Leader__c = true and ' +
                                                               ' Off_Squad_Team_del__c includes' + value;
            List<Contact> contactList = DataBase.query(queryString);
        
        for(Virtusa_Offering__c vr : vOfferingList.values()){
            if(vr.Offering_Squad__c != null){
                for(Contact con : contactList){
                    if(con.Off_Squad_Team_del__c.contains(vr.Offering_Squad__c)){
                        //emailVsName.put(con.email,con.name);
                        if(!emailVsVirtusaId.containskey(con.email)){
                            emailVsVirtusaId.put(con.email,new Set<Id>{vr.Id});
                        }
                        else{
                            emailVsVirtusaId.get(con.email).add(vr.Id);
                        }
                        if(!virOffIdVsEmail.containskey(vr.Id)){
                            
                            virOffIdVsEmail.put(vr.Id,new List<String>{con.email});
                        }
                        else{
                            virOffIdVsEmail.get(vr.Id).add(con.email);
                        }
                    }
                }
            }
        }
        Set<String> toAddresses = new Set<String>();
        for(Opportunity_Offering__c opOffering : opOfferingList){
            Set<String> to = new Set<String>();
            if(offeringOpp.get(opOffering.Opportunity_Name__c) != null){
                Set<Id> relatedOfferingIds = oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c);
                if(relatedOfferingIds != null && relatedOfferingIds.size() > 0){
                    for(Id relatedOffId : relatedOfferingIds){
                        if(virOffIdVsEmail != null && idVsRelOfferingRecord != null && idVsRelOfferingRecord.get(relatedOffId) != null
                           && idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c != null )
                            to.addAll(virOffIdVsEmail.get(idVsRelOfferingRecord.get(relatedOffId).Virtusa_Offering__c));
                        
                    }
                }
            }
            if(virOffIdVsEmail != null && virOffIdVsEmail.get(opOffering.Virtusa_Offering__c) != null){
                to.addAll(virOffIdVsEmail.get(opOffering.Virtusa_Offering__c));
            }
            if(to.size() > 0) toAddresses.addAll(to);
        }
        List<User> userRecords = [select id,email from User where email IN :toAddresses];
        Map<String,Opportunity_Offering__share> oppOffList = new Map<String,Opportunity_Offering__share>();
        for(User userRec : userRecords){
            if(emailVsVirtusaId != null && emailVsVirtusaId.get(userRec.email) != null){
                Set<Id> virtusaIds = emailVsVirtusaId.get(userRec.email);
                for(Id oppOfferId : virOfferIdVsOppId.keySet()){
                    Set<Id> offerIds = oppIdVsOfferingIdSet.get(oppOfferIdVsOppId.get(oppOfferId));
                    if(virtusaIds.contains(virOfferIdVsOppId.get(oppOfferId))){
                        for(Id offerId : offerIds){
                            Opportunity_Offering__share oppOfferShare = new Opportunity_Offering__share();
                            oppOfferShare.ParentId = offerId;
                            oppOfferShare.UserOrGroupId = userRec.Id;
                            oppOfferShare.AccessLevel = 'edit';
                            oppOfferShare.RowCause = 'Manual';
                            if(offerId != null && userRec != null)
                                oppOffList.put(offerId+'-'+userRec.Id,oppOfferShare);
                        }
                    }
                }
            }
        }
        if(oppOffList.size() > 0) Database.upsert(oppOffList.values(),false);
        
    }
    
    //Author    - Viji
    //Arguments - opOfferingList -> list of opportunity offering record
    //Purpose   - called from after update,after insert
    //Date      - 21/03/2023
    @future
    public static void updateOffOwnerAccessToOppOwnerHelper(Set<Id> offeringIds){
        createShareRecordsForOppOwner(offeringIds);
    }
    
    public static void createShareRecordsForOppOwner(Set<Id> offeringIds){
        Map<Id,Id> oppOfferIdVsOppId = new Map<Id,Id>();
        Map<Id,Set<Id>> oppIdVsOfferingIdSet = new Map<Id,Set<Id>>();
        Map<Id,Id> offOwner = new Map<Id,Id>();
        List<Opportunity_Offering__c> opOfferingList = new List<Opportunity_Offering__c>();
        opOfferingList = [select id,Opportunity_Name__c,Virtusa_Offering__c,OwnerId from
                          Opportunity_Offering__c where id IN :offeringIds];
        
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppOfferIdVsOppId.put(oppOffering.id,oppOffering.Opportunity_Name__c);
            if(!oppIdVsOfferingIdSet.containsKey(oppOffering.Opportunity_Name__c)){
                oppIdVsOfferingIdSet.put(oppOffering.Opportunity_Name__c,new Set<Id>{oppOffering.Id});
            }else{
                oppIdVsOfferingIdSet.get(oppOffering.Opportunity_Name__c).add(oppOffering.Id);
            }
        }
        Map<Id,Opportunity> offeringOpp = new Map<Id,Opportunity>([Select id,
                                                                   name,stagename,ownerid
                                                                   from Opportunity where id In :oppOfferIdVsOppId.values() ]);
        for(Opportunity_Offering__c opOffering : opOfferingList){
            Opportunity oppRec = offeringOpp.get(opOffering.Opportunity_Name__c);
            Id offeringOwner = opOffering.ownerId;
            if(oppRec != null){
                Set<Id> relatedOfferingIds = oppIdVsOfferingIdSet.get(opOffering.Opportunity_Name__c);
                if(relatedOfferingIds != null && relatedOfferingIds.size() > 0){
                    for(Id relatedOffId : relatedOfferingIds){
                        if(oppRec.OwnerId != null && offeringOwner != null && oppRec.OwnerId != offeringOwner){
                            offOwner.put(oppRec.Id, oppRec.OwnerId);
                        }
                    }
                }
            }
        }
        
        List<User> ownerUserRecords = [select id from User where Id =: offOwner.values()];
        Map<String,Opportunity_Offering__share> oppOffList = new Map<String,Opportunity_Offering__share>();
        List<Opportunity_Offering__c> oppOwnerOffList= [select id,Opportunity_Name__c,ownerId from
                                                        Opportunity_Offering__c where ownerId NOT IN :ownerUserRecords 
                                                        AND Opportunity_Name__c =: offOwner.keySet()];    
        for(User userRec : ownerUserRecords){
            if(userRec!=null){
                for(Opportunity_Offering__c offering : oppOwnerOffList){
                    Opportunity_Offering__share oppOfferShare = new Opportunity_Offering__share();
                    oppOfferShare.ParentId = offering.Id;
                    oppOfferShare.UserOrGroupId = userRec.Id;
                    oppOfferShare.AccessLevel = 'edit';
                    oppOfferShare.RowCause = 'Manual';
                    if(offering!=null && userRec != null){
                        oppOffList.put(offering.Id+'-'+userRec.Id,oppOfferShare);
                    }
                }
                if(oppOffList.size() > 0) upsert oppOffList.values();         
                
            }
        }    
    }        
    
    public static void deleteNoOffering(List<Opportunity_Offering__c> opOfferingList,Boolean isUpdate){
        Set<Id> oppIds = new Set<Id>();
        Set<Id> curroppIds = new Set<Id>();
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppIds.add(oppOffering.Opportunity_Name__c);
            if(!isUpdate) curroppIds.add(oppOffering.Id);
        }
		deletNoOfferingFuture(oppIds,curroppIds);
    }
    @future
    public static void deletNoOfferingFuture(Set<Id> oppIds,Set<Id> curroppIds){
        List<Opportunity_Offering__c> oppList = [SELECT Id, OwnerId, Name, Opportunity_Name__c, Opportunity_Id__c, Virtusa_Offering__c,Virtusa_Offering__r.name 
                                                 FROM Opportunity_Offering__c where Opportunity_Name__c IN :oppIds AND Virtusa_Offering__r.name = 'No Offerings' AND id NOT IN :curroppIds];
        if(oppList != null && oppList.size() > 0){
            delete oppList;
        }
    }
    public static void stampOldPec(Map<Id, Opportunity_Offering__c > mapOldRecord,Map<Id, Opportunity_Offering__c > mapNewRecord){
        for(Opportunity_Offering__c opOffering : mapNewRecord.values()){
            if(mapOldRecord.get(opOffering.Id).Virtu_Offering_Split_p__c != null){
                   opOffering.Old_Offering_Split__c = mapOldRecord.get(opOffering.Id).Virtu_Offering_Split_p__c;
               }
        }
    }
    
    public static void validateNoOffering(List<Opportunity_Offering__c> opOfferingList){
        Set<Id> oppIds = new Set<Id>();
        Set<Id> virIds = new Set<Id>();
        Map<Id,Boolean> oppIdToRes = new Map<Id,Boolean>();
        //Boolean noOffering;
        for(Opportunity_Offering__c oppOffering : opOfferingList){
            oppIds.add(oppOffering.Opportunity_Name__c);
            virIds.add(oppOffering.Virtusa_Offering__c);
        }
        Map<Id,Virtusa_Offering__c> vOfferingList = new Map<Id,Virtusa_Offering__c>([Select id,Name,
                                                                                     Offering_Squad__c,
                                                                                     Virtu_Squad_Email_Address__c
                                                                                     from Virtusa_Offering__c
                                                                                     where    id In :virIds]);
        List<Opportunity_Offering__c> oppList = [SELECT Id, OwnerId, Name, Opportunity_Name__c, Opportunity_Id__c, Virtusa_Offering__c,Virtusa_Offering__r.name, Virtu_Offering_Split_p__c 
                                                 FROM Opportunity_Offering__c where Opportunity_Name__c IN :oppIds];
        oppList.addAll(opOfferingList);
        for(Opportunity_Offering__c opp : oppList){
            if(oppList.size()>0){
                oppIdToRes.put(opp.Opportunity_Name__c,false);
                if(opp.Virtu_Offering_Split_p__c == 0){
                    //noOffering = true;
                }else{
                    //noOffering = false;
                    oppIdToRes.put(opp.Opportunity_Name__c,true);
                }
            }
        }
        for(Opportunity_Offering__c opp : opOfferingList){
            if(oppList.size()>0){
            //if(vOfferingList.get(opp.Virtusa_Offering__c).name == 'No Offerings' && !noOffering && oppIdToRes.contains(opp.Opportunity_Name__c)){
            if(vOfferingList.get(opp.Virtusa_Offering__c).name == 'No Offerings' && oppIdToRes.containsKey(opp.Opportunity_Name__c) && oppIdToRes.get(opp.Opportunity_Name__c)){
                opp.addError('"No Offerings" Cannot Be Tagged If Opportunity has Offerings');
            }
            }
        }
    }
}
Leave a Comment