Example #1
0
 protected function processChangeProductInCart()
 {
     $mode = Tools::getIsset('update') && $this->id_product ? 'update' : 'add';
     if (!$this->id_product) {
         $this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax'));
     }
     $product = new Product($this->id_product, true, $this->context->language->id);
     if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) {
         $this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax'));
         return;
     }
     $qty_factor = 1;
     $ext_qty_factor = 1;
     $ext_prop_quantities = null;
     $id_cart_product = 0;
     $qty_behavior = 0;
     $icp = (int) Tools::getValue('icp');
     $properties = $product->productProperties();
     if ($icp && $this->context->cart->id) {
         $cart_products = $this->context->cart->getProducts();
         if (count($cart_products)) {
             foreach ($cart_products as $cart_product) {
                 if ($icp == (int) $cart_product['id_cart_product']) {
                     $id_cart_product = $icp;
                     if ($mode == 'add') {
                         if (Tools::getValue('qty') != 'default') {
                             $qty_factor = (int) Tools::getValue('qty');
                         }
                         $_POST['qty'] = (double) $cart_product['cart_quantity_fractional'] > 0 ? (double) $cart_product['cart_quantity_fractional'] : ($product->qtyStep() > 0 ? $product->qtyStep() : 1);
                     } elseif ($mode == 'update') {
                         $qty_behavior = PP::qtyBehavior($product, $cart_product['cart_quantity']);
                     }
                     break;
                 }
             }
         }
     } else {
         if ($properties['pp_ext'] == 1 && in_array($properties['pp_ext_policy'], array(0, 2))) {
             $ext_prop_quantities = array();
             $ext_prop_qty_ratio = array();
             if ($properties['pp_ext_policy'] == 2) {
                 $prop = $product->productProp();
                 if ($this->id_product_attribute) {
                     $id_product_attribute = $this->id_product_attribute;
                 } else {
                     if ($product->hasAttributes()) {
                         $id_product_attribute = Product::getDefaultAttribute($product->id);
                     } else {
                         $id_product_attribute = 0;
                     }
                 }
             }
             $positions = count($properties['pp_ext_prop']);
             for ($position = 1; $position <= $positions; $position++) {
                 $pp_ext_prop = $properties['pp_ext_prop'][$position];
                 if ($properties['pp_ext_policy'] == 2) {
                     $q = PP::productProp($prop, $id_product_attribute, $position, 'quantity');
                     if ($q === false) {
                         $q = (double) $pp_ext_prop['default_quantity'];
                     }
                     if ($q <= 0) {
                         $q = 1;
                     }
                 } else {
                     $q = PP::resolveInputQty(Tools::getValue('pp_ext_prop_quantity_' . $position, 'default'), $properties['pp_qty_policy'], $pp_ext_prop['qty_step'], $pp_ext_prop['default_quantity'] > 0 ? $pp_ext_prop['default_quantity'] : 1);
                 }
                 $ext_prop_quantities[$position] = $q;
                 $ext_prop_qty_ratio[$position] = $properties['pp_ext_prop'][$position]['qty_ratio'];
                 if ($q <= 0) {
                     $this->errors[] = Tools::displayError('Quantity not specified.', !Tools::getValue('ajax'));
                 }
                 $min_qty = (double) $pp_ext_prop['minimum_quantity'];
                 if ($min_qty > 0 && $q < $min_qty) {
                     $this->errors[] = Tools::displayError(sprintf('Please specify at least %s for %s', (string) PP::formatQty($min_qty), (string) $pp_ext_prop['property']), !Tools::getValue('ajax'));
                 }
                 $max_qty = (double) $pp_ext_prop['maximum_quantity'];
                 if ($max_qty > 0 && $q > $max_qty) {
                     $this->errors[] = Tools::displayError(sprintf('Please specify no more than %s for %s', (string) PP::formatQty($max_qty), (string) $pp_ext_prop['property']), !Tools::getValue('ajax'));
                 }
             }
             if (!$this->errors) {
                 $ext_qty_factor = $properties['pp_ext_method'] == 1 ? 1 : 0;
                 $positions = count($ext_prop_quantities);
                 for ($position = 1; $position <= $positions; $position++) {
                     $value = $ext_prop_quantities[$position];
                     $qty_ratio = $ext_prop_qty_ratio[$position];
                     if ($properties['pp_ext_method'] == 1) {
                         $ext_qty_factor *= $qty_ratio > 0 ? $value / $qty_ratio : $value;
                     } elseif ($properties['pp_ext_method'] == 2) {
                         $ext_qty_factor += $qty_ratio > 0 ? $value / $qty_ratio : $value;
                     }
                 }
             }
         }
     }
     if (!$this->errors) {
         if ($this->id_product_attribute) {
             $default_quantity = $product->attributeDefaultQty($this->id_product_attribute);
             $this->qty = $qty_factor * $this->resolveInputQty($properties, $default_quantity);
             if ($this->qty == 0) {
                 $this->errors[] = Tools::displayError('Quantity not specified.', !Tools::getValue('ajax'));
             } else {
                 if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $ext_qty_factor * $this->qty)) {
                     $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
                 }
             }
         } else {
             if ($product->hasAttributes()) {
                 $min_quantity = $product->out_of_stock == 2 ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock;
                 $this->id_product_attribute = Product::getDefaultAttribute($product->id, $min_quantity);
                 if (!$this->id_product_attribute) {
                     Tools::redirectAdmin($this->context->link->getProductLink($product));
                 } else {
                     $default_quantity = $product->attributeDefaultQty($this->id_product_attribute);
                     $this->qty = $qty_factor * $this->resolveInputQty($properties, $default_quantity);
                     if ($this->qty == 0) {
                         $this->errors[] = Tools::displayError('Quantity not specified.', !Tools::getValue('ajax'));
                     } else {
                         if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $ext_qty_factor * $this->qty)) {
                             $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
                         }
                     }
                 }
             } else {
                 $default_quantity = $product->defaultQty();
                 $this->qty = $qty_factor * $this->resolveInputQty($properties, $default_quantity);
                 if ($this->qty == 0) {
                     $this->errors[] = Tools::displayError('Quantity not specified.', !Tools::getValue('ajax'));
                 } else {
                     if (!$product->checkQty($ext_qty_factor * $this->qty)) {
                         $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
                     }
                 }
             }
         }
     }
     if (!$this->errors && ($mode == 'add' || $mode == 'update' && $qty_behavior)) {
         if ($mode == 'add' && !$this->context->cart->id) {
             if (Context::getContext()->cookie->id_guest) {
                 $guest = new Guest(Context::getContext()->cookie->id_guest);
                 $this->context->cart->mobile_theme = $guest->mobile_theme;
             }
             $this->context->cart->add();
             if ($this->context->cart->id) {
                 $this->context->cookie->id_cart = (int) $this->context->cart->id;
             }
         }
         if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) {
             $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax'));
         }
         if (!$this->errors) {
             $cart_rules = $this->context->cart->getCartRules();
             $update_quantity = $this->context->cart->updateQty($id_cart_product ? $mode == 'add' ? $qty_factor : $this->qty : ($ext_prop_quantities !== null ? $ext_qty_factor : $this->qty), $this->id_product, $this->id_product_attribute, $this->customization_id, $mode == 'update' ? 'update' : Tools::getValue('op', 'up'), $this->id_address_delivery, null, true, $id_cart_product, $ext_prop_quantities, $this->qty);
             if ($update_quantity < 0) {
                 $minimal_quantity = $this->id_product_attribute ? $product->attributeMinQty($this->id_product_attribute) : $product->minQty();
                 $this->errors[] = Tools::displayError(sprintf('You must add %s minimum quantity', $minimal_quantity), !Tools::getValue('ajax'));
             } elseif (!$update_quantity) {
                 $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax'));
             } elseif ((int) Tools::getValue('allow_refresh')) {
                 $cart_rules2 = $this->context->cart->getCartRules();
                 if (count($cart_rules2) != count($cart_rules)) {
                     $this->ajax_refresh = true;
                 } else {
                     $rule_list = array();
                     foreach ($cart_rules2 as $rule) {
                         $rule_list[] = $rule['id_cart_rule'];
                     }
                     foreach ($cart_rules as $rule) {
                         if (!in_array($rule['id_cart_rule'], $rule_list)) {
                             $this->ajax_refresh = true;
                             break;
                         }
                     }
                 }
             }
         }
     }
     $removed = CartRule::autoRemoveFromCart();
     CartRule::autoAddToCart();
     if (count($removed) && (int) Tools::getValue('allow_refresh')) {
         $this->ajax_refresh = true;
     }
 }
    protected function _displaySpecificPriceModificationForm($defaultCurrency, $shops, $currencies, $countries, $groups)
    {
        if (!($obj = $this->loadObject())) {
            return;
        }
        $content = '';
        $specific_prices = SpecificPrice::getByProductId((int) $obj->id);
        $specific_price_priorities = SpecificPrice::getPriority((int) $obj->id);
        $tmp = array();
        foreach ($shops as $shop) {
            $tmp[$shop['id_shop']] = $shop;
        }
        $shops = $tmp;
        $tmp = array();
        foreach ($currencies as $currency) {
            $tmp[$currency['id_currency']] = $currency;
        }
        $currencies = $tmp;
        $tmp = array();
        foreach ($countries as $country) {
            $tmp[$country['id_country']] = $country;
        }
        $countries = $tmp;
        $tmp = array();
        foreach ($groups as $group) {
            $tmp[$group['id_group']] = $group;
        }
        $groups = $tmp;
        $length_before = strlen($content);
        if (is_array($specific_prices) && count($specific_prices)) {
            $i = 0;
            foreach ($specific_prices as $specific_price) {
                $id_currency = $specific_price['id_currency'] ? $specific_price['id_currency'] : $defaultCurrency->id;
                if (!isset($currencies[$id_currency])) {
                    continue;
                }
                $current_specific_currency = $currencies[$id_currency];
                if ($specific_price['reduction_type'] == 'percentage') {
                    $impact = '- ' . $specific_price['reduction'] * 100 . ' %';
                } elseif ($specific_price['reduction'] > 0) {
                    $impact = '- ' . Tools::displayPrice(Tools::ps_round($specific_price['reduction'], 2), $current_specific_currency) . ' ';
                    if ($specific_price['reduction_tax']) {
                        $impact .= '(' . $this->l('Tax incl.') . ')';
                    } else {
                        $impact .= '(' . $this->l('Tax excl.') . ')';
                    }
                } else {
                    $impact = '--';
                }
                if ($specific_price['from'] == '0000-00-00 00:00:00' && $specific_price['to'] == '0000-00-00 00:00:00') {
                    $period = $this->l('Unlimited');
                } else {
                    $period = $this->l('From') . ' ' . ($specific_price['from'] != '0000-00-00 00:00:00' ? $specific_price['from'] : '0000-00-00 00:00:00') . '<br />' . $this->l('To') . ' ' . ($specific_price['to'] != '0000-00-00 00:00:00' ? $specific_price['to'] : '0000-00-00 00:00:00');
                }
                if ($specific_price['id_product_attribute']) {
                    $combination = new Combination((int) $specific_price['id_product_attribute']);
                    $attributes = $combination->getAttributesName((int) $this->context->language->id);
                    $attributes_name = '';
                    foreach ($attributes as $attribute) {
                        $attributes_name .= $attribute['name'] . ' - ';
                    }
                    $attributes_name = rtrim($attributes_name, ' - ');
                } else {
                    $attributes_name = $this->l('All combinations');
                }
                $rule = new SpecificPriceRule((int) $specific_price['id_specific_price_rule']);
                $rule_name = $rule->id ? $rule->name : '--';
                if ($specific_price['id_customer']) {
                    $customer = new Customer((int) $specific_price['id_customer']);
                    if (Validate::isLoadedObject($customer)) {
                        $customer_full_name = $customer->firstname . ' ' . $customer->lastname;
                    }
                    unset($customer);
                }
                if (!$specific_price['id_shop'] || in_array($specific_price['id_shop'], Shop::getContextListShopID())) {
                    $content .= '
					<tr ' . ($i % 2 ? 'class="alt_row"' : '') . '>
						<td>' . $rule_name . '</td>
						<td>' . $attributes_name . '</td>';
                    $can_delete_specific_prices = true;
                    if (Shop::isFeatureActive()) {
                        $id_shop_sp = $specific_price['id_shop'];
                        $can_delete_specific_prices = count($this->context->employee->getAssociatedShops()) > 1 && !$id_shop_sp || $id_shop_sp;
                        $content .= '
						<td>' . ($id_shop_sp ? $shops[$id_shop_sp]['name'] : $this->l('All shops')) . '</td>';
                    }
                    $price = Tools::ps_round($specific_price['price'], 2);
                    $fixed_price = $price == Tools::ps_round($obj->price, 2) || $specific_price['price'] == -1 ? '--' : Tools::displayPrice($price, $current_specific_currency);
                    $content .= '
						<td>' . ($specific_price['id_currency'] ? $currencies[$specific_price['id_currency']]['name'] : $this->l('All currencies')) . '</td>
						<td>' . ($specific_price['id_country'] ? $countries[$specific_price['id_country']]['name'] : $this->l('All countries')) . '</td>
						<td>' . ($specific_price['id_group'] ? $groups[$specific_price['id_group']]['name'] : $this->l('All groups')) . '</td>
						<td title="' . $this->l('ID:') . ' ' . $specific_price['id_customer'] . '">' . (isset($customer_full_name) ? $customer_full_name : $this->l('All customers')) . '</td>
						<td>' . $fixed_price . '</td>
						<td>' . $impact . '</td>
						<td>' . $period . '</td>
						<td>' . PP::formatQty($specific_price["from_quantity"]) . '</th>
						<td>' . (!$rule->id && $can_delete_specific_prices ? '<a class="btn btn-default" name="delete_link" href="' . self::$currentIndex . '&id_product=' . (int) Tools::getValue('id_product') . '&action=deleteSpecificPrice&id_specific_price=' . (int) $specific_price['id_specific_price'] . '&token=' . Tools::getValue('token') . '"><i class="icon-trash"></i></a>' : '') . '</td>
					</tr>';
                    $i++;
                    unset($customer_full_name);
                }
            }
        }
        if ($length_before === strlen($content)) {
            $content .= '
				<tr>
					<td class="text-center" colspan="13"><i class="icon-warning-sign"></i>&nbsp;' . $this->l('No specific prices.') . '</td>
				</tr>';
        }
        $content .= '
				</tbody>
			</table>
			</div>
			<div class="panel-footer">
				<a href="' . $this->context->link->getAdminLink('AdminProducts') . '" class="btn btn-default"><i class="process-icon-cancel"></i> ' . $this->l('Cancel') . '</a>
				<button id="product_form_submit_btn"  type="submit" name="submitAddproduct" class="btn btn-default pull-right" disabled="disabled"><i class="process-icon-loading"></i> ' . $this->l('Save') . '</button>
				<button id="product_form_submit_btn"  type="submit" name="submitAddproductAndStay" class="btn btn-default pull-right" disabled="disabled"><i class="process-icon-loading"></i> ' . $this->l('Save and stay') . '</button>
			</div>
		</div>';
        $content .= '
		<script type="text/javascript">
			var currencies = new Array();
			currencies[0] = new Array();
			currencies[0]["sign"] = "' . $defaultCurrency->sign . '";
			currencies[0]["format"] = ' . intval($defaultCurrency->format) . ';
			';
        foreach ($currencies as $currency) {
            $content .= '
				currencies[' . $currency['id_currency'] . '] = new Array();
				currencies[' . $currency['id_currency'] . ']["sign"] = "' . $currency['sign'] . '";
				currencies[' . $currency['id_currency'] . ']["format"] = ' . intval($currency['format']) . ';
				';
        }
        $content .= '
		</script>
		';
        // Not use id_customer
        if ($specific_price_priorities[0] == 'id_customer') {
            unset($specific_price_priorities[0]);
        }
        // Reindex array starting from 0
        $specific_price_priorities = array_values($specific_price_priorities);
        $content .= '<div class="panel">
		<h3>' . $this->l('Priority management') . '</h3>
		<div class="alert alert-info">
				' . $this->l('Sometimes one customer can fit into multiple price rules. Priorities allow you to define which rule applies to the customer.') . '
		</div>';
        $content .= '
		<div class="form-group">
			<label class="control-label col-lg-3" for="specificPricePriority1">' . $this->l('Priorities') . '</label>
			<div class="input-group col-lg-9">
				<select id="specificPricePriority1" name="specificPricePriority[]">
					<option value="id_shop"' . ($specific_price_priorities[0] == 'id_shop' ? ' selected="selected"' : '') . '>' . $this->l('Shop') . '</option>
					<option value="id_currency"' . ($specific_price_priorities[0] == 'id_currency' ? ' selected="selected"' : '') . '>' . $this->l('Currency') . '</option>
					<option value="id_country"' . ($specific_price_priorities[0] == 'id_country' ? ' selected="selected"' : '') . '>' . $this->l('Country') . '</option>
					<option value="id_group"' . ($specific_price_priorities[0] == 'id_group' ? ' selected="selected"' : '') . '>' . $this->l('Group') . '</option>
				</select>
				<span class="input-group-addon"><i class="icon-chevron-right"></i></span>
				<select name="specificPricePriority[]">
					<option value="id_shop"' . ($specific_price_priorities[1] == 'id_shop' ? ' selected="selected"' : '') . '>' . $this->l('Shop') . '</option>
					<option value="id_currency"' . ($specific_price_priorities[1] == 'id_currency' ? ' selected="selected"' : '') . '>' . $this->l('Currency') . '</option>
					<option value="id_country"' . ($specific_price_priorities[1] == 'id_country' ? ' selected="selected"' : '') . '>' . $this->l('Country') . '</option>
					<option value="id_group"' . ($specific_price_priorities[1] == 'id_group' ? ' selected="selected"' : '') . '>' . $this->l('Group') . '</option>
				</select>
				<span class="input-group-addon"><i class="icon-chevron-right"></i></span>
				<select name="specificPricePriority[]">
					<option value="id_shop"' . ($specific_price_priorities[2] == 'id_shop' ? ' selected="selected"' : '') . '>' . $this->l('Shop') . '</option>
					<option value="id_currency"' . ($specific_price_priorities[2] == 'id_currency' ? ' selected="selected"' : '') . '>' . $this->l('Currency') . '</option>
					<option value="id_country"' . ($specific_price_priorities[2] == 'id_country' ? ' selected="selected"' : '') . '>' . $this->l('Country') . '</option>
					<option value="id_group"' . ($specific_price_priorities[2] == 'id_group' ? ' selected="selected"' : '') . '>' . $this->l('Group') . '</option>
				</select>
				<span class="input-group-addon"><i class="icon-chevron-right"></i></span>
				<select name="specificPricePriority[]">
					<option value="id_shop"' . ($specific_price_priorities[3] == 'id_shop' ? ' selected="selected"' : '') . '>' . $this->l('Shop') . '</option>
					<option value="id_currency"' . ($specific_price_priorities[3] == 'id_currency' ? ' selected="selected"' : '') . '>' . $this->l('Currency') . '</option>
					<option value="id_country"' . ($specific_price_priorities[3] == 'id_country' ? ' selected="selected"' : '') . '>' . $this->l('Country') . '</option>
					<option value="id_group"' . ($specific_price_priorities[3] == 'id_group' ? ' selected="selected"' : '') . '>' . $this->l('Group') . '</option>
				</select>
			</div>
		</div>
		<div class="form-group">
			<div class="col-lg-9 col-lg-offset-3">
				<p class="checkbox">
					<label for="specificPricePriorityToAll"><input type="checkbox" name="specificPricePriorityToAll" id="specificPricePriorityToAll" />' . $this->l('Apply to all products') . '</label>
				</p>
			</div>
		</div>
		<div class="panel-footer">
				<a href="' . $this->context->link->getAdminLink('AdminProducts') . '" class="btn btn-default"><i class="process-icon-cancel"></i> ' . $this->l('Cancel') . '</a>
				<button id="product_form_submit_btn"  type="submit" name="submitAddproduct" class="btn btn-default pull-right" disabled="disabled"><i class="process-icon-loading"></i> ' . $this->l('Save') . '</button>
				<button id="product_form_submit_btn"  type="submit" name="submitAddproductAndStay" class="btn btn-default pull-right" disabled="disabled"><i class="process-icon-loading"></i> ' . $this->l('Save and stay') . '</button>
			</div>
		</div>
		';
        return $content;
    }
