0

I have written an application in CakePHP. I am facing an issue. Sometimes it happens that when an order is placed, it's not reflecting in database, but I am both getting an email and it's reflecting in my PayU account dashboard that someone has placed an order with x amount.

Below is my code. What is wrong?

if(!empty($this->data)){
    $data = $this->data;

    $userInfo = $this->User->find('first',array('conditions'=>array('User.id'=>$userID)));
    $sales_rep_email = $userInfo["User"]["sales_rep_email"];
    $user_email = $userInfo["User"]["primary_contact_email"];
    $virtual_account = $userInfo["User"]["virtual_account"];

    if($data['payment_method']=="RTGS Payment"){
        $orderData['Order']['invoice_no'] = 0;
        $orderData['Order']['invoice_prefix'] = "INV-2015-00";
        $orderData['Order']['user_id'] = $userInfo['User']['id'];
        $orderData['Order']['name'] = $userInfo['User']['name'];
        $orderData['Order']['email'] = $userInfo['User']['primary_contact_email'];
        $orderData['Order']['phone'] = $userInfo['User']['primary_contact_number'];
        $orderData['Order']['billing_address'] = $userInfo['User']['address'].", ".$userInfo['User']['city'].", ".$userInfo['User']['district'].", ".$userInfo['User']['state']."-".$userInfo['User']['pin_code'];
        $orderData['Order']['order_item_count'] = $shop['Order']['quantity'];
        $orderData['Order']['shipping'] = $data['shipping_method'];
        $orderData['Order']['total'] = $shop['Order']['total'];
        $orderData['Order']['payment_method'] = $data['payment_method'];
        if($data['shipping_method']=="Express Delivery"){
            $orderData['Order']['delivery_charges'] = 400;
        }

        if($data['payment_method']=="RTGS Payment"){
            $orderData['Order']['status'] = 'open';
            $orderData['Order']['temp_status'] = 'rtgs';
        }else if($data['payment_method']=="COD"){
            $orderData['Order']['status'] = 'open';
            $orderData['Order']['temp_status'] = 'cod';
            $orderData['Order']['customer_status'] = 'unconfirmed';
        }else{
            $orderData['Order']['status'] = 'open';
            $orderData['Order']['temp_status'] = 'open';
        }

        $this->Order->save($orderData);
        $id = $this->Order->getLastInsertId();

        $orderupdateData['Order']['orderid'] = date("Y").date("m").'-'.$id;
        $orderupdateData['Order']['temporary_order'] = "TO".'-'.$id;
        $orderupdateData['Order']['id'] = $id;
        $this->Order->save($orderupdateData);

        $orderItemData = array();


        foreach($shop['OrderItem'] as $key=>$item){
            $quantityNewCheckOut = 0;
            if(!empty($data['payment_method'])){
                $this->manageInventory($item['Product']['smb_code'],$item['quantity']);
            }

            $orderItemData['OrderItem']['order_id'] = $id;
            $orderItemData['OrderItem']['sku_id'] = $key;
            $inventoryData = $this->Inventory->find("first",array("conditions"=>array("Inventory.smb_item_code"=>$item['Product']['smb_code'])));
            $quantityNewCheckOut = (int)$inventoryData["Inventory"]["quantity"];
            if($quantityNewCheckOut<=0){
                $orderItemData["OrderItem"]["mod_name"] = "back";
            }else if($quantityNewCheckOut>0){
                $orderItemData["OrderItem"]["mod_name"] = "available";
            }
            $orderItemData['OrderItem']['name'] = $item['Product']['smb_code'];
            $orderItemData['OrderItem']['quantity'] = $item['quantity'];
            $orderItemData['OrderItem']['price'] = $item['price'];
            if(!empty($item['discount_amount'])){
                $orderItemData['OrderItem']['discount_amount'] = $item['discount_amount'];
            }
            $orderItemData['OrderItem']['subtotal'] = $item['subtotal'];
            $orderItemData['OrderItem']['status'] = "open";

            $this->OrderItem->save($orderItemData);
            $this->OrderItem->create();
            unset($orderItemData);
        }


        $orderDetails = $this->OrderItem->find("all",array("conditions"=>array("OrderItem.order_id"=>$id),'recursive'=>2));
        $content = "<b>Order Date:</b>".date("d F Y H:i:s")."<br/>";
        $content .= "<b>Temporary Order Number:</b>"."TO".'-'.$id."<br/><br/><br/>";
        $content .= "<table border='1'><thead><th>Company Name</th><th>Brand</th><th>SMB Item Code</th><th>Mfg Code</th><th>Product Description</th><th>UOM</th><th>MRP</th><th>Unit Price</th><th>Qty</th><th>Subtotal</th><th>Tax%</th><th>Total</th></thead><tbody>";
        foreach($orderDetails as $orderItem){
            $content .= "<tr>";
            $content .= "<td>".$orderItem["Sku"]["Company"]["name"]."</td>";
            $content .= "<td>".$orderItem["Sku"]["Brand"]["name"]."</td>";
            $content .= "<td>".$orderItem["Sku"]["smb_code"]."</td>";
            $content .= "<td>".$orderItem["Sku"]["title"]."</td>";
            $content .= "<td>".$orderItem["Sku"]["description"]."</td>";
            $content .= "<td>".$orderItem["Sku"]["uom"]."</td>";
            $content .= "<td>"."Rs.".$orderItem["Sku"]["mrp"]."</td>";
            $content .= "<td>"."Rs.".$orderItem["OrderItem"]["price"]."</td>";
            $content .= "<td>".$orderItem["OrderItem"]["quantity"]."</td>";
            $content .= "<td>"."Rs.".sprintf('%01.2f', $orderItem["OrderItem"]["price"] * $orderItem["OrderItem"]["quantity"])."</td>";
            $content .= "<td>".$orderItem["Sku"]["Product"]["tax"]."</td>";
            $content .= "<td>"."Rs.".$orderItem["OrderItem"]["subtotal"]."</td>";
            $content.= "</tr>";
        }
        if($data['shipping_method']=="Express Delivery"){
            $totalAmount = ($orderItem["Order"]["total"])+400;
            $content .= "<tr><td style='text-align:right' colspan='10'>Delivery Charges:</td><td style='text-align:right'colspan='2'>"."Rs. 400</td></tr>";
            $content .= "<tr><td style='text-align:right' colspan='10'>Grand Total:</td><td style='text-align:right'colspan='2'>"."Rs. ".$totalAmount."</td></tr>";
        }else{
            $content .= "<tr><td style='text-align:right' colspan='10'>Grand Total:</td><td style='text-align:right'colspan='2'>"."Rs. ".$orderItem["Order"]["total"]."</td></tr>";
        }

        $content .= "</tbody></table>";



        $emailTemplate = $this->EmailTemplate->find('first',array('conditions'=>array('EmailTemplate.id'=>'23')));
        $emailContent = $emailTemplate['EmailTemplate']['html_content'];
        $subject = $emailTemplate['EmailTemplate']['subject']."TO".'-'.$id;
        $template_info = str_replace(array('$temp_order','$virtual_id','$content','$salesrep'),array("TO".'-'.$id,$virtual_account,$content,$sales_rep_email),$emailContent);
        $email = new CakeEmail();
        $email->template('email_template');
        $email->emailFormat('both');
        $email->viewVars(array('emailContent' => $template_info));
        $to = array($user_email);//$to = '';
        $from = '';
        $email->to($to);
        $email->bcc("");
        $email->cc($sales_rep_email);
        $email->from(array($from=>''));
        $email->subject($subject);
        $email->smtpOptions = array(
            'port'=>'25',
            'timeout'=>'30',
            'host' => '',
            'username'=>'',
            'password'=>'',
        );
        //Set delivery method 
        $email->delivery = 'smtp';
        //pry($email);
        $email->send();
        $this->redirect(array('action'=>"successOrderRTGS"));
    }else{

        $paymentMethod = $data['payment_method'];
        $shippingMethod = $data['shipping_method'];

        if(!empty($paymentMethod)){
            $this->Session->write("User.payment_method",$paymentMethod);
            $this->Session->write("User.shipping_method",$shippingMethod);
        }
        $orderData['Order']['total'] = $shop['Order']['total'];

        if($data['shipping_method']=="Express Delivery"){
            $orderData['Order']['delivery_charges'] = 400;
            $amount =($shop['Order']['total'])+400;
        }else{
            $amount =($shop['Order']['total']);
        }


        $this->pay_page( array (    'key' => '', 'txnid' => uniqid( 'test' ), 'amount' => $amount,
            'firstname' => $userInfo['User']['name'], 'email' => $userInfo['User']['primary_contact_email'], 'phone' => $userInfo['User']['primary_contact_number'],
            'productinfo' => 'Product Info', 'surl' => 'payment_success', 'furl' => 'payment_failure'), '' );
    }
}        
Inigo Flores
  • 4,461
  • 1
  • 15
  • 36

