Skip to content

Commit

Permalink
Merge pull request #890 from abhishek-webkul/gli-1652
Browse files Browse the repository at this point in the history
Added: Service products can now be assigned to a room type from room type edit page at back office
  • Loading branch information
rohit053 authored Mar 14, 2024
2 parents 509008b + fdc635b commit 61c1a4c
Show file tree
Hide file tree
Showing 8 changed files with 441 additions and 266 deletions.
121 changes: 89 additions & 32 deletions admin/themes/default/template/controllers/products/serviceproduct.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,134 @@
<input type="hidden" name="submitted_tabs[]" value="ServiceProduct" />
<h3 class="tab"> <i class="icon-AdminAdmin"></i> {l s='Service Products'}</h3>

{if isset($service_products) && $service_products}
{if (isset($associated_service_products) && $associated_service_products) || (isset($unassociated_service_products) && $unassociated_service_products)}
<div class="from-group table-responsive-row clearfix">
<table class="table tableDnD hotel-roomtype-link-table">
<table class="table hotel-roomtype-link-table">
<thead>
<tr class="nodrag nodrop">
<th class="text-center">
<input type="checkbox" class="bulk-service-products-status">
</th>
<th class="col-sm-1">
<span>{l s='Id Product'}</span>
<span>{l s='ID'}</span>
</th>
<th class="col-sm-3">
<span>{l s='name'}</span>
<th class="col-sm-2">
<span>{l s='Name'}</span>
</th>
<th class="">
<span>{l s='Auto add to cart'}</span>
<th class="text-center">
<span>{l s='Auto Add to Cart'}</span>
</th>
<th>
<span>{l s='Position'}</span>
</th>
<th class="">
<th>
<span>{l s='Price'}</span>
</th>
<th class="">
<th>
<span>{l s='Tax'}</span>
</th>
<th class="text-right">
<span>{l s='Action'}</span>
</th>
</tr>
</thead>
<tbody>
{foreach from=$service_products key=key item=service_product}
<tr id='room_type_service_product_{$service_product.id_room_type_service_product|escape:'html':'UTF-8'}' position='{$service_product.position|escape:'html':'UTF-8'}' id_product='{$service_product.id_product|escape:'html':'UTF-8'}' id_element="{$product->id}" data-roomtype_url="{$link->getAdminLink('AdminProducts', true)|addslashes}">
<td class="col-sm-1">{$service_product.id_product|escape:'html':'UTF-8'} <a target="blank" href="{$link->getAdminLink('AdminNormalProducts')|escape:'html':'UTF-8'}&amp;id_product={$service_product.id_product|escape:'html':'UTF-8'}&amp;updateproduct"><i class="icon-external-link-sign"></i></a></td>
{foreach from=$associated_service_products item=service_product}
<tr id='room_type_service_product_{$service_product.id_product|escape:'html':'UTF-8'}' position="{$service_product.association_info.position|escape:'html':'UTF-8'}" id_product='{$service_product.id_product|escape:'html':'UTF-8'}' id_element="{$product->id}" data-roomtype_url="{$link->getAdminLink('AdminProducts', true)|addslashes}">
{assign var=inputs_prefix value="service_product_`$service_product.id_product`_"}
<input type="hidden" name="available_service_products[]" value="{$service_product.id_product}">

