Jump to content

[SOLUCIONADO]Como hacer llamadas desde prestashop a servicios externos?


xabikip

Recommended Posts

Buenas,

 

¿Alguien sabe como podria hacer llamadas desde prestashop a servicios externos?

 

En mi caso me gustaria tener el catalogo en el ERP de mi enpresa. Cuando un usuario haga una busqueda de un producto como haria para que llamara a mi ERP y desde hay traer los productos?

 

Espero que alguien me pueda dar alguna pista.

 

Gracias,

 

Edited by xabikip (see edit history)
Link to comment
Share on other sites

Mi ERP ya tiene un servicio web al que puedo llamarle. Lo que no se es cuando y como llamarle desde prestashop. ¿Sabes de algun ejemplo o guia de como hacer esto?

 

He visto que existen hooks de acción ¿sabes que tipos de acción podria hacer con estos hooks?

Link to comment
Share on other sites

Bueno eso depende de tu ERP, es decir que tipo de servicio web ofrece (SOAP REST). Quizás en la documentación de tu ERP haya algún ejemplo.

 

P.ej Prestashop tiene documentación de como acceder a los servicios web de una tienda prestashop. En su caso utiliza REST

http://doc.prestashop.com/display/PS15/Using+the+PrestaShop+Web+Service

 

Pero lo dicho, es en la documentación de tu ERP donde encontraras como configurar el servicio y conectarse desde fuera.

 

Los hooks de accion son puntos donde ejecutar código en los módulos en determinados momentos (antes de salvar un producto, después..

http://doc.prestashop.com/display/PS15/Hooks+in+PrestaShop+1.5

Link to comment
Share on other sites

Bueno eso depende de tu ERP, es decir que tipo de servicio web ofrece (SOAP REST). Quizás en la documentación de tu ERP haya algún ejemplo.

 

P.ej Prestashop tiene documentación de como acceder a los servicios web de una tienda prestashop. En su caso utiliza REST

http://doc.prestashop.com/display/PS15/Using+the+PrestaShop+Web+Service

Como hacer llamadas a mi ERP ya lo se. Lo que me gustaria saber es cuando o como hacerlo desde Prestashop.

 

Desde que parte del codigo deberia de llamar para cuando se crea un pedido en prestashop y enviar la info del pedido en esa llamada a mi ERP?

Link to comment
Share on other sites

Como hacer llamadas a mi ERP ya lo se. Lo que me gustaria saber es cuando o como hacerlo desde Prestashop.

 

Desde que parte del codigo deberia de llamar para cuando se crea un pedido en prestashop y enviar la info del pedido en esa llamada a mi ERP?

 

Para el como, si los servicios web de tu ERP son REST te puede servir incluso la libreria de prestashop

https://github.com/PrestaShop/PrestaShop-webservice-lib/blob/master/PSWebServiceLibrary.php

 

En el fondo es un Envoltorio para usar REST de forma mas sencilla.

$request = self::executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'GET'));

Pero yo miraría otra librería mas general como

http://phphttpclient.com/

O alguna librería similar que te haga de cliente REST para ir contra los servicios web de tu ERP.

 

Pero claro si tus servicios web de tu ERP son SOAP tienes que usar una librería SOAP.

 

Si tu ERP esta muy extendido, lo mas probable es que exista una librería en PHP (o C#, Java, Python..otros lenguajes) para acceder (que te haga de envoltorio a REST o SOAP) y te facilite la vida, sino tendrás que usar una librería genérica.

 

 

Para los hooks:

 

Yo he usado

actionPaymentConfirmation. Se ejecuta cuando hay un pago (la orden pasa a un estado Pagado) y se le pasa el identificador del pedido

 

P.ej

public function hookActionPaymentConfirmation($params){
		$order=new Order($params["id_order"]);
		//when a valid purchase we change the value for customer to paid
		$customer = new Customer($order->id_customer);
		if (Validate::isLoadedObject($customer)){
			$customer->pele_first_fee_paid =1;
			$customer->update();
		}
			
		
		
	}

Aunque también hay otros puntos como actionOrderStatusUpdate al cual se le pasa el id del pedido y el nuevo estado del pedido

Edited by Enrique Gómez (see edit history)
  • Like 2
Link to comment
Share on other sites

Gracias Enrique por la explicación. Me ha sido de ayuda.

 

Mi ERP tiene un servico web SOAP. Conoces alguna libreria SOAP?

 

Yo tambien habia pensado usar el hook actionPaymentConfirmation. Pero la verdad que no entiendo muy bien el flujo de las llamadas a los hooks.

 

Por ejemplo veo que en /classes/order/orderHistory.php linea 100 se hace referencia a este hook en:

Hook::exec('actionPaymentConfirmation', array('id_order' => (int)$order->id));

Entiendo que en esa linea se dice que ejecute el hook actionPaymentConfirmation. Si no es asi me podrias decir que hace esa linea? Tambien lo que no se es que hace ese hook.

 

No encuentro la funcion hookActionPaymentConfirmation que mencionas tu. Lo has creado tu? y si es asi donde lo creaste, en que archivo?

Link to comment
Share on other sites

 

Entiendo que en esa linea se dice que ejecute el hook actionPaymentConfirmation. Si no es asi me podrias decir que hace esa linea? Tambien lo que no se es que hace ese hook.

Si hace eso, de forma que todos los módulos que están suscritos a ese hook se ejecutaran. Como es un hook de acción no importa lo que devuelva, si fuese de display el html que devuelven se mete finalmente en algún sitio de alguna plantilla.

 

 

 

No encuentro la funcion hookActionPaymentConfirmation que mencionas tu. Lo has creado tu? y si es asi donde lo creaste, en que archivo?

 

Los hooks se crean en los modulos, y normalmente se registran en el mismo método install del módulo

Tendrás que mirarte la doc de modulos de prestashop http://doc.prestashop.com/display/PS15/Creating+a+PrestaShop+module

 

80uo.jpg

  • Like 1
Link to comment
Share on other sites

 

Mi ERP tiene un servico web SOAP. Conoces alguna libreria SOAP?

En php no he usado ninguna...

 

Php tiene un cliente nativo.

http://stackoverflow.com/questions/17567424/how-to-make-a-php-soap-client-and-store-the-result-xml-in-php-variables#answer-17567515

 

Algunas librerias

http://stackoverflow.com/questions/9633858/soap-libraries-for-php

Link to comment
Share on other sites

Pero no entiendo, entonces si no creo un modulo que use ese hook como lo tienes creado tu, no se se usara nunca?

 

Tengo que crear un modulo por cada hook que quiera usar?

 

Por otro lado entiendo que si por ejemplo la accion que deseo realizar es mandar datos del pedido a mi ERP tendria que usar un hook de accion porque no quiero hacer nada con la respuesta. Pero si lo que quisiera fuese traer datos de mi ERP y mostrarlos en prestashop tendria que usar un hook de display?

 

 

Gracias, me esta ssiendo de gran ayuda. ;-)

Link to comment
Share on other sites

Por otro lado entiendo que si por ejemplo la accion que deseo realizar es mandar datos del pedido a mi ERP tendria que usar un hook de accion porque no quiero hacer nada con la respuesta. Pero si lo que quisiera fuese traer datos de mi ERP y mostrarlos en prestashop tendria que usar un hook de display?

Exacto. Con los de display, si te fijas, hay un montón de etiquetas smarty como {$HOOK_HEADER} en las plantillas de forma que en ese punto se enchufaría el html generado por el hook de display (de todos los módulos suscritos a ese hook).

 

Pero no entiendo, entonces si no creo un modulo que use ese hook como lo tienes creado tu, no se se usara nunca?

 

El tema de los hooks tienes que verlo como una suscripción. PS tiene una API de hooks http://doc.prestashop.com/display/PS15/Hooks+in+PrestaShop+1.5.  PS lo que hace internamente es ejecutar

$reuturnvaluetodisplaysomething=Hook::exec('identificador_del hook', parámetros);
De forma que este exec lista a todos los módulos que están registrados a ese identificador_del hook y ejecuta el método hookidentificador_del hook de cada uno (por orden). Habitualmente hay bastantes módulos suscritos a un hook. Es una forma muy buena de modularizar una aplicación informática para que cualquier tercero mirando la API de esa aplicación pueda crear funcionalidades

 

p.ej con los de display tienes que PS internamente mete en la plantilla todo el html devuelto por los módulos suscritos al displayTop..etc

$this->context->smarty->assign(array(
			'HOOK_HEADER' => $hook_header,
			'HOOK_TOP' => Hook::exec('displayTop'),
			'HOOK_LEFT_COLUMN' => ($this->display_column_left ? Hook::exec('displayLeftColumn') : ''),
			'HOOK_RIGHT_COLUMN' => ($this->display_column_right ? Hook::exec('displayRightColumn', array('cart' => $this->context->cart)) : ''),
			'HOOK_FOOTER' => Hook::exec('displayFooter')
		));
Si no hay ningún módulo suscrito al hook sera como si nada.

 

---

 

