0

I have a requirement of creating Service Contracts when Order is Approved and add Order Products inside to Contract Line Items in Service Contract. Following is the code I am using to accomplish what I need.

public class GenerateServiceContract {
    @InvocableMethod
    public static void fetchOrderItems(List<Id> orderId) {
        List<Order> relatedOrder = [SELECT Id, AccountId, Order_Name__c FROM Order WHERE Id = :orderId];

        ServiceContract scontract = new ServiceContract(
            Order__c = relatedOrder[0].Id,
            Name = relatedOrder[0].Order_Name__c,
            AccountId = relatedOrder[0].AccountId
        );
        try {
            insert scontract;
            List<OrderItem> oproduct = [SELECT Id, Product2Id, Quantity, Contact_Name__c, UnitPrice FROM OrderItem WHERE OrderId = :orderId];
            List<ContractLineItem> citemsToInsert = new List<ContractLineItem>();
            
            for (OrderItem oitem: oproduct) {
                citemsToInsert.add(new ContractLineItem(
                    ServiceContractId = scontract.Id,
                    Product2Id = oitem.Product2Id,
                    Quantity = oitem.Quantity,
                    UnitPrice = oitem.UnitPrice
                ));
            }
            insert citemsToInsert;
        } catch (Exception e) {}
        
    }
}

I am getting this Error "Field is not writeable: ContractLineItem.Product2Id"

Can anyone help me with this? as I found nothing to make Product2Id field writeable.

2
  • It could help... salesforce.stackexchange.com/questions/129942/…
    – m Peixoto
    Commented Aug 5, 2021 at 7:28
  • Thank you for your comment. I looked to the reference you shared and changed my code accordingly. Now I am fetching PriceBookEntryId from PriceBookEntry Object using Product2Id and adding it to PriceBookEntryId field in Contract Line Items. It removed the error but still not able to add Line Item. Commented Aug 5, 2021 at 8:05

1 Answer 1

0

The post referenced by @m Peixoto explains exactly the problem you are experiencing. To be more specific:

  1. Product2Id is not writable in ContractLineItem
  2. You need to write PricebookEntryId instead —previously including it in your OrderItem query

Here's how your code should look like:

[Edit: added Pricebook2Id after OP solution comment]

public class GenerateServiceContract {
    @InvocableMethod
    public static void fetchOrderItems(List<Id> orderId) {
        List<Order> relatedOrder = [SELECT Id, 
                                       AccountId, 
                                       Pricebook2Id,
                                       Order_Name__c 
                                       FROM Order 
                                       WHERE Id = :orderId];

        ServiceContract scontract = new ServiceContract(
            Order__c = relatedOrder[0].Id,
            Name = relatedOrder[0].Order_Name__c,
            AccountId = relatedOrder[0].AccountId,
            Pricebook2Id = relatedOrder[0]. Pricebook2Id
        );
        try {
            insert scontract;
            List<OrderItem> oproduct = [SELECT Id, PricebookEntryId, Quantity, Contact_Name__c, UnitPrice FROM OrderItem WHERE OrderId = :orderId];
            List<ContractLineItem> citemsToInsert = new List<ContractLineItem>();
            
            for (OrderItem oitem: oproduct) {
                citemsToInsert.add(new ContractLineItem(
                    ServiceContractId = scontract.Id,
                    PricebookEntryId = oitem. PricebookEntryId,
                    Quantity = oitem.Quantity,
                    UnitPrice = oitem.UnitPrice
                ));
            }
            insert citemsToInsert;
        } catch (Exception e) {}
        
    }
}
6
  • In OrderItem Object there is no such column as PriceBookEntryId, so I cannot do it like "PricebookEntryId = oitem.PricebookEntryId". Instead I fetched PriceBookEntryId from PriceBookEntry Object using Product2Id from OrderItem Object like this... List<PriceBookEntry> pbEntry = [SELECT Id FROM PriceBookEntry WHERE Product2Id = :oitem.Product2Id]; And added it like this... "PricebookEntryId = pbEntry[0].PriceBook2Id", Still not adding to Line Items. Commented Aug 5, 2021 at 8:28
  • There DEFINITELY is a PricebookEntryId field in OrderItem, see the developer guide: developer.salesforce.com/docs/atlas.en-us.api.meta/api/… What error are you getting when trying the snippet I provided?
    – Ideasforce
    Commented Aug 5, 2021 at 8:46
  • Yes I checked the guide and they say there should be...but I don't have this column on my OrderItem Object in both Development & Production Orgs. I will create this column in OrderItem and will check if this works. Commented Aug 5, 2021 at 8:52
  • Oh, you do not need to create it. It is a standard field, should be there already, try querying for it
    – Ideasforce
    Commented Aug 5, 2021 at 8:54
  • 1
    Thank you for your help and support, now I got it working. The issue was that I was not assigning PriceBookId to Service Contract and that's why it wasn't adding the LineItems even with PriceBookentryId. So following is a line of code I added to Service Contract block, PriceBook2Id = relatedOrder[0].PriceBook2Id Commented Aug 5, 2021 at 10:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .