Version Notes
The wrong js file was included
Download this release
Release Info
Developer | Magento Core Team |
Extension | Automatic_Configurables_1dot3 |
Version | 0.0.8 |
Comparing to | |
See all releases |
Version 0.0.8
- app/code/local/QS/Quickconfigurables/Block/Adminhtml/Catalog/Product/Edit/Tab/Super/Config.php +78 -0
- app/code/local/QS/Quickconfigurables/Block/Adminhtml/Catalog/Product/Edit/Tab/Super/Config/Combination.php +159 -0
- app/code/local/QS/Quickconfigurables/Helper/Data.php +13 -0
- app/code/local/QS/Quickconfigurables/controllers/Adminhtml/ProductController.php +182 -0
- app/code/local/QS/Quickconfigurables/etc/config.xml +91 -0
- app/design/adminhtml/default/default/layout/quickconfigurables.xml +36 -0
- app/design/adminhtml/default/default/template/quickconfigurables/catalog/product/edit/super/config.phtml +142 -0
- app/etc/modules/QS_Quickconfigurables.xml +9 -0
- js/qs/adminhtml/product_13.js +1007 -0
- package.xml +22 -0
app/code/local/QS/Quickconfigurables/Block/Adminhtml/Catalog/Product/Edit/Tab/Super/Config.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Magento
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
18 |
+
* versions in the future. If you wish to customize Magento for your
|
19 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Adminhtml
|
23 |
+
* @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Adminhtml catalog super product configurable tab
|
30 |
+
*
|
31 |
+
* @category Mage
|
32 |
+
* @package Mage_Adminhtml
|
33 |
+
* @author Magento Core Team <core@magentocommerce.com>
|
34 |
+
*/
|
35 |
+
class QS_Quickconfigurables_Block_Adminhtml_Catalog_Product_Edit_Tab_Super_Config extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config implements Mage_Adminhtml_Block_Widget_Tab_Interface
|
36 |
+
{
|
37 |
+
/**
|
38 |
+
* Initialize block
|
39 |
+
*
|
40 |
+
*/
|
41 |
+
public function __construct()
|
42 |
+
{
|
43 |
+
parent::__construct();
|
44 |
+
$this->setTemplate('quickconfigurables/catalog/product/edit/super/config.phtml');
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Prepare Layout data
|
49 |
+
*
|
50 |
+
* @return Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config
|
51 |
+
*/
|
52 |
+
protected function _prepareLayout()
|
53 |
+
{
|
54 |
+
if ($this->_getProduct()->getId()) {
|
55 |
+
$this->setChild('combination',
|
56 |
+
$this->getLayout()->createBlock('quickconfigurables/adminhtml_catalog_product_edit_tab_super_config_combination')
|
57 |
+
);
|
58 |
+
}
|
59 |
+
return parent::_prepareLayout();
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Retrieve Create New Empty Product URL
|
64 |
+
*
|
65 |
+
* @return string
|
66 |
+
*/
|
67 |
+
public function getCombinationsUrl()
|
68 |
+
{
|
69 |
+
return $this->getUrl(
|
70 |
+
'quickconfigurables/adminhtml_product/combination',
|
71 |
+
array(
|
72 |
+
'set' => $this->_getProduct()->getAttributeSetId(),
|
73 |
+
'product' => $this->_getProduct()->getId(),
|
74 |
+
'required' => $this->_getRequiredAttributesIds(),
|
75 |
+
)
|
76 |
+
);
|
77 |
+
}
|
78 |
+
}
|
app/code/local/QS/Quickconfigurables/Block/Adminhtml/Catalog/Product/Edit/Tab/Super/Config/Combination.php
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Adminhtml catalog super product configurable create combinations tab
|
4 |
+
*
|
5 |
+
* @category QS
|
6 |
+
* @package QS_Quickconfigurables
|
7 |
+
* @author Quart-soft Magento Team <info@quart-soft.com>
|
8 |
+
* @copyright Copyright (c) 2010 Quart-soft Ltd http://quart-soft.com
|
9 |
+
*/
|
10 |
+
class QS_Quickconfigurables_Block_Adminhtml_Catalog_Product_Edit_Tab_Super_Config_Combination extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Attributes
|
11 |
+
{
|
12 |
+
protected function _prepareForm()
|
13 |
+
{
|
14 |
+
$form = new Varien_Data_Form();
|
15 |
+
|
16 |
+
$form->setFieldNameSuffix('combination');
|
17 |
+
|
18 |
+
$fieldset = $form->addFieldset('combination', array(
|
19 |
+
'legend' => Mage::helper('quickconfigurables')->__('Create Combinations in One Click')
|
20 |
+
));
|
21 |
+
$this->_addElementTypes($fieldset);
|
22 |
+
$attributesConfig = array(
|
23 |
+
'autogenerate' => array('name'),
|
24 |
+
'nonedit' => array('sku'),
|
25 |
+
'additional' => array('name', 'sku', 'visibility', 'status')
|
26 |
+
);
|
27 |
+
|
28 |
+
$availableTypes = array('text', 'select', 'multiselect', 'textarea', 'price');
|
29 |
+
|
30 |
+
$attributes = Mage::getModel('catalog/product')
|
31 |
+
->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE)
|
32 |
+
->setAttributeSetId($this->_getProduct()->getAttributeSetId())
|
33 |
+
->getAttributes();
|
34 |
+
|
35 |
+
/* Standart attributes */
|
36 |
+
foreach ($attributes as $attribute) {
|
37 |
+
if (($attribute->getIsRequired()
|
38 |
+
&& $attribute->getApplyTo()
|
39 |
+
// If not applied to configurable
|
40 |
+
&& !in_array(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE, $attribute->getApplyTo())
|
41 |
+
// If not used in configurable
|
42 |
+
&& !in_array($attribute->getId(),$this->_getProduct()->getTypeInstance(true)->getUsedProductAttributeIds($this->_getProduct())))
|
43 |
+
// Or in additional
|
44 |
+
|| in_array($attribute->getAttributeCode(), $attributesConfig['additional'])) {
|
45 |
+
|
46 |
+
$inputType = $attribute->getFrontend()->getInputType();
|
47 |
+
if (!in_array($inputType, $availableTypes)) {
|
48 |
+
continue;
|
49 |
+
}
|
50 |
+
$attributeCode = $attribute->getAttributeCode();
|
51 |
+
$element = $fieldset->addField(
|
52 |
+
'combination_' . $attributeCode,
|
53 |
+
$inputType,
|
54 |
+
array(
|
55 |
+
'label' => $attribute->getFrontend()->getLabel(),
|
56 |
+
'name' => $attributeCode,
|
57 |
+
'required' => $attribute->getIsRequired(),
|
58 |
+
)
|
59 |
+
)->setEntityAttribute($attribute);
|
60 |
+
|
61 |
+
if (in_array($attributeCode, $attributesConfig['autogenerate'])) {
|
62 |
+
$element->setDisabled('true');
|
63 |
+
$element->setValue($this->_getProduct()->getData($attributeCode));
|
64 |
+
$element->setAfterElementHtml(
|
65 |
+
'<input type="checkbox" id="combination_' . $attributeCode . '_autogenerate" '
|
66 |
+
. 'name="combination[' . $attributeCode . '_autogenerate]" value="1" '
|
67 |
+
. 'onclick="toggleValueElements(this, this.parentNode)" checked="checked" /> '
|
68 |
+
. '<label for="combination_' . $attributeCode . '_autogenerate" >'
|
69 |
+
. Mage::helper('catalog')->__('Autogenerate')
|
70 |
+
. '</label>'
|
71 |
+
);
|
72 |
+
}
|
73 |
+
|
74 |
+
if (in_array($attributeCode, $attributesConfig['nonedit'])) {
|
75 |
+
$element->setDisabled('true');
|
76 |
+
$element->setValue(Mage::helper('quickconfigurables')->__('Attribute value will be autogenerated'));
|
77 |
+
$element->setAfterElementHtml(
|
78 |
+
'<input type="hidden" id="combination_' . $attributeCode . '_autogenerate" '
|
79 |
+
. 'name="combination[' . $attributeCode . '_autogenerate]" value="1" '
|
80 |
+
);
|
81 |
+
}
|
82 |
+
|
83 |
+
|
84 |
+
if ($inputType == 'select' || $inputType == 'multiselect') {
|
85 |
+
$element->setValues($attribute->getFrontend()->getSelectOptions());
|
86 |
+
}
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
/* Configurable attributes */
|
91 |
+
foreach ($this->_getProduct()->getTypeInstance(true)->getUsedProductAttributes($this->_getProduct()) as $attribute) {
|
92 |
+
$attributeCode = $attribute->getAttributeCode();
|
93 |
+
$fieldset->addField( 'combination_' . $attributeCode, 'multiselect', array(
|
94 |
+
'label' => $attribute->getFrontend()->getLabel(),
|
95 |
+
'name' => $attributeCode,
|
96 |
+
'values' => $attribute->getSource()->getAllOptions(true, true),
|
97 |
+
'required' => true,
|
98 |
+
'class' => 'validate-configurable',
|
99 |
+
));
|
100 |
+
}
|
101 |
+
|
102 |
+
/* Inventory Data */
|
103 |
+
$fieldset->addField('combination_inventory_qty', 'text', array(
|
104 |
+
'label' => Mage::helper('catalog')->__('Qty'),
|
105 |
+
'name' => 'stock_data[qty]',
|
106 |
+
'class' => 'validate-number',
|
107 |
+
'required' => true,
|
108 |
+
'value' => 0
|
109 |
+
));
|
110 |
+
|
111 |
+
$fieldset->addField('combination_inventory_is_in_stock', 'select', array(
|
112 |
+
'label' => Mage::helper('catalog')->__('Stock Availability'),
|
113 |
+
'name' => 'stock_data[is_in_stock]',
|
114 |
+
'values' => array(
|
115 |
+
array('value'=>1, 'label'=> Mage::helper('catalog')->__('In Stock')),
|
116 |
+
array('value'=>0, 'label'=> Mage::helper('catalog')->__('Out of Stock'))
|
117 |
+
),
|
118 |
+
'value' => 1
|
119 |
+
));
|
120 |
+
|
121 |
+
$stockHiddenFields = array(
|
122 |
+
'use_config_min_qty' => 1,
|
123 |
+
'use_config_min_sale_qty' => 1,
|
124 |
+
'use_config_max_sale_qty' => 1,
|
125 |
+
'use_config_backorders' => 1,
|
126 |
+
'use_config_notify_stock_qty' => 1,
|
127 |
+
'is_qty_decimal' => 0
|
128 |
+
);
|
129 |
+
|
130 |
+
foreach ($stockHiddenFields as $fieldName=>$fieldValue) {
|
131 |
+
$fieldset->addField('combination_inventory_' . $fieldName, 'hidden', array(
|
132 |
+
'name' => 'stock_data[' . $fieldName .']',
|
133 |
+
'value' => $fieldValue
|
134 |
+
));
|
135 |
+
}
|
136 |
+
|
137 |
+
|
138 |
+
$fieldset->addField('create_button', 'note', array(
|
139 |
+
'text' => $this->getButtonHtml(
|
140 |
+
Mage::helper('catalog')->__('Create Combinations'),
|
141 |
+
//'superProduct.createPopup(createCombinationsUrl)',
|
142 |
+
'superProduct.quickCombinations()',
|
143 |
+
'save'
|
144 |
+
)
|
145 |
+
));
|
146 |
+
|
147 |
+
$this->setForm($form);
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Retrieve currently edited product object
|
152 |
+
*
|
153 |
+
* @return Mage_Catalog_Model_Product
|
154 |
+
*/
|
155 |
+
protected function _getProduct()
|
156 |
+
{
|
157 |
+
return Mage::registry('current_product');
|
158 |
+
}
|
159 |
+
}
|
app/code/local/QS/Quickconfigurables/Helper/Data.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Quickconfigurables Helper Data
|
4 |
+
*
|
5 |
+
* @category QS
|
6 |
+
* @package QS_Quickconfigurables
|
7 |
+
* @author Quart-soft Magento Team <info@quart-soft.com>
|
8 |
+
* @copyright Copyright (c) 2010 Quart-soft Ltd http://quart-soft.com
|
9 |
+
*/
|
10 |
+
|
11 |
+
class QS_Quickconfigurables_Helper_Data extends Mage_Core_Helper_Abstract
|
12 |
+
{
|
13 |
+
}
|
app/code/local/QS/Quickconfigurables/controllers/Adminhtml/ProductController.php
ADDED
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Adminhtml quickconfigurable product controller
|
4 |
+
*
|
5 |
+
* @category QS
|
6 |
+
* @package QS_Quickconfigurables
|
7 |
+
* @author Quart-soft Magento Team <info@quart-soft.com>
|
8 |
+
* @copyright Copyright (c) 2010 Quart-soft Ltd http://quart-soft.com
|
9 |
+
*/
|
10 |
+
|
11 |
+
class QS_Quickconfigurables_Adminhtml_ProductController extends Mage_Adminhtml_Controller_action
|
12 |
+
{
|
13 |
+
public function combinationAction()
|
14 |
+
{
|
15 |
+
$result = array();
|
16 |
+
$error = false;
|
17 |
+
$success = false;
|
18 |
+
|
19 |
+
/* @var $configurableProduct Mage_Catalog_Model_Product */
|
20 |
+
$configurableProduct = Mage::getModel('catalog/product')
|
21 |
+
->setStoreId(0)
|
22 |
+
->load($this->getRequest()->getParam('product'));
|
23 |
+
|
24 |
+
if (!$configurableProduct->isConfigurable()) {
|
25 |
+
// If invalid parent product
|
26 |
+
$this->_redirect('*/*/');
|
27 |
+
return;
|
28 |
+
}
|
29 |
+
|
30 |
+
$postData = $this->getRequest()->getParam('combination', array());
|
31 |
+
|
32 |
+
$attributeValues = array();
|
33 |
+
$requiredAttributesIds = explode(',',$this->getRequest()->getParam('required'));
|
34 |
+
foreach ($requiredAttributesIds as $requiredAttributeId){
|
35 |
+
$attributeData = Mage::getModel('eav/config')->getAttribute('catalog_product', $requiredAttributeId);
|
36 |
+
foreach ($postData[$attributeData->getAttributeCode()] as $option){
|
37 |
+
if ($option){
|
38 |
+
$attributeValues[$attributeData->getAttributeCode()][] = $option;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
$combinationsTemp = array();
|
44 |
+
$combinationsFinal = array();
|
45 |
+
$i = 0;
|
46 |
+
|
47 |
+
foreach($attributeValues as $code=>$values){
|
48 |
+
$combinationsFinal = array();
|
49 |
+
if ($combinationsTemp){
|
50 |
+
foreach ($combinationsTemp as $tmpComb){
|
51 |
+
foreach ($values as $value){
|
52 |
+
$combinationsFinal[] = array(
|
53 |
+
'codes' => $tmpComb['codes'] . ':' . $code,
|
54 |
+
'values' => $tmpComb['values'] . ':' . $value,
|
55 |
+
);
|
56 |
+
}
|
57 |
+
}
|
58 |
+
} else {
|
59 |
+
foreach ($values as $value){
|
60 |
+
$combinationsFinal[] = array(
|
61 |
+
'codes' => $code,
|
62 |
+
'values' => $value,
|
63 |
+
);
|
64 |
+
}
|
65 |
+
}
|
66 |
+
$combinationsTemp = $combinationsFinal;
|
67 |
+
}
|
68 |
+
|
69 |
+
$result['product_ids'] = array();
|
70 |
+
|
71 |
+
foreach ($combinationsFinal as $comb){
|
72 |
+
|
73 |
+
/* @var $product Mage_Catalog_Model_Product */
|
74 |
+
$product = Mage::getModel('catalog/product')
|
75 |
+
->setStoreId(0)
|
76 |
+
->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE)
|
77 |
+
->setAttributeSetId($configurableProduct->getAttributeSetId());
|
78 |
+
|
79 |
+
|
80 |
+
foreach ($product->getTypeInstance()->getEditableAttributes() as $attribute) {
|
81 |
+
if ($attribute->getIsUnique()
|
82 |
+
|| $attribute->getFrontend()->getInputType() == 'gallery'
|
83 |
+
|| $attribute->getFrontend()->getInputType() == 'media_image'
|
84 |
+
|| !$attribute->getIsVisible()) {
|
85 |
+
continue;
|
86 |
+
}
|
87 |
+
|
88 |
+
$product->setData(
|
89 |
+
$attribute->getAttributeCode(),
|
90 |
+
$configurableProduct->getData($attribute->getAttributeCode())
|
91 |
+
);
|
92 |
+
}
|
93 |
+
|
94 |
+
$product->addData($this->getRequest()->getParam('combination', array()));
|
95 |
+
|
96 |
+
$codesToSet = explode(':',$comb['codes']);
|
97 |
+
$valuesToSet = explode(':',$comb['values']);
|
98 |
+
$i = 0;
|
99 |
+
foreach ($codesToSet as $codeToSet ){
|
100 |
+
$product->setData(
|
101 |
+
$codeToSet,
|
102 |
+
$valuesToSet[$i++]
|
103 |
+
);
|
104 |
+
}
|
105 |
+
|
106 |
+
$product->setWebsiteIds($configurableProduct->getWebsiteIds());
|
107 |
+
|
108 |
+
$autogenerateOptions = array();
|
109 |
+
|
110 |
+
$attrsIds = explode(',',$this->getRequest()->getParam('required'));
|
111 |
+
|
112 |
+
foreach ($attrsIds as $attrId) {
|
113 |
+
$attribute = Mage::getModel('eav/entity_attribute')->load($attrId);
|
114 |
+
Mage::log($attribute);
|
115 |
+
$value = $product->getAttributeText($attribute->getAttributeCode());
|
116 |
+
$autogenerateOptions[] = $value;
|
117 |
+
$result['attributes'][] = array(
|
118 |
+
'label' => $value,
|
119 |
+
'value_index' => $product->getData($attribute->getAttributeCode()),
|
120 |
+
'attribute_id' => $attribute->getId()
|
121 |
+
);
|
122 |
+
}
|
123 |
+
|
124 |
+
if ($product->getNameAutogenerate()) {
|
125 |
+
$product->setName($configurableProduct->getName() . '-' . implode('-', $autogenerateOptions));
|
126 |
+
}
|
127 |
+
|
128 |
+
if ($product->getSkuAutogenerate()) {
|
129 |
+
$product->setSku($configurableProduct->getSku() . '-' . implode('-', $autogenerateOptions));
|
130 |
+
}
|
131 |
+
|
132 |
+
if (is_array($product->getPricing())) {
|
133 |
+
$result['pricing'] = $product->getPricing();
|
134 |
+
$additionalPrice = 0;
|
135 |
+
foreach ($product->getPricing() as $pricing) {
|
136 |
+
if (empty($pricing['value'])) {
|
137 |
+
continue;
|
138 |
+
}
|
139 |
+
|
140 |
+
if (!empty($pricing['is_percent'])) {
|
141 |
+
$pricing['value'] = ($pricing['value']/100)*$product->getPrice();
|
142 |
+
}
|
143 |
+
|
144 |
+
$additionalPrice += $pricing['value'];
|
145 |
+
}
|
146 |
+
|
147 |
+
$product->setPrice($product->getPrice() + $additionalPrice);
|
148 |
+
$product->unsPricing();
|
149 |
+
}
|
150 |
+
|
151 |
+
try {
|
152 |
+
$success = true;
|
153 |
+
$product->validate();
|
154 |
+
$product->save();
|
155 |
+
$result['product_ids'][] = $product->getId();
|
156 |
+
} catch (Mage_Core_Exception $e) {
|
157 |
+
$result['error'] = array(
|
158 |
+
'message' => $e->getMessage(),
|
159 |
+
'fields' => array(
|
160 |
+
'sku' => $product->getSku()
|
161 |
+
)
|
162 |
+
);
|
163 |
+
|
164 |
+
} catch (Exception $e) {
|
165 |
+
Mage::logException($e);
|
166 |
+
$result['error'] = array(
|
167 |
+
'message' => $this->__('Product saving error. ') . $e->getMessage()
|
168 |
+
);
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
if ($success || $result['product_ids']){
|
173 |
+
$this->_getSession()->addSuccess(Mage::helper('catalog')->__('Total %s products were successfully created.',count($result['product_ids'])));
|
174 |
+
$this->_initLayoutMessages('adminhtml/session');
|
175 |
+
$result['messages'] = $this->getLayout()->getMessagesBlock()->getGroupedHtml();
|
176 |
+
}
|
177 |
+
|
178 |
+
//$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
|
179 |
+
$this->getResponse()->setBody(Zend_Json::encode($result));
|
180 |
+
}
|
181 |
+
|
182 |
+
}
|
app/code/local/QS/Quickconfigurables/etc/config.xml
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* Adminhtml catalog super product configurable create combinations tab
|
5 |
+
*
|
6 |
+
* @category QS
|
7 |
+
* @package QS_Quickconfigurables
|
8 |
+
* @author Quart-soft Magento Team <info@quart-soft.com>
|
9 |
+
* @copyright Copyright (c) 2010 Quart-soft Ltd http://quart-soft.com
|
10 |
+
*/
|
11 |
+
-->
|
12 |
+
<config>
|
13 |
+
<modules>
|
14 |
+
<QS_Quickconfigurables>
|
15 |
+
<version>0.1.0</version>
|
16 |
+
</QS_Quickconfigurables>
|
17 |
+
</modules>
|
18 |
+
<frontend>
|
19 |
+
<routers>
|
20 |
+
<quickconfigurables>
|
21 |
+
<use>standard</use>
|
22 |
+
<args>
|
23 |
+
<module>QS_Quickconfigurables</module>
|
24 |
+
<frontName>quickconfigurables</frontName>
|
25 |
+
</args>
|
26 |
+
</quickconfigurables>
|
27 |
+
</routers>
|
28 |
+
</frontend>
|
29 |
+
<adminhtml>
|
30 |
+
<layout>
|
31 |
+
<updates>
|
32 |
+
<quickconfigurables>
|
33 |
+
<file>quickconfigurables.xml</file>
|
34 |
+
</quickconfigurables>
|
35 |
+
</updates>
|
36 |
+
</layout>
|
37 |
+
</adminhtml>
|
38 |
+
<admin>
|
39 |
+
<routers>
|
40 |
+
<quickconfigurables>
|
41 |
+
<use>admin</use>
|
42 |
+
<args>
|
43 |
+
<module>QS_Quickconfigurables</module>
|
44 |
+
<frontName>quickconfigurables</frontName>
|
45 |
+
</args>
|
46 |
+
</quickconfigurables>
|
47 |
+
</routers>
|
48 |
+
</admin>
|
49 |
+
<global>
|
50 |
+
<models>
|
51 |
+
<quickconfigurables>
|
52 |
+
<class>QS_Quickconfigurables_Model</class>
|
53 |
+
</quickconfigurables>
|
54 |
+
</models>
|
55 |
+
<resources>
|
56 |
+
<quickconfigurables_setup>
|
57 |
+
<setup>
|
58 |
+
<module>QS_Quickconfigurables</module>
|
59 |
+
</setup>
|
60 |
+
<connection>
|
61 |
+
<use>core_setup</use>
|
62 |
+
</connection>
|
63 |
+
</quickconfigurables_setup>
|
64 |
+
<quickconfigurables_write>
|
65 |
+
<connection>
|
66 |
+
<use>core_write</use>
|
67 |
+
</connection>
|
68 |
+
</quickconfigurables_write>
|
69 |
+
<quickconfigurables_read>
|
70 |
+
<connection>
|
71 |
+
<use>core_read</use>
|
72 |
+
</connection>
|
73 |
+
</quickconfigurables_read>
|
74 |
+
</resources>
|
75 |
+
<blocks>
|
76 |
+
<quickconfigurables>
|
77 |
+
<class>QS_Quickconfigurables_Block</class>
|
78 |
+
</quickconfigurables>
|
79 |
+
<adminhtml>
|
80 |
+
<rewrite>
|
81 |
+
<catalog_product_edit_tab_super_config>QS_Quickconfigurables_Block_Adminhtml_Catalog_Product_Edit_Tab_Super_Config</catalog_product_edit_tab_super_config>
|
82 |
+
</rewrite>
|
83 |
+
</adminhtml>
|
84 |
+
</blocks>
|
85 |
+
<helpers>
|
86 |
+
<quickconfigurables>
|
87 |
+
<class>QS_Quickconfigurables_Helper</class>
|
88 |
+
</quickconfigurables>
|
89 |
+
</helpers>
|
90 |
+
</global>
|
91 |
+
</config>
|
app/design/adminhtml/default/default/layout/quickconfigurables.xml
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* Magento
|
5 |
+
*
|
6 |
+
* NOTICE OF LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the Academic Free License (AFL 3.0)
|
9 |
+
* that is bundled with this package in the file LICENSE_AFL.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://opensource.org/licenses/afl-3.0.php
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* DISCLAIMER
|
17 |
+
*
|
18 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
19 |
+
* versions in the future. If you wish to customize Magento for your
|
20 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
21 |
+
*
|
22 |
+
* @category design
|
23 |
+
* @package default_default
|
24 |
+
* @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
|
25 |
+
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
26 |
+
*/
|
27 |
+
-->
|
28 |
+
|
29 |
+
<layout>
|
30 |
+
<default>
|
31 |
+
<reference name="head">
|
32 |
+
<action method="removeItem"><type>js</type><name>mage/adminhtml/product.js</name></action>
|
33 |
+
<action method="addJs"><script>qs/adminhtml/product_13.js</script></action>
|
34 |
+
</reference>
|
35 |
+
</default>
|
36 |
+
</layout>
|
app/design/adminhtml/default/default/template/quickconfigurables/catalog/product/edit/super/config.phtml
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Magento
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Academic Free License (AFL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE_AFL.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/afl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
18 |
+
* versions in the future. If you wish to customize Magento for your
|
19 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category design
|
22 |
+
* @package default_default
|
23 |
+
* @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
|
24 |
+
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
25 |
+
*/
|
26 |
+
?>
|
27 |
+
<?php if (!$this->isReadonly()):?>
|
28 |
+
<div class="entry-edit">
|
29 |
+
<div id="assign_product_warrning" style="display: none;">
|
30 |
+
<ul class="messages">
|
31 |
+
<li class="error-msg">
|
32 |
+
<ul>
|
33 |
+
<li><?php echo $this->__('Links with associated products will retain only after saving current product.') ?></li>
|
34 |
+
</ul>
|
35 |
+
</li>
|
36 |
+
</ul>
|
37 |
+
</div>
|
38 |
+
<div class="entry-edit-head">
|
39 |
+
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Create Simple Associated Product') ?></h4>
|
40 |
+
</div>
|
41 |
+
<fieldset class="a-right">
|
42 |
+
<?php echo $this->getChildHtml('create_empty') ?> <?php echo $this->getChildHtml('create_from_configurable') ?>
|
43 |
+
</fieldset>
|
44 |
+
</div>
|
45 |
+
|
46 |
+
<?php // Externally Added ?>
|
47 |
+
<div id="<?php echo $this->getHtmlId() ?>_combination_form" class="ignore-validate configurable-combination">
|
48 |
+
<?php echo $this->getChildHtml('combination'); ?>
|
49 |
+
</div>
|
50 |
+
<?php //end ?>
|
51 |
+
|
52 |
+
<div id="<?php echo $this->getHtmlId() ?>_simple_form" class="ignore-validate configurable-simple-product">
|
53 |
+
<?php echo $this->getChildHtml('simple'); ?>
|
54 |
+
</div>
|
55 |
+
<?php endif;?>
|
56 |
+
<div class="entry-edit">
|
57 |
+
<div class="entry-edit-head">
|
58 |
+
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('catalog')->__('Super product attributes configuration') ?></h4>
|
59 |
+
</div>
|
60 |
+
<fieldset id="<?php echo $this->getHtmlId() ?>">
|
61 |
+
<legend><?php echo Mage::helper('catalog')->__('Super product attributes configuration') ?></legend>
|
62 |
+
<input type="hidden" id="<?php echo $this->getHtmlId() ?>_save_links" name="configurable_products_data" value=""/>
|
63 |
+
<input type="hidden" id="<?php echo $this->getHtmlId() ?>_save_attributes" name="configurable_attributes_data" />
|
64 |
+
|
65 |
+
<ul class="messages">
|
66 |
+
<li class="notice-msg">
|
67 |
+
<ul><li><?php echo Mage::helper('catalog')->__('Price values for options should be specified in system base currency.')?></li></ul>
|
68 |
+
<ul><li><?php echo Mage::helper('catalog')->__('Attrribute names can be specified per store.')?></li></ul>
|
69 |
+
</li>
|
70 |
+
</ul>
|
71 |
+
<ul id="<?php echo $this->getHtmlId() ?>_attributes" class="super-attributes">
|
72 |
+
</ul>
|
73 |
+
</fieldset>
|
74 |
+
</div>
|
75 |
+
<div class="no-display" id="<?php echo $this->getHtmlId() ?>_attribute_template">
|
76 |
+
<div class="<?php if (!$this->isReadonly()):?>attribute-name-container <?php endif;?>left">
|
77 |
+
'{{frontend_label}}'
|
78 |
+
</div>
|
79 |
+
<div class="values-container right">
|
80 |
+
<label for="__id___label" class="bold"><?php echo Mage::helper('catalog')->__('Attribute Name:') ?></label>
|
81 |
+
<input id="__id___label" type="text" <?php if ($this->isReadonly()):?> disabled="disabled" <?php endif;?> class="input-text attribute-label required-entry template no-display" value="'{{label}}'" readonly="label" />
|
82 |
+
<input id="__id___label_use_default" type="checkbox" value="1" " checked="use_default" class="attribute-use-default-label">
|
83 |
+
<label for="__id___label_use_default"><?php echo Mage::helper('catalog')->__('Use default')?> ('{{store_label}}')</label>
|
84 |
+
<ul class="attribute-values">
|
85 |
+
</ul>
|
86 |
+
</div>
|
87 |
+
</div>
|
88 |
+
<div class="no-display" id="<?php echo $this->getHtmlId() ?>_value_template">
|
89 |
+
<div class="attribute-value-label-container left">
|
90 |
+
<?php echo Mage::helper('catalog')->__('Option:') ?> <strong>'{{label}}'</strong>
|
91 |
+
</div>
|
92 |
+
<div class="attribute-values-container-main">
|
93 |
+
<div class="attribute-values-container left">
|
94 |
+
<?php echo Mage::helper('catalog')->__('Price:') ?>
|
95 |
+
<input id="__id___pricing" type="text" <?php if ($this->isReadonly()):?> disabled="disabled" <?php endif;?> class="input-text attribute-price validate-number template no-display" value="'{{pricing_value}}'"/>
|
96 |
+
</div>
|
97 |
+
<div class="attribute-values-container left">
|
98 |
+
<select class="attribute-price-type" <?php if ($this->isReadonly()):?> disabled="disabled" <?php endif;?>>
|
99 |
+
<option value="0"><?php echo Mage::helper('catalog')->__('Fixed') ?></option>
|
100 |
+
<option value="1"><?php echo Mage::helper('catalog')->__('Percentage') ?></option>
|
101 |
+
</select>
|
102 |
+
</div>
|
103 |
+
<?php if ($this->getShowUseDefaultPrice()):?>
|
104 |
+
<div class="attribute-values-container">
|
105 |
+
<input id="__id___default" type="checkbox" <?php if ($this->isReadonly()):?> disabled="disabled" <?php endif;?> class="attribute-use-default-value"> <label for="__id___default" class="normal"><?php echo Mage::helper('catalog')->__('Use Default Value') ?></label>
|
106 |
+
</div>
|
107 |
+
<?php endif;?>
|
108 |
+
</div>
|
109 |
+
</div>
|
110 |
+
<div class="template no-display" id="<?php echo $this->getHtmlId() ?>_simple_pricing">
|
111 |
+
<div class="attribute-values-container left v-middle">
|
112 |
+
<?php echo Mage::helper('catalog')->__('Price:') ?>
|
113 |
+
<input type="text" class="input-text attribute-price validate-number"/>
|
114 |
+
</div>
|
115 |
+
<div class="attribute-values-container left v-middle">
|
116 |
+
<select class="attribute-price-type">
|
117 |
+
<option value="0"><?php echo Mage::helper('catalog')->__('Fixed') ?></option>
|
118 |
+
<option value="1"><?php echo Mage::helper('catalog')->__('Percentage') ?></option>
|
119 |
+
</select>
|
120 |
+
</div>
|
121 |
+
</div>
|
122 |
+
<div class="template no-display" id="<?php echo $this->getHtmlId() ?>_simple_pricing_view">
|
123 |
+
<?php echo Mage::helper('catalog')->__('Price') ?> <strong>'{{value}}'</strong>
|
124 |
+
</div>
|
125 |
+
<?php echo $this->getGridHtml() ?>
|
126 |
+
<script type="text/javascript">
|
127 |
+
var superProduct = new Product.Configurable(<?php echo $this->getAttributesJson() ?>,<?php echo $this->getLinksJson() ?>,'<?php echo $this->getHtmlId() ?>_',<?php echo $this->getGridJsObject() ?>, <?php echo ( $this->isReadonly() ? 'true' : 'false'); ?>);
|
128 |
+
superProduct.createEmptyUrl = '<?php echo $this->getNewEmptyProductUrl() ?>';
|
129 |
+
superProduct.createNormalUrl = '<?php echo $this->getNewProductUrl() ?>';
|
130 |
+
superProduct.createQuickUrl = '<?php echo $this->getQuickCreationUrl() ?>';
|
131 |
+
<?php // Externally Added ?>
|
132 |
+
superProduct.createCombinationsUrl = '<?php echo $this->getCombinationsUrl() ?>';
|
133 |
+
<?php // End ?>
|
134 |
+
|
135 |
+
Validation.add(
|
136 |
+
'validate-configurable',
|
137 |
+
'<?php echo $this->escapeJs(Mage::helper('catalog')->__('Product with this combination of attributes already associated to configurable.')) ?>',
|
138 |
+
superProduct.checkCreationUniqueAttributes.bind(superProduct)
|
139 |
+
)
|
140 |
+
</script>
|
141 |
+
|
142 |
+
<div><input type="hidden" name="affect_configurable_product_attributes" value="1" /></div>
|
app/etc/modules/QS_Quickconfigurables.xml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<QS_Quickconfigurables>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>local</codePool>
|
7 |
+
</QS_Quickconfigurables>
|
8 |
+
</modules>
|
9 |
+
</config>
|
js/qs/adminhtml/product_13.js
ADDED
@@ -0,0 +1,1007 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Magento
|
3 |
+
*
|
4 |
+
* NOTICE OF LICENSE
|
5 |
+
*
|
6 |
+
* This source file is subject to the Academic Free License (AFL 3.0)
|
7 |
+
* that is bundled with this package in the file LICENSE_AFL.txt.
|
8 |
+
* It is also available through the world-wide-web at this URL:
|
9 |
+
* http://opensource.org/licenses/afl-3.0.php
|
10 |
+
* If you did not receive a copy of the license and are unable to
|
11 |
+
* obtain it through the world-wide-web, please send an email
|
12 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
13 |
+
*
|
14 |
+
* DISCLAIMER
|
15 |
+
*
|
16 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
17 |
+
* versions in the future. If you wish to customize Magento for your
|
18 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
19 |
+
*
|
20 |
+
* @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
|
21 |
+
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
|
22 |
+
*/
|
23 |
+
|
24 |
+
var Product = {};
|
25 |
+
|
26 |
+
Product.Gallery = Class.create();
|
27 |
+
Product.Gallery.prototype = {
|
28 |
+
images: [],
|
29 |
+
file2id: {'no_selection':0},
|
30 |
+
idIncrement: 1,
|
31 |
+
containerId: '',
|
32 |
+
container: null,
|
33 |
+
uploader: null,
|
34 |
+
imageTypes: {},
|
35 |
+
initialize: function (containerId, uploader, imageTypes) {
|
36 |
+
this.containerId = containerId,
|
37 |
+
this.container = $(this.containerId);
|
38 |
+
this.uploader = uploader;
|
39 |
+
this.imageTypes = imageTypes;
|
40 |
+
if (this.uploader) {
|
41 |
+
this.uploader.onFilesComplete = this.handleUploadComplete.bind(this);
|
42 |
+
}
|
43 |
+
//this.uploader.onFileProgress = this.handleUploadProgress.bind(this);
|
44 |
+
//this.uploader.onFileError = this.handleUploadError.bind(this);
|
45 |
+
this.images = this.getElement('save').value.evalJSON();
|
46 |
+
this.imagesValues = this.getElement('save_image').value.evalJSON();
|
47 |
+
this.template = new Template('<tr id="__id__" class="preview">' + this.getElement('template').innerHTML + '</tr>', new RegExp('(^|.|\\r|\\n)(__([a-zA-Z0-9_]+)__)', ''));
|
48 |
+
this.fixParentTable();
|
49 |
+
this.updateImages();
|
50 |
+
varienGlobalEvents.attachEventHandler('moveTab', this.onImageTabMove.bind(this));
|
51 |
+
},
|
52 |
+
onImageTabMove: function(event) {
|
53 |
+
var imagesTab = false;
|
54 |
+
this.container.ancestors().each(function(parentItem){
|
55 |
+
if (parentItem.tabObject) {
|
56 |
+
imagesTab = parentItem.tabObject;
|
57 |
+
throw $break;
|
58 |
+
}
|
59 |
+
}.bind(this));
|
60 |
+
if(imagesTab && event.tab && event.tab.name && imagesTab.name == event.tab.name) {
|
61 |
+
this.updateImages();
|
62 |
+
}
|
63 |
+
},
|
64 |
+
fixParentTable: function() {
|
65 |
+
this.container.ancestors().each(function(parentItem){
|
66 |
+
if(parentItem.tagName.toLowerCase()=='td') {
|
67 |
+
parentItem.style.width ='100%';
|
68 |
+
}
|
69 |
+
if(parentItem.tagName.toLowerCase()=='table') {
|
70 |
+
parentItem.style.width ='100%';
|
71 |
+
throw $break;
|
72 |
+
}
|
73 |
+
});
|
74 |
+
},
|
75 |
+
getElement: function (name) {
|
76 |
+
return $(this.containerId + '_' + name);
|
77 |
+
},
|
78 |
+
showUploader: function () {
|
79 |
+
this.getElement('add_images_button').hide();
|
80 |
+
this.getElement('uploader').show();
|
81 |
+
},
|
82 |
+
handleUploadComplete: function (files) {
|
83 |
+
files.each(function(item) {
|
84 |
+
if (!item.response.isJSON()) {
|
85 |
+
try {
|
86 |
+
console.log(item.response);
|
87 |
+
} catch (e2) {
|
88 |
+
alert(item.response);
|
89 |
+
}
|
90 |
+
return;
|
91 |
+
}
|
92 |
+
var response = item.response.evalJSON();
|
93 |
+
if (response.error) {
|
94 |
+
return;
|
95 |
+
}
|
96 |
+
var newImage = {};
|
97 |
+
newImage.url = response.url;
|
98 |
+
newImage.file = response.file;
|
99 |
+
newImage.label = '';
|
100 |
+
newImage.position = this.getNextPosition();
|
101 |
+
newImage.disabled = 0;
|
102 |
+
newImage.removed = 0;
|
103 |
+
this.images.push(newImage);
|
104 |
+
this.uploader.removeFile(item.id);
|
105 |
+
}.bind(this));
|
106 |
+
this.container.setHasChanges();
|
107 |
+
this.updateImages();
|
108 |
+
},
|
109 |
+
updateImages: function() {
|
110 |
+
this.getElement('save').value = this.images.toJSON();
|
111 |
+
$H(this.imageTypes).each(function(pair) {
|
112 |
+
this.getFileElement('no_selection', 'cell-' + pair.key + ' input').checked = true;
|
113 |
+
}.bind(this));
|
114 |
+
this.images.each(function(row){
|
115 |
+
if (!$(this.prepareId(row.file))) {
|
116 |
+
this.createImageRow(row);
|
117 |
+
}
|
118 |
+
this.updateVisualisation(row.file);
|
119 |
+
}.bind(this));
|
120 |
+
this.updateUseDefault(false);
|
121 |
+
},
|
122 |
+
createImageRow: function(image) {
|
123 |
+
var vars = Object.clone(image);
|
124 |
+
vars.id = this.prepareId(image.file);
|
125 |
+
var html = this.template.evaluate(vars);
|
126 |
+
Element.insert(this.getElement('list'), {bottom: html});
|
127 |
+
},
|
128 |
+
prepareId: function(file) {
|
129 |
+
if(typeof this.file2id[file] == 'undefined') {
|
130 |
+
this.file2id[file] = this.idIncrement++;
|
131 |
+
}
|
132 |
+
return this.containerId + '-image-' + this.file2id[file];
|
133 |
+
},
|
134 |
+
getNextPosition: function() {
|
135 |
+
var maxPosition = 0;
|
136 |
+
this.images.each(function (item) {
|
137 |
+
if (parseInt(item.position) > maxPosition) {
|
138 |
+
maxPosition = parseInt(item.position);
|
139 |
+
}
|
140 |
+
});
|
141 |
+
return maxPosition + 1;
|
142 |
+
},
|
143 |
+
updateImage: function(file) {
|
144 |
+
var index = this.getIndexByFile(file);
|
145 |
+
this.images[index].label = this.getFileElement(file, 'cell-label input').value;
|
146 |
+
this.images[index].position = this.getFileElement(file, 'cell-position input').value;
|
147 |
+
this.images[index].removed = (this.getFileElement(file, 'cell-remove input').checked ? 1 : 0);
|
148 |
+
this.images[index].disabled = (this.getFileElement(file, 'cell-disable input').checked ? 1 : 0);
|
149 |
+
this.getElement('save').value = this.images.toJSON();
|
150 |
+
this.updateState(file);
|
151 |
+
this.container.setHasChanges();
|
152 |
+
},
|
153 |
+
loadImage: function(file) {
|
154 |
+
var image = this.getImageByFile(file);
|
155 |
+
this.getFileElement(file, 'cell-image img').src = image.url;
|
156 |
+
this.getFileElement(file, 'cell-image img').show();
|
157 |
+
this.getFileElement(file, 'cell-image .place-holder').hide();
|
158 |
+
},
|
159 |
+
setProductImages: function(file) {
|
160 |
+
$H(this.imageTypes).each(function(pair){
|
161 |
+
if(this.getFileElement(file, 'cell-' + pair.key + ' input').checked) {
|
162 |
+
this.imagesValues[pair.key] = (file == 'no_selection' ? null : file);
|
163 |
+
}
|
164 |
+
}.bind(this));
|
165 |
+
|
166 |
+
this.getElement('save_image').value = $H(this.imagesValues).toJSON();
|
167 |
+
},
|
168 |
+
updateVisualisation: function(file) {
|
169 |
+
var image = this.getImageByFile(file);
|
170 |
+
this.getFileElement(file, 'cell-label input').value = image.label;
|
171 |
+
this.getFileElement(file, 'cell-position input').value = image.position;
|
172 |
+
this.getFileElement(file, 'cell-remove input').checked = (image.removed == 1);
|
173 |
+
this.getFileElement(file, 'cell-disable input').checked = (image.disabled == 1);
|
174 |
+
$H(this.imageTypes).each(function(pair) {
|
175 |
+
if(this.imagesValues[pair.key] == file) {
|
176 |
+
this.getFileElement(file, 'cell-' + pair.key + ' input').checked = true;
|
177 |
+
}
|
178 |
+
}.bind(this));
|
179 |
+
this.updateState(file);
|
180 |
+
},
|
181 |
+
updateState: function (file) {
|
182 |
+
if(this.getFileElement(file, 'cell-disable input').checked) {
|
183 |
+
this.getFileElement(file, 'cell-position input').disabled = true;
|
184 |
+
} else {
|
185 |
+
this.getFileElement(file, 'cell-position input').disabled = false;
|
186 |
+
}
|
187 |
+
},
|
188 |
+
getFileElement: function(file, element){
|
189 |
+
var selector = '#' + this.prepareId(file) + ' .' + element;
|
190 |
+
var elems = $$(selector);
|
191 |
+
if(!elems[0]) {
|
192 |
+
try {
|
193 |
+
console.log(selector);
|
194 |
+
} catch (e2) {
|
195 |
+
alert(selector);
|
196 |
+
}
|
197 |
+
}
|
198 |
+
|
199 |
+
return $$('#' + this.prepareId(file) + ' .' + element)[0];
|
200 |
+
},
|
201 |
+
getImageByFile: function(file) {
|
202 |
+
if (this.getIndexByFile(file)===null) {
|
203 |
+
return false;
|
204 |
+
}
|
205 |
+
|
206 |
+
return this.images[this.getIndexByFile(file)];
|
207 |
+
},
|
208 |
+
getIndexByFile: function(file) {
|
209 |
+
var index;
|
210 |
+
this.images.each(function (item, i) {
|
211 |
+
if (item.file == file) {
|
212 |
+
index = i;
|
213 |
+
}
|
214 |
+
});
|
215 |
+
return index;
|
216 |
+
},
|
217 |
+
updateUseDefault: function ()
|
218 |
+
{
|
219 |
+
if (this.getElement('default')) {
|
220 |
+
this.getElement('default').select('input').each(function(input){
|
221 |
+
$(this.containerId).select('.cell-' + input.value + ' input').each(function(radio) {
|
222 |
+
radio.disabled = input.checked;
|
223 |
+
});
|
224 |
+
}.bind(this));
|
225 |
+
}
|
226 |
+
|
227 |
+
if (arguments.length == 0) {
|
228 |
+
this.container.setHasChanges();
|
229 |
+
}
|
230 |
+
},
|
231 |
+
handleUploadProgress: function (file) {
|
232 |
+
|
233 |
+
},
|
234 |
+
handleUploadError: function (fileId) {
|
235 |
+
|
236 |
+
}
|
237 |
+
};
|
238 |
+
|
239 |
+
Product.AttributesBridge = {
|
240 |
+
tabsObject: false,
|
241 |
+
bindTabs2Attributes: {},
|
242 |
+
bind: function(tabId, attributesObject) {
|
243 |
+
this.bindTabs2Attributes[tabId] = attributesObject;
|
244 |
+
},
|
245 |
+
getAttributes: function(tabId) {
|
246 |
+
return this.bindTabs2Attributes[tabId];
|
247 |
+
},
|
248 |
+
setTabsObject: function(tabs) {
|
249 |
+
this.tabsObject = tabs;
|
250 |
+
},
|
251 |
+
getTabsObject: function() {
|
252 |
+
return this.tabsObject;
|
253 |
+
},
|
254 |
+
addAttributeRow: function(data)
|
255 |
+
{
|
256 |
+
$H(data).each(function(item){
|
257 |
+
if(this.getTabsObject().activeTab.name!=item.key) {
|
258 |
+
this.getTabsObject().showTabContent($(item.key));
|
259 |
+
}
|
260 |
+
this.getAttributes(item.key).addRow(item.value);
|
261 |
+
}.bind(this));
|
262 |
+
}
|
263 |
+
};
|
264 |
+
|
265 |
+
Product.Attributes = Class.create();
|
266 |
+
Product.Attributes.prototype = {
|
267 |
+
config: {},
|
268 |
+
containerId: null,
|
269 |
+
initialize: function(containerId) {
|
270 |
+
this.containerId = containerId;
|
271 |
+
},
|
272 |
+
setConfig: function(config) {
|
273 |
+
this.config = config;
|
274 |
+
Product.AttributesBridge.bind(this.getConfig().tab_id, this);
|
275 |
+
},
|
276 |
+
getConfig: function () {
|
277 |
+
return this.config;
|
278 |
+
},
|
279 |
+
create: function () {
|
280 |
+
var win = window.open(this.getConfig().url, 'new_attribute', 'width=900,height=600,resizable=1,scrollbars=1');
|
281 |
+
win.focus();
|
282 |
+
},
|
283 |
+
addRow: function(html) {
|
284 |
+
var attributesContainer = $$('#group_fields' + this.getConfig().group_id + ' .form-list tbody')[0];
|
285 |
+
Element.insert(attributesContainer, {bottom: html});
|
286 |
+
|
287 |
+
var childs = attributesContainer.childElements();
|
288 |
+
var element = childs[childs.size()-1].select('input','select','textarea')[0];
|
289 |
+
if (element) {
|
290 |
+
window.scrollTo(0, Position.cumulativeOffset(element)[1] + element.offsetHeight);
|
291 |
+
}
|
292 |
+
}
|
293 |
+
};
|
294 |
+
|
295 |
+
Product.Configurable = Class.create();
|
296 |
+
Product.Configurable.prototype = {
|
297 |
+
initialize: function (attributes, links, idPrefix, grid, readonly) {
|
298 |
+
this.templatesSyntax = new RegExp('(^|.|\\r|\\n)(\'{{\\s*(\\w+)\\s*}}\')', "");
|
299 |
+
this.attributes = attributes; // Attributes
|
300 |
+
this.idPrefix = idPrefix; // Container id prefix
|
301 |
+
this.links = $H(links); // Associated products
|
302 |
+
this.newProducts = []; // For product that's created througth Create Empty and Copy from Configurable
|
303 |
+
this.readonly = readonly;
|
304 |
+
|
305 |
+
/* Generation templates */
|
306 |
+
this.addAttributeTemplate = new Template($(idPrefix + 'attribute_template').innerHTML.replace(/__id__/g,"'{{html_id}}'").replace(/ template no-display/g,''), this.templatesSyntax);
|
307 |
+
this.addValueTemplate = new Template($(idPrefix + 'value_template').innerHTML.replace(/__id__/g,"'{{html_id}}'").replace(/ template no-display/g,''), this.templatesSyntax);
|
308 |
+
this.pricingValueTemplate = new Template($(idPrefix + 'simple_pricing').innerHTML, this.templatesSyntax);
|
309 |
+
this.pricingValueViewTemplate = new Template($(idPrefix + 'simple_pricing_view').innerHTML, this.templatesSyntax);
|
310 |
+
|
311 |
+
this.container = $(idPrefix + 'attributes');
|
312 |
+
|
313 |
+
/* Listeners */
|
314 |
+
this.onLabelUpdate = this.updateLabel.bindAsEventListener(this); // Update attribute label
|
315 |
+
this.onValuePriceUpdate = this.updateValuePrice.bindAsEventListener(this); // Update pricing value
|
316 |
+
this.onValueTypeUpdate = this.updateValueType.bindAsEventListener(this); // Update pricing type
|
317 |
+
this.onValueDefaultUpdate = this.updateValueUseDefault.bindAsEventListener(this);
|
318 |
+
|
319 |
+
/* Grid initialization and attributes initialization */
|
320 |
+
this.createAttributes(); // Creation of default attributes
|
321 |
+
|
322 |
+
this.grid = grid;
|
323 |
+
this.grid.rowClickCallback = this.rowClick.bind(this);
|
324 |
+
this.grid.initRowCallback = this.rowInit.bind(this);
|
325 |
+
this.grid.checkboxCheckCallback = this.registerProduct.bind(this); // Associate/Unassociate simple product
|
326 |
+
|
327 |
+
this.grid.rows.each(function(row) {
|
328 |
+
this.rowInit(this.grid, row);
|
329 |
+
}.bind(this));
|
330 |
+
},
|
331 |
+
createAttributes: function() {
|
332 |
+
this.attributes.each(function(attribute, index) {
|
333 |
+
//var li = Builder.node('li', {className:'attribute'});
|
334 |
+
var li = $(document.createElement('LI'));
|
335 |
+
li.className = 'attribute';
|
336 |
+
li.id = this.idPrefix + '_attribute_' + index;
|
337 |
+
attribute.html_id = li.id;
|
338 |
+
if(attribute && attribute.label && attribute.label.blank()) {
|
339 |
+
attribute.label = ' '
|
340 |
+
}
|
341 |
+
li.update(this.addAttributeTemplate.evaluate(attribute));
|
342 |
+
li.attributeObject = attribute;
|
343 |
+
|
344 |
+
this.container.appendChild(li);
|
345 |
+
li.attributeValues = li.down('.attribute-values');
|
346 |
+
|
347 |
+
if (attribute.values) {
|
348 |
+
attribute.values.each(function(value){
|
349 |
+
this.createValueRow(li, value); // Add pricing values
|
350 |
+
}.bind(this));
|
351 |
+
}
|
352 |
+
|
353 |
+
/* Observe label change */
|
354 |
+
Event.observe(li.down('.attribute-label'),'change', this.onLabelUpdate);
|
355 |
+
Event.observe(li.down('.attribute-label'),'keyup', this.onLabelUpdate);
|
356 |
+
}.bind(this));
|
357 |
+
if (!this.readonly) {
|
358 |
+
// Creation of sortable for attributes sorting
|
359 |
+
Sortable.create(this.container, {handle:'attribute-name-container',onUpdate:this.updatePositions.bind(this)});
|
360 |
+
}
|
361 |
+
this.updateSaveInput();
|
362 |
+
},
|
363 |
+
|
364 |
+
updateLabel: function (event) {
|
365 |
+
var li = Event.findElement(event, 'LI');
|
366 |
+
li.attributeObject.label = Event.element(event).value;
|
367 |
+
this.updateSaveInput();
|
368 |
+
},
|
369 |
+
updatePositions: function(param) {
|
370 |
+
this.container.childElements().each(function(row, index) {
|
371 |
+
row.attributeObject.position = index;
|
372 |
+
});
|
373 |
+
this.updateSaveInput();
|
374 |
+
},
|
375 |
+
addNewProduct: function(productId, attributes) {
|
376 |
+
if (this.checkAttributes(attributes)) {
|
377 |
+
this.links.set(productId, this.cloneAttributes(attributes));
|
378 |
+
} else {
|
379 |
+
this.newProducts.push(productId);
|
380 |
+
}
|
381 |
+
|
382 |
+
this.updateGrid();
|
383 |
+
this.updateValues();
|
384 |
+
this.grid.reload(null);
|
385 |
+
},
|
386 |
+
createEmptyProduct: function() {
|
387 |
+
this.createPopup(this.createEmptyUrl)
|
388 |
+
},
|
389 |
+
createNewProduct: function() {
|
390 |
+
this.createPopup(this.createNormalUrl);
|
391 |
+
},
|
392 |
+
createPopup: function(url) {
|
393 |
+
if (this.win && !this.win.closed) {
|
394 |
+
this.win.close();
|
395 |
+
}
|
396 |
+
|
397 |
+
this.win = window.open(url, '','width=1000,height=700,resizable=1,scrollbars=1');
|
398 |
+
this.win.focus();
|
399 |
+
},
|
400 |
+
registerProduct: function(grid, element, checked) {
|
401 |
+
if(checked){
|
402 |
+
if(element.linkAttributes) {
|
403 |
+
this.links.set(element.value, element.linkAttributes);
|
404 |
+
}
|
405 |
+
}
|
406 |
+
else{
|
407 |
+
this.links.unset(element.value);
|
408 |
+
}
|
409 |
+
this.updateGrid();
|
410 |
+
this.grid.rows.each(function(row) {
|
411 |
+
this.revalidateRow(this.grid, row);
|
412 |
+
}.bind(this));
|
413 |
+
this.updateValues();
|
414 |
+
},
|
415 |
+
updateProduct: function(productId, attributes) {
|
416 |
+
var isAssociated = false;
|
417 |
+
|
418 |
+
if (typeof this.links.get(productId) != 'undefined') {
|
419 |
+
isAssociated = true;
|
420 |
+
this.links.unset(productId);
|
421 |
+
}
|
422 |
+
|
423 |
+
if (isAssociated && this.checkAttributes(attributes)) {
|
424 |
+
this.links.set(productId, this.cloneAttributes(attributes));
|
425 |
+
} else if (isAssociated) {
|
426 |
+
this.newProducts.push(productId);
|
427 |
+
}
|
428 |
+
|
429 |
+
this.updateGrid();
|
430 |
+
this.updateValues();
|
431 |
+
this.grid.reload(null);
|
432 |
+
},
|
433 |
+
cloneAttributes: function (attributes) {
|
434 |
+
var newObj = [];
|
435 |
+
for (var i=0, length=attributes.length; i<length; i++) {
|
436 |
+
newObj[i] = Object.clone(attributes[i]);
|
437 |
+
}
|
438 |
+
return newObj;
|
439 |
+
},
|
440 |
+
rowClick: function(grid, event) {
|
441 |
+
var trElement = Event.findElement(event, 'tr');
|
442 |
+
var isInput = Event.element(event).tagName.toUpperCase() == 'INPUT';
|
443 |
+
|
444 |
+
if ($(Event.findElement(event, 'td')).down('a')) {
|
445 |
+
return;
|
446 |
+
}
|
447 |
+
|
448 |
+
if(trElement){
|
449 |
+
var checkbox = $(trElement).down('input');
|
450 |
+
if(checkbox && !checkbox.disabled){
|
451 |
+
var checked = isInput ? checkbox.checked : !checkbox.checked;
|
452 |
+
grid.setCheckboxChecked(checkbox, checked);
|
453 |
+
}
|
454 |
+
}
|
455 |
+
},
|
456 |
+
rowInit: function(grid, row) {
|
457 |
+
var checkbox = $(row).down('.checkbox');
|
458 |
+
var input = $(row).down('.value-json');
|
459 |
+
|
460 |
+
if(checkbox && input) {
|
461 |
+
checkbox.linkAttributes = input.value.evalJSON();
|
462 |
+
if(!checkbox.checked) {
|
463 |
+
if(!this.checkAttributes(checkbox.linkAttributes)) {
|
464 |
+
$(row).addClassName('invalid');
|
465 |
+
checkbox.disable();
|
466 |
+
} else {
|
467 |
+
$(row).removeClassName('invalid');
|
468 |
+
checkbox.enable();
|
469 |
+
}
|
470 |
+
}
|
471 |
+
}
|
472 |
+
},
|
473 |
+
// Added by QS
|
474 |
+
revalidateRowAfterReload : function(grid, row) {
|
475 |
+
var checkbox = $(row).down('.checkbox');
|
476 |
+
if (checkbox) {
|
477 |
+
if (!checkbox.checked) {
|
478 |
+
if (!this.checkAttributes(checkbox.linkAttributes)) {
|
479 |
+
$(row).addClassName('invalid');
|
480 |
+
checkbox.disable();
|
481 |
+
} else {
|
482 |
+
$(row).removeClassName('invalid');
|
483 |
+
checkbox.enable();
|
484 |
+
}
|
485 |
+
} else {
|
486 |
+
if (!this.checkAttributes(checkbox.linkAttributes)) {
|
487 |
+
$(row).addClassName('invalid');
|
488 |
+
checkbox.checked = false;
|
489 |
+
this.updateValues();
|
490 |
+
} else {
|
491 |
+
$(row).removeClassName('invalid');
|
492 |
+
checkbox.enable();
|
493 |
+
this.updateValues();
|
494 |
+
}
|
495 |
+
}
|
496 |
+
}
|
497 |
+
},
|
498 |
+
// End
|
499 |
+
revalidateRow: function(grid, row) {
|
500 |
+
var checkbox = $(row).down('.checkbox');
|
501 |
+
if(checkbox ) {
|
502 |
+
if(!checkbox.checked) {
|
503 |
+
if(!this.checkAttributes(checkbox.linkAttributes)) {
|
504 |
+
$(row).addClassName('invalid');
|
505 |
+
checkbox.disable();
|
506 |
+
} else {
|
507 |
+
$(row).removeClassName('invalid');
|
508 |
+
checkbox.enable();
|
509 |
+
}
|
510 |
+
}
|
511 |
+
}
|
512 |
+
},
|
513 |
+
checkAttributes: function(attributes) {
|
514 |
+
var result = true;
|
515 |
+
this.links.each(function(pair) {
|
516 |
+
var fail = false;
|
517 |
+
for(var i = 0; i < pair.value.length && !fail; i++) {
|
518 |
+
for(var j = 0; j < attributes.length && !fail; j ++) {
|
519 |
+
if(pair.value[i].attribute_id == attributes[j].attribute_id && pair.value[i].value_index != attributes[j].value_index) {
|
520 |
+
fail = true;
|
521 |
+
}
|
522 |
+
}
|
523 |
+
}
|
524 |
+
if(!fail) {
|
525 |
+
result = false;
|
526 |
+
}
|
527 |
+
});
|
528 |
+
return result;
|
529 |
+
},
|
530 |
+
updateGrid: function () {
|
531 |
+
this.grid.reloadParams = {'products[]':this.links.keys().size() ? this.links.keys() : [0], 'new_products[]':this.newProducts};
|
532 |
+
},
|
533 |
+
updateValues: function () {
|
534 |
+
var uniqueAttributeValues = $H({});
|
535 |
+
/* Collect unique attributes */
|
536 |
+
this.links.each(function(pair) {
|
537 |
+
for (var i = 0, length=pair.value.length; i < length; i ++) {
|
538 |
+
var attribute = pair.value[i];
|
539 |
+
if (uniqueAttributeValues.keys().indexOf(attribute.attribute_id) == -1) {
|
540 |
+
uniqueAttributeValues.set(attribute.attribute_id, $H({}));
|
541 |
+
}
|
542 |
+
uniqueAttributeValues.get(attribute.attribute_id).set(attribute.value_index, attribute);
|
543 |
+
}
|
544 |
+
});
|
545 |
+
/* Updating attributes value container */
|
546 |
+
this.container.childElements().each(function(row) {
|
547 |
+
var attribute = row.attributeObject;
|
548 |
+
for (var i = 0, length=attribute.values.length; i < length; i ++) {
|
549 |
+
if (uniqueAttributeValues.keys().indexOf(attribute.attribute_id) == -1
|
550 |
+
|| uniqueAttributeValues.get(attribute.attribute_id).keys().indexOf(attribute.values[i].value_index)==-1) {
|
551 |
+
row.attributeValues.childElements().each(function(elem) {
|
552 |
+
if (elem.valueObject.value_index==attribute.values[i].value_index) {
|
553 |
+
elem.remove();
|
554 |
+
}
|
555 |
+
});
|
556 |
+
attribute.values[i] = undefined;
|
557 |
+
|
558 |
+
} else {
|
559 |
+
uniqueAttributeValues.get(attribute.attribute_id).unset(attribute.values[i].value_index);
|
560 |
+
}
|
561 |
+
}
|
562 |
+
attribute.values = attribute.values.compact();
|
563 |
+
if (uniqueAttributeValues.get(attribute.attribute_id)) {
|
564 |
+
uniqueAttributeValues.get(attribute.attribute_id).each(function(pair) {
|
565 |
+
attribute.values.push(pair.value);
|
566 |
+
this.createValueRow(row, pair.value);
|
567 |
+
}.bind(this));
|
568 |
+
}
|
569 |
+
}.bind(this));
|
570 |
+
this.updateSaveInput();
|
571 |
+
this.updateSimpleForm();
|
572 |
+
},
|
573 |
+
createValueRow: function(container, value) {
|
574 |
+
var templateVariables = $H({});
|
575 |
+
if(!this.valueAutoIndex) {
|
576 |
+
this.valueAutoIndex = 1;
|
577 |
+
}
|
578 |
+
templateVariables.set('html_id', container.id + '_' + this.valueAutoIndex);
|
579 |
+
templateVariables = templateVariables.merge(value);
|
580 |
+
var pricingValue = parseFloat(templateVariables.get('pricing_value'));
|
581 |
+
if (!isNaN(pricingValue)) {
|
582 |
+
templateVariables.set('pricing_value', pricingValue);
|
583 |
+
} else {
|
584 |
+
templateVariables.unset('pricing_value');
|
585 |
+
}
|
586 |
+
this.valueAutoIndex++;
|
587 |
+
|
588 |
+
//var li = $(Builder.node('li', {className:'attribute-value'}));
|
589 |
+
var li = $(document.createElement('LI'));
|
590 |
+
li.className = 'attribute-value';
|
591 |
+
li.id = templateVariables.get('html_id');
|
592 |
+
li.update(this.addValueTemplate.evaluate(templateVariables));
|
593 |
+
li.valueObject = value;
|
594 |
+
if (typeof li.valueObject.is_percent == 'undefined') {
|
595 |
+
li.valueObject.is_percent = 0;
|
596 |
+
}
|
597 |
+
|
598 |
+
if (typeof li.valueObject.pricing_value == 'undefined') {
|
599 |
+
li.valueObject.pricing_value = '';
|
600 |
+
}
|
601 |
+
|
602 |
+
container.attributeValues.appendChild(li);
|
603 |
+
var priceField = li.down('.attribute-price');
|
604 |
+
var priceTypeField = li.down('.attribute-price-type');
|
605 |
+
|
606 |
+
if(parseInt(value.is_percent)) {
|
607 |
+
priceTypeField.options[1].selected = !(priceTypeField.options[0].selected = false);
|
608 |
+
} else {
|
609 |
+
priceTypeField.options[1].selected = !(priceTypeField.options[0].selected = true);
|
610 |
+
}
|
611 |
+
Event.observe(priceField, 'keyup', this.onValuePriceUpdate);
|
612 |
+
Event.observe(priceField, 'change', this.onValuePriceUpdate);
|
613 |
+
Event.observe(priceTypeField, 'change', this.onValueTypeUpdate);
|
614 |
+
var useDefaultEl = li.down('.attribute-use-default-value');
|
615 |
+
if (useDefaultEl) {
|
616 |
+
if (li.valueObject.use_default_value) {
|
617 |
+
useDefaultEl.checked = true;
|
618 |
+
this.updateUseDefaultRow(useDefaultEl, li);
|
619 |
+
}
|
620 |
+
Event.observe(useDefaultEl, 'change', this.onValueDefaultUpdate);
|
621 |
+
}
|
622 |
+
},
|
623 |
+
updateValuePrice: function(event) {
|
624 |
+
var li = Event.findElement(event, 'LI');
|
625 |
+
li.valueObject.pricing_value = (Event.element(event).value.blank() ? null : Event.element(event).value);
|
626 |
+
this.updateSimpleForm();
|
627 |
+
this.updateSaveInput();
|
628 |
+
},
|
629 |
+
updateValueType: function(event) {
|
630 |
+
var li = Event.findElement(event, 'LI');
|
631 |
+
li.valueObject.is_percent = (Event.element(event).value.blank() ? null : Event.element(event).value);
|
632 |
+
this.updateSimpleForm();
|
633 |
+
this.updateSaveInput();
|
634 |
+
},
|
635 |
+
updateValueUseDefault: function(event) {
|
636 |
+
var li = Event.findElement(event, 'LI');
|
637 |
+
var useDefaultEl = Event.element(event);
|
638 |
+
li.valueObject.use_default_value = useDefaultEl.checked;
|
639 |
+
this.updateUseDefaultRow(useDefaultEl, li);
|
640 |
+
},
|
641 |
+
updateUseDefaultRow: function(useDefaultEl, li)
|
642 |
+
{
|
643 |
+
var priceField = li.down('.attribute-price');
|
644 |
+
var priceTypeField = li.down('.attribute-price-type');
|
645 |
+
if (useDefaultEl.checked) {
|
646 |
+
priceField.disabled = true;
|
647 |
+
priceTypeField.disabled = true;
|
648 |
+
}
|
649 |
+
else {
|
650 |
+
priceField.disabled = false;
|
651 |
+
priceTypeField.disabled = false;
|
652 |
+
}
|
653 |
+
this.updateSimpleForm();
|
654 |
+
this.updateSaveInput();
|
655 |
+
},
|
656 |
+
updateSaveInput: function() {
|
657 |
+
$(this.idPrefix + 'save_attributes').value = this.attributes.toJSON();
|
658 |
+
$(this.idPrefix + 'save_links').value = this.links.toJSON();
|
659 |
+
},
|
660 |
+
initializeAdvicesForSimpleForm: function() {
|
661 |
+
if ($(this.idPrefix + 'simple_form').advicesInited) {
|
662 |
+
return;
|
663 |
+
}
|
664 |
+
|
665 |
+
$(this.idPrefix + 'simple_form').select('td.value').each(function (td) {
|
666 |
+
var adviceContainer = $(Builder.node('div'));
|
667 |
+
td.appendChild(adviceContainer);
|
668 |
+
td.select('input', 'select').each(function(element){
|
669 |
+
element.advaiceContainer = adviceContainer;
|
670 |
+
});
|
671 |
+
});
|
672 |
+
$(this.idPrefix + 'simple_form').advicesInited = true;
|
673 |
+
},
|
674 |
+
quickCreateNewProduct: function() {
|
675 |
+
this.initializeAdvicesForSimpleForm();
|
676 |
+
$(this.idPrefix + 'simple_form').removeClassName('ignore-validate');
|
677 |
+
var validationResult = $(this.idPrefix + 'simple_form').select('input','select','textarea').collect(
|
678 |
+
function(elm) {
|
679 |
+
return Validation.validate(elm,{useTitle : false, onElementValidate : function(){}});
|
680 |
+
}
|
681 |
+
).all();
|
682 |
+
$(this.idPrefix + 'simple_form').addClassName('ignore-validate');
|
683 |
+
|
684 |
+
if (!validationResult) {
|
685 |
+
return;
|
686 |
+
}
|
687 |
+
|
688 |
+
var params = Form.serializeElements(
|
689 |
+
$(this.idPrefix + 'simple_form').select('input','select','textarea'),
|
690 |
+
true
|
691 |
+
);
|
692 |
+
params.form_key = FORM_KEY;
|
693 |
+
$('messages').update();
|
694 |
+
new Ajax.Request(this.createQuickUrl, {
|
695 |
+
parameters: params,
|
696 |
+
method:'post',
|
697 |
+
area: $(this.idPrefix + 'simple_form'),
|
698 |
+
onComplete: this.quickCreateNewProductComplete.bind(this)
|
699 |
+
});
|
700 |
+
},
|
701 |
+
// Added by QS
|
702 |
+
quickCombinations: function() {
|
703 |
+
this.initializeAdvicesForSimpleForm();
|
704 |
+
$(this.idPrefix + 'combination_form').removeClassName('ignore-validate');
|
705 |
+
var validationResult = $(this.idPrefix + 'combination_form').select('input','select','textarea').collect(
|
706 |
+
function(elm) {
|
707 |
+
return Validation.validate(elm,{useTitle : false, onElementValidate : function(){}});
|
708 |
+
}
|
709 |
+
).all();
|
710 |
+
$(this.idPrefix + 'combination_form').addClassName('ignore-validate');
|
711 |
+
|
712 |
+
if (!validationResult) {
|
713 |
+
return;
|
714 |
+
}
|
715 |
+
|
716 |
+
var params = Form.serializeElements(
|
717 |
+
$(this.idPrefix + 'combination_form').select('input','select','textarea'),
|
718 |
+
true
|
719 |
+
);
|
720 |
+
params.form_key = FORM_KEY;
|
721 |
+
params.attribute_values = this.attributes;
|
722 |
+
$('messages').update();
|
723 |
+
|
724 |
+
new Ajax.Request(this.createCombinationsUrl, {
|
725 |
+
parameters: params,
|
726 |
+
method:'post',
|
727 |
+
area: $(this.idPrefix + 'combination_form'),
|
728 |
+
onComplete: this.quickCombinationComplete.bind(this)
|
729 |
+
});
|
730 |
+
},
|
731 |
+
quickCombinationComplete : function(transport) {
|
732 |
+
var result = transport.responseText.evalJSON();
|
733 |
+
|
734 |
+
if (result.error) {
|
735 |
+
if (result.error.fields) {
|
736 |
+
$(this.idPrefix + 'simple_form').removeClassName(
|
737 |
+
'ignore-validate');
|
738 |
+
$H(result.error.fields)
|
739 |
+
.each(
|
740 |
+
function(pair) {
|
741 |
+
$('simple_product_' + pair.key).value = pair.value;
|
742 |
+
$('simple_product_' + pair.key + '_autogenerate').checked = false;
|
743 |
+
toggleValueElements(
|
744 |
+
$('simple_product_' + pair.key + '_autogenerate'),
|
745 |
+
$('simple_product_' + pair.key + '_autogenerate').parentNode);
|
746 |
+
Validation.ajaxError(
|
747 |
+
$('simple_product_' + pair.key),
|
748 |
+
result.error.message);
|
749 |
+
});
|
750 |
+
$(this.idPrefix + 'simple_form')
|
751 |
+
.addClassName('ignore-validate');
|
752 |
+
} else {
|
753 |
+
if (result.error.message) {
|
754 |
+
alert(result.error.message);
|
755 |
+
} else {
|
756 |
+
alert(result.error);
|
757 |
+
}
|
758 |
+
}
|
759 |
+
return;
|
760 |
+
} else if (result.messages) {
|
761 |
+
$('messages').update(result.messages);
|
762 |
+
}
|
763 |
+
|
764 |
+
result.attributes
|
765 |
+
.each( function(attribute) {
|
766 |
+
var attr = this.getAttributeById(attribute.attribute_id);
|
767 |
+
if (!this.getValueByIndex(attr, attribute.value_index)
|
768 |
+
&& result.pricing
|
769 |
+
&& result.pricing[attr.attribute_code]) {
|
770 |
+
|
771 |
+
attribute.is_percent = result.pricing[attr.attribute_code].is_percent;
|
772 |
+
attribute.pricing_value = (result.pricing[attr.attribute_code].value == null ? ''
|
773 |
+
: result.pricing[attr.attribute_code].value);
|
774 |
+
}
|
775 |
+
}.bind(this));
|
776 |
+
|
777 |
+
this.attributes.each( function(attribute) {
|
778 |
+
if ($('simple_product_' + attribute.attribute_code)) {
|
779 |
+
$('simple_product_' + attribute.attribute_code).value = '';
|
780 |
+
}
|
781 |
+
}.bind(this));
|
782 |
+
|
783 |
+
result.product_ids.each( function(product_id) {
|
784 |
+
this.links.set(product_id, result.attributes);
|
785 |
+
}.bind(this));
|
786 |
+
|
787 |
+
//this.links.set(result.product_id, result.attributes);
|
788 |
+
this.updateGrid();
|
789 |
+
this.updateValues();
|
790 |
+
this.grid.reload();
|
791 |
+
this.grid.rows.each( function(row) {
|
792 |
+
this.revalidateRowAfterReload(this.grid, row);
|
793 |
+
}.bind(this));
|
794 |
+
this.updateValues();
|
795 |
+
},
|
796 |
+
// End
|
797 |
+
quickCreateNewProductComplete: function (transport) {
|
798 |
+
var result = transport.responseText.evalJSON();
|
799 |
+
|
800 |
+
if (result.error) {
|
801 |
+
if (result.error.fields) {
|
802 |
+
$(this.idPrefix + 'simple_form').removeClassName('ignore-validate');
|
803 |
+
$H(result.error.fields).each(function(pair){
|
804 |
+
$('simple_product_' + pair.key).value = pair.value;
|
805 |
+
$('simple_product_' + pair.key + '_autogenerate').checked = false;
|
806 |
+
toggleValueElements(
|
807 |
+
$('simple_product_' + pair.key + '_autogenerate'),
|
808 |
+
$('simple_product_' + pair.key + '_autogenerate').parentNode
|
809 |
+
);
|
810 |
+
Validation.ajaxError($('simple_product_' + pair.key), result.error.message);
|
811 |
+
});
|
812 |
+
$(this.idPrefix + 'simple_form').addClassName('ignore-validate');
|
813 |
+
} else {
|
814 |
+
if (result.error.message) {
|
815 |
+
alert(result.error.message);
|
816 |
+
}
|
817 |
+
else {
|
818 |
+
alert(result.error);
|
819 |
+
}
|
820 |
+
}
|
821 |
+
return;
|
822 |
+
} else if(result.messages) {
|
823 |
+
$('messages').update(result.messages);
|
824 |
+
}
|
825 |
+
|
826 |
+
|
827 |
+
result.attributes.each(function(attribute) {
|
828 |
+
var attr = this.getAttributeById(attribute.attribute_id);
|
829 |
+
if (!this.getValueByIndex(attr, attribute.value_index)
|
830 |
+
&& result.pricing
|
831 |
+
&& result.pricing[attr.attribute_code]) {
|
832 |
+
|
833 |
+
attribute.is_percent = result.pricing[attr.attribute_code].is_percent;
|
834 |
+
attribute.pricing_value = (result.pricing[attr.attribute_code].value == null ? '' : result.pricing[attr.attribute_code].value);
|
835 |
+
}
|
836 |
+
}.bind(this));
|
837 |
+
|
838 |
+
this.attributes.each(function(attribute) {
|
839 |
+
if ($('simple_product_' + attribute.attribute_code)) {
|
840 |
+
$('simple_product_' + attribute.attribute_code).value = '';
|
841 |
+
}
|
842 |
+
}.bind(this));
|
843 |
+
|
844 |
+
this.links.set(result.product_id, result.attributes);
|
845 |
+
this.updateGrid();
|
846 |
+
this.updateValues();
|
847 |
+
this.grid.reload();
|
848 |
+
},
|
849 |
+
checkCreationUniqueAttributes: function () {
|
850 |
+
var attributes = [];
|
851 |
+
this.attributes.each(function(attribute) {
|
852 |
+
attributes.push({
|
853 |
+
attribute_id:attribute.attribute_id,
|
854 |
+
value_index: $('simple_product_' + attribute.attribute_code).value
|
855 |
+
});
|
856 |
+
}.bind(this));
|
857 |
+
|
858 |
+
return this.checkAttributes(attributes);
|
859 |
+
},
|
860 |
+
getAttributeByCode: function (attributeCode) {
|
861 |
+
var attribute = null;
|
862 |
+
this.attributes.each(function(item){
|
863 |
+
if (item.attribute_code == attributeCode) {
|
864 |
+
attribute = item;
|
865 |
+
throw $break;
|
866 |
+
}
|
867 |
+
});
|
868 |
+
return attribute;
|
869 |
+
},
|
870 |
+
getAttributeById: function (attributeId) {
|
871 |
+
var attribute = null;
|
872 |
+
this.attributes.each(function(item){
|
873 |
+
if (item.attribute_id == attributeId) {
|
874 |
+
attribute = item;
|
875 |
+
throw $break;
|
876 |
+
}
|
877 |
+
});
|
878 |
+
return attribute;
|
879 |
+
},
|
880 |
+
getValueByIndex: function (attribute, valueIndex) {
|
881 |
+
var result = null;
|
882 |
+
attribute.values.each(function(value){
|
883 |
+
if (value.value_index == valueIndex) {
|
884 |
+
result = value;
|
885 |
+
throw $break;
|
886 |
+
}
|
887 |
+
});
|
888 |
+
return result;
|
889 |
+
},
|
890 |
+
showPricing: function (select, attributeCode) {
|
891 |
+
var attribute = this.getAttributeByCode(attributeCode);
|
892 |
+
if (!attribute) {
|
893 |
+
return;
|
894 |
+
}
|
895 |
+
|
896 |
+
select = $(select);
|
897 |
+
if (select.value && !$('simple_product_' + attributeCode + '_pricing_container')) {
|
898 |
+
Element.insert(select, {after: '<div class="left"></div> <div id="simple_product_' + attributeCode + '_pricing_container" class="left"></div>'});
|
899 |
+
var newContainer = select.next('div');
|
900 |
+
select.parentNode.removeChild(select);
|
901 |
+
newContainer.appendChild(select);
|
902 |
+
// Fix visualization bug
|
903 |
+
$(this.idPrefix + 'simple_form').down('.form-list').style.width = '100%';
|
904 |
+
}
|
905 |
+
|
906 |
+
var container = $('simple_product_' + attributeCode + '_pricing_container');
|
907 |
+
|
908 |
+
if (select.value) {
|
909 |
+
var value = this.getValueByIndex(attribute,select.value);
|
910 |
+
if (!value) {
|
911 |
+
if (!container.down('.attribute-price')) {
|
912 |
+
if (value == null) {
|
913 |
+
value = {};
|
914 |
+
}
|
915 |
+
container.update(this.pricingValueTemplate.evaluate(value));
|
916 |
+
var priceValueField = container.down('.attribute-price');
|
917 |
+
var priceTypeField = container.down('.attribute-price-type');
|
918 |
+
|
919 |
+
priceValueField.attributeCode = attributeCode;
|
920 |
+
priceValueField.priceField = priceValueField;
|
921 |
+
priceValueField.typeField = priceTypeField;
|
922 |
+
|
923 |
+
priceTypeField.attributeCode = attributeCode;
|
924 |
+
priceTypeField.priceField = priceValueField;
|
925 |
+
priceTypeField.typeField = priceTypeField;
|
926 |
+
|
927 |
+
Event.observe(priceValueField, 'change', this.updateSimplePricing.bindAsEventListener(this));
|
928 |
+
Event.observe(priceValueField, 'keyup', this.updateSimplePricing.bindAsEventListener(this));
|
929 |
+
Event.observe(priceTypeField, 'change', this.updateSimplePricing.bindAsEventListener(this));
|
930 |
+
|
931 |
+
$('simple_product_' + attributeCode + '_pricing_value').value = null;
|
932 |
+
$('simple_product_' + attributeCode + '_pricing_type').value = null;
|
933 |
+
}
|
934 |
+
} else if (!isNaN(parseFloat(value.pricing_value))) {
|
935 |
+
container.update(this.pricingValueViewTemplate.evaluate({
|
936 |
+
'value': (parseFloat(value.pricing_value) > 0 ? '+' : '') + parseFloat(value.pricing_value)
|
937 |
+
+ ( parseInt(value.is_percent) > 0 ? '%' : '')
|
938 |
+
}));
|
939 |
+
$('simple_product_' + attributeCode + '_pricing_value').value = value.pricing_value;
|
940 |
+
$('simple_product_' + attributeCode + '_pricing_type').value = value.is_percent;
|
941 |
+
} else {
|
942 |
+
container.update('');
|
943 |
+
$('simple_product_' + attributeCode + '_pricing_value').value = null;
|
944 |
+
$('simple_product_' + attributeCode + '_pricing_type').value = null;
|
945 |
+
}
|
946 |
+
} else if(container) {
|
947 |
+
container.update('');
|
948 |
+
$('simple_product_' + attributeCode + '_pricing_value').value = null;
|
949 |
+
$('simple_product_' + attributeCode + '_pricing_type').value = null;
|
950 |
+
}
|
951 |
+
},
|
952 |
+
updateSimplePricing: function(evt) {
|
953 |
+
var element = Event.element(evt);
|
954 |
+
if (!element.priceField.value.blank()) {
|
955 |
+
$('simple_product_' + element.attributeCode + '_pricing_value').value = element.priceField.value;
|
956 |
+
$('simple_product_' + element.attributeCode + '_pricing_type').value = element.typeField.value;
|
957 |
+
} else {
|
958 |
+
$('simple_product_' + element.attributeCode + '_pricing_value').value = null;
|
959 |
+
$('simple_product_' + element.attributeCode + '_pricing_type').value = null;
|
960 |
+
}
|
961 |
+
},
|
962 |
+
updateSimpleForm: function() {
|
963 |
+
this.attributes.each(function(attribute) {
|
964 |
+
if ($('simple_product_' + attribute.attribute_code)) {
|
965 |
+
this.showPricing($('simple_product_' + attribute.attribute_code), attribute.attribute_code);
|
966 |
+
}
|
967 |
+
}.bind(this));
|
968 |
+
}
|
969 |
+
}
|
970 |
+
|
971 |
+
var onInitDisableFieldsList = [];
|
972 |
+
|
973 |
+
function toogleFieldEditMode(toogleIdentifier, fieldContainer) {
|
974 |
+
if($(toogleIdentifier).checked) {
|
975 |
+
enableFieldEditMode(fieldContainer);
|
976 |
+
} else {
|
977 |
+
disableFieldEditMode(fieldContainer);
|
978 |
+
}
|
979 |
+
}
|
980 |
+
|
981 |
+
function disableFieldEditMode(fieldContainer) {
|
982 |
+
$(fieldContainer).disabled = true;
|
983 |
+
if($(fieldContainer + '_hidden')) {
|
984 |
+
$(fieldContainer + '_hidden').disabled = true;
|
985 |
+
}
|
986 |
+
}
|
987 |
+
|
988 |
+
function enableFieldEditMode(fieldContainer) {
|
989 |
+
$(fieldContainer).disabled = false;
|
990 |
+
if($(fieldContainer + '_hidden')) {
|
991 |
+
$(fieldContainer + '_hidden').disabled = false;
|
992 |
+
}
|
993 |
+
}
|
994 |
+
|
995 |
+
function initDisableFields(fieldContainer)
|
996 |
+
{
|
997 |
+
onInitDisableFieldsList.push(fieldContainer);
|
998 |
+
}
|
999 |
+
|
1000 |
+
function onCompleteDisableInited()
|
1001 |
+
{
|
1002 |
+
onInitDisableFieldsList.each(function(item){
|
1003 |
+
disableFieldEditMode(item);
|
1004 |
+
});
|
1005 |
+
}
|
1006 |
+
|
1007 |
+
Event.observe(window, 'load', onCompleteDisableInited);
|
package.xml
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>Automatic_Configurables_1dot3</name>
|
4 |
+
<version>0.0.8</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>This extension will help you to automatically create simple products for configurables.</summary>
|
10 |
+
<description>This extension will help you to automatically create simple associated products for configurable products and add them to the grid of associated products. It makes all combinations of attribute values that you will choose. The number of products is not limited. Please remember that you need to save configurable product first to see this module tab.
|
11 |
+
Overriden classes:
|
12 |
+
Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config
|
13 |
+
And overriden js:
|
14 |
+
js/mage/adminhtml/product.js</description>
|
15 |
+
<notes>The wrong js file was included</notes>
|
16 |
+
<authors><author><name>QuartSoft</name><user>auto-converted</user><email>alexeybulash@gmail.com</email></author></authors>
|
17 |
+
<date>2010-05-27</date>
|
18 |
+
<time>20:10:49</time>
|
19 |
+
<contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="quickconfigurables.xml" hash="993e213c74431667274ae1c828e983ec"/></dir><dir name="template"><dir name="quickconfigurables"><dir name="catalog"><dir name="product"><dir name="edit"><dir name="super"><file name="config.phtml" hash="5f9fadc3c04b5b2b35c8e05ed57c5160"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="qs"><dir name="adminhtml"><file name="product_13.js" hash="e9309efb7632cb134aedee673b0cecaf"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="QS_Quickconfigurables.xml" hash="2fa9d665b16c54645966e27c693935f3"/></dir></target><target name="magelocal"><dir name="QS"><dir name="Quickconfigurables"><dir name="Block"><dir name="Adminhtml"><dir name="Catalog"><dir name="Product"><dir name="Edit"><dir name="Tab"><dir name="Super"><dir name="Config"><file name="Combination.php" hash="ad3779c9daf8b0bf21bf7a2a168db03a"/></dir><file name="Config.php" hash="ff0bf25c35bb5069e847e3230ce56eeb"/></dir></dir></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="ProductController.php" hash="1f62f04b1d3005c5064278ee790aedd6"/></dir></dir><dir name="etc"><file name="config.xml" hash="72157ba83c8281b13b0b4235328355e8"/></dir><dir name="Helper"><file name="Data.php" hash="a5651545c4121211e4fae9de2a5eddf7"/></dir></dir></dir></target></contents>
|
20 |
+
<compatible/>
|
21 |
+
<dependencies/>
|
22 |
+
</package>
|