• Bob 11
  • NEWBIE
  • 50 Points
  • Member since 2021

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 30
    Questions
  • 23
    Replies
I have this class below that create service appointments. It should allow a customer to find a appointment time slot and select it , then create the work order and servcie appointment,. But while the Lightning component is searching for aviable time slots this class will keep creating blank service appointments and work orders even beofre the customer selects an appointment time slot. Does anyone know what in this apex class is causing that to happen? 
 
public without sharing class advic_fsl_AppointmentBooking {

    @AuraEnabled
    public static CmpData createWorkOrderAndServiceAppointment() {
        CmpData retData = new CmpData();
        User runningUser = getRunningUser();
        system.debug('Who is the running user: '+runningUser.AccountId);
        retData.isEligibleCustomer = checkCustomerEligibility(runningUser.AccountId);
        if(retData.isEligibleCustomer) {
            retData.workOrderId = createWorkOrder(runningUser);
            retData.serviceAppointmentId = createServiceAppointment(runningUser, retData.workOrderId);
        }
        
        return retData;
    }
    
    @AuraEnabled
    public static CmpData getAppointmentSlots(Id workOrderId, Id serviceAppointmentId) {
        System.debug('@@@@ HERE');
        CmpData retData = new CmpData();
        retData.slots = getSlots(serviceAppointmentId);
        // We delete the created Work Order and Service Appointment in case the user quits the process before scheduling his/her appointment.
        // Once the user confirms their scheduled appointment, we will undelete the Work Order and Service Appointment.
        deleteWorkOrderAndServiceAppointment(workOrderId, serviceAppointmentId);
        System.debug('@@@@ retData: ' + retData);
        return retData;
    }
    
    @AuraEnabled
    public static void undeleteWorkOrderAndServiceAppointment(Id workOrderId, Id serviceAppointmentId) {
        List<WorkOrder> deletedWorkOrders = [SELECT Id FROM WorkOrder WHERE Id =: workOrderId ALL ROWS];
        List<ServiceAppointment> deletedServiceAppointments = [SELECT Id FROM ServiceAppointment WHERE Id =: serviceAppointmentId ALL ROWS];
        try {
            undelete deletedWorkOrders;
            undelete deletedServiceAppointments;
        } catch(DmlException e) {
            System.debug('Error in undeleteWorkOrderAndServiceAppointment: ' + e.getMessage());
        }
    }
    
    @AuraEnabled
    public static void updateServiceAppointment(String slotJSON, Id serviceAppointmentId, String detailsAccount, String detailsServiceAppt) {
        System.debug(slotJSON);
        System.debug(serviceAppointmentId);
        System.debug(detailsAccount);
        System.debug(detailsServiceAppt);
        AppointmentBookingSlot slot = (AppointmentBookingSlot)JSON.deserialize(slotJSON, advic_fsl_AppointmentBooking.AppointmentBookingSlot.class);
        try{
            ServiceAppointment serviceAppointment = [SELECT ArrivalWindowStartTime, ArrivalWindowEndTime, Status, Additional_Details__c FROM ServiceAppointment WHERE Id =: serviceAppointmentId];
            serviceAppointment.ArrivalWindowStartTime = utcToUserTimezone(slot.times.startDT);
            serviceAppointment.ArrivalWindowEndTime = utcToUserTimezone(slot.times.endDT);
            
            serviceAppointment.Status = 'Scheduled';
            ServiceAppointment.Additional_Details__c = detailsServiceAppt;
            
            User runningUser = getRunningUser();
            system.debug('Who is the running user: '+runningUser.AccountId);
            Account account = [SELECT Additional_Details__c FROM Account WHERE Id =: runningUser.AccountId];
            account.Additional_Details__c = detailsAccount;
            
            update serviceAppointment;
            update account;
        } catch(DmlException e) {
            System.debug('updateServiceAppointment: ' + serviceAppointmentId + ' Error: ' + + e.getMessage());
        }
        
    }
    
    @AuraEnabled
    public static void scheduleServiceAppointment(Id serviceAppointmentId) {
        Id schedulingPolicyId = [SELECT Id, Name FROM FSL__Scheduling_Policy__c WHERE Name = 'Customer First' LIMIT 1].Id;
        
        //Schedules the service appointment in the best available slot. If there are no available slots, the appointment isn’t scheduled.
        FSL.ScheduleResult result = new FSL.ScheduleResult();
        //Returns the result of the scheduling process.
        System.debug('svcApptId to Svc: '+ serviceAppointmentId);
        result = FSL.ScheduleService.schedule(schedulingPolicyId, serviceAppointmentId);
        try{
            System.debug('FSL.ScheduleService result: ' + JSON.serializePretty(result));
        }
        catch(Exception e){
            System.debug('JSON ERROR. On: '+ result);
        }
    }
    
    private static Boolean checkCustomerEligibility(Id accountId) {
        Account account = [SELECT Customer_Eligible__c FROM Account WHERE Id =: accountId];
        
        //return account.Customer_Eligible__c;
        return true; //for testing only.
    }
    //new eligibility that we need to incoporate REMS-191
    @AuraEnabled
    public static String checkAccountEligibility() {
        String eligibilityStatus = '';
        Boolean codeStartsWithPp = false;
        User runningUser = getRunningUser();
        Contact cont = [SELECT Electric_Utility_Number__c, Gas_Utility_Number__c, How_do_you_heat_your_home__c, AccountId, Part_of_Condo_Association__c FROM Contact WHERE Id =: runningUser.ContactId];
        System.debug('@@@ cont.Gas_Utility_Number__c: ' + cont.Gas_Utility_Number__c);
        System.debug('@@@ cont.Electric_Utility_Number__c: ' + cont.Electric_Utility_Number__c);
        if(String.isBlank(cont.Gas_Utility_Number__c) && String.isBlank(cont.Electric_Utility_Number__c)) {
            Account account = [SELECT Eligible_Testing__c, Ineligible_Reason_Code__c, Square_Footage__c, Building_Type__c FROM Account WHERE Id = :cont.AccountId];
            System.debug('@@@ account: ' + account);
            codeStartsWithPp = checkIneligibleReasonCode(account.Ineligible_Reason_Code__c);
            if(account.Eligible_Testing__c == false) {
                //Need to display general ineligible code info
                if(account.Ineligible_Reason_Code__c == 'DISC'){
                    eligibilityStatus = 'Due to your utility service rate code, we are not able to service your property. Please contact your local Community Action Partnership, or call our offices for more information.';
                }
                else if(account.Ineligible_Reason_Code__c == 'COM'){
                    eligibilityStatus = 'Please contact out office for further assistance at 401-000-0000';
                }
                else if(codeStartsWithPp){
                    eligibilityStatus = 'We are not able to schedule you  Thank you.';
                } else if(account.Ineligible_Reason_Code__c != 'DISC' || account.Ineligible_Reason_Code__c != 'COM' || !codeStartsWithPp){
                eligibilityStatus = 'thank you';
                } else{
                    eligibilityStatus = 'thank you';                    
                }
            } else if(account.Eligible_Testing__c == true && (cont.Part_of_Condo_Association__c == 'Yes' || account.Building_Type__c != 'Single-Family Home' || account.Square_Footage__c == '3000-3500 sq ft' || account.Square_Footage__c == '3500-6000 sq ft' || account.Square_Footage__c == '6000+ sq ft')){
                    eligibilityStatus = 'Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices.';                    
            } else {
                eligibilityStatus = 'Eligible';
                }}
        if(String.isNotBlank(cont.Gas_Utility_Number__c)) {
            Account gasAcc = [SELECT Eligible_Testing__c, Ineligible_Reason_Code__c, Building_Type__c, Square_Footage__c FROM Account WHERE Utility_Number__c =: cont.Gas_Utility_Number__c LIMIT 1];
            System.debug('@@@ gasAcc: ' + gasAcc);
            codeStartsWithPp = checkIneligibleReasonCode(gasAcc.Ineligible_Reason_Code__c);
            if(cont.How_do_you_heat_your_home__c == 'Natural Gas' && gasAcc.Eligible_Testing__c == true && gasAcc.Ineligible_Reason_Code__c != 'DISC' && (cont.Part_of_Condo_Association__c == 'Yes' || gasAcc.Building_Type__c != 'Single-Family Home' || gasAcc.Square_Footage__c == '3000-3500 sq ft' || gasAcc.Square_Footage__c == '3500-6000 sq ft' || gasAcc.Square_Footage__c == '6000+ sq ft')){
                System.debug('@@@@ A');
                eligibilityStatus = 'Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices. ';
            }
            else if(cont.How_do_you_heat_your_home__c == 'Natural Gas' && gasAcc.Eligible_Testing__c == true && gasAcc.Ineligible_Reason_Code__c != 'DISC'){
                System.debug('@@@@ B');
                eligibilityStatus = 'Eligible';
            }
            else if(cont.How_do_you_heat_your_home__c == 'Natural Gas' && gasAcc.Ineligible_Reason_Code__c == 'DISC'){
                //Need to display DISC code info:
                System.debug('@@@@ C');
                eligibilityStatus = 'Due to your utility service rate code, we are not able to service your property.';
            } else if(cont.How_do_you_heat_your_home__c == 'Natural Gas' && gasAcc.Eligible_Testing__c == false){
                //Need to display general ineligible code info
                System.debug('@@@@ D');
                if(gasAcc.Ineligible_Reason_Code__c == 'DISC'){
                    System.debug('@@@@ E');
                    eligibilityStatus = 'Due to your utility service rate code, we are not able to service your property.';
                }
                else if(gasAcc.Ineligible_Reason_Code__c == 'COM'){
                    System.debug('@@@@ F');
                    eligibilityStatus = 'Due';
                }
                else if(codeStartsWithPp){
                    System.debug('@@@@ G');
                    eligibilityStatus = 'We are not able to schedule you';
                } else{
                    System.debug('@@@@ H');
                    eligibilityStatus = 'Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices.';
                }} else {
                    if (cont.How_do_you_heat_your_home__c == 'None') {
                        System.debug('@@@@ I');
                        //Need to display general ineligible code info
                        if(gasAcc.Ineligible_Reason_Code__c == 'DISC'){
                            System.debug('@@@@ J');
                            eligibilityStatus = 'Due to your utility service rate code, we are not able to service your property.';
                        }
                        else if(gasAcc.Ineligible_Reason_Code__c == 'COM'){
                            System.debug('@@@@ K');
                            eligibilityStatus = 'Due to the commercial rate code on this property, we are not able to schedule a residential No-Cost Energy Assessment.';
                        }
                        else if(codeStartsWithPp){
                            System.debug('@@@@ L');
                            eligibilityStatus = 'We are not able to schedule you a No-Cost energy assessment due to the recent participation in the program.';
                        }
                        else{
                            System.debug('@@@@ M');
                            eligibilityStatus = 'Thank you for your inquiry, we are unable to complete your request at this time.';
                        }}
                }
        }
        if(String.isNotBlank(cont.Electric_Utility_Number__c)) {
            Account elecAcc = [SELECT Eligible_Testing__c, Ineligible_Reason_Code__c, Building_Type__c, Square_Footage__c FROM Account WHERE Utility_Number__c =: cont.Electric_Utility_Number__c LIMIT 1];
            System.debug('@@@ elecAcc: ' + elecAcc);
            codeStartsWithPp = checkIneligibleReasonCode(elecAcc.Ineligible_Reason_Code__c);
            if(cont.How_do_you_heat_your_home__c == 'Natural Gas' && elecAcc.Ineligible_Reason_Code__c != 'DISC' && (cont.Part_of_Condo_Association__c == 'Yes' || elecAcc.Building_Type__c != 'Single-Family Home' || elecAcc.Square_Footage__c == '3000-3500 sq ft' || elecAcc.Square_Footage__c == '3500-6000 sq ft' || elecAcc.Square_Footage__c == '6000+ sq ft')){
                eligibilityStatus = 'Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices.';
            }
            else if(cont.How_do_you_heat_your_home__c == 'Natural Gas' && elecAcc.Ineligible_Reason_Code__c != 'DISC'){
                eligibilityStatus = 'Eligible';
            }
            else if(cont.How_do_you_heat_your_home__c == 'Natural Gas' && elecAcc.Ineligible_Reason_Code__c == 'DISC'){
                //Need to display DISC code info:
                eligibilityStatus = 'Due to your utility service rate code, we are not able to service your property.  Thank you.';
            } 
            else if(cont.How_do_you_heat_your_home__c != 'Natural Gas' && cont.How_do_You_heat_your_home__c != 'None' && elecAcc.Eligible_Testing__c == true && (cont.Part_of_Condo_Association__c == 'Yes' || elecAcc.Building_Type__c != 'Single-Family Home' || elecAcc.Square_Footage__c == '3000-3500 sq ft' || elecAcc.Square_Footage__c == '3500-6000 sq ft' || elecAcc.Square_Footage__c == '6000+ sq ft')){
                eligibilityStatus = 'Thank you for your inquiry, we are unable to complete your request at this time.';
            }
            else  if(cont.How_do_you_heat_your_home__c != 'Natural Gas' && cont.How_do_you_heat_your_home__c != 'None' && elecAcc.Eligible_Testing__c == true){
                eligibilityStatus = 'Eligible';
            } else  if(cont.How_do_you_heat_your_home__c != 'Natural Gas' && cont.How_do_you_heat_your_home__c != 'None' && elecAcc.Eligible_Testing__c == false){
                //Need to display general ineligible code info
                if(elecAcc.Ineligible_Reason_Code__c == 'DISC'){
                    eligibilityStatus = 'Due to your utility service rate code, we are not able to service your property.  Thank you.';
                }
                else if(elecAcc.Ineligible_Reason_Code__c == 'COM'){
                    eligibilityStatus = 'Due to the commercial rate code on this property, we are not able to schedule a residential No-Cost Energy Assessment.';
                }
                else if(codeStartsWithPp){
                    eligibilityStatus = 'We are not able to schedule you a No-Cost energy assessment due to the recent participation in the program.. Thank you.';
                } else {
                    eligibilityStatus = 'Thank you for your inquiry, we are unable to complete your request at this time. For further assistance,';
                }} else {
                    if (cont.How_do_you_heat_your_home__c == 'None') {
                        //Need to display general ineligible code info
                        if(elecAcc.Ineligible_Reason_Code__c == 'DISC'){
                            eligibilityStatus = 'Due to your utility service rate code, we are not able to service your property.  Thank you.';
                        }
                        else if(elecAcc.Ineligible_Reason_Code__c == 'COM'){
                            eligibilityStatus = 'Due to the commercial rate code on this property, we are not able to schedule a residential No-Cost Energy Assessment.';
                        }
                        else if(codeStartsWithPp){
                            eligibilityStatus = 'We are not able to schedule you a No-Cost energy assessment due to the recent participation in the program. For further assistance, please contact our offices. Thank you.';
                        }else{
                            eligibilityStatus = 'Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices.';
                        }}
            }
        }

        System.debug('@@@@ eligibilityStatus: ' + eligibilityStatus);

        return eligibilityStatus;
    }

    public static User getRunningUser() {
        Id runningUserId = UserInfo.getUserId();

        return [SELECT AccountId, ContactId, Account.BillingStreet, Account.BillingCity, Account.BillingState, Account.BillingCountry, Account.BillingPostalCode FROM User WHERE Id =: runningUserId];
    }

    public static Id createWorkOrder(User runningUser) {
        WorkType energyInHomeWt = [SELECT Id FROM WorkType WHERE Name = 'Energy Assessment - In Home' LIMIT 1];
        WorkOrder workOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId, Street=runningUser.Account.BillingStreet, WorkTypeId=energyInHomeWt.Id,
                City=runningUser.Account.BillingCity, State=runningUser.Account.BillingState, Country=runningUser.Account.BillingCountry, PostalCode=runningUser.Account.BillingPostalCode);
        try {
            insert workOrder;
        } catch(DmlException e) {
            System.debug('Error in createWorkOrder: ' + e.getMessage());
        }

        return workOrder.Id;
    }

    public static Id createServiceAppointment(User runningUser, Id workOrderId) {
        ServiceAppointment serviceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=workOrderId, EarliestStartTime=Datetime.now().addMonths(1), DueDate=Datetime.now().addMonths(1),
            Street=runningUser.Account.BillingStreet, City=runningUser.Account.BillingCity, State=runningUser.Account.BillingState, Country=runningUser.Account.BillingCountry,
            PostalCode=runningUser.Account.BillingPostalCode);
        try {
            insert serviceAppointment;
        } catch(DmlException e) {
            System.debug('Error in createServiceAppointment: ' + e.getMessage());
        }

        return serviceAppointment.Id;
    }

    private static Boolean checkIneligibleReasonCode(String ineligibleReasonCode) {
        Boolean codeStartsWithPp = false;
        if(String.isNotBlank(ineligibleReasonCode)) {
            if(ineligibleReasonCode.startsWith('PP')) {
                codeStartsWithPp = true;
            }
        }

        return codeStartsWithPp;
    }

    private static void deleteWorkOrderAndServiceAppointment(Id workOrderId, Id serviceAppointmentId) {
        try {
            delete [SELECT Id FROM WorkOrder WHERE Id =: workOrderId];
            delete [SELECT Id FROM ServiceAppointment WHERE Id =: serviceAppointmentId];
        } catch(DmlException e) {
            System.debug('Error in deleteWorkOrderAndServiceAppointment: ' + e.getMessage());
        }
    }

    /*
    * Appointment booking returns the available slots for a service appointment, while considering scheduling policies, work rules, and service objectives.
    * */
    public static List<AppointmentBookingSlot> getSlots(Id serviceAppointmentId) {
        System.debug('@@@@ serviceAppointmentId: ' + serviceAppointmentId);
        ServiceAppointment serviceAppointment = [SELECT Id, AccountId, ContactId, EarliestStartTime, DueDate FROM ServiceAppointment WHERE Id =: serviceAppointmentId LIMIT 5];

        Id schedulingPolicyId = [SELECT Id, Name FROM FSL__Scheduling_Policy__c LIMIT 1].Id;

        Id operatingHoursId  = [SELECT Id, Name FROM OperatingHours WHERE Name = 'Energy Assessment Calendar' LIMIT 1].Id;

        Timezone tz = UserInfo.getTimeZone();
        System.debug('getting slots with....'+ serviceAppointment.Id + '//'+schedulingPolicyId+ '//'+operatingHoursId+ '//'+tz) ;
        List<FSL.AppointmentBookingSlot> slots = FSL.AppointmentBookingService.GetSlots(serviceAppointment.Id, schedulingPolicyId, operatingHoursId, tz, false);
        System.debug('slots: ' + slots);

        List<AppointmentBookingSlot> slotList = new List<AppointmentBookingSlot>();
        for(FSL.AppointmentBookingSlot slot : slots){
            DateTime slotStartDT = slot.interval.start;
            DateTime slotFinishDT = slot.interval.finish;
            Date slotStartDay = slotStartDT.date();
            
            if(slotStartDay > Date.today() ){
                AppointmentBookingSlot newSlot = new AppointmentBookingSlot();
                Interval times = new Interval();
                times.startDT = slot.interval.start;
                times.endDT = slot.interval.finish;
                newSlot.grade = slot.grade;
                newSlot.times = times;
                slotList.add(newSlot);
            }
        }
        System.debug('slotList:: '+ slotList);
        //I'm thinking they may want these ordered by rank, but not 100% sure. If so, we can do that with the comparable interface:
        //https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_comparable.htm --Chuck
        
        //return setToTimeZone(slotList);
        return slotList;
    }
    
    public static DateTime utcToUserTimezone(DateTime utcDT){
        DateTime userDT = utcDT;
        String utcDtString = utcDT.format('yyyy-MM-dd HH:mm:ss', 'UTC');
        //String utcDtString = utcDT.format('yyyy-MM-dd hh:mm a', 'UTC');

        System.debug('@@@@ str: '+utcDtString);
        userDT = DateTime.valueOf(utcDtString);
        System.debug('@@@@ DT: '+userDT);
        return userDT;
    }
    
    /*public static List<AppointmentBookingSlot> setToTimezone(List<AppointmentBookingSlot> slots){
        if(slots.isEmpty()){
            return slots;
        }
        String timeZone = UserInfo.getTimeZone().getID();

        for(AppointmentBookingSlot slot: slots){
            if(slot.times != NULL){
                System.debug('~~~~~~');
                System.debug('BEFORE: '+ slot.times.endDT);
                slot.times.startDT = Datetime.valueOf(slot.times.startDT);
                slot.times.endDT = Datetime.valueOf(slot.times.endDT);
                System.debug('AFTER: '+ slot.times.endDT.format());
            }
        }
        
        return slots;
    }*/
    
    

    public class CmpData {
        @AuraEnabled
        public Id workOrderId {get;set;}
        @AuraEnabled
        public Id serviceAppointmentId {get;set;}
        @AuraEnabled
        public List<AppointmentBookingSlot> slots {get;set;}
        @AuraEnabled
        public Boolean isEligibleCustomer {get;set;}
    }
    public class AppointmentBookingSlot {
        @AuraEnabled
        public Decimal grade {get;set;}
        @AuraEnabled
        public Interval times {get;set;}
    }
    public class Interval {
        @AuraEnabled
        public DateTime startDT {get;set;}
        @AuraEnabled
        public DateTime endDT {get;set;}
    }
}

 
  • August 03, 2022
  • Like
  • 0