Example #3
0
 private function defaultQtyInternal($qty, $format)
 {
     $default_qty = $this->p_properties['pp_default_quantity'];
     if ($qty > $default_qty) {
         $default_qty = $qty;
     }
     return $format ? PP::formatQty($default_qty) : $default_qty;
 }
Example #4
0
    private function getEditTemplateTabHtml($templates, $mode, $title)
    {
        if (!$this->integrated) {
            return '';
        }
        if ($mode == 'add') {
            $id = 0;
            if ($templates == null) {
                foreach ($this->active_languages as $language) {
                    $template = PP::getProductPropertiesByTemplateId($id);
                    $template['name'] = '';
                    $template['auto_desc'] = 1;
                    $template['description'] = '';
                    $templates[$language['id_lang']][$id] = $template;
                }
            }
        } else {
            $id = (int) Tools::getValue('id');
        }
        if ($templates == null) {
            $templates = PP::getAllTemplates();
        }
        $template = $templates[$this->default_language_id][$id];
        $ms = PP::resolveMS($template['pp_bo_measurement_system']);
        $all_properties = $this->getAllProperties($ms);
        $property_types = $this->getPropertyTypes();
        $translations = $this->getTranslations('EditTemplate');
        $buttons = array(array('title' => $this->l('Cancel'), 'type' => 'submit', 'name' => 'cancelSaveTemplate', 'icon' => 'process-icon-cancel'));
        $helper = $this->createHelperForm('pp_template_form', $title, 'submitSaveTemplate', 'icon-edit');
        $form = array('input' => array(array('type' => 'div', 'label' => $this->l('ID'), 'name' => $id, 'class' => 'control-text', 'condition' => $mode == 'edit'), array('type' => 'text', 'label' => $this->l('name'), 'name' => 'name_input', 'lang' => true), array('type' => 'text', 'label' => $this->l('description'), 'name' => 'description_input', 'lang' => true, 'desc' => $this->l('leave blank to use auto generated description')), array('type' => 'radio', 'label' => $translations['s_pp_qty_policy'], 'name' => 'pp_qty_policy', 'desc' => $this->l('ordered quantity specifies number of items (pieces, packs, etc.) or one item of the specified number of whole or fractional units (kg, m, ft, etc.)'), 'values' => array(array('id' => 'pp_qty_policy_0', 'value' => 0, 'label' => $translations['s_pp_qty_policy_0']), array('id' => 'pp_qty_policy_1', 'value' => 1, 'label' => $translations['s_pp_qty_policy_1']), array('id' => 'pp_qty_policy_2', 'value' => 2, 'label' => $translations['s_pp_qty_policy_2']), array('id' => 'pp_qty_policy_3', 'value' => 3, 'label' => $translations['s_pp_qty_policy_ext']))), array('type' => 'radio', 'label' => $translations['s_pp_qty_mode'], 'name' => 'pp_qty_mode', 'desc' => $this->l('product quantity can be exactly measured or only approximately (the exact amount cannot be ordered) - only if quantity policy is set to units'), 'values' => array(array('id' => 'pp_qty_mode_0', 'value' => 0, 'label' => $translations['s_pp_qty_mode_0']), array('id' => 'pp_qty_mode_1', 'value' => 1, 'label' => $translations['s_pp_qty_mode_1']))), array('type' => 'radio', 'label' => $translations['s_pp_display_mode'], 'name' => 'pp_display_mode', 'desc' => $translations['s_pp_display_mode_1_long'], 'values' => array(array('id' => 'pp_display_mode_0', 'value' => 0, 'label' => $translations['s_pp_display_mode_0']), array('id' => 'pp_display_mode_1', 'value' => 1, 'label' => $translations['s_pp_display_mode_1'])), 'checkboxes' => array(array('values' => array('query' => array(array('id' => 'retail_price', 'name' => $translations['s_pp_display_mode_2'], 'val' => '1')), 'id' => 'id', 'name' => 'name')), array('values' => array('query' => array(array('id' => 'base_unit_price', 'name' => $translations['s_pp_display_mode_4'], 'val' => '1')), 'id' => 'id', 'name' => 'name')))), array('type' => 'radio', 'label' => $translations['s_pp_price_display_mode'], 'name' => 'pp_price_display_mode', 'desc' => $this->l('show calculated price separately, display it the position of the product price or hide the calculated price'), 'values' => array(array('id' => 'pp_price_display_mode_0', 'value' => 0, 'label' => $translations['s_pp_price_display_mode_0']), array('id' => 'pp_price_display_mode_1', 'value' => 1, 'label' => $translations['s_pp_price_display_mode_1']), array('id' => 'pp_price_display_mode_16', 'value' => 16, 'label' => $translations['s_pp_price_display_mode_16']))), $this->createHelperFormSelect('pp_price_text', array('label' => $translations['s_pp_price_text'], 'desc' => $this->l('displayed after the product\'s price')), self::PROPERTY_TYPE_GENERAL, $helper, $template, $all_properties, $property_types), $this->createHelperFormSelect('pp_qty_text', array('label' => $translations['s_pp_qty_text'], 'desc' => $this->l('displayed after the product\'s quantity')), self::PROPERTY_TYPE_GENERAL, $helper, $template, $all_properties, $property_types), $this->createHelperFormSelect('pp_unity_text', array('label' => $translations['s_pp_unity_text'], 'desc' => $this->l('displayed for products with unit price greater than zero')), self::PROPERTY_TYPE_GENERAL, $helper, $template, $all_properties, $property_types), array('type' => 'text', 'label' => $translations['s_pp_unit_price_ratio'], 'name' => 'unit_price_ratio', 'class' => 'fixed-width-xl', 'desc' => $this->l('used to auto calculate unit price in product catalog')), array('type' => 'text', 'label' => $translations['s_pp_minimal_price_ratio'], 'name' => 'minimal_price_ratio', 'class' => 'fixed-width-xl', 'desc' => $this->l('used to calculate minimum price for quantity less than the specified threshold')), array('type' => 'text', 'label' => $translations['s_pp_minimal_quantity'], 'name' => 'minimal_quantity', 'class' => 'fixed-width-xl', 'desc' => $this->l('the minimum quantity to buy a product (leave blank to use default)')), array('type' => 'text', 'label' => $translations['s_pp_default_quantity'], 'name' => 'default_quantity', 'class' => 'fixed-width-xl', 'desc' => $this->l('the initial quantity to buy a product (leave blank to use default)')), array('type' => 'text', 'label' => $translations['s_pp_qty_step'], 'name' => 'qty_step', 'class' => 'fixed-width-xl', 'desc' => $this->l('quantity step (leave blank to use default)')), $this->createHelperFormSelect('pp_explanation', array('label' => $translations['s_pp_explanation']), self::PROPERTY_TYPE_BUY_BLOCK_TEXT, $helper, $template, $all_properties, $property_types), array('type' => 'text', 'label' => $this->l('CSS classes'), 'name' => 'pp_css', 'desc' => $this->l('specify valid CSS classes separated by space (these classes will be added to HTML for products using this template)') . '
							   <br/>' . sprintf($this->l('add your classes definitions in the "%s" file'), PSM::normalizePath('themes/' . _THEME_NAME_ . '/css/modules/pproperties/custom.css'))), array('type' => 'radio', 'label' => $this->l('display available quantities mode'), 'name' => 'pp_bo_qty_available_display', 'desc' => $this->l('display available quantities on the product page based on the template configuration (only if enabled in preferences)') . ($template['pp_bo_qty_available_display'] == 0 ? '<br>' . ($template['pp_qty_available_display'] == 2 ? $this->l('-- available quantities will be hidden on the product page for current template --') : $this->l('-- available quantities will be displayed on the product page for current template --')) : ''), 'values' => array(array('id' => 'pp_bo_qty_available_display_0', 'value' => 0, 'label' => $this->l('auto')), array('id' => 'pp_bo_qty_available_display_1', 'value' => 1, 'label' => $this->l('visible')), array('id' => 'pp_bo_qty_available_display_2', 'value' => 2, 'label' => $this->l('hidden')))), array('type' => 'radio', 'label' => $this->l('measurement system'), 'name' => 'pp_bo_measurement_system', 'desc' => $this->l('unit measurement system used by this template (default - use measurement system defined in Settings)'), 'values' => array(array('id' => 'pp_bo_measurement_system_0', 'value' => (int) PP::PP_MS_DEFAULT, 'label' => $this->l('default')), array('id' => 'pp_bo_measurement_system_1', 'value' => (int) PP::PP_MS_METRIC, 'label' => $this->l('metric')), array('id' => 'pp_bo_measurement_system_2', 'value' => (int) PP::PP_MS_NON_METRIC, 'label' => $this->l('non metric')))), array('type' => 'radio', 'label' => $this->l('visible in catalog'), 'name' => 'pp_bo_hidden', 'desc' => $this->l('hidden template is not visible in the product catalog, but still used in the shop'), 'values' => array(array('id' => 'pp_bo_hidden_0', 'value' => 0, 'label' => $this->l('visible')), array('id' => 'pp_bo_hidden_1', 'value' => 1, 'label' => $this->l('hidden')))), array('type' => 'hidden', 'name' => 'id'), array('type' => 'hidden', 'name' => 'mode')), 'buttons' => $buttons);
        $helper->fields_value['id'] = $id;
        $helper->fields_value['mode'] = $mode;
        $helper->fields_value['name_input'] = array();
        $helper->fields_value['description_input'] = array();
        foreach ($this->active_languages as $language) {
            $id_lang = $language['id_lang'];
            $helper->fields_value['name_input'][$id_lang] = isset($templates[$id_lang]) ? PP::safeOutputValue($templates[$id_lang][$id]['name']) : '';
            $helper->fields_value['description_input'][$id_lang] = isset($templates[$id_lang]) ? PP::safeOutputValue($templates[$id_lang][$id]['auto_desc'] || $mode == 'copy' ? '' : $templates[$id_lang][$id]['description']) : '';
        }
        $helper->fields_value['pp_qty_mode'] = $template['pp_qty_mode'];
        $helper->fields_value['pp_display_mode'] = (int) (($template['pp_display_mode'] & 1) == 1);
        $helper->fields_value['pp_display_mode_retail_price'] = (int) (($template['pp_display_mode'] & 2) == 2);
        $helper->fields_value['pp_display_mode_base_unit_price'] = (int) (($template['pp_display_mode'] & 4) == 4);
        $helper->fields_value['pp_price_display_mode'] = $template['pp_price_display_mode'];
        $helper->fields_value['unit_price_ratio'] = (double) $template['pp_unit_price_ratio'] > 0 ? PP::formatQty($template['pp_unit_price_ratio']) : '';
        $helper->fields_value['minimal_price_ratio'] = (double) $template['pp_minimal_price_ratio'] > 0 ? PP::formatQty($template['pp_minimal_price_ratio']) : '';
        $helper->fields_value['minimal_quantity'] = (double) $template['pp_minimal_quantity'] > 0 ? PP::formatQty($template['pp_minimal_quantity']) : '';
        $helper->fields_value['default_quantity'] = (double) $template['pp_default_quantity'] > 0 ? PP::formatQty($template['pp_default_quantity']) : '';
        $helper->fields_value['qty_step'] = (double) $template['pp_qty_step'] > 0 ? PP::formatQty($template['pp_qty_step']) : '';
        $helper->fields_value['pp_css'] = $template['pp_css'];
        $helper->fields_value['pp_bo_qty_available_display'] = $template['pp_bo_qty_available_display'];
        $helper->fields_value['pp_bo_measurement_system'] = $template['pp_bo_measurement_system'];
        $helper->fields_value['pp_bo_hidden'] = $template['pp_bo_hidden'];
        $dimensions = isset($template['pp_ext_method']) && isset($template['pp_ext_prop']) ? count($template['pp_ext_prop']) : 0;
        if ($dimensions == 0) {
            $value = 0;
        } elseif ($dimensions == 1) {
            $value = 3;
        } else {
            $value = $template['pp_ext_method'];
        }
        $helper->fields_value['pp_ext_method'] = $value;
        $helper->fields_value['pp_ext_method_fallback'] = $value;
        $helper->fields_value['pp_ext_policy'] = isset($template['pp_ext_policy']) ? $template['pp_ext_policy'] : 0;
        if ($template['pp_qty_policy'] == 2 && $helper->fields_value['pp_ext_method'] > 0) {
            $helper->fields_value['pp_qty_policy'] = 3;
        } else {
            $helper->fields_value['pp_qty_policy'] = $template['pp_qty_policy'];
        }
        $translations = $this->getTranslations('ppExt');
        $dimensions_form = array('legend' => array('title' => $this->l('Dimensions')), 'multidimensional-feature' => array('text' => $this->l('this feature is disabled if calculation method is not specified'), 'disabled' => $this->l('This feature is disabled. To enable this feature please install the multidimensional plugin from'), 'readme_url' => $this->multidimensional_plugin ? $this->multidimensional_plugin->readme_url() : '', 'readme_pdf' => $this->l('Multidimensional plugin user guide')), 'input' => array(array('type' => 'select', 'label' => $this->l('calculation method'), 'name' => 'pp_ext_method', 'options' => array('query' => array(array('id' => 0, 'name' => '&nbsp;'), array('id' => 1, 'name' => $translations['s_multiplication']), array('id' => 2, 'name' => $translations['s_summation']), array('id' => 3, 'name' => $translations['s_single_dimension'])), 'id' => 'id', 'name' => 'name')), array('type' => 'hidden', 'name' => 'pp_ext_method_fallback'), $this->createHelperFormSelect('pp_ext_title', array('label' => $this->l('dimensions block title'), 'form_group_class' => 'dimensions-toggle'), self::DIMENSIONS, $helper, $template, $all_properties, $property_types), $this->createHelperFormSelect('pp_ext_property', array('label' => $this->l('calculation result label'), 'desc' => $this->l('leave blank to hide calculation result'), 'form_group_class' => 'dimensions-toggle'), self::DIMENSIONS, $helper, $template, $all_properties, $property_types), $this->createHelperFormSelect('pp_ext_text', array('label' => $this->l('calculation result text'), 'form_group_class' => 'dimensions-toggle'), array(self::PROPERTY_TYPE_GENERAL, self::DIMENSIONS), $helper, $template, $all_properties, $property_types), array('type' => 'radio', 'label' => $this->l('dimensions policy'), 'name' => 'pp_ext_policy', 'desc' => $this->l('dimensions can be specified by the customer (default) or used by the packs calculator or used as the product properties affecting price, visible in the shop and editable only in the back office'), 'form_group_class' => 'dimensions-toggle', 'values' => array(array('id' => 'pp_ext_policy_0', 'value' => 0, 'label' => $this->l('default')), array('id' => 'pp_ext_policy_1', 'value' => 1, 'label' => $this->l('packs calculator')), array('id' => 'pp_ext_policy_2', 'value' => 2, 'label' => $this->l('product properties'))))), 'buttons' => $buttons);
        $dimensions_form['dimensions-table'] = array('th' => array($this->l('dimension'), $this->l('quantity text *'), $this->l('minimum quantity'), $this->l('maximum quantity'), $this->l('default quantity'), $this->l('quantity step'), $this->l('quantity ratio'), $this->l('order quantity text **')), 'tbody' => array());
        $max_dimensions = isset($template['pp_ext_prop']) ? count($template['pp_ext_prop']) : 3;
        if ($max_dimensions < 3) {
            $max_dimensions = 3;
        }
        for ($dimension_index = 1; $dimension_index <= $max_dimensions; $dimension_index++) {
            $td = array();
            $value = PP::getTemplateExtProperty($template, $dimension_index, 'property');
            $td[] = $this->createHelperFormSelect('dimension_' . $dimension_index, array('data_type' => 'dimension_', 'data_position' => $dimension_index), self::PROPERTY_TYPE_EXT, $helper, $value, $all_properties, $property_types);
            $value = PP::getTemplateExtProperty($template, $dimension_index, 'text');
            $td[] = $this->createHelperFormSelect('dimension_text_' . $dimension_index, array('data_type' => 'dimension_text_', 'data_position' => $dimension_index), array(self::PROPERTY_TYPE_GENERAL, self::DIMENSIONS), $helper, $value, $all_properties, $property_types);
            $td[] = array('type' => 'text', 'name' => 'dimension_minimum_quantity_' . $dimension_index, 'data_type' => 'dimension_minimum_quantity_', 'data_position' => $dimension_index);
            $td[] = array('type' => 'text', 'name' => 'dimension_maximum_quantity_' . $dimension_index, 'data_type' => 'dimension_maximum_quantity_', 'data_position' => $dimension_index);
            $td[] = array('type' => 'text', 'name' => 'dimension_default_quantity_' . $dimension_index, 'data_type' => 'dimension_default_quantity_', 'data_position' => $dimension_index);
            $td[] = array('type' => 'text', 'name' => 'dimension_qty_step_' . $dimension_index, 'data_type' => 'dimension_qty_step_', 'data_position' => $dimension_index);
            $td[] = array('type' => 'text', 'name' => 'dimension_qty_ratio_' . $dimension_index, 'data_type' => 'dimension_qty_ratio_', 'data_position' => $dimension_index);
            $helper->fields_value['dimension_minimum_quantity_' . $dimension_index] = (double) PP::getTemplateExtProperty($template, $dimension_index, 'minimum_quantity') > 0 ? PP::formatQty(PP::getTemplateExtProperty($template, $dimension_index, 'minimum_quantity')) : '';
            $helper->fields_value['dimension_maximum_quantity_' . $dimension_index] = (double) PP::getTemplateExtProperty($template, $dimension_index, 'maximum_quantity') > 0 ? PP::formatQty(PP::getTemplateExtProperty($template, $dimension_index, 'maximum_quantity')) : '';
            $helper->fields_value['dimension_default_quantity_' . $dimension_index] = (double) PP::getTemplateExtProperty($template, $dimension_index, 'default_quantity') > 0 ? PP::formatQty(PP::getTemplateExtProperty($template, $dimension_index, 'default_quantity')) : '';
            $helper->fields_value['dimension_qty_step_' . $dimension_index] = (double) PP::getTemplateExtProperty($template, $dimension_index, 'qty_step') > 0 ? PP::formatQty(PP::getTemplateExtProperty($template, $dimension_index, 'qty_step')) : '';
            $helper->fields_value['dimension_qty_ratio_' . $dimension_index] = (double) PP::getTemplateExtProperty($template, $dimension_index, 'qty_ratio') > 0 ? PP::formatQty(PP::getTemplateExtProperty($template, $dimension_index, 'qty_ratio')) : '';
            $value = PP::getTemplateExtProperty($template, $dimension_index, 'order_text');
            $td[] = $this->createHelperFormSelect('dimension_order_text_' . $dimension_index, array('data_type' => 'dimension_order_text_', 'data_position' => $dimension_index), array(self::PROPERTY_TYPE_GENERAL, self::DIMENSIONS), $helper, $value, $all_properties, $property_types);
            $dimensions_form['dimensions-table']['tbody'][] = array('tr' => array('td' => $td));
        }
        $dimensions_form['help-block'] = array('class' => 'dimensions-toggle', 'text' => array('*&nbsp;&nbsp;&nbsp;' . $this->l('quantity text is used on the product page in the shop'), '**&nbsp;&nbsp;' . $this->l('order quantity text is used in order and invoice')));
        if ($this->multidimensional_plugin) {
            $dimensions_form['multidimensionalAdmin'] = 'multidimensionalAdmin';
        }
        $forms = array('form' => $form, 'dimensions_form' => $dimensions_form);
        $hook_forms = Hook::exec('ppropertiesAdmin', array('mode' => 'displayEditTemplateForm', 'id_pp_template' => $id), null, true);
        if (is_array($hook_forms)) {
            foreach ($hook_forms as $hook_module => $hook_form) {
                if (isset($hook_form['form'])) {
                    if (!isset($hook_form['form']['buttons'])) {
                        $hook_form['form']['buttons'] = $buttons;
                    }
                    $forms[$hook_module . '_form'] = $hook_form['form'];
                }
            }
        }
        $html = $this->generateForm($helper, $forms, array('id_pp_template' => $id, 'multidimensional' => $this->multidimensional_plugin, 'script' => array('multidimensional')));
        return $html;
    }