Browse Source

all reports

Alexander Musikhin 6 months ago
parent
commit
3ad0298e2d

+ 189 - 3
app/Http/Controllers/ReportController.php

@@ -3,11 +3,14 @@
 namespace App\Http\Controllers;
 
 use App\Helpers\Price;
+use App\Models\Dictionary\District;
 use App\Models\ObjectType;
 use App\Models\Order;
 use App\Models\OrderStatus;
 use App\Models\Product;
 use App\Models\ProductSKU;
+use App\Models\Reclamation;
+use App\Models\ReclamationStatus;
 use App\Models\User;
 use Illuminate\Http\Request;
 use Illuminate\Support\Str;
@@ -29,7 +32,8 @@ class ReportController extends Controller
         $this->data['objectTypes'] = $objectTypes;
         $user_ids = Order::query()->distinct()->get('user_id')->pluck('user_id')->toArray();
         $managers = User::query()->whereIn('id', $user_ids)->get()->pluck('name', 'id')->toArray();
-        $this->data['managers'] = $managers;
+        $this->data['managers'] = $managers ?? [];
+        $this->data['doneMafsManager'] = $this->data['notDoneMafsManager'] = [];
 
 
         // всего заказов, выполнено заказов
@@ -48,8 +52,8 @@ class ReportController extends Controller
             $query->whereIn('order_status_id', $mountStatuses);
         })->count();
 
