/**
  * Which Carts need to be deleted
  *
  * @return Market_OrderModel[]
  */
 public function getCartsToPurge()
 {
     $configInterval = craft()->market_settings->getSettings()->purgeIncompleteCartDuration;
     $edge = new DateTime();
     $interval = new DateInterval($configInterval);
     $interval->invert = 1;
     $edge->add($interval);
     $records = Market_OrderRecord::model()->findAllByAttributes(['dateOrdered' => null], 'dateUpdated <= :edge', ['edge' => $edge->format('Y-m-d H:i:s')]);
     return Market_OrderModel::populateModels($records);
 }
 /**
  * @param Market_OrderModel $order
  *
  * @return bool
  * @throws \Exception
  */
 public function save($order)
 {
     if (!$order->dateOrdered) {
         //raising event
         $event = new Event($this, ['order' => $order]);
         $this->onBeforeSaveOrder($event);
     }
     if (!$order->id) {
         $orderRecord = new Market_OrderRecord();
     } else {
         $orderRecord = Market_OrderRecord::model()->findById($order->id);
         if (!$orderRecord) {
             throw new Exception(Craft::t('No order exists with the ID “{id}”', ['id' => $order->id]));
         }
     }
     // Set default shipping method
     if (!$order->shippingMethodId) {
         $method = craft()->market_shippingMethod->getDefault();
         if ($method) {
             $order->shippingMethodId = $method->id;
         }
     }
     // Set default payment method
     if (!$order->paymentMethodId) {
         $methods = craft()->market_paymentMethod->getAllForFrontend();
         if ($methods) {
             $order->paymentMethodId = $methods[0]->id;
         }
     }
     //Only set default addresses on carts
     if (!$order->dateOrdered) {
         // Set default shipping address if last used is available
         $lastShippingAddressId = craft()->market_customer->getCustomer()->lastUsedShippingAddressId;
         if (!$order->shippingAddressId && $lastShippingAddressId) {
             if ($address = craft()->market_address->getAddressById($lastShippingAddressId)) {
                 $order->shippingAddressId = $address->id;
                 $order->shippingAddressData = JsonHelper::encode($address->attributes);
             }
         }
         // Set default billing address if last used is available
         $lastBillingAddressId = craft()->market_customer->getCustomer()->lastUsedBillingAddressId;
         if (!$order->billingAddressId && $lastBillingAddressId) {
             if ($address = craft()->market_address->getAddressById($lastBillingAddressId)) {
                 $order->billingAddressId = $address->id;
                 $order->billingAddressData = JsonHelper::encode($address->attributes);
             }
         }
     }
     if (!$order->customerId) {
         $order->customerId = craft()->market_customer->getCustomerId();
     } else {
         // if there is no email set and we have a customer, get their email.
         if (!$order->email) {
             $order->email = craft()->market_customer->getById($order->customerId)->email;
         }
     }
     // Will not adjust a completed order, we don't want totals to change.
     $this->calculateAdjustments($order);
     $oldStatusId = $orderRecord->orderStatusId;
     $orderRecord->number = $order->number;
     $orderRecord->itemTotal = $order->itemTotal;
     $orderRecord->email = $order->email;
     $orderRecord->dateOrdered = $order->dateOrdered;
     $orderRecord->datePaid = $order->datePaid;
     $orderRecord->billingAddressId = $order->billingAddressId;
     $orderRecord->shippingAddressId = $order->shippingAddressId;
     $orderRecord->shippingMethodId = $order->shippingMethodId;
     $orderRecord->paymentMethodId = $order->paymentMethodId;
     $orderRecord->orderStatusId = $order->orderStatusId;
     $orderRecord->couponCode = $order->couponCode;
     $orderRecord->baseDiscount = $order->baseDiscount;
     $orderRecord->baseShippingCost = $order->baseShippingCost;
     $orderRecord->totalPrice = $order->totalPrice;
     $orderRecord->totalPaid = $order->totalPaid;
     $orderRecord->customerId = $order->customerId;
     $orderRecord->returnUrl = $order->returnUrl;
     $orderRecord->cancelUrl = $order->cancelUrl;
     $orderRecord->message = $order->message;
     $orderRecord->shippingAddressData = $order->shippingAddressData;
     $orderRecord->billingAddressData = $order->billingAddressData;
     $orderRecord->validate();
     $order->addErrors($orderRecord->getErrors());
     MarketDbHelper::beginStackedTransaction();
     try {
         if (!$order->hasErrors()) {
             if (craft()->elements->saveElement($order)) {
                 //creating order history record
                 if ($orderRecord->id && $oldStatusId != $orderRecord->orderStatusId) {
                     if (!craft()->market_orderHistory->createFromOrder($order, $oldStatusId)) {
                         throw new Exception('Error saving order history');
                     }
                 }
                 //saving order record
                 $orderRecord->id = $order->id;
                 $orderRecord->save(false);
                 MarketDbHelper::commitStackedTransaction();
                 //raising event
                 if (!$order->dateOrdered) {
                     $event = new Event($this, ['order' => $order]);
                     $this->onSaveOrder($event);
                 }
                 return true;
             }
         }
     } catch (\Exception $e) {
         MarketDbHelper::rollbackStackedTransaction();
         throw $e;
     }
     MarketDbHelper::rollbackStackedTransaction();
     return false;
 }