1 Answers1

2

The reason your code is sending out the email despite not saving the Order data in the database is because you are not checking whether the save() is successful or not. It's probably failing due to validation errors, but your code won't do anything about it.

The proper way of handling this is by wrapping the save() method inside an if condition:

if ($this->Order->save($orderData)) {
    //send email
    //redirect
} else {
    Debugger::log($this->Order->validationErrors);
    $this->Flash->set('Order could not be saved');
}

You should also refactor your action to reduce its size. The main purpose of using a MVC framework is to make life easier by separating business logic, control logic and views. If you find yourself writing HTML in your controller, you are probably doing something wrong.

Interesting read: Fat models, skinny controllers and the MVC design pattern

Community
  • 1
  • 1
Inigo Flores
  • 4,461
  • 1
  • 15
  • 36
  • 1
    As Inigo says the action code could really do with a rewrite to be more inline with the MVC approach of CakePHP. The markup shouldn't be being built up in the Controller, Views should be used for this. It also looks like some of the after save logic should be in the `Order` model's `afterSave()` callback. Ideally, emails should be handled using [Event listeners](http://andy-carter.com/blog/events-in-cakephp-2-using-the-observer-pattern) and even better if using something like the [Queue plugin](https://github.com/dereuromark/cakephp-queue) to defer execution to improve app performance. – drmonkeyninja Dec 14 '15 at 12:29
  • 1
    @drmonkeyninjaI I agree. There's also stuff that could go into `Order::beforeSave()`. – Inigo Flores Dec 14 '15 at 12:43
  • @RaviKanth great! Perhaps you could mark the answer as accepted, so that members can focus on other questions. – Inigo Flores Dec 21 '15 at 08:34