function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
AlanisticAlanistic 

sObject type 'ServiceContacts' is not supported.

I'm trying to have a controller extension that will pull back service contracts on an account:

The contacts pull through fine.  However the service contacts displays the error:

Error: Compile Error: sObject type 'ServiceContacts' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names. at line 30 column 29

My class is:


public class myAccountControllerExtension {

    public Account acct { get; set;}
    public List<Contact> cont { get; set;}
    public List<ServiceContracts> sc { get; set;}
   
    public myAccountControllerExtension(ApexPages.StandardController controller) {
        this.acct = (Account)controller.getRecord();
        getContacts(acct.id);
        getServiceContacts(acct.id);
    }

    public void getContacts(String aid){
        if(aid != null && aid instanceOf Id)
        {
            for(Account a : [select id,name,AccountNumber ,(SELECT Id, Name FROM Contacts WHERE Portal_User__c = true) FROM Account where id =:aid])
            { 
                if(a.contacts!=null && a.contacts.size()>0)
                {
                cont = a.contacts;
                system.debug('my contacts ' + cont);
                }
            }
        }
    }
   
    public void getServiceContracts(String aid){
        if(aid != null && aid instanceOf Id)
        {
            for(Account a : [select id,name,AccountId FROM ServiceContacts WHERE AccountId =:aid])
            { 
                if(a.servicecontracts!=null && a.servicecontracts.size()>0)
                {
                sc = a.servicecontracts;
                system.debug('my service contracts' + sc);
                }
            }
        }
    }
}
    
}


What is the reason for the error?  How would I resolve this?  My end goal is to have a VF page that displays specific contract fields and specific contacts.
Best Answer chosen by Alanistic
pconpcon
You had a typo in your query.  I've gone ahead and condensed and simplified your controller significantly.  There are other ways to do this in a single DML operations, but given what you have, this is closest to what you have.

public class myAccountControllerExtension {
    public Account acct { get; set;}
    public List<Contact> cont { get; set;}
    public List<ServiceContract> sc { get; set;}

    public myAccountControllerExtension(ApexPages.StandardController controller) {
        this.acct = (Account) controller.getRecord();
        getContacts(acct.id);
        getServiceContacts(acct.id);
    }

    public void getContacts(Id aid) {
        this.cont = [
            select Name
            from Contact
            where Portal_User__c = true and
                AccountId = :aid
        ];
    }   

    public void getServiceContracts(Id aid){
        this.sc = [
            select Name
            from ServiceContract
            where AccountId = :aid
        ];   
    }
}

to do it in a single DML operation you could have the following:

public class myAccountControllerExtension {
    public Account acct { get; set;}
    public List<Contact> cont { get; set;}
    public List<ServiceContract> sc { get; set;}

    public myAccountControllerExtension(ApexPages.StandardController controller) {
        this.acct = (Account) controller.getRecord();
        getChildObjects();
    }

    private void getChildObjects() {
        Account account = [
            select (
                select Name
                from Contacts
                where Portal_User__c = true
            ),
            (
                select Name
                from ServiceContracts
            )
        ];

        this.cont = account.Contacts;
        this.sc = account.ServiceContracts;

        //If you want to avoid NPEs

        this.cont = (this.cont != null) ? this.cont : new List<Contact>();
        this.sc = (this.sc != null) ? this.sc : new List<ServiceContract>();
    }
}

NOTE: This code has not been tested and may contain typographical or logical errors.

All Answers

pconpcon
The API name for this object is ServiceContract so update your list to be

public List<ServiceContract> sc { get; set;}

This information can be viewed either with a metadata describe or inside of workbench [1]

For additional information, the relationship between ServiceContract and Account is called ServiceContracts.  That is why this work with your query but not with your definition of your list.

ServiceContract

Service Contract attributes

Account Child Relationship

Account relationship


[1] https://workbench.developerforce.com/describe.php
AlanisticAlanistic
I did look at that already, however even if I update my list to be of type ServiceContract I see the error:

Error: Compile Error: sObject type 'ServiceContacts' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names. at line 30 column 29

Line 30 is:

for(Account a : [select id,name,AccountId FROM ServiceContact WHERE AccountId =:aid])

I've tried ServiceContracts and ServiceContract.  What is the best way for me to query the contract information for account a?
pconpcon
You had a typo in your query.  I've gone ahead and condensed and simplified your controller significantly.  There are other ways to do this in a single DML operations, but given what you have, this is closest to what you have.

public class myAccountControllerExtension {
    public Account acct { get; set;}
    public List<Contact> cont { get; set;}
    public List<ServiceContract> sc { get; set;}

    public myAccountControllerExtension(ApexPages.StandardController controller) {
        this.acct = (Account) controller.getRecord();
        getContacts(acct.id);
        getServiceContacts(acct.id);
    }

    public void getContacts(Id aid) {
        this.cont = [
            select Name
            from Contact
            where Portal_User__c = true and
                AccountId = :aid
        ];
    }   

    public void getServiceContracts(Id aid){
        this.sc = [
            select Name
            from ServiceContract
            where AccountId = :aid
        ];   
    }
}

to do it in a single DML operation you could have the following:

public class myAccountControllerExtension {
    public Account acct { get; set;}
    public List<Contact> cont { get; set;}
    public List<ServiceContract> sc { get; set;}

    public myAccountControllerExtension(ApexPages.StandardController controller) {
        this.acct = (Account) controller.getRecord();
        getChildObjects();
    }

    private void getChildObjects() {
        Account account = [
            select (
                select Name
                from Contacts
                where Portal_User__c = true
            ),
            (
                select Name
                from ServiceContracts
            )
        ];

        this.cont = account.Contacts;
        this.sc = account.ServiceContracts;

        //If you want to avoid NPEs

        this.cont = (this.cont != null) ? this.cont : new List<Contact>();
        this.sc = (this.sc != null) ? this.sc : new List<ServiceContract>();
    }
}

NOTE: This code has not been tested and may contain typographical or logical errors.
This was selected as the best answer
AlanisticAlanistic
Fantastic.  Do you know if there is any way to query the service contract record type?  I've not been able to find a way to do this.
pconpcon
It's not listed in the describe, but it should just be doing:

select RecordTypeId, RecordType.Name from ServiceContract