2016-04-14 16:14:31 +02:00
< ? php
/*
* 2007 - 2014 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License ( AFL 3.0 )
* that is bundled with this package in the file LICENSE . txt .
* It is also available through the world - wide - web at this URL :
* http :// opensource . org / licenses / afl - 3.0 . php
* If you did not receive a copy of the license and are unable to
* obtain it through the world - wide - web , please send an email
* to license @ prestashop . com so we can send you a copy immediately .
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future . If you wish to customize PrestaShop for your
* needs please refer to http :// www . prestashop . com for more information .
*
* @ author PrestaShop SA < contact @ prestashop . com >
* @ copyright 2007 - 2014 PrestaShop SA
* @ license http :// opensource . org / licenses / afl - 3.0 . php Academic Free License ( AFL 3.0 )
* International Registered Trademark & Property of PrestaShop SA
*/
if ( ! defined ( '_PS_VERSION_' ))
exit ;
class Followup extends Module
{
2017-01-16 17:59:32 +01:00
private static $cancelled_cart_min_amount_order = 30 ;
2016-04-14 16:14:31 +02:00
public function __construct ()
{
$this -> name = 'followup' ;
$this -> tab = 'advertising_marketing' ;
$this -> version = '1.6.2' ;
$this -> author = 'PrestaShop' ;
$this -> need_instance = 0 ;
$this -> conf_keys = array (
'PS_FOLLOW_UP_ENABLE_1' ,
'PS_FOLLOW_UP_ENABLE_2' ,
'PS_FOLLOW_UP_ENABLE_3' ,
'PS_FOLLOW_UP_ENABLE_4' ,
'PS_FOLLOW_UP_ENABLE_5' ,
'PS_FOLLOW_UP_AMOUNT_1' ,
'PS_FOLLOW_UP_AMOUNT_2' ,
'PS_FOLLOW_UP_AMOUNT_3' ,
'PS_FOLLOW_UP_AMOUNT_4' ,
'PS_FOLLOW_UP_AMOUNT_5' ,
'PS_FOLLOW_UP_DAYS_1' ,
'PS_FOLLOW_UP_DAYS_2' ,
'PS_FOLLOW_UP_DAYS_3' ,
'PS_FOLLOW_UP_DAYS_4' ,
'PS_FOLLOW_UP_DAYS_5' ,
'PS_FOLLOW_UP_MIN_5' ,
'PS_FOLLOW_UP_THRESHOLD_3' ,
'PS_FOLLOW_UP_DAYS_THRESHOLD_4' ,
'PS_FOLLOW_UP_CLEAN_DB'
);
$this -> bootstrap = true ;
parent :: __construct ();
$secure_key = Configuration :: get ( 'PS_FOLLOWUP_SECURE_KEY' );
if ( $secure_key === false )
Configuration :: updateValue ( 'PS_FOLLOWUP_SECURE_KEY' , Tools :: strtoupper ( Tools :: passwdGen ( 16 )));
$this -> displayName = $this -> l ( 'Customer follow-up' );
$this -> description = $this -> l ( 'Follow-up with your customers with daily customized e-mails.' );
$this -> confirmUninstall = $this -> l ( 'Are you sure you want to delete all settings and your logs?' );
}
public function install ()
{
Db :: getInstance () -> execute ( '
CREATE TABLE '._DB_PREFIX_.' log_email (
`id_log_email` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`id_email_type` INT UNSIGNED NOT NULL ,
`id_cart_rule` INT UNSIGNED NOT NULL ,
`id_customer` INT UNSIGNED NULL ,
`id_cart` INT UNSIGNED NULL ,
`date_add` DATETIME NOT NULL ,
INDEX `date_add` ( `date_add` ),
INDEX `id_cart` ( `id_cart` )
) ENGINE = ' . _MYSQL_ENGINE_ );
foreach ( $this -> conf_keys as $key )
Configuration :: updateValue ( $key , 0 );
return parent :: install ();
}
public function uninstall ()
{
foreach ( $this -> conf_keys as $key )
Configuration :: deleteByName ( $key );
Configuration :: deleteByName ( 'PS_FOLLOWUP_SECURE_KEY' );
Db :: getInstance () -> execute ( 'DROP TABLE ' . _DB_PREFIX_ . 'log_email' );
return parent :: uninstall ();
}
public function getContent ()
{
$html = '' ;
/* @Override */
if ( Tools :: isSubmit ( 'sendMailTest' )){
$email = Tools :: getValue ( 'email_test' );
$id_email = Tools :: getValue ( 'id_email_test' );
$this -> _sendMailTest ( $id_email , $email );
}
if ( Tools :: isSubmit ( 'flw_export' )){
$this -> _processExport ( Tools :: getValue ( 'id_export_type' ));
}
/* @End Override */
/* Save settings */
if ( Tools :: isSubmit ( 'submitFollowUp' ))
{
$ok = true ;
foreach ( $this -> conf_keys as $c )
if ( Tools :: getValue ( $c ) !== false ) // Prevent saving when URL is wrong
$ok &= Configuration :: updateValue ( $c , ( float ) Tools :: getValue ( $c ));
if ( $ok )
$html .= $this -> displayConfirmation ( $this -> l ( 'Settings updated succesfully' ));
else
$html .= $this -> displayError ( $this -> l ( 'Error occurred during settings update' ));
}
$html .= $this -> renderForm ();
$html .= $this -> renderStats ();
return $html ;
}
/* Log each sent e-mail */
private function logEmail ( $id_email_type , $id_cart_rule , $id_customer = null , $id_cart = null )
{
$values = array (
'id_email_type' => ( int ) $id_email_type ,
'id_cart_rule' => ( int ) $id_cart_rule ,
'date_add' => date ( 'Y-m-d H:i:s' )
);
if ( ! empty ( $id_cart ))
$values [ 'id_cart' ] = ( int ) $id_cart ;
if ( ! empty ( $id_customer ))
$values [ 'id_customer' ] = ( int ) $id_customer ;
Db :: getInstance () -> insert ( 'log_email' , $values );
}
public static function getIdProductOfAllActiveSale ()
{
include_once ( dirname ( __FILE__ ) . '../../privatesales/models/SaleCore.php' );
$sales = SaleCore :: getSales ( SaleCore :: STATE_CURRENT );
$ids_products = array ();
foreach ( $sales as $sale )
{
$ids_products = array_merge ( $ids_products , $sale -> getProducts ());
}
return $ids_products ;
}
/* Each cart which wasn't transformed into an order */
private function cancelledCart ( $count = false )
{
$ids_products = self :: getIdProductOfAllActiveSale ();
if ( count ( $ids_products ) == 0 )
return 0 ;
2016-06-01 10:16:39 +02:00
/* $email_logs = $this -> getLogsEmail ( 1 );
2016-04-14 16:14:31 +02:00
$sql = '
SELECT DISTINCT c . id_cart , c . id_lang , cu . id_default_group , cu . id_customer , c . id_shop , cu . firstname , cu . lastname , cu . email
FROM '._DB_PREFIX_.' cart c
LEFT JOIN '._DB_PREFIX_.' orders o ON ( o . id_cart = c . id_cart )
RIGHT JOIN '._DB_PREFIX_.' customer cu ON ( cu . id_customer = c . id_customer )
RIGHT JOIN '._DB_PREFIX_.' cart_product cp ON ( cp . id_cart = c . id_cart AND cp . id_product IN ( '.implode(' , ', $ids_products).' ))
WHERE 1
AND DATE_SUB ( NOW (), INTERVAL 9 DAY ) <= c . date_upd
AND DATE_SUB ( NOW (), INTERVAL 1 DAY ) >= c . date_upd
2016-06-01 10:16:39 +02:00
AND o . id_order IS NULL ' ; */
$sql = '
SELECT DISTINCT c . id_cart , c . id_lang , cu . id_default_group , cu . id_customer , c . id_shop , cu . firstname , cu . lastname , cu . email
FROM '._DB_PREFIX_.' cart c
LEFT JOIN '._DB_PREFIX_.' orders o ON ( o . id_cart = c . id_cart )
LEFT JOIN `'._DB_PREFIX_.'log_email` le ON ( le . `id_cart` = c . `id_cart` AND le . `id_email_type` = 1 )
RIGHT JOIN '._DB_PREFIX_.' customer cu ON ( cu . id_customer = c . id_customer )
RIGHT JOIN '._DB_PREFIX_.' cart_product cp ON ( cp . id_cart = c . id_cart AND cp . id_product IN ( '.implode(' , ', $ids_products).' ))
WHERE 1
-- AND DATE_SUB ( NOW (), INTERVAL 9 DAY ) <= c . date_add
-- AND DATE_SUB ( NOW (), INTERVAL 1 DAY ) >= c . date_add
AND DATE_SUB ( NOW (), INTERVAL 5 HOUR ) <= c . date_upd
AND DATE_SUB ( NOW (), INTERVAL 3 HOUR ) >= c . date_upd
AND le . `id_log_email` IS NULL
AND o . id_order IS NULL ' ;
2016-04-14 16:14:31 +02:00
$sql .= Shop :: addSqlRestriction ( Shop :: SHARE_CUSTOMER , 'c' );
2016-06-01 10:16:39 +02:00
/* if ( ! empty ( $email_logs )){
2016-04-14 16:14:31 +02:00
$sql .= '
AND c . id_cart NOT IN ( '.join(' , ', $email_logs).' ) ' ;
2016-06-01 10:16:39 +02:00
} */
2016-04-14 16:14:31 +02:00
$sql .= ' LIMIT 100' ;
$emails = Db :: getInstance () -> executeS ( $sql );
if ( $count || ! count ( $emails )){
return count ( $emails );
}
$order_url = Context :: getContext () -> link -> getPageLink ( 'order.php' , true , Context :: getContext () -> language -> id , null , false );
$shop_url = Context :: getContext () -> link -> getPageLink ( 'index' , true , Context :: getContext () -> language -> id , null , false );
$img_url = $shop_url . 'themes/' . _THEME_NAME_ . '/img/' ;
2017-01-16 17:59:32 +01:00
// ticket 12164 : remove conf 'PS_FOLLOW_UP_AMOUNT_1' loading, never used here
$conf = Configuration :: getMultiple ( array ( 'PS_FOLLOW_UP_DAYS_1' ));
//$conf = Configuration::getMultiple(array('PS_FOLLOW_UP_AMOUNT_1', 'PS_FOLLOW_UP_DAYS_1'));
2016-04-14 16:14:31 +02:00
foreach ( $emails as $email )
{
// $voucher = $this->createDiscount(1, (float)$conf['PS_FOLLOW_UP_AMOUNT_1'], (int)$email['id_customer'], strftime('%Y-%m-%d', strtotime('+'.(int)$conf['PS_FOLLOW_UP_DAYS_1'].' day')), $this->l('Discount for your cancelled cart'));
// if ($voucher !== false)
// {
//AJOUT 20-01-2015
//Get cart
$cart = new Cart ( intval ( $email [ 'id_cart' ]));
$products = $cart -> getProducts ( true );
$price_display_method = Group :: getPriceDisplayMethod ( $email [ 'id_default_group' ]);
$cartHtml = '' ;
// if (Product::getTaxCalculationMethod())
// $product['is_discounted'] = $product['price_without_specific_price'] != $product['price'];
// else
// $product['is_discounted'] = $product['price_without_specific_price'] != $product['price_wt'];
//Création du panier
$cart_product_context = Context :: getContext () -> cloneContext ();
$cart_product_context -> customer = new Customer ( $cart -> id_customer );
$cart_product_context -> cart = $cart ;
if ( $cart_product_context -> shop -> id != $cart -> id_shop )
{
$cart_product_context -> shop = new Shop (( int ) $cart -> id_shop );
}
$cartText = '' ;
foreach ( $products as $product )
{
2016-05-10 13:04:43 +02:00
$cover = Product :: getCover ( $product [ 'id_product' ]);
$product [ 'id_image' ] = $cover [ 'id_image' ];
2016-04-14 16:14:31 +02:00
$imagePath = Context :: getContext () -> link -> getImageLink ( $product [ 'link_rewrite' ], $product [ 'id_image' ], 'block_cart' ); // change the last parameters to get the size you need
$imagePath = str_replace ( 'https:' , 'http:' , $imagePath );
if ( ! preg_match ( " /^(http):/ " , $imagePath )) {
$imagePath = 'http://' . $imagePath ;
}
if ( ! empty ( $cartHtml ))
{
$cartHtml .= '<tr style="height: 1px;"><td colspan="4" style="height: 1px;"><div style="border-top:1px dashed #778899;max-height: 1px;"> </div>' ;
}
$hack = '' ;
$product [ 'price_without_specific_price' ] = Product :: getPriceStatic (
( int ) $product [ 'id_product' ],
! $price_display_method ,
$product [ 'id_product_attribute' ],
6 ,
null ,
false ,
false ,
1 ,
false ,
null ,
null ,
null ,
$hack ,
true ,
true ,
$cart_product_context
);
$price = ! $price_display_method ? $product [ 'price_wt' ] : $product [ 'price' ];
$cartHtml .= '
< tr style = " border-bottom:3px dashed #778899; " >
< td style = " width:100px; " >
< img style = " max-width: 100px; " src = " '. $imagePath .' " alt = " '. $product['legend'] .' " title = " '. $product['legend'] .' " />
</ td >
< td style = " padding:8px; " >< span style = " color:#484848; " > '.$product[' name '].' </ span ></ td >
< td style = " width:110px; " >
< span style = " color:#F3766E;font-weight:bold; " >
'.Tools::displayPrice($price, (int)$cart->id_currency).' < sup > '.(!$price_display_method ? $this->l(' TTC ') : $this->l(' HT ') ).' </ sup >
</ span > ' ;
if ( ! empty ( $product [ 'price_without_specific_price' ])
&& $product [ 'price_without_specific_price' ] != $price )
$cartHtml .= '<span style="color:#484848;font-size:12px;display:block;">' . $this -> l ( 'au lieu de' ) . '
< span style = " text-decoration: line-through; " > ' .
Tools :: displayPrice ( $product [ 'price_without_specific_price' ], ( int ) $cart -> id_currency ) . '
</ span >
</ span > ' ;
$cartHtml .= '
</ td >
< td align = " center " style = " width:100px; " >
< div style = " margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; " >
< p style = " clear: both; padding: 0; margin: 10px 0 9px 7px; " >
< a href = " '. $order_url .' " style = " color: #fff; text-transform : uppercase; font-size: 14px; display: inline-block; padding: 4px ; margin-bottom: 0; font-size: 13px; font-weight: normal; line-height: 1.42857; text-align: center; vertical-align: middle; cursor: pointer; border: 1px solid transparent; background:#ef5149; border-radius: 0px; white-space: nowrap; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; " >
< span style = " font-size: 12px; background: url('. $img_url .'cart.png) no-repeat 10px center; color: rgb(255, 255, 255); font-family: verdana; text-transform: uppercase; display: inline-block; padding: 10px 15px 10px 35px; border: 1px solid #EF8179; " > '.$this->l(' Finaliser ma ').' < br /> '.$this->l(' commande ').' </ span >
</ a >
</ p >
</ div >
</ td >
</ tr > ' ;
// <td align="center">'.$product['cart_quantity'].'</td>
$cartText .= $product [ 'name' ] . ' - qté : ' . $product [ 'cart_quantity' ] . " \n \r " ;
}
//FIN AJOUT
$template_vars = array (
'{email}' => $email [ 'email' ],
'{lastname}' => $email [ 'lastname' ],
'{firstname}' => $email [ 'firstname' ],
2017-01-16 17:59:32 +01:00
// ticket 12164 : remove conf loading, never used here
//'{amount}' => $conf['PS_FOLLOW_UP_AMOUNT_1'],
2016-04-14 16:14:31 +02:00
'{days}' => $conf [ 'PS_FOLLOW_UP_DAYS_1' ],
// '{voucher_num}' => $voucher->code,
'{cartHtml}' => $cartHtml ,
'{cartText}' => $cartText
);
// coppee@antadis.com
// Mail::Send((int)$email['id_lang'], 'followup_1', Mail::l('Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!', (int)$email['id_lang']), $template_vars, 'coppee@antadis.com', $email['firstname'].' '.$email['lastname'], null, null, null, null, dirname(__FILE__).'/mails/');
2016-05-10 13:04:43 +02:00
// marion@antadis.com
2016-06-01 10:16:39 +02:00
// Mail::Send((int)$email['id_lang'], 'followup_H3', Mail::l('Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!', (int)$email['id_lang']), $template_vars, 'marion@antadis.com', $email['firstname'].' '.$email['lastname'], null, null, null, null, dirname(__FILE__).'/mails/');
2016-05-10 13:04:43 +02:00
2016-04-14 16:14:31 +02:00
// clefebvre@privilegedemarque.com
// Mail::Send((int)$email['id_lang'], 'followup_1', Mail::l('Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!', (int)$email['id_lang']), $template_vars, 'clefebvre@privilegedemarque.com', $email['firstname'].' '.$email['lastname'], null, null, null, null, dirname(__FILE__).'/mails/');
2016-06-01 10:16:39 +02:00
Mail :: Send (( int ) $email [ 'id_lang' ], 'followup_H3' , Mail :: l ( 'Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!' , ( int ) $email [ 'id_lang' ]), $template_vars , $email [ 'email' ], $email [ 'firstname' ] . ' ' . $email [ 'lastname' ], null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
2016-04-14 16:14:31 +02:00
// $this->logEmail(1, (int)$voucher->id, (int)$email['id_customer'], (int)$email['id_cart']);
$this -> logEmail ( 1 , 0 , ( int ) $email [ 'id_customer' ], ( int ) $email [ 'id_cart' ]);
// }
}
}
private function cancelledCartRecall ( $count = false ){
$ids_products = self :: getIdProductOfAllActiveSale ();
if ( count ( $ids_products ) == 0 )
return 0 ;
2016-06-01 10:16:39 +02:00
/* $sql = '
2016-04-14 16:14:31 +02:00
SELECT DISTINCT c . id_cart , c . id_lang , cu . id_customer , cu . id_default_group , c . id_shop , cu . firstname , cu . lastname , cu . email
FROM '._DB_PREFIX_.' cart c
LEFT JOIN '._DB_PREFIX_.' orders o ON ( o . id_cart = c . id_cart )
LEFT JOIN `'._DB_PREFIX_.'log_email` le1 ON ( le1 . `id_cart` = c . `id_cart` AND le1 . `id_email_type` = 1 AND le1 . `id_cart_rule` = 0 )
LEFT JOIN `'._DB_PREFIX_.'log_email` le5 ON ( le5 . `id_cart` = c . `id_cart` AND le5 . `id_email_type` = 5 )
RIGHT JOIN '._DB_PREFIX_.' customer cu ON ( cu . id_customer = c . id_customer )
RIGHT JOIN '._DB_PREFIX_.' cart_product cp ON ( cp . id_cart = c . id_cart AND cp . id_product IN ( '.implode(' , ', $ids_products).' ))
WHERE 1
AND DATE_SUB ( NOW (), INTERVAL 9 DAY ) <= c . date_upd
AND le1 . `id_log_email` IS NOT NULL
AND DATE_SUB ( NOW (), INTERVAL 2 DAY ) >= le1 . `date_add`
AND le5 . `id_log_email` IS NULL
2016-06-01 10:16:39 +02:00
AND o . id_order IS NULL ' ; */
// a verifier pour Si le client n'a pas déjà reçu cette relance pour ce panier
// a verifier Si le client n'a pas déjà reçu cette relance (quelque soit le panier) dans les 2 mois d'avant
$sql = '
SELECT DISTINCT c . id_cart , c . id_lang , cu . id_customer , cu . id_default_group , c . id_shop , cu . firstname , cu . lastname , cu . email
FROM '._DB_PREFIX_.' cart c
LEFT JOIN '._DB_PREFIX_.' orders o ON ( o . id_cart = c . id_cart )
LEFT JOIN '._DB_PREFIX_.' log_email le1 ON ( le1 . id_cart = c . id_cart AND le1 . id_email_type = 1 AND le1 . id_cart_rule = 0 )
LEFT JOIN '._DB_PREFIX_.' log_email le5 ON ( le5 . id_cart = c . id_cart AND le5 . id_customer = c . id_customer AND le5 . id_email_type = 5 )
RIGHT JOIN '._DB_PREFIX_.' customer cu ON ( cu . id_customer = c . id_customer )
RIGHT JOIN '._DB_PREFIX_.' cart_product cp ON ( cp . id_cart = c . id_cart AND cp . id_product IN ( '.implode(' , ', $ids_products).' ))
WHERE 1
AND le1 . `id_log_email` IS NOT NULL
AND o . id_order IS NULL
AND DATE_SUB ( NOW (), INTERVAL 25 HOUR ) <= c . date_upd
AND DATE_SUB ( NOW (), INTERVAL 23 HOUR ) >= c . date_upd
AND le5 . `id_log_email` IS NULL
AND (
DATE_SUB ( NOW (), INTERVAL 2 MONTH ) > (
SELECT IF ( MAX ( le . `date_add` ), MAX ( le . `date_add` ), " 0000-00-00 00:00:00 " )
FROM '._DB_PREFIX_.' log_email le
WHERE le . id_email_type = 5
AND le . id_customer = cu . id_customer
)
) ' ;
2016-04-14 16:14:31 +02:00
$emails = Db :: getInstance () -> executeS ( $sql );
if ( $count || ! count ( $emails ))
return count ( $emails );
$order_url = Context :: getContext () -> link -> getPageLink ( 'order.php' , true , Context :: getContext () -> language -> id , null , false );
$shop_url = Context :: getContext () -> link -> getPageLink ( 'index' , true , Context :: getContext () -> language -> id , null , false );
$img_url = $shop_url . 'themes/' . _THEME_NAME_ . '/img/' ;
$conf = Configuration :: getMultiple ( array ( 'PS_FOLLOW_UP_AMOUNT_5' , 'PS_FOLLOW_UP_DAYS_5' , 'PS_FOLLOW_UP_MIN_5' ));
foreach ( $emails as $email )
{
2016-06-01 10:16:39 +02:00
// Ajout 22-10-2015
// Get cart
$cart = new Cart ( intval ( $email [ 'id_cart' ]));
$totalWithoutShipping = floatval ( $cart -> getOrderTotal ( true , Cart :: BOTH_WITHOUT_SHIPPING ));
2017-01-16 17:59:32 +01:00
if ( $totalWithoutShipping < self :: $cancelled_cart_min_amount_order ) {
2016-06-01 10:16:39 +02:00
continue ;
}
// $voucher = $this->createDiscount(1, (float)$conf['PS_FOLLOW_UP_AMOUNT_5'], (int)$email['id_customer'], strftime('%Y-%m-%d', strtotime('+'.(int)$conf['PS_FOLLOW_UP_DAYS_5'].' day')), $this->l('Discount for your cancelled cart'));
$voucher = $this -> createAdvancedDiscount ( 1 , ( float ) $conf [ 'PS_FOLLOW_UP_AMOUNT_5' ], 0 , ( int ) $email [ 'id_customer' ], strftime ( '%Y-%m-%d' , strtotime ( '+' . ( int ) $conf [ 'PS_FOLLOW_UP_DAYS_5' ] . ' day' )), $this -> l ( 'Discount for your cancelled cart' ), 0 , ( int ) $conf [ 'PS_FOLLOW_UP_MIN_5' ]);
if ( $voucher !== false )
2016-04-14 16:14:31 +02:00
{
//AJOUT 20-01-2015
//Get cart
2016-06-01 10:16:39 +02:00
// $cart = new Cart(intval($email['id_cart']));
2016-04-14 16:14:31 +02:00
$products = $cart -> getProducts ( true );
$price_display_method = Group :: getPriceDisplayMethod ( $email [ 'id_default_group' ]);
$cartHtml = '' ;
//Création du panier
$cart_product_context = Context :: getContext () -> cloneContext ();
$cart_product_context -> customer = new Customer ( $cart -> id_customer );
$cart_product_context -> cart = $cart ;
if ( $cart_product_context -> shop -> id != $cart -> id_shop )
{
$cart_product_context -> shop = new Shop (( int ) $cart -> id_shop );
}
$cartText = '' ;
foreach ( $products as $product )
{
2016-05-10 13:04:43 +02:00
$cover = Product :: getCover ( $product [ 'id_product' ]);
$product [ 'id_image' ] = $cover [ 'id_image' ];
2016-04-14 16:14:31 +02:00
$imagePath = Context :: getContext () -> link -> getImageLink ( $product [ 'link_rewrite' ], $product [ 'id_image' ], 'block_cart' ); // change the last parameters to get the size you need
$imagePath = str_replace ( 'https:' , 'http:' , $imagePath );
if ( ! preg_match ( " /^(http):/ " , $imagePath )) {
$imagePath = 'http://' . $imagePath ;
}
if ( ! empty ( $cartHtml ))
{
$cartHtml .= '<tr style="height: 1px;"><td colspan="4" style="height: 1px;"><div style="border-top:1px dashed #778899;max-height: 1px;"> </div>' ;
}
$hack = '' ;
$product [ 'price_without_specific_price' ] = Product :: getPriceStatic (
( int ) $product [ 'id_product' ],
! $price_display_method ,
$product [ 'id_product_attribute' ],
6 ,
null ,
false ,
false ,
1 ,
false ,
null ,
null ,
null ,
$hack ,
true ,
true ,
$cart_product_context
);
$price = ! $price_display_method ? $product [ 'price_wt' ] : $product [ 'price' ];
$cartHtml .= '
< tr style = " border-bottom:3px dashed #778899; " >
< td style = " width:100px; " >
< img style = " margin: -20px; " src = " '. $imagePath .' " alt = " '. $product['legend'] .' " title = " '. $product['legend'] .' " />
</ td >
< td style = " padding:8px; " >< span style = " color:#484848; " > '.$product[' name '].' </ span ></ td >
< td style = " width:110px; " >
< span style = " color:#F3766E;font-weight:bold; " >
'.Tools::displayPrice($price, (int)$cart->id_currency).' < sup > '.(!$price_display_method ? $this->l(' TTC ') : $this->l(' HT ') ).' </ sup >
</ span > ' ;
if ( ! empty ( $product [ 'price_without_specific_price' ])
&& $product [ 'price_without_specific_price' ] != $price )
$cartHtml .= '<span style="color:#484848;font-size:12px;display:block;">' . $this -> l ( 'au lieu de' ) . '
< span style = " text-decoration: line-through; " > ' .
Tools :: displayPrice ( $product [ 'price_without_specific_price' ], ( int ) $cart -> id_currency ) . '
</ span >
</ span > ' ;
$cartHtml .= '
</ td >
< td align = " center " style = " width:100px; " >
< div style = " margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; " >
< p style = " clear: both; padding: 0; margin: 10px 0 9px 7px; " >
< a href = " '. $order_url .' " style = " color: #fff; text-transform : uppercase; font-size: 14px; display: inline-block; padding: 4px ; margin-bottom: 0; font-size: 13px; font-weight: normal; line-height: 1.42857; text-align: center; vertical-align: middle; cursor: pointer; border: 1px solid transparent; background:#ef5149; border-radius: 0px; white-space: nowrap; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; " >
< span style = " font-size: 12px; background: url('. $img_url .'cart.png) no-repeat 10px center; color: rgb(255, 255, 255); font-family: verdana; text-transform: uppercase; display: inline-block; padding: 10px 15px 10px 35px; border: 1px solid #EF8179; " > '.$this->l(' Finaliser ma ').' < br /> '.$this->l(' commande ').' </ span >
</ a >
</ p >
</ div >
</ td >
</ tr > ' ;
// <td align="center">'.$product['cart_quantity'].'</td>
$cartText .= $product [ 'name' ] . ' - qté : ' . $product [ 'cart_quantity' ] . " \n \r " ;
}
//FIN AJOUT
$template_vars = array (
'{email}' => $email [ 'email' ],
'{lastname}' => $email [ 'lastname' ],
'{firstname}' => $email [ 'firstname' ],
'{amount}' => $conf [ 'PS_FOLLOW_UP_AMOUNT_5' ],
'{days}' => $conf [ 'PS_FOLLOW_UP_DAYS_5' ],
'{voucher_num}' => $voucher -> code ,
'{cartHtml}' => $cartHtml ,
'{cartText}' => $cartText
);
// coppee@antadis.com
// Mail::Send((int)$email['id_lang'], 'followup_1', Mail::l('Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!', (int)$email['id_lang']), $template_vars, 'coppee@antadis.com', $email['firstname'].' '.$email['lastname'], null, null, null, null, dirname(__FILE__).'/mails/');
2016-05-10 13:04:43 +02:00
// marion@antadis.com
2016-06-01 10:16:39 +02:00
// Mail::Send((int)$email['id_lang'], 'followup_H24', Mail::l('Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!', (int)$email['id_lang']), $template_vars, 'marion@antadis.com', $email['firstname'].' '.$email['lastname'], null, null, null, null, dirname(__FILE__).'/mails/');
2016-05-10 13:04:43 +02:00
2016-04-14 16:14:31 +02:00
// clefebvre@privilegedemarque.com
// Mail::Send((int)$email['id_lang'], 'followup_1', Mail::l('Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!', (int)$email['id_lang']), $template_vars, 'clefebvre@privilegedemarque.com', $email['firstname'].' '.$email['lastname'], null, null, null, null, dirname(__FILE__).'/mails/');
2016-06-01 10:16:39 +02:00
Mail :: Send (( int ) $email [ 'id_lang' ], 'followup_H24' , Mail :: l ( 'Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!' , ( int ) $email [ 'id_lang' ]), $template_vars , $email [ 'email' ], $email [ 'firstname' ] . ' ' . $email [ 'lastname' ], null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
2016-04-14 16:14:31 +02:00
$this -> logEmail ( 5 , ( int ) $voucher -> id , ( int ) $email [ 'id_customer' ], ( int ) $email [ 'id_cart' ]);
}
}
}
private function getLogsEmail ( $email_type )
{
static $id_list = array (
'1' => array (),
'2' => array (),
'3' => array (),
'4' => array (),
'5' => array (),
);
static $executed = false ;
if ( ! $executed )
{
$query = '
SELECT id_cart , id_customer , id_email_type FROM '._DB_PREFIX_.' log_email
WHERE id_email_type <> 4 OR date_add >= DATE_SUB ( date_add , INTERVAL '.(int)Configuration::get(' PS_FOLLOW_UP_DAYS_THRESHOLD_4 ').' DAY ) ' ;
$results = Db :: getInstance () -> executeS ( $query );
foreach ( $results as $line )
{
switch ( $line [ 'id_email_type' ])
{
case 1 :
$id_list [ '1' ][] = $line [ 'id_cart' ];
break ;
case 2 :
$id_list [ '2' ][] = $line [ 'id_cart' ];
break ;
case 3 :
$id_list [ '3' ][] = $line [ 'id_customer' ];
break ;
case 4 :
$id_list [ '4' ][] = $line [ 'id_customer' ];
break ;
case 5 :
$id_list [ '5' ][] = $line [ 'id_cart' ];
break ;
}
}
$executed = true ;
}
return $id_list [ $email_type ];
}
/* For all validated orders, a discount if re-ordering before x days */
private function reOrder ( $count = false )
{
$email_logs = $this -> getLogsEmail ( 2 );
$sql = '
SELECT o . id_order , c . id_cart , o . id_lang , o . id_shop , cu . id_customer , cu . firstname , cu . lastname , cu . email
FROM '._DB_PREFIX_.' orders o
LEFT JOIN '._DB_PREFIX_.' customer cu ON ( cu . id_customer = o . id_customer )
LEFT JOIN '._DB_PREFIX_.' cart c ON ( c . id_cart = o . id_cart )
WHERE o . valid = 1
AND c . date_add >= DATE_SUB ( CURDATE (), INTERVAL 7 DAY )
AND cu . is_guest = 0 ' ;
$sql .= Shop :: addSqlRestriction ( Shop :: SHARE_CUSTOMER , 'o' );
if ( ! empty ( $email_logs ))
$sql .= ' AND o.id_cart NOT IN (' . join ( ',' , $email_logs ) . ')' ;
$emails = Db :: getInstance () -> executeS ( $sql );
if ( $count || ! count ( $emails ))
return count ( $emails );
$conf = Configuration :: getMultiple ( array ( 'PS_FOLLOW_UP_AMOUNT_2' , 'PS_FOLLOW_UP_DAYS_2' ));
foreach ( $emails as $email )
{
$voucher = $this -> createDiscount ( 2 , ( float ) $conf [ 'PS_FOLLOW_UP_AMOUNT_2' ], ( int ) $email [ 'id_customer' ], strftime ( '%Y-%m-%d' , strtotime ( '+' . ( int ) $conf [ 'PS_FOLLOW_UP_DAYS_2' ] . ' day' )), $this -> l ( 'Thank you for your order.' ));
if ( $voucher !== false )
{
$template_vars = array (
'{email}' => $email [ 'email' ],
'{lastname}' => $email [ 'lastname' ],
'{firstname}' => $email [ 'firstname' ],
'{amount}' => $conf [ 'PS_FOLLOW_UP_AMOUNT_2' ],
'{days}' => $conf [ 'PS_FOLLOW_UP_DAYS_2' ],
'{voucher_num}' => $voucher -> code
);
$object = " Bénéficiez de " . $conf [ 'PS_FOLLOW_UP_AMOUNT_2' ] . " .% sur votre prochaine commande, profitez-en dès à présent! " ;
Mail :: Send (( int ) $email [ 'id_lang' ], 'followup_2' , $object , $template_vars , $email [ 'email' ], $email [ 'firstname' ] . ' ' . $email [ 'lastname' ], null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
$this -> logEmail ( 2 , ( int ) $voucher -> id , ( int ) $email [ 'id_customer' ], ( int ) $email [ 'id_cart' ]);
}
}
}
/* For all customers with more than x euros in 90 days */
private function bestCustomer ( $count = false )
{
$email_logs = $this -> getLogsEmail ( 3 );
$sql = '
SELECT SUM ( o . total_paid ) total , c . id_cart , o . id_lang , cu . id_customer , cu . id_shop , cu . firstname , cu . lastname , cu . email
FROM '._DB_PREFIX_.' orders o
LEFT JOIN '._DB_PREFIX_.' customer cu ON ( cu . id_customer = o . id_customer )
LEFT JOIN '._DB_PREFIX_.' cart c ON ( c . id_cart = o . id_cart )
WHERE o . valid = 1
AND DATE_SUB ( CURDATE (), INTERVAL 90 DAY ) <= o . date_add
AND cu . is_guest = 0 ' ;
$sql .= Shop :: addSqlRestriction ( Shop :: SHARE_CUSTOMER , 'o' );
if ( ! empty ( $email_logs ))
$sql .= ' AND cu.id_customer NOT IN (' . join ( ',' , $email_logs ) . ') ' ;
$sql .= '
GROUP BY o . id_customer
HAVING total >= '.(float)Configuration::get(' PS_FOLLOW_UP_THRESHOLD_3 ' );
$emails = Db :: getInstance () -> executeS ( $sql );
if ( $count || ! count ( $emails ))
return count ( $emails );
$conf = Configuration :: getMultiple ( array ( 'PS_FOLLOW_UP_AMOUNT_3' , 'PS_FOLLOW_UP_DAYS_3' ));
foreach ( $emails as $email )
{
$voucher = $this -> createDiscount ( 3 , ( float ) $conf [ 'PS_FOLLOW_UP_AMOUNT_3' ], ( int ) $email [ 'id_customer' ], strftime ( '%Y-%m-%d' , strtotime ( '+' . ( int ) $conf [ 'PS_FOLLOW_UP_DAYS_3' ] . ' day' )), $this -> l ( 'You are one of our best customers!' ));
if ( $voucher !== false )
{
$template_vars = array (
'{email}' => $email [ 'email' ],
'{lastname}' => $email [ 'lastname' ],
'{firstname}' => $email [ 'firstname' ],
'{amount}' => $conf [ 'PS_FOLLOW_UP_AMOUNT_3' ],
'{days}' => $conf [ 'PS_FOLLOW_UP_DAYS_3' ],
'{voucher_num}' => $voucher -> code
);
$object = " Nous vous offrons " . $conf [ 'PS_FOLLOW_UP_AMOUNT_3' ] . " % pour votre fidélité privilégiée. " ;
Mail :: Send (( int ) $email [ 'id_lang' ], 'followup_3' , $object , $template_vars , $email [ 'email' ], $email [ 'firstname' ] . ' ' . $email [ 'lastname' ], null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
$this -> logEmail ( 3 , ( int ) $voucher -> id , ( int ) $email [ 'id_customer' ], ( int ) $email [ 'id_cart' ]);
}
}
}
/* For all customers with no orders since more than x days */
/**
* badCustomer send mails to all customers with no orders since more than x days ,
* with at least one valid order in history
*
* @ param boolean $count if set to true , will return number of customer ( default : false , will send mails , no return value )
*
* @ return void
*/
private function badCustomer ( $count = false )
{
$email_logs = $this -> getLogsEmail ( 4 );
$sql = '
SELECT o . id_lang , c . id_cart , cu . id_customer , cu . id_shop , cu . firstname , cu . lastname , cu . email , ( SELECT COUNT ( o . id_order ) FROM '._DB_PREFIX_.' orders o WHERE o . id_customer = cu . id_customer and o . valid = 1 ) nb_orders
FROM '._DB_PREFIX_.' customer cu
LEFT JOIN '._DB_PREFIX_.' orders o ON ( o . id_customer = cu . id_customer )
LEFT JOIN '._DB_PREFIX_.' cart c ON ( c . id_cart = o . id_cart )
WHERE cu . id_customer NOT IN ( SELECT o . id_customer FROM '._DB_PREFIX_.' orders o WHERE DATE_SUB ( CURDATE (), INTERVAL '.(int)Configuration::get(' PS_FOLLOW_UP_DAYS_THRESHOLD_4 ').' DAY ) <= o . date_add )
AND cu . is_guest = 0 ' ;
$sql .= Shop :: addSqlRestriction ( Shop :: SHARE_CUSTOMER , 'cu' );
if ( ! empty ( $email_logs ))
$sql .= ' AND cu.id_customer NOT IN (' . join ( ',' , $email_logs ) . ') ' ;
$sql .= ' GROUP BY cu.id_customer HAVING nb_orders >= 1' ;
$emails = Db :: getInstance () -> executeS ( $sql );
if ( $count || ! count ( $emails ))
return count ( $emails );
$conf = Configuration :: getMultiple ( array ( 'PS_FOLLOW_UP_AMOUNT_4' , 'PS_FOLLOW_UP_DAYS_4' ));
foreach ( $emails as $email )
{
$voucher = $this -> createDiscount ( 4 , ( float ) $conf [ 'PS_FOLLOW_UP_AMOUNT_4' ], ( int ) $email [ 'id_customer' ], strftime ( '%Y-%m-%d' , strtotime ( '+' . ( int ) $conf [ 'PS_FOLLOW_UP_DAYS_4' ] . ' day' )), $this -> l ( 'We miss you!' ));
if ( $voucher !== false )
{
$template_vars = array (
'{email}' => $email [ 'email' ],
'{lastname}' => $email [ 'lastname' ],
'{firstname}' => $email [ 'firstname' ],
'{amount}' => $conf [ 'PS_FOLLOW_UP_AMOUNT_4' ],
'{days}' => $conf [ 'PS_FOLLOW_UP_DAYS_4' ],
'{days_threshold}' => ( int ) Configuration :: get ( 'PS_FOLLOW_UP_DAYS_THRESHOLD_4' ),
'{voucher_num}' => $voucher -> code
);
Mail :: Send (( int ) $email [ 'id_lang' ], 'followup_4' , Mail :: l ( 'Vous nous manquez, revenez!' , ( int ) $email [ 'id_lang' ]), $template_vars , $email [ 'email' ], $email [ 'firstname' ] . ' ' . $email [ 'lastname' ], null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
$this -> logEmail ( 4 , ( int ) $voucher -> id , ( int ) $email [ 'id_customer' ], ( int ) $email [ 'id_cart' ]);
}
}
}
private function createDiscount ( $id_email_type , $amount , $id_customer , $date_validity , $description , $free_shipping = false )
{
$cart_rule = new CartRule ();
$cart_rule -> reduction_percent = ( float ) $amount ;
$cart_rule -> id_customer = ( int ) $id_customer ;
$cart_rule -> date_to = $date_validity ;
$cart_rule -> date_from = date ( 'Y-m-d H:i:s' );
$cart_rule -> quantity = 1 ;
$cart_rule -> quantity_per_user = 1 ;
$cart_rule -> cart_rule_restriction = 1 ;
$cart_rule -> minimum_amount = 0 ;
if ( $free_shipping )
$cart_rule -> free_shipping = 1 ;
$languages = Language :: getLanguages ( true );
foreach ( $languages as $language )
$cart_rule -> name [( int ) $language [ 'id_lang' ]] = $description ;
$code = 'FLW-' . ( int ) $id_email_type . '-' . Tools :: strtoupper ( Tools :: passwdGen ( 10 ));
2016-06-01 10:16:39 +02:00
// $code = 'PRIVILEGE'.Tools::strtoupper(Tools::passwdGen(4));
2016-04-14 16:14:31 +02:00
$cart_rule -> code = $code ;
$cart_rule -> active = 1 ;
if ( ! $cart_rule -> add ())
return false ;
return $cart_rule ;
}
/**
* @ Override Create advanced discount with more options
*/
private function createAdvancedDiscount ( $id_email_type , $reduction_percent = 0 , $reduction_amount = 0 , $id_customer , $date_validity , $description , $cart_rule_restriction = 0 , $minimum_amount = 0 , $highlight = 1 )
{
$cart_rule = new CartRule ();
$cart_rule -> id_customer = ( int ) $id_customer ;
$cart_rule -> date_from = date ( 'Y-m-d H:i:s' );
$cart_rule -> date_to = $date_validity ;
$cart_rule -> minimum_amount = $minimum_amount ;
$cart_rule -> minimum_amount_tax = 1 ;
$cart_rule -> cart_rule_restriction = 0 ;
$cart_rule -> reduction_percent = ( float ) $reduction_percent ;
$cart_rule -> reduction_amount = ( float ) $reduction_amount ;
$cart_rule -> reduction_tax = 1 ;
$cart_rule -> quantity = 1 ;
$cart_rule -> quantity_per_user = 1 ;
$cart_rule -> highlight = $highlight ;
/* Modification */
if (( $minimum_amount - ( float ) $reduction_amount ) > 0 ){
$cart_rule -> partial_use = 0 ;
} else {
$cart_rule -> partial_use = 1 ;
}
/* end of Modification */
$languages = Language :: getLanguages ( true );
foreach ( $languages as $language )
$cart_rule -> name [( int ) $language [ 'id_lang' ]] = $description ;
2016-06-01 10:16:39 +02:00
$code = 'PRIVILEGE' . Tools :: strtoupper ( Tools :: passwdGen ( 4 ));
2016-04-14 16:14:31 +02:00
$cart_rule -> code = $code ;
$cart_rule -> active = 1 ;
if ( ! $cart_rule -> add ())
return false ;
return $cart_rule ;
}
public function cronTask ()
{
Context :: getContext () -> link = new Link (); //when this is call by cron context is not init
$conf = Configuration :: getMultiple ( array (
'PS_FOLLOW_UP_ENABLE_1' ,
'PS_FOLLOW_UP_ENABLE_2' ,
'PS_FOLLOW_UP_ENABLE_3' ,
'PS_FOLLOW_UP_ENABLE_4' ,
'PS_FOLLOW_UP_ENABLE_5' ,
'PS_FOLLOW_UP_CLEAN_DB'
));
if ( $conf [ 'PS_FOLLOW_UP_ENABLE_1' ])
$this -> cancelledCart ();
if ( $conf [ 'PS_FOLLOW_UP_ENABLE_2' ])
$this -> reOrder ();
if ( $conf [ 'PS_FOLLOW_UP_ENABLE_3' ])
$this -> bestCustomer ();
if ( $conf [ 'PS_FOLLOW_UP_ENABLE_4' ])
$this -> badCustomer ();
if ( $conf [ 'PS_FOLLOW_UP_ENABLE_5' ])
$this -> cancelledCartRecall ();
/* Clean-up database by deleting all outdated discounts */
if ( $conf [ 'PS_FOLLOW_UP_CLEAN_DB' ] == 1 )
{
$outdated_discounts = Db :: getInstance () -> executeS ( 'SELECT id_cart_rule FROM ' . _DB_PREFIX_ . 'cart_rule WHERE date_to < NOW() AND code LIKE "FLW-%"' );
foreach ( $outdated_discounts as $outdated_discount )
{
$cart_rule = new CartRule (( int ) $outdated_discount [ 'id_cart_rule' ]);
if ( Validate :: isLoadedObject ( $cart_rule ))
$cart_rule -> delete ();
}
}
}
public function renderStats ()
{
$sql = '
SELECT DATE_FORMAT ( l . date_add , \ ' % Y -% m -% d\ ' ) date_stat , l . id_email_type , COUNT ( l . id_log_email ) nb ,
( SELECT COUNT ( l2 . id_cart_rule )
FROM '._DB_PREFIX_.' log_email l2
LEFT JOIN '._DB_PREFIX_.' order_cart_rule ocr ON ( ocr . id_cart_rule = l2 . id_cart_rule )
LEFT JOIN '._DB_PREFIX_.' orders o ON ( o . id_order = ocr . id_order )
WHERE l2 . id_email_type = l . id_email_type AND l2 . date_add = l . date_add AND ocr . id_order IS NOT NULL AND o . valid = 1 ) nb_used
FROM '._DB_PREFIX_.' log_email l
WHERE l . date_add >= DATE_SUB ( CURDATE (), INTERVAL 30 DAY )
GROUP BY DATE_FORMAT ( l . date_add , \ '%Y-%m-%d\'), l.id_email_type' ;
$stats = Db :: getInstance ( _PS_USE_SQL_SLAVE_ ) -> executeS ( $sql );
$stats_array = array ();
foreach ( $stats as $stat )
{
$stats_array [ $stat [ 'date_stat' ]][ $stat [ 'id_email_type' ]][ 'nb' ] = ( int ) $stat [ 'nb' ];
$stats_array [ $stat [ 'date_stat' ]][ $stat [ 'id_email_type' ]][ 'nb_used' ] = ( int ) $stat [ 'nb_used' ];
}
foreach ( $stats_array as $date_stat => $array )
{
$rates = array ();
for ( $i = 1 ; $i != 6 ; $i ++ )
if ( isset ( $stats_array [ $date_stat ][ $i ][ 'nb' ]) && isset ( $stats_array [ $date_stat ][ $i ][ 'nb_used' ]) && $stats_array [ $date_stat ][ $i ][ 'nb_used' ] > 0 )
$rates [ $i ] = number_format (( $stats_array [ $date_stat ][ $i ][ 'nb_used' ] / $stats_array [ $date_stat ][ $i ][ 'nb' ]) * 100 , 2 , '.' , '' );
for ( $i = 1 ; $i != 6 ; $i ++ )
{
$stats_array [ $date_stat ][ $i ][ 'nb' ] = isset ( $stats_array [ $date_stat ][ $i ][ 'nb' ]) ? ( int ) $stats_array [ $date_stat ][ $i ][ 'nb' ] : 0 ;
$stats_array [ $date_stat ][ $i ][ 'nb_used' ] = isset ( $stats_array [ $date_stat ][ $i ][ 'nb_used' ]) ? ( int ) $stats_array [ $date_stat ][ $i ][ 'nb_used' ] : 0 ;
$stats_array [ $date_stat ][ $i ][ 'rate' ] = isset ( $rates [ $i ]) ? $rates [ $i ] : '0.00' ;
}
ksort ( $stats_array [ $date_stat ]);
}
$this -> context -> smarty -> assign ( array ( 'stats_array' => $stats_array ));
return $this -> display ( __FILE__ , 'stats.tpl' );
}
public function renderForm ()
{
$currency = new Currency (( int ) Configuration :: get ( 'PS_CURRENCY_DEFAULT' ));
$n1 = $this -> cancelledCart ( true );
$n2 = $this -> reOrder ( true );
$n3 = $this -> bestCustomer ( true );
$n4 = $this -> badCustomer ( true );
$n5 = $this -> cancelledCartRecall ( true );
$cron_info = '' ;
if ( Shop :: getContext () === Shop :: CONTEXT_SHOP )
$cron_info = $this -> l ( 'Define the settings and place the following URL in the crontab, or call it manually on a daily basis:' ) . ' < br />
< b > '.$this->context->shop->getBaseURL().' modules / followup / cron . php ? secure_key = '.Configuration::get(' PS_FOLLOWUP_SECURE_KEY ').' </ b ></ p > ' ;
$fields_form_info = array (
'form' => array (
'legend' => array (
'title' => $this -> l ( 'Informations' ),
'icon' => 'icon-cogs' ,
),
'description' => $this -> l ( 'Four kinds of e-mail alerts are available in order to stay in touch with your customers!' ) . '<br />' . $cron_info ,
)
);
$fields_form_1 = array (
'form' => array (
'legend' => array (
2017-01-16 17:59:32 +01:00
// ticket 12164 - change title to explicit it
2017-01-16 18:10:14 +01:00
'title' => $this -> l ( 'Paniers annulés (1ère relance)' ),
2016-04-14 16:14:31 +02:00
'icon' => 'icon-cogs'
),
2017-01-16 17:59:32 +01:00
// ticket 12164 - change sentence to explicit it
2017-01-16 18:10:14 +01:00
'description' => $this -> l ( 'Pour chaque panier abandonné (sans commande), envoit un premier email de relance au client (pas de bon de réduction).' ),
2017-01-16 17:59:32 +01:00
//'description' => $this->l('For each cancelled cart (with no order), generate a discount and send it to the customer.'),
2016-04-14 16:14:31 +02:00
'input' => array (
array (
'type' => 'switch' ,
'is_bool' => true , //retro-compat
'label' => $this -> l ( 'Enable' ),
'name' => 'PS_FOLLOW_UP_ENABLE_1' ,
'values' => array (
array (
'id' => 'active_on' ,
'value' => 1 ,
'label' => $this -> l ( 'Enabled' )
),
array (
'id' => 'active_off' ,
'value' => 0 ,
'label' => $this -> l ( 'Disabled' )
)
),
),
2017-01-16 17:59:32 +01:00
// ticket 12164 - never used
/*
2016-04-14 16:14:31 +02:00
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount amount' ),
'name' => 'PS_FOLLOW_UP_AMOUNT_1' ,
'suffix' => '%' ,
),
2017-01-16 17:59:32 +01:00
*/
2016-04-14 16:14:31 +02:00
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount validity' ),
'name' => 'PS_FOLLOW_UP_DAYS_1' ,
'suffix' => $this -> l ( 'day(s)' ),
),
array (
'type' => 'desc' ,
'name' => '' ,
'text' => sprintf ( $this -> l ( 'The next process will send %d e-mail(s).' ), $n1 )
),
),
'submit' => array (
'title' => $this -> l ( 'Save' ),
'class' => 'btn btn-default pull-right'
)
),
);
$fields_form_2 = array (
'form' => array (
'legend' => array (
'title' => $this -> l ( 'Re-order' ),
'icon' => 'icon-cogs'
),
'description' => $this -> l ( 'For each validated order, generate a discount and send it to the customer.' ),
'input' => array (
array (
'type' => 'switch' ,
'is_bool' => true , //retro-compat
'label' => $this -> l ( 'Enable' ),
'name' => 'PS_FOLLOW_UP_ENABLE_2' ,
'values' => array (
array (
'id' => 'active_on' ,
'value' => 1 ,
'label' => $this -> l ( 'Enabled' )
),
array (
'id' => 'active_off' ,
'value' => 0 ,
'label' => $this -> l ( 'Disabled' )
)
),
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount amount' ),
'name' => 'PS_FOLLOW_UP_AMOUNT_2' ,
'suffix' => '%' ,
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount validity' ),
'name' => 'PS_FOLLOW_UP_DAYS_2' ,
'suffix' => $this -> l ( 'day(s)' ),
),
array (
'type' => 'desc' ,
'name' => '' ,
'text' => sprintf ( $this -> l ( 'Next process will send: %d e-mail(s)' ), $n2 )
),
),
'submit' => array (
'title' => $this -> l ( 'Save' ),
'class' => 'btn btn-default pull-right'
)
),
);
$fields_form_3 = array (
'form' => array (
'legend' => array (
'title' => $this -> l ( 'Best customers' ),
'icon' => 'icon-cogs'
),
'description' => $this -> l ( 'For each customer raising a threshold, generate a discount and send it to the customer.' ),
'input' => array (
array (
'type' => 'switch' ,
'is_bool' => true , //retro-compat
'label' => $this -> l ( 'Enable' ),
'name' => 'PS_FOLLOW_UP_ENABLE_3' ,
'values' => array (
array (
'id' => 'active_on' ,
'value' => 1 ,
'label' => $this -> l ( 'Enabled' )
),
array (
'id' => 'active_off' ,
'value' => 0 ,
'label' => $this -> l ( 'Disabled' )
)
),
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount amount' ),
'name' => 'PS_FOLLOW_UP_AMOUNT_3' ,
'suffix' => '%' ,
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Threshold' ),
'name' => 'PS_FOLLOW_UP_THRESHOLD_3' ,
'suffix' => $currency -> sign ,
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount validity' ),
'name' => 'PS_FOLLOW_UP_DAYS_3' ,
'suffix' => $this -> l ( 'day(s)' ),
),
array (
'type' => 'desc' ,
'name' => '' ,
'text' => sprintf ( $this -> l ( 'Next process will send: %d e-mail(s)' ), $n3 )
),
),
'submit' => array (
'title' => $this -> l ( 'Save' ),
'class' => 'btn btn-default pull-right'
)
),
);
$fields_form_4 = array (
'form' => array (
'legend' => array (
'title' => $this -> l ( 'Bad customers' ),
'icon' => 'icon-cogs'
),
'description' => $this -> l ( 'For each customer who has already passed at least one order and with no orders since a given duration, generate a discount and send it to the customer.' ),
'input' => array (
array (
'type' => 'switch' ,
'is_bool' => true , //retro-compat
'label' => $this -> l ( 'Enable' ),
'name' => 'PS_FOLLOW_UP_ENABLE_4' ,
'values' => array (
array (
'id' => 'active_on' ,
'value' => 1 ,
'label' => $this -> l ( 'Enabled' )
),
array (
'id' => 'active_off' ,
'value' => 0 ,
'label' => $this -> l ( 'Disabled' )
)
),
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount amount' ),
'name' => 'PS_FOLLOW_UP_AMOUNT_4' ,
'suffix' => '%' ,
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Since x days' ),
'name' => 'PS_FOLLOW_UP_DAYS_THRESHOLD_4' ,
'suffix' => $this -> l ( 'day(s)' ),
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount validity' ),
'name' => 'PS_FOLLOW_UP_DAYS_4' ,
'suffix' => $this -> l ( 'day(s)' ),
),
array (
'type' => 'desc' ,
'name' => '' ,
'text' => sprintf ( $this -> l ( 'Next process will send: %d e-mail(s)' ), $n4 )
),
),
'submit' => array (
'title' => $this -> l ( 'Save' ),
'class' => 'btn btn-default pull-right'
)
),
);
$fields_form_5 = array (
'form' => array (
'legend' => array (
2017-01-16 17:59:32 +01:00
// ticket 12164 - change title to explicit it
'title' => $this -> l ( 'Relance avec remise (si précédente sans réponse)' ),
2016-04-14 16:14:31 +02:00
'icon' => 'icon-cogs'
),
2017-01-16 18:10:14 +01:00
'description' => sprintf ( $this -> l ( 'Pour chaque panier abandonné (ayant un montant minimum de %d €) et si le client n\'a pas répondu au précédent email, génère un bon d\'achat et l\'envoit au client.' ), self :: $cancelled_cart_min_amount_order ),
2016-04-14 16:14:31 +02:00
'input' => array (
array (
'type' => 'switch' ,
'is_bool' => true , //retro-compat
'label' => $this -> l ( 'Enable' ),
'name' => 'PS_FOLLOW_UP_ENABLE_5' ,
'values' => array (
array (
'id' => 'active_on' ,
'value' => 1 ,
'label' => $this -> l ( 'Enabled' )
),
array (
'id' => 'active_off' ,
'value' => 0 ,
'label' => $this -> l ( 'Disabled' )
)
),
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount amount' ),
'name' => 'PS_FOLLOW_UP_AMOUNT_5' ,
2016-06-01 10:16:39 +02:00
'suffix' => '%' ,
2016-04-14 16:14:31 +02:00
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount min' ),
'name' => 'PS_FOLLOW_UP_MIN_5' ,
'suffix' => '€' ,
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Discount validity' ),
'name' => 'PS_FOLLOW_UP_DAYS_5' ,
'suffix' => $this -> l ( 'day(s)' ),
),
array (
'type' => 'desc' ,
'name' => '' ,
'text' => sprintf ( $this -> l ( 'The next process will send %d e-mail(s).' ), $n5 )
),
),
'submit' => array (
'title' => $this -> l ( 'Save' ),
'class' => 'btn btn-default pull-right'
)
),
);
$fields_form_settings = array (
'form' => array (
'legend' => array (
'title' => $this -> l ( 'General' ),
'icon' => 'icon-cogs'
),
'input' => array (
array (
'type' => 'switch' ,
'is_bool' => true , //retro-compat
'label' => $this -> l ( 'Delete outdated discounts during each launch to clean database' ),
'name' => 'PS_FOLLOW_UP_CLEAN_DB' ,
'values' => array (
array (
'id' => 'active_on' ,
'value' => 1 ,
'label' => $this -> l ( 'Enabled' )
),
array (
'id' => 'active_off' ,
'value' => 0 ,
'label' => $this -> l ( 'Disabled' )
)
),
),
),
'submit' => array (
'title' => $this -> l ( 'Save' ),
'class' => 'btn btn-default pull-right'
)
),
);
/* @Override */
$mailTemplates = array (
array ( 'id' => 1 , 'name' => 'Paniers annulés (cancelledCart)' ),
array ( 'id' => 5 , 'name' => 'Relance paniers annulés (cancelledCartRecall)' ),
// array('id' => 2, 'name' => 'reOrder'),
// array('id' => 3, 'name' => 'bestCustomer'),
// array('id' => 4, 'name' => 'badCustomer'),
);
$fields_form_test = array (
'form' => array (
'legend' => array (
'title' => $this -> l ( 'Send test mail' ),
'icon' => 'icon-cogs'
),
'input' => array (
array (
'type' => 'select' ,
'options' => array (
'query' => $mailTemplates ,
'id' => 'id' ,
'name' => 'name'
),
'label' => $this -> l ( 'Mail tempalte' ),
'name' => 'id_email_test'
),
array (
'type' => 'text' ,
'label' => $this -> l ( 'Email address' ),
'name' => 'email_test'
),
),
'submit' => array (
'title' => $this -> l ( 'Send Mail' ),
'class' => 'btn btn-default pull-right' ,
'name' => 'sendMailTest'
)
),
);
$exportOptions = array (
array ( 'id' => 1 , 'name' => 'Paniers abandonnés' ),
// array('id' => 5, 'name' => 'cancelledCartRecall'),
// array('id' => 2, 'name' => 'reOrder'),
// array('id' => 3, 'name' => 'bestCustomer'),
array ( 'id' => 4 , 'name' => 'Mauvais Clients' ),
);
$fields_form_export = array (
'form' => array (
'legend' => array (
'title' => $this -> l ( 'Export' ),
'icon' => 'icon-cogs'
),
'input' => array (
array (
'type' => 'select' ,
'options' => array (
'query' => $exportOptions ,
'id' => 'id' ,
'name' => 'name'
),
'label' => $this -> l ( 'Mail tempalte' ),
'name' => 'id_export_type'
),
),
'submit' => array (
'title' => $this -> l ( 'Export' ),
'class' => 'btn btn-default pull-right' ,
'name' => 'flw_export'
)
),
);
$helper = new HelperForm ();
$helper -> show_toolbar = false ;
$helper -> table = $this -> table ;
$lang = new Language (( int ) Configuration :: get ( 'PS_LANG_DEFAULT' ));
$helper -> default_form_language = $lang -> id ;
$helper -> allow_employee_form_lang = Configuration :: get ( 'PS_BO_ALLOW_EMPLOYEE_FORM_LANG' ) ? Configuration :: get ( 'PS_BO_ALLOW_EMPLOYEE_FORM_LANG' ) : 0 ;
$helper -> identifier = $this -> identifier ;
$helper -> override_folder = '/' ;
$helper -> module = $this ;
$helper -> submit_action = 'submitFollowUp' ;
$helper -> currentIndex = $this -> context -> link -> getAdminLink ( 'AdminModules' , false ) . '&configure=' . $this -> name . '&tab_module=' . $this -> tab . '&module_name=' . $this -> name ;
$helper -> token = Tools :: getAdminTokenLite ( 'AdminModules' );
$helper -> tpl_vars = array (
'fields_value' => $this -> getConfigFieldsValues (),
'languages' => $this -> context -> controller -> getLanguages (),
'id_language' => $this -> context -> language -> id
);
$forms = array (
$fields_form_info ,
$fields_form_1 ,
$fields_form_5 ,
$fields_form_2 ,
$fields_form_3 ,
$fields_form_4 ,
$fields_form_settings ,
$fields_form_export ,
$fields_form_test
);
return $helper -> generateForm ( $forms );
}
public function getConfigFieldsValues ()
{
return array (
'PS_FOLLOW_UP_ENABLE_1' => Tools :: getValue ( 'PS_FOLLOW_UP_ENABLE_1' , Configuration :: get ( 'PS_FOLLOW_UP_ENABLE_1' )),
'PS_FOLLOW_UP_DAYS_1' => Tools :: getValue ( 'PS_FOLLOW_UP_DAYS_1' , Configuration :: get ( 'PS_FOLLOW_UP_DAYS_1' )),
'PS_FOLLOW_UP_AMOUNT_1' => Tools :: getValue ( 'PS_FOLLOW_UP_AMOUNT_1' , Configuration :: get ( 'PS_FOLLOW_UP_AMOUNT_1' )),
'PS_FOLLOW_UP_ENABLE_2' => Tools :: getValue ( 'PS_FOLLOW_UP_ENABLE_2' , Configuration :: get ( 'PS_FOLLOW_UP_ENABLE_2' )),
'PS_FOLLOW_UP_DAYS_2' => Tools :: getValue ( 'PS_FOLLOW_UP_DAYS_2' , Configuration :: get ( 'PS_FOLLOW_UP_DAYS_2' )),
'PS_FOLLOW_UP_AMOUNT_2' => Tools :: getValue ( 'PS_FOLLOW_UP_AMOUNT_2' , Configuration :: get ( 'PS_FOLLOW_UP_AMOUNT_2' )),
'PS_FOLLOW_UP_THRESHOLD_3' => Tools :: getValue ( 'PS_FOLLOW_UP_THRESHOLD_3' , Configuration :: get ( 'PS_FOLLOW_UP_THRESHOLD_3' )),
'PS_FOLLOW_UP_DAYS_3' => Tools :: getValue ( 'PS_FOLLOW_UP_DAYS_3' , Configuration :: get ( 'PS_FOLLOW_UP_DAYS_3' )),
'PS_FOLLOW_UP_ENABLE_3' => Tools :: getValue ( 'PS_FOLLOW_UP_ENABLE_3' , Configuration :: get ( 'PS_FOLLOW_UP_ENABLE_3' )),
'PS_FOLLOW_UP_AMOUNT_3' => Tools :: getValue ( 'PS_FOLLOW_UP_AMOUNT_3' , Configuration :: get ( 'PS_FOLLOW_UP_AMOUNT_3' )),
'PS_FOLLOW_UP_AMOUNT_4' => Tools :: getValue ( 'PS_FOLLOW_UP_AMOUNT_4' , Configuration :: get ( 'PS_FOLLOW_UP_AMOUNT_4' )),
'PS_FOLLOW_UP_ENABLE_4' => Tools :: getValue ( 'PS_FOLLOW_UP_ENABLE_4' , Configuration :: get ( 'PS_FOLLOW_UP_ENABLE_4' )),
'PS_FOLLOW_UP_DAYS_THRESHOLD_4' => Tools :: getValue ( 'PS_FOLLOW_UP_DAYS_THRESHOLD_4' , Configuration :: get ( 'PS_FOLLOW_UP_DAYS_THRESHOLD_4' )),
'PS_FOLLOW_UP_DAYS_4' => Tools :: getValue ( 'PS_FOLLOW_UP_DAYS_4' , Configuration :: get ( 'PS_FOLLOW_UP_DAYS_4' )),
/*@Override*/
'PS_FOLLOW_UP_ENABLE_5' => Tools :: getValue ( 'PS_FOLLOW_UP_ENABLE_5' , Configuration :: get ( 'PS_FOLLOW_UP_ENABLE_5' )),
'PS_FOLLOW_UP_DAYS_5' => Tools :: getValue ( 'PS_FOLLOW_UP_DAYS_5' , Configuration :: get ( 'PS_FOLLOW_UP_DAYS_5' )),
'PS_FOLLOW_UP_AMOUNT_5' => Tools :: getValue ( 'PS_FOLLOW_UP_AMOUNT_5' , Configuration :: get ( 'PS_FOLLOW_UP_AMOUNT_5' )),
'PS_FOLLOW_UP_MIN_5' => Tools :: getValue ( 'PS_FOLLOW_UP_MIN_5' , Configuration :: get ( 'PS_FOLLOW_UP_MIN_5' )),
'PS_FOLLOW_UP_CLEAN_DB' => Tools :: getValue ( 'PS_FOLLOW_UP_CLEAN_DB' , Configuration :: get ( 'PS_FOLLOW_UP_CLEAN_DB' )),
'id_email_test' => '' ,
2016-06-01 10:16:39 +02:00
'email_test' => 'marion@antadis.com' ,
2016-04-14 16:14:31 +02:00
'id_export_type' => '1' ,
);
}
private function _sendMailTest ( $id_email , $email ){
switch ( $id_email ) {
case 1 :
$this -> _cancelledCartTest ( $email );
break ;
case 2 :
# code...
break ;
case 3 :
# code...
break ;
case 4 :
# code...
break ;
case 5 :
$this -> _cancelledCartRecallTest ( $email );
break ;
default :
break ;
}
return ;
}
private function _cancelledCartTest ( $email , $is_pro = false ){
$order_url = Context :: getContext () -> link -> getPageLink ( 'order.php' , true , Context :: getContext () -> language -> id , null , false );
$shop_url = Context :: getContext () -> link -> getPageLink ( 'index' , true , Context :: getContext () -> language -> id , null , false );
$img_url = $shop_url . 'themes/' . _THEME_NAME_ . '/img/' ;
$conf = Configuration :: getMultiple ( array ( 'PS_FOLLOW_UP_AMOUNT_1' , 'PS_FOLLOW_UP_DAYS_1' ));
//AJOUT 20-01-2015
//Get cart
$products = Product :: getProducts ( Context :: getContext () -> language -> id , 0 , 3 , 'id_product' , 'ASC' );
$cartHtml = '' ;
$cartText = '' ;
foreach ( $products as $product )
{
$cover = Product :: getCover ( $product [ 'id_product' ]);
$product [ 'id_image' ] = $cover [ 'id_image' ];
$imagePath = Context :: getContext () -> link -> getImageLink ( $product [ 'link_rewrite' ], $product [ 'id_image' ], 'block_cart' ); // change the last parameters to get the size you need
$imagePath = str_replace ( 'https:' , 'http:' , $imagePath );
if ( ! preg_match ( " /^(http):/ " , $imagePath )) {
$imagePath = 'http://' . $imagePath ;
}
if ( ! empty ( $cartHtml ))
$cartHtml .= '<tr style="height: 1px;"><td colspan="4" style="height: 1px;"><div style="border-top:1px dashed #778899;max-height: 1px;"> </div>' ;
$hack = '' ;
$product [ 'price_without_specific_price' ] = Product :: getPriceStatic (
( int ) $product [ 'id_product' ],
! $is_pro ,
null ,
6 ,
null ,
false ,
false
);
$product [ 'price_wt' ] = Product :: getPriceStatic (
( int ) $product [ 'id_product' ],
! $is_pro
);
$price = ! $is_pro ? $product [ 'price_wt' ] : $product [ 'price' ];
$cartHtml .= '
< tr style = " border-bottom:3px dashed #778899; " >
< td style = " width:100px; " >
< img style = " margin: -20px; " src = " '. $imagePath .' " alt = " " title = " " />
</ td >
< td style = " padding:8px; " >< span style = " color:#484848; " > '.$product[' name '].' </ span ></ td >
< td style = " width:110px; " >
< span style = " color:#F3766E;font-weight:bold; " >
'.Tools::displayPrice($price).' < sup > '.(!$is_pro ? $this->l(' TTC ') : $this->l(' HT ') ).' </ sup >
</ span > ' ;
if ( ! empty ( $product [ 'price_without_specific_price' ])
&& $product [ 'price_without_specific_price' ] != $price )
$cartHtml .= '<span style="color:#484848;font-size:12px;display:block;">' . $this -> l ( 'au lieu de' ) . '
< span style = " text-decoration: line-through; " > ' .
Tools :: displayPrice ( $product [ 'price_without_specific_price' ]) . '
</ span >
</ span > ' ;
$cartHtml .= '
</ td >
< td align = " center " style = " width:100px; " >
< div style = " margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; " >
< p style = " clear: both; padding: 0; margin: 10px 0 9px 7px; " >
< a href = " '. $order_url .' " style = " color: #fff; text-transform : uppercase; font-size: 14px; display: inline-block; padding: 4px ; margin-bottom: 0; font-size: 13px; font-weight: normal; line-height: 1.42857; text-align: center; vertical-align: middle; cursor: pointer; border: 1px solid transparent; background:#ef5149; border-radius: 0px; white-space: nowrap; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; " >
< span style = " font-size: 12px; background: url('. $img_url .'cart.png) no-repeat 10px center; color: rgb(255, 255, 255); font-family: verdana; text-transform: uppercase; display: inline-block; padding: 10px 15px 10px 35px; border: 1px solid #EF8179; " > '.$this->l(' Finaliser ma ').' < br /> '.$this->l(' commande ').' </ span >
</ a >
</ p >
</ div >
</ td >
</ tr > ' ;
$cartText .= $product [ 'name' ] . ' - qté : 1' . " \n \r " ;
}
// FIN AJOUT
$template_vars = array (
'{email}' => $email ,
'{lastname}' => 'lastname' ,
'{firstname}' => 'firstname' ,
'{amount}' => $conf [ 'PS_FOLLOW_UP_AMOUNT_1' ],
'{days}' => $conf [ 'PS_FOLLOW_UP_DAYS_1' ],
'{voucher_num}' => Tools :: passwdGen ( 10 ),
'{cartHtml}' => $cartHtml ,
'{cartText}' => $cartText
);
2016-06-01 10:16:39 +02:00
return Mail :: Send ( $this -> context -> language -> id , 'followup_H3' , Mail :: l ( 'Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!' , ( int ) $this -> context -> language -> id ), $template_vars , $email , 'firstname lastname' , null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
2016-04-14 16:14:31 +02:00
}
private function _cancelledCartRecallTest ( $email , $is_pro = false ){
$order_url = Context :: getContext () -> link -> getPageLink ( 'order.php' , true , Context :: getContext () -> language -> id , null , false );
$shop_url = Context :: getContext () -> link -> getPageLink ( 'index' , true , Context :: getContext () -> language -> id , null , false );
$img_url = $shop_url . 'themes/' . _THEME_NAME_ . '/img/' ;
$conf = Configuration :: getMultiple ( array ( 'PS_FOLLOW_UP_AMOUNT_5' , 'PS_FOLLOW_UP_DAYS_5' , 'PS_FOLLOW_UP_MIN_5' ));
//AJOUT 20-01-2015
//Get cart
$products = Product :: getProducts ( Context :: getContext () -> language -> id , 0 , 3 , 'id_product' , 'ASC' );
$cartHtml = '' ;
$cartText = '' ;
foreach ( $products as $product )
{
$cover = Product :: getCover ( $product [ 'id_product' ]);
$product [ 'id_image' ] = $cover [ 'id_image' ];
$imagePath = Context :: getContext () -> link -> getImageLink ( $product [ 'link_rewrite' ], $product [ 'id_image' ], 'block_cart' ); // change the last parameters to get the size you need
2016-05-10 13:04:43 +02:00
$imagePath = str_replace ( 'https:' , 'http:' , $imagePath );
if ( ! preg_match ( " /^(http):/ " , $imagePath )) {
$imagePath = 'http://' . $imagePath ;
}
2016-04-14 16:14:31 +02:00
if ( ! empty ( $cartHtml ))
$cartHtml .= '<tr style="height: 1px;"><td colspan="4" style="height: 1px;"><div style="border-top:1px dashed #778899;max-height: 1px;"> </div>' ;
$hack = '' ;
$product [ 'price_without_specific_price' ] = Product :: getPriceStatic (
( int ) $product [ 'id_product' ],
! $is_pro ,
null ,
6 ,
null ,
false ,
false
);
$product [ 'price_wt' ] = Product :: getPriceStatic (
( int ) $product [ 'id_product' ],
! $is_pro
);
$price = ! $is_pro ? $product [ 'price_wt' ] : $product [ 'price' ];
$cartHtml .= '
< tr style = " border-bottom:3px dashed #778899; " >
< td style = " width:100px; " >
< img style = " margin: -20px; " src = " '. $imagePath .' " alt = " " title = " " />
</ td >
< td style = " padding:8px; " >< span style = " color:#484848; " > '.$product[' name '].' </ span ></ td >
< td style = " width:110px; " >
< span style = " color:#F3766E;font-weight:bold; " >
'.Tools::displayPrice($price).' < sup > '.(!$is_pro ? $this->l(' TTC ') : $this->l(' HT ') ).' </ sup >
</ span > ' ;
if ( ! empty ( $product [ 'price_without_specific_price' ])
&& $product [ 'price_without_specific_price' ] != $price )
$cartHtml .= '<span style="color:#484848;font-size:12px;display:block;">' . $this -> l ( 'au lieu de' ) . '
< span style = " text-decoration: line-through; " > ' .
Tools :: displayPrice ( $product [ 'price_without_specific_price' ]) . '
</ span >
</ span > ' ;
$cartHtml .= '
</ td >
< td align = " center " style = " width:100px; " >
< div style = " margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; " >
< p style = " clear: both; padding: 0; margin: 10px 0 9px 7px; " >
< a href = " '. $order_url .' " style = " color: #fff; text-transform : uppercase; font-size: 14px; display: inline-block; padding: 4px ; margin-bottom: 0; font-size: 13px; font-weight: normal; line-height: 1.42857; text-align: center; vertical-align: middle; cursor: pointer; border: 1px solid transparent; background:#ef5149; border-radius: 0px; white-space: nowrap; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; " >
< span style = " font-size: 12px; background: url('. $img_url .'cart.png) no-repeat 10px center; color: rgb(255, 255, 255); font-family: verdana; text-transform: uppercase; display: inline-block; padding: 10px 15px 10px 35px; border: 1px solid #EF8179; " > '.$this->l(' Finaliser ma ').' < br /> '.$this->l(' commande ').' </ span >
</ a >
</ p >
</ div >
</ td >
</ tr > ' ;
$cartText .= $product [ 'name' ] . ' - qté : 1' . " \n \r " ;
}
// FIN AJOUT
$template_vars = array (
'{email}' => $email ,
'{lastname}' => 'lastname' ,
'{firstname}' => 'firstname' ,
'{amount}' => $conf [ 'PS_FOLLOW_UP_AMOUNT_5' ],
'{days}' => $conf [ 'PS_FOLLOW_UP_DAYS_5' ],
'{voucher_num}' => Tools :: passwdGen ( 10 ),
'{cartHtml}' => $cartHtml ,
'{cartText}' => $cartText
);
2016-06-01 10:16:39 +02:00
return Mail :: Send ( $this -> context -> language -> id , 'followup_H24' , Mail :: l ( 'Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!' , ( int ) $this -> context -> language -> id ), $template_vars , $email , 'firstname lastname' , null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
2016-04-14 16:14:31 +02:00
}
private function _processExport ( $id_export_type = 1 ){
header ( 'Pragma: public' );
header ( 'Expires: 0' );
header ( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
header ( 'Content-Description: File Transfer' );
header ( 'Content-Type: text/csv; charset=utf-8' );
header ( 'Content-Disposition: attachment; filename=export_followup.csv;' );
header ( 'Content-Transfer-Encoding: binary' );
$fp = fopen ( 'php://output' , 'w' );
$delim = ';' ;
$row_definition = $this -> _getRowDefinition (( int ) $id_export_type );
// First row
$data = array ();
foreach ( $row_definition as $colName => $value )
$data [] = Tools :: htmlentitiesDecodeUTF8 ( $colName );
fputcsv ( $fp , $data , $delim );
$logs = $this -> _getLogmails (( int ) $id_export_type );
foreach ( $logs as $log ){
$data = array ();
foreach ( $row_definition as $index )
$data [] = $log [ $index ];
fputcsv ( $fp , $data , $delim );
}
fclose ( $fp );
exit ;
}
private function _getRowDefinition ( $id_export_type ){
$row_definition = array (
'ID Client' => 'id_customer' ,
'ID Panier' => 'id_cart' ,
2016-06-01 10:16:39 +02:00
/*'date Panier' => 'date_upd',*/
2016-04-14 16:14:31 +02:00
'relance 1' => 'date_flw1' ,
'relance 2' => 'date_flw2' ,
'ID commande' => 'id_order' ,
'Date commande' => 'order_date_add' ,
'Total TTC' => 'total_paid_tax_incl' ,
'Total HT' => 'total_paid_tax_excl' ,
'Bon utilise' => 'have_discount' ,
// 'Cmd avec bon' => 'voucher_cmd',
);
switch ( $id_export_type ) {
case 1 :
break ;
case 2 :
break ;
case 3 :
break ;
case 4 :
$row_definition = array_merge ( $row_definition , array (
'Derniere commande' => 'last_order' ,
'Total TTC DC' => 'total_paid_tax_incl_last_order' ,
'Total HT DC' => 'total_paid_tax_excl_last_order' ,
));
break ;
case 5 :
break ;
default :
break ;
}
return $row_definition ;
}
private function _getLogmails ( $id_export_type ){
switch ( $id_export_type ) {
case 1 :
return $this -> _getLogsCancelledCart ();
break ;
case 2 :
return array ();
break ;
case 3 :
return array ();
break ;
case 4 :
return $this -> _getLogsBadCustomer ();
break ;
case 5 :
return array ();
break ;
default :
return array ();
break ;
}
}
private function _getLogsCancelledCart (){
$sql = '
SELECT DISTINCT
le . `id_customer` ,
le . `id_cart` ,
DATE_FORMAT ( le . `date_add` , \ ' % Y -% m -% d\ ' ) as `date_flw1` ,
DATE_FORMAT ( le2 . `date_add` , \ ' % Y -% m -% d\ ' ) as `date_flw2` ,
o . `id_order` ,
DATE_FORMAT ( o . `date_add` , \ ' % Y -% m -% d\ ' ) as `order_date_add` ,
o . `total_paid_tax_incl` ,
o . `total_paid_tax_excl` ,
(
SELECT COUNT ( * )
FROM `'._DB_PREFIX_.'order_cart_rule` ocr
2016-06-01 10:16:39 +02:00
WHERE `id_cart_rule` = le2 . `id_cart_rule`
) as `have_discount`
2016-04-14 16:14:31 +02:00
FROM `'._DB_PREFIX_.'log_email` le
LEFT JOIN `'._DB_PREFIX_.'orders` o ON ( o . `id_cart` = le . `id_cart` )
2016-06-01 10:16:39 +02:00
LEFT JOIN `'._DB_PREFIX_.'log_email` le2 ON ( le2 . `id_cart` = le . `id_cart` AND le2 . `id_email_type` = 5 )
2016-04-14 16:14:31 +02:00
WHERE 1
AND le . `id_email_type` = 1
ORDER BY le . `date_add` DESC , le2 . `date_add` DESC , o . `date_add` DESC ' ;
2016-06-01 10:16:39 +02:00
/* $sql = '
SELECT DISTINCT
le . `id_customer` ,
le . `id_cart` ,
c . `date_upd` ,
( SELECT DATE_FORMAT ( le2 . `date_add` , \ ' % Y -% m -% d\ ' )
FROM `'._DB_PREFIX_.'log_email` le2
WHERE le2 . `id_cart` = le . `id_cart` AND le2 . `id_email_type` = 1
ORDER BY le2 . `date_add` DESC LIMIT 1
) as `date_flw1` ,
DATE_FORMAT ( le . `date_add` , \ ' % Y -% m -% d\ ' ) as `date_flw2` ,
-- le . `id_cart_rule` ,
o . `id_order` ,
DATE_FORMAT ( o . `date_add` , \ ' % Y -% m -% d\ ' ) as `order_date_add` ,
o . `total_paid_tax_incl` ,
o . `total_paid_tax_excl` ,
(
SELECT COUNT ( * )
FROM `'._DB_PREFIX_.'order_cart_rule` ocr
WHERE `id_cart_rule` = le . `id_cart_rule`
) as `have_discount`
FROM `'._DB_PREFIX_.'log_email` le
LEFT JOIN `'._DB_PREFIX_.'orders` o ON ( o . `id_cart` = le . `id_cart` )
LEFT JOIN `'._DB_PREFIX_.'cart` c ON ( c . `id_cart` = le . `id_cart` )
WHERE 1
AND le . `id_email_type` = 5
ORDER BY le . `date_add` DESC , `date_flw2` DESC , o . `date_add` DESC ' ; */
2016-04-14 16:14:31 +02:00
return Db :: getInstance () -> executeS ( $sql );
}
private function _getLogsBadCustomer (){
$sql = '
SELECT DISTINCT
le . `id_customer` ,
le . `id_cart` ,
DATE_FORMAT ( le . `date_add` , \ ' % Y -% m -% d\ ' ) as `date_flw1` ,
o . `id_order` ,
DATE_FORMAT ( o . `date_add` , \ ' % Y -% m -% d\ ' ) as `order_date_add` ,
o . `total_paid_tax_incl` ,
o . `total_paid_tax_excl` ,
(
SELECT COUNT ( * )
FROM `'._DB_PREFIX_.'order_cart_rule` ocr
WHERE `id_cart_rule` = le . `id_cart_rule`
) as `have_discount` ,
lo . `id_order` as last_order ,
lo . `total_paid_tax_incl` as total_paid_tax_incl_last_order ,
lo . `total_paid_tax_excl` as total_paid_tax_excl_last_order
FROM `'._DB_PREFIX_.'log_email` le
LEFT JOIN `'._DB_PREFIX_.'orders` o ON ( o . `id_cart` = le . `id_cart` )
LEFT JOIN `'._DB_PREFIX_.'orders` lo ON ( lo . `id_order` = (
SELECT `id_order`
FROM `'._DB_PREFIX_.'orders`
WHERE `id_customer` = le . `id_customer`
ORDER BY `date_add` DESC
LIMIT 1
)
AND lo . `id_order` <> o . `id_order`
)
WHERE 1
AND le . `id_email_type` = 4
ORDER BY le . `date_add` DESC , le . `date_add` DESC , o . `date_add` DESC ' ;
return Db :: getInstance () -> executeS ( $sql );
}
public function cancelledCartBis ( $count = false )
{
$ids_products = self :: getIdProductOfAllActiveSale ();
if ( count ( $ids_products ) == 0 )
return 0 ;
$email_logs = $this -> getLogsEmail ( 1 );
$sql = '
SELECT DISTINCT c . id_cart , c . id_lang , cu . id_default_group , cu . id_customer , c . id_shop , cu . firstname , cu . lastname , cu . email
FROM '._DB_PREFIX_.' cart c
LEFT JOIN '._DB_PREFIX_.' orders o ON ( o . id_cart = c . id_cart )
RIGHT JOIN '._DB_PREFIX_.' customer cu ON ( cu . id_customer = c . id_customer )
RIGHT JOIN '._DB_PREFIX_.' cart_product cp ON ( cp . id_cart = c . id_cart AND cp . id_product IN ( '.implode(' , ', $ids_products).' ))
WHERE c . id_cart = 49469 ' ;
$sql .= Shop :: addSqlRestriction ( Shop :: SHARE_CUSTOMER , 'c' );
$emails = Db :: getInstance () -> executeS ( $sql );
if ( $count || ! count ( $emails )){
return count ( $emails );
}
$order_url = Context :: getContext () -> link -> getPageLink ( 'order.php' , true , Context :: getContext () -> language -> id , null , false );
$shop_url = Context :: getContext () -> link -> getPageLink ( 'index' , true , Context :: getContext () -> language -> id , null , false );
$img_url = $shop_url . 'themes/' . _THEME_NAME_ . '/img/' ;
$conf = Configuration :: getMultiple ( array ( 'PS_FOLLOW_UP_AMOUNT_1' , 'PS_FOLLOW_UP_DAYS_1' ));
foreach ( $emails as $email )
{
//AJOUT 20-01-2015
//Get cart
$cart = new Cart ( intval ( $email [ 'id_cart' ]));
$products = $cart -> getProducts ( true );
$price_display_method = Group :: getPriceDisplayMethod ( $email [ 'id_default_group' ]);
$cartHtml = '' ;
//Création du panier
$cart_product_context = Context :: getContext () -> cloneContext ();
$cart_product_context -> customer = new Customer ( $cart -> id_customer );
$cart_product_context -> cart = $cart ;
if ( $cart_product_context -> shop -> id != $cart -> id_shop )
{
$cart_product_context -> shop = new Shop (( int ) $cart -> id_shop );
}
$cartText = '' ;
foreach ( $products as $product )
{
$imagePath = Context :: getContext () -> link -> getImageLink ( $product [ 'link_rewrite' ], $product [ 'id_image' ], 'block_cart' ); // change the last parameters to get the size you need
if ( ! empty ( $cartHtml ))
{
$cartHtml .= '<tr style="height: 1px;"><td colspan="4" style="height: 1px;"><div style="border-top:1px dashed #778899;max-height: 1px;"> </div>' ;
}
$hack = '' ;
$product [ 'price_without_specific_price' ] = Product :: getPriceStatic (
( int ) $product [ 'id_product' ],
! $price_display_method ,
$product [ 'id_product_attribute' ],
6 ,
null ,
false ,
false ,
1 ,
false ,
null ,
null ,
null ,
$hack ,
true ,
true ,
$cart_product_context
);
$price = ! $price_display_method ? $product [ 'price_wt' ] : $product [ 'price' ];
$cartHtml .= '
< tr style = " border-bottom:3px dashed #778899; " >
< td style = " width:100px; " >
< img style = " max-width: 100px; " src = " '. $imagePath .' " alt = " '. $product['legend'] .' " title = " '. $product['legend'] .' " />
</ td >
< td style = " padding:8px; " >< span style = " color:#484848; " > '.$product[' name '].' </ span ></ td >
< td style = " width:110px; " >
< span style = " color:#F3766E;font-weight:bold; " >
'.Tools::displayPrice($price, (int)$cart->id_currency).' < sup > '.(!$price_display_method ? $this->l(' TTC ') : $this->l(' HT ') ).' </ sup >
</ span > ' ;
if ( ! empty ( $product [ 'price_without_specific_price' ])
&& $product [ 'price_without_specific_price' ] != $price )
$cartHtml .= '<span style="color:#484848;font-size:12px;display:block;">' . $this -> l ( 'au lieu de' ) . '
< span style = " text-decoration: line-through; " > ' .
Tools :: displayPrice ( $product [ 'price_without_specific_price' ], ( int ) $cart -> id_currency ) . '
</ span >
</ span > ' ;
$cartHtml .= '
</ td >
< td align = " center " style = " width:100px; " >
< div style = " margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; " >
< p style = " clear: both; padding: 0; margin: 10px 0 9px 7px; " >
< a href = " '. $order_url .' " style = " color: #fff; text-transform : uppercase; font-size: 14px; display: inline-block; padding: 4px ; margin-bottom: 0; font-size: 13px; font-weight: normal; line-height: 1.42857; text-align: center; vertical-align: middle; cursor: pointer; border: 1px solid transparent; background:#ef5149; border-radius: 0px; white-space: nowrap; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; " >
< span style = " font-size: 12px; background: url('. $img_url .'cart.png) no-repeat 10px center; color: rgb(255, 255, 255); font-family: verdana; text-transform: uppercase; display: inline-block; padding: 10px 15px 10px 35px; border: 1px solid #EF8179; " > '.$this->l(' Finaliser ma ').' < br /> '.$this->l(' commande ').' </ span >
</ a >
</ p >
</ div >
</ td >
</ tr > ' ;
$cartText .= $product [ 'name' ] . ' - qté : ' . $product [ 'cart_quantity' ] . " \n \r " ;
}
//FIN AJOUT
$template_vars = array (
'{email}' => $email [ 'email' ],
'{lastname}' => $email [ 'lastname' ],
'{firstname}' => $email [ 'firstname' ],
'{amount}' => $conf [ 'PS_FOLLOW_UP_AMOUNT_1' ],
'{days}' => $conf [ 'PS_FOLLOW_UP_DAYS_1' ],
// '{voucher_num}' => $voucher->code,
'{cartHtml}' => $cartHtml ,
'{cartText}' => $cartText
);
Mail :: Send (( int ) $email [ 'id_lang' ], 'followup_J1' , Mail :: l ( 'Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!' , ( int ) $email [ 'id_lang' ]), $template_vars , 'coppee@antadis.com' , $email [ 'firstname' ] . ' ' . $email [ 'lastname' ], null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
return Mail :: Send (( int ) $email [ 'id_lang' ], 'followup_J1' , Mail :: l ( 'Ne manquez pas les ventes privilégiées que vous aviez sélectionnées, validez votre panier!' , ( int ) $email [ 'id_lang' ]), $template_vars , 'clefebvre@privilegedemarque.com' , $email [ 'firstname' ] . ' ' . $email [ 'lastname' ], null , null , null , null , dirname ( __FILE__ ) . '/mails/' );
}
}
}