2016-01-04 12:49:26 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class SaleStats
|
|
|
|
{
|
|
|
|
public $sale;
|
|
|
|
public $category;
|
|
|
|
public $data_stats = array();
|
|
|
|
public $data_subcategories = array();
|
|
|
|
|
|
|
|
public $lang = array(
|
|
|
|
'name' => 'Nom de la vente',
|
|
|
|
'date_start' => 'Date de début',
|
|
|
|
'date_end' => 'Date de fin',
|
|
|
|
'duration' => 'Nb jours',
|
|
|
|
'nb_ref' => 'Nb de réf.',
|
|
|
|
'nb_quantity_start' => 'Quantité mise en vente',
|
|
|
|
'nb_order_multi' => 'Nb commandes Multi',
|
|
|
|
'nb_order_simple' => 'Nb commandes Simples',
|
|
|
|
'nb_order_total' => 'Nb commandes Total',
|
|
|
|
'taux_multi' => 'Taux de multi',
|
|
|
|
'quantity_sale' => 'Quantités vendues',
|
|
|
|
'percent_sale' => '% d\'écoulement du stock',
|
|
|
|
'percent_out_of_stock' => '% produits épuisés ("Hors stock")',
|
|
|
|
'ca_ttc' => 'CA TTC produit',
|
|
|
|
'marge' => 'Taux de marge',
|
|
|
|
'total_bdc_ht' => 'BDC HT',
|
|
|
|
|
|
|
|
'bestsale_1_product' => 'Meilleure vente 1',
|
|
|
|
'bestsale_1_quantity' => 'Quantité',
|
|
|
|
'bestsale_1_ca' => 'Montant HT',
|
|
|
|
|
|
|
|
'bestsale_2_product' => 'Meilleure vente 2',
|
|
|
|
'bestsale_2_quantity' => 'Quantité',
|
|
|
|
'bestsale_2_ca' => 'Montant HT',
|
|
|
|
|
|
|
|
'bestsale_3_product' => 'Meilleure vente 3',
|
|
|
|
'bestsale_3_quantity' => 'Quantité',
|
|
|
|
'bestsale_3_ca' => 'Montant HT',
|
|
|
|
|
|
|
|
'cat_name' => 'Titre de la catégorie',
|
|
|
|
'total_ref' => 'Nb ID',
|
|
|
|
'total_quantity' => 'Quantité vendue',
|
|
|
|
'total_amount_wholesale_price' => 'Total prix achat HT',
|
|
|
|
);
|
|
|
|
|
|
|
|
public function __construct(Sale $sale, Category $category, $id_lang = 2)
|
|
|
|
{
|
|
|
|
$this->sale = $sale;
|
|
|
|
$this->category = $category;
|
|
|
|
$this->id_lang = $id_lang;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function loadData()
|
|
|
|
{
|
|
|
|
$this->addToStats('name', $this->category->name);
|
|
|
|
|
|
|
|
$this->addToStats('date_start', date('d-m-Y', strtotime($this->sale->date_start)) );
|
|
|
|
$this->addToStats('date_end', date('d-m-Y', strtotime($this->sale->date_end)) );
|
|
|
|
$diff = abs(strtotime($this->sale->date_start) - strtotime($this->sale->date_end));
|
|
|
|
$this->addToStats('duration', ceil($diff / (60 * 60 * 24)) );
|
|
|
|
|
|
|
|
$this->addToStats('nb_ref', $this->getNbRef());
|
|
|
|
|
|
|
|
$stat_info = $this->loadStatFromSale();
|
|
|
|
$this->addToStats('nb_quantity_start', $stat_info['init_stock']);
|
|
|
|
$this->addToStats('nb_order_multi', $stat_info['total_multi']);
|
|
|
|
$this->addToStats('nb_order_simple', $stat_info['total_orders'] - $stat_info['total_multi']);
|
|
|
|
|
|
|
|
$this->addToStats('nb_order_total', $stat_info['total_orders']);
|
|
|
|
$this->addToStats('taux_multi', number_format(($stat_info['total_multi'] / $stat_info['total_orders'] * 100),2).'%' );
|
|
|
|
$this->addToStats('quantity_sale', $stat_info['total_products']);
|
|
|
|
$this->addToStats('percent_sale', number_format(($stat_info['total_products'] / $stat_info['init_stock'] * 100),2).'%');
|
|
|
|
$this->addToStats('percent_out_of_stock', number_format($stat_info['oos'], 2) . '%');
|
|
|
|
$this->addToStats('ca_ttc', (int) $stat_info['total_sales_wt']);
|
|
|
|
$this->addToStats('marge', number_format(($stat_info['margin_rate'] * 100),2).'%');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function addToStats($key, $data)
|
|
|
|
{
|
|
|
|
$this->data_stats[$key] = $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function loadDataForSubCategory()
|
|
|
|
{
|
|
|
|
if (!Validate::isLoadedObject($this->category)) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-03-02 10:14:16 +01:00
|
|
|
$childrens = Category::getChildren($this->category->id, $this->id_lang, false);
|
2016-01-04 12:49:26 +01:00
|
|
|
if ($childrens) {
|
|
|
|
foreach ($childrens as $key => $child) {
|
|
|
|
$total_ref = self::getTotalRefByCategory($child['id_category']);
|
|
|
|
$quantity_sale = self::getTotalQuantityByCategory($child['id_category']);
|
|
|
|
$total_ca = self::getTotalWholesalePrice($child['id_category']);
|
|
|
|
|
|
|
|
$this->data_subcategories[] = array(
|
|
|
|
'cat_name' => $child['name'],
|
|
|
|
'total_ref' => (int) $total_ref,
|
|
|
|
'total_quantity' => (int) $quantity_sale,
|
|
|
|
'total_amount_wholesale_price' => $total_ca,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->reOrderSubCategory();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function reOrderSubCategory()
|
|
|
|
{
|
|
|
|
if ($this->data_subcategories) {
|
|
|
|
$size = count($this->data_subcategories);
|
|
|
|
for ($i=0; $i < $size; $i++) {
|
|
|
|
for ($j=$size-1; $j >= $i ; $j--) {
|
|
|
|
if ($this->data_subcategories[$j+1]['total_amount_wholesale_price']
|
|
|
|
> $this->data_subcategories[$j]['total_amount_wholesale_price']) {
|
|
|
|
$temp = $this->data_subcategories[$j+1];
|
|
|
|
$this->data_subcategories[$j+1] = $this->data_subcategories[$j];
|
|
|
|
$this->data_subcategories[$j] = $temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getTotalWholesalePrice($id_category)
|
|
|
|
{
|
|
|
|
$total = 0;
|
|
|
|
$details = Db::getInstance()->executeS('
|
|
|
|
SELECT *
|
|
|
|
FROM `ps_order_detail` od
|
|
|
|
LEFT JOIN `ps_orders` o ON o.`id_order` = od.`id_order`
|
|
|
|
WHERE od.`product_id` IN (
|
|
|
|
SELECT `id_product` FROM `'._DB_PREFIX_.'category_product` WHERE `id_category` = '.(int) $id_category.'
|
|
|
|
)
|
|
|
|
AND o.`valid` = 1
|
|
|
|
');
|
|
|
|
|
|
|
|
$wholesale_price = self::getWholesalePriceByCategory($id_category);
|
|
|
|
foreach ($details as $key => $detail) {
|
|
|
|
$wholesale_price_product = $wholesale_price[(int) $detail['product_id']]['wholesale_price'];
|
|
|
|
$wholesale_price_product_attribute = $wholesale_price[(int) $detail['product_id']]['product_attribute'][$detail['product_attribute_id']];
|
|
|
|
|
|
|
|
if ($detail['product_attribute_id'] != 0
|
|
|
|
&& $wholesale_price_product_attribute != 0) {
|
|
|
|
$total += $wholesale_price_product_attribute * ($detail['product_quantity'] - $detail['product_quantity_reinjected']);
|
|
|
|
} else {
|
|
|
|
$total += $wholesale_price_product * ($detail['product_quantity'] - $detail['product_quantity_reinjected']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (float) $total;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getWholesalePriceByCategory($id_category)
|
|
|
|
{
|
|
|
|
$wholesale_price_product = Db::getInstance()->ExecuteS('
|
|
|
|
SELECT `wholesale_price`, p.`id_product`
|
|
|
|
FROM `'._DB_PREFIX_.'product` p
|
|
|
|
LEFT JOIN `'._DB_PREFIX_.'order_detail` o ON o.`product_id` = p.`id_product`
|
|
|
|
WHERE o.`product_id` IN (
|
|
|
|
SELECT `id_product` FROM `'._DB_PREFIX_.'category_product` WHERE `id_category` = '.(int) $id_category.'
|
|
|
|
)'
|
|
|
|
);
|
|
|
|
$wholesale_price_product_attribute = Db::getInstance()->ExecuteS('
|
|
|
|
SELECT `wholesale_price`, pa.`id_product`, pa.`id_product_attribute`
|
|
|
|
FROM `'._DB_PREFIX_.'product_attribute` pa
|
|
|
|
LEFT JOIN `'._DB_PREFIX_.'order_detail` o ON o.`product_id` = pa.`id_product`
|
|
|
|
WHERE o.`product_id` IN (
|
|
|
|
SELECT `id_product` FROM `'._DB_PREFIX_.'category_product` WHERE `id_category` = '.(int) $id_category.'
|
|
|
|
)'
|
|
|
|
);
|
|
|
|
|
|
|
|
$prix_achat = array();
|
|
|
|
foreach ($wholesale_price_product as $key => $price) {
|
|
|
|
$prix_achat[$price['id_product']]['wholesale_price'] = $price['wholesale_price'];
|
|
|
|
$prix_achat[$price['id_product']]['product_attribute'] = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($wholesale_price_product_attribute) {
|
|
|
|
foreach ($wholesale_price_product_attribute as $key => $price) {
|
|
|
|
$prix_achat[$price['id_product']]['product_attribute'][(int) $price['id_product_attribute']] = $price['wholesale_price'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $prix_achat;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getTotalQuantityByCategory($id_category)
|
|
|
|
{
|
|
|
|
return (int) Db::getInstance()->getValue('
|
|
|
|
SELECT sum(od.`product_quantity` - od.`product_quantity_refunded` ) as total_sale
|
|
|
|
FROM `'._DB_PREFIX_.'order_detail` od
|
|
|
|
WHERE od.`product_id` IN (
|
|
|
|
SELECT `id_product` FROM `'._DB_PREFIX_.'category_product` WHERE `id_category` = '.(int) $id_category.'
|
|
|
|
)'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getTotalRefByCategory($id_category)
|
|
|
|
{
|
|
|
|
return (int) Db::getInstance()->getValue('
|
|
|
|
SELECT COUNT(DISTINCT(`id_product`)) as total_ref
|
|
|
|
FROM `'._DB_PREFIX_.'category_product`
|
|
|
|
WHERE id_category = '.(int) $id_category.'
|
|
|
|
');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function export()
|
|
|
|
{
|
|
|
|
$filename = 'Stats vente '. $this->sale->title[2].'.csv';
|
|
|
|
header('Content-Type: application/force-download; charset=UTF-8');
|
|
|
|
header('Content-disposition: attachment; filename="'.$filename.'"');
|
|
|
|
$fp = fopen("php://output", 'w+');
|
|
|
|
|
|
|
|
foreach ($this->data_stats as $key => $stat) {
|
|
|
|
$text = $this->lang[$key] . ';' . $stat ."\r\n";
|
|
|
|
fwrite($fp, $text);
|
|
|
|
}
|
|
|
|
foreach ($this->data_subcategories as $key => $subcategories) {
|
|
|
|
fwrite($fp, 'Sous categorie '. ($key+1)."\r\n");
|
|
|
|
|
|
|
|
foreach ($subcategories as $key_2 => $subcategory) {
|
|
|
|
$text = $this->lang[$key_2] . ';' . $subcategory ."\r\n";
|
|
|
|
fwrite($fp, $text);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose($fp);
|
|
|
|
die;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getNbRef()
|
|
|
|
{
|
|
|
|
return (int) Db::getInstance()->getValue('
|
|
|
|
SELECT COUNT(DISTINCT(p.`reference`)) as nb_ref
|
|
|
|
FROM `'._DB_PREFIX_.'product` p
|
|
|
|
LEFT JOIN `'._DB_PREFIX_.'product_ps_cache` pc ON (pc.`id_product` = p.`id_product`)
|
|
|
|
WHERE pc.`id_sale` = '.(int) $this->sale->id.'
|
|
|
|
');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function loadStatFromSale()
|
|
|
|
{
|
|
|
|
return Db::getInstance()->getRow('
|
|
|
|
SELECT *
|
|
|
|
FROM `'._DB_PREFIX_.'privatesale_livestats_sale`
|
|
|
|
WHERE `id_sale` ='.(int)$this->sale->id
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|