From fcecebe47907a9347e2a5242f1bd76482c67b345 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 18 Apr 2021 22:29:46 +0200 Subject: [PATCH] new form layout and other tpl fixes --- Controller/BackendController.php | 163 ++++- Theme/Backend/client-analysis.tpl.php | 882 ++++++++++++++++++++++++++ Theme/Backend/client-list.tpl.php | 2 +- 3 files changed, 1043 insertions(+), 4 deletions(-) create mode 100644 Theme/Backend/client-analysis.tpl.php diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 9764e1e..01aef4f 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -25,6 +25,7 @@ use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Stdlib\Base\SmartDateTime; use phpOMS\Views\View; +use phpOMS\Localization\ISO3166NameEnum; /** * ClientManagement class. @@ -54,10 +55,9 @@ final class BackendController extends Controller $view->setTemplate('/Modules/ClientManagement/Theme/Backend/client-list'); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1003102001, $request, $response)); - $client = ClientMapper - ::with('notes', models: null) + $client = ClientMapper::with('notes', models: null) ::with('contactElements', models: null) - ::with('type', 'backend_image', models: [Media::class]) // @todo: it would be nicer if I coult say files:type or files/type and remove the models parameter? + //::with('type', 'backend_image', models: [Media::class]) // @todo: it would be nicer if I coult say files:type or files/type and remove the models parameter? @todo: uncommented for now because the type is also part of client and therefore bug. that's the problem with a mix of black/whitelisting in the datamapper with the "with" feature. make it whitelist only for belongsTo, ownsMany, hasOne, .... ::getAfterPivot(0, null, 25); $view->addData('client', $client); @@ -163,4 +163,161 @@ final class BackendController extends Controller return $view; } + + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function viewClientAnalysis(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface + { + $head = $response->get('Content')->getData('head'); + $head->addAsset(AssetType::CSS, 'Resources/chartjs/Chartjs/chart.css'); + $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/Chartjs/chart.js'); + $head->addAsset(AssetType::JSLATE, 'Modules/ClientManagement/Controller.js', ['type' => 'module']); + + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/ClientManagement/Theme/Backend/client-analysis'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1001602001, $request, $response)); + + // + $monthlySalesCosts = []; + for ($i = 1; $i < 13; ++$i) { + $monthlySalesCosts[] = [ + 'net_sales' => $sales = \mt_rand(1200000000, 2000000000), + 'net_costs' => (int) ($sales * \mt_rand(25, 55) / 100), + 'year' => 2020, + 'month' => $i, + ]; + } + + $view->addData('monthlySalesCosts', $monthlySalesCosts); + + // + $salesCustomer = []; + for ($i = 1; $i < 13; ++$i) { + $salesCustomer[] = [ + 'net_sales' => $sales = \mt_rand(1200000000, 2000000000), + 'customers' => \mt_rand(200, 400), + 'year' => 2020, + 'month' => $i, + ]; + } + + $view->addData('salesCustomer', $salesCustomer); + + // + $customerRetention = []; + for ($i = 1; $i < 10; ++$i) { + $customerRetention[] = [ + 'customers' => \mt_rand(200, 400), + 'year' => \date('y') - 9 + $i, + ]; + } + + $view->addData('customerRetention', $customerRetention); + + // + $customerRegion = [ + '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->addData('customerRegion', $customerRegion); + + // + $customersRep = []; + for ($i = 1; $i < 13; ++$i) { + $customersRep['Rep ' . $i] = [ + 'customers' => (int) (\mt_rand(200, 400) / 12), + ]; + } + + \uasort($customersRep, function($a, $b) { return $b['customers'] <=> $a['customers']; }); + + $view->addData('customersRep', $customersRep); + + // + $customersCountry = []; + for ($i = 1; $i < 13; ++$i) { + $country = ISO3166NameEnum::getRandom(); + $customersCountry[\substr($country, 0, 20)] = [ + 'customers' => (int) (\mt_rand(200, 400) / 12), + ]; + } + + \uasort($customersCountry, function($a, $b) { return $b['customers'] <=> $a['customers']; }); + + $view->addData('customersCountry', $customersCountry); + + // + $customerGroups = []; + for ($i = 1; $i < 7; ++$i) { + $customerGroups['Group ' . $i] = [ + 'customers' => (int) (\mt_rand(200, 400) / 12), + ]; + } + + $view->addData('customerGroups', $customerGroups); + + // + $salesRegion = [ + 'Europe' => (int) (\mt_rand(1200000000, 2000000000) / 4), + 'America' => (int) (\mt_rand(1200000000, 2000000000) / 4), + 'Asia' => (int) (\mt_rand(1200000000, 2000000000) / 4), + 'Africa' => (int) (\mt_rand(1200000000, 2000000000) / 4), + 'CIS' => (int) (\mt_rand(1200000000, 2000000000) / 4), + 'Other' => (int) (\mt_rand(1200000000, 2000000000) / 4), + ]; + + $view->addData('salesRegion', $salesRegion); + + // + $salesRep = []; + for ($i = 1; $i < 13; ++$i) { + $salesRep['Rep ' . $i] = [ + 'net_sales' => (int) (\mt_rand(1200000000, 2000000000) / 12), + ]; + } + + \uasort($salesRep, function($a, $b) { return $b['net_sales'] <=> $a['net_sales']; }); + + $view->addData('salesRep', $salesRep); + + // + $salesCountry = []; + for ($i = 1; $i < 13; ++$i) { + $country = ISO3166NameEnum::getRandom(); + $salesCountry[\substr($country, 0, 20)] = [ + 'net_sales' => (int) (\mt_rand(1200000000, 2000000000) / 12), + ]; + } + + \uasort($salesCountry, function($a, $b) { return $b['net_sales'] <=> $a['net_sales']; }); + + $view->addData('salesCountry', $salesCountry); + + // + $salesGroups = []; + for ($i = 1; $i < 7; ++$i) { + $salesGroups['Group ' . $i] = [ + 'net_sales' => (int) (\mt_rand(1200000000, 2000000000) / 12), + ]; + } + + $view->addData('salesGroups', $salesGroups); + + return $view; + } } diff --git a/Theme/Backend/client-analysis.tpl.php b/Theme/Backend/client-analysis.tpl.php new file mode 100644 index 0000000..05f953d --- /dev/null +++ b/Theme/Backend/client-analysis.tpl.php @@ -0,0 +1,882 @@ +getData('nav')->render(); +?> + +
+
+ +
+
+ request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>> +
+
+
+
+
getHtml('Filter'); ?>
+
+
+ +
+
+
+
+
+
+
+
+
+ + request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>> +
+
+
+
+
+ Sales / Customers + +
+ getData('salesCustomer'); ?> +
+ + + ], + "datasets": [ + { + "label": "getHtml('Customers'); ?>", + "type": "line", + "data": [ + + + ], + "yAxisID": "axis-2", + "fill": false, + "borderColor": "rgb(255, 99, 132)", + "backgroundColor": "rgb(255, 99, 132)", + "tension": 0.0 + }, + { + "label": "getHtml('Sales'); ?>", + "type": "bar", + "data": [ + + + ], + "yAxisID": "axis-1", + "fill": false, + "borderColor": "rgb(54, 162, 235)", + "backgroundColor": "rgb(54, 162, 235)", + "tension": 0.0 + } + ] + }, + "options": { + "title": { + "display": false, + "text": "Sales / Customers" + }, + "scales": { + "yAxes": [ + { + "id": "axis-1", + "display": true, + "position": "left" + }, + { + "id": "axis-2", + "display": true, + "position": "right", + "scaleLabel": { + "display": true, + "labelString": "getHtml('Customers'); ?>" + }, + "gridLines": { + "display": false + } + } + ] + } + } + }'> +
+ + +
+ + + + + + + +
Month + Sales + Customer count +
+ getCurrency(); ?> + + +
Total + getCurrency(); ?> + +
+
+
+
+
+
+ +
+
+ getData('customerRetention'); ?> +
+ + + ], + "datasets": [ + { + "label": "getHtml('Retention'); ?>", + "type": "line", + "data": [ + + + ], + "yAxisID": "axis-1", + "fill": false, + "borderColor": "rgb(54, 162, 235)", + "backgroundColor": "rgb(54, 162, 235)", + "tension": 0.0 + } + ] + }, + "options": { + "title": { + "display": true, + "text": "Customer retention" + }, + "scales": { + "yAxes": [ + { + "id": "axis-1", + "display": true, + "position": "left" + } + ] + } + } + }'> + + + + + + + + +
Year + Retention +
+ + +
Avg. + +
+
+
+
+ +
+
+ getData('customerRegion'); ?> +
+ , + , + , + , + , + + ], + "backgroundColor": [ + "rgb(255, 99, 132)", + "rgb(255, 159, 64)", + "rgb(255, 205, 86)", + "rgb(75, 192, 192)", + "rgb(54, 162, 235)", + "rgb(153, 102, 255)" + ] + }] + }, + "options": { + "title": { + "display": true, + "text": "Customers per region" + } + } + }'> + + + + + $values) : $sum += $values; ?> + + +
Region + Customer count +
+ + +
Total + +
+
+
+
+ +
+
+ getData('customersRep'); ?> +
+ + ], + "datasets": [ + { + "label": "getHtml('Customers'); ?>", + "type": "horizontalBar", + "data": [ + + + ], + "fill": false, + "borderColor": "rgb(54, 162, 235)", + "backgroundColor": "rgb(54, 162, 235)", + "tension": 0.0 + } + ] + }, + "options": { + "title": { + "display": true, + "text": "Customers per rep" + } + } + }'> + + + + + $values) : $sum += $values['customers']; ?> + + +
Rep + Customer count +
+ + +
Total + +
+
+
+
+ +
+
+ getData('customersCountry'); ?> +
+ + ], + "datasets": [ + { + "label": "getHtml('Customers'); ?>", + "type": "horizontalBar", + "data": [ + + + ], + "fill": false, + "borderColor": "rgb(54, 162, 235)", + "backgroundColor": "rgb(54, 162, 235)", + "tension": 0.0 + } + ] + }, + "options": { + "title": { + "display": true, + "text": "Customers per country" + } + } + }'> + + + + + + $values) : $sum += $values['customers']; ?> + + +
Country + Customer count +
+ + +
Total + +
+
+
+
+ +
+
+ getData('customerGroups'); ?> +
+ + ], + "datasets": [{ + "data": [ + + + ], + "backgroundColor": [ + "rgb(255, 99, 132)", + "rgb(255, 159, 64)", + "rgb(255, 205, 86)", + "rgb(75, 192, 192)", + "rgb(54, 162, 235)", + "rgb(153, 102, 255)" + ] + }] + }, + "options": { + "title": { + "display": true, + "text": "Customers per group" + } + } + }'> + + + + + + $values) : $sum += $values['customers']; ?> + + +
Groups + Customer count +
+ + +
Total + +
+
+
+
+ +
+
+ getData('salesRegion'); ?> +
+ , + , + , + , + , + + ], + "backgroundColor": [ + "rgb(255, 99, 132)", + "rgb(255, 159, 64)", + "rgb(255, 205, 86)", + "rgb(75, 192, 192)", + "rgb(54, 162, 235)", + "rgb(153, 102, 255)" + ] + }] + }, + "options": { + "title": { + "display": true, + "text": "Sales per region" + } + } + }'> +
+
+
+ +
+
+ getData('salesCountry'); ?> +
+ + ], + "datasets": [ + { + "label": "getHtml('Sales'); ?>", + "type": "horizontalBar", + "data": [ + + + ], + "fill": false, + "borderColor": "rgb(54, 162, 235)", + "backgroundColor": "rgb(54, 162, 235)", + "tension": 0.0 + } + ] + }, + "options": { + "title": { + "display": true, + "text": "Sales per country" + } + } + }'> +
+
+
+ +
+
+ getData('salesGroups'); ?> +
+ + ], + "datasets": [{ + "data": [ + + + ], + "backgroundColor": [ + "rgb(255, 99, 132)", + "rgb(255, 159, 64)", + "rgb(255, 205, 86)", + "rgb(75, 192, 192)", + "rgb(54, 162, 235)", + "rgb(153, 102, 255)" + ] + }] + }, + "options": { + "title": { + "display": true, + "text": "Sales per group" + } + } + }'> +
+
+
+
+
+ + request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>> +
+
+
+
+
New customers
+
+ Shows new customers and their sales +
+
+
+ +
+
+
New customers per region
+
+
+
+
+ +
+
+
New customers per sales rep
+
+
+
+
+ +
+
+
New customers per sales group
+
+
+
+
+ +
+
+
New customers per customer group
+
+
+
+
+ +
+
+
New customers sales per customer group
+
+
+
+
+
+
+ + request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>> +
+
+
+
+
Lost customers
+
+ Shows lost customers and their sales +
+
+
+ +
+
+
Lost customers per region
+
+
+
+
+ +
+
+
Lost customers per sales rep
+
+
+
+
+ +
+
+
Lost customers per sales group
+
+
+
+
+ +
+
+
Lost customers per customer group
+
+
+
+
+ +
+
+
Lost customers sales per customer group
+
+
+
+
+
+
+ + request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>> +
+
+
+
+ getData('monthlySalesCosts'); ?> +
+ + + ], + "datasets": [ + { + "label": "getHtml('Margin'); ?>", + "type": "line", + "data": [ + + + ], + "yAxisID": "axis-2", + "fill": false, + "borderColor": "rgb(255, 99, 132)", + "backgroundColor": "rgb(255, 99, 132)", + "tension": 0.0 + }, + { + "label": "getHtml('Sales'); ?>", + "type": "bar", + "data": [ + + + ], + "yAxisID": "axis-1", + "backgroundColor": "rgb(54, 162, 235)" + } + ] + }, + "options": { + "title": { + "display": true, + "text": "Sales / Margin" + }, + "scales": { + "yAxes": [ + { + "id": "axis-1", + "display": true, + "position": "left" + }, + { + "id": "axis-2", + "display": true, + "position": "right", + "scaleLabel": { + "display": true, + "labelString": "getHtml('Margin'); ?> %" + }, + "gridLines": { + "display": false + }, + "beginAtZero": true, + "ticks": { + "min": 0, + "max": 100, + "stepSize": 10 + } + } + ] + } + } + }'> +
+
+
+ +
+
+
Margins per region
+
+
+
+
+ +
+
+
Margins per sales rep
+
+
+
+
+ +
+
+
Margins per sales group
+
+
+
+
+ +
+
+
Margins per customer group
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/Theme/Backend/client-list.tpl.php b/Theme/Backend/client-list.tpl.php index d4de24c..eae2b9e 100755 --- a/Theme/Backend/client-list.tpl.php +++ b/Theme/Backend/client-list.tpl.php @@ -23,7 +23,7 @@ echo $this->getData('nav')->render(); ?>
getHtml('Clients'); ?>
- +