<td class="text-center">
<input type="checkbox" name="{$inputs_prefix}associated" class="is-associated" checked>
</td>
<td class="col-sm-1">
{$service_product.id_product|escape:'html':'UTF-8'}
<a target="blank" href="{$link->getAdminLink('AdminNormalProducts')|escape:'html':'UTF-8'}&amp;id_product={$service_product.id_product|escape:'html':'UTF-8'}&amp;updateproduct">
<i class="icon-external-link-sign"></i>
</a>
</td>
<td>{$service_product.name}</td>
<td><span {if $service_product.auto_add_to_cart}class="badge badge-success"{/if}>{if $service_product.auto_add_to_cart}{l s='Yes'}{else}{l s='No'}{/if}</span></td>
<td class="text-center">
<span {if $service_product.auto_add_to_cart}class="badge badge-success"{/if}>
{if $service_product.auto_add_to_cart}{l s='Yes'}{else}{l s='No'}{/if}
</span>
</td>
<td class="pointer dragHandle center positionImage">
<div class="dragGroup">
<div class="positions">
{$service_product.position + 1}
{$service_product.association_info.position + 1}
</div>
</div>
</td>
<td>
<span class="field-view service-product-price-text">{if isset($service_product.custom_price) && $service_product.custom_price}{displayPrice price=$service_product.custom_price currency=$currency->id}{else}{displayPrice price=$service_product.default_price currency=$currency->id}{/if}</span>
<div class="field-edit" style="display:none">
<div class="fixed-width-xl">
<div class="input-group">
<input type="text" value="{if isset($service_product.custom_price) && $service_product.custom_price}{$service_product.custom_price|escape:'html':'UTF-8'}{else}{$service_product.default_price|escape:'html':'UTF-8'}{/if}" class="service-product-price" data-id_product="{$service_product.id_product|escape:'html':'UTF-8'}">
<span class="input-group-addon">{$currency->prefix}{$currency->suffix}</span>
{assign var=price_value value=0}
{if isset($smarty.post["{$inputs_prefix}price"])}
{assign var=price_value value=$smarty.post["{$inputs_prefix}price"]}
{else}
{if isset($service_product.association_info.custom_price)}
{assign var=price_value value=$service_product.association_info.custom_price}
{elseif isset($service_product.association_info.default_price)}
{assign var=price_value value=$service_product.association_info.default_price}
{/if}
{/if}
<input type="text" name="{$inputs_prefix}price" value="{$price_value}" data-id_product="{$service_product.id_product}">
</div>
</div>
<div class="help-block">{l s='Default price: %s' sprintf={displayPrice price=$service_product.default_price currency=$currency->id}}
<div class="help-block">
{l s='Default price: %s' sprintf={displayPrice price=$service_product.association_info.default_price currency=$currency->id}}
</div>
</td>
<td>
<span class="field-view service_product_tax_text">{if isset($service_product.tax_rules_group_name) && $service_product.tax_rules_group_name}{$service_product.tax_rules_group_name}{else}{$service_product.default_tax_rules_group_name}{/if}</span>
<div class="field-edit" style="display:none">
<select class="service_product_id_tax_rules_group">
<div class="fixed-width-xl">
<select class="service_product_id_tax_rules_group" name="{$inputs_prefix}id_tax_rules_group">
<option value="0">{l s='No Tax'}</option>
{foreach from=$tax_rules_groups item=tax_rules_group}
<option value="{$tax_rules_group.id_tax_rules_group}" {if $service_product.id_tax_rules_group == $tax_rules_group.id_tax_rules_group}selected="selected"{/if} >
<option value="{$tax_rules_group.id_tax_rules_group}" {if $service_product.association_info.id_tax_rules_group == $tax_rules_group.id_tax_rules_group}selected="selected"{/if} >
{$tax_rules_group['name']|htmlentitiesUTF8}
</option>
{/foreach}
</select>
</div>
<div class="help-block">{l s='Default tax rule: %s' sprintf=$service_product.default_tax_rules_group_name}
<div class="help-block">{l s='Default tax rule: %s' sprintf=$service_product.association_info.default_tax_rules_group_name}</div>
</td>
<td class="text-right">
<a href="#" class="btn btn-default button-edit-price field-view"><i class="icon-pencil"></i></a>
<span class="field-edit" style="display:none">
<a href="#" class="btn btn-default btn-save" data-roomtype_url="{$link->getAdminLink('AdminProducts', true)|addslashes}" data-id_product="{$service_product.id_product|escape:'html':'UTF-8'}"><i class="icon-save"></i> {l s='save'}</a>
<a href="#" class="btn btn-default btn-cancel"><i class="icon-times"></i></a>
</span>
</tr>
{/foreach}

{foreach from=$unassociated_service_products item=service_product}
<tr class="nodrop nodrag">
{assign var=inputs_prefix value="service_product_`$service_product.id_product`_"}
<input type="hidden" name="available_service_products[]" value="{$service_product.id_product}">

<td class="text-center">
<input type="checkbox" name="{$inputs_prefix}associated" class="is-associated" {if isset($smarty.post["{$inputs_prefix}associated"]) && in_array($smarty.post["{$inputs_prefix}associated"], array('on', 'true', '1'))}checked{/if}>
</td>
<td class="col-sm-1">{$service_product.id_product|escape:'html':'UTF-8'} <a target="blank" href="{$link->getAdminLink('AdminNormalProducts')|escape:'html':'UTF-8'}&amp;id_product={$service_product.id_product|escape:'html':'UTF-8'}&amp;updateproduct"><i class="icon-external-link-sign"></i></a></td>
<td>{$service_product.name}</td>
<td class="text-center"><span {if $service_product.auto_add_to_cart}class="badge badge-success"{/if}>{if $service_product.auto_add_to_cart}{l s='Yes'}{else}{l s='No'}{/if}</span></td>
<td>{l s='--'}</td>
<td>
<div class="fixed-width-xl">
<div class="input-group">
<span class="input-group-addon">{$currency->prefix}{$currency->suffix}</span>
<input type="text" name="{$inputs_prefix}price" data-id_product="{$service_product.id_product|escape:'html':'UTF-8'}" value="{if isset($smarty.post["{$inputs_prefix}price"]) && $smarty.post["{$inputs_prefix}price"]}{$smarty.post["{$inputs_prefix}price"]}{else}{$service_product.price}{/if}">
</div>
</div>
<div class="help-block">
{l s='Default price: %s' sprintf={displayPrice price=$service_product.price currency=$currency->id}}
</div>
</td>
<td>
<div class="fixed-width-xl">
<select class="service_product_id_tax_rules_group" name="{$inputs_prefix}id_tax_rules_group">
<option value="0">{l s='No Tax'}</option>
{foreach from=$tax_rules_groups item=tax_rules_group}
<option value="{$tax_rules_group.id_tax_rules_group}" {if isset($smarty.post["{$inputs_prefix}id_tax_rules_group"])}{if $tax_rules_group.id_tax_rules_group == $smarty.post["{$inputs_prefix}id_tax_rules_group"]}{/if}{elseif $tax_rules_group.id_tax_rules_group == $service_product.id_tax_rules_group}selected{/if}>
{$tax_rules_group['name']|htmlentitiesUTF8}
</option>
{/foreach}
</select>
</div>
<div class="help-block">{l s='Default tax rule: %s' sprintf=$service_product.tax_rules_group_name}</div>
</td>
</tr>
{/foreach}
Expand Down
32 changes: 17 additions & 15 deletions classes/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -1454,23 +1454,25 @@ public function getAvailableServiceProductsCategories($id_lang, $front = false,
return $result;
}

