浏览代码

added schedules

Alexander Musikhin 2 月之前
父节点
当前提交
2fe0a7553b

+ 15 - 0
app/Helpers/DateHelper.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 namespace App\Helpers;
 
 use Carbon\Exceptions\InvalidDateException;
+use DateTime;
 use Exception;
 use Illuminate\Support\Carbon;
 use Illuminate\Support\Str;
@@ -32,6 +33,12 @@ class DateHelper
         return Str::lower($dt->isoFormat($format));
     }
 
+    public static function getHumanDayOfWeek(string $date): string
+    {
+        $dt = Carbon::parse($date);
+        return Str::ucfirst($dt->dayName);
+    }
+
     /**
      * Случайная дата за последние X лет в формате YYYY-MM-DD
      * @param int|null $last_years
@@ -78,4 +85,12 @@ class DateHelper
         }
     }
 
+    public static function getDateOfWeek(int $year, int $weekNumber, $dayOfWeek = 1): string
+    {
+        $date = new DateTime();
+        // Set the date to the specified year and week number, with Monday as the day (1)
+        $date->setISODate($year, $weekNumber, $dayOfWeek);
+        return $date->format('Y-m-d');
+    }
+
 }

+ 60 - 0
app/Http/Controllers/ScheduleController.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Helpers\DateHelper;
+use App\Models\Order;
+use App\Models\OrderStatus;
+use Illuminate\Http\Request;
+
+class ScheduleController extends Controller
+{
+    protected array $data = [
+        'active'    => 'reports',
+        'title'     => 'Отчёты',
+        'id'        => 'reports',
+    ];
+
+    public function index(Request $request)
+    {
+        $this->data['weekNumber'] = $request->get('week' ,date('W'));
+        $weekDates = [
+            'mon' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber']),
+            'tue' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 2),
+            'wed' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 3),
+            'thu' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 4),
+            'fri' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 5),
+            'sat' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 6),
+            'sun' => DateHelper::getDateOfWeek(year(), $this->data['weekNumber'], 7),
+        ];
+        $this->data['weekDates'] = $weekDates;
+
+        $maxInstallDays = Order::query()->max('install_days');
+
+        $from = date('Y-m-d', strtotime($weekDates['mon']) - $maxInstallDays * 86400);
+
+        $orders = Order::query()
+            ->whereNotNull('installation_date')
+            ->whereNotNull('brigadier_id')
+            ->whereBetween('installation_date', [$from , $weekDates['sun'] ])
+            ->where('order_status_id', 5)
+            ->orderBy('installation_date')
+            ->orderBy('brigadier_id')
+            ->get();
+        $schedules = [];
+        foreach ($weekDates as $wd)
+            $schedules[$wd] = null;
+        foreach ($orders as $order) {
+            for ($iDays = 1; $iDays < $order->install_days + 1; $iDays++) {
+                $instDate = date('Y-m-d', strtotime('+' . $iDays - 1 . ' days', strtotime($order->installation_date)));
+                if(in_array($instDate, $weekDates)) {
+                    $schedules[$instDate][] = $order;
+                }
+            }
+        }
+
+
+        $this->data['schedules'] = $schedules;
+        return view('schedule.index', $this->data);
+    }
+}

+ 6 - 0
resources/sass/app.scss

@@ -92,6 +92,12 @@
   max-width: 100px;
 }
 
+.vertical {
+  writing-mode: sideways-lr;
+  vertical-align: middle;
+  text-align: center;
+}
+
 .vertical th{
   writing-mode: sideways-lr;
   vertical-align: middle;

+ 2 - 0
resources/views/layouts/menu.blade.php

@@ -10,6 +10,8 @@
 
     <li class="nav-item"><a class="nav-link @if($active == 'catalog') active @endif"
                             href="{{ route('catalog.index', session('gp_catalog')) }}">Каталог</a></li>
+    <li class="nav-item"><a class="nav-link @if($active == 'schedule') active @endif"
+                            href="{{ route('schedule.index', session('gp_schedule')) }}">График монтажей</a></li>
     <li class="nav-item"><a class="nav-link @if($active == 'reports') active @endif"
                             href="{{ route('reports.index', session('gp_reports')) }}">Отчёты</a></li>
 

+ 113 - 0
resources/views/schedule/index.blade.php

@@ -0,0 +1,113 @@
+@extends('layouts.app')
+
+@section('content')
+    <div class="row mb-3">
+        <div class="col-6">
+            <h3>График монтажей</h3>
+        </div>
+        <div class="col-6 text-end">
+            <div class="d-flex flex-row justify-content-end">
+                <div class="p-2">
+                    <button @disabled($weekNumber == 1) class="btn btn-sm btn-primary"
+                            onclick="document.location = '{{ route('schedule.index', ['week' => $weekNumber - 1]) }}'">
+                        <i class="bi bi-arrow-left"></i>
+                    </button>
+                </div>
+                <label class="p-2 d-block small mt-1">Неделя №</label>
+                <div class="p-2">
+                    <input type="number" style="width: 3rem" value="{{ $weekNumber }}" class="form-control form-control-sm"
+                           onchange="document.location = '{{ route('schedule.index') }}?week='+this.value"
+                           min="1" max="53" title="№ недели">
+                </div>
+
+                <div class="p-2">
+                    <input type="date" min="{{ year() . '-01-01' }}" max="{{ year() . '-12-31' }}"
+                           class="form-control form-control-sm" value="{{ $weekDates['mon'] }}" title="начало недели"
+                           onchange="document.location = '{{ route('schedule.index') }}?week=' + getWeekNumber(this.value)">
+                </div>
+                <div class="p-2">
+                    <input type="date" disabled
+                           class="form-control form-control-sm" value="{{ $weekDates['sun'] }}" title="конец недели">
+                </div>
+
+                <div class="p-2">
+                    <button @disabled($weekNumber > 52) class="btn btn-sm btn-primary"
+                            onclick="document.location = '{{ route('schedule.index', ['week' => $weekNumber + 1]) }}'">
+                        <i class="bi bi-arrow-right"></i>
+                    </button>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="schedule">
+        <table class="table">
+            <thead>
+                <tr>
+                    <th class="text-center vertical">День недели</th>
+                    <th class="text-center vertical">Дата</th>
+                    <th>Код адр</th>
+                    <th>Округ</th>
+                    <th>Район</th>
+                    <th>Адрес</th>
+                    <th>Тип объекта</th>
+                    <th>Артикулы МАФ</th>
+                    <th>Кол-во позиций</th>
+                    <th>Бригадир</th>
+                    <th>Примечание</th>
+                </tr>
+            </thead>
+            <tbody>
+            @foreach($schedules as $dow => $orders)
+                <tr>
+                    <td rowspan="{{ ($orders) ? count($orders) : '1' }}" class="vertical">{{ \App\Helpers\DateHelper::getHumanDayOfWeek($dow) }}</td>
+                    <td rowspan="{{ ($orders) ? count($orders) : '1' }}" class="vertical">{{ \App\Helpers\DateHelper::getHumanDate($dow) }}</td>
+                    @if($orders)
+                        @foreach($orders as $order)
+                            @if(!$loop->first) <tr> @endif
+                            <td>{{ $order->id }}</td>
+                            <td>{{ $order->district->shortname }}</td>
+                            <td>{{ $order->area->name }}</td>
+                            <td>{{ $order->object_address }}</td>
+                            <td>{{ $order->objectType->name }}</td>
+                            <td>{!! $order->productsWithCount !!}</td>
+                            <td>{{ $order->products_sku()->count() }}</td>
+                            <td>{{ $order->brigadier->name }}</td>
+                            <td></td>
+                            @if(!$loop->first) </tr> @endif
+
+                                @endforeach
+                    @endif
+
+                </tr>
+
+            @endforeach
+
+            </tbody>
+        </table>
+
+
+    </div>
+
+
+    @if($errors->any())
+        @dump($errors)
+    @endif
+@endsection
+
+@push('scripts')
+    <script type="text/javascript">
+        function getWeekNumber(d) {
+            // Copy date so don't modify original
+            d = new Date(Date.parse(d));
+            // Set to nearest Thursday: current date + 4 - current day number
+            // Make Sunday's day number 7
+            d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay()||7));
+            // Get first day of year
+            let yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
+            // Calculate and return week number
+            return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
+        }
+
+    </script>
+@endpush

+ 3 - 0
routes/web.php

@@ -9,6 +9,7 @@ use App\Http\Controllers\ProductSKUController;
 use App\Http\Controllers\ReclamationController;
 use App\Http\Controllers\ReportController;
 use App\Http\Controllers\ResponsibleController;
+use App\Http\Controllers\ScheduleController;
 use App\Http\Controllers\UserController;
 use App\Models\Role;
 use Illuminate\Http\Request;
@@ -144,6 +145,8 @@ Route::middleware('auth:web')->group(function () {
 
     Route::get('reports', [ReportController::class, 'index'])->name('reports.index');
 
+    Route::get('schedule', [ScheduleController::class, 'index'])->name('schedule.index');
+
 
     // ajax search products
     Route::get('product/search', [ProductController::class, 'search'])->name('product.search');