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
SF7SF7 

Auto Clone and create 2 new orders when an existing order is updated with a different status


<apex:commandButton value="Submit Order" action="{!submitOrder}" rendered="{!isOrderSubmitable}" reRender="pgBlock" 
                                        onclick="if ( !confirm('{!$Label.CCMTY_Submit_Msg}') ){return false;}" status="status" />


public PageReference submitOrder(){

        PageReference pr = null;
        try{
            // Calculate the time Difference between Qoute Submition to uptil now
           Order ordTemp = [select Quote_Created_Date__c from Order where id =:orderRecord.ID];
           Double qouteSubmitTimeDiff =
               double.valueOf(((System.now().getTime())/1000/60/60) - ((ordTemp.Quote_Created_Date__c.getTime())/1000/60/60));
            // Don't process the order with 24hrs older qoutes.
            if(qouteSubmitTimeDiff > 24){
                addErrorMessage(Label.ErrorMsg_QuoteExpired);
                return pr;
            }
            
            eiJcCreateOrderServices.createOrderRequestType cor = new eiJcCreateOrderServices.createOrderRequestType();
            cor.orderNumber = CCMTY_StringUtil.stripRegionFromId(this.orderRecord.Order_Quote_Number__c);
            eiJcCreateOrderServices.PSCreateOrderSOAP osp = new  eiJcCreateOrderServices.PSCreateOrderSOAP();
            osp.inputHttpHeaders_x = new Map<String, String>{'apikey' => CCMTY_Settings__c.getInstance().EI_API_Key__c};
            osp.timeout_x = 60000;
          
            
            eiJcCreateOrderServices.createOrderResponseType restp;// = osp.createOrder(cor.orderNumber);
            restp = osp.createOrder(cor.orderNumber);    
            System.debug(restp);
            
            System.debug('restp.orderNumber: ' + restp.orderNumber);
            if( !String.isBlank(restp.orderNumber) ) {

                this.orderRecord.Order_External_Key__c = this.orderRecord.Order_Region__c + '-' + restp.orderNumber;
                this.orderRecord.Status = 'Submitted';
                this.orderRecord.Order_Submit_Date__c = System.today();
                System.debug('order rebate total:'+orderRecord.Order_Total_Rebate__c+' status:'+orderRecord.Status);
                update this.orderRecord;

                List<OrderItem> orderItems = 
                    [select Order_Products_Line_Number__c from OrderItem where OrderId = :this.orderRecord.Id];
                for ( OrderItem oi : orderItems ) {
                    oi.Order_Products_External_Key__c = this.orderRecord.Order_External_Key__c + '-' + oi.Order_Products_Line_Number__c;
                }
                update orderItems;
                
                if(test.isRunningTest())
                {
                   orderRecord = [Select accountId, Order_Total_Rebate__c,Status,OrderNumber, (Select id,name, Order_Discount_Value__c,Order_Discount_Type__c from Order_Discounts__r ) from order where id=: ordTemp.Id limit 1 ];
                }
                System.debug('order rebate total:'+orderRecord.Order_Total_Rebate__c+' status:'+orderRecord.Status+' this.orderRecord.Order_Discounts__r:'+this.orderRecord.Order_Discounts__r);
                if(orderRecord.Order_Total_Rebate__c > 0 && orderRecord.Status.equals('Submitted')) {
                    List<Rebate_Transaction__c> rebateTransactions = new List<Rebate_Transaction__c>();
                    System.debug('this.orderRecord.Order_Discounts__r: ' + this.orderRecord.Order_Discounts__r);
                    for ( Order_Discount__c od : this.orderRecord.Order_Discounts__r ) {
                        if ( od.Order_Discount_Type__c == 'Rebate' ) {
                            Decimal startingBal =  (rebateTypesAvailableAmtMap.get(od.Name) != null)? rebateTypesAvailableAmtMap.get(od.Name) : 0 ;
                            
                            rebateTransactions.add(getRebateConsumedRecord(od.Name, od.Order_Discount_Value__c,startingBal,
                                                                           (startingBal - od.Order_Discount_Value__c)));
                        }
                    }
                    insert rebateTransactions;
                }
                
                pr = new PageReference( '/' + this.getOrderKeyPrefix() );
                pr.getParameters().put('feedback', 'OrderSubmitted');
                pr.getParameters().put('orderNumber', this.orderRecord.OrderNumber);
                pr.getParameters().put('selectedFilterId', CCMTY_Settings__c.getInstance().Orders_Default_List_View_ID__c);
            }
        }catch( DmlException e){
           
            this.orderRecord.Order_Submit_Date__c = null;
            this.addGenericErrorMessage();
        }
        return pr;
    }