Tengo que crear un modulo por cada hook que quiera usar?

Un módulo puede estar suscrito a todos los hooks que quiera.

 

----

 

Por si no queda claro el método

Hook::exec('identificador_del hook', parámetros);
Se ejecuta para los diferentes identificador_del hook en los puntos que toca  dentro del Core de prestashop.

 

P.ej cuando se crea un producto en el controlador AdminProductsController

public function processAdd()
	{
		$this->checkProduct();
                 ETC ETC..		
			if (empty($this->errors))
			{
				ETC ETC..
				{
					Hook::exec('actionProductAdd', array('product' => $this->object));
					ETC ETC..
				}
ETC..
}
  • Like 1
Link to comment
Share on other sites

Creo que me voy aclarando. Gracias ;-)

 

Te explico lo que necesito y que es lo que creo que tendria que hacer teóricamente.

 

Lo que necesito son 2 cosas:

 

1.- Que cuando en prestashop se genere un pedido pagado llame a mi ERP para guardar los datos del pedido.

 

2.- Cuando alguien introduce un codigo para buscar un producto, prestashop llame a mi ERP y le traiga el producto con dicho codigo. Despues quiero mostrar dicho producto en prestashop.

 

Para ello tendria que crear un modulo que este suscrito a los hooks que se necesiten para hacer las funcionalidades mencionadas.

 

1.- Suscribirse al hook actionPaymentConfirmation y hacer la llamada a mi ERP para guardar los datos.

En el modulo tendria que poner esta funcion:

public function hookActionPaymentConfirmation($params){
		
		//hacer llamada a mi ERP y enviarle los datos del pedido
                //Algun ejemplo de codigo de como obtener los datos del pedido?	
				
}

2.- Suscribirse al hook actionSearch y hacer la llamda al ERP para traer los productos:

En el modulo tendria que poner esta funcion:

public function hookActionSearch($params){
		
		//hacer llamada a mi ERP y traer el producto	
				
}

Despues me faltaria mostrar el producto que he traido desde el ERP. Para ello tendria que suscribirme a algun hook display. He estado mirando en la docu oficial pero no se cual podria ser.

 

 

 

Los pasos a seguir para la primera funcionalidad creo que los veo bien, pero tengo dudas de como tendria que hacer la segunda funcionalidad. No se si suscribirme primero al hook actionSearch y luego al display adecuado o directamente en el display adecuado llamar a mi ERP y mostrar lo que me trae. No se si me explico.

Link to comment
Share on other sites

 

2.- Cuando alguien introduce un codigo para buscar un producto, prestashop llame a mi ERP y le traiga el producto con dicho codigo. Despues quiero mostrar dicho producto en prestashop.

Pero luego que quieres hacer con ese "producto"?. Porque este productoERP  no tiene nada que ver con el producto de prestashop que esta guardado en la base de datos de PS.

 

Ya olvídate de que se pueda comprar etc etc, estos datos que te traigas del ERP los puedes mostrar, pero si tienes que montarte todo el código de programación para que se pueda comprar no es una buena estrategia.

Link to comment
Share on other sites

El productoERP es solo para mostrar, no necesito que se pueda comprar ni nada, solo mostrar info del productoERP. Habra otros productos en el catalogo de Presatshop que si se podran comprar. la idea es tener unos productos en el catalogo de prestashop que se podran comprar y otro traerlos desde el ERP solo para mostrarlos.

 

¿Pero que estrategia tomarias? ¿suscribirse a dos hooks? uno para actionSearcha para recoger el codigo introducido para hacer la busqueda en mi ERP y otro para mostrarlo?

 

O solo en un hook?......esto no lo tengo nada claro. Se que en actionHook puedo suscribirme cuando alguien introduce algo para la busqueda, y eso me valdria para recoger el valor introducido y hacer la busqueda en mi ERP. Pero luego no se como tendria que mostrar el producto.

 

¿Que display hook el que se actica cuando muestra los productos de las busquedas?

 

 

La estrategia para la primera funcionalidad te parece correcta?

Edited by xabikip (see edit history)
Link to comment
Share on other sites

 

La estrategia para la primera funcionalidad te parece correcta?

Si

 

 

 

Para la búsqueda tienes que tener en cuenta que Prestashop usa ajax para que se vaya viendo los resultados así que con servicios web creo que quizás eso no se pueda hacer mas que nada por lentitud.

 

