/**
  * Check Shipment
  *
  * @param Snap $Model
  * @param $shipment_id
  * @return array
  */
 public function checkShipment(Snap $Model, $shipment_id)
 {
     $results = "{$Model->name}\n";
     $this->OrderShipment = ClassRegistry::init('OrderShipment');
     $this->OrderShipment->useDbConfig = "replicated";
     unset($this->OrderShipment->virtualFields);
     $shipment = $this->OrderShipment->find('first', ['contain' => ['Order' => ['OrderCustomer' => ['Email', 'Address' => ['State']], 'User']], 'conditions' => ['OrderShipment.id' => $shipment_id]]);
     $this->OrderShipment->useDbConfig = "default";
     $this->OrderShipment->clear();
     $this->OrderShipment->id = $shipment_id;
     $total = count($shipment);
     if ($total == 0) {
         return ['success' => FALSE, 'message' => "Shipment not found"];
     }
     $market_id = $shipment['Order']['order_market_id'];
     try {
         if (!empty($shipment['Order']['OrderCustomer']['Address']['State']['ns_warehouse_id'])) {
             $wh_id = $shipment['Order']['OrderCustomer']['Address']['State']['ns_warehouse_id'];
         } else {
             $wh_id = (int) WarehouseUtil::idByMarket($market_id);
         }
         $snap_shipment = SnapFulfilAPI::call("shipments/{$shipment_id}", NULL, FALSE, $wh_id);
     } catch (Exception $e) {
         return ['success' => FALSE, 'message' => "Shipment not in Snap"];
     }
     if (empty($snap_shipment->CarrierTrackingNumber) && $snap_shipment->Stage != '90') {
         //has no tracking number
         $this->OrderShipment->saveField('order_shipment_status_id', OrderShipmentStatus::PROCESSING);
         return ['success' => FALSE, 'message' => "Shipment is still being picked or packed."];
     } elseif ($snap_shipment->Stage == '90') {
         // order is marked as shipped
         $results .= "Adding tracking and sending email\n";
         $results .= "Adding order_shipment_packages record for order_shipment_id: " . $shipment_id . "\n";
         $results .= "Tracking number: " . $snap_shipment->CarrierTrackingNumber . "\n";
         if ($snap_shipment->CarrierTrackingNumber && $snap_shipment->ShippingMethod) {
             $tracking_url = $this->OrderShipment->getTrackingLink($snap_shipment->CarrierTrackingNumber, $snap_shipment->ShippingMethod);
         } else {
             $tracking_url = '';
         }
         $email_data = ["name" => $snap_shipment->CustomerName, "order_id" => $snap_shipment->CustomerRef, "tracking_number" => $snap_shipment->CarrierTrackingNumber, "tracking_url" => $tracking_url, "country_id" => $snap_shipment->ShipAddress[0]->Country];
         $usable_userLocale = empty($shipment['Order']['User']['user_default_locale']) ? 'en_US' : $shipment['Order']['User']['user_default_locale'];
         YouniqueEmail::queueEmail($email_data, 'en_us_tracking_numbers', $shipment['Order']['OrderCustomer']['Email']['email'], 'email order tracking', 'purchase-page', $usable_userLocale);
         $results .= "Tracking email sent: " . $snap_shipment->CarrierTrackingNumber . "\n";
         $this->OrderShipment->clear();
         $this->OrderShipment->id = $shipment_id;
         $this->OrderShipment->saveField('tracking_number', $snap_shipment->CarrierTrackingNumber);
         $this->OrderShipment->saveField('carrier', $snap_shipment->ShippingMethod);
         $this->OrderShipment->saveField('date_shipped', $snap_shipment->DateClosed);
         $this->OrderShipment->saveField('order_shipment_status_id', OrderShipmentStatus::FULFILLED);
         $results .= "Order Shipment updated.\n";
     } elseif ($snap_shipment->Stage == '00' && strtotime($snap_shipment->DateDueOut) < strtotime('now')) {
         // shipment is past scheduled due date
         $results .= "00: " . $shipment_id . "\n";
         $this->OrderShipment->saveField('order_shipment_status_id', OrderShipmentStatus::UNSPECIFIED_ERROR);
     } else {
         $results .= "Unspecified error: " . $shipment_id . "\n";
     }
     $results .= "Completed check of order shipping record.\n";
     return ['success' => TRUE, 'message' => $results];
 }
 /**
  * @param $clientIp
  */
 public function getMarketByIp($clientIp)
 {
     $location = $this->Geolocation->getCountryByIp($clientIp);
     $market_id = Market::$id_by_shortcode[$location['country_code']];
     if (empty($market_id)) {
         $market_id = 1;
     }
     $marketData = ['market_id' => $market_id, 'location' => $location, 'warehouse' => WarehouseUtil::idByMarket($market_id)];
     $this->sendSuccess($marketData);
 }
 /**
  * Get product availability for admin replacement order item
  *
  * @param $order_id
  * @param $sku
  */
 public function product_availability($order_id, $sku)
 {
     if (empty($order_id) || empty($sku)) {
         $this->set(['result' => ['available' => false], '_serialize' => ['result']]);
         return;
     }
     $order = $this->Order->find('first', ['fields' => 'order_market_id', 'conditions' => ['id' => $order_id]]);
     $order_market = $order['Order']['order_market_id'];
     $warehouse_id = WarehouseUtil::idByMarket($order_market);
     $item = $this->Item->find('first', ['contain' => ['ItemAvailabilityTimes'], 'conditions' => ['Item.sku' => $sku, 'ItemAvailabilityTimes.item_availability_id' => 3, 'ItemAvailabilityTimes.ns_warehouse_id' => $warehouse_id, 'ItemAvailabilityTimes.start_date < NOW()', 'OR' => ['ItemAvailabilityTimes.end_date IS NULL', 'ItemAvailabilityTimes.end_date > NOW()']]]);
     if (!empty($item)) {
         $result = ['available' => true];
     } else {
         $result = ['available' => false];
     }
     $this->set(['result' => $result, '_serialize' => ['result']]);
 }
 /**
  * Send a Backorder Notice
  *
  * @param $order
  * @return bool
  */
 private function sendNotice($order)
 {
     if (empty($order['Email']['email'])) {
         $this->out('Valid email not found for order.', 1, Shell::NORMAL);
         return false;
     }
     $locale = $order['User']['user_default_locale'];
     $item = $this->Item->detailsBySku($order['Item']['sku'], $locale, true);
     if (!empty($order['OrderItem']['ns_warehouse_id'])) {
         $wid = $order['OrderItem']['ns_warehouse_id'];
     } else {
         $wid = WarehouseUtil::idByMarket($order['Order']['order_market_id']);
     }
     $restock = $this->ItemAvailabilityTimes->restockDate($order['Item']['sku'], $wid);
     $email_data = ['name' => $order['User']['first_name'] . ' ' . $order['User']['last_name'], 'qty' => $order['OrderItem']['quantity'], 'sku' => $order['Item']['sku'], 'description' => $item['name'], 'restock_date' => $restock];
     /**
      * Send email via queue
      */
     YouniqueEmail::queueEmail($email_data, 'backordered_item', $order['Email']['email'], 'Backorder Notice', 'sendbackorder_email-page', $locale);
     return true;
 }
 /**
  * Process cart change from checkout market switch
  *
  * @param AppController $controller
  * @param $market_id
  * @return bool
  */
 public function changeMarket(AppController $controller, $market_id)
 {
     $this->ShoppingCartItem = ClassRegistry::init('ShoppingCartItem');
     $this->NsWarehouse = ClassRegistry::init('NsWarehouse');
     $this->ShoppingCartItem->session = $controller->Session;
     $cart = $controller->Session->read('shoppingcart');
     $warehouse = (int) WarehouseUtil::idByMarket($market_id);
     $session_w_id = (int) Configure::read('ns_warehouse_id');
     if ($warehouse !== $session_w_id) {
         Configure::write('ns_warehouse_id', $warehouse);
     }
     /**
      * Remove all unavailable items
      */
     foreach ($cart as $key => $item) {
         $sku_unavailable = $this->NsWarehouse->unorderable($item['sku'], $warehouse);
         if ($sku_unavailable) {
             unset($cart[$key]);
         }
         if (!empty($item['options'])) {
             foreach ($item['options'] as $subSku => $subItem) {
                 $sub_unavailable = $this->NsWarehouse->unorderable($subSku, $warehouse, true);
                 if (!empty($subItem) && !empty($subItem['skus'])) {
                     foreach ($subItem['skus'] as $ts => $tsValue) {
                         $sub_sku_unavailable = $this->NsWarehouse->unorderable($ts, $warehouse, true);
                         if ($sub_sku_unavailable) {
                             unset($cart[$key]);
                         }
                     }
                 }
                 if ($sub_unavailable) {
                     unset($cart[$key]);
                 }
             }
         }
     }
     /**
      * Write out modified cart
      */
     $controller->Session->write("shoppingcart", $cart);
     /**
      * Update cart after removals
      */
     $cart_after = $this->afterCart($controller, $cart);
     /**
      * Run Kudos if enabled
      */
     if (isset($controller->Kudos)) {
         $collection = new ComponentCollection();
         $ctrl = new ShoppingcartController($collection);
         $ctrl->request = $controller->request;
         $ctrl->ShoppingCartItem = $this->ShoppingCartItem;
         $ctrl->request->data['bypass'] = true;
         $ctrl->request->data['items'] = $cart_after;
         $ctrl->request->data['market_id'] = $market_id;
         $ctrl->request->params['action'] = 'prices';
         $ctrl->Session = $controller->Session;
         $controller->Kudos->initialize($ctrl);
     }
     /**
      * Run Promos if enabled
      */
     if (isset($controller->Promotional)) {
         $collection = new ComponentCollection();
         $ctrl = new ShoppingcartController($collection);
         $ctrl->request = $controller->request;
         $ctrl->ShoppingCartItem = $this->ShoppingCartItem;
         $ctrl->request->data['items'] = $cart_after;
         $ctrl->request->data['market_id'] = $market_id;
         $ctrl->request->params['action'] = 'prices';
         $ctrl->Session = $controller->Session;
         $controller->Promotional->initialize($ctrl);
         $ctrl->ShoppingCartItem->pruneItems($ctrl->request->data['items'], true, $this->request->data['productcredits']);
     }
     return $this->afterCart($controller, $cart);
 }
