• Gary Singh (BlackBeltHelp)
  • NEWBIE
  • 10 Points
  • Member since 2014

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 7
    Questions
  • 6
    Replies

I have a use case where users are required to enter their timesheet records no later than 10 am the next working day. 

For this I have created a Business hours profile called '
Krow Timesheet Users' and attempting to use a trigger that is not working. 

Looking for assistance what is the best way to handle this.  I have tried using a point and click validation but that does not work either. 

Business hours profile look as : 

User-added image

Trigger: 

 

trigger Krow_Timesheet_Split_Validation on Krow__Timesheet_Split__c (before insert, before update) {
    // Define the business hours name we want to look for
    String businessHoursName = 'Krow Timesheet Users';

    // Get the organization's default timezone
    TimeZone orgTimezone = UserInfo.getTimeZone();

    for (Krow__Timesheet_Split__c timesheetSplit : Trigger.new) {
        // Only validate records that have a Krow__Date__c value
        if (timesheetSplit.Krow__Date__c != null) {
            // Get the day of the week for the Krow__Date__c value
			Integer dayOfWeek = (Integer)timesheetSplit.Krow__Date__c.toStartOfWeek().daysBetween(Date.newInstance(1900, 1, 7));
			dayOfWeek = Math.mod(dayOfWeek, 7);

            // Check if the day of the week is between Monday (1) and Friday (5)
            if (dayOfWeek >= 1 && dayOfWeek <= 5) {
                // Get the business hours for the specified name and timezone
                BusinessHours bh = [SELECT Id FROM BusinessHours WHERE Name = :businessHoursName AND TimeZoneSidKey = :orgTimezone.getID()];

                if (bh != null) {
                    // Calculate the last work day as the previous Friday
                    Date lastWorkDay = Date.today().toStartOfWeek().addDays(dayOfWeek - 1);

                    // Check if the timesheet date is on or after the last work day
                    if (timesheetSplit.Krow__Date__c >= lastWorkDay) {
                        // Validation passed, allow the record to be saved
                    } else {
                        // Validation failed, add an error message to the record
                        timesheetSplit.addError('You cannot enter a timesheet for a date prior to ' + lastWorkDay.format());
                    }
                } else {
                    // Business hours not found, add an error message to the record
                    timesheetSplit.addError('The business hours ' + businessHoursName + ' could not be found.');
                }
            }
        }
    }
}

Right now, it allows a user to enter timesheetsplits (Timesheet records) for any day any time. 

Expected behaviour should be, Timesheet splits entered on May 15, 2023 , the trigger should allow users to enter timesheetsplits for May 12, 2023 no later that 10 AM on May 15, 2023. 

Also, any attempt to enter the Timesheet splits for days prior to May 12, should also be prevented. 

Thanks, 
Gary 

 

Need some assistance, I have a requirnment where in an employee has to be permitted to enter their timesheet data by the next working day by 10 AM EST, post which a validation rule should prevent them in entering / modifying the previous work day's timesheet. 

The following validation does not seem to be working as expected. For instance Timesheet entered on Friday (May 5,2023) , should permit saving it on Next Monday (May 8,2023) but it prevents saving before 10 AM. 

Also, it further does not allow a user to enter the timesheet for the work day (May 8, 2023) even after 10 AM. 

Wondering if any one have dealt with similar scenario, what was the approach / what can we modify in the validation rule shared below.

AND(
Krow__Timesheet__r.EVC_Employee_Id__c ='939',
TEXT(Krow__Timesheet__r.Krow__Approval_Status__c) = '', /* If the timesheet is still not submitted */
$User.Id <> CreatedById, /* Checks if the user is not the case owner */
DATETIMEVALUE(TEXT(Krow__Date__c) + " 04:00:00") < ( /* Converts Krow__Date__c field to a datetime value and compares it to the next business day at 10 AM EST */
CASE(
MOD(5 + WEEKDAY(TODAY() - 1), 7), /* Calculates the day of the week for yesterday's date */
0, DATETIMEVALUE(TEXT(TODAY() - 2) + " 10:00:00"), /* If today is Sunday(0), sets the next business day to Monday */
1, DATETIMEVALUE(TEXT(TODAY() - 1) + " 10:00:00"), /* If today is Monday(1), sets the next business day to Tuesday */
2, DATETIMEVALUE(TEXT(TODAY() - 1) + " 10:00:00"), /* If today is Tuesday(2), sets the next business day to Wednesday */
3, DATETIMEVALUE(TEXT(TODAY() - 1) + " 10:00:00"), /* If today is Wednesday(3), sets the next business day to Thursday */
4, DATETIMEVALUE(TEXT(TODAY() - 1) + " 10:00:00"), /* If today is Thursday(4), sets the next business day to Friday */
5, DATETIMEVALUE(TEXT(TODAY() + 3) + " 10:00:00"), /* If today is Friday (5), sets the next business day to Monday */
DATETIMEVALUE(TEXT(TODAY() + 2) + " 10:00:00") /* If today is Saturday (6), sets the next business day to Monday */
) - (5/24) /* Subtracts 5 hours to adjust for EST time zone */
)
)
Thanks, 
Gary

 

 

 

