Apex Trigger, change Account Owner to Event Owner - salesforce

I'm a newbie and I'd like to ask you a little help for what follows:
I create a new Event on an Account owned by User X and I assign this event to User Y.
Then, I'd like to have a trigger that changes the ownership of the Account to user Y (previously owned by User X).
How can I do it?
Thanks a lot

This can be solved just changing some fields on the account every time it a new event is created on this account.
You would need a trigger on Event:
trigger EventTrigger on Event (after insert){
EventTriggerHandler.changeAccountOwner(Trigger.New);
}
then on the EventTriggerHandler class you would have this:
public static class EventTriggerHandler{
public void changeAccountOwner(Event triggerNew){
//we are cheching the prefix of the field on the event that tells you where it was created
String idPrefix = String.valueOf(triggerNew.WhatId).subString(0,2);
if(idPrefix == '001'){ // this is because the event may be created sometwhere else and not always in an account
Account a = [SELECT Id, OwnerId FROM Account WHERE Id = :triggerNew.WhatId];
//we just place the owner of the event to be the owner of the account
a.OwnerId = triggerNew.OwnerId;
update a;
}
}
}

Related

Salesforce Lookup field showing ID value instead of record name

Hi I have a custom object which has a custom field of type lookup to Account. The child custom record gets created when Account record is created. I am creating child record in after insert trigger on Account and keeping the name of child record same as of the name of Account.
But In the name I am getting 15 digit Id instead of real name of account. What can be the issue?
Code## for Trigger
if(Trigger.isAfter && (Trigger.isInsert)){
AccountTriggerHelper.createReferrer(Trigger.new);
}
In Apex Class:
public static void createReferrer(List<Account> accountList){
List<Referral__c> newReferral = new List<Referral__c>();
for(Account acc : accountList) {
if(acc.Talos_RecordType__c=='Referrer'){
system.debug('==acc=1='+acc);
Referral__c ref = new Referral__c();
System.debug('-----acc.Name----'+acc.Name);
ref.Name = acc.Name;
ref.Account__c = acc.Id;
ref.Email__c = acc.PersonEmail;
ref.Talos_IQOS_Expert_ID__c = acc.Talos_IQOS_Expert_ID__c;
ref.Talos_Referrer_Type__c = acc.Referrer_Type__c;
ref.User_Id__c = acc.UserID__c;
ref.Email_Validation__c = true;
ref.Store_Code__c = acc.Store_Code__c;
newReferral.add(ref);
system.debug('==referral=1='+newReferral);
}
}
Thanks,
Marc
This code can't lead to population of Id in the Name field. There might be another trigger on Account or child Object, or any workflow, process builder on your org creating that change again. Can you check the created date and modified date of the child record.
If they are different, then most probably I am right.

System.TypeException: DML operation INSERT not allowed on __Share

I have created share object in my salesforce environment.
From Setup-> security Controls -> Sharing Settings -> I made my custom object access to "Private". So suppose my object name is EVT_Client__c & I am trying to insert data into EVT_Client__Share from trigger(AfterInsert) I am unable to do it. I am getting error as given below.
Once data get inserted into EVT_Client__c object our trigger tries to insert data into EVT_Client__share object but we are getting error. Profile user who is inserting data into EVT_Client__c object through UI having Read/create/edit/delete access on object.
System.TypeException: DML operation INSERT not allowed on
EVT_Client__Share
My code in trigger is as below in which I am getting error.
public with sharing class EVT_Client_TriggerHandler {
private void ShareClientToThirdPartyJobGroup(List<EVT_Client__c> lstClients){
List<EVT_Client__Share> lstSharesForThirdPartyGroup = new List<EVT_Client__Share>();
List<Group> lstThirdPartyGroups = [Select Id, RelatedId from Group where Name = 'Third Party'];
for(EVT_Client__c client: lstClients){
for(Group roleGroup : lstThirdPartyGroups ){
EVT_Client___Share objShareForThirdPartyGroup = new EVT_Client__Share(ParentId = client.Id,
UserOrGroupId = roleGroup.Id,
AccessLevel = 'Edit',
RowCause = Schema.EVT_Client__Share.RowCause.User_Client__Access__c);
lstSharesForThirdPartyGroup.add(objShareForThirdPartyGroup);
}
}
insert lstSharesForThirdPartyGroup;
}
}
You're sure it's not a "detail" in any master-detail relationship? The OWD would then say "controlled by parent" instead of "private". Can you switch to Classic view, go to page layout and verify the [Sharing] button can be added, displays OK, this user can manually share this record from UI?
Post your code sample? I suspect you need to define Apex Sharing Reason first. It's bit like roles if you ever played with Account/Contact/Opportunity/Case roles.
Once it's set you should be able to do something like this code sample: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_bulk_sharing_creating_with_apex.htm (they use "manual" as sharing reason but you might have more luck with custom sharing reason.
I quickly created your object and this worked like a charm for me:
trigger Stack57201752 on EVT_Client__c (after insert) {
List<Group> groups = [SELECT Id FROM Group WHERE Name = 'Third Party'];
List<EVT_Client__Share> shares = new List<EVT_Client__Share>();
for(EVT_Client__c c : trigger.new){
for(Group g : groups){
shares.add(new EVT_Client__Share(
ParentId = c.Id,
UserOrGroupId = g.Id,
AccessLevel = 'Edit',
RowCause = 'Manual'
));
}
}
insert shares;
}
And when I click the [Sharing] button on the record it looks good:
So... Stupid question time: have you clicked this checkbox?

I to assign a default account to a custom object using Visualforce page

I am new to salesforce development. I am trying to create a visualforce page which helps to insert a new record into the custom object. Custom object has master-detail relationship with account. I am having issue when assiging a default value to the Account. The account already exists in the accounts table. Here is the Apex class I am trying.
public class RelatedAccount{
public Account parent {get; set;}
public RelatedAccount(ApexPages.StandardController controller){
Transaction__c child = (Transaction__c)controller.getRecord();
if (child.Account__c != null) { parent = [Select ID,Name FROM Account WHERE Account.Name = :'1Company Inc.,' LIMIT 1];
child.Account__c = parent;
}
}}
I am getting the error : "Illegal assignment from Account to Id"
Thanks In advance.
This should work:
child.Account__c = parent.Id
In your case you try to put the "whole" account object object into the Lookup field. But this just needs the Id of the parent account.

How can we reverse the functionality to copy billing Address to shipping Address in Account object?

Actually there was an existed functionality to copy billing Address to shipping Address in Account object. But i want to create a button so that shipping address have to copy into billing address.
You can create page and controller and call them from the button
public with sharing class CopyBilling {
string accId;
public CopyBilling (){
accId = ApexPages.currentPage().getParameters().get('accId');
}
public PageReference copy(){
Account acc = ...
return new PageReference('/'+acc.Id)
}
}
<apex:page controller="CopyBilling" action="{!copy}"></apex:page>
I implemented a custom check box field and workflow field update. Slightly more rudimentary, but it works.
Create a custom checkbox 'copy shipping to billing' on the account object.
Create immediate workflow actions of 'field update' for each field you want copied over. Select 'Use a formula to set the new value' and insert the corresponding shipping address field for each field update.
On save, the record with replace the billing fields with the shipping fields.

How can I get the name of the Lead Owner in a Lead custom formula field?

I've got an application that reads Lead records from Salesforce via the API and I want to link the Lead Owner field to an attribute in the application. The Lead Owner field doesn't up in the list of available fields but all the custom fields do.
So, my first attempt at a solution was to create a custom field that displayed the Lead Owner name. In the SF formula editor, as far as I can tell, it doesn't display the actual data field but instead displays the ID string. Which is pretty meaningless in the context that I need it for.
alt text http://skinny.fire-storm.net/forposting/insertfield.JPG
Is there a way that we can get at the data in the object that the ID string references?
alt text http://skinny.fire-storm.net/forposting/havewant.JPG
I have the RED BOX but need the GREEN BOX.
EDIT: I can't change the application code that calls the API. I can only change salesforce. So, this is more of a salesforce superuser / formula-writer question, not a question about writing code that calls the SF API.
Salesforce allows access to related data through what they call relationship queries. Instead of joining, you specify the query like this:
System.debug([SELECT Owner.Name FROM Lead WHERE Id = '00QS00000037lvv'].Owner.Name);
Try running that in the system log, just replace the lead ID with one that you're looking at.
When accessing the data through the API, the principle is the same, your proxy objects should allow you to access Lead.Owner.Name.
EDIT:
I agree with eyescream, since you can't change the application code, creating an Apex trigger would be the best way to go here. Here's some code to get you started:
trigger Lead_UpdateOwner on Lead(before insert, before update)
{
Map<Id, String> ownerMap = new Map<Id, String>();
for (Lead lead : Trigger.new)
{
ownerMap.put(lead.OwnerId, null);
}
if (ownerMap.size() > 0)
{
for (User[] users : [SELECT Id, Name FROM User WHERE Id IN :ownerMap.keySet()])
{
for (Integer i=0; i<users.size(); i++)
{
ownerMap.put(users[i].Id, users[i].Name);
}
}
for (Lead lead : Trigger.new)
{
lead.OwnerName__c = ownerMap.get(lead.OwnerId);
}
}
}
lead.OwnerName__c would need to be the name of your custom field on the lead object that will hold the owner name. Type Text, length 121.
I had a similar problem, but wanted all the current and future User fields available. Since a custom lookup field to the User is not restricted by formula fields, I created one named
OwnerLookup
on the Opportunity and Account objects, then used a triggers to populate it on creation or edit. For example the Opportunity trigger is this:
trigger OpportunityTrigger on Opportunity (before insert, after insert, before update, after update) {
if(trigger.isBefore && trigger.isInsert) {
OpportunityTriggerHandler.newOpportunity(Trigger.old, Trigger.new);
}
else if(trigger.isAfter && trigger.isInsert){
//OpportunityTriggerHandler.futureUse(Trigger.new);
}
else if(trigger.isBefore && trigger.isUpdate){
OpportunityTriggerHandler.updateOpportunity(Trigger.new, Trigger.oldMap);
}
else if(trigger.isAfter && trigger.isUpdate){
//OpportunityTriggerHandler.futureUse(Trigger.new, Trigger.oldMap);
}
}
and the OpportunityTriggerHandler class (Apex code) is:
public with sharing class OpportunityTriggerHandler {
public static void newOpportunity( List<Opportunity> oldOpportunitys, List<Opportunity> newOpportunitys ) {
for (Opportunity opp: newOpportunitys) {
updateOwnerData( opp );
}
}
public static void updateOpportunity( List<Opportunity> oldOpportunitys, Map<Id, Opportunity> newOpportunitys ) {
for (Opportunity opp: oldOpportunitys) {
updateOwnerData( opp );
}
}
public static void updateOwnerData( Opportunity opp ) {
opp.OwnerLookup__c = opp.OwnerId;
}
}
I then create Formula fields on the Opportunity/Account objects to get to any of the owner (User) object fields, such as Oppty Owner Name formula field:
OwnerLookup__r.FirstName & " " & OwnerLookup__r.LastName
VLOOKUP function would be a good try, but
it's available only in validation rules, not in field definitions
it can be used only on custom objects and you need data from User
I'd say you need to query from your application for
SELECT Owner.FirstName, Owner.LastName FROM Lead
Other than that... some "after insert, after update" trigger that would populate your custom field when owner changes?
Just posting for completeness sake (and for the Google searches): The issue arises with any object that can be queued, not just Lead, since the source of it is that the owner can refer to either a user (as usual) or a queue object.
This can be resolved using a formula field instead of triggers, like below:
BLANKVALUE(Owner:Queue.QueueName, Owner:User.FirstName & " " & Owner:User.LastName)
Basically, the BLANKVALUE function in the formula checks whether the owner.queuename is blank, and if so gives the name of the user.

Resources