public ServiceParentUtils(AppointmentBookingData i_ABData)
        {
            m_ABData = i_ABData;
            m_WOandWOLIParentsReqRuleFields      = new Dictionary <string, string>();
            m_WOParentsReqRuleFields             = new Dictionary <string, string>();
            m_WOandWOLIParentsReqObjectiveFields = new Dictionary <string, string>();
            m_WOParentsReqObjectiveFields        = new Dictionary <string, string>();

            string Service_Visiting_Hours      = "VisitingHours__c";
            string Required_Resources_Service  = "(Select Id, ServiceResourceId, PreferenceType, RelatedRecordId From ResourcePreferences)";
            string Match_Skills_Service        = "(Select Skill.MasterLabel,Id, RelatedRecordId,SkillLevel,SkillId From SkillRequirements)";
            string Excluded_Resource_Service   = "(Select Id, ServiceResourceId, PreferenceType, RelatedRecordId From ResourcePreferences)";
            string Objective_Skill_Level       = "(Select Skill.MasterLabel,Id, RelatedRecordId,SkillLevel,SkillId From SkillRequirements)";
            string Objective_PreferredEngineer = "(Select Id, ServiceResourceId, PreferenceType, RelatedRecordId From ResourcePreferences)";

            m_WOandWOLIParentsReqRuleFields.Add("Service_Visiting_Hours", Service_Visiting_Hours);
            m_WOandWOLIParentsReqRuleFields.Add("Match_Skills_Service", Match_Skills_Service);

            m_WOandWOLIParentsReqObjectiveFields.Add("Objective_Skill_Level", Objective_Skill_Level);

            m_WOParentsReqRuleFields.Add("Required_Resources_Service", Required_Resources_Service);
            m_WOParentsReqRuleFields.Add("Excluded_Resource_Service", Excluded_Resource_Service);

            m_WOParentsReqObjectiveFields.Add("Objective_PreferredEngineer", Objective_PreferredEngineer);
        }
        private static sObjectUtils createUtilsByClassName(string i_UtilClassName, AppointmentBookingData i_ABData)
        {
            sObjectUtils objectUtils;

            switch (i_UtilClassName)
            {
            case "MSTServiceUtils":
                objectUtils = new MSTServiceUtils(i_ABData);
                break;

            case "WorkOrder":
            case "WorkOrderLineItem":
            case "Account":
                objectUtils = new ServiceParentUtils(i_ABData);
                break;

            case "UserLicense":
                objectUtils = new LicensedUsersUtils(i_ABData);
                break;

            case "AdditionalObjects":
                objectUtils = new AdditionalObjectsUtils(i_ABData);
                break;

            default:
                objectUtils = null;
                break;
            }

            return(objectUtils);
        }
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            switch (i_AdditionalObjQuery)
            {
            case eAdditionalObjectQuery.ServicesInResourcesTimeDomain:
                deserializeServicesInResourcesTimeDomain(i_ABData, deserializedQuery, async);
                break;

            case eAdditionalObjectQuery.ResourcesAdditionalObjects:
                i_ABData.ABAdditionalObjects.ResBreaksAndShiftsByResId =
                    deserializedQuery.records.ToDictionary(record => record.Id);
                break;

            case eAdditionalObjectQuery.ResourceTerritories:
                deserializedResourceTerritories(i_ABData, deserializedQuery.records);
                break;

            case eAdditionalObjectQuery.Capacities:
                i_ABData.ABAdditionalObjects.Capacities =
                    deserializedQuery.records;
                break;

            case eAdditionalObjectQuery.Calendars:
                i_ABData.ABAdditionalObjects.Calendars =
                    deserializedQuery.records;
                break;

            default:
                break;
            }
        }
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            i_ABData.VisitingHours = deserializedQuery.records;
        }
