Map to avoid Duplicate records - triggers

I have a Holiday Custom object,it contains Unique Dates based on
country based How to retrieve the value in Map
I have tried:
List<Holiday__c> holidays = new List<Holiday__c>([Select id, Date__c,Country__c from Holiday__c]);
Map<date, Holiday__c> mapOfHolidays = new Map<date, Holiday__c>();
for (Holiday__c holiday: holidays) mapOfHolidays.put(holiday.Date__c , holiday);
Suppose date for example 3/8/17 is for country france and Italy,If i put Key Value as Date__c,Map does not contain Key as duplicates,But for each country unique Dates are there
So what i have to use Key and Value in Map,I want to retrieve the date using Map,please anyone Help for me the answer
trigger ignoreweekends on order (before insert,before update) {
Set<id> accountIds = new Set<Id>();
for (order ord : Trigger.new) {
accountids.add(ord.AccountId);
}
map<id, account> mapOfAccounts = new map<id, account>([select id,JDE_Date_Delivery_Offset__c from account where id IN: accountIds]);
List<Holiday__c> holidays = new List<Holiday__c>([Select id, Date__c from Holiday__c]);
Map<date, Holiday__c> mapOfHolidays = new Map<date, Holiday__c>();
for (Holiday__c holiday: holidays) mapOfHolidays.put(holiday.Date__c , holiday);
for (order so : Trigger.new) {
Account acc = mapOfAccounts.get(so.AccountId);
for(integer i=0;i<=acc.JDE_Date_Delivery_Offset__c;i++) {
Datetime dt = DateTime.newInstance(Date.today() +acc.JDE_Date_Delivery_Offset__c.longvalue(), Time.newInstance(0, 0, 0, 0));
String dayOfWeek=dt.format('EEEE');
if(dayOfWeek == 'saturday' || dayOfWeek == 'sunday'|| mapOfHolidays.containskey(mapOfHolidays.Date__c))
acc.JDE_Date_Delivery_Offset__c = acc.JDE_Date_Delivery_Offset__c+ 1;
so.JDE_Synchronization_Date__c = Date.today().addDays(acc.JDE_Date_Delivery_Offset__c.intValue());
}
}
}

If I understood correctly, for one unique date you have multiple countries.
For this you can create a map of Date as key and List as value instead of creating a Map of Date and Holiday_c.
For example :
Map<Date, List<Holiday__c>> mapofHolidays = new HashMap<Date, List<Holiday__c>>();
After that you can retrieve all countries for a unique date and do the required processing.

Related

How to map newest records from the list by each id?

I have a method in apex class that will get attachments (ContentDocument) from e-mail of case and will add it to another case. There are 2 questions below in order to finish my code:
How to create logic to get list of e-mails where I need only the newest e-mail for each case?
How can I create logic to get list of srID passed in this method?
Both questions are mentioned in the proper part of the code below:
public static void AttFromParenttoClonedCaseList(list<ID>srID){
list< ContentDocumentLink> attchlist2=new list< ContentDocumentLink>();
Map<Id, Case> mapCasess = new Map<Id, Case>();
Map<Id, EmailMessage> mapEmail = new map<Id, EmailMessage>();
Map<Id, EmailMessage> mapemailmessageId = new Map<Id, EmailMessage>();
List<String> externalIdCases = new List<String>();
List<String> casesID = new List<String>();
List<Case> ListCaseNumber = new List<Case>([SELECT ID, External_ID__c From Case WHERE ID IN :srID]);
for (Case mpC : ListCaseNumber){
mapCasess.put(mpC.id, mpC);
}
for (Case Listcase : ListCaseNumber) {
externalIdCases.add(Listcase.External_ID__c);
}
List<Case> ListCaseID = new List<Case>([SELECT ID From Case WHERE ID IN :externalIdCases]);
for (Case listIdcases : ListCaseID) {
casesId.add(listIdcases.id);
}
Map<id, EmailMessage> listEmailMessage = new Map<id, EmailMessage>([SELECT parentID, ID From EmailMessage WHERE parentID IN :casesId order by parentid, createddate desc]);
\\How to create logic to get list of e-mails where I need only the newest e-mail for each case (base on list listEmailMessage above)?
List<ContentDocumentLink> contentdocumentId = new List<ContentDocumentLink>([SELECT ID, ContentDocumentId FROM ContentDocumentLink WHERE LinkedEntityId IN :/*list of emailmessages*/]);
for (ContentDocumentLink links : contentdocumentId){
ContentDocumentLink linkAtt = new ContentDocumentLink();
linkAtt.LinkedEntityId = \\how can I create logic to get list of srID passed in this method?
linkAtt.ContentDocumentId = links.ContentDocumentId;
linkAtt.ShareType = 'V';
linkAtt.Visibility = 'AllUsers';
attchlist2.add(linkAtt);
}
if (attchlist2.size() > 0)
insert attchlist2;
}
How to create logic to get list of e-mails where I need only the
newest e-mail for each case?
Something like this should be a good start
SELECT Id, CaseNumber, Subject,
(SELECT Id, FromAddress, ContentDocumentIds
FROM EmailMessages
WHERE Incoming = true
ORDER BY CreatedDate DESC
LIMIT 1)
FROM Case
LIMIT 10
It's simpler to treat it as "parent + related list, filtered, sorted" than "give me all emails for this parent, I'll build a Map or something with them, manually loop through them, compare dates to pick most recent...". I haven't worked with Emails for a while so you might need more filters but it's a good start.
how can I create logic to get list of srID passed in this method?
Not sure I understand. You want to re-link attachments from old case's emails to new case? See if that ContentDocumentIds is enough to build new links. If not - loop through results of my query, collect all EmailMessage Ids and query ContentDocumentLinks WHERE LinkedEntityId IN :emailMessageIds?
Check if this compiles?
// I don't really need it as a Map, list seems to be fine. But looks like you wanted Maps so I went with map.
// Map might be useful if External_ID__c is not a lookup.
// If you want a list (or set) of Ids from a query the very easy trick is to do
// Set<Id> myIds = new Map<Id, Account>([SELECT Id FROM Account LIMIT 5]).keyset();
// Anyway.
// "External_ID__c" is a lookup to Case or something else? Assuming it's just a lookup, bit like "ParentId".
Map<Id, Case> originals = new Map<Id, Case>([SELECT Id, CaseNumber, External_ID__c, External_ID__r.CaseNumber,
(SELECT Id, FromAddress, ContentDocumentIds
FROM EmailMessages
WHERE Incoming = true
ORDER BY CreatedDate DESC
LIMIT 1)
FROM Case
WHERE Id IN :srId AND External_ID__c != null]);
List<ContentDocumentLink> links = new List<ContentDocumentLink>();
for(Case original : originals.values()){
System.debug('source: ' + original);
System.debug('target: ' + original.External_ID__r.CaseNumber);
if(!original.EmailMessages.isEmpty()){
List<String> documentIds = original.EmailMessages[0].ContentDocumentIds;
for(String i : documentIds){
links.add(new ContentDocumentLink(
LinkedEntityId = original.External_ID__c,
ContentDocumentId = i,
ShareType = 'V',
Visibility = 'AllUsers'
));
}
}
}
insert links;

