string('q')->toString(); $variations = VarietyVariation::with('grapeVariety') ->when($query !== '', function ($builder) use ($query) { $builder->where(function ($inner) use ($query) { $inner->whereHas('grapeVariety', function ($sub) use ($query) { $sub->where('variety_name', 'like', '%' . $query . '%'); })->orWhere('color', 'like', '%' . $query . '%'); }); }) ->orderBy('grape_variety_id') ->orderBy('color') ->limit(15) ->get() ->map(fn (VarietyVariation $variation) => $this->formatVariation($variation)); return response()->json([ 'data' => $variations, ]); } public function createIfMissing(Request $request) { $validated = $request->validate([ 'grape_variety_id' => ['nullable', 'integer', 'exists:grape_varieties,id'], 'grape_variety_name' => ['nullable', 'string', 'max:255'], 'color' => ['required', 'string', 'max:50'], 'description' => ['nullable', 'string'], 'typical_sugar_content' => ['nullable', 'numeric', 'min:0'], 'typical_alcohol' => ['nullable', 'numeric', 'min:0'], 'ripening_period' => ['nullable', 'string', 'max:255'], ], [ 'grape_variety_id.required_without' => 'Provide an existing variety or a name for a new variety.', 'grape_variety_name.required_without' => 'Provide an existing variety or a name for a new variety.', ]); $variety = null; if (! empty($validated['grape_variety_id'])) { $variety = GrapeVariety::find($validated['grape_variety_id']); } if (! $variety && ! empty($validated['grape_variety_name'])) { $variety = GrapeVariety::firstOrCreate([ 'variety_name' => $validated['grape_variety_name'], ]); } if (! $variety) { return response()->json([ 'message' => 'Unable to determine grape variety for variation creation.', ], 422); } $variation = VarietyVariation::firstOrCreate( [ 'grape_variety_id' => $variety->getKey(), 'color' => $validated['color'], ], [ 'description' => $validated['description'] ?? null, 'typical_sugar_content' => $validated['typical_sugar_content'] ?? null, 'typical_alcohol' => $validated['typical_alcohol'] ?? null, 'ripening_period' => $validated['ripening_period'] ?? null, 'status' => 'active', ] ); return response()->json([ 'created' => $variation->wasRecentlyCreated, 'variation' => $this->formatVariation($variation->loadMissing('grapeVariety')), ], $variation->wasRecentlyCreated ? 201 : 200); } protected function formatVariation(VarietyVariation $variation): array { $grape = $variation->grapeVariety; return [ 'id' => $variation->getKey(), 'label' => sprintf('%s — %s', $grape?->variety_name ?? 'Unknown', Str::title($variation->color)), 'color' => $variation->color, 'grape_variety' => $grape ? [ 'id' => $grape->getKey(), 'name' => $grape->variety_name, ] : null, ]; } }