mirror of
https://github.com/Karaka-Management/oms-SalesAnalysis.git
synced 2026-01-24 16:58:40 +00:00
Went through todos
This commit is contained in:
parent
f8d933b3f5
commit
3ab72fd319
|
|
@ -19,6 +19,7 @@ use Modules\SalesAnalysis\Models\ClientMapper;
|
|||
use Modules\SalesAnalysis\Models\GeneralMapper;
|
||||
use Modules\SalesAnalysis\Models\ItemMapper;
|
||||
use Modules\SalesAnalysis\Models\RegionMapper;
|
||||
use Modules\SalesAnalysis\Models\SalesRepMapper;
|
||||
use phpOMS\Asset\AssetType;
|
||||
use phpOMS\Contract\RenderableInterface;
|
||||
use phpOMS\Localization\ISO3166CharEnum;
|
||||
|
|
@ -37,6 +38,12 @@ use phpOMS\Views\View;
|
|||
* @license OMS License 1.0
|
||||
* @link https://jingga.app
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @feature Create a map of sales (maybe as data points or as heat maps)
|
||||
* https://github.com/Karaka-Management/oms-ClientManagement/issues/14
|
||||
*
|
||||
* @feature Create a map of all customers (maybe as data points or as heat maps)
|
||||
* https://github.com/Karaka-Management/oms-ClientManagement/issues/15
|
||||
*/
|
||||
final class BackendController extends Controller
|
||||
{
|
||||
|
|
@ -348,7 +355,7 @@ final class BackendController extends Controller
|
|||
* @since 1.0.0
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function viewBillAnalysis(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
|
||||
public function viewSalesRepAnalysis(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
|
||||
{
|
||||
$head = $response->data['Content']->head;
|
||||
$nonce = $this->app->appSettings->getOption('script-nonce');
|
||||
|
|
@ -358,9 +365,79 @@ final class BackendController extends Controller
|
|||
$head->addAsset(AssetType::JSLATE, 'Modules/SalesAnalysis/Controller/Controller.js?v=' . self::VERSION, ['nonce' => $nonce, 'type' => 'module']);
|
||||
|
||||
$view = new View($this->app->l11nManager, $request, $response);
|
||||
$view->setTemplate('/Modules/SalesAnalysis/Theme/Backend/analysis-bill');
|
||||
$view->setTemplate('/Modules/SalesAnalysis/Theme/Backend/analysis-rep');
|
||||
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005401001, $request, $response);
|
||||
|
||||
$businessStart = 1;
|
||||
$startOfYear = SmartDateTime::createFromDateTime(SmartDateTime::startOfYear($businessStart));
|
||||
$startCurrent = $request->getDataDateTime('startcurrent') ?? clone $startOfYear;
|
||||
$endCurrent = $request->getDataDateTime('endcurrent') ?? SmartDateTime::endOfMonth();
|
||||
$endCurrentIndex = SmartDateTime::calculateMonthIndex((int) $endCurrent->format('m'), $businessStart);
|
||||
$startComparison = $request->getDataDateTime('startcomparison') ?? SmartDateTime::createFromDateTime($startCurrent)->createModify(-1);
|
||||
$endComparison = $request->getDataDateTime('endcomparison') ?? SmartDateTime::createFromDateTime(SmartDateTime::endOfYear($businessStart))->smartModify(-1);
|
||||
$historyStart = $startOfYear->createModify(-9);
|
||||
|
||||
$view->data['startCurrent'] = $startCurrent;
|
||||
$view->data['endCurrent'] = $endCurrent;
|
||||
$view->data['startComparison'] = $startComparison;
|
||||
$view->data['endComparison'] = $endComparison;
|
||||
$view->data['historyStart'] = $historyStart;
|
||||
|
||||
$domestic = UnitMapper::get()
|
||||
->with('mainAddress')
|
||||
->where('id', $this->app->unitId)
|
||||
->execute();
|
||||
|
||||
[
|
||||
$mtdCurrent,
|
||||
$ytdCurrent,
|
||||
$monthlyCurrent
|
||||
] = SalesRepMapper::monthlySalesProfit(
|
||||
$startCurrent,
|
||||
$endCurrent,
|
||||
$businessStart
|
||||
);
|
||||
|
||||
[
|
||||
$mtdPY,
|
||||
$ytdPY,
|
||||
$monthlyPY
|
||||
] = SalesRepMapper::monthlySalesProfit(
|
||||
$startComparison,
|
||||
$endComparison,
|
||||
$businessStart
|
||||
);
|
||||
|
||||
[
|
||||
$view->data['mtdPYClientRep'],
|
||||
$view->data['mtdAClientRep'],
|
||||
$view->data['ytdPYClientRep'],
|
||||
$view->data['ytdAClientRep'],
|
||||
] = SalesRepMapper::mtdYtdRep(
|
||||
$startCurrent,
|
||||
$endCurrent,
|
||||
$startComparison,
|
||||
$endComparison,
|
||||
$businessStart
|
||||
);
|
||||
|
||||
$annualRepSales = SalesRepMapper::salesProfitRep($historyStart, $startCurrent, $startCurrent, $endCurrent);
|
||||
|
||||
[
|
||||
$view->data['mtdPYClientRepCount'],
|
||||
$view->data['mtdAClientRepCount'],
|
||||
$view->data['ytdPYClientRepCount'],
|
||||
$view->data['ytdAClientRepCount'],
|
||||
] = SalesRepMapper::mtdYtdClientRep(
|
||||
$startCurrent,
|
||||
$endCurrent,
|
||||
$startComparison,
|
||||
$endComparison,
|
||||
$businessStart
|
||||
);
|
||||
|
||||
$annualRepCount = SalesRepMapper::annualCustomerRep(clone $historyStart, $endCurrent);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +453,7 @@ final class BackendController extends Controller
|
|||
* @since 1.0.0
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function viewSalesRepAnalysis(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
|
||||
public function viewBillAnalysis(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
|
||||
{
|
||||
$head = $response->data['Content']->head;
|
||||
$nonce = $this->app->appSettings->getOption('script-nonce');
|
||||
|
|
@ -386,65 +463,9 @@ final class BackendController extends Controller
|
|||
$head->addAsset(AssetType::JSLATE, 'Modules/SalesAnalysis/Controller/Controller.js?v=' . self::VERSION, ['nonce' => $nonce, 'type' => 'module']);
|
||||
|
||||
$view = new View($this->app->l11nManager, $request, $response);
|
||||
$view->setTemplate('/Modules/SalesAnalysis/Theme/Backend/analysis-rep');
|
||||
$view->setTemplate('/Modules/SalesAnalysis/Theme/Backend/analysis-bill');
|
||||
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005401001, $request, $response);
|
||||
|
||||
/////
|
||||
$currentCustomerRegion = [
|
||||
'Europe' => (int) (\mt_rand(200, 400) / 4),
|
||||
'America' => (int) (\mt_rand(200, 400) / 4),
|
||||
'Asia' => (int) (\mt_rand(200, 400) / 4),
|
||||
'Africa' => (int) (\mt_rand(200, 400) / 4),
|
||||
'CIS' => (int) (\mt_rand(200, 400) / 4),
|
||||
'Other' => (int) (\mt_rand(200, 400) / 4),
|
||||
];
|
||||
|
||||
$view->data['currentCustomerRegion'] = $currentCustomerRegion;
|
||||
|
||||
$annualCustomerRegion = [];
|
||||
for ($i = 1; $i < 11; ++$i) {
|
||||
$annualCustomerRegion[] = [
|
||||
'year' => 2020 - 10 + $i,
|
||||
'Europe' => $a = (int) (\mt_rand(200, 400) / 4),
|
||||
'America' => $b = (int) (\mt_rand(200, 400) / 4),
|
||||
'Asia' => $c = (int) (\mt_rand(200, 400) / 4),
|
||||
'Africa' => $d = (int) (\mt_rand(200, 400) / 4),
|
||||
'CIS' => $e = (int) (\mt_rand(200, 400) / 4),
|
||||
'Other' => $f = (int) (\mt_rand(200, 400) / 4),
|
||||
'Total' => $a + $b + $c + $d + $e + $f,
|
||||
];
|
||||
}
|
||||
|
||||
$view->data['annualCustomerRegion'] = $annualCustomerRegion;
|
||||
|
||||
/////
|
||||
$currentCustomersRep = [];
|
||||
for ($i = 1; $i < 13; ++$i) {
|
||||
$currentCustomersRep['Rep ' . $i] = [
|
||||
'customers' => (int) (\mt_rand(200, 400) / 12),
|
||||
];
|
||||
}
|
||||
|
||||
\uasort($currentCustomersRep, function($a, $b) {
|
||||
return $b['customers'] <=> $a['customers'];
|
||||
});
|
||||
|
||||
$view->data['currentCustomersRep'] = $currentCustomersRep;
|
||||
|
||||
$annualCustomersRep = [];
|
||||
for ($i = 1; $i < 13; ++$i) {
|
||||
$annualCustomersRep['Rep ' . $i] = [];
|
||||
|
||||
for ($j = 1; $j < 11; ++$j) {
|
||||
$annualCustomersRep['Rep ' . $i][] = [
|
||||
'customers' => (int) (\mt_rand(200, 400) / 12),
|
||||
'year' => 2020 - 10 + $j,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$view->data['annualCustomersRep'] = $annualCustomersRep;
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ class ClientMapper extends DataMapperFactory
|
|||
clientmgmt_attr_value_l11n_title,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_transfer_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_transfer_sign) as netprofit
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ class GeneralMapper extends DataMapperFactory
|
|||
'SELECT
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_transfer_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_transfer_sign) as netprofit
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
|
|
@ -143,8 +143,8 @@ class GeneralMapper extends DataMapperFactory
|
|||
'SELECT
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_transfer_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_transfer_sign) as netprofit
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ class ItemMapper extends DataMapperFactory
|
|||
itemmgmt_attr_value_l11n_title,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_element_total_netsalesprice * billing_type_transfer_sign) as netsales,
|
||||
SUM(billing_bill_element_total_netprofit * billing_type_transfer_sign) as netprofit
|
||||
SUM(billing_bill_element_total_netsalesprice * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_element_total_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ class RegionMapper extends DataMapperFactory
|
|||
address_country,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_transfer_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_transfer_sign) as netprofit
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
|
|
@ -327,8 +327,8 @@ class RegionMapper extends DataMapperFactory
|
|||
address_country,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_transfer_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_transfer_sign) as netprofit
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
|
|
@ -394,8 +394,8 @@ class RegionMapper extends DataMapperFactory
|
|||
address_country,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_transfer_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_transfer_sign) as netprofit
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
|
|
|
|||
490
Models/SalesRepMapper.php
Executable file
490
Models/SalesRepMapper.php
Executable file
|
|
@ -0,0 +1,490 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 7.4
|
||||
*
|
||||
* @package Modules\SalesAnalysis\Models
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\SalesAnalysis\Models;
|
||||
|
||||
use Modules\Billing\Models\BillTransferType;
|
||||
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
|
||||
use phpOMS\DataStorage\Database\Query\Builder;
|
||||
use phpOMS\Stdlib\Base\SmartDateTime;
|
||||
|
||||
/**
|
||||
* Permission category enum.
|
||||
*
|
||||
* @package Modules\SalesAnalysis\Models
|
||||
* @license OMS License 1.0
|
||||
* @link https://jingga.app
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class SalesRepMapper extends DataMapperFactory
|
||||
{
|
||||
/**
|
||||
* @todo Re-implement, still in use?
|
||||
*/
|
||||
public static function monthlySalesProfit(
|
||||
\DateTime $start,
|
||||
\DateTime $end,
|
||||
int $businessStart = 1
|
||||
) : array
|
||||
{
|
||||
$endCurrentIndex = SmartDateTime::calculateMonthIndex((int) $end->format('m'), $businessStart);
|
||||
|
||||
$query = new Builder(self::$db);
|
||||
$query->raw(
|
||||
'SELECT
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
LEFT JOIN clientmgmt_client
|
||||
ON clientmgmt_client_id = billing_bill_client
|
||||
LEFT JOIN address
|
||||
ON clientmgmt_client_address = address_id
|
||||
WHERE
|
||||
billing_type_transfer_type = ' . BillTransferType::SALES . '
|
||||
AND billing_type_accounting = 1
|
||||
AND billing_bill_performance_date >= \'' . $start->format('Y-m-d') . '\'
|
||||
AND billing_bill_performance_date <= \'' . $end->format('Y-m-d') . '\'
|
||||
GROUP BY
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date),
|
||||
MONTH(billing_bill_performance_date)
|
||||
ORDER BY
|
||||
YEAR(billing_bill_performance_date) ASC,
|
||||
MONTH(billing_bill_performance_date) ASC,
|
||||
billing_bill_rep'
|
||||
);
|
||||
|
||||
$results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC) ?? [];
|
||||
|
||||
$monthlySales = [];
|
||||
|
||||
$mtd = [];
|
||||
$ytd = [];
|
||||
|
||||
foreach ($results as $result) {
|
||||
$monthIndex = SmartDateTime::calculateMonthIndex((int) $result['salesmonth'], $businessStart);
|
||||
|
||||
if (!isset($monthlySales[$result['billing_bill_rep']])) {
|
||||
$monthlySales[$result['billing_bill_rep']] = [];
|
||||
|
||||
$mtdA[$result['billing_bill_rep']] = ['net_sales' => 0, 'net_profit' => 0];
|
||||
$mtdPY[$result['billing_bill_rep']] = ['net_sales' => 0, 'net_profit' => 0];
|
||||
|
||||
$ytdA[$result['billing_bill_rep']] = ['net_sales' => 0, 'net_profit' => 0];
|
||||
$ytdPY[$result['billing_bill_rep']] = ['net_sales' => 0, 'net_profit' => 0];
|
||||
|
||||
for ($i = 1; $i < 3; ++$i) {
|
||||
$monthlySales[$result['billing_bill_rep']][$i] = \array_fill(1, 12, [
|
||||
'net_sales' => null,
|
||||
'net_profit' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// indexed according to the fiscal year
|
||||
$monthlySales[$result['billing_bill_rep']][$monthIndex] = [
|
||||
'net_sales' => (int) $result['netsales'],
|
||||
'net_profit' => (int) $result['netprofit'],
|
||||
];
|
||||
|
||||
if ($monthIndex === $endCurrentIndex) {
|
||||
$mtd[$result['billing_bill_rep']] = $monthlySales[$result['billing_bill_rep']][$monthIndex];
|
||||
}
|
||||
|
||||
if ($monthIndex <= $endCurrentIndex) {
|
||||
$ytd[$result['billing_bill_rep']]['net_sales'] += $monthlySales[$result['billing_bill_rep']][$monthIndex]['net_sales'];
|
||||
$ytd[$result['billing_bill_rep']]['net_profit'] += $monthlySales[$result['billing_bill_rep']][$monthIndex]['net_profit'];
|
||||
}
|
||||
}
|
||||
|
||||
return [$mtd, $ytd, $monthlySales];
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Re-implement, still in use?
|
||||
*/
|
||||
public static function annualCustomerRep(
|
||||
SmartDateTime $historyStart,
|
||||
\DateTime $endCurrent,
|
||||
int $businessStart = 1
|
||||
) : array {
|
||||
$query = new Builder(self::$db);
|
||||
$query->raw(
|
||||
'SELECT
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
COUNT(billing_bill_netsales) as client_count
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
LEFT JOIN clientmgmt_client
|
||||
ON clientmgmt_client_id = billing_bill_client
|
||||
LEFT JOIN address
|
||||
ON clientmgmt_client_address = address_id
|
||||
WHERE
|
||||
billing_type_transfer_type = ' . BillTransferType::SALES . '
|
||||
AND billing_type_accounting = 1
|
||||
AND billing_bill_performance_date >= \'' . $historyStart->format('Y-m-d') . '\'
|
||||
AND billing_bill_performance_date <= \'' . $endCurrent->format('Y-m-d') . '\'
|
||||
GROUP BY
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date),
|
||||
MONTH(billing_bill_performance_date)
|
||||
ORDER BY
|
||||
YEAR(billing_bill_performance_date) ASC,
|
||||
MONTH(billing_bill_performance_date) ASC,
|
||||
billing_bill_rep'
|
||||
);
|
||||
|
||||
$results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC) ?? [];
|
||||
|
||||
$annualCustomer = [];
|
||||
|
||||
$oldIndex = 1;
|
||||
// @todo this calculation doesn't consider the start of the fiscal year
|
||||
$period = (int) (((((int) $results[0]['salesyear']) - ((int) $historyStart->format('Y'))) * 12
|
||||
- ((int) $results[0]['salesmonth']) + ((int) $historyStart->format('m'))) / 12 + 1);
|
||||
|
||||
foreach ($results as $result) {
|
||||
$monthIndex = SmartDateTime::calculateMonthIndex((int) $result['salesmonth'], $businessStart);
|
||||
if ($monthIndex < $oldIndex) {
|
||||
$oldIndex = $monthIndex;
|
||||
|
||||
++$period;
|
||||
}
|
||||
|
||||
if ($period > 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
$oldIndex = $monthIndex;
|
||||
|
||||
if (!isset($annualCustomer[$result['billing_bill_rep']])) {
|
||||
for ($i = 1; $i < 11; ++$i) {
|
||||
$annualCustomer[$result['billing_bill_rep']][$i] = [
|
||||
'client_count' => 0,
|
||||
];
|
||||
|
||||
$historyStart->smartModify(1);
|
||||
}
|
||||
|
||||
$historyStart->smartModify(-10);
|
||||
}
|
||||
|
||||
// indexed according to the fiscal year
|
||||
$annualCustomer[$result['billing_bill_rep']][$period]['client_count'] += (int) $result['client_count'];
|
||||
}
|
||||
|
||||
return $annualCustomer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Re-implement, still in use?
|
||||
*/
|
||||
public static function mtdYtdClientRep(
|
||||
\DateTime $startCurrent,
|
||||
\DateTime $endCurrent,
|
||||
\DateTime $startComparison,
|
||||
\DateTime $endComparison,
|
||||
int $businessStart = 1,
|
||||
) : array {
|
||||
// @todo this cannot be correct since the same customer may buy something in two month (distinct is required over an actual period)
|
||||
$endCurrentIndex = SmartDateTime::calculateMonthIndex((int) $endCurrent->format('m'), $businessStart);
|
||||
|
||||
$query = new Builder(self::$db);
|
||||
$query->raw(
|
||||
'SELECT
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
COUNT(billing_bill_netsales) as client_count
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
LEFT JOIN clientmgmt_client
|
||||
ON clientmgmt_client_id = billing_bill_client
|
||||
LEFT JOIN address
|
||||
ON clientmgmt_client_address = address_id
|
||||
WHERE
|
||||
billing_type_transfer_type = ' . BillTransferType::SALES . '
|
||||
AND billing_type_accounting = 1
|
||||
AND billing_bill_performance_date >= \'' . $startComparison->format('Y-m-d') . '\'
|
||||
AND billing_bill_performance_date <= \'' . $endCurrent->format('Y-m-d') . '\'
|
||||
GROUP BY
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date),
|
||||
MONTH(billing_bill_performance_date)
|
||||
ORDER BY
|
||||
YEAR(billing_bill_performance_date) ASC,
|
||||
MONTH(billing_bill_performance_date) ASC,
|
||||
billing_bill_rep ASC'
|
||||
);
|
||||
|
||||
$results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC) ?? [];
|
||||
|
||||
$oldIndex = 1;
|
||||
$period = 1;
|
||||
|
||||
$mtdAClientCountry = [];
|
||||
$mtdPYClientCountry = [];
|
||||
|
||||
$ytdAClientCountry = [];
|
||||
$ytdPYClientCountry = [];
|
||||
|
||||
foreach ($results as $result) {
|
||||
$monthIndex = SmartDateTime::calculateMonthIndex((int) $result['salesmonth'], $businessStart);
|
||||
if ($monthIndex < $oldIndex) {
|
||||
$oldIndex = $monthIndex;
|
||||
|
||||
++$period;
|
||||
}
|
||||
|
||||
if ($period > 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
$oldIndex = $monthIndex;
|
||||
|
||||
// indexed according to the fiscal year
|
||||
$temp = [
|
||||
'client_count' => (int) $result['client_count'],
|
||||
];
|
||||
|
||||
if ($temp['client_count'] === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($monthIndex === $endCurrentIndex) {
|
||||
if ($period === 1) {
|
||||
$mtdPYClientCountry[$result['billing_bill_rep']] = $temp;
|
||||
} else {
|
||||
$mtdAClientCountry[$result['billing_bill_rep']] = $temp;
|
||||
}
|
||||
}
|
||||
|
||||
if ($monthIndex <= $endCurrentIndex) {
|
||||
if (!isset($ytdPYClientCountry[$result['billing_bill_rep']])) {
|
||||
$ytdPYClientCountry[$result['billing_bill_rep']] = [
|
||||
'client_count' => 0,
|
||||
];
|
||||
|
||||
$ytdAClientCountry[$result['billing_bill_rep']] = [
|
||||
'client_count' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
if ($period === 1) {
|
||||
$ytdPYClientCountry[$result['billing_bill_rep']]['client_count'] += $temp['client_count'];
|
||||
} else {
|
||||
$ytdAClientCountry[$result['billing_bill_rep']]['client_count'] += $temp['client_count'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
$mtdPYClientCountry,
|
||||
$mtdAClientCountry,
|
||||
$ytdPYClientCountry,
|
||||
$ytdAClientCountry,
|
||||
];
|
||||
}
|
||||
|
||||
// @todo remove businessStart, that should be baked into the historyStart
|
||||
// Explanation: in the past I had to compare periods which weren't even business years!!!
|
||||
/**
|
||||
* @todo Re-implement, still in use?
|
||||
*/
|
||||
public static function salesProfitRep(
|
||||
\DateTime $historyStart,
|
||||
\DateTime $historyEnd,
|
||||
\DateTime $currentStart,
|
||||
\DateTime $currentEnd
|
||||
) : array {
|
||||
$query = new Builder(self::$db);
|
||||
$query->raw(
|
||||
'SELECT
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
LEFT JOIN clientmgmt_client
|
||||
ON clientmgmt_client_id = billing_bill_client
|
||||
LEFT JOIN address
|
||||
ON clientmgmt_client_address = address_id
|
||||
WHERE
|
||||
billing_type_transfer_type = ' . BillTransferType::SALES . '
|
||||
AND billing_type_accounting = 1
|
||||
AND billing_bill_performance_date >= \'' . $historyStart->format('Y-m-d') . '\'
|
||||
AND billing_bill_performance_date <= \'' . $currentEnd->format('Y-m-d') . '\'
|
||||
GROUP BY
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date),
|
||||
MONTH(billing_bill_performance_date)
|
||||
ORDER BY
|
||||
YEAR(billing_bill_performance_date) ASC,
|
||||
MONTH(billing_bill_performance_date) ASC,
|
||||
billing_bill_rep ASC'
|
||||
);
|
||||
|
||||
$results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC) ?? [];
|
||||
|
||||
$sales = [];
|
||||
$period = 0;
|
||||
|
||||
foreach ($results as $result) {
|
||||
// @todo Handle fiscal year
|
||||
$period = $result['salesyear'] - ((int) $historyStart->format('Y')) + 1;
|
||||
if (!isset($sales[$result['billing_bill_rep']])) {
|
||||
for ($i = 1; $i < 11; ++$i) {
|
||||
$sales[$result['billing_bill_rep']][$i] = [
|
||||
'net_sales' => 0,
|
||||
'net_profit' => 0,
|
||||
'year' => $period === 0 ? 'PY' : 'A',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$sales[$result['billing_bill_rep']][$period]['net_sales'] += (int) $result['netsales'];
|
||||
$sales[$result['billing_bill_rep']][$period]['net_profit'] += (int) $result['netprofit'];
|
||||
}
|
||||
|
||||
return $sales;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Re-implement, still in use?
|
||||
*/
|
||||
public static function mtdYtdRep(
|
||||
\DateTime $startCurrent,
|
||||
\DateTime $endCurrent,
|
||||
\DateTime $startComparison,
|
||||
\DateTime $endComparison,
|
||||
int $businessStart = 1,
|
||||
) : array {
|
||||
$endCurrentIndex = SmartDateTime::calculateMonthIndex((int) $endCurrent->format('m'), $businessStart);
|
||||
|
||||
$query = new Builder(self::$db);
|
||||
$query->raw(
|
||||
'SELECT
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date) as salesyear,
|
||||
MONTH(billing_bill_performance_date) as salesmonth,
|
||||
SUM(billing_bill_netsales * billing_type_sign) as netsales,
|
||||
SUM(billing_bill_netprofit * billing_type_sign) as netprofit
|
||||
FROM billing_bill
|
||||
LEFT JOIN billing_type
|
||||
ON billing_bill_type = billing_type_id
|
||||
LEFT JOIN clientmgmt_client
|
||||
ON clientmgmt_client_id = billing_bill_client
|
||||
LEFT JOIN address
|
||||
ON clientmgmt_client_address = address_id
|
||||
WHERE
|
||||
billing_type_transfer_type = ' . BillTransferType::SALES . '
|
||||
AND billing_type_accounting = 1
|
||||
AND billing_bill_performance_date >= \'' . $startComparison->format('Y-m-d') . '\'
|
||||
AND billing_bill_performance_date <= \'' . $endCurrent->format('Y-m-d') . '\'
|
||||
GROUP BY
|
||||
billing_bill_rep,
|
||||
YEAR(billing_bill_performance_date),
|
||||
MONTH(billing_bill_performance_date)
|
||||
ORDER BY
|
||||
YEAR(billing_bill_performance_date) ASC,
|
||||
MONTH(billing_bill_performance_date) ASC,
|
||||
billing_bill_rep ASC'
|
||||
);
|
||||
|
||||
$results = $query->execute()?->fetchAll(\PDO::FETCH_ASSOC) ?? [];
|
||||
|
||||
$oldIndex = 1;
|
||||
$period = 1;
|
||||
|
||||
$mtdAClientCountry = [];
|
||||
$mtdPYClientCountry = [];
|
||||
|
||||
$ytdAClientCountry = [];
|
||||
$ytdPYClientCountry = [];
|
||||
|
||||
foreach ($results as $result) {
|
||||
$monthIndex = SmartDateTime::calculateMonthIndex((int) $result['salesmonth'], $businessStart);
|
||||
if ($monthIndex < $oldIndex) {
|
||||
$oldIndex = $monthIndex;
|
||||
|
||||
++$period;
|
||||
}
|
||||
|
||||
if ($period > 2) {
|
||||
break;
|
||||
}
|
||||
|
||||
$oldIndex = $monthIndex;
|
||||
|
||||
// indexed according to the fiscal year
|
||||
$temp = [
|
||||
'net_sales' => (int) $result['netsales'],
|
||||
'net_profit' => (int) $result['netprofit'],
|
||||
];
|
||||
|
||||
if (($temp['net_sales'] === 0 && $temp['net_profit'] === 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($monthIndex === $endCurrentIndex) {
|
||||
if ($period === 1) {
|
||||
$mtdPYClientCountry[$result['billing_bill_rep']] = $temp;
|
||||
} else {
|
||||
$mtdAClientCountry[$result['billing_bill_rep']] = $temp;
|
||||
}
|
||||
}
|
||||
|
||||
if ($monthIndex <= $endCurrentIndex) {
|
||||
if (!isset($ytdPYClientCountry[$result['billing_bill_rep']])) {
|
||||
$ytdPYClientCountry[$result['billing_bill_rep']] = [
|
||||
'net_sales' => 0,
|
||||
'net_profit' => 0,
|
||||
];
|
||||
|
||||
$ytdAClientCountry[$result['billing_bill_rep']] = [
|
||||
'net_sales' => 0,
|
||||
'net_profit' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
if ($period === 1) {
|
||||
$ytdPYClientCountry[$result['billing_bill_rep']]['net_sales'] += $temp['net_sales'];
|
||||
$ytdPYClientCountry[$result['billing_bill_rep']]['net_profit'] += $temp['net_profit'];
|
||||
} else {
|
||||
$ytdAClientCountry[$result['billing_bill_rep']]['net_sales'] += $temp['net_sales'];
|
||||
$ytdAClientCountry[$result['billing_bill_rep']]['net_profit'] += $temp['net_profit'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
$mtdPYClientCountry,
|
||||
$mtdAClientCountry,
|
||||
$ytdPYClientCountry,
|
||||
$ytdAClientCountry,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -68,4 +68,6 @@ return ['SalesAnalysis' => [
|
|||
'America' => 'Amerika',
|
||||
'Oceania' => 'Ozeanien',
|
||||
'Africa' => 'Afrika',
|
||||
'SalesRep' => 'Verkäufer',
|
||||
'SalesReps' => 'Verkäufer',
|
||||
]];
|
||||
|
|
|
|||
|
|
@ -68,4 +68,6 @@ return ['SalesAnalysis' => [
|
|||
'America' => 'America',
|
||||
'Oceania' => 'Oceania',
|
||||
'Africa' => 'Africa',
|
||||
'SalesRep' => 'SalesRep',
|
||||
'SalesReps' => 'SalesReps',
|
||||
]];
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user