I made an update to a apex test class but when i try to deploy it give me the following error. I'm not sure how to fix this

System.QueryException: List has no rows for assignment to SObject
Stack Trace: Class.advic_fsl_AppointmentBooking.scheduleServiceAppointment: line 71, column 1 Class.advic_fsl_AppointmentBookingTest.testScheduleServiceAppointment: line 146, column 1

here is the test class below. i will post the apex class too
 
@isTest
private class advic_fsl_AppointmentBookingTest {

    @testSetup
    static void setup() {
        // Create test data
        // Create Scheduling Policy
        FSL__Scheduling_Policy__c schedulingPolicy = new FSL__Scheduling_Policy__c(FSL__Commit_Mode__c='AlwaysCommit', FSL__Fix_Overlaps__c=false, FSL__Daily_Optimization__c=false,
                Name='Customer First', FSL__Travel_Mode__c=false);
        insert schedulingPolicy;
        // Create Operating Hours
        OperatingHours operatingHours = new OperatingHours(Description='Testing Hours', Name='Energy Assessment Calendar', TimeZone='America/New_York');
        insert operatingHours;
        // Create Time Slots
        List<TimeSlot> timeSlots = new List<TimeSlot>();
        timeSlots.add(new TimeSlot(DayOfWeek='Monday', Type='Normal', OperatingHoursId=operatingHours.Id,
                StartTime=Time.newInstance(10,0,0,0), EndTime=Time.newInstance(12,0,0,0)));
        timeSlots.add(new TimeSlot(DayOfWeek='Tuesday', Type='Normal', OperatingHoursId=operatingHours.Id,
                StartTime=Time.newInstance(10,0,0,0), EndTime=Time.newInstance(12,0,0,0)));
        insert timeSlots;
        Account testAccount = new Account(Name='Test Account', Customer_Eligible__c=true);
        insert testAccount;
        Contact testContact = new Contact(AccountId=testAccount.Id, LastName='TestContact');
        insert testContact;
        Profile riseCommunityCustomerProfile = [SELECT Id FROM Profile WHERE Name='RISE Community Customer User'];
        User runningUser = new User(Alias = 'standt', Email='standarduser@testorg.com', EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
                LocaleSidKey='en_US', ProfileId = riseCommunityCustomerProfile.Id, TimeZoneSidKey='America/New_York', UserName='standarduser@testorg.com',
                ContactId=testContact.Id);
        insert runningUser;
        
        
        WorkType eaIh  = new WorkType();
        eaIh.Name = 'Energy Assessment - In Home';
        eaIh.EstimatedDuration = 90.0;
        insert eaIh;
        
        
    }

