/**
  * Authenticates the all inputs and there relations with each other
  * returning true false does not stops proceeding to action. to stop add error to attribute.
  */
 public function customInputValidator($attribute, $params)
 {
     //check if address has been passed
     if (isset($this->address) && !AppCommon::isEmpty($this->address)) {
         //if passed check if address passed is allowed for the given user
         //array( addrId => array( locality, addrText ) )
         $allowedAddresses = AAddress::model()->getAllowedAddressForUser(AppCommon::getUserDetailsId());
         if (!isset($allowedAddresses[$this->address])) {
             $this->addError("address", CHtml::encode("Kindly select a valid address."));
             return;
         }
         //continue to check more errors only if address selected is valid
         //as cart depends on a valid address
         //set customerLocality a valid value taken from selected address this will override
         //upon the value passed by user and thus will be more reliable value
         $this->customerLocality = $allowedAddresses[$this->address][0];
         $this->getAddressData[$this->address] = $allowedAddresses[$this->address];
         $this->getCartArray = ACart::getCart($this->customerLocality, 0);
         //check if cart has rows > 0 for the selected locality
         if (isset($this->getCartArray) && isset($this->getCartArray["total_items_at_locality"]) && $this->getCartArray["total_items_at_locality"] <= 0) {
             $this->addError("extraErrorMessages", CHtml::encode("Error: The cart contains no tiffins which are available at the selected address's locality. Kindly, either add tiffins available at selected address's locality to the cart or select addresses with different locality."));
         }
         //check if for selected locality cart has not changed
         if (AppCommon::hasCartChanged($this->getCartArray)) {
             $this->addError("extraErrorMessages", CHtml::encode("Notification: The cart has changed. Kindly retry."));
         }
     }
 }
 /**
  * gets only those addresses for a user for which both address2bangaloreLocalities and
  * address record are not deleted.
  *
  * Returns array( addrId => array( locality, addrText ) )
  */
 public static function getAllowedAddressForUser($userId = NULL)
 {
     $response = array();
     if (isset($userId)) {
         $selectedAddresses = AAddress::model()->findAll(array('with' => array('address2bangaloreLocalities' => array('on' => 'address2bangaloreLocalities.is_deleted = "no" AND 
     				t.is_deleted = "no" AND t.link_table = "user_details"  AND t.link = ' . $userId . ' '))));
         foreach ($selectedAddresses as $row) {
             $response[$row->id][] = $row->address2bangaloreLocalities->locality_name;
             $response[$row->id][] = $row->getAddressString();
         }
     }
     return $response;
 }
 /**
  * Returns the data model based on the primary key given in the GET variable.
  * If the data model is not found, an HTTP exception will be raised.
  * @param integer $id the ID of the model to be loaded
  * @return AAddress the loaded model
  * @throws CHttpException
  */
 public function loadModel($id)
 {
     $model = AAddress::model()->findByPk($id);
     if ($model === null) {
         throw new CHttpException(404, 'The requested page does not exist.');
     }
     return $model;
 }
 /**
  * $id is order unique id
  *
  * TODO::add comments
  */
 public function actionCheckout($id = null)
 {
     $sm = Yii::app()->getSecurityManager();
     $orderId = $id;
     $selectedOrders = null;
     if (isset($orderId)) {
         if (($orderId = $sm->validateData($orderId)) == false) {
             $this->render('cart_error', array('errorMessage' => "Either this page does not exists or has expired.", 'link' => CHtml::normalizeUrl(array('site/index'))));
             Yii::app()->end();
         }
         //if order id exists and belongs to current user and is in 'order_start' status
         //(other status mean order has already crossed the checkout process once)
         //as order id's input has been added to checkout action to facilitate the
         //order resumption. Note: As order is being modified or created in this function
         //do check before any POST or GET if order can be modified. Order can be modified
         //only and only if it is in 'order-start' status.
         $selectedOrders = AOrder::model()->findAll(array('condition' => 'is_deleted = "no" AND ordered_by2user_details = ' . AppCommon::getUserDetailsId() . ' AND  order_unique_id = "' . $orderId . '" ' . ' AND  status = "order_start" '));
         if (!isset($selectedOrders) || count($selectedOrders) < 1) {
             $this->render('cart_error', array('errorMessage' => "Either this page does not exists or has expired or you are not allowed to view this page.", 'link' => CHtml::normalizeUrl(array('cart/checkout'))));
             Yii::app()->end();
         }
     }
     $model = new CheckoutFirstStageForm();
     if (Yii::app()->getRequest()->getRequestType() == 'GET' || isset($_POST['CheckoutFirstStageForm'])) {
         if (isset($orderId) && Yii::app()->getRequest()->getRequestType() == 'GET') {
             //first add the items retreived from $orderId to cart
             if (isset($selectedOrders)) {
                 foreach ($selectedOrders as $row) {
                     $this->actionAddToCart($row->order2tiffin, $row->num_of_units, 0);
                     $model->address = $row->order2address;
                     $model->phone = $row->destination_phone;
                     $model->customerLocality = $row->destination_locality;
                 }
             }
         }
         if (AppCommon::cartItemCount() < 1) {
             $this->render('cart_error', array('errorMessage' => "Cart is empty.", 'link' => CHtml::normalizeUrl(array('site/index'))));
             Yii::app()->end();
         }
         //handling POST method here
         if (isset($_POST['CheckoutFirstStageForm'])) {
             $model->attributes = $_POST['CheckoutFirstStageForm'];
             if ($model->validate()) {
                 //get a order id if not there create new
                 //after this if we will have a order id for sure :)
                 if (!isset($orderId) && ($orderId = AppCommon::getUniqueOrderNumForUser(AppCommon::getUserDetailsId())) == false) {
                     $this->render('cart_error', array('errorMessage' => "Order number could not be created.", 'link' => CHtml::normalizeUrl(array('site/index'))));
                     Yii::app()->end();
                 }
                 //Yii::ankFileSave( $orderId );
                 //create order rows in table
                 $transaction = Yii::app()->db->beginTransaction();
                 try {
                     //remove all old records if any with supplied orderId
                     if (isset($selectedOrders) && count($selectedOrders) > 0) {
                         foreach ($selectedOrders as $row) {
                             $row->is_deleted = AppCommon::getUserDetailsId();
                             $row->save();
                         }
                     }
                     $currDateTime = new DateTime();
                     $currDateTime = $currDateTime->format('Y-m-d H:i:s');
                     //Yii::ankFileSave( var_export( $model->getCartArray, true ) );
                     //save orders rows for item in current locality
                     foreach ($model->getCartArray as $key => $value) {
                         if (is_array($value)) {
                             if ($value["is_available_at_current_locality"]) {
                                 //saved order record
                                 $orderRecord = new AOrder();
                                 $orderRecord->order_unique_id = $orderId;
                                 $orderRecord->num_of_units = $value["quantity"];
                                 $orderRecord->ordered_by2user_details = AppCommon::getUserDetailsId();
                                 $orderRecord->order2tiffin = $value["id"];
                                 $orderRecord->order2address = $model->address;
                                 $orderRecord->status = 'order_start';
                                 $orderRecord->last_status_update = $currDateTime;
                                 $orderRecord->destination_phone = $model->phone;
                                 $orderRecord->destination_address = $model->getAddressData[$model->address][1];
                                 $orderRecord->destination_locality = $model->getAddressData[$model->address][0];
                                 if ($emailPhoneArr = AppCommon::getEmailAndBasePhoneNumForUser($value["chef_id"])) {
                                     if (isset($emailPhoneArr['phone'])) {
                                         $orderRecord->source_phone = $emailPhoneArr['phone'];
                                     }
                                 }
                                 if ($AddressDataArrForChef = AppCommon::getBaseAddressDataForUser($value["chef_id"])) {
                                     foreach ($AddressDataArrForChef as $key1 => $value1) {
                                         $orderRecord->source_address = $value1[1];
                                         $orderRecord->source_locality = $value1[0];
                                     }
                                 }
                                 $orderRecord->save();
                                 //saved order history record
                                 AppCommon::createOrderHistoryRecord($orderRecord->id, 'order_start', $currDateTime, $orderId);
                                 //TODO save phone number with user id in phone table if not exists already
                             }
                         }
                     }
                     $transaction->commit();
                 } catch (Exception $e) {
                     //Yii::ankFileSave($e->getMessage());
                     $transaction->rollback();
                     $this->render('cart_error', array('errorMessage' => "Order could not be created.", 'link' => CHtml::normalizeUrl(array('site/index'))));
                     Yii::app()->end();
                 }
                 $secStage = new CheckoutSecondStageForm($orderId, AppCommon::getUserDetailsId());
                 $secStage->validate();
                 $secStage->clearErrors();
                 //clear error as it the first time display of form
                 //Yii::ankFileSave( var_export( $secStage, true ) );
                 $this->render('checkout_second_stage', array('model' => $secStage));
                 Yii::app()->end();
                 //stop here after displaying checkout second stage
             }
         }
         //datastructure format : array( addrId => array( locality, addrText ) )
         $addressArray = AAddress::getAllowedAddressForUser(AppCommon::getUserDetailsId());
         $this->render('checkout_first_stage', array('model' => $model, 'addressArray' => $addressArray));
     } else {
         if (isset($_POST['CheckoutSecondStageForm']) && isset($orderId) && isset($orderId) && isset($selectedOrders) && count($selectedOrders) > 0) {
             $secStage1 = new CheckoutSecondStageForm($orderId, AppCommon::getUserDetailsId());
             $secStage1->attributes = $_POST['CheckoutSecondStageForm'];
             foreach ($secStage1->tiffinPriceTimeSelectionArr as $key1 => $value1) {
                 if (isset($_POST['TiffinPriceTimeSelectionForm'][$key1])) {
                     $value1->attributes = $_POST['TiffinPriceTimeSelectionForm'][$key1];
                 }
             }
             //validation passed finishing orders
             if ($secStage1->validate()) {
                 //TODO: javascript thing also
                 //TODO: before displaying make sure pament method is set accoding to wallet money and total value
                 //TODO: and discount and cash back value should be rest user should press verify to set them.
                 //TODO: things to make order confirmed
                 $transaction1 = Yii::app()->db->beginTransaction();
                 try {
                     $currDateTime1 = new DateTime();
                     $currDateTime1 = $currDateTime1->format('Y-m-d H:i:s');
                     foreach ($secStage1->tiffinPriceTimeSelectionArr as $key3 => $value3) {
                         /* @var $value3 TiffinPriceTimeSelectionForm */
                         /* @var $aOrderObj $currOrder */
                         $currOrder = $value3->aOrderObj;
                         $currOrder->total_price = $value3->totalPrice;
                         $currOrder->per_unit_price = $value3->perUnitPrice;
                         $currOrder->order2price_time = $value3->selectedPriceTimeId;
                         if (!AppCommon::isEmpty($secStage1->couponCode)) {
                             $currOrder->applied_offer_id = $secStage1->couponCode;
                             if ($secStage1->billArray[1] != 0) {
                                 $currOrder->applied_order_amount = $secStage1->billArray[1];
                             } else {
                                 if ($secStage1->billArray[2] != 0) {
                                     $currOrder->applied_order_amount = $secStage1->billArray[2];
                                 }
                             }
                         }
                         $currOrder->order_pickup_time = $value3->selectedAPriceTimeObj->order_pickup_time;
                         $currOrder->order_delivery_time = $value3->selectedAPriceTimeObj->order_delivery_time;
                         $currOrder->wallet_amount_used = $secStage1->amountUsedFromWallet;
                         if ($secStage1->paymentMethod == 1) {
                             //order_start -> wallet -> order_confirmed
                             $currOrder->payment_mode = 'wallet';
                             AppCommon::createOrderHistoryRecord($currOrder->id, 'wallet', $currDateTime1, $currOrder->order_unique_id);
                             AppCommon::createOrderHistoryRecord($currOrder->id, 'order_confirmed', $currDateTime1, $currOrder->order_unique_id);
                             $currOrder->status = 'order_confirmed';
                             $currOrder->last_status_update = $currDateTime1;
                         } else {
                             if ($secStage1->paymentMethod == 2) {
                                 throw new Exception();
                                 //order_start -> online_payment -> awaiting_payment_confirmation -> payment_received -> order_confirmed/ order_failed
                                 $currOrder->payment_mode = 'online_payment';
                                 AppCommon::createOrderHistoryRecord($currOrder->id, 'online_payment', $currDateTime1, $currOrder->order_unique_id);
                                 AppCommon::createOrderHistoryRecord($currOrder->id, 'awaiting_payment_confirmation', $currDateTime1, $currOrder->order_unique_id);
                             } else {
                                 if ($secStage1->paymentMethod == 3) {
                                     //order_start -> cod -> awaiting_order_verification -> order_confirmed
                                     $currOrder->payment_mode = 'cod';
                                     AppCommon::createOrderHistoryRecord($currOrder->id, 'cod', $currDateTime1, $currOrder->order_unique_id);
                                     AppCommon::createOrderHistoryRecord($currOrder->id, 'awaiting_order_verification', $currDateTime1, $currOrder->order_unique_id);
                                     AppCommon::createOrderHistoryRecord($currOrder->id, 'order_confirmed', $currDateTime1, $currOrder->order_unique_id);
                                     $currOrder->status = 'order_confirmed';
                                     $currOrder->last_status_update = $currDateTime1;
                                 }
                             }
                         }
                         $currOrder->save();
                     }
                     if ($secStage1->paymentMethod == 1) {
                         //deduct money from wallet if wallet used
                         AppCommonWallet::debitAmountFromWallet($secStage1->amountUsedFromWallet, 'order_creation', $currDateTime1, $secStage1->orderId, 'wallet', $secStage1->userId);
                     } else {
                         if ($secStage1->paymentMethod == 3) {
                             //deduct money from wallet if wallet used
                             AppCommonWallet::debitAmountFromWallet($secStage1->amountUsedFromWallet, 'order_creation', $currDateTime1, $secStage1->orderId, 'wallet', $secStage1->userId);
                         }
                     }
                     $transaction1->commit();
                 } catch (Exception $e) {
                     Yii::ankFileSave($e->getMessage());
                     $transaction1->rollback();
                     $this->render('cart_error', array('errorMessage' => "Order could not be created.", 'link' => CHtml::normalizeUrl(array('cart/checkout', 'id' => $secStage1->encryptedOrderId))));
                     Yii::app()->end();
                 }
                 $orderViewLink = Yii::app()->getRequest()->getHostInfo() . Yii::app()->getRequest()->getScriptUrl() . '/order/view/id/' . $secStage1->encryptedOrderId;
                 Yii::ankFileSave("order links");
                 Yii::ankFileSave($orderViewLink);
                 $subject_email = "tw.in Order Confirmation order no. " . $secStage1->orderId;
                 $content_user = "******" . Yii::app()->user->name . ",\n" . "Your order no. " . $secStage1->orderId . " has been accepted. The url containing details of your order is \n\n\n" . $orderViewLink . "\n\n\n We will deliver the order by as per your selected time. We may call you for asking directions, if needed." . " Kindly receive the calls to make us deliver quickly. \nThanks and regards, \nTiffinwale.in team ";
                 //notify customer
                 AppCommon::sendEmail(AppCommon::getEmail(), Yii::app()->user->name, $subject_email, $content_user, array("order_notification_customer"));
                 //notify tw team
                 AppCommon::sendEmail(Yii::app()->params['adminEmail'], Yii::app()->user->name, $subject_email, $content_user, array("order_notification_tiffinwale.in_team"));
                 $content_sms = "Dear Customer, we have received your order no. " . $secStage1->orderId . ". For more details click " . CHtml::encode($orderViewLink) . " or view email" . " Thanks! tw.in";
                 /*$content_sms = "Dear Customer, we have received your order from".
                 		" and it will be delivered between 12:30 PM to 2:00 PM. Thank You! tw.in";*/
                 //sms customer
                 AppCommon::sendSmsOnTime($secStage1->tiffinPriceTimeSelectionArr[0]->aOrderObj->destination_phone, $content_sms, "null", true);
                 AppCommon::sendSmsOnTime('9999999999', $content_sms, "null", true);
                 //redirect to view order details
                 Yii::app()->getRequest()->redirect($orderViewLink);
                 //TODO: price time and cart value decrease
                 Yii::app()->end();
                 //stop here
             }
             $this->render('checkout_second_stage', array('model' => $secStage1));
         } else {
             $this->render('cart_error', array('errorMessage' => "Few security issues has been detected with this request.", 'link' => CHtml::normalizeUrl(array('site/index'))));
             Yii::app()->end();
         }
     }
 }
 public static function getBaseAddressDataForUser($userDetailsId)
 {
     $response = array();
     if (isset($userDetailsId)) {
         $selectedAddresses = AAddress::model()->findAll(array('order' => 't.id DESC', 'with' => array('address2bangaloreLocalities' => array('on' => 'address2bangaloreLocalities.is_deleted = "no" AND 
     				t.is_deleted = "no" AND t.link_table = "user_details"  AND 
     				t.meta_data = "base_address" AND t.link = ' . $userDetailsId . ' '))));
         foreach ($selectedAddresses as $row) {
             $response[$row->id][] = $row->address2bangaloreLocalities->locality_name;
             $response[$row->id][] = $row->getAddressString();
             break;
             //get the last updated and exit
         }
     }
     if (AppCommon::isEmpty($response)) {
         $response = false;
     }
     return $response;
 }