Esempio n. 5
0
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            //TODO: add support for long responses that has to be pulled with identifier
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            i_ABData.ObjectivesByDevName = parseAdditionalData(deserializedQuery.records);
        }
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            foreach (PermissionSetAssignment record in deserializedQuery.records)
            {
                m_RelatedRecordIds.Remove(record.AssigneeId);
            }

            i_ABData.UnLicensedUsers = m_RelatedRecordIds;
        }
Esempio n. 7
0
        public MSTServiceUtils(AppointmentBookingData i_ABData)
        {
            m_MSTServiceIds = new HashSet <string>();

            foreach (List <Time_Dependency__c> dependenciesByRoot in i_ABData.TimeDependeciesByRootId.Values)
            {
                foreach (Time_Dependency__c dependency in dependenciesByRoot)
                {
                    m_MSTServiceIds.Add(dependency.Service_Appointment_1__c);
                    m_MSTServiceIds.Add(dependency.Service_Appointment_2__c);
                }
            }
        }
        public static sObjectUtils CreateUtilsByType(Type i_ObjectType = null, AppointmentBookingData i_ABData = null, string i_UtilClassName = null)
        {
            sObjectUtils objectUtils;

            if (i_UtilClassName != null)
            {
                return(createUtilsByClassName(i_UtilClassName, i_ABData));
            }

            //TODO: check the value of Name in managed package
            switch (i_ObjectType.Name)
            {
            case "Work_Rule__c":
                objectUtils = new WorkRuleUtils();
                break;

            case "Scheduling_Policy_Goal__c":
                objectUtils = new ObjectiveUtils();
                break;

            case "ServiceAppointment":
                objectUtils = new ServiceAppointmentUtils(i_ABData);
                break;

            case "Time_Dependency__c":
                objectUtils = new TimeDependencyUtils();
                break;

            case "ServiceTerritoryMember":
                objectUtils = new STMUtils(i_ABData);
                break;

            case "OperatingHours":
                objectUtils = new OperatingHoursUtils(i_ABData);
                break;

            case "ServiceResource":
                objectUtils = new ServiceResourceUtils(i_ABData);
                break;

            default:
                objectUtils = null;
                break;
            }

            return(objectUtils);
        }
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            if (m_TimeDependencies == null)
            {
                m_TimeDependencies = new List <Time_Dependency__c>(deserializedQuery.records);
                m_Roots            = new HashSet <string>();
                foreach (Time_Dependency__c dependency in m_TimeDependencies)
                {
                    m_Roots.Add(dependency.Root_Service_Appointment__c);
                }
            }
            else
            {
                if (i_ABData.TimeDependeciesByRootId == null)
                {
                    i_ABData.TimeDependeciesByRootId = new Dictionary <string, List <Time_Dependency__c> >();
                }

                foreach (Time_Dependency__c dependency in deserializedQuery.records)
                {
                    if (!m_TimeDependencies.Contains(dependency))
                    {
                        m_TimeDependencies.Add(dependency);
                    }
                }

                foreach (IGrouping <string, Time_Dependency__c> timeDependencies in m_TimeDependencies.GroupBy(dependency => dependency.Root_Service_Appointment__c))
                {
                    if (!i_ABData.TimeDependeciesByRootId.ContainsKey(timeDependencies.Key))
                    {
                        i_ABData.TimeDependeciesByRootId[timeDependencies.Key] = new List <Time_Dependency__c>();
                    }

                    foreach (Time_Dependency__c dependency in timeDependencies)
                    {
                        i_ABData.TimeDependeciesByRootId[timeDependencies.Key].Add(dependency);
                    }
                }
            }
        }