    static testMethod void testCreateWorkOrderAndServiceAppointment() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT Id FROM User WHERE ContactId =: contact.Id];

        

        List<WorkOrder> insertedWorkOrders = [SELECT AccountId, ContactId FROM WorkOrder];
        List<ServiceAppointment> insertedServiceAppointments = [SELECT AccountId, ContactId, ParentRecordId, EarliestStartTime, DueDate FROM ServiceAppointment ];

      
       

        if(insertedWorkOrders.size() == 1) {
            WorkOrder insertedWorkOrder = insertedWorkOrders[0];
            System.assertEquals(account.Id, insertedWorkOrder.AccountId, 'The Work Order AccountId was not assigned.');
            System.assertEquals(contact.Id, insertedWorkOrder.ContactId, 'The Work Order ContactId was not assigned.');

            if(insertedServiceAppointments.size() == 1) {
                ServiceAppointment insertServiceAppointment = insertedServiceAppointments[0];
                System.assertEquals(account.Id, insertServiceAppointment.AccountId, 'The Service Appointment AccountId was not assigned.');
                System.assertEquals(contact.Id, insertServiceAppointment.ContactId, 'The Service Appointment ContactId was not assigned.');
                System.assertEquals(insertedWorkOrder.Id, insertServiceAppointment.ParentRecordId, 'The Work Order that was inserted was not assigned to the inserted Service Appointment.');
                System.assert(insertServiceAppointment.EarliestStartTime != null, 'The Service Appointment EarliestStartTime was not populated.');
                System.assert(insertServiceAppointment.DueDate != null, 'The Service Appointment DueDate was not populated.');
            }
        }
    }

    static testMethod void testGetAppointmentSlots() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];

        WorkOrder testWorkOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId);
        insert testWorkOrder;
        ServiceAppointment testServiceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=testWorkOrder.Id, EarliestStartTime=Datetime.now(), DueDate=Datetime.now().addMonths(1));
        insert testServiceAppointment;

        Test.startTest();
            advic_fsl_AppointmentBooking.CmpData data = advic_fsl_AppointmentBooking.getAppointmentSlots(testWorkOrder.Id, testServiceAppointment.Id);
        Test.stopTest();

        // Letting the managed package tests control the FSL methods and test them.
        // The method itself is covered in the FSL managed package tests.
    }

    static testMethod void testUndeleteWorkOrderAndServiceAppointment() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];

        WorkOrder testWorkOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId);
        insert testWorkOrder;
        ServiceAppointment testServiceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=testWorkOrder.Id, EarliestStartTime=Datetime.now(), DueDate=Datetime.now().addMonths(1));
        insert testServiceAppointment;

        delete testWorkOrder;

        Test.startTest();
            advic_fsl_AppointmentBooking.undeleteWorkOrderAndServiceAppointment(testWorkOrder.Id, testServiceAppointment.Id);
        Test.stopTest();

        System.assertEquals(1, [SELECT Id FROM WorkOrder WHERE Id =: testWorkOrder.Id].size(), 'The Work Order was not undeleted.');
        System.assertEquals(1, [SELECT Id FROM ServiceAppointment WHERE Id =: testServiceAppointment.Id].size(), 'The Service Appointment was not undeleted');
    }

    static testMethod void testUpdateServiceAppointment() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];

        WorkOrder testWorkOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId);
        insert testWorkOrder;
        ServiceAppointment testServiceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=testWorkOrder.Id, EarliestStartTime=Datetime.now(), DueDate=Datetime.now().addMonths(1));
        insert testServiceAppointment;

        String slotJSON = '{"grade":100,"times":{"endDT":"2020-06-02T15:00:00.000Z","startDT":"2020-06-02T13:00:00.000Z"}}';

        System.runAs(runningUser) {
            Test.startTest();
            advic_fsl_AppointmentBooking.updateServiceAppointment(slotJSON, testServiceAppointment.Id, 'abc', 'xyz');
            Test.stopTest();
        }

        ServiceAppointment serviceAppointment = [SELECT ArrivalWindowStartTime, ArrivalWindowEndTime FROM ServiceAppointment WHERE Id =: testServiceAppointment.Id];

        DateTime arrivalWindowStartTime = (DateTime)json.deserialize('"2020-06-02T13:00:00.000Z"', datetime.class);
        DateTime arrivalWindowEndTime = (DateTime)json.deserialize('"2020-06-02T15:00:00.000Z"', datetime.class);

        //System.assertEquals(arrivalWindowStartTime, serviceAppointment.ArrivalWindowStartTime, 'The Service Appointment ArrivalWindowStartTime is incorrect.');
        //System.assertEquals(arrivalWindowEndTime, serviceAppointment.ArrivalWindowEndTime, 'The Service Appointment ArrivalWindowEndTime is incorrect.');
    }

    static testMethod void testScheduleServiceAppointment() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];

        WorkOrder testWorkOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId);
        insert testWorkOrder;
        ServiceAppointment testServiceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=testWorkOrder.Id,
                EarliestStartTime=Datetime.now(), DueDate=Datetime.now().addMonths(1), ArrivalWindowStartTime=Datetime.now(), ArrivalWindowEndTime=Datetime.now().addMonths(1), Status = 'Scheduled');
        insert testServiceAppointment;

        Test.startTest();
            advic_fsl_AppointmentBooking.scheduleServiceAppointment(testServiceAppointment.Id);
        Test.stopTest();

        // Letting the managed package tests control the FSL methods and test them.
        // The method itself is covered in the FSL managed package tests.
    }

    static testMethod void testCheckAccountEligibility_NoAccounts() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'DISC';
        account.Square_Footage__c = '';
        account.Building_Type__c = 'Single-Family Home';
        contact.Part_of_Condo_Association__c = 'No';
        update account;
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
                eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Due to your utility service rate code, we are not able to service your property. Please contact your local Community Action Partnership, or call our offices for more information. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335. Thank you.', eligibilityStatus, 'The Account should be ineligible.');
    }
    static testMethod void testCheckAccountEligibility_NoAccounts1() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'COM';
        account.Square_Footage__c = '';
        account.Building_Type__c = 'Single-Family Home';
        contact.Part_of_Condo_Association__c = 'No';
        update account;
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
                eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Due to the commercial rate code on this property, we are not able to schedule a residential No-Cost Energy Assessment. Please contact out office for further assistance at 401-784-3700.', eligibilityStatus, 'The Account should be ineligible.');
    }
    static testMethod void testCheckAccountEligibility_NoAccounts2() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'PP';
        account.Square_Footage__c = '';
        account.Building_Type__c = 'Single-Family Home';
        contact.Part_of_Condo_Association__c = 'No';
        update account;
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
                eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('We are not able to schedule you a No-Cost energy assessment due to the recent participation in the program. For further assistance, please contact our offices. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335. Thank you.', eligibilityStatus, 'The Account should be ineligible.');
    }
    static testMethod void testCheckAccountEligibility_NoAccounts3() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'AMA';
        account.Square_Footage__c = '';
        account.Building_Type__c = 'Single-Family Home';
        contact.Part_of_Condo_Association__c = 'No';
        update account;
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
                eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335.', eligibilityStatus, 'The Account should be ineligible.');
    }

    static testMethod void testCheckAccountEligibility_GasAccountEligible() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Eligible_Testing__c = true;
        account.Building_Type__c = 'Single-Family Home';
        account.Square_Footage__c = '2000-3000 sq ft';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        contact.Part_of_Condo_Association__c = 'No';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Eligible', eligibilityStatus, 'The Contact should be eligible.');
    }

    static testMethod void testCheckAccountEligibility_GasAccountIneligible() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Ineligible_Reason_Code__c = 'DISC';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Due to your utility service rate code, we are not able to service your property. Please contact your local Community Action Partnership, or call our offices for more information. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335. Thank you.', eligibilityStatus, 'The General Error message should have returned.');
    }
     static testMethod void testCheckAccountEligibility_GasAccountIneligible1() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Ineligible_Reason_Code__c = 'COM';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Due to the commercial rate code on this property, we are not able to schedule a residential No-Cost Energy Assessment. Please contact out office for further assistance at 401-784-3700.', eligibilityStatus, 'The General Error message should have returned.');
    }
    static testMethod void testCheckAccountEligibility_GasAccountIneligible2() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Ineligible_Reason_Code__c = 'PP';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('We are not able to schedule you a No-Cost energy assessment due to the recent participation in the program. For further assistance, please contact our offices. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335. Thank you.', eligibilityStatus, 'The Contact should be eligible.');
    }
    static testMethod void testCheckAccountEligibility_GasAccountIneligible3() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Ineligible_Reason_Code__c = 'AMA';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335.', eligibilityStatus, 'The Contact should be eligible.');
    }

   
  

    

        
    static testMethod void testCheckAccountEligibility_ElectricAccountIneligibleq1() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Electric_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'COM';
        update account;
        contact.Electric_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Electric';
        update contact;

    }
    static testMethod void testCheckAccountEligibility_ElectricAccountIneligible2() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Electric_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'PP';
        update account;
        contact.Electric_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Electric';
        update contact;

    }     
    static testMethod void testCheckAccountEligibility_ElectricAccountIneligible3() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Electric_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'AMA';
        update account;
        contact.Electric_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Electric';
        update contact;

               }
}
  • August 03, 2022
  • Like
  • 0
I am trying to create a self scheduling flow for service appointments and i am having issues with completing it.

I keep getting this error message
Error element Get_Slots (FlowActionCall).
An Apex error occurred: FSL.Exceptions.GeneralException: Script-thrown exception


also i'm not sure how to add the work order or service appointment elements or if i need to add them. I am using the flow scheduler flow fomr the Unofficial SF site (https://unofficialsf.com/flow-scheduler-enable-self-service-scheduling-for-field-service/), but i am not sure if i am using it correctly in my flow.  I could use some help completing this flow so it works to display dates a community user can select.

Here ar emy elements

User-added image

User-added image

User-added image

User-added imageUser-added image
I need to make my community self-registration screen wider to support my login flow window. How can this be accomplished through the experience builder or any other way? I tried creating a new page but it didn't work.  I tried to add this css to the theme but I'm not sure what to use for a class. I tried this below but it didnt work.

.salesforceIdentityinputContainer {width:600px;}

This worked for the login page but not the registration page

.salesforceIdentityLoginForm2 {width:300px;}
I was wondering if there is a custom coponent already built that is more customizable that this standard componenent. Can the Log In button color be changed anywhere? 



User-added image
I have a lightning component that i have updated with a new picklist field but when i enter a value in the component it does not save to the record in salesforce. Where should i look to set this value so it saves to the record?
User-added imageUser-added image
I urgently need help with adding a spinner to a lightning component. right now there is a pause when the component is looking for available time slots. There is one component that call another component to find time slots. I need a spinner displayed while the called component is get those time slots. I've tried a few different things with no success.

No Tutorials please, i need actual help on the placement of the spinner in the code 

The first component calling to the BookSlot component
 
<aura:iteration items="{!v.slotList}" var="slot" indexVar="i">
                                       <aura:if isTrue="{!(i > v.rowCount) == false}">
                                           
                                      <c:BookingSlot slot="{!slot}" workOrderId="{!v.workOrderId}" serviceAppointmentId="{!v.serviceAppointmentId}"/>
                                        </aura:if>
                                       </aura:iteration>

BookingSlot Component:
 
<aura:component controller="AppointmentBooking" description="Books the slot for a given Service Appointment">

    
    <aura:attribute name="debug" type="boolean" default="false"/>
    <aura:attribute name="isOpen" type="boolean" default="false"/>
    <aura:attribute name="slot" type="Object"/>
    <aura:attribute name="workOrderId" type="Id"/>
    <aura:attribute name="serviceAppointmentId" type="Id"/>
    <aura:attribute name="detailsAccount" type="String"/>
    <aura:attribute name="detailsSA" type="String"/>
    

    
      
    <aura:if isTrue="{!v.debug}">
                
        open={!v.isOpen}<br/>
        serviceAppointmentId={!v.serviceAppointmentId}<br/>
        slot={!v.slot}
            
    </aura:if>    
       

    <span class="apptSlot" onclick="{!c.openModel}">
        
           <center class="slotPill">
            <lightning:progressBar value="{!v.slot.grade}" size="large" class="rankBar" title="{!'Rank: '+v.slot.grade}"/>
            <lightning:formattedDateTime value="{!v.slot.times.startDT}" weekday="long" year="numeric" month="short" day="2-digit" hour="2-digit"
                                         minute="2-digit" hour12="true" timeZone="UTC"/>
            -
            <lightning:formattedDateTime value="{!v.slot.times.endDT}" hour="2-digit" minute="2-digit" hour12="true" timeZone="UTC"/>
        </center>
           
    </span>
 
    <aura:if isTrue="{!v.isOpen}">
        <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open slds-modal_small">
            <div class="slds-modal__container">
                <header class="slds-modal__header">
                    <lightning:buttonIcon iconName="utility:close"
                                          onclick="{! c.closeModal }" 
                                          alternativeText="close"
                                          variant="bare-inverse"
                                          class="slds-modal__close"/>
                    <h1 class="slds-text-heading--small">Confirmation</h1>
                </header>
                <div class="slds-modal__content slds-p-around_small" id="modal-content-id-1">
                    <p>
                        <div>You have selected the following slot:</div>
                        <br/>
                        <div class="slds-form_horizontalX slds-formX slds-gridX slds-wrapX">
                            <center>
                                <lightning:formattedDateTime value="{!v.slot.times.startDT}" weekday="long" year="numeric" month="short" day="2-digit" hour="2-digit"
                                                             minute="2-digit" hour12="true" timeZone="UTC"/>
                                -
                                <lightning:formattedDateTime value="{!v.slot.times.endDT}" hour="2-digit" minute="2-digit" hour12="true" timeZone="UTC"/>
                            </center>
                        </div>
                        <br/>
                        <!-- test fields that we need -->
                        <div>
                            <lightning:input type="text" value="{!v.detailsAccount}" class="input" require="true" label="Is there anything additional we need to know to locate your home?"/>
                            <br/>
                            <lightning:input type="text" value="{!v.detailsSA}" class="input" require="true" label="Is there anything else you would like us to know prior to the appointment?"/>
                            <br/>
                        </div>
                        <!-- end test fields that we need -->
                        <div>Please confirm you would like the selected date and time</div>
                    </p>
                </div>
                <footer class="slds-modal__footer">
                     <lightning:button name='Cancel' label='Cancel' onclick='{!c.closeModal}'/>
                     <lightning:button variant="brand" name='Confirm' label='Confirm' onclick='{!c.handleSlotSelected}'/>
                </footer>
            </div>
        </section>
        <div class="slds-backdrop slds-backdrop_open"></div>
     </aura:if>
    
    <br/>
     
</aura:component>

Controller:
({
    handleSlotSelected: function (component, e, helper) {
        console.log('in booking slot component');
        helper.undeleteWorkOrderAndServiceAppointment(component);
        helper.updateServiceAppointment(component); 
        helper.scheduleServiceAppointment(component);
    },
    openModel: function(component) {
        component.set("v.isOpen", true);
    },
    closeModal: function(component) {
        component.set("v.isOpen", false);
    }
   
});

Helper Class:
({
    undeleteWorkOrderAndServiceAppointment : function (component) {
        
        
        
        var workOrderId = component.get("v.workOrderId")
        var serviceAppointmentId = component.get("v.serviceAppointmentId");
       

        var action = component.get("c.undeleteWorkOrderAndServiceAppointment");
            
        action.setParams({
            'workOrderId' : workOrderId,
            'serviceAppointmentId': serviceAppointmentId
            
        });
      
        
        action.setCallback(this, function(response) {
           
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.isOpen", false);
               
            } else {
                let errors = response.getError();
                console.log('Error response: ' + response);
                console.log("Error message: " + errors[0].message);
                
            }
        });

        $A.enqueueAction(action);
    },
    updateServiceAppointment : function (component) {
        var slot = component.get("v.slot");
        var serviceAppointmentId = component.get("v.serviceAppointmentId");
        var detailsAccount = component.get("v.detailsAccount");
        var detailsServiceAppt = component.get("v.detailsSA");

        var action = component.get("c.updateServiceAppointment");
        
        action.setParams({
            'slotJSON' : JSON.stringify(slot),
            'serviceAppointmentId': serviceAppointmentId,
            'detailsAccount' : detailsAccount,
            'detailsServiceAppt' : detailsServiceAppt
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.isOpen", false);
               
            } else {
                let errors = response.getError();
                console.log('Error response: ' + response);
                console.log("Error message: " + errors[0].message);
            }
        });

        $A.enqueueAction(action);
    },
    scheduleServiceAppointment : function (component) {
        var serviceAppointmentId = component.get("v.serviceAppointmentId");

        var action = component.get("c.scheduleServiceAppointment");
        action.setParams({
            'serviceAppointmentId': serviceAppointmentId
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            var serviceAppointmentId = component.get("v.serviceAppointmentId");
            if (state === "SUCCESS") {
                component.set("v.isOpen", false);
                var toastEvent = $A.get("e.force:showToast");
                toastEvent.setParams({
                    "title": "Success",
                    "type":"success",
                    "message": "You have successfully scheduled your service appointment!",
                    "messageTemplate": 'You have successfully scheduled your service appointment! Click {0} for details!',
        			"messageTemplateData": [
                        {
            			url: '/detail/' + serviceAppointmentId,
            			label: 'here',
            			}
        			],
                    "mode":'sticky'

                });
                toastEvent.fire();
            } else {
                let errors = response.getError();
                console.log('Error response: ' + response);
                console.log("Error message: " + errors[0].message);
            }
        });

        $A.enqueueAction(action);
    }
    
});

