From abd42067f0aa0378a31814560072364b2f6643c2 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 6 Feb 2021 13:48:48 +0100 Subject: [PATCH] continue item/billing impl. --- Controller.js | 47 ++++++ Controller/BackendController.php | 41 +++++ Theme/Backend/sales-item-profile.tpl.php | 203 ++++++++++++++++++++--- 3 files changed, 271 insertions(+), 20 deletions(-) create mode 100644 Controller.js diff --git a/Controller.js b/Controller.js new file mode 100644 index 0000000..c04d145 --- /dev/null +++ b/Controller.js @@ -0,0 +1,47 @@ +import { Autoloader } from '../../jsOMS/Autoloader.js'; + +Autoloader.defineNamespace('jsOMS.Modules'); + +jsOMS.Modules.ItemManagement = class { + /** + * @constructor + * + * @since 1.0.0 + */ + constructor (app) + { + this.app = app; + }; + + bind (id) + { + const e = typeof id === 'undefined' ? document.getElementsByTagName('canvas') : [document.getElementById(id)], + length = e.length; + + for (let i = 0; i < length; ++i) { + if (e[i].getAttribute('data-chart') === null + && e[i].getAttribute('data-chart') !== 'undefined' + ) { + continue; + } + + this.bindElement(e[i]); + } + }; + + bindElement (chart) + { + if (typeof chart === 'undefined' || !chart) { + jsOMS.Log.Logger.instance.error('Invalid chart: ' + chart, 'ItemManagementController'); + + return; + } + + const self = this; + const data = JSON.parse(chart.getAttribute('data-chart')); + + const myChart = new Chart(chart.getContext('2d'), data); + }; +}; + +window.omsApp.moduleManager.get('ItemManagement').bind(); diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 2fa468c..cb0d537 100644 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -16,11 +16,15 @@ namespace Modules\ItemManagement\Controller; use Model\SettingsEnum; use Modules\Admin\Models\LocalizationMapper; +use Modules\Billing\Models\BillMapper; use Modules\ItemManagement\Models\ItemMapper; use phpOMS\Contract\RenderableInterface; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Views\View; +use phpOMS\Stdlib\Base\SmartDateTime; +use phpOMS\Localization\Money; +use phpOMS\Asset\AssetType; /** * ItemManagement controller class. @@ -178,6 +182,11 @@ final class BackendController extends Controller */ public function viewItemManagementSalesItem(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/ItemManagement/Controller.js', ['type' => 'module']); + $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/sales-item-profile'); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004805001, $request, $response)); @@ -191,6 +200,38 @@ final class BackendController extends Controller $view->setData('defaultlocalization', LocalizationMapper::get((int) $settings['id'])); + if ($this->app->moduleManager->isActive('Billing')) { + $ytd = BillMapper::getSalesByItemId($item->getId(), new SmartDateTime('Y-01-01'), new SmartDateTime('now')); + $mtd = BillMapper::getSalesByItemId($item->getId(), new SmartDateTime('Y-m-01'), new SmartDateTime('now')); + $avg = BillMapper::getAvgSalesPriceByItemId($item->getId(), (new SmartDateTime('now'))->smartModify(-1), new SmartDateTime('now')); + $lastOrder = BillMapper::getLastOrderDateByItemId($item->getId()); + $newestInvoices = BillMapper::getNewestItemInvoices($item->getId(), 5); + $topCustomers = BillMapper::getItemTopCustomers($item->getId(), new SmartDateTime('Y-01-01'), new SmartDateTime('now'), 5); + $regionSales = BillMapper::getItemRegionSales($item->getId(), new SmartDateTime('Y-01-01'), new SmartDateTime('now')); + $countrySales = BillMapper::getItemCountrySales($item->getId(), new SmartDateTime('Y-01-01'), new SmartDateTime('now'), 5); + $monthlySalesCosts = BillMapper::getItemMonthlySalesCosts($item->getId(), (new SmartDateTime('now'))->createModify(-1), new SmartDateTime('now')); + } else { + $ytd = new Money(); + $mtd = new Money(); + $avg = new Money(); + $lastOrder = null; + $newestInvoices = []; + $topCustomers = []; + $regionSales = []; + $countrySales = []; + $monthlySalesCosts = []; + } + + $view->addData('ytd', $ytd); + $view->addData('mtd', $mtd); + $view->addData('avg', $avg); + $view->addData('lastOrder', $lastOrder); + $view->addData('newestInvoices', $newestInvoices); + $view->addData('topCustomers', $topCustomers); + $view->addData('regionSales', $regionSales); + $view->addData('countrySales', $countrySales); + $view->addData('monthlySalesCosts', $monthlySalesCosts); + return $view; } } diff --git a/Theme/Backend/sales-item-profile.tpl.php b/Theme/Backend/sales-item-profile.tpl.php index d44b602..689f5d9 100644 --- a/Theme/Backend/sales-item-profile.tpl.php +++ b/Theme/Backend/sales-item-profile.tpl.php @@ -15,11 +15,17 @@ declare(strict_types=1); use Modules\Media\Models\NullMedia; use phpOMS\Localization\NullLocalization; use phpOMS\Uri\UriFactory; +use phpOMS\Localization\Money; /** * @var \Modules\ItemManagement\Models\Item $item */ $item = $this->getData('item'); +$newestInvoices = $this->getData('newestInvoices') ?? []; +$topCustomers = $this->getData('topCustomers') ?? []; +$regionSales = $this->getData('regionSales') ?? []; +$countrySales = $this->getData('countrySales') ?? []; +$monthlySalesCosts = $this->getData('monthlySalesCosts') ?? []; $languages = \phpOMS\Localization\ISO639Enum::getConstants(); @@ -94,9 +100,9 @@ echo $this->getData('nav')->render();
YTD Sales: - + getData('ytd')->getCurrency(); ?>
MTD Sales: - + getData('mtd')->getCurrency(); ?>
ILV:
MRR: @@ -111,11 +117,11 @@ echo $this->getData('nav')->render();
Last Order: - + getData('lastOrder') !== null ? $this->getData('lastOrder')->format('Y-m-d H:i') : ''; ?>
Price Change:
Created: - + createdAt->format('Y-m-d H:i'); ?>
Modified:
@@ -128,13 +134,13 @@ echo $this->getData('nav')->render();
Sales Price: - + salesPrice->getCurrency(); ?>
Purchase Price: - + purchasePrice->getCurrency(); ?>
Margin: - + salesPrice->getInt() - $item->purchasePrice->getInt()) / $item->salesPrice->getInt() * 100, 2); ?> %
Avg. Price: - + getData('avg')->getCurrency(); ?>
@@ -160,40 +166,197 @@ echo $this->getData('nav')->render();
-
Invoices
-
+
Recent Invoices
+ + + + + + +
Number + Name + Net + Date +
getNumber(); ?> + billTo; ?> + net->getCurrency(); ?> + createdAt->format('Y-m-d'); ?> + +
-
+ -
+
Sales
-
+
+ + + ], + "datasets": [ + { + "label": "Margin", + "type": "line", + "data": [ + + + ], + "yAxisID": "axis-2", + "fill": false, + "borderColor": "rgb(255, 99, 132)", + "backgroundColor": "rgb(255, 99, 132)" + }, + { + "label": "Sales", + "type": "bar", + "data": [ + + + ], + "yAxisID": "axis-1", + "backgroundColor": "rgb(54, 162, 235)" + } + ] + }, + "options": { + "scales": { + "yAxes": [ + { + "id": "axis-1", + "display": true, + "position": "left" + }, + { + "id": "axis-2", + "display": true, + "position": "right", + "scaleLabel": { + "display": true, + "labelString": "Margin %" + }, + "beginAtZero": true, + "ticks": { + "min": 0, + "max": 100, + "stepSize": 10 + } + } + ] + } + } + }'> +
-
+
Regions
-
+
+ , + , + , + , + , + + ], + "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)" + ] + }] + } + }'> +
-
+
-
Margins
-
+
Countries
+
+ + ], + "datasets": [{ + "label": "YTD", + "type": "bar", + "data": [ + + + ], + "backgroundColor": "rgb(54, 162, 235)" + }] + } + }'> +