Jump to content

How to use the email alert function for clients of the ps_emailalerts module in another module?


vav_
 Share

Recommended Posts

Hello, 

In our company, we have developed a module to manage our stocks outside the PrestaShop back office.

The tool interacts with the database and handles the inventory as desired. However, we would like to notify the customer who made an alert request on a product that was out of stock, when we replenish the stock from the external module. 

Finally, we want to use the ps_emailalerts module, like PrestaShop does, when making stock changes in the back office.

Does anyone have an idea on how to implement the customer alert function of the module mentioned above? 

It seems to me that the function used is :

MailAlert::sendCustomerAlert()

but no way to understand how to use it and implement it.

Thanks in advance for your help.

Share this post


Link to post
Share on other sites

If you are using direct database writing, this is bad.
The ps_emailalerts module uses a hook to change the state of the actionProductUpdate warehouse.
If the Prestashop function is used, the ps_mailaerts module sends emails itself.
Otherwise you will have to go through all the orders with a shortage and only then it is possible to use the toys module ps_emailaerts
actionModuleMailAlertSendCustomer.

  • Like 1

Share this post


Link to post
Share on other sites

13 hours ago, knacky said:

If you are using direct database writing, this is bad.
The ps_emailalerts module uses a hook to change the state of the actionProductUpdate warehouse.
If the Prestashop function is used, the ps_mailaerts module sends emails itself.
Otherwise you will have to go through all the orders with a shortage and only then it is possible to use the toys module ps_emailaerts
actionModuleMailAlertSendCustomer.

Thanks for your answer! 

Do you mean I have to use something like "Hook::exec(actionModuleMailAlertSendCustomer, array($arg))" within my module? 

Share this post


Link to post
Share on other sites

If you use such a notation, you do not have to use any other hook.

I don't know how you do the import so I can clarify it for you.
I guess it's a secret 😄

 

public function myImportFunction($params)
{
	$idProduct = $params['id_product'];
	$product = new Product((int) $idProduct);
	....
	....
	$product->update();
}
  • Like 1

Share this post


Link to post
Share on other sites

Posted (edited)
12 minutes ago, knacky said:

If you use such a notation, you do not have to use any other hook.

I don't know how you do the import so I can clarify it for you.
I guess it's a secret 😄

 

public function myImportFunction($params)
{
	$idProduct = $params['id_product'];
	$product = new Product((int) $idProduct);
	....
	....
	$product->update();
}

it's not really a secret !  :D

I have a lot of trouble with the PrestaShop code structure, I guess your great directions are supposed to help me. But I don't understand how I can make sending a mail to the customer from a specific page of my module is reproducing the native function. 

I have to modify the Controller of my module? 
And add the function that you have indicated to me? 

I'm really trying to elucidate "PrestaShop logics" to master the tool more easily. For now, you are contributing perfectly! :)

Edited by vav_
In english its better (see edit history)

Share this post


Link to post
Share on other sites

Posted (edited)

Look in ps_emailalerts / ps_emailers.php for the function:

public function hookActionUpdateQuantity($params)

You need to know the product id and possibly the product attribute id.

Then you can use other functions.

So if I don't know how to import, I can't give you more precise instructions.