Example #6
0
 /**
  * Auto Allocate setting is per market or type
  *
  * @return string
  */
 private function _getAutoAllocate()
 {
     $market_id = $this->shipment['Order']['order_market_id'];
     if (!empty($this->order_warehouse_id)) {
         $wh_id = $this->order_warehouse_id;
     } else {
         if (!empty($this->shipment['Order']['OrderCustomer']['Address']['State']['ns_warehouse_id'])) {
             $wh_id = $this->shipment['Order']['OrderCustomer']['Address']['State']['ns_warehouse_id'];
         } else {
             $wh_id = (int) WarehouseUtil::idByMarket($market_id);
         }
     }
     $allocate_setting = SnapConfig::$allocate_setting[$wh_id];
     // expedited are always on
     if (in_array($this->shipment_class, $this->always_on) || in_array($this->shipment['OrderShipment']['shipment_method'], OrderShipmentMethod::$expedited_shipment_methods)) {
         return $allocate_setting;
     }
     // charms are always off
     if (in_array($this->shipment_class, $this->always_off) || $this->shipment['Order']['order_type_id'] == Order::TYPE_CHARM) {
         return self::SNAP_AUTO_ALLOCATE_OFF;
     }
     // default is the setting that is in the db
     $auto_allocate = Hash::get($this->TraitCountry->find('first', ['conditions' => ['TraitCountry.reference_id' => $market_id, 'TraitCountry.name' => 'auto_allocate']]), 'TraitCountry.value');
     if ($auto_allocate == 1) {
         return $allocate_setting;
     } else {
         return self::SNAP_AUTO_ALLOCATE_OFF;
     }
 }
 /**
  * Get net suite formatted data by shipment
  *
  * @param $shipment
  * @return array
  * @throws NetSuiteException
  */
 protected function backOrderDataByShipment($shipment)
 {
     if (empty($shipment) || empty($shipment['Order']['OrderCustomer']['Address']) || empty($shipment['OrderItem'])) {
         throw new NetSuiteException('No Order Data');
     }
     $ship = $shipment['OrderShipment'];
     $status_id = $shipment['order_shipment_status_id'];
     $order = $shipment['Order'];
     $customer = $order['OrderCustomer'];
     $address = $customer['Address'];
     $phone = $customer['Phone'];
     $items = [];
     /**
      * Get Items
      */
     foreach ($shipment['OrderItem'] as $order_item) {
         /**
          * Half price items
          */
         $half_price_items = $this->CouponPresenterUser->find('count', ['conditions' => ['CouponPresenterUser.redemption_reference_id' => $order_item['id']]]);
         $items[] = ['sku' => $order_item['Item']['sku'], 'quantity' => $order_item['quantity'], 'order_item_id' => $order_item['id'], 'order_shipment_id' => $ship['id'], 'item_id' => $order_item['Item']['id'], 'parent_id' => $order_item['parent_id'], 'price' => $order_item['price'], 'discount' => $order_item['discount'], 'item_type' => $order_item['Item']['item_type_id'], 'total' => $order_item['extended_price'], 'hpi_qty' => (int) $half_price_items, 'item_tax' => $order_item['tax_amount']];
     }
     return ['order_id' => $order['id'], 'order_shipment_id' => $ship['id'], 'order_header' => ['order_id' => $order['id'], 'order_status_id' => $order['order_status_id'], 'user_id' => $order['user_id'], 'presenter_id' => $order['presenter_id'], 'party_id' => $order['Order']['party_id']], 'items' => $items, 'shipment' => ['id' => $ship['id'], 'address1' => $address['address1'], 'address2' => $address['address2'], 'address3' => $address['address3'], 'city' => $address['city'], 'state_id' => $address['state_id'], 'country_id' => $address['country_id'], 'postal_code' => $address['postal_code'], 'first_name' => $customer['first_name'], 'last_name' => $customer['last_name'], 'phone' => $phone['phone'], 'order_shipment_status_id' => $status_id, 'warehouse_id' => WarehouseUtil::idByMarket($order['order_market_id']), 'shipping_method' => OrderShipmentMethod::$shipment_methods[$ship['shipment_method']], 'priority' => '02', 'shipping_class' => null, 'fulfilment_instance' => null]];
 }
Example #8
0
 public function snapFix()
 {
     $this->Order = ClassRegistry::init("Order");
     //          if(isset($this->args[0]))
     //              $order_shipment_ids = $this->args[0];
     //              $shipment_id_string = $this->makesArrayStingForInClaus($order_shipment_ids);
     //          else {
     $shipment_id_string = "8684006";
     //          }
     $sql = "\r\nSELECT\r\n    *\r\nFROM\r\n    orders o\r\n        JOIN\r\n        order_shipments os ON os.order_id = o.id\r\nWHERE\r\n    os.id IN ({$shipment_id_string});\r\n        ";
     $affected_orders = $this->Order->query($sql);
     $count_orders = count($affected_orders);
     $this->out("Total orders: " . $count_orders);
     $ittr = 0;
     foreach ($affected_orders as $order) {
         usleep(500000);
         //sleep for 1/2 a second to slowdown the API push
         try {
             $ittr++;
             $this->out("Left: " . $count_orders - $ittr);
             // query snap for status and existence of the kudo item
             $order_id = $order['o']['id'];
             $shipment_id = $order['os']['id'];
             $market_id = $order['o']['order_market_id'];
             $wh_id = (int) WarehouseUtil::idByMarket($market_id);
             $date = date('c');
             $user_id = $order['o']['user_id'];
             $update_shipment = ["ShipmentId" => $shipment_id, "OrderClass" => "BO", "CustomerId" => $user_id, "DateDueOut" => $date];
             SnapFulfilAPI::call("shipments/{$shipment_id}", $update_shipment, TRUE, $wh_id);
             $this->out("<success>O: {$order_id} - S: {$shipment_id} - Shipment class updated</success>");
             continue;
         } catch (Exception $f) {
             $this->out("<error>O: {$order_id} - S: {$shipment_id} - Update failed. " . $f->getMessage() . "</error>");
             sleep(5);
             continue;
         }
         // add item to order
     }
 }
 public function setUserData($userId)
 {
     App::uses("CustomizeProvider", "Lib");
     $user = $this->User->find('first', array("contain" => array("UserOauth2" => array('order' => 'UserOauth2.primary DESC', 'limit' => 1), "Email" => array("fields" => array("email"))), 'conditions' => array("User.id" => $userId)));
     $sms = $this->Sms->find('first', array('conditions' => array('user_id' => $userId)));
     if (isset($user['UserOauth2'][0])) {
         $user['UserOauth2'] = $user['UserOauth2'][0];
     }
     $profile_imgs = CustomizeProvider::getProviderImages($user['UserOauth2']['provider'], $user['UserOauth2']['imageUrl'], $user['User']['facebook_id']);
     $this->Session->write("user_id", $userId);
     $this->Session->write("user", array("id" => $userId, "first_name" => $user['User']['first_name'], "last_name" => $user['User']['last_name'], "facebook_id" => !empty($user['UserOauth2']['uid']) ? $user['UserOauth2']['uid'] : '', "img" => $profile_imgs['img_150'], "language" => $user['User']['user_default_locale'], "primary_email" => $user['User']['email'], "smsoptin" => $sms['Sms']['smsoptin'], "userOauth" => !empty($user['UserOauth2']['uid']) ? "true" : ""));
     $this->Session->write('Config.language', $user['User']['user_default_locale']);
     if (empty($user['User']['facebook_id']) && !empty($user['UserOauth2']['uid'])) {
         //$this->User->read(null, $userId);
         $this->User->id = $userId;
         $this->User->save(array('facebook_id' => $user['UserOauth2']['uid']));
     }
     $presenterSequenceId = $this->Presenter->isUserSignedup($userId);
     if (!empty($presenterSequenceId)) {
         $this->Session->write("presenter_id", $presenterSequenceId);
         $presenter = $this->Presenter->presenterFromSequenceId($presenterSequenceId);
         $site = $this->PresenterSite->findByPresenterId($presenter['Presenter']['id']);
         $this->site_url = $site['PresenterSite']['site_url'];
         // Set presenter market
         if (!empty($presenter['Presenter']['market_id'])) {
             $this->Session->write('market_id', $presenter['Presenter']['market_id']);
             $this->Session->write("warehouse", WarehouseUtil::idByMarket((int) $presenter['Presenter']['market_id']));
         }
         if (!empty($presenter['Presenter']['default_locale'])) {
             $this->Session->write('Config.language', $presenter['Presenter']['default_locale']);
         }
     }
 }
Example #10
0
 public function checkCancelledOrders()
 {
     $email = "*****@*****.**";
     //			$email = "*****@*****.**";
     $cancel_status = 91;
     $cancelled_orders = $this->Order->find('all', ['conditions' => ['order_status_id' => Order::STATUS_CANCELLED, 'date_completed >= DATE_SUB( NOW(), INTERVAL 24 HOUR)'], 'contain' => ['OrderShipment' => ['OrderItem']]]);
     if (empty($cancelled_orders)) {
         $this->out("No cancelled orders found");
         return;
     }
     $this->out("Found orders :" . count($cancelled_orders));
     foreach ($cancelled_orders as $order) {
         $this->hr();
         $order_id = $order['Order']['id'];
         $this->out("Checking cancelled order: " . $order_id, 1, Shell::VERBOSE);
         foreach ($order['OrderShipment'] as $shipment) {
             $shipment_id = $shipment['id'];
             $this->out("Shipment id: " . $shipment_id, 1, Shell::VERBOSE);
             //					$continue = $this->in("Continue to check Snap?", ['y', 'n'], 'y');
             //					if($continue == 'n')
             //						continue;
             try {
                 if (!empty($shipment['OrderItem'][0]['ns_warehouse_id'])) {
                     $wh_id = $shipment['OrderItem'][0]['ns_warehouse_id'];
                 } else {
                     $wh_id = (int) WarehouseUtil::idByMarket($order['Order']['order_market_id']);
                 }
                 $response = SnapFulfilAPI::call("shipments/{$shipment_id}", NULL, FALSE, $wh_id);
                 //						$this->out(var_export($response, true));
                 if ($response && $response->Stage != 90 && $response->Stage != 91) {
                     $this->out("Stage: " . $response->Stage);
                     // send notifications to people that it needs to be cancelled.
                     $subject = 'Cancelled order in WMS. Shipment id: ' . $shipment_id;
                     $message = "Cancel order: {$order_id}<br />" . "Shipment id: {$shipment_id}<br />" . "Customer: {$response->CustomerName}<br />" . "WMS instance: {$wh_id}";
                     $update_shipment_status_params = array("ShipmentId" => $shipment_id, "Status" => $cancel_status);
                     //							$do_cancel = $this->in("Cancel shipment in Snap?", ['y', 'n'], 'y');
                     //							if($do_cancel == 'n')
                     //								continue;
                     try {
                         SnapFulfilAPI::call("ShipmentStatus/{$shipment_id}", $update_shipment_status_params, TRUE, $wh_id);
                     } catch (Exception $e) {
                         $this->_sendEmail($email, $subject, $message);
                     }
                     $this->out("<info>Shipment cancelled Snap</info>", 1, Shell::VERBOSE);
                     $this->out("<info>Email send</info>", 1, Shell::VERBOSE);
                 }
             } catch (Exception $e) {
                 // Order should not be in Snap
                 $this->out("<warning>Shipment not in Snap</warning>", 1, Shell::VERBOSE);
                 continue;
             }
         }
     }
     $this->out("All done.");
 }
 /**
  * Warehouse selection logic
  *
  * @param $market_id
  * @return int
  */
 private function getWarehouseForOrder($market_id)
 {
     return (int) WarehouseUtil::idByMarket($market_id);
 }
