Snippets Collections
HttpRequest request = new HttpRequest();
request.setEndPoint('callout:Spoke_Org/services/data');
request.setMethod('GET');
HttpResponse response = new HTTP().send(request);
System.assertEquals(200, response.getStatusCode());
String jsonStr = '[{"Id":"0015800001PTKzHAAX","Name":"test1" },{"Id":"0015800001PTKxpAAH","Name":"test2"}]';
        JSONParser parser = JSON.createParser(jsonStr);
        while (parser.nextToken() != null) {
            if (parser.getCurrentToken() == JSONToken.START_ARRAY) {
                while (parser.nextToken() != null) {
                    if (parser.getCurrentToken() == JSONToken.START_OBJECT) {
                        Contact acc = (Contact)parser.readValueAs(Contact.class);
                        system.debug('acc: ' + acc);
                    }
                }
            }
        }
// String or webservice response
String xmlString = '<Books><Book author="J.K. Rowling" title="Harry Potter and the philosopher\'s stone"/><Book author="Stephen King" title="Carry"/></Books>';

// Create a XSR
XmlStreamReader reader = new XmlStreamReader(xmlString);

while(reader.hasNext()) {
	
	switch on reader.getEventType() {
		
		// Attributes only occur on start elements
		when START_ELEMENT{
			
			// Check for your required property
			if (reader.getLocalName() =='Book') {
				
				// Iterate all the atttributes in the Book tag
				for(Integer i=0, attrCount=reader.getAttributeCount(); i<attrCount; i++){
					
					// "Verbosed" for a more clear explanation
					String attrName = reader.getAttributeLocalName(i);
					String attrValue= reader.getAttributeValue(null,attrName);
					
					// Get the attribute + value
					System.debug(attrName + ' :: ' + attrValue);
				}
			}
		}
	}
	reader.next();
}
syncUserPermissions('0058d0000020p2jAAA','0058d000005QinC');


/**
 * Method to sync permission sets between users
 */
void syncUserPermissions(Id sourceUserId, Id targetUserId){
	
	// Get the users details
	User sourceUser = [SELECT Id, Profile.UserLicense.Name FROM User WHERE Id =:sourceUserId];
	User targetUser = [SELECT Id, Profile.UserLicense.Name FROM User WHERE Id =:targetUserId];
	
	// This solves a lot of headaches
	if(sourceUser.Profile.UserLicense.Name != targetUser.Profile.UserLicense.Name ){
		throw new StringException('You can only sync users are of the same licence type.');
	}

	// Query PSAs for source user
	PermissionSetAssignment[] sourceUserAssignments = [SELECT PermissionSetId, IsActive FROM PermissionSetAssignment WHERE  
													  	AssigneeId = :sourceUser.Id AND 
													  	PermissionSet.IsOwnedByProfile = false AND 
													  	PermissionSet.License.Name IN(null, :sourceUser.Profile.UserLicense.Name)
													  ];
	// Query PSA's for the target user
	PermissionSetAssignment[] targetUserAssignments = [SELECT PermissionSetId FROM PermissionSetAssignment WHERE AssigneeId = :targetUser.Id AND PermissionSet.IsOwnedByProfile = false ];


	// Clean target user
	delete targetUserAssignments;

	/**
	 * Create the new assignments
	 */
	targetUserAssignments = new PermissionSetAssignment[]{};
	for(PermissionSetAssignment psa : sourceUserAssignments){
		targetUserAssignments.add(
			new PermissionSetAssignment(
				AssigneeId = targetUser.Id,
				PermissionSetId = psa.PermissionSetId
			)
		);
	}
	insert targetUserAssignments;
}
String input = 'Envelope,Body,describeSObjectResponse,result, custom,customSetting, childRelationships,relationshipName,childSObject';

String[] values = input.split(',');
for(integer i=0, max=values.size(); i<max; i++){
	values[i] = values[i].trim();
}


System.debug('Set<String> xmlTagFilter = new Set<String>{\''  + String.join(values,'\', \'') + '\'};');
global static List<SelectOption> getDependentSelectOptions(String objectType, String controllerName, String dependentFieldName, String parentValue) {
   List<SelectOption> dependentItems = new list<SelectOption>();
   if(null!=objectType && null!=controllerName && null!=dependentFieldName && null!=parentValue){
       Schema.DescribeFieldResult dependentField;
       Integer parentValueIndex = -1;
       
       //FIRST get the Parent PL's index value
       Schema.DescribeSObjectResult objectMeta = Schema.describeSObjects(new String[]{objectType})[0];
       Schema.SObjectField[] fields = objectMeta.fields.getMap().values();
       for (Schema.SObjectField f: fields) {
           Schema.DescribeFieldResult d = f.getDescribe();
           String fieldname = d.getName().toLowerCase();
           String ftype = String.valueOf(d.getType()).toLowerCase();
           if (fieldname.equals(controllerName.toLowerCase()) && ('picklist'.equals(ftype) || 'multipicklist'.equals(ftype))) {
               Schema.PicklistEntry[] pplvalues = d.getPicklistValues();
               for(Integer i=0; i<pplvalues.size(); i++) {
                   if(parentValue.equals(pplvalues[i].getValue())){
                       parentValueIndex = i;
                       break;
                   }
               }
           }
           if(fieldname.equals(dependentFieldName.toLowerCase()) && ('picklist'.equals(ftype) || 'multipicklist'.equals(ftype))) {
                dependentField = d;
           }
       }

       //2nd get the dependent PL values mapped to the target parent PL's value
       if(-1!=parentValueIndex && null!=dependentField ){
           Schema.PicklistEntry[] plValues = dependentField.getPicklistValues();
           for (PicklistEntry plv: plValues) {
               String jsonstr = JSON.serialize(plv);
               Map<String,String> jMap = (Map<String,String>) JSON.deserialize(jsonstr, Map<String,String>.class);
               String validFor = jMap.get('validFor');
               String plvalue = jMap.get('value');
               if(null!=validFor && !''.equals(validFor.trim()) && isDependentValue(parentValueIndex,validFor)){
                   dependentItems.add(new SelectOption(plvalue, plvalue));
               }
           }
       }
   }
   return dependentItems;
}

global static Boolean isDependentValue(Integer index, String validFor) { 
   String decoded = EncodingUtil.convertToHex(EncodingUtil.base64Decode(validFor));
   Integer bits = hexToInt(decoded);
   return ( ( bits & (128>>Math.mod(index,8)) ) != 0 );
}

private static Map<String,Integer> hexMap = new Map<String, Integer>{'0'=>0,'1'=>1,'2'=>2,'3'=>3,'4'=>4,'5'=>5,'6'=>6,'7'=>7,'8'=>8,'9'=>9,'A'=>10,'B'=>11,'C'=>12,'D'=>13,'E'=>14,'F'=>15,'a'=>10,'b'=>11,'c'=>12,'d'=>13,'e'=>14,'f'=>15};
global static Integer hexToInt(String hex) {
    Integer retVal = 0;
    for(Integer i=0;i<hex.length();i+=2) {
        retVal += (hexMap.get(hex.substring(i,i+1)) * 16) + (hexMap.get(hex.substring(i+1,i+2)));
    }
    return retVal;
}
Map<String,List<String>> pickValueMap=DependentPickListValueController.GetDependentOptions('SObject','ControllingPickList','DependentPicklist');