Esempio n. 10
0
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            //TODO: add support for long responses that has to be pulled with identifier
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            parseAdditionalData(deserializedQuery.records);

            i_ABData.RulesByDevName = new Dictionary <string, List <Work_Rule__c> >();
            foreach (Work_Rule__c workRule in deserializedQuery.records)
            {
                if (!i_ABData.RulesByDevName.ContainsKey(workRule.DeveloperName))
                {
                    i_ABData.RulesByDevName[workRule.DeveloperName] = new List <Work_Rule__c>();
                }

                i_ABData.RulesByDevName[workRule.DeveloperName].Add(workRule);
            }
        }
        private void deserializeServicesInResourcesTimeDomain(AppointmentBookingData i_ABData, DeserializedQueryResult i_DeserializedQuery, bool async)
        {
            if (!async)
            {
                m_ResourceServices.AddRange(i_DeserializedQuery.records);
            }

            if (i_DeserializedQuery.nextRecordsUrl != null)
            {
                i_ABData.ABAdditionalObjects.nextRecordsUrl = i_DeserializedQuery.nextRecordsUrl;
            }
            else
            {
                if (!async)
                {
                    i_ABData.ABAdditionalObjects.ServicesById =
                        m_ResourceServices.ToDictionary(record => record.Id);
                }
            }
        }
Esempio n. 12
0
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            ServiceAppointmentUtils serviceUtils = new ServiceAppointmentUtils(i_ABData);
            Dictionary <string, ServiceAppointment> deserializedServices = serviceUtils.parseAdditionalData(deserializedQuery.records);

            foreach (KeyValuePair <string, List <Time_Dependency__c> > dependencyTreeByRoot in i_ABData.TimeDependeciesByRootId)
            {
                foreach (Time_Dependency__c dependency in dependencyTreeByRoot.Value)
                {
                    if (!i_ABData.ServicesById.ContainsKey(dependency.Service_Appointment_1__c))
                    {
                        i_ABData.ServicesById[dependency.Service_Appointment_1__c] = deserializedServices[dependency.Service_Appointment_1__c];
                    }

                    dependency.Service_Appointment_1__r = deserializedServices[dependency.Service_Appointment_1__c];

                    if (!i_ABData.ServicesById.ContainsKey(dependency.Service_Appointment_2__c))
                    {
                        i_ABData.ServicesById[dependency.Service_Appointment_2__c] = deserializedServices[dependency.Service_Appointment_2__c];
                    }

                    dependency.Service_Appointment_2__r = deserializedServices[dependency.Service_Appointment_2__c];

                    if (dependency.Service_Appointment_1__c == dependency.Root_Service_Appointment__c)
                    {
                        dependency.Root_Service_Appointment__r = deserializedServices[dependency.Service_Appointment_1__c];
                    }

                    if (dependency.Service_Appointment_2__c == dependency.Root_Service_Appointment__c)
                    {
                        dependency.Root_Service_Appointment__r = deserializedServices[dependency.Service_Appointment_2__c];
                    }
                }
            }
        }
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            //TODO: implement this generic for WOLI and Account parents also
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            foreach (ServiceParent parent in deserializedQuery.records)
            {
                if (parent.SkillRequirements == null)
                {
                    parent.SkillRequirements = new List <SkillRequirement>();
                }

                foreach (SkillRequirement skillReq in parent.skillRequirementsCollection.records)
                {
                    parent.SkillRequirements.Add(skillReq);
                }
            }

            i_ABData.ServiceParent = deserializedQuery.records.ToDictionary(parent => parent.Id);
        }
