Projects/3BIT/winter-semester/IIS/xnecasr00/app/Http/Controllers/VineyardOverviewController.php
2026-04-14 19:28:46 +02:00

141 lines
4.8 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Harvest;
use App\Models\PlannedTask;
use App\Models\VarietyVariation;
use App\Models\VineyardRow;
use App\Models\Treatment;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
class VineyardOverviewController extends Controller
{
public function index(Request $request)
{
$query = VineyardRow::query()
->with(['varietyVariation.grapeVariety'])
->withMax('treatments as last_treatment_at', 'created_at');
$query = $this->applyFilters($query, $request);
$rows = $query
->orderBy('id')
->paginate(15)
->withQueryString();
$rowIds = $rows->pluck('id');
$upcomingCounts = $this->upcomingPlannedCounts($rowIds);
$rows->transform(function (VineyardRow $row) use ($upcomingCounts) {
if ($row->last_treatment_at) {
$row->last_treatment_at = Carbon::parse($row->last_treatment_at);
}
$row->upcoming_planned_count = $upcomingCounts[$row->getKey()] ?? 0;
return $row;
});
$variationOptions = VarietyVariation::with('grapeVariety')
->orderBy('grape_variety_id')
->get()
->map(fn (VarietyVariation $variation) => [
'id' => $variation->getKey(),
'label' => sprintf(
'%s — %s',
$variation->grapeVariety->variety_name,
ucfirst($variation->color)
),
]);
return view('vineyard.overview.index', [
'rows' => $rows,
'variationOptions' => $variationOptions,
'statusOptions' => ['active', 'inactive', 'replanting', 'discarded'],
'filters' => Arr::only($request->all(), [
'status',
'variety_variation_id',
'planting_year_from',
'planting_year_to',
'vine_count_min',
'vine_count_max',
]),
]);
}
protected function applyFilters($query, Request $request)
{
if ($request->filled('status')) {
$query->where('status', $request->string('status'));
}
if ($request->filled('variety_variation_id')) {
$query->where('variety_variation_id', $request->integer('variety_variation_id'));
}
if ($request->filled('planting_year_from')) {
$query->where('planting_year', '>=', $request->integer('planting_year_from'));
}
if ($request->filled('planting_year_to')) {
$query->where('planting_year', '<=', $request->integer('planting_year_to'));
}
if ($request->filled('vine_count_min')) {
$query->where('vine_count', '>=', $request->integer('vine_count_min'));
}
if ($request->filled('vine_count_max')) {
$query->where('vine_count', '<=', $request->integer('vine_count_max'));
}
return $query;
}
protected function upcomingPlannedCounts(Collection $rowIds): array
{
if ($rowIds->isEmpty()) {
return [];
}
$today = Carbon::now()->toDateString();
$treatmentCounts = PlannedTask::query()
->selectRaw('treatments.row_id as row_id, COUNT(*) as aggregate')
->join('treatments', function ($join) {
$join->on('planned_tasks.taskable_id', '=', 'treatments.treatment_id')
->where('planned_tasks.taskable_type', '=', Treatment::class);
})
->whereIn('treatments.row_id', $rowIds)
->whereNull('planned_tasks.execution_date')
->whereDate('planned_tasks.planned_date', '>=', $today)
->groupBy('treatments.row_id')
->pluck('aggregate', 'row_id');
$harvestCounts = PlannedTask::query()
->selectRaw('harvests.vineyard_row_id as row_id, COUNT(*) as aggregate')
->join('harvests', function ($join) {
$join->on('planned_tasks.taskable_id', '=', 'harvests.id')
->where('planned_tasks.taskable_type', '=', Harvest::class);
})
->whereIn('harvests.vineyard_row_id', $rowIds)
->whereNull('planned_tasks.execution_date')
->whereDate('planned_tasks.planned_date', '>=', $today)
->groupBy('harvests.vineyard_row_id')
->pluck('aggregate', 'row_id');
$combined = [];
foreach ($treatmentCounts as $rowId => $count) {
$combined[$rowId] = ($combined[$rowId] ?? 0) + $count;
}
foreach ($harvestCounts as $rowId => $count) {
$combined[$rowId] = ($combined[$rowId] ?? 0) + $count;
}
return $combined;
}
}