91 lines
3.2 KiB
JavaScript
91 lines
3.2 KiB
JavaScript
const db = require('../db/models');
|
|
const { ValidationError } = require('../helpers');
|
|
const { Logger } = require('./logger');
|
|
|
|
class Appeal_draftsService {
|
|
static async create(data, currentUser) {
|
|
if (!data.caseId) {
|
|
throw new ValidationError('caseIdRequired', 'Case ID is required');
|
|
}
|
|
|
|
// Auth: current user org must match case org
|
|
const cases = await db.cases.findByPk(data.caseId);
|
|
if (!cases || (cases.organizationId !== currentUser.organizationId && !currentUser.app_role.globalAccess)) {
|
|
throw new ValidationError('accessDenied', 'Cannot create draft for this case');
|
|
}
|
|
|
|
// Versioning
|
|
const maxVersionDraft = await db.appeal_drafts.findOne({
|
|
where: { caseId: data.caseId },
|
|
order: [['version', 'DESC']]
|
|
});
|
|
|
|
data.version = (maxVersionDraft ? maxVersionDraft.version : 0) + 1;
|
|
data.organizationId = currentUser.organizationId;
|
|
data.status = 'draft';
|
|
|
|
const draft = await db.appeal_drafts.create(data);
|
|
await Logger.log(currentUser, 'appeal_drafts', draft.id, 'Draft created', { version: data.version });
|
|
return draft;
|
|
}
|
|
|
|
static async update(data, id, currentUser) {
|
|
const draft = await db.appeal_drafts.findByPk(id);
|
|
if (!draft) {
|
|
throw new ValidationError('draftNotFound', 'Draft not found');
|
|
}
|
|
|
|
if (draft.status === 'submitted') {
|
|
throw new ValidationError('draftIsReadOnly', 'Submitted drafts are read-only');
|
|
}
|
|
|
|
const isSubmitting = data.status === 'submitted';
|
|
|
|
if (isSubmitting) {
|
|
// Role check: Only case owner or admin can submit appeal
|
|
const cases = await db.cases.findByPk(draft.caseId);
|
|
const isAdmin = currentUser.app_role.name === 'admin' || currentUser.app_role.globalAccess;
|
|
const isOwner = cases.owner_userId === currentUser.id;
|
|
|
|
if (!isOwner && !isAdmin) {
|
|
throw new ValidationError('accessDenied', 'Only the case owner or an administrator can submit an appeal');
|
|
}
|
|
|
|
// Only one draft can be submitted per case
|
|
const existingSubmitted = await db.appeal_drafts.findOne({
|
|
where: { caseId: draft.caseId, status: 'submitted' }
|
|
});
|
|
|
|
if (existingSubmitted) {
|
|
throw new ValidationError('alreadySubmitted', 'Another draft is already submitted for this case');
|
|
}
|
|
|
|
data.submitted_at = new Date();
|
|
data.submittedByUserId = currentUser.id;
|
|
|
|
// Sync case status
|
|
const CasesService = require('./cases');
|
|
await CasesService.update({ status: 'submitted', submitted_at: data.submitted_at }, draft.caseId, currentUser);
|
|
}
|
|
|
|
await db.appeal_drafts.update(data, { where: { id } });
|
|
return await db.appeal_drafts.findByPk(id);
|
|
}
|
|
|
|
static async deleteByIds(ids, currentUser) {
|
|
for (const id of ids) {
|
|
const draft = await db.appeal_drafts.findByPk(id);
|
|
if (draft && draft.status === 'submitted') {
|
|
throw new ValidationError('cannotDeleteSubmittedDraft', 'Cannot delete submitted drafts');
|
|
}
|
|
}
|
|
return await db.appeal_drafts.destroy({ where: { id: ids } });
|
|
}
|
|
|
|
static async remove(id, currentUser) {
|
|
return this.deleteByIds([id], currentUser);
|
|
}
|
|
}
|
|
|
|
module.exports = Appeal_draftsService;
|