Esempio n. 14
0
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            foreach (ServiceTerritoryMember stm in deserializedQuery.records)
            {
                if (stm.m_JSONAdditionalData.TryGetValue("ServiceResource", out var resourceToken))
                {
                    stm.ServiceResource = resourceToken.ToObject <ServiceResource>();
                }
            }

            if (m_TerritoryMembers == null)
            {
                m_TerritoryMembers = new List <ServiceTerritoryMember>();
            }

            m_TerritoryMembers.AddRange(deserializedQuery.records);
            i_ABData.TerritoryMembers = m_TerritoryMembers;
            i_ABData.STMResourcesIDs  = m_ABData.STMResourcesIDs;
        }
        private void deserializedResourceTerritories(AppointmentBookingData i_ABData, List <sObject> i_DeserializedRecords)
        {
            m_CalendarIDs = new HashSet <string>();
            foreach (sObject stm in i_DeserializedRecords)
            {
                ServiceTerritory territory;
                string           terrOpHours = "";
                string           stmOpHours  = "";
                if (stm.m_JSONAdditionalData.TryGetValue("OperatingHoursId", out var opHoursToken))
                {
                    stmOpHours = opHoursToken.ToObject <string>();
                }

                if (stm.m_JSONAdditionalData.TryGetValue("ServiceTerritory", out var resourceToken))
                {
                    territory   = resourceToken.ToObject <ServiceTerritory>();
                    terrOpHours = territory.OperatingHoursId;
                }

                m_CalendarIDs.Add(!string.IsNullOrEmpty(stmOpHours) ? stmOpHours : terrOpHours);
            }

            i_ABData.ABAdditionalObjects.ResourceTerritories = i_DeserializedRecords;
        }
Esempio n. 16
0
 //TODO: add try catch around every implementation of this method
 public abstract void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                  AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false);
 public AdditionalObjectsUtils(AppointmentBookingData i_ABData)
 {
     m_ABData    = i_ABData;
     m_Resources = formatIdList(m_ABData.CandidatesById.Keys.ToList());
 }