En ese caso puedes hacerlo todo nuevo, es decir una página nueva que tenga un buscador de toda la vida que hasta que no le des a buscar no haga nada. Tendrías que crear el controlador y su vista nuevos (modelo no creo que haga falta). Aquí la cosa se complica. Puede seguir siendo un módulo pero que extienda de ModuleFrontController. Quizás este tuto de nemo te oriente http://nemops.com/creating-new-pages-in-prestashop/#.UwyIMYUv-Eo

Aprovecharías mucho código (copy paste) del controlador que se ocupa de las búsquedas (SearchController y su vista search.tpl)

 

 

 

También puedes pasar del tema Ajax (no se si incluso se puede desactivar desde el backoffice) y hacer un override del SearchController (esto es otro aspecto de PS http://doc.prestashop.com/display/PS15/Overriding+default+behaviors#Overridingdefaultbehaviors-Overridingacontroller) . Este es mucho mas sencillo

 

Sobrescribes el initContent() copias el del padre y metes tú llamada adicional a tu servicio web en la zona marcada en rojo. De esta forma estas bajo control de toda la búsqueda. Tendrás que mezclar los dos listados

 

m6h0.jpg

Link to comment
Share on other sites

Pasare del tema Ajax, no lo necesitaba y por lo que comentas sera mas facil hacer el override del SearchController.

 

Una duda. En este troco de codigo es donde deveria de asignar el resultado de la busqueda para que se vea en la tpl?

$this->context->smarty->assign(array(
				'products' => $search['result'], // DEPRECATED (since to 1.4), not use this: conflict with block_cart module
				'search_products' => $search['result'],
				'nbProducts' => $search['total'],
				'search_query' => $query,
				'homeSize' => Image::getSize(ImageType::getFormatedName('home'))));

Por otra parte he empezado a crear el modulo para dichas funcionalidades y por ahora va bien.

Link to comment
Share on other sites

Si, ahí puedes asignar nuevas variables que en la plantilla search.tpl (que al final tira de la que se usa en todos los listados -> product-list.tpl ) se pueden usar. También puedes modificar  search_products y nbProducts y meterle nuevos arrays (info de productos). Incluso estos nuevos arrays pueden tener algún flag para saber si son de PS o del ERP (puede venir bien a la hora de mostrarlos en la plantilla)

 

Puedes probar de modificar search_products y nbProducts a mano para ver que te funciona.

 

P.ej aquí hay 44 resultados y cada uno tiene 75 campos (atributos de los productos)... No creo que la plantilla lea todos ni mucho menos

 

t0v0.jpg

 

 

En search.tpl se incluye product-list.tpl

{include file="$tpl_dir./product-list.tpl" products=$search_products}

Luego la en product-list va iterando y montando la página. Va mirando estos atributos $product.id_product .. etc   si espera un atributo y éste no existe Smarty se quejará y petará.

{foreach from=$products item=product name=products}
		<li class="ajax_block_product {if $smarty.foreach.products.first}first_item{elseif $smarty.foreach.products.last}last_item{/if} {if $smarty.foreach.products.index % 2}alternate_item{else}item{/if} {if $smarty.foreach.products.iteration%$nbItemsPerLine == 0}last_item_of_line mobile_no_margin{/if}  {if $smarty.foreach.products.iteration%$nbItemsPerLinebig == 0}last_item_of_line_big{/if} clearfix">
			<div class="left_block">
				{if isset($comparator_max_item) && $comparator_max_item}
					<p class="compare">
						<input type="checkbox" class="comparator" id="comparator_item_{$product.id_product}" value="comparator_item_{$product.id_product}" {if isset($compareProducts) && in_array($product.id_product, $compareProducts)}checked="checked"{/if} /> 
						<label for="comparator_item_{$product.id_product}">{l s='Select to compare'}</label>
					</p>
  • Like 1
Link to comment
Share on other sites

Buenas Enrique, estoy intentando hacer el override del SearchController.

 

Para ver si me coje el override lo que hago es en modules/mimodulo/override/controllers/front/SearchController.php meterle un string para ver si aparce como resultado de busqueda.

 

En SearchController.php este archivo he cambiado lo siguiente.

 

El nombre:

class SearchController extends SearchControllerCore

Y despues dentro de esta clase pongo lo siguiente (le he puesto en todos los 'search_products' para asegurarme, jeje):

$this->context->smarty->assign(array(
				'products' => $search['result'], // DEPRECATED (since to 1.4), not use this: conflict with block_cart module
				'search_products' => $this->l('Este es un mensaje desde el override del search controller'),
				'nbProducts' => $search['total'],
				'search_query' => $query,
				'instant_search' => $this->instant_search,
				'homeSize' => Image::getSize(ImageType::getFormatedName('home'))));

Fijate que en 'search_products' le he metido un string para ver si pasa por este archivo, por mi override.

 

Supuestamente si todo lo hice bien deveria de aparecer el string que he metido en el reusltado de la busqueda verdad? pero no aparece y me muestra el producto bien, sin fallos ni nada.

 

Puede ser por tema de cache?........la verdad que he leido algo de borrar no se que archivo para el cache, pero no se cual es.

 

Puedes ver que estoy haciendo mal o porque no me carga el mensaje en el resultado de la busqueda?

 

Gracias ;-)

Edited by xabikip (see edit history)
Link to comment
Share on other sites

Estoy seguro que no entra a mi override porque si modifico en el original puedo ver la modoficacion, y haciendo lo mismo en el override no pasa nada.

 

He probado de dos maneras:

 

 

1.- Poniendolo en override/controllers/front/SearchController.php

2.- poniendolo en modules/mimodulo/overrides/controllers/front/SearchController.php

 

Y no me detecta el override de ninguna de las maneras. ¿Alguna idea de porque puede ser?

Edited by xabikip (see edit history)
Link to comment
Share on other sites

Estoy seguro que no entra a mi override porque si mo difico en el original puedo ver la modoficacion, y haciendo lo mismo en el override no pasa nada.

 

He probado de dos maneras:

 

 

1.- Poniendolo en override/controllers/front/SearchController.php

 

Y no me detecta el override de ninguna de las maneras.

 

La opción 1 que comentas es un override correcto, creo.

 

Recuerda que tienes que borrar el fichero:

/cache/class_index.php

para que Prestashop te detecte el nuevo override que has metido. (Al menos eso me paso a mi) (El fichero se regenera de nuevo, asi que no te alarmes por borrarlo)

Edited by Feliz Garcia (see edit history)
  • Like 1
Link to comment
Share on other sites

Tienes que borrar el class_index.php como dice Feliz

 

 

Supuestamente si todo lo hice bien deveria de aparecer el string que he metido en el reusltado de la busqueda verdad? pero no aparece y me muestra el producto bien, sin fallos ni nada.

 

La plantilla smarty (product-list.tpl) espera un array de "Productos" (array compuesto por id_producto, precio,etc..). Si le metes un string petará. Otra cosa es que añadas una nueva variable smarty con un string y luego en la plantilla la leas.

Link to comment
Share on other sites

Efectivamente era borrar el class_index.php como me deciais. Pero sabeis si hay forma de que no te genere o no lo tenga encuanta. Mas que nada por no andar borrandolo cada vez que haga un cambio.

 

Encuanto a meterle otra variable lo hago asi. En el SearchController.php:

$this->context->smarty->assign(array(
				'search_tag' => $tag,
				'products' => $result, // DEPRECATED (since to 1.4), not use this: conflict with block_cart module
				'search_products' => $search['result'],
				'nbProducts' => $nbProducts,
				'my_message' => $this->l('Este es un mensaje desde el override del search controller'),
				'homeSize' => Image::getSize(ImageType::getFormatedName('home'))));

Le añado un srtng en en 'my_message'.

 

Luego en search.tpl le añado mi variable en el include:

{include file="$tpl_dir./product-list.tpl" products=$search_products mensaje=$my_message}

y para terminar en product-list.tpl muestro mi mensaje:

<p>{$mensaje}</p> 

El tema es que no se porque me muestra la pantalla en blanco. No se donde me peta, en que archivo estoy haciendo mal. Introduzco la palabra de la busqueda y al mostra los resultados, me sale una pantalla en blanco.

Link to comment
Share on other sites

Nada el prblema estaba en

'my_message' => $this->l('Este es un mensaje desde el override del search controller'),

lo he cambiado a.

'my_message' => $this->'Este es un mensaje desde el override del search controller'

y puedo ver el mensaje en el resutakldo de busaqueda.

 

Pero ahora tengo otro problema. He creado una funcion en en SearchController.php para hacer la llamada a mi servico web y me falla. No digo que me falla el servicio web si no que por solo declarar una funcion mas en el controller, aunque esta funcion no la utilice ya me falla.

 

Esto es lo que he añadido al SearchController:

public static function llamada_a_mi_webservice($parametros) 
{
		 
//aqui hago la logica de mi llamada y retorno lo que me ha devuelto
	
 }

Por ahora no la utilizo, la idea es que antes de asignar los resultados al smarty, llamar a esta funcion y añadirle mis resultados. Pero con solo declarar esta funcion ya me falla.

 

¿Estoy declarando mal la funcion? ¿sabais como tendria que hacer?

Edited by xabikip (see edit history)
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...