Example #12
0
 public function beforeFilter()
 {
     if ($this->request->header("X-YNQ-NOSESSION") == true) {
         $this->Session = $this->Components->load("NullSession");
         //Don't want to keep this session around if it is an internal call
     } else {
         $this->Session = $this->Components->load("Session");
     }
     /** Load Kudos */
     if (YOUNIQUE_TESTSERVER == true) {
         $kudos_date = strtotime($this->SystemSetting->getSystemSetting("kudos_date", time()));
     } else {
         $kudos_date = time();
     }
     $settings = ['current_month' => date('n', $kudos_date)];
     $this->Kudos = $this->Components->load(date('F', $kudos_date), $settings);
     $this->Kudos->initialize($this);
     /** End Load Kudos */
     $this->layout = '';
     Configure::write("market_id", 1);
     if ($this->Session->check("market_id")) {
         Configure::write("market_id", (int) $this->Session->read("market_id"));
     }
     if (($activeMarkets = Cache::read('active_markets', 'medium')) === false) {
         $activeMarkets = $this->Market->getActiveMarkets();
     }
     if (!empty($_REQUEST['market_id']) && array_key_exists($_REQUEST['market_id'], $activeMarkets)) {
         Configure::write("market_id", (int) $_REQUEST['market_id']);
     }
     /**
      * Get Warehouse
      */
     $wid = WarehouseUtil::idByMarket(Configure::read('market_id'));
     Configure::write('ns_warehouse_id', $wid);
     if (!empty($_REQUEST['callback'])) {
         $this->set('callback', $_REQUEST['callback']);
         $this->view = "/jsonp";
         $this->RequestHandler->respondAs('json');
     } else {
         $this->view = "/json";
         $this->RequestHandler->respondAs('json');
     }
     if (isset($this->params['prefix']) && $this->params['prefix'] == 'admin') {
         try {
             $this->requireAdminRights();
         } catch (NotFoundException $e) {
             $this->sendError(401, "Not authorized");
             $this->render($this->view);
             $this->response->send();
             $this->_stop();
         }
     }
     $this->userId = $this->Session->read("user_id");
     if (!empty($this->userId)) {
         /**
          * Admins can view inactive presenters
          */
         if ($this->Session->check("admin_override")) {
             $this->presenterId = $this->Presenter->presenterIdFromUserId($this->userId, false);
         } else {
             $this->presenterId = $this->Presenter->presenterIdFromUserId($this->userId);
         }
     }
     $this->disableCache();
     return parent::beforeFilter();
 }
 /**
  * Shopping cart Purchase 
  *
  * Validates order details, creates order, processes payment
  * and queues for emails and post order process.
  * 
  */
 public function purchase()
 {
     if ($this->request->data['market_id'] == 7 || $this->request->data['market_id'] == 8 || $this->request->data['market_id'] == 9) {
         $this->request->data['state'] = null;
     }
     $this->Presenter->id = $this->data['sponsor_id'];
     if ($this->Session->check('activate_link')) {
         $this->Session->delete('activate_link');
     }
     if ($this->Session->check("user_id")) {
         $userId = $this->Session->read("user_id");
     } else {
         if (!empty($this->request->data['email'])) {
             $data = $this->User->find('first', array('conditions' => array("User.email" => $this->request->data['email']), 'order' => array('User.id DESC')));
             $userId = $data['User']['id'];
         } else {
             $userId = null;
         }
     }
     $presenter = $this->Presenter->loadBasicDetails();
     if (!empty($presenter)) {
         $promoterId = 0;
         $presenterId = $presenter['Presenter']['id'];
         if (isset($this->request->data['personal_consumption']) && $this->request->data['personal_consumption']) {
             $recargo_exempt = true;
         } else {
             $recargo_exempt = Configure::read("market_id") == Market::MARKET_SPAIN ? $this->checkRecargoTaxStatus($this->request->data, $presenter['Presenter']['user_id'], $userId) : true;
         }
     } else {
         $promoterId = 0;
         $presenterId = 0;
         $recargo_exempt = true;
     }
     $validation_errors = array();
     $vertex_success = $this->data['vertex_success'];
     if ($this->data['processor'] == OrderPaymentProcessor::PROCESSOR_CYBERSOURCE) {
         if (!strlen($this->data['billingCardholderFirstName']) || !strlen($this->data['billingCardholderLastName'])) {
             $validation_errors['cardHolder'] = array(DruniqueAPIUtil::content('name required', $this->DruniqueAPI->page_data));
         }
         $credit_card_number = $this->data['cardNum'];
         if (!strlen($this->data['cardNum'])) {
             $validation_errors['cardNum'] = array(DruniqueAPIUtil::content('credit card required', $this->DruniqueAPI->page_data));
         } else {
             $credit_card_number = preg_replace('/\\D/', '', $credit_card_number);
             if (!preg_match('/\\d{13,16}/', $credit_card_number) || !$this->luhn_check($credit_card_number)) {
                 $validation_errors['cardNum'] = array(DruniqueAPIUtil::content('credit card invalid', $this->DruniqueAPI->page_data));
             }
         }
         $credit_card_code = preg_replace('/\\D/', '', $this->data['cardCode']);
         if (!strlen($credit_card_code) || strlen($credit_card_code) < 3 || strlen($credit_card_code) > 4) {
             $validation_errors['cardCode'] = array(DruniqueAPIUtil::content('card code invalid', $this->DruniqueAPI->page_data));
         }
         if (!strlen($this->data['cardExpMonth']) || !strlen($this->data['cardExpYear'])) {
             $validation_errors['cardExpYear'] = array(DruniqueAPIUtil::content('expiration date required', $this->DruniqueAPI->page_data));
         }
         switch ($this->data['sameAsShipping']) {
             case "on":
                 if (!strlen($this->data['postal_code'])) {
                     $validation_errors['postal_code'] = array(DruniqueAPIUtil::content('billing postal code required', $this->DruniqueAPI->page_data));
                 }
                 break;
             default:
                 //check for not empty
                 if (!strlen($this->data['billingState']) && $this->data['billing_market_id'] != Market::MARKET_UNITED_KINGDOM) {
                     $validation_errors['billingState'] = array(DruniqueAPIUtil::content('billing state required', $this->DruniqueAPI->page_data));
                 }
                 if (!strlen($this->data['billingZip'])) {
                     $validation_errors['billingZip'] = array(DruniqueAPIUtil::content('billing postal code required', $this->DruniqueAPI->page_data));
                 }
                 if (!strlen($this->data['billingEmail'])) {
                     $validation_errors['billingEmail'] = array(DruniqueAPIUtil::content('billing email required', $this->DruniqueAPI->page_data));
                 }
                 if (!strlen($this->data['billingAddress1'])) {
                     $validation_errors['billingAddress1'] = array(DruniqueAPIUtil::content('billing address required', $this->DruniqueAPI->page_data));
                 }
                 $this->Email->set('email', $this->data['billingEmail']);
                 if (!$this->Email->validates(array('fieldList' => array('email')))) {
                     $validation_errors['billingEmail'] = array(DruniqueAPIUtil::content('valid billing email address', $this->DruniqueAPI->page_data));
                 }
                 break;
         }
         if (!empty($this->request->data['cardExpMonth'])) {
             $this->request->data['cardExp'] = $this->request->data['cardExpMonth'] . "/" . $this->request->data['cardExpYear'];
         }
         if (!empty($validation_errors)) {
             $this->sendError(500, $validation_errors);
             return;
         }
     }
     if (empty($presenterId)) {
         $this->sendError(500, array("process_error" => array(DruniqueAPIUtil::content('presenter for purchase', $this->DruniqueAPI->page_data))));
         return;
     }
     /**
      * Return error when cart is empty
      */
     if (empty($this->request->data['items'])) {
         $this->sendError(500, ['process_error' => [DruniqueAPIUtil::content('no items in cart', $this->DruniqueAPI->page_data)]]);
         return;
     }
     $itemIds = $this->request->data['items'];
     $party = $this->Party->partyFromId($this->data['party_id'], $presenterId, true);
     if (!empty($party)) {
         $partyId = $party['Party']['id'];
     } else {
         $partyId = 0;
     }
     /**
      * @var Money
      */
     $productCredits = null;
     if (!empty($this->request->data['productcredits'])) {
         $productCredits = Money::fromPennies((int) $this->request->data['productcredits']);
     }
     $commission_total = null;
     //determine if user is a presenter
     $is_presenter = $this->Presenter->presenterFromUserId($userId);
     if (!empty($is_presenter)) {
         $commission_total = $this->request->data['commissionable_total'];
     }
     $country = $this->Country->getByMarketId(Configure::read("market_id"));
     if (!empty($this->request->data['state'])) {
         $state_id = (int) $this->Address->State->search($this->request->data['state']);
     } else {
         $state_id = null;
     }
     $first_last = array();
     if (empty($this->request->data['first_name'])) {
         $first_last['first_name'][0] = array(DruniqueAPIUtil::content('valid First Name', $this->DruniqueAPI->page_data));
     }
     if (Configure::read("market_id") != Market::MARKET_MEXICO) {
         if (empty($this->request->data['last_name'])) {
             $first_last['last_name'][0] = array(DruniqueAPIUtil::content('valid Last Name', $this->DruniqueAPI->page_data));
         }
     }
     @($address = array("first_name" => $this->request->data['first_name'], "last_name" => $this->request->data['last_name'], "address1" => $this->request->data['address1'], "address2" => $this->request->data['address2'], "address3" => $this->request->data['address3'], "city" => $this->request->data['city'], "state_id" => $state_id, "state" => $this->request->data['state'], "country_id" => $country['Country']['id'], "postal_code" => strtoupper($this->request->data['postal_code']), "phone" => $this->request->data['phone']));
     $email = ['email' => trim($this->request->data['email'])];
     $hasDailySpecial = false;
     $hasConventionTicket = false;
     $this->Address->set($address);
     $this->Email->set($email);
     /**
      * Currently us market does not require phone number
      */
     if (Configure::read("market_id") != Market::MARKET_USA) {
         $this->Phone->set(['phone' => $this->request->data['phone']]);
         $phone_validation = true;
         //$this->Phone->validates();
     } else {
         $phone_validation = true;
     }
     if (!$this->Address->validates() || !$this->Email->validates() || !$phone_validation || !empty($first_last)) {
         $address_error = $this->Address->validationErrors;
         foreach ($address_error as $key => $error_details) {
             if ($key == 'first_name') {
                 $address_error[$key][0] = DruniqueAPIUtil::content('valid First Name', $this->DruniqueAPI->page_data);
             } elseif ($key == 'last_name') {
                 $address_error[$key][0] = DruniqueAPIUtil::content('valid Last Name', $this->DruniqueAPI->page_data);
             } elseif ($key == 'address1') {
                 $address_error[$key][0] = DruniqueAPIUtil::content('valid Address', $this->DruniqueAPI->page_data);
             } elseif ($key == 'city') {
                 $address_error[$key][0] = DruniqueAPIUtil::content('valid City', $this->DruniqueAPI->page_data);
             } elseif ($key == 'country_id') {
                 $address_error[$key][0] = DruniqueAPIUtil::content('Check your Country', $this->DruniqueAPI->page_data);
             } elseif ($key == 'postal_code') {
                 $address_error[$key][0] = DruniqueAPIUtil::content('valid Postal Code', $this->DruniqueAPI->page_data);
             } elseif ($key == 'state_id') {
                 $address_error[$key][0] = DruniqueAPIUtil::content('Check your State', $this->DruniqueAPI->page_data);
             }
         }
         if (!$this->Email->validates()) {
             $email_validation_errors = $this->Email->validationErrors;
             foreach ($email_validation_errors as $key => $error_details) {
                 if ($key == 'email_address') {
                     $email_validation_errors[$key][0] = DruniqueAPIUtil::content('valid email address', $this->DruniqueAPI->page_data);
                 }
             }
         }
         if (Configure::read("market_id") != Market::MARKET_USA) {
             $phone_error = $this->Phone->validationErrors;
             foreach ($phone_error as $key => $error_details) {
                 if ($key == 'phone') {
                     $phone_error[$key][0] = DruniqueAPIUtil::content('valid phone number', $this->DruniqueAPI->page_data);
                 }
             }
         } else {
             $phone_error = [];
         }
         $this->sendError(500, array_merge($address_error, $email_validation_errors, $phone_error, $first_last));
         return;
     } else {
         $address['email_address'] = $email['email'];
         foreach ($itemIds as &$item) {
             if (strpos($item['sku'], "US-3001-") === 0) {
                 $hasDailySpecial = true;
             }
             if (empty($item['coupons'])) {
                 continue;
             }
             $couponIds = $item['coupons'];
             unset($item['coupons']);
             $coupons = $this->User->CouponPresenterUser->availableCouponsById($presenterId, $userId, $couponIds);
             foreach ($coupons as $coupon) {
                 $item['coupons'][$coupon['id']] = array("discount_percentage" => $coupon['discount_percentage'], "discount_flat" => $coupon['discount_flat'], "name" => $coupon['name']);
             }
         }
         $toUseCoupons = array();
         foreach ($this->User->CouponPresenterUser->availableCouponsById($presenterId, $userId, $this->ShoppingCartItem->getCoupons()) as $coupon) {
             $toUseCoupons[$coupon['id']] = $coupon;
         }
         $hasdonation = $this->data['hasdonation'] == 'true' ? TRUE : FALSE;
         /**
          * Warehouse selection logic
          */
         $whm_id = $this->Country->getMarketFromCountryId($address['country_id']);
         if (!empty($address['state_id'])) {
             $warehouse = $this->Address->State->warehouse($address['state_id']);
         }
         if (empty($warehouse)) {
             $warehouse = (int) WarehouseUtil::idByMarket($whm_id);
         }
         /**
          * Catch Order Validation error
          */
         try {
             $this->Order->recargo_exempt = $recargo_exempt;
             $prices = $this->Order->createOrder($promoterId, $presenterId, $userId, $partyId, $itemIds, $address, Order::TYPE_PRODUCT, $productCredits, $toUseCoupons, FALSE, $is_presenter, $hasdonation, $warehouse);
         } catch (OrderValidationException $e) {
             $this->sendError(500, [DruniqueAPIUtil::content($e->getMessage(), $this->DruniqueAPI->page_data)]);
             return;
         }
         if ($prices !== false) {
             foreach ($prices['total']['usedCoupons'] as $couponId => $details) {
                 $this->User->CouponPresenterUser->id = $couponId;
                 $this->User->CouponPresenterUser->save(array("date_redeemed" => date('Y-m-d H:i:s'), "redemption_reference_id" => $details['reference_id'], "redemption_amount" => (string) $details['amount']));
             }
             $order = $this->Order->loadDisplayDetails();
             if ($vertex_success == 'false') {
                 $this->ApiAudit = ClassRegistry::init('ApiAudit');
                 $api_data = ['reference_name' => get_class(), 'reference_id' => 0, 'source' => __FILE__ . ' ' . __LINE__, 'destination' => 'vertex', 'sent' => json_encode($order), 'received' => 'vertex error', 'notes' => 'Vertex fail'];
                 $this->ApiAudit->clear();
                 $this->ApiAudit->create($api_data);
                 $this->ApiAudit->save();
             }
             $shipped_by_dates = $this->Order->estimatedShippingDates(date('Y-m-d H:i:s'));
             $ship_type = null;
             $expedited_date = null;
             switch ($this->data['ship_type']) {
                 case 'twoday':
                     $ship_type = 'twoday';
                     $expedited_date = $shipped_by_dates['TwoDay'];
                     break;
                 case 'ground':
                     $ship_type = 'ground';
                     $expedited_date = $shipped_by_dates['Ground'];
                     break;
                 default:
             }
             //I now need to fund this order...Possibly from multiple payment sources.
             $payments = array();
             /** @noinspection PhpUndefinedMethodInspection */
             if ($prices["total"]['productcredits']->isGreaterThanZero()) {
                 $payments[] = array("type" => "ledger", "presenter_id" => $presenterId, "user_id" => $userId, "amount" => $prices["total"]['productcredits']);
             }
             if ($this->data['hasdonation'] == 'true') {
                 $charge = $prices['total']['charge_w_donation'];
                 $donation = $prices['total']['donation'];
             } else {
                 $charge = $prices['total']['charge'];
                 $donation = 0.0;
             }
             $ip = array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
             /**
              * Prepare Payments
              */
             if (!empty($this->request->data['bankcode'])) {
                 $payments[] = $this->Payment->preparePayments(['request' => $this->request, 'session' => $this->Session->id(), 'country' => $country, 'address' => $address, 'amount' => $charge, 'party' => $partyId, 'order' => $order, 'ip' => $ip, 'bankcode' => $this->request->data['bankcode']]);
             } else {
                 $payments[] = $this->Payment->preparePayments(['request' => $this->request, 'session' => $this->Session->id(), 'country' => $country, 'address' => $address, 'amount' => $charge, 'party' => $partyId, 'order' => $order, 'ip' => $ip]);
             }
             /**
              * Process Payment
              */
             $paymentResult = $this->Payment->processOrderPayments($order['Order']['id'], $payments);
             /**
              * Finalize Order
              */
             $this->Order->finalize($paymentResult, $donation);
             /**
              * Payment Failed
              */
             if ($paymentResult['success'] !== true) {
                 foreach ($prices['total']['usedCoupons'] as $couponId => $details) {
                     $this->User->CouponPresenterUser->id = $couponId;
                     $this->User->CouponPresenterUser->save(["date_redeemed" => null, "redemption_reference_id" => null, "redemption_amount" => null]);
                 }
                 /**
                  * Cancel Payments
                  */
                 foreach ($payments as $payment) {
                     $this->Payment->cancel($payment['processor'], $order['Order']['order_market_id'], $order['Order']['id']);
                 }
                 $this->sendError(500, ['process_error' => [$paymentResult['error']]]);
                 return;
             } else {
                 if ($hasDailySpecial) {
                     $this->ShoppingCartItem->usedDailySpecial();
                 }
                 // Back Order Start
                 foreach ($order['OrderCustomer'] as $customerKey => $customer) {
                     foreach ($customer['OrderItem'] as $itemKey => $item) {
                         if (!empty($item['backorder_start'])) {
                             $order['OrderCustomer'][$customerKey]['BackOrderItem'][] = $item;
                         }
                     }
                 }
                 // Back Order End
                 $ycash = $productCredits ? number_format((int) $this->request->data['productcredits'] / 100, 2, '.', ',') : null;
                 $credit_card_payments = null;
                 $paypal = null;
                 if (empty($order['Party']['Hostess']) && !empty($order['Party']['ContactBook'])) {
                     $hostess = $order['Party']['ContactBook']['first_name'] . " " . $order['Party']['ContactBook']['last_name'];
                 } else {
                     $hostess = $order['Party']['Hostess']['first_name'] . " " . $order['Party']['Hostess']['last_name'];
                 }
                 $royalty_earned = $this->RoyaltiesEarned->getOrderCommission($order['Order']['id']);
                 $orderDetails = array("order" => $order, "ship_type" => $ship_type, "expedited_date" => $expedited_date, "presenter" => $presenter, "user_id" => $order['User']['id'], "sponsor" => $presenter['User']['first_name'] . " " . $presenter['User']['last_name'], "royalty_earned" => $royalty_earned, "name" => $address['first_name'] . " " . $address['last_name'], "current_locale" => $this->Session->read('Config.language'), "payments" => array("ycash" => $ycash, "creditcard" => $credit_card_payments, "paypal" => $paypal, "commission" => $commission_total, "hasdonation" => $this->data['hasdonation'], "orderwdonation" => $prices['total']['charge_w_donation'], "donation" => $prices['total']['donation'], "taxTypes" => $order['Order']['order_market_id'] == Market::MARKET_CANADA ? $prices['total']['taxes_by_type'] : array(), "recargo" => $order['Order']['order_market_id'] == Market::MARKET_SPAIN ? $prices['total']['recargo_tax']->display : '0.00'), "hasConventionTicket" => $hasConventionTicket, "hostess" => $hostess);
                 $user = $this->Session->read('user');
                 $tolkien = "";
                 if (isset($user['guest_checkout']) && $user['guest_checkout'] == TRUE) {
                     $tolkien = $this->User->setResetToken($user['id'], $user['primary_email']);
                     $orderDetails['tolkien'] = $tolkien;
                     $orderDetails['site_url'] = $presenter['PresenterSite']['site_url'];
                 }
                 if ($order['Order']['order_market_id'] == Market::MARKET_CANADA) {
                     $canda_tax_breakout = json_encode($prices['total']['taxes_by_type']);
                     $this->Order->setDynamicData($order['Order']['id'], 'canada_tax', $canda_tax_breakout);
                 }
                 if ($order['Order']['order_market_id'] == Market::MARKET_FRANCE) {
                     //grab what the customer paid with
                     $orderDetails['paid_with'] = $paymentResult['payments']['0']['paid_with'];
                 }
                 if ($this->request->data['processor'] == OrderPaymentProcessor::PROCESSOR_WORLDPAY_OXXO) {
                     $orderDetails['pending_payment'] = true;
                 }
                 //cakelog::debug('$orderDetails = '.var_export($orderDetails,true));
                 /**
                  * Customer Email
                  */
                 YouniqueEmail::queueEmail($orderDetails, 'en_us_order', $address['email_address'], 'Younique Order Confirmation', 'purchase-page', $orderDetails['current_locale']);
                 /**
                  * Sponsor Email
                  */
                 YouniqueEmail::queueEmail($orderDetails, 'en_us_sponsor_order', $presenter['User']['Email']['email'], 'Younique Order Confirmation', 'purchase-page', $presenter['User']['user_default_locale']);
                 /**
                  * Queue for after purchase order modifications
                  */
                 if (!$this->Order->noQueueFlagged($order['Order']['id'])) {
                     $this->Order->queueOrder($order['Order']['id']);
                 }
                 if ($order['Order']['order_market_id'] == Market::MARKET_CANADA) {
                     $canda_tax_breakout = json_encode($prices['total']['taxes_by_type']);
                     $this->Order->setDynamicData($order['Order']['id'], 'canada_tax', $canda_tax_breakout);
                 }
                 //get the items in the order
                 $order_items = array();
                 foreach ($order['OrderCustomer']['OrderItem'] as $oi) {
                     $order_items[] = array('sku' => $oi['Item']['sku'], 'name' => $oi['Item']['name'], 'price' => $oi['price'], 'qty' => $oi['quantity'], 'subtotal' => $oi['extended_price'], 'originalSubtotal' => $oi['discount'] + $oi['extended_price'], 'display_name' => $oi['Item']['ItemContent']['display_name'], 'tax_type' => $this->Item->getTaxTypeName($oi['Item']['id']));
                 }
                 $shipping = Money::fromString($order['Order']['shippingtotal']);
                 // Send Invoice to Vertex for tax purposes
                 $this->Order->create_invoice($address, $order['Order']['order_market_id'], $order_items, $order['Order']['id'], $userId, $this->Session->check('last_quote_date') ? $this->Session->read('last_quote_date') : date(Y - m - d), $shipping);
                 $this->Session->write('order.id', $this->Order->id);
                 $this->Session->write('order.user_id', $order['Order']['user_id']);
                 $countPayment = count($paymentResult['payments']);
                 $redirect = false;
                 for ($i = 0; $i < $countPayment; $i++) {
                     if (!empty($paymentResult['payments'][$i]['redirect'])) {
                         $redirect = true;
                         $redirect_value = $paymentResult['payments'][$i]['transaction_id'];
                     }
                 }
                 if ($redirect == true) {
                     $this->ShoppingCartItem->clear();
                     $this->sendSuccess(['redirect' => $redirect_value]);
                 } else {
                     $this->sendSuccess(["id" => $this->Order->id, 'subtotal' => $order['Order']['subtotal'], 'tax' => $order['Order']['taxtotal'], 'shipping' => $order['Order']['shippingtotal'], 'city' => $this->request->data['city'], 'state' => $this->request->data['state'], 'country' => 'USA', 'items' => $order_items, 'access_token' => $tolkien]);
                 }
             }
         } else {
             $this->sendError(500, array("process_error" => array(DruniqueAPIUtil::content('cannot create order', $this->DruniqueAPI->page_data))));
         }
     }
 }
 /**
  * Execute Promotion Awards for 2016 rules
  *
  * @return bool
  */
 public function execute()
 {
     $promotion_id = 3;
     $winners = $this->PresenterPromotionPoints->find('all', ['fields' => ['presenter_id', 'SUM(value) as point_total'], 'conditions' => ['promotion_id' => $promotion_id], 'group' => "presenter_id having SUM(value) >= 10000", 'order' => "SUM(value) desc"]);
     foreach ($winners as $presenter) {
         $this->hr();
         $awards = [];
         $presenter_id = $presenter['PresenterPromotionPoints']['presenter_id'];
         $points = $presenter[0]['point_total'];
         $this->Presenter->clear();
         $this->Presenter->id = $presenter_id;
         $awarded = $this->PresenterPromotionAward->find('all', ['conditions' => ['promotion_id' => $promotion_id, 'presenter_id' => $presenter_id]]);
         foreach ($awarded as $award) {
             $awards[] = $award['PresenterPromotionAward']['award'];
         }
         unset($award);
         $presenter = $this->Presenter->loadBasicDetails();
         $presenter_market_id = $presenter['Presenter']['market_id'];
         $presenter_user_id = $presenter['Presenter']['user_id'];
         $presenter_display = $presenter['User']['first_name'] . " " . $presenter['User']['last_name'] . " " . $presenter['Presenter']['presenter_sequence_id'];
         $date = new DateTime();
         $date_display = $date->format('Y-m');
         $this->out("<info>Presenter {$presenter_display} ({$presenter_id}) - Points: {$points}</info>");
         // get trunk
         if (!in_array('level3', $awards)) {
             if ($points >= 20000) {
                 $level_name = "Level3";
                 $level = "level3";
                 $this->out("-- Adding award for {$level_name}");
                 $sku = "US-61006-01";
                 $order_type = Order::TYPE_PRODUCT;
                 $ship_to = ["first_name" => $presenter['User']['first_name'], "last_name" => $presenter['User']['last_name'], "address1" => $presenter['User']['ShippingAddress']['address1'], "address2" => $presenter['User']['ShippingAddress']['address2'], "address3" => $presenter['User']['ShippingAddress']['address3'], "city" => $presenter['User']['ShippingAddress']['city'], "state_id" => $presenter['User']['ShippingAddress']['state_id'], "postal_code" => $presenter['User']['ShippingAddress']['postal_code'], "country_id" => $presenter['User']['ShippingAddress']['country_id'], "email_address" => $presenter['email']['email']];
                 $qty = 1;
                 $items = [['qty' => $qty, 'sku' => $sku]];
                 $this->Order->clear();
                 $this->Order->createOrder(0, $presenter_id, $presenter['Presenter']['user_id'], 0, $items, $ship_to, $order_type, NULL, [], TRUE, TRUE, FALSE, WarehouseUtil::idByMarket($presenter['Presenter']['market_id']));
                 $this->Order->finalize(array('success' => TRUE, 'payments' => []));
                 $new_order_id = $this->Order->id;
                 $this->out("Trunk Order Id: " . $new_order_id);
                 $new_order_id = $this->Order->id;
                 // Set Shipment Method
                 $this->Order->queueOrder();
                 $this->PresenterPromotionAward->create(['presenter_id' => $presenter_id, 'award' => $level, 'promotion_id' => $promotion_id]);
                 $this->PresenterPromotionAward->save();
                 $this->UserNote->clear();
                 $this->UserNote->save(['user_id' => $presenter_user_id, 'note' => "Trunk order placed for Incentive Trip {$level_name} Award", 'reference_type' => '', 'reference_id' => '', 'user_note_status' => 'normal', 'admin_user_id' => 584]);
                 $this->out("Added trunk order({$new_order_id}) for Incentive Trip {$level_name} Award");
             }
         } else {
             $this->out("<warning>Already got award for Level3</warning>");
         }
         // get 75$ ycash
         if (!in_array('level2', $awards)) {
             if ($points >= 15000) {
                 $level_name = "Level2";
                 $level = "level2";
                 $this->out("-- Adding award for {$level_name}");
                 $ycash = [1 => 75, 2 => 82.5, 3 => 86.25, 4 => 104.25, 5 => 48.75, 6 => 975, 7 => 63.75, 8 => 63.75, 9 => 63.75];
                 $amount = $ycash[$presenter_market_id];
                 $this->ProductCredit->credit(ProductCredit::METHOD_SYSTEM, ProductCredit::TYPE_CONCESSION, $presenter_market_id, $presenter_id, $presenter_user_id, Money::fromString($ycash[$presenter_market_id]), "Incentive Trip {$level_name} Award {$date_display}", 0);
                 $this->out("{$level_name} Ycash paid: {$amount} to Presenter: {$presenter_display}");
                 $this->PresenterPromotionAward->create(['presenter_id' => $presenter_id, 'award' => $level, 'promotion_id' => $promotion_id]);
                 $this->PresenterPromotionAward->save();
                 //add user note
                 $this->UserNote->clear();
                 $this->UserNote->save(['user_id' => $presenter_user_id, 'note' => "Ycash ({$amount}) added for Incentive Trip {$level_name} Award", 'reference_type' => '', 'reference_id' => '', 'user_note_status' => 'normal', 'admin_user_id' => 584]);
             }
         } else {
             $this->out("<warning>Already got award for Level2</warning>");
         }
         // get 25$ ycash
         if (!in_array('level1', $awards)) {
             if ($points >= 10000) {
                 $level_name = "Level1";
                 $level = "level1";
                 $this->out("-- Adding award for {$level_name}");
                 $ycash = [1 => 25, 2 => 27.5, 3 => 28.75, 4 => 34.75, 5 => 16.25, 6 => 325, 7 => 21.25, 8 => 21.25, 9 => 21.25];
                 $amount = $ycash[$presenter_market_id];
                 $this->ProductCredit->credit(ProductCredit::METHOD_SYSTEM, ProductCredit::TYPE_CONCESSION, $presenter_market_id, $presenter_id, $presenter_user_id, Money::fromString($ycash[$presenter_market_id]), "Incentive Trip {$level_name} Award {$date_display}", 0);
                 $this->out("{$level_name} Ycash paid: {$amount} to Presenter: {$presenter_display}");
                 $this->PresenterPromotionAward->create(['presenter_id' => $presenter_id, 'award' => $level, 'promotion_id' => $promotion_id]);
                 $this->PresenterPromotionAward->save();
                 //add user note
                 $this->UserNote->clear();
                 $this->UserNote->save(['user_id' => $presenter_user_id, 'note' => "Ycash ({$amount}) added for Incentive Trip {$level_name} Award", 'reference_type' => '', 'reference_id' => '', 'user_note_status' => 'normal', 'admin_user_id' => 584]);
             }
         } else {
             $this->out("<warning>Already got award for Level1</warning>");
         }
     }
 }
 public function admin_getNetsuiteData()
 {
     $result = [];
     $result['meta'] = [];
     $warehouse_names = [];
     $result['meta']['market'] = $this->Market->find('list');
     $result['meta']['status'] = $this->OrderShipmentStatus->find('list');
     //Hash::extract($this->OrderShipmentStatus->find('all'), '{n}.OrderShipmentStatus');
     $result['meta']['status'][9] = '*Order Closed';
     $result['meta']['status'][10] = '*In snap';
     $result['meta']['status'][11] = '*Backorder reset';
     $result['meta']['status'][12] = '*Has replacement';
     $result['meta']['status'][13] = '*Prekit reset';
     $result['meta']['status'][0] = 'No Status';
     $result['total_open'] = $this->Order->find('count', ['conditions' => ['order_status_id' => [Order::STATUS_ENTERED, Order::STATUS_PROCESSING]]]);
     $result['not_in_ns'] = $this->Order->notInNetSuite(true);
     $result['no_ship_method'] = $this->Order->noShipmentMethod(true);
     $result['compliance_hold'] = $this->Order->complianceHold(true);
     $result['ns_error_import'] = $this->Order->find('count', ['conditions' => ['order_status_id' => Order::STATUS_ENTERED, 'secondary_order_status_id' => Order::SECONDARY_NETSUITE_ERROR_SUBMIT]]);
     $result['ns_error_stale'] = $this->Order->staleNetSuite(false, true);
     //            $result['ns_backorder']    = $this->Order->staleNetSuite(true,true);
     $result['ns_error_other'] = $this->Order->find('count', ['conditions' => ['order_status_id' => Order::STATUS_ENTERED, 'secondary_order_status_id' => Order::SECONDARY_NETSUITE_ERROR_OTHER]]);
     $in_snap = $this->Order->find('all', ['fields' => ['order_market_id', 'count(id) as qty'], 'conditions' => ['order_status_id' => Order::STATUS_PROCESSING, 'order_market_id > 0'], 'group' => ['order_market_id']]);
     $total = 0;
     foreach ($in_snap as $data_set) {
         $total += $data_set[0]['qty'];
         $wms = WarehouseUtil::nameByMarket($data_set['Order']['order_market_id']);
         $warehouse_names[$data_set['Order']['order_market_id']] = $wms;
         array_key_exists($wms, $result['in_snap']) ? $result['in_snap'][$wms] += $data_set[0]['qty'] : ($result['in_snap'][$wms] = $data_set[0]['qty']);
     }
     $result['in_snap']['total'] = $total;
     unset($total);
     unset($data_set);
     unset($in_snap);
     $in_snap_stale = $this->Order->find('all', ['fields' => ['order_market_id', 'count(id) as qty'], 'conditions' => ['order_status_id' => Order::STATUS_PROCESSING, 'secondary_order_status_id' => Order::SECONDARY_NETSUITE_ERROR_RETURN], 'group' => ['order_market_id']]);
     $total = 0;
     foreach ($in_snap_stale as $data_set) {
         $total += $data_set[0]['qty'];
         $wms = array_key_exists($data_set['Order']['order_market_id'], $warehouse_names) ? $warehouse_names[$data_set['Order']['order_market_id']] : WarehouseUtil::nameByMarket($data_set['Order']['order_market_id']);
         array_key_exists($wms, $result['in_snap_stale']) ? $result['in_snap_stale'][$wms] += $data_set[0]['qty'] : ($result['in_snap_stale'][$wms] = $data_set[0]['qty']);
     }
     $result['in_snap_stale']['total'] = $total;
     unset($total);
     unset($data_set);
     unset($in_snap);
     // Days
     $days = 3;
     $result['sla_lehi'] = $this->Order->outOfWindow(1, true, $days);
     $result['sla_netherlands'] = $this->Order->outOfWindow(2, true, $days);
     $result['sla_mexico'] = $this->Order->outOfWindow(3, true, $days);
     $result['sla_total'] = array_sum([$result['sla_lehi'], $result['sla_netherlands'], $result['sla_mexico']]);
     $days = 5;
     $result['sla_lehi_5'] = $this->Order->outOfWindow(1, true, $days);
     $result['sla_netherlands_5'] = $this->Order->outOfWindow(2, true, $days);
     $result['sla_mexico_5'] = $this->Order->outOfWindow(3, true, $days);
     $result['sla_total_5'] = array_sum([$result['sla_lehi_5'], $result['sla_netherlands_5'], $result['sla_mexico_5']]);
     $days = 10;
     $result['sla_lehi_10'] = $this->Order->outOfWindow(1, true, $days);
     $result['sla_netherlands_10'] = $this->Order->outOfWindow(2, true, $days);
     $result['sla_mexico_10'] = $this->Order->outOfWindow(3, true, $days);
     $result['sla_total_10'] = array_sum([$result['sla_lehi_10'], $result['sla_netherlands_10'], $result['sla_mexico_10']]);
     $shipped = $this->Order->find('all', ['fields' => ['order_market_id', 'count(id) as qty'], 'conditions' => ['order_status_id' => [Order::STATUS_SHIPPED], 'date_completed >= DATE_SUB( NOW(), INTERVAL 3 DAY)'], 'group' => ['order_market_id']]);
     foreach ($shipped as $data_set) {
         $wms = array_key_exists($data_set['Order']['order_market_id'], $warehouse_names) ? $warehouse_names[$data_set['Order']['order_market_id']] : WarehouseUtil::nameByMarket($data_set['Order']['order_market_id']);
         array_key_exists($wms, $result['shipped']) ? $result['shipped'][$wms] += (int) $data_set[0]['qty'] : ($result['shipped'][$wms] = (int) $data_set[0]['qty']);
     }
     unset($data_set);
     unset($in_snap);
     //			$result['ns_import_errors'] = $this->Order->find('all', [
     //				'conditions' => [
     //					'secondary_order_status_id' => Order::SECONDARY_NETSUITE_ERROR_SUBMIT,
     //				],
     //				'contain' => ['OrderShipment']
     //			]);
     //
     //			foreach($result['ns_import_errors'] as &$error)
     //			{
     //				// check fail points
     //
     //				// char encoding
     //				$input_fields = [
     //					"first_name"		=> $error['OrderShipment'][0]['first_name'],
     //					"last_name"			=> $error['OrderShipment'][0]['last_name'],
     //					"address1"			=> $error['OrderShipment'][0]['address1'],
     //					"address2"			=> $error['OrderShipment'][0]['address2'],
     //					"address3"			=> $error['OrderShipment'][0]['address3'],
     //					"city"				=> $error['OrderShipment'][0]['city'],
     //					"phone"				=> $error['OrderShipment'][0]['phone'],
     //					"postal_code"		=> $error['OrderShipment'][0]['postal_code'],
     //					"email_address"		=> $error['OrderShipment'][0]['email_address']
     //				];
     //				foreach($input_fields as $field => $value)
     //				{
     //					if(mb_detect_encoding($value) == 'UTF-8')
     //					{
     //						$error['errors'][] = "Encoding: " . $field . " - " . $value;
     //					}
     //				}
     //				// address field length
     //				foreach($input_fields as $field => $value)
     //				{
     //					if(strlen($value) > 30)
     //					{
     //						$error['errors'][] = "Address: " . $field . " - " . $value;
     //					}
     //				}
     //				$error['market'] = $result['meta']['market'][$error['Order']['order_market_id']];
     //			}
     //
     //			$result['snap_export_errors'] = $this->Order->find('all', [
     //				'conditions' => [
     //					'secondary_order_status_id' => Order::SECONDARY_NETSUITE_ERROR_RETURN,
     //				],
     //				'fields' => [
     //					'date(min(date_completed)) oldest, count(id) as qty, order_market_id'
     //				],
     //				'group' => 'order_market_id'
     //
     //			]);
     //
     //			$result['other_errors'] = $this->Order->find('all', [
     //				'conditions' => [
     //					'secondary_order_status_id' => Order::SECONDARY_NETSUITE_ERROR_OTHER,
     //				]
     //			]);
     //
     //			$result['backorder_items'] = $this->Order->query("
     //			SELECT count(oi.id) count, i.sku, i.name
     //			FROM order_items oi
     //			LEFT JOIN items i ON oi.item_id = i.id
     //			LEFT JOIN order_shipment_items osi ON oi.id = osi.order_item_id
     //			LEFT JOIN order_customers oc ON oi.order_customer_id = oc.id
     //			LEFT JOIN orders o ON oc.order_id = o.id
     //			WHERE i.id IN (
     //				SELECT id as item_id
     //				FROM items
     //			)
     //			AND (
     //					osi.order_shipment_id = 0
     //					OR
     //					(
     //						osi.order_shipment_id IS NULL
     //						AND
     //						osi.id IS NOT NULL
     //					)
     //				)
     //			AND order_status_id in (3,8)
     //			GROUP BY i.id;
     //		");
     //
     //			$result['backorder_orders'] = $this->Order->query("
     //			SELECT *
     //			FROM order_items oi
     //			LEFT JOIN items i ON oi.item_id = i.id
     //			LEFT JOIN order_shipment_items osi ON oi.id = osi.order_item_id
     //			LEFT JOIN order_customers oc ON oi.order_customer_id = oc.id
     //			LEFT JOIN orders o ON oc.order_id = o.id
     //			WHERE i.id IN (
     //				SELECT id as item_id
     //				FROM items
     //			)
     //			AND (
     //					osi.order_shipment_id = 0
     //					OR
     //					(
     //						osi.order_shipment_id IS NULL
     //						AND
     //						osi.id IS NOT NULL
     //					)
     //				)
     //			 AND order_status_id in (3,8)
     //			;
     //		");
     //
     //			$backorder_ids = [];
     //			foreach($result['backorder_orders'] as $backorder)
     //				$backorder_ids[] = $backorder['o']['id'];
     //
     //			// orders not in snap
     //			$result['snap_import_errors'] = $this->Order->find('all', [
     //				'conditions' => [
     //					'order_status_id' => [
     //						Order::STATUS_ENTERED,
     //						Order::STATUS_PROCESSING
     //					],
     //					'secondary_order_status_id' => Order::SECONDARY_NETSUITE_ERROR_SNAP,
     //					'NOT' => [
     //						'id' => $backorder_ids
     //					]
     //				],
     //				'fields' => [
     //					'date(min(date_completed)) oldest, count(id) as qty, order_market_id'
     //				],
     //				'group' => 'order_market_id'
     //			]);
     //
     $this->sendSuccess($result);
 }
 public function setMarket($marketId)
 {
     if (($market_data = Cache::read('active_markets', 'medium')) === false) {
         $market_data = $this->Market->getActiveMarkets();
         if (!empty($market_data)) {
             Cache::write('active_markets', $market_data, 'medium');
         }
     }
     if (array_key_exists($marketId, $market_data)) {
         $this->Session->write("market_id", (int) $marketId);
         $this->ShoppingCart->changeMarket($this, (int) $marketId);
         $this->Session->write("warehouse", WarehouseUtil::idByMarket((int) $marketId));
         $this->sendSuccess($marketId);
     } else {
         $this->sendError(500, 'Invalid Market Id');
     }
 }
