// Product Warehouse location : Manage multiple warehouses and location associated for a product / product attribute

git-svn-id: http://dev.prestashop.com/svn/v1/branches/1.5.x@10375 b9a71923-0436-4b27-9f14-aed3839534dd
This commit is contained in:
dSevere
2011-11-21 18:43:04 +00:00
parent de6d9c7bbe
commit a9b5f70767
10 changed files with 263 additions and 70 deletions
@@ -100,8 +100,6 @@
{l s='EAN13:'}<input size="55" maxlength="13" type="text" id="attribute_ean13" name="attribute_ean13" value="" style="width: 110px; margin-left: 10px; margin-right: 44px;" />
{l s='UPC:'}<input size="55" maxlength="12" type="text" id="attribute_upc" name="attribute_upc" value="" style="width: 110px; margin-left: 10px; margin-right: 44px;" />
<span class="hint" name="help_box">{l s='Special characters allowed:'} .-_#<span class="hint-pointer">&nbsp;</span></span>
{l s='Location:'}<input size="55" type="text" id="attribute_location" name="attribute_location" value="" style="width: 101px; margin-left: 10px;" />
<span class="hint" name="help_box">{l s='Special characters allowed:'} .-_#<span class="hint-pointer">&nbsp;</span></span>
</td>
</tr>
@@ -126,12 +126,6 @@
<input size="55" maxlength="12" type="text" name="upc" value="{$product->upc}" style="width: 130px; margin-right: 5px;" /> <span class="small">{l s='(US, Canada)'}</span>
</td>
</tr>
<tr>
<td class="col-left"><label>{l s='Location (warehouse):' }</label></td>
<td style="padding-bottom:5px;">
<input size="55" type="text" name="location" value="{$product->location|htmlentitiesUTF8}" style="width: 130px; margin-right: 44px;" />
</td>
</tr>
</table>
{* status informations *}
<table cellpadding="5" style="width: 40%; float: left; margin-left: 10px;">
@@ -39,6 +39,7 @@
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<div class="margin-form">
<input type="submit" class="button" name="submitSuppliers" value="{l s='Update suppliers of this product'}"/>
</div>
@@ -54,42 +55,48 @@
</table>
<div class="separation"></div>
<p>{l s='You can specify product reference(s) for each supplier associated.'}</p>
<table cellpadding="5" style="width:100%">
<tbody>
<tr>
<td valign="top" style="text-align:center;vertical-align:top;">
<table class="table" cellpadding="0" cellspacing="0" style="min-width:80%;margin-left:10%;">
<thead>
<tr>
<th>{l s='Product Name'}</th>
{foreach from=$associated_suppliers item=supplier}
<th>{$supplier->name}</th>
{/foreach}
</tr>
</thead>
<tbody>
{foreach from=$attributes item=attribute}
<tr>
<td>{$product_designation[$attribute['id_product_attribute']]}</td>
{foreach from=$associated_suppliers item=supplier}
{assign var=reference value=''}
{foreach from=$associated_suppliers_collection item=asc}
{if $asc->id_product == $attribute['id_product'] && $asc->id_product_attribute == $attribute['id_product_attribute'] && $asc->id_supplier == $supplier->id_supplier}
{assign var=reference value=$asc->product_supplier_reference}
{/if}
{/foreach}
<td>
<input type="text" size="10" value="{$reference}" name="supplier_reference_{$attribute['id_product']}_{$attribute['id_product_attribute']}_{$supplier->id_supplier}" />
</td>
{/foreach}
</tr>
<div id="accordion" style="margin-top:10px; display:block;">
{foreach from=$associated_suppliers item=supplier}
<h3 style="margin-bottom:0;"><a href="#">{$supplier->name}</a></h3>
<div style="display:block;">
<table cellpadding="5" cellspacing="5" style="width:80%; margin-left:0;">
<thead>
<tr>
<th>{l s='product name'}</th>
<th width="150">{l s='supplier reference'}</th>
</tr>
</thead>
<tbody>
{foreach from=$attributes item=attribute}
{assign var=reference value=''}
{foreach from=$associated_suppliers_collection item=asc}
{if $asc->id_product == $attribute['id_product'] && $asc->id_product_attribute == $attribute['id_product_attribute'] && $asc->id_supplier == $supplier->id_supplier}
{assign var=reference value=$asc->product_supplier_reference}
{/if}
{/foreach}
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<tr>
<td>{$product_designation[$attribute['id_product_attribute']]}</td>
<td>
<input type="text" size="10" value="{$reference}" name="supplier_reference_{$attribute['id_product']}_{$attribute['id_product_attribute']}_{$supplier->id_supplier}" />
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
{/foreach}
</div>
<p>&nbsp;</p>
<div class="margin-form">
<input type="submit" class="button" name="submitSupplierReferences" value="{l s='Update supplier reference(s)'}"/>
</div>
<script type="text/javascript">
$(function() {
window.setTimeout(function() {
$('#accordion').accordion();
}, 500);
});
</script>
@@ -0,0 +1,69 @@
<table cellpadding="5">
<tbody>
<tr>
<td colspan="2">
<b>{l s='Product location in warehouses'}</b>
</td>
</tr>
</tbody>
</table>
<div class="separation"></div>
<p>{l s='Please choose the warehouses associated to this product, and the default one.'}</p>
{assign var=confirm value="Are you sure you want to delete entered product information?"}
<a href="{$link->getAdminLink('AdminWarehouses')}&addwarehouse" onclick="return confirm(' {$confirm} ')">
<img src="../img/admin/add.gif" alt="{l s='Create new warehouse'}" title="{l s='Create new warehouse'}" /> <b>{l s='Create new warehouse'}</b>
</a>
<div id="accordion" style="margin-top:10px; display:block;">
{foreach from=$warehouses item=warehouse}
<h3 style="margin-bottom:0;"><a href="#">{$warehouse['name']}</a></h3>
<div style="display:block;">
<table cellpadding="5" cellspacing="5" style="width:80%; margin-left:0;">
<tr>
<th width="40">{l s='In the warehouse?'}</th>
<th>{l s='product name'}</th>
<th width="150">{l s='location in the warehouse (optionnal)'}</th>
</tr>
{foreach from=$attributes item=attribute}
{assign var=location value=''}
{assign var=selected value=''}
{foreach from=$associated_warehouses item=aw}
{if $aw->id_product == $attribute['id_product'] && $aw->id_product_attribute == $attribute['id_product_attribute'] && $aw->id_warehouse == $warehouse['id_warehouse']}
{assign var=location value=$aw->location}
{assign var=selected value=true}
{/if}
{/foreach}
<tr>
<td><input type="checkbox"
name="check_warehouse_{$warehouse['id_warehouse']}_{$attribute['id_product']}_{$attribute['id_product_attribute']}"
{if $selected == true}checked="checked"{/if}
value="1" />
</td>
<td>{$product_designation[$attribute['id_product_attribute']]}</td>
<td><input type="text"
name="location_warehouse_{$warehouse['id_warehouse']}_{$attribute['id_product']}_{$attribute['id_product_attribute']}"
value="{$location}"
size="20" />
</td>
</tr>
{/foreach}
</table>
</div>
{/foreach}
</div>
<p>&nbsp;</p>
<div class="margin-form">
<input type="submit" class="button" name="submitProductWarehouses" value="{l s='Update warehouses locations'}"/>
</div>
<script type="text/javascript">
$(function() {
window.setTimeout(function() {
$('#accordion').accordion();
}, 500);
});
</script>
+135 -9
View File
@@ -45,6 +45,7 @@ class AdminProductsControllerCore extends AdminController
'Attachments',
'Quantities',
'Suppliers',
'Warehouses',
'Accounting');
public function __construct()
@@ -912,7 +913,9 @@ class AdminProductsControllerCore extends AdminController
//Manage suppliers
else if (Tools::isSubmit('submitSupplierReferences'))
$this->postProcessFormSupplierReferences();
//Manage warehouses
else if (Tools::isSubmit('submitProductWarehouses'))
$this->postProcessFormWarehouses();
parent::postProcess(true);
}
@@ -1783,6 +1786,7 @@ class AdminProductsControllerCore extends AdminController
$this->addJs(_PS_JS_DIR_.'attributesBack.js');
$this->display = 'edit';
$this->addJqueryUI('ui.datepicker');
$this->addJqueryUI('ui.accordion');
$this->tpl_form_vars['pos_select'] = ($tab = Tools::getValue('tabs')) ? $tab : '0';
$this->tpl_form_vars['token'] = $this->token;
$this->tpl_form_vars['combinationImagesJs'] = $this->getCombinationImagesJs();
@@ -1983,7 +1987,7 @@ class AdminProductsControllerCore extends AdminController
if ($reference != $psc->product_supplier_reference)
{
$psc->product_supplier_reference = pSQL($reference);
$psc->save();
$psc->update();
}
break;
}
@@ -1995,6 +1999,88 @@ class AdminProductsControllerCore extends AdminController
}
}
/**
* Post traitment for warehouses
*/
public function postProcessFormWarehouses()
{
if (Validate::isLoadedObject($product = new Product((int)Tools::getValue('id_product'))))
{
// Get all id_product_attribute
$attributes = $product->getAttributesResume($this->context->language->id);
if (empty($attributes))
$attributes[] = array(
'id_product_attribute' => 0,
'attribute_designation' => ''
);
// Get all available warehouses
$warehouses = Warehouse::getWarehouses(true);
// Get already associated warehouses
$associated_warehouses_collection = WarehouseProductLocation::getCollection($product->id);
$elements_to_manage = array();
// get form inforamtion
foreach ($attributes as $attribute)
{
foreach ($warehouses as $warehouse)
{
$key = $warehouse['id_warehouse'].'_'.$attribute['id_product'].'_'.$attribute['id_product_attribute'];
// get elements to manage
if (Tools::isSubmit('check_warehouse_'.$key))
{
$location = Tools::getValue('location_warehouse_'.$key, '');
$elements_to_manage[$key] = $location;
}
}
}
// Delete entry if necessary
foreach ($associated_warehouses_collection as $awc)
{
if (!array_key_exists($awc->id_warehouse.'_'.$awc->id_product.'_'.$awc->id_product_attribute, $elements_to_manage))
$awc->delete();
}
// Manage locations
foreach ($elements_to_manage as $key => $location)
{
$params = explode('_', $key);
$wpl_id = WarehouseProductLocation::getIdByProductAndWarehouse($params[1], $params[2], $params[0]);
if (empty($wpl_id))
{
//create new record
$warehouse_location_entity = new WarehouseProductLocation();
$warehouse_location_entity->id_product = $params[1];
$warehouse_location_entity->id_product_attribute = $params[2];
$warehouse_location_entity->id_warehouse = $params[0];
$warehouse_location_entity->location = pSQL($location);
$warehouse_location_entity->save();
}
else
{
$warehouse_location_entity = new WarehouseProductLocation($wpl_id);
$location = pSQL($location);
if ($location != $warehouse_location_entity->location)
{
$warehouse_location_entity->location = pSQL($location);
$warehouse_location_entity->update();
}
break;
}
}
$this->confirmations[] = $this->l('Warehouses and location(s) of the product have been updated');
}
}
/**
* Init data for accounting
*/
@@ -2476,11 +2562,11 @@ class AdminProductsControllerCore extends AdminController
// @todo : uses the helperform
$data->assign('displayAssoShop', $this->displayAssoShop());
$data->assign('carrier_list', $this->getCarrierList());
$product_props = array();
// global informations
array_push($product_props, 'reference', 'ean13', 'upc', 'location',
array_push($product_props, 'reference', 'ean13', 'upc',
'available_for_order', 'show_price', 'online_only',
'id_manufacturer'
);
@@ -2756,7 +2842,7 @@ class AdminProductsControllerCore extends AdminController
$this->tpl_form_vars['product'] = $product;
$this->tpl_form_vars['custom_form'] = $this->context->smarty->createTemplate($this->tpl_form, $data)->fetch();
}
protected function getCarrierList()
{
$carrier_list = Carrier::getCarriers($this->context->language->id);
@@ -2773,7 +2859,7 @@ class AdminProductsControllerCore extends AdminController
}
return $carrier_list;
}
protected function addCarriers()
{
if (Tools::getValue('carriers'))
@@ -2785,7 +2871,7 @@ class AdminProductsControllerCore extends AdminController
}
}
}
public function initFormImages($obj, $token = null)
{
$this->addJs('admin-dnd');
@@ -2931,7 +3017,6 @@ class AdminProductsControllerCore extends AdminController
$combArray[$combinaison['id_product_attribute']]['upc'] = $combinaison['upc'];
$combArray[$combinaison['id_product_attribute']]['minimal_quantity'] = $combinaison['minimal_quantity'];
$combArray[$combinaison['id_product_attribute']]['available_date'] = strftime($combinaison['available_date']);
$combArray[$combinaison['id_product_attribute']]['location'] = $combinaison['location'];
$combArray[$combinaison['id_product_attribute']]['id_image'] = isset($combinationImages[$combinaison['id_product_attribute']][0]['id_image']) ? $combinationImages[$combinaison['id_product_attribute']][0]['id_image'] : 0;
$combArray[$combinaison['id_product_attribute']]['default_on'] = $combinaison['default_on'];
$combArray[$combinaison['id_product_attribute']]['ecotax'] = $combinaison['ecotax'];
@@ -3003,7 +3088,7 @@ class AdminProductsControllerCore extends AdminController
<a style="cursor: pointer;">
<img src="../img/admin/edit.gif" alt="'.$this->l('Modify this combination').'"
onclick="javascript:fillCombinaison(\''.$product_attribute['wholesale_price'].'\', \''.$product_attribute['price'].'\', \''.$product_attribute['weight'].'\', \''.$product_attribute['unit_impact'].'\', \''.$product_attribute['reference'].'\', \''.$product_attribute['ean13'].'\',
\'0\', \''.($attrImage ? $attrImage->id : 0).'\', Array('.$jsList.'), \''.$id_product_attribute.'\', \''.$product_attribute['default_on'].'\', \''.$product_attribute['ecotax'].'\', \''.$product_attribute['location'].'\', \''.$product_attribute['upc'].'\', \''.$product_attribute['minimal_quantity'].'\', \''.$available_date.'\',
\'0\', \''.($attrImage ? $attrImage->id : 0).'\', Array('.$jsList.'), \''.$id_product_attribute.'\', \''.$product_attribute['default_on'].'\', \''.$product_attribute['ecotax'].'\', \''.$product_attribute['upc'].'\', \''.$product_attribute['minimal_quantity'].'\', \''.$available_date.'\',
\''.$product->productDownload->display_filename.'\', \''.$filename.'\', \''.$product->productDownload->nb_downloadable.'\', \''.$available_date_attribute.'\', \''.$product->productDownload->nb_days_accessible.'\', \''.$product->productDownload->is_shareable.'\'); calcImpactPriceTI();" /></a>&nbsp;
'.(!$product_attribute['default_on'] ? '<a href="'.self::$currentIndex.'&defaultProductAttribute&id_product_attribute='.$id_product_attribute.'&id_product='.$product->id.'&'.(Tools::isSubmit('id_category') ? 'id_category='.(int)(Tools::getValue('id_category')).'&' : '&').'token='.Tools::getAdminToken('AdminProducts'.(int)(Tab::getIdFromClassName('AdminProducts')).$this->context->employee->id).'">
<img src="../img/admin/asterisk.gif" alt="'.$this->l('Make this the default combination').'" title="'.$this->l('Make this combination the default one').'"></a>' : '').'
@@ -3172,6 +3257,47 @@ class AdminProductsControllerCore extends AdminController
$this->tpl_form_vars['custom_form'] = $this->context->smarty->createTemplate($this->tpl_form, $data)->fetch();
}
public function initFormWarehouses($obj)
{
$data = $this->context->smarty->createData();
if ($this->object->id)
{
// Get all id_product_attribute
$attributes = $obj->getAttributesResume($this->context->language->id);
if (empty($attributes))
$attributes[] = array(
'id_product_attribute' => 0,
'attribute_designation' => ''
);
$product_designation = array();
foreach ($attributes as $attribute)
$product_designation[$attribute['id_product_attribute']] = rtrim($obj->name[$this->context->language->id].' - '.$attribute['attribute_designation'], ' - ');
// Get all available warehouses
$warehouses = Warehouse::getWarehouses(true);
// Get already associated warehouses
$associated_warehouses_collection = WarehouseProductLocation::getCollection($this->object->id);
$data->assign(array(
'attributes' => $attributes,
'warehouses' => $warehouses,
'associated_warehouses' => $associated_warehouses_collection,
'product_designation' => $product_designation,
'product' => $this->object,
'link' => $this->context->link,
'token' => $this->token
));
}
else
$data->assign('content', '<b>'.$this->l('You must save this product before manage warehouses').'.</b>');
$this->tpl_form_vars['custom_form'] = $this->context->smarty->createTemplate($this->tpl_form, $data)->fetch();
}
public function initFormFeatures($obj)
{
if (!Feature::isFeatureActive())
@@ -280,7 +280,7 @@ class AdminStockMvtControllerCore extends AdminController
),
'reason' => array(
'title' => $this->l('Reason'),
'width' => 250,
'width' => 100,
'havingFilter' => true
),
'employee' => array(
@@ -518,22 +518,22 @@ class AdminSupplyOrdersControllerCore extends AdminController
$this->fieldsDisplay = array(
'reference' => array(
'title' => $this->l('Order Reference'),
'width' => 120,
'width' => 100,
'havingFilter' => true
),
'supplier' => array(
'title' => $this->l('Supplier'),
'width' => 200,
'width' => 100,
'filter_key' => 's!name'
),
'warehouse' => array(
'title' => $this->l('Warehouse'),
'width' => 200,
'width' => 100,
'filter_key' => 'w!name'
),
'state' => array(
'title' => $this->l('State'),
'width' => 250,
'width' => 200,
'filter_key' => 'stl!name',
'color' => 'color',
),
@@ -204,8 +204,8 @@ class AdminWarehousesControllerCore extends AdminController
'type' => 'text',
'label' => $this->l('City:'),
'name' => 'city',
'size' => 10,
'maxlength' => 12,
'size' => 20,
'maxlength' => 32,
'required' => true,
),
array(
+8 -9
View File
@@ -2067,14 +2067,13 @@ CREATE TABLE `PREFIX_warehouse` (
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_warehouse_product_location` (
`id_product` INT(11) UNSIGNED NOT NULL,
`id_product_attribute` INT(11) UNSIGNED NOT NULL,
`id_warehouse` INT(11) UNSIGNED NOT NULL,
`location` VARCHAR(64) DEFAULT NULL,
PRIMARY KEY (`id_product`, `id_product_attribute`, `id_warehouse`),
KEY `id_warehouse` (`id_warehouse`),
KEY `id_product` (`id_product`),
KEY `id_product_attribute` (`id_product_attribute`)
`id_warehouse_product_location` int(11) unsigned NOT NULL AUTO_INCREMENT,
`id_product` int(11) unsigned NOT NULL,
`id_product_attribute` int(11) unsigned NOT NULL,
`id_warehouse` int(11) unsigned NOT NULL,
`location` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id_warehouse_product_location`),
UNIQUE KEY `id_product` (`id_product`,`id_product_attribute`,`id_warehouse`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
CREATE TABLE `PREFIX_warehouse_shop` (
@@ -2245,4 +2244,4 @@ CREATE TABLE `PREFIX_accounting_product_zone_shop` (
`account_number` varchar(64) NOT NULL,
PRIMARY KEY (`id_accounting_product_zone_shop`),
UNIQUE KEY `id_product` (`id_product`,`id_shop`,`id_zone`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8;
+2 -2
View File
@@ -27,7 +27,7 @@
var storeUsedGroups = {};
function fillCombinaison(wholesale_price, price_impact, weight_impact, unit_impact, reference,
ean, quantity, image, old_attr, id_product_attribute, default_attribute, eco_tax, location, upc, minimal_quantity, available_date,
ean, quantity, image, old_attr, id_product_attribute, default_attribute, eco_tax, upc, minimal_quantity, available_date,
virtual_product_name_attribute, virtual_product_filename_attribute, virtual_product_nb_downloable, virtual_product_expiration_date_attribute,
virtual_product_nb_days, is_shareable)
{
@@ -59,7 +59,7 @@ virtual_product_nb_days, is_shareable)
getE('attribute_unity').value = Math.abs(unit_impact);
if ($('#attribute_ecotax').length != 0)
getE('attribute_ecotax').value = eco_tax;
getE('attribute_location').value = location;
if (default_attribute == 1)
getE('attribute_default').checked = true;
else