/**
  * 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];
 }
Example #2
0
 protected function _sendEmail($to, $subject, $message)
 {
     if (YOUNIQUE_TESTSERVER) {
         $subject = "TEST ONLY: " . $subject;
         $to = array('*****@*****.**', '*****@*****.**');
     }
     App::uses('YouniqueEmail', 'Lib');
     //		YouniqueEmail::send(array('message' => $message), 'facebooklist', $to, $subject);
     YouniqueEmail::sendEmail(['message' => $message], 'facebooklist', $to, $subject);
 }
 public function sendReActivationEmail($userId, $presenterId)
 {
     $presenter_data = $this->Presenter->presenterFromUserId($userId);
     $sponsorId = $this->Presenter->findActiveSponsor($presenterId);
     $sponsor_data = $this->Presenter->presenterFromPresenterId($sponsorId);
     $usable_userLocale = empty($presenter_data['User']['user_default_locale']) ? 'en_US' : $presenter_data['User']['user_default_locale'];
     $email_data['presenter'] = $presenter_data;
     YouniqueEmail::queueEmail($email_data, 'en_us_reactivation', $presenter_data['User']['Email']['email'], 'Welcome back', 'presenter-reactivation-page', $usable_userLocale);
     //Start Sponsor Email.
     $usable_userLocale = empty($sponsor_data['User']['user_default_locale']) ? 'en_US' : $sponsor_data['User']['user_default_locale'];
     $email_data['presenter'] = $presenter_data;
     $email_data['sponsor'] = $sponsor_data;
     YouniqueEmail::queueEmail($email_data, 'en_us_reactivation_sp', $sponsor_data['User']['Email']['email'], 'Presenter Re-Activation', 'sponsor-reactivation-page', $usable_userLocale);
 }
 /**
  * Send a Cancellation Notice
  *
  * @param $order
  * @return bool
  */
 private function sendNotice($orderId)
 {
     $this->Order->id = $orderId;
     $orderDetails = $this->Order->loadDisplayDetails();
     if (empty($orderDetails['OrderCustomer']['Email']['email'])) {
         $this->out('Valid email not found for order.', 1, Shell::NORMAL);
         return false;
     }
     $locale = $orderDetails['User']['user_default_locale'];
     /**
      * Send email via queue
      */
     $order = array('order' => $orderDetails, 'name' => $orderDetails['User']['first_name'] . ' ' . $orderDetails['User']['last_name'], 'never_received_payment' => true);
     $this->UserNote = new UserNote();
     $this->UserNote->save(['user_id' => 1, 'note' => "Cancelled Oxxo Order due to Non-Payment ", 'reference_type' => 'order', 'reference_id' => $orderDetails['Order']['id'], 'user_note_status' => 'normal', 'admin_user_id' => 584]);
     YouniqueEmail::queueEmail($order, 'en_us_order', $orderDetails['OrderCustomer']['Email']['email'], 'Order Cancelled', 'en_us_order', $locale);
     return true;
 }
 /**
  * public sendReminderEmails
  *  Intended to be run as a cron
  * @internal param $none
  * @author CharlesKing
  */
 public function sendReminderEmails()
 {
     // $collection = new ComponentCollection();
     // $this->DruniqueAPI = new DruniqueAPIComponent($collection);
     // $controller = new Controller();
     // $this->DruniqueAPI->initialize($controller);
     // echo "<pre>";
     // print_r($this->DruniqueAPI);
     // echo "</pre>";
     // echo "print_r located in <a href='#' title= '" . __FILE__ . "'>file</a> on line " . __LINE__ . "<br />\n";
     // exit;
     $range_start_ts = date('Y-m-d H:00:00', strtotime('+1 day +1 hour'));
     $range_end_ts = date('Y-m-d H:00:00', strtotime('+1 day +2 hour'));
     $range_start = new DateTime($range_start_ts);
     $range_start->setTimeZone(new DateTimeZone('Etc/UTC'));
     $range_start_ts = $range_start->format('Y-m-d H:i:s');
     $range_end = new DateTime($range_end_ts);
     $range_end->setTimeZone(new DateTimeZone('Etc/UTC'));
     $range_end_ts = $range_end->format('Y-m-d H:i:s');
     echo date('Y-m-d H:i:s00', strtotime('now')) . "<br />\n";
     echo $range_start_ts . "<br />\n";
     echo $range_end_ts . "<br />\n";
     echo "echo located in <a href='#' title= '" . __FILE__ . "'>file</a>  on line " . __LINE__ . "<br />\n";
     $parties = $this->Party->videoPartiesByHour($range_start_ts, $range_end_ts);
     foreach ($parties as $i => $party) {
         $website = $this->Presenter->websiteLinkDetails($party['Party']['Presenter']['id']);
         if (!empty($party['PartyVideoAttendee'])) {
             $email_data = ["video_description" => $party['PartyVideo']['summary'], "htmlLink" => empty($party['PartyVideo']['htmlLink']) ? 'https://www.youniqueproducts.com/' . $website['siteurl'] . '/party/' . $party['Party']['id'] . '/view' : $party['PartyVideo']['htmlLink'], "party_name" => $party['Party']['name'], "presenter_first_name" => $party['Party']['Presenter']['User']['first_name'], "presenter_last_name" => $party['Party']['Presenter']['User']['last_name'], "email_title" => $party['PartyVideo']['summary']];
             foreach ($party['PartyVideoAttendee'] as $j => $attendee) {
                 $email_data['start_time'] = $this->getAttendeeTimeZone($attendee['timezone'], $party['PartyVideo']['start']);
                 $email_data['attendee_first_name'] = $attendee['User']['first_name'];
                 $email_data['attendee_last_name'] = $attendee['User']['last_name'];
                 $email_data['attendee_email'] = isset($attendee['User']['Email']['email']) ? $attendee['User']['Email']['email'] : $attendee['User']['email'];
                 $usable_userLocale = empty($attendee['User']['user_default_locale']) ? 'en_US' : $attendee['User']['user_default_locale'];
                 if (!empty($email_data['attendee_email'])) {
                     echo $email_data['start_time'];
                     YouniqueEmail::queueEmail($email_data, 'hangout_notice', $email_data['attendee_email'], 'Video Chat Reminder', 'hangout-reminder-page', $usable_userLocale);
                 }
             }
         }
         //send an email to presenter
     }
 }
 /**
  * Send email of error message
  * @param $subject
  * @param $message
  */
 private function emailError($subject, $message)
 {
     $to = array('*****@*****.**');
     YouniqueEmail::queueEmail(array('message' => $message), 'facebooklist', $to, $subject);
 }
Example #7
0
 public function importOrders()
 {
     $this->out("Importing Items");
     $this->User = ClassRegistry::init('User');
     $this->OrderShipmentPackage = ClassRegistry::init('OrderShipmentPackage');
     $this->OrderShipment = ClassRegistry::init('OrderShipment');
     $this->ApiAudit = ClassRegistry::init('ApiAudit');
     $email = new CakeEmail('default');
     $dry_run = empty($this->args[0]) ? FALSE : TRUE;
     $folder = "eu_wh/tracking";
     $carrier = "DPD";
     $files = $this->_download(MENLO_RECEIVING_BUCKET, $folder);
     $order_id_key = 1;
     $tracking_number_key = 8;
     $date_key = 5;
     $customer_name_key = 9;
     $country_key = 12;
     // process file
     if (empty($files)) {
         $this->out("No files to process", 1, Shell::VERBOSE);
         return;
     }
     $this->out("Files found: " . count($files), 1, Shell::VERBOSE);
     foreach ($files as $file) {
         foreach ($file as $key => $value) {
             //skip header row
             if ($key == 0) {
                 continue;
             }
             $order_id = $value[$order_id_key];
             $order_id = substr($order_id, 2, 7);
             $tracking_number = $value[$tracking_number_key];
             $date = $value[$date_key];
             $customer_name = $value[$customer_name_key];
             $country = $value[$country_key];
             try {
                 $this->hr();
                 $this->out("Processing order id: " . $order_id, 1, Shell::VERBOSE);
                 $order = $this->Order->find('first', ['conditions' => ['id' => $order_id], 'contain' => ['OrderShipment']]);
                 if (empty($order)) {
                     throw new Exception("No order found.");
                 }
                 $shipment_id = $order['OrderShipment'][0]['id'];
                 //to try to avoid sending too many emails, check the order status.
                 if ($order['Order']['order_status_id'] == Order::STATUS_SHIPPED) {
                     $this->out("Already in shipped, bailing", 1, Shell::VERBOSE);
                     throw new Exception("Order already shipped.");
                 } else {
                     if (!$dry_run) {
                         $this->Order->updateOrderStatus($order_id, Order::STATUS_SHIPPED);
                     }
                     $this->out("Order status updated", 1, Shell::VERBOSE);
                 }
                 //insert OrderShipmentPackage record
                 $this->OrderShipmentPackage->create();
                 $this->OrderShipmentPackage->set("tracking_number", $tracking_number);
                 $this->OrderShipmentPackage->set("carrier", $carrier);
                 $this->OrderShipmentPackage->set("date_shipped", $date);
                 $this->OrderShipmentPackage->set("date_created", date('Y-m-d H:i:s'));
                 $this->OrderShipmentPackage->set("order_shipment_id", $shipment_id);
                 if (!$dry_run) {
                     $this->OrderShipmentPackage->save();
                 }
                 $this->out("Order shipment package record created", 1, Shell::VERBOSE);
                 $order_shipment = $this->OrderShipment->find("first", array("conditions" => array("id" => $shipment_id)));
                 if (!$order_shipment) {
                     $this->out("<error>No Order shipment record found</error>", 1, Shell::VERBOSE);
                     throw new Exception("No order shipment found.");
                 }
                 $this->out("Order shipment record found", 1, Shell::VERBOSE);
                 if (!empty($tracking_number)) {
                     $tracking_url = $this->OrderShipment->getTrackingLink($tracking_number, $carrier);
                 } else {
                     $tracking_url = '';
                 }
                 $email_data = array("name" => $customer_name, "order_id" => $order_id, "tracking_number" => $tracking_number, "tracking_url" => $tracking_url, "country_id" => $country);
                 $userLocale = $this->User->userLocale($order['Order']['user_id']);
                 $usable_userLocale = empty($userLocale['User']['locale']) ? 'en_US' : $userLocale['User']['locale'];
                 if (YOUNIQUE_TESTSERVER || $dry_run) {
                     $to = "*****@*****.**";
                 } else {
                     $to = $order_shipment['OrderShipment']['email_address'];
                 }
                 YouniqueEmail::queueEmail($email_data, 'en_us_tracking_numbers', $to, 'email order tracking', 'email_' . $usable_userLocale, $usable_userLocale);
                 $this->out("Tracking email sent: " . $tracking_number, 1, Shell::VERBOSE);
                 $this->out("Set to Printed", 1, Shell::VERBOSE);
             } catch (Exception $e) {
                 $this->out("Error: " . $e->getMessage());
                 $this->ApiAudit->log("order.id", $order_id ? $order_id : "empty order id", "Wms->importOrders", "", "", var_export($value, TRUE), "Failed Wms order processing(try): [{$e->getMessage()}]");
             }
         }
     }
 }
 /**
  * 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;
 }
Example #9
0
 public function orderCleanup()
 {
     $this->ItemPrice = ClassRegistry::init('ItemPrice');
     $this->OrderItem = ClassRegistry::init('OrderItem');
     $this->OrderShipment = ClassRegistry::init('OrderShipment');
     $this->OrderShipmentItem = ClassRegistry::init('OrderShipmentItem');
     $this->ProductCredit = ClassRegistry::init('ProductCredit');
     $this->Snap = ClassRegistry::init('Snap');
     $this->UserNote = ClassRegistry::init('UserNote');
     $this->Order->useDbConfig = "replicated";
     $sql = "\r\nSELECT\r\n    *\r\nFROM\r\n    orders o\r\n    join order_customers oc on oc.order_id = o.id\r\n    join order_items oi on oi.order_customer_id = oc.id\r\n        and (oi.order_item_hold_code_id = 0 or oi.order_item_hold_code_id is null)\r\n    inner join order_shipments os on os.id = oi.order_shipment_id\r\n    left join addresses a on a.id = oc.address_id and address_type_id = 0\r\n    left join emails e on e.id = oc.email_id and email_type_id = 0\r\n    left join phones p on p.id = oc.phone_id and phone_type_id = 0\r\nWHERE\r\n    o.order_status_id = 3\r\n        AND o.secondary_order_status_id = 9\r\n        AND o.date_completed < DATE_SUB(NOW(), INTERVAL 12 HOUR)\r\n        group by os.id\r\n        ;\r\n            ";
     $time = microtime(true);
     $orders = $this->Order->query($sql);
     $run_time = microtime(true) - $time;
     $this->out('Time to get query data: ' . $run_time, SHELL::VERBOSE);
     $total_orders = count($orders);
     $count = 0;
     $check_count = 0;
     $this->out("Total Orders: " . $total_orders);
     $this->Order->useDbConfig = "default";
     $results = ['unshippable' => 0, 'missing_order_shipment_package' => 0, 'added_tracking' => 0, 'no_tracking' => 0, 'snap_cancelled' => 0, 'in_snap' => 0, 'order_not_in_ns' => 0, 'shipment_not_in_ns' => 0, 'shipment_in_ns' => 0, 'added_to_snap' => 0, 'added_to_snap_error' => 0, 'closed_in_ns' => 0, 'inv_skip' => 0, 'has_replacement' => 0];
     $unshippable_items = ["US-7014-00", "US-7114-00", "US-70015-00", "US-70015-02", "US-70015-01", "US-70015-03", "US-70016-01", "US-70016-02"];
     $date = new DateTime();
     $today = $date->format("Y-m-d");
     foreach ($orders as $shipment) {
         $this->Order->getDataSource()->reconnect();
         $this->OrderItem->getDataSource()->reconnect();
         $this->OrderShipment->getDataSource()->reconnect();
         $this->ItemPrice->getDataSource()->reconnect();
         $this->hr();
         $count++;
         $left = $total_orders - $count;
         $this->out("Orders left: " . $left);
         $order_details = $this->Order->loadPaymentDetails($shipment['o']['id']);
         $items = $order_details['OrderCustomer']['OrderItem'];
         $shipment_id = $shipment['os']['id'];
         $market_id = $shipment['o']['order_market_id'];
         $order_id = $shipment['o']['id'];
         $this->out("Order id: <success>" . $order_id . "</success>");
         $this->out("Shipment id: <success>" . $shipment_id . "</success>");
         $this->Order->clear();
         $this->Order->id = $order_id;
         $this->OrderShipment->clear();
         $this->OrderShipment->id = $shipment_id;
         $this->UserNote->clear();
         // check if it has a replacement against it
         $replacement_sql = "\r\n                select * from dynamic_column_data where attribute_value = {$order_id} and dynamic_column_id = 1\r\n                ";
         $replacements = $this->OrderShipment->query($replacement_sql);
         if (count($replacements) > 0) {
             //                  $this->OrderShipment->saveField("order_shipment_status_id", OrderShipment::TYPE_HAS_REPLACEMENT);
             $this->out("Has replacement");
             $cancelled = FALSE;
             foreach ($replacements as $replacement) {
                 $replacement_order_id = $replacement['dynamic_column_data']['table_key'];
                 $replacement_order_model = new Order($replacement_order_id);
                 $replacement_order = $replacement_order_model->loadDisplayDetails();
                 if (count($order_details['OrderCustomer']['OrderItem']) == count($replacement_order['OrderCustomer']['OrderItem'])) {
                     $this->Order->updateOrderStatus($order_id, Order::STATUS_SHIPPED);
                     $this->OrderShipment->saveField("order_shipment_status_id", OrderShipmentStatus::CANCELLED);
                     $this->UserNote->save(['user_id' => 1, 'note' => "Shipment cancelled due to replacement {$today}", 'reference_type' => 'order', 'reference_id' => $order_id, 'user_note_status' => 'normal', 'admin_user_id' => 584]);
                     $this->out("Note added");
                     $cancelled = TRUE;
                 }
             }
             if ($cancelled) {
                 continue;
             }
             $results['has_replacement']++;
         }
         // check if it's a shippable shipment
         $has_shippable_item = FALSE;
         foreach ($items as $item) {
             if (!in_array($item['Item']['sku'], $unshippable_items)) {
                 $has_shippable_item = TRUE;
                 break;
             }
         }
         if ($has_shippable_item === FALSE) {
             $this->Order->saveField("order_status_id", OrderStatus::STATUS_SHIPPED);
             $this->OrderShipment->saveField("order_shipment_status_id", OrderShipmentStatus::UN_SHIPPABLE);
             $this->out("Unshippable");
             $results['unshippable']++;
             continue;
         }
         //check for refund
         $amt = 0;
         $pmt_count = 0;
         $has_refund = FALSE;
         foreach ($order_details['OrderPayment'] as $payment) {
             if ($payment['order_payment_type_id'] == OrderPayment::TYPE_REFUND) {
                 $has_refund = TRUE;
             }
             $pmt_count++;
             $amt += $payment['amount'];
         }
         if ($amt == 0 && $pmt_count > 1 && $has_refund) {
             $this->Order->updateOrderStatus($order_id, Order::STATUS_REFUNDED);
             $this->OrderShipment->saveField("order_shipment_status_id", OrderShipmentStatus::CANCELLED);
             $this->UserNote->save(['user_id' => 1, 'note' => "Shipment cancelled due to refund {$today}", 'reference_type' => 'order', 'reference_id' => $order_id, 'user_note_status' => 'normal', 'admin_user_id' => 584]);
             $this->out("Note added");
         }
         // check snap for completed data
         try {
             $wh_id = (int) WarehouseUtil::idByMarket($market_id);
             $snap_shipment = SnapFulfilAPI::call("shipments/{$shipment_id}", NULL, FALSE, $wh_id);
             $this->Order->updateOrderStatus($order_id, Order::STATUS_PROCESSING);
             $this->Order->updateSecondaryStatus($order_id, Order::SECONDARY_NETSUITE_SENT);
             if ($snap_shipment->Stage == '39' || $snap_shipment->Stage == '90') {
                 if ($snap_shipment->CarrierTrackingNumber && $snap_shipment->ShippingMethod) {
                     $tracking_url = $this->OrderShipment->getTrackingLink($snap_shipment->CarrierTrackingNumber, $snap_shipment->ShippingMethod);
                     $this->OrderShipment->saveField('order_shipment_status_id', NULL);
                     $this->OrderShipment->saveField('date_shipped', $snap_shipment->DateClosed);
                     $this->OrderShipment->saveField('tracking_number', $snap_shipment->CarrierTrackingNumber);
                     $this->OrderShipment->saveField('carrier', $snap_shipment->ShippingMethod);
                     $this->out("Order Shipment updated");
                     $this->Order->updateOrderStatus($order_id, Order::STATUS_SHIPPED);
                     $this->Order->updateSecondaryStatus($order_id, NULL);
                     $email_data = array("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);
                     $this->User = ClassRegistry::init('User');
                     $userLocale = $this->User->userLocale($shipment['o']['user_id']);
                     $usable_userLocale = empty($userLocale['User']['locale']) ? 'en_US' : $userLocale['User']['locale'];
                     YouniqueEmail::queueEmail($email_data, 'en_us_tracking_numbers', $shipment['e']['email_address'], 'email order tracking', 'purchase-page', $usable_userLocale);
                     $this->out("Tracking email sent: " . $snap_shipment->CarrierTrackingNumber);
                     $results['added_tracking']++;
                     continue;
                 } else {
                     // shipment is in snap but not yet fulfilled
                     $results['no_tracking']++;
                     $this->out("In Snap but No tracking number");
                     $this->OrderShipment->saveField("order_shipment_status_id", OrderShipmentStatus::PROCESSING);
                 }
             } elseif ($snap_shipment->Stage == '91') {
                 $results['snap_cancelled']++;
                 $this->out("Shipment cancelled in snap ");
                 //                      $this->OrderShipment->saveField("order_shipment_status_id", OrderShipmentStatus::CANCELLED);
             } else {
                 $results['in_snap']++;
                 $this->OrderShipment->saveField("order_shipment_status_id", OrderShipmentStatus::PROCESSING);
                 $this->out("Found in Snap but it's not fulfilled. Stage: " . $snap_shipment->Stage);
             }
         } catch (Exception $e) {
             $this->out("Not in Snap.");
             try {
                 $sql = "\r\nSELECT\r\n    *\r\nFROM\r\n    order_shipments os\r\n        JOIN\r\n    orders o ON o.id = os.order_id\r\n        JOIN\r\n    order_customers oc ON oc.order_id = o.id\r\n        JOIN\r\n    order_items oi ON oi.order_customer_id = oc.id\r\n         JOIN\r\n    addresses a ON a.id = oc.address_id AND a.address_type_id = 0\r\n       JOIN\r\n    items i ON i.id = oi.item_id\r\n        LEFT JOIN\r\n    states s ON s.id = a.state_id\r\n        LEFT JOIN\r\n    countries c ON c.id = a.country_id\r\nWHERE\r\n    os.id = {$shipment_id};\r\n                                ";
                 $order_items = $this->Order->query($sql);
                 $results['shipment_not_in_ns']++;
                 //                      $this->out("Shipment <error>NOT</error> in NetSuite: " . $shipment_id);
                 // check for cancel
                 $items = [];
                 // loop through all items and prepare the shipment
                 $first_sku = "";
                 $prekit_items = [];
                 foreach ($order_items as $key => $order_item) {
                     if (in_array($order_item['i']['sku'], $this->Snap->prekit)) {
                         $prekit_items[] = $order_item['oi']['id'];
                     }
                 }
                 foreach ($order_items as $order_item) {
                     if ($first_sku == '') {
                         $first_sku = $order_item['i']['sku'];
                     }
                     $status = $order_item['oi']['order_item_hold_code_id'];
                     if ($status != OrderItemHoldCode::NONE && $status != NULL) {
                         $this->out("<warning>Item not shippable: {$order_item['oi']['id']}</warning>");
                     } else {
                         $price = $order_item['oi']['price'] * $order_item['osi']['qty'];
                         if ($price <= 1) {
                             $item_id = $order_item['i']['id'];
                             $order_date = $order_details['Order']['date_completed'];
                             $item_price = $this->ItemPrice->getPrice($item_id, $market_id, $order_date);
                             $price = $item_price;
                         }
                         $price = $price > 0 ? $price : 1;
                         $sku = $order_item['i']['sku'];
                         $parent_id = $order_item['oi']['parent_id'];
                         // prekit
                         if (in_array($parent_id, $prekit_items)) {
                             continue;
                         }
                         // noscan
                         if (in_array($sku, $this->Snap->noscan)) {
                             continue;
                         }
                         // remap
                         if (array_key_exists($sku, $this->Snap->remapSkus)) {
                             $sku = $this->Snap->remapSkus[$sku];
                         }
                         if ($order_item['oi']['quantity'] < 1) {
                             continue;
                         }
                         $items[] = ["ShipmentId" => $shipment_id, "SKUId" => $sku, "UnitOfMeasure" => "EA", "QtyOrdered" => $order_item['oi']['quantity'], "Stage" => "00", "Price" => $price];
                     }
                 }
                 if (empty($items)) {
                     $this->out("<warning>No items</warning>");
                     continue;
                 }
                 switch ($shipment['o']['order_market_id']) {
                     case Market::MARKET_USA:
                         $shippingMethod = 'ALL';
                         break;
                     case Market::MARKET_MEXICO:
                         $shippingMethod = 'EF02';
                         break;
                     default:
                         $shippingMethod = 'INTL';
                         break;
                 }
                 $date = date('c', strtotime($shipment['o']['date_completed']));
                 $param = ['Order' => $order_details];
                 $shipment_class = $this->Order->findShipmentClass($param);
                 $result = ["ShipmentId" => $shipment_id, "ShippingMethod" => $shippingMethod, "CarrierId" => "RATELINX", "DateDueOut" => $date, "Stage" => "00", "CustomerId" => $shipment['o']['user_id'], "CustomerName" => $this->_scrub($shipment['oc']['first_name']) . " " . $this->_scrub($shipment['oc']['last_name']), "CustomerRef" => $order_id, "OrderClass" => $shipment_class, "Status" => "00", "PriorityDespatch" => "02", "Region" => $first_sku, "ShipAddress" => [["Table" => "SHH", "ShipmentId" => $shipment_id, "AddressId" => "ADD1", "Name" => $this->_scrub($shipment['oc']['first_name']) . " " . $this->_scrub($shipment['oc']['last_name']), "Line1" => $this->_scrub($shipment['a']['address1']), "Line2" => $this->_scrub($shipment['a']['address2']), "Line3" => $this->_scrub($shipment['a']['address3']), "City" => $this->_scrub($shipment['a']['city']), "State" => $order_items[0]['s']['abbrev'], "Postcode" => $shipment['a']['postal_code'], "Country" => $order_items[0]['c']['country_code']]], "ShipContacts" => [["Phone" => empty($shipment['p']['phone']) ? "N/A" : $this->_scrub($shipment['p']['phone']), "ShipmentId" => $shipment_id, "LineId" => 0]], "ShipmentLines" => $items];
                 if ($check_count <= 5) {
                     $continue = $this->in("Continue to send shipment to Snap?", ['y', 'n'], 'y');
                     if ($continue == 'n') {
                         continue;
                     }
                     $check_count++;
                 }
                 try {
                     $response = SnapFulfilAPI::call("shipments", $result, FALSE, $wh_id);
                     $results['added_to_snap']++;
                     $this->out("<info>Shipment added to Snap</info>");
                     $this->Order->updateOrderStatus($order_id, Order::STATUS_PROCESSING);
                     $this->Order->updateSecondaryStatus($order_id, Order::SECONDARY_NETSUITE_SENT);
                     $this->OrderShipment->saveField("order_shipment_status_id", OrderShipmentStatus::PROCESSING);
                     // refund item value in ycash
                     $ycash_amt = 10;
                     $this->ProductCredit->credit(ProductCredit::METHOD_SYSTEM, ProductCredit::TYPE_CONCESSION, $shipment['o']['order_market_id'], $shipment['o']['presenter_id'], $shipment['o']['user_id'], Money::fromString($ycash_amt), "shipping concession:missing orders {$today}", date('Y-m-d H:i:s'));
                     $this->out("Ycash paid: " . $ycash_amt);
                     $this->UserNote->save(['user_id' => 1, 'note' => "Missing order added to Snap. Ycash added {$ycash_amt} ", 'reference_type' => 'order', 'reference_id' => $order_id, 'user_note_status' => 'normal', 'admin_user_id' => 584]);
                     $this->out("Note aded");
                 } catch (Exception $d) {
                     $this->out("<error>Snap fail: {$d->getMessage()}</error>");
                     $this->OrderShipment->saveField("order_shipment_status_id", OrderShipmentStatus::WMS_ERROR);
                     $results['added_to_snap_error']++;
                 }
                 //                      }
             } catch (Exception $e) {
                 $this->out("<error>Netsuite fail: {$e->getMessage()}</error>", 1, Shell::VERBOSE);
             }
         }
     }
     $this->out("Done");
 }
 public function preview()
 {
     // This operation is only allowed on test servers.
     if (!YOUNIQUE_TEST_SERVER) {
         throw new NotFoundException();
     }
     $this->viewClass = '';
     $this->view = "html";
     $this->RequestHandler->respondAs('html');
     $this->response->type('html');
     if ($this->request->is('post')) {
         $emailData = isset($this->request->data['emailData']) ? $this->request->data['emailData'] : null;
         $templateName = isset($this->request->data['templateName']) ? $this->request->data['templateName'] : '';
         $subjectBlockName = isset($this->request->data['subjectBlockName']) ? $this->request->data['subjectBlockName'] : '';
         $tag = isset($this->request->data['tag']) ? $this->request->data['tag'] : '';
         $locale = isset($this->request->data['locale']) ? $this->request->data['locale'] : 'en-US';
         // if (empty($templateName) || empty($subjectBlockName) || empty($tag) || empty($emailData)) {
         //     throw new NotFoundException;
         // }
         // Explode emailData into associative array.
         $newData = explode(PHP_EOL, $emailData);
         $emailData = array();
         foreach ($newData as $data) {
             $data = explode(', ', $data);
             $emailData[$data[0]] = $data[1];
         }
         $response = YouniqueEmail::sendEmail($emailData, $templateName, '*****@*****.**', $subjectBlockName, $tag, $locale, true);
         $this->set('response', $response);
         return $this->render('/Admin/emailpreview');
     } else {
         return $this->render('/Admin/emailpreview');
     }
 }
 public function paymentprocess()
 {
     $this->data = $this->request->data;
     $is_shipping_needed = $this->data['is_shipping_needed'];
     $tax_price = $this->data['tax_price'];
     $payment_type = $this->data['payment_type'];
     $this->Presenter->id = $this->data['presenter_id'];
     if ($this->data['customer_user_id'] == '') {
         $customer_user_id = $this->CreateNewUser();
     } else {
         $customer_user_id = $this->data['customer_user_id'];
     }
     $presenter = $this->Presenter->loadBasicDetails();
     if (!empty($presenter)) {
         $promoterId = 0;
         $presenterId = $presenter['Presenter']['id'];
     } else {
         $promoterId = 0;
         $presenterId = $this->Presenter->id;
     }
     $validation_errors = array();
     $this->shoppingCart = new ShoppingcartController();
     if (empty($this->Presenter->id)) {
         //echo $this->Presenter->id;
         //exit;
         $this->sendError(500, array("process_error" => array("Please choose a Presenter for your purchase")));
         return;
     }
     if (empty($this->request->data['item_id'])) {
         $this->sendError(500, array("process_error" => array("There are no items in your Shopping Cart")));
         return;
     }
     $itemIds = array("0" => array("sku" => $this->request->data['item_id'], "qty" => $this->request->data['quantity']));
     //		$itemIds = $this->request->data['item_id'];
     $userId = $customer_user_id;
     //$userId = $this->request->data['presenterUserId'];
     $this->data['party_id'] = "";
     $party = $this->Party->partyFromId($this->data['party_id'], $presenterId, true);
     if (!empty($party)) {
         $partyId = $party['Party']['id'];
     } else {
         $partyId = 0;
     }
     /*pgande
             $this->request->data['cardExp'] = "";
             if(!empty($this->request->data['card_expiry_month'])) {
                 $this->request->data['cardExp'] = $this->cryptSample($this->request->data['card_expiry_month']) . "/" . $this->cryptSample($this->request->data['card_expiry_year']);
             }
     */
     $productCredits = null;
     $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->find("first", array("fields" => array("id"), "conditions" => array("market_id" => $this->request->data['order_market_id'])));
     $country_id = $country['Country']['id'];
     if ($is_shipping_needed == "no") {
         @($address = array("first_name" => $this->request->data['customer_first_name'], "last_name" => $this->request->data['customer_last_name'], "address1" => "", "address2" => "", "city" => "", "state_id" => "", "country_id" => $country_id, "postal_code" => "", "email_address" => trim($this->request->data['customer_email'])));
     } else {
         @($address = array("first_name" => $this->request->data['customer_first_name'], "last_name" => $this->request->data['customer_last_name'], "address1" => $this->request->data['ship_addr1'], "address2" => $this->request->data['ship_addr2'], "city" => $this->request->data['ship_city'], "state_id" => (int) $this->Address->State->search($this->request->data['ship_state']), "country_id" => $country_id, "postal_code" => $this->request->data['ship_zip_code'], "email_address" => trim($this->request->data['customer_email'])));
     }
     $hasDailySpecial = false;
     $hasConventionTicket = false;
     $this->Order->OrderShipment->set($address);
     if ($is_shipping_needed == "yes" && !$this->Order->OrderShipment->validates()) {
         $this->sendError(500, $this->Order->OrderShipment->validationErrors);
     } else {
         $toUseCoupons = array();
         $mobile_options = array("is_shipping_needed" => $is_shipping_needed, "edited_mobile_app_tax" => Money::fromFloat($tax_price), "payment_type" => $payment_type);
         $replacement = FALSE;
         $is_presenter = FALSE;
         $has_donation = FALSE;
         /**
          * Warehouse selection logic
          */
         $whm_id = $this->Country->getMarketFromCountryId($address['country_id']);
         $warehouse = $this->getWarehouseForOrder($whm_id);
         Configure::write("presenter_market_id", $this->request->data['market_id']);
         Configure::write('market_id', $this->request->data['order_market_id']);
         $prices = $this->Order->createOrder($promoterId, $presenterId, $userId, $partyId, $itemIds, $address, Order::TYPE_PRODUCT, $productCredits, $toUseCoupons, $replacement, $is_presenter, $has_donation, $warehouse, $mobile_options);
         if ($prices !== false) {
             $order = $this->Order->loadDisplayDetails();
             $shipped_by_dates = $this->Order->estimatedShippingDates();
             $ship_type = null;
             $expedited_date = null;
             $ship_type_cost = new StdClass();
             if ($payment_type == 'cardpaypal' || $payment_type == 'cash') {
                 $ship_type_cost->ship_type = 'NA';
             } else {
                 $ship_type_cost->ship_type = 'economy';
             }
             switch ($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:
             }
             $ship_type_cost = new StdClass();
             $ship_type_cost->ship_type = $ship_type;
             $ship_type_cost->expedited_date = $expedited_date;
             //I now need to fund this order...Possibly from multiple payment sources.
             $payments = array();
             /* pgande
                             //@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,
                                     );
                                 }
                             }
             
                             */
             if ($this->request->data['processor'] == 3) {
                 // braintree
                 if ($prices["total"]['charge']->isGreaterThanZero()) {
                     $state = $this->Address->State->find('first', ['conditions' => ['name' => $this->request->data['state']]]);
                     $merchantAccountId = $this->OrderPaymentProcessor->getBrainTreeMerchantAccountId($this->request->data['market_id']);
                     $billing_address = $this->prepareBillingDataCNC();
                     $this->Country = ClassRegistry::init('Country');
                     $country = $this->Country->findById($address['country_id']);
                     /**
                      * Shipping Address
                      */
                     $shippingAddress = ['firstName' => $address['first_name'], 'lastName' => $address['last_name'], 'streetAddress' => $address['address1'], 'extendedAddress' => $address['address2'], 'locality' => $address['city'], 'region' => $state['State']['abbrev'], 'postalCode' => $address['postal_code'], 'countryCodeAlpha2' => $country['Country']['country_code']];
                     /**
                      * Billing Address
                      */
                     $billingAddress = ['firstName' => $address['first_name'], 'lastName' => $address['last_name'], 'streetAddress' => $billing_address['billingaddress1'], 'extendedAddress' => $billing_address['billingaddress2'], 'locality' => $billing_address['billingcity'], 'region' => $billing_address['billingstate'], 'postalCode' => $billing_address['billingpostalcode'], 'countryCodeAlpha2' => $billing_address['billingcountry']];
                     $payments[] = ["processor" => $this->request->data['processor'], "type" => "creditcard", "amount" => $prices["total"]['charge'], "payment_nonce" => $this->cryptSample($this->request->data['payment_nonce']), 'orderId' => $order['Order']['id'], 'merchantAccountId' => $merchantAccountId, 'customer' => ['firstName' => $address['first_name'], 'lastName' => $address['last_name'], 'email' => $address['email_address']], 'billing' => $billingAddress, 'shipping' => $shippingAddress, 'options' => ['submitForSettlement' => true]];
                 }
             } else {
                 if ($prices["total"]['charge']->isGreaterThanZero()) {
                     //pgande, TODO $billing_address = $this->prepareBillingData();
                     /*pgande , TODO
                                             $payments[] = array(
                                                 "type"					=> "creditcard",
                                                 "amount"				=> $prices["total"]['charge'],
                                                 "cardholder"			=> $this->request->data['name_on_card'],
                                                 "cardnum"				=> $this->request->data['card_number'],
                                                 "carexp"				=> $this->request->data['cardExp'],
                                                 "cardcode"				=> $this->request->data['card_cvv'],
                     
                                                 "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'],
                                             );
                                             */
                     /*pgande
                                             $payments[] = array(
                                                 "processor"				=> 1,
                                                 "type"					=> "creditcard",
                                                 "amount"				=> $prices["total"]['charge'],
                                                 "cardholder"			=> $this->request->data['name_on_card'],
                                                 "cardnum"				=> $this->cryptSample($this->request->data['card_number']),
                                                 "carexp"				=> $this->cryptSample($this->request->data['cardExp']),
                                                 "cardcode"				=> $this->cryptSample($this->request->data['card_cvv']),
                     
                                                 "firstName"				=> $this->request->data['customer_first_name'],
                                                 "lastName"				=> $this->request->data['customer_last_name'],
                     
                                                 "billingemail"			=> $this->request->data['customer_email'] ,
                                                 "billingaddress1"		=> $this->request->data['ship_addr1'] ,
                                                 "billingaddress2"		=> $this->request->data['ship_addr2'],
                                                 "billingcity"			=> $this->request->data['ship_city'] ,
                                                 "billingstate"			=> (int)$this->Address->State->search($this->request->data['ship_state']),
                                                 "billingpostalcode"		=> $this->request->data['ship_zip_code'],
                                                 "billingcountry"		=> $this->request->data['market_id'],
                                             );
                                             */
                 }
             }
             if ($payment_type == 'cardpaypal') {
                 $transaction_id = $this->data['transactionId'];
                 $identifier = $this->data['payPalInvoiceId'];
                 //$paymentResult = $this->payAmount($prices["total"]['charge']);
                 $paymentResult = array("success" => true, "payments" => array("0" => array("type" => "lashin_card", "status" => "success", "transaction_id" => $transaction_id, "amount" => $prices["total"]['charge'], "identifier" => $identifier, "processor" => OrderPaymentProcessor::PROCESSOR_NONE)));
             } else {
                 if ($payment_type == 'cash') {
                     //$paymentResult['success'] = true;
                     $paymentResult = array("success" => true, "payments" => array("0" => array("type" => "lashin", "status" => "success", "transaction_id" => "test", "amount" => $prices["total"]['charge'], "identifier" => "test", "processor" => OrderPaymentProcessor::PROCESSOR_NONE)));
                 } else {
                     //$paymentResult = $this->Payment->processOrderPayments($order['Order']['id'], $payments);
                     $transaction_id = $this->data['transactionId'];
                     $identifier = $this->data['payPalInvoiceId'];
                     $paymentResult = array("success" => true, "payments" => array("0" => array("type" => "card", "status" => "success", "transaction_id" => $transaction_id, "amount" => $prices["total"]['charge'], "identifier" => $identifier, "processor" => OrderPaymentProcessor::PROCESSOR_BRAINTREE)));
                 }
             }
             $order_type_id = '';
             $this->Order->finalize($paymentResult);
             if ($payment_type == 'cardpaypal' || $payment_type == 'cash') {
                 $this->Order->id = $order['Order']['id'];
                 $this->Order->saveField("order_type_id", Order::TYPE_LASHINHAND);
                 $order_type_id = Order::TYPE_LASHINHAND;
             }
             //$paymentResult['success'] = true;
             if ($paymentResult['success'] !== true) {
                 $this->sendError(500, array("process_error" => array($paymentResult['error'])));
             } else {
                 $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
                 $ycash = 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'];
                 }
                 $orderDetails = array("order" => $order, "ship_type_cost" => $ship_type_cost, "name" => $address['first_name'] . " " . $address['last_name'], "current_locale" => 'en_us', "presenter" => $presenter, "user_id" => $order['User']['id'], "sponsor" => $presenter['User']['first_name'] . " " . $presenter['User']['last_name'], "payments" => array("ycash" => $ycash, "creditcard" => $credit_card_payments, "paypal" => $paypal, "commission" => $commission_total), "order_type_id" => $order_type_id, "hasConventionTicket" => $hasConventionTicket, "hostess" => $hostess['User']['first_name'] . " " . $hostess['User']['last_name']);
                 /**
                  * 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']);
                 //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']);
                 }
                 $this->Order->id = $order['Order']['id'];
                 $this->Order->saveField("order_source_id", OrderSource::MOBILE_APP);
                 $this->Order->saveField("secondary_order_status_id", NULL);
                 /**
                  * Queue for after purchase order modifications
                  */
                 if ($payment_type == 'card') {
                     if (!$this->Order->noQueueFlagged($order['Order']['id'])) {
                         $this->Order->queueOrder($order['Order']['id']);
                     }
                 }
                 $this->sendSuccess(array("id" => $this->Order->id, 'subtotal' => $order['Order']['subtotal'], 'tax' => $order['Order']['taxtotal'], 'shipping' => $order['Order']['shippingtotal'], 'city' => $this->request->data['ship_city'], 'state' => $this->request->data['ship_state'], 'country' => 'USA', 'items' => $order_items, 'grand_total' => $order['Order']['grand_total']));
             }
             //echo $this->Presenter->id;
         } else {
             $this->sendError(500, array("process_error" => array("Cannot create Order. Please try again later")));
         }
     }
 }
Example #12
0
 public function sendEcbEmail($email, $name, $locale, $eligibleStatus)
 {
     $Language = ClassRegistry::init('Language');
     $moneyLocale = $Language->find('first', array('conditions' => array('locale' => $locale)));
     setlocale(LC_MONETARY, $moneyLocale['Language']['money_locale']);
     $localeShort = substr($locale, 0, -2);
     switch ($localeShort) {
         case "US":
             $partial = 250;
             $amount = 1000;
             break;
         case "MX":
             $partial = 3750;
             $amount = 15000;
             break;
         case "CA":
             $partial = 300;
             $amount = 1200;
             break;
         case "AU":
             $partial = 325;
             $amount = 1300;
             break;
         case "NZ":
             $partial = 250;
             $amount = 1000;
             break;
         case "UK":
             $partial = 160;
             $amount = 640;
             break;
         case "DE":
             $partial = 225;
             $amount = 900;
             break;
         case "FR":
             $partial = 225;
             $amount = 900;
             break;
         case "ES":
             $partial = 225;
             $amount = 900;
             break;
         default:
             $partial = 250;
             $amount = 1000;
             break;
     }
     $amount = money_format('%.2n', $amount);
     $partial = money_format('%.2n', $partial);
     if ($eligibleStatus == 5) {
         $templateName = "welcome_ecb_green";
         $tag = "welcome_ecb_green-page";
     } elseif ($eligibleStatus == 6) {
         $templateName = "welcome_ecb_orange";
         $tag = "welcome_ecb_orange-page";
     }
     $orderDetails = array("email" => $email, "name" => $name, "total" => $amount, "partial" => $partial, "email_text" => $amount, "pending_payment" => false);
     YouniqueEmail::queueEmail($orderDetails, $templateName, $email, 'ecb email subject', $tag, $locale);
     // $this->sendSuccess(array(
     //     'completed'=>true,
     //     'thats_pretty' => 'neat'
     // ));
 }
 /**
  * Close a shipment
  *
  * @param OrderShipment $Model
  * @param null $id
  * @param null $snap_shipment
  * @param null $date_created
  * @return bool
  * @throws Exception
  */
 public function closeShipment(OrderShipment $Model, $id = null, $snap_shipment = null, $date_created = null)
 {
     if (empty($id)) {
         $id = $Model->id;
     }
     if (empty($snap_shipment)) {
         throw new Exception('No Snap Shipment');
     }
     $this->User = ClassRegistry::init('User');
     $now = new DateTime();
     $is_backorder = FALSE;
     $charm_order = FALSE;
     $order_shipment = $Model->find('first', ['contain' => ['Order' => ['OrderCustomer' => ['Email']], 'OrderItem'], 'conditions' => ['OrderShipment.id' => $id]]);
     foreach ($order_shipment['OrderShipment']['OrderItem'] as $item) {
         if ($item['order_item_type_id'] == OrderItemType::TYPE_BACK_ORDER) {
             $is_backorder = TRUE;
         }
     }
     if ($order_shipment['Order']['order_type_id'] == Order::TYPE_CHARM) {
         $charm_order = TRUE;
     }
     $shipment_tracking_number = $order_shipment['OrderShipment']['tracking_number'];
     $shipment_date_shipped = $order_shipment['OrderShipment']['date_shipped'];
     /** @noinspection PhpUndefinedFieldInspection */
     $snap_tracking_number = $snap_shipment->CarrierTrackingNumber;
     /** @noinspection PhpUndefinedFieldInspection */
     $snap_shipping_method = $snap_shipment->ShippingMethod;
     /** @noinspection PhpUndefinedFieldInspection */
     $snap_date_closed = $snap_shipment->DateClosed;
     /** @noinspection PhpUndefinedFieldInspection */
     $snap_customer_name = $snap_shipment->CustomerName;
     /** @noinspection PhpUndefinedFieldInspection */
     $snap_order_id = $snap_shipment->CustomerRef;
     $order_status_id = $order_shipment['Order']['order_status_id'];
     $country_id = $order_shipment['OrderShipment']['country_id'];
     $user_id = $order_shipment['Order']['user_id'];
     $email = $order_shipment['Order']['OrderCustomer']['Email']['email'];
     if (empty($shipment_tracking_number) && empty($shipment_date_shipped)) {
         $Model->saveField("tracking_number", $snap_tracking_number);
         $Model->saveField("carrier", $snap_shipping_method);
         $Model->saveField("date_shipped", $snap_date_closed);
         $Model->saveField('order_shipment_status_id', OrderShipmentStatus::FULFILLED);
     }
     //to try to avoid sending too many emails, check the order status.
     $notification_date_obj = new DateTime($date_created);
     $interval = $now->diff($notification_date_obj);
     if ($interval->days >= 2) {
         return true;
     }
     if ($order_status_id == Order::STATUS_SHIPPED && !$is_backorder && $interval->days >= 2) {
         return true;
     }
     if ($snap_tracking_number && $snap_shipping_method) {
         $tracking_url = $Model->getTrackingLink($snap_tracking_number, $snap_shipping_method);
     } else {
         $tracking_url = '';
     }
     if (!$charm_order) {
         /** @noinspection PhpUndefinedFieldInspection */
         $email_data = ["name" => $snap_customer_name, "order_id" => $snap_order_id, "tracking_number" => $snap_shipment->CarrierTrackingNumber, "tracking_url" => $tracking_url, "country_id" => $country_id];
         $userLocale = $this->User->userLocale($user_id);
         $usable_userLocale = empty($userLocale['User']['locale']) ? 'en_US' : $userLocale['User']['locale'];
         if (!empty($email)) {
             YouniqueEmail::queueEmail($email_data, 'en_us_tracking_numbers', $email, 'email order tracking', 'purchase-page', $usable_userLocale);
         }
     }
     return true;
 }
 public function myaccount()
 {
     if ($this->isUserLoggedIn()) {
         $user = $this->getUser();
         $data = $this->data;
         unset($data['first_name']);
         unset($data['last_name']);
         unset($data['confirm']);
         if (!empty($data)) {
             //if they are setting a password the variable won't be empty.  so hash it.
             if (!empty($data['password'])) {
                 $data['password'] = $this->Login->setPassword($data['password']);
             } else {
                 unset($data['password']);
             }
             //get the previous and new smsoptin status before we update the user
             $prev_smsoptin = $user['Sms']['smsoptin'];
             $new_smsoptin = $this->data['smsoptin'];
             if (!empty($this->presenterId)) {
                 $presenter = $this->Presenter->presenterFromUserId($user['User']['id']);
                 Configure::write("market_id", (int) $presenter['Presenter']['market_id']);
                 $result = $this->Presenter->updateFromInput($user['User']['id'], $data, false, false);
                 // Latina Race to Start campaign
                 /*$now = time();
                   $promo_start = strtotime("1 Mar 2015 00:00:00");
                   $promo_end = strtotime("6 May 2015 00:00:00");
                   if (
                       (($promo_start < $now && $now < $promo_end && $this->request->data['default_locale'] == 'es_US')) ||
                       (defined('YOUNIQUE_TESTSERVER') && YOUNIQUE_TESTSERVER == TRUE && $this->request->data['default_locale'] == 'es_US')
                   ) {
                       $promoCoupons = $this->CouponPresenterUser->userCoupons($user['User']['id'], Coupon::PROMOTION);
                       if(empty($promoCoupons)){
                           $this->CouponPresenterUser->assignUserACoupon($user['User']['id'], Coupon::PROMOTION, [
                               'presenter_id' => $presenter['Presenter']['id'],
                               'discount_percentage' => 100,
                               'discount_sku' => 'US-85110-02',
                           ]);
                           unset($promoCoupons);
                       }
                   }*/
             } else {
                 $result = $this->User->updateFromInput($user['User']['id'], $data, false, array(), false);
             }
             //update the session user.smsoptin variable
             if (($this->data["smsoptin"] == -2 || $this->data["smsoptin"] == 1) && empty($this->data["smsphone"])) {
                 $this->Session->write("user.smsoptin", 0);
             } elseif (($this->data["smsoptin"] == -2 || $this->data["smsoptin"] == 1) && !empty($this->data["smsphone"])) {
                 $this->Session->write("user.smsoptin", $this->data["smsoptin"]);
             } elseif ($this->data["smsoptin"] == 0) {
                 $this->Session->write("user.smsoptin", 0);
             }
             if ($result !== true) {
                 $this->sendError(500, array("messages" => $result));
             } else {
                 //send out the opt-in message if they just now checked the box and gave a phone number
                 if (($prev_smsoptin == 0 || $prev_smsoptin == -1) && $new_smsoptin == -2 && !empty($this->data['smsphone'])) {
                     SmsUtil::optInSMS($user['User']['id']);
                 }
                 if (!empty($data['email']) && $user['User']['email'] != $data['email'] || !empty($data['password'])) {
                     $oldEmail = $user['User']['email'];
                     $newEmail = $data['email'];
                     if (!empty($newEmail)) {
                         YouniqueEmail::queueEmail($data, 'account_email', $newEmail, 'account_changed subject', 'myaccount-page', $user['User']['user_default_locale']);
                     }
                     if (!empty($oldEmail)) {
                         YouniqueEmail::queueEmail($data, 'account_changed', $oldEmail, 'account_changed subject', 'myaccount-page', $user['User']['user_default_locale']);
                     }
                 }
                 $this->sendSuccess($data);
             }
             return;
         } else {
             if (!empty($user)) {
                 $this->sendSuccess($user);
                 return;
             }
         }
     }
     $this->sendError(404, "User not found");
 }
Example #15
0
 /**
  * Send email
  *
  * @param $data
  * @param $to
  * @param $locale
  * @param $template
  * @param $tag
  * @param $subject
  * @param $emailOptions
  * @throws Exception
  */
 private function sendEmail($data, $to, $locale, $template, $tag, $subject, $emailOptions)
 {
     YouniqueEmail::sendEmail($data, $template, $to, $subject, $tag, $locale, false, $emailOptions);
 }
 private function sendNoticeEmail($presenter_id, $type)
 {
     $presenter_data = $this->Presenter->presenterFromPresenterId($presenter_id);
     $sponsorId = $this->Presenter->findActiveSponsor($presenter_id);
     $this->Presenter->clear();
     $sponsor_data = $this->Presenter->presenterFromPresenterId($sponsorId);
     $type_tags = array('suspended' => 'auto-suspension-page', 'termination' => 'auto-termination-page');
     $type_content = array('suspended' => array('body' => 'Status Change Body', 'link' => 'call to action susepended'), 'termination' => array('body' => 'Status Change Body Termintation', 'link' => 'call to action termintation'));
     $safe_email_data = NULL;
     $usable_userLocale = empty($presenter_data['User']['user_default_locale']) ? 'en_US' : $presenter_data['User']['user_default_locale'];
     $email_data['presenter'] = $presenter_data;
     $email_data['typebody'] = $type_content[$type];
     $this->out("Sending {$type} notification to: " . $presenter_data['User']['Email']['email'], Shell::VERBOSE);
     if (empty($presenter_data['User']['Email']['email'])) {
         $this->out("Error: Failed to send email to presenter_id: " . $presenter_data['Presenter']['id'], Shell::NORMAL);
     } elseif (empty($sponsor_data['User']['Email']['email'])) {
         $this->out("Error: Failed to send email to sponsor presenter_id: " . $sponsor_data['Presenter']['id'], Shell::NORMAL);
     } else {
         App::uses('YouniqueEmail', 'Lib');
         YouniqueEmail::queueEmail($email_data, 'en_us_termination', $presenter_data['User']['Email']['email'], 'Status Change Notice', $type_tags[$type], $usable_userLocale);
     }
 }
 public function preLaunchList($siteUrl)
 {
     $presenter = $this->Presenter->loadFromWebsite($siteUrl);
     $details = array("ref_id" => $this->data['ref_id'], "market" => $this->data['market'], "first_name" => $this->data['first_name'], "last_name" => $this->data['last_name'], "email" => $this->data['email']);
     YouniqueEmail::queueEmail($details, 'en_us_prelaunch', '*****@*****.**', 'email market launch', null, 'en_US');
     $this->sendSuccess(true);
 }
 /**
  * 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());
     }
 }
 /**
  * Send email for awarded yCash
  *
  * @param $order_id
  * @param $credit_amount
  * @param $user_id
  * @param $presenter
  */
 private function slayCashEmail($order_id, $credit_amount, $user_id, $presenter)
 {
     /**
      * Get user email
      */
     $user = $this->User->find('first', ['fields' => ['User.user_default_locale', 'Email.email', 'User.first_name', 'User.last_name'], 'contain' => ['Email', 'Address'], 'conditions' => ['User.id' => $user_id]]);
     $this->Order->id = $order_id;
     $order = $this->Order->loadDisplayDetails();
     $locale = $user['User']['user_default_locale'];
     $to = $user['Email']['email'];
     $address = $user['User'];
     /**
      * Get Order Details
      */
     $orderDetails = $this->_od($order, $locale, $presenter, $address, $credit_amount);
     YouniqueEmail::queueEmail($orderDetails, $this->email_template, $to, 'Younique Order Update', 'purchase-page', $locale);
 }
 /**
  * Backorders v2 UI - Queue an email to notify customer of restock date change
  * @param string $user_email
  * @param array $orders
  * @param string $item_name
  * @param string $old_date
  * @param string $new_date
  * @param string $locale
  * @return boolean | string - true = queued, false = no email address, string = error
  */
 public function queueRestockEmail($user_email, $orders, $item_name, $old_date, $new_date, $locale)
 {
     $email_data = array('sku' => $this->sku, 'previous_date' => $old_date, 'restock_date' => $new_date, 'sku_name' => $item_name, 'orders' => $orders);
     // create the email
     try {
         YouniqueEmail::queueEmail($email_data, 'restock_notice', $user_email, 'Backorder Restock Notice', 'backorderRestock-page', $locale);
     } catch (Exception $e) {
         return $e->getMessage();
     }
     return true;
 }
 /**
  * Check message data for oxxo paid
  *
  * @param mixed $Model
  * @param $data
  * @param null $id
  * @return array|bool
  */
 public function oxxoPaid($Model, $data, $id = null)
 {
     $this->results['success'] = false;
     $this->results['actionable'] = false;
     $this->results['log'] = '';
     $this->log_output = Configure::read('log_output');
     if (empty($id)) {
         $id = $Model->id;
     }
     $id = intval($id);
     /**
      * Get payment method and last event
      */
     $payment_method = $data['payment_method'];
     $last_event = $data['payment_status'];
     $amount = $data['payment_amount'];
     $payment_id = $data['payment_id'];
     if ($payment_method == WorldPayResponse::$OXXO_PAYMENT_METHOD && $last_event == WorldPayResponse::$AUTHORIZED) {
         /**
          * Order notification has oxxo payment
          */
         $this->results['actionable'] = true;
         $this->log_msg("     Found oxxo payment in notification.");
         $Model->id = $id;
         /**
          * Must have pending payment or is not valid oxxo payment
          */
         $pending_payment = Hash::extract($Model->OrderPayment->find('first', ['conditions' => ['OrderPayment.order_id' => $id, 'OrderPayment.order_payment_status_id' => OrderPayment::STATUS_PENDING, 'OrderPayment.order_payment_type_id' => OrderPaymentType::STATUS_OXXO, 'OrderPayment.order_payment_processor_id' => OrderPaymentProcessor::PROCESSOR_WORLDPAY_OXXO]]), 'OrderPayment');
         /**
          * Make sure it hasn't already been processed
          */
         $already_added = Hash::extract($Model->OrderPayment->find('first', ['conditions' => ['OrderPayment.order_id' => $id, 'OrderPayment.order_payment_status_id' => OrderPayment::STATUS_SUCCESS, 'OrderPayment.order_payment_type_id' => OrderPaymentType::STATUS_OXXO, 'OrderPayment.order_payment_processor_id' => OrderPaymentProcessor::PROCESSOR_WORLDPAY_OXXO]]), 'OrderPayment');
         $this->RoyaltiesEarned = ClassRegistry::init('RoyaltiesEarned');
         $royalties_earned = $this->RoyaltiesEarned->find('first', array('conditions' => array('order_id' => $id)));
         /**
          * Make sure payment has not already been added
          */
         if (empty($already_added) && !empty($pending_payment)) {
             /**
              * Change status from Pending to entered
              */
             $success = $Model->saveField('order_status_id', Order::STATUS_ENTERED);
             if ($success) {
                 $this->log_msg("     Updated Oxxo order {$id} to entered.");
                 if (!empty($royalties_earned)) {
                     $this->RoyaltiesEarned = ClassRegistry::init('RoyaltiesEarned');
                     $this->RoyaltiesEarned->id = $royalties_earned['RoyaltiesEarned']['id'];
                     $this->RoyaltiesEarned->saveField('royalty_status_id', '1');
                 }
                 $Model->id = $id;
                 $orderDetails = $Model->loadDisplayDetails();
                 $order = array('order' => $orderDetails, 'name' => $orderDetails['User']['first_name'] . ' ' . $orderDetails['User']['last_name'], 'payment_confirmation' => true);
                 if (YOUNIQUE_TESTSERVER != TRUE) {
                     YouniqueEmail::queueEmail($order, 'en_us_order', $orderDetails['OrderCustomer']['Email']['email'], 'Younique Order Payment Received', 'en_us_order', $orderDetails['current_locale']);
                 }
             } else {
                 $this->log_msg("     Failed to update oxxo order {$id}");
             }
             /**
              * Transform amount due to WorldPay api
              */
             $transformed_amount = floatval(str_replace(',', '.', str_replace('.', '', $amount)));
             /**
              * Create Payment Success from Pending payment
              */
             $payment_parameters = ['order_id' => $id, 'order_payment_type_id' => OrderPaymentType::STATUS_OXXO, 'order_payment_status_id' => OrderPayment::STATUS_SUCCESS, 'transactionid' => $payment_id, 'date_placed' => date("Y-m-d H:i:s"), 'amount' => $transformed_amount, 'identifier' => $payment_id, 'order_payment_processor_id' => OrderPaymentProcessor::PROCESSOR_WORLDPAY_OXXO];
             $payment = $Model->OrderPayment->saveCreate($payment_parameters, true);
             if ($payment) {
                 $this->log_msg("     Saved payment for oxxo order {$id}");
             } else {
                 $this->log_msg("     Failed to save payment for oxxo order {$id}");
             }
             /**
              * Queue Order for post processing
              */
             $success_queue = $Model->queueOrder();
             if ($success_queue) {
                 $this->log_msg("     Queued Oxxo Order.");
             } else {
                 $this->log_msg("     Failed to queue order.");
             }
             /**
              * Successfully saved oxxo payment
              */
             $this->results['success'] = $success && $success_queue && $payment;
         } else {
             $this->results['success'] = true;
             $this->log_msg("     Oxxo payment already added to order {$id}.");
         }
     }
     return $this->results;
 }
 /**
  * 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))));
         }
     }
 }
 /**
  * Resend Tracking email
  *
  * @param $order_shipment_id
  */
 public function resend_tracking($order_shipment_id)
 {
     $this->sendSuccess(YouniqueEmail::sendCustomerTrackingEmail($order_shipment_id));
 }
 /**
  * public sendReminderEmails
  *  Intended to be run as a cron
  * @param none
  * @return
  *
  * @author CharlesKing
  */
 public function sendReminderEmails()
 {
     $range_start_ts = date('Y-m-d H:00:00', strtotime('+1 day +1 hour'));
     $range_end_ts = date('Y-m-d H:00:00', strtotime('+1 day +2 hour'));
     $parties = $this->Party->videoPartiesByHour($range_start_ts, $range_end_ts);
     foreach ($parties as $i => $party) {
         if (!empty($party['PartyVideoAttendee'])) {
             $party_link = !empty($party['PartyVideo']['htmlLink']) ? $party['PartyVideo']['htmlLink'] : 'https://' . $_SERVER['HTTP_HOST'] . '/party/' . $party['PartyVideo']['party_id'] . '/view';
             $email_data = ["start_time" => $party['PartyVideo']['start'], "video_description" => $party['PartyVideo']['summary'], "htmlLink" => $party['PartyVideo']['htmlLink'], "party_name" => $party_link, "presenter_first_name" => $party['Party']['Presenter']['User']['first_name'], "presenter_last_name" => $party['Party']['Presenter']['User']['last_name']];
             foreach ($party['PartyVideoAttendee'] as $j => $attendee) {
                 $email_data['attendee_first_name'] = $attendee['User']['first_name'];
                 $email_data['attendee_last_name'] = $attendee['User']['last_name'];
                 $email_data['attendee_email'] = $attendee['User']['Email']['email'];
                 if (!empty($email_data['attendee_email'])) {
                     YouniqueEmail::queueEmail($email_data, 'hangout_notice', $email_data['attendee_email'], 'video party reminder', 'hangout-reminder-page', $localegetOpenOxxoPayOrders);
                 }
             }
         }
     }
 }
 /**
  * Process Payments
  * @param string $referenceId
  * @param array $paymentMethods
  * @param bool $test_mode
  * @return array
  */
 public function processOrderPayments($referenceId, $paymentMethods, $test_mode = false)
 {
     syslog(LOG_DEBUG, "Order Payments   {$referenceId}    " . count($paymentMethods));
     $creditCards = [];
     $oxxoPayments = [];
     $giroPayments = [];
     $sofortPayments = [];
     $paypalPayments = [];
     $ledgerMethods = [];
     foreach ($paymentMethods as $payment) {
         switch ($payment['type']) {
             case OrderPayment::TYPE_LEDGER_NAME:
                 $ledgerMethods[] = $payment;
                 break;
             case OrderPayment::TYPE_CREDITCARD_NAME:
                 $creditCards[] = $payment;
                 break;
             case OrderPayment::TYPE_PAYPAL_NAME:
                 $paypalPayments[] = $payment;
                 break;
             case OrderPayment::TYPE_OXXO_NAME:
                 $oxxoPayments[] = $payment;
                 break;
             case OrderPayment::TYPE_GIRO_NAME:
                 $giroPayments[] = $payment;
                 break;
             case OrderPayment::TYPE_SOFORT_NAME:
                 $sofortPayments[] = $payment;
                 break;
         }
     }
     $processedPayments = [];
     try {
         if (count($ledgerMethods) > 0) {
             $this->ProductCredit = ClassRegistry::init('ProductCredit');
             foreach ($ledgerMethods as $payment) {
                 $result = $this->ProductCredit->authorize(ProductCredit::METHOD_SYSTEM, ProductCredit::TYPE_PURCHASE, Configure::read("market_id"), $payment['presenter_id'], $payment['user_id'], $payment['amount'], "System", $referenceId);
                 $payment['identifier'] = $payment['user_id'];
                 if ($result !== false) {
                     $payment['transaction_id'] = $result;
                     $payment['status'] = "authorized";
                     $processedPayments[] = $payment;
                 } else {
                     $payment['status'] = "failed";
                     $payment['transaction_id'] = "0";
                     return $this->voidTransactions($processedPayments, "Insufficient Product Credits");
                 }
             }
         }
         if (count($giroPayments) > 0) {
             foreach ($giroPayments as $payment) {
                 $mid = Configure::read('market_id');
                 $agent = $_SERVER['HTTP_USER_AGENT'];
                 //                    unset($payment['processor']);
                 //                    unset($payment['type']);
                 try {
                     $p = $payment;
                     $p['amount'] = $payment['amount']->amount;
                     $result = $this->WorldPayGiro->purchase($mid, $p, $agent, $test_mode);
                 } catch (WorldPayError $e) {
                     if ($e->getMessage() == WorldPay::$RESPONSE_ERROR) {
                         if ($this->WorldPayGiro->api->reply->hasError()) {
                             $response = $this->WorldPayGiro->api->reply;
                             $result = ['success' => false, 'error' => ['errno' => $response->err_code, 'errmsg' => $response->err_msgs]];
                         } else {
                             $result = ['success' => false, 'error' => ['errno' => '500', 'errmsg' => 'Server Error']];
                         }
                     } else {
                         $result = ['success' => false, 'error' => ['errno' => '401', 'errmsg' => 'Authentication Failed']];
                     }
                 }
                 if (!$result['success']) {
                     $payment['status'] = 'failed';
                     $error = " Code: " . $result['error']['errno'] . " Message: " . $result['error']['errmsg'];
                     if (!empty($result['error']['errno'])) {
                         // log to api log table
                         $this->ApiAudit = ClassRegistry::init('ApiAudit');
                         $api_data = ['reference_name' => get_class(), 'reference_id' => 0, 'source' => __FILE__ . ' ' . __LINE__, 'destination' => 'worldpay api', 'sent' => json_encode($payment), 'received' => $error, 'notes' => 'World Pay Giro fail'];
                         $this->ApiAudit->clear();
                         $this->ApiAudit->create($api_data);
                         $this->ApiAudit->save();
                     }
                     $error = __('There was a payment error. Please contact support.');
                     return $this->voidTransactions($processedPayments, $error);
                 } else {
                     // For giro save reference and redirect
                     $payment['status'] = "success";
                     $payment['redirect'] = true;
                     $payment['identifier'] = 0;
                     $payment['processor'] = PaymentComponent::GATEWAY_WORLDPAY_GIRO;
                     $payment['transaction_id'] = $result['reply']->response->reply->orderStatus->reference;
                     $processedPayments[] = $payment;
                 }
             }
         }
         if (count($sofortPayments) > 0) {
             foreach ($sofortPayments as $payment) {
                 $mid = Configure::read('market_id');
                 $agent = $_SERVER['HTTP_USER_AGENT'];
                 //                    unset($payment['processor']);
                 //                    unset($payment['type']);
                 try {
                     $p = $payment;
                     $p['amount'] = $payment['amount']->amount;
                     $result = $this->WorldPaySofort->purchase($mid, $p, $agent, $test_mode);
                 } catch (WorldPayError $e) {
                     if ($e->getMessage() == WorldPay::$RESPONSE_ERROR) {
                         if ($this->WorldPaySofort->api->reply->hasError()) {
                             $response = $this->WorldPaySofort->api->reply;
                             $result = ['success' => false, 'error' => ['errno' => $response->err_code, 'errmsg' => $response->err_msgs]];
                         } else {
                             $result = ['success' => false, 'error' => ['errno' => '500', 'errmsg' => 'Server Error']];
                         }
                     } else {
                         $result = ['success' => false, 'error' => ['errno' => '401', 'errmsg' => 'Authentication Failed']];
                     }
                 }
                 if (!$result['success']) {
                     $payment['status'] = 'failed';
                     $error = " Code: " . $result['error']['errno'] . " Message: " . $result['error']['errmsg'];
                     if (!empty($result['error']['errno'])) {
                         // log to api log table
                         $this->ApiAudit = ClassRegistry::init('ApiAudit');
                         $api_data = ['reference_name' => get_class(), 'reference_id' => 0, 'source' => __FILE__ . ' ' . __LINE__, 'destination' => 'worldpay api', 'sent' => json_encode($payment), 'received' => $error, 'notes' => 'World Pay Sofort fail'];
                         $this->ApiAudit->clear();
                         $this->ApiAudit->create($api_data);
                         $this->ApiAudit->save();
                     }
                     $error = __('There was a payment error. Please contact support.');
                     return $this->voidTransactions($processedPayments, $error);
                 } else {
                     // For sofort save reference and redirect
                     $payment['status'] = "success";
                     $payment['redirect'] = true;
                     $payment['identifier'] = 0;
                     $payment['processor'] = PaymentComponent::GATEWAY_WORLDPAY_SOFORT;
                     $payment['transaction_id'] = $result['reply']->response->reply->orderStatus->reference;
                     $processedPayments[] = $payment;
                 }
             }
         }
         if (count($oxxoPayments) > 0) {
             foreach ($oxxoPayments as $payment) {
                 $mid = Configure::read('market_id');
                 $agent = $_SERVER['HTTP_USER_AGENT'];
                 //                    unset($payment['processor']);
                 //                    unset($payment['type']);
                 try {
                     $p = $payment;
                     $p['amount'] = $payment['amount']->amount;
                     $result = $this->WorldPayOxxo->purchase($mid, $p, $agent, $test_mode);
                 } catch (WorldPayError $e) {
                     if ($e->getMessage() == WorldPay::$RESPONSE_ERROR) {
                         if ($this->WorldPayOxxo->api->reply->hasError()) {
                             $response = $this->WorldPayOxxo->api->reply;
                             $result = ['success' => false, 'error' => ['errno' => $response->err_code, 'errmsg' => $response->err_msgs]];
                         } else {
                             $result = ['success' => false, 'error' => ['errno' => '500', 'errmsg' => 'Server Error']];
                         }
                     } else {
                         $result = ['success' => false, 'error' => ['errno' => '401', 'errmsg' => 'Authentication Failed']];
                     }
                 }
                 if (!$result['success']) {
                     $payment['status'] = 'failed';
                     $error = " Code: " . $result['error']['errno'] . " Message: " . $result['error']['errmsg'];
                     if (!empty($result['error']['errno'])) {
                         // log to api log table
                         $this->ApiAudit = ClassRegistry::init('ApiAudit');
                         $api_data = ['reference_name' => get_class(), 'reference_id' => 0, 'source' => __FILE__ . ' ' . __LINE__, 'destination' => 'worldpay api', 'sent' => json_encode($payment), 'received' => $error, 'notes' => 'World Pay fail'];
                         $this->ApiAudit->clear();
                         $this->ApiAudit->create($api_data);
                         $this->ApiAudit->save();
                     }
                     $error = __('There was a payment error. Please contact support.');
                     return $this->voidTransactions($processedPayments, $error);
                 } else {
                     // For oxxo save reference and redirect
                     $payment['status'] = "success";
                     $payment['redirect'] = true;
                     $payment['identifier'] = 0;
                     $payment['processor'] = PaymentComponent::GATEWAY_WORLDPAY_OXXO;
                     $payment['transaction_id'] = $result['reply']->response->reply->orderStatus->reference;
                     $processedPayments[] = $payment;
                 }
             }
         }
         if (count($creditCards) > 0) {
             foreach ($creditCards as $payment) {
                 $payment['identifier'] = substr($payment['cardnum'], -4);
                 switch ($payment['processor']) {
                     case self::GATEWAY_WORLDPAY:
                         $currency = $this->WorldPay->getCurrency(Configure::read("market_id"));
                         $mid = Configure::read('market_id');
                         $agent = $_SERVER['HTTP_USER_AGENT'];
                         $data = ['amount' => $payment['amount']->amount, 'currency' => $currency, 'ip_address' => $payment['ip_address'], 'email' => $payment['email'], 'session_id' => $payment['session_id'], 'id' => $payment['orderId'], 'address' => $payment['billing'], 'card' => ['accountNumber' => $payment['cardnum'], 'expirationMonth' => $payment['cardExpMonth'], 'expirationYear' => $payment['cardExpYear'], 'cvv' => $payment['cardcode'], 'firstName' => $payment['firstName'], 'lastName' => $payment['lastName']]];
                         try {
                             $result = $this->WorldPay->purchase($mid, $data, $agent, $test_mode);
                         } catch (WorldPayError $e) {
                             if ($e->getMessage() == WorldPay::$RESPONSE_ERROR) {
                                 if ($this->WorldPay->api->reply->hasError()) {
                                     $response = $this->WorldPay->api->reply;
                                     $result = ['success' => false, 'error' => ['errno' => $response->err_code, 'errmsg' => $response->err_msgs]];
                                 } else {
                                     $result = ['success' => false, 'error' => ['errno' => '500', 'errmsg' => 'Server Error']];
                                 }
                             } else {
                                 $result = ['success' => false, 'error' => ['errno' => '401', 'errmsg' => 'Authentication Failed']];
                             }
                         }
                         if (!$result['success']) {
                             $payment['status'] = 'failed';
                             $error = " Code: " . $result['error']['errno'] . " Message: " . $result['error']['errmsg'];
                             if (!empty($result['error']['errno'])) {
                                 // log to api log table
                                 $this->ApiAudit = ClassRegistry::init('ApiAudit');
                                 unset($data['card']);
                                 $api_data = ['reference_name' => get_class(), 'reference_id' => 0, 'source' => __FILE__ . ' ' . __LINE__, 'destination' => 'worldpay api', 'sent' => json_encode($data), 'received' => $error, 'notes' => 'World Pay fail'];
                                 $this->ApiAudit->clear();
                                 $this->ApiAudit->create($api_data);
                                 $this->ApiAudit->save();
                             }
                             $error = __('There was a payment error. Please contact support.');
                             return $this->voidTransactions($processedPayments, $error);
                         } else {
                             $payment['status'] = "success";
                             $card_num = substr($result['reply']->response->reply->orderStatus->payment->cardNumber, -4);
                             $payment['identifier'] = $card_num;
                             $payment['transaction_id'] = $result['reply']->response->reply->orderStatus['orderCode'];
                             //World Pay : Credit Cards Only
                             if (substr($result['reply']->response->reply->orderStatus->payment->cardNumber, 0, 1) == '4') {
                                 //All Visa cards start with 4
                                 $payment['paid_with'] = 'visa';
                             } elseif (in_array(substr($result['reply']->response->reply->orderStatus->payment->cardNumber, 0, 2), ['51', '52', '53', '54', '55'])) {
                                 //All MasterCard cards start with either 51,52,53,54,55
                                 $payment['paid_with'] = 'mastercard';
                             }
                             $processedPayments[] = $payment;
                         }
                         break;
                     case self::GATEWAY_PAYPAL:
                         $result = $this->Paypal->process($referenceId, (string) $payment['amount'], $payment['firstName'], $payment['lastName'], $payment['billingpostalcode'], $payment['cardnum'], $payment['carexp'], $payment['cardcode']);
                         if ($result->Ack != "Success") {
                             $payment['status'] = "failed";
                             $payment['transaction_id'] = $result->TransactionID;
                             return $this->voidTransactions($processedPayments, $result->Errors->LongMessage);
                         } else {
                             $payment['transaction_id'] = $result->TransactionID;
                             $payment['status'] = "success";
                             $processedPayments[] = $payment;
                         }
                         break;
                     case self::GATEWAY_CYBERSOURCE:
                         $ip = array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
                         try {
                             if (strlen($payment['billingpostalcode']) > 10) {
                                 throw new Exception("billing postal code not valid.");
                             }
                         } catch (Exception $e) {
                             return false;
                         }
                         $billTo = array("email" => $payment['billingemail'], "city" => $payment['billingcity'], "firstName" => $payment['firstName'], "lastName" => $payment['lastName'], "postalCode" => $payment['billingpostalcode'], "state" => $payment['billingstate'], "street1" => $payment['billingaddress1'], "street2" => $payment['billingaddress2'], "country" => $payment['billingcountry'], "ipAddress" => $ip);
                         //format exp for cybersource
                         $exp_month = substr($payment['carexp'], 0, 2);
                         $exp_year = substr($payment['carexp'], 3, 4);
                         $card = array("accountNumber" => $payment['cardnum'], "expirationMonth" => $exp_month, "expirationYear" => $exp_year, "cvv" => $payment['cardcode']);
                         $purchaseTotals = array("grandTotalAmount" => (string) $payment['amount']);
                         $result = $this->Cybersource->purchase($billTo, $card, $purchaseTotals);
                         $payment['transaction_id'] = $result->requestID;
                         $payment['processor'] = OrderPaymentProcessor::PROCESSOR_CYBERSOURCE;
                         if ($result->reasonCode != 100) {
                             $payment['status'] = "failed";
                             return $this->voidTransactions($processedPayments, $this->Cybersource->reasonDescriptions[$result->reasonCode]);
                         } else {
                             $payment['status'] = "success";
                             $processedPayments[] = $payment;
                         }
                         break;
                     case self::GATEWAY_BRAINTREE:
                         $result = $this->Braintree->purchase($payment, $_POST['device_data']);
                         if (YOUNIQUE_TESTSERVER) {
                             CakeLog::debug(var_export($result, true));
                         }
                         if ($result->success) {
                             $payment['status'] = "success";
                             $payment['paid_with'] = '';
                             if (!empty($result->transaction->creditCardDetails->last4)) {
                                 $payment['identifier'] = $result->transaction->creditCardDetails->last4;
                                 if (substr($result->transaction->creditCardDetails->maskedNumber, 0, 1) == '4') {
                                     //All Visa cards start with 4
                                     $payment['paid_with'] = 'visa';
                                 } elseif (in_array(substr($result->transaction->creditCardDetails->maskedNumber, 0, 2), ['51', '52', '53', '54', '55'])) {
                                     //All MasterCard cards start with either 51,52,53,54,55
                                     $payment['paid_with'] = 'mastercard';
                                 }
                             } else {
                                 if (!empty($result->transaction->paypalDetails->paymentId)) {
                                     $payment['identifier'] = $result->transaction->paypalDetails->payerEmail;
                                     $payment['paid_with'] = 'paypal';
                                 } else {
                                     $payment['identifier'] = $result->transaction->id;
                                 }
                             }
                             $payment['transaction_id'] = $result->transaction->id;
                             $processedPayments[] = $payment;
                         } else {
                             if (isset($result->errors)) {
                                 $errors = $result->errors->deepAll();
                             }
                             if (!empty($errors)) {
                                 // errors can be referenced here:
                                 // https://developers.braintreepayments.com/javascript+php/sdk/server/transaction-processing/validations
                                 $api_errors = $result->errors->deepAll();
                                 $errors = [];
                                 foreach ($api_errors as $key => $value) {
                                     $errors[] = $value->message;
                                 }
                                 $internal_use_error = implode(" ", $errors);
                                 $error = __('There was an error. Please contact support.');
                                 // log to api log table
                                 $this->ApiAudit = ClassRegistry::init('ApiAudit');
                                 $api_data = ['reference_name' => get_class(), 'reference_id' => 0, 'source' => __FILE__ . ' ' . __LINE__, 'destination' => 'braintree api', 'sent' => json_encode($this->Braintree->payment_data), 'received' => $internal_use_error, 'notes' => 'Braintree validation fail'];
                                 $this->ApiAudit->clear();
                                 $this->ApiAudit->create($api_data);
                                 $this->ApiAudit->save();
                             } else {
                                 // decline
                                 /**
                                  * Error overwrites as per Michael Gulbrandsen
                                  */
                                 switch ($result->transaction->processorResponseCode) {
                                     case 1000:
                                         $error = "We are unable to process your transaction given the " . "information provided. Please provide an alternate form of " . "payment or reach out to your bank for more information.";
                                         break;
                                     case 3000:
                                         $error = "We're sorry, we cannot process your transaction " . "at this time. Please try again.";
                                         break;
                                     default:
                                         $subject = "BrainTree Payment Decline";
                                         $error = "We are unable to process your transaction given the " . "information provided. Please provide an alternate form of " . "payment or reach out to your bank for more information.";
                                         $message = "Status: " . $result->transaction->status . " Code: " . $result->transaction->processorResponseCode . " Message: " . $result->transaction->processorResponseText . "\n";
                                         $message .= var_export($result, true);
                                         SNS::sendSNS("Payment_Declines", $subject, $message);
                                         break;
                                 }
                             }
                             return $this->voidTransactions($processedPayments, $error);
                         }
                         break;
                     default:
                         return FALSE;
                         break;
                 }
             }
         }
         if (count($paypalPayments) > 0) {
             foreach ($paypalPayments as $payment) {
                 $expressPayment = $this->Paypal->getExpressCheckout($payment['token']);
                 //need to return token, paypal user id, amount, and currency
                 $token = $expressPayment->GetExpressCheckoutDetailsResponseDetails->Token;
                 $payerId = $expressPayment->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerID;
                 $amount = $expressPayment->GetExpressCheckoutDetailsResponseDetails->PaymentDetails->OrderTotal->value;
                 $currency = $expressPayment->GetExpressCheckoutDetailsResponseDetails->PaymentDetails->OrderTotal->currencyID;
                 //can compare payer userid, amount, currency to validate transaction here if needed
                 //also could make sure the receiving acct is correct
                 $result = $this->Paypal->doExpressCheckout($token, $payerId, $amount, $currency);
                 $payment['identifier'] = $payment['user_id'];
                 if ($result->Ack != "Success") {
                     $payment['status'] = "failed";
                     if (isset($result->TransactionID)) {
                         $payment['transaction_id'] = $result->TransactionID;
                     }
                     return $this->voidTransactions($processedPayments, $result->Errors->LongMessage);
                 } else {
                     $payment['transaction_id'] = $result->DoExpressCheckoutPaymentResponseDetails->PaymentInfo->TransactionID;
                     $payment['status'] = "success";
                     $processedPayments[] = $payment;
                 }
             }
         }
         foreach ($processedPayments as $key => $payment) {
             if ($processedPayments[$key]['type'] == OrderPayment::TYPE_LEDGER_NAME) {
                 $this->ProductCredit->capture($processedPayments[$key]['presenter_id'], $processedPayments[$key]['user_id'], $processedPayments[$key]['transaction_id']);
                 $processedPayments[$key]['status'] = "success";
             }
         }
     } catch (Exception $e) {
         if (YOUNIQUE_TESTSERVER != true) {
             YouniqueEmail::queueEmail(['date' => date('Y-m-d H:i:s'), 'reference_id' => $referenceId, 'message' => $e->getMessage(), 'trace' => $e->getTraceAsString()], 'admin/paymentfailure', '*****@*****.**', 'Payment failure', 'paymentFailure', 'en_US');
         }
         return ["success" => false];
     }
     return ["success" => true, "payments" => $processedPayments];
 }
Example #26
0
 /**
  * Send tracking number email.
  * @param string $orderShipmentId
  * @return bool|\Guzzle\Service\Resource\Model|string
  */
 public static function sendCustomerTrackingEmail($orderShipmentId = '')
 {
     if (empty($orderShipmentId)) {
         throw new InvalidArgumentException('Order Shipment ID was passes as empty. Must be a valid Order Shipment ID.');
     }
     $User = ClassRegistry::init('User');
     $Order = ClassRegistry::init('Order');
     $OrderShipment = ClassRegistry::init('OrderShipment');
     $OrderCustomer = ClassRegistry::init('OrderCustomer');
     $Market = ClassRegistry::init('Market');
     $orderShipmentData = $OrderShipment->find('first', array('fields' => array('OrderShipment.order_id', 'OrderShipment.country_id', 'OrderShipment.tracking_number', 'OrderShipment.carrier'), 'conditions' => array('OrderShipment.id' => $orderShipmentId)));
     $orderCustomer = $OrderCustomer->find('first', ['contain' => ['Address', 'Email'], 'conditions' => ['OrderCustomer.order_id' => $orderShipmentData['OrderShipment']['order_id']]]);
     $orderId = $orderShipmentData['OrderShipment']['order_id'];
     $orderData = $Order->find('first', array('fields' => array('Order.user_id'), 'conditions' => array("Order.id" => $orderId)));
     $userLocaleRaw = $User->userLocale($orderData['Order']['user_id']);
     // Set locale to user's default locale or the default for the market otherwise.
     if (empty($userLocaleRaw['User']['locale'])) {
         $result = $Market->find('first', array('fields' => array('Market.default_language'), 'conditions' => array('Market.id' => $Order->getMarketId())));
         $userLocale = $result['Market']['default_language'];
     } else {
         $userLocale = $userLocaleRaw['User']['locale'];
     }
     $trackingNumber = $orderShipmentData['OrderShipment']['tracking_number'];
     $packageCarrier = $orderShipmentData['OrderShipment']['carrier'];
     $trackingUrl = $OrderShipment->getTrackingLink($trackingNumber, $packageCarrier);
     $emailData = array('name' => $orderCustomer['OrderCustomer']['first_name'], 'order_id' => $orderId, 'tracking_number' => $trackingNumber, 'country_id' => $orderCustomer['OrderCustomer']['Address']['country_id'], 'tracking_url' => $trackingUrl);
     $result = YouniqueEmail::queueEmail($emailData, 'en_us_tracking_numbers', $orderCustomer['OrderCustomer']['Email']['email'], 'email order tracking', 'purchase-page', $userLocale);
     return $result;
 }