public function display()
 {
     if (!$this->form) {
         $this->form = shopHelper::getCustomerForm();
     }
     $contact = $this->getContact();
     if ($contact) {
         $this->form->setValue($contact);
         // Make sure there are no more than one address of each type in the form
         foreach (array('address', 'address.shipping', 'address.billing') as $fld) {
             if (isset($this->form->values[$fld]) && count($this->form->values[$fld]) > 1) {
                 $this->form->values[$fld] = array(reset($this->form->values[$fld]));
             }
         }
     }
     $view = wa()->getView();
     $view->assign('checkout_contact_form', $this->form);
     $view->assign('customer', $contact ? $contact : new waContact());
     if (!$view->getVars('error')) {
         $view->assign('error', array());
     }
     $checkout_flow = new shopCheckoutFlowModel();
     $step_number = shopOnestepCheckout::getStepNumber('contactinfo');
     // IF no errors
     $checkout_flow->add(array('step' => $step_number));
     // ELSE
     //        $checkout_flow->add(array(
     //            'step' => $step_number,
     //            'description' => ERROR MESSAGE HERE
     //        ));
 }
 public function display()
 {
     $settings = wa('shop')->getConfig()->getCheckoutSettings();
     if (!empty($settings['confirmation']['terms']) && waRequest::get('terms')) {
         echo $settings['confirmation']['terms'];
         exit;
     }
     $cart = new shopCart();
     $items = $cart->items(false);
     $subtotal = $cart->total(false);
     $order = array('contact' => $this->getContact(), 'total' => $subtotal, 'items' => $items);
     $order['discount'] = shopDiscounts::calculate($order);
     $contact = $this->getContact();
     $view = wa()->getView();
     if (!$contact) {
         $view->assign('error', _w('Not enough data in the contact information to place the order.'));
         return;
     }
     $shipping_address = $contact->getFirst('address.shipping');
     if (!$shipping_address) {
         $shipping_address = array('data' => array(), 'value' => '');
     }
     $billing_address = $contact->getFirst('address.billing');
     if (!$billing_address) {
         $billing_address = array('data' => array(), 'value' => '');
     }
     $discount_rate = (double) $subtotal ? $order['discount'] / $subtotal : 0;
     $taxes = shopTaxes::apply($items, array('shipping' => $shipping_address['data'], 'billing' => $billing_address['data'], 'discount_rate' => $discount_rate));
     $tax = 0;
     $tax_included = 0;
     foreach ($taxes as $t) {
         if (isset($t['sum'])) {
             $tax += $t['sum'];
         }
         if (isset($t['sum_included'])) {
             $tax_included += $t['sum_included'];
         }
     }
     if (!isset($order['shipping'])) {
         $shipping_step = new shopOnestepCheckoutShipping();
         $rate = $shipping_step->getRate();
         if ($rate) {
             $order['shipping'] = $rate['rate'];
         } else {
             $order['shipping'] = 0;
         }
     }
     $plugin_model = new shopPluginModel();
     $params = array();
     if ($shipping = $this->getSessionData('shipping')) {
         $params['shipping_id'] = $shipping['id'];
         if ($shipping['id']) {
             $plugin_info = $plugin_model->getById($shipping['id']);
             $params['shipping_rate_id'] = $shipping['rate_id'];
             $params['shipping_name'] = $shipping['name'];
             $params['shipping_description'] = $plugin_info['description'];
         }
     }
     if ($payment_id = $this->getSessionData('payment')) {
         $params['payment_id'] = $payment_id;
         $plugin_info = $plugin_model->getById($payment_id);
         $params['payment_name'] = $plugin_info['name'];
         $params['payment_plugin'] = $plugin_info['plugin'];
         $params['payment_description'] = $plugin_info['description'];
     }
     $view->assign(array('params' => $params, 'contact' => $contact, 'items' => $items, 'shipping' => $order['shipping'], 'discount' => $order['discount'], 'total' => $subtotal - $order['discount'] + $order['shipping'] + $tax, 'tax' => $tax_included + $tax, 'subtotal' => $subtotal, 'shipping_address' => $shipping_address, 'billing_address' => !empty($settings['contactinfo']['fields']['address.billing']) ? $billing_address : false, 'terms' => !empty($settings['confirmation']['terms']) ? $settings['confirmation']['terms'] : false));
     $checkout_flow = new shopCheckoutFlowModel();
     $step_number = shopOnestepCheckout::getStepNumber('confirmation');
     // IF no errors
     $checkout_flow->add(array('step' => $step_number));
     // ELSE
     //        $checkout_flow->add(array(
     //            'step' => $step_number,
     //            'description' => ERROR MESSAGE HERE
     //        ));
 }
 protected function createOrder()
 {
     $checkout_data = wa()->getStorage()->get('shop/checkout');
     if (wa()->getUser()->isAuth()) {
         $contact = wa()->getUser();
     } else {
         if (!empty($checkout_data['contact']) && $checkout_data['contact'] instanceof waContact) {
             $contact = $checkout_data['contact'];
         } else {
             $contact = new waContact();
         }
     }
     $cart = new shopCart();
     $items = $cart->items(false);
     // remove id from item
     foreach ($items as &$item) {
         unset($item['id']);
         unset($item['parent_id']);
     }
     unset($item);
     $order = array('contact' => $contact, 'items' => $items, 'total' => $cart->total(false), 'params' => isset($checkout_data['params']) ? $checkout_data['params'] : array());
     $order['discount_description'] = null;
     $order['discount'] = shopDiscounts::apply($order, $order['discount_description']);
     if (isset($checkout_data['shipping'])) {
         $order['params']['shipping_id'] = $checkout_data['shipping']['id'];
         $order['params']['shipping_rate_id'] = $checkout_data['shipping']['rate_id'];
         $shipping_step = new shopOnestepCheckoutShipping();
         $rate = $shipping_step->getRate($order['params']['shipping_id'], $order['params']['shipping_rate_id']);
         $order['params']['shipping_plugin'] = $rate['plugin'];
         $order['params']['shipping_name'] = $rate['name'];
         if (isset($rate['est_delivery'])) {
             $order['params']['shipping_est_delivery'] = $rate['est_delivery'];
         }
         if (!isset($order['shipping'])) {
             $order['shipping'] = $rate['rate'];
         }
         if (!empty($order['params']['shipping'])) {
             foreach ($order['params']['shipping'] as $k => $v) {
                 $order['params']['shipping_params_' . $k] = $v;
             }
             unset($order['params']['shipping']);
         }
     } else {
         $order['shipping'] = 0;
     }
     if (isset($checkout_data['payment'])) {
         $order['params']['payment_id'] = $checkout_data['payment'];
         $plugin_model = new shopPluginModel();
         $plugin_info = $plugin_model->getById($checkout_data['payment']);
         $order['params']['payment_name'] = $plugin_info['name'];
         $order['params']['payment_plugin'] = $plugin_info['plugin'];
         if (!empty($order['params']['payment'])) {
             foreach ($order['params']['payment'] as $k => $v) {
                 $order['params']['payment_params_' . $k] = $v;
             }
             unset($order['params']['payment']);
         }
     }
     if ($skock_id = waRequest::post('stock_id')) {
         $order['params']['stock_id'] = $skock_id;
     }
     $routing_url = wa()->getRouting()->getRootUrl();
     $order['params']['storefront'] = wa()->getConfig()->getDomain() . ($routing_url ? '/' . $routing_url : '');
     if ($ref = waRequest::cookie('referer')) {
         $order['params']['referer'] = $ref;
         $ref_parts = @parse_url($ref);
         $order['params']['referer_host'] = $ref_parts['host'];
         // try get search keywords
         if (!empty($ref_parts['query'])) {
             $search_engines = array('text' => 'yandex\\.|rambler\\.', 'q' => 'bing\\.com|mail\\.|google\\.', 's' => 'nigma\\.ru', 'p' => 'yahoo\\.com');
             $q_var = false;
             foreach ($search_engines as $q => $pattern) {
                 if (preg_match('/(' . $pattern . ')/si', $ref_parts['host'])) {
                     $q_var = $q;
                     break;
                 }
             }
             // default query var name
             if (!$q_var) {
                 $q_var = 'q';
             }
             parse_str($ref_parts['query'], $query);
             if (!empty($query[$q_var])) {
                 $order['params']['keyword'] = $query[$q_var];
             }
         }
     }
     if ($utm = waRequest::cookie('utm')) {
         $utm = json_decode($utm, true);
         if ($utm && is_array($utm)) {
             foreach ($utm as $k => $v) {
                 $order['params']['utm_' . $k] = $v;
             }
         }
     }
     if (($landing = waRequest::cookie('landing')) && ($landing = @parse_url($landing))) {
         if (!empty($landing['query'])) {
             @parse_str($landing['query'], $arr);
             if (!empty($arr['gclid']) && !empty($order['params']['referer_host']) && strpos($order['params']['referer_host'], 'google') !== false) {
                 $order['params']['referer_host'] .= ' (cpc)';
                 $order['params']['cpc'] = 1;
             } else {
                 if (!empty($arr['_openstat']) && !empty($order['params']['referer_host']) && strpos($order['params']['referer_host'], 'yandex') !== false) {
                     $order['params']['referer_host'] .= ' (cpc)';
                     $order['params']['openstat'] = $arr['_openstat'];
                     $order['params']['cpc'] = 1;
                 }
             }
         }
         $order['params']['landing'] = $landing['path'];
     }
     // A/B tests
     /*
             $abtest_variants_model = new shopAbtestVariantsModel();
             foreach (waRequest::cookie() as $k => $v) {
                 if (substr($k, 0, 5) == 'waabt') {
                     $variant_id = $v;
                     $abtest_id = substr($k, 5);
                     if (wa_is_int($abtest_id) && wa_is_int($variant_id)) {
                         $row = $abtest_variants_model->getById($variant_id);
                         if ($row && $row['abtest_id'] == $abtest_id) {
                             $order['params']['abt' . $abtest_id] = $variant_id;
                         }
                     }
                 }
             }
     */
     $order['params']['ip'] = waRequest::getIp();
     $order['params']['user_agent'] = waRequest::getUserAgent();
     foreach (array('shipping', 'billing') as $ext) {
         $address = $contact->getFirst('address.' . $ext);
         if ($address) {
             foreach ($address['data'] as $k => $v) {
                 $order['params'][$ext . '_address.' . $k] = $v;
             }
         }
     }
     if (isset($checkout_data['comment'])) {
         $order['comment'] = $checkout_data['comment'];
     }
     $workflow = new shopWorkflow();
     if ($order_id = $workflow->getActionById('create')->run($order)) {
         $step_number = shopOnestepCheckout::getStepNumber();
         $checkout_flow = new shopCheckoutFlowModel();
         $checkout_flow->add(array('step' => $step_number));
         $cart->clear();
         wa()->getStorage()->remove('shop/checkout');
         wa()->getStorage()->set('shop/order_id', $order_id);
         return $order_id;
     } else {
         return false;
     }
 }
 public function display()
 {
     $plugin_model = new shopPluginModel();
     if (waRequest::param('payment_id') && is_array(waRequest::param('payment_id'))) {
         $methods = $plugin_model->getById(waRequest::param('payment_id'));
     } else {
         $methods = $plugin_model->listPlugins('payment');
     }
     $shipping = $this->getSessionData('shipping');
     if ($shipping) {
         $disabled = shopHelper::getDisabledMethods('payment', $shipping['id']);
     } else {
         $disabled = array();
     }
     $currencies = wa('shop')->getConfig()->getCurrencies();
     $selected = null;
     foreach ($methods as $key => $m) {
         $method_id = $m['id'];
         if (in_array($method_id, $disabled)) {
             unset($methods[$key]);
             continue;
         }
         $plugin = shopPayment::getPlugin($m['plugin'], $m['id']);
         $plugin_info = $plugin->info($m['plugin']);
         $methods[$key]['icon'] = $plugin_info['icon'];
         $custom_fields = $this->getCustomFields($method_id, $plugin);
         $custom_html = '';
         foreach ($custom_fields as $c) {
             $custom_html .= '<div class="wa-field">' . $c . '</div>';
         }
         $methods[$key]['custom_html'] = $custom_html;
         $allowed_currencies = $plugin->allowedCurrency();
         if ($allowed_currencies !== true) {
             $allowed_currencies = (array) $allowed_currencies;
             if (!array_intersect($allowed_currencies, array_keys($currencies))) {
                 $methods[$key]['error'] = sprintf(_w('Payment procedure cannot be processed because required currency %s is not defined in your store settings.'), implode(', ', $allowed_currencies));
             }
         }
         if (!$selected && empty($methods[$key]['error'])) {
             $selected = $method_id;
         }
     }
     $view = wa()->getView();
     $view->assign('checkout_payment_methods', $methods);
     $view->assign('payment_id', $this->getSessionData('payment', $selected));
     $checkout_flow = new shopCheckoutFlowModel();
     $step_number = shopOnestepCheckout::getStepNumber('payment');
     // IF no errors
     $checkout_flow->add(array('step' => $step_number));
     // ELSE
     //        $checkout_flow->add(array(
     //            'step' => $step_number,
     //            'description' => ERROR MESSAGE HERE
     //        ));
 }
 public function display()
 {
     $plugin_model = new shopPluginModel();
     if (waRequest::param('shipping_id') && is_array(waRequest::param('shipping_id'))) {
         $methods = $plugin_model->getById(waRequest::param('shipping_id'));
     } else {
         $methods = $plugin_model->listPlugins('shipping');
     }
     $address = $this->getAddress();
     $empty = true;
     foreach ($address as $v) {
         if ($v) {
             $empty = false;
             break;
         }
     }
     if ($empty) {
         $address = array();
     }
     $items = $this->getItems();
     $cart = new shopCart();
     $total = $cart->total();
     $settings = wa('shop')->getConfig()->getCheckoutSettings();
     $address_form = !isset($settings['contactinfo']) || !isset($settings['contactinfo']['fields']['address.shipping']);
     if (!isset($settings['contactinfo']) || !isset($settings['contactinfo']['fields']['address.shipping']) && !isset($settings['contactinfo']['fields']['address'])) {
         $settings = wa('shop')->getConfig()->getCheckoutSettings(true);
     }
     if (!$address) {
         $shipping_address = array();
         $address_form = true;
         if ($settings['contactinfo']['fields']['address']) {
             foreach ($settings['contactinfo']['fields']['address']['fields'] as $k => $f) {
                 if (!empty($f['value'])) {
                     $shipping_address[$k] = $f['value'];
                 }
             }
         }
     } else {
         $shipping_address = $address;
     }
     if (waRequest::method() == 'post') {
         $shipping_id = waRequest::post('shipping_id');
         $rate_id = waRequest::post('rate_id');
         $selected_shipping = array('id' => $shipping_id, 'rate_id' => !empty($rate_id[$shipping_id]) ? $rate_id[$shipping_id] : '');
     } else {
         $selected_shipping = $this->getSessionData('shipping', array());
     }
     $dimension = shopDimension::getInstance()->getDimension('weight');
     $currencies = wa('shop')->getConfig()->getCurrencies();
     foreach ($methods as $method_id => $m) {
         $plugin = shopShipping::getPlugin($m['plugin'], $m['id']);
         $plugin_info = $plugin->info($m['plugin']);
         $m['icon'] = $plugin_info['icon'];
         $m['img'] = $plugin_info['img'];
         $m['currency'] = $plugin->allowedCurrency();
         $weight_unit = $plugin->allowedWeightUnit();
         if ($weight_unit != $dimension['base_unit']) {
             $shipping_items = array();
             foreach ($items as $item_id => $item) {
                 if ($item['weight']) {
                     $item['weight'] = $item['weight'] / $dimension['units'][$weight_unit]['multiplier'];
                 }
                 $shipping_items[$item_id] = $item;
             }
         } else {
             $shipping_items = $items;
         }
         $m['external'] = $selected_shipping && $selected_shipping['id'] == $m['id'] ? 0 : $plugin->getProperties('external');
         if ($m['external']) {
             $m['rates'] = array();
         } else {
             $m['rates'] = $plugin->getRates($shipping_items, $shipping_address, array('total_price' => $total));
         }
         if (is_array($m['rates'])) {
             if (!isset($currencies[$m['currency']])) {
                 $m['rate'] = 0;
                 $m['error'] = sprintf(_w('Shipping rate was not calculated because required currency %s is not defined in your store settings.'), $m['currency']);
                 $methods[$method_id] = $m;
                 continue;
             }
             foreach ($m['rates'] as &$r) {
                 if (is_array($r['rate'])) {
                     $r['rate'] = max($r['rate']);
                 }
             }
             if ($m['rates']) {
                 if (!empty($selected_shipping['rate_id']) && isset($m['rates'][$selected_shipping['rate_id']])) {
                     $rate = $m['rates'][$selected_shipping['rate_id']];
                 } else {
                     $rate = reset($m['rates']);
                 }
                 $m['rate'] = $rate['rate'];
                 $m['est_delivery'] = isset($rate['est_delivery']) ? $rate['est_delivery'] : '';
                 if (!empty($rate['comment'])) {
                     $m['comment'] = $rate['comment'];
                 }
             } else {
                 $m['rates'] = array();
                 $m['rate'] = null;
             }
         } elseif (is_string($m['rates'])) {
             if ($address) {
                 $m['error'] = $m['rates'];
             } else {
                 $m['rates'] = array();
                 $m['rate'] = null;
             }
         } else {
             unset($methods[$method_id]);
             continue;
         }
         $custom_fields = $this->getCustomFields($method_id, $plugin);
         $custom_html = '';
         foreach ($custom_fields as $c) {
             $custom_html .= '<div class="wa-field">' . $c . '</div>';
         }
         if ($custom_html) {
             $m['custom_html'] = $custom_html;
         }
         $f = $this->getAddressForm($m['id'], $plugin, $settings, $address, $address_form);
         if ($f) {
             $m['form'] = $f;
             $m['form']->setValue($this->getContact());
         }
         $methods[$method_id] = $m;
     }
     $view = wa()->getView();
     $view->assign('checkout_shipping_methods', $methods);
     $default_method = '';
     foreach ($methods as $m) {
         if (empty($m['error'])) {
             $default_method = $m['id'];
             break;
         }
     }
     $view->assign('shipping', $selected_shipping ? $selected_shipping : array('id' => $default_method, 'rate_id' => ''));
     $checkout_flow = new shopCheckoutFlowModel();
     $step_number = shopOnestepCheckout::getStepNumber('shipping');
     // IF no errors
     $checkout_flow->add(array('step' => $step_number));
     // ELSE
     //        $checkout_flow->add(array(
     //            'step' => $step_number,
     //            'description' => ERROR MESSAGE HERE
     //        ));
 }