-        // общая сумма
-        $this->data['totalSum'] = Price::format(
+        // общая сумма mount
+        $this->data['totalMountSum'] = Price::format(
             ProductSKU::query()->
             whereHas('order', function ($query) use ($mountStatuses) {
                 $query->whereIn('order_status_id', $mountStatuses);
@@ -121,12 +125,194 @@ class ReportController extends Controller
                     ->whereNotIn('order_status_id', $mountStatuses);
             })->count();
 
+        }
 
+        // рекламации
+        $this->data['totalReclamations'] = Reclamation::query()->count();
+        $this->data['reclamationStatuses'] = ReclamationStatus::query()->get()->pluck('name', 'id')->toArray();
+        foreach ($this->data['reclamationStatuses'] as $reclamationStatusId => $reclamationStatus) {
+            $this->data['reclamations'][$reclamationStatus] = Reclamation::query()->where('status_id', '=', $reclamationStatusId)->count();
         }
+        $this->data['reclamationMafs'] = $this->data['reclamationDetails'] = [];
+        foreach (Reclamation::all() as $reclamation) {
+            foreach ($reclamation->skus as $sku) {
+                $a = $sku->product->article;
+                if(isset($this->data['reclamationMafs'][$a])){
+                    $this->data['reclamationMafs'][$a]++;
+                } else {
+                    $this->data['reclamationMafs'][$a] = 1;
+                }
+            }
 
+            foreach ($reclamation->details as $detail) {
+                $a = $detail->name;
+                if(isset($this->data['reclamationDetails'][$a])){
+                    $this->data['reclamationDetails'][$a] += $detail->quantity;
+                } else {
+                    $this->data['reclamationDetails'][$a] = $detail->quantity;
+                }
+            }
+        }
 
 
+        // svod
+        $orderStatuses = OrderStatus::query()->get()->pluck('name', 'id')->toArray();
+        foreach ($orderStatuses as $orderStatusId => $orderStatus) {
+            $this->data['orderStatuses'][$orderStatus] = Order::query()->where('order_status_id', '=', $orderStatusId)->count();
+            $this->data['orderMafStatuses'][$orderStatus]     = ProductSKU::query()->
+            whereHas('order', function ($query) use ($orderStatusId) {
+                $query->where('order_status_id', $orderStatusId);
+            })->count();
+        }
+        // общая сумма
+        $this->data['totalSum'] = Price::format(
+            ProductSKU::query()
+                ->withSum('product', 'total_price')
+                ->get()
+                ->sum('product_sum_total_price')
+        );
+        // общая сумма done
+        $this->data['totalDoneSum'] = Price::format(
+            ProductSKU::query()->
+            whereHas('order', function ($query) use ($doneStatuses) {
+                $query->whereIn('order_status_id', $doneStatuses);
+            })
+                ->withSum('product', 'total_price')
+                ->get()
+                ->sum('product_sum_total_price')
+        );
+
+        $districts = District::query()->get()->pluck('shortname', 'id')->toArray();
+        foreach ($districts as $districtId => $district) {
+
+            $totalOrders = $this->getOrderCount($districtId);
+            $totalMafs = $this->getMafCount($districtId);
+            $readyOrders = $this->getOrderCount($districtId, 4);
+            $readyMafs = $this->getMafCount($districtId, 4);
+            $mountOrders = $this->getOrderCount($districtId, 5);
+            $mountMafs = $this->getMafCount($districtId, 5);
+            $readyDoneOrders = $this->getOrderCount($districtId, 7);
+            $readyDoneMafs = $this->getMafCount($districtId, 7);
+            $doneOrders = $this->getOrderCount($districtId, $doneStatuses);
+            $doneMafs = $this->getMafCount($districtId, $doneStatuses);
+            $statusOstOrders = $totalOrders - $mountOrders - $readyDoneOrders - $doneOrders;
+            $statusOstMafs = $totalMafs - $mountMafs - $readyDoneMafs - $doneMafs;
+
+            $totalYardOrders = $this->getOrderCount($districtId, null, 1);
+            $totalYardMafs = $this->getMafCount($districtId, null, 1);
+            $mountYardOrders = $this->getOrderCount($districtId, $mountStatuses, 1);
+            $mountYardMafs = $this->getMafCount($districtId, $mountStatuses, 1);
+            $ostYardOrders = $totalYardOrders - $mountYardOrders;
+            $ostYardMafs = $totalYardMafs - $mountYardMafs;
+
+            $totalEduOrders = $this->getOrderCount($districtId, null, 2);
+            $totalEduMafs = $this->getMafCount($districtId, null, 2);
+            $mountEduOrders = $this->getOrderCount($districtId, $mountStatuses, 2);
+            $mountEduMafs = $this->getMafCount($districtId, $mountStatuses, 2);
+            $ostEduOrders = $totalYardOrders - $mountYardOrders;
+            $ostEduMafs = $totalYardMafs - $mountYardMafs;
+
+            $totalZnakOrders = $this->getOrderCount($districtId, null, 3);
+            $totalZnakMafs = $this->getMafCount($districtId, null, 3);
+            $mountZnakOrders = $this->getOrderCount($districtId, $mountStatuses, 3);
+            $mountZnakMafs = $this->getMafCount($districtId, $mountStatuses, 3);
+            $ostZnakOrders = $totalYardOrders - $mountYardOrders;
+            $ostZnakMafs = $totalYardMafs - $mountYardMafs;
+
+
+            $this->data['byDistrict'][$district] = [
+                'name'  => $district,
+                'totalSum' => $this->getDistrictSum($districtId),
+                'doneSum' => $this->getDistrictSum($districtId, $doneStatuses),
+                'totalOrders' => $totalOrders,
+                'totalMafs' => $totalMafs,
+                'readyOrders' => $readyOrders,
+                'readyMafs' => $readyMafs,
+                'mountOrders' => $mountOrders,
+                'mountMafs' => $mountMafs,
+                'readyDoneOrders' => $readyDoneOrders,
+                'readyDoneMafs' => $readyDoneMafs,
+                'doneOrders' => $doneOrders,
+                'doneMafs' => $doneMafs,
+                'statusOstOrders' => $statusOstOrders,
+                'statusOstMafs' => $statusOstMafs,
+
+                'totalYardOrders' => $totalYardOrders,
+                'totalYardMafs' => $totalYardMafs,
+                'mountYardOrders' => $mountYardOrders,
+                'mountYardMafs' => $mountYardMafs,
+                'ostYardOrders' => $ostYardOrders,
+                'ostYardMafs' => $ostYardMafs,
+                'totalEduOrders' => $totalEduOrders,
+                'totalEduMafs' => $totalEduMafs,
+                'mountEduOrders' => $mountEduOrders,
+                'mountEduMafs' => $mountEduMafs,
+                'ostEduOrders' => $ostEduOrders,
+                'ostEduMafs' => $ostEduMafs,
+                'totalZnakOrders' => $totalZnakOrders,
+                'totalZnakMafs' => $totalZnakMafs,
+                'mountZnakOrders' => $mountZnakOrders,
+                'mountZnakMafs' => $mountZnakMafs,
+                'ostZnakOrders' => $ostZnakOrders,
+                'ostZnakMafs' => $ostZnakMafs,
+            ];
+
+
+        }
 
         return view('reports.index', $this->data);
     }