// This is another class which Auto Clones the Order when a clone button is clicked on the Front end maully by the user . 

<apex:page standardController="Order"  extensions="OrderCloneWithItemsController" action="{!cloneWithItems}">
     <apex:pageMessages />
</apex:page>

public class OrderCloneWithItemsController {

    //added an instance varaible for the standard controller
    private ApexPages.StandardController controller {get; set;}
     // add the instance for the variables being passed by id on the url
    private Order po {get;set;}
    // set the id of the record that is created -- ONLY USED BY THE TEST CLASS
    public ID newRecordId {get;set;}

    // initialize the controller
    public OrderCloneWithItemsController(ApexPages.StandardController controller) {

        //initialize the stanrdard controller
        this.controller = controller;
        // load the current record
        po = (Order)controller.getRecord();

    }

    // method called from the VF's action attribute to clone the po
    public PageReference cloneWithItems() {

         // setup the save point for rollback
         Savepoint sp = Database.setSavepoint();
         Order newPO;

         try {

              //copy the purchase order - ONLY INCLUDE THE FIELDS YOU WANT TO CLONE
             po = [select Id, Name, accountId, Order_Total_Rebate__c,EffectiveDate,Status,Order_Region__c,OrderNumber,Order_ShipTo_Address__c,CurrencyIsoCode , PoNumber, Order_Requested_Delivery_Date__c ,Order_Comments__c, Pricebook2Id from Order where id = :po.id];
             newPO = po.clone(false);
             insert newPO;

             // set the id of the new po created for testing
               newRecordId = newPO.id;

             // copy over the line items - ONLY INCLUDE THE FIELDS YOU WANT TO CLONE
             List<OrderItem> items = new List<OrderItem>();
             for (OrderItem pi : [Select p.Id, p.UnitPrice,p.Price_Book_External_Key__C, p.Quantity,p.Order_Products_Line_Number__c,p.Description,p.Brand__c,p.PricebookEntryId From OrderItem p where OrderId = :po.id]) {
                  OrderItem newPI = pi.clone(false);
                  newPI.OrderId = newPO.id;
                  items.add(newPI);
             }
             insert items;

         } catch (Exception e){
             // roll everything back in case of error
            Database.rollback(sp);
            ApexPages.addMessages(e);
            return null;
         }

        return new PageReference('/'+newPO.id+'/e?retURL=%2F'+newPO.id);
    }

}
I want to auto clone and create 2 new orders from an existing order when the Order is submitted (Status on order is changed to Submitted ).
I was able to cretae a button from the front end and clone the records but i want this clone called from the first class and create the records without manul intervention like clicking the clone button. 


Thanks

 
Ravi Dutt SharmaRavi Dutt Sharma
Hey Akhil,

So you want to achieve this in a trigger? Is that what you mean - when status of order is changed to Submitted, create 2 new order records which are exact replica of original record?
SF7SF7
Hi Ravi
So iam thinking of 2 ways 

1. I already have a class which excutes clone method when a button is clicked manaully (second section of my above post) , Some how execute this from the first class when ststus is updated.
or
2. Create a Triiger like you said which creates 2 new order records of the exact replica

Thanks
Akhil;
Ravi Dutt SharmaRavi Dutt Sharma
If you need an exact replica and want to go with option#2, have a look at the clone method present on sObject. You do not need to write any logic for that, just call the clone method on the record you get in the trigger and its done.
1) In your trigger, check whether the order status has changed. If it is changed, then check whether the new value of status is Submitted.
2) Call clone method on that record and insert the cloned record. Before inserting you can make any changes to the cloned record, if required.

Example of clone method :
 
Account acc = new account(Name = 'Acme', Description = 'Acme Account');
Account clonedAcc = acc.clone(false, false, false, false);
System.assertEquals(acc, clonedAcc);

Let me know if it helps.
Ravi Dutt SharmaRavi Dutt Sharma
Ok, so you want to clone parent along with child records. I have written a generic code for such use-cases. You can have a look at it, maybe you can get some help from there. Thanks.

http://salesforceravisharma.blogspot.com/2016/03/clone-with-related-list.html
Ravi Dutt SharmaRavi Dutt Sharma
Yes Akhil, you can call the class from the trigger. Just make sure that if the method is expecting any parameters that it is receiving from button click, you have to pass those parameters from your trigger.