From 05e29a2ea38b2bc93dda2d3aabe016cccb54486c Mon Sep 17 00:00:00 2001 From: Shohrat Date: Wed, 11 Oct 2023 21:29:51 +0500 Subject: [PATCH] reports --- plugins/offline/cors/.gitignore | 1 + plugins/offline/cors/CONTRIBUTING.md | 7 + plugins/offline/cors/LICENSE | 21 ++ plugins/offline/cors/Plugin.php | 49 +++++ plugins/offline/cors/README.md | 45 ++++ plugins/offline/cors/classes/Cors.php | 71 +++++++ plugins/offline/cors/classes/CorsService.php | 199 ++++++++++++++++++ plugins/offline/cors/classes/HandleCors.php | 49 +++++ .../offline/cors/classes/HandlePreflight.php | 74 +++++++ .../offline/cors/classes/OriginMatcher.php | 100 +++++++++ .../offline/cors/classes/ServiceProvider.php | 90 ++++++++ plugins/offline/cors/composer.json | 13 ++ plugins/offline/cors/lang/de/lang.php | 6 + plugins/offline/cors/lang/en/lang.php | 6 + plugins/offline/cors/models/Settings.php | 12 ++ .../offline/cors/models/settings/fields.yaml | 55 +++++ plugins/offline/cors/plugin.yaml | 6 + plugins/offline/cors/updates/version.yaml | 14 ++ plugins/romanah/gokbakja/components/Order.php | 179 +++++++++++++++- .../gokbakja/components/Production.php | 125 ++++++++--- themes/gokbakja/pages/orders/report.htm | 141 ++++++++++++- themes/gokbakja/pages/orders/shipping.htm | 150 ++++++++++++- .../pages/production/report-dynamic.htm | 13 +- .../partials/production/modal-report.htm | 7 +- 24 files changed, 1385 insertions(+), 48 deletions(-) create mode 100644 plugins/offline/cors/.gitignore create mode 100644 plugins/offline/cors/CONTRIBUTING.md create mode 100644 plugins/offline/cors/LICENSE create mode 100644 plugins/offline/cors/Plugin.php create mode 100644 plugins/offline/cors/README.md create mode 100644 plugins/offline/cors/classes/Cors.php create mode 100644 plugins/offline/cors/classes/CorsService.php create mode 100644 plugins/offline/cors/classes/HandleCors.php create mode 100644 plugins/offline/cors/classes/HandlePreflight.php create mode 100644 plugins/offline/cors/classes/OriginMatcher.php create mode 100644 plugins/offline/cors/classes/ServiceProvider.php create mode 100644 plugins/offline/cors/composer.json create mode 100644 plugins/offline/cors/lang/de/lang.php create mode 100644 plugins/offline/cors/lang/en/lang.php create mode 100644 plugins/offline/cors/models/Settings.php create mode 100644 plugins/offline/cors/models/settings/fields.yaml create mode 100644 plugins/offline/cors/plugin.yaml create mode 100644 plugins/offline/cors/updates/version.yaml diff --git a/plugins/offline/cors/.gitignore b/plugins/offline/cors/.gitignore new file mode 100644 index 0000000..57872d0 --- /dev/null +++ b/plugins/offline/cors/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/plugins/offline/cors/CONTRIBUTING.md b/plugins/offline/cors/CONTRIBUTING.md new file mode 100644 index 0000000..f74dc2f --- /dev/null +++ b/plugins/offline/cors/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# How to contribute + +Contributions to this project are highly welcome. + +1. Submit your pull requests to the `develop` branch +1. Adhere to the [PSR-2 coding](http://www.php-fig.org/psr/psr-2/) standard +1. If you are not sure if your ideas are fit for this project, create an issue and ask \ No newline at end of file diff --git a/plugins/offline/cors/LICENSE b/plugins/offline/cors/LICENSE new file mode 100644 index 0000000..6aece30 --- /dev/null +++ b/plugins/offline/cors/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 OFFLINE GmbH + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/offline/cors/Plugin.php b/plugins/offline/cors/Plugin.php new file mode 100644 index 0000000..0dcb0e2 --- /dev/null +++ b/plugins/offline/cors/Plugin.php @@ -0,0 +1,49 @@ +app['Illuminate\Contracts\Http\Kernel'] + ->prependMiddleware(HandleCors::class); + + if (request()->isMethod('OPTIONS')) { + $this->app['Illuminate\Contracts\Http\Kernel'] + ->prependMiddleware(HandlePreflight::class); + } + } + + public function registerPermissions() + { + return [ + 'offline.cors.manage' => [ + 'label' => 'Can manage cors settings', + 'tab' => 'CORS', + ], + ]; + } + + public function registerSettings() + { + return [ + 'cors' => [ + 'label' => 'CORS-Settings', + 'description' => 'Manage CORS headers', + 'category' => 'system::lang.system.categories.cms', + 'icon' => 'icon-code', + 'class' => Settings::class, + 'order' => 500, + 'keywords' => 'cors', + 'permissions' => ['offline.cors.manage'], + ], + ]; + } +} diff --git a/plugins/offline/cors/README.md b/plugins/offline/cors/README.md new file mode 100644 index 0000000..ecbb035 --- /dev/null +++ b/plugins/offline/cors/README.md @@ -0,0 +1,45 @@ +# CORS plugin for October CMS + +This plugin is based on [https://github.com/barryvdh/laravel-cors](https://github.com/barryvdh/laravel-cors/blob/master/config/cors.php). + +All configuration for the plugin can be done via the backend settings. + +The following cors headers are supported: + +* Access-Control-Allow-Origin +* Access-Control-Allow-Headers +* Access-Control-Allow-Methods +* Access-Control-Allow-Credentials +* Access-Control-Expose-Headers +* Access-Control-Max-Age + +Currently these headers are sent for every request. There is no per-route configuration possible at this time. + +## Setup + +After installing the plugin visit the CORS settings page in your October CMS backend settings. + +You can add `*` as an entry to `Allowed origins`, `Allowed headers` and `Allowed methods` to allow any kind of CORS request from everywhere. + +It is advised to be more explicit about these settings. You can add values for each header via the repeater fields. + +> It is important to set these intial settings once for the plugin to work as excpected! + +### Filesystem configuration + +As an alternative to the backend settings you can create a `config/config.php` file in the plugins root directory to configure it. + +The filesystem configuration will overwrite any defined backend setting. + +```php + true, + 'maxAge' => 3600, + 'allowedOrigins' => ['*'], + 'allowedHeaders' => ['*'], + 'allowedMethods' => ['GET', 'POST'], + 'exposedHeaders' => [''], +]; +``` \ No newline at end of file diff --git a/plugins/offline/cors/classes/Cors.php b/plugins/offline/cors/classes/Cors.php new file mode 100644 index 0000000..2ceeade --- /dev/null +++ b/plugins/offline/cors/classes/Cors.php @@ -0,0 +1,71 @@ + [], + 'allowedMethods' => [], + 'allowedOrigins' => [], + 'exposedHeaders' => false, + 'maxAge' => false, + 'supportsCredentials' => false, + ]; + + /** + * Cors constructor. + * + * @param HttpKernelInterface $app + * @param array $options + */ + public function __construct(HttpKernelInterface $app, array $options = []) + { + $this->app = $app; + $this->cors = new CorsService(array_merge($this->defaultOptions, $options)); + + } + + /** + * @param Request $request + * @param int $type + * @param bool $catch + * + * @return bool|Response + */ + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) + { + if ( ! $this->cors->isCorsRequest($request)) { + return $this->app->handle($request, $type, $catch); + } + + if ($this->cors->isPreflightRequest($request)) { + return $this->cors->handlePreflightRequest($request); + } + + if ( ! $this->cors->isActualRequestAllowed($request)) { + return new Response('Not allowed.', 403); + } + + $response = $this->app->handle($request, $type, $catch); + + return $this->cors->addActualRequestHeaders($response, $request); + } +} \ No newline at end of file diff --git a/plugins/offline/cors/classes/CorsService.php b/plugins/offline/cors/classes/CorsService.php new file mode 100644 index 0000000..41758e7 --- /dev/null +++ b/plugins/offline/cors/classes/CorsService.php @@ -0,0 +1,199 @@ +options = $this->normalizeOptions($options); + } + + private function normalizeOptions(array $options = []) + { + $options += [ + 'supportsCredentials' => false, + 'maxAge' => 0, + ]; + + // Make sure these values are arrays, if not specified in the backend settings. + $arrayKeys = [ + 'allowedOrigins', + 'allowedHeaders', + 'exposedHeaders', + 'allowedMethods', + ]; + + foreach ($arrayKeys as $key) { + if (!$options[$key]) { + $options[$key] = []; + } + } + + // normalize array('*') to true + if (in_array('*', $options['allowedOrigins'])) { + $options['allowedOrigins'] = true; + } + if (in_array('*', $options['allowedHeaders'])) { + $options['allowedHeaders'] = true; + } else { + $options['allowedHeaders'] = array_map('strtolower', $options['allowedHeaders']); + } + + if (in_array('*', $options['allowedMethods'])) { + $options['allowedMethods'] = true; + } else { + $options['allowedMethods'] = array_map('strtoupper', $options['allowedMethods']); + } + + return $options; + } + + public function isActualRequestAllowed(Request $request) + { + return $this->checkOrigin($request); + } + + public function isCorsRequest(Request $request) + { + return $request->headers->has('Origin') && $request->headers->get('Origin') !== $request->getSchemeAndHttpHost(); + } + + public function isPreflightRequest(Request $request) + { + return $this->isCorsRequest($request) + && $request->getMethod() === 'OPTIONS' + && $request->headers->has('Access-Control-Request-Method'); + } + + public function addActualRequestHeaders(Response $response, Request $request) + { + if ( ! $this->checkOrigin($request)) { + return $response; + } + + $response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin')); + + if ( ! $response->headers->has('Vary')) { + $response->headers->set('Vary', 'Origin'); + } else { + $response->headers->set('Vary', $response->headers->get('Vary') . ', Origin'); + } + + if ($this->options['supportsCredentials']) { + $response->headers->set('Access-Control-Allow-Credentials', 'true'); + } + + if ($this->options['exposedHeaders']) { + $response->headers->set('Access-Control-Expose-Headers', implode(', ', $this->options['exposedHeaders'])); + } + + return $response; + } + + public function handlePreflightRequest(Request $request) + { + if (true !== $check = $this->checkPreflightRequestConditions($request)) { + return $check; + } + + return $this->buildPreflightCheckResponse($request); + } + + private function buildPreflightCheckResponse(Request $request) + { + $response = new Response(); + + if ($this->options['supportsCredentials']) { + $response->headers->set('Access-Control-Allow-Credentials', 'true'); + } + + $response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin')); + + if ($this->options['maxAge']) { + $response->headers->set('Access-Control-Max-Age', $this->options['maxAge']); + } + + $allowMethods = $this->options['allowedMethods'] === true + ? strtoupper($request->headers->get('Access-Control-Request-Method')) + : implode(', ', $this->options['allowedMethods']); + $response->headers->set('Access-Control-Allow-Methods', $allowMethods); + + $allowHeaders = $this->options['allowedHeaders'] === true + ? strtoupper($request->headers->get('Access-Control-Request-Headers')) + : implode(', ', $this->options['allowedHeaders']); + $response->headers->set('Access-Control-Allow-Headers', $allowHeaders); + + return $response; + } + + private function checkPreflightRequestConditions(Request $request) + { + if ( ! $this->checkOrigin($request)) { + return $this->createBadRequestResponse(403, 'Origin not allowed'); + } + + if ( ! $this->checkMethod($request)) { + return $this->createBadRequestResponse(405, 'Method not allowed'); + } + + $requestHeaders = []; + // if allowedHeaders has been set to true ('*' allow all flag) just skip this check + if ($this->options['allowedHeaders'] !== true && $request->headers->has('Access-Control-Request-Headers')) { + $headers = strtolower($request->headers->get('Access-Control-Request-Headers')); + $requestHeaders = explode(',', $headers); + + foreach ($requestHeaders as $header) { + if ( ! in_array(trim($header), $this->options['allowedHeaders'])) { + return $this->createBadRequestResponse(403, 'Header not allowed'); + } + } + } + + return true; + } + + private function createBadRequestResponse($code, $reason = '') + { + return new Response($reason, $code); + } + + private function checkOrigin(Request $request) + { + if ($this->options['allowedOrigins'] === true) { + // allow all '*' flag + return true; + } + $origin = $request->headers->get('Origin'); + + foreach ($this->options['allowedOrigins'] as $allowedOrigin) { + if (OriginMatcher::matches($allowedOrigin, $origin)) { + return true; + } + } + + return false; + } + + private function checkMethod(Request $request) + { + if ($this->options['allowedMethods'] === true) { + // allow all '*' flag + return true; + } + + $requestMethod = strtoupper($request->headers->get('Access-Control-Request-Method')); + + return in_array($requestMethod, $this->options['allowedMethods']); + } + +} \ No newline at end of file diff --git a/plugins/offline/cors/classes/HandleCors.php b/plugins/offline/cors/classes/HandleCors.php new file mode 100644 index 0000000..9f2a88d --- /dev/null +++ b/plugins/offline/cors/classes/HandleCors.php @@ -0,0 +1,49 @@ +cors = $cors; + } + + /** + * Handle an incoming request. Based on Asm89\Stack\Cors by asm89 + * @see https://github.com/asm89/stack-cors/blob/master/src/Asm89/Stack/Cors.php + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * + * @return mixed + */ + public function handle($request, Closure $next) + { + if ( ! $this->cors->isCorsRequest($request)) { + return $next($request); + } + + if ( ! $this->cors->isActualRequestAllowed($request)) { + abort(403); + } + + /** @var \Illuminate\Http\Response $response */ + $response = $next($request); + + return $this->cors->addActualRequestHeaders($response, $request); + } + +} \ No newline at end of file diff --git a/plugins/offline/cors/classes/HandlePreflight.php b/plugins/offline/cors/classes/HandlePreflight.php new file mode 100644 index 0000000..392b5a3 --- /dev/null +++ b/plugins/offline/cors/classes/HandlePreflight.php @@ -0,0 +1,74 @@ +cors = $cors; + $this->router = $router; + $this->kernel = $kernel; + } + + /** + * Handle an incoming OPTIONS request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * + * @return mixed + */ + public function handle($request, Closure $next) + { + $response = $next($request); + if ($this->cors->isPreflightRequest($request) && $this->hasMatchingCorsRoute($request)) { + $preflight = $this->cors->handlePreflightRequest($request); + $response->headers->add($preflight->headers->all()); + } + $response->setStatusCode(204); + return $response; + } + + /** + * Verify the current OPTIONS request matches a CORS-enabled route + * + * @param \Illuminate\Http\Request $request + * + * @return boolean + */ + private function hasMatchingCorsRoute($request) + { + // Check if CORS is added in a global middleware + if ($this->kernel->hasMiddleware(HandleCors::class)) { + return true; + } + + // Check if CORS is added as a route middleware + $request = clone $request; + $request->setMethod($request->header('Access-Control-Request-Method')); + + try { + $route = $this->router->getRoutes()->match($request); + // change of method name in laravel 5.3 + if (method_exists($this->router, 'gatherRouteMiddleware')) { + $middleware = $this->router->gatherRouteMiddleware($route); + } else { + $middleware = $this->router->gatherRouteMiddlewares($route); + } + + return in_array(HandleCors::class, $middleware); + } catch (\Exception $e) { + app('log')->error($e); + + return false; + } + } +} diff --git a/plugins/offline/cors/classes/OriginMatcher.php b/plugins/offline/cors/classes/OriginMatcher.php new file mode 100644 index 0000000..bf529d2 --- /dev/null +++ b/plugins/offline/cors/classes/OriginMatcher.php @@ -0,0 +1,100 @@ + $patternComponent) { + if ($patternComponent === '*') { + return true; + } + if ( ! isset($hostComponents[$index])) { + return false; + } + if ($hostComponents[$index] !== $patternComponent) { + return false; + } + } + + return count($patternComponents) === count($hostComponents); + } + + public static function portMatches($pattern, $port) + { + if ($pattern === "*") { + return true; + } + if ((string)$pattern === "") { + return (string)$port === ""; + } + if (preg_match('/\A\d+\z/', $pattern)) { + return (string)$pattern === (string)$port; + } + if (preg_match('/\A(?P\d+)-(?P\d+)\z/', $pattern, $captured)) { + return $captured['from'] <= $port && $port <= $captured['to']; + } + throw new \InvalidArgumentException("Invalid port pattern: ${pattern}"); + } + + public static function parseOriginPattern($originPattern, $component = -1) + { + $matched = preg_match( + '!\A + (?: (?P ([a-z][a-z0-9+\-.]*) ):// )? + (?P (?:\*|[\w-]+)(?:\.[\w-]+)* ) + (?: :(?P (?: \*|\d+(?:-\d+)? ) ) )? + \z!x', + $originPattern, + $captured + ); + if ( ! $matched) { + throw new \InvalidArgumentException("Invalid origin pattern ${originPattern}"); + } + $components = [ + 'scheme' => $captured['scheme'] ?: null, + 'host' => $captured['host'], + 'port' => array_key_exists('port', $captured) ? $captured['port'] : null, + ]; + switch ($component) { + case -1: + return $components; + case PHP_URL_SCHEME: + return $components['scheme']; + case PHP_URL_HOST: + return $components['host']; + case PHP_URL_PORT: + return $components['port']; + } + throw new \InvalidArgumentException("Invalid component: ${component}"); + } +} \ No newline at end of file diff --git a/plugins/offline/cors/classes/ServiceProvider.php b/plugins/offline/cors/classes/ServiceProvider.php new file mode 100644 index 0000000..7138f9c --- /dev/null +++ b/plugins/offline/cors/classes/ServiceProvider.php @@ -0,0 +1,90 @@ +app->singleton(CorsService::class, function ($app) { + return new CorsService($this->getSettings()); + }); + } + + /** + * Return default Settings + */ + protected function getSettings() + { + $supportsCredentials = (bool)$this->getConfigValue('supportsCredentials', false); + $maxAge = (int)$this->getConfigValue('maxAge', 0); + $allowedOrigins = $this->getConfigValue('allowedOrigins', []); + $allowedHeaders = $this->getConfigValue('allowedHeaders', []); + $allowedMethods = $this->getConfigValue('allowedMethods', []); + $exposedHeaders = $this->getConfigValue('exposedHeaders', []); + + return compact( + 'supportsCredentials', + 'allowedOrigins', + 'allowedHeaders', + 'allowedMethods', + 'exposedHeaders', + 'maxAge' + ); + } + + /** + * Returns an effective config value. + * + * If a filesystem config is available it takes precedence + * over the backend settings values. + * + * @param $key + * @param null $default + * + * @return mixed + */ + public function getConfigValue($key, $default = null) + { + return $this->filesystemConfig($key) ?: $this->getValues(Settings::get($key, $default)); + } + + /** + * Return the filesystem config value if available. + * + * @param string $key + * + * @return mixed + */ + public function filesystemConfig($key) + { + return config('offline.cors::' . $key); + } + + /** + * Extract the repeater field values. + * + * @param mixed $values + * + * @return array + */ + protected function getValues($values) + { + return \is_array($values) ? collect($values)->pluck('value')->toArray() : $values; + } +} \ No newline at end of file diff --git a/plugins/offline/cors/composer.json b/plugins/offline/cors/composer.json new file mode 100644 index 0000000..4ce370d --- /dev/null +++ b/plugins/offline/cors/composer.json @@ -0,0 +1,13 @@ +{ + "name": "offline/oc-cors-plugin", + "description": "Setup and manage Cross-Origin Resource Sharing headers in October CMS", + "type": "october-plugin", + "license": "MIT", + "authors": [ + { + "name": "Tobias Kündig", + "email": "tobias@offline.swiss" + } + ], + "require": {} +} diff --git a/plugins/offline/cors/lang/de/lang.php b/plugins/offline/cors/lang/de/lang.php new file mode 100644 index 0000000..0df3bb1 --- /dev/null +++ b/plugins/offline/cors/lang/de/lang.php @@ -0,0 +1,6 @@ + [ + 'name' => 'CORS', + 'description' => 'Verwalte Cross-Origin Resource Sharing Header in October CMS', + ], +]; \ No newline at end of file diff --git a/plugins/offline/cors/lang/en/lang.php b/plugins/offline/cors/lang/en/lang.php new file mode 100644 index 0000000..beaa2e5 --- /dev/null +++ b/plugins/offline/cors/lang/en/lang.php @@ -0,0 +1,6 @@ + [ + 'name' => 'CORS', + 'description' => 'Setup and manage Cross-Origin Resource Sharing headers', + ], +]; \ No newline at end of file diff --git a/plugins/offline/cors/models/Settings.php b/plugins/offline/cors/models/Settings.php new file mode 100644 index 0000000..381d13f --- /dev/null +++ b/plugins/offline/cors/models/Settings.php @@ -0,0 +1,12 @@ +timezone('UTC +05:00'); + $currentDateFormat = $currentDate->format('Y-m-d'); + + $data = post(); + + + $orders = OrderModel::with(["client", "shipping"]) + ->withCount(['order_items as order_all_amount' => function ($query) { + $query->select(DB::raw('sum(amount)')); + }]) + ->withCount(['order_items as order_all_price' => function ($query) { + $query->select(DB::raw('sum(price) * sum(amount)')); + }]) + ->withCount(['payment as all_payments' => function ($query) { + $query->select(DB::raw('sum(amount)')); + }]) + ->orderBy('id', 'DESC'); + + + $start = Carbon::parse($data["start"])->format('Y-m-d'); + $end = Carbon::parse($data["end"])->format('Y-m-d');; + + $client_id = $data["client_id"]; + $note = $data["note"]; + + + if ($client_id) { + $orders->where("client_id", $client_id); + } + + if ($note) { + $orders->where("note", "like", "%" . $note . "%"); + } + + if ($start != $currentDateFormat){ + $orders->whereBetween('created_at', [$start, $end]); + } + + $ordersFiltered = $orders->get(); + + + $html_data = ''; + + for ($x = 0; $x < count($ordersFiltered); $x++) { + $status = ''; + + $html_data .= ' + ' . ($x + 1) . ' + Sargyt #' . $ordersFiltered[$x]->id . ' + ' . $ordersFiltered[$x]->client->name . ' + ' . $ordersFiltered[$x]->client->country . ' + ' . number_format($ordersFiltered[$x]->order_all_amount) . ' kg + ' . number_format($ordersFiltered[$x]->order_all_price) . ' $ + + ' . number_format($ordersFiltered[$x]->all_payments) . ' $ + + ' . number_format($ordersFiltered[$x]->order_all_price - $ordersFiltered[$x]->all_payments) . ' $ + + ' . $ordersFiltered[$x]->created_at->format('d.m.Y') . ' + ' . $ordersFiltered[$x]->note . ' + + '; + } + + if ($ordersFiltered) { + return [ + '#orders_report_datas' => $html_data, + + ]; + } else { + Flash::error("Yalnyshlyk bar!!"); + } + } + + public function onReportLogistics() + { + + $currentDate = Carbon::now()->timezone('UTC +05:00'); + $currentDateFormat = $currentDate->format('Y-m-d'); + + $data = post(); + + + $shippingTransports = ShippingTransportModel::with("shipping.order")->orderBy('shipping_id', 'DESC'); + + // $start = Carbon::parse($data["start"])->format('Y-m-d'); + // $end = Carbon::parse($data["end"])->format('Y-m-d');; + + $transport = $data["transport_type"]; + $place = $data["place_now"]; + $status = $data["status"]; + $transport_no = $data["transport_no"]; + + + if ($transport) { + $shippingTransports->where("transport_type", $transport); + } + + if ($place) { + $shippingTransports->where("place_now", "like", "%" . $place . "%"); + } + + if ($transport_no) { + $shippingTransports->where("transport_no", "like", "%" . $transport_no . "%"); + } + + if ($status) { + $shippingTransports->where("status", $status); + } + + // if ($start != $currentDateFormat){ + // $shippingTransports->whereBetween('created_at', [$start, $end]); + // } + + $shippingTransportsFiltered = $shippingTransports->get(); + $shippingTransportsAmountLoaded = $shippingTransports->sum("loaded_amount"); + + + $html_data = ''; + + for ($x = 0; $x < count($shippingTransportsFiltered); $x++) { + $status = ''; + + if($shippingTransportsFiltered[$x]->status == "loaded"){ + $status = 'ÝÜKLENDI'; + } + + if($shippingTransportsFiltered[$x]->status == "loading"){ + $status = 'ÝÜKLENÝÄR'; + } + + if($shippingTransportsFiltered[$x]->status == "complated"){ + $status = 'ÝERINE ÝETIRILDI'; + } + + $html_data .= ' + ' . ($x + 1) . ' + ' . $shippingTransportsFiltered[$x]->transport_type . ' + ' . $shippingTransportsFiltered[$x]->transport_no . ' + Sargyt #'.$shippingTransportsFiltered[$x]->shipping->order->id.' + ' . $shippingTransportsFiltered[$x]->place_now . ' + ' . $shippingTransportsFiltered[$x]->loaded_amount . ' kg + + ' . $status . ' + ' . $shippingTransportsFiltered[$x]->note . ' + '; + } + + if ($shippingTransportsFiltered) { + return [ + '#logistics_report_datas' => $html_data, + '#all_amount' => '
+

Logistika Boýunça Umumy

+

Hasabat

+
+
+
+
+
Ýük Mukdary: ' . number_format($shippingTransportsAmountLoaded) . ' kg
+
+
+
', + ]; + } else { + Flash::error("Yalnyshlyk bar!!"); + } + } public function onRender() { @@ -508,7 +683,7 @@ class Order extends ComponentBase ' . number_format($orderDatas[$x]->all_payments) . ' $ - ' . number_format($orderDatas[$x]->order_all_price - $orderDatas[$x]->all_payments ) . ' $ + ' . number_format($orderDatas[$x]->order_all_price - $orderDatas[$x]->all_payments) . ' $ ' . $orderDatas[$x]->created_at->format('d.m.Y') . ' ' . $orderDatas[$x]->note . ' @@ -831,7 +1006,7 @@ class Order extends ComponentBase ' . number_format($orderDatas[$x]->all_payments) . ' $ - ' . number_format($orderDatas[$x]->order_all_price - $orderDatas[$x]->all_payments ) . ' $ + ' . number_format($orderDatas[$x]->order_all_price - $orderDatas[$x]->all_payments) . ' $ ' . $orderDatas[$x]->created_at->format('d.m.Y') . ' ' . $orderDatas[$x]->note . ' diff --git a/plugins/romanah/gokbakja/components/Production.php b/plugins/romanah/gokbakja/components/Production.php index 15bded0..746c6f4 100644 --- a/plugins/romanah/gokbakja/components/Production.php +++ b/plugins/romanah/gokbakja/components/Production.php @@ -37,6 +37,7 @@ class Production extends ComponentBase $productions = ProductionModel::with(['pivot_production', 'excruiter', 'shift'])->orderBy('id', 'DESC'); + $productionsCalc = ProductionModel::orderBy('id', 'DESC'); $start = Carbon::parse($data["start"])->format('Y-m-d'); $end = Carbon::parse($data["end"])->format('Y-m-d'); @@ -50,23 +51,36 @@ class Production extends ComponentBase if ($excruiter) { $productions->where("excruiter_id", $excruiter); + $productionsCalc->where("excruiter_id", $excruiter); } if ($shiftId) { $productions->where("shift_id", $shiftId); + $productionsCalc->where("shift_id", $shiftId); } if ($start != $currentDateFormat) { $productions->whereBetween('created_at', [$start, $end]); + + $calc = $productionsCalc->select(DB::raw('MAX(all_amount) - MIN(all_amount) AS amount_subtraction'), DB::raw('MAX(all_amount) AS max_amount'), DB::raw('MIN(all_amount) AS min_amount'), DB::raw('MAX(time) AS max_time'), DB::raw('MIN(time) AS min_time')) + ->whereBetween('created_at', [$start, $end])->first(); + + $diffMinutes = Carbon::parse($calc->max_time)->diffInMinutes($calc->min_time); + $calcTimeDiff = floor($diffMinutes / 60) . ' sagat ' . ($diffMinutes - floor($diffMinutes / 60) * 60) . ' minut'; + // dd($max); + // $min = $productions->select(DB::raw("MIN(id)")); + + } $productionsFiltered = $productions->get(); + $html_data = ''; for ($x = 0; $x < count($productionsFiltered); $x++) { // dd($productionsFiltered[0]->shift->desc); $html_data .= ' - ' . ($x + 1) . ' + ' . ($x+1) . ' ' . $productionsFiltered[$x]->created_at->format("d.m.Y | H:i") . ' ' . $productionsFiltered[$x]->shift->desc . ' @@ -80,7 +94,7 @@ class Production extends ComponentBase for ($i = 0; $i < count($productionsFiltered[$x]->pivot_production); $i++) { - $html_data .= ' '.number_format($productionsFiltered[$x]->pivot_production[$i]->amount_percentage).'%'; + $html_data .= ' '.number_format($productionsFiltered[$x]->pivot_production[$i]->amount_percentage).'% '; } $html_data .= '' . $productionsFiltered[$x]->note . ' @@ -90,7 +104,26 @@ class Production extends ComponentBase if ($productionsFiltered) { return [ '#production_report_datas' => $html_data, - '#exampleModalFullscreenLabel' => ''. $startView .' - '. $endView .' seneleri aralygynda güni jemi', + // '#exampleModalFullscreenLabel' => ''. $startView .' - '. $endView .' seneleri aralygynda güni jemi', + '#report_dynamic' => '
+

Çig Mallar Boýunça Umumy

+

Hasabat

+
+
+
+
+
Sarp Edilen Wagt: '.$calcTimeDiff.' sany
+
+
+
+
+
+
+
Sarp Edilen Çig mal: '.number_format($calc->amount_subtraction).' kg
+
+
+
+ ' ]; } else { Flash::error("Yalnyshlyk bar!!"); @@ -112,7 +145,17 @@ class Production extends ComponentBase $currentDateLast = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $excruiter)->with("excruiter")->orderBy('id', 'DESC')->first(); $currentDateFirst = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $excruiter)->orderBy('id', 'ASC')->first(); - $diffMinutes = Carbon::parse($currentDateLast->time)->diffInMinutes($currentDateFirst->time); + $productionsCalc = ProductionModel::orderBy('id', 'DESC'); + + $calc = $productionsCalc->select(DB::raw('MAX(all_amount) - MIN(all_amount) AS amount_subtraction'), DB::raw('MAX(all_amount) AS max_amount'), DB::raw('MIN(all_amount) AS min_amount'), DB::raw('MAX(time) AS max_time'), DB::raw('MIN(time) AS min_time')) + ->whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $excruiter)->first(); + + $diffMinutes = Carbon::parse($calc->max_time)->diffInMinutes($calc->min_time); + + // $calcTimeDiff = floor($diffMinutes / 60) . ' sagat ' . ($diffMinutes - floor($diffMinutes / 60) * 60) . ' minut'; + + + // $diffMinutes = Carbon::parse($currentDateLast->time)->diffInMinutes($currentDateFirst->time); $currentDateProductionAll = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $excruiter)->avg('all_amount'); @@ -135,7 +178,7 @@ class Production extends ComponentBase ) ); - $producedAll = $currentDateLast->all_amount - $currentDateFirst->all_amount; + $producedAll = $calc->amount_subtraction; $countDailyChanges = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $excruiter)->get(); @@ -220,17 +263,31 @@ class Production extends ComponentBase $currentDateExcruiters = ProductionModel::whereDate('created_at', date($currentDateFormat))->groupBy("excruiter_id")->orderBy('id', 'DESC')->with("excruiter")->get(); + for ($i = 0; $i < count($currentDateExcruiters); $i++) { $currentDateLastExc = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $currentDateExcruiters[$i]->excruiter_id)->orderBy('id', 'DESC')->first(); - $currentDateFirstExc = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $currentDateExcruiters[$i]->excruiter_id)->orderBy('id', 'ASC')->first(); + // $currentDateFirstExc = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $currentDateExcruiters[$i]->excruiter_id)->orderBy('id', 'ASC')->first(); - $diffMinutesExc = Carbon::parse($currentDateLastExc->time)->diffInMinutes($currentDateFirstExc->time); + ///////////// + + + $productionsCalc = ProductionModel::orderBy('id', 'DESC'); + + $calc = $productionsCalc->select(DB::raw('MAX(all_amount) - MIN(all_amount) AS amount_subtraction'), DB::raw('MAX(all_amount) AS max_amount'), DB::raw('MIN(all_amount) AS min_amount'), DB::raw('MAX(time) AS max_time'), DB::raw('MIN(time) AS min_time')) + ->whereDate('created_at', date($currentDateFormat))->where('excruiter_id', $currentDateExcruiters[$i]->excruiter_id)->first(); + + $diffMinutesExc = Carbon::parse($calc->max_time)->diffInMinutes($calc->min_time); + + + ///////////// + + // $diffMinutesExc = Carbon::parse($currentDateLastExc->time)->diffInMinutes($currentDateFirstExc->time); $hourCountExc = floor($diffMinutesExc / 60) . ' sagat ' . ($diffMinutesExc - floor($diffMinutesExc / 60) * 60) . ' minut'; - $allAmountExc = $currentDateLastExc->all_amount - $currentDateFirstExc->all_amount; + $allAmountExc = $calc->amount_subtraction; // dd($currentDateFirstExc); $html_data3 .= '
'; @@ -272,13 +329,21 @@ class Production extends ComponentBase // } + + + + + $currentDateShifts = ProductionModel::whereDate('created_at', date($currentDateFormat)) - ->where("excruiter_id", $excruiter) + // ->where("excruiter_id", $excruiter) ->with(["shift", "excruiter", "pivot_production"]) - ->orderBy('id', 'ASC') - ->groupBy("shift_id") + ->groupBy("shift_id", "excruiter_id") + // ->max("id") + ->orderBy('excruiter_id', 'DESC') + // ->distinct() ->get(); + // dd($currentDateShifts); // $products = ProductModel::where("report", "simple")->get(); @@ -296,9 +361,9 @@ class Production extends ComponentBase Wagty Jemi '; - for ($ii = 0; $ii < count($currentDateShifts[0]->pivot_production); $ii++) { - $html_data4 .= '' . $currentDateShifts[0]->pivot_production[$ii]->product_name . ''; - } + // for ($ii = 0; $ii < count($currentDateShifts[0]->pivot_production); $ii++) { + // $html_data4 .= '' . $currentDateShifts[0]->pivot_production[$ii]->product_name . ''; + // } $html_data4 .= ' '; @@ -306,40 +371,38 @@ class Production extends ComponentBase for ($i = 0; $i < count($currentDateShifts); $i++) { - $pivotShiftLasts = PivotProductionModel::where('production_id', $currentDateShifts[$i]->id)->get(); + $productionsCalc = ProductionModel::orderBy('id', 'DESC')->whereDate('created_at', date($currentDateFormat)); - $currentDateLastShift = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('shift_id', $currentDateShifts[$i]->shift_id)->where('excruiter_id', $currentDateShifts[$i]->excruiter_id)->with('excruiter')->orderBy('id', 'DESC')->first(); + $calc = $productionsCalc->select(DB::raw('MAX(all_amount) - MIN(all_amount) AS amount_subtraction'), DB::raw('MAX(all_amount) AS max_amount'), DB::raw('MIN(all_amount) AS min_amount'), DB::raw('MAX(time) AS max_time'), DB::raw('MIN(time) AS min_time')) + ->where('shift_id', $currentDateShifts[$i]->shift_id)->where('excruiter_id', $currentDateShifts[$i]->excruiter_id)->first(); - $currentDateFirstShift = ProductionModel::whereDate('created_at', date($currentDateFormat))->where('shift_id', $currentDateShifts[$i]->shift_id)->where('excruiter_id', $currentDateShifts[$i]->excruiter_id)->orderBy('id', 'ASC')->first(); + $diffMinutes = Carbon::parse($calc->max_time)->diffInMinutes($calc->min_time); - $diffMinutesShift = Carbon::parse($currentDateLastShift->time)->diffInMinutes($currentDateFirstShift->time); - - $hourCountShift = floor($diffMinutesShift / 60) . ' sagat ' . ($diffMinutesShift - floor($diffMinutesShift / 60) * 60) . ' minut'; - - $hourCountShiftCalc = floor($diffMinutesShift / 60) . '.' . ($diffMinutesShift - floor($diffMinutesShift / 60) * 60); - - $allAmountShift = $currentDateLastShift->all_amount - $currentDateFirstShift->all_amount; + $hourCountShift = floor($diffMinutes / 60) . ' sagat ' . ($diffMinutes - floor($diffMinutes / 60) * 60) . ' minut'; $html_data4 .= ' ' . ($i + 1) . ' ' . $currentDateShifts[$i]->shift->desc . '(' . $currentDateShifts[$i]->shift->start . ' - ' . $currentDateShifts[$i]->shift->end . ') ' . $currentDateLastShift->excruiter->name . ' - ' . $hourCountShift . ' - ' . $allAmountShift . ' kg'; + style="font-size: 14px;">' . $currentDateShifts[$i]->excruiter->name . ' + '.$hourCountShift.' + '.$calc->amount_subtraction.' kg'; - for ($x = 0; $x < count($pivotShiftLasts); $x++) { + // for ($x = 0; $x < count($pivotShiftLasts); $x++) { - $calculatedPercentageShift = (float) ($pivotShiftLasts[$x]->amount_percentage / 100) * (float) $allAmountShift; + // $calculatedPercentageShift = (float) ($pivotShiftLasts[$x]->amount_percentage / 100) * (float) $allAmountShift; - $html_data4 .= '' . ($calculatedPercentageShift) . ' kg '; - } + // $html_data4 .= '' . ($calculatedPercentageShift) . ' kg '; + // } $html_data4 .= ''; } + $html_data4 .= ' + + '; $html_data4 .= '
'; diff --git a/themes/gokbakja/pages/orders/report.htm b/themes/gokbakja/pages/orders/report.htm index f3c26d8..9a26c69 100644 --- a/themes/gokbakja/pages/orders/report.htm +++ b/themes/gokbakja/pages/orders/report.htm @@ -2,5 +2,144 @@ title = "orders/report" url = "/orders/report" layout = "platform_main" is_hidden = 0 + +[order] == -list order \ No newline at end of file + +== +{% put styles %} + + + + + +{% endput %} + + +
+
+
+
+
+
+
+
+
+ + +
+ + +
+
+
+
+ + +
+ +
+ + +
+ + +
+ +
+ + + +
+
+ +
+
+
+ +
+
+ + +
+
+
+
+
+
+
+

Sargytlar Boýunça Umumy

+

Hasabat

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sargyt NoKlentÝurdyMukdaryBahasyTölenenBergisiSenesiBellik
Sargyt NoKlentÝurdyMukdaryBahasyTölenenBergisiSenesiBellik
+
+ + + +
+
+
+
+ + +{% partial 'dataTableJs' %} +{% put scripts %} + + + +{% endput %} diff --git a/themes/gokbakja/pages/orders/shipping.htm b/themes/gokbakja/pages/orders/shipping.htm index f31107c..1dfa7ac 100644 --- a/themes/gokbakja/pages/orders/shipping.htm +++ b/themes/gokbakja/pages/orders/shipping.htm @@ -2,5 +2,153 @@ title = "orders/shipping" url = "/orders/shipping" layout = "platform_main" is_hidden = 0 + +[order] == -shipping order \ No newline at end of file + +== +{% put styles %} + + + + + +{% endput %} + + +
+
+
+
+
+
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + + +
+
+ +
+
+
+ +
+
+ + +
+
+
+
+
+
+
+

Logistika Boýunça Umumy

+

Hasabat

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TransportTransport NoSargyt NoÝükiŞu Wagtky ÝeriStatusBellik
TransportTransport NoSargyt NoÝükiŞu Wagtky ÝeriStatusBellik
+
+ + + +
+
+
+
+ + +{% partial 'dataTableJs' %} +{% put scripts %} + + + +{% endput %} diff --git a/themes/gokbakja/pages/production/report-dynamic.htm b/themes/gokbakja/pages/production/report-dynamic.htm index a05a411..2fc9e51 100644 --- a/themes/gokbakja/pages/production/report-dynamic.htm +++ b/themes/gokbakja/pages/production/report-dynamic.htm @@ -99,21 +99,20 @@ function onStart(){
-
-
-

Çig Mallar Boýunça Umumy

-

Hasabat

-
-
+
+ +
{% partial "production/modal-report" %} + diff --git a/themes/gokbakja/partials/production/modal-report.htm b/themes/gokbakja/partials/production/modal-report.htm index a6963f4..0d6ef70 100644 --- a/themes/gokbakja/partials/production/modal-report.htm +++ b/themes/gokbakja/partials/production/modal-report.htm @@ -42,12 +42,7 @@
-
- -
-
-
- +