+
+    private function getOrderCount($districtId, $status = null, $type = null)
+    {
+        $q = Order::query()->where('district_id', '=', $districtId);
+
+        if($status) {
+            if(!is_array($status)) $status = [$status];
+            $q->whereIn('order_status_id', $status);
+        }
+
+        if($type) {
+            if(!is_array($type)) $type = [$type];
+            $q->whereIn('object_type_id', $type);
+        }
+        return $q->count();
+    }
+
+    private function getMafCount($districtId, $status = null, $type = null)
+    {
+        return ProductSKU::query()->
+            whereHas('order', function ($query) use ($districtId, $status, $type) {
+                $query->where('district_id', '=', $districtId);
+
+                if($status) {
+                    if(!is_array($status)) $status = [$status];
+                    $query->whereIn('order_status_id', $status);
+                }
+
+                if($type) {
+                    if(!is_array($type)) $type = [$type];
+                    $query->whereIn('object_type_id', $type);
+                }
+            })->count();
+    }
+
+    private function getDistrictSum($districtId, $done = false)
+    {
+        return Price::format(
+            ProductSKU::query()->
+            whereHas('order', function ($query) use ($done, $districtId) {
+                $query->where('district_id', $districtId);
+                if($done){
+                    $query->whereIn('order_status_id', $done);
+                }
+            })
+            ->withSum('product', 'total_price')
+            ->get()
+            ->sum('product_sum_total_price')
+        );
+
+}
+
+
 }

+ 33 - 1
resources/sass/app.scss

@@ -77,4 +77,36 @@
 .maf-img {
   max-height: 100px;
   max-width: 100px;
-}
+}
+
+.vertical th{
+  writing-mode: vertical-lr;
+  vertical-align: middle;
+  text-align: center;
+}
+
+.svod-6, .svod-7 {
+  background-color: #86b7fe !important;
+}
+.svod-8, .svod-9 {
+  background-color: #fec886 !important;
+}
+.svod-10, .svod-11 {
+  background-color: #ccffd8 !important;
+}
+.svod-12, .svod-13 {
+  background-color: #54ab4e !important;
+}
+.svod-14, .svod-15 {
+  background-color: #effc76 !important;
+}
+
+.svod-20, .svod-21, .svod-16, .svod-17, .svod-18, .svod-19{
+  background-color: #c4c4c4 !important;
+}
+.svod-26, .svod-27, .svod-22, .svod-23, .svod-24, .svod-25{
+  background-color: #a4f7ff !important;
+}
+.svod-32, .svod-33, .svod-28, .svod-29, .svod-30, .svod-31{
+  background-color: #ffc0c0 !important;
+}

+ 244 - 73
resources/views/reports/index.blade.php

@@ -16,104 +16,275 @@
 @endphp
 
 @section('content')
