Started product management
This commit is contained in:
@@ -42,6 +42,11 @@
|
|||||||
<tag name="kernel.event_subscriber"/>
|
<tag name="kernel.event_subscriber"/>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="thelia.action.product" class="Thelia\Action\Product">
|
||||||
|
<argument type="service" id="service_container"/>
|
||||||
|
<tag name="kernel.event_subscriber"/>
|
||||||
|
</service>
|
||||||
|
|
||||||
<service id="thelia.action.config" class="Thelia\Action\Config">
|
<service id="thelia.action.config" class="Thelia\Action\Config">
|
||||||
<argument type="service" id="service_container"/>
|
<argument type="service" id="service_container"/>
|
||||||
<tag name="kernel.event_subscriber"/>
|
<tag name="kernel.event_subscriber"/>
|
||||||
|
|||||||
@@ -114,6 +114,50 @@
|
|||||||
<requirement key="_format">xml|json</requirement>
|
<requirement key="_format">xml|json</requirement>
|
||||||
</route>
|
</route>
|
||||||
|
|
||||||
|
<!-- Product Management -->
|
||||||
|
|
||||||
|
<route id="admin.products.default" path="/admin/products">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::defaultAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.products.create" path="/admin/products/create">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::createAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.products.update" path="/admin/products/update">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::updateAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.products.save" path="/admin/products/save">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::processUpdateAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.products.set-default" path="/admin/products/toggle-online">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::setToggleVisibilityAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.products.delete" path="/admin/products/delete">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::deleteAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.products.update-position" path="/admin/products/update-position">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::updatePositionAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.products.related-content.add" path="/admin/products/related-content/add">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::addRelatedContentAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.products.related-content.delete" path="/admin/products/related-content/delete">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::deleteRelatedContentAction</default>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<route id="admin.product.available-related-content" path="/admin/product/{productId}/available-related-content/{folderId}.{_format}" methods="GET">
|
||||||
|
<default key="_controller">Thelia\Controller\Admin\ProductController::getAvailableRelatedContentAction</default>
|
||||||
|
<requirement key="_format">xml|json</requirement>
|
||||||
|
</route>
|
||||||
|
|
||||||
|
|
||||||
<!-- Route to the Coupon controller (process Coupon browsing) -->
|
<!-- Route to the Coupon controller (process Coupon browsing) -->
|
||||||
|
|
||||||
<route id="admin.coupon.list" path="/admin/coupon/">
|
<route id="admin.coupon.list" path="/admin/coupon/">
|
||||||
|
|||||||
@@ -169,9 +169,14 @@ class CategoryController extends AbstractCrudController
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function renderListTemplate($currentOrder) {
|
protected function renderListTemplate($currentOrder) {
|
||||||
|
|
||||||
|
// Get product order
|
||||||
|
$product_order = $this->getListOrderFromSession('product', 'product_order', 'manual');
|
||||||
|
|
||||||
return $this->render('categories',
|
return $this->render('categories',
|
||||||
array(
|
array(
|
||||||
'category_order' => $currentOrder,
|
'category_order' => $currentOrder,
|
||||||
|
'product_order' => $product_order,
|
||||||
'category_id' => $this->getRequest()->get('category_id', 0)
|
'category_id' => $this->getRequest()->get('category_id', 0)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,6 +165,26 @@ final class TheliaEvents
|
|||||||
const BEFORE_UPDATECATEGORY = "action.before_updateCategory";
|
const BEFORE_UPDATECATEGORY = "action.before_updateCategory";
|
||||||
const AFTER_UPDATECATEGORY = "action.after_updateCategory";
|
const AFTER_UPDATECATEGORY = "action.after_updateCategory";
|
||||||
|
|
||||||
|
// -- Product management -----------------------------------------------
|
||||||
|
|
||||||
|
const PRODUCT_CREATE = "action.createProduct";
|
||||||
|
const PRODUCT_UPDATE = "action.updateProduct";
|
||||||
|
const PRODUCT_DELETE = "action.deleteProduct";
|
||||||
|
const PRODUCT_TOGGLE_VISIBILITY = "action.toggleProductVisibility";
|
||||||
|
const PRODUCT_UPDATE_POSITION = "action.updateProductPosition";
|
||||||
|
|
||||||
|
const PRODUCT_ADD_CONTENT = "action.productAddContent";
|
||||||
|
const PRODUCT_REMOVE_CONTENT = "action.productRemoveContent";
|
||||||
|
|
||||||
|
const BEFORE_CREATEPRODUCT = "action.before_createproduct";
|
||||||
|
const AFTER_CREATEPRODUCT = "action.after_createproduct";
|
||||||
|
|
||||||
|
const BEFORE_DELETEPRODUCT = "action.before_deleteproduct";
|
||||||
|
const AFTER_DELETEPRODUCT = "action.after_deleteproduct";
|
||||||
|
|
||||||
|
const BEFORE_UPDATEPRODUCT = "action.before_updateProduct";
|
||||||
|
const AFTER_UPDATEPRODUCT = "action.after_updateProduct";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sent when a new existing cat id duplicated. This append when current customer is different from current cart
|
* sent when a new existing cat id duplicated. This append when current customer is different from current cart
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class Product extends BaseI18nLoop
|
|||||||
new Argument(
|
new Argument(
|
||||||
'order',
|
'order',
|
||||||
new TypeCollection(
|
new TypeCollection(
|
||||||
new Type\EnumListType(array('alpha', 'alpha_reverse', 'min_price', 'max_price', 'manual', 'manual_reverse', 'ref', 'promo', 'new', 'random', 'given_id'))
|
new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha_reverse', 'min_price', 'max_price', 'manual', 'manual_reverse', 'ref', 'promo', 'new', 'random', 'given_id'))
|
||||||
),
|
),
|
||||||
'alpha'
|
'alpha'
|
||||||
),
|
),
|
||||||
@@ -536,6 +536,12 @@ class Product extends BaseI18nLoop
|
|||||||
|
|
||||||
foreach ($orders as $order) {
|
foreach ($orders as $order) {
|
||||||
switch ($order) {
|
switch ($order) {
|
||||||
|
case "id":
|
||||||
|
$search->orderById(Criteria::ASC);
|
||||||
|
break;
|
||||||
|
case "id_reverse":
|
||||||
|
$search->orderById(Criteria::DESC);
|
||||||
|
break;
|
||||||
case "alpha":
|
case "alpha":
|
||||||
$search->addAscendingOrderByColumn('i18n_TITLE');
|
$search->addAscendingOrderByColumn('i18n_TITLE');
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class CategoryCreationForm extends BaseForm
|
|||||||
"label_attr" => array("for" => "locale_create")
|
"label_attr" => array("for" => "locale_create")
|
||||||
))
|
))
|
||||||
->add("visible", "integer", array(
|
->add("visible", "integer", array(
|
||||||
"label" => Translator::getInstance()->trans("This category is online on the front office."),
|
"label" => Translator::getInstance()->trans("This category is online."),
|
||||||
"label_attr" => array("for" => "visible_create")
|
"label_attr" => array("for" => "visible_create")
|
||||||
))
|
))
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class ProductCreationForm extends BaseForm
|
|||||||
"for" => "title"
|
"for" => "title"
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
->add("parent", "integer", array(
|
->add("default_category", "integer", array(
|
||||||
"constraints" => array(
|
"constraints" => array(
|
||||||
new NotBlank()
|
new NotBlank()
|
||||||
)
|
)
|
||||||
@@ -57,7 +57,11 @@ class ProductCreationForm extends BaseForm
|
|||||||
new NotBlank()
|
new NotBlank()
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
;
|
->add("visible", "integer", array(
|
||||||
|
"label" => Translator::getInstance()->trans("This product is online."),
|
||||||
|
"label_attr" => array("for" => "visible_create")
|
||||||
|
))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getName()
|
public function getName()
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ class AttributeCombinationTableMap extends TableMap
|
|||||||
{
|
{
|
||||||
$this->addRelation('Attribute', '\\Thelia\\Model\\Attribute', RelationMap::MANY_TO_ONE, array('attribute_id' => 'id', ), 'CASCADE', 'RESTRICT');
|
$this->addRelation('Attribute', '\\Thelia\\Model\\Attribute', RelationMap::MANY_TO_ONE, array('attribute_id' => 'id', ), 'CASCADE', 'RESTRICT');
|
||||||
$this->addRelation('AttributeAv', '\\Thelia\\Model\\AttributeAv', RelationMap::MANY_TO_ONE, array('attribute_av_id' => 'id', ), 'CASCADE', 'RESTRICT');
|
$this->addRelation('AttributeAv', '\\Thelia\\Model\\AttributeAv', RelationMap::MANY_TO_ONE, array('attribute_av_id' => 'id', ), 'CASCADE', 'RESTRICT');
|
||||||
$this->addRelation('ProductSaleElements', '\\Thelia\\Model\\ProductSaleElements', RelationMap::MANY_TO_ONE, array('product_sale_elements_id' => 'id', ), null, null);
|
$this->addRelation('ProductSaleElements', '\\Thelia\\Model\\ProductSaleElements', RelationMap::MANY_TO_ONE, array('product_sale_elements_id' => 'id', ), 'CASCADE', 'RESTRICT');
|
||||||
} // buildRelations()
|
} // buildRelations()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ class ProductSaleElementsTableMap extends TableMap
|
|||||||
public function buildRelations()
|
public function buildRelations()
|
||||||
{
|
{
|
||||||
$this->addRelation('Product', '\\Thelia\\Model\\Product', RelationMap::MANY_TO_ONE, array('product_id' => 'id', ), 'CASCADE', 'RESTRICT');
|
$this->addRelation('Product', '\\Thelia\\Model\\Product', RelationMap::MANY_TO_ONE, array('product_id' => 'id', ), 'CASCADE', 'RESTRICT');
|
||||||
$this->addRelation('AttributeCombination', '\\Thelia\\Model\\AttributeCombination', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), null, null, 'AttributeCombinations');
|
$this->addRelation('AttributeCombination', '\\Thelia\\Model\\AttributeCombination', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), 'CASCADE', 'RESTRICT', 'AttributeCombinations');
|
||||||
$this->addRelation('CartItem', '\\Thelia\\Model\\CartItem', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), null, null, 'CartItems');
|
$this->addRelation('CartItem', '\\Thelia\\Model\\CartItem', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), null, null, 'CartItems');
|
||||||
$this->addRelation('ProductPrice', '\\Thelia\\Model\\ProductPrice', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), 'CASCADE', null, 'ProductPrices');
|
$this->addRelation('ProductPrice', '\\Thelia\\Model\\ProductPrice', RelationMap::ONE_TO_MANY, array('id' => 'product_sale_elements_id', ), 'CASCADE', null, 'ProductPrices');
|
||||||
} // buildRelations()
|
} // buildRelations()
|
||||||
@@ -206,6 +206,7 @@ class ProductSaleElementsTableMap extends TableMap
|
|||||||
{
|
{
|
||||||
// Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool,
|
// Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool,
|
||||||
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
|
// since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule.
|
||||||
|
AttributeCombinationTableMap::clearInstancePool();
|
||||||
ProductPriceTableMap::clearInstancePool();
|
ProductPriceTableMap::clearInstancePool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ use Thelia\Model\Base\Product as BaseProduct;
|
|||||||
use Thelia\Tools\URL;
|
use Thelia\Tools\URL;
|
||||||
use Thelia\TaxEngine\Calculator;
|
use Thelia\TaxEngine\Calculator;
|
||||||
use Propel\Runtime\Connection\ConnectionInterface;
|
use Propel\Runtime\Connection\ConnectionInterface;
|
||||||
|
use Thelia\Core\Event\TheliaEvents;
|
||||||
|
use Thelia\Core\Event\ProductEvent;
|
||||||
|
|
||||||
class Product extends BaseProduct
|
class Product extends BaseProduct
|
||||||
{
|
{
|
||||||
@@ -41,6 +43,45 @@ class Product extends BaseProduct
|
|||||||
return round($taxCalculator->load($this, $country)->getTaxedPrice($this->getRealLowestPrice()), 2);
|
return round($taxCalculator->load($this, $country)->getTaxedPrice($this->getRealLowestPrice()), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current default category for this product
|
||||||
|
*/
|
||||||
|
public function getDefaultCategory() {
|
||||||
|
// Find default category
|
||||||
|
$default_category = ProductCategoryQuery::create()
|
||||||
|
->filterByProductId($this->getId())
|
||||||
|
->filterByDefaultCategory(true)
|
||||||
|
->findOne();
|
||||||
|
|
||||||
|
return $default_category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set default category for this product
|
||||||
|
*
|
||||||
|
* @param integer $categoryId the new default category id
|
||||||
|
*/
|
||||||
|
public function setDefaultCategory($categoryId) {
|
||||||
|
|
||||||
|
// Unset previous category
|
||||||
|
ProductCategoryQuery::create()
|
||||||
|
->filterByProductId($this->getId())
|
||||||
|
->filterByDefaultCategory(true)
|
||||||
|
->find()
|
||||||
|
->setByDefault(false)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
// Set new default category
|
||||||
|
ProductCategoryQuery::create()
|
||||||
|
->filterByProductId($this->getId())
|
||||||
|
->filterByCategoryId($categoryId)
|
||||||
|
->find()
|
||||||
|
->setByDefault(true)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate next position relative to our default category
|
* Calculate next position relative to our default category
|
||||||
*/
|
*/
|
||||||
@@ -60,6 +101,53 @@ class Product extends BaseProduct
|
|||||||
|
|
||||||
$this->generateRewritenUrl($this->getLocale());
|
$this->generateRewritenUrl($this->getLocale());
|
||||||
|
|
||||||
|
$this->dispatchEvent(TheliaEvents::BEFORE_CREATEPRODUCT, new ProductEvent($this));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function postInsert(ConnectionInterface $con = null)
|
||||||
|
{
|
||||||
|
$this->dispatchEvent(TheliaEvents::AFTER_CREATEPRODUCT, new ProductEvent($this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function preUpdate(ConnectionInterface $con = null)
|
||||||
|
{
|
||||||
|
$this->dispatchEvent(TheliaEvents::BEFORE_UPDATEPRODUCT, new ProductEvent($this));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function postUpdate(ConnectionInterface $con = null)
|
||||||
|
{
|
||||||
|
$this->dispatchEvent(TheliaEvents::AFTER_UPDATEPRODUCT, new ProductEvent($this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function preDelete(ConnectionInterface $con = null)
|
||||||
|
{
|
||||||
|
$this->dispatchEvent(TheliaEvents::BEFORE_DELETEPRODUCT, new ProductEvent($this));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function postDelete(ConnectionInterface $con = null)
|
||||||
|
{
|
||||||
|
$this->dispatchEvent(TheliaEvents::AFTER_DELETEPRODUCT, new ProductEvent($this));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -449,11 +449,14 @@ try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "Generating coupns fixtures\n";
|
echo "Generating coupons fixtures\n";
|
||||||
|
|
||||||
generateCouponFixtures($thelia);
|
generateCouponFixtures($thelia);
|
||||||
|
|
||||||
$con->commit();
|
$con->commit();
|
||||||
|
|
||||||
|
echo "Successfully terminated.\n";
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo "error : ".$e->getMessage()."\n";
|
echo "error : ".$e->getMessage()."\n";
|
||||||
$con->rollBack();
|
$con->rollBack();
|
||||||
|
|||||||
@@ -343,6 +343,8 @@ CREATE TABLE `attribute_combination`
|
|||||||
CONSTRAINT `fk_attribute_combination_product_sale_elements_id`
|
CONSTRAINT `fk_attribute_combination_product_sale_elements_id`
|
||||||
FOREIGN KEY (`product_sale_elements_id`)
|
FOREIGN KEY (`product_sale_elements_id`)
|
||||||
REFERENCES `product_sale_elements` (`id`)
|
REFERENCES `product_sale_elements` (`id`)
|
||||||
|
ON UPDATE RESTRICT
|
||||||
|
ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------
|
-- ---------------------------------------------------------------------
|
||||||
@@ -893,9 +895,8 @@ CREATE TABLE `area_delivery_module`
|
|||||||
`created_at` DATETIME,
|
`created_at` DATETIME,
|
||||||
`updated_at` DATETIME,
|
`updated_at` DATETIME,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE INDEX `delivery_module_id_area_id_UNIQUE` (`area_id`, `delivery_module_id`),
|
|
||||||
INDEX `idx_area_delivery_module_area_id` (`area_id`),
|
INDEX `idx_area_delivery_module_area_id` (`area_id`),
|
||||||
INDEX `idx_area_delivery_module_delivery_module_id` (`delivery_module_id`),
|
INDEX `idx_area_delivery_module_delivery_module_id_idx` (`delivery_module_id`),
|
||||||
CONSTRAINT `fk_area_delivery_module_area_id`
|
CONSTRAINT `fk_area_delivery_module_area_id`
|
||||||
FOREIGN KEY (`area_id`)
|
FOREIGN KEY (`area_id`)
|
||||||
REFERENCES `area` (`id`)
|
REFERENCES `area` (`id`)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="general-block-decorator">
|
<div class="general-block-decorator">
|
||||||
|
|
||||||
<table class="table table-striped table-condensed" id="category_list">
|
<table class="table table-striped table-condensed" id="category_list">
|
||||||
<caption>
|
<caption>
|
||||||
{* display parent category name, and get current cat ID *}
|
{* display parent category name, and get current cat ID *}
|
||||||
@@ -171,6 +172,162 @@
|
|||||||
</thead>
|
</thead>
|
||||||
{/elseloop}
|
{/elseloop}
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{* -- PRODUCT MANAGEMENT ---------------------------------------------------- *}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="general-block-decorator">
|
||||||
|
|
||||||
|
<table class="table table-striped table-condensed">
|
||||||
|
<caption>
|
||||||
|
{* display parent category name *}
|
||||||
|
{loop name="category_title" type="category" visible="*" id=$category_id}
|
||||||
|
{intl l="Products in %cat" cat=$TITLE}
|
||||||
|
{/loop}
|
||||||
|
|
||||||
|
{elseloop rel="category_title"}
|
||||||
|
{intl l="Top level Products"}
|
||||||
|
{/elseloop}
|
||||||
|
|
||||||
|
{module_include location='product_list_caption'}
|
||||||
|
|
||||||
|
<a class="btn btn-default btn-primary action-btn" title="{intl l='Add a new product'}" href="#productAddModal" data-toggle="modal">
|
||||||
|
<span class="glyphicon glyphicon-plus-sign"></span>
|
||||||
|
</a>
|
||||||
|
</caption>
|
||||||
|
|
||||||
|
{ifloop rel="product_list"}
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="object-title">
|
||||||
|
{admin_sortable_header
|
||||||
|
current_order=$product_order
|
||||||
|
order='id'
|
||||||
|
reverse_order='id_reverse'
|
||||||
|
path={url path='/admin/categories' id_category=$category_id target='products'}
|
||||||
|
label="{intl l='ID'}"
|
||||||
|
}
|
||||||
|
|
||||||
|
<th> </th>
|
||||||
|
|
||||||
|
<th class="object-title">
|
||||||
|
{admin_sortable_header
|
||||||
|
current_order=$product_order
|
||||||
|
order='ref'
|
||||||
|
reverse_order='ref_reverse'
|
||||||
|
path={url path='/admin/categories' id_category=$category_id target='products'}
|
||||||
|
label="{intl l='Reference'}"
|
||||||
|
}
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th class="object-title">
|
||||||
|
{admin_sortable_header
|
||||||
|
current_order=$product_order
|
||||||
|
order='alpha'
|
||||||
|
reverse_order='alpha_reverse'
|
||||||
|
path={url path='/admin/categories' id_category=$category_id target='products'}
|
||||||
|
label="{intl l='Product title'}"
|
||||||
|
}
|
||||||
|
|
||||||
|
{module_include location='product_list_header'}
|
||||||
|
|
||||||
|
<th>
|
||||||
|
{admin_sortable_header
|
||||||
|
current_order=$product_order
|
||||||
|
order='visible'
|
||||||
|
reverse_order='visible_reverse'
|
||||||
|
path={url path='/admin/categories' id_category=$category_id target='products'}
|
||||||
|
label="{intl l='Online'}"
|
||||||
|
}
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
{admin_sortable_header
|
||||||
|
current_order=$product_order
|
||||||
|
order='manual'
|
||||||
|
reverse_order='manual_reverse'
|
||||||
|
path={url path='/admin/categories' id_category=$category_id target='products'}
|
||||||
|
label="{intl l='Position'}"
|
||||||
|
}
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{loop name="product_list" type="product" visible="*" category_default=$category_id order=$product_order}
|
||||||
|
<tr>
|
||||||
|
<td>{$ID}</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
{loop type="image" name="cat_image" source="product" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"}
|
||||||
|
<a href="{url path='admin/product/edit' id=$ID}" title="{intl l='Edit this product'}">
|
||||||
|
<img src="{$IMAGE_URL}" alt="{$TITLE}" />
|
||||||
|
</a>
|
||||||
|
{/loop}
|
||||||
|
|
||||||
|
<td class="object-title"><a href="{url path="/admin/product/update/$ID"}" title="{intl l='Edit this product'}">{$REF}</a></td>
|
||||||
|
|
||||||
|
<td class="object-title"><a href="{url path="/admin/product/update/$ID"}" title="{intl l='Edit this product'}">{$TITLE}</a></td>
|
||||||
|
|
||||||
|
{module_include location='product_list_row'}
|
||||||
|
|
||||||
|
<td>
|
||||||
|
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.products.edit"}
|
||||||
|
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
|
||||||
|
<input type="checkbox" data-id="{$ID}" class="productVisibleToggle" {if $VISIBLE == 1}checked="checked"{/if}>
|
||||||
|
</div>
|
||||||
|
{/loop}
|
||||||
|
|
||||||
|
{elseloop rel="can_delete"}
|
||||||
|
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok'></i>" data-off-label="<i class='glyphicon glyphicon-remove'></i>">
|
||||||
|
<input type="checkbox" data-id="{$ID}" class="displayToggle" {if $VISIBLE == 1}checked="checked"{/if}>
|
||||||
|
</div>
|
||||||
|
{/elseloop}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
{admin_position_block
|
||||||
|
permission="admin.product.edit"
|
||||||
|
path={url path='admin/product' category_id=$ID}
|
||||||
|
url_parameter="product_id"
|
||||||
|
in_place_edit_class="productPositionChange"
|
||||||
|
position=$POSITION
|
||||||
|
id=$ID
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div class="btn-group">
|
||||||
|
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.product.edit"}
|
||||||
|
<a class="btn btn-default btn-xs" title="{intl l='Edit this product'}" href="{url path="admin/product/update/$ID"}"><i class="glyphicon glyphicon-edit"></i></a>
|
||||||
|
{/loop}
|
||||||
|
|
||||||
|
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.product.delete"}
|
||||||
|
<a class="btn btn-default btn-xs product-delete" title="{intl l='Delete this product'}" href="#product_delete_dialog" data-id="{$ID}" data-toggle="modal"><i class="glyphicon glyphicon-trash"></i></a>
|
||||||
|
{/loop}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/loop}
|
||||||
|
</tbody>
|
||||||
|
{/ifloop}
|
||||||
|
|
||||||
|
{elseloop rel="product_list"}
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td class="message"><div class="alert alert-info">{intl l="This category doesn't contains any products. To add a new product, <strong>click the + button</strong> above."}</div></td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{/elseloop}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -178,6 +335,10 @@
|
|||||||
{module_include location='categories_bottom'}
|
{module_include location='categories_bottom'}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{module_include location='catalog_bottom'}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -251,7 +412,7 @@
|
|||||||
{/form}
|
{/form}
|
||||||
|
|
||||||
|
|
||||||
{* Delete confirmation dialog *}
|
{* Delete category confirmation dialog *}
|
||||||
|
|
||||||
{capture "category_delete_dialog"}
|
{capture "category_delete_dialog"}
|
||||||
<input type="hidden" name="category_id" id="category_delete_id" value="" />
|
<input type="hidden" name="category_id" id="category_delete_id" value="" />
|
||||||
@@ -270,6 +431,26 @@
|
|||||||
form_action = {url path='/admin/categories/delete'}
|
form_action = {url path='/admin/categories/delete'}
|
||||||
form_content = {$smarty.capture.category_delete_dialog nofilter}
|
form_content = {$smarty.capture.category_delete_dialog nofilter}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{* Delete product confirmation dialog *}
|
||||||
|
|
||||||
|
{capture "product_delete_dialog"}
|
||||||
|
<input type="hidden" name="product_id" id="product_delete_id" value="" />
|
||||||
|
|
||||||
|
{module_include location='product_delete_form'}
|
||||||
|
|
||||||
|
{/capture}
|
||||||
|
|
||||||
|
{include
|
||||||
|
file = "includes/generic-confirm-dialog.html"
|
||||||
|
|
||||||
|
dialog_id = "product_delete_dialog"
|
||||||
|
dialog_title = {intl l="Delete product"}
|
||||||
|
dialog_message = {intl l="Do you really want to delete this product ?"}
|
||||||
|
|
||||||
|
form_action = {url path='/admin/products/delete'}
|
||||||
|
form_content = {$smarty.capture.product_delete_dialog nofilter}
|
||||||
|
}
|
||||||
{/block}
|
{/block}
|
||||||
|
|
||||||
{block name="javascript-initialization"}
|
{block name="javascript-initialization"}
|
||||||
@@ -290,6 +471,11 @@
|
|||||||
$('#category_delete_id').val($(this).data('id'));
|
$('#category_delete_id').val($(this).data('id'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set proper product ID in delete from
|
||||||
|
$('a.product-delete').click(function(ev) {
|
||||||
|
$('#product_delete_id').val($(this).data('id'));
|
||||||
|
});
|
||||||
|
|
||||||
// JS stuff for creation form
|
// JS stuff for creation form
|
||||||
{include
|
{include
|
||||||
file = "includes/generic-js-dialog.html"
|
file = "includes/generic-js-dialog.html"
|
||||||
|
|||||||
Reference in New Issue
Block a user