const { query } = require('../database/db'); class Mortality { static async getByCycle(cycleId, kandangId = null) { let sql = 'SELECT * FROM mortality_records WHERE cycle_id = $1'; const params = [cycleId]; if (kandangId !== null && kandangId !== undefined) { sql += ' AND kandang_id = $2'; params.push(kandangId); } sql += ' ORDER BY day'; const result = await query(sql, params); return result.rows.map(this.formatRecord); } static async getByDay(cycleId, day, kandangId = null) { let sql = 'SELECT * FROM mortality_records WHERE cycle_id = $1 AND day = $2'; const params = [cycleId, day]; if (kandangId !== null && kandangId !== undefined) { sql += ' AND kandang_id = $3'; params.push(kandangId); } else { sql += ' AND kandang_id IS NULL'; } const result = await query(sql, params); if (result.rows.length === 0) return null; return this.formatRecord(result.rows[0]); } static async upsert( cycleId, day, mortalityCount, isEdited = true, chickenCount = null, kandangId = null, panen = 0, keterangan = null, afkir = 0, beratPanen = 0 ) { try { const sql = ` INSERT INTO mortality_records (cycle_id, day, mortality_count, chicken_count, kandang_id, is_edited, afkir, panen, berat_panen, keterangan, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, CURRENT_TIMESTAMP) ON CONFLICT (cycle_id, day, COALESCE(kandang_id, -1)) DO UPDATE SET mortality_count = EXCLUDED.mortality_count, chicken_count = EXCLUDED.chicken_count, is_edited = EXCLUDED.is_edited, afkir = EXCLUDED.afkir, panen = EXCLUDED.panen, berat_panen = EXCLUDED.berat_panen, keterangan = EXCLUDED.keterangan, updated_at = CURRENT_TIMESTAMP `; await query(sql, [ cycleId, day, mortalityCount, chickenCount, kandangId, isEdited ? 1 : 0, afkir, panen, beratPanen, keterangan ]); return this.getByDay(cycleId, day, kandangId); } catch (error) { console.error('Error upserting mortality record:', error); throw error; } } static async delete(cycleId, day, kandangId = null) { try { let sql = 'DELETE FROM mortality_records WHERE cycle_id = $1 AND day = $2'; const params = [cycleId, day]; if (kandangId !== null && kandangId !== undefined) { sql += ' AND kandang_id = $3'; params.push(kandangId); } else { sql += ' AND kandang_id IS NULL'; } const result = await query(sql, params); return result.rowCount > 0; } catch (error) { console.error('Error deleting mortality record:', error); throw error; } } // Get totals aggregated across all kandangs for a cycle static async getTotalsByCycle(cycleId) { const result = await query(` SELECT day, SUM(mortality_count) as total_mortality, SUM(afkir) as total_afkir, SUM(chicken_count) as total_chicken_count, SUM(panen) as total_panen, SUM(berat_panen) as total_berat_panen FROM mortality_records WHERE cycle_id = $1 GROUP BY day ORDER BY day `, [cycleId]); return result.rows.map(row => ({ day: row.day, mortalityCount: parseInt(row.total_mortality) || 0, afkir: parseInt(row.total_afkir) || 0, chickenCount: row.total_chicken_count ? parseInt(row.total_chicken_count) : null, panen: parseInt(row.total_panen) || 0, beratPanen: row.total_berat_panen ? parseFloat(row.total_berat_panen) : 0 })); } static formatRecord(record) { return { id: record.id, cycleId: record.cycle_id, day: record.day, mortalityCount: record.mortality_count, chickenCount: record.chicken_count, population: record.population, kandangId: record.kandang_id, isEdited: Boolean(record.is_edited), afkir: record.afkir || 0, panen: record.panen || 0, beratPanen: record.berat_panen ? parseFloat(record.berat_panen) : 0, keterangan: record.keterangan || '', createdAt: record.created_at, updatedAt: record.updated_at }; } } module.exports = Mortality;