-    <div class="row">
-        <div class="col-12 text-center">
-            <h1 class="text-success">Выполнение плана по монтажу МАФ</h1>
-        </div>
-    </div>
-    <hr>
-    <div class="row">
-        <div class="col-xl-4 mb-2">
-            <div class="text-center text-success fs-4 fw-bold" >
-               {{ $totalMafs }} / {{ $totalOrders }}
-            </div>
-            <div class="text-center">
-                Всего МАФ / Площадок
+
+    <ul class="nav nav-tabs" id="myTab" role="tablist">
+        <li class="nav-item" role="presentation">
+            <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#mount" type="button"
+                    role="tab" aria-controls="mount" aria-selected="true">Монтаж МАФ
+            </button>
+        </li>
+        <li class="nav-item" role="presentation">
+            <button class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#done" type="button"
+                    role="tab" aria-controls="done" aria-selected="false">Сдача МАФ
+            </button>
+        </li>
+        <li class="nav-item" role="presentation">
+            <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#all" type="button"
+                    role="tab" aria-controls="all" aria-selected="false">Свод
+            </button>
+        </li>
+        <li class="nav-item" role="presentation">
+            <button class="nav-link" id="disabled-tab" data-bs-toggle="tab" data-bs-target="#reclamation" type="button"
+                    role="tab" aria-controls="reclamations" aria-selected="false">Рекламации
+            </button>
+        </li>
+    </ul>
+
+    <div class="tab-content border-end border-start border-bottom" id="myTabContent">
+
+        <div class="tab-pane fade show active" id="mount" role="tabpanel" aria-labelledby="home-tab" tabindex="0">
+            <div class="row">
+                <div class="col-12 text-center">
+                    <h1 class="text-success my-3">Выполнение плана по монтажу МАФ</h1>
+                </div>
             </div>
-        </div>
-        <div class="col-xl-4 mb-2">
-            <div class="text-center text-success fs-4 fw-bold" >
-               {{ $mountMafs }} / {{ $mountOrders }}
+
+            <div class="row">
+                <div class="col-xl-4 mb-2">
+                    <div class="text-center text-success fs-4 fw-bold">
+                        {{ $totalMafs }} / {{ $totalOrders }}
+                    </div>
+                    <div class="text-center">
+                        Всего МАФ / Площадок
+                    </div>
+                </div>
+                <div class="col-xl-4 mb-2">
+                    <div class="text-center text-success fs-4 fw-bold">
+                        {{ $mountMafs }} / {{ $mountOrders }}
+                    </div>
+                    <div class="text-center">
+                        Установлено МАФ / Площадок
+                    </div>
+                </div>
+                <div class="col-xl-4 mb-2">
+
+                    <div class="text-center text-success fs-6 fw-bold">
+                        {{ implode('; ', $la) }}
+                    </div>
+                    <div class="text-center">
+                        Установлено по типам объекта
+                    </div>
+                </div>
             </div>
-            <div class="text-center">
-                Установлено МАФ / Площадок
+            <div class="col-12 border-top my-3"></div>
+            <div class="row align-items-center">
+                <div class="col-xl-6">
+                    <div class="mx-5 px-5 mb-3">
+                        <canvas id="total_orders" class="mx-4"></canvas>
+                    </div>
+                </div>
+
+                <div class="col-xl-6 ">
+                    <div class=" mb-3">
+                        <canvas id="order_types" class="mx-4"></canvas>
+                    </div>
+                </div>
             </div>
         </div>
-        <div class="col-xl-4 mb-2">
 
-            <div class="text-center text-success fs-6 fw-bold" >
-                {{ implode('; ', $la) }}
+        <div class="tab-pane fade" id="done" role="tabpanel" aria-labelledby="home-tab" tabindex="1">
+            <div class="row">
+                <div class="col-12 text-center">
+                    <h1 class="text-success my-3">Выполнение плана по сдаче МАФ</h1>
+                </div>
             </div>
-            <div class="text-center">
-                Установлено по типам объекта
+            <div class="row">
+                <div class="col-xl-4">
+                    <div class="text-center text-success fs-4 fw-bold">
+                        {{ $totalMafs }} / {{ $totalOrders }}
+                    </div>
+                    <div class="text-center">
+                        Всего МАФ / Площадок
+                    </div>
+                </div>
+                <div class="col-xl-4">
+                    <div class="text-center text-success fs-4 fw-bold">
+                        {{ $doneMafs }} / {{ $doneOrders }}
+                    </div>
+                    <div class="text-center">
+                        Сдано МАФ / Площадок
+                    </div>
+                </div>
+                <div class="col-xl-4">
+                    <div class="text-center text-success fs-4 fw-bold">
+                        {!! $totalMountSum !!}
+                    </div>
+                    <div class="text-center">
+                        Сдано на сумму
+                    </div>
+                </div>
             </div>
