Hola, buenas a todos los del foro.
He visto que mucha gente, incluyendo yo mismo, necesitaba la funcionalidad de poder definir articulos que ya implican que al añadirlos al carrito los gastos de envio se convierten en gratuitos.
Pues llevo un par de dias intentando ver como hacerlo y creo que al final lo he conseguido, pero antes unas notas:
- Mi campo de accion es Oracle y PL/sql
- Solo he tocado mysql porque lo necesitaba para montar mi tienda y lo mismo se puede aplicar a smarty y php
- La documentacion del prestashop en cuanto a programacion es bastante escasa.
-
Y lo mas importante, al dar de alta o modificar un nuevo articulo desde el Back Office no es posible indicar si queremos ponerlo con envio gratis. ¿entonces como ponemos a un articulo que tenga envio gratis? pues ahora mismo solo se puede hacer desde Mysql. Yo es que no doy de alta los articulos desde el Back Office sino desde una base de datos que tengo en Oracle donde esta toda la informacion de cada producto. Si alguien se curra esto (y pienso en el maquina de Hans) ya creo q quedaria del todo terminado a la espera de que en Prestashop dejen esta funcionalidad a 'lo bonico'. Seguro que alguien que sepa de php lo puede hacer en un momento.
- He estado haciendo pruebas en mi pagina de pruebas y parece que todo funciona bien , ya esta puesta en produccion, podias ver un ejemplo de como queda en los productos de PHD(
http://laproteina.es/tienda/46_phd)
De todas maneras si alguien utiliza estos cambios agradeceria que me comentara que tal le va y si ha detectado algun error(en principio parece que no los tiene, salen bien los carritos, los albaranes, las facturas etc)
Bueno, os comento lo que he hecho
1º Añadir un campo en la tabla products que se llama envio_gratis , es un campo tinyint(1)
unsigned que puede ser nulo pero con valor por defecto 0. Si el valor se asigna a 1 este producto implicara los gastos de envio gratis.
2º Modificaciones en las clases(carpeta classes):
Product.php , añadir despues de
Código:
/*** @var array Tags */
public $tags;
esto otro
Código:
//para los articulos con envio gratuito
/** @var boolean Product statuts */
public $envio_gratis = 0;
y despues de
Código:
$fields['date_upd'] = pSQL($this->date_upd);
añadir este otro codigo
Código:
$fields['envio_gratis'] = pSQL($this->envio_gratis);
El cambio de este archivo creo que no es necesario tal y como lo tengo yo pero si creo que lo sera para poder modificar esta funcionalidad desde el Back Office
Y tambien
modificar la clase Cart.php , para ser mas precisos dentro de la funcion getOrderShippingCost
Os dejo el trozo que estaba antes
Código:
function getOrderShippingCost($id_carrier = NULL, $useTax = true)
{
global $defaultCountry;
if ($this->isVirtualCart())
return 0;
// Checking discounts in cart
$products = $this->getProducts();
$discounts = $this->getDiscounts(true);
if ($discounts)
foreach ($discounts AS $id_discount)
{
$discount = new Discount(intval($id_discount['id_discount']));
if (!Validate::isLoadedObject($discount))
die(Tools::displayError());
if ($discount->id_discount_type == 3)
{
$total_cart = 0;
$categories = Discount::getCategories($discount->id);
foreach($products AS $product)
{
if(count($categories))
if (Product::idIsOnCategoryId($product['id_product'], $categories))
$total_cart += $product['total_wt'];
}
if ($total_cart >= $discount->minimal)
return 0;
}
}
y el que debeis dejar
Código:
function getOrderShippingCost($id_carrier = NULL, $useTax = true)
{
global $defaultCountry;
if ($this->isVirtualCart())
return 0;
// Checking discounts in cart
$products = $this->getProducts();
$discounts = $this->getDiscounts(true);
if ($discounts)
foreach ($discounts AS $id_discount)
{
$discount = new Discount(intval($id_discount['id_discount']));
if (!Validate::isLoadedObject($discount))
die(Tools::displayError());
if ($discount->id_discount_type == 3)
{
$total_cart = 0;
$categories = Discount::getCategories($discount->id);
foreach($products AS $product)
{
if(count($categories))
if (Product::idIsOnCategoryId($product['id_product'], $categories))
$total_cart += $product['total_wt'];
}
if ($total_cart >= $discount->minimal)
return 0;
}
}
// Inicio modificacion
//Si hay algun producto con gastos de envio gratis ya devuelvo cero
$fila = Db::getInstance()->getRow('
SELECT count(*) AS nb
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'product` p ON cp.`id_product` = p.`id_product`
WHERE p.`envio_gratis` = 1 AND cp.`id_cart` = '.intval($this->id));
if (intval($fila['nb']) > 0)
return 0;
//$this->_nb_products = intval($row['nb']);
// fin modificacion
Con esto ya se obtiene el articulo que deja el pedido sin gastos de envio, pero aun he modificado otra cosa: en el resumen del pedido hay un texto donde sale el dinero que falta para obtener el envio gratuito, si no tocamos algo mas, este texto va a seguir saliendo confundiendo al cliente pues por un lado sale que tiene envio gratuito y por otro lado le dice que aun le falta para conseguirlo.
Asi que hay que tocar el archivo
Order.php que se encuentra en el directorio raiz de nuestra tienda Prestashop
Buscad el trozo de codigo que pone:
Código:
if ($free_ship = intval(Configuration::get('PS_SHIPPING_FREE_PRICE')))
{
$discounts = $cart->getDiscounts();
$total_free_ship = $free_ship - ($summary['total_products_wt'] + $summary['total_discounts']);
foreach ($discounts as $discount)
if ($discount['id_discount_type'] == 3)
{
$total_free_ship = 0;
break ;
}
$smarty->assign('free_ship', $total_free_ship);
}
Y cambiarlo por este otro:
Código:
if ($free_ship = intval(Configuration::get('PS_SHIPPING_FREE_PRICE')))
{
$discounts = $cart->getDiscounts();
// Si los gastos de envio son mayores que cero pues miro a ver si hay otros descuentos
// si los gastos de envio ya son cero pues pongo a cero la variable que controla si debe salir
// el texto de lo que falta para conseguir los gastos de envio gratuitos
if ($summary['total_shipping'] > 0) {
$total_free_ship = $free_ship - ($summary['total_products_wt'] + $summary['total_discounts']);
foreach ($discounts as $discount)
if ($discount['id_discount_type'] == 3)
{
$total_free_ship = 0;
break ;
}
}
else
$free_ship = 0;
$smarty->assign('free_ship', $total_free_ship);
}
Añadido 14/11/2009
Texto descriptivo indicando que el articulo tiene los gastos de envio gratuitos:
En el directorio donde se encuentran los archivos tpl de nuestro tema cambiar
En
product.tpl para que en la pantalla del producto salga indicado esta oferta
Donde ponia:
Código:
<!-- prices -->
<p class="price">
{if $product->on_sale}
<img src="{$img_dir}onsale_{$lang_iso}.gif" alt="{l s='On sale'}" class="on_sale_img"/>
<span class="on_sale">{l s='On sale!'}</span>
{elseif ($product->reduction_price != 0 || $product->reduction_percent != 0) && ($product->reduction_from == $product->reduction_to OR ($smarty.now|date_format:'%Y-%m-%d' <= $product->reduction_to && $smarty.now|date_format:'%Y-%m-%d' >= $product->reduction_from))}
<span class="discount">{l s='Price lowered!'}</span>
{/if}
Cambiarlo por
Código:
<!-- prices -->
<p class="price">
<!-- gestion de articulos con envio gratuito -->
{if $product->envio_gratis}
<span class="envio gratis"> {l s='Producto con envio gratis!'} </span>
{/if}
{if $product->on_sale}
<img src="{$img_dir}onsale_{$lang_iso}.gif" alt="{l s='On sale'}" class="on_sale_img"/>
<span class="on_sale">{l s='On sale!'}</span>
{elseif ($product->reduction_price != 0 || $product->reduction_percent != 0) && ($product->reduction_from == $product->reduction_to OR ($smarty.now|date_format:'%Y-%m-%d' <= $product->reduction_to && $smarty.now|date_format:'%Y-%m-%d' >= $product->reduction_from))}
{if $product->envio_gratis}
<br />
{/if}
<span class="discount">{l s='Price lowered!'}</span>
{/if}
Pero tambien hay que hacer que en el listado de articulos se vea que estos tienen la oferta asi que en
product-list.tplDonde ponia:
Código:
<div class="right_block">
{if $product.on_sale}
Poner esto:
Código:
<div class="right_block">
<!-- Productos con envio gratuito -->
{if $product.envio_gratis}
<span class="on_sale">{l s='Producto con envio gratis!'} </span>
{/if}
{if $product.on_sale}
Un saludo y agradeceria los comentarios al respecto
