283 lines
12 KiB
PHP
283 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Breeding;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\{Matting, Cat, Kitten};
|
|
use App\Traits\LogsActivity;
|
|
use Illuminate\Http\{Request, RedirectResponse, JsonResponse};
|
|
use Illuminate\Support\Facades\{DB, Storage, Gate};
|
|
use Illuminate\View\View;
|
|
|
|
class MattingController extends Controller
|
|
{
|
|
use LogsActivity;
|
|
|
|
public function index(): View
|
|
{
|
|
Gate::authorize('check-access', ['matting', 'read']);
|
|
$mattings = Matting::with(['sire', 'dam'])
|
|
->withCount('kittens')
|
|
->latest()
|
|
->paginate(15);
|
|
|
|
return view('pages.matting.index', compact('mattings'));
|
|
}
|
|
|
|
public function create(): View
|
|
{
|
|
Gate::authorize('check-access', ['matting', 'create']);
|
|
$sires = Cat::where('jenis_kelamin', 'Jantan')->get(['id', 'nama_kucing', 'ras']);
|
|
$dams = Cat::where('jenis_kelamin', 'Betina')->get(['id', 'nama_kucing', 'ras']);
|
|
return view('pages.matting.create', compact('sires', 'dams'));
|
|
}
|
|
|
|
public function getCatData($id): JsonResponse
|
|
{
|
|
Gate::authorize('check-access', ['matting', 'read']);
|
|
$cat = Cat::find($id);
|
|
if (!$cat) return response()->json(['error' => 'Kucing tidak ditemukan'], 404);
|
|
|
|
return response()->json([
|
|
'tgl_lahir' => $cat->tanggal_lahir ? $cat->tanggal_lahir->format('Y-m-d') : '',
|
|
'pedigree' => $cat->pedigree ?? '',
|
|
'microchip' => $cat->microchip ?? '',
|
|
'kode_ems' => $cat->kode_ems ?? '',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* STORE: Menyimpan Data Breeding Baru
|
|
*/
|
|
public function store(Request $request): RedirectResponse
|
|
{
|
|
Gate::authorize('check-access', ['matting', 'create']);
|
|
$this->validateMatting($request);
|
|
|
|
return DB::transaction(function () use ($request) {
|
|
// 1. Sinkronisasi Data Induk (Update profil bapak/ibu di tabel cats)
|
|
$this->syncParentData($request);
|
|
|
|
// 2. Simpan Transaksi Matting
|
|
$matting = Matting::create(array_merge($request->except('kittens'), [
|
|
'tanggal_kawin' => $request->tgl_kawin_awal,
|
|
'user_id' => auth()->id(),
|
|
'ems_bapak' => $request->ems_bapak,
|
|
'ems_ibu' => $request->ems_ibu,
|
|
]));
|
|
|
|
// 3. Simpan Kittens
|
|
if ($request->has('kittens')) {
|
|
foreach ($request->kittens as $index => $data) {
|
|
$this->saveKittenData($matting, $data, $index, $request);
|
|
}
|
|
}
|
|
|
|
$this->logAction('MATTING_CREATED', $matting, "Registrasi Breeding Baru");
|
|
return redirect()->route('matting.index')->with('success', 'Data Breeding & Anak berhasil disimpan!');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* EDIT: Menampilkan Form Edit (Metode yang tadi hilang)
|
|
*/
|
|
public function edit(Matting $matting): View
|
|
{
|
|
Gate::authorize('check-access', ['matting', 'update']);
|
|
// Load relasi agar data anak muncul di form edit
|
|
$matting->load('kittens.cat');
|
|
|
|
$sires = Cat::where('jenis_kelamin', 'Jantan')->get(['id', 'nama_kucing', 'ras']);
|
|
$dams = Cat::where('jenis_kelamin', 'Betina')->get(['id', 'nama_kucing', 'ras']);
|
|
|
|
return view('pages.matting.edit', compact('matting', 'sires', 'dams'));
|
|
}
|
|
|
|
/**
|
|
* UPDATE: Memperbarui Data Breeding & Sinkronisasi Ulang Kittens
|
|
*/
|
|
public function update(Request $request, Matting $matting): RedirectResponse
|
|
{
|
|
Gate::authorize('check-access', ['matting', 'update']);
|
|
$this->validateMatting($request);
|
|
|
|
return DB::transaction(function () use ($request, $matting) {
|
|
// 1. Update profil Bapak/Ibu di tabel 'cats'
|
|
$this->syncParentData($request);
|
|
|
|
// 2. Update data di tabel 'mattings'
|
|
$matting->update(array_merge($request->except('kittens'), [
|
|
'tanggal_kawin' => $request->tgl_kawin_awal,
|
|
'ems_bapak' => $request->ems_bapak,
|
|
'ems_ibu' => $request->ems_ibu,
|
|
]));
|
|
|
|
// 3. Sinkronisasi Kittens (CRUD Logic)
|
|
$requestKittenIds = collect($request->kittens)->pluck('id')->filter()->toArray();
|
|
|
|
// Hapus Kitten yang tidak ada di form lagi
|
|
$kittensToDelete = $matting->kittens()->whereNotIn('id', $requestKittenIds)->get();
|
|
foreach ($kittensToDelete as $kDelete) {
|
|
if ($kDelete->cat_id) Cat::find($kDelete->cat_id)?->delete();
|
|
$kDelete->delete();
|
|
}
|
|
|
|
if ($request->has('kittens')) {
|
|
foreach ($request->kittens as $index => $data) {
|
|
if (isset($data['id']) && !empty($data['id'])) {
|
|
$kitten = Kitten::find($data['id']);
|
|
if ($kitten) {
|
|
// Update profil master anak di tabel 'cats'
|
|
Cat::where('id', $kitten->cat_id)->update([
|
|
'nama_kucing' => $data['nama'],
|
|
'jenis_kelamin' => $data['jenis_kelamin'],
|
|
'tanggal_lahir' => $data['tgl_lahir'],
|
|
'kode_ems' => $data['kode_ems'] ?? null,
|
|
'registry' => $data['registry'] ?? [],
|
|
]);
|
|
// Update record silsilah di tabel 'kittens'
|
|
$kitten->update([
|
|
'nama' => $data['nama'],
|
|
'tgl_lahir' => $data['tgl_lahir'],
|
|
'jenis_kelamin' => $data['jenis_kelamin'],
|
|
'kode_ems' => $data['kode_ems'] ?? null,
|
|
'is_pedigree' => isset($data['is_pedigree']),
|
|
'registry' => $data['registry'] ?? [],
|
|
]);
|
|
$this->handlePedigreeUploads($kitten, $index, $request);
|
|
}
|
|
} else {
|
|
$this->saveKittenData($matting, $data, $index, $request);
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->logAction('MATTING_UPDATED', $matting, "Update Breeding Record");
|
|
return redirect()->route('matting.index')->with('success', 'Perubahan berhasil disimpan!');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* SINKRONISASI DATA INDUK (EMS Fix)
|
|
*/
|
|
private function syncParentData(Request $request)
|
|
{
|
|
Cat::where('id', $request->sire_id)->update([
|
|
'microchip' => $request->no_microchip_bapak,
|
|
'tanggal_lahir' => $request->tgl_lahir_sire,
|
|
'kode_ems' => $request->ems_bapak // Sinkron EMS Bapak
|
|
]);
|
|
|
|
Cat::where('id', $request->dam_id)->update([
|
|
'microchip' => $request->no_microchip_ibu,
|
|
'tanggal_lahir' => $request->tgl_lahir_dam,
|
|
'kode_ems' => $request->ems_ibu // Sinkron EMS Ibu
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* SIMPAN DATA KITTEN (EMS & Registry Fix)
|
|
*/
|
|
private function saveKittenData($matting, $data, $index, $request)
|
|
{
|
|
$newCat = Cat::create([
|
|
'nama_kucing' => $data['nama'],
|
|
'ras' => $matting->dam->ras ?? 'Persian',
|
|
'jenis_kelamin' => $data['jenis_kelamin'],
|
|
'induk_jantan_id' => $matting->sire_id,
|
|
'induk_betina_id' => $matting->dam_id,
|
|
'status' => 'Kitten',
|
|
'tanggal_lahir' => $data['tgl_lahir'],
|
|
'kode_ems' => $data['kode_ems'] ?? null,
|
|
'registry' => $data['registry'] ?? [],
|
|
'pic_id' => auth()->id(),
|
|
'lokasi_kandang' => $matting->dam->lokasi_kandang ?? 'Lorong',
|
|
]);
|
|
|
|
$kitten = new Kitten([
|
|
'cat_id' => $newCat->id,
|
|
'matting_id' => $matting->id,
|
|
'nama' => $data['nama'],
|
|
'tgl_lahir' => $data['tgl_lahir'],
|
|
'jenis_kelamin' => $data['jenis_kelamin'],
|
|
'kode_ems' => $data['kode_ems'] ?? null,
|
|
'is_pedigree' => isset($data['is_pedigree']),
|
|
'registry' => $data['registry'] ?? [],
|
|
]);
|
|
|
|
$this->handlePedigreeUploads($kitten, $index, $request);
|
|
$kitten->save();
|
|
}
|
|
|
|
private function handlePedigreeUploads($kitten, $index, $request)
|
|
{
|
|
for ($i = 1; $i <= 4; $i++) {
|
|
$field = "foto_ped_$i";
|
|
if ($request->hasFile("kittens.$index.$field")) {
|
|
if ($kitten->$field) Storage::disk('public')->delete($kitten->$field);
|
|
$kitten->$field = $request->file("kittens.$index.$field")->store('kittens/pedigrees', 'public');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function destroy(Matting $matting): RedirectResponse
|
|
{
|
|
Gate::authorize('check-access', ['matting', 'delete']);
|
|
return DB::transaction(function () use ($matting) {
|
|
try {
|
|
$pairName = ($matting->sire->nama_kucing ?? 'Sire') . ' x ' . ($matting->dam->nama_kucing ?? 'Dam');
|
|
|
|
// 1. Loop setiap data anak yang terhubung
|
|
foreach ($matting->kittens as $kitten) {
|
|
if ($kitten->cat_id) {
|
|
$cat = Cat::find($kitten->cat_id);
|
|
|
|
if ($cat) {
|
|
// Cek apakah anak ini punya data medis atau riwayat berat
|
|
$hasMedical = $cat->treatments()->exists();
|
|
$hasWeight = $cat->weightHistories()->exists();
|
|
|
|
if ($hasMedical || $hasWeight) {
|
|
// JIKA ADA DATA TERKAIT, BATALKAN DAN BERI INFO
|
|
return back()->with('error', "Gagal menghapus! Anak ({$cat->nama_kucing}) sudah memiliki data Rekam Medis/Berat Badan. Hapus data medis anak tersebut terlebih dahulu.");
|
|
}
|
|
|
|
$cat->delete();
|
|
}
|
|
}
|
|
$kitten->delete();
|
|
}
|
|
|
|
// 2. Hapus data Matting utama
|
|
$matting->delete();
|
|
|
|
$this->logAction('MATTING_DELETED', $matting, "Menghapus riwayat breeding: $pairName");
|
|
|
|
return redirect()->route('matting.index')->with('success', "Riwayat $pairName berhasil dihapus.");
|
|
|
|
} catch (\Illuminate\Database\QueryException $e) {
|
|
// Menangkap error database (Foreign Key Constraint)
|
|
return back()->with('error', "Sistem tidak dapat menghapus data ini karena integritas database terganggu. Silakan periksa data anak yang terkait.");
|
|
}
|
|
});
|
|
}
|
|
private function validateMatting(Request $request)
|
|
{
|
|
return $request->validate([
|
|
'sire_id' => 'required|exists:cats,id',
|
|
'dam_id' => 'required|exists:cats,id',
|
|
'tgl_kawin_awal' => 'required|date',
|
|
'status' => 'required|in:proses,berhasil,gagal',
|
|
'ems_bapak' => 'nullable|string',
|
|
'ems_ibu' => 'nullable|string',
|
|
'no_pedigree_bapak' => 'nullable|string',
|
|
'no_pedigree_ibu' => 'nullable|string',
|
|
'no_microchip_bapak'=> 'nullable|string',
|
|
'no_microchip_ibu' => 'nullable|string',
|
|
'kittens' => 'nullable|array',
|
|
'kittens.*.nama' => 'required_with:kittens|string',
|
|
'kittens.*.kode_ems'=> 'nullable|string',
|
|
'kittens.*.registry'=> 'nullable|array',
|
|
]);
|
|
}
|
|
} |