This is a Trigger that will send an email when the same Account has 8 cases created in the last 5 days.  I am receiving a SOQL error:     System.UnexpectedException: field 'Client_Advisor_Email__c' can not be grouped in a query call   However when I remove 'Client_Advisor_Email__c' from the search I receive a total opposite message:     System.UnexpectedException: field 'Client_Advisor_Email__c' can not be grouped in a query call   This is a field I will need further into the code as you will see.  Any assistance is appreciated.  trigger CaseHandlerCountAlert on Case (after insert) {     List&lt;AggregateResult&gt; AggregateResultList = [SELECT AccountId, Account.Name name, COUNT(Id) co,                                     Project__r.Implementation_status__c, Project__r.Client_Advisor_Email__c                                     FROM Case                                     WHERE CreatedDate = LAST_N_DAYS:5 AND Id IN :Trigger.New                                     GROUP BY AccountId, Account.Name                                     HAVING COUNT(Id)  &gt;= 8];                   for(AggregateResult aggr:AggregateResultList){                          Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();                              if(aggr != Null &amp;&amp; Project__r.Implementation_status__c == 'LIVE - TRANSITION'){                                      //Set Outgoing Email to Implementation Coordinator                                  message.toAddresses = new String[] { Project__r.Client_Advisor_Email__c };                              }                             else if (aggr != Null &amp;&amp; Project__r.Implementation_status__c == 'Live - Closed Project'){                                    //Private method getAddresses() retrieves email address from Customer_Success_Managers Public Group                                   message.toAddresses = new String[] { getAddresses() };                             }                           message.Subject = 'Subject Test Message';                         message.PlainTextBody = 'Account name: ' + aggr.get('name') + ' has ' + (Integer)aggr.get('co') + ' cases opened in the last 8 days.';                         Messaging.SingleEmailMessage[] messages =   new List&lt;Messaging.SingleEmailMessage&gt; {message};                         Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);                     System.debug('Account Name: ' + aggr.get('name'));                    }              private List&lt;String&gt; getAddresses(){     List&lt;User&gt; UserList =             [SELECT id, name, email             FROM User              WHERE id              IN (SELECT userorgroupid                  FROM groupmember                 WHERE group.name = 'Customer Success Managers')];      List&lt;String&gt; emailString = new List&lt;String&gt;();      for(User u: UserList){         emailstring.add(u.email);     }        return (emailString);     }     }
121987
I need to get Account names and asset count for each account.  From Asset table I can get AccountId and asset count.  But I need to get Account names also. This is where I stuck.  How to use Ids, from aggregate query and get Account names by Id.
66376
I have written a trigger on custom object Order_Item__c. This object has a custom field Shipping_Number__c. When the user enters value in Shipping_Number__c and clicks save, the contact lookup field will automatically populate with contact record which has same shipping number as the value entered by the user. The trigger is working fine. I am unable to get code coverage. The coverage is 0%. Any insights will be lot helpful.  Trigger:  trigger updatelookupfield on Order_Item__c (before update, before insert)  {       Set&lt;String&gt; shippingNumbers = new Set&lt;String&gt;();      for (Order_Item__c collectNumFromOrder : Trigger.new) {         shippingNumbers.add(collectNumFromOrder.Shipping_Customer_Number__c);     }        List&lt;Contact&gt; contactList = [SELECT id, Shipping_customer_number__c FROM Contact WHERE Shipping_Customer_Number__c IN :shippingNumbers];      Map&lt;String, Contact&gt; shippingNumToContactMap = new Map&lt;String, Contact&gt;();      for (Contact c : contactList) {         shippingNumToContactMap.put(c.Shipping_customer_number__c, c);     }      for (Order_Item__c o : Trigger.new) {            if (o.Shipping_Customer_Number__c != null) {             o.RSM_Shipping_Contact__c = shippingNumToContactMap.get(o.Shipping_Customer_Number__c).id;         }         else {             o.RSM_Shipping_Contact__c = null;         }      }     }    Test Class:  @isTest public class testupdatelookupfield{      Static testMethod void insertOrderItem()     {   // create and insert the contact record - this part is correct         contact c = new contact();         c.Shipping_Customer_Number__c = '0987654';         c.lastName = 'Surekha';        insert c;           // create an order item and insert it         Order_Item__c op = new Order_Item__c();          op.Name = 'Test Varun Order';         op.Shipping_Customer_Number__c = '0987654';         insert op;           system.assertequals(op.RSM_Shipping_Contact__c,c.id);     } }
25839
Error Message:     Developer script exception from Nicomatic : quotepotential :   quotepotential: execution of AfterUpdate caused by:   System.DmlException: Update failed. First exception on row 0 with id   a0Q90000005PoxtEAC; first error: UNABLE_TO_LOCK_ROW, unable to obtain   exclusive access to this record: [] Trigger.quotepotential: line 14,   column 1      Apex script unhandled trigger exception by user/organization:   00590000001A6jh/00D90000000bovq      quotepotential: execution of AfterUpdate      caused by: System.DmlException: Update failed. First exception on row   0 with id a0Q90000005PoxtEAC; first error: UNABLE_TO_LOCK_ROW, unable   to obtain exclusive access to this record: []      Trigger.quotepotential: line 14, column 1   these mails are getting to my mail..........  trigger quotepotential on Quote_Line_Item__c (after insert,after update) {     Set&lt;Id&gt; quoteIds = new Set&lt;Id&gt;();     List&lt;Quote__c&gt; quotes = new List&lt;Quote__c&gt;();     for (Quote_Line_Item__c record: Trigger.new) {         if (record.Quote1__c != null){             quoteIds.add(record.Quote1__c);         }     }     for(AggregateResult ar:[                 SELECT                      Quote1__c,                      SUM(Max_Batch__c)sumMax                  FROM Quote_Line_Item__c                  WHERE Quote1__c=:quoteIds                  GROUP BY Quote1__c                 ]) {          quotes.add(new Quote__c(              Id=(Id) ar.get('Quote1__c'),              Potential__c = (Decimal) ar.get('sumMax')              ));     }     if (quotes.isempty() == false) {         update quotes;     } }
90260
We have a workflow that creates tasks and assigns them to a specific user when an opportunity is closed. It's salesforce standard behavior that when the account owner is changed, the open tasks are also reassigned to the new account owner. I'm trying to write a trigger that:   checks if the account owner and/or task owner is changed FROM 00590000000a3xU if yes, reassign the tasks back to 00590000000a3xU only open tasks and tasks where Orb Team Task (checkbox) is true will be reassigned   I was getting all sorts of errors from the old code even after making the changes sfdcfox's pointed out. So I decided to change my approach. Here's the new and working code:  trigger AssignTaskBackToWarehouse on Account (after update){ List&lt;Task&gt;TasksToUpdate = new List&lt;Task&gt;(); Map&lt;Id,Account&gt;amap = new Map&lt;Id,Account&gt;([SELECT Id, OwnerId,(SELECT Id, Status, Warehouse_Task__c     FROM tasks     WHERE Status != 'Completed' AND     Warehouse_Task__c = true)     FROM Account     WHERE Id =: Trigger.newmap.keyset()]); for(Account a : Trigger.new){     for(Task t : amap.get(a.Id).tasks){         t.OwnerId = '00590000000XXXX';         TasksToUpdate.add(t);     }     } if(TasksToUpdate.size() &gt; 0){     update TasksToUpdate; } }
91232
I have created an app that would change CampaignMemeber Status Values by calling our web application api and storing info in custom objects. In my developer org where the package is created works fine but on our clients sandbox they get the error      System.QueryException: Non-selective query against large object type   (more than 200000 rows).   I know the reason that they get is because the query is not selective or that they have a lot of record. The error is occurring in a trigger. Below i have my trigger. Could anyone suggest a way to make my query more selective(i know about indexed field and tire that already) or any other way around the issue?    trigger SynchronizeTrigger on Attendee__c (after update, after insert) {      Map&lt;String,String&gt; matchedRegistration = new Map&lt;String,String&gt;();      Map&lt;String,String&gt; matchedCheckin = new Map&lt;String,String&gt;();      Set&lt;String&gt; matchedEmails = new Set&lt;String&gt;();      Map&lt;String,String&gt; matchedSurnames = new Map&lt;String,String&gt;();      CampaignMember[] cmList = new CampaignMember[]{};      List&lt;Fail__c&gt; flist = new List&lt;Fail__c&gt;();        Public Authentication__c auth = new Authentication__c();     auth = [SELECT Authentication_Campaign__c FROM Authentication__c LIMIT 1];        public Integer attendeesAttended = 0;     public Integer attendeesDidNotShow = 0;     public Integer attendeesAccepted= 0;     public Integer attendeesCancelled = 0;     public Integer attendeesfailed = 0;      for(Attendee__c a : Trigger.new){         matchedRegistration.put(a.Attendee_Email_Address__c,a.Attendee_Registration__c);         matchedCheckin.put(a.Attendee_Email_Address__c,a.Attendee_Checkin__c);          matchedEmails.add(a.Attendee_Email_Address__c);     }       for(List&lt;CampaignMember&gt; cms : [SELECT Id,Campaign.Id, Contact.Email,Status                            FROM CampaignMember                            WHERE  Campaign.Id =: auth.Authentication_Campaign__c AND  Contact.Email  IN: matchedEmails]){         for(CampaignMember cm : cms){            if(matchedRegistration.get(cm.Contact.Email)=='1' &amp;&amp; matchedCheckin.get(cm.Contact.Email)=='1'){                cm.Status = 'Attended';               cmList.add(cm);               attendeesAttended++;            }else if(matchedRegistration.get(cm.Contact.Email)=='1' &amp;&amp; matchedCheckin.get(cm.Contact.Email)=='0'){                cm.Status = 'Did Not Show';               cmList.add(cm);               attendeesDidNotShow ++;             }else if(matchedRegistration.get(cm.Contact.Email) =='1' &amp;&amp; String.isEmpty(matchedCheckin.get(cm.Contact.Email))){                cm.Status = 'Accepted';               cmList.add(cm);               attendeesAccepted ++;            }else if(matchedRegistration.get(cm.Contact.Email)=='0'){                cm.Status = 'Cancelled';               cmList.add(cm);               attendeesCancelled ++;                 }      update cmList;       }     }     for(List&lt;CampaignMember&gt; cms : [SELECT Id,Campaign.Id,FirstName,LastName,Contact.Email                            FROM CampaignMember                            WHERE Campaign.Id =: auth.Authentication_Campaign__c AND Contact.Email NOT IN: matchedEmails]){              for(CampaignMember cm : cms){              fList.add(new Fail__c(Fail_Firstname__c = cm.FirstName, Fail_Surname__c = cm.LastName, Fail_Email__c = cm.Contact.Email,Fail_Campaign_Name__c = cm.Campaign.Name ,Fail_Campaign__c = auth.Authentication_Campaign__c));             attendeesfailed ++;             upsert fList Fail_Email__c;           }   }     ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Confirm, 'Attended: ' + attendeesAttended + ' Delegate(s)' + ', ' + 'Did Not Show: ' + attendeesDidNotShow + ' Delegate(s)'+ ', ' + 'Accepted: ' + attendeesAccepted + ' Delegate(s)' + ', ' + 'Cancelled: ' + attendeesCancelled + ' Delegate(s)'));   ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.Error, 'Failed Syncs: ' + attendeesfailed + ' Delegate(s)')); }   Thanks
37213
I am trying to run SOQL statement in salesforce.schema tool of FORCE.COM the following query:  Select c.LastName, c.FirstName From Contact c WHERE (FirstName+' '+LastName) In ('Good Name','Bad Name')   It produces an error.   Can I do this kind of things with SOQL ? If yes, then how I can concatenate fields in the query ?
80179
i have created a trigger which creates an opprtunity when the accounte is created and i have a custom field No of contact on account which displays the count of related contact for a particular account whenever it is updated.  I have tested seperated that the opportnity is created but for the second part ,it displays a big error when i try to save a record.  I am not getting any error while saving a record.Can someone help      trigger insertOpp on Account(After insert,after update,before update) { List&lt;Opportunity&gt; opplist=new List&lt;Opportunity&gt;(); for(Account acc:Trigger.new){  Opportunity op=new Opportunity(); op.Name='Cook'; op.accountid=acc.id; op.CloseDate=System.today(); op.StageName='Qualification'; opplist.add(op); }  insert opplist;     if(trigger.isupdate) {         Integer no_of_contact;         String accID;      for(Account c:Trigger.new )     {         accid = c.id;      }      account acclist = new account();     acclist = [select No_of_Contacts__c from account where id = :accid ];     no_of_contact = [SELECT count() FROM Contact WHERE AccountId = :accid];     acclist.No_of_Contacts__c = no_of_contact;     //update acclist;  }  }   ERROR:       Review all error messages below to correct your data. Apex trigger   insertOpp caused an unexpected exception, contact your administrator:   insertOpp: execution of AfterUpdate caused by: System.DmlException:   Update failed. First exception on row 0 with id 00128000002r8gKAAQ;   first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, insertOpp: maximum   trigger depth exceeded Account trigger event AfterUpdate for   [00128000002r8gK] Account trigger event AfterUpdate for   [00128000002r8gK]
62150
I need to be able to detect that the trigger execution is happening because of a workflow field update. There is a suggestion in the cookbook:  But this solution is not properly bulkified. If my batch of records is split up (200, 100, 50 whatever the server decides) the 2nd to nth batches are not processed correctly because the flag has already been set. The second part of the problem is: This is part of a managed package. I have no control of the customer's workflow rules, supporting and configuring a flag/last changed field on a record is not realistic, our company doesn't have the support resources to be walking each customer through the configuration. Has anyone been able to solve this problem for large batches of records? Edit (In Response to Calebs Answer) Separate trigger batches do not run in separate contexts trigger AccountTriggerContext on Account (before insert) {     System.debug('counter='+TriggerContextCounter.getCounter()); }  . global without sharing class TriggerContextCounter {      private static Integer counter = 0;          public static Integer getCounter() {         Integer value = counter;         counter++;         return value;     }      private static testMethod void testTriggerContexts() {         List&lt;Account&gt; accounts = new List&lt;Account&gt;();         for(Integer i = 0; i &lt; 250; i++) {             accounts.add(new Account(Name='testTriggerContexts: ' + i));         }         insert accounts;     } }  Unit test debug messages  USER_DEBUG|[2]|DEBUG|counter=0 USER_DEBUG|[2]|DEBUG|counter=1  Both counters should have been 0 if the batches were running in separate contexts Edit Further explanation of background for @Ralph This is a generalized explanation, but when certain conditions are met, some date fields on other objects are updated. The trigger runs and updates the dates. If a workflow rule causes a field update on the object, the same trigger is run again and the dates on the other objects are updated for a second time. And because this is an increment operation the dates on the other objects are off by a factor of 2.
123622
How how do I query recent account views and group by LastViewedDate    SELECT Id, Name                 FROM Account                ORDER BY Name DESC limit 10 FOR VIEW   I used to have it like this, but my test case is keep failing  SELECT SELECT Id, Name, LastModifiedDate                         FROM account                         WHERE LastModifiedDate !=null ORDER BY LastViewedDate DESC limit 10  static testmethod void testOppExt_TestMethod(){        Opportunity testOpp = new Opportunity(Name = 'TestOpp', StageName='Test', CloseDate = Date.today());       insert testOpp;        Account testAcc = new Account(Name = 'Test Account');       insert testAcc;        Contact con = new Contact(LastName='Test',AccountId=testAcc.id);       insert con;        Test.startTest();       OppExt testCon = new OppExt();       Contact conn = testCon.contact;       Account  Accn = testCon.acc;       Test.stopTest();     }   Error Message   Component Errors API Name Type Line Column Error Message 0 0 , Details: Average test coverage across all Apex Classes and Triggers is 0%, at least 75% test coverage is required. 0 0 SiteRegisterControllerTest.null(), Details: line -1, column -1: Previous load of class failed: oppext null 0 0 SiteLoginControllerTest.null(), Details: line -1, column -1: Previous load of class failed: oppext null 0 0 SiteRegisterController.null(), Details: line -1, column -1: Previous load of class failed: oppext null 0 0 testnewOpportunityController.null(), Details: line -1, column -1: Previous load of class failed: oppext null 0 0 SiteLoginController.null(), Details: line -1, column -1: Previous load of class failed: oppext null 0 0 testOppExt.null(), Details: line -1, column -1: Previous load of class failed: oppext null 0 0 OppExt.null(), Details: line 32, column 17: No such column 'LastViewedDate' on entity 'Account'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. null
71184
I'm getting the following error message:     System.QueryException: Didn't understand relationship 'AccountContactRelation' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names.   Select Email, Id, (Select ContactId, AccountId From AccountContactRelation) From Contact  In AccountContactRelation object there are two lookup fields for Account and for Contact.  Please advise how to avoid such error message?
107926
The Salesforce documentation is notably terse in describing . The guidance provided for determining which fields can be grouped is simply:     The Field object associated with DescribeSObjectResult has a groupable field that defines whether you can include the field in a GROUP BY clause.   Further, the document states that     You can't use child relationship expressions that use the __r syntax in a query that uses a GROUP BY clause.    Which field types in fact permit grouping? Does the final sentence prohibit the use of custom relationships in GROUP BY?    have not yielded a conclusive statement.   Failure to use a properly groupable field yields the error     field 'FIELD_NAME__c' can not be grouped in a query call
105367
I'm trying to develop my first test class in our sandbox instance. When running the below test, I am getting no records return from the first query to build accountsList. The test succeeds, but I have 0% code coverage. The trigger works as expected when ran.  My Test Class:  @isTest private class test_deleteAccountSharesOnUpdate {  static testMethod void updateAccounts()  {     Set&lt;String&gt; accountIds = new Set&lt;String&gt;();      List&lt;Account&gt; accountsList =      [         SELECT Id, Is_Script_Update__c, Description FROM Account     ];      Integer i = 0;     for (Account acct : accountsList)     {         if(i &gt; 199)         {             break;         }          acct.Is_Script_Update__c = True;         acct.Description = 'Testing at ' + System.now();          accountIds.add(acct.Id);          i++;     }      test.startTest();      update accountsList;      test.stopTest();      List&lt;Account&gt; updatedAccts =      [         SELECT Id, Is_Script_Update__c, Description         FROM Account          WHERE Id IN : accountIds     ];      for(Account acct : updatedAccts)     {         System.assertEquals         (             'Testing at',             acct.Description.substring(0,10)         );     } }   }  Trigger I'm trying to test:  trigger deleteAccountSharesOnUpdate on Account (after update)  {    Set&lt;String&gt; accountIds = new Set&lt;String&gt;();  // Gather the account Ids being updated for (Account acct : trigger.new) {     // Only remove shares for accounts being updated by data loader.     // Loader script will insert new shares after this job.     if(acct.Is_Script_Update__c)     {         String terrCode = acct.Territory_Code_String__c;          if(terrCode != null &amp;&amp; terrCode.length() == 5)         {                accountIds.add(acct.id);         }     } }  if(accountIds.size() &gt; 0) {     // Remove the shares associated with these accounts     delete      [         select id          from AccountShare          where RowCause = 'TerritoryManual' AND          AccountId IN : accountIds     ];      // Reset flag that indicates this update is from a data loader.     // Data loader will set this checkbox as true on update.     // This prevents the trigger on UI update.     //     List&lt;Account&gt; accountsList =      [         SELECT Id, Is_Script_Update__c          FROM Account          WHERE Id IN: accountIds     ];      for (Account acct : accountsList)     {         acct.Is_Script_Update__c = False;     }      update accountsList; }   }  Degub log shows no rows returned for the first query:  14:47:14.461 (3461430000)|SOQL_EXECUTE_BEGIN|[8]|Aggregations:0|select Id,       Is_Script_Update__c, Description from Account 14:47:14.483 (3483545000)|SOQL_EXECUTE_END|[8]|Rows:0  Any help is greatly appreciated!
17780
I am running this script from developer console.  List&lt;Account&gt; lstAccount = [SELECT Id, Name, BillingStreet From Account LIMIT 1]; System.debug(lstAccount);   Debug Log:     23:47:04:012 USER_DEBUG [5]|DEBUG|(Account:{Id=0019000001nNLGEAA4, Name=Acct_nm001, BillingStreet=xyz Road, RecordTypeId=01290000000iaNiAAI})   I never queried for RecordtypeId in SOQL, but it is included in the list.  Although, if I run the query from the query editor, it is not showing RecordtypeId column.   Is this by design? Then why not Salesforce is not providing us audit fields in the first scenario.
30114
I have a business logic as follows.   1. A web service class parses XML file containing case data and loads the case to SF. 2. Trigger that on update of case email field make a call to future method to generate attachment ,send email and update case owner field.  trigger CaseUpdate on Case (After update)  {  for(case c : trigger.old)  {     for(case ca : trigger.new)     {         if((c.Email__c != ca.Email__c) &amp;&amp; (c.CS_ID__c != null) &amp;&amp; (c.Count__c == 1))         {           UtilsClass.generateReport_Future(c.id);         }     }  } }    @Future(callout=true)  public static void generateReport_future(String caseId)  { String result = ''; result = generateReport(caseId); if(result == '')  {     result = emailReport(caseId); } UtilsClass.ChangeOwner(caseId);  }   The issue i am facing is,  System.LimitException: Too many future calls: 11, even though single case record is loaded.  Multiple records may be loaded at the same time, but they are sequential(One By One).  Are the records coming in a single batch even though they are being loaded individually..?
119235
I'm trying to use an aggregate query, but one of the fields I want to group by is not groupable (saw it in the soql error and then verified groupable=false in the metadata).  It's just a number field that holds an integer (number 2,0 in salesforce field spec-speak).  Is there a trick to make it groupable?  Any way around this problem? I don't want to write hundreds of lines of code just to average a list by this field.
67038
I'm trying to retrieve a list of Account objects from Salesforce using SOQL. Originally my query was this:  var result = service.query("SELECT Id, Name, RecordTypeId FROM Account"); return result.records.Select(record =&gt; record as Account).ToList();   However this only returns a maximum of 2,000 records and I have over that which I need to be returned by this query. After some digging around I found an example in Java which loops over the SOQL query which will allow a maximum of 10,000 records to be returned. I tried to replicate this in C# but it differs slightly, here is what I have now:  var accounts = new List&lt;Account&gt;(); foreach (Account account in service.query("SELECT Id, Name, Composer_ID__c, RecordTypeId FROM Account").records)     accounts.Add(account);  return accounts;   However this still only returns a maximum of 2,000 records. How can I return more than 2,000 records by querying Account?
18923
I am trying to write a test for a trigger that is firing a future apex callout :  The trigger calls the callBillingService method from this class:  public class BillingCalloutService {     //Implement business and callout logic methods here     @Future(callout=true)     public static void callBillingService(List&lt;Id&gt; recordIds) {         List&lt;Project__c&gt; projects = [Select Id, ProjectRef__c,Billable_Amount__c from Project__c Where Id = :recordIds];          List&lt;Project__c&gt; projectsToUpdate = new List&lt;Project__c&gt;();          String username = ServiceCredentials__c.getValues('BillingServiceCredential').Username__c;         String password = ServiceCredentials__c.getValues('BillingServiceCredential').Password__c;          String auth = username + ':' + password;         String encodedAuth = EncodingUtil.base64Encode(Blob.valueOf(auth));          for(Project__c p : projects) {              BillingServiceProxy.InvoicesPortSoap11 service = new BillingServiceProxy.InvoicesPortSoap11();             service.inputHttpHeaders_x = new Map&lt;String, String&gt;();             service.inputHttpHeaders_x.put('Authorization', 'Basic ' + encodedAuth);              BillingServiceProxy.project project = new BillingServiceProxy.project();             project.username = username;             project.password = password;             project.projectRef = p.ProjectRef__c;             project.billAmount = p.Billable_Amount__c;              if(service.billProject(project).equals('ok')){                 projectsToUpdate.add(new Project__c(ProjectRef__c = p.ProjectRef__c, Status__c = 'Billed'));             }         }         shouldIRun.stopTrigger();         upsert projectsToUpdate ProjectRef__c;     } }   Error     Methods defined as TestMethod do not support Web service callouts   Test Class  @IsTest private class BillingCalloutServiceTest {      @IsTest     private static void testBillingCalloutService() {     Account a = new Account(Name = 'Acme');     insert a;     Opportunity o = new Opportunity(Name='Test', StageName='Submitted Project', AccountId=a.Id, Amount=1000, CloseDate=Date.Today());     insert o;     Project__c p = new Project__c(Status__c='Running',Start_Date__c=Date.Today(),End_Date__c=Date.Today(),Billable_Amount__c=10000,ProjectRef__c='projectX',Opportunity__c=o.Id);     insert p;      insert new ServiceCredentials__c(Name='BillingServiceCredential',Username__c='toto', Password__c='azerty');      Test.startTest();     Test.setMock(HttpCalloutMock.class, new BillingCalloutServiceMock());       p.Status__c = 'Billable';       update p;     Test.stopTest();     // runs callout and check results     p = [select Status__c from Project__c where id =: p.id];     System.assertEquals('Billed', p.Status__c);     }  }