Query regarding trigger? - triggers

I am having following requirement:
1) To get list of all the users for whome profile has been changed.
2) Then query on FRUP (It is a custom object) to retrieve all the records which are associated with the user whose profile is changed.(FRUP object will contain the list of all the records created by all the users on all the objects say Account, Opportunity)
3) Update FRUP.
For achieving this I wrote one trigger through which i am able to fetch list of all the users whose profile has changed which is as follows:
Trigger UserProfileTrigger on User (before update) {
List<User> usr = new List<User>();
Map<String,String> userMap = new Map<String,String>();
for(User u: Trigger.new){
//Create an old and new map so that we can compare values
User oldOpp = Trigger.oldMap.get(u.ID);
User newOpp = Trigger.newMap.get(u.ID);
//Retrieve the old and new profile
string oldProfileId = oldOpp.profileId;
string newProfileId = newOpp.profileId;
//If the fields are different, the profile has changed
if(oldProfileId != newProfileId){
System.debug('Old:'+oldProfileId);
System.debug('New :'+newProfileId);
usr.add(u);
System.debug('User :'+usr);
}
}
}
Also Following are the fields on custom object FRUP:
1)Owner
2)Name
3)Record ID
4)Folder ID
5)Created By
6)Last Modified By
any help/suggestions??

I'm not sure what field on the FRUP references the user Id it relates to, but you can loop through the FRUP object with something like this:
List<FRUP> frupToUpdate = new List<FRUP>();
for (FRUP f : [
Select
OwnerId,
Name, //etc.
UserId //the field that references the user Id
from FRUP
where userId = : usr]) {
//update field on FRUP, e.g. f.Name = 'New Name';
frupToUpdate.add(f);
}
This selects the FRUP records that relate to the users with changed profiles. It then updates a field on the record and adds the record to a list for updating. Note that this should be after your loop for(User u: Trigger.new). Then update the FRUP records that have changed:
update frupToUpdate;

Related

How to change CreatedBy in work item history?

I am trying to change the CreatedBy field in a work item to a test user I have. The CreatedBy field is being updated on the creation of the work item and I have bypassRules set to true. For a bit I thought the code I wrote was not updating the CreatedBy field because in the History section it still said: "USER created the User Story". Note that "USER" is the member who has the access token.
However, if I pull the work item I just created and pull the CreatedBy information it points out to the test user member, which is correct behavior. So my only problem is that history is not updating, is there a way to change CreatedBy in the history section? Below is a snippet of the code I am using to create the work item.
patchDocument.Add(
new JsonPatchOperation()
{
Operation = Operation.Add,
Path = "/fields/System.CreatedBy",
Value = workItem.CreatedBy //Represents string "Test User"
}
);
WorkItem result = workItemTrackingHttpClient.CreateWorkItemAsync(patchDocument, project, "User Story", bypassRules: true).Result;
Console.WriteLine("User Story Successfully Created: User Story #{0}", result.Id);
workItem.ItemId = (int)result.Id;
WorkItem testResult = workItemTrackingHttpClient.GetWorkItemAsync(project, workItem.ItemId).Result;
IdentityRef createdBy = (IdentityRef)testResult.Fields["System.CreatedBy"];
Console.WriteLine(createdBy.DisplayName); //This correctly displays "Test User"
return result;

Apex code to update new Opportunity with values from related object

What would be the proper method to update a list of new Opportunities with the values from a related record.
for (Opportunity opps:Trigger.new){
[SELECT Id, CorpOwner__r, Contact__r,(SELECT Id, AccountLocation from Account)]
o.CorpOwner__r =Account.Id; o.AccountLocation = opps.Account.AccountLocation;
insert opps
Do you call the lookup fields by the __r suffix? Could you do a before insert operation and still look up the Opportunity.CorpOwner__r relationship to values in the CorpOwner__r Account record, or does that relationship not exist since the record has not been created? What would be a proper batchified way to go about it?
Here's a possibility that demonstrates a number of concepts:
trigger UpdateOpptyWithAccountInfo on Opportunity (before insert) {
// Keep this SOQL query out of the FOR loop for better efficiency/batching
Map<Id, Account> relatedAccounts = new Map<Id, Account>(
[SELECT Id, AccountLocation__c
FROM Account
WHERE Id IN
(SELECT AccountId
FROM Opportunity
WHERE Id = :Trigger.new)
]
);
for (Opportunity o : Trigger.new) {
/* Find each opportunity's Account in the map we queried for earlier
* Note: there's probably a more efficient way to use a Map of Opportunity IDs to Account objects...
* This works fine and could be more readable.
*/
for (Account a : relatedAccounts.values()) {
if (a.Id == o.AccountId) {
// Once you've found the account related to this opportunity, update the values
o.CorpOwner__c = a.Id;
o.AccountLocation__c = a.AccountLocation__c;
}
}
}
// We're still inside an `insert` trigger, so no need to call `insert` again.
// The new fields will be inserted along with everything else.
}
If you're establishing the relationship between objects, use the __c suffix:
o.CorpOwner__c = a.Id; // Associate Account `a` as Opportunity `o`'s CorpOwner
If you're looking up a field on a related object, then you would use __r:
System.debug(o.CorpOwner__r.Name); // Print Opportunity `o`'s CorpOwner's name

Creating a Trigger that will create a new Opportunity Owner every time a there is a new Opportunity in Salesforce

I'm new to Salesforce and I'm trying to create a trigger that will basically update fields and create a new Opportunity owner every time a new Opportunity gets added.
For clarity, I've attached my code below:
trigger trig_Opportunity_CreateOppOwner on Opportunity (before insert, before update) {
//Opportunity OppOwner = null;
List<id>OppsID = new List<id>(); //Get the id of all new Opportunities owners
for (Opportunity Opp : Trigger.new) { //If a new Opportunity is added, then create new OppOwner, if not, then don't add.
OppsId.add(Opp.ID); //adds all new Opportunities Id's
}
List<Opportunity>OppToUpdate = [SELECT Id,
Name,
Owner__c,
OppOwner,
FROM Opportunity
WHERE Id IN: Opp.ID // Select Id, OpportunityName,
];
if Trigger.oldMap.get(opp.id).Owner__c != Trigger.oldMap.get(OppToUpdate.id).Owner__c // verify that if previous Opportunity has a matching owner.
OppsId.add(Opp.ID); //populates new oppowner with ID's of all owners.
This is basically what I'm trying to do:
Trigger(Before Update, Before Insert){
Get all Triggered Opportunities.
Verify if old opportunities already has a matching Owner.
If it's not a matching owner, update Opportunity fields and update the opportunity.
I'm not sure how to get from step 2 to step 3. Any help would be appreciated.
By the code that you provided isn't clear where it's finished, from my side seems that after couples of lines that you've provided another couples of lines exists. Could you please post all your code? If it isn't so, and code that you posted is all your code, from my point of view, this code do nothing, absolutely nothing.
Why?
no validation's errors
no DML operation
trigger trig_Opportunity_CreateOppOwner on Opportunity (before insert, before update) {
//Opportunity OppOwner = null;
/*
List<id>OppsID = new List<id>(); //Get the id of all new Opportunities owners
for (Opportunity Opp : Trigger.new) { //If a new Opportunity is added, then create new OppOwner, if not, then don't add.
OppsId.add(Opp.ID); //adds all new Opportunities Id's
}
*/
// 3 started lines might be replaced by the following one
List<id>OppsID = Trigger.newMap.getKeys();
//but the following code perform select on Opportunity object and return the same list as Trigger.new
// OppToUpdate == Trigger.new
// What for? May be you should work with this part on "after insert/update"
List<Opportunity>OppToUpdate = [SELECT Id,
Name,
Owner__c,
OppOwner,
FROM Opportunity
//WHERE Id IN: Opp.ID // Opp - isn't exist and it isn't list/set of id
WHERE Id IN OppsId // I guess you meant this
];
// 1.variable "opp" isn't exist here
// 2. "OppToUpdate.id" - you can't use list in this manner
if Trigger.oldMap.get(opp.id).Owner__c != Trigger.oldMap.get(OppToUpdate.id).Owner__c // verify that if previous Opportunity has a matching owner.
OppsId.add(Opp.ID); //populates new oppowner with ID's of all owners.

Prevent duplicate values on bulk insert (Salesforce)

I need a trigger that receives data from users (Bulk load of about 1000 records) and store them in a Salesforce database. The problem is that users can show up more than once in Trigger.new or even on a different batch. The custom object name is CBK_User and has an EXTERNAL_ID (unique) called USER_ID. In my code I check that the users does not yet exist in the database:
Map<String, CBK_User__c> users = new Map<String,CBK_User__c>
([select Id, USER_ID__c from CBK_User__c where USER_ID__c in : userIds]);
(userIds has the external ids of the Trigger.new objects)
When a I try to insert, it gives me the error:
DUPLICATE_VALUE, duplicate value found: USER_ID__c duplicates value on
record with id: a1QJ0000000HRd8"
How do I prevent duplicate values on bulk insert?
I've adapted your problem to this basic example (Exercise 2: Lead duplicate prevention)
You should clean first the "new" list from duplicated entries, and then clean from existing in db.
trigger CBK_UserDuplicatePreventer on CBK_User__c (before insert, before update) {
//Enter a map declaration to hold records which we will add,
// this will become a unique map, no duplicate values within it.
Map<String, CBK_User__c> cbkUserMap = new Map<String, CBK_User__c>();
//The next few lines loop across the array of records that are passed into
//the trigger in bulk fashion from any API or User Interface database operation.
//The goal of this loop is to ensure that there are no duplicates within
//the batch that we have received and to gather a list of externalIds that we will use later
for (CBK_User__c cbkUser : System.Trigger.new) {
/* Make sure we don't treat an externalId that
isn't changing during an update as a duplicate. */
if ((cbkUser.USER_ID__c != null) && (System.Trigger.isInsert ||
(cbkUser.USER_ID__c != System.Trigger.oldMap.get(cbkUser.Id).USER_ID__c))) {
// Make sure another new CBK_User__c isn't also a duplicate
if (cbkUserMap.containsKey(cbkUser.USER_ID__c)) {
cbkUser.USER_ID__c.addError('Another new CBK_User__c has the same USER_ID.');
} else {
cbkUserMap.put(cbkUser.USER_ID__c, cbkUser);
}
}
}
// Using a single database query, find all the CBK_User__c in
// the database that have the same USER_ID as ANY
// of the CBK_User__c being inserted or updated. */
for (CBK_User__c cbkUser : [SELECT USER_ID__c FROM CBK_User__c WHERE USER_ID__c IN :cbkUserMap.KeySet()]) {
CBK_User__c newCbkUser = cbkUserMap.get(cbkUser.USER_ID__c);
newCbkUser.USER_ID__c.addError('A CBK_User__c with this USER_ID already exists.');
}
}

Why is this Exception?- The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects

I m getting this Exception-"The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects."
I ve user table and country table. The countryid is referred in user table.
I am getting the above Exception when I am trying to add entry in user table.
This is my code-
using (MyContext _db = new MyContext ())
{
User user = User .CreateUser(0, Name, address, city, 0, 0, email, zip);
Country country = _db.Country.Where("it.Id=#Id", new ObjectParameter("Id",countryId)).First();
user.Country = country;
State state = _db.State.Where("it.Id=#Id", new ObjectParameter("Id", stateId)).First();
user.State = state;
_db.AddToUser(user );//Here I am getting that Exception
_db.SaveChanges();
}
Try adding the user first, then adding the relationships.
See http://www.code-magazine.com/article.aspx?quickid=0907071&page=4
Or, don't use User.CreateUser where you are explicitly setting an Id = 0, instead use User user = new User() {Name = Name, Address = ...}
BTW, with Entity Framework 4 you can set the foreign key IDs directly removing the need to load the related object if you know its ID.