Загрузка данных


@php
  use Carbon\Carbon;

  // Русские названия месяцев
  $monthNames = [
    1 => 'Январь', 2 => 'Февраль', 3 => 'Март', 4 => 'Апрель',
    5 => 'Май', 6 => 'Июнь', 7 => 'Июль', 8 => 'Август',
    9 => 'Сентябрь', 10 => 'Октябрь', 11 => 'Ноябрь', 12 => 'Декабрь',
  ];

  // 1. Найти минимальную и максимальную дату среди всех записей
  $allDates = [];
  foreach ($items as $item) {
    foreach ($item['daily'] ?? [] as $record) {
      $allDates[] = $record['date'];
    }
  }

  if (empty($allDates)) {
    $minDate = Carbon::now()->startOfMonth();
    $maxDate = Carbon::now()->endOfMonth();
  } else {
    $minDate = Carbon::parse(min($allDates));
    $maxDate = Carbon::parse(max($allDates));
  }

  // 2. Сформировать полный диапазон дат
  $dateRange = [];
  $cursor = $minDate->copy();
  while ($cursor <= $maxDate) {
    $dateRange[] = $cursor->copy();
    $cursor->addDay();
  }

  // 3. Сгруппировать даты по месяцам для шапки
  $months = [];
  foreach ($dateRange as $date) {
    $key = $date->format('Y-m');
    $months[$key]['label'] = $monthNames[(int)$date->format('n')] . ' ' . $date->format('Y');
    $months[$key]['dates'][] = $date;
  }

  // 4. Переиндексировать daily по дате для быстрого доступа
  $dailyByDate = [];
  foreach ($items as $idx => $item) {
    $dailyByDate[$idx] = [];
    foreach ($item['daily'] ?? [] as $record) {
      $dailyByDate[$idx][$record['date']] = $record;
    }
  }

  $totalCols = count($dateRange);
@endphp

<table>
  <!-- Первый уровень шапки -->
  <tr>
    <td rowspan="3" style="background-color: #DDEBF7">№ п/п</td>
    <td rowspan="3" style="background-color: #DDEBF7">ФИО</td>
    <td rowspan="3" style="background-color: #DDEBF7">Подразделение</td>
    <td rowspan="3" style="background-color: #DDEBF7">Доп. инфо</td>
    <td rowspan="3" style="background-color: #DDEBF7">imei</td>
    <td colspan="{{ $totalCols }}" style="background-color: #DDEBF7">
      Пройденное расстояние по дням месяца, км
    </td>
    <td rowspan="3" style="background-color: #DDEBF7">Сумма, км</td>
  </tr>

  <!-- Второй уровень шапки: названия месяцев -->
  <tr>
    @foreach ($months as $month)
      <td colspan="{{ count($month['dates']) }}" style="background-color: #DDEBF7; text-align: center;">
        {{ $month['label'] }}
      </td>
    @endforeach
  </tr>

  <!-- Третий уровень шапки: числа -->
  <tr>
    @foreach ($dateRange as $date)
      <td style="background-color: #DDEBF7; text-align: center;">
        {{ $date->format('j') }}
      </td>
    @endforeach
  </tr>

  <!-- Данные -->
  @foreach ($items as $item)
  @php
    $itemDailyMap = $dailyByDate[$loop->index];
  @endphp
  <tr>
    <td>{{ $loop->iteration }}</td>
    <td>{{ $item['w_fio'] }}</td>
    <td>{{ $item['department'] ? $item['department']['d_name'] : '' }}</td>
    <td>
      {{ $item['asup'] && $item['asup']['lk43'] ? 'уволен ' . date('d.m.Y', strtotime($item['asup']['lk43'])) : '' }}
      {{ $item['w_closedate'] ? 'закрыт ' . date('d.m.Y', strtotime($item['w_closedate'])) : '' }}
    </td>
    <td>
      {{ $item['trackers'] ? array_reduce($item['trackers'], function ($carry, $tracker) { return $carry . $tracker['t_imei'] . ' '; }, '') : '' }}
    </td>

    <!-- Пройденное расстояние по дням -->
    @foreach ($dateRange as $date)
      @php $key = $date->format('Y-m-d'); @endphp
      <td style="text-align: right;">
        {{ isset($itemDailyMap[$key]) ? $itemDailyMap[$key]['d_distance'] : '' }}
      </td>
    @endforeach

    <!-- Сумма по всем дням -->
    <td style="font-weight: bold; text-align: right;">
      {{ number_format(collect($itemDailyMap)->sum('d_distance'), 3, '.', ' ') }}
    </td>
  </tr>
  @endforeach
</table>