Jump to content

Usar API externa para añadir productos a PS y actualizar stock


gusman126

Recommended Posts

Hola, he visto que algunos de los desarrolladores que empiezan no tienen claro el uso del webservice o usar un modulo para realizar llamadas API a un sistema externo por lo que voy a poner un pequeño resumen de código para hacer llamadas API a un sistema externo y añadir o actualizar productos.

Empezamos.

Código para hacer llamadas a API externa, yo uso la orden Curl anteriormente hago las pruebas con el software Postman, de esa manera puedo ver los resultados, el código seria el siguiente

Obviamente el valor de URL y orden dependerá de vuestra API y si es necesario una autenticación, buscad ejemplos de curl diferentes o usad el postman, tiene la opción de mostrar el código en PHP

Es posible que el código que he puesto tenga algún error, falten datos que obviamente debes saber y leer de los datos leídos del resultado del Curl

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url_api.$orden,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
	"Accept: */*",
	"Accept-Encoding: gzip, deflate",
	"Cache-Control: no-cache",
	"Connection: keep-alive",
	"cache-control: no-cache"
),
));
			
$response = curl_exec($curl);
			

Una vez tengo la respuesta

$articulos = json_decode($resultado,true);
foreach($articulos as $articulo){
  $product = new Product();
	$product->name[$idlang] = $articulo['nombre'];
   
/*
  Aqui se rellena todos los datos del producto
  nombre en el idioma, referecia, precio, descripciones etc..
  */

//añadimos producto y si es correcto leemos su ID
if($product->add()){
      $id_product = $product->id;
  }

if($id_product > 0){
// continuamos añadiendo el producto
StockAvailable::setQuantity($id_product, 0, (int)$stock, $id_shop = null);
$product->id_category_default = (int)$id_cat;
				$product->addToCategories(array($id_cat));

	//ahora las imagenes, este codigo es mas largo y se suelen usar funciones independientes
	
	$img = 0;
	$cover = 1;
	foreach($articulo['imagenes'] as $imagen){
		if($img > 0){
			$cover = 0;
		}
		addimg($imagen['url'],$cover,$id_product);
		$img++
	}
	$product->update();

}



}

Funciones

function addimg($image,$cover,$id_product){
	
	$urlimg = $image;
	
	$image = new Image();
	$image->id_product = $id_product;
	$image->position = Image::getHighestPosition($id_product) + 1;
	if (($image->validateFields(false, true)) === true && ($image->validateFieldsLang(false, true)) === true && $image->add()){
		$copy = copyImg($id_product, $image->id, $urlimg, 'products', true);
		if (!$copy){
			$image->delete();
			return 0;
		}else{
			$image->cover = $cover;
			$image->save();
			
		}
	}
	
	
	
}
function copyImg($id_entity, $id_image = null, $url, $entity = 'products'){
		$tmpfile = tempnam(_PS_TMP_IMG_DIR_, 'ps_import');
		$watermark_types = explode(',', Configuration::get('WATERMARK_TYPES'));
		$image_obj = new Image($id_image);
		$path = $image_obj->getPathForCreation();
		$url = str_replace(' ', '%20', trim($url));
		if (!ImageManager::checkImageMemoryLimit($url)){
			return;
		}
		if (@copy($url, $tmpfile)){
			ImageManager::resize($tmpfile, $path.'.jpg');
			$images_types = ImageType::getImagesTypes($entity);
			foreach ($images_types as $image_type){
				ImageManager::resize($tmpfile, $path.'-'.stripslashes($image_type['name']).'.jpg', $image_type['width'], $image_type['height']);
				if (in_array($image_type['id_image_type'], $watermark_types)){
					Hook::exec('actionWatermark', array('id_image' => $id_image, 'id_product' => $id_entity));
				}
			}
		}else{
			unlink($tmpfile);
			return;
		}
		unlink($tmpfile);
		return true;
		
	}

Y ya tenemos añadido nuestro producto.

Ahora actualizar datos, usamos la misma orden Curl cambiando la URL y la orden para que lea el stock de los producto o de un solo producto

$id_lang = Configuration::get('PS_LANG_DEFAULT');
$resultado = readdata($url,$orden);
if($resultado){
	$datos = json_decode($resultado,true);
	foreach($datos as $dato){
	
	
	$referencia = $dato['referencia'];
	$sql = "select id_product from "._DB_PREFIX_."product where reference = '".$referencia."'";
	$id_product = Db::getInstance()->getValue($sql);
	if(!id_product){
		continue;
	}
	$product = new Product($id_product);
	/*
	una vez tenemos el id del producto ya podemos actualizar el stock y el precio
	*/
	$product->price = round($pvpok,2);
	StockAvailable::setQuantity($id_product, 0, $quantity, $id_shop = null);
	$product->update();
	}

}

 

  • Thanks 1
Link to comment
Share on other sites

2 hours ago, gusman126 said:

Con un cron

Yo suelo añadir un fichero class y llamo las órdenes con un fichero PHP que ejecutó con un cron

Con un cron está bien. Pero ya para rizar el rizo se puede implementar dentro de un módulo con un controlador que reciba las peticiones desde la API externa, de modo que cuando en el otro programa haya un cambio de stock, por ejemplo, envíe a ese controlador la información y actualice el stock del producto en Prestashop. Y que cuando se produzca una venta en Prestashop se use el hook correspondiente para enviar también desde ahí a la API externa la sincronización de stock de los productos vendidos (e incluso los datos de la venta y del cliente, si se quieren sincronizar también). De este modo nos podemos asegurar de que los datos están siempre sincronizados.

Evidentemente, en cualquier caso dependemos de las posibilidades que ofrezca la API externa, pero con un poco de maña se puede conseguir una sincronización bastante buena.

Aprovecho para lanzar una pregunta: ¿alguna idea sobre cómo gestionar el tema de las imágenes? Yo cuando he programado algo así he utilizado un acceso FTP para subirlas al servidor y poder acceder después a ellas a través de una URL, pero claro, porque el programa externo donde se gestionaban los productos me ofrecía esa posibilidad. Pero... ¿se os ocurre algo más "universal"?

Link to comment
Share on other sites

hace 7 minutos, Prestafan33 dijo:

Aprovecho para lanzar una pregunta: ¿alguna idea sobre cómo gestionar el tema de las imágenes? Yo cuando he programado algo así he utilizado un acceso FTP para subirlas al servidor y poder acceder después a ellas a través de una URL, pero claro, porque el programa externo donde se gestionaban los productos me ofrecía esa posibilidad. Pero... ¿se os ocurre algo más "universal"?

Siempre lo mejor es que el propio software/API  tenga un acceso por FTP, http a las imágenes pero no todos los tienen

La unica manera es como dices subir al FTP de la tienda los ficheros, tener un listado que asocie las imagenes(fichero) con el producto o la obligación de poner en el nombre la referencia del producto y usar esa referencia para asociar y añadir la imagen

No hay nada universal que yo sepa

 

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

  • 3 months later...

Estoy integrando una Api depasarela de pago, se un poco de programación pero tengo muchas dudas ya que estoy haciendo la integración con php de manera manual y me pide << En la parte superior del script PHP en el que se usará la biblioteca del cliente (o en la sección que incluye otras bibliotecas), agregue el script principal de la biblioteca del cliente:>>

y no se donde colocar el scrip PHP dentro de Prestashop 1,7 

Link to comment
Share on other sites

En 5/2/2020 a las 8:46 PM, aleiny96 dijo:

Estoy integrando una Api depasarela de pago, se un poco de programación pero tengo muchas dudas ya que estoy haciendo la integración con php de manera manual y me pide << En la parte superior del script PHP en el que se usará la biblioteca del cliente (o en la sección que incluye otras bibliotecas), agregue el script principal de la biblioteca del cliente:>>

y no se donde colocar el scrip PHP dentro de Prestashop 1,7 

Lo mejor sera que hagas un modulo para que ejecute los script dependiendo de lo que necesites "hooks"

Link to comment
Share on other sites

  • 2 years later...
  • 1 year later...

Buenas tardes, me gustaría saber si en la linea de codigo del script que has compartido 

$image = new Image();

 ES Imagick o a que extensión o librería es la que estas usando. 

la misma duda con la sig. linea: 

ImageType::getImagesTypes($entity);

De antemano agradezo el tiempo que te tomes para responderme.

 

Link to comment
Share on other sites

En 26/6/2023 a las 10:22 PM, mr_dev dijo:

Buenas tardes, me gustaría saber si en la linea de codigo del script que has compartido 

$image = new Image();

 ES Imagick o a que extensión o librería es la que estas usando. 

la misma duda con la sig. linea: 

ImageType::getImagesTypes($entity);

De antemano agradezo el tiempo que te tomes para responderme.

 

Pues está usando la configuración de prestashop, ahora mismo no recuerdo cuál utiliza 

Debe estar en alguna documentación de PrestaShop 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...