Browse Source

create schedule from reclamations

Alexander Musikhin 2 months ago
parent
commit
8ec358e20a

+ 4 - 0
app/Http/Controllers/ReclamationController.php

@@ -34,6 +34,9 @@ class ReclamationController extends Controller
             'order-object_address' => 'Адрес объекта',
             'create_date' => 'Дата создания',
             'finish_date' => 'Дата завершения',
+            'start_work_date' => 'Дата начала работ',
+            'work_days' => 'Срок работ, дней',
+            'brigadier_id' => 'Бригадир',
             'reason' => 'Причина',
             'guarantee' => 'Гарантии',
             'whats_done' => 'Что сделано',
@@ -88,6 +91,7 @@ class ReclamationController extends Controller
 
     public function show(Request $request, Reclamation $reclamation)
     {
+        $this->data['brigadiers'] = User::query()->where('role', Role::BRIGADIER)->get()->pluck('name', 'id');
         $this->data['reclamation'] = $reclamation;
         $this->data['previous_url'] = $request->get('previous_url');
         return view('reclamations.edit', $this->data);

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

@@ -4,11 +4,13 @@ namespace App\Http\Controllers;
 
 use App\Helpers\DateHelper;
 use App\Http\Requests\CreateScheduleFromOrderRequest;
+use App\Http\Requests\CreateScheduleFromReclamationRequest;
 use App\Http\Requests\UpdateScheduleRequest;
 use App\Models\Dictionary\Area;
 use App\Models\Dictionary\District;
 use App\Models\Order;
 use App\Models\ProductSKU;
+use App\Models\Reclamation;
 use App\Models\Role;
 use App\Models\Schedule;
 use App\Models\User;
@@ -64,6 +66,7 @@ class ScheduleController extends Controller
         if(isset($validated['delete_old_records'])) {
             Schedule::query()
                 ->where('order_id', $validated['order_id'])
+                ->where('source', 'Площадки')
                 ->where('manual', false)
                 ->delete();
         }
@@ -117,6 +120,67 @@ class ScheduleController extends Controller
 
     }
 
+    public function createFromReclamation(CreateScheduleFromReclamationRequest $request)
+    {
+        $validated = $request->validated();
+
+        // delete all auto schedules for this order
+        if(isset($validated['delete_old_records'])) {
+            Schedule::query()
+                ->where('address_code', 'РЕКЛ-' . $validated['reclamation_id'])
+                ->where('source', 'Рекламации')
+                ->where('manual', false)
+                ->delete();
+        }
+
+        $reclamation = Reclamation::query()
+            ->where('id', $validated['reclamation_id'])
+            ->first();
+
+        $order = $reclamation->order;
+
+        $mafs = [];
+        if(empty($validated['skus'])) {
+            foreach ($reclamation->skus as $sku)
+                if(!isset($mafs[$sku->product->article])) {
+                    $mafs[$sku->product->article] = 1;
+                } else {
+                    $mafs[$sku->product->article] += 1;
+                }
+        }
+
+        $mafsCount = 0;
+        $mafsText = '';
+
+        foreach ($mafs as $article => $count) {
+            $mafsCount += $count;
+            $mafsText .= $article . ' - ' . $count . "\r\n";
+        }
+
+        for ($iDays = 1; $iDays < $reclamation->work_days + 1; $iDays++) {
+            $instDate = date('Y-m-d', strtotime('+' . $iDays - 1 . ' days', strtotime($reclamation->start_work_date)));
+            Schedule::query()
+                ->create([
+                    'order_id' => $order->id,
+                    'address_code' => 'РЕКЛ-' . $validated['reclamation_id'],
+                    'source'    => 'Рекламации',
+                    'installation_date' => $instDate,
+                    'manual' => false,
+                    'district_id' => $order->district_id,
+                    'area_id' => $order->area_id,
+                    'object_address' => $order->object_address,
+                    'object_type' => $reclamation->reason,
+                    'mafs' => $mafsText,
+                    'mafs_count' => $mafsCount,
+                    'brigadier_id' => $reclamation->brigadier_id,
+                    'comment'   => $reclamation->guarantee,
+                ]);
+        }
+        return redirect()->route('schedule.index');
+
+    }
+
+
     public function update(UpdateScheduleRequest $request)
     {
         $validated = $request->validated();

+ 29 - 0
app/Http/Requests/CreateScheduleFromReclamationRequest.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class CreateScheduleFromReclamationRequest extends FormRequest
+{
+    /**
+     * Determine if the user is authorized to make this request.
+     */
+    public function authorize(): bool
+    {
+        return auth()->check();
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
+     */
+    public function rules(): array
+    {
+        return [
+            'reclamation_id'        => 'required|exists:reclamations,id',
+            'delete_old_records'    => 'nullable|string',
+        ];
+    }
+}

+ 3 - 0
app/Http/Requests/StoreReclamationRequest.php

@@ -29,6 +29,9 @@ class StoreReclamationRequest extends FormRequest
             'whats_done'    => 'nullable|string',
             'create_date'   => 'required|date',
             'finish_date'   => 'required|date',
+            'start_work_date' => 'nullable|date',
+            'work_days'     => 'nullable|integer',
+            'brigadier_id'  => 'nullable|exists:users,id',
         ];
     }
 }