​​​​​​​​​​​​​​
 
I have a lightning component that has required fields. my issue is i want the require field message to be displayed on every field if it is missing that information and not at the top of the page. I was wondering if anyone could help me with updating the code below to accomplish this update.

Lightning Component
<aura:component description="ContactQuestions" controller="ContactQuestionsController" implements="forceCommunity:availableForAllPageTypes,lightning:isUrlAddressable" access="global">
    <aura:attribute name="toScheduling" type="Boolean" default="false"/>
    <aura:attribute name="displayFlowModal" type="Boolean" default="false"/>
    <aura:attribute name="showAssist" type="Boolean" default="false"/>
    <aura:attribute name="showError" type="Boolean" default="false"/>
    <aura:attribute name="errorMessage" type="String"/>
    <aura:attribute name="firstname" type="string"/>
    <aura:attribute name="lastname" type="string"/>
    <aura:attribute name="email" type="string"/>
    <aura:attribute name="gasUtilityNumber" type="string"/>
    <aura:attribute name="electricUtilityNumber" type="string"/>
    <aura:attribute name="phoneNum" type="string"/>
    <aura:attribute name="serviceZip" type="string"/>
    <aura:attribute name="opLang" type="List"/>
    <aura:attribute name="opHeatFuel" type="List"/>
    <aura:attribute name="opCondo" type="List"/>
    <aura:attribute name="opOwnRent" type="List"/>
    <aura:attribute name="opHear" type="List"/>
    <aura:attribute name="opBuildingType" type="List"/>
    <aura:attribute name="opGasUtilHolder" type="List"/>
    <aura:attribute name="opElectricUtilHolder" type="List"/>
    <aura:attribute name="opHeatWith" type="List"/>
    <aura:attribute name="opSquareFeet" type="List"/>
    <aura:attribute name="opHowMany" type="List"/>
    <aura:attribute name="opWhyContactUs" type="List"/>
    <aura:attribute name="opMakeImprove" type="List"/>
    <aura:attribute name="opHowManyUnits" type="List"/>
    <aura:attribute name="opHomeStyle" type="List"/>
    <aura:attribute name="opPrimaryFuel" type="List"/>
    <aura:attribute name="opSecondaryFuel" type="List"/>
    <aura:attribute name="opLive" type="List" default="[
    {'label': 'Yes', 'value': 'yes'},
    {'label': 'No', 'value': 'no'}]"/>
    <aura:attribute name="recordId" type="String"/>

    <!-- Contact Attributes -->
    <aura:attribute name="ContactInformation" type="Object"/>
    <aura:attribute name="preferredLanguage" type="String"/>
    <aura:attribute name="streetAddress" type="String"/>
    <aura:attribute name="zip" type="String"/>
    <aura:attribute name="city" type="String"/>
    <aura:attribute name="state" type="String"/>
    <aura:attribute name="mobile" type="String"/>
    <aura:attribute name="alternatePhone" type="String"/>
<!--    <aura:attribute name="heatFuel" type="String"/>-->
    <aura:attribute name="condoAssoc" type="String"/>
    <aura:attribute name="makeImprovements" type="String"/>
    <aura:attribute name="ownOrRent" type="String"/>
    <aura:attribute name="liveThere" type="String"/>
    <aura:attribute name="howHear" type="String"/>
<!--    <aura:attribute name="promoCode" type="String"/>-->
    <aura:attribute name="whyContactUs" type="String"/>
    <aura:attribute name="gasUtilHolder" type="String"/>
    <aura:attribute name="electricUtilHolder" type="String"/>
    <aura:attribute name="abandonedForm" type="Boolean"/>
    <aura:attribute name="externalLead" type="Boolean"/>

    <!-- Account Attributes -->
    <aura:attribute name="howManyUnits" type="Integer"/>
    <aura:attribute name="yearBuilt" type="String"/>
    <aura:attribute name="sqFeet" type="Integer"/>
    <aura:attribute name="primaryFuel" type="String"/>
    <aura:attribute name="secondaryFuel" type="String"/>
    <aura:attribute name="buildingType" type="String"/>
    <aura:attribute name="homeStyle" type="String"/>
    <aura:attribute name="primaryFuelPercent" type="Integer" default="50"/>
    <aura:attribute name="secondaryFuelPercent" type="Integer" default="50"/>
    <aura:attribute name="landlordName" type="String"/>
    <aura:attribute name="landlordEmail" type="String"/>
    <aura:attribute name="landlordPhone" type="String"/>
    <aura:attribute name="associationName" type="String"/>
    <aura:attribute name="associationEmail" type="String"/>
    <aura:attribute name="associationPhone" type="String"/>
    <aura:attribute name="optOut" type="Boolean" default="false"/>
    <aura:attribute name="gasHolderFirstName" type="String"/>
    <aura:attribute name="gasHolderLastName" type="String"/>
    <aura:attribute name="electricHolderFirstName" type="String"/>
    <aura:attribute name="electricHolderLastName" type="String"/>

    <!-- Accordion Attributes -->
    <aura:attribute name="section" type="String"/>

    <lightning:navigation aura:id="navService"/>

    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <aura:if isTrue="{!!v.toScheduling}">
        <lightning:layout horizontalAlign="spread">
            <lightning:layoutItem size = "2"><lightning:input type="text" label="First Name" value="{!v.ContactInformation.FirstName}" disabled="true"/></lightning:layoutItem>
            <lightning:layoutItem size = "2"><lightning:input type="text" label ="Last Name" value="{!v.ContactInformation.LastName}" disabled="true"/></lightning:layoutItem>
            <lightning:layoutItem size = "2"><lightning:input type="text" label = "Email" value="{!v.ContactInformation.Email}" disabled="true"/></lightning:layoutItem>
            <lightning:layoutItem size = "2"><lightning:input type="text" label = "Phone" value="{!v.ContactInformation.Phone}" disabled="true"/></lightning:layoutItem>
            <lightning:layoutItem size = "2"><lightning:input type="text" label = "Zip Code" value="{!v.ContactInformation.MailingPostalCode}" disabled="true"/></lightning:layoutItem>
        </lightning:layout>

        <lightning:accordion aura:id="accordion" allowMultipleSectionsOpen="true" activeSectionName="{!v.section}" onsectiontoggle="{!c.handleSectionToggle}">
            <lightning:layout class="slds-align_absolute-center">
                <lightning:layoutItem size = "6" padding="around-small">
                    <aura:if isTrue="{!v.showError}">
                        <div id="error" class="errormessage">
                            <lightning:input value="{!v.errorMessage}" readonly="true"/>
                        </div>
                    </aura:if>
                    
                    <br/>
                    <lightning:accordionSection name="reason" label="What brought you here today">
                        <lightning:combobox options="{!v.opHear}" value="{!v.howHear}" aura:id="howHear" class="widthFix" required="true" label="How did you hear about us?"/>
                        <lightning:combobox options="{!v.opWhyContactUs}" value="{!v.whyContactUs}" aura:id="whyContactUs" class="widthFix" required="true" label="What is the primary reason you contacted us?"/>
                    </lightning:accordionSection>
                    <lightning:accordionSection name="home" label="Tell us a bit more about your home">
                        <lightning:combobox options="{!v.opPrimaryFuel}" value="{!v.primaryFuel}" aura:id="primFuel" class="widthFix" required="true" label="What is your primary heat fuel?"/>
                        <lightning:input type="text" value="{!v.streetAddress}" maxlength="100" aura:id="streetAddress" class="input" required="true" label="Street Address"/>
                        <lightning:input type="text" value="{!v.zip}" maxlength="10" aura:id="zip" class="input" required="true" label="Zip"/>
                        <lightning:input type="text" value="{!v.city}" maxlength="25" aura:id="city" class="input" required="true" label="City"/>
                        <lightning:input type="text" value="{!v.state}" maxlength="10" aura:id="state" class="input" required="true" label="State"/>
                        <lightning:input type="text" value="{!v.mobile}" maxlength="12" aura:id="mobile" class="input" required="false" label="Mobile Phone"/>
                        <lightning:input type="text" value="{!v.alternatePhone}" maxlength="12" aura:id="alternatePhone" class="input" label="Alternate Phone"/>
                        <lightning:combobox options="{!v.opOwnRent}" value="{!v.ownOrRent}" aura:id="ownOrRent" class="widthFix" label="Are you the owner, tenant or landlord?"/>
                        <aura:if isTrue="{!v.ownOrRent == 'Tenant'}">
                            <lightning:input type="text" value="{!v.landlordName}" maxlength="100" aura:id="landlordName" class="input" label="Landlord Name"/>
                            <lightning:input type="email" value="{!v.landlordEmail}" maxlength="255" aura:id="landlordEmail" class="input" label="Landlord Email"/>
                            <lightning:input type="tel" value="{!v.landlordPhone}" maxlength="40" aura:id="landlordPhone" class="input" label="Landlord Phone"/>
                        </aura:if>
                        <aura:if isTrue="{!or(v.ownOrRent == 'Owner', v.ownOrRent == 'Landlord')}">
                            <lightning:combobox options="{!v.opLive}" value="{!v.liveThere}" aura:id="liveThere" class="widthFix" label="Do you reside in this dwelling?"/>
                        </aura:if>
<!--                        <aura:if isTrue="{!v.ownOrRent == 'Owner'}">-->
<!--                            <lightning:combobox options="{!v.opLive}" value="{!v.liveThere}" aura:id="liveThere" class="widthFix" label="Do you own or rent?"/>-->
<!--                        </aura:if>-->
                        <lightning:combobox options="{!v.opBuildingType}" value="{!v.buildingType}" aura:id="homeStyle" class="widthFix" label="What is your building type?"/>
                      <!--  <lightning:combobox options="{!v.opHowManyUnits}" value="{!v.howManyUnits}" aura:id="units" class="widthFix" label="How many units?"/> -->
                        <lightning:combobox options="{!v.opHomeStyle}" value="{!v.homeStyle}" aura:id="homeStyle" class="widthFix" label="What is the home style?"/>
                        <lightning:input aura:id="yearBuilt" class="input" value="{!v.yearBuilt}" minlength="4" maxlength="4" label="What year was your home built?"/>
                        <lightning:combobox options="{!v.opSquareFeet}" value="{!v.sqFeet}" aura:id="squareFeet" class="widthFix" label="The approximate Square footage of living space, (not including garage, basements, attic)"/>
                        <lightning:combobox options="{!v.opCondo}" value="{!v.condoAssoc}" aura:id="condoAss" class="widthFix" label="Do you have a Condo Association?"/>
                        <lightning:input type="checkbox" value="{!v.optOut}" onchange="{!c.optOutOfEmails}" aura:id="optOut" class="input" label="Opt Out of Promotional Emails"/>
                      <!--  <aura:if isTrue="{!v.condoAssoc == 'Yes'}">
                            <lightning:combobox options="{!v.opMakeImprove}" value="{!v.makeImprovements}" aura:id="makeImprovs" class="widthFix" label="Can you make improvements to your building without association approval?"/>
                            <aura:if isTrue="{!v.makeImprovements == 'No'}">
                                <lightning:input type="text" value="{!v.associationName}" maxlength="100" aura:id="associationName" class="input" label="Association Name"/>
                                <lightning:input type="email" value="{!v.associationEmail}" maxlength="255" aura:id="associationEmail" class="input" label="Association Email"/>
                                <lightning:input type="tel" value="{!v.associationPhone}" maxlength="40" aura:id="associationPhone" class="input" label="Association Phone"/>
                            </aura:if>
                        </aura:if> -->
                    </lightning:accordionSection>
                    <lightning:accordionSection name="account" label="Account information">
                        <aura:if isTrue="{!v.primaryFuel == 'Natural Gas'}">
                        <lightning:input type="text" value="{!v.gasUtilityNumber}" maxlength="100" aura:id="gasUtilNumber" class="input" required="false" label="Gas Utility Number"/>
                        <lightning:combobox options="{!v.opGasUtilHolder}" value="{!v.gasUtilHolder}" aura:id="gasUtilHolder" class="widthFix" label="Are you listed as the Gas Account holder?"/>
                        <aura:if isTrue="{!v.gasUtilHolder == 'No'}">
                            <lightning:input type="text" value="{!v.gasHolderFirstName}" maxlength="100" aura:id="gasHolderFirstName" class="input" label="Gas Account Holder First Name"/>
                            <lightning:input type="text" value="{!v.gasHolderLastName}" maxlength="100" aura:id="gasHolderLastName" class="input" label="Gas Account Holder Last Name"/>
                        </aura:if>
                        </aura:if>
                        <lightning:input type="text" value="{!v.electricUtilityNumber}" maxlength="100" aura:id="electricUtilNumber" class="input" required="false" label="Electric Utility Number"/>
                        <lightning:combobox options="{!v.opElectricUtilHolder}" value="{!v.electricUtilHolder}" aura:id="electricUtilHolder" class="widthFix" label="Are you listed as the Electric Account holder?"/>
                        <aura:if isTrue="{!v.electricUtilHolder == 'No'}">
                            <lightning:input type="text" value="{!v.electricHolderFirstName}" maxlength="100" aura:id="electricHolderFirstName" class="input" label="Electric Account Holder First Name"/>
                            <lightning:input type="text" value="{!v.electricHolderLastName}" maxlength="100" aura:id="electricHolderLastName" class="input" label="Electric Account Holder Last Name"/>
                        </aura:if>
                    </lightning:accordionSection>
                </lightning:layoutItem>
            </lightning:layout>
        </lightning:accordion>

        <div class="slds-text-align--right">
            <lightning:button variant="brand-outline" class="slds-m-right_medium" label="Exit" name="cancel" onclick="{!c.navigateToHomePage}" aura:id="exitToHome"/>
            <lightning:button variant="brand-outline" class="slds-m-right_medium" label="Don’t Have Account Information" name="cancel" onclick="{!c.navigateToSchedulingSupport}" aura:id="schedulingSupport"/>
            <lightning:buttonGroup>
                <lightning:button variant="brand" label="Book Appointment" name="schedule" onclick="{!c.completeRegistration}" aura:id="submitreg"/>
            </lightning:buttonGroup>
        </div>

    </aura:if>
    <aura:if isTrue="{!v.toScheduling}">
       <c:FSL_AppointmentBooking></c:FSL_AppointmentBooking>
    </aura:if>
