Add OSHA Form 301 and Osha page components
- Implemented Form301 component for displaying OSHA Form 301 equivalent, including employee and case information. - Created Osha component to manage OSHA recordkeeping, including tabs for 300 Log, 300A Summary, Hours & rates, and Submit to OSHA. - Added functionality for printing and downloading CSV files for OSHA submissions. - Integrated loading and error handling states for data fetching.
This commit is contained in:
1 parent
3e964d1176
commit
61c876edec
59 files changed
+9180
-183
No files matched your search
+27
-1
@@ -2,7 +2,8 @@ import { and, eq, inArray, isNotNull, isNull, lt, lte, ne, or } from 'drizzle-or
|
||||
import { incidentReference } from '../shared/format.ts'
|
||||
import type { Config } from './config.ts'
|
||||
import type { Db } from './db/client.ts'
|
||||
import { correctiveActions, incidents, users } from './db/schema.ts'
|
||||
import { OSHA_REPORTING_CONTACT, severeInjuryReport } from '../shared/osha.ts'
|
||||
import { correctiveActions, incidents, injuredPersons, users } from './db/schema.ts'
|
||||
import { addDays, localDate } from './lib/dates.ts'
|
||||
import type { Mailer } from './mail.ts'
|
||||
|
||||
@@ -93,6 +94,31 @@ export class Notifier {
|
||||
})
|
||||
}
|
||||
|
||||
/** 1904.39: fatalities must be reported to OSHA within 8 hours; hospitalizations, amputations and eye losses within 24. */
|
||||
severeInjury(caseId: string) {
|
||||
this.dispatch(async () => {
|
||||
const [row] = await this.db
|
||||
.select({ person: injuredPersons, incident: incidents })
|
||||
.from(injuredPersons)
|
||||
.innerJoin(incidents, eq(incidents.id, injuredPersons.incidentId))
|
||||
.where(eq(injuredPersons.id, caseId))
|
||||
const report = row && severeInjuryReport(row.person)
|
||||
if (!report) return
|
||||
const recipients = await this.db
|
||||
.select({ email: users.email })
|
||||
.from(users)
|
||||
.where(and(eq(users.organizationId, row.incident.organizationId), eq(users.active, true), inArray(users.role, ['safety_manager', 'admin'])))
|
||||
const reference = incidentReference(row.incident.number)
|
||||
for (const { email } of recipients) {
|
||||
await this.mailer.send({
|
||||
to: email,
|
||||
subject: `Report to OSHA within ${report.withinHours} hours: ${reference}`,
|
||||
text: `${reference} (${row.incident.title}) was recorded with: ${report.reasons.join(', ')}. OSHA requires a direct report within ${report.withinHours} hours of learning about it (29 CFR 1904.39).\n\n${OSHA_REPORTING_CONTACT}\n\nAfter reporting, record the date and time on the case: ${this.link(`/incidents/${row.incident.number}`)}`,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
actionAssigned(actionId: string, assignedBy: string) {
|
||||
this.dispatch(async () => {
|
||||
const [row] = await this.db
|
||||
|
||||
Reference in new issue
Block a user