Example #17
0
 /**
  * @param array $items [['qty' => $qty, 'sku' => $sku]]
  * @param int $original_order_id
  */
 public function createReplacementOrder($items, $original_order_id, $notes = "")
 {
     $this->OrderShipmentMethod = ClassRegistry::init('OrderShipmentMethod');
     $this->UserNote = ClassRegistry::init('UserNotes');
     $order_type = self::TYPE_REPLACEMENT;
     $this->clear();
     $this->id = $original_order_id;
     $database_record = $this->loadDisplayDetails();
     $original_order = $database_record['Order'];
     $original_order_customer = $database_record['OrderCustomer'];
     $ship_to = ["first_name" => $original_order_customer['first_name'], "last_name" => $original_order_customer['last_name'], "address1" => $original_order_customer['Address']['address1'], "address2" => $original_order_customer['Address']['address2'], "address3" => $original_order_customer['Address']['address3'], "city" => $original_order_customer['Address']['city'], "state_id" => $original_order_customer['Address']['state_id'], "postal_code" => $original_order_customer['Address']['postal_code'], "country_id" => $original_order_customer['Address']['country_id'], "email_address" => $original_order_customer['Email']['email_address']];
     $new_order = $this->createOrder($original_order['promoter_id'], $original_order['presenter_id'], $original_order['user_id'], 0, $items, $ship_to, $order_type, NULL, [], TRUE, FALSE, FALSE, WarehouseUtil::idByMarket($database_record['Order']['order_market_id']));
     $this->finalize(array('success' => TRUE, 'payments' => []));
     $new_order_id = $this->id;
     $this->setDynamicData($new_order_id, 'replaces_order', $original_order_id);
     // Set Shipment Method
     $this->queueOrder();
     $this->UserNote->clear();
     $this->UserNote->save(['user_id' => 1, 'note' => "Backorder created - {$notes}", 'reference_type' => 'order', 'reference_id' => $original_order_id, 'user_note_status' => 'normal', 'admin_user_id' => 584]);
     return $new_order_id;
 }
 /**
  * Replacement Orders from Admin
  */
 public function admin_replacementOrder()
 {
     $replacement_data = $this->request->data('replacement_data');
     $order_data = $this->request->data('order');
     $notes = $this->request->data('note');
     $items = [];
     $party = NULL;
     $promoterId = 0;
     $presenterId = $order_data['presenter_id'];
     $userId = $order_data['user_id'];
     $partyId = $order_data['party'];
     $order_market = $order_data['order_market_id'];
     $old_order_id = $order_data['id'];
     /**
      * Re-sku and set quantity
      */
     foreach ($replacement_data['items'] as $value) {
         // check for re-sku
         $item = $this->Item->detailsBySku($value['sku']);
         // Override re-sku
         if (empty($item['redirect_sku'])) {
             $sku = ltrim($value['sku'], '-');
         } elseif ($value['sku'] == 'US-1017-00') {
             $sku = 'US-1017-00';
         } else {
             $sku = $item['redirect_sku'];
         }
         $quantity = 1;
         if (!empty($value['quantity'])) {
             $quantity = $value['quantity'];
         }
         $items[] = ['sku' => $sku, 'qty' => $quantity];
     }
     $shipping_address = $this->request->data('recipient');
     $customer = $this->OrderCustomer->find('first', ['contain' => ['Address' => ['State'], 'Email', 'Phone'], 'conditions' => ['OrderCustomer.order_id' => $order_data['id']]]);
     $shipTo = Hash::extract($customer, 'OrderCustomer.Address');
     $shipTo['phone'] = Hash::extract($customer, 'OrderCustomer.Phone.phone');
     $shipTo['email_address'] = Hash::extract($customer, 'OrderCustomer.Email.email');
     if (!empty($customer['OrderCustomer']['Address']['State']['ns_warehouse_id'])) {
         $ns_warehouse_id = $customer['OrderCustomer']['Address']['State']['ns_warehouse_id'];
     } elseif (!empty($order_market)) {
         $ns_warehouse_id = (int) WarehouseUtil::idByMarket($order_market);
     } else {
         $market_id = $this->Country->getMarketFromCountryId($shipping_address['country_id']);
         $ns_warehouse_id = (int) WarehouseUtil::idByMarket($market_id);
     }
     /**
      * Override address with posted recipient
      */
     if (!empty($shipping_address['city'])) {
         $phone = $shipTo['phone'];
         $shipTo = $shipping_address;
         if (!empty($phone)) {
             $shipTo['phone'] = $phone;
         }
     }
     /**
      * Create order with correct warehouse
      */
     $order = $this->Order->createOrder($promoterId, $presenterId, $userId, $partyId, $items, $shipTo, Order::TYPE_REPLACEMENT, NULL, [], TRUE, FALSE, FALSE, $ns_warehouse_id);
     // Finalize order
     $this->Order->finalize(['success' => TRUE, 'payments' => []]);
     $new_order_id = $this->Order->id;
     $this->Order->setDynamicData($new_order_id, 'replaces_order', $old_order_id);
     // Set Shipment Method
     $this->Order->queueOrder();
     // Add new element for replacement order  ($primary_key=false, $attribute_name=false, $attribute_value=false, $table_name=false, $new_attribute=false )
     $new_order_id = $this->Order->id;
     $old_order_id = $order_data['id'];
     $this->Order->setDynamicData($new_order_id, 'replaces_order', $old_order_id);
     // Log admin user
     $admin_user = $this->Session->read("admin_user");
     $this->AdminUserAudit->create();
     $this->AdminUserAudit->saveField('admin_user_id', $admin_user->id);
     $this->AdminUserAudit->saveField('reference_name', 'order.id');
     $this->AdminUserAudit->saveField('reference_id', $old_order_id);
     $this->AdminUserAudit->saveField('old_value', $old_order_id);
     $this->AdminUserAudit->saveField('new_value', $new_order_id);
     $this->AdminUserAudit->saveField('notes', "Admin3 replacement order. " . $notes);
     // send email
     try {
         if (empty($shipTo)) {
             throw new Exception("No address");
         }
         $presenter = $this->Presenter->find('first', ['conditions' => ['Presenter.id' => $order_data['presenter_id']], 'contain' => ['User', 'PresenterSite']]);
         if (!empty($order_data['party'])) {
             $party = $this->Party->partyFromId($order_data['party']);
         }
         $email_data = ["name" => $shipTo['first_name'], "new_order_id" => $this->Order->id, "original_order_id" => $order_data['id'], "presenter_name" => $presenter['User']['first_name'] . " " . $presenter['User']['last_name'], "presenter_site_url" => $presenter['PresenterSite']['site_url'], "items" => $replacement_data];
         if ($party) {
             $email_data['party_name'] = $party['Party']['name'];
         }
         $userLocale = $this->User->userLocale($this->Order->find("first", ['fields' => ["user_id"], "conditions" => ["Order.id" => $order['Order']['id']]]));
         YouniqueEmail::queueEmail($email_data, 'en_us_replacement_order', $shipTo['email_address'], 'email replacement order', 'admin_replacementOrder-page', $userLocale);
         $this->sendSuccess('Replacement order placed ' . $this->Order->id);
     } catch (Exception $e) {
         error_log($e->getMessage());
         $this->sendError(500, "Failed " . $e->getMessage());
     }
 }