-        </div>
-    </div>
-    <hr>
-    <div class="row align-items-center">
-        <div class="col-xl-6">
-            <div class="mx-5 px-5 mb-3">
-                <canvas id="total_orders" class="mx-4"></canvas>
+            <div class="col-12 border-top my-3"></div>
+
+            <div class="row align-items-center">
+                <div class="col-xl-6 align-middle">
+                    <div class="mx-5 px-5 mb-3">
+                        <canvas id="done_orders" class="mx-4"></canvas>
+                    </div>
+                </div>
+
+                <div class="col-xl-6 align-middle">
+                    <div class=" mb-3">
+                        <canvas id="done_users" class="mx-4"></canvas>
+                    </div>
+                </div>
             </div>
         </div>
 
-        <div class="col-xl-6 ">
-            <div class=" mb-3">
-                <canvas id="order_types" class="mx-4"></canvas>
+        <div class="tab-pane fade" id="all" role="tabpanel" aria-labelledby="home-tab" tabindex="2">
+            <div class="row">
+                <div class="col-12 text-center">
+                    <h1 class="text-success my-3">Свод по МАФ</h1>
+                </div>
             </div>
-        </div>
-    </div>
-    <hr>
+            <div class="row">
+
+
+                <div class="col">
+                    <div class="text-center text-success fs-4 fw-bold">
+                        {{ $totalMafs }} / {{ $totalOrders }}
+                    </div>
+                    <div class="text-center">
+                        Всего МАФ / Площадок
+                    </div>
+                </div>
+
+                @foreach($orderStatuses as $name => $orders)
+                    <div class="col">
+                        <div class="text-center text-success fs-4 fw-bold">
+                            {{ $orderMafStatuses[$name] }} / {{ $orders }}
+                        </div>
+                        <div class="text-center">
+                            {{ $name }}
+                        </div>
+                    </div>
+                @endforeach
+
 
 
-    <div class="row">
-        <div class="col-12 text-center">
-            <h1 class="text-success">Выполнение плана по сдаче МАФ</h1>
-        </div>
-    </div>
-    <hr>
-    <div class="row">
-        <div class="col-xl-4">
-            <div class="text-center text-success fs-4 fw-bold" >
-               {{ $totalMafs }} / {{ $totalOrders }}
             </div>
-            <div class="text-center">
-                Всего МАФ / Площадок
+            <div class="col-12 border-top my-3"></div>
+            <div class="row">
+                <div class="col-12">
+                    @include('reports.svod')
+                </div>
             </div>
-        </div>
-        <div class="col-xl-4">
-            <div class="text-center text-success fs-4 fw-bold" >
-               {{ $doneMafs }} / {{ $doneOrders }}
-            </div>
-            <div class="text-center">
-                Сдано МАФ / Площадок
+
+            <div class="col-12 border-top my-3"></div>
+            <div class="row">
+                <div class="col">
+                    <div class="text-center text-success fs-4 fw-bold">
+                        {!! $totalSum !!}
+                    </div>
+                    <div class="text-center">
+                        Всего МАФ на сумму
+                    </div>
+                </div>
+                <div class="col">
+                    <div class="text-center text-success fs-4 fw-bold">
+                        {!! $totalDoneSum !!}
+                    </div>
+                    <div class="text-center">
+                        Сдано МАФ на сумму
+                    </div>
+                </div>
+
             </div>
+
         </div>
-        <div class="col-xl-4">
-            <div class="text-center text-success fs-4 fw-bold" >
-               {!! $totalSum !!}
-            </div>
-            <div class="text-center">
-                Сдано на сумму
+
+        <div class="tab-pane fade" id="reclamation" role="tabpanel" aria-labelledby="home-tab" tabindex="3">
+            <div class="row">
+                <div class="col-12 text-center">
+                    <h1 class="text-success my-3">Отчет по рекламациям</h1>
+                </div>
             </div>
