• Eric Pepin
  • NEWBIE
  • 165 Points
  • Member since 2016

  • Chatter
    Feed
  • 6
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 36
    Replies

Hi I am new to SOQL and trying to write a query on the account object that will return a count of the number of records that have been edited in the last 7 days.

I tried this code but get error on compile Illegal assignment from integer to list

public with sharing class TestDisplayQueryList{ 
public List<Account> Records {get; set;} 
public TestDisplayQueryList(){ 
Records = 
[select count() from account where LastModifiedDate = LAST_N_DAYS:7]; 

}

Any help would be greatly appreciated! 
Hi Everyone,
    I have a situation in which I am trying to push an apex invocable code (used by a process builder) in production . Now the process flow gets deployed as inactive flow . So in order to get coverage for my apex invocable , I am using following test class to fire the invocable . Important lines are marked in bold. Now when I run this , it does not throw any error and says 0/0 methods passed. Can someone please help me with this?
///////////////////Test Class//////////////////////////////
@isTest
private class CanInvocableHelperTest {

    @testSetup static void setup1() {

        Id currentUser = UserInfo.getUserId();
        Opportunity opp = TestUtil.setupTestData();
        opp.StageName = 'Closed Won';
        opp.Sub_Stage__c = 'Awarded';
        opp.Qty_of_CANs_Required__c = 1;
        opp.Did_Price_Change__c='No';
        update opp;
        //Updating Opportunity creates 1 can record.
        //Retrive the related CAN record using SOQL.
        CAN__c theCan = [SELECT Opportunity__c,Contract_Manager__c,Status__c,Awarded_Project__c FROM CAN__c Where Opportunity__c =:opp.Id];
        theCan.Contract_Manager__c = currentUser;
        theCan.Status__c='CP Setup';
        theCan.Awarded_Project__c='111111111';
        List<Id> TestCanIdList= new List<Id>();
        TestCanIdList.add(theCan.Id);
        // Change status to simulate process flow firing mechanism.As process flow is inactive.
        update theCan;

        Test.startTest();
        //calling invocable method here with can id
        CreateProjectRecord.ProjectRecordCreateMethod(TestCanIdList);

        
        Test.stopTest();
        }
}


///////////////////Invocable apex class////////////////////////////
public class CreateProjectRecord{ 
    
    @InvocableMethod     
    public static void ProjectRecordCreateMethod(List<Id> CanIds)     
    {        
        //Logic here
    }
}
Hello Developers!

I have a trigger on contact which rollsup number of contact on account.
Trigger works fine but however I have a question.
Trigger Code:
Trigger ContacstTotalCount On Contact(After Insert, After Update, After Delete, After Undelete){
    
    Set<ID> AccountIds = New Set<ID>();
    
    If(Trigger.IsInsert || Trigger.IsUpdate || Trigger.IsUndelete){
        For(Contact C:Trigger.New){
            AccountIds.add(C.AccountID);
        }
    }
    If(Trigger.IsDelete){
        For(Contact C:Trigger.Old){
            AccountIds.add(C.AccountID);
        }
    }
    
    List<Account> AccountListToUpdate = New List<Account>();
    
    For(Account a: [Select Id, total_contacts__c, (Select Id FROM Contacts) FROM Account WHERE ID = :AccountIds]){
        
        a.total_contacts__c = a.contacts.size();
        AccountListToUpdate.add(a);
    }
    try{
    Update AccountListToUpdate;
    }
    Catch(Exception E){
    System.Debug('Thrown Exception is: ' + E.getMessage());
    }
    
}

In line 18 I am having SOQL in parameters of FOR loop. Would that be okay or I should be write something like following?
List<Account> FetchingActs = [Select Id, total_contacts__c, (Select Id FROM Contacts) FROM Account WHERE ID = :AccountIds];
    
    For(Account a: FetchingActs ){
        
        a.total_contacts__c = a.contacts.size();
        AccountListToUpdate.add(a);
    }
I mean... if I take the above approach then wouldn't it only work for first 50,000 Accounts?
And also what happens when each account has 5 contacts then would query fetch 50,000 accounts plus 5 contact from each?
Thank You!
 
I wrote a trigger that parses values from the Description field on our case object.  The purpose is to parse out values from our internal monitoring service to update fields and the appropriate accounts.  The parsing works and the trigger has worked consistantly in our sandbox but I cannot write a test class that passes.  I keep getting an the following error:  "System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, RmmEmailCaseUpdate: execution of AfterInsert
caused by: System.StringException: Invalid id:  
Trigger.RmmEmailCaseUpdate: line 51, column 1: []"  

The account I am using in the string is correct and always sets the account when I use the trigger in Sandbox but does not work when I write the test class.  My class and test class are below.



trigger RmmEmailCaseUpdate on Case (after insert) {
    
    if (trigger.isAfter){
        if (trigger.isUpdate || trigger.isInsert){
            
            //Create set of Opportunity Ids based on updated Opportunity/s
            
            Set <String> caseIds = new Set <String>();            
            for (Case ca : trigger.new){                
                caseIds.add(ca.ID);
            }            
            Map <String, case>matchingcasecomps = new Map <String, case> ();
            for(case c: [select Id, Subject, Description, SuppliedEmail, RMM_Alert_Date_and_Time__c , RMM_Action_Required__c, RMM_Computer_Name__c, RMM_Error_Message__c , 
                         RMM_Client_Location__c, RMM_Last_Contact_with_Player__c from case where Id in :caseIds])
            {                
                IF( c.SuppliedEmail == 'nocmonitoring@fourwindsinteractive.com' && c.subject.startswith('FWIRMM - Offline Players:')){
                    {
                        string body = c.Description;
                        string sub = c.Subject;
                        string fromAdd = c.SuppliedEmail; 
                        dateTime alertDate = system.now();
                        string action;
                        string computer;
                        string alert;
                        string location;
                        string contact;
                        string accRmm;
                        string accTrimFront;
                        string accTrimRear;                       
                        Id accId;
                                                
                        List<string> parse = body.split('\\n');
                        alert = parse[0];             
                        computer = parse[1];
                        location = parse[3];
                        contact = parse[4];
                        action = parse[5]; 
                        accRmm = parse[8];
                        accTrimFront = accRmm.replaceFirst('\\[(?:rmm)\\:', '');
                        accTrimRear = accTrimFront.replaceFirst('\\:(?:rmm)\\]', '');
                        string accString = accTrimRear;
                       
                        /*List<Account> accQuery = [Select Id from Account Where Id =:accString];
                        FOR(Account accQ: accQuery){
                        IF(accQuery[0] != Null){  
                            accId = [Select Id from Account Where Id =:accString].Id;
                        }else{
                            accId='';
                        }}*/
                        
                        accId = Id.valueOf(accString);
                        c.RMM_Alert_Date_and_Time__c = system.now();
                        c.RMM_Action_Required__c = action;
                        c.RMM_Computer_Name__c = computer;
                        c.RMM_Error_Message__c = alert;
                        c.RMM_Client_Location__c = location;
                        c.RMM_Last_Contact_with_Player__c = contact;
                        c.AccountId = accId;            
                        update c;
                    }

@isTest(seealldata = true)
public class RmmEmailCaseUpdateTest {
static testMethod void RmmEmailCaseUpdate(){


    Case c = new Case(
    subject ='FWIRMM - Offline Players:',
    Description = 'Alert issue - Content Player PC is unreachable \r\n Computer - CLTSD \r\n PC Type/Serial Number - FWPW-QUAD-WIFI-SW / GIG41327 \r\n  \r\n Alert Date and Time - 4/25/2017 3:17:27 AM Client/Location - SpringHill Suites / SpringHill Suites Site \r\n Last contact with Player: ~4/25/2017 12:29:52 AM id 4113~ FAILED \r\n \r\n ACTION REQUIRED - Investigate computer logs. If no fault found, contact client to get PC back online. \r\n \r\n [rmm:0018000000MEgf1:rmm]',
    Origin = 'NOC',
    Status = 'New',
    RecordTypeId = '0123400000046GJ',
    SuppliedEmail = 'nocmonitoring@fourwindsinteractive.com');{
    insert c;  
        }
}     
}
Hello all,

I am struggling to write a Test Class for the following trigger and static class that synchronizes portal users with contact record data:
trigger UpdateContactFromPortalUser on User (after update) {
    //We only want to run on the single item that the user edited 
    if (Trigger.new.size()==1) 
    { 
        User u =_ Trigger.new[0]; 
        //And only if it's a portal user 
        if (u.ContactId!=null) { 
            UpdateContactFromPortalUser.updateContacts(u.Id); 
        } 
    } 
}
global class UpdateContactFromPortalUser { 
    @future 
    public static void updateContacts(String userId) {
        User u = [select ContactId,Email,FirstName,LastName,Title
                    from User
                    where Id=:userId];

        if (u!=null && u.ContactId!=null) {
            Contact c = new Contact(Id=u.ContactId,Email=u.Email,FirstName=u.FirstName,LastName=u.LastName,Title=u.Title);
            update c; 
        }
    }
}
Here is my test class code:
 
@isTest
private class UpdateContactFromPortalUserTest {

static testMethod void testUpdateContacts() {

        Test.startTest(); 
        
        User u = [select Id,ContactId,FirstName from User where ContactId<>'' limit 1]; 

        u.FirstName='Bar';
         
        update u; 

        Test.stopTest(); 

        Contact c = [select FirstName from Contact where Id=:u.ContactId]; 
        System.assertEquals(c.FirstName,u.FirstName); 
    }
}

I am getting no code coverage when I runt the test.  Can someone help point me to what I am missing?

Thanks in advance for any help.

 
public static void sendEmail(String messageBody,String sSubject){
           
       try{
        
        String sRecipantName = UserInfo.getUserEmail();
        String[] sendingTo = new String[]{sRecipantName};
        Messaging.SingleEmailMessage oMail = new Messaging.SingleEmailMessage();
        String sBody = messageBody ;
        oMail.setHtmlBody(sBody);
        oMail.setSubject(sSubject);
        oMail.setBccSender(false);
        oMail.setSenderDisplayName('noreply@salesforce.com');
        oMail.setSaveAsActivity(false);
        oMail.setToAddresses(sendingTo);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { oMail });
       
        }catch(Exception ex){
            system.debug('Exception while Sending Mail ' + ex.getMessage());
        }

    }

}
 

Hi I am new to SOQL and trying to write a query on the account object that will return a count of the number of records that have been edited in the last 7 days.

I tried this code but get error on compile Illegal assignment from integer to list

public with sharing class TestDisplayQueryList{ 
public List<Account> Records {get; set;} 
public TestDisplayQueryList(){ 
Records = 
[select count() from account where LastModifiedDate = LAST_N_DAYS:7]; 

}

Any help would be greatly appreciated! 
Hello all,

I'm working with enterprise org created from environment hub for the client and need to extend apex code limit to 3 500 000 characters to be able to transfer all required code for the custom app.
Where should I address with it or how to achieve this?

Hey guys -
I have a unit test that is exhibiting surprising behavior. In our code there is a trigger on Contact that runs when the contact is inserted/updated & in that trigger there is a future method (callout=true if that makes any difference) that also executes on insert/update.

I have a unit test that runs as a Community user. In the test setup, running as a different admin user, a Contact is created and then the test is run as the Community user.

In the log output, the trigger runs as the admin user & invokes the future method, effectively putting it on the 'future queue'. My expectation was that the @future method would execute as the same user that ran the initial trigger, or - possibly - that it would run in system mode. But what I am seeing is that when the @future method is executed, it is executed as the current user. 

Can I really not know what user my future methods will run as? Is this a bug in the testing framework? Can anyone shed some light on this issue?

Thanks!

Hi Everyone,
    I have a situation in which I am trying to push an apex invocable code (used by a process builder) in production . Now the process flow gets deployed as inactive flow . So in order to get coverage for my apex invocable , I am using following test class to fire the invocable . Important lines are marked in bold. Now when I run this , it does not throw any error and says 0/0 methods passed. Can someone please help me with this?
///////////////////Test Class//////////////////////////////
@isTest
private class CanInvocableHelperTest {

    @testSetup static void setup1() {

        Id currentUser = UserInfo.getUserId();
        Opportunity opp = TestUtil.setupTestData();
        opp.StageName = 'Closed Won';
        opp.Sub_Stage__c = 'Awarded';
        opp.Qty_of_CANs_Required__c = 1;
        opp.Did_Price_Change__c='No';
        update opp;
        //Updating Opportunity creates 1 can record.
        //Retrive the related CAN record using SOQL.
        CAN__c theCan = [SELECT Opportunity__c,Contract_Manager__c,Status__c,Awarded_Project__c FROM CAN__c Where Opportunity__c =:opp.Id];
        theCan.Contract_Manager__c = currentUser;
        theCan.Status__c='CP Setup';
        theCan.Awarded_Project__c='111111111';
        List<Id> TestCanIdList= new List<Id>();
        TestCanIdList.add(theCan.Id);
        // Change status to simulate process flow firing mechanism.As process flow is inactive.
        update theCan;

        Test.startTest();
        //calling invocable method here with can id
        CreateProjectRecord.ProjectRecordCreateMethod(TestCanIdList);

        
        Test.stopTest();
        }
}


///////////////////Invocable apex class////////////////////////////
public class CreateProjectRecord{ 
    
    @InvocableMethod     
    public static void ProjectRecordCreateMethod(List<Id> CanIds)     
    {        
        //Logic here
    }
}
Hi all,

I am trying to make a rendering work with a combination of my email template, a visualforce component and an apex, controller class.

My email template has as RelatedToType the object Opportunity. In the email there should be displayed the most important account data (Account lookup in the object Opportunity). It should also show the contacts to this account, which have their Codigo_JDE__c empty.

What I would like to achieve is to display these contacts only if there are any, if not, the part to display the table of these contacts, should not be displayed.

Here is the part in my email template where I am invoking the Visualforce component:
 
<c:AccountContacts accountIdValue="{!relatedTo.AccountId}"/>

Here is my Visualforce component:
 
<apex:component access="global" controller="AccountContacts">

    <apex:attribute name="accountIdValue" type="String" description="This is the Id of the account" assignTo="{!accountId}" access="global" />
    
    <apex:outputPanel rendered="{!IF(AND(NOT(ISBLANK(conList)),conList.size>0),'Yes','No')}">  
    <tr >
        <td >
          Contact data:<br/><br/>
    
           <table>
           <thead>    
              <tr>
                <th>FIRST NAME</th> 
                <th>LAST NAME</th>
              </tr>
           </thead>        
           <tbody>
           <apex:repeat value="{!Cons}" var="pos">
              <tr>
                <td>{!pos.FirstName}</td>
                <td>{!pos.LastName}</td>                                        
              </tr>
                    
        </apex:repeat>
        </tbody>   
    </table>
   </td>
  </tr>
  </apex:outputpanel>

</apex:component>

I am using this part in the code:
 
rendered="{!IF(AND(NOT(ISBLANK(conList)),conList.size>0),'Yes','No')}"
to render only if the conList is not empty. The conList is declared in the apex class:
 
global with sharing class AccountContacts{
    
    global String accountId{get;set;}
    
    global List<Contact> conList{get;set;}

    global account account{
        get {
          Account = [Select Id, name from Account where id =: accountId];
          return account; }
       set;
    }
    
    global AccountContacts(){

    }
    
    
    global List<Contact> Cons{
        get{        
  
            List<Contact> conList = [SELECT Id,FirstName,LastName,Codigo_JDE__c FROM Contact WHERE AccountId=:accountId and Codigo_JDE__c = null];
            
            Boolean display = false;
            
            if(conList != null && conList.size()>0){

             display=true;
            
            }
            return conList;
        }
        set;
    }
    
    
    global String NewLine {
        get { return '\r\n'; }
        set;
    }
    
}
Unfortunately when I receive the email, even when there are contacts with Codigo_JDE__c empty, they are not being displayed (the table is not being displayed), why?.
I would appreciate if someone could give me tips where to correct this, as I have been spending hours trying to amend this without success.

 
Hi All,

I want to format the SSN number with dashes. By default, it will without dashes.

Example : SSN = 1234567891

I want to convert into this format using apex 123-45-7891

Please let me know how to achieve this.

Thanks,
Vijay

 
Hello Developers!

I have a trigger on contact which rollsup number of contact on account.
Trigger works fine but however I have a question.
Trigger Code:
Trigger ContacstTotalCount On Contact(After Insert, After Update, After Delete, After Undelete){
    
    Set<ID> AccountIds = New Set<ID>();
    
    If(Trigger.IsInsert || Trigger.IsUpdate || Trigger.IsUndelete){
        For(Contact C:Trigger.New){
            AccountIds.add(C.AccountID);
        }
    }
    If(Trigger.IsDelete){
        For(Contact C:Trigger.Old){
            AccountIds.add(C.AccountID);
        }
    }
    
    List<Account> AccountListToUpdate = New List<Account>();
    
    For(Account a: [Select Id, total_contacts__c, (Select Id FROM Contacts) FROM Account WHERE ID = :AccountIds]){
        
        a.total_contacts__c = a.contacts.size();
        AccountListToUpdate.add(a);
    }
    try{
    Update AccountListToUpdate;
    }
    Catch(Exception E){
    System.Debug('Thrown Exception is: ' + E.getMessage());
    }
    
}

In line 18 I am having SOQL in parameters of FOR loop. Would that be okay or I should be write something like following?
List<Account> FetchingActs = [Select Id, total_contacts__c, (Select Id FROM Contacts) FROM Account WHERE ID = :AccountIds];
    
    For(Account a: FetchingActs ){
        
        a.total_contacts__c = a.contacts.size();
        AccountListToUpdate.add(a);
    }
I mean... if I take the above approach then wouldn't it only work for first 50,000 Accounts?
And also what happens when each account has 5 contacts then would query fetch 50,000 accounts plus 5 contact from each?
Thank You!
 
Hello all,

I am struggling to write a Test Class for the following trigger and static class that synchronizes portal users with contact record data:
trigger UpdateContactFromPortalUser on User (after update) {
    //We only want to run on the single item that the user edited 
    if (Trigger.new.size()==1) 
    { 
        User u =_ Trigger.new[0]; 
        //And only if it's a portal user 
        if (u.ContactId!=null) { 
            UpdateContactFromPortalUser.updateContacts(u.Id); 
        } 
    } 
}
global class UpdateContactFromPortalUser { 
    @future 
    public static void updateContacts(String userId) {
        User u = [select ContactId,Email,FirstName,LastName,Title
                    from User
                    where Id=:userId];

        if (u!=null && u.ContactId!=null) {
            Contact c = new Contact(Id=u.ContactId,Email=u.Email,FirstName=u.FirstName,LastName=u.LastName,Title=u.Title);
            update c; 
        }
    }
}
Here is my test class code:
 
@isTest
private class UpdateContactFromPortalUserTest {

static testMethod void testUpdateContacts() {

        Test.startTest(); 
        
        User u = [select Id,ContactId,FirstName from User where ContactId<>'' limit 1]; 

        u.FirstName='Bar';
         
        update u; 

        Test.stopTest(); 

        Contact c = [select FirstName from Contact where Id=:u.ContactId]; 
        System.assertEquals(c.FirstName,u.FirstName); 
    }
}

I am getting no code coverage when I runt the test.  Can someone help point me to what I am missing?

Thanks in advance for any help.

 

Hi all,
I am new to the trigger,Please help me for the error
I have searched all the forums but i couldnt find the answer
trigger OP on Opportunity (after insert)
{
    List<Account> acc=new List<Account>();
    for(Opportunity anu:Trigger.new)
   
    {
        if(anu.OrderNumber__c==111)
        {
            Account at=new Account();
            at.Ownership='Public';
            acc.add(at);
        }
    }
    insert acc;
}
 
We'd like to check if about 200 fields are referenced anywhere in code-- Apex, VF, workflows, trigger.  Text searches really don't cut it as you could have a field such as MyCustomField__c in more than one object.  So without doing the same symbol-table work a compiler would do, with references like myObj1.MyCustomField__c and myObj2.MyCustomField__c you would not know the objec type.

I thought of a way to do it via validation but it does not appear to be working.  The idea I had is --

create a package.xml with no types.
create a destructiveChanges.xml with CustomField entries for the custom fields.

But one the descructiveChanges.xml field has one field I know is reference and a I run a validation with the ant deployment tool, I get a successful validation.

Anyone know why the validation could succeed even with a reference to the field in Apex?

Anyone know any other method that is 100% realiable and understands the object and field name together (no simple text searches)?

 
Hi,
I am using PHP to insert NULL value inside SalesForce's DB (field type is Date).

I tried using NULL, it would not work.
I tried 'NULL', it would not work either.

What is expression to insert NULL value into Date field?

Thanks in advance.
Justin
public static void sendEmail(String messageBody,String sSubject){
           
       try{
        
        String sRecipantName = UserInfo.getUserEmail();
        String[] sendingTo = new String[]{sRecipantName};
        Messaging.SingleEmailMessage oMail = new Messaging.SingleEmailMessage();
        String sBody = messageBody ;
        oMail.setHtmlBody(sBody);
        oMail.setSubject(sSubject);
        oMail.setBccSender(false);
        oMail.setSenderDisplayName('noreply@salesforce.com');
        oMail.setSaveAsActivity(false);
        oMail.setToAddresses(sendingTo);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { oMail });
       
        }catch(Exception ex){
            system.debug('Exception while Sending Mail ' + ex.getMessage());
        }

    }

}
 
I have a trigger which uses UserInfo.getTimeZone() in order to obtain the GMT offset for the current user's timezone.
This offset is then compared to a timezone selected from a picklist field in order to convert a Date/Time field.

For example, if a user is in Los Angeles (GMT -08:00), and they select New York in this timezone picklist (GMT -05:00), the value of the Date/Time picklist field will be adjusted by 3 hours. 
The problem I recently discovered is that sometimes, Timezone.getOffset returns -25200000 milliseconds (-7 hours) instead of the expected -28800000 (-8 hours). This happens using the same user on different records without changing the user timezone at all. 

Because of this, many of our records have fields which are an hour off. Daylight savings time in the US does not go into effect until mid March (2017), so I don't understand how the getOffset function can be returning -7 hours so randomly.
It is highly inconsistent and I have not been able to find anything in common between records using -7 versus those using the correct number of -8. 
Any ideas or help would be greatly appreciated here.
Is there a way to include null values in a Trigger.new record? It looks like the record only includes non-null. In an "after update" trigger, I post the data to an external system to be updated, and I need to know what fields have been removed. I haven't been able to find any information on this.

Thanks.
Hi All

I am new to the apex and trying to link Sobjects Task Activities to a Sobject Weekly Utilization with the same week number and summarize activities' durations. I made a trigger which uses aggregateresult to do this, and it works just fine except it thinks, that the same week's wednesday and thursday have different week numbers. Could anyone help me with this?

Code:
trigger WeeklyUtilizationTrigger on Weekly_Utilization__c (after insert, after update) {

	if((!UtilizerClass.inUtiSync) && (!UtilizerClass.inTaskSync)){
        
        UtilizerClass.inUtiSync = true;

        Map<Id,SFDC_Resource__c> resot = new Map<Id,SFDC_Resource__c>();
        
        Map<Id,Task_Activity__c> tasksToUpdate = new Map<Id,Task_Activity__c>();
        
        List<Weekly_Utilization__c> newUtiz = new List<Weekly_Utilization__c>();
        
        List<Task_Activity__c> tsksToUpdate = new List<Task_Activity__c>();
        
        List<Weekly_Utilization__c> utizToUpdate = new List<Weekly_Utilization__c>();
        
        Map<Id,Task_Activity__c> acts = new Map<Id,Task_Activity__c>();
        
        List<Date> dlist = new List<Date>();

        Set<Id> tskIds = new Set<Id>();

        Set<Id> utiIds = new Set<Id>();
        
        Set<Id> resIds = new Set<Id>();
        
        Map<Id,Task_Activity__c> taskIdsToTask = new Map<Id,Task_Activity__c>();
        
        Map<Id,Id> wuResIds = new Map<Id,Id>();
        
        Map<Id,Weekly_Utilization__c> utiz = new Map<Id,Weekly_Utilization__c>(); 
        
        for(Weekly_Utilization__c uti : Trigger.New){
            dlist.add(uti.Start_Date__c);
            resIDs.add(uti.Resource__c);
            utiz.put(uti.Id,uti);
            resot.put(uti.Resource__c,null);
            wuResIDs.put(uti.Id,uti.Resource__c);
            utiIds.add(uti.Id);
            
        }
        //Collecting dates and using the smallest one as a filter
        dlist.sort();
        Date PVM_A = dlist[0];

        //Quering Task Activities

        for(Task_Activity__c tsk :[select Id, Resourcee__c, Billable__c, Project_Task__c, Duration_in_minutes__c, Start__c, End__c, Week_Number__c 
                                    from Task_Activity__c 
                                    where Resourcee__c in :resIds
                                    and End__c>=:PVM_A
                                    and End__c <:PVM_A+7
                                    and Billable__c=true]){
            acts.put(tsk.Id,tsk);
            taskIdsToTask.put(tsk.Id,tsk);
        }
        system.debug('taskIdsToTask values: '+taskIdsToTask.keySet());
        for(Task_Activity__c tsk :[select Id, Resourcee__c, Billable__c, Project_Task__c, Duration_in_minutes__c, Start__c, End__c, Week_Number__c 
                                    from Task_Activity__c 
                                    where Resourcee__c in :resIds
                                    and End__c>=:PVM_A
                                    and End__c <:PVM_A+7
                                    and Weekly_Utilization__c in :utiIds]){
            tskIds.add(tsk.Id);
        }
        Map<String,List<Id>> tskDates = new Map<String,List<Id>>();
        Map<Id,Map<String,Decimal>> durations = new Map<Id,Map<String,Decimal>>();
        
        //AggregateResult for Task Activities
        for(AggregateResult ar : [select Id, CALENDAR_YEAR(End__c) year, WEEK_IN_YEAR(End__c) week, SUM(Duration_in_minutes__c) duration
                                    from Task_Activity__c 
                                    where End__c>=:PVM_A
                                    and End__c <:PVM_A+7
                                    and Billable__c=true
                                    and Resourcee__c in :resIds
                                    group by rollup (CALENDAR_YEAR(End__c), WEEK_IN_YEAR(End__c), Id)]){
                                        


            if(ar.get('year') != null && ar.get('week') != null && ar.get('Id') != null){

                Task_Activity__c tsk = taskIdsToTask.get((Id)ar.get('Id'));
                if(tsk!=null){
                    system.debug('AGGREGATE RESULT TASK ID: '+(Id)ar.get('Id'));
                    system.debug('TSK RECORD: '+tsk);
                    system.debug('TSK RECORD WEEK: '+String.valueOf(ar.get('week')));
                    system.debug('TSK RECORD WEEK: '+(Long)ar.get('week'));
                    String yearAndWeek = String.valueOf(ar.get('year')) + '-' + String.valueOf(ar.get('week'));
                    
                    if(tskDates.containsKey(yearAndWeek + '-' + tsk.Resourcee__c)){

                        tskDates.get(yearAndWeek + '-' + tsk.Resourcee__c).add(tsk.Id);

                    }else{
                        tskDates.put(yearAndWeek + '-' + tsk.Resourcee__c, new List<Id>{tsk.Id});
                    }
                    
                    if(durations.containsKey(tsk.Resourcee__c)){
                        if(durations.get(tsk.Resourcee__c).containsKey(yearAndWeek)){
                            durations.get(tsk.Resourcee__c).put(yearAndWeek,durations.get(tsk.Resourcee__c).get(yearAndWeek) + (Decimal)ar.get('duration'));
                        }else{
                            durations.get(tsk.Resourcee__c).put(yearAndWeek,(Decimal)ar.get('duration'));
                        }
                    }else{  
                        durations.put(tsk.Resourcee__c, new Map<String,Decimal>{String.valueOf(ar.get('year'))+'-'+String.valueOf(ar.get('week')) => (Decimal)ar.get('duration')});
                        
                    }
                }
            }
                                        
            
                                   
        }
        //AggrefateResult for Weekly Utilization
        system.debug('TASKDATES: '+tskDates);
        for(AggregateResult ar : [select Id, CALENDAR_YEAR(Start_Date__c) year, WEEK_IN_YEAR(Start_Date__c) week, SUM(Duration_in_minutes__c) duration
                                    from Weekly_Utilization__c
                                    where Id in :Trigger.New
                                    group by rollup (CALENDAR_YEAR(Start_Date__c), WEEK_IN_YEAR(Start_Date__c), Id)]){
                                        
            Id resourceId = wuResIds.get((Id)ar.get('Id'));
            String yearAndWeek = String.valueOf(ar.get('year')) + '-' + String.valueOf(ar.get('week'));
                                        
            if(durations.containsKey(resourceId)){
                if(durations.get(resourceId).containsKey(yearAndWeek)){ 
                    utizToUpdate.add(new Weekly_Utilization__c(
                                        Id=(Id)ar.get('Id'),
                                        Duration_in_minutes__c = (Decimal)durations.get(resourceId).get(yearAndWeek)
                                        
                    ));
                }
            }
            if(ar.get('year') != null && ar.get('week') != null && ar.get('Id') != null){
                    
                    if(tskDates.containsKey(yearAndWeek+'-'+resourceId)){

                        for(Id i2 : tskDates.get(yearAndWeek+'-'+resourceId)){
                            
                            system.debug('TASK TO UPDATE: '+i2);     
                            tsksToUpdate.add(new Task_Activity__c(
                                                                    Id=i2,
                                                                    Weekly_Utilization__c=(Id)ar.get('Id')
                                        ));
                            
                        }
                        
                    }
                             
                
            }

            
        } 
        for(Task_Activity__c tsk :[select Id from Task_Activity__c where Id in :tskIds and Id not in :tsksToUpdate]){
            
                    system.debug('Task To Update: '+tsk);
                    tsksToUpdate.add(new Task_Activity__c(
                                        Id=tsk.Id,
                                        Weekly_Utilization__c=null
                                        ));
                
            
        }
                                        
          system.debug('Tasks To Update Size: '+tsksToUpdate.size());


        update  utizToUpdate;
        update tsksToUpdate;
    }
}
Thanks
Tatu
 
Hi everyone.

I have a Quote trigger that should update a custom field when the Quote is unsynced, but I'm having troubles in representing this correctly in a test. This is from my trigger:

// Only case that it shouldn't be marked is when editing an unsynced Quote
if (!old_map.get(quote.Id).IsSyncing && !quote.IsSyncing) {
    continue;
}

sales_order.Quote_was_modified__c = true;
update sales_order;

As you can see, the field should always be updated, unless the Quote was unsynced and remains unsynced. Doing this in Salesforce interface (pressing Stop Sync button) works fine, but this test fails and I can't figure out why:

quote = [SELECT Id, IsSyncing FROM Quote WHERE Id =: quote.Id];
system.assert(quote.IsSyncing);

// Unsync that quote
opportunity.SyncedQuoteId = null;
update opportunity;

// Check if it was unsynced
quote = [SELECT Id, IsSyncing FROM Quote WHERE Id =: quote.Id];
system.assert(!quote.IsSyncing);

sales_order = [SELECT Id, Quote_was_modified__c FROM Sales_Order__c WHERE Id =: sales_order.Id];
system.assert(sales_order.Quote_was_modified__c);


This last assert fails. I have added some system.debug calls in this code and found out that it is getting into that if statement that checks if the Quote was and remains unsynced. When accessing the oldMap version of the Quote right after the update opportunity call, IsSyncing is already set to false. So, why is that happening? Am I missing something?

Thank you

I'm writing a trigger for new opportunity products to populate a field Product_Category__c (on opportunity lineitem) getting the value from Product_Category_new__c (on Product).

This is my trigger:

trigger SetProductCategory on OpportunityLineItem (after insert) {

            for (OpportunityLineItem opplineitem: Trigger.new){

                         opplineitem.Product_Category__c= opplineitem.PricebookEntry.Product2.Product_Category_new__c;

              }     
}

I get this error message:

execution of AfterInsert caused by: System.FinalException: Record is read-only

I have tried with before insert;in this case there aren't errors but the value Product category it's not saved on Opportunity Line item.

 

I have found that:

In a after insert trigger is not allowed change field using trigger.new

 

Please can you suggest a solution for this? i would like to copy the value Product category (Product) on Product Category (Opportunity Product) after the insert of the new opportunity products.

Thanks in advantage for any advice.

Br