Example #19
0
 /**
  * Populate restock date for order item
  *
  * @param bool $created
  * @param array $options
  * @throws Exception
  */
 public function afterSave($created, $options = [])
 {
     if ($created) {
         if (empty($this->data['OrderItem']['item_id']) || empty($this->data['OrderItem']['order_customer_id'])) {
             return;
         }
         $item = $this->Item->find('first', ['fields' => ['Item.sku'], 'conditions' => ['Item.id' => $this->data['OrderItem']['item_id']]]);
         $customer = $this->OrderCustomer->find('first', ['contain' => ['Order'], 'fields' => ['Order.id', 'Order.order_market_id'], 'conditions' => ['OrderCustomer.id' => $this->data['OrderItem']['order_customer_id']]]);
         $order = $customer['Order'];
         $sku = $item['Item']['sku'];
         $wid = WarehouseUtil::idByMarket($order['order_market_id']);
         $restock_date = $this->Item->ItemAvailabilityTimes->restockDate($sku, $wid);
         if (!empty($restock_date)) {
             $data = ['order_id' => $order['id'], 'order_item_id' => $this->id, 'active' => OrderItemRestock::ACTIVE, 'restock_date' => $restock_date];
             $this->OrderItemRestock->clear();
             $this->OrderItemRestock->save($data);
         }
     }
 }