Connecting Unrelated Objects during Apex Trigger

I am trying to create a trigger that does the following:
Once an Account has been created, create an unrelated record (called a "Portal Content" record) that bears the same name, assuming the default RecordTypeId
Take the ID of the newly created "Portal Content" record, and insert it into a lookup field on the originally created Account
Add the ID of the original Account, and enter it into a field of the newly created "Portal Content" record
Steps 1 and 2 were addressed in post Populate Lookup Field with Record Created From Trigger. The new problem is that when attempting Item 3, in the Trigger.isAfter code block, a.Portal_Content_Record__r returns null rather than with the Id value populated after insert p in the Trigger.isBefore block.
trigger newAccountCreated on Account (before insert, after insert) {
List<Account> alist = Trigger.New;
if(Trigger.isBefore){
for(Account a : alist) {
if (a.RecordTypeId == '012i0000001Iy1H') {
Portal_Content__c p = new Portal_Content__c(
Name=a.Name,
RecordTypeId='012i0000001J1zZ'
);
insert p;
a.Portal_Content_Record__c = p.Id;
system.debug('Made it to insert p. P = ' + p.Id +'. a.Portal_Content_Record__c = ' + a.Portal_Content_Record__c);
}
}
}
if (Trigger.isAfter) {
for(Account a : alist){
system.debug('a.Id = ' + a.Id + ', p = ' +a.Portal_Content_Record__r);
String p = a.Portal_Content_Record__c;
for(Portal_Content__c port : [SELECT ID FROM Portal_Content__c WHERE Id = :p]){
port.School_SFDC_ID__c = a.Id;
update port;
}
}
}
}
My question has two parts:
How do I assign a field on the newly inserted Portal_Content__c record with the ID of the Account that started the trigger?
Can this be done within this trigger, or is a secondary "helper" trigger needed?
I was able to figure out a way to answer this issue within the same Trigger. The Trigger.isAfter && Trigger.isInsert code block is what solved my problem.
trigger newAccountCreated on Account (before insert, after insert, after delete) {
List<Account> alist = Trigger.New;
List<Account> oldlist = Trigger.old;
if(Trigger.isBefore){
for(Account a : alist) {
if (a.RecordTypeId == '012i0000001Iy1H') {
Portal_Content__c p = new Portal_Content__c(
Name=a.Name,
RecordTypeId='012i0000001J1zZ'
);
insert p;
a.Portal_Content_Record__c = p.Id;
}
}
}
else if (Trigger.isAfter && Trigger.isDelete){
for(Account a : oldlist){
for(Portal_Content__c p : [SELECT ID FROM Portal_Content__c WHERE ID = :a.Portal_Content_Record__c]){
delete p;
}
}
}
if (Trigger.isAfter && Trigger.isInsert){
for(Account a : alist){
List<Portal_Content__c> plist = [SELECT ID FROM Portal_Content__c WHERE Id = :a.Portal_Content_Record__c];
for(Portal_Content__c p : plist){
p.School_SFDC_ID__c = a.Id;
update p;
}
}
}
}
This code block does a query for Portal_Contact__c records that match the Account record's Portal_Content_Record__c field value, which is assigned in the first code block. It then takes the Portal_Content__c records found, and assigns the original Account's Id to the record's School_SFDC_ID__c field value.

Trying to convert Apex Query List to string not sure if this is correct

I am trying to execute a SOQL query that may return a list. If list is null I want to set default value. I am new to apex so not sure if this is correct.
Here is what I have:
// SET USERNAME STRING
string username = '%'+UserInfo.getFirstName()+'%';
//SET DEFAULT PRODUCTid
Id ProductID = '01t46000000nPO0AAM';
//MAP IDMAPPRODUCT2
Map<Id> idmapproduct2 = new Map<Id>([Select Id FROM Product2 WHERE ProductCode like '%LAB %' AND ProductCode like:username]); system.debug(idmapproduct2);
//CHECK IF MAP IS NULL AND IF NOT SET IT TO PRODUCT ID
if(idmapproduct2 != null)
{ProductID = idmapproduct2;}
In this case you dont ned a Map and your use of Map is incorrect. Use a list instead.
List<Product2> idmapproduct2 = [Select Id FROM Product2 WHERE ProductCode like '%LAB %' AND ProductCode like:username LIMIT 1]; system.debug(idmapproduct2);
//CHECK IF MAP IS NULL AND IF NOT SET IT TO PRODUCT ID
if(idmapproduct2.size() != 0){
ProductID = idmapproduct2[0].Id;
}
use below lines....
List<Product2> prodList = new List<Product2>([Select Id FROM Product2 WHERE ProductCode like '%LAB %' AND ProductCode like:username Limit 1]);
if(prodList.size() > 0) ProductID = prodList[0].Id;

Salesforce Trigger: Update field Trigger from Custom Object

New to apex and have a question about writing triggers. Essentially, I'm trying to create a trigger that updates a given field when another field is updated (after a record is created/inserted into Salesforce).
More specifically, when a custom Account lookup field (lookup value is a custom object record) is updated, it should update another field with a different value from the custom object record.
i.e. When I update the High School name to Elm High School, it will also update the yield associated with that high school.
Below is the code that I've created so far:
trigger UpdateYield on Account (before update) {
Set<String> HS = new Set<String>();
for (Account hsName : Trigger.new) {
if (hsName.High_School_LU__c != null) {
HS.add(hsName.High_School_LU__c);
}
List<High_School__c> y = [SELECT Name, Yield__c FROM High_School__c WHERE Name IN :HS];
Map<String, High_School__c> yLU = new Map<String, High_School__c>();
for (High_School__c h : y) {
yLU.put(h.Name, h);
}
for (Account YieldU : Trigger.new) {
if (YieldU.High_School_LU__c != null) {
High_School__c a = yLU.get(YieldU.Name);
if (a != null) {
YieldU.Yield__c = a.Yield__c;
}
}
}
}
}
It saves however, it still does not work when I update the field.
Any help would be greatly appreciated. Thanks in advance.
The problem here is that the value of a lookup field is not actually a string (as displayed in the UI) but an ID, so when you perform your SOQL query you are comparing an ID to the Name field and getting no results.
If you change your code to the following you should get the result you expect.
It should also be notified that this simple use case could also be accomplished using a simple Workflow Field Update rather than a trigger.
trigger UpdateYield on Account (before update)
{
Set<Id> HS = new Set<Id>();
for (Account hsName : Trigger.new)
{
if (hsName.High_School_LU__c != null)
{
HS.add(hsName.High_School_LU__c);
}
}
Map<Id, High_School__c> y = [SELECT Name, Yield__c FROM High_School__c WHERE Id IN :HS];
for (Account YieldU : Trigger.new)
{
High_School__c a = y.get(YieldU.High_School_LU__c);
if (a != null)
{
YieldU.Yield__c = a.Yield__c;
}
}
}

Match Dates and Count in Entity Framework

I have two tables:
create table dbo.Dates (
Id int not null
constraint Dates_Id_PK primary key clustered (Id),
[DateValue] date not null
}
create table dbo.Posts (
Id int identity not null
constraint Posts_Id_PK primary key clustered (Id),
Created datetime not null,
Title nvarchar (200) not null
)
For these tables I have Date and Post entities.
How can I get a table that has the column DateValue from Dates and the number of Posts with that date.
I need to match the datetime Created value to the date DateValue.
Thank you,
Miguel
I assume your Posts have dates with times, so you'll have to truncate them to the date part (as in the Date property of a DateTime):
from d in context.Dates
select new {
Date = d.DateValue,
NrOfPosts = (from p in context.Posts
where EntityFunctions.TruncateTime(t.Created) == d.DateValue
select p).Count()
}
you can use anonymous types. try the following snippet.
DateTime dateToMatch = GetDateToMatch();
using(YourEntities context = new YourEntities())
{
var result = context.Dates.Where(d => d.DateValue == dateToMatch)
.Select(d => new { Date = d.DateValue, PostCount = d.Posts.Count() });
}