</aura:component>


 
I have an account list view lightning component that i would like to add a button so users can select an account from the list view click the button to add the account to a custom object record but i am not sure how to accomplish this and I'm looking for help. Can i use a flow button inside the lightning coponent? or maybe create a quick action button and add it to the component? My code is below.

Controller
({
    onAccountsLoaded: function( component, event, helper ) {
        var cols = [
            {
                'label': 'Name',
                'fieldName': 'Name',
                'type': 'text'
            },
            {
                'label': 'External ID',
                'fieldName': 'External_ID__c',
                'type': 'text'
            },
            {
                'label': 'Utility Number',
                'fieldName': 'Utility_Number__c',
                'type': 'text'
            },
            {
                'label': 'Active Utility Customer?',
                'fieldName': 'Active_Utility_Customer__c',
                'type': 'checkbox'
                                
            },
            {
                'label': 'Action',
                'type': 'button',
                'typeAttributes': {
                    'label': 'View details',
                    'name': 'view_details'
                }
            }
        ];
        component.set( 'v.cols', cols );
        component.set( 'v.rows', event.getParam( 'accounts' ) );
    },
    onRowAction: function( component, event, helper ) {
        var action = event.getParam( 'action' );
        var row = event.getParam( 'row' );
        if ( action.name == 'view_details' ) {
            var navigation = component.find( 'navigation' );
            navigation.navigate({
                'type': 'standard__recordPage',
                'attributes': {
                    'objectApiName': 'Account',
                    'recordId': row.Id,
                    'actionName': 'view'
                }
            });
        }
    }
})
Aura Component
 
<aura:component>
    <aura:handler event="c:AccountsLoaded" action="{!c.onAccountsLoaded}"/>
    <lightning:navigation aura:id="navigation"/>
    <aura:attribute name="rows" type="Map[]"/>
    <aura:attribute name="cols" type="Map[]"/>
    <lightning:card title="Account List" iconName="standard:account">
        <lightning:datatable
            data="{!v.rows}"
            columns="{!v.cols}"
            keyField="Id"
            hideCheckboxColumn="false"
            showRowNumberColumn="true"
            onrowaction="{!c.onRowAction}"/>
    </lightning:card>
</aura:component>


 
I have a lightning component that is used in a customer community and needs to be updated so it is mobile friendly. I have not done this before and would like some help with updating my code below. Right now it does not render well at all. 
 
<aura:component implements="flexipage:availableForAllPageTypes,forceCommunity:availableForAllPageTypes,force:hasRecordId,flexipage:availableForRecordHome" access="global"
                controller="acme_fsl_AppointmentBooking">



    <aura:attribute name="debug" type="Boolean" default="false"/>

    <aura:attribute name="loading" type="Boolean" default="true"/>
    <aura:attribute name="showSpinner" type="Boolean" default="true"/>
    <aura:attribute name="isEligible" type="Boolean" default="true"/>
    <aura:attribute name="showError" type="Boolean" default="false"/>
    <aura:attribute name="errorMessage" type="String"/>
    <aura:attribute name="rowCount" type="Integer" default="4"/>
    <aura:attribute name="isOpen" type="boolean" default="false"/>


    <aura:attribute name="data" type="Object" default="{}"/>
    <aura:attribute name="slotList" type="List" default="[]"/>
    <aura:attribute name="allSlots" type="List" default="[]"/>
    <aura:attribute name="workOrderId" type="Id"/>
    <aura:attribute name="serviceAppointmentId" type="Id"/>
    <aura:attribute name="selectedDate" type="Date"/>
    <aura:attribute name="todayDate" type="Date"/>
    <aura:attribute name="currentUser" type="User"/>
	<force:recordData aura:id="recordLoader" recordId="{!$SObjectType.CurrentUser.Id}" fields="Account.BillingStreet, Account.BillingCity, Account.BillingState, Account.BillingCountry, Account.BillingPostalCode" targetFields="{!v.currentUser}"/> 
    <aura:handler name="init" value="{!this}" action="{!c.initCmpData}"/>
    <aura:handler name="change" value="{!v.selectedDate}" action="{!c.getFilterApptSlots}"/>
    <aura:if isTrue="{!v.debug}">
        Debug<br/>
        recId {!v.recordId}<br/>
        data {!v.data.slots.length}<br/>
        todayDate {!v.todayDate}<br/>
        selectedDate {!v.selectedDate}<br/>
        isEligible {!v.isEligible} <br/>
    </aura:if>

    <aura:if isTrue="{!v.loading}">
        <aura:if isTrue="{!v.showSpinner}">
            <lightning:spinner/>
        </aura:if>
        <aura:set attribute="else">
            <aura:if isTrue="{!v.isEligible}">
                <div class="cmpWrapper">
                    <lightning:layout multipleRows="true">
                        <lightning:layoutItem size="4" padding="around-small">
                            <span class="calWrapper">
                                
                                <center>
                                 
                                    <c:DatePicker aura:id="closeDate" label="Select a preferred appointment date to view availability"
                                                  placeholder="Date"
                                                  value="{!v.selectedDate}"
                                                  formatSpecifier="MM/dd/yyyy" />
                                </center>
                            </span>
                            
                            
                            <br/>
                             <aura:if isTrue="{!v.isEligible}">
                                 <center><br/>
            <div class="slds-float_leftX additionalOption slds-p-bottom_xx-small">
               <h2> Not seeing any results or can’t find an appointment that fits your needs? Contact us at (800) 422-5365.</h2>
                
            </div>
        </center>
        <br/>
            
    </aura:if>
    <center>
        <!-- removing create a case access-->
        <!-- <a href="./contactsupport">
            <lightning:button label="Create Case" variant="brand"/>
        </a> -->
    </center>
                    </lightning:layoutItem>
                        <lightning:layoutItem size="8" padding="around-small">
                            <span class="slotsWrapper">
                                <center>
                               
                                    <aura:iteration items="{!v.slotList}" var="slot" indexVar="i">
                                       <aura:if isTrue="{!(i > v.rowCount) == false}">
                                           
                                           
                                            <c:AdVic_BookingSlot slot="{!slot}" workOrderId="{!v.workOrderId}" serviceAppointmentId="{!v.serviceAppointmentId}"/>
                                        </aura:if>
                                       </aura:iteration>
                                    <lightning:button label="Display Additional Appointments" onclick="{!c.showMore}" variant="brand"/>
                                </center>
                            </span>
                        </lightning:layoutItem>
                    </lightning:layout>
                    
                    
                    
                    
                    
                    

                   
                </div>
                <aura:set attribute="else">
                    <lightning:icon iconName="utility:warning" alternativeText="Customer Not Eligible"
                                    variant="Warning" title="Not Eligible" class="notification-icon"/>
                    <aura:if isTrue="{!v.showError}">
                        <div id="error">
<!--                            <lightning:input value="{!v.errorMessage}" readonly="true"/>-->
                           
                        </div>
                        <aura:set attribute="else">
                            <br/>
                        </aura:set>
                    </aura:if>
                    <br/>
                    <span>{!v.errorMessage}</span>
                </aura:set>
            </aura:if>
        </aura:set>
    </aura:if>

    <br/>
    <br/>
   
</aura:component>


 
I have an account list view lightning component that i would like to add a button so users can select an account from the list view click the button to add the account to a custom object record but i am not sure how to accomplish this and I'm looking for help. Can i use a flow button inside the lightning coponent? or maybe create a quick action button and add it to the component? My code is below. 
User-added image
Controller
({
    onAccountsLoaded: function( component, event, helper ) {
        var cols = [
            {
                'label': 'Name',
                'fieldName': 'Name',
                'type': 'text'
            },
            {
                'label': 'External ID',
                'fieldName': 'External_ID__c',
                'type': 'text'
            },
            {
                'label': 'Utility Number',
                'fieldName': 'Utility_Number__c',
                'type': 'text'
            },
            {
                'label': 'Active Utility Customer?',
                'fieldName': 'Active_Utility_Customer__c',
                'type': 'checkbox'
                                
            },
            {
                'label': 'Action',
                'type': 'button',
                'typeAttributes': {
                    'label': 'View details',
                    'name': 'view_details'
                }
            }
        ];
        component.set( 'v.cols', cols );
        component.set( 'v.rows', event.getParam( 'accounts' ) );
    },
    onRowAction: function( component, event, helper ) {
        var action = event.getParam( 'action' );
        var row = event.getParam( 'row' );
        if ( action.name == 'view_details' ) {
            var navigation = component.find( 'navigation' );
            navigation.navigate({
                'type': 'standard__recordPage',
                'attributes': {
                    'objectApiName': 'Account',
                    'recordId': row.Id,
                    'actionName': 'view'
                }
            });
        }
    }
})

Aura Component
 
<aura:component>
    <aura:handler event="c:AccountsLoaded" action="{!c.onAccountsLoaded}"/>
    <lightning:navigation aura:id="navigation"/>
    <aura:attribute name="rows" type="Map[]"/>
    <aura:attribute name="cols" type="Map[]"/>
    <lightning:card title="Account List" iconName="standard:account">
        <lightning:datatable
            data="{!v.rows}"
            columns="{!v.cols}"
            keyField="Id"
            hideCheckboxColumn="false"
            showRowNumberColumn="true"
            onrowaction="{!c.onRowAction}"/>
    </lightning:card>
</aura:component>

 
I was wondering if I can update this segment of code to look at a formula field that uses date & time thats adds at least 60 days or how i can update this piece of code like  if(slotStartDay > Date.today() +60?  I tried addDays(60) and Date.today() +60 and when i tried to search for avialable appointment slots nothing was displayed

 
List<AppointmentBookingSlot> slotList = new List<AppointmentBookingSlot>();
        for(FSL.AppointmentBookingSlot slot : slots){
            DateTime slotStartDT = slot.interval.start;
            DateTime slotFinishDT = slot.interval.finish;
            Date slotStartDay = slotStartDT.date();
            
            if(slotStartDay > Date.today() ){
                AppointmentBookingSlot newSlot = new AppointmentBookingSlot();
                Interval times = new Interval();
                times.startDT = slot.interval.start;
                times.endDT = slot.interval.finish;
                newSlot.grade = slot.grade;
                newSlot.times = times;
                slotList.add(newSlot);
            }
        }
        System.debug('slotList:: '+ slotList);
       
        
        //return setToTimeZone(slotList);
        return slotList;
    }
    
    public static DateTime utcToUserTimezone(DateTime utcDT){
        DateTime userDT = utcDT;
        String utcDtString = utcDT.format('yyyy-MM-dd HH:mm:ss', 'UTC');
        //String utcDtString = utcDT.format('yyyy-MM-dd hh:mm a', 'UTC');

        System.debug('@@@@ str: '+utcDtString);
        userDT = DateTime.valueOf(utcDtString);
        System.debug('@@@@ DT: '+userDT);
        return userDT;
    }

 
  • April 20, 2022
  • Like
  • 0
I am trying to use a link to a site in an email where a custom can click on it and select preferences for communications. The flow on the site works fine but i am trying to correctly formulate a link to have the contactId (conId)in it but i'm not sure if i have this link correct because when i test this link I dont see the contact first and last name.  Can anyone help with how the link should be built to show the contact's information

User-added imageUser-added image
  • January 10, 2022
  • Like
  • 0
The Book Appointment feature on a work order only goes out 30 days from the Earliest Start Permitted date. I am looking to see if there is something custom already created that would extend the 30 day window to 60 days if a user executed something like an embedded flow.. Is there anything already created that performs this functionality 
  • January 03, 2022
  • Like
  • 0
I have just created a new community site and added a flow. This community will be use as a link in a email that is sent to contacts. The contact receieves the email and clicks on the link. The flow on the site allows the contact to upload photos and once they click the submit button. The photos are attached to the contacts record within salesforce.

The community has nothing else on but the flow, but when I do test email and click on the link it gives me the Flow Finished message and the flow did not run.  

User-added image

The flow has a get element for the contactid and file upload inputs. 
My site has public access too so im not sure if i am missing a setting somewhere. 
My link in my email template is formatted like below

https://acme.force.com/veaphotos/s/?=ContactId%3D0036g000000000

