Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
BackendController
n/a
0 / 0
n/a
0 / 0
41
n/a
0 / 0
 viewBillingSalesList
n/a
0 / 0
n/a
0 / 0
3
 viewBillingSalesInvoice
n/a
0 / 0
n/a
0 / 0
1
 viewBillingSalesInvoiceCreate
n/a
0 / 0
n/a
0 / 0
1
 viewBillingPurchaseInvoiceCreate
n/a
0 / 0
n/a
0 / 0
1
 viewBillingStockInvoiceCreate
n/a
0 / 0
n/a
0 / 0
1
 viewBillingPurchaseList
n/a
0 / 0
n/a
0 / 0
3
 viewBillingPurchaseInvoice
n/a
0 / 0
n/a
0 / 0
1
 viewBillingStockList
n/a
0 / 0
n/a
0 / 0
3
 viewBillingStockInvoice
n/a
0 / 0
n/a
0 / 0
1
 viewRegionAnalysis
n/a
0 / 0
n/a
0 / 0
14
 viewBillAnalysis
n/a
0 / 0
n/a
0 / 0
1
 viewSalesRepAnalysis
n/a
0 / 0
n/a
0 / 0
5
 viewBillingPurchaseInvoiceUpload
n/a
0 / 0
n/a
0 / 0
1
 viewPrivatePurchaseBillUpload
n/a
0 / 0
n/a
0 / 0
1
 viewPrivatePurchaseBillDashboard
n/a
0 / 0
n/a
0 / 0
3
 viewPrivateBillingPurchaseInvoice
