Beispiel #1
0
 public function testIsGreaterThan()
 {
     $base = Money::fromPennies(1000);
     $less = Money::fromPennies(999.99);
     $equal = Money::fromPennies(1000);
     $more = Money::fromPennies(1001);
     $this->assertFalse($less->isEqualOrGreaterThan($base));
     $this->assertFalse($less->isGreaterThan($base));
     $this->assertTrue($equal->isEqualOrGreaterThan($base));
     $this->assertFalse($equal->isGreaterThan($base));
     $this->assertTrue($more->isEqualOrGreaterThan($base));
     $this->assertTrue($more->isGreaterThan($base));
 }
Beispiel #2
0
 /**
  * TestOrder constructor.
  * @param array $options
  */
 public function __construct($options = [])
 {
     if (!empty($options['items'])) {
         $this->items = array_replace($this->items, $options['items']);
     }
     if (!empty($options['address'])) {
         $this->address = array_replace($this->address, $options['address']);
     }
     if (!empty($options['payment'])) {
         $this->payment = array_replace($this->payment, $options['payment']);
     }
     if (!empty($options['y_cash'])) {
         $this->ycash = array_replace($this->ycash, $options['y_cash']);
     }
     if (!empty($options['card'])) {
         $this->card = array_replace($this->card, $options['card']);
     }
     if (!empty($options['party_id'])) {
         $this->party_id = $options['party_id'];
     }
     if (!empty($options['credits'])) {
         $this->credits = Money::fromPennies($options['credits']);
     }
     if (!empty($options['coupons'])) {
         $this->coupons = $options['coupons'];
     }
     if (!empty($options['replacement'])) {
         $this->replacement = $options['replacement'];
     }
     if (!empty($options['user_id'])) {
         $this->user_id = $options['user_id'];
     }
     if (!empty($options['presenter_id'])) {
         $this->presenter_id = $options['presenter_id'];
     }
     if (!empty($options['warehouse'])) {
         $this->warehouse = $options['warehouse'];
     }
     if (!empty($options['database'])) {
         $this->database = $options['database'];
     }
     if (!empty($options['expedited'])) {
         $this->expedited = $options['expedited'];
     }
     if (session_id() === "") {
         session_start();
     }
 }
 public function purchase()
 {
     $this->Presenter->id = $this->data['sponsor_id'];
     $presenter = $this->Presenter->loadBasicDetails();
     if (!empty($presenter)) {
         $promoterId = 0;
         $presenterId = $presenter['Presenter']['id'];
     } else {
         $promoterId = 0;
         $presenterId = 0;
     }
     $validation_errors = array();
     $this->shoppingCart = new ShoppingcartController();
     if (empty($this->data['paypaluserid'])) {
         if (!strlen($this->data['billingCardholderFirstName']) || !strlen($this->data['billingCardholderLastName'])) {
             $validation_errors['cardHolder'] = array("The name on the card is required");
         }
         $credit_card_number = $this->data['cardNum'];
         if (!strlen($this->data['cardNum'])) {
             $validation_errors['cardNum'] = array("The credit card number is required");
         } else {
             $credit_card_number = preg_replace('/\\D/', '', $credit_card_number);
             //pgandhay if ( ! preg_match('/\d{13,16}/', $credit_card_number) || !$this->luhn_check($credit_card_number)) {
             if (!preg_match('/\\d{13,16}/', $credit_card_number) || !$this->shoppingCart->luhn_check($credit_card_number)) {
                 $validation_errors['cardNum'] = array("The credit card number is invalid");
             }
         }
         $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("The card code is invalid");
         }
         if (!strlen($this->data['cardExpMonth']) || !strlen($this->data['cardExpYear'])) {
             $validation_errors['cardExpYear'] = array("The expiration date is required");
         } else {
         }
         switch ($this->data['sameAsShipping']) {
             case "on":
                 if (!strlen($this->data['postal_code'])) {
                     $validation_errors['postal_code'] = array("The billing postal code is required");
                 }
                 break;
             default:
                 //check for not empty
                 if (!strlen($this->data['billingState']) && $this->data['billing_market_id'] != Market::MARKET_UNITED_KINGDOM) {
                     $validation_errors['billingState'] = array("The billing state is required");
                 }
                 if (!strlen($this->data['billingZip'])) {
                     $validation_errors['billingZip'] = array("The billing postal code is required");
                 }
                 if (!strlen($this->data['billingEmail'])) {
                     $validation_errors['billingEmail'] = array("The billing email is required");
                 }
                 if (!strlen($this->data['billingAddress1'])) {
                     $validation_errors['billingAddress1'] = array("The billing address is required");
                 }
                 //validate
                 //					$this->Address->set('postal_code', $this->data['billingZip']);
                 //					if (!$this->Address->validates(array('fieldList' => array('postal_code'))))
                 //						$validation_errors['billingZip'] 		= array("Please use a valid billing postal code.");
                 $this->Email->set('email', $this->data['billingEmail']);
                 if (!$this->Email->validates(array('fieldList' => array('email')))) {
                     $validation_errors['billingEmail'] = array("Please use a valid billing email address.");
                 }
                 break;
         }
         if (!empty($validation_errors)) {
             $this->sendError(500, $validation_errors);
             return;
         }
     }
     if (empty($presenterId)) {
         $this->sendError(500, array("process_error" => array("Please choose a Presenter for your purchase")));
         return;
     }
     if (empty($this->request->data['items'])) {
         $this->sendError(500, array("process_error" => array("There are no items in your Shopping Cart")));
         return;
     }
     $itemIds = $this->request->data['items'];
     //$userId = $this->Session->read("user_id");
     $userId = $this->request->data['userId'];
     $party = $this->Party->partyFromId($this->data['party_id'], $presenterId, true);
     if (!empty($party)) {
         $partyId = $party['Party']['id'];
     } else {
         $partyId = 0;
     }
     if (!empty($this->request->data['cardExpMonth'])) {
         $this->request->data['cardExp'] = $this->request->data['cardExpMonth'] . "/" . $this->request->data['cardExpYear'];
     }
     /**
      * @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'];
     }
     @($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" => (int) $this->Address->State->search($this->request->data['state']), "country_id" => Configure::read("market_id"), "postal_code" => $this->request->data['postal_code'], "email_address" => trim($this->request->data['email'])));
     $hasDailySpecial = false;
     $hasConventionTicket = false;
     $this->Order->OrderShipment->set($address);
     if (!$this->Order->OrderShipment->validates()) {
         $this->sendError(500, $this->Order->OrderShipment->validationErrors);
     } else {
         //Kudos Block
         $hasKudos = $this->KudosCheck(true);
         //Kudos End
         foreach ($itemIds as &$item) {
             if (strpos($item['sku'], "US-3001-") === 0) {
                 $hasDailySpecial = true;
             }
             if ($item['sku'] == 'US-70015-00' || $item['sku'] == 'US-70115-00') {
                 $hasConventionTicket = true;
             }
             //                if ($item['sku'] == 'US-12301-01' && $hasKudos != 1) {
             //                    unset($item);
             //                    continue;
             //                }
             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;
         }
         $prices = $this->Order->createOrder($promoterId, $presenterId, $userId, $partyId, $itemIds, $address, Order::TYPE_PRODUCT, $productCredits, $toUseCoupons);
         if ($prices !== false) {
             foreach ($prices['total']['usedCoupons'] as $couponId => $details) {
                 $this->User->CouponPresenterUser->id = $couponId;
                 $result = $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();
             //I now need to fund this order...Possibly from multiple payment sources.
             $payments = array();
             if ($prices["total"]['productcredits']->isGreaterThanZero()) {
                 $payments[] = array("type" => "ledger", "presenter_id" => $presenterId, "user_id" => $userId, "amount" => $prices["total"]['productcredits']);
             }
             //@todo have this check for paypal pmt
             if (isset($this->request->data['token'])) {
                 if ($prices["total"]['charge']->isGreaterThanZero()) {
                     $payments[] = array("type" => "paypal", "amount" => $prices["total"]['charge'], "paypaluserid" => $this->request->data['paypaluserid'], "token" => $this->request->data['token'], "user_id" => $userId);
                 }
             } else {
                 if ($prices["total"]['charge']->isGreaterThanZero()) {
                     $billing_address = $this->prepareBillingData();
                     $payments[] = array("type" => "creditcard", "amount" => $prices["total"]['charge'], "cardholder" => $this->request->data['cardHolder'], "cardnum" => $this->request->data['cardNum'], "carexp" => $this->request->data['cardExp'], "cardcode" => $this->request->data['cardCode'], "firstName" => $billing_address['cardholderfirstname'], "lastName" => $billing_address['cardholderlastname'], "billingemail" => $billing_address['billingemail'], "billingaddress1" => $billing_address['billingaddress1'], "billingaddress2" => $billing_address['billingaddress2'], "billingcity" => $billing_address['billingcity'], "billingstate" => $billing_address['billingstate'], "billingpostalcode" => $billing_address['billingpostalcode'], "billingcountry" => $billing_address['billingcountry']);
                 }
             }
             // test code til payment process is worked out
             $payment['transaction_id'] = "Test123";
             $payment['status'] = "success";
             $payment['processor'] = 2;
             $paymentResult = $payment;
             //				$paymentResult = $this->Payment->processOrderPayments($order['Order']['id'], $payments);
             $this->Order->finalize($paymentResult);
             if ($paymentResult['success'] !== true) {
                 foreach ($prices['total']['usedCoupons'] as $couponId => $details) {
                     $this->User->CouponPresenterUser->id = $couponId;
                     $result = $this->User->CouponPresenterUser->save(array("date_redeemed" => null, "redemption_reference_id" => null, "redemption_amount" => null));
                 }
                 $this->sendError(500, array("process_error" => array($paymentResult['error'])));
             } else {
                 // Kudos Block
                 // $this->Kudos->finalizeOrder();
                 //					if ((date('Y-m') <= '2014-10') && $hasKudos > 0) {
                 //						$credit_amount = Money::fromPennies(500 * $hasKudos);
                 //						$market_id = Configure::read("market_id");
                 //
                 //						$this->ProductCredit->credit(ProductCredit::METHOD_SYSTEM, ProductCredit::TYPE_PROMOCREDIT, $market_id, $presenterId, $userId, $credit_amount, "ShoppingCart:Purchase:October2014Kudos", $order['Order']['id']);
                 //
                 //						$order['freeItems'][] = array(
                 //							'sku' => 'Y-Cash',
                 //							'description' => 'Earned $' . 5*$hasKudos . ' Younique Cash',
                 //							'quantity' => 1,
                 //						);
                 //					}
                 // Kudos End
                 if ($hasDailySpecial) {
                     $this->ShoppingCartItem->usedDailySpecial();
                 }
                 $this->Party->id = $partyId;
                 $this->Party->read();
                 $hostess_id = $this->Party->data['Party']['hostess_id'];
                 $hostess = $this->User->find("first", array("conditions" => array("id" => $hostess_id)));
                 // Back Order Start
                 //$order['OrderCustomer'][0]['OrderItem']
                 foreach ($order['OrderCustomer'] as $customerKey => $customer) {
                     foreach ($customer['OrderItem'] as $itemKey => $item) {
                         if (!empty($item['backorder_start'])) {
                             $order['OrderCustomer'][$customerKey]['BackOrderItem'][] = $item;
                             //                                unset($order['OrderCustomer'][$customerKey]['OrderItem'][$itemKey]);
                         }
                     }
                 }
                 // Back Order End
                 $orderDetails = array("order" => $order, "name" => $address['first_name'] . " " . $address['last_name'], "payments" => array("ycash" => $ycash, "creditcard" => $credit_card_payments, "paypal" => $paypal, "commission" => $commission_total), "hasConventionTicket" => $hasConventionTicket, "hostess" => $hostess['User']['first_name'] . " " . $hostess['User']['last_name']);
                 try {
                     $email = new CakeEmail('default');
                     $email->template('order', 'default')->emailFormat('both')->to($address['email_address'])->viewVars($orderDetails)->subject('Younique Order Confirmation!')->send();
                     if (!empty($presenter['User']['Email']['email'])) {
                         $orderDetails['sponsor'] = $presenter['User']['first_name'] . " " . $presenter['User']['last_name'];
                         $email = new CakeEmail('default');
                         $email->template('sponsor_order', 'default')->emailFormat('both')->to($presenter['User']['Email']['email'])->viewVars($orderDetails)->subject('Congratulations!  Younique Order Confirmation!')->send();
                     }
                 } catch (Exception $e) {
                     //Since I processed the order, I don't want this to fail anywhere..
                     //Need to do better logging here
                     error_log($e->getMessage());
                 }
                 //get the items in the order
                 $order_items = array();
                 foreach ($order['OrderCustomer'][0]['OrderItem'] as $oi) {
                     $order_items[] = array('sku' => $oi['Item']['sku'], 'name' => $oi['Item']['name'], 'price' => $oi['price'], 'qty' => $oi['quantity']);
                 }
                 $this->sendSuccess(array("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));
             }
         } else {
             $this->sendError(500, array("process_error" => array("Cannot create Order. Please try again later")));
         }
     }
 }
 /**
  * Use this to calculate a value to be decremented from promo items due to ycash and HPI usage.
  *
  * If you change this function to match a kudo promo, save the existing code in the wiki with a
  * description so that it can be reused in the future
  *
  */
 private function _checkPromoAdjustments($items, $ycash = null, $qualifying_items = array())
 {
     //load the item model to get the price info on items
     App::import("Model", "Item");
     $this->Item = new Item();
     //get the productcredits
     $trigger_item = $this->Item->detailsBySku('US-1051-00');
     $trigger_item_price = (double) $trigger_item['price'];
     //$trigger_item = $this->Item->detailsBySku($qualifying_items);
     //get additional skus (sets, combos, etc) of qualifying items if applicable
     //Hard code collections since I am short on time
     $collections = array("US-41011-01", "US-41021-01", "US-41031-01", "US-41041-01", "US-41051-01", "US-41061-01", "US-91201-01");
     //to keep track of HPI in case of no ycash
     $total_qualifying_items = 0;
     $hpi_qty = 0;
     $count = 0;
     //contains the price value of trigger items in cart
     $qualifying_items_value = Money::fromFloat(0);
     //contains the price value of the non trigger items in the cart
     $total_adjusted_item_value = Money::fromFloat(0);
     $product_credits = Money::fromPennies($ycash);
     foreach ($items as $value) {
         $item_detail = $this->Item->detailsBySku($value['sku']);
         $price = $item_detail['price'];
         $coupons = (int) count(array_unique($value['coupons']));
         $qty = (int) $value['qty'];
         if (in_array($value['sku'], $qualifying_items)) {
             $count += $qty;
             $floor = $qty - $coupons;
             $total_qualifying_items += $floor > 0 ? $floor : 0;
             $hpi_qty += $coupons;
             $iteration_value = Money::fromFloat($trigger_item_price)->times($qty - $coupons);
             $qualifying_items_value->add($iteration_value);
         }
         //for collections containing trigger item, make the min allowed non coupon value equal to the trigger item price
         if (in_array($value['sku'], $qualifying_items) && in_array($value['sku'], $collections)) {
             $total_adjusted_item_value->add(Money::fromFloat($price)->times($qty));
             //reduce amount by items with HPI applied
             $total_adjusted_item_value->subtract(Money::fromFloat($price)->times($coupons));
         } else {
             $total_adjusted_item_value->add(Money::fromFloat($price)->times($qty));
             //reduce amount by items with HPI applied
             $total_adjusted_item_value->subtract(Money::fromFloat($price)->times($coupons));
         }
     }
     $commissionable = $total_adjusted_item_value->copy()->subtract($product_credits);
     if ($commissionable->amount > 0 && $ycash->amount > 0) {
         //don't want to divide by 0
         $divisor = $trigger_item_price == 0 ? 1 : $trigger_item_price * 100;
         $qualified_promo_qty = floor(($commissionable->amount - $ycash->amount) / $divisor);
         //			$qualified_promo_qty = "($commissionable->amount / 100) / $divisor)";
         return $qualified_promo_qty;
     } else {
         return $total_qualifying_items;
     }
 }
 public function prices($internalUse = FALSE)
 {
     $this->CashAndCarry = new CashAndCarry();
     if (!empty($this->request->data['zip'])) {
         $zipCode = $this->request->data['zip'];
     } else {
         $zipCode = null;
     }
     if (!empty($this->data['sponsor_id'])) {
         $presenter = $this->Presenter->findById($this->data['sponsor_id']);
     }
     if (!empty($presenter)) {
         $promoterId = 0;
         $presenterId = $presenter['Presenter']['id'];
     } else {
         $promoterId = 0;
         $presenterId = 0;
     }
     if (empty($this->request->data['items'])) {
         $items = array();
     } else {
         $items = $this->ShoppingCartItem->pruneItems($this->request->data['items'], false, $this->request->data['productcredits']);
     }
     $this->Session->write('user_id', $this->request->data['user_id']);
     $userId = $this->Session->read("user_id");
     if (empty($this->request->data['productcredits'])) {
         $productcredits = null;
     } else {
         $productcredits = Money::fromPennies((int) $this->request->data['productcredits']);
         //check if product credits is greater than their balance
         $balance = $this->ProductCredit->balance(Configure::read("market_id"), $presenterId, $userId);
         if ($productcredits->isGreaterThan($balance)) {
             $productcredits = $balance;
         }
     }
     //used for removing the ycash exempt value from the amount ycash can be applied
     $discount_exclusion = Money::fromFloat(0);
     foreach ($items as &$item) {
         //items that are y-cash excluded
         if (in_array($item['sku'], ProductGlobal::yCashExcluded())) {
             App::import("Model", "Item");
             $this->Item = new Item();
             $limit_item = $this->Item->detailsBySku($item['sku'], $this->Session->read('Config.language'), true);
             $discount_exclusion->add(Money::fromFloat($limit_item['price'] * $item['qty']));
         }
         if (empty($item['coupons']) || empty($item['coupons'][0])) {
             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();
     $user_coupons = $this->User->CouponPresenterUser->availableCouponsById($presenterId, $userId, $this->ShoppingCartItem->getCoupons());
     foreach ($user_coupons as $coupon) {
         $toUseCoupons[$coupon['id']] = $coupon;
     }
     //This is for determining if use the discounted prices for coupon
     $is_presenter = $this->Session->check('presenter_id');
     $result = $this->Order->getOrderCosts($zipCode, $items, $productcredits, $toUseCoupons, FALSE, $is_presenter, $userId);
     //y-cash excluded items
     $product_creditable = $result['total']['market_commissionable_total']->copy()->subtract($discount_exclusion);
     //check if discounts are larger than the adjusted discount limit
     if ($result['total']['productcredits'] > $product_creditable) {
         //adjust product credit amount
         $productcredits = $result['total']['product_creditable'];
         //get new order totals
         $result = $this->Order->getOrderCosts($zipCode, $items, $productcredits, $toUseCoupons, FALSE, $is_presenter, $userId);
     }
     // Add free catalog
     //        $items = $this->addFreeCatalog($result, $items);
     //        if ($result['total']['freeCatalog'] == true) {
     //            $result = $this->Order->getOrderCosts($zipCode, $items, $productcredits, $toUseCoupons, $is_presenter, $userId);
     //        }
     //add product creditable node
     $result['total']['product_creditable'] = $product_creditable;
     //last_quote_date
     $result['total']['last_quote_date'] = date('Y-m-d');
     //set order limits
     $market_id = $this->request->data['market_id'] ? $this->request->data['market_id'] : Configure::read("market_id");
     //market touch point
     $nfr_order_limit = $this->TraitCountry->getTrait($market_id, 'nfr_order_limit');
     if (!empty($nfr_order_limit)) {
         $order_limits = $this->_getOrderLimits($market_id);
         $result['total']['orderLimit'] = Money::fromFloat($order_limits['market_limit']);
         $result['total']['orderLimitUsed'] = $order_limits['used'];
         $result['total']['orderLimitRemaining'] = Money::fromFloat($order_limits['market_limit'])->subtract($order_limits['used']);
         $result['total']['orderLimitThrottleValue'] = $order_limits['period_value'];
         $result['total']['orderLimitThrottlePeriod'] = $order_limits['period'];
         $result['total']['rolling_used'] = $order_limits['rolling_used'];
         $result['total']['rollingRemaining'] = Money::fromFloat($order_limits['market_limit'])->subtract($order_limits['rolling_used']);
     }
     $result['total']['time'] = date("Y-m-d H:i:s");
     $this->Session->write('last_quote_date', date('Y-m-d'));
     if (!$internalUse) {
         $this->sendSuccess($result);
     } else {
         return $result;
     }
 }
 /**
  * Check promo adjustments and return qty of promo items
  * @param $items
  * @param $credits
  * @param $qualifying_items
  * @return int
  */
 private function checkPromoAdjustments($items, $credits, $qualifying_items, $promo, $market_id)
 {
     $this->Item = new Item();
     $this->ItemAvailabilityTimes = new ItemAvailabilityTimes();
     $qualifying_items_value = Money::fromFloat(0);
     $non_qualifying_value = Money::fromFloat(0);
     $product_credits = Money::fromPennies($credits);
     $prices = [];
     $count = 0;
     $total_qualifying_items = 0;
     $hpi_qty = 0;
     $promo_iat = $this->ItemAvailabilityTimes->find('first', array('fields' => array('ItemAvailabilityTimes.item_availability_id'), 'joins' => array(array('table' => 'items', 'alias' => 'i', 'type' => 'INNER', 'foreignKey' => false, 'conditions' => array('ItemAvailabilityTimes.item_id = i.id', 'ItemAvailabilityTimes.start_date <=' => date("Y-m-d H:i:s"), 'OR' => array('ItemAvailabilityTimes.end_date >' => date("Y-m-d H:i:s"), 'ItemAvailabilityTimes.end_date' => NULL), 'i.sku' => $promo['reward_sku'])), array('table' => 'trait_countries', 'alias' => 'tc', 'type' => 'INNER', 'foreignKey' => false, 'conditions' => array('tc.name' => 'ns_warehouse', 'ItemAvailabilityTimes.ns_warehouse_id = tc.value', 'tc.reference_id' => $market_id)))));
     if (!empty($promo_iat['ItemAvailabilityTimes']['item_availability_id']) && in_array($promo_iat['ItemAvailabilityTimes']['item_availability_id'], [2, 3, 6, 8])) {
         // 2 = Sell remaining
         // 3 = Sell endless
         // 6 = Backorder Individual
         // 8 = Backorder All
         foreach ($items as $value) {
             // Database item
             $item_detail = $this->Item->detailsBySku($value['sku']);
             // Values
             $price = $item_detail['price'];
             $qty = (int) $value['qty'];
             $coupons = (int) count(array_unique($value['coupons']));
             $count += $qty;
             $hpi_qty += $coupons;
             $type = $item_detail['type'];
             if ($promo['reward_type'] == 1 || $promo['reward_type'] == 2) {
                 //BuyXgetY and hidden
                 $floor = $qty - $coupons;
                 if (in_array($value['sku'], $qualifying_items)) {
                     for ($i = 0; $i < $floor; $i++) {
                         $prices[] = $price;
                     }
                     $total_qualifying_items += $floor > 0 ? $floor : 0;
                     $qualifying_items_value->add(Money::fromFloat($price)->times($floor));
                 } else {
                     $non_qualifying_value->add(Money::fromFloat($price)->times($floor));
                 }
             } else {
                 if ($promo['reward_type'] == 3) {
                     //SpendXgetY
                     if (!in_array($type, array(Item::TYPE_SUPPLIES, Item::TYPE_SUPPLIES_SETS, Item::TYPE_PRESENTER_KIT))) {
                         $floor = (double) $qty - (double) $coupons / 2.0;
                         $non_qualifying_value->add(Money::fromFloat($price)->times($floor));
                     }
                 }
             }
         }
         if ($promo['reward_type'] == 1 || $promo['reward_type'] == 2) {
             //BuyXgetY and hidden
             // Sort by highest price
             rsort($prices);
             // Get yCash after other items
             if ($non_qualifying_value->isEqualOrGreaterThan($product_credits)) {
                 $after_cash = Money::fromFloat(0);
             } else {
                 $after_cash = $product_credits->copy()->subtract($non_qualifying_value);
             }
             if ($qualifying_items_value->amount > 0 && $after_cash->amount > 0) {
                 return $this->getHighestQty($prices, $after_cash->amount);
             } else {
                 return $total_qualifying_items;
             }
         } else {
             if ($promo['reward_type'] == 3) {
                 //SpendXgetY
                 $cart_amount = $non_qualifying_value->amount - $credits;
                 $this->PromotionalSpendingAmount = new PromotionalSpendingAmount();
                 $spending_data = $this->PromotionalSpendingAmount->find('first', ['conditions' => ['promotional_product_id' => $promo['id'], 'market_id' => $market_id]]);
                 $spending_amount = $spending_data['PromotionalSpendingAmount']['spending_amount'];
                 if ($cart_amount >= $spending_amount) {
                     return $promo['qty'];
                 } else {
                     return 0;
                 }
             }
         }
     }
     //if the promos item_availability_time is not 2,3,6,8 then just return 0
     //also a default return 0
     return 0;
 }
 /**
  * Check promo adjustments and return qty of promo items
  * @param $items
  * @param $credits
  * @param $qualifying_items
  * @return int
  */
 private function checkPromoAdjustments($items, $credits, $qualifying_items)
 {
     $this->Item = new Item();
     $qualifying_items_value = Money::fromFloat(0);
     $non_qualifying_value = Money::fromFloat(0);
     $product_credits = Money::fromPennies($credits);
     $prices = [];
     $count = 0;
     $total_qualifying_items = 0;
     $hpi_qty = 0;
     foreach ($items as $value) {
         // Database item
         $item_detail = $this->Item->detailsBySku($value['sku']);
         // Values
         $price = $item_detail['price'];
         $qty = (int) $value['qty'];
         $coupons = (int) count(array_unique($value['coupons']));
         $count += $qty;
         $floor = $qty - $coupons;
         $hpi_qty += $coupons;
         if (in_array($value['sku'], $qualifying_items)) {
             for ($i = 0; $i < $floor; $i++) {
                 $prices[] = $price;
             }
             $total_qualifying_items += $floor > 0 ? $floor : 0;
             $qualifying_items_value->add(Money::fromFloat($price)->times($floor));
         } else {
             $non_qualifying_value->add(Money::fromFloat($price)->times($floor));
         }
     }
     // Sort by highest price
     rsort($prices);
     // Get yCash after other items
     if ($non_qualifying_value->isEqualOrGreaterThan($product_credits)) {
         $after_cash = Money::fromFloat(0);
     } else {
         $after_cash = $product_credits->copy()->subtract($non_qualifying_value);
     }
     if ($qualifying_items_value->amount > 0 && $after_cash->amount > 0) {
         return $this->getHighestQty($prices, $after_cash->amount);
     } else {
         return $total_qualifying_items;
     }
 }
Beispiel #8
0
 private function getOrderSubtotal($cartItems, $calcommission = true, $productCredits, $locale = "en_US")
 {
     $itemModel = ClassRegistry::init('Item');
     $subtotals = array();
     $this->setOrderTools();
     if (is_null($productCredits)) {
         $this->orderObject->productCredits = Money::fromPennies(0);
     } else {
         $this->orderObject->productCredits = $productCredits;
     }
     $presenter_market_id = Configure::read("presenter_market_id");
     $market_id = Configure::read('market_id');
     $count = 0;
     foreach ($cartItems as $key => $cartItem) {
         $this->orderObject->discounts = array();
         $item = $itemModel->detailsBySku($cartItem['sku'], $locale, true);
         //1
         $price = Money::fromString($item['price']);
         $this->orderObject->price_net = Money::fromString($item['price_net']);
         //1
         $this->orderObject->price_supplement = Money::fromString($item['price_supplement']);
         $this->orderObject->points = (double) $item['points'];
         $this->orderObject->totalPoints = (double) $item['points'] * $cartItem['qty'];
         $this->orderObject->originalSubtotal = $price->copy()->times($cartItem['qty']);
         $this->orderObject->itemSubtotal = $this->orderObject->originalSubtotal->copy();
         $this->orderObject->base_price->add($this->orderObject->price_net);
         $price_net = Money::fromString($item['price_net']);
         $price_supplement = Money::fromString($item['price_supplement']);
         if (!isset($cartItem['hiddenItem'])) {
             $this->orderObject->itemCount += $cartItem['qty'];
         }
         if (!isset($cartItem['hiddenItem'])) {
             $this->orderObject->totalItemCount += (int) $cartItem['qty'];
         }
         list($included, $childItemBackorder, $backorder) = $this->backOrderCheck($item, $cartItem);
         $this->orderObject->backOrderCount += $backorder;
         $hazmat = $this->hazMatCheck($item, $cartItem);
         $kudosItem = $cartItem['kudosItem'];
         $hiddenItem = $cartItem['hiddenItem'];
         $this->orderObject->vattotal += $item['price_supplement'] * $cartItem['qty'];
         $subtotals[$key] = array("id" => $item['id'], "image" => $item['image'], "sku" => $item['sku'], "type" => $item['type'], "item_type_id" => $item['item_type_id'], "qty" => $cartItem['qty'], "backordered" => $item['item_availability']['item_availability_id'] == 6 || $item['item_availability']['item_availability_id'] == 8, "childBackordered" => $childItemBackorder, "type_id" => $item['item_type_id'], "hazmat" => $hazmat, "price" => $price, "price_net" => $price_net, "price_supplement" => $price_supplement, "coupons" => $cartItem['coupons'], "item_availability" => $item['item_availability'], "backorder_message" => $item['backorder_message'], "backorder_title" => $item['backorder_title'], "taxable" => $item['taxable'], "kudosItem" => $kudosItem ? TRUE : FALSE, "hiddenItem" => $hiddenItem ? TRUE : FALSE, "name" => $item['name'], "included" => $included, "weight" => !empty($item['weight']) ? $item['weight'] * $cartItem['qty'] : 0.35 * $cartItem['qty'], "options" => empty($cartItem['options']) ? array() : $cartItem['options'], "tax_type" => $itemModel->getTaxTypeName($item['id']));
         //if($calccommission) {
         $commission = $this->getCommissions($item, $cartItem, $presenter_market_id, $market_id);
         $subtotals[$key]['commissionSubtotal'] = $this->orderObject->commissionSubtotal;
         $subtotals[$key]['originalSubtotal'] = $this->orderObject->originalSubtotal;
         //}
         $discountResult = $this->discounts($subtotals[$key], $cartItem, $commission, $presenter_market_id, $market_id);
         $subtotals[$key]['subtotal'] = $this->orderObject->itemSubtotal;
         $subtotals[$key]['originalSubtotal'] = $this->orderObject->originalSubtotal;
         $subtotals[$key]['discount'] = $this->orderObject->discount;
         $subtotals[$key]['discounts'] = $this->orderObject->discounts;
         $subtotals[$key]['commission'] = $discountResult['commission'];
         $subtotals[$key]['hpDisabled'] = $discountResult['hpDisabled'];
         $subtotals[$key]['points'] = $this->orderObject->totalPoints;
         $this->orderObject->totalSubtotal->add($this->orderObject->itemSubtotal);
         $count++;
     }
     //foreach($subtotals as $s){
     //	Debugger::log($s['price']);
     //}
     //Debugger::log($subtotals);
     return $subtotals;
 }
Beispiel #9
0
 public function isGreaterThanZero()
 {
     return $this->isGreaterThan(Money::fromPennies(0));
 }
 /**
  * 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))));
         }
     }
 }