any help would be greatly appreciated. maybe another way to present this flow to the public? 

 
  • December 23, 2021
  • Like
  • 0

I am trying to avoid creating a separate community and build out an entirely new community for two sets of users.
 
Is there a way to share a community with the ability to hide or expose certain pages, functionality and permissions with two profiles?
 
Profile 1 - Does not have permission to create Accounts, Work Orders, Service Orders, etc. 
 
Profile 2 - Has permissions to create Accounts, Enable Portal Accounts, Work Orders, Service Orders, etc. 
 
If the above is not possible:
Is there the ability to clone an existing community without needing to build a new community? 
  • November 04, 2021
  • Like
  • 0
Is there a flow or process builder workflow that has the ability to do the following.
 
When a note is created from any object that is associated to an account, it is automatically shared with that account and can be seen from the account page. I can do this manually using the Add to Records feature. But I am trying to eliminate a users remembering to do this step every time

User-added image
  • November 04, 2021
  • Like
  • 0
I have a flow that some else created and it is not working correctly.

How it should Works:

User starts from a Contact record and clicks New Work Order/s button
flow screen pops up for user to selected multiple account related to the contact.
When the user clicks the next button the flow should create new work orders for both locations related to the contact but it only creates work orders for the first location. Even If you select multiple checkboxes it will create two work orders with the same location. 

The screenshots below are part of the flow. If anyone can help that would be appreciate 

User-added imageUser-added imageUser-added imageUser-added imageUser-added image
 
  • October 29, 2021
  • Like
  • 0
I was wondering if there is a way to add an opt -out option when you send a SMS message through a flow. 
  • September 30, 2021
  • Like
  • 0
I have a flow that is trying to update records, but users are getting the following error message

This error occurred when the flow tried to update records: Too many SOQL queries: 101

Is there any criteria I can add to the update element to stop this from happening? 
  • August 25, 2021
  • Like
  • 0
I made an update to a apex test class but when i try to deploy it give me the following error. I'm not sure how to fix this

System.QueryException: List has no rows for assignment to SObject
Stack Trace: Class.advic_fsl_AppointmentBooking.scheduleServiceAppointment: line 71, column 1 Class.advic_fsl_AppointmentBookingTest.testScheduleServiceAppointment: line 146, column 1

here is the test class below. i will post the apex class too
 
@isTest
private class advic_fsl_AppointmentBookingTest {

    @testSetup
    static void setup() {
        // Create test data
        // Create Scheduling Policy
        FSL__Scheduling_Policy__c schedulingPolicy = new FSL__Scheduling_Policy__c(FSL__Commit_Mode__c='AlwaysCommit', FSL__Fix_Overlaps__c=false, FSL__Daily_Optimization__c=false,
                Name='Customer First', FSL__Travel_Mode__c=false);
        insert schedulingPolicy;
        // Create Operating Hours
        OperatingHours operatingHours = new OperatingHours(Description='Testing Hours', Name='Energy Assessment Calendar', TimeZone='America/New_York');
        insert operatingHours;
        // Create Time Slots
        List<TimeSlot> timeSlots = new List<TimeSlot>();
        timeSlots.add(new TimeSlot(DayOfWeek='Monday', Type='Normal', OperatingHoursId=operatingHours.Id,
                StartTime=Time.newInstance(10,0,0,0), EndTime=Time.newInstance(12,0,0,0)));
        timeSlots.add(new TimeSlot(DayOfWeek='Tuesday', Type='Normal', OperatingHoursId=operatingHours.Id,
                StartTime=Time.newInstance(10,0,0,0), EndTime=Time.newInstance(12,0,0,0)));
        insert timeSlots;
        Account testAccount = new Account(Name='Test Account', Customer_Eligible__c=true);
        insert testAccount;
        Contact testContact = new Contact(AccountId=testAccount.Id, LastName='TestContact');
        insert testContact;
        Profile riseCommunityCustomerProfile = [SELECT Id FROM Profile WHERE Name='RISE Community Customer User'];
        User runningUser = new User(Alias = 'standt', Email='standarduser@testorg.com', EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US',
                LocaleSidKey='en_US', ProfileId = riseCommunityCustomerProfile.Id, TimeZoneSidKey='America/New_York', UserName='standarduser@testorg.com',
                ContactId=testContact.Id);
        insert runningUser;
        
        
        WorkType eaIh  = new WorkType();
        eaIh.Name = 'Energy Assessment - In Home';
        eaIh.EstimatedDuration = 90.0;
        insert eaIh;
        
        
    }

    static testMethod void testCreateWorkOrderAndServiceAppointment() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT Id FROM User WHERE ContactId =: contact.Id];

        

        List<WorkOrder> insertedWorkOrders = [SELECT AccountId, ContactId FROM WorkOrder];
        List<ServiceAppointment> insertedServiceAppointments = [SELECT AccountId, ContactId, ParentRecordId, EarliestStartTime, DueDate FROM ServiceAppointment ];

      
       

        if(insertedWorkOrders.size() == 1) {
            WorkOrder insertedWorkOrder = insertedWorkOrders[0];
            System.assertEquals(account.Id, insertedWorkOrder.AccountId, 'The Work Order AccountId was not assigned.');
            System.assertEquals(contact.Id, insertedWorkOrder.ContactId, 'The Work Order ContactId was not assigned.');

            if(insertedServiceAppointments.size() == 1) {
                ServiceAppointment insertServiceAppointment = insertedServiceAppointments[0];
                System.assertEquals(account.Id, insertServiceAppointment.AccountId, 'The Service Appointment AccountId was not assigned.');
                System.assertEquals(contact.Id, insertServiceAppointment.ContactId, 'The Service Appointment ContactId was not assigned.');
                System.assertEquals(insertedWorkOrder.Id, insertServiceAppointment.ParentRecordId, 'The Work Order that was inserted was not assigned to the inserted Service Appointment.');
                System.assert(insertServiceAppointment.EarliestStartTime != null, 'The Service Appointment EarliestStartTime was not populated.');
                System.assert(insertServiceAppointment.DueDate != null, 'The Service Appointment DueDate was not populated.');
            }
        }
    }

    static testMethod void testGetAppointmentSlots() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];

        WorkOrder testWorkOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId);
        insert testWorkOrder;
        ServiceAppointment testServiceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=testWorkOrder.Id, EarliestStartTime=Datetime.now(), DueDate=Datetime.now().addMonths(1));
        insert testServiceAppointment;

        Test.startTest();
            advic_fsl_AppointmentBooking.CmpData data = advic_fsl_AppointmentBooking.getAppointmentSlots(testWorkOrder.Id, testServiceAppointment.Id);
        Test.stopTest();

        // Letting the managed package tests control the FSL methods and test them.
        // The method itself is covered in the FSL managed package tests.
    }

    static testMethod void testUndeleteWorkOrderAndServiceAppointment() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];

        WorkOrder testWorkOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId);
        insert testWorkOrder;
        ServiceAppointment testServiceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=testWorkOrder.Id, EarliestStartTime=Datetime.now(), DueDate=Datetime.now().addMonths(1));
        insert testServiceAppointment;

        delete testWorkOrder;

        Test.startTest();
            advic_fsl_AppointmentBooking.undeleteWorkOrderAndServiceAppointment(testWorkOrder.Id, testServiceAppointment.Id);
        Test.stopTest();

        System.assertEquals(1, [SELECT Id FROM WorkOrder WHERE Id =: testWorkOrder.Id].size(), 'The Work Order was not undeleted.');
        System.assertEquals(1, [SELECT Id FROM ServiceAppointment WHERE Id =: testServiceAppointment.Id].size(), 'The Service Appointment was not undeleted');
    }

    static testMethod void testUpdateServiceAppointment() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];

        WorkOrder testWorkOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId);
        insert testWorkOrder;
        ServiceAppointment testServiceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=testWorkOrder.Id, EarliestStartTime=Datetime.now(), DueDate=Datetime.now().addMonths(1));
        insert testServiceAppointment;

        String slotJSON = '{"grade":100,"times":{"endDT":"2020-06-02T15:00:00.000Z","startDT":"2020-06-02T13:00:00.000Z"}}';

        System.runAs(runningUser) {
            Test.startTest();
            advic_fsl_AppointmentBooking.updateServiceAppointment(slotJSON, testServiceAppointment.Id, 'abc', 'xyz');
            Test.stopTest();
        }

        ServiceAppointment serviceAppointment = [SELECT ArrivalWindowStartTime, ArrivalWindowEndTime FROM ServiceAppointment WHERE Id =: testServiceAppointment.Id];

        DateTime arrivalWindowStartTime = (DateTime)json.deserialize('"2020-06-02T13:00:00.000Z"', datetime.class);
        DateTime arrivalWindowEndTime = (DateTime)json.deserialize('"2020-06-02T15:00:00.000Z"', datetime.class);

        //System.assertEquals(arrivalWindowStartTime, serviceAppointment.ArrivalWindowStartTime, 'The Service Appointment ArrivalWindowStartTime is incorrect.');
        //System.assertEquals(arrivalWindowEndTime, serviceAppointment.ArrivalWindowEndTime, 'The Service Appointment ArrivalWindowEndTime is incorrect.');
    }

    static testMethod void testScheduleServiceAppointment() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];

        WorkOrder testWorkOrder = new WorkOrder(AccountId=runningUser.AccountId, ContactId=runningUser.ContactId);
        insert testWorkOrder;
        ServiceAppointment testServiceAppointment = new ServiceAppointment(ContactId=runningUser.ContactId, ParentRecordId=testWorkOrder.Id,
                EarliestStartTime=Datetime.now(), DueDate=Datetime.now().addMonths(1), ArrivalWindowStartTime=Datetime.now(), ArrivalWindowEndTime=Datetime.now().addMonths(1), Status = 'Scheduled');
        insert testServiceAppointment;

        Test.startTest();
            advic_fsl_AppointmentBooking.scheduleServiceAppointment(testServiceAppointment.Id);
        Test.stopTest();

        // Letting the managed package tests control the FSL methods and test them.
        // The method itself is covered in the FSL managed package tests.
    }

    static testMethod void testCheckAccountEligibility_NoAccounts() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'DISC';
        account.Square_Footage__c = '';
        account.Building_Type__c = 'Single-Family Home';
        contact.Part_of_Condo_Association__c = 'No';
        update account;
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
                eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Due to your utility service rate code, we are not able to service your property. Please contact your local Community Action Partnership, or call our offices for more information. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335. Thank you.', eligibilityStatus, 'The Account should be ineligible.');
    }
    static testMethod void testCheckAccountEligibility_NoAccounts1() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'COM';
        account.Square_Footage__c = '';
        account.Building_Type__c = 'Single-Family Home';
        contact.Part_of_Condo_Association__c = 'No';
        update account;
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
                eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Due to the commercial rate code on this property, we are not able to schedule a residential No-Cost Energy Assessment. Please contact out office for further assistance at 401-784-3700.', eligibilityStatus, 'The Account should be ineligible.');
    }
    static testMethod void testCheckAccountEligibility_NoAccounts2() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'PP';
        account.Square_Footage__c = '';
        account.Building_Type__c = 'Single-Family Home';
        contact.Part_of_Condo_Association__c = 'No';
        update account;
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
                eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('We are not able to schedule you a No-Cost energy assessment due to the recent participation in the program. For further assistance, please contact our offices. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335. Thank you.', eligibilityStatus, 'The Account should be ineligible.');
    }
    static testMethod void testCheckAccountEligibility_NoAccounts3() {
        Account account = [SELECT Id FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'AMA';
        account.Square_Footage__c = '';
        account.Building_Type__c = 'Single-Family Home';
        contact.Part_of_Condo_Association__c = 'No';
        update account;
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
                eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335.', eligibilityStatus, 'The Account should be ineligible.');
    }

    static testMethod void testCheckAccountEligibility_GasAccountEligible() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Eligible_Testing__c = true;
        account.Building_Type__c = 'Single-Family Home';
        account.Square_Footage__c = '2000-3000 sq ft';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        contact.Part_of_Condo_Association__c = 'No';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Eligible', eligibilityStatus, 'The Contact should be eligible.');
    }

    static testMethod void testCheckAccountEligibility_GasAccountIneligible() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Ineligible_Reason_Code__c = 'DISC';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Due to your utility service rate code, we are not able to service your property. Please contact your local Community Action Partnership, or call our offices for more information. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335. Thank you.', eligibilityStatus, 'The General Error message should have returned.');
    }
     static testMethod void testCheckAccountEligibility_GasAccountIneligible1() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Ineligible_Reason_Code__c = 'COM';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Due to the commercial rate code on this property, we are not able to schedule a residential No-Cost Energy Assessment. Please contact out office for further assistance at 401-784-3700.', eligibilityStatus, 'The General Error message should have returned.');
    }
    static testMethod void testCheckAccountEligibility_GasAccountIneligible2() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Ineligible_Reason_Code__c = 'PP';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('We are not able to schedule you a No-Cost energy assessment due to the recent participation in the program. For further assistance, please contact our offices. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335. Thank you.', eligibilityStatus, 'The Contact should be eligible.');
    }
    static testMethod void testCheckAccountEligibility_GasAccountIneligible3() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Gas_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Ineligible_Reason_Code__c = 'AMA';
        update account;
        contact.Gas_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Natural Gas';
        update contact;

        String eligibilityStatus = '';
        System.runAs(runningUser) {
            Test.startTest();
            eligibilityStatus = advic_fsl_AppointmentBooking.checkAccountEligibility();
            Test.stopTest();
        }

        System.assertEquals('Thank you for your inquiry, we are unable to complete your request at this time. For further assistance, please contact our offices. For National Grid Rhode Island customers dial 888-633-7947. For National Grid Cape Cod or Cape Light Compact customers dial 774-352-1022. For Eversource, Liberty or Unitil customers dial 339-502-6335.', eligibilityStatus, 'The Contact should be eligible.');
    }

   
  

    

        
    static testMethod void testCheckAccountEligibility_ElectricAccountIneligibleq1() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Electric_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'COM';
        update account;
        contact.Electric_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Electric';
        update contact;

    }
    static testMethod void testCheckAccountEligibility_ElectricAccountIneligible2() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Electric_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'PP';
        update account;
        contact.Electric_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Electric';
        update contact;

    }     
    static testMethod void testCheckAccountEligibility_ElectricAccountIneligible3() {
        Account account = [SELECT Id, Utility_Number__c, Eligible_Testing__c, Ineligible_Reason_Code__c FROM Account WHERE Customer_Eligible__c = true LIMIT 1];
        Contact contact = [SELECT Id, Electric_Utility_Number__c, How_do_you_heat_your_home__c FROM Contact WHERE AccountId =: account.Id];
        User runningUser = [SELECT AccountId, ContactId FROM User WHERE ContactId =: contact.Id];
        account.Utility_Number__c = '14356';
        account.Eligible_Testing__c = false;
        account.Ineligible_Reason_Code__c = 'AMA';
        update account;
        contact.Electric_Utility_Number__c = '14356';
        contact.How_do_you_heat_your_home__c = 'Electric';
        update contact;

               }
}
  • August 03, 2022
  • Like
  • 0