Example #20
0
    public function deprecated_exportBackOrderShipments(array $entered_skus = null, $warehouse_id = 0, $params = array(), $snap_direct = true)
    {
        if (isset($params['file_size'])) {
            $limit = $params['file_size'];
        } else {
            $limit = 2000;
        }
        if (isset($params['total_export'])) {
            $total_export = $params['total_export'];
        } else {
            $total_export = $limit;
        }
        print_r(array('params' => $params));
        print 'Entered Skus: ' . print_r($entered_skus, true);
        $dataflow_name = "dataflow10";
        $sub_folder = "tmp";
        $sku_set = '';
        $this->OrderItem = ClassRegistry::init('OrderItem');
        $this->OrderShipment = ClassRegistry::init('OrderShipment');
        $this->ItemShipmentClass = ClassRegistry::init('ItemShipmentClass');
        $this->OrderShipmentMethod = ClassRegistry::init('OrderShipmentMethod');
        $this->UserNote = ClassRegistry::init('UserNote');
        //	This method requires a product sku to fullfill
        //	it MUST be in an array when hitting this method.
        //	e.g. $skus = array('US-1017-00', 'US-80002-03', 'US-666-etc')
        //
        // NOTICE: $entered_skus is deprecated by $params['sksu'] and support will be removed in a future version
        if (is_array($entered_skus)) {
            foreach ($entered_skus as $asku => $details) {
                if ($asku == null) {
                    $asku = $details;
                }
                $sku_set .= "'" . $asku . "',";
            }
            $sku_set = rtrim($sku_set, ',');
        } else {
            $sku_set = $params['skus'];
        }
        $use_these_order_ids = "";
        if (!empty($params['orders']) && !is_array($params['orders'])) {
            $these_order_ids = explode(',', $params['orders']);
            foreach ($these_order_ids as $this_orderid) {
                $use_these_order_ids .= "'" . $this_orderid . "',";
            }
            $use_these_order_ids = rtrim($use_these_order_ids, ',');
        }
        if ($warehouse_id) {
            $fulfill_markets = '';
            foreach ($this->market_warehouses as $market_id => $market_settings) {
                if ($market_settings['warehouse'] == $warehouse_id) {
                    $fulfill_markets .= $market_id . ',';
                }
            }
            $fulfill_markets = rtrim($fulfill_markets, ',');
        }
        $processing = Order::STATUS_PROCESSING;
        $shipped = Order::STATUS_SHIPPED;
        $entered = Order::STATUS_ENTERED;
        $Orders = ClassRegistry::init('Orders');
        $db = $Orders->getDataSource('default');
        $output = array();
        while ($total_export >= 1) {
            // !Backorder Query
            $sql = <<<EOF
\t\t\t\tSELECT *
\t\t\t\tFROM order_items oi
\t\t\t\tLEFT JOIN items i
\t\t\t\t\tON oi.item_id = i.id
\t\t\t\tLEFT JOIN order_customers oc
\t\t\t\t\tON oi.order_customer_id = oc.id
\t\t\t\tLEFT JOIN orders o
\t\t\t\t\tON oc.order_id = o.id
\t\t\t\tWHERE i.sku IN ({$sku_set})
\t\t\t\tAND oi.order_item_hold_code_id = 1
\t\t\t\tAND order_status_id in ({$entered}, {$processing}, {$shipped})
\t\t\t\tAND o.date_completed >= '2015-09-17 00:00:00'
EOF;
            if ($warehouse_id) {
                $sql .= " AND oi.ns_warehouse_id = {$warehouse_id}";
            }
            if (strlen($use_these_order_ids) > 0) {
                $sql .= " AND o.id IN ({$use_these_order_ids})";
            }
            $sql .= " ORDER BY o.id";
            $sql .= " LIMIT {$limit} ";
            $sql = str_replace(chr(13), "", $sql);
            $sql = str_replace("\t", "", $sql);
            $sql = str_replace("\n", " ", $sql);
            print $sql . "\n";
            $item_backorders = null;
            $backorder_count = 0;
            $item_backorders = $db->fetchall($sql, false);
            $backorder_count = count($item_backorders);
            if (!$backorder_count) {
                return $output;
            } else {
                $total_export = $total_export - $backorder_count;
            }
            if ($backorder_count < $limit) {
                $total_export = 0;
            }
            /******
             *	Here we take the raw data from the database and
             *	compile it into a new array that is indexed
             *	by the order_id
             *******/
            $backorders = array();
            foreach ($item_backorders as $details) {
                $order_id = $details['oc']['order_id'];
                $market_id = $details['o']['market_id'];
                $item_id = $details['oi']['item_id'];
                $order_item_id = $details['oi']['id'];
                $item_type_id = $details['i']['item_type_id'];
                #$warehouse_id	= (int)WarehouseUtil::idByMarket($details['o']['order_market_id']);
                //**** fulfillment Warehouse Info ********/
                $fulfilldata = $this->getFulfillmentData($details['o'], array());
                $warehouse_id = $fulfilldata['warehouse'];
                if ($item_type_id == Item::TYPE_PRESENTER_KIT) {
                    $shipment_class = "P";
                } else {
                    $shipment_class = $this->ItemShipmentClass->getItemShipmentClass($warehouse_id, $item_id);
                }
                if (!$shipment_class) {
                    $shipment_class = $details['i']['shipment_class'];
                }
                $oi_header = array('order_id' => $order_id, 'order_item_id' => $order_item_id, 'market_id' => $market_id);
                /*  I've divested the order_shipment records from the main query
                 *	because accomodating multiple order shipment
                 *	records per order get's tricky and brittle.
                 */
                $sql = <<<EOF
\t\t\t\t\tSELECT oship.*, s.abbrev as state_two, c.country_code
\t\t\t\t\tFROM order_shipments oship
\t\t\t\t\tLEFT JOIN states s on s.id = oship.state_id
\t\t\t\t\tLEFT JOIN countries c on c.id = oship.country_id
\t\t\t\t\tWHERE order_id = '{$order_id}'
\t\t\t\t\tLIMIT 1
EOF;
                $sql = str_replace(chr(13), "", $sql);
                $sql = str_replace("\t", "", $sql);
                $sql = str_replace("\n", " ", $sql);
                $oship_data = $db->fetchall($sql);
                $oship = $oship_data[0]['oship'];
                $oship['ORIGINAL_shipment_id'] = $oship['id'];
                $oship['ORIGINAL_ship_method'] = $oship['shipment_method'];
                $ostate = $oship_data[0]['s'];
                $ocountry = $oship_data[0]['c'];
                unset($oship['id']);
                unset($oship['date_shipped']);
                unset($oship['order_shipment_status_id']);
                $item_details = array('oiHeader' => $oi_header, 'oiDetails' => $details['oi'], 'iDetails' => $details['i']);
                $backorders[$order_id]['order_header'] = $details['o'];
                $backorders[$order_id]['order_items'][] = $item_details;
                $backorders[$order_id]['order_shipments'][] = $oship;
                $backorders[$order_id]['item_ship_class'][$shipment_class]++;
                if ($snap_direct) {
                    $snap_addendum = array('order_date' => $details['o']['date_completed'], 'market_id' => $market_id, 'customer_id' => $details['oc']['user_id'], 'address3' => $oship['address3'], 'state_two' => $ostate['state_two'], 'country_code' => $ocountry['country_code']);
                    $backorders[$order_id]['snap_addendum'] = $snap_addendum;
                }
            }
            /******
             *	Now we take the order_id indexed array with
             *	all of the backordered line items and
             *	compile it into the exportable data
             *******/
            $ship_method_ids = OrderShipmentMethod::$shipment_methods;
            $methods_by_name = array();
            foreach ($ship_method_ids as $key => $val) {
                $methods_by_name[$val] = $key;
            }
            $raw_output = array();
            $oi_db_ref = array();
            /* We need a separate container for updating backorder item statuses when we're done. */
            foreach ($backorders as $theOrderId => $vals) {
                print "**** Starting Order #" . $theOrderId . " **********\n";
                /* Then we get a new order_shipment_id by creating the order_shipments record */
                $raw_shipment = $vals['order_shipments'][0];
                // Do not carry the original ship method so that a new one is determined
                $raw_shipment['shipment_method'] = 0;
                $raw_shipment['created'] = date("Y-m-d H:i:s");
                $raw_shipment['tracking_number'] = null;
                $raw_shipment['carrier'] = null;
                $this->OrderShipment->create($raw_shipment);
                $result = $this->OrderShipment->save($raw_shipment, false);
                $order_shipment_id = $result['OrderShipment']['id'];
                /* The entry into the order_shipment table is complete, now we add the the Dataflow elements  */
                $stshipment = array('id' => null, 'address1' => null, 'address2' => null, 'city' => null, 'state_id' => null, 'country_id' => null, 'postal_code' => null, 'first_name' => null, 'last_name' => null, 'phone' => null, 'order_shipment_status_id' => null, 'priority' => null, 'warehouse_id' => null, 'shipping_method' => null, 'shipping_class' => null, 'fulfillment_instance' => null);
                foreach ($raw_shipment as $key => $value) {
                    if (array_key_exists($key, $stshipment)) {
                        $stshipment[$key] = $value;
                    }
                }
                $order_shipment_class = $this->getShipmentClass($vals['item_ship_class']);
                # We will override this later if there is only one item in the fulfillment.
                $storder = array();
                $storder['order_id'] = (int) $vals['order_header']['id'];
                $storder['order_status_id'] = (int) $vals['order_header']['order_status_id'];
                $storder['user_id'] = (int) $vals['order_header']['user_id'];
                $storder['presenter_id'] = (int) $vals['order_header']['presenter_id'];
                $storder['party_id'] = (int) $vals['order_header']['party_id'];
                $stshipment['id'] = (int) $order_shipment_id;
                $stshipment['state_id'] = (int) $result['OrderShipment']['state_id'];
                $stshipment['country_id'] = (int) $result['OrderShipment']['country_id'];
                $stshipment['order_shipment_status_id'] = (int) OrderShipmentStatus::OPEN;
                $warehouse_id = (int) WarehouseUtil::idByMarket($vals['order_header']['order_market_id']);
                $market_id = $vals['order_header']['order_market_id'];
                $stshipment['warehouse_id'] = (int) $warehouse_id;
                $stshipment['shipping_class'] = $order_shipment_class;
                $stshipment['priority'] = '04';
                $this->OrderShipmentMethod->setOrderShipmentMethod($storder['order_id'], TRUE, $order_shipment_id);
                $new_result = $this->OrderShipment->findAllById($order_shipment_id);
                $shipmethod_code = $new_result[0]['OrderShipment']['shipment_method'];
                if ($shipmethod_code == 0) {
                    $shipping_method = $this->market_economy_shipmethods[$market_id];
                } else {
                    $shipping_method = $ship_method_ids[$shipmethod_code];
                }
                $stshipment['shipping_method'] = $shipping_method;
                if ($vals['order_shipments'][0]['ORIGINAL_ship_method'] == 0) {
                    $orig_shipment = $vals['order_shipments'][0]['ORIGINAL_shipment_id'];
                    $method_id = $methods_by_name[$shipping_method];
                    print "Running Shipment Update on " . $orig_shipment . " with method " . $method_id . "\n";
                    $this->OrderShipment->id = $orig_shipment;
                    $this->OrderShipment->saveField('shipment_method', $method_id);
                }
                print "HELLO?";
                print_r(array('shipping_method' => $stshipment['shipping_method'], 'shipment_code' => $shipmethod_code, 'order_id' => $storder['order_id'], 'address1' => $stshipment['address1'], 'warehouse_id' => $stshipment['warehouse_id'], 'country_id' => $stshipment['country_id'], 'market_id' => $vals['order_header']['order_market_id'], 'state' => $stshipment['state_id']));
                $phone = $stshipment['phone'];
                if ($vals['order_header']['order_market_id'] != 1) {
                    $phone = $vals['order_shipments']['phone'];
                    if (empty($phone)) {
                        $phone = $this->getShipmentPhone($vals['order_header']['user_id']);
                    }
                }
                $phone = str_replace("-", "", $phone);
                $stshipment['phone'] = $phone;
                /*	Next is the shipments top level reference info. */
                $stheader = array('order_id' => (int) $storder['order_id'], 'order_shipment_id' => (int) $stshipment['id']);
                /*	The shipment data is complete. Now we focus on the shipment items. */
                $order_items = $vals['order_items'];
                $stitems = array();
                $total_quanity = 0;
                foreach ($order_items as $core_item) {
                    $item = $core_item['oiDetails'];
                    $product = $core_item['iDetails'];
                    $item['order_shipment_id'] = $order_shipment_id;
                    /* : order items. */
                    $oi_db_ref[] = $item;
                    $ordered_item_id = $item['id'];
                    $cpu_sql = <<<EOF
\t\t\t\t\tSELECT
\t\t\t\t\t\tCOUNT(*) as cpu_count
\t\t\t\t\t\tFROM coupon_presenter_users cpu
\t\t\t\t\t\tWHERE cpu.redemption_reference_id = '{$ordered_item_id}'
\t\t\t\t\t\tGROUP BY cpu.redemption_reference_id
\t\t\t\t\t\tORDER BY cpu_count DESC
EOF;
                    $cpu_sql = str_replace(chr(13), "", $cpu_sql);
                    $cpu_sql = str_replace("\t", "", $cpu_sql);
                    $cpu_sql = str_replace("\n", " ", $cpu_sql);
                    $cpu_data = $db->fetchall($cpu_sql);
                    $cpu_count = 0;
                    if (count($cpu_data)) {
                        $cpu_count = $cpu_data[0][0]['cpu_count'];
                    }
                    $total_quanity += (int) $item['quantity'];
                    $myitems = array('sku' => $product['sku'], 'quantity' => (int) $item['quantity'], 'order_item_id' => (int) $ordered_item_id, 'order_shipment_id' => (int) $order_shipment_id, 'item_id' => (int) $product['id'], 'parent_id' => (int) $item['parent_id'], 'price' => $item['price'], 'discount' => (double) $item['discount'], 'item_type' => (int) $item['item_type_id'], 'total' => $item['extended_price'], 'hpi_qty' => (int) $cpu_count, 'item_tax' => $item['tax_amount']);
                    $stitems[] = $myitems;
                }
                $stoutput = array('order_id' => (int) $stheader['order_id'], 'order_shipment_id' => (int) $stheader['order_shipment_id'], 'order_header' => $storder, 'items' => $stitems, 'shipment' => $stshipment);
                if ($total_quanity == 1 && ($params['total_export'] > 500 && $warehouse_id == 1 || $warehouse_id != 1)) {
                    $stoutput['shipment']['shipping_class'] = "BO";
                }
                // Under snap direct, we skip adding data to netsuite if it fails snap.
                if ($snap_direct) {
                    $results_array = array();
                    $stoutput['addendum'] = $vals['snap_addendum'];
                    $wh_id = $stoutput['shipment']['warehouse_id'];
                    $snap_success = $this->snap_direct($wh_id, 'netsuite', 1, $stoutput);
                    $results_array[$stheader['order_shipment_id']] = $snap_success;
                    if ($snap_success) {
                        $raw_output[] = $stoutput;
                    } else {
                        // Roll back database modifications
                        $delete_result = $this->OrderShipment->delete($stheader['order_shipment_id']);
                    }
                } else {
                    $raw_output[] = $stoutput;
                }
            }
            /* Here we build and send the output file */
            $timestamp = time();
            $theOutput = json_encode($raw_output);
            $filename = sys_get_temp_dir() . DS . $dataflow_name . "_" . $timestamp . '.tmp';
            $fh = fopen($filename, 'w+');
            fwrite($fh, $theOutput);
            fclose($fh);
            $target_name = $dataflow_name . DS . $sub_folder . DS . $dataflow_name . "_" . $timestamp . ".json";
            $xfer_result = $this->upload($target_name, $filename);
            if ($xfer_result) {
                /* And now it's time to update the order shipment items. */
                foreach ($oi_db_ref as $sent_item) {
                    $new_os_id = $sent_item['order_shipment_id'];
                    $oi_id = $sent_item['id'];
                    $this->OrderItem->id = $oi_id;
                    $this->OrderItem->saveField('order_shipment_id', $new_os_id);
                    $this->OrderItem->saveField('order_item_hold_code_id', 0);
                }
                foreach ($raw_output as $allocated) {
                    //add user note
                    $date = new DateTime();
                    $allocated_items = "";
                    foreach ($allocated['items'] as $allocated_item) {
                        $allocated_items .= $allocated_item['sku'] . ", ";
                    }
                    $this->UserNote->clear();
                    $note = "Backorder item allocated for shipment {$allocated['order_shipment_id']} on {$date->format('Y-m-d H:i:s')}. Items allocated: {$allocated_items}";
                    $note_data = ['user_id' => $allocated['order_header']['user_id'], 'note' => $note, 'reference_type' => 'order', 'reference_id' => $allocated['order_id'], 'user_note_status' => 'normal', 'admin_user_id' => 584];
                    $this->UserNote->save($note_data);
                }
            }
            $output['Files'][] = $target_name;
        }
        return $output;
    }