I am new to APEX and attempting to fetch value returned from a fuction of the same class, the sample below gives me NULL and no errors. 

Sounds silly, but I am unable to figure out I am doing wrong: 
public class ServiceCloudUtils {
    
    public static string getQueueId(string q){
        LIST<group> queueInfo = [SELECT Id from group WHERE name = :q and TYPE='queue'];
        Set<id> Idset = new Set<id>();
        string capturedId;
        for (group gvar: queueInfo){
         capturedId = gvar.id; 
        }
        system.debug('########### captured Queue Id : '+capturedId);
        return capturedId;        
    }
    
    public static list<GroupMember> getQueueMembers(string queueToFetch){
        list<string> queueMemberInfo = new list<string>();
        // call above function to fetch queueId
        string tempQId = getQueueId(queueToFetch);
        system.debug('##### id collected in tempQId : '+tempQId);
        // SOQL to fetch queue members
        list<GroupMember> gMembers = [Select UserOrGroupId From GroupMember where GroupId =:tempQId];
        system.debug('########### group Members for the Queue ID'+ tempQId +'are :'+ gMembers);
        return gMembers;
    }
   
}

 
I am new to apex and am trying to use Maps to figure out total Open and Closed cases for a Contact record. 

The following is not working, please suggest what is wrong. 
// Trigger should update contact with total tickets : closed and Opened

trigger Prac_caseUtil on Case (after insert, after delete, after update) {
map<id,List<case>> caseMap = new map<id,list<case>>();
    for(case caseObject : trigger.new){
        if(caseObject.accountid !=NULL && caseMap.get(caseObject.accountid)==NULL){
            caseMap.put(caseObject.accountid,new LIST<case>());            
            caseMap.get(caseObject.AccountId).add(caseObject); 
        }
    }
    // SOQL 
    LIST<contact> conListToUpdateOpen = [SELECT Id,Total_Open_Tickets__c,Total_Closed_Tickets__c,(SELECT ID FROM Cases WHERE IsClosed=FALSE) 
                                     FROM CONTACT 
                                     WHERE ID IN:caseMap.keySet()];
    
   LIST<contact> conListToUpdateClosed = [SELECT Id,Total_Open_Tickets__c,Total_Closed_Tickets__c,(SELECT ID FROM Cases WHERE IsClosed=TRUE) 
                                     FROM CONTACT 
                                     WHERE ID IN:caseMap.keySet()];
    
    for(contact c:conListToUpdateOpen){
        c.Total_Open_Tickets__c = caseMap.get(c.id).size();
        system.debug('###### open tickets' + caseMap.get(c.id).size());
    }

    for(contact c:conListToUpdateClosed){
        c.Total_Closed_Tickets__c = caseMap.get(c.id).size();
        system.debug('###### closed tickets' + caseMap.get(c.id).size());
    }
    update conListToUpdateOpen;
    update conListToUpdateClosed;
}

 
Wonderful people,

I am working on a requirnment to populate a Case from Opportunity records page via Custom button. For this I have created a simple flow for that which references the fields on Opp, however i get error while using it.

Configuration looks as under: 

Custom button on Opportunities layout

Referencing Owner ID for the Opp
Here i am unable to get the Opportunity Contact ID so referenced OwnerID

Create record criteria on Flow
Formula field
Error log

From the looks of the logs I can make out that it is User record can not be passed to Case Contact lookup as the ID will never match, therefore created a formula feild to fetch the contact ID refer it on the flow, however the value is always blank.

Please suggest as what i am missing, or may be a better way to accomplish this.

Thanks
I am noob to Apex and Developer community and want to konw if Article version history can be enabled for Partner Portal users by creating a custom VF page.

In our existing setup we have allocated Partner Portal licenses to our Call Center agents and they get Articles but Version history does not show by default which users with Full Salesforce license do have access to.

