+ Start a Discussion
Mauricio OliveiraMauricio Oliveira 

Visualforce page: pageblock table messing data

Hi there,

I have this custom Visualforce page for QuoteLineItem's multiple edit. It works as a shopping cart: it has the Quote items at the top, and the list of available pricebook entries with a search bar. Some users have reported that this multi-line edit page is messing around some data, as QuoteLineItem "A" getting item "B" data (custom fields that were filled in this page) after saving.

I was able to reproduce one of the mess arounds that can happen. I suspect other cases are variations of this one, so I'm focusing on getting this one fixed before going further. But I don't know what is going on. See detailed explanation below:

1. This is the initial page, I already have 4 QuoteLineItems in the Quote. Check out the "New/Renewal" column. Red arrow is where I will click next.
User-added image

2. Selecting an item from the "Available Products", it goes to the shopping cart as expected, without "New/Renewal" field filled (no default value for that field, nad not added when the QuoteLineItem is created via code). All good for now, but before filling out the visible fields, I will just remove an existing item that I don't want anymore...
User-added image

3. Now it gets weird. "New/Renewal" field of the new item gets populated with the last existing item's value. View State confirms that is does not have that filled.
User-added image

4. I just ignored that and hit Save without filling the other fields. So it does not pass validation and the page is reloaded with error message. But this time the wrong "New/Renewal" value was cleared.
User-added image


So, this is what is going on. Any idea of what is going on?

Visualforce page: "Remove" button:

<apex:column>
    <apex:commandButton value="Remove" action="{!removeFromShoppingCart}" reRender="selected,searchResults" immediate="true" status="loadStatus">
        <apex:param value="{!index}" assignTo="{!toUnselect}" name="toUnselect"/>
    </apex:commandButton>
</apex:column>

Visualforce page: "Select" button
<apex:column >
    <apex:commandButton value="Select" action="{!addToShoppingCart}" reRender="selected,searchResults" immediate="true" status="loadStatus">
        <apex:param value="{!a.Id}" assignTo="{!toSelect}" name="toSelect"/>
    </apex:commandButton>
</apex:column>

Apex class: removeFromShoppingCart
public PageReference removeFromShoppingCart() {
    QuoteLineItem to_remove = shoppingCart.remove(Integer.valueOf(toUnselect));
    if (to_remove.Id != null) {
        // Can only delete if item was already inserted into database (has ID)
        forDeletion.add(to_remove);
    }
    updateAvailableList();
    return null;
}

Apex class: addToShoppingCart
public void addToShoppingCart() {
    for(PricebookEntry d : AvailableProducts){
        String entry_id = (String) d.Id;
        if (entry_id.equals(toSelect)) {
            shoppingCart.add(
                new QuoteLineItem(
                        QuoteId=theQuote.Id, 
                        PriceBookEntry=d, 
                        PriceBookEntryId=d.Id, 
                        UnitPrice=d.UnitPrice, 
                        Quantity=1, 
                        SPF__c=0
                    )
                );
            break;
        }
    }
    updateAvailableList();  
}

So, what am I doing wrong? As I said, there are other cases where users edit multiple lines and after saving their custom fields get saved to different items... but the problem I reported with this simple example makes me feel I'm missing something very basic. Can someone help me?

Thanks in advance.