-        </div>
-    </div>
-    <hr>
-    <div class="row align-items-center">
-        <div class="col-xl-6 align-middle">
-            <div class="mx-5 px-5 mb-3">
-                <canvas id="done_orders" class="mx-4"></canvas>
+            <div class="row">
+                <div class="col">
+                    <div class="text-center text-success fs-5 fw-bold">
+                        {{ $totalReclamations }}
+                    </div>
+                    <div class="text-center">
+                        Всего рекламаций
+                    </div>
+                </div>
+
+                @foreach($reclamations as $name => $r)
+                    <div class="col">
+                        <div class="text-center text-success fs-4 fw-bold">
+                            {{ $r }}
+                        </div>
+                        <div class="text-center">
+                            {{ $name }}
+                        </div>
+                    </div>
+                @endforeach
+
+
             </div>
-        </div>
+            <div class="col-12 border-top my-3"></div>
+            <div class="row ">
+                <div class="col-xl-6 p-3">
+                    <h4 class="text-success">
+                        Общий свод по МАФ
+                    </h4>
+                    <table class="table">
+                        <tr>
+                            <th>Артикул МАФ</th>
+                            <th>Кол-во</th>
+                        </tr>
+                        @foreach($reclamationMafs as $n => $val)
+                            <tr>
+                                <td>{{ $n }}</td>
+                                <td>{{ $val }}</td>
+                            </tr>
+                        @endforeach
+                    </table>
+                </div>
+
+                <div class="col-xl-6 p-3">
+                    <h4 class="text-success">
+                        Общий свод по деталям
+                    </h4>
+                    <table class="table">
+                        <tr>
+                            <th>Деталь</th>
+                            <th>Кол-во</th>
+                        </tr>
+                        @foreach($reclamationDetails as $n => $val)
+                            <tr>
+                                <td>{{ $n }}</td>
+                                <td>{{ $val }}</td>
+                            </tr>
+                        @endforeach
+                    </table>
+                </div>
 
-        <div class="col-xl-6 align-middle">
-            <div class=" mb-3">
-                <canvas id="done_users" class="mx-4"></canvas>
             </div>
         </div>
+
     </div>
 
 
+
+
+
+
+
+
+
+    {{--@dump($reclamationMafs, $reclamationDetails)--}}
+
 @endsection
 
 

+ 69 - 0
resources/views/reports/svod.blade.php

@@ -0,0 +1,69 @@
+<table class="table small">
+    <tr class="vertical">
+        <th>Округ</th>
+        <th>Сумма</th>
+        <th>Сдано на сумму</th>
+        <th colspan="2">Всего</th>
+        <th colspan="2">Готов к монтажу</th>
+        <th colspan="2">В монтаже</th>
+        <th colspan="2">Готов к сдаче</th>
+        <th colspan="2">Сдан</th>
+        <th colspan="2">Остаток</th>
+        <th colspan="2">Двор всего</th>
+        <th colspan="2">Двор установлено</th>
+        <th colspan="2">Двор остаток</th>
+        <th colspan="2">Школы всего</th>
+        <th colspan="2">Школы установлено</th>
+        <th colspan="2">Школы остаток</th>
+        <th colspan="2">Знаковые всего</th>
+        <th colspan="2">Знаковые установлено</th>
+        <th colspan="2">Знаковые остаток</th>
+    </tr>
+    <tr>
+        <th></th>
+        <th></th>
+        <th></th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+        <th>Адр</th>
+        <th>МАФ</th>
+    </tr>
+    @foreach($byDistrict as $vvv)
+        <tr>
+            @foreach($vvv as $v)
+                <td class="text-center svod-{{ $loop->iteration }}">{!! $v !!}</td>
+            @endforeach
+        </tr>
+
+    @endforeach
+</table>
+
+
+
+{{--@dump($byDistrict)--}}

+ 1 - 1
todo.md

@@ -26,5 +26,5 @@
 - [x] формирование документов на рекламации
 - [x] возвраты после редактирования (добавить поле referrer)
 - [ ] фильтры как в экселе
-- [ ] вывод отчетов (сколько смонтировано, сколько осталось и т.д.)
+- [x] вывод отчетов (сколько смонтировано, сколько осталось и т.д.)
 - [ ] мобильная верстка