1

I have a custom object "Order" with detail object "Order Lines". I want to place a custom button on the Quote header called "Create Order" that when clicked will copy the Quote header and detail records and create a corresponding "Order" and "Order Lines" records.

Mimicing the same functionality that is standard when syncing a quote to an opportunity.

I'm wondering what is the best approach to do this? Should the custom button use the ajax toolkit and execute javascript using the onclick event?

Or, would a visualforce page with a controller be a better option for this?

Are there any examples that demonstrate this functionality?

Thank you.

4

1 回答 1

0

I'd go with a bit of Apex code. Faster than doing it purely with JavaScript toolkit plus let's face it, S-Controls are thing of the past. There's a chance that if your colleague will have to maintain it in future he'll know Apex but maybe not the JS toolkit.

Now - simple JS button + call to Apex exposed with webservice keyword or a visualforce page?. Only you can answer that. Would you like to display the "edit" page, let user change some values and save only afterwards? Are there some statuses on order or line item that have to be "reset" before you save the clone?

As for actual code - best type of clone will dynamically select all (so it'll work also in future when you add new fields). Sadly there's no SELECT * syntax in Apex, you need to use describe calls.

Something like this (untested! just to give you an idea)

List<Schema.SObjectField> orderFields = Schema.SObjectType.Order__c.fields.getMap().values();
List<Schema.SObjectField> itemFields = Schema.SObjectType.Order_Line__c.fields.getMap().values();

// You might also want to use simple fields.getMap().keyset(), that'll be set of strings
Id orderId = 'a01...';

String orderQuery = 'SELECT ' + String.join(orderFields, ', ') + ' FROM Order__c WHERE Id = :orderId';
Order__c oldOrder = Database.query(orderQuery);
Order__c newOrder = oldOrder.clone(false,true); //options do not retain ID; deep clone

insert newOrder;

String itemsQuery = 'SELECT ' + String.join(itemFields, ', ') + ' FROM Order_Line__c WHERE Order__c = :orderId';
List<Order_Line__c> oldLines = Database.query(itemsQuery);
List<Order_Line__c> newLines = oldLines.deepClone(false);
for(Order_Line__c newLine : newLines){
    newLine.Order__c = newOrder.Id;
}
insert newLines;

Feel free to experiment with it (refactor to a helper method, work on generic sObjects instead of concrete Orders... after all if lookup change is the only thing to do - why not?). Also if you're sure orders will have < 200 lines you can try making the query in one go?

于 2013-04-19T07:27:06.443 回答