/////////////////////////////////////////////////////////////////////////////////////////////////
public class DependentPickListValueController{
    public  DependentPickListValueController(){}
    public  static Map<String,List<String>> GetDependentOptions(String pObjName, String pControllingFieldName, String pDependentFieldName){
        Map<String,List<String>> objResults = new Map<String,List<String>>();
        //get the string to sobject global map
        Map<String,Schema.SObjectType> objGlobalMap = Schema.getGlobalDescribe();
        //get the type being dealt with
        Schema.SObjectType pType = objGlobalMap.get(pObjName);
        Map<String, Schema.SObjectField> objFieldMap = pType.getDescribe().fields.getMap();
        //get the control values   
        List<Schema.PicklistEntry> ctrl_ple = objFieldMap.get(pControllingFieldName).getDescribe().getPicklistValues();
        //get the dependent values
        List<Schema.PicklistEntry> dep_ple = objFieldMap.get(pDependentFieldName).getDescribe().getPicklistValues();
        //iterate through the values and get the ones valid for the controlling field name
        PickListUtils.Bitset objBitSet = new PickListUtils.Bitset();
        //set up the results
        for(Integer pControllingIndex=0; pControllingIndex<ctrl_ple.size(); pControllingIndex++){            
            //get the pointer to the entry
            Schema.PicklistEntry ctrl_entry = ctrl_ple[pControllingIndex];
            //get the label
            String pControllingLabel = ctrl_entry.getLabel();
            //create the entry with the label
            objResults.put(pControllingLabel,new List<String>());
        }
        //check the dependent values
        for(Integer pDependentIndex=0; pDependentIndex<dep_ple.size(); pDependentIndex++){            
            //get the pointer to the dependent index
            Schema.PicklistEntry dep_entry = dep_ple[pDependentIndex];
            //get the valid for
            String pEntryStructure = JSON.serialize(dep_entry);                
            PickListUtils.PicklistDetails objDepPLE = (PickListUtils.PicklistDetails)JSON.deserialize(pEntryStructure, PickListUtils.PicklistDetails.class);
            //iterate through the controlling values
            for(Integer pControllingIndex=0; pControllingIndex<ctrl_ple.size(); pControllingIndex++){    
                if (objBitSet.fitBit(objDepPLE.validFor,pControllingIndex)){                    
                    //get the label
                    String pControllingLabel = ctrl_ple[pControllingIndex].getLabel();
                    objResults.get(pControllingLabel).add(objDepPLE.label);
                }
            }
        } 
        return objResults;
    }
}
//////////////////////////////////////////////////////////////////

public class PickListUtils{
    public PickListUtils(){}
    public class PicklistDetails{
            public string active {get;set;}
            public string defaultValue {get;set;}
            public string label {get;set;}
            public string value {get;set;}
            public string validFor {get;set;}
            public PicklistDetails(){}
    }
    public class Bitset{
        public Map<String,Integer> AlphaNumCharCodes {get;set;}
        public Map<String, Integer> Base64CharCodes { get; set; }
        public Bitset(){
            findChacterCodes();
        }
        private void findChacterCodes(){
            AlphaNumCharCodes = new Map<String,Integer>{
                'A'=>65,'B'=>66,'C'=>67,'D'=>68,'E'=>69,'F'=>70,'G'=>71,'H'=>72,'I'=>73,'J'=>74,
                'K'=>75,'L'=>76,'M'=>77,'N'=>78,'O'=>79,'P'=>80,'Q'=>81,'R'=>82,'S'=>83,'T'=>84,
                'U'=>85,'V'=> 86,'W'=>87,'X'=>88,'Y'=>89,'Z'=>90    
            };
            Base64CharCodes = new Map<String, Integer>();
            //lower case
            Set<String> pUpperCase = AlphaNumCharCodes.keySet();
            for(String pKey : pUpperCase){
                //the difference between upper case and lower case is 32
                AlphaNumCharCodes.put(pKey.toLowerCase(),AlphaNumCharCodes.get(pKey)+32);
                //Base 64 alpha starts from 0 (The ascii charcodes started from 65)
                Base64CharCodes.put(pKey,AlphaNumCharCodes.get(pKey) - 65);
                Base64CharCodes.put(pKey.toLowerCase(),AlphaNumCharCodes.get(pKey) - (65) + 26);
            }
            //numerics
            for (Integer i=0; i<=9; i++){
                AlphaNumCharCodes.put(string.valueOf(i),i+48);
                //base 64 numeric starts from 52
                Base64CharCodes.put(string.valueOf(i), i + 52);
            }
        }
        public Boolean fitBit(String pValidFor,Integer n){
            //the list of bytes
            List<Integer> pBytes = new List<Integer>();
            //multiply by 6 since base 64 uses 6 bits
            Integer bytesBeingUsed = (pValidFor.length() * 6)/8;
            //will be used to hold the full decimal value
            Integer pFullValue = 0;
            //must be more than 1 byte
            if (bytesBeingUsed <= 1)
                return false;
            //calculate the target bit for comparison
            Integer bit = 7 - (Math.mod(n,8));
            //calculate the octet that has in the target bit
            Integer targetOctet = (bytesBeingUsed - 1) - (n >> bytesBeingUsed);
            //the number of bits to shift by until we find the bit to compare for true or false
            Integer shiftBits = (targetOctet * 8) + bit;
            //get the base64bytes
            for(Integer i=0;i<pValidFor.length();i++){
                //get current character value
                pBytes.Add((Base64CharCodes.get((pValidFor.Substring(i, i+1)))));
            }
            //calculate the full decimal value
            for (Integer i = 0; i < pBytes.size(); i++){
                Integer pShiftAmount = (pBytes.size()-(i+1))*6;//used to shift by a factor 6 bits to get the value
                pFullValue = pFullValue + (pBytes[i] << (pShiftAmount));
            }
            //shift to the bit which will dictate true or false
            Integer tBitVal = ((Integer)(Math.Pow(2, shiftBits)) & pFullValue) >> shiftBits;
            return  tBitVal == 1;
        }
     }  
 }
writeAddMethod('controllingFields','ControllingField', 'String');
writeAddMethod('actionOverrides','ActionOverride', 'ActionOverride');
writeAddMethod('childRelationships','ChildRelationship', 'ChildRelationship');
writeAddMethod('fields','Field', 'Field');
writeAddMethod('namedLayoutInfos','NamedLayoutInfo', 'NamedLayoutInfo');
writeAddMethod('recordTypeInfos','RecordTypeInfo', 'RecordTypeInfo');
writeAddMethod('supportedScopes','ScopeInfo', 'ScopeInfo');

/**
 * Method to quickly write an add method to for a class
 */
void writeAddMethod(String listVariableName, String className, String dataType){
	System.debug('/**');
	System.debug(' * Method to add a '+dataType+' Object to the ' + listVariableName + ' variable');
	System.debug(' */');
	System.debug('global void add' + className + '(' + dataType + ' ' + className.uncapitalize()+'){');
	System.debug('	if(this.' + listVariableName + ' == null){');
	System.debug('		this.' + listVariableName + ' = new ' + dataType+'[]{};');
	System.debug('	}');
	System.debug('	this.' + listVariableName + '.add(' + className.uncapitalize() + ');');
	System.debug('}');
	System.debug('');
	System.debug('');
}
@AuraEnabled()
public static Map<String, Object> test() { 
        Map<String, Object> scc = new Map<String, Object>();
        
        try {
          //CODE

            scc.put('key', value);
        } catch (Exception e) {
            throw new AuraHandledException(e.getMessage());
        }
        
        return scc;
    }
// (example from Daniel Ballinger)
public void checkDeployStatus(Id deployRequestId) {
    HttpRequest req = new HttpRequest();
    req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
    req.setHeader('Content-Type', 'application/json');

    req.setMethod('GET');     
    String instanceName = System.Url.getSalesforceBaseUrl().toExternalForm();
    // Visualforce can't make the direct API calls. Might need to massage the instanceName
    req.setEndpoint(instanceName + '/services/data/v49.0/metadata/deployRequest/' + deployRequestId + '?includeDetails=true');
    
    Http http = new Http();
    try {
        HTTPResponse res = http.send(req);                 
        System.debug('STATUS:' + res.getStatus());
        System.debug('STATUS_CODE:' + res.getStatusCode());
        String responseBody = res.getBody(); 

        if(res.getStatusCode() == 200) {

            DeployResultJson jsonResult = (DeployResultJson)JSON.deserialize(responseBody, DeployResultJson.class);

            if(jsonResult.deployResult.details != null) {
                for(Metadata.DeployMessage dm : jsonResult.deployResult.details.componentSuccesses) {
                    if(dm.fileName == 'package.xml') {
                        continue;
                    }

                    // Do something with the DeployMessage

                }
            }
        }
    } catch(System.CalloutException e) {
        // Exception handling goes here
    }
}

// Support unpacking via JSON.deserialize from deployRequest metadata api call
public class DeployResultJson {       
    public String id;
    public Object validatedDeployRequestId;
    public Object deployOptions;
    public Metadata.DeployResult deployResult;
}
// Verbose
String sObjectPrefix = '0Af';
Id sObjectId =  Id.valueOf(sObjectPrefix.rightPad(15, '0'));
SObjectType sot = sObjectId.getSObjectType();
System.debug(sot);

// Single line (thanks to Adrian Larson on SO)
System.debug(Id.valueOf('0Af'.rightPad(15, '0')).getSObjectType());
/* ** ******************************************************************* ** * 
 *                                CONSTANTS                                  * 
 * ** ******************************************************************* ** */
// Switch so you don't excidentally create a whole lot of users
final Boolean INSERT_USER = false;

// Switch to deactivate the created users so we dont expose the wrong users
final Boolean DEACTIVATE_USERS = true;

// Username / Email address post fixes, update these to match your sandbox
final String EMAIL_EXTENSION		= '@example.com.invalid';
final String UNAME_EXTENSION		= '@example.com.demo';
final String SYS_ADMIN_PROFILE_NAME	= 'System Administrator';

// Specify a start url so users can easily be redirected during demos
final String START_URL	= '/lightning/n/Tree_Applications';

// Override any values on the user object
final Map<String,Object> CUSTOM_DATA = new Map<String,Object>{
	'FirstName' => 'Henk 07',
	'LastName'	=> 'de Vries 07'
};


/* ** ******************************************************************* ** * 
 *                                VARIABLES                                  * 
 * ** ******************************************************************* ** */
// User counter so multiple users can be created at the same time using the same method
Integer userCounter = 0;


/* ** ******************************************************************* ** * 
 *                            ANONYMOUS EXECUTION                            * 
 * ** ******************************************************************* ** */
try{
	// Create the demo user
	User u = createDemoUser(SYS_ADMIN_PROFILE_NAME, CUSTOM_DATA);
	
	// Create a random password basedon the username (unique) + current timestamp
	String password = EncodingUtil.convertToHex(Crypto.generateDigest('SHA1', Blob.valueOf(u.username + DateTime.now().getTime())));
	
	// Check if the user needs to be inserted into the database
	if(INSERT_USER){
		// Create the user
		insert u;

		// Set the password
		System.setPassword(u.Id,password);
	}

	// Output an easy login url details
	System.debug(password);

	// Very bad, but good for demos 8-)
	System.debug(URL.getSalesforceBaseUrl().toExternalForm() + '/login.jsp?un=' + u.Username +'&startURL='+START_URL);
	
	// Debug the user info
	System.debug(JSON.serializePretty(u));
	
	// Deactivate the users
	if(DEACTIVATE_USERS){
		deactivateUsers();
	}
	
}catch(Exception e){
	System.debug(e.getMessage());
}


/* ** ******************************************************************* ** * 
 *                             PUBLIC SUPPORT METHODS                        * 
 * ** ******************************************************************* ** */
/**
 * Method for creating a demo user record
 */
public User createDemoUser(String profileName, Map<String,Object> dataMap){

	// Check profile name is not blank
	if(String.isBlank(profileName)){
		throw new StringException('Profile name cannot be blank');
	}

	// Query profile Id
	String profileId = [SELECT Id FROM Profile WHERE Name = :profileName WITH SECURITY_ENFORCED LIMIT 1]?.Id;

	// Check the profile exists else throw an error
	if(profileId == null){
		throw new StringException('Profile does not exist, check the profile name');
	}
	
	// Generate a semi random username for a test user
	String userName = EncodingUtil.convertToHex(Crypto.generateDigest('SHA1', Blob.valueOf(UNAME_EXTENSION + userCounter + DateTime.now().getTime()))).substring(0,25);
		
	// Setup a user, so you can run the test code for a specific profile / permission set
	// In out best practice we use permission sets, so it's best to test these permission sets accordingly with the proper user Profile
	User runAsUser = new User();
	runAsUser.Alias 				= userName.subString(0,8);
	runAsUser.UserName		 		= userName + UNAME_EXTENSION;
	runAsUser.Email			 		= userName + EMAIL_EXTENSION;
	runAsUser.LastName				= userName;
	runAsUser.FederationIdentifier	= userName;
	runAsUser.EmailEncodingKey		= 'UTF-8';
	runAsUser.LanguageLocaleKey		= 'en_US';
	runAsUser.LocaleSidKey			= 'en_US';
	runAsUser.TimeZoneSidKey		= 'Europe/London';
	runAsUser.ProfileId				= profileId;
	
	// Allow the developers to populate additional data to the user record or override any of the default values
	populateSObjectDataFromMap(runAsUser,dataMap);
	
	// Update the user counter so the next one can be created
	userCounter++;
		
	// Return the new user
	return runAsUser;
}

/* ** ******************************************************************* ** * 
 *                 PRIVATE SUPPORT METHODS (CLASS SPECIFIC)                  * 
 * ** ******************************************************************* ** */
/**
 * Method to populate data on an sObject from a data map
 */
private static void populateSObjectDataFromMap(sObject sObj, Map<String,Object> dataMap){
	// Null check
	if(sObj ==  null || dataMap == null){return;}

	// Fetch the fields from the metadata so we can check they exist
	Schema.SObjectType sObjectType = sObj.getSObjectType();
	Map<String, Schema.SObjectField> fieldMap = sObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).fields.getMap();

	// Populate the data from the data map
	for(String fieldName : dataMap.keySet()){

		// Check the field exists on the sObject
		if(!fieldMap.containsKey(fieldName)){
			throw new StringException(String.format('The field "{0}" on sObject "{1}" cannot be found in the metadata', new String[]{fieldName,String.valueOf(sObjectType)}));
		}

		// Populate the field
		sObj.put(fieldName,dataMap.get(fieldName));
	}
}