n/a
0 / 0
n/a
0 / 0
1
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   Modules\Billing
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace Modules\Billing\Controller;
16
17use Modules\Auditor\Models\AuditMapper;
18use Modules\Billing\Models\BillElementMapper;
19use Modules\Billing\Models\BillMapper;
20use Modules\Billing\Models\BillStatus;
21use Modules\Billing\Models\BillTransferType;
22use Modules\Billing\Models\BillTypeMapper;
23use Modules\Billing\Models\PurchaseBillMapper;
24use Modules\Billing\Models\SalesBillMapper;
25use Modules\Billing\Models\SettingsEnum;
26use Modules\Billing\Models\StockBillMapper;
27use phpOMS\Asset\AssetType;
28use phpOMS\Contract\RenderableInterface;
29use phpOMS\DataStorage\Database\Query\OrderType;
30use phpOMS\Localization\ISO3166CharEnum;
31use phpOMS\Localization\ISO3166NameEnum;
32use phpOMS\Message\RequestAbstract;
33use phpOMS\Message\ResponseAbstract;
34use phpOMS\Utils\StringUtils;
35use phpOMS\Views\View;
36
37/**
38 * Billing class.
39 *
40 * @package Modules\Billing
41 * @license OMS License 2.0
42 * @link    https://jingga.app
43 * @since   1.0.0
44 * @codeCoverageIgnore
45 */
46final class BackendController extends Controller
47{
48    /**
49     * Routing end-point for application behaviour.
50     *
51     * @param RequestAbstract  $request  Request
52     * @param ResponseAbstract $response Response
53     * @param array            $data     Generic data
54     *
55     * @return RenderableInterface
56     *
57     * @since 1.0.0
58     * @codeCoverageIgnore
59     */
60    public function viewBillingSalesList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
61    {
62        $view = new View($this->app->l11nManager, $request, $response);
63        $view->setTemplate('/Modules/Billing/Theme/Backend/sales-bill-list');
64        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response);
65
66        $mapperQuery = SalesBillMapper::getAll()
67            ->with('type')
68            ->with('type/l11n')
69            ->with('client')
70            ->where('type/transferType', BillTransferType::SALES)
71            ->where('type/l11n/language', $response->header->l11n->language)
72            ->sort('id', OrderType::DESC)
73            ->limit(25);
74
75        if ($request->getData('ptype') === 'p') {
76            $view->data['bills'] = $mapperQuery
77                    ->where('id', $request->getDataInt('id') ?? 0, '<')
78                    ->where('client', null, '!=')
79                    ->execute();
80        } elseif ($request->getData('ptype') === 'n') {
81            $view->data['bills'] = $mapperQuery->where('id', $request->getDataInt('id') ?? 0, '>')
82                    ->where('client', null, '!=')
83                    ->execute();
84        } else {
85            $view->data['bills'] = $mapperQuery->where('id', 0, '>')
86                    ->where('client', null, '!=')
87                    ->execute();
88        }
89
90        return $view;
91    }
92
93    /**
94     * Routing end-point for application behaviour.
95     *
96     * @param RequestAbstract  $request  Request
97     * @param ResponseAbstract $response Response
98     * @param array            $data     Generic data
99     *
100     * @return RenderableInterface
101     *
102     * @since 1.0.0
103     * @codeCoverageIgnore
104     */
105    public function viewBillingSalesInvoice(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
106    {
107        $view = new View($this->app->l11nManager, $request, $response);
108        $view->setTemplate('/Modules/Billing/Theme/Backend/bill-create');
109        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response);
110
111        /** @var \Modules\Billing\Models\Bill $bill */
112        $bill = SalesBillMapper::get()
113            ->with('client')
114            ->with('elements')
115            ->with('files')
116            ->with('files/types')
117            ->with('notes')
118            ->where('id', (int) $request->getData('id'))
119            ->execute();
120
121        $view->data['bill'] = $bill;
122
123        /** @var \Modules\Auditor\Models\Audit[] $logsBill */
124        $logsBill = AuditMapper::getAll()
125            ->with('createdBy')
126            ->where('module', 'Billing')
127            ->where('type', StringUtils::intHash(BillMapper::class))
128            ->where('ref', $bill->id)
129            ->execute();
130
131        /** @var \Modules\Auditor\Models\Audit[] $logsElements */
132        $logsElements = AuditMapper::getAll()
133            ->with('createdBy')
134            ->where('module', 'Billing')
135            ->where('type', StringUtils::intHash(BillElementMapper::class))
136            ->where('ref', \array_keys($bill->getElements()), 'IN')
137            ->execute();
138
139        $logs = \array_merge($logsBill, $logsElements);
140
141        $view->data['logs'] = $logs;
142
143        return $view;
144    }
145
146    /**
147     * Routing end-point for application behaviour.
148     *
149     * @param RequestAbstract  $request  Request
150     * @param ResponseAbstract $response Response
151     * @param array            $data     Generic data
152     *
153     * @return RenderableInterface
154     *
155     * @since 1.0.0
156     * @codeCoverageIgnore
157     */
158    public function viewBillingSalesInvoiceCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
159    {
160        $view = new View($this->app->l11nManager, $request, $response);
161        $view->setTemplate('/Modules/Billing/Theme/Backend/bill-create');
162        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response);
163
164        $billTypes = BillTypeMapper::getAll()
165            ->with('l11n')
166            ->where('isTemplate', false)
167            ->where('transferType', BillTransferType::SALES)
168            ->where('l11n/language', $request->header->l11n->language)
169            ->execute();
170
171        $view->data['billtypes'] = $billTypes;
172
173        $mediaListView = new \Modules\Media\Theme\Backend\Components\Media\ListView($this->app->l11nManager, $request, $response);
174        $mediaListView->setTemplate('/Modules/Media/Theme/Backend/Components/Media/list');
175        $view->data['medialist'] = $mediaListView;
176
177        return $view;
178    }
179
180    /**
181     * Routing end-point for application behaviour.
182     *
183     * @param RequestAbstract  $request  Request
184     * @param ResponseAbstract $response Response
185     * @param array            $data     Generic data
186     *
187     * @return RenderableInterface
188     *
189     * @since 1.0.0
190     * @codeCoverageIgnore
191     */
192    public function viewBillingPurchaseInvoiceCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
193    {
194        $view = new View($this->app->l11nManager, $request, $response);
195        $view->setTemplate('/Modules/Billing/Theme/Backend/bill-create');
196        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response);
197
198        return $view;
199    }
200
201    /**
202     * Routing end-point for application behaviour.
203     *
204     * @param RequestAbstract  $request  Request
205     * @param ResponseAbstract $response Response
206     * @param array            $data     Generic data
207     *
208     * @return RenderableInterface
209     *
210     * @since 1.0.0
211     * @codeCoverageIgnore
212     */
213    public function viewBillingStockInvoiceCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
214    {
215        $view = new View($this->app->l11nManager, $request, $response);
216        $view->setTemplate('/Modules/Billing/Theme/Backend/bill-create');
217        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response);
218
219        return $view;
220    }
221
222    /**
223     * Routing end-point for application behaviour.
224     *
225     * @param RequestAbstract  $request  Request
226     * @param ResponseAbstract $response Response
227     * @param array            $data     Generic data
228     *
229     * @return RenderableInterface
230     *
231     * @since 1.0.0
232     * @codeCoverageIgnore
233     */
234    public function viewBillingPurchaseList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
235    {
236        $view = new View($this->app->l11nManager, $request, $response);
237        $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill-list');
238        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005105001, $request, $response);
239
240        $mapperQuery = PurchaseBillMapper::getAll()
241            ->with('type')
242            ->with('type/l11n')
243            ->with('supplier')
244            ->where('type/transferType', BillTransferType::PURCHASE)
245            ->sort('id', OrderType::DESC)
246            ->limit(25);
247
248        if ($request->getData('ptype') === 'p') {
249            $view->data['bills'] = $mapperQuery
250                    ->where('id', $request->getDataInt('id') ?? 0, '<')
251                    ->where('supplier', null, '!=')
252                    ->where('type/l11n/language', $response->header->l11n->language)
253                    ->execute();
254        } elseif ($request->getData('ptype') === 'n') {
255            $view->data['bills'] = $mapperQuery->where('id', $request->getDataInt('id') ?? 0, '>')
256                    ->where('supplier', null, '!=')
257                    ->where('type/l11n/language', $response->header->l11n->language)
258                    ->execute();
259        } else {
260            $view->data['bills'] = $mapperQuery->where('id', 0, '>')
261                    ->where('supplier', null, '!=')
262                    ->where('type/l11n/language', $response->header->l11n->language)
263                    ->execute();
264        }
265
266        return $view;
267    }
268
269    /**
270     * Routing end-point for application behaviour.
271     *
272     * @param RequestAbstract  $request  Request
273     * @param ResponseAbstract $response Response
274     * @param array            $data     Generic data
275     *
276     * @return RenderableInterface
277     *
278     * @since 1.0.0
279     * @codeCoverageIgnore
280     */
281    public function viewBillingPurchaseInvoice(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
282    {
283        $view = new View($this->app->l11nManager, $request, $response);
284        $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill');
285        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005105001, $request, $response);
286
287        $bill = PurchaseBillMapper::get()
288            ->with('elements')
289            ->with('files')
290            ->with('files/types')
291            ->with('notes')
292            ->where('id', (int) $request->getData('id'))
293            ->execute();
294
295        $view->data['bill'] = $bill;
296
297        /** @var \Model\Setting $previewType */
298        $previewType = $this->app->appSettings->get(
299            names: SettingsEnum::PREVIEW_MEDIA_TYPE,
300            module: self::NAME
301        );
302
303        $view->data['previewType'] = (int) $previewType->content;
304
305        /** @var \Model\Setting $originalType */
306        $originalType = $this->app->appSettings->get(
307            names: SettingsEnum::ORIGINAL_MEDIA_TYPE,
308            module: self::NAME
309        );
310
311        $view->data['originalType'] = (int) $originalType->content;
312
313        return $view;
314    }
315
316    /**
317     * Routing end-point for application behaviour.
318     *
319     * @param RequestAbstract  $request  Request
320     * @param ResponseAbstract $response Response
321     * @param array            $data     Generic data
322     *
323     * @return RenderableInterface
324     *
325     * @since 1.0.0
326     * @codeCoverageIgnore
327     */
328    public function viewBillingStockList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
329    {
330        $view = new View($this->app->l11nManager, $request, $response);
331        $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill-list');
332        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005106001, $request, $response);
333
334        if ($request->getData('ptype') === 'p') {
335            $view->data['bills'] = StockBillMapper::getAll()->where('id', $request->getDataInt('id') ?? 0, '<')->limit(25)->execute();
336        } elseif ($request->getData('ptype') === 'n') {
337            $view->data['bills'] = StockBillMapper::getAll()->where('id', $request->getDataInt('id') ?? 0, '>')->limit(25)->execute();
338        } else {
339            $view->data['bills'] = StockBillMapper::getAll()->where('id', 0, '>')->limit(25)->execute();
340        }
341
342        return $view;
343    }
344
345    /**
346     * Routing end-point for application behaviour.
347     *
348     * @param RequestAbstract  $request  Request
349     * @param ResponseAbstract $response Response
350     * @param array            $data     Generic data
351     *
352     * @return RenderableInterface
353     *
354     * @since 1.0.0
355     * @codeCoverageIgnore
356     */
357    public function viewBillingStockInvoice(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
358    {
359        $view = new View($this->app->l11nManager, $request, $response);
360        $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill');
361        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005106001, $request, $response);
362
363        $bill = StockBillMapper::get()->where('id', (int) $request->getData('id'))->execute();
364
365        $view->data['bill'] = $bill;
366
367        return $view;
368    }
369
370    /**
371     * Routing end-point for application behaviour.
372     *
373     * @param RequestAbstract  $request  Request
374     * @param ResponseAbstract $response Response
375     * @param array            $data     Generic data
376     *
377     * @return RenderableInterface
378     *
379     * @since 1.0.0
380     * @codeCoverageIgnore
381     */
382    public function viewRegionAnalysis(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
383    {
384        $head  = $response->data['Content']->head;
385        $nonce = $this->app->appSettings->getOption('script-nonce');
386
387        $head->addAsset(AssetType::CSS, 'Resources/chartjs/Chartjs/chart.css');
388        $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/Chartjs/chart.js', ['nonce' => $nonce]);
389        $head->addAsset(AssetType::JSLATE, 'Modules/ClientManagement/Controller.js', ['nonce' => $nonce, 'type' => 'module']);
390
391        $view = new View($this->app->l11nManager, $request, $response);
392        $view->setTemplate('/Modules/Billing/Theme/Backend/region-analysis');
393        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1001602001, $request, $response);
394
395        $monthlySalesCosts = [];
396        for ($i = 1; $i < 13; ++$i) {
397            $monthlySalesCosts[] = [
398                'net_sales' => $sales = \mt_rand(1200000000, 2000000000),
399                'net_costs' => (int) ($sales * \mt_rand(25, 55) / 100),
400                'year'      => 2020,
401                'month'     => $i,
402            ];
403        }
404
405        $view->data['monthlySalesCosts'] = $monthlySalesCosts;
406
407        /////
408        $currentCustomerRegion = [
409            'Europe'  => (int) (\mt_rand(200, 400) / 4),
410            'America' => (int) (\mt_rand(200, 400) / 4),
411            'Asia'    => (int) (\mt_rand(200, 400) / 4),
412            'Africa'  => (int) (\mt_rand(200, 400) / 4),
413            'CIS'     => (int) (\mt_rand(200, 400) / 4),
414            'Other'   => (int) (\mt_rand(200, 400) / 4),
415        ];
416
417        $view->data['currentCustomerRegion'] = $currentCustomerRegion;
418
419        $annualCustomerRegion = [];
420        for ($i = 1; $i < 11; ++$i) {
421            $annualCustomerRegion[] = [
422                'year'    => 2020 - 10 + $i,
423                'Europe'  => $a = (int) (\mt_rand(200, 400) / 4),
424                'America' => $b = (int) (\mt_rand(200, 400) / 4),
425                'Asia'    => $c = (int) (\mt_rand(200, 400) / 4),
426                'Africa'  => $d = (int) (\mt_rand(200, 400) / 4),
427                'CIS'     => $e = (int) (\mt_rand(200, 400) / 4),
428                'Other'   => $f = (int) (\mt_rand(200, 400) / 4),
429                'Total'   => $a + $b + $c + $d + $e + $f,
430            ];
431        }
432
433        $view->data['annualCustomerRegion'] = $annualCustomerRegion;
434
435        /////
436        $monthlySalesCustomer = [];
437        for ($i = 1; $i < 13; ++$i) {
438            $monthlySalesCustomer[] = [
439                'net_sales' => $sales = \mt_rand(1200000000, 2000000000),
440                'customers' => \mt_rand(200, 400),
441                'year'      => 2020,
442                'month'     => $i,
443            ];
444        }
445
446        $view->data['monthlySalesCustomer'] = $monthlySalesCustomer;
447
448        $annualSalesCustomer = [];
449        for ($i = 1; $i < 11; ++$i) {
450            $annualSalesCustomer[] = [
451                'net_sales' => $sales = \mt_rand(1200000000, 2000000000) * 12,
452                'customers' => \mt_rand(200, 400) * 6,
453                'year'      => 2020 - 10 + $i,
454            ];
455        }
456
457        $view->data['annualSalesCustomer'] = $annualSalesCustomer;
458
459        /////
460        $monthlyCustomerRetention = [];
461        for ($i = 1; $i < 10; ++$i) {
462            $monthlyCustomerRetention[] = [
463                'customers' => \mt_rand(200, 400),
464                'year'      => \date('y') - 9 + $i,
465            ];
466        }
467
468        $view->data['monthlyCustomerRetention'] = $monthlyCustomerRetention;
469
470        /////
471        $currentCustomerRegion = [
472            'Europe'  => (int) (\mt_rand(200, 400) / 4),
473            'America' => (int) (\mt_rand(200, 400) / 4),
474            'Asia'    => (int) (\mt_rand(200, 400) / 4),
475            'Africa'  => (int) (\mt_rand(200, 400) / 4),
476            'CIS'     => (int) (\mt_rand(200, 400) / 4),
477            'Other'   => (int) (\mt_rand(200, 400) / 4),
478        ];
479
480        $view->data['currentCustomerRegion'] = $currentCustomerRegion;
481
482        $annualCustomerRegion = [];
483        for ($i = 1; $i < 11; ++$i) {
484            $annualCustomerRegion[] = [
485                'year'    => 2020 - 10 + $i,
486                'Europe'  => $a = (int) (\mt_rand(200, 400) / 4),
487                'America' => $b = (int) (\mt_rand(200, 400) / 4),
488                'Asia'    => $c = (int) (\mt_rand(200, 400) / 4),
489                'Africa'  => $d = (int) (\mt_rand(200, 400) / 4),
490                'CIS'     => $e = (int) (\mt_rand(200, 400) / 4),
491                'Other'   => $f = (int) (\mt_rand(200, 400) / 4),
492                'Total'   => $a + $b + $c + $d + $e + $f,
493            ];
494        }
495
496        $view->data['annualCustomerRegion'] = $annualCustomerRegion;
497
498        /////
499        $currentCustomersRep = [];
500        for ($i = 1; $i < 13; ++$i) {
501            $currentCustomersRep['Rep ' . $i] = [
502                'customers' => (int) (\mt_rand(200, 400) / 12),
503            ];
504        }
505
506        \uasort($currentCustomersRep, function($a, $b) {
507            return $b['customers'] <=> $a['customers'];
508        });
509
510        $view->data['currentCustomersRep'] = $currentCustomersRep;
511
512        $annualCustomersRep = [];
513        for ($i = 1; $i < 13; ++$i) {
514            $annualCustomersRep['Rep ' . $i] = [];
515
516            for ($j = 1; $j < 11; ++$j) {
517                $annualCustomersRep['Rep ' . $i][] = [
518                    'customers' => (int) (\mt_rand(200, 400) / 12),
519                    'year'      => 2020 - 10 + $j,
520                ];
521            }
522        }
523
524        $view->data['annualCustomersRep'] = $annualCustomersRep;
525
526        /////
527        $currentCustomersCountry = [];
528        for ($i = 1; $i < 51; ++$i) {
529            $country                                           = (string) ISO3166NameEnum::getRandom();
530            $currentCustomersCountry[\substr($country, 0, 20)] = [
531                'customers' => (int) (\mt_rand(200, 400) / 12),
532            ];
533        }
534
535        \uasort($currentCustomersCountry, function($a, $b) {
536            return $b['customers'] <=> $a['customers'];
537        });
538
539        $view->data['currentCustomersCountry'] = $currentCustomersCountry;
540
541        $annualCustomersCountry = [];
542        for ($i = 1; $i < 51; ++$i) {
543            $countryCode                                          = ISO3166CharEnum::getRandom();
544            $countryName                                          = (string) ISO3166NameEnum::getByName('_' . $countryCode);
545            $annualCustomersCountry[\substr($countryName, 0, 20)] = [];
546
547            for ($j = 1; $j < 11; ++$j) {
548                $annualCustomersCountry[\substr($countryName, 0, 20)][] = [
549                    'customers' => (int) (\mt_rand(200, 400) / 12),
550                    'year'      => 2020 - 10 + $j,
551                    'name'      => $countryName,
552                    'code'      => $countryCode,
553                ];
554            }
555        }
556
557        $view->data['annualCustomersCountry'] = $annualCustomersCountry;
558
559        /////
560        $customerGroups = [];
561        for ($i = 1; $i < 7; ++$i) {
562            $customerGroups['Group ' . $i] = [
563                'customers' => (int) (\mt_rand(200, 400) / 12),
564            ];
565        }
566
567        $view->data['customerGroups'] = $customerGroups;
568
569        return $view;
570    }
571
572    /**
573     * Routing end-point for application behaviour.
574     *
575     * @param RequestAbstract  $request  Request
576     * @param ResponseAbstract $response Response
577     * @param array            $data     Generic data
578     *
579     * @return RenderableInterface
580     *
581     * @since 1.0.0
582     * @codeCoverageIgnore
583     */
584    public function viewBillAnalysis(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
585    {
586        $head  = $response->data['Content']->head;
587        $nonce = $this->app->appSettings->getOption('script-nonce');
588
589        $head->addAsset(AssetType::CSS, 'Resources/chartjs/Chartjs/chart.css');
590        $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/Chartjs/chart.js', ['nonce' => $nonce]);
591        $head->addAsset(AssetType::JSLATE, 'Modules/ClientManagement/Controller.js', ['nonce' => $nonce, 'type' => 'module']);
592
593        $view = new View($this->app->l11nManager, $request, $response);
594        $view->setTemplate('/Modules/Billing/Theme/Backend/bill-analysis');
595        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1001602001, $request, $response);
596
597        return $view;
598    }
599
600    /**
601     * Routing end-point for application behaviour.
602     *
603     * @param RequestAbstract  $request  Request
604     * @param ResponseAbstract $response Response
605     * @param array            $data     Generic data
606     *
607     * @return RenderableInterface
608     *
609     * @since 1.0.0
610     * @codeCoverageIgnore
611     */
612    public function viewSalesRepAnalysis(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
613    {
614        $head  = $response->data['Content']->head;
615        $nonce = $this->app->appSettings->getOption('script-nonce');
616
617        $head->addAsset(AssetType::CSS, 'Resources/chartjs/Chartjs/chart.css');
618        $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/Chartjs/chart.js', ['nonce' => $nonce]);
619        $head->addAsset(AssetType::JSLATE, 'Modules/ClientManagement/Controller.js', ['nonce' => $nonce, 'type' => 'module']);
620
621        $view = new View($this->app->l11nManager, $request, $response);
622        $view->setTemplate('/Modules/Billing/Theme/Backend/rep-analysis');
623        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1001602001, $request, $response);
624
625        /////
626        $currentCustomerRegion = [
627            'Europe'  => (int) (\mt_rand(200, 400) / 4),
628            'America' => (int) (\mt_rand(200, 400) / 4),
629            'Asia'    => (int) (\mt_rand(200, 400) / 4),
630            'Africa'  => (int) (\mt_rand(200, 400) / 4),
631            'CIS'     => (int) (\mt_rand(200, 400) / 4),
632            'Other'   => (int) (\mt_rand(200, 400) / 4),
633        ];
634
635        $view->data['currentCustomerRegion'] = $currentCustomerRegion;
636
637        $annualCustomerRegion = [];
638        for ($i = 1; $i < 11; ++$i) {
639            $annualCustomerRegion[] = [
640                'year'    => 2020 - 10 + $i,
641                'Europe'  => $a = (int) (\mt_rand(200, 400) / 4),
642                'America' => $b = (int) (\mt_rand(200, 400) / 4),
643                'Asia'    => $c = (int) (\mt_rand(200, 400) / 4),
644                'Africa'  => $d = (int) (\mt_rand(200, 400) / 4),
645                'CIS'     => $e = (int) (\mt_rand(200, 400) / 4),
646                'Other'   => $f = (int) (\mt_rand(200, 400) / 4),
647                'Total'   => $a + $b + $c + $d + $e + $f,
648            ];
649        }
650
651        $view->data['annualCustomerRegion'] = $annualCustomerRegion;
652
653         /////
654        $currentCustomersRep = [];
655        for ($i = 1; $i < 13; ++$i) {
656            $currentCustomersRep['Rep ' . $i] = [
657                'customers' => (int) (\mt_rand(200, 400) / 12),
658            ];
659        }
660
661        \uasort($currentCustomersRep, function($a, $b) {
662            return $b['customers'] <=> $a['customers'];
663        });
664
665        $view->data['currentCustomersRep'] = $currentCustomersRep;
666
667        $annualCustomersRep = [];
668        for ($i = 1; $i < 13; ++$i) {
669            $annualCustomersRep['Rep ' . $i] = [];
670
671            for ($j = 1; $j < 11; ++$j) {
672                $annualCustomersRep['Rep ' . $i][] = [
673                    'customers' => (int) (\mt_rand(200, 400) / 12),
674                    'year'      => 2020 - 10 + $j,
675                ];
676            }
677        }
678
679        $view->data['annualCustomersRep'] = $annualCustomersRep;
680
681        return $view;
682    }
683
684    /**
685     * Routing end-point for application behaviour.
686     *
687     * @param RequestAbstract  $request  Request
688     * @param ResponseAbstract $response Response
689     * @param array            $data     Generic data
690     *
691     * @return RenderableInterface
692     *
693     * @since 1.0.0
694     * @codeCoverageIgnore
695     */
696    public function viewBillingPurchaseInvoiceUpload(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
697    {
698        $view = new View($this->app->l11nManager, $request, $response);
699        $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill-upload');
700        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1002901101, $request, $response);
701
702        return $view;
703    }
704
705    /**
706     * Routing end-point for application behaviour.
707     *
708     * @param RequestAbstract  $request  Request
709     * @param ResponseAbstract $response Response
710     * @param array            $data     Generic data
711     *
712     * @return RenderableInterface
713     *
714     * @since 1.0.0
715     * @codeCoverageIgnore
716     */
717    public function viewPrivatePurchaseBillUpload(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
718    {
719        $view = new View($this->app->l11nManager, $request, $response);
720        $view->setTemplate('/Modules/Billing/Theme/Backend/user-purchase-bill-upload');
721        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005109001, $request, $response);
722
723        return $view;
724    }
725
726    /**
727     * Routing end-point for application behaviour.
728     *
729     * @param RequestAbstract  $request  Request
730     * @param ResponseAbstract $response Response
731     * @param array            $data     Generic data
732     *
733     * @return RenderableInterface
734     *
735     * @since 1.0.0
736     * @codeCoverageIgnore
737     */
738    public function viewPrivatePurchaseBillDashboard(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
739    {
740        $view = new View($this->app->l11nManager, $request, $response);
741        $view->setTemplate('/Modules/Billing/Theme/Backend/user-purchase-bill-dashboard');
742        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005109001, $request, $response);
743
744        $mapperQuery = PurchaseBillMapper::getAll()
745            ->with('type')
746            ->with('type/l11n')
747            ->with('supplier')
748            ->where('type/transferType', BillTransferType::PURCHASE)
749            ->where('status', BillStatus::UNPARSED)
750            ->sort('id', OrderType::DESC)
751            ->limit(25);
752
753        if ($request->getData('ptype') === 'p') {
754            $view->data['bills'] = $mapperQuery
755                    ->where('id', $request->getDataInt('id') ?? 0, '<')
756                    ->where('type/l11n/language', $response->header->l11n->language)
757                    ->execute();
758        } elseif ($request->getData('ptype') === 'n') {
759            $view->data['bills'] = $mapperQuery->where('id', $request->getDataInt('id') ?? 0, '>')
760                    ->where('type/l11n/language', $response->header->l11n->language)
761                    ->execute();
762        } else {
763            $view->data['bills'] = $mapperQuery->where('id', 0, '>')
764                    ->where('type/l11n/language', $response->header->l11n->language)
765                    ->execute();
766        }
767
768        return $view;
769    }
770
771    /**
772     * Routing end-point for application behaviour.
773     *
774     * @param RequestAbstract  $request  Request
775     * @param ResponseAbstract $response Response
776     * @param array            $data     Generic data
777     *
778     * @return RenderableInterface
779     *
780     * @since 1.0.0
781     * @codeCoverageIgnore
782     */
783    public function viewPrivateBillingPurchaseInvoice(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
784    {
785        $view = new View($this->app->l11nManager, $request, $response);
786        $view->setTemplate('/Modules/Billing/Theme/Backend/user-purchase-bill');
787        $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005109001, $request, $response);
788
789        $bill = PurchaseBillMapper::get()
790            ->with('elements')
791            ->with('files')
792            ->with('files/types')
793            ->with('notes')
794            ->where('id', (int) $request->getData('id'))
795            ->execute();
796
797        $view->data['bill'] = $bill;
798
799        /** @var \Model\Setting $previewType */
800        $previewType = $this->app->appSettings->get(
801            names: SettingsEnum::PREVIEW_MEDIA_TYPE,
802            module: self::NAME
803        );
804
805        $view->data['previewType'] = (int) $previewType->content;
806
807        /** @var \Model\Setting $originalType */
808        $originalType = $this->app->appSettings->get(
809            names: SettingsEnum::ORIGINAL_MEDIA_TYPE,
810            module: self::NAME
811        );
812
813        $view->data['originalType'] = (int) $originalType->content;
814
815        return $view;
816    }
817}