diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php
index dd3c914..7003696 100755
--- a/Admin/Routes/Web/Backend.php
+++ b/Admin/Routes/Web/Backend.php
@@ -107,7 +107,7 @@ return [
],
'^.*/sales/analysis/bill(\?.*|$)$' => [
[
- 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewBillAnalysis',
+ 'dest' => '\Modules\Billing\Controller\BackendController:viewBillAnalysis',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
@@ -116,4 +116,26 @@ return [
],
],
],
+ '^.*/sales/analysis/rep(\?.*|$)$' => [
+ [
+ 'dest' => '\Modules\Billing\Controller\BackendController:viewSalesRepAnalysis',
+ 'verb' => RouteVerb::GET,
+ 'permission' => [
+ 'module' => BackendController::MODULE_NAME,
+ 'type' => PermissionType::READ,
+ 'state' => PermissionState::SALES_ANALYSIS,
+ ],
+ ],
+ ],
+ '^.*/sales/analysis/region(\?.*|$)$' => [
+ [
+ 'dest' => '\Modules\Billing\Controller\BackendController:viewRegionAnalysis',
+ 'verb' => RouteVerb::GET,
+ 'permission' => [
+ 'module' => BackendController::MODULE_NAME,
+ 'type' => PermissionType::READ,
+ 'state' => PermissionState::SALES_ANALYSIS,
+ ],
+ ],
+ ],
];
diff --git a/Controller/BackendController.php b/Controller/BackendController.php
index c44e400..f6d8976 100755
--- a/Controller/BackendController.php
+++ b/Controller/BackendController.php
@@ -22,6 +22,9 @@ use phpOMS\Contract\RenderableInterface;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Views\View;
+use phpOMS\Asset\AssetType;
+use phpOMS\Localization\ISO3166CharEnum;
+use phpOMS\Localization\ISO3166NameEnum;
/**
* Billing class.
@@ -242,4 +245,303 @@ 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 viewRegionAnalysis(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/Billing/Theme/Backend/region-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);
+
+ /////
+ $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->addData('currentCustomerRegion', $currentCustomerRegion);
+
+ 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->addData('annualCustomerRegion', $annualCustomerRegion);
+
+ /////
+ $monthlySalesCustomer = [];
+ for ($i = 1; $i < 13; ++$i) {
+ $monthlySalesCustomer[] = [
+ 'net_sales' => $sales = \mt_rand(1200000000, 2000000000),
+ 'customers' => \mt_rand(200, 400),
+ 'year' => 2020,
+ 'month' => $i,
+ ];
+ }
+
+ $view->addData('monthlySalesCustomer', $monthlySalesCustomer);
+
+ $annualSalesCustomer = [];
+ for ($i = 1; $i < 11; ++$i) {
+ $annualSalesCustomer[] = [
+ 'net_sales' => $sales = \mt_rand(1200000000, 2000000000) * 12,
+ 'customers' => \mt_rand(200, 400) * 6,
+ 'year' => 2020 - 10 + $i,
+ ];
+ }
+
+ $view->addData('annualSalesCustomer', $annualSalesCustomer);
+
+ /////
+ $monthlyCustomerRetention = [];
+ for ($i = 1; $i < 10; ++$i) {
+ $monthlyCustomerRetention[] = [
+ 'customers' => \mt_rand(200, 400),
+ 'year' => \date('y') - 9 + $i,
+ ];
+ }
+
+ $view->addData('monthlyCustomerRetention', $monthlyCustomerRetention);
+
+ /////
+ $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->addData('currentCustomerRegion', $currentCustomerRegion);
+
+ 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->addData('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->addData('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->addData('annualCustomersRep', $annualCustomersRep);
+
+ /////
+ $currentCustomersCountry = [];
+ for ($i = 1; $i < 51; ++$i) {
+ $country = ISO3166NameEnum::getRandom();
+ $currentCustomersCountry[\substr($country, 0, 20)] = [
+ 'customers' => (int) (\mt_rand(200, 400) / 12),
+ ];
+ }
+
+ \uasort($currentCustomersCountry, function($a, $b) { return $b['customers'] <=> $a['customers']; });
+
+ $view->addData('currentCustomersCountry', $currentCustomersCountry);
+
+ $annualCustomersCountry = [];
+ for ($i = 1; $i < 51; ++$i) {
+ $countryCode = ISO3166CharEnum::getRandom();
+ $countryName = ISO3166NameEnum::getByName('_' . $countryCode);
+ $annualCustomersCountry[\substr($countryName, 0, 20)] = [];
+
+ for ($j = 1; $j < 11; ++$j) {
+ $annualCustomersCountry[\substr($countryName, 0, 20)][] = [
+ 'customers' => (int) (\mt_rand(200, 400) / 12),
+ 'year' => 2020 - 10 + $j,
+ 'name' => $countryName,
+ 'code' => $countryCode,
+ ];
+ }
+ }
+
+ $view->addData('annualCustomersCountry', $annualCustomersCountry);
+
+ /////
+ $customerGroups = [];
+ for ($i = 1; $i < 7; ++$i) {
+ $customerGroups['Group ' . $i] = [
+ 'customers' => (int) (\mt_rand(200, 400) / 12),
+ ];
+ }
+
+ $view->addData('customerGroups', $customerGroups);
+
+ 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 viewBillAnalysis(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/Billing/Theme/Backend/bill-analysis');
+ $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1001602001, $request, $response));
+
+ 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 viewSalesRepAnalysis(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/Billing/Theme/Backend/rep-analysis');
+ $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1001602001, $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->addData('currentCustomerRegion', $currentCustomerRegion);
+
+ 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->addData('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->addData('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->addData('annualCustomersRep', $annualCustomersRep);
+
+ return $view;
+ }
}
diff --git a/Models/Bill.php b/Models/Bill.php
index 58b2412..6a5b6da 100755
--- a/Models/Bill.php
+++ b/Models/Bill.php
@@ -99,13 +99,9 @@ class Bill implements \JsonSerializable
*/
public Account $createdBy;
- public int |
+ public ?Client $client = null;
- Client $client = 0;
-
- public int |
-
- Supplier $supplier = 0;
+ public ?Supplier $supplier = null;
/**
* Receiver.
diff --git a/Models/PermissionState.php b/Models/PermissionState.php
index c55a9b4..7486bd5 100755
--- a/Models/PermissionState.php
+++ b/Models/PermissionState.php
@@ -29,4 +29,6 @@ abstract class PermissionState extends Enum
public const SALES_INVOICE = 1;
public const PURCHASE_INVOICE = 2;
+
+ public const SALES_ANALYSIS = 4;
}
diff --git a/Theme/Backend/Lang/ar.lang.php b/Theme/Backend/Lang/ar.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/cs.lang.php b/Theme/Backend/Lang/cs.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/da.lang.php b/Theme/Backend/Lang/da.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/el.lang.php b/Theme/Backend/Lang/el.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/es.lang.php b/Theme/Backend/Lang/es.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/fi.lang.php b/Theme/Backend/Lang/fi.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/fr.lang.php b/Theme/Backend/Lang/fr.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/hu.lang.php b/Theme/Backend/Lang/hu.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/it.lang.php b/Theme/Backend/Lang/it.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/ja.lang.php b/Theme/Backend/Lang/ja.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/ko.lang.php b/Theme/Backend/Lang/ko.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/no.lang.php b/Theme/Backend/Lang/no.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/pl.lang.php b/Theme/Backend/Lang/pl.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/pt.lang.php b/Theme/Backend/Lang/pt.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/ru.lang.php b/Theme/Backend/Lang/ru.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/sv.lang.php b/Theme/Backend/Lang/sv.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/th.lang.php b/Theme/Backend/Lang/th.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/tr.lang.php b/Theme/Backend/Lang/tr.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/uk.lang.php b/Theme/Backend/Lang/uk.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/Lang/zh.lang.php b/Theme/Backend/Lang/zh.lang.php
old mode 100644
new mode 100755
diff --git a/Theme/Backend/bill-analysis.tpl.php b/Theme/Backend/bill-analysis.tpl.php
new file mode 100644
index 0000000..8b25827
--- /dev/null
+++ b/Theme/Backend/bill-analysis.tpl.php
@@ -0,0 +1,25 @@
+getData('nav')->render();
+?>
\ No newline at end of file
diff --git a/Theme/Backend/region-analysis.tpl.php b/Theme/Backend/region-analysis.tpl.php
new file mode 100644
index 0000000..650591b
--- /dev/null
+++ b/Theme/Backend/region-analysis.tpl.php
@@ -0,0 +1,1757 @@
+getData('nav')->render();
+?>
+
+
+
+
+ = $this->getHtml('General'); ?>
+ = $this->getHtml('Region'); ?>
+ = $this->getHtml('Filter'); ?>
+
+
+
+
request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>>
+
+
+
request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>>
+
+
+
+
+
+ Sales per Region - Current
+
+
+ getData('currentCustomerRegion'); ?>
+
+
,
+ = (int) ($customerRegion['America'] ?? 0); ?>,
+ = (int) ($customerRegion['Asia'] ?? 0); ?>,
+ = (int) ($customerRegion['Africa'] ?? 0); ?>,
+ = (int) ($customerRegion['CIS'] ?? 0); ?>,
+ = (int) ($customerRegion['Other'] ?? 0); ?>
+ ],
+ "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": false,
+ "text": "Customers per Region - Currently"
+ }
+ }
+ }'>
+
+
+
+
+ Data
+
+
+
+
+
+
+ Region
+ Customer count
+
+ $values) : $sum += $values; ?>
+
+ = $region; ?>
+ = $values; ?>
+
+
+ Total
+ = $sum; ?>
+
+
+
+
+
+
+
+
+
+
+ Sales per Region - Annual
+
+
+ getData('annualCustomerRegion'); ?>
+
+
+ = '"' . \implode('", "', $temp) . '"'; ?>
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Total'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(139, 139, 139)",
+ "backgroundColor": "rgb(139, 139, 139)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Europe'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 99, 132)",
+ "backgroundColor": "rgb(255, 99, 132)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('America'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 159, 64)",
+ "backgroundColor": "rgb(255, 159, 64)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Asia'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 205, 86)",
+ "backgroundColor": "rgb(255, 205, 86)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Africa'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(75, 192, 192)",
+ "backgroundColor": "rgb(75, 192, 192)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('CIS'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Other'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(153, 102, 255)",
+ "backgroundColor": "rgb(153, 102, 255)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Sales per Region - Annual"
+ },
+ "scales": {
+ "yAxes": [
+ {
+ "id": "axis-1",
+ "display": true,
+ "position": "left"
+ }
+ ]
+ }
+ }
+ }'>
+
+
+
+
+ Data
+
+
+
+
+
+
+ Region
+ $values) : ?>
+ = $values; ?>
+
+
+
+
+ = $region; ?>
+ $annual) : ?>
+ = $annual[$region] ?? 0; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Profit per Region - Current
+
+
+ getData('currentCustomerRegion'); ?>
+
+
,
+ = (int) ($customerRegion['America'] ?? 0); ?>,
+ = (int) ($customerRegion['Asia'] ?? 0); ?>,
+ = (int) ($customerRegion['Africa'] ?? 0); ?>,
+ = (int) ($customerRegion['CIS'] ?? 0); ?>,
+ = (int) ($customerRegion['Other'] ?? 0); ?>
+ ],
+ "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": false,
+ "text": "Customers per Region - Currently"
+ }
+ }
+ }'>
+
+
+
+
+ Data
+
+
+
+
+
+
+ Region
+ Customer count
+
+ $values) : $sum += $values; ?>
+
+ = $region; ?>
+ = $values; ?>
+
+
+ Total
+ = $sum; ?>
+
+
+
+
+
+
+
+
+
+
+ Profit per Region - Annual
+
+
+ getData('annualCustomerRegion'); ?>
+
+
+ = '"' . \implode('", "', $temp) . '"'; ?>
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Total'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(139, 139, 139)",
+ "backgroundColor": "rgb(139, 139, 139)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Europe'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 99, 132)",
+ "backgroundColor": "rgb(255, 99, 132)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('America'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 159, 64)",
+ "backgroundColor": "rgb(255, 159, 64)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Asia'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 205, 86)",
+ "backgroundColor": "rgb(255, 205, 86)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Africa'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(75, 192, 192)",
+ "backgroundColor": "rgb(75, 192, 192)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('CIS'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Other'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(153, 102, 255)",
+ "backgroundColor": "rgb(153, 102, 255)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Sales per Region - Annual"
+ },
+ "scales": {
+ "yAxes": [
+ {
+ "id": "axis-1",
+ "display": true,
+ "position": "left"
+ }
+ ]
+ }
+ }
+ }'>
+
+
+
+
+ Data
+
+
+
+
+
+
+ Region
+ $values) : ?>
+ = $values; ?>
+
+
+
+
+ = $region; ?>
+ $annual) : ?>
+ = $annual[$region] ?? 0; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sales / Region
+
+
+
+
+
+ Country
+ Sales PY
+ Sales B
+ Sales A
+ Diff PY
+ Diff B
+
+
+
+
+
+
+
+
request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>>
+
+
+
+
+
+
+
+ Sales / Profit - Monthly
+
+
+ getData('monthlySalesCustomer'); ?>
+
+
+ = '"' . \implode('", "', $temp) . '"'; ?>
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Profit'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "yAxisID": "axis-2",
+ "fill": false,
+ "borderColor": "rgb(255, 99, 132)",
+ "backgroundColor": "rgb(255, 99, 132)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Sales'); ?>",
+ "type": "bar",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "yAxisID": "axis-1",
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Sales / Profit"
+ },
+ "scales": {
+ "yAxes": [
+ {
+ "id": "axis-1",
+ "display": true,
+ "position": "left"
+ },
+ {
+ "id": "axis-2",
+ "display": true,
+ "position": "right",
+ "scaleLabel": {
+ "display": true,
+ "labelString": "= $this->getHtml('Profit'); ?>"
+ },
+ "gridLines": {
+ "display": false
+ }
+ }
+ ]
+ }
+ }
+ }'>
+
+
+
+ Data
+
+
+
+
+
+
+ Month
+ Sales
+ Profit
+ Profit %
+
+
+
+ = $values['month'] . '/' . \substr((string) $values['year'], -2); ?>
+ = (new Money(((int) $values['net_sales']) / 1000))->getCurrency(); ?>
+ = ((int) $values['customers']); ?>
+ = ((int) $values['customers']); ?>
+
+
+ Total
+ = (new Money($sum1))->getCurrency(); ?>
+ = (int) ($sum2 / 12); ?>
+ = (int) ($sum2 / 12); ?>
+
+
+
+
+
+
+
+
+
+
+ Sales / Profit - Annual
+
+
+ getData('annualSalesCustomer'); ?>
+
+
+ = '"' . \implode('", "', $temp) . '"'; ?>
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Profit'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "yAxisID": "axis-2",
+ "fill": false,
+ "borderColor": "rgb(255, 99, 132)",
+ "backgroundColor": "rgb(255, 99, 132)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Sales'); ?>",
+ "type": "bar",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "yAxisID": "axis-1",
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Sales / Profit"
+ },
+ "scales": {
+ "yAxes": [
+ {
+ "id": "axis-1",
+ "display": true,
+ "position": "left"
+ },
+ {
+ "id": "axis-2",
+ "display": true,
+ "position": "right",
+ "scaleLabel": {
+ "display": true,
+ "labelString": "= $this->getHtml('Profit'); ?>"
+ },
+ "gridLines": {
+ "display": false
+ }
+ }
+ ]
+ }
+ }
+ }'>
+
+
+
+ Data
+
+
+
+
+
+
+ Year
+ Sales
+ Profit
+ Profit %
+
+
+
+ = (string) $values['year']; ?>
+ = (new Money(((int) $values['net_sales']) / 1000))->getCurrency(); ?>
+ = ((int) $values['customers']); ?>
+ = ((int) $values['customers']); ?>
+
+
+
+
+
+
+
+
+
+
+
+ Sales per Attribute - Current
+
+
+ getData('customerGroups'); ?>
+
+
+ = $this->getHtml('Attribute'); ?>
+
+ Attribute to Analyse
+
+
+
+
+
+ ],
+ "datasets": [{
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "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": false,
+ "text": "Customers per group"
+ }
+ }
+ }'>
+
+
+
+
+
+ Data
+
+
+
+
+
+
+ Groups
+ Customer count
+
+ $values) : $sum += $values['customers']; ?>
+
+ = $groups; ?>
+ = $values['customers']; ?>
+
+
+ Total
+ = $sum; ?>
+
+
+
+
+
+
+
+
+
+
+ Sales per Attribute - Annual
+
+
+ getData('annualCustomerRegion'); ?>
+
+
+ = $this->getHtml('Attribute'); ?>
+
+ Attribute to Analyse
+
+
+
+
+
+ = '"' . \implode('", "', $temp) . '"'; ?>
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Total'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(139, 139, 139)",
+ "backgroundColor": "rgb(139, 139, 139)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Europe'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 99, 132)",
+ "backgroundColor": "rgb(255, 99, 132)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('America'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 159, 64)",
+ "backgroundColor": "rgb(255, 159, 64)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Asia'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 205, 86)",
+ "backgroundColor": "rgb(255, 205, 86)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Africa'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(75, 192, 192)",
+ "backgroundColor": "rgb(75, 192, 192)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('CIS'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Other'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(153, 102, 255)",
+ "backgroundColor": "rgb(153, 102, 255)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Customers per Region - Annual"
+ },
+ "scales": {
+ "yAxes": [
+ {
+ "id": "axis-1",
+ "display": true,
+ "position": "left"
+ }
+ ]
+ }
+ }
+ }'>
+
+
+
+
+
+ Data
+
+
+
+
+
+
+ Region
+ $values) : ?>
+ = $values; ?>
+
+
+
+
+ = $region; ?>
+ $annual) : ?>
+ = $annual[$region] ?? 0; ?>
+
+
+
+
+
+
+
+
+
+
+
+ Profit per Attribute - Current
+
+
+ getData('customerGroups'); ?>
+
+
+ = $this->getHtml('Attribute'); ?>
+
+ Attribute to Analyse
+
+
+
+
+
+ ],
+ "datasets": [{
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "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": false,
+ "text": "Customers per group"
+ }
+ }
+ }'>
+
+
+
+
+
+ Data
+
+
+
+
+
+
+ Groups
+ Customer count
+
+ $values) : $sum += $values['customers']; ?>
+
+ = $groups; ?>
+ = $values['customers']; ?>
+
+
+ Total
+ = $sum; ?>
+
+
+
+
+
+
+
+
+
+
+ Profit per Attribute - Annual
+
+
+ getData('annualCustomerRegion'); ?>
+
+
+ = $this->getHtml('Attribute'); ?>
+
+ Attribute to Analyse
+
+
+
+
+
+ = '"' . \implode('", "', $temp) . '"'; ?>
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Total'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(139, 139, 139)",
+ "backgroundColor": "rgb(139, 139, 139)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Europe'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 99, 132)",
+ "backgroundColor": "rgb(255, 99, 132)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('America'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 159, 64)",
+ "backgroundColor": "rgb(255, 159, 64)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Asia'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(255, 205, 86)",
+ "backgroundColor": "rgb(255, 205, 86)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Africa'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(75, 192, 192)",
+ "backgroundColor": "rgb(75, 192, 192)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('CIS'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Other'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(153, 102, 255)",
+ "backgroundColor": "rgb(153, 102, 255)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Customers per Region - Annual"
+ },
+ "scales": {
+ "yAxes": [
+ {
+ "id": "axis-1",
+ "display": true,
+ "position": "left"
+ }
+ ]
+ }
+ }
+ }'>
+
+
+
+
+
+ Data
+
+
+
+
+
+
+ Region
+ $values) : ?>
+ = $values; ?>
+
+
+
+
+ = $region; ?>
+ $annual) : ?>
+ = $annual[$region] ?? 0; ?>
+
+
+
+
+
+
+
+
+
+
+
+ Invoices / Articles - Monthly
+
+
+ getData('monthlySalesCustomer'); ?>
+
+
+ = '"' . \implode('", "', $temp) . '"'; ?>
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Articles'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "yAxisID": "axis-2",
+ "fill": false,
+ "borderColor": "rgb(255, 99, 132)",
+ "backgroundColor": "rgb(255, 99, 132)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Sales'); ?>",
+ "type": "bar",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "yAxisID": "axis-1",
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Sales / Articles"
+ },
+ "scales": {
+ "yAxes": [
+ {
+ "id": "axis-1",
+ "display": true,
+ "position": "left"
+ },
+ {
+ "id": "axis-2",
+ "display": true,
+ "position": "right",
+ "scaleLabel": {
+ "display": true,
+ "labelString": "= $this->getHtml('Articles'); ?>"
+ },
+ "gridLines": {
+ "display": false
+ }
+ }
+ ]
+ }
+ }
+ }'>
+
+
+
+ Data
+
+
+
+
+
+
+ Month
+ Sales
+ Articles
+
+
+
+ = $values['month'] . '/' . \substr((string) $values['year'], -2); ?>
+ = (new Money(((int) $values['net_sales']) / 1000))->getCurrency(); ?>
+ = ((int) $values['customers']); ?>
+ = ((int) $values['customers']); ?>
+
+
+ Total
+ = (new Money($sum1))->getCurrency(); ?>
+ = (int) ($sum2 / 12); ?>
+ = (int) ($sum2 / 12); ?>
+
+
+
+
+
+
+
+
+
+
+ Invoices / Articles - Annual
+
+
+ getData('annualSalesCustomer'); ?>
+
+
+ = '"' . \implode('", "', $temp) . '"'; ?>
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Articles'); ?>",
+ "type": "line",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "yAxisID": "axis-2",
+ "fill": false,
+ "borderColor": "rgb(255, 99, 132)",
+ "backgroundColor": "rgb(255, 99, 132)",
+ "tension": 0.0
+ },
+ {
+ "label": "= $this->getHtml('Sales'); ?>",
+ "type": "bar",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "yAxisID": "axis-1",
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Sales / Articles"
+ },
+ "scales": {
+ "yAxes": [
+ {
+ "id": "axis-1",
+ "display": true,
+ "position": "left"
+ },
+ {
+ "id": "axis-2",
+ "display": true,
+ "position": "right",
+ "scaleLabel": {
+ "display": true,
+ "labelString": "= $this->getHtml('Articles'); ?>"
+ },
+ "gridLines": {
+ "display": false
+ }
+ }
+ ]
+ }
+ }
+ }'>
+
+
+
+ Data
+
+
+
+
+
+
+ Year
+ Sales
+ Articles
+
+
+
+ = (string) $values['year']; ?>
+ = (new Money(((int) $values['net_sales']) / 1000))->getCurrency(); ?>
+ = ((int) $values['customers']); ?>
+ = ((int) $values['customers']); ?>
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Theme/Backend/rep-analysis.tpl.php b/Theme/Backend/rep-analysis.tpl.php
new file mode 100644
index 0000000..0da7db1
--- /dev/null
+++ b/Theme/Backend/rep-analysis.tpl.php
@@ -0,0 +1,347 @@
+getData('nav')->render();
+?>
+
+
+
+
+ = $this->getHtml('General'); ?>
+ = $this->getHtml('Filter'); ?>
+
+
+
+
request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>>
+
+
+
request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>>
+
+
+
+
+
+ Sales per Rep - Current
+
+
+ getData('currentCustomersRep'); ?>
+
+
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Customers'); ?>",
+ "type": "horizontalBar",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Customers per rep"
+ }
+ }
+ }'>
+
+
+
+
+ Data
+
+
+
+
+
+
+ Rep
+ Customer count
+
+ $values) : $sum += $values['customers']; ?>
+
+ = $rep; ?>
+ = $values['customers']; ?>
+
+
+ Total
+ = $sum; ?>
+
+
+
+
+
+
+
+
+
+
+ Sales per Rep - Annual
+
+
+ getData('annualCustomersRep'); ?>
+
+
+
+ Rep
+
+ = $year; ?>
+
+
+ $annual) : ?>
+
+ = $rep; ?>
+ $values) :
+ $sum[$values['year']] = ($sum[$values['year']] ?? 0) + $values['customers']; ?>
+ = $values['customers']; ?>
+
+
+
+ Total
+
+ = $sum[$year]; ?>
+
+
+
+
+
+
+
+
+
+
+ Profit per Rep - Current
+
+
+ getData('currentCustomersRep'); ?>
+
+
+ ],
+ "datasets": [
+ {
+ "label": "= $this->getHtml('Customers'); ?>",
+ "type": "horizontalBar",
+ "data": [
+
+ = \implode(',', $temp); ?>
+ ],
+ "fill": false,
+ "borderColor": "rgb(54, 162, 235)",
+ "backgroundColor": "rgb(54, 162, 235)",
+ "tension": 0.0
+ }
+ ]
+ },
+ "options": {
+ "title": {
+ "display": false,
+ "text": "Customers per rep"
+ }
+ }
+ }'>
+
+
+
+
+ Data
+
+
+
+
+
+
+ Rep
+ Customer count
+
+ $values) : $sum += $values['customers']; ?>
+
+ = $rep; ?>
+ = $values['customers']; ?>
+
+
+ Total
+ = $sum; ?>
+
+
+
+
+
+
+
+
+
+
+ Profit per Rep - Annual
+
+
+ getData('annualCustomersRep'); ?>
+
+
+
+ Rep
+
+ = $year; ?>
+
+
+ $annual) : ?>
+
+ = $rep; ?>
+ $values) :
+ $sum[$values['year']] = ($sum[$values['year']] ?? 0) + $values['customers']; ?>
+ = $values['customers']; ?>
+
+
+
+ Total
+
+ = $sum[$year]; ?>
+
+
+
+
+
+
+
+
+
+
+ Sales / Rep
+
+
+
+
+
+ Rep
+ Sales PY
+ Sales B
+ Sales A
+ Diff PY
+ Diff B
+
+
+
+
+
+
+
+
\ No newline at end of file