void deactivateUsers(){
	User[] users = [SELECT Id,Name FROM User WHERE CreatedById = :UserInfo.getUserId() AND Id != :UserInfo.getUserId() AND IsActive=true];
	for(User u : users){
		u.isActive = false;
	}
	update users;
	System.debug(JSON.serializePretty(users));
}
{
    "swagger": "2.0",
    "basePath": "/",
    "info": {
        "version": "1.0",
        "title": "External Service for demo bank",
        "description": "### External Service for demo bank",
        "x-vcap-service-name": "DemoBankRestServices"
    },
    "securityDefinitions": {
        "basicAuth": {
            "type": "basic"
        }
    },
    "security": [{
        "basicAuth": []
    }],
    "tags": [{
        "name": "DemoBankRestServices"
    }],
    "paths": {
        "/accounts/{accountName}": {
            "get": {
                "operationId": "getAccount",
                "summary": "Retrieves an account",
                "description": "Retrieves the account with specific name",
                "consumes": ["text/plain"],
                "produces": ["application/json"],
                "parameters": [{
                    "name": "accountName",
                    "in": "path",
                    "required": true,
                    "type": "string",
                    "description": "Name of the account"
                }],
                "responses": {
                    "200": {
                        "description": "The response when system finds an account with given name",
                        "schema": {
                            "$ref": "#/definitions/accountDetails"
                        }
                    },
                    "400": {
                        "description": "Error response if the account name parameter is less than minimum characters",
                        "schema": {
                            "$ref": "#/definitions/errorModel"
                        }
                    },
                    "404": {
                        "description": "Error response if the account is not supported by service or account is not found",
                        "schema": {
                            "$ref": "#/definitions/errorModel"
                        }
                    }
                }
            },
            "delete": {
                "operationId": "DeleteAccount",
                "summary": "Deletes an account",
                "description": "Deletes the account with specific name",
                "consumes": ["text/plain"],
                "produces": ["application/json"],
                "parameters": [{
                    "name": "accountName",
                    "in": "path",
                    "required": true,
                    "type": "string",
                    "description": "Name of the account"
                }],
                "responses": {
                    "204": {
                        "description": "The response when system finds an account with given name",
                        "schema": {
                            "type": "string"
                        }
                    },
                    "400": {
                        "description": "Error response if the account name parameter is less than minimum characters",
                        "schema": {
                            "$ref": "#/definitions/errorModel"
                        }
                    },
                    "404": {
                        "description": "Error response if the account is not supported by service or account is not found",
                        "schema": {
                            "$ref": "#/definitions/errorModel"
                        }
                    }
                }
            },
            "post": {
                "operationId": "addAccount",
                "summary": "Add an account",
                "description": "Add an account to the database",
                "consumes": ["text/plain"],
                "produces": ["application/json"],
                "parameters": [{
                    "name": "accountName",
                    "in": "path",
                    "required": true,
                    "type": "string",
                    "description": "Name of the account"
                }, {
                    "name": "accountType",
                    "in": "query",
                    "required": true,
                    "type": "string",
                    "description": "The type of account"
                }],
                "responses": {
                    "201": {
                        "description": "The response when the account does not already exist and we can create one",
                        "schema": {
                            "$ref": "#/definitions/accountDetails"
                        }
                    },
                    "409": {
                        "description": "The response when the account already exists and we cannot create one",
                        "schema": {
                            "$ref": "#/definitions/accountDetails"
                        }
                    },
                    "400": {
                        "description": "Error response if the account name parameter is less than minimum characters",
                        "schema": {
                            "$ref": "#/definitions/errorModel"
                        }
                    },
                    "404": {
                        "description": "Error response if the account is not supported by service or account is not found",
                        "schema": {
                            "$ref": "#/definitions/errorModel"
                        }
                    }
                }
            },
            "put": {
                "operationId": "updateAccount",
                "summary": "Updates an account",
                "description": "Updates the account with specified name",
                "consumes": ["text/plain"],
                "produces": ["application/json"],
                "parameters": [{
                    "name": "accountName",
                    "in": "path",
                    "required": true,
                    "type": "string",
                    "description": "Name of the account"
                }, {
                    "name": "accountType",
                    "in": "query",
                    "required": true,
                    "type": "string",
                    "description": "The type of account"
                }],
                "responses": {
                    "200": {
                        "description": "The response when system finds an account with given name",
                        "schema": {
                            "$ref": "#/definitions/accountDetails"
                        }
                    },
                    "400": {
                        "description": "Error response if the account name parameter is less than minimum characters",
                        "schema": {
                            "$ref": "#/definitions/errorModel"
                        }
                    },
                    "404": {
                        "description": "Error response if the account is not supported by service or account is not found",
                        "schema": {
                            "$ref": "#/definitions/errorModel"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "accountDetails": {
            "required": ["id", "name", "type", "availableBal"],
            "properties": {
                "id": {
                    "type": "string",
                    "description": "id"
                },
                "name": {
                    "type": "string",
                    "description": "name"
                },
                "type": {
                    "type": "string",
                    "description": "type"
                },
                "availableBal": {
                    "type": "string",
                    "description": "availableBal"
                }
            }
        },
        "errorModel": {
            "required": ["errorCode", "errorMessage"],
            "properties": {
                "errorCode": {
                    "type": "string",
                    "description": "A service-specific error code."
                },
                "errorMessage": {
                    "type": "string",
                    "description": "A service-specific error code."
                }
            }
        }
    }
}
public static String generateXMLSignature(String docBodyString){
	// 1. Apply the Transforms, as determined by the application, to the data object.
	// (no transforms are done, since the body should be delivered in canonicalized form (Force.com offers no canonicalization algorithm))
	
	// 2. Calculate the digest value over the resulting data object. 
	
	Blob bodyDigest = Crypto.generateDigest('SHA1',Blob.valueOf(docBodyString));
	
	// 3. Create a Reference element, including the (optional) identification of the data object, any (optional) transform elements, the digest algorithm and the DigestValue.
	// (Note, it is the canonical form of these references that are signed and validated in next steps.)

	String referenceString = '';
	referenceString += '';
	referenceString += '<ds:Reference URI="#msgBody">';
	referenceString += '<ds:Transforms>';
	referenceString += '<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>';
	referenceString += '<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>';
	referenceString += '</ds:Transforms>';
	referenceString += '<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>';
	referenceString += '<ds:DigestValue>'+EncodingUtil.base64Encode(bodyDigest)+'</ds:DigestValue>';
	referenceString += '</ds:Reference>';		 
	
	// 4. Create SignedInfo element with SignatureMethod, CanonicalizationMethod and Reference(s).
	String signedInfoString = '';
	signedInfoString += '<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">';
	signedInfoString += '<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>';
	signedInfoString += '<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>';
	signedInfoString += referenceString;
	signedInfoString += '</ds:SignedInfo>';
	
	// 5. Canonicalize and then calculate the SignatureValue over SignedInfo based on algorithms specified in SignedInfo.
	// (no canonicalization is done, since the signedinfo element should be delivered in canonicalized form (Force.com offers no canonicalization algorithm))

	String algorithmName = 'RSA-SHA1';
	// decrypted private key pkcs8 format from certificate
	String key = '[decryptedPrivateKeypkcs8formatfromcertificate]';
	Blob privateKey = EncodingUtil.base64Decode(key);
	
	Blob siBlob = Blob.valueOf(signedInfoString);
	
	Blob signatureValue = Crypto.sign(algorithmName, siBlob, privateKey);
	String signatureValueString = EncodingUtil.base64Encode(signatureValue);

	// 6. Construct the Signature element that includes SignedInfo, Object(s) (if desired, encoding may be different than that used for signing), KeyInfo (if required), and SignatureValue. 
	String signatureString = '';
	
	signatureString += '<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">';
	signatureString += signedInfoString; 
	signatureString += '<ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'+signatureValueString+'</ds:SignatureValue>';
	signatureString += '<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">';
	signatureString += '<ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">';
	signatureString += '<ds:X509Certificate xmlns:ds="http://www.w3.org/2000/09/xmldsig#">[the certificate used for signing]</ds:X509Certificate>';
	signatureString += '</ds:X509Data>';
	signatureString += '</ds:KeyInfo>';
	signatureString += '</ds:Signature>';
	
	return signatureString;
}	
// Data and private key. Use a method for getting the keys and signature
// so the example is more readable
private final String DATA		= 'The quick brown fox jumps over the lazy dog';
private final String SIGNATURE	= getSignature();
private final String PUBLIC_KEY	= getPublicKey();
private final String PRIVATE_KEY= getPrivateKey();

// Performance measuring
Integer startTime = Limits.getCpuTime();

// Validate the newly created signature is as expected
System.assertEquals(
	SIGNATURE,
	createSignature(DATA, PRIVATE_KEY),
	'The expected signature does not match the actual signature created using the private key.'
);


// VERIFY the signature is as expected
System.assertEquals(
	true,
	verifySignature(
		DATA,
		SIGNATURE,
		PUBLIC_KEY
	),
	'Error verifying the signature using the public key'
);


// If no errors let us know, also output the time it took, as signatures might be CPU intensive
System.debug('All Key tests were OK. Execution took: ' +( Limits.getCpuTime() - startTime) + 'ms');


/**
 * Method to get the signature when signing some data
 * @param dataToSign	The data that needs to be signed
 * @param privateKey	The RSA Private key
 */
public String createSignature(String dataToSign, String privateKey){
	return EncodingUtil.base64Encode(
		Crypto.sign(
			'RSA-SHA256', // The algorith you want to use
			Blob.valueOf(dataToSign), // Convert the string to a blog
			EncodingUtil.base64Decode(privateKey) // decode converts string into a blob
		)
	);
}


/**
 * Method to verify a signature
 * @param dataToVerify	The data that needs to be verified
 * @param signature		The B64 encoded signature that needs to be verified
 * @param publicKey		The B64 encoded RSA Public key
 */
public Boolean verifySignature(String dataToVerify, String signature, String publicKey){
	return Crypto.verify(
		'RSA-SHA256', // The algorith you want to use
		Blob.valueOf(dataToVerify), // Convert to blob
		EncodingUtil.base64Decode(signature), // Creates Blob from String
		EncodingUtil.base64Decode(publicKey)  // Creates Blob from String
	);
}
	

/**
 * Method to get the expected signature. This is for testing only, just so you have an
 * idea what the output of the signature looks like
 */ 
private String getSignature(){
	return 'RzgwUN39Dicag301cyf79neCKTZjotoguttb34gZjKKvT3kRj1ZvBtmynqHIRWBET0vDKugtKg/MtPu5h1Y8hqSHmZnkXbld/i737ptVEB6PQdRp26izWlLqpEyzkGrJ/FuJYyRNEV1xJdrnsTP3nBZ8qB0NPwCr9ZInZOWfO3DKspCOBWGaQ7H2ewC1OEr0OKdWqB1ThTP7U9+42KjABgNsnLpVge5xsPQja5QPbvqq+1Krl5z66xTTQQNxMvnKQt1fjUMqaDB52vDYbm8yh8iM4+fDPhbfmoDB5eFqwADjQ3b7kcKYgCF2D56KBxrVVHzFMMR70lkn8q6krZ4Ie9djkfBYAkVTkWSwlxwg70u7mg3O123Ddlcbasikg7FihdE3rRXrV69MkG7XzaxPAhEF0Abtubodoe6B78M8GrGUMGGdS8ad13BOGPTkCo9au8uZO7PjjKr16Hi8z4UAc3j6yFAjwkx6Hc5BgBlrVzdmfeRN6GBEMFkj1X5/OdBDLqSgUQ7t8QQr5GE1p24mMOGSHpvp45EQELJjyqGzJb4SL3CIBN82q0HOryKXE3NUd3PiZK+WanAQKYZfjCn3FpeSnbjXpRu+Fst7oqrv5Zkh4FucwihLqjGfEtwJhJ/gG3mUXqNOTHZ0S03pPuIVo4iiWrBRzY4EeqBDwkqgJCc=';
}


/**
 * Method to get a 256 Bit SHA 256 Private key to give an idea of the format
 * Your key should come from a secure certificate or secret store
 * and NEVER be stored in code or where it is user readable
 */
private String getPrivateKey(){
	String privateKey ='';
	privateKey+='MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDaVmKLA1RFOpv5';
	privateKey+='uCI8QgpeAxpDlkNSxksSn+aJGnLHzBjhAQRLD0skGXk3DH8FQp3ffEX3BC6/M8Ga';
	privateKey+='IF7pAdOt+j3xHv+0+dQ7qpDqk433KKYLJaoI6AfDA5R+CfsJH4RcR0W8kTHF/+SB';
	privateKey+='3aNGq5fDFD5AymIJiQeuJ3GO/r3gbRd5MpC6tI8UzGUQlnKFZvBK0W63nnYkxHEk';
	privateKey+='E7gu/JWoZdfY7UcXEfhWte5DjOwtzq3DsGu4J6peGkYCAOtwCCrkpaumiDe3AqrQ';
	privateKey+='eKoDsT+KDj1qMoD4Tnq1buCKMFQEKHY0KqCeT5IrcHZzsSNYZF4zz2gT6h5N+56G';
	privateKey+='+F281mkHAFzIV582N5P0gh38FCJ/Qg6crRyYKeoxqm12sbxVbGEw0pROMURbHYnc';
	privateKey+='nJlTTFQploVz5ZW8jgO8XEEjWbjkF7IBuu+FCgHFZ3JwoPyMeaAcGPPPRBrJAlR7';
	privateKey+='1sm5f2WelHfJZKBLG8vxOFY9W85v7fMLZztE4yL1+0LiI2W7426ADfJRQ3sO2EA/';
	privateKey+='WyOlTrBrk3Mvsj/9bkQ6C2aIIqNsmnvtQU+hzaZ10tyoIuQiUmHuDWvvKHiLw3EQ';
	privateKey+='c7BLSlZaQkwG66kZUf/OUwsf5u2knywxw3oEbptrhuA8iZ17lQWoxbvkum2an6tA';
	privateKey+='J7cL5yOVEYiq+C/O4gIVAXo7OTfDKwIDAQABAoICAQDXbq8zDSjkWi023EnjfSIv';
	privateKey+='mw4aLDTngsLmcKIPG+qvW6IcuV0cFs4Eo6HoAEuAzDdsIXoDfrwFazMXOeOMM4JD';
	privateKey+='QwxFU1npnyybZvQwkUFd41za2OIKga/O60RkjMKHQPLf/m8/3V/oR1KYFTIa9Ar9';
	privateKey+='sIawdUEAuZW7cC3rc021GM81hgAqSSh41CjQkjITkPt+R2Hgidl28+HTQCXXLuEY';
	privateKey+='VM0CvTUM/W01WbPsMSuFE05/LR9MiM7gpTn4liG43EY+b32MBxI6YMZchwLyO70/';
	privateKey+='IkfU9lotJ3qKdQnXMFJl++qOFJWBP3AxrnkiNGF0wSv2IStHoxUdyy2jbYNIZaMg';
	privateKey+='MmQE+kFhUz0mNaiJqHKoELDT6xEBMxWrfEVt8iQeISplCAh4cBtPUL+xFQ94yIFo';
	privateKey+='CFecmgDk3noUwWu5fbEIkx2ui2mb4aWUN2FICd2KLyJSY/wbtFiKJ4eX49mukGId';
	privateKey+='chNlAymrtVWI0k1GVa3JF+rjGbzJHG/hkxp2ccK4aq3Kl7mmvvYyKVXcgRQ3UQiA';
	privateKey+='EuawNmqXtaTXwWOiBFYG6Gq/GIzsMZAPI2slg3pM0rCR1rJx+EqE8Fd8f4/Ua8WM';
	privateKey+='m3rP50izBEtKWuNNSCopWyWDFH/HRvgKixU71NkLYQ5MHvfcpealH4i7zi3W6aeR';
	privateKey+='5weNmGZ47o5l9xz/JIKpsQKCAQEA//Df6UsDNuCAcyk89d0+AELZ2T0i4xk+7p2M';
	privateKey+='hgPo2iTm5MTgRl01NJ/LmsNJJ813h2dwyV6bMzdx+daziGybbivRJpz2mkCOwSqD';
	privateKey+='E4+7wRjyaYRK8/aBY8KbcTYt6GY+UhBMh01Yg7mRZWSmFo0LL6V6vVVo3irkY6Kh';
	privateKey+='Oy3plW6mTa1LNUMoavqEVyn/v9tYVTsRxiZVtvxjzsfcTuQ+gS1INKs8sTIfY9PV';
	privateKey+='keho+gDaJYn/ZmFb1Tt70zSkQblwAG7nIA0pQtuuUF874FzhH7hUkwuASbjv2D5G';
	privateKey+='5TwXOHbrR+MBrp2XbXSQ074DrCCMuw0xofSeELsaADK9c1p0GQKCAQEA2mNJvB1/';
	privateKey+='TrJY2I/uzILEBl2qo66Sr8o8U0FCl/6/kVWzMIPhZz92+KedFKmJ5DGgFTUWri9F';
	privateKey+='vz8ZxoeUDizikQKG9R26ZxZDJtvlkyKqY28ja9D0Iyb3QhV1qwExO4Fo2XCFgzCY';
	privateKey+='2bqEwMCZ9G9LI3vWE3AOXQi0LdE39ImSRLoYJQmgfxDnoNQeofd3v7mbrwkyKuBv';
	privateKey+='6jB+apeysiXSEsK3c/Xmrc2ceNnwHeZbWJJW+9aMWB0g6kK4fneXOz84F6gaAtU5';
	privateKey+='q5kje02qRJZW8tKGBt07DnflhqAQRuuIIipk5yxCFmnJXUVSyzohoO5QSa53NAS4';
	privateKey+='J7a8t9ivhJt54wKCAQA+IxXJhuut3A1zaBSjwGX4HELVihE5P3zW46slMjfLFmB0';
	privateKey+='NBQbIS/0qcL9vOG65xhY6FUqnmxhn9ltBaIqwetucPbjQAJi6r99yDtweVnlBJB9';
	privateKey+='659i4XsCZFHmx3eXz5Lby5c41h9iQ6A4FJp6KR4JIEzPQLgoEBPI2Mf6HShznhyE';
	privateKey+='CUmUEczzRATzQIAV7UPh1Wh4SgBPX7E/l6g2AxXluL+qAdTHVFromppkRR+ParuL';
	privateKey+='l5hJG+P2ve1PFp22UzYM9N/qGSfmUn1ch/J6gzIoyFDILmej/mFEh8Igj1k33S88';
	privateKey+='EbHr2djUuxMaRSyREon4M7jUEBZ8C2DBoY/7PH+pAoIBAF7wqR6ByFWjDSLgt9Tq';
	privateKey+='yGNoFwXfn9+SUNV02omPcyKwmhzuSHCFU6hX3d8csVimBk0R7lE9NdoliYQYbtIW';
	privateKey+='y0x1R8yJ5v5n3Dupf02O1Xoy17hId8pMZ1OwVp5H/2o6ISXeV/ynhNuqzYmqcYOl';
	privateKey+='WooLjQ6YOXZSkVoVyXii0hbUvChl3gM/iyMM9GA/YCzWeQsIOWoQdjbebCbU2he+';
	privateKey+='f2wugGiGL4nBiFO1k0C8Y1vHCs+i/xJTX3rYFLLONM3J9w25w80Ve2PRSG6TXgFB';
	privateKey+='Rn177k5PoRvyHbOAJHNgc6c+vO0O/ZAW3zaQK6U0GWiIEhlmImZX4uNI+xQFvJAu';
	privateKey+='szcCggEAdOOsFRBiTMWgCZ3Q3vqB6rkzIUiqZ9vwJzJHy3mIoENkQLsjZgKSsJBq';
	privateKey+='Ter+eMX8HaObGbKV7f10RBzJnV6yq/z7BohuUbkQ+an8BWYSnveWgu1eHifyaDVG';
	privateKey+='h7SivmPeJDq6HE0Nh2jehfjpsmZmnUSTk0Lz7FBshT5o7R5T8Od7hXWIZMLBoXih';
	privateKey+='CSjMXI6IbT94nG0110GbvlHkwbbK/TN/7rUA3Afepzq74kKgY5zJP3aj6tq1FlCh';
	privateKey+='8Y5Y9uoB29EfrzSWrRkXjZQhR/yiyIulUV/NZS2KqWMtQGJjw9aeUVLqyglIzS5q';
	privateKey+='SB/8ZTFkXV09anyt4L5j8t6Th1DUdA==';
	return privateKey;
}


/**
 * Method to get the public key
 * Again this is just for illustative purposes, you would NEVER put a key like this in your code
 */
private String getPublicKey(){
	String publicKey ='';
	publicKey+='MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2lZiiwNURTqb+bgiPEIK';
	publicKey+='XgMaQ5ZDUsZLEp/miRpyx8wY4QEESw9LJBl5Nwx/BUKd33xF9wQuvzPBmiBe6QHT';
	publicKey+='rfo98R7/tPnUO6qQ6pON9yimCyWqCOgHwwOUfgn7CR+EXEdFvJExxf/kgd2jRquX';
	publicKey+='wxQ+QMpiCYkHridxjv694G0XeTKQurSPFMxlEJZyhWbwStFut552JMRxJBO4LvyV';
	publicKey+='qGXX2O1HFxH4VrXuQ4zsLc6tw7BruCeqXhpGAgDrcAgq5KWrpog3twKq0HiqA7E/';
	publicKey+='ig49ajKA+E56tW7gijBUBCh2NCqgnk+SK3B2c7EjWGReM89oE+oeTfuehvhdvNZp';
	publicKey+='BwBcyFefNjeT9IId/BQif0IOnK0cmCnqMaptdrG8VWxhMNKUTjFEWx2J3JyZU0xU';
	publicKey+='KZaFc+WVvI4DvFxBI1m45BeyAbrvhQoBxWdycKD8jHmgHBjzz0QayQJUe9bJuX9l';
	publicKey+='npR3yWSgSxvL8ThWPVvOb+3zC2c7ROMi9ftC4iNlu+NugA3yUUN7DthAP1sjpU6w';
	publicKey+='a5NzL7I//W5EOgtmiCKjbJp77UFPoc2mddLcqCLkIlJh7g1r7yh4i8NxEHOwS0pW';
	publicKey+='WkJMBuupGVH/zlMLH+btpJ8sMcN6BG6ba4bgPImde5UFqMW75Lptmp+rQCe3C+cj';
	publicKey+='lRGIqvgvzuICFQF6Ozk3wysCAwEAAQ==';
	return publicKey;
}
{
    "messageId": "PfNxko2cChY94KsiU9cvUL",
    "eventId": "client.updated",    
    "eventSchemaVersion": 1.0,
    "eventInstanceOriginationDateTime": "2022-03-07T00:37:23Z",
    "eventData": {
        "siteId": 123,
        "saleId": 96,
        "purchasingClientId": "100001049",
        "payments": [
            {
                "paymentId": 103,
                "paymentMethodId": 14,
                "paymentMethodName": "Cash",
                "paymentAmountPaid": 300,
                "paymentLastFour": null,
                "paymentNotes": null
            }
        ],
        "saleDateTime": "2018-05-03T16:52:23Z",
        "soldById": 10,
        "soldByName": "Jane Doe",
        "locationId": 1,
        "totalAmountPaid": 150,
        "items": [
            {
                "itemId": 78,
                "type": "Service",
                "name": "10 Punch Pass",
                "amountPaid": 150,
                "amountDiscounted": 0,
                "quantity": 1,
                "recipientClientId": "100000009",
                "paymentReferenceId": 44
            },
            {
                "itemId": 79,
                "type": "Service",
                "name": "10 Kick Pass",
                "amountPaid": 150,
                "amountDiscounted": 0,
                "quantity": 1,
                "recipientClientId": "100000009",
                "paymentReferenceId": 44
            }
        ]
    }
}
public class Sale {
public String messageId;
public String eventId;
public Decimal eventSchemaVersion;
public String eventInstanceOriginationDateTime;
public SaleEventData eventData;
}


public class SaleEventData {
public Integer siteId;
public Integer saleId;
public String purchasingClientId;
public List<PaymentDetails> payments;
public String saleDateTime;
public String soldById;
public String soldByName;
public Integer locationId;
public Integer totalAmountPaid;
public List<SaleItemDetails> items;
}

public class PaymentDetails {
public Integer paymentId;
public Integer paymentMethodId;
public String paymentMethodName;
public String paymentAmountPaid;
public Integer paymentLastFour;
public String paymentNotes;
}

public class SaleItemDetails {
public Integer itemId;
public String type;
public String name;
public Integer amountPaid;
public Integer amountDiscounted;
public Integer quantity;
public String recipientClientId;
public Integer paymentReferenceId;
}

Sale mbSale = (Sale)JSON.deserialize(jsonInput, Sale.class);
/* JSON EXAMPLE
{
    "messageId": "PfNxko2cChY94KsiU9cvUL",
    "eventId": "client.updated",    
    "eventSchemaVersion": 1.0,
    "eventInstanceOriginationDateTime": "2022-03-07T00:37:23Z",
    "eventData": {
        "siteId": 123,
        "saleId": 96,
        "purchasingClientId": "100001049",
        "payments": [
            {
                "paymentId": 103,
                "paymentMethodId": 14,
                "paymentMethodName": "Cash",
                "paymentAmountPaid": 300,
                "paymentLastFour": null,
                "paymentNotes": null
            }
        ],
        "saleDateTime": "2018-05-03T16:52:23Z",
        "soldById": 10,
        "soldByName": "Jane Doe",
        "locationId": 1,
        "totalAmountPaid": 150,
        "items": [
            {
                "itemId": 78,
                "type": "Service",
                "name": "10 Punch Pass",
                "amountPaid": 150,
                "amountDiscounted": 0,
                "quantity": 1,
                "recipientClientId": "100000009",
                "paymentReferenceId": 44
            },
            {
                "itemId": 79,
                "type": "Service",
                "name": "10 Kick Pass",
                "amountPaid": 150,
                "amountDiscounted": 0,
                "quantity": 1,
                "recipientClientId": "100000009",
                "paymentReferenceId": 44
            }
        ]
    }
}*/


public class Sale {
public String messageId;
public String eventId;
public Decimal eventSchemaVersion;
public String eventInstanceOriginationDateTime;
public SaleEventData eventData;
}


public class SaleEventData {
public Integer siteId;
public Integer saleId;
public String purchasingClientId;
public List<PaymentDetails> payments;
public String saleDateTime;
public String soldById;
public String soldByName;
public Integer locationId;
public Integer totalAmountPaid;
public List<SaleItemDetails> items;
}

public class PaymentDetails {
public Integer paymentId;
public Integer paymentMethodId;
public String paymentMethodName;
public String paymentAmountPaid;
public Integer paymentLastFour;
public String paymentNotes;
}

public class SaleItemDetails {
public Integer itemId;
public String type;
public String name;
public Integer amountPaid;
public Integer amountDiscounted;
public Integer quantity;
public String recipientClientId;
public Integer paymentReferenceId;
}

Sale mbSale = (Sale)JSON.deserialize(jsonInput, Sale.class);
/* JSON EXAMPLE
{
    "messageId": "PfNxko2cChY94KsiU9cvUL",
    "eventId": "client.updated",    
    "eventSchemaVersion": 1.0,
    "eventInstanceOriginationDateTime": "2022-03-07T00:37:23Z",
    "eventData": {
        "siteId": 123,
        "saleId": 96,
        "purchasingClientId": "100001049",
        "payments": [
            {
                "paymentId": 103,
                "paymentMethodId": 14,
                "paymentMethodName": "Cash",
                "paymentAmountPaid": 300,
                "paymentLastFour": null,
                "paymentNotes": null
            }
        ],
        "saleDateTime": "2018-05-03T16:52:23Z",
        "soldById": 10,
        "soldByName": "Jane Doe",
        "locationId": 1,
        "totalAmountPaid": 150,
        "items": [
            {
                "itemId": 78,
                "type": "Service",
                "name": "10 Punch Pass",
                "amountPaid": 150,
                "amountDiscounted": 0,
                "quantity": 1,
                "recipientClientId": "100000009",
                "paymentReferenceId": 44
            },
            {
                "itemId": 79,
                "type": "Service",
                "name": "10 Kick Pass",
                "amountPaid": 150,
                "amountDiscounted": 0,
                "quantity": 1,
                "recipientClientId": "100000009",
                "paymentReferenceId": 44
            }
        ]
    }
}*/


public class Sale {
public String messageId;
public String eventId;
public Decimal eventSchemaVersion;
public String eventInstanceOriginationDateTime;
public SaleEventData eventData;
}


public class SaleEventData {
public Integer siteId;
public Integer saleId;
public String purchasingClientId;
public List<PaymentDetails> payments;
public String saleDateTime;
public String soldById;
public String soldByName;
public Integer locationId;
public Integer totalAmountPaid;
public List<SaleItemDetails> items;
}

public class PaymentDetails {
public Integer paymentId;
public Integer paymentMethodId;
public String paymentMethodName;
public String paymentAmountPaid;
public Integer paymentLastFour;
public String paymentNotes;
}

public class SaleItemDetails {
public Integer itemId;
public String type;
public String name;
public Integer amountPaid;
public Integer amountDiscounted;
public Integer quantity;
public String recipientClientId;
public Integer paymentReferenceId;
}

Sale mbSale = (Sale)JSON.deserialize(jsonInput, Sale.class);
public Boolean mapContains(Map<id,Object> searchObj, String searchKey, String searchVal){
	for (ID idKey : searchObj.keyset()) {
		System.debug(searchObj.get(idKey).get(searchKey));
		if( searchObj.get(idKey).get(searchKey) == searchVal) {
			System.debug('Match Found'+ searchObj.get(idKey));
			return true;
		}else{
			System.debug('No Match');

		}
	}
	return false;
}
@wire(callout2Apex, {id: this.recordId})
function({ error, data }) {
  if (data) {
    this.arr = JSON.parse(data).keyFromJSON;
    this.loaded = true;
  } else if (error) {
    this.loaded = false;
  };
}
Map<String,String> theOne = new Map<String,String>();
Map<String,String> theTwo = new Map<String,String>();

theOne.put('task', 'Active');
theOne.put('task2', 'Inactive');
theOne.put('task3', 'Inactive');
theOne.put('task4', 'Inactive');

theTwo.put('task', 'Active');
theTwo.put('task2', 'Inactive');
theTwo.put('task3', 'Inactive');
theTwo.put('task4', 'Inactive');

void toggleActive(String taskName, Map<String,String> taskMap){
    taskMap.put(taskName, 'Active'); 
    for(String key : taskMap.keySet()){
        if(key != taskName){
       	 taskMap.put(key, 'Inactive');
        }
    }
}

toggleActive('task3', theTwo);

System.debug(theOne);
System.debug(theTwo);
Human fred = new Human();

fred.setName('Fred');
fred.setAge(18);

fred.Run();
fred.Jump();
fred.Climb();
public class Human {
    public String Name;
    public Integer Age;
    
    public Human(){
      this.Age = 0;
    }
        
    public void setName(String Name){
        this.Name = Name;
    } 
    
    public void setAge(String Name){
        this.Age = Age;
    } 
    
    public void Run(){
        System.debug('Run');
    } 
    
    public void Jump(){
        System.debug('Jump');
    } 
    
    public void Climb(){
        System.debug('Climb');
    } 
}
public class TestClass {
    
    public Static Integer copies = 0;
    
    
    public TestClass(){
        this.add();
    }
    
       
    public void add(){
        copies++;
    } 
    
    public Static void subtract(){
        copies--;
        System.debug(copies);
    } 


}
trigger AccountTrigger on Account (before insert) {

      if(Trigger.isInsert && Trigger.isBefore) {

        
        List<Account> myList = new List<Account>();

        for(Account acct : Trigger.new){
          if(acct.name == 'My Test Account'){
           acct.AnnualRevenue = 0;
           myList.add(acct);
          }
        }

        if(myList.size() >= 0){
          insert myList;
        }
      }   
}
(before insert, after insert,before update, after update, before delete, after delete, after undelete)
trigger ContactTrigger on Contact (before insert) { //Context and Event
   
    if(Trigger.isInsert && Trigger.isBefore) { // Condition
       System.debug(Trigger.new);	// Action
    } 
  
}
public with sharing class ContactTriggerHandler {
    //
    // custom trigger handler setup to handler all triggers received on Contact object
    //
    public Boolean isTriggerExecuted = true;
    private boolean myIsExecuting = false;
    private integer BatchSize = 0;

    public ContactTriggerHandler(boolean isExecuting, integer size) {
        myIsExecuting = isExecuting;
        BatchSize = size;
    }

    //
    // On Before Insert
    //
    public void OnBeforeInsert(List<Contact> contactList){
        List<String> emailList = new  List<String>();
        
        for(Contact contact : contactList){
              emailList.add(contact.email);
        }
        
		List<Contact> newContactList = new List<Contact>();
        List<Lead> leadList = [SELECT id,firstname,lastname, email,LeadSource,phone, MobilePhone,OwnerId,HasOptedOutOfEmail FROM Lead WHERE email IN :emailList];
       
        for(Contact cItem : contactList){
            //Merge
            for(Lead lItem: leadList){
            	cItem.HasOptedOutOfEmail = lItem.HasOptedOutOfEmail;
            	cItem.OwnerId = lItem.OwnerId;
            	cItem.LeadSource = lItem.LeadSource;
            	cItem.MobilePhone = lItem.MobilePhone;
				cItem.phone = lItem.phone;
            	cItem.LeadSource = lItem.LeadSource;
           	 	newContactList.add(cItem);
            }

        }
                

    }

    //
    // On After Insert
    //
    public void OnAfterInsert(List<Contact>  contactList) {
       
        List<String> emailList = new  List<String>(); 
        for(Contact contact : contactList){
              emailList.add(contact.email);
        }
        
        List<Lead> leadList = [SELECT id,firstname,lastname, email,LeadSource,phone, MobilePhone,OwnerId,HasOptedOutOfEmail FROM Lead WHERE email IN :emailList];
        List<Task> taskTransferList = [SELECT Id, Who.Id, Who.Type FROM Task WHERE Who.Type = 'Lead'];
        List<Task> taskUpdate = new List<Task>();
        
        for(Contact cItem : contactList){
            //Move Task to Contact
            for(Lead lItem: leadList){
                if(taskTransferList.size() > 0){
                    for(Task taskItem :taskTransferList){
                        taskItem.whoid = cItem.id;
                        taskUpdate.add(taskItem);
                    }
                }

        
            }
            upsert taskUpdate;
            delete leadList;

        }
  
}
public with sharing class TruncateId {
    public TruncateId() {

    }

    @InvocableMethod(label='Truncate ID' description='Transaction Id on Opportunity Object' category='Opportunity')
    public static void Truncate(List<Opportunity> OppIds){

        ID oppID = OppIds[0].id;

        Opportunity opp = [SELECT id, TranscationId__c, name FROM Opportunity WHERE id = :oppID];

      
        String last6 = opp.TranscationId__c.right(6);
        if(opp.TranscationId__c != null){    
            if(last6 != opp.Name.right(6)){
                opp.name = opp.name + last6;
                update  opp;
            }
        }
      

    }

    public class GetOppId{
        @InvocableVariable(required=true label='Opportunity Id')
        public ID oppID;

    }

}
//Parent to Child
SELECT Name, (SELECT name FROM Sessions__r) FROM Public_Event__c
//Child to Parent
SELECT id, name, Public_Event_Name__r.name, Public_Event_Name__r.id From Sessions__c
public class OutterClass {
    Public String name = 'outterclass';
    
    public void setName(String name){
        this.name = name;
	}
    
    public class InnerClass{
       Public String name = 'innerclass';
    }

}
Integer year = 2021, mon=02, day=12, hour=23, min=50;

Datetime dtGMT = Datetime.newInstanceGMT(year, mon, day, hour, min, 0);

String exTimezone = 'America/Los_Angeles';
String dateTimeForamat = 'yyyy-MM-dd HH:mm:ssz';
String schedulerFormat = 'mm:HH:dd:MM:yyyy';
String crnTemplate = '0 {0} {1} {2} {3} ? {4}';

String localFromatted = dtGMT.format(dateTimeForamat, UserInfo.getTimeZone().getId());
String exFormatted = dtGMT.format(dateTimeForamat, exTimezone);

Datetime localDTValueGMT = Datetime.valueOfGMT(localFromatted);
Datetime exDTVaueGMT = Datetime.valueOfGMT(exFormatted);

Integer minDiff = (Integer)(localDTValueGMT.getTime() - exDTVaueGMT.getTime())/60000;

Datetime scheduleDTGMT = dtGMT.addMinutes(minDiff + 15);

String schFormmated = scheduleDTGMT.formatGMT(schedulerFormat);

String cronExp = String.format(crnTemplate, schFormmated.split(':'));

System.debug('dtGMT : ' + JSON.serialize(dtGMT));
System.debug('localDTValueGMT : ' + JSON.serialize(localDTValueGMT));
System.debug('exDTVaueGMT : ' + JSON.serialize(exDTVaueGMT));
System.debug('scheduleDTGMT : ' + JSON.serialize(scheduleDTGMT));
System.debug('cronExp: ' + cronExp);
star

Wed Feb 22 2023 20:09:34 GMT+0000 (UTC)

#apex
star

Mon Dec 05 2022 13:55:41 GMT+0000 (UTC)

#apex
star

Tue Nov 08 2022 11:30:02 GMT+0000 (UTC)

#apex
star

Thu Nov 03 2022 12:41:59 GMT+0000 (UTC)

#apex
star

Thu Nov 03 2022 12:11:51 GMT+0000 (UTC) https://developer.salesforce.com/forums/?id=906F0000000BIVqIAO

#apex
star

Thu Nov 03 2022 12:05:58 GMT+0000 (UTC) https://developer.salesforce.com/forums/?id=906F0000000BIVqIAO

#apex
star

Thu Nov 03 2022 11:34:28 GMT+0000 (UTC)

#apex
star

Thu Oct 20 2022 02:32:03 GMT+0000 (UTC)

#apex
star

Mon Oct 10 2022 11:20:54 GMT+0000 (UTC)

#apex
star

Mon Oct 10 2022 11:16:34 GMT+0000 (UTC)

#apex
star

Fri Aug 12 2022 15:25:54 GMT+0000 (UTC)

#apex
star

Tue Jul 05 2022 14:57:47 GMT+0000 (UTC) https://developer.salesforce.com/forums?id=906F00000008wSGIAY

#apex
star

Mon Jul 04 2022 15:54:08 GMT+0000 (UTC)

#apex
star

Thu Sep 16 2021 17:38:28 GMT+0000 (UTC) https://www.zenintech.org/blog/creating-your-first-apex-class

#apex #salesforce #static #keywords #class
star

Sat Jul 24 2021 14:14:46 GMT+0000 (UTC)

#apex #salesforce #trigger
star

Sat Jul 24 2021 09:42:42 GMT+0000 (UTC)

#apex #salesforce #trigger
star

Fri Jul 23 2021 00:18:27 GMT+0000 (UTC)

#apex #salesforce #trigger
star

Sat Jun 05 2021 06:34:17 GMT+0000 (UTC)

#apex #salesforce
star

Mon Apr 05 2021 17:47:03 GMT+0000 (UTC)

#apex #salesforce
star

Wed Dec 16 2020 17:34:22 GMT+0000 (UTC)

#apex #datetime

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension