public function execute()
 {
     $service_model = new shopServiceModel();
     $service_product_model = new shopProductServicesModel();
     $id = waRequest::get('id', null, waRequest::TYPE_INT);
     $edit = waRequest::get('edit', null, waRequest::TYPE_STRING_TRIM);
     if ($edit == 'name') {
         $service_model->updateById($id, array('name' => waRequest::post('name', '', waRequest::TYPE_STRING_TRIM)));
         return;
     }
     if ($id) {
         $service = $service_model->getById($id);
         if (!$service) {
             $this->errors[] = _w("Unknown service to update");
             return;
         }
     }
     if ($id) {
         // delete products
         $delete_products = waRequest::post('delete_product', array(), waRequest::TYPE_ARRAY_INT);
         $service_product_model->deleteByProducts($delete_products, $id);
     }
     $id = $service_model->save($this->getData(), $id, true);
     $this->response = array('id' => $id);
 }
 public function move($service_id, $id, $before_id = null)
 {
     $service_id = (int) $service_id;
     $service_model = new shopServiceModel();
     $service = $service_model->getById($service_id);
     if (!$service) {
         return false;
     }
     $id = (int) $id;
     if (!$before_id) {
         $item = $this->getById($id);
         if (!$item) {
             return false;
         }
         $sort = $this->query("SELECT MAX(sort) sort FROM {$this->table} WHERE service_id = {$service_id}")->fetchField('sort') + 1;
         $this->updateById($id, array('sort' => $sort));
     } else {
         $before_id = $this->escape($before_id);
         $items = $this->query("SELECT * FROM {$this->table} WHERE id IN ('{$id}', '{$before_id}')")->fetchAll('id');
         if (!$items || count($items) != 2) {
             return false;
         }
         $sort = $items[$before_id]['sort'];
         $this->query("UPDATE {$this->table} SET sort = sort + 1 WHERE sort >= {$sort} AND service_id = {$service_id}");
         $this->updateById($id, array('sort' => $sort));
     }
     return true;
 }
 public function execute($data = null)
 {
     $order_model = new shopOrderModel();
     $order = $order_model->getById($data['id']);
     $subtotal = 0;
     $services = $products = array();
     foreach ($data['items'] as $item) {
         if ($item['service_id']) {
             $services[] = $item['service_id'];
         } else {
             $products[] = $item['product_id'];
         }
     }
     $service_model = new shopServiceModel();
     $product_model = new shopProductModel();
     $services = $service_model->getById($services);
     $products = $product_model->getById($products);
     foreach ($data['items'] as &$item) {
         $item['currency'] = $order['currency'];
         $item['price'] = $this->price($item['price']);
         if ($item['service_id']) {
             $item['service'] = $services[$item['service_id']];
         } else {
             $item['product'] = $products[$item['product_id']];
         }
         $subtotal += $item['price'] * $item['quantity'];
     }
     unset($item);
     foreach (array('shipping', 'discount') as $k) {
         if (!isset($data[$k])) {
             $data[$k] = 0;
         }
     }
     $contact = new waContact($order['contact_id']);
     $shipping_address = $contact->getFirst('address.shipping');
     if (!$shipping_address) {
         $shipping_address = $contact->getFirst('address');
     }
     $shipping_address = $shipping_address ? $shipping_address['data'] : array();
     $billing_address = $contact->getFirst('address.billing');
     if (!$billing_address) {
         $billing_address = $contact->getFirst('address');
     }
     $billing_address = $billing_address ? $billing_address['data'] : array();
     $discount_rate = $subtotal ? $data['discount'] / $subtotal : 0;
     $taxes = shopTaxes::apply($data['items'], array('shipping' => $shipping_address, 'billing' => $billing_address, 'discount_rate' => $discount_rate), $order['currency']);
     $tax = $tax_included = 0;
     foreach ($taxes as $t) {
         if (isset($t['sum'])) {
             $tax += $t['sum'];
         }
         if (isset($t['sum_included'])) {
             $tax_included += $t['sum_included'];
         }
     }
     $data['tax'] = $tax_included + $tax;
     $data['total'] = $subtotal + $tax + $this->price($data['shipping']) - $this->price($data['discount']);
     // for logging changes in stocks
     shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_ORDER, 'Order %s was edited', array('order_id' => $data['id']));
     // update
     $order_model->update($data, $data['id']);
     $log_model = new waLogModel();
     $log_model->add('order_edit', $data['id']);
     shopProductStocksLogModel::clearContext();
     if (!empty($data['params'])) {
         $params_model = new shopOrderParamsModel();
         $params_model->set($data['id'], $data['params'], false);
     }
     return true;
 }
    public function execute()
    {
        $this->setLayout(new shopFrontendLayout());
        if ($this->params) {
            $product = $this->params;
        } else {
            $product_model = new shopProductModel();
            $product = $product_model->getByField('url', waRequest::param('product_url'));
        }
        if (!$product) {
            throw new waException(_w('Product not found'), 404);
        }
        if ($types = waRequest::param('type_id')) {
            if (!in_array($product['type_id'], (array) $types)) {
                throw new waException(_w('Product not found'), 404);
            }
        }
        $is_cart = waRequest::get('cart');
        if ($is_cart) {
            $this->setLayout(null);
        }
        $product = new shopProduct($product);
        if (!$is_cart) {
            $this->getBreadcrumbs($product);
        }
        // check url
        $product['num'] = 141;
        if ($product['url'] !== urldecode(waRequest::param('product_url'))) {
            $url_params = array('product_url' => $product['url']);
            if ($product['category_id']) {
                $url_params['category_url'] = $product['category_url'];
            }
            $q = waRequest::server('QUERY_STRING');
            $this->redirect(wa()->getRouteUrl('/frontend/product', $url_params) . ($q ? '?' . $q : ''), 301);
        }
        $this->prepareProduct($product);
        $this->addCanonical();
        // get services
        $type_services_model = new shopTypeServicesModel();
        $services = $type_services_model->getServiceIds($product['type_id']);
        $service_model = new shopServiceModel();
        $product_services_model = new shopProductServicesModel();
        $services = array_merge($services, $product_services_model->getServiceIds($product['id']));
        $services = array_unique($services);
        $services = $service_model->getById($services);
        $variants_model = new shopServiceVariantsModel();
        $rows = $variants_model->getByField('service_id', array_keys($services), true);
        foreach ($rows as $row) {
            if (!$row['price']) {
                $row['price'] = $services[$row['service_id']]['price'];
            }
            $services[$row['service_id']]['variants'][$row['id']] = $row;
        }
        $rows = $product_services_model->getByField('product_id', $product['id'], true);
        $skus_services = array();
        foreach ($product['skus'] as $sku) {
            $skus_services[$sku['id']] = array();
        }
        foreach ($rows as $row) {
            if (!$row['sku_id']) {
                // remove disabled services and variantsimg
                if (!$row['status']) {
                    unset($services[$row['service_id']]['variants'][$row['service_variant_id']]);
                } elseif ($row['price'] !== null) {
                    // update price
                    $services[$row['service_id']]['variants'][$row['service_variant_id']]['price'] = $row['price'];
                }
                if ($row['status'] == shopProductServicesModel::STATUS_DEFAULT) {
                    // update default
                    $services[$row['service_id']]['variant_id'] = $row['service_variant_id'];
                }
            } else {
                if (!$row['status']) {
                    $skus_services[$row['sku_id']][$row['service_id']][$row['service_variant_id']] = false;
                } else {
                    $skus_services[$row['sku_id']][$row['service_id']][$row['service_variant_id']] = $row['price'];
                }
            }
        }
        foreach ($skus_services as $sku_id => &$sku_services) {
            $sku_price = $product['skus'][$sku_id]['price'];
            foreach ($services as $service_id => $service) {
                if (isset($sku_services[$service_id])) {
                    if ($sku_services[$service_id]) {
                        foreach ($service['variants'] as $v) {
                            if (!isset($sku_services[$service_id][$v['id']]) || $sku_services[$service_id][$v['id']] === null) {
                                $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($v['price'], $service['currency'], $sku_price, $product['currency']));
                            } elseif ($sku_services[$service_id][$v['id']]) {
                                $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($sku_services[$service_id][$v['id']], $service['currency'], $sku_price, $product['currency']));
                            }
                        }
                    }
                } else {
                    foreach ($service['variants'] as $v) {
                        $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($v['price'], $service['currency'], $sku_price, $product['currency']));
                    }
                }
            }
        }
        unset($sku_services);
        // disable service if all variants disabled
        foreach ($skus_services as $sku_id => $sku_services) {
            foreach ($sku_services as $service_id => $service) {
                if (is_array($service)) {
                    $disabled = true;
                    foreach ($service as $v) {
                        if ($v !== false) {
                            $disabled = false;
                            break;
                        }
                    }
                    if ($disabled) {
                        $skus_services[$sku_id][$service_id] = false;
                    }
                }
            }
        }
        foreach ($services as $s_id => &$s) {
            if (!$s['variants']) {
                unset($services[$s_id]);
                continue;
            }
            if ($s['currency'] == '%') {
                foreach ($s['variants'] as $v_id => $v) {
                    $s['variants'][$v_id]['price'] = $v['price'] * $product['skus'][$product['sku_id']]['price'] / 100;
                }
                $s['currency'] = $product['currency'];
            }
            if (count($s['variants']) == 1) {
                $v = reset($s['variants']);
                if ($v['name']) {
                    $s['name'] .= ' ' . $v['name'];
                }
                $s['variant_id'] = $v['id'];
                $s['price'] = $v['price'];
                unset($s['variants']);
                foreach ($skus_services as $sku_id => $sku_services) {
                    if (isset($sku_services[$s_id]) && isset($sku_services[$s_id][$v['id']])) {
                        $skus_services[$sku_id][$s_id] = $sku_services[$s_id][$v['id']][1];
                    }
                }
            }
        }
        unset($s);
        uasort($services, array('shopServiceModel', 'sortServices'));
        $this->view->assign('sku_services', $skus_services);
        $this->view->assign('services', $services);
        $compare = waRequest::cookie('shop_compare', array(), waRequest::TYPE_ARRAY_INT);
        $this->view->assign('compare', in_array($product['id'], $compare) ? $compare : array());
        if (!$is_cart) {
            $this->view->assign('reviews', $this->getTopReviews($product['id']));
            $this->view->assign('rates', $this->reviews_model->getProductRates($product['id']));
            $this->view->assign('reviews_total_count', $this->getReviewsTotalCount($product['id']));
            $meta_fields = $this->getMetafields($product);
            $title = $meta_fields['meta_title'] ? $meta_fields['meta_title'] : $product['name'];
            wa()->getResponse()->setTitle($title);
            wa()->getResponse()->setMeta('keywords', $meta_fields['meta_keywords']);
            wa()->getResponse()->setMeta('description', $meta_fields['meta_description']);
            $feature_codes = array_keys($product->features);
            $feature_model = new shopFeatureModel();
            $features = $feature_model->getByCode($feature_codes);
            $this->view->assign('features', $features);
        }
        $this->view->assign('currency_info', $this->getCurrencyInfo());
        /**
         * @event frontend_product
         * @param shopProduct $product
         * @return array[string][string]string $return[%plugin_id%]['menu'] html output
         * @return array[string][string]string $return[%plugin_id%]['cart'] html output
         * @return array[string][string]string $return[%plugin_id%]['block_aux'] html output
         * @return array[string][string]string $return[%plugin_id%]['block'] html output
         */
        $this->view->assign('frontend_product', wa()->event('frontend_product', $product, array('menu', 'cart', 'block_aux', 'block')));
        $sku_stocks = array();
        foreach ($product->skus as $sku) {
            $sku_stocks[$sku_id] = array($sku['count'], $sku['stock']);
        }
        $stock_model = new shopStockModel();
        $this->view->assign('stocks', $stock_model->getAll('id'));
        $duble = db_query("SELECT * FROM shop_product where id=" . $product['id']);
        $dubles = mysql_fetch_assoc($duble);
        $dubles_sku = db_query("SELECT * FROM shop_product_skus where product_id=" . $product['id'] . " and  id=" . $dubles['sku_id']);
        $dubl_sku = mysql_fetch_assoc($dubles_sku);
        $dubles_prod = db_query("SELECT * FROM shop_product_skus where product_id!=" . $product['id'] . " and  sku='" . $dubl_sku['sku'] . "' Group by product_id");
        while ($dubl_product = mysql_fetch_array($dubles_prod)) {
            $dubles_img_pr = db_query("SELECT * FROM shop_product p, shop_product_images img where p.id=" . $dubl_product['product_id'] . " and img.product_id=" . $dubl_product['product_id'] . "");
            $dubles_img = mysql_fetch_assoc($dubles_img_pr);
            if ($dubles_img['status'] != 0) {
                $koldz = substr($dubles_img['product_id'], -2, 2);
                $kolds = str_replace($koldz, '', $dubles_img['product_id']);
                if (preg_match_all("#\\d#", $kolds) < 2) {
                    $kolds = '0' . $kolds;
                }
                if ($kolds == 0) {
                    $kolds = '00';
                }
                $alt_test = db_query("SELECT * FROM shop_product_features_selectable where feature_id=12 and  product_id=" . $dubles_img['product_id'] . "");
                $alt_t = mysql_fetch_assoc($alt_test);
                $alt_value = db_query("SELECT * FROM shop_feature_values_color where id=" . $alt_t['value_id'] . "");
                $alt = mysql_fetch_assoc($alt_value);
                $dubl_p = $dubl_p . ' <a  class="duble_prod"  href="http://' . $_SERVER['HTTP_HOST'] . '/index.php/' . $dubles_img['url'] . '" >
		 
		 
		 <img alt="' . $alt['value'] . '" title="' . $alt['value'] . '"  style="width:50px" src="/wa-data/public/shop/products/' . $koldz . '/' . $kolds . '/' . $dubles_img['product_id'] . '/images/' . $dubles_img['id'] . '/' . $dubles_img['id'] . '.96x96.jpg"/></a>';
                $dubl_p2 = $dubl_p2 . '<a onclick="doubl(' . $dubles_img['product_id'] . ')" class="duble_prod" >
		 
		 
		 <img alt="' . $alt['value'] . '" title="' . $alt['value'] . '" style="width:50px" src="/wa-data/public/shop/products/' . $koldz . '/' . $kolds . '/' . $dubles_img['product_id'] . '/images/' . $dubles_img['id'] . '/' . $dubles_img['id'] . '.96x96.jpg"/></a>';
            }
            $dubl_p = $dubl_p;
            $dubl_p2 = $dubl_p2;
        }
        $this->view->assign('duble', $dubl_p);
        $this->view->assign('duble2', $dubl_p2);
        $this->view->assign('duble_list', $dubl_p);
        $product['num'] = $_GET['num'];
        $this->view->assign('numis', $_GET['num']);
        $this->setThemeTemplate($is_cart ? 'product.cart.html' : 'product.html');
    }
 /**
  * @param $data
  */
 protected function addService($data)
 {
     $item = $this->cart_model->getById($data['parent_id']);
     if (!$item) {
         $this->errors = _w('Error');
         return;
     }
     unset($item['id']);
     $item['parent_id'] = $data['parent_id'];
     $item['type'] = 'service';
     $item['service_id'] = $data['service_id'];
     if (isset($data['service_variant_id'])) {
         $item['service_variant_id'] = $data['service_variant_id'];
     } else {
         $service_model = new shopServiceModel();
         $service = $service_model->getById($data['service_id']);
         $item['service_variant_id'] = $service['variant_id'];
     }
     $id = $this->cart->addItem($item);
     $total = $this->cart->total();
     $discount = $this->cart->discount();
     $this->response['id'] = $id;
     $this->response['total'] = $this->currencyFormat($total);
     $this->response['count'] = $this->cart->count();
     $this->response['discount'] = $this->currencyFormat($discount);
     $item_total = $this->cart->getItemTotal($data['parent_id']);
     $this->response['item_total'] = $this->currencyFormat($item_total);
     if (shopAffiliate::isEnabled()) {
         $add_affiliate_bonus = shopAffiliate::calculateBonus(array('total' => $total, 'discount' => $discount, 'items' => $this->cart->items(false)));
         $this->response['add_affiliate_bonus'] = sprintf(_w("This order will add +%s points to your affiliate bonus."), round($add_affiliate_bonus, 2));
     }
 }
 protected function getServiceVars($product)
 {
     $type_services_model = new shopTypeServicesModel();
     $services = $type_services_model->getServiceIds($product['type_id']);
     // Fetch services
     $service_model = new shopServiceModel();
     $product_services_model = new shopProductServicesModel();
     $services = array_merge($services, $product_services_model->getServiceIds($product['id']));
     $services = array_unique($services);
     $services = $service_model->getById($services);
     shopRounding::roundServices($services);
     // Convert service.price from default currency to service.currency
     foreach ($services as &$s) {
         $s['price'] = shop_currency($s['price'], null, $s['currency'], false);
     }
     unset($s);
     // Fetch service variants
     $variants_model = new shopServiceVariantsModel();
     $rows = $variants_model->getByField('service_id', array_keys($services), true);
     shopRounding::roundServiceVariants($rows, $services);
     foreach ($rows as $row) {
         if (!$row['price']) {
             $row['price'] = $services[$row['service_id']]['price'];
         } else {
             if ($services[$row['service_id']]['variant_id'] == $row['id']) {
                 $services[$row['service_id']]['price'] = $row['price'];
             }
         }
         $services[$row['service_id']]['variants'][$row['id']] = $row;
     }
     // Fetch service prices for specific products and skus
     $rows = $product_services_model->getByField('product_id', $product['id'], true);
     shopRounding::roundServiceVariants($rows, $services);
     $skus_services = array();
     // sku_id => [service_id => price]
     $frontend_currency = wa('shop')->getConfig()->getCurrency(false);
     foreach ($product['skus'] as $sku) {
         $skus_services[$sku['id']] = array();
     }
     foreach ($rows as $row) {
         if (!$row['sku_id']) {
             if (!$row['status']) {
                 // remove disabled services and variants
                 unset($services[$row['service_id']]['variants'][$row['service_variant_id']]);
             } elseif ($row['price'] !== null) {
                 // update price for service variant, when it is specified for this product
                 $services[$row['service_id']]['variants'][$row['service_variant_id']]['price'] = $row['price'];
                 // !!! also set other keys related to price
             }
             if ($row['status'] == shopProductServicesModel::STATUS_DEFAULT) {
                 // default variant is different for this product
                 $services[$row['service_id']]['variant_id'] = $row['service_variant_id'];
             }
         } else {
             if (!$row['status']) {
                 $skus_services[$row['sku_id']][$row['service_id']][$row['service_variant_id']] = false;
             } else {
                 $skus_services[$row['sku_id']][$row['service_id']][$row['service_variant_id']] = $row['price'];
             }
         }
     }
     // Fill in gaps in $skus_services
     foreach ($skus_services as $sku_id => &$sku_services) {
         $sku_price = $product['skus'][$sku_id]['price'];
         foreach ($services as $service_id => $service) {
             if (isset($sku_services[$service_id])) {
                 if ($sku_services[$service_id]) {
                     foreach ($service['variants'] as $v) {
                         if (!isset($sku_services[$service_id][$v['id']]) || $sku_services[$service_id][$v['id']] === null) {
                             $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($v['price'], $service['currency'], $sku_price, $product['currency']));
                         } elseif ($sku_services[$service_id][$v['id']]) {
                             $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($sku_services[$service_id][$v['id']], $service['currency'], $sku_price, $product['currency']));
                         }
                     }
                 }
             } else {
                 foreach ($service['variants'] as $v) {
                     $sku_services[$service_id][$v['id']] = array($v['name'], $this->getPrice($v['price'], $service['currency'], $sku_price, $product['currency']));
                 }
             }
         }
     }
     unset($sku_services);
     // disable service if all variants are disabled
     foreach ($skus_services as $sku_id => $sku_services) {
         foreach ($sku_services as $service_id => $service) {
             if (is_array($service)) {
                 $disabled = true;
                 foreach ($service as $v) {
                     if ($v !== false) {
                         $disabled = false;
                         break;
                     }
                 }
                 if ($disabled) {
                     $skus_services[$sku_id][$service_id] = false;
                 }
             }
         }
     }
     // Calculate prices for %-based services,
     // and disable variants selector when there's only one value available.
     foreach ($services as $s_id => &$s) {
         if (!$s['variants']) {
             unset($services[$s_id]);
             continue;
         }
         if ($s['currency'] == '%') {
             foreach ($s['variants'] as $v_id => $v) {
                 $s['variants'][$v_id]['price'] = $v['price'] * $product['skus'][$product['sku_id']]['price'] / 100;
             }
             $s['currency'] = $product['currency'];
         }
         if (count($s['variants']) == 1) {
             $v = reset($s['variants']);
             if ($v['name']) {
                 $s['name'] .= ' ' . $v['name'];
             }
             $s['variant_id'] = $v['id'];
             $s['price'] = $v['price'];
             unset($s['variants']);
             foreach ($skus_services as $sku_id => $sku_services) {
                 if (isset($sku_services[$s_id]) && isset($sku_services[$s_id][$v['id']])) {
                     $skus_services[$sku_id][$s_id] = $sku_services[$s_id][$v['id']][1];
                 }
             }
         }
     }
     unset($s);
     uasort($services, array('shopServiceModel', 'sortServices'));
     return array($services, $skus_services);
 }