public function getServiceProducts($idLang, $front = false, $context = false)
public function getServiceProducts($active = null, $serviceProductType = null, $idLang = null, $orderBy = 'pl.name', $orderWay = 'ASC')
{
if (!$context) {
$context = Context::getContext();
if (!$idLang) {
$idLang = Context::getContext()->language->id;
}
$sql = 'SELECT p.*, product_shop.*, pl.*, image_shop.`id_image` id_image, il.`legend` as legend
FROM `'._DB_PREFIX_.'product` p
'.Shop::addSqlAssociation('product', 'p').'
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` '.Shop::addSqlRestrictionOnLang('pl').')
LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop
ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context->shop->id.')
LEFT JOIN `'._DB_PREFIX_.'image_lang` il
ON (image_shop.`id_image` = il.`id_image`
AND il.`id_lang` = '.(int)$idLang.')';
$sql .= 'WHERE pl.`id_lang` = '.(int)$idLang.' AND p.`booking_product` = 0
AND p.`service_product_type` = '.Product::SERVICE_PRODUCT_WITHOUT_ROOMTYPE.'
ORDER BY pl.`name`';

$sql = 'SELECT p.*, pl.*, i.`id_image`, il.`legend` AS legend
FROM `'._DB_PREFIX_.'product` p
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (pl.`id_product` = p.`id_product` AND pl.`id_lang` = '.(int) $idLang.')
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (il.`id_image` = i.`id_image` AND il.`id_lang` = '.(int) $idLang.')
WHERE p.`booking_product` = 0'.
(!is_null($active) ? ' AND p.`active` = '.(int) $active : '').
($serviceProductType ? ' AND p.`service_product_type` = '.(int) $serviceProductType : '');

if (Validate::isOrderBy($orderBy) && Validate::isOrderBy($orderWay)) {
$sql .= ' ORDER BY '.$orderBy.' '.$orderWay;
}

return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
}

Expand Down
47 changes: 41 additions & 6 deletions controllers/admin/AdminNormalProductsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2791,18 +2791,53 @@ public function getPreviewUrl(Product $product)
public function updateLinkedHotelsAndRooms($product)
{
if (Validate::isLoadedObject($product)) {
RoomTypeServiceProduct::deleteRoomProductLink($product->id);

$objRoomTypeServiceProduct = new RoomTypeServiceProduct();
$associatedRoomTypes = $objRoomTypeServiceProduct->getAssociatedHotelsAndRoomType($product->id)['room_types'];
if (Product::SERVICE_PRODUCT_WITH_ROOMTYPE == $product->service_product_type) {
$objRoomTypeServiceProduct = new RoomTypeServiceProduct();
// add product link for room types
if ($selectedRoomTypes = Tools::getValue('roomTypeBox')) {
$selectedRoomTypes = Tools::getValue('roomTypeBox');

// Generate list of new associations
$newRoomTypes = array();
foreach ($selectedRoomTypes as $selectedRoomType) {
if (!in_array($selectedRoomType, $associatedRoomTypes)) {
$newRoomTypes[] = $selectedRoomType;
}
}

// Generate list of associations to remove
$removedRoomTypes = array();
foreach ($associatedRoomTypes as $associatedRoomType) {
if (!in_array($associatedRoomType, $selectedRoomTypes)) {
$removedRoomTypes[] = $associatedRoomType;
}
}

// Remove associations
foreach ($removedRoomTypes as $removedRoomType) {
RoomTypeServiceProduct::deleteRoomProductLink(
$product->id,
RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE,
$removedRoomType
);
}

// Save new associations
if ($newRoomTypes) {
$objRoomTypeServiceProduct->addRoomProductLink(
$product->id,
$selectedRoomTypes,
$newRoomTypes,
RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE
);
}
} else {
// Remove associations
foreach ($associatedRoomTypes as $associatedRoomType) {
RoomTypeServiceProduct::deleteRoomProductLink(
$product->id,
RoomTypeServiceProduct::WK_ELEMENT_TYPE_ROOM_TYPE,
$associatedRoomType
);
}
}
}
}
Expand Down
Loading

0 comments on commit 61c1a4c

Please sign in to comment.