Files
dashboard/backend/models/Mortality.js
T
Alberto-Audrix 32a36cceff
CI / lint-and-test (push) Canceled after 0s
first commit
2026-07-28 08:55:05 +07:00

144 lines
5.0 KiB
JavaScript

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;