'date', 'tgl_kawin_awal' => 'date', 'tgl_kawin_akhir' => 'date', 'tgl_lahir_sire' => 'date', 'tgl_lahir_dam' => 'date', 'jumlah_anak_hidup' => 'integer', ]; } /** * SINKRONISASI OTOMATIS (Mesin sinkronisasi) * Saat data Matting disimpan, otomatis update data di tabel Cats. */ protected static function booted() { static::saved(function ($matting) { // 1. Update data Sire (Bapak) if ($matting->sire_id && $matting->sire) { $matting->sire->update([ 'microchip' => $matting->no_microchip_bapak, 'tanggal_lahir' => $matting->tgl_lahir_sire, // Pastikan kolom di tabel 'mattings' adalah ems_bapak 'kode_ems' => $matting->ems_bapak, ]); } // 2. Update data Dam (Ibu) if ($matting->dam_id && $matting->dam) { $matting->dam->update([ 'microchip' => $matting->no_microchip_ibu, 'tanggal_lahir' => $matting->tgl_lahir_dam, // Pastikan kolom di tabel 'mattings' adalah ems_ibu 'kode_ems' => $matting->ems_ibu, ]); } }); } /* -------------------------------------------------------------------------- */ /* RELATIONS */ /* -------------------------------------------------------------------------- */ public function sire(): BelongsTo { return $this->belongsTo(Cat::class, 'sire_id'); } public function dam(): BelongsTo { return $this->belongsTo(Cat::class, 'dam_id'); } public function kittens(): HasMany { return $this->hasMany(Kitten::class, 'matting_id'); } /* -------------------------------------------------------------------------- */ /* ACCESSORS (UI & BREEDING) */ /* -------------------------------------------------------------------------- */ /** * EDD (Expected Delivery Date) - H+63 */ protected function edd(): Attribute { return Attribute::make( get: fn () => $this->tgl_kawin_awal ? $this->tgl_kawin_awal->addDays(63) : null ); } /** * Deskripsi Sisa Hari (Countdown Text) */ protected function countdownText(): Attribute { return Attribute::make( get: function () { if (!$this->edd || $this->status !== 'proses') return null; $days = (int) now()->startOfDay()->diffInDays($this->edd->startOfDay(), false); if ($days > 0) return "$days Hari Lagi"; if ($days === 0) return "Prediksi Lahir Hari Ini"; return "Overdue " . abs($days) . " Hari"; } ); } /** * Badge Status Modern */ protected function statusBadge(): Attribute { return Attribute::make( get: function () { $status = strtolower($this->status); return match($status) { 'proses' => 'Dipantau', 'berhasil' => 'Lahir', 'gagal' => 'Gagal', default => ''.$status.'', }; } ); } /** * PIC (Point of Contact) */ public function pic(): BelongsTo { // Pastikan kolom di tabel 'mattings' adalah 'user_id' // Jika kolomnya bernama 'pic_id', ganti 'user_id' menjadi 'pic_id' return $this->belongsTo(User::class, 'user_id')->withDefault([ 'name' => 'Sistem / Admin' ]); } }