Serveur preprod f0c0c48223 first push
2016-04-14 16:14:31 +02:00

652 lines
28 KiB
PHP

<?php
class makeStats {
static $sales = array();
static $errors = array();
static $array_product;
public static function pushSale(SaleCore $sale)
{
if(!Validate::isLoadedObject($sale))
return false;
self::$sales[$sale->id] = $sale;
}
public static function getSales()
{
return self::$sales;
}
public static function getStateNull()
{
return $state_null = array(6, 7, 8);
}
public function getAllSales(DateTime $date_from = null, DateTime $date_to = null, $orderby = null, $ordered = null)
{
$collection = new Collection('SaleCoreExtend', Context::getContext()->language->id);
if($date_from !== null && $date_to !== null)
{
$format = 'Y-m-d';
$collection->sqlWhere('(date_start BETWEEN "'.$date_from->format($format).'" AND "'.$date_to->format($format).'") OR (date_end BETWEEN "'.$date_from->format($format).'" AND "'.$date_to->format($format).'") ');
}
if($orderby === null || $ordered === null)
$collection->orderBy('id_privatesales', 'DESC');
else
{
$definition = ObjectModel::getDefinition('SaleCoreExtend', $orderby);
$collection->orderBy(($definition['lang'] == 1 ? 'l.' : '').$orderby, $ordered);
}
//print_r($collection);
//exit;
$array = array();
foreach($collection as $sale)
$array[$sale->id] = $sale;
return $array;
}
/*******************************MISE A JOUR*********************************/
public static function run(DateTime $date_from = null, DateTime $date_to = null)
{
$sales = self::getSales();
foreach($sales as $sale)
{
$ids_products = $sale->getProducts();
try {
self::setProducts($sale, $ids_products, $date_from, $date_to);
self::setOrders($sale, $ids_products, $date_from, $date_to);
self::setTotal($sale);
} catch(Exception $e) {
self::$errors[] = sprintf(Tools::displayError('An error occured during stats update, private sale : %s (%s)'), $sale->title, $e->getMessage() );
}
}
self::runGeneral($date_from, $date_to);
}
public static function runGeneral(DateTime $date_from = null, DateTime $date_to = null)
{
self::setTotalFields($date_from, $date_to);
}
private static function setProducts($sale, $ids_products, DateTime $date_from = null, DateTime $date_to = null)
{
Db::getInstance()->delete('privatesales_stats_products', ($date_from !== null && $date_to !== null ? '(date BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_to->format('Y-m-d')).'") AND ' : '') . ' id_sale = '.(int)$sale->id);
if(count($ids_products) > 0)
{
$total = Db::getInstance()->executeS('
SELECT a.*,
(total_products_price_tax_excl - total_products_wholesale_price) as rate_amount,
(1 - total_products_wholesale_price/total_products_price_tax_excl) as rate
FROM
(
SELECT '.$sale->id.' as id_sale,
d.product_id,
d.product_attribute_id,
d.product_reference AS reference,
d.product_supplier_reference AS supplier_reference,
DATE_FORMAT(o.`date_add`, "%Y-%m-%d") as date,
d.product_name as name,
SUM(d.`product_quantity`) AS `total_products`,
SUM( ROUND(
d.unit_price_tax_incl * d.`product_quantity`, 6
)
) AS `total_products_price`,
SUM( ROUND(
d.unit_price_tax_excl * d.`product_quantity`, 6
)
) AS `total_products_price_tax_excl`,
CASE WHEN pas.wholesale_price IS NULL AND d.product_attribute_id != 0 AND pas.wholesale_price != 0 THEN SUM(pas.wholesale_price * d.`product_quantity`) ELSE SUM(ps.wholesale_price * d.`product_quantity`) END AS total_products_wholesale_price
FROM `'._DB_PREFIX_.'order_detail` d
RIGHT JOIN `'._DB_PREFIX_.'orders` o
ON (d.`id_order` = o.`id_order`
AND o.current_state NOT IN ("'.implode('","', self::getStateNull()).'") )
LEFT OUTER JOIN `'._DB_PREFIX_.'product_shop` ps
ON ps.id_shop = o.id_shop AND ps.id_product = d.product_id
LEFT OUTER JOIN `'._DB_PREFIX_.'product_attribute_shop` pas
ON d.product_attribute_id != 0 AND pas.id_product_attribute = d.product_attribute_id
WHERE d.`product_id` IN ("'.implode('","', $ids_products).'")
'.($date_from !== null && $date_to !== null ?
'AND DATE_FORMAT(o.`date_add`, "%Y-%m-%d") BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_to->format('Y-m-d')).'"' : '').'
GROUP BY date, d.product_id, d.product_attribute_id
) a
');
foreach($total as $k => $tot)
$total[$k]['name'] = pSQL($tot['name']);
Db::getInstance()->insert('privatesales_stats_products', $total);
}
}
public static function setOrders($sale, $ids_products, DateTime $date_from = null, DateTime $date_to = null)
{
Db::getInstance()->delete('privatesales_stats_order', ($date_from !== null && $date_to !== null ? '(date BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_to->format('Y-m-d')).'") AND' : '') . ' id_sale = '.(int)$sale->id);
if(count($ids_products) > 0)
{
$total = Db::getInstance()->executeS('
SELECT a.*,
ROUND(total_products_price_tax_excl - total_wholesale_price, 2) as rate_amount,
(1 - ROUND(total_wholesale_price/total_products_price_tax_excl,2)) as rate
FROM
(
SELECT
'.$sale->id.' as id_sale,
DATE_FORMAT(o.`date_add`, "%Y-%m-%d") as date,
SUM(d.`product_quantity`) AS `total_products`,
SUM(d.`total_shipping_price_tax_incl`) as `total_shipping`,
COUNT(d.id_order) AS total_order,
SUM( ROUND(
d.unit_price_tax_incl * d.`product_quantity`, 6
)
) AS `total_products_price`,
SUM( ROUND(
d.unit_price_tax_excl * d.`product_quantity`, 6
)
) AS `total_products_price_tax_excl`,
CASE WHEN pas.wholesale_price IS NULL AND d.product_attribute_id != 0 THEN SUM(pas.wholesale_price * d.`product_quantity`) ELSE SUM(ps.wholesale_price * d.`product_quantity`) END AS total_wholesale_price
FROM `'._DB_PREFIX_.'order_detail` d
RIGHT JOIN `'._DB_PREFIX_.'orders` o
ON d.`id_order` = o.`id_order`
AND o.current_state NOT IN ("'.implode('","', self::getStateNull()).'")
LEFT OUTER JOIN `'._DB_PREFIX_.'product_shop` ps
ON ps.id_shop = o.id_shop AND ps.id_product = d.product_id
LEFT OUTER JOIN `'._DB_PREFIX_.'product_attribute_shop` pas
ON d.product_attribute_id != 0 AND pas.id_product_attribute = d.product_attribute_id
WHERE d.`product_id` IN ("'.implode('","', $ids_products).'")
'.($date_from !== null && $date_to !== null ?
'AND DATE_FORMAT(o.`date_add`, "%Y-%m-%d") BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_to->format('Y-m-d')).'"' : '').'
GROUP BY date
) a
');
Db::getInstance()->insert('privatesales_stats_order', $total);
}
}
public static function setTotal($sale)
{
$total = Db::getInstance()->executeS('SELECT
id_sale,
SUM(`total_products`) AS `total_products`,
SUM(`total_products_price`) AS `total_products_price`,
SUM(`total_products_price_tax_excl`) AS `total_products_price_tax_excl`,
SUM(`total_shipping`) AS `total_shipping`,
SUM(`total_wholesale_price`) AS `total_wholesale_price`,
SUM(`rate_amount`) AS `rate_amount`,
AVG(`rate`) AS `rate`
FROM '._DB_PREFIX_.'privatesales_stats_order
WHERE id_sale = '.(int)$sale->id.'
GROUP BY id_sale');
Db::getInstance()->delete('privatesales_stats_order_global', 'id_sale = '.(int)$sale->id);
Db::getInstance()->insert('privatesales_stats_order_global', $total);
}
public static function setTotalFields(DateTime $date_from = null, DateTime $date_to = null)
{
Db::getInstance()->delete('privatesales_stats_other', ($date_from !== null && $date_to !== null ? 'date BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_to->format('Y-m-d')).'"' : ''));
self::setTotalOrder($date_from, $date_to);
self::setTotalPayment($date_from, $date_to);
}
public static function setTotalPayment(DateTime $date_from = null, DateTime $date_to = null)
{
$sql = 'SELECT
o.date,
SUM(amount) AS total_paid,
payment_method
FROM '._DB_PREFIX_.'order_payment op
RIGHT JOIN (
SELECT reference, DATE_FORMAT(o.`date_add`, "%Y-%m-%d") as date
FROM '._DB_PREFIX_.'orders o
WHERE o.current_state NOT IN ("'.implode('","', self::getStateNull()).'")
'.($date_from !== null && $date_to !== null ?
'AND DATE_FORMAT(o.`date_add`, "%Y-%m-%d") BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_to->format('Y-m-d')).'"' : '').'
) o ON o.reference = op.order_reference
GROUP BY payment_method, date';
$total_payment_type = Db::getInstance()->executeS($sql);
$array_insert = array();
foreach($total_payment_type as $value)
{
if($value['total_paid'] === null)
continue;
$array_insert[] = array(
'name' => 'total_payment',
'date' => $value['date'],
'value' => $value['total_paid'],
'value_txt' => $value['payment_method']
);
}
return Db::getInstance()->insert('privatesales_stats_other', $array_insert, false, true, Db::INSERT_IGNORE);
}
public static function setTotalOrder(DateTime $date_from = null, DateTime $date_to = null)
{
$sql = 'SELECT
DATE_FORMAT(o.`date_add`, "%Y-%m-%d") AS date,
SUM(total_products) AS total_products_tax_excl,
SUM(total_products_wt) AS total_products_tax_incl,
SUM(total_shipping_tax_incl) AS total_shipping_tax_incl,
SUM(total_shipping_tax_excl) AS total_shipping_tax_excl,
SUM(total_discounts_tax_incl) AS total_discounts_tax_incl,
SUM(total_discounts_tax_excl) AS total_discounts_tax_excl,
SUM(total_paid_tax_excl) AS total_paid_tax_excl,
SUM(total_paid_tax_incl) AS total_paid_tax_incl
FROM '._DB_PREFIX_.'orders o
WHERE o.current_state NOT IN ("'.implode('","', self::getStateNull()).'")
'.($date_from !== null && $date_to !== null ? '
AND DATE_FORMAT(o.`date_add`, "%Y-%m-%d") BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_to->format('Y-m-d')).'"' : '').'
GROUP BY date
';
$total_order = Db::getInstance()->executeS($sql);
$array_insert = array();
foreach($total_order as $values)
{
foreach($values as $key => $value)
{
if($key == 'date')
continue;
$array_insert[] = array(
'name' => $key,
'date' => $values['date'],
'value' => $value
);
}
}
return Db::getInstance()->insert('privatesales_stats_other', $array_insert, false, true, Db::INSERT_IGNORE);;
}
/*******************************FIN MISE A JOUR*********************************/
/*******************************RECUPERATION*********************************/
public static function getStatsGlobal(DateTime $date_from = null, DateTime $date_to = null)
{
$array = array(
'total_products_tax_excl', 'total_products_tax_incl', 'total_shipping_tax_incl', 'total_shipping_tax_excl', 'total_discounts_tax_incl', 'total_discounts_tax_excl',
'total_paid_tax_excl', 'total_paid_tax_incl'
);
$returns = array();
foreach($array as $field)
{
$sql = 'SELECT SUM(value) FROM '._DB_PREFIX_.'privatesales_stats_other WHERE name = \''.$field.'\'
'.($date_from !== null && $date_to !== null ? '
AND date BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_from->format('Y-m-d')).'"' : '').'';
$returns[$field] = Db::getInstance()->getValue($sql);
}
return $returns;
}
public static function getStatsPaymentType(DateTime $date_from = null, DateTime $date_to = null)
{
$sql = 'SELECT SUM(value) as total_paid , value_txt as payment_method FROM '._DB_PREFIX_.'privatesales_stats_other WHERE name = \'total_payment\'
'.($date_from !== null && $date_to !== null ? '
AND date BETWEEN "'.pSQL($date_from->format('Y-m-d')).'" AND "'.pSQL($date_from->format('Y-m-d')).'"' : '').' GROUP BY value_txt';
$total_payment_type = Db::getInstance()->executeS($sql);
return $total_payment_type;
}
public static function getSaleDateToDate(DateTime $date_from = null, DateTime $date_to = null)
{
$format = 'Y-m-d';
$sql = '
SELECT p.id_privatesales
FROM `'. _DB_PREFIX_ . self::$definition['table'].' p
WHERE
CAST(`date_start` AS DATE) BETWEEN "'.pSQL($format).'" AND "'.pSQL($date_to).'"
OR CAST(`date_end` AS DATE) BETWEEN "'.pSQL($date_from).'" AND "'.pSQL($date_to).'"
OR (CAST(p.`date_start` AS DATE) <= "'.pSQL($date_from).'" AND CAST(p.`date_end` AS DATE) >= "'.pSQL($date_to).'")
GROUP BY p.`id_privatesales`
ORDER BY p.`date_start` DESC';
$res = Db::getInstance()->executeS($sql);
$sales = array();
foreach($res as $sale)
$sales[(int) $sale['id_sale']] = new SaleCoreExtend($sale['id_sale']);
return $sales;
}
public static function getStatsStatic($sales = array(), $type = 'global', DateTime $date_from = null, DateTime $date_to = null, $order_by = null, $ordered = null)
{
if(is_object($sales) && get_class($sales) == 'Collection')
$sales = $sales->getResults();
if(!is_array($sales) || count($sales) == 0)
return false;
$sales_ids = array();
foreach($sales as $sale)
{
if(!is_object($sale))
$sales_ids[] = $sale['id'];
else $sales_ids[] = $sale->id;
}
if($order_by != null && $ordered != null)
{
$order_by_req = $order_by.' '.$ordered;
}
else
{
$order_by_req = 'id_sale DESC';
}
switch($type)
{
case 'global':
if($date_from !== null && $date_to !== null)
{
$req = 'SELECT
id_sale,
SUM(total_products_price) AS total_products_price,
SUM(total_products_price_tax_excl) as total_products_price_tax_excl,
SUM(total_products) AS total_products,
SUM(total_shipping) AS total_shipping,
SUM(total_wholesale_price) AS total_wholesale_price,
SUM(rate_amount) AS rate_amount,
AVG(`rate`) AS `rate`
FROM '._DB_PREFIX_.'privatesales_stats_order
WHERE id_sale IN ('.implode(',',$sales_ids).')
AND `date` BETWEEN "'.$date_from->format('Y-m-d').'" AND "'.$date_to->format('Y-m-d').'"
GROUP BY id_sale
ORDER BY '.$order_by_req;
$totals = Db::getInstance()->executeS($req);
}
else
{
$totals = Db::getInstance()->executeS('SELECT *
FROM '._DB_PREFIX_.'privatesales_stats_order_global
WHERE id_sale IN ('.implode(',',$sales_ids).')
GROUP BY id_sale
ORDER BY '.$order_by_req);
}
if(count($totals) == 0)
return array();
$array_stats = array();
foreach($totals as $k => $total)
{
$array_stats[$total['id_sale']] = $total['id_sale'];
}
foreach($sales_ids as $sale)
if(!in_array($sale, $array_stats))
{
$array = array();
foreach(array_keys(reset($totals)) as $field)
$array[$field] = 0;
$array['id_sale'] = $sale;
if($order_by != null && $ordered != null)
{
if($ordered == 'ASC')
array_unshift($totals, $array);
else $totals[] = $array;
}
else $totals[] = $array;
}
$array_stats = $totals;
if($date_from !== null && $date_to !== null)
{
$array_stats['total'] = Db::getInstance()->getRow('
SELECT b.*,
ROUND(b.total_total_products_price_tax_excl - b.total_total_wholesale_price, 2) as rate_amount,
(1 - ROUND(total_total_wholesale_price/total_total_products_price_tax_excl,2)) as rate
FROM (
SELECT
SUM(total_products_price) as total_total_products_price,
SUM(total_products_price_tax_excl) as total_total_products_price_tax_excl,
SUM(total_shipping) as total_total_shipping,
SUM(total_products) as total_total_products,
SUM(total_wholesale_price) as total_total_wholesale_price
FROM (
'.$req.'
) a
) b
');
}
else
{
$array_stats['total'] = Db::getInstance()->getRow('
SELECT a.*,
ROUND(a.total_total_products_price_tax_excl - a.total_total_wholesale_price, 2) as rate_amount,
(1 - ROUND(total_total_wholesale_price/total_total_products_price_tax_excl,2)) as rate
FROM (
SELECT
SUM(total_products_price) as total_total_products_price,
SUM(total_products_price_tax_excl) as total_total_products_price_tax_excl,
SUM(total_shipping) as total_total_shipping,
SUM(total_products) as total_total_products,
SUM(total_wholesale_price) as total_total_wholesale_price
FROM '._DB_PREFIX_.'privatesales_stats_order_global
WHERE id_sale IN ('.implode(',',$sales_ids).')
) a ');
}
//BUG DE LA CLE 0
$array_final = array();
foreach($array_stats as $k => $v)
$array_final[(Validate::isInt($k) ? ($k+1) : $k)] = $v;
return $array_final;
break;
}
}
public function getStats($sale, $type = 'global', DateTime $date_from = null, DateTime $date_to = null, $order_by = null, $ordered = null)
{
$date_req = '';
if($date_to !== null && $date_from !== null)
$date_req = ' AND date BETWEEN \''.$date_from->format('Y-m-d').'\' AND \''.$date_to->format('Y-m-d').'\'';
if($order_by != null && $ordered != null)
$order_by_req = $order_by.' '.$ordered;
else
switch($type)
{
case 'product': $order_by_req = 'product_name ASC'; break;
case 'order': $order_by_req = 'date DESC'; break;
case 'global': $order_by_req = 'id_sale ASC'; break;
}
switch($type)
{
case 'global':
case 'summary':
if($date_req != '')
{
$req = 'SELECT
id_sale,
SUM(total_products_price) AS total_products_price,
SUM(total_products_price_tax_excl) as total_products_price_tax_excl,
SUM(total_products) AS total_products,
SUM(total_wholesale_price) AS total_wholesale_price,
SUM(rate_amount) AS rate_amount,
AVG(`rate`) AS `rate`
FROM '._DB_PREFIX_.'privatesales_stats_order
WHERE id_sale = '.(int)$sale->id.'
'.$date_req.'
GROUP BY id_sale';
return Db::getInstance()->getRow($req);
}
else
{
return Db::getInstance()->getRow('SELECT * FROM '._DB_PREFIX_.'privatesales_stats_order_global WHERE id_sale = '.$sale->id);
}
break;
case 'product':
$sql =
'SELECT
id_sale,
product_id,
reference,
supplier_reference,
SUM(total_products_price) AS total_total_products_price,
SUM(total_products_price_tax_excl) AS total_total_products_price_tax_excl,
SUM(total_products) AS total_total_products,
SUM(rate_amount) AS rate_amount,
AVG(`rate`) AS `rate`,
SUM(total_products_wholesale_price) AS total_total_products_wholesale_price,
name as product_name
FROM '._DB_PREFIX_.'privatesales_stats_products a
WHERE id_sale = '.(int)$sale->id.'
'.$date_req.'
GROUP BY id_sale, product_id, product_attribute_id
ORDER BY '.$order_by_req.'
';
return Db::getInstance()->executeS($sql);
break;
case 'order':
return Db::getInstance()->executeS('SELECT
id_sale,
`date`,
SUM(total_products_price) AS total_total_products_price,
SUM(total_products_price_tax_excl) AS total_products_price_tax_excl,
SUM(total_products) AS total_total_products,
SUM(total_wholesale_price) AS total_total_wholesale_price,
SUM(rate_amount) AS rate_amount,
AVG(`rate`) AS `rate`
FROM '._DB_PREFIX_.'privatesales_stats_order
WHERE id_sale = '.$sale->id.'
'.$date_req.'
GROUP BY id_sale, date
ORDER BY '.$order_by_req.'
');
break;
}
}
/*******************************FIN RECUPERATION*********************************/
/*******************************EXPORT*********************************/
public static function getSaleExport(SaleCoreExtend $sale, $order_states = array(), $type = 1, DateTime $date_from, DateTime $date_to)
{ //TYPE 1 = BDC ; TYPE 2 = MARGE
if(count($order_states) == 0)
throw new Exception("Aucun statut de commande sélectionné");
$ids_products = $sale->getProducts();
if(count($ids_products) == 0)
throw new Exception("Aucun produit pour cette vente");
$orders = self::getProductsOrder($ids_products, $order_states, $date_from, $date_to);
self::$array_product = array();
foreach($ids_products as $id_product)
self::$array_product[$id_product] = new Product($id_product);
$lines = self::getSaleExportLine($orders, $type);
if(count($lines) == 0)
throw new Exception("Aucune vente pour cette vente privée");
return $lines;
}
public static function getProductsOrder($ids_products = array(), $order_states = array(), DateTime $date_from = null, DateTime $date_to = null)
{
if($date_from !== null && $date_to !== null)
{
$format = 'Y-m-d H:i:s';
$date_from = $date_from->format($format);
$date_to = $date_to->format($format);
if(!Validate::isDate($date_from) || !Validate::isDate($date_to))
throw new PrestaShopException(Tools::displayError('Invalid date'));
}
$req = 'SELECT od.*
FROM '._DB_PREFIX_.'order_detail od
RIGHT JOIN '._DB_PREFIX_.'orders o
ON (
od.id_order = o.id_order
'.($date_from !== null && $date_to !== null && Validate::isDate($date_from) && Validate::isDate($date_to) ?
'AND o.date_add >= "'.$date_from.'" AND o.date_add <= "'.$date_to.'"' : '' ).'
)
WHERE (SELECT id_order_state
FROM '._DB_PREFIX_.'order_history oh
WHERE o.id_order = oh.id_order
ORDER BY id_order_history DESC
LIMIT 1)
IN ("'.implode('","', $order_states).'")
AND product_id IN ("'.implode('","', $ids_products).'")';
$res = Db::getInstance()->executeS($req);
return $res;
}
public static function getProductPriceWithReduction($values)
{
return (float)( $values['product_price']*( 1-($values['reduction_percent']/100) ) );
}
public static function getSaleExportLine($lines, $type, $by_product_price = false)
{
$arrayTmp = array();
$g = 0;
foreach($lines as $line)
{
if( ($line['product_quantity'] - $line['product_quantity_reinjected']) == 0)
continue;
if(!isset($arrayTmp[$line['product_id']]))
$arrayTmp[$line['product_id']] = array();
$product_price = self::getProductPriceWithReduction($line);
if($by_product_price)
{
if(!isset($arrayTmp[$line['product_id']][$line['product_attribute_id']]))
$arrayTmp[$line['product_id']][$line['product_attribute_id']] = array();
if(!isset($arrayTmp[$line['product_id']][$line['product_attribute_id']][$product_price]))
$arrayTmp[$line['product_id']][$line['product_attribute_id']][$product_price] = array('line' => $line, 'total' => 0);
}
else
{
if(!isset($arrayTmp[$line['product_id']][$line['product_attribute_id']]))
$arrayTmp[$line['product_id']][$line['product_attribute_id']] = array('line' => $line, 'total' => 0);
}
$quantity = $line['product_quantity'] - $line['product_quantity_reinjected'];
if($by_product_price)
$arrayTmp[$line['product_id']][$line['product_attribute_id']][$product_price]['total'] += $quantity;
else
$arrayTmp[$line['product_id']][$line['product_attribute_id']]['total'] += $quantity;
}
return $lines = $arrayTmp;
}
/*******************************FIN EXPORT*********************************/
}