120 lines
4.6 KiB
JavaScript
120 lines
4.6 KiB
JavaScript
const { query, toISODate, parseISODate } = require('../database/db');
|
|
|
|
class Cycle {
|
|
static async getAll() {
|
|
try {
|
|
const result = await query('SELECT * FROM cycles ORDER BY start_date DESC', []);
|
|
return result.rows.map(this.formatCycle);
|
|
} catch (error) {
|
|
console.error('Error getting all cycles:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async getById(id) {
|
|
try {
|
|
const result = await query('SELECT * FROM cycles WHERE id = $1', [id]);
|
|
if (result.rows.length === 0) return null;
|
|
return this.formatCycle(result.rows[0]);
|
|
} catch (error) {
|
|
console.error('Error getting cycle by ID:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async create(cycleData) {
|
|
try {
|
|
const { id, totalDays, currentDay, startDate, endDate, chickInWeight, docInCount, status } = cycleData;
|
|
await query('INSERT INTO cycles (id, total_days, current_day, start_date, end_date, chick_in_weight, doc_in_count, status) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)', [id, totalDays, currentDay, toISODate(startDate), toISODate(endDate), chickInWeight || null, docInCount || null, status]);
|
|
return this.getById(id);
|
|
} catch (error) {
|
|
console.error('Error creating cycle:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async update(id, cycleData) {
|
|
try {
|
|
const { totalDays, currentDay, startDate, endDate, chickInWeight, docInCount, status } = cycleData;
|
|
const result = await query('UPDATE cycles SET total_days = $1, current_day = $2, start_date = $3, end_date = $4, chick_in_weight = $5, doc_in_count = $6, status = $7, updated_at = CURRENT_TIMESTAMP WHERE id = $8', [totalDays, currentDay, toISODate(startDate), toISODate(endDate), chickInWeight || null, docInCount || null, status, id]);
|
|
if (result.rowCount === 0) return null;
|
|
return this.getById(id);
|
|
} catch (error) {
|
|
console.error('Error updating cycle:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async delete(id) {
|
|
try {
|
|
const result = await query('DELETE FROM cycles WHERE id = $1', [id]);
|
|
return result.rowCount > 0;
|
|
} catch (error) {
|
|
console.error('Error deleting cycle:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async getActive() {
|
|
try {
|
|
const result = await query("SELECT * FROM cycles WHERE status = 'Active' LIMIT 1", []);
|
|
if (result.rows.length === 0) return null;
|
|
return this.formatCycle(result.rows[0]);
|
|
} catch (error) {
|
|
console.error('Error getting active cycle:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async markAllActiveAsCompleted() {
|
|
try {
|
|
const result = await query(
|
|
"UPDATE cycles SET status = 'Completed', updated_at = CURRENT_TIMESTAMP WHERE status = 'Active'",
|
|
[]
|
|
);
|
|
return result;
|
|
} catch (error) {
|
|
console.error('Error marking active cycles as completed:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static formatCycle(cycle) {
|
|
// Calculate current day dynamically based on start_date
|
|
let calculatedCurrentDay = cycle.current_day;
|
|
|
|
if (cycle.status === 'Active' && cycle.start_date) {
|
|
const startDate = new Date(cycle.start_date);
|
|
const today = new Date();
|
|
|
|
// Reset time to midnight for accurate day calculation
|
|
startDate.setHours(0, 0, 0, 0);
|
|
today.setHours(0, 0, 0, 0);
|
|
|
|
// Calculate days difference
|
|
const diffMs = today - startDate;
|
|
const daysDiff = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
|
|
// 0-based day index: day 0 = startDate, last day = startDate + (totalDays - 1)
|
|
// Cap at totalDays - 1 so currentDay never maps past Estimasi Panen / end_date
|
|
const lastDayIndex = Math.max(0, cycle.total_days - 1);
|
|
calculatedCurrentDay = Math.min(daysDiff, lastDayIndex);
|
|
}
|
|
|
|
return {
|
|
id: cycle.id,
|
|
totalDays: cycle.total_days,
|
|
currentDay: calculatedCurrentDay, // Use dynamically calculated day for active cycles
|
|
startDate: cycle.start_date,
|
|
endDate: cycle.end_date,
|
|
chickInWeight: cycle.chick_in_weight,
|
|
docInCount: cycle.doc_in_count,
|
|
status: cycle.status,
|
|
createdAt: cycle.created_at,
|
|
updatedAt: cycle.updated_at
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = Cycle;
|