Esempio n. 18
0
 public STMUtils(AppointmentBookingData i_ABData)
 {
     m_ABData      = i_ABData;
     m_DateTimeNow = DateTime.Now;
 }
 public LicensedUsersUtils(AppointmentBookingData i_ABData)
 {
     m_ABData = i_ABData;
 }
        public ServiceResourceUtils(AppointmentBookingData i_ABData)
        {
            m_ABData             = i_ABData;
            m_ReqObjectiveFields = new Dictionary <string, List <string> >();
            m_ReqRuleFields      = new Dictionary <string, List <string> >();

            HashSet <string> Objective_Resource_Priority = new HashSet <string>();

            if (m_ABData.ObjectivesByDevName.TryGetValue("Objective_Resource_Priority", out var resPriorityObjs))
            {
                foreach (Service_Goal__c obj in resPriorityObjs)
                {
                    if (!string.IsNullOrEmpty(obj.Resource_Priority_Field__c))
                    {
                        Objective_Resource_Priority.Add(obj.Resource_Priority_Field__c);
                    }
                }
            }

            List <string> Skill_Level = new List <string>()
            {
                "(Select Id,SkillId,ServiceResourceId,SkillLevel,EffectiveStartDate,EffectiveEndDate " +
                "From ServiceResourceSkills Where (EffectiveStartDate <= {0}) AND " +
                "(EffectiveEndDate = null OR EffectiveEndDate >= {1}) AND SkillId in ({2}) " +
                "ORDER BY EffectiveStartDate ASC NULLS FIRST)"
            };

            m_ReqObjectiveFields.Add("Objective_Resource_Priority", Objective_Resource_Priority.ToList());
            m_ReqObjectiveFields.Add("Objective_Skill_Level", Skill_Level);

            HashSet <string> Count_Rule = new HashSet <string>();

            if (m_ABData.RulesByDevName.TryGetValue("Count_Rule", out var countRules))
            {
                foreach (Work_Rule__c rule in countRules)
                {
                    if (!string.IsNullOrEmpty(rule.Resource_Property__c))
                    {
                        Count_Rule.Add(rule.Resource_Property__c);
                    }
                }
            }

            HashSet <string> Match_Fields_Service = new HashSet <string>();

            if (m_ABData.RulesByDevName.TryGetValue("Match_Fields_Service", out var matchFieldsRules))
            {
                foreach (Work_Rule__c rule in matchFieldsRules)
                {
                    if (!string.IsNullOrEmpty(rule.Resource_Property__c))
                    {
                        Match_Fields_Service.Add(rule.Resource_Property__c);
                    }
                }
            }

            HashSet <string> Match_Boolean_Service = new HashSet <string>();

            if (m_ABData.RulesByDevName.TryGetValue("Match_Boolean_Service", out var matchBooleanRules))
            {
                foreach (Work_Rule__c rule in matchBooleanRules)
                {
                    if (!string.IsNullOrEmpty(rule.Resource_Property__c))
                    {
                        Match_Boolean_Service.Add(rule.Resource_Property__c);
                    }
                }
            }

            m_ReqRuleFields.Add("Match_Boolean_Service", Match_Boolean_Service.ToList());
            m_ReqRuleFields.Add("Match_Fields_Service", Match_Fields_Service.ToList());
            m_ReqRuleFields.Add("Count_Rule", Count_Rule.ToList());
            m_ReqRuleFields.Add("Match_Crew_Size_Service", new List <string>()
            {
                "ServiceCrew.CrewSize"
            });
            m_ReqRuleFields.Add("Match_Skills_Service", Skill_Level);
            //TODO: add fields for Enhanced match
        }
        private void initializeRequiredFieldsFromRules(AppointmentBookingData i_ABData)
        {
            List <string> relevanceGroupFields = new List <string>();

            foreach (KeyValuePair <string, List <Work_Rule__c> > ruleByDev in i_ABData.RulesByDevName)
            {
                //Time rule required fields
                if (ruleByDev.Key.Equals("Time_Rule_Service"))
                {
                    List <string> timeRuleRequiredFields = new List <string>();
                    foreach (Work_Rule__c rule in ruleByDev.Value)
                    {
                        timeRuleRequiredFields.AddRange(new List <string>()
                        {
                            rule.Service_Schedule_Time_Property__c, rule.Service_Time_Property__c
                        });

                        if (rule.Object_Group_Field__c != null)
                        {
                            relevanceGroupFields.Add(rule.Object_Group_Field__c);
                        }
                    }

                    if (!m_ServiceReqFieldsByRules.ContainsKey("Time_Rule_Service"))
                    {
                        m_ServiceReqFieldsByRules.Add("Time_Rule_Service", timeRuleRequiredFields);
                    }
                }

                //Match rule required fields
                else if (ruleByDev.Key.Equals("Match_Fields_Service"))
                {
                    List <string> matchFieldsRequiredFields = new List <string>();
                    foreach (Work_Rule__c rule in ruleByDev.Value)
                    {
                        matchFieldsRequiredFields.Add(rule.Service_Property__c);
                        if (rule.Object_Group_Field__c != null)
                        {
                            relevanceGroupFields.Add(rule.Object_Group_Field__c);
                        }
                    }

                    if (!m_ServiceReqFieldsByRules.ContainsKey("Match_Fields_Service"))
                    {
                        m_ServiceReqFieldsByRules.Add("Match_Fields_Service", matchFieldsRequiredFields);
                    }
                }

                //Enhanced match rule required fields
                else if (ruleByDev.Key.Equals("Enhanced_Match_Service"))
                {
                    List <string> enhancedMatchRequiredFields = new List <string>();
                    foreach (Work_Rule__c rule in ruleByDev.Value)
                    {
                        enhancedMatchRequiredFields.Add(rule.Service_Appointment_Matching_Field__c);
                        if (rule.Object_Group_Field__c != null)
                        {
                            relevanceGroupFields.Add(rule.Object_Group_Field__c);
                        }
                    }

                    if (!m_ServiceReqFieldsByRules.ContainsKey("Enhanced_Match_Service"))
                    {
                        m_ServiceReqFieldsByRules.Add("Enhanced_Match_Service", enhancedMatchRequiredFields);
                    }
                }

                //Count rule required fields
                else if (ruleByDev.Key.Equals("Count_Rule"))
                {
                    List <string> countRuleRequiredFields = new List <string>();
                    foreach (Work_Rule__c rule in ruleByDev.Value)
                    {
                        if (rule.CustomFieldName__c != null)
                        {
                            countRuleRequiredFields.Add(rule.CustomFieldName__c);
                        }
                        if (rule.Object_Group_Field__c != null)
                        {
                            relevanceGroupFields.Add(rule.Object_Group_Field__c);
                        }
                    }

                    if (!m_ServiceReqFieldsByRules.ContainsKey("Count_Rule"))
                    {
                        m_ServiceReqFieldsByRules.Add("Count_Rule", countRuleRequiredFields);
                    }
                }

                else
                {
                    foreach (Work_Rule__c rule in ruleByDev.Value)
                    {
                        if (rule.Object_Group_Field__c != null)
                        {
                            relevanceGroupFields.Add(rule.Object_Group_Field__c);
                        }
                    }
                }
            }
            //For custom field in relevance group
            if (!m_ServiceReqFieldsByRules.ContainsKey("Relevance Group Fields"))
            {
                m_ServiceReqFieldsByRules.Add("Relevance Group Fields", relevanceGroupFields);
            }
        }
 public OperatingHoursUtils(AppointmentBookingData i_ABData)
 {
     m_ABData = i_ABData;
 }
        public override void Deserialize(string i_QueryResult, AppointmentBookingData i_ABData,
                                         AdditionalObjectsUtils.eAdditionalObjectQuery i_AdditionalObjQuery = default, bool async = false)
        {
            DeserializedQueryResult deserializedQuery =
                JsonConvert.DeserializeObject <DeserializedQueryResult>(i_QueryResult);

            bool serviceHasSkills = false;
            Dictionary <string, double?> skillIdToLevel = new Dictionary <string, double?>();

            foreach (SkillRequirement skillReq in i_ABData.ServiceParent[i_ABData.ServiceToSchedule.ParentRecordId].SkillRequirements)
            {
                skillIdToLevel.Add(skillReq.SkillId, skillReq.SkillLevel);
                serviceHasSkills = true;
            }

            bool matchSkillLevel = false;

            if (i_ABData.RulesByDevName.ContainsKey("Match_Skills_Service"))
            {
                List <Work_Rule__c> matchSkillsRules = i_ABData.RulesByDevName["Match_Skills_Service"];
                foreach (Work_Rule__c rule in matchSkillsRules)
                {
                    if (rule.Match_Skill_Level__c == true)
                    {
                        matchSkillLevel = true;
                    }
                }
            }

            i_ABData.CandidatesById = new Dictionary <string, ServiceResource>();
            if (!matchSkillLevel || !serviceHasSkills)
            {
                i_ABData.CandidatesById = deserializedQuery.records.ToDictionary(candidate => candidate.Id);
            }
            else
            {
                foreach (ServiceResource resource in deserializedQuery.records)
                {
                    if (resource.serviceResourceSkillsCollection == null)
                    {
                        continue;
                    }

                    foreach (ServiceResourceSkill skill in resource.serviceResourceSkillsCollection.records)
                    {
                        if (skillIdToLevel.ContainsKey(skill.SkillId))
                        {
                            if (matchSkillLevel && skill.SkillLevel < skillIdToLevel[skill.SkillId])
                            {
                                continue;
                            }

                            if (!i_ABData.CandidatesById.ContainsKey(resource.Id))
                            {
                                i_ABData.CandidatesById.Add(resource.Id, resource);
                            }
                        }
                    }
                }
            }
        }
 public ServiceAppointmentUtils(AppointmentBookingData i_ABData)
 {
     m_ServiceReqFieldsByRules = new Dictionary <string, List <string> >();
     m_RulesByDeveloperName    = i_ABData.RulesByDevName;
     initializeRequiredFieldsFromRules(i_ABData);
 }