+ 1 - 1
app/Http/Requests/UpdateScheduleRequest.php

@@ -11,7 +11,7 @@ class UpdateScheduleRequest extends FormRequest
      */
     public function authorize(): bool
     {
-        return auth()->check();
+        return hasRole('admin');
     }
 
     /**

+ 8 - 0
app/Models/Reclamation.php

@@ -42,6 +42,9 @@ class Reclamation extends Model
         'whats_done',
         'create_date',
         'finish_date',
+        'start_work_date',
+        'work_days',
+        'brigadier_id',
     ];
 
     public function order(): BelongsTo
@@ -69,6 +72,11 @@ class Reclamation extends Model
         return $this->belongsTo(User::class);
     }
 
+    public function brigadier(): BelongsTo
+    {
+        return $this->belongsTo(User::class, 'brigadier_id', 'id');
+    }
+
     public function photos_before(): BelongsToMany
     {
         return $this->belongsToMany(File::class, 'reclamation_photo_before');

+ 31 - 0
database/migrations/2025_09_26_212018_add_fields_to_reclamations_table.php

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('reclamations', function (Blueprint $table) {
+            $table->date('start_work_date')->nullable();
+            $table->unsignedInteger('work_days')->default(1);
+            $table->foreignId('brigadier_id')->nullable()->constrained('users')->restrictOnDelete();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('reclamations', function (Blueprint $table) {
+            $table->dropForeign('reclamations_brigadier_id_foreign');
+            $table->dropColumn(['start_work_date', 'work_days', 'brigadier_id']);
+        });
+    }
+};

+ 40 - 3
resources/views/reclamations/edit.blade.php

@@ -8,11 +8,13 @@
                 <h4>Рекламация</h4>
             </div>
             <div class="col-xl-6 text-end mb-2">
+                @if(hasRole('admin') && !is_null($reclamation->brigadier_id) && !is_null($reclamation->start_work_date))
+                    <button class="btn btn-sm btn-primary" id="createScheduleButton">Перенести в график</button>
+                @endif
                 @if(hasRole('admin,manager'))
-                <a href="{{ route('order.generate-reclamation-pack', $reclamation) }}" class="btn btn-primary btn-sm">Пакет
-                    документов рекламации</a>
+                    <a href="{{ route('order.generate-reclamation-pack', $reclamation) }}"
+                       class="btn btn-primary btn-sm">Пакет документов рекламации</a>
                 @endif
-
             </div>
         </div>
         <div class="row">
@@ -28,6 +30,9 @@
                     @include('partials.select', ['name' => 'user_id', 'title' => 'Менеджер', 'options' => $users, 'value' => $reclamation->user_id ?? old('user_id') ?? auth()->user()->id, 'disabled' => !hasRole('admin,manager')])
                     @include('partials.input', ['name' => 'create_date', 'title' => 'Дата создания', 'type' => 'date', 'required' => true, 'value' => $reclamation->create_date ?? date('Y-m-d'), 'disabled' => !hasRole('admin,manager')])
                     @include('partials.input', ['name' => 'finish_date', 'title' => 'Дата завершения', 'type' => 'date', 'required' => true, 'value' => $reclamation->finish_date ?? date('Y-m-d', strtotime('+30 days')), 'disabled' => !hasRole('admin,manager')])
+                    @include('partials.select', ['name' => 'brigadier_id', 'title' => 'Бригадир', 'options' => $brigadiers, 'value' => $reclamation->brigadier_id ?? old('brigadier_id'), 'disabled' => !hasRole('admin,manager'), 'first_empty' => true])
+                    @include('partials.input', ['name' => 'start_work_date', 'title' => 'Дата начала работ', 'type' => 'date', 'value' => $reclamation->start_work_date, 'disabled' => !hasRole('admin,manager')])
+                    @include('partials.input', ['name' => 'work_days', 'title' => 'Срок работ, дней', 'type' => 'number', 'min' => 1, 'value' => $reclamation->work_days, 'disabled' => !hasRole('admin,manager')])
                     @include('partials.select', ['name' => 'reason', 'title' => 'Причина', 'size' => 6, 'value' => $reclamation->reason ?? '', 'options' => ['Вандализм', 'Гарантия', 'Сервисное обслуживание'], 'key_as_val' => true, 'disabled' => !hasRole('admin,manager')])
                     @include('partials.textarea', ['name' => 'guarantee', 'title' => 'Гарантии', 'size' => 6, 'value' => $reclamation->guarantee ?? '', 'disabled' => !hasRole('admin,manager')])
                     @include('partials.textarea', ['name' => 'whats_done', 'title' => 'Что сделано', 'size' => 6, 'value' => $reclamation->whats_done ?? '', 'disabled' => !hasRole('admin,manager')])
@@ -285,5 +290,37 @@
             </div>
         </div>
     </div>
+
+    <!-- Модальное окно графика -->
+    <div class="modal fade" id="copySchedule" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
+        <div class="modal-dialog modal-fullscreen-sm-down modal-lg">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h1 class="modal-title fs-5" id="addModalLabel">Перенести в график монтажей</h1>
+                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
+                </div>
+                <div class="modal-body">
+                    <form action="{{ route('schedule.create-from-reclamation') }}" method="post" id="scheduleCreateForm">
+                        @csrf
+                        <div>
+                            <input type="hidden" name="reclamation_id" value="{{ $reclamation->id }}">
+{{--                            <textarea name="comment" placeholder="Комментарий для графика" class="form-control mb-3"></textarea>--}}
+                            <input type="checkbox" id="deleteOldRecords" name="delete_old_records" class="form-check-inline">
+                            <label for="deleteOldRecords" class="form-check-label mb-2">Удалить старые записи в графике для этой рекламации?</label><br>
+                            <button type="submit" class="btn btn-primary btn-sm">Обновить график</button>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
 @endsection
 
+@push('scripts')
+    <script type="module">
+        $('#createScheduleButton').on('click', function () {
+            let myModalSchedule = new bootstrap.Modal(document.getElementById("copySchedule"), {});
+            myModalSchedule.show();
+        });
+    </script>
+@endpush

+ 1 - 0
routes/web.php

@@ -134,6 +134,7 @@ Route::middleware('auth:web')->group(function () {
 
         // график
         Route::post('schedule/create_from_order', [ScheduleController::class, 'createFromOrder'])->name('schedule.create-from-order');
+        Route::post('schedule/create_from_reclamation', [ScheduleController::class, 'createFromReclamation'])->name('schedule.create-from-reclamation');
         Route::post('schedule/update', [ScheduleController::class, 'update'])->name('schedule.update');
         Route::delete('schedule/delete/{schedule}', [ScheduleController::class, 'delete'])->name('schedule.delete');