269 lines
9.6 KiB
PHP
269 lines
9.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Requests\StoreBulkPlannedTasksRequest;
|
|
use App\Http\Requests\UpdatePlannedTaskRequest;
|
|
use App\Models\PlannedTask;
|
|
use App\Models\Treatment;
|
|
use App\Models\VineyardRow;
|
|
use App\Services\BulkPlannedTaskService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class PlannedTaskController extends Controller
|
|
{
|
|
public function __construct(protected BulkPlannedTaskService $bulkService)
|
|
{
|
|
}
|
|
|
|
public function showWateringForm(Request $request)
|
|
{
|
|
if (! $request->query('date')) {
|
|
return redirect()->route('vineyard.map')
|
|
->with('error', 'Please choose a date on the vineyard map before planning watering.');
|
|
}
|
|
|
|
return $this->renderForm('watering', 'planned-tasks.watering', $request);
|
|
}
|
|
|
|
public function showPruningForm(Request $request)
|
|
{
|
|
if (! $request->query('date')) {
|
|
return redirect()->route('vineyard.map')
|
|
->with('error', 'Please choose a date on the vineyard map before planning pruning.');
|
|
}
|
|
|
|
return $this->renderForm('pruning', 'planned-tasks.pruning', $request);
|
|
}
|
|
|
|
public function showFertilisationForm(Request $request)
|
|
{
|
|
if (! $request->query('date')) {
|
|
return redirect()->route('vineyard.map')
|
|
->with('error', 'Please choose a date on the vineyard map before planning fertilisation.');
|
|
}
|
|
|
|
return $this->renderForm('fertilization', 'planned-tasks.fertilisation', $request, 'fertilisation');
|
|
}
|
|
|
|
public function showPesticideForm(Request $request)
|
|
{
|
|
if (! $request->query('date')) {
|
|
return redirect()->route('vineyard.map')
|
|
->with('error', 'Please choose a date on the vineyard map before planning pesticide treatment.');
|
|
}
|
|
|
|
return $this->renderForm('spraying', 'planned-tasks.pesticide', $request, 'pesticide');
|
|
}
|
|
|
|
public function showHarvestForm(Request $request)
|
|
{
|
|
if (! $request->query('date')) {
|
|
return redirect()->route('vineyard.map')
|
|
->with('error', 'Please choose a date on the vineyard map before planning harvest.');
|
|
}
|
|
|
|
return $this->renderForm('harvest', 'planned-tasks.harvest', $request);
|
|
}
|
|
|
|
public function storeBulk(StoreBulkPlannedTasksRequest $request)
|
|
{
|
|
$result = $this->bulkService->handle($request->validated());
|
|
|
|
$status = $result['success'] ? 201 : 422;
|
|
|
|
return response()->json($result, $status);
|
|
}
|
|
|
|
protected function renderForm(string $actionKey, string $view, Request $request, ?string $displayAction = null)
|
|
{
|
|
$selectedRowIds = $this->parseRowIds($request->input('rows', []));
|
|
|
|
$plannedDate = $request->query('date');
|
|
|
|
$rows = VineyardRow::with('varietyVariation.grapeVariety')
|
|
->when($selectedRowIds->isNotEmpty(), fn ($query) => $query->whereIn('id', $selectedRowIds))
|
|
->orderBy('id')
|
|
->get();
|
|
|
|
return view($view, [
|
|
'action' => $displayAction ?? $actionKey,
|
|
'actionKey' => $actionKey,
|
|
'rows' => $rows,
|
|
'selectedRowIds' => $selectedRowIds,
|
|
'plannedDate' => $plannedDate,
|
|
]);
|
|
}
|
|
|
|
protected function parseRowIds(array|string $value): Collection
|
|
{
|
|
if (is_string($value)) {
|
|
$value = explode(',', $value);
|
|
}
|
|
|
|
return collect($value)
|
|
->map(fn ($id) => (int) $id)
|
|
->filter(fn ($id) => $id > 0)
|
|
->values();
|
|
}
|
|
|
|
public function edit(PlannedTask $task)
|
|
{
|
|
$task->load('taskable');
|
|
|
|
// Find all tasks in the same group (same type, date, note)
|
|
$groupTasks = PlannedTask::with('taskable')
|
|
->where('type', $task->type)
|
|
->where('planned_date', $task->planned_date)
|
|
->where(function($query) use ($task) {
|
|
if ($task->note) {
|
|
$query->where('note', $task->note);
|
|
} else {
|
|
$query->whereNull('note');
|
|
}
|
|
})
|
|
->whereNull('execution_date')
|
|
->get();
|
|
|
|
// Build task_rows array with task IDs and vineyard row info
|
|
$taskRows = $groupTasks->map(function($t) {
|
|
$row = null;
|
|
|
|
if (!$t->taskable) {
|
|
return null;
|
|
}
|
|
|
|
// Check taskable type to determine how to get vineyard row
|
|
$taskableType = $t->taskable_type;
|
|
|
|
// For Harvest, vineyard_row_id is directly on the taskable
|
|
if (str_contains($taskableType, 'Harvest') && $t->taskable->vineyard_row_id) {
|
|
$row = VineyardRow::with('varietyVariation.grapeVariety')
|
|
->find($t->taskable->vineyard_row_id);
|
|
}
|
|
// For treatment types (Watering, Spraying, Fertilization, Pruning), get it through parent Treatment
|
|
elseif ($t->taskable->treatment_id) {
|
|
$treatment = Treatment::with('vineyardRow.varietyVariation.grapeVariety')
|
|
->find($t->taskable->treatment_id);
|
|
if ($treatment && $treatment->vineyardRow) {
|
|
$row = $treatment->vineyardRow;
|
|
}
|
|
}
|
|
|
|
return $row ? [
|
|
'task_id' => $t->planned_task_id,
|
|
'row_id' => $row->id,
|
|
'row' => $row,
|
|
] : null;
|
|
})->filter()->sortBy('row_id')->values();
|
|
|
|
// Get the vineyard row for the main task (for display)
|
|
$vineyardRow = null;
|
|
if ($task->taskable) {
|
|
$taskableType = $task->taskable_type;
|
|
|
|
// For Harvest
|
|
if (str_contains($taskableType, 'Harvest') && $task->taskable->vineyard_row_id) {
|
|
$vineyardRow = VineyardRow::with('varietyVariation.grapeVariety')
|
|
->find($task->taskable->vineyard_row_id);
|
|
}
|
|
// For treatment types
|
|
elseif ($task->taskable->treatment_id) {
|
|
$treatment = Treatment::with('vineyardRow.varietyVariation.grapeVariety')
|
|
->find($task->taskable->treatment_id);
|
|
if ($treatment) {
|
|
$vineyardRow = $treatment->vineyardRow;
|
|
}
|
|
}
|
|
}
|
|
|
|
return view('planned-tasks.edit', [
|
|
'task' => $task,
|
|
'vineyardRow' => $vineyardRow,
|
|
'taskRows' => $taskRows,
|
|
]);
|
|
}
|
|
|
|
public function update(UpdatePlannedTaskRequest $request, PlannedTask $task)
|
|
{
|
|
$validated = $request->validated();
|
|
|
|
// Get selected task IDs (if provided, otherwise just update the single task)
|
|
$taskIds = $request->input('task_ids', [$task->planned_task_id]);
|
|
|
|
// Get all selected tasks
|
|
$tasksToUpdate = PlannedTask::with('taskable')
|
|
->whereIn('planned_task_id', $taskIds)
|
|
->whereNull('execution_date')
|
|
->get();
|
|
|
|
foreach ($tasksToUpdate as $taskToUpdate) {
|
|
// Update PlannedTask
|
|
$updateData = [
|
|
'note' => $validated['note'] ?? null,
|
|
];
|
|
|
|
// For spraying and harvest tasks, don't update the date (it's readonly)
|
|
if (!str_contains($taskToUpdate->taskable_type, 'Spraying') && !str_contains($taskToUpdate->taskable_type, 'Harvest') && isset($validated['planned_date'])) {
|
|
$updateData['planned_date'] = $validated['planned_date'];
|
|
}
|
|
|
|
$taskToUpdate->update($updateData);
|
|
|
|
// Update taskable (Treatment/Harvest) specific fields
|
|
if ($taskToUpdate->taskable) {
|
|
$taskableData = [];
|
|
$taskableType = $taskToUpdate->taskable_type;
|
|
|
|
if (str_contains($taskableType, 'Watering')) {
|
|
$taskableData = [
|
|
'time_interval' => $validated['time_interval'] ?? null,
|
|
'amount' => $validated['amount'],
|
|
];
|
|
} elseif (str_contains($taskableType, 'Fertilization')) {
|
|
$taskableData = [
|
|
'substance' => $validated['substance'],
|
|
'concentration' => $validated['concentration'] ?? null,
|
|
];
|
|
} elseif (str_contains($taskableType, 'Spraying')) {
|
|
$taskableData = [
|
|
'pesticide' => $validated['pesticide'],
|
|
'concentration' => $validated['concentration'] ?? null,
|
|
];
|
|
} elseif (str_contains($taskableType, 'Pruning')) {
|
|
$taskableData = [
|
|
'method' => $validated['method'],
|
|
'percentage_removed' => $validated['percentage_removed'] ?? null,
|
|
];
|
|
}
|
|
|
|
if (!empty($taskableData)) {
|
|
$taskToUpdate->taskable->update($taskableData);
|
|
}
|
|
}
|
|
}
|
|
|
|
$count = $tasksToUpdate->count();
|
|
$message = $count === 1
|
|
? 'Planned task updated successfully.'
|
|
: "{$count} planned tasks updated successfully.";
|
|
|
|
return redirect()->route('winemaker.planned-tasks')
|
|
->with('success', $message);
|
|
}
|
|
|
|
public function destroy(PlannedTask $task)
|
|
{
|
|
// Delete the taskable first (Treatment/Harvest)
|
|
if ($task->taskable) {
|
|
$task->taskable->delete();
|
|
}
|
|
|
|
// Delete the planned task
|
|
$task->delete();
|
|
|
|
return redirect()->route('winemaker.planned-tasks')
|
|
->with('success', 'Planned task deleted successfully.');
|
|
}
|
|
}
|