161 lines
5.3 KiB
TypeScript
161 lines
5.3 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { DataSource } from 'typeorm';
|
|
import { administrationAuditContext } from '../administration/common/administration-audit';
|
|
import { AuditService } from '../audit/audit.service';
|
|
import type { AuthPrincipal, RequestWithContext } from '../common/http/request-context';
|
|
import { AuditAction } from '../database/entities';
|
|
import type { UpdateDeadlinePolicyDto, UpsertBusinessCalendarDayDto } from './dto/update-deadline-policy.dto';
|
|
|
|
@Injectable()
|
|
export class InspectionDeadlineAdminService {
|
|
constructor(
|
|
private readonly dataSource: DataSource,
|
|
private readonly audit: AuditService,
|
|
) {}
|
|
|
|
async policy() {
|
|
const [row] = await this.dataSource.query(`
|
|
SELECT id,
|
|
urgent_days AS "urgentDays",
|
|
urgent_day_type AS "urgentDayType",
|
|
non_urgent_days AS "nonUrgentDays",
|
|
non_urgent_day_type AS "nonUrgentDayType",
|
|
updated_by AS "updatedBy",
|
|
updated_at AS "updatedAt"
|
|
FROM inspection_deadline_policies
|
|
ORDER BY created_at
|
|
LIMIT 1
|
|
`);
|
|
return row ?? {
|
|
urgentDays: 5,
|
|
urgentDayType: 'BUSINESS',
|
|
nonUrgentDays: 10,
|
|
nonUrgentDayType: 'BUSINESS',
|
|
};
|
|
}
|
|
|
|
async updatePolicy(
|
|
dto: UpdateDeadlinePolicyDto,
|
|
principal: AuthPrincipal,
|
|
request: RequestWithContext,
|
|
) {
|
|
const before = await this.policy();
|
|
const [existing] = await this.dataSource.query(`
|
|
SELECT id FROM inspection_deadline_policies ORDER BY created_at LIMIT 1
|
|
`) as Array<{ id: string }>;
|
|
if (existing) {
|
|
await this.dataSource.query(`
|
|
UPDATE inspection_deadline_policies
|
|
SET urgent_days=$2,
|
|
urgent_day_type=$3,
|
|
non_urgent_days=$4,
|
|
non_urgent_day_type=$5,
|
|
updated_by=$6,
|
|
updated_at=CURRENT_TIMESTAMP
|
|
WHERE id=$1
|
|
`, [
|
|
existing.id,
|
|
dto.urgentDays,
|
|
dto.urgentDayType,
|
|
dto.nonUrgentDays,
|
|
dto.nonUrgentDayType,
|
|
principal.userId,
|
|
]);
|
|
} else {
|
|
await this.dataSource.query(`
|
|
INSERT INTO inspection_deadline_policies(
|
|
urgent_days,urgent_day_type,non_urgent_days,non_urgent_day_type,updated_by
|
|
) VALUES($1,$2,$3,$4,$5)
|
|
`, [
|
|
dto.urgentDays,
|
|
dto.urgentDayType,
|
|
dto.nonUrgentDays,
|
|
dto.nonUrgentDayType,
|
|
principal.userId,
|
|
]);
|
|
}
|
|
const after = await this.policy();
|
|
await this.audit.record({
|
|
...administrationAuditContext(principal, request),
|
|
action: AuditAction.INSPECTION_DEADLINE_POLICY_UPDATED,
|
|
entityType: 'inspection_deadline_policy',
|
|
entityId: String((after as { id?: string }).id ?? 'singleton'),
|
|
beforeData: before as Record<string, unknown>,
|
|
afterData: after as Record<string, unknown>,
|
|
metadata: {
|
|
appliesOnlyToFutureLockedActs: true,
|
|
historicalActsKeepSnapshot: true,
|
|
},
|
|
});
|
|
return after;
|
|
}
|
|
|
|
async calendar() {
|
|
const data = await this.dataSource.query(`
|
|
SELECT id,date,is_business_day AS "isBusinessDay",label,
|
|
updated_by AS "updatedBy",created_at AS "createdAt",updated_at AS "updatedAt"
|
|
FROM inspection_business_calendar_days
|
|
ORDER BY date
|
|
`);
|
|
return { data };
|
|
}
|
|
|
|
async upsertCalendarDay(
|
|
dto: UpsertBusinessCalendarDayDto,
|
|
principal: AuthPrincipal,
|
|
request: RequestWithContext,
|
|
) {
|
|
const [before] = await this.dataSource.query(`
|
|
SELECT id,date,is_business_day AS "isBusinessDay",label
|
|
FROM inspection_business_calendar_days WHERE date=$1::date
|
|
`, [dto.date]);
|
|
await this.dataSource.query(`
|
|
INSERT INTO inspection_business_calendar_days(date,is_business_day,label,updated_by)
|
|
VALUES($1::date,$2,$3,$4)
|
|
ON CONFLICT(date) DO UPDATE SET
|
|
is_business_day=EXCLUDED.is_business_day,
|
|
label=EXCLUDED.label,
|
|
updated_by=EXCLUDED.updated_by,
|
|
updated_at=CURRENT_TIMESTAMP
|
|
`, [dto.date, dto.isBusinessDay, dto.label, principal.userId]);
|
|
const [after] = await this.dataSource.query(`
|
|
SELECT id,date,is_business_day AS "isBusinessDay",label,
|
|
updated_by AS "updatedBy",updated_at AS "updatedAt"
|
|
FROM inspection_business_calendar_days WHERE date=$1::date
|
|
`, [dto.date]);
|
|
await this.audit.record({
|
|
...administrationAuditContext(principal, request),
|
|
action: AuditAction.INSPECTION_BUSINESS_CALENDAR_UPDATED,
|
|
entityType: 'inspection_business_calendar_day',
|
|
entityId: String(after.id),
|
|
beforeData: before ?? null,
|
|
afterData: after,
|
|
});
|
|
return after;
|
|
}
|
|
|
|
async removeCalendarDay(
|
|
date: string,
|
|
principal: AuthPrincipal,
|
|
request: RequestWithContext,
|
|
) {
|
|
const [before] = await this.dataSource.query(`
|
|
SELECT id,date,is_business_day AS "isBusinessDay",label
|
|
FROM inspection_business_calendar_days WHERE date=$1::date
|
|
`, [date]);
|
|
if (before) {
|
|
await this.dataSource.query(`DELETE FROM inspection_business_calendar_days WHERE id=$1`, [before.id]);
|
|
await this.audit.record({
|
|
...administrationAuditContext(principal, request),
|
|
action: AuditAction.INSPECTION_BUSINESS_CALENDAR_UPDATED,
|
|
entityType: 'inspection_business_calendar_day',
|
|
entityId: String(before.id),
|
|
beforeData: before,
|
|
afterData: null,
|
|
metadata: { removed: true },
|
|
});
|
|
}
|
|
return { removed: Boolean(before), date };
|
|
}
|
|
}
|