I have a lightning component that i have updated with a new picklist field but when i enter a value in the component it does not save to the record in salesforce. Where should i look to set this value so it saves to the record?
User-added imageUser-added image
I urgently need help with adding a spinner to a lightning component. right now there is a pause when the component is looking for available time slots. There is one component that call another component to find time slots. I need a spinner displayed while the called component is get those time slots. I've tried a few different things with no success.

No Tutorials please, i need actual help on the placement of the spinner in the code 

The first component calling to the BookSlot component
 
<aura:iteration items="{!v.slotList}" var="slot" indexVar="i">
                                       <aura:if isTrue="{!(i > v.rowCount) == false}">
                                           
                                      <c:BookingSlot slot="{!slot}" workOrderId="{!v.workOrderId}" serviceAppointmentId="{!v.serviceAppointmentId}"/>
                                        </aura:if>
                                       </aura:iteration>

BookingSlot Component:
 
<aura:component controller="AppointmentBooking" description="Books the slot for a given Service Appointment">

    
    <aura:attribute name="debug" type="boolean" default="false"/>
    <aura:attribute name="isOpen" type="boolean" default="false"/>
    <aura:attribute name="slot" type="Object"/>
    <aura:attribute name="workOrderId" type="Id"/>
    <aura:attribute name="serviceAppointmentId" type="Id"/>
    <aura:attribute name="detailsAccount" type="String"/>
    <aura:attribute name="detailsSA" type="String"/>
    

    
      
    <aura:if isTrue="{!v.debug}">
                
        open={!v.isOpen}<br/>
        serviceAppointmentId={!v.serviceAppointmentId}<br/>
        slot={!v.slot}
            
    </aura:if>    
       

    <span class="apptSlot" onclick="{!c.openModel}">
        
           <center class="slotPill">
            <lightning:progressBar value="{!v.slot.grade}" size="large" class="rankBar" title="{!'Rank: '+v.slot.grade}"/>
            <lightning:formattedDateTime value="{!v.slot.times.startDT}" weekday="long" year="numeric" month="short" day="2-digit" hour="2-digit"
                                         minute="2-digit" hour12="true" timeZone="UTC"/>
            -
            <lightning:formattedDateTime value="{!v.slot.times.endDT}" hour="2-digit" minute="2-digit" hour12="true" timeZone="UTC"/>
        </center>
           
    </span>
 
    <aura:if isTrue="{!v.isOpen}">
        <section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open slds-modal_small">
            <div class="slds-modal__container">
                <header class="slds-modal__header">
                    <lightning:buttonIcon iconName="utility:close"
                                          onclick="{! c.closeModal }" 
                                          alternativeText="close"
                                          variant="bare-inverse"
                                          class="slds-modal__close"/>
                    <h1 class="slds-text-heading--small">Confirmation</h1>
                </header>
                <div class="slds-modal__content slds-p-around_small" id="modal-content-id-1">
                    <p>
                        <div>You have selected the following slot:</div>
                        <br/>
                        <div class="slds-form_horizontalX slds-formX slds-gridX slds-wrapX">
                            <center>
                                <lightning:formattedDateTime value="{!v.slot.times.startDT}" weekday="long" year="numeric" month="short" day="2-digit" hour="2-digit"
                                                             minute="2-digit" hour12="true" timeZone="UTC"/>
                                -
                                <lightning:formattedDateTime value="{!v.slot.times.endDT}" hour="2-digit" minute="2-digit" hour12="true" timeZone="UTC"/>
                            </center>
                        </div>
                        <br/>
                        <!-- test fields that we need -->
                        <div>
                            <lightning:input type="text" value="{!v.detailsAccount}" class="input" require="true" label="Is there anything additional we need to know to locate your home?"/>
                            <br/>
                            <lightning:input type="text" value="{!v.detailsSA}" class="input" require="true" label="Is there anything else you would like us to know prior to the appointment?"/>
                            <br/>
                        </div>
                        <!-- end test fields that we need -->
                        <div>Please confirm you would like the selected date and time</div>
                    </p>
                </div>
                <footer class="slds-modal__footer">
                     <lightning:button name='Cancel' label='Cancel' onclick='{!c.closeModal}'/>
                     <lightning:button variant="brand" name='Confirm' label='Confirm' onclick='{!c.handleSlotSelected}'/>
                </footer>
            </div>
        </section>
        <div class="slds-backdrop slds-backdrop_open"></div>
     </aura:if>
    
    <br/>
     
</aura:component>

Controller:
({
    handleSlotSelected: function (component, e, helper) {
        console.log('in booking slot component');
        helper.undeleteWorkOrderAndServiceAppointment(component);
        helper.updateServiceAppointment(component); 
        helper.scheduleServiceAppointment(component);
    },
    openModel: function(component) {
        component.set("v.isOpen", true);
    },
    closeModal: function(component) {
        component.set("v.isOpen", false);
    }
   
});

Helper Class:
({
    undeleteWorkOrderAndServiceAppointment : function (component) {
        
        
        
        var workOrderId = component.get("v.workOrderId")
        var serviceAppointmentId = component.get("v.serviceAppointmentId");
       

        var action = component.get("c.undeleteWorkOrderAndServiceAppointment");
            
        action.setParams({
            'workOrderId' : workOrderId,
            'serviceAppointmentId': serviceAppointmentId
            
        });
      
        
        action.setCallback(this, function(response) {
           
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.isOpen", false);
               
            } else {
                let errors = response.getError();
                console.log('Error response: ' + response);
                console.log("Error message: " + errors[0].message);
                
            }
        });

        $A.enqueueAction(action);
    },
    updateServiceAppointment : function (component) {
        var slot = component.get("v.slot");
        var serviceAppointmentId = component.get("v.serviceAppointmentId");
        var detailsAccount = component.get("v.detailsAccount");
        var detailsServiceAppt = component.get("v.detailsSA");

        var action = component.get("c.updateServiceAppointment");
        
        action.setParams({
            'slotJSON' : JSON.stringify(slot),
            'serviceAppointmentId': serviceAppointmentId,
            'detailsAccount' : detailsAccount,
            'detailsServiceAppt' : detailsServiceAppt
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.isOpen", false);
               
            } else {
                let errors = response.getError();
                console.log('Error response: ' + response);
                console.log("Error message: " + errors[0].message);
            }
        });

        $A.enqueueAction(action);
    },
    scheduleServiceAppointment : function (component) {
        var serviceAppointmentId = component.get("v.serviceAppointmentId");

        var action = component.get("c.scheduleServiceAppointment");
        action.setParams({
            'serviceAppointmentId': serviceAppointmentId
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            var serviceAppointmentId = component.get("v.serviceAppointmentId");
            if (state === "SUCCESS") {
                component.set("v.isOpen", false);
                var toastEvent = $A.get("e.force:showToast");
                toastEvent.setParams({
                    "title": "Success",
                    "type":"success",
                    "message": "You have successfully scheduled your service appointment!",
                    "messageTemplate": 'You have successfully scheduled your service appointment! Click {0} for details!',
        			"messageTemplateData": [
                        {
            			url: '/detail/' + serviceAppointmentId,
            			label: 'here',
            			}
        			],
                    "mode":'sticky'

                });
                toastEvent.fire();
            } else {
                let errors = response.getError();
                console.log('Error response: ' + response);
                console.log("Error message: " + errors[0].message);
            }
        });

        $A.enqueueAction(action);
    }
    
});

​​​​​​​​​​​​​​
 
I have a lightning component that has required fields. my issue is i want the require field message to be displayed on every field if it is missing that information and not at the top of the page. I was wondering if anyone could help me with updating the code below to accomplish this update.

Lightning Component
<aura:component description="ContactQuestions" controller="ContactQuestionsController" implements="forceCommunity:availableForAllPageTypes,lightning:isUrlAddressable" access="global">
    <aura:attribute name="toScheduling" type="Boolean" default="false"/>
    <aura:attribute name="displayFlowModal" type="Boolean" default="false"/>
    <aura:attribute name="showAssist" type="Boolean" default="false"/>
    <aura:attribute name="showError" type="Boolean" default="false"/>
    <aura:attribute name="errorMessage" type="String"/>
    <aura:attribute name="firstname" type="string"/>
    <aura:attribute name="lastname" type="string"/>
    <aura:attribute name="email" type="string"/>
    <aura:attribute name="gasUtilityNumber" type="string"/>
    <aura:attribute name="electricUtilityNumber" type="string"/>
    <aura:attribute name="phoneNum" type="string"/>
    <aura:attribute name="serviceZip" type="string"/>
    <aura:attribute name="opLang" type="List"/>
    <aura:attribute name="opHeatFuel" type="List"/>
    <aura:attribute name="opCondo" type="List"/>
    <aura:attribute name="opOwnRent" type="List"/>
    <aura:attribute name="opHear" type="List"/>
    <aura:attribute name="opBuildingType" type="List"/>
    <aura:attribute name="opGasUtilHolder" type="List"/>
    <aura:attribute name="opElectricUtilHolder" type="List"/>
    <aura:attribute name="opHeatWith" type="List"/>
    <aura:attribute name="opSquareFeet" type="List"/>
    <aura:attribute name="opHowMany" type="List"/>
    <aura:attribute name="opWhyContactUs" type="List"/>
    <aura:attribute name="opMakeImprove" type="List"/>
    <aura:attribute name="opHowManyUnits" type="List"/>
    <aura:attribute name="opHomeStyle" type="List"/>
    <aura:attribute name="opPrimaryFuel" type="List"/>
    <aura:attribute name="opSecondaryFuel" type="List"/>
    <aura:attribute name="opLive" type="List" default="[
    {'label': 'Yes', 'value': 'yes'},
    {'label': 'No', 'value': 'no'}]"/>
    <aura:attribute name="recordId" type="String"/>

    <!-- Contact Attributes -->
    <aura:attribute name="ContactInformation" type="Object"/>
    <aura:attribute name="preferredLanguage" type="String"/>
    <aura:attribute name="streetAddress" type="String"/>
    <aura:attribute name="zip" type="String"/>
    <aura:attribute name="city" type="String"/>
    <aura:attribute name="state" type="String"/>
    <aura:attribute name="mobile" type="String"/>
    <aura:attribute name="alternatePhone" type="String"/>
<!--    <aura:attribute name="heatFuel" type="String"/>-->
    <aura:attribute name="condoAssoc" type="String"/>
    <aura:attribute name="makeImprovements" type="String"/>
    <aura:attribute name="ownOrRent" type="String"/>
    <aura:attribute name="liveThere" type="String"/>
    <aura:attribute name="howHear" type="String"/>
