diff --git a/core/lib/Thelia/Action/Product.php b/core/lib/Thelia/Action/Product.php
index 97c3dbdd7..095f2d32e 100644
--- a/core/lib/Thelia/Action/Product.php
+++ b/core/lib/Thelia/Action/Product.php
@@ -61,6 +61,11 @@ use Thelia\Model\ProductSaleElementsQuery;
use Propel\Runtime\ActiveQuery\PropelQuery;
use Thelia\Core\Event\ProductDeleteCategoryEvent;
use Thelia\Core\Event\ProductAddCategoryEvent;
+use Thelia\Model\AttributeAvQuery;
+use Thelia\Model\AttributeCombination;
+use Thelia\Core\Event\ProductCreateCombinationEvent;
+use Propel\Runtime\Propel;
+use Thelia\Model\Map\ProductTableMap;
class Product extends BaseAction implements EventSubscriberInterface
{
@@ -331,7 +336,6 @@ class Product extends BaseAction implements EventSubscriberInterface
->setProductId($event->getProductId())
->setFeatureId($event->getFeatureId())
-
;
}
@@ -356,6 +360,58 @@ class Product extends BaseAction implements EventSubscriberInterface
;
}
+ public function createProductCombination(ProductCreateCombinationEvent $event) {
+
+ $con = Propel::getWriteConnection(ProductTableMap::DATABASE_NAME);
+
+ $con->beginTransaction();
+
+ try {
+
+ if ($event->getUseDefaultPricing()) {
+ // Get the default pricing
+ $salesElement = ProductSaleElementsQuery::create()->filterByIsDefault(true)->findOne();
+ }
+ else {
+ // We have to create a new ProductSaleElement
+ echo "no default !!!!";
+ exit;
+ }
+
+ if (null == $salesElement)
+ throw new \LogicException("Cannot create or get the product sales element for this new combination.");
+
+ $combinationAttributes = $event->getAttributeAvList();
+
+ if (count($combinationAttributes) > 0) {
+
+ foreach($combinationAttributes as $attributeAvId) {
+
+ $attributeAv = AttributeAvQuery::create()->findPk($attributeAvId);
+
+ if ($attributeAv !== null) {
+ $attributeCombination = new AttributeCombination();
+
+ $attributeCombination
+ ->setAttributeAvId($attributeAvId)
+ ->setAttribute($attributeAv->getAttribute())
+ ->setProductSaleElements($salesElement)
+ ->save();
+ }
+ }
+ }
+
+ // Store all the stuff !
+ $con->commit();
+ }
+ catch(\Exception $ex) {
+
+ $con->rollback();
+
+ throw $ex;
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -374,6 +430,9 @@ class Product extends BaseAction implements EventSubscriberInterface
TheliaEvents::PRODUCT_UPDATE_ACCESSORY_POSITION => array("updateAccessoryPosition", 128),
TheliaEvents::PRODUCT_UPDATE_CONTENT_POSITION => array("updateContentPosition", 128),
+ TheliaEvents::PRODUCT_ADD_COMBINATION => array("createProductCombination", 128),
+ TheliaEvents::PRODUCT_DELETE_COMBINATION => array("deleteProductCombination", 128),
+
TheliaEvents::PRODUCT_ADD_ACCESSORY => array("addAccessory", 128),
TheliaEvents::PRODUCT_REMOVE_ACCESSORY => array("removeAccessory", 128),
diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml
index d2b9e4ffb..5c6afbfc5 100755
--- a/core/lib/Thelia/Config/Resources/routing/admin.xml
+++ b/core/lib/Thelia/Config/Resources/routing/admin.xml
@@ -230,12 +230,19 @@
xml|json
-
Thelia\Controller\Admin\ProductController::addAttributeValueToCombinationAction
xml|json
+
+ Thelia\Controller\Admin\ProductController::addCombinationAction
+
+
+
+ Thelia\Controller\Admin\ProductController::deleteCombinationAction
+
+
diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php
index adc3da942..f46bda291 100644
--- a/core/lib/Thelia/Controller/Admin/ProductController.php
+++ b/core/lib/Thelia/Controller/Admin/ProductController.php
@@ -48,11 +48,14 @@ use Thelia\Model\FeatureQuery;
use Thelia\Core\Event\FeatureProductDeleteEvent;
use Thelia\Model\FeatureTemplateQuery;
use Thelia\Core\Event\ProductSetTemplateEvent;
-use Thelia\Model\Base\ProductSaleElementsQuery;
use Thelia\Core\Event\ProductAddCategoryEvent;
use Thelia\Core\Event\ProductDeleteCategoryEvent;
use Thelia\Model\AttributeQuery;
use Thelia\Model\AttributeAvQuery;
+use Thelia\Model\ProductSaleElementsQuery;
+use Thelia\Model\AttributeCombination;
+use Thelia\Model\AttributeAv;
+use Thelia\Core\Event\ProductCreateCombinationEvent;
/**
* Manages products
@@ -699,6 +702,7 @@ class ProductController extends AbstractCrudController
}
public function addAttributeValueToCombinationAction($productId, $attributeAvId, $combination) {
+
$result = array();
// Get attribute for this product
@@ -708,6 +712,8 @@ class ProductController extends AbstractCrudController
$addIt = true;
+ $attribute = $attributeAv->getAttribute();
+
// Check if this attribute is not already present
$combinationArray = explode(',', $combination);
@@ -717,9 +723,7 @@ class ProductController extends AbstractCrudController
if ($attrAv !== null) {
- if ($attrAv->getAttributeId() == $attributeAv->getAttributeId()) {
-
- $attribute = AttributeQuery::create()->joinWithI18n($this->getCurrentEditionLocale())->findPk($attributeAv->getAttributeId());
+ if ($attrAv->getAttributeId() == $attribute->getId()) {
$result['error'] = $this->getTranslator()->trans(
'A value for attribute "%name" is already present in the combination',
@@ -729,13 +733,39 @@ class ProductController extends AbstractCrudController
$addIt = false;
}
- $result[] = array('id' => $attrAv->getId(), 'title' => $attrAv->getTitle());
+ $result[] = array('id' => $attrAv->getId(), 'title' => $attrAv->getAttribute()->getTitle() . " : " . $attrAv->getTitle());
}
}
- if ($addIt) $result[] = array('id' => $attributeAv->getId(), 'title' => $attributeAv->getTitle());
+ if ($addIt) $result[] = array('id' => $attributeAv->getId(), 'title' => $attribute->getTitle() . " : " . $attributeAv->getTitle());
}
return $this->jsonResponse(json_encode($result));
}
+
+ /**
+ * A a new combination to a product
+ */
+ public function addCombinationAction() {
+
+ // Check current user authorization
+ if (null !== $response = $this->checkAuth("admin.products.update")) return $response;
+
+ $event = new ProductCreateCombinationEvent(
+ $this->getExistingObject(),
+ $this->getRequest()->get('use_default_princing', 0),
+ $this->getRequest()->get('combination_attributes', array())
+ );
+
+ try {
+ $this->dispatch(TheliaEvents::PRODUCT_ADD_COMBINATION, $event);
+ }
+ catch (\Exception $ex) {
+ // Any error
+ return $this->errorPage($ex);
+ }
+echo "done!";
+exit;
+ $this->redirectToEditionTemplate();
+ }
}
diff --git a/core/lib/Thelia/Core/Event/ProductCreateCombinationEvent.php b/core/lib/Thelia/Core/Event/ProductCreateCombinationEvent.php
new file mode 100644
index 000000000..092dc7f82
--- /dev/null
+++ b/core/lib/Thelia/Core/Event/ProductCreateCombinationEvent.php
@@ -0,0 +1,63 @@
+. */
+/* */
+/*************************************************************************************/
+
+namespace Thelia\Core\Event;
+
+use Thelia\Model\Product;
+class ProductCreateCombinationEvent extends ProductEvent
+{
+ protected $use_default_pricing;
+ protected $attribute_av_list;
+
+ public function __construct(Product $product, $use_default_pricing, $attribute_av_list)
+ {
+ parent::__construct($product);
+
+ $this->use_default_pricing = $use_default_pricing;
+ $this->attribute_av_list = $attribute_av_list;
+ }
+
+ public function getUseDefaultPricing()
+ {
+ return $this->use_default_pricing;
+ }
+
+ public function setUseDefaultPricing($use_default_pricing)
+ {
+ $this->use_default_pricing = $use_default_pricing;
+
+ return $this;
+ }
+
+ public function getAttributeAvList()
+ {
+ return $this->attribute_av_list;
+ }
+
+ public function setAttributeAvList($attribute_av_list)
+ {
+ $this->attribute_av_list = $attribute_av_list;
+
+ return $this;
+ }
+}
diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php
index 767800733..e1f356cda 100755
--- a/core/lib/Thelia/Core/Event/TheliaEvents.php
+++ b/core/lib/Thelia/Core/Event/TheliaEvents.php
@@ -188,7 +188,10 @@ final class TheliaEvents
const PRODUCT_REMOVE_CONTENT = "action.productRemoveContent";
const PRODUCT_UPDATE_CONTENT_POSITION = "action.updateProductContentPosition";
- const PRODUCT_SET_TEMPLATE = "action.productSetTemplate";
+ const PRODUCT_ADD_COMBINATION = "action.productAddCombination";
+ const PRODUCT_DELETE_COMBINATION = "action.productDeleteCombination";
+
+ const PRODUCT_SET_TEMPLATE = "action.productSetTemplate";
const PRODUCT_ADD_ACCESSORY = "action.productAddProductAccessory";
const PRODUCT_REMOVE_ACCESSORY = "action.productRemoveProductAccessory";
diff --git a/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php b/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php
index 8fb044556..bf8ccf512 100755
--- a/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php
+++ b/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php
@@ -170,17 +170,18 @@ class ProductSaleElements extends BaseLoop
$taxedPromoPrice = null;
}
- $loopResultRow->set("ID", $PSEValue->getId())
- ->set("QUANTITY", $PSEValue->getQuantity())
- ->set("IS_PROMO", $PSEValue->getPromo() === 1 ? 1 : 0)
- ->set("IS_NEW", $PSEValue->getNewness() === 1 ? 1 : 0)
- ->set("WEIGHT", $PSEValue->getWeight())
- ->set("PRICE", $price)
- ->set("PRICE_TAX", $taxedPrice - $price)
- ->set("TAXED_PRICE", $taxedPrice)
- ->set("PROMO_PRICE", $promoPrice)
- ->set("PROMO_PRICE_TAX", $taxedPromoPrice - $promoPrice)
- ->set("TAXED_PROMO_PRICE", $taxedPromoPrice);
+ $loopResultRow
+ ->set("ID" , $PSEValue->getId())
+ ->set("QUANTITY" , $PSEValue->getQuantity())
+ ->set("IS_PROMO" , $PSEValue->getPromo() === 1 ? 1 : 0)
+ ->set("IS_NEW" , $PSEValue->getNewness() === 1 ? 1 : 0)
+ ->set("WEIGHT" , $PSEValue->getWeight())
+ ->set("PRICE" , $price)
+ ->set("PRICE_TAX" , $taxedPrice - $price)
+ ->set("TAXED_PRICE" , $taxedPrice)
+ ->set("PROMO_PRICE" , $promoPrice)
+ ->set("PROMO_PRICE_TAX" , $taxedPromoPrice - $promoPrice)
+ ->set("TAXED_PROMO_PRICE" , $taxedPromoPrice);
$loopResult->addRow($loopResultRow);
}
diff --git a/core/lib/Thelia/Model/Product.php b/core/lib/Thelia/Model/Product.php
index 8e332a73b..2348a9c0d 100755
--- a/core/lib/Thelia/Model/Product.php
+++ b/core/lib/Thelia/Model/Product.php
@@ -98,8 +98,6 @@ class Product extends BaseProduct
->filterByDefaultCategory(true)
->findOne()
;
-echo "newcat= $defaultCategoryId ";
-var_dump($productCategory);
if ($productCategory == null || $productCategory->getCategoryId() != $defaultCategoryId) {
exit;
diff --git a/templates/admin/default/includes/generic-create-dialog.html b/templates/admin/default/includes/generic-create-dialog.html
index f30825d5a..fe3488535 100755
--- a/templates/admin/default/includes/generic-create-dialog.html
+++ b/templates/admin/default/includes/generic-create-dialog.html
@@ -12,6 +12,8 @@ A generic modal creation dialog template. Parameters
form_action = The form action URL. Form is submitted when OK button is clicked
form_enctype = The form encoding
form_error_message = The form error message (optional)
+
+ ok_button_id (optionnal) = the id of the OK button
*}
@@ -33,7 +35,7 @@ A generic modal creation dialog template. Parameters
diff --git a/templates/admin/default/includes/product-details-tab.html b/templates/admin/default/includes/product-details-tab.html
index 46ddfed86..238b7d987 100644
--- a/templates/admin/default/includes/product-details-tab.html
+++ b/templates/admin/default/includes/product-details-tab.html
@@ -37,6 +37,10 @@
{/form_field}
{/loop}
+
{intl l='Default pricing'}
+
+
{intl l="The default pricing is used with product that do not have any combinations. It is also used for product with combinations which share the same pricing information"}
+
{* -- Pricing ------------------------------------------------------- *}
@@ -173,81 +177,193 @@
{* -- Attribute combinations -------------------------------------------- *}
-
-
+ {module_include location='product_before_combinations'}
-
{intl l='Attribute Combinations'}
+
+
+
- {module_include location='product_before_combinations'}
+
+
+ {intl l='Attribute Combinations'}
- {ifloop rel="product-attributes"}
-
+
+
+
+
+ {module_include location='product_after_combinations'}
+
+
+{* -- Adding a new combination ------------------------------------------------- *}
+
+{* Capture the dialog body, to pass it to the generic dialog *}
+
+{capture "combination_creation_dialog"}
+
+
+
+
+
+ {intl l="Attribute"} :
+
+ {intl l='Select an attribute...'}
+ {loop name="product-attributes" type="attribute" product=$product_id backend_context="1" lang=$edit_language_id}
+ {$TITLE}
+ {/loop}
+
+ {intl l='Select an attribute and click (+) to view available values'}
+
-
-
+
{intl l='Select a value click (+) to add it to the combination'}
+
-
-
- {intl l="No available value for this attribute"}
-
-
+
+
+ {intl l="No available value for this attribute"}
+
+
-
-
-
- {/ifloop}
+ {form_field form=$form field='isnew'}
+
+ {/form_field}
- {elseloop rel="product-attributes"}
-
- {intl l="No attributes are attached to this product."}
-
- {/elseloop}
+{/capture}
- {module_include location='product_after_combinations'}
+{include
+ file = "includes/generic-create-dialog.html"
-
{* com *}
-
{* row *}
-
\ No newline at end of file
+ dialog_id = "combination_creation_dialog"
+ dialog_title = {intl l="Create a new combination"}
+ dialog_body = {$smarty.capture.combination_creation_dialog nofilter}
+
+ dialog_ok_label = {intl l="Create this combination"}
+
+ form_action = {url path='/admin/product/combination/add'}
+ form_enctype = ''
+ form_error_message = ''
+
+ ok_button_id = "combination_creation_dialog_ok"
+}
+
+
+{* -- Delete combination confirmation dialog ----------------------------------- *}
+
+{capture "combination_delete_dialog"}
+
+
+
+
+
+
+ {module_include location='category_delete_form'}
+
+{/capture}
+
+{include
+ file = "includes/generic-confirm-dialog.html"
+
+ dialog_id = "combination_delete_dialog"
+ dialog_title = {intl l="Delete a combunation"}
+ dialog_message = {intl l="Do you really want to delete this combination ?"}
+
+ form_action = {url path='/admin/product/combination/delete'}
+ form_content = {$smarty.capture.combination_delete_dialog nofilter}
+}
diff --git a/templates/admin/default/product-edit.html b/templates/admin/default/product-edit.html
index d9cda2f8d..1eaec9219 100644
--- a/templates/admin/default/product-edit.html
+++ b/templates/admin/default/product-edit.html
@@ -229,6 +229,17 @@ $(function() {
event.preventDefault();
});
+
+ // Set proper category ID in combination delete from
+ $('a.combination-delete').click(function(ev) {
+ $('#combination_delete_id').val($(this).data('id'));
+ });
+
+ // In create combination dialog, select all element of conbination list
+ $('#combination_creation_dialog_ok').click(function() {
+ $('#combination_attributes option').prop('selected', 'selected');
+ });
+
});