0

While creating a instance of wrapper class, which uses a formula field from another object, I get this error.

Field is not writeable: OrderItem.ReleaseNo__c

Sample wrapper class I am working on

public class wrapper{
    public string name;
    public List<OrderItem> products;  // orderItem object has a formula field that I need to use
}

And in the class create an instance of the wrapper (I have to query from child-to-parent levels up due to the information I seek)

List<CompartmentFrom__c> lstCompartments =
            [SELECT Id, Name, DeliveryLine__r.OrderProduct__r.order.ReleaseNo__c, 
                    DeliveryLine__r.OrderProduct__r.Quantity,
            FROM CompartmentFrom__c ];
        
       
        for(CompartmentFrom__c comp: lstCompartments){
                wrapper wrp= new wrapper();
                wrp.name = comp.Name;
                
                OrderItem product = new OrderItem(Id = comp.DeliveryLine__r.OrderProduct__c, 
                                                ReleaseNo__c = comp.DeliveryLine__r.OrderProduct__r.ReleaseNo__c, 
                                                Quantity = comp.DeliveryLine__r.OrderProduct__r.Quantity);
                wrp.products.add(product); 
        }

While assigning ReleaseNo__c, I get Field not writable error, which I am just using to fill the wrapper instance. Is there any way to get around it?

1
  • 1
    Please edit your post to clarify - is ReleaseNo__c a formula field in the OrderItem object? Sep 10, 2023 at 21:37

2 Answers 2

1

If you don't need to have an SObject instance, then you could just make a wrapper for your OrderItem as well.

public class Wrapper{
    public String name;
    public List<OrderItemWrapper> products;

    // Need to initialize the list before you can add items to it
    public Wrapper(){
        products = new List<OrderItemWrapper>();
    }
}

public class OrderItemWrapper{
    public Id id;
    public String releaseNo;
    public Double quantity;

    // Since it looks like everything comes from your OrderItem, might
    //   as well just pass that into this constructor
    public OrderItemWrapper(OrderItem inputData){
        id = inputData.Id;
        releaseNo = inputData.ReleaseNo__c;
        quantity = inputData.Quantity;
    }

    // And toss in a method to turn it into an OrderItem for good measure
    public OrderItem makeOrderItem(){
        return new OrderItem(Id = id, Quantity = quantity);
    }
}

Which you would then use like so (assuming you also query DeliveryLine__r.OrderProduct__r.Id)

for(CompartmentFrom__c comp: lstCompartments){
    Wrapper wrp = new Wrapper();
    wrp.name = comp.Name;
    
    // When you query up a relationship, the "__r" field is a fully fledged
    //   SObject, and you can treat it as such
    wrp.products.add(
        new OrderItemWrapper(comp.DeliveryLine__r.OrderProduct__r);
    );
}
1
  • Thanks, @Derek , I already working on it. I was thinking if there was any other way out.
    – Mahmood
    Sep 10, 2023 at 21:44
2

You could do the following for this code element

for(CompartmentFrom__c comp: lstCompartments){
    wrapper wrp= new wrapper();
    wrp.name = comp.Name;
            
    OrderItem product = 
       (OrderItem) new sfab_FabricatedSObject(OrderItem.class)
           .setField(OrderItem.Id,comp.DeliveryLine__r.OrderProduct__c)
           .setField(OrderItem.ReleaseNo__c, comp.DeliveryLine__r.OrderProduct__r.ReleaseNo__c)
           .setField(OrderItem.Quantity,comp.DeliveryLine__r.OrderProduct__r.Quantity)
           .toSobject();
     wrp.products.add(product); 
    }

This uses the Matt Addy SObjectFabricator to construct any Sobject (including hierarchy: parent(s) and children) with read-only fields if needed. Underneath, it uses the JSON serialize/deserialize technique to create SObjects in memory. Highly recommended to add to your arsenal.

You must log in to answer this question.

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