I know that there's already several posts on SE for this error but none of them explain this for me.
I'm testing my code by editing one Project Deadline date field, the upProjects size is one and as you can see, I'm adding the Project Month records to a list (existPMs).
But I still get the error
List has more than 1 row for assignment to SObject: External entry point
when I execute the code.
trigger ProjectLifecycle on MPM4_BASE__Milestone1_Project__c (after insert, after update) {
List<WEID__c> weids = WEID__c.getall().values();
Set<Id> validRecordTypeIds = new Set<Id>();
// add Project Record Type Ids from Custom Setting to list of valid Ids
for(WEID__c weid: weids) {
try {
validRecordTypeIds.add(weid.WEProjectId__c);
} catch (System.StringException e) {
System.debug(
System.LoggingLevel.ERROR,
'Invalid Record Type Id ' + weid.WEProjectId__c
);
}
}
List<MPM4_BASE__Milestone1_Project__c> insProjects = new List<MPM4_BASE__Milestone1_Project__c>();
List<MPM4_BASE__Milestone1_Project__c> upProjects = new List<MPM4_BASE__Milestone1_Project__c>();
Map<Id,Integer> projectDuration = new Map<Id,Integer>();
Map<Integer,String> monthName = new Map<Integer,String>{1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December'};
List<Project_Month__c> newPMs = new List<Project_Month__c>();
List<Project_Month__c> existPMs = new List<Project_Month__c>();
for(MPM4_BASE__Milestone1_Project__c p : Trigger.New){
//check that Project record type is valid
if(validRecordTypeIds.contains(p.RecordTypeId))
{
try{
MPM4_BASE__Milestone1_Project__c oldP = Trigger.OldMap.get(p.Id);
if(oldP.MPM4_BASE__Kickoff__c != p.MPM4_BASE__Kickoff__c
||
oldP.MPM4_BASE__Deadline__c != p.MPM4_BASE__Deadline__c)
{
upProjects.add(p);
projectDuration.put(p.Id, p.MPM4_BASE__Kickoff__c.monthsBetween(p.MPM4_BASE__Deadline__c));
}
//if old.Map is null, record has been inserted & project months should be added
}catch(system.NullPointerException e){
insProjects.add(p);
projectDuration.put(p.Id, p.MPM4_BASE__Kickoff__c.monthsBetween(p.MPM4_BASE__Deadline__c));
}
}
}
if(insProjects.size() > 0){
for(MPM4_BASE__Milestone1_Project__c p : insProjects){
Date k = p.MPM4_BASE__Kickoff__c;
Integer km = p.MPM4_BASE__Kickoff__c.month();
Integer dur = projectDuration.get(p.Id);
//create a set of Project Month records for each Project
for(Integer m = km; m < km + dur + 1; m++){
Project_Month__c pm = new Project_Month__c();
pm.Project__c = p.Id;
pm.Name = monthName.get(m)+' '+ k.addMonths(m - 1).year();
pm.month__c = k.addMonths(m - km + 1).toStartOfMonth() - 1;
pm.Project_Value__c = p.Opportunity_Total_Net_FSR__c;
newPMs.add(pm);
system.debug('newPMs contains ' + newPMs);
}
}
}
system.debug('upProjects size is ' + upProjects.size() );
if(upProjects.size() > 0){
for(MPM4_BASE__Milestone1_Project__c p : [SELECT Id,
(SELECT Id FROM Project_Months__r) FROM MPM4_BASE__Milestone1_Project__c
WHERE Id IN :upProjects]){
existPMs.add(p.Project_Months__r);
}
delete existPMs;
for(MPM4_BASE__Milestone1_Project__c p : upProjects){
Date k = p.MPM4_BASE__Kickoff__c;
Integer km = p.MPM4_BASE__Kickoff__c.month();
Integer dur = projectDuration.get(p.Id);
for(Integer m = km; m < km + dur + 1; m++){
Project_Month__c pm = new Project_Month__c();
pm.Project__c = p.Id;
pm.Name = monthName.get(m)+' '+ k.addMonths(m - 1).year();
pm.month__c = k.addMonths(m - km + 1).toStartOfMonth() - 1;
pm.Project_Value__c = p.Opportunity_Total_Net_FSR__c;
newPMs.add(pm);
system.debug('newPMs contains ' + newPMs);
}
}
}
insert newPMs;
}
I'd used some code from Trailhead as the template for this! (The last sample code on the page).
I've also tried changing the above to
List<MPM4_BASE__Milestone1_Project__c> pList = [SELECT Id,
(SELECT Id FROM Project_Months__r) FROM MPM4_BASE__Milestone1_Project__c
WHERE Id IN :upProjects];{
existPMs.add(pList.Project_Months__r);
}
delete existPMs;
but that causes the error
Initial term of field expression must be a concrete SObject: