commit
32a36cceff
444 files changed
+67186
No files matched your search
@@ -0,0 +1,135 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const Mortality = require('../models/Mortality');
|
||||
const { captureAuditLog, filterAuditFields } = require('../middleware/auditLogger');
|
||||
|
||||
router.get('/:cycleId', async (req, res) => {
|
||||
try {
|
||||
const kandangId = req.query.kandangId ? parseInt(req.query.kandangId, 10) : null;
|
||||
const records = await Mortality.getByCycle(req.params.cycleId, kandangId);
|
||||
res.json({ success: true, data: records });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// GET aggregated totals across all kandangs
|
||||
router.get('/:cycleId/totals', async (req, res) => {
|
||||
try {
|
||||
const totals = await Mortality.getTotalsByCycle(req.params.cycleId);
|
||||
res.json({ success: true, data: totals });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/:cycleId/:day', async (req, res) => {
|
||||
try {
|
||||
const day = parseInt(req.params.day, 10);
|
||||
if (isNaN(day)) return res.status(400).json({ success: false, error: 'Day must be a number' });
|
||||
const kandangId = req.query.kandangId ? parseInt(req.query.kandangId, 10) : null;
|
||||
const record = await Mortality.getByDay(req.params.cycleId, day, kandangId);
|
||||
if (!record) return res.status(404).json({ success: false, error: 'Mortality record not found' });
|
||||
res.json({ success: true, data: record });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/:cycleId/:day', async (req, res) => {
|
||||
try {
|
||||
const day = parseInt(req.params.day, 10);
|
||||
const { mortalityCount, chickenCount, kandangId, panen, keterangan, afkir, beratPanen } = req.body;
|
||||
|
||||
// Validation
|
||||
if (isNaN(day) || mortalityCount === undefined || mortalityCount < 0) {
|
||||
return res.status(400).json({ success: false, error: 'Invalid mortality count' });
|
||||
}
|
||||
if (afkir !== undefined && afkir < 0) {
|
||||
return res.status(400).json({ success: false, error: 'Afkir must be non-negative' });
|
||||
}
|
||||
if (panen !== undefined && panen < 0) {
|
||||
return res.status(400).json({ success: false, error: 'Panen must be non-negative' });
|
||||
}
|
||||
if (beratPanen !== undefined && beratPanen < 0) {
|
||||
return res.status(400).json({ success: false, error: 'Berat panen must be non-negative' });
|
||||
}
|
||||
if (keterangan && keterangan.length > 200) {
|
||||
return res.status(400).json({ success: false, error: 'Keterangan must be 200 characters or less' });
|
||||
}
|
||||
|
||||
const parsedKandangId = kandangId ? parseInt(kandangId, 10) : null;
|
||||
const parsedAfkir = afkir !== undefined ? parseInt(afkir, 10) : 0;
|
||||
const parsedPanen = panen !== undefined ? parseInt(panen, 10) : 0;
|
||||
const parsedBeratPanen = beratPanen !== undefined ? parseFloat(beratPanen) : 0;
|
||||
const parsedKeterangan = keterangan || null;
|
||||
|
||||
if (beratPanen !== undefined && Number.isNaN(parsedBeratPanen)) {
|
||||
return res.status(400).json({ success: false, error: 'Berat panen must be a number' });
|
||||
}
|
||||
|
||||
// Fetch old record for audit logging
|
||||
const oldRecord = await Mortality.getByDay(req.params.cycleId, day, parsedKandangId);
|
||||
const isCreate = !oldRecord;
|
||||
|
||||
// Perform update/insert
|
||||
const record = await Mortality.upsert(
|
||||
req.params.cycleId,
|
||||
day,
|
||||
mortalityCount,
|
||||
true,
|
||||
chickenCount,
|
||||
parsedKandangId,
|
||||
parsedPanen,
|
||||
parsedKeterangan,
|
||||
parsedAfkir,
|
||||
parsedBeratPanen
|
||||
);
|
||||
|
||||
// Capture audit log
|
||||
const recordId = `${req.params.cycleId}-${day}${parsedKandangId ? `-${parsedKandangId}` : ''}`;
|
||||
await captureAuditLog(
|
||||
'mortality_records',
|
||||
recordId,
|
||||
isCreate ? 'CREATE' : 'UPDATE',
|
||||
isCreate ? null : filterAuditFields(oldRecord),
|
||||
filterAuditFields(record)
|
||||
);
|
||||
|
||||
res.json({ success: true, data: record });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete('/:cycleId/:day', async (req, res) => {
|
||||
try {
|
||||
const day = parseInt(req.params.day, 10);
|
||||
if (isNaN(day)) return res.status(400).json({ success: false, error: 'Day must be a number' });
|
||||
const kandangId = req.query.kandangId ? parseInt(req.query.kandangId, 10) : null;
|
||||
|
||||
// Fetch record before deleting for audit log
|
||||
const oldRecord = await Mortality.getByDay(req.params.cycleId, day, kandangId);
|
||||
|
||||
const deleted = await Mortality.delete(req.params.cycleId, day, kandangId);
|
||||
if (!deleted) return res.status(404).json({ success: false, error: 'Mortality record not found' });
|
||||
|
||||
// Capture audit log
|
||||
if (oldRecord) {
|
||||
const recordId = `${req.params.cycleId}-${day}${kandangId ? `-${kandangId}` : ''}`;
|
||||
await captureAuditLog(
|
||||
'mortality_records',
|
||||
recordId,
|
||||
'DELETE',
|
||||
filterAuditFields(oldRecord),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
res.json({ success: true, message: 'Mortality record deleted successfully' });
|
||||
} catch (error) {
|
||||
res.status(500).json({ success: false, error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in new issue
Block a user