Appriciate your suggestions on achieving this.

Thanks,
Gary S

 
Is it possible to assign Assets Standard object to Contacts or Partner Portal accounts just like we can assign Case Records to Contacts ?
Is it possible to assign Assets Standard object to Contacts or Partner Portal accounts just like we can assign Case Records to Contacts ?
I am new to APEX and attempting to fetch value returned from a fuction of the same class, the sample below gives me NULL and no errors. 

Sounds silly, but I am unable to figure out I am doing wrong: 
public class ServiceCloudUtils {
    
    public static string getQueueId(string q){
        LIST<group> queueInfo = [SELECT Id from group WHERE name = :q and TYPE='queue'];
        Set<id> Idset = new Set<id>();
        string capturedId;
        for (group gvar: queueInfo){
         capturedId = gvar.id; 
        }
        system.debug('########### captured Queue Id : '+capturedId);
        return capturedId;        
    }
    
    public static list<GroupMember> getQueueMembers(string queueToFetch){
        list<string> queueMemberInfo = new list<string>();
        // call above function to fetch queueId
        string tempQId = getQueueId(queueToFetch);
        system.debug('##### id collected in tempQId : '+tempQId);
        // SOQL to fetch queue members
        list<GroupMember> gMembers = [Select UserOrGroupId From GroupMember where GroupId =:tempQId];
        system.debug('########### group Members for the Queue ID'+ tempQId +'are :'+ gMembers);
        return gMembers;
    }
   
}

 
I am new to apex and am trying to use Maps to figure out total Open and Closed cases for a Contact record. 

The following is not working, please suggest what is wrong. 
// Trigger should update contact with total tickets : closed and Opened

trigger Prac_caseUtil on Case (after insert, after delete, after update) {
map<id,List<case>> caseMap = new map<id,list<case>>();
    for(case caseObject : trigger.new){
        if(caseObject.accountid !=NULL && caseMap.get(caseObject.accountid)==NULL){
            caseMap.put(caseObject.accountid,new LIST<case>());            
            caseMap.get(caseObject.AccountId).add(caseObject); 
        }
    }
    // SOQL 
    LIST<contact> conListToUpdateOpen = [SELECT Id,Total_Open_Tickets__c,Total_Closed_Tickets__c,(SELECT ID FROM Cases WHERE IsClosed=FALSE) 
                                     FROM CONTACT 
                                     WHERE ID IN:caseMap.keySet()];
    
   LIST<contact> conListToUpdateClosed = [SELECT Id,Total_Open_Tickets__c,Total_Closed_Tickets__c,(SELECT ID FROM Cases WHERE IsClosed=TRUE) 
                                     FROM CONTACT 
                                     WHERE ID IN:caseMap.keySet()];
    
    for(contact c:conListToUpdateOpen){
        c.Total_Open_Tickets__c = caseMap.get(c.id).size();
        system.debug('###### open tickets' + caseMap.get(c.id).size());
    }

    for(contact c:conListToUpdateClosed){
        c.Total_Closed_Tickets__c = caseMap.get(c.id).size();
        system.debug('###### closed tickets' + caseMap.get(c.id).size());
    }
    update conListToUpdateOpen;
    update conListToUpdateClosed;
}

 
I am trying to set up JIT provisioning, I have SSO set up and functioning properly, the SAML Assertion I receive from the IDP contains the FederationID in the subject, so I have written the following code to search for a contact that has the FederationID in the subject populated in a custom field Campus_id__c, but when I attempt to log in with a test ID a new user account is not being created, can anyone assist?  I really appreciate any help that can be provided.

My Code:

global class SSOUserHandler implements Auth.SamlJitHandler {
 
    //JIT Handler Exception
    private class JitException extends Exception {}
 
    //Handle User
    private void handleUser(boolean create, User u, Map < String, String > attributes, 
        String federationIdentifier, boolean isStandard) {
        if (create && attributes.containsKey('User.FederationIdentifier')) {
            u.FederationIdentifier = attributes.get('User.FederationIdentifier');
        }
        
        if (attributes.containsKey('User.ProfileId')) {
            String profileId = attributes.get('User.ProfileId');
            Profile p = [SELECT Id FROM Profile WHERE Id =: profileId];
            u.ProfileId = p.Id;
        }
            
        Contact c = [Select ID, Email, FirstName, LastName from Contact where Campus_ID__c =:federationIdentifier];
        if (attributes.containsKey('User.FirstName')) {
            u.FirstName = attributes.get('User.FirstName');
        } else if (create) {
            u.FirstName = c.FirstName;
        }
        if (attributes.containsKey('LastName')) {
            u.FirstName = attributes.get('LastName');
        } else if (create) {
            u.LastName = c.LastName;
        }
        if(attributes.containsKey('User.Email')) {
            u.Email = attributes.get('User.Email');
        } else if (create) {
            u.Email = c.Email;
        }
        if (attributes.containsKey('UserName')) {
            u.UserName = attributes.get('UserName');
        } else if (create) {
            u.UserName = c.Email;
        }
        if (attributes.containsKey('User.CommunityNickname')) {
            u.CommunityNickname = attributes.get('User.CommunityNickname');
        }
        if (attributes.containsKey('User.IsActive')) {
            String IsActiveVal = attributes.get('User.IsActive');
            u.IsActive = '1'.equals(IsActiveVal) || Boolean.valueOf(IsActiveVal);
        }
        String uid = UserInfo.getUserId();
        User currentUser = [SELECT LocaleSidKey, LanguageLocaleKey, TimeZoneSidKey, EmailEncodingKey FROM User WHERE Id =: uid];
        if (attributes.containsKey('User.LocaleSidKey')) {
            u.LocaleSidKey = attributes.get('User.LocaleSidKey');
        } else if (create) {
            u.LocaleSidKey = currentUser.LocaleSidKey;
        }
        if (attributes.containsKey('User.LanguageLocaleKey')) {
            u.LanguageLocaleKey = attributes.get('User.LanguageLocaleKey');
        } else if (create) {
            u.LanguageLocaleKey = currentUser.LanguageLocaleKey;
        }
        if (attributes.containsKey('User.Alias')) {
            u.Alias = attributes.get('User.Alias');
        } else if (create) {
            String alias = '';
            if (u.FirstName == null) {
                alias = u.LastName;
            } else {
                alias = u.FirstName.charAt(0) + u.LastName;
            }
            if (alias.length() > 5) {
                alias = alias.substring(0, 5);
            }
            u.Alias = alias;
        }
        if (attributes.containsKey('User.TimeZoneSidKey')) {
            u.TimeZoneSidKey = attributes.get('User.TimeZoneSidKey');
        } else if (create) {
            u.TimeZoneSidKey = currentUser.TimeZoneSidKey;
        }
        if (attributes.containsKey('User.EmailEncodingKey')) {
            u.EmailEncodingKey = attributes.get('User.EmailEncodingKey');
        } else if (create) {
            u.EmailEncodingKey = currentUser.EmailEncodingKey;
        }
 
        if (!create) {
            update(u);
        } else {
            Insert u;
        }
    }
    
//Handle JIT
    private void handleJit(boolean create, User u, Id samlSsoProviderId, Id communityId, Id portalId, 
        String federationIdentifier, Map < String, String > attributes, String assertion) {
        if (communityId != null || portalId != null) {
            handleUser(create, u, attributes, federationIdentifier, false);
        } else {
            handleUser(create, u, attributes, federationIdentifier, true);
        }
    }
 
    //For New User
    global User createUser(Id samlSsoProviderId, Id communityId, Id portalId, 
        String federationIdentifier, Map < String, String > attributes, String assertion) {
        User u = new User();
        handleJit(true, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
        return u;
    }
 
    //For Existing User
    global void updateUser(Id userId, Id samlSsoProviderId, Id communityId, Id portalId,
        String federationIdentifier, Map < String, String > attributes, String assertion) {
        User u = [SELECT Id, FirstName, ContactId FROM User WHERE Id =: userId];
        handleJit(false, u, samlSsoProviderId, communityId, portalId, federationIdentifier, attributes, assertion);
    }
}
Hi all,

I'm newbie on SSO and I have the following issue on the jit provisioning: when the customer user access to the community(new user, new contact, account already existing), the SSO correctly created a new user, but nobody contact is created.

I'm using axiom tool adn the attribute I used to create new user and contact are the following(at the moment I given the sys adm profile because I got the permission error on the user creation for the customer login profile, but I'll resolve this issue later):

Contact.Account= 0012500000XXXX; 
Contact.LastName=prova16Sett2;
Contact.Email=prova16Sett2@test.com;
User.Email=prova16Sett2@prova16Sett2.com;
User.LastName=prova16Sett2;
User.ProfileId=System Administrator;
User.Username=prova16Sett2@test.com;



Any ideas? Can anyone help me? :(