Edited by knacky (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites

4 minutes ago, knacky said:

Look in ps_emailalerts / ps_emailers.php for the function:

public function hookActionUpdateQuantity($params)

You need to know the product id and possibly the product attribute id.

Then you can use other functions.

So if I don't know how to import, I can't give you more precise instructions.

Great, thank you very much, I will continue on this path! 

  • Like 1

Share this post


Link to post
Share on other sites

Posted (edited)

You need to write me more information.
For example:
I use direct database entry for import

Db::getInstance()->execute('INSERT INTO .....

or, I'm using a database entry

Db::getInstance()->insert('product', ...

/* or */

Db::getInstance()->update('product', ...

or, I use the Prestashop function

$product = new Product();
$product->price = $myImport['price'];
$product->name = $myImport['product_name'];
$product->save();

/* or */

$product = new Product((int)$myImport['id_product']);
$product->price = $myImport['price'];
$product->name = $myImport['product_name'];
$product->update();
	

etc....

There are many ways to achieve this.

Edited by knacky (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites

5 minutes ago, knacky said:

You need to write me more information.
For example:
I use direct database entry for import

Db::getInstance()->execute('INSERT INTO .....

or, I'm using a database entry

Db::getInstance()->insert('product', ...

/* or */

Db::getInstance()->update('product', ...

or, I use the Prestashop function

$product = new Product();
$product->price = $myImport['price'];
$product->name = $myImport['product_name'];
$product->save();

/* or */

$product = new Product((int)$myImport['id_product']);
$product->price = $myImport['price'];
$product->name = $myImport['product_name'];
$product->update();
	

etc....

There are many ways to achieve this.

My module isn't writed in php, but in javascript.
For example, my page which is used to update the stock uses this function to update the database: 

function update_product(id_product, id_attribute){

    let datas = {
        path : "manage_stock",
        page : "manage_stock_update",
        bJSON : 1,
        id_product : id_product,
        id_attribute : id_attribute,
        quantity_received : quantity_received
    }

    $.ajax({
        type: "POST",
        url: "route.php",
        async: true,
        data: datas,
        dataType: "json",
        cache: false
    })
        .done(function(result) {
            console.log('ok')
        })
        .fail(function(err) {
            // error
            console.log('error : ' + err.status);
        });
}

 

Is the structure of my module compatible with Prestashop functions ?

To summarize, I don't use PrestaShop's methods to interact with the database.

I inject values in variables, then they are called in .sql files, then executed.

Like : 

UPDATE PS_stock_available
SET quantity = quantity + @quantity, physical_quantity = physical_quantity + @quantity
WHERE id_product = @id_product AND id_product_attribute = @id_attribute;

You know what i mean ? 

  • Like 1

Share this post


Link to post
Share on other sites

I understand, but unnecessarily complicated.
To file route.php just add the path to ./config/config.inc.php and ./init.php at the beginning of php.

eg.:

	include('./config/config.inc.php');
	include('./init.php'); 

	$id_shop = null;
	$add_movement = true

	$product = new Product((int)$id_product);

	StockAvailable::setQuantity((int)$id_product, $id_attribute, $quantity, $id_shop, $add_movement);

	$product->update();

 

  • Like 1

Share this post


Link to post
Share on other sites

2 hours ago, knacky said:

I understand, but unnecessarily complicated.
To file route.php just add the path to ./config/config.inc.php and ./init.php at the beginning of php.

eg.:

	include('./config/config.inc.php');
	include('./init.php'); 

	$id_shop = null;
	$add_movement = true

	$product = new Product((int)$id_product);

	StockAvailable::setQuantity((int)$id_product, $id_attribute, $quantity, $id_shop, $add_movement);

	$product->update();

 

Okay, how useful will this implementation be? 

I don't understand the link between my stock management page and the route file.

However I have the route.php file in front of me, with a "session_start()" integrated in it.

(Sorry if my indications are vague, I try to be as precise as possible, so we can work together.
Especially, ask the right questions! :D

Share this post


Link to post
Share on other sites

Where is route.php file located?
The proposed solution has the advantage that you do not have to enter any additional function for sending emails. The update function automatically runs the hookProductUpdate function in the ps_emailaerts module.

  • Like 1

Share this post


Link to post
Share on other sites

Posted (edited)
19 minutes ago, knacky said:

Where is route.php file located?
The proposed solution has the advantage that you do not have to enter any additional function for sending emails. The update function automatically runs the hookProductUpdate function in the ps_emailaerts module.

In brief, this is the root of my module :

image.png.c2810504b76e5fc13c7691aa1c2a8ecd.png

And route.php file is in framework.

I understand the usefulness of "hookProductUpdate", this is the beginning of a cascade of Prestashop functions which, in the end, causes the sending of mail.

 

On the other hand, for each action in my tool, there is a SQL query called, but above all a PHP file that stores and transmits to the query the values that I would have entered in my tool. For example, the number of product received in stock.
See here: 

image.thumb.png.34f02b18f15966a5c3654bb291c56270.png

Edited by vav_
MORE INFOS (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites

Ok, on the fly to enjoy the cannon 😄
So it will be better to use, respectively. copy the function from ps_emailalerts.php and modify it for your solution 😉

include_once('./modules/ps_emailerts/MailAlert.php');
include('./../../config/config.inc.php');
include('./../../init.php');

$customer_qty = (int) Configuration::get('MA_CUSTOMER_QTY');
$quantity = $diff_received;

...

if ($customer_qty && $quantity > 0) {
    MailAlert::sendCustomerAlert((int) $old_received['id_product'], (int) $old_received['id_product_attribute']);
}

 

  • Like 1

Share this post


Link to post
Share on other sites

Posted (edited)
1 hour ago, knacky said:

Ok, on the fly to enjoy the cannon 😄
So it will be better to use, respectively. copy the function from ps_emailalerts.php and modify it for your solution 😉

include_once('./modules/ps_emailerts/MailAlert.php');
include('./../../config/config.inc.php');
include('./../../init.php');

$customer_qty = (int) Configuration::get('MA_CUSTOMER_QTY');
$quantity = $diff_received;

...

if ($customer_qty && $quantity > 0) {
    MailAlert::sendCustomerAlert((int) $old_received['id_product'], (int) $old_received['id_product_attribute']);
}

 

It is really a great help that you offer me, I begin to understand more and more.

I will try to be even more explicit, to make sure that we have the same information to move things forward :

 

It is contained in a large PHP file that groups all the useful functions, like this one.

public function manage_stock_supply_order_detail_update()
{
...

    $spathSQL_update_stock= $this->GLOBALS_INI["PATH_HOME"] . "files/manage_stock/sql/supply_list/manage_stock_UPDATE_supply_order_update_stock.sql";
    $this->oBdd->getSelectDatas($spathSQL_update_stock, array(
	'id_product' => $old_received['id_product'],
	'id_attribute' => $old_received['id_product_attribute'],
	'quantity' => $diff_received));

...
}

But each of the functions has its own files: 

image.png.343eed25914fdcc7df09dc99f9826330.png

Do I make sense? 

There are paths, structures that block my progress.

 

<?php
    if((include_once './../ps_emailalerts/MailAlert.php') == TRUE){
        echo 'MailAlert is ok ! <br>';
    }
    if((include './../../config/config.inc.php') == TRUE){
        echo 'config is ok ! <br>';
    }
    if((include './../../init.php') == TRUE){
        echo 'init is ok ! <br>';
    }

    echo 'beginning<br>';

    $customer_qty = 1;
    $quantity = 1;

    $id = 495;
    $ida = 0;

    if ($customer_qty && $quantity > 0) {
        MailAlert::sendCustomerAlert((int) $id, (int) $ida);
    }
    
    echo 'end';
?>

I make a test, but MailAlert.php include return HTTP ERROR 500.

 

 

 

After correction, the email is sent :

<?php
    
    if((include './../../config/config.inc.php') == TRUE){
        echo 'config is ok ! <br>';
    }
    if((include './../../init.php') == TRUE){
        echo 'init is ok ! <br>';
    }
    if((include_once './../ps_emailalerts/MailAlert.php') == TRUE){
        echo 'MailAlert is ok ! <br>';
    }

    echo 'beginning<br>';

    $customer_qty = 1;
    $quantity = 1;

    $id = 495;
    $ida = 0;

    if ($customer_qty && $quantity > 0) {
        MailAlert::sendCustomerAlert((int) $id, (int) $ida);
    }
    
    echo 'end';

The orders of the calls

Edited by vav_ (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites

23 minutes ago, knacky said:

Well, you see how easy it is in the end 😜

<?php
include './../../config/config.inc.php';
include './../../init.php';
include_once './../ps_emailalerts/MailAlert.php';

public function manage_stock_supply_order_detail_update()
	{
  
  ...
    
  	$spathSQL_update_stock= $this->GLOBALS_INI["PATH_HOME"] . "files/manage_stock/sql/supply_list/manage_stock_UPDATE_supply_order_update_stock.sql";
	$this->oBdd->getSelectDatas($spathSQL_update_stock, array(
		'id_product' => $old_received['id_product'],
		'id_attribute' => $old_received['id_product_attribute'],
		'quantity' => $diff_received
	));
  
	$customer_qty = (int) Configuration::get('MA_CUSTOMER_QTY');
	$quantity = $diff_received;
	if ($customer_qty && $quantity > 0) {
		MailAlert::sendCustomerAlert((int) $old_received['id_product'], (int) $old_received['id_product_attribute']);
    }
  
  ...
    
  }
?>

I followed your directions, but the JS code returns an error if I implement the function :

const update_product = (id_product, id_attribute) => {

    let datas = {
        path : "manage_stock",
        page : "manage_stock_supply_order_detail_update",
        bJSON : 1,
        quantity_received : quantity_received,
        id_product : id_product,
        id_attribute : id_attribute
    }

    $.ajax({
        type: "POST",
        url: "route.php",
        async: true,
        data: datas,
        dataType: "json",
        cache: false
    })
        .done(function(result) {
            console.log('ok')
		})
        .fail(function(err) {
            // error
            console.log('error : ' + err.status);
        });
}

The "manage_stock_supply_order_detail_update()" function does not like the "Mail::sendCustomerAlert" function.

Share this post


Link to post
Share on other sites

I'm not at the computer anymore.
You can call the function differently.

$alert = new MailAlert();

$alert->sendCustomerAlert(......);

Share this post


Link to post
Share on other sites

Posted (edited)
15 hours ago, knacky said:

I'm not at the computer anymore.
You can call the function differently.

$alert = new MailAlert();

$alert->sendCustomerAlert(......);

Hi, 

I tried this way but obviously I have to find another location.

I have the impression that the instantiation of a class in another class does not work.

My file : 

<?php
require_once __DIR__ . "/../../includes/php/initialize.php";
include './../../config/config.inc.php';
include './../../init.php';

class Manage_stock_service extends Initialize	{

	public $resultat;

	public function __construct()	{
		parent::__construct();
		$this->resultat= [];
	}

	public function __destruct()	{
		parent::__destruct();
	}
  
  
  public function manage_stock_supply_order_detail_update()
	{
		$spathSQL_update_stock= $this->GLOBALS_INI["PATH_HOME"] . "files/manage_stock/sql/supply_list/manage_stock_UPDATE_supply_order_update_stock.sql";
		$this->oBdd->getSelectDatas($spathSQL_update_stock, array(
			'id_product' => $old_received['id_product'],
			'id_attribute' => $old_received['id_product_attribute'],
			'quantity' => $diff_received
		));
		
		include_once './../ps_emailalerts/MailAlert.php';
		$customer_qty = (int) Configuration::get('MA_CUSTOMER_QTY');
     	$quantity = $diff_received;
      	if ($customer_qty && $quantity > 0) {
			$alert = new MailAlert();
			$alert->sendCustomerAlert((int) $old_received['id_product'], (int) $old_received['id_product_attribute']);
      	}
  }
}

In this case I get a javascript error 500, but if I write a simple "echo 'hello';", it will return a error 200.

Edited by vav_ (see edit history)

Share this post


Link to post
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
 Share

×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More