<!--    <aura:attribute name="promoCode" type="String"/>-->
    <aura:attribute name="whyContactUs" type="String"/>
    <aura:attribute name="gasUtilHolder" type="String"/>
    <aura:attribute name="electricUtilHolder" type="String"/>
    <aura:attribute name="abandonedForm" type="Boolean"/>
    <aura:attribute name="externalLead" type="Boolean"/>

    <!-- Account Attributes -->
    <aura:attribute name="howManyUnits" type="Integer"/>
    <aura:attribute name="yearBuilt" type="String"/>
    <aura:attribute name="sqFeet" type="Integer"/>
    <aura:attribute name="primaryFuel" type="String"/>
    <aura:attribute name="secondaryFuel" type="String"/>
    <aura:attribute name="buildingType" type="String"/>
    <aura:attribute name="homeStyle" type="String"/>
    <aura:attribute name="primaryFuelPercent" type="Integer" default="50"/>
    <aura:attribute name="secondaryFuelPercent" type="Integer" default="50"/>
    <aura:attribute name="landlordName" type="String"/>
    <aura:attribute name="landlordEmail" type="String"/>
    <aura:attribute name="landlordPhone" type="String"/>
    <aura:attribute name="associationName" type="String"/>
    <aura:attribute name="associationEmail" type="String"/>
    <aura:attribute name="associationPhone" type="String"/>
    <aura:attribute name="optOut" type="Boolean" default="false"/>
    <aura:attribute name="gasHolderFirstName" type="String"/>
    <aura:attribute name="gasHolderLastName" type="String"/>
    <aura:attribute name="electricHolderFirstName" type="String"/>
    <aura:attribute name="electricHolderLastName" type="String"/>

    <!-- Accordion Attributes -->
    <aura:attribute name="section" type="String"/>

    <lightning:navigation aura:id="navService"/>

    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <aura:if isTrue="{!!v.toScheduling}">
        <lightning:layout horizontalAlign="spread">
            <lightning:layoutItem size = "2"><lightning:input type="text" label="First Name" value="{!v.ContactInformation.FirstName}" disabled="true"/></lightning:layoutItem>
            <lightning:layoutItem size = "2"><lightning:input type="text" label ="Last Name" value="{!v.ContactInformation.LastName}" disabled="true"/></lightning:layoutItem>
            <lightning:layoutItem size = "2"><lightning:input type="text" label = "Email" value="{!v.ContactInformation.Email}" disabled="true"/></lightning:layoutItem>
            <lightning:layoutItem size = "2"><lightning:input type="text" label = "Phone" value="{!v.ContactInformation.Phone}" disabled="true"/></lightning:layoutItem>
            <lightning:layoutItem size = "2"><lightning:input type="text" label = "Zip Code" value="{!v.ContactInformation.MailingPostalCode}" disabled="true"/></lightning:layoutItem>
        </lightning:layout>

        <lightning:accordion aura:id="accordion" allowMultipleSectionsOpen="true" activeSectionName="{!v.section}" onsectiontoggle="{!c.handleSectionToggle}">
            <lightning:layout class="slds-align_absolute-center">
                <lightning:layoutItem size = "6" padding="around-small">
                    <aura:if isTrue="{!v.showError}">
                        <div id="error" class="errormessage">
                            <lightning:input value="{!v.errorMessage}" readonly="true"/>
                        </div>
                    </aura:if>
                    
                    <br/>
                    <lightning:accordionSection name="reason" label="What brought you here today">
                        <lightning:combobox options="{!v.opHear}" value="{!v.howHear}" aura:id="howHear" class="widthFix" required="true" label="How did you hear about us?"/>
                        <lightning:combobox options="{!v.opWhyContactUs}" value="{!v.whyContactUs}" aura:id="whyContactUs" class="widthFix" required="true" label="What is the primary reason you contacted us?"/>
                    </lightning:accordionSection>
                    <lightning:accordionSection name="home" label="Tell us a bit more about your home">
                        <lightning:combobox options="{!v.opPrimaryFuel}" value="{!v.primaryFuel}" aura:id="primFuel" class="widthFix" required="true" label="What is your primary heat fuel?"/>
                        <lightning:input type="text" value="{!v.streetAddress}" maxlength="100" aura:id="streetAddress" class="input" required="true" label="Street Address"/>
                        <lightning:input type="text" value="{!v.zip}" maxlength="10" aura:id="zip" class="input" required="true" label="Zip"/>
                        <lightning:input type="text" value="{!v.city}" maxlength="25" aura:id="city" class="input" required="true" label="City"/>
                        <lightning:input type="text" value="{!v.state}" maxlength="10" aura:id="state" class="input" required="true" label="State"/>
                        <lightning:input type="text" value="{!v.mobile}" maxlength="12" aura:id="mobile" class="input" required="false" label="Mobile Phone"/>
                        <lightning:input type="text" value="{!v.alternatePhone}" maxlength="12" aura:id="alternatePhone" class="input" label="Alternate Phone"/>
                        <lightning:combobox options="{!v.opOwnRent}" value="{!v.ownOrRent}" aura:id="ownOrRent" class="widthFix" label="Are you the owner, tenant or landlord?"/>
                        <aura:if isTrue="{!v.ownOrRent == 'Tenant'}">
                            <lightning:input type="text" value="{!v.landlordName}" maxlength="100" aura:id="landlordName" class="input" label="Landlord Name"/>
                            <lightning:input type="email" value="{!v.landlordEmail}" maxlength="255" aura:id="landlordEmail" class="input" label="Landlord Email"/>
                            <lightning:input type="tel" value="{!v.landlordPhone}" maxlength="40" aura:id="landlordPhone" class="input" label="Landlord Phone"/>
                        </aura:if>
                        <aura:if isTrue="{!or(v.ownOrRent == 'Owner', v.ownOrRent == 'Landlord')}">
                            <lightning:combobox options="{!v.opLive}" value="{!v.liveThere}" aura:id="liveThere" class="widthFix" label="Do you reside in this dwelling?"/>
                        </aura:if>
<!--                        <aura:if isTrue="{!v.ownOrRent == 'Owner'}">-->
<!--                            <lightning:combobox options="{!v.opLive}" value="{!v.liveThere}" aura:id="liveThere" class="widthFix" label="Do you own or rent?"/>-->
<!--                        </aura:if>-->
                        <lightning:combobox options="{!v.opBuildingType}" value="{!v.buildingType}" aura:id="homeStyle" class="widthFix" label="What is your building type?"/>
                      <!--  <lightning:combobox options="{!v.opHowManyUnits}" value="{!v.howManyUnits}" aura:id="units" class="widthFix" label="How many units?"/> -->
                        <lightning:combobox options="{!v.opHomeStyle}" value="{!v.homeStyle}" aura:id="homeStyle" class="widthFix" label="What is the home style?"/>
                        <lightning:input aura:id="yearBuilt" class="input" value="{!v.yearBuilt}" minlength="4" maxlength="4" label="What year was your home built?"/>
                        <lightning:combobox options="{!v.opSquareFeet}" value="{!v.sqFeet}" aura:id="squareFeet" class="widthFix" label="The approximate Square footage of living space, (not including garage, basements, attic)"/>
                        <lightning:combobox options="{!v.opCondo}" value="{!v.condoAssoc}" aura:id="condoAss" class="widthFix" label="Do you have a Condo Association?"/>
                        <lightning:input type="checkbox" value="{!v.optOut}" onchange="{!c.optOutOfEmails}" aura:id="optOut" class="input" label="Opt Out of Promotional Emails"/>
                      <!--  <aura:if isTrue="{!v.condoAssoc == 'Yes'}">
                            <lightning:combobox options="{!v.opMakeImprove}" value="{!v.makeImprovements}" aura:id="makeImprovs" class="widthFix" label="Can you make improvements to your building without association approval?"/>
                            <aura:if isTrue="{!v.makeImprovements == 'No'}">
                                <lightning:input type="text" value="{!v.associationName}" maxlength="100" aura:id="associationName" class="input" label="Association Name"/>
                                <lightning:input type="email" value="{!v.associationEmail}" maxlength="255" aura:id="associationEmail" class="input" label="Association Email"/>
                                <lightning:input type="tel" value="{!v.associationPhone}" maxlength="40" aura:id="associationPhone" class="input" label="Association Phone"/>
                            </aura:if>
                        </aura:if> -->
                    </lightning:accordionSection>
                    <lightning:accordionSection name="account" label="Account information">
                        <aura:if isTrue="{!v.primaryFuel == 'Natural Gas'}">
                        <lightning:input type="text" value="{!v.gasUtilityNumber}" maxlength="100" aura:id="gasUtilNumber" class="input" required="false" label="Gas Utility Number"/>
                        <lightning:combobox options="{!v.opGasUtilHolder}" value="{!v.gasUtilHolder}" aura:id="gasUtilHolder" class="widthFix" label="Are you listed as the Gas Account holder?"/>
                        <aura:if isTrue="{!v.gasUtilHolder == 'No'}">
                            <lightning:input type="text" value="{!v.gasHolderFirstName}" maxlength="100" aura:id="gasHolderFirstName" class="input" label="Gas Account Holder First Name"/>
                            <lightning:input type="text" value="{!v.gasHolderLastName}" maxlength="100" aura:id="gasHolderLastName" class="input" label="Gas Account Holder Last Name"/>
                        </aura:if>
                        </aura:if>
                        <lightning:input type="text" value="{!v.electricUtilityNumber}" maxlength="100" aura:id="electricUtilNumber" class="input" required="false" label="Electric Utility Number"/>
                        <lightning:combobox options="{!v.opElectricUtilHolder}" value="{!v.electricUtilHolder}" aura:id="electricUtilHolder" class="widthFix" label="Are you listed as the Electric Account holder?"/>
                        <aura:if isTrue="{!v.electricUtilHolder == 'No'}">
                            <lightning:input type="text" value="{!v.electricHolderFirstName}" maxlength="100" aura:id="electricHolderFirstName" class="input" label="Electric Account Holder First Name"/>
                            <lightning:input type="text" value="{!v.electricHolderLastName}" maxlength="100" aura:id="electricHolderLastName" class="input" label="Electric Account Holder Last Name"/>
                        </aura:if>
                    </lightning:accordionSection>
                </lightning:layoutItem>
            </lightning:layout>
        </lightning:accordion>

        <div class="slds-text-align--right">
            <lightning:button variant="brand-outline" class="slds-m-right_medium" label="Exit" name="cancel" onclick="{!c.navigateToHomePage}" aura:id="exitToHome"/>
            <lightning:button variant="brand-outline" class="slds-m-right_medium" label="Don’t Have Account Information" name="cancel" onclick="{!c.navigateToSchedulingSupport}" aura:id="schedulingSupport"/>
            <lightning:buttonGroup>
                <lightning:button variant="brand" label="Book Appointment" name="schedule" onclick="{!c.completeRegistration}" aura:id="submitreg"/>
            </lightning:buttonGroup>
        </div>

    </aura:if>
    <aura:if isTrue="{!v.toScheduling}">
       <c:FSL_AppointmentBooking></c:FSL_AppointmentBooking>
    </aura:if>
</aura:component>


 
I was wondering if I can update this segment of code to look at a formula field that uses date & time thats adds at least 60 days or how i can update this piece of code like  if(slotStartDay > Date.today() +60?  I tried addDays(60) and Date.today() +60 and when i tried to search for avialable appointment slots nothing was displayed

 
List<AppointmentBookingSlot> slotList = new List<AppointmentBookingSlot>();
        for(FSL.AppointmentBookingSlot slot : slots){
            DateTime slotStartDT = slot.interval.start;
            DateTime slotFinishDT = slot.interval.finish;
            Date slotStartDay = slotStartDT.date();
            
            if(slotStartDay > Date.today() ){
                AppointmentBookingSlot newSlot = new AppointmentBookingSlot();
                Interval times = new Interval();
                times.startDT = slot.interval.start;
                times.endDT = slot.interval.finish;
                newSlot.grade = slot.grade;
                newSlot.times = times;
                slotList.add(newSlot);
            }
        }
        System.debug('slotList:: '+ slotList);
       
        
        //return setToTimeZone(slotList);
        return slotList;
    }
    
    public static DateTime utcToUserTimezone(DateTime utcDT){
        DateTime userDT = utcDT;
        String utcDtString = utcDT.format('yyyy-MM-dd HH:mm:ss', 'UTC');
        //String utcDtString = utcDT.format('yyyy-MM-dd hh:mm a', 'UTC');

        System.debug('@@@@ str: '+utcDtString);
        userDT = DateTime.valueOf(utcDtString);
        System.debug('@@@@ DT: '+userDT);
        return userDT;
    }

 
  • April 20, 2022
  • Like
  • 0
I have a flow that some else created and it is not working correctly.

How it should Works:

User starts from a Contact record and clicks New Work Order/s button
flow screen pops up for user to selected multiple account related to the contact.
When the user clicks the next button the flow should create new work orders for both locations related to the contact but it only creates work orders for the first location. Even If you select multiple checkboxes it will create two work orders with the same location. 

The screenshots below are part of the flow. If anyone can help that would be appreciate 

User-added imageUser-added imageUser-added imageUser-added imageUser-added image
 
  • October 29, 2021
  • Like
  • 0
I have a flow that is trying to update records, but users are getting the following error message

This error occurred when the flow tried to update records: Too many SOQL queries: 101

Is there any criteria I can add to the update element to stop this from happening? 
  • August 25, 2021
  • Like
  • 0
I am working on a flow that should update a service appointment from a work order line item if a service appointment from the parent work schedule start and end dates are updated then the work order line item appointment should update to the same values.

My new flow is giving me a  Error $Record.ParentRecordId because it hasn't been set or assigned.

Information about my flow
there are three objects: Work Order, Service Appointment & Work Order Line Item.

We have a process that when a Service Appointment  schedule start and end dates are added a work order line item and a new service appointment is created with those same dates. 

User-added imageUser-added imageUser-added imageUser-added imageUser-added image

 
  • August 12, 2021
  • Like
  • 0
I am getting the following error when i try to save and activate a flow

f_EndDateTime (Formula) - The formula expression is invalid: Incorrect parameter type for function 'YEAR()'. Expected Date, received DateTime

Here is the formula below:

how would I adjust this formula to stop that error
DATETIMEVALUE(TEXT(YEAR({!End_Date_Time}))+"-" +TEXT(MONTH({!End_Date_Time}))+"-"+TEXT(DAY({!End_Date_Time}))+" 12:00:00")

 
I am looking for a solution to assign two resources to one service appointment. Currently we have two service appointments being created. We have a contractor appointment and a inspector   appointment. ideally we would like to have one appointment that shows both the contractor and inspector resource on one appointment. The issue is the contractor can't see who the inspector is  when the view there appointments on the community. 

 

Any help would be appreciated i.e. workflow rule, process builder workflow, flow, etc.
I have service appointment list views that when a user navigates from list view to list view the last modified date and time show the current date and time. 

I just refreshed my sandbox from production and after testing the sandbox, the sandbox does not update the Last Modified Date to the current date and time. 

I would think if I just refresh the sandbox from our production org this issue would carry over to the sandbox if it was custom apex job, flow, process builder workflow etc.

HELP!  Is there a tool in salesforce or other that can identify what is causing? ​​​​​​​User-added image