financial data entry
Build and Push Docker Image / build (push) Successful in 1m4s

This commit is contained in:
2026-05-11 12:04:34 -05:00
parent 5a2b581c71
commit 3220ee70c4
7 changed files with 20 additions and 7 deletions
+1 -1
View File
@@ -82,7 +82,7 @@ The following fields on `violations` are locked after submission. They are the b
- `prior_active_points` (snapshot at insert time)
- `prior_tier_label`
Amendable fields (non-scoring): `location`, `details`, `witness_name`, `acknowledged_by`, `acknowledged_date`
Amendable fields (non-scoring): `incident_time`, `location`, `details`, `submitted_by`, `witness_name`, `acknowledged_by`, `acknowledged_date`, `amount`
### Soft-Delete Pattern
@@ -7,6 +7,7 @@ const FIELD_LABELS = {
details: 'Incident Notes',
submitted_by: 'Submitted By',
witness_name: 'Witness / Documenting Officer',
amount: 'Amount in Question',
};
const s = {
@@ -84,6 +85,7 @@ export default function AmendViolationModal({ violation, onClose, onSaved }) {
details: violation.details || '',
submitted_by: violation.submitted_by || '',
witness_name: violation.witness_name || '',
amount: violation.amount || '',
});
const [changedBy, setChangedBy] = useState('');
const [saving, setSaving] = useState(false);
+1 -1
View File
@@ -36,7 +36,6 @@ const s = {
const EMPTY_FORM = {
employeeId: '', employeeName: '', department: '', supervisor: '', witnessName: '',
violationType: '', incidentDate: '', incidentTime: '',
// TODO [MAJOR #6]: `amount` and `minutesLate` are rendered but never sent to the API
amount: '', minutesLate: '', location: '', additionalDetails: '', points: 1,
acknowledgedBy: '', acknowledgedDate: '',
};
@@ -159,6 +158,7 @@ export default function ViolationForm() {
witness_name: form.witnessName || null,
acknowledged_by: form.acknowledgedBy || null,
acknowledged_date: form.acknowledgedDate || null,
amount: form.amount || null,
});
const newId = violRes.data.id;
+2
View File
@@ -21,6 +21,8 @@ if (!cols.includes('prior_active_points')) db.exec("ALTER TABLE violations ADD C
if (!cols.includes('prior_tier_label')) db.exec("ALTER TABLE violations ADD COLUMN prior_tier_label TEXT");
if (!cols.includes('acknowledged_by')) db.exec("ALTER TABLE violations ADD COLUMN acknowledged_by TEXT");
if (!cols.includes('acknowledged_date')) db.exec("ALTER TABLE violations ADD COLUMN acknowledged_date TEXT");
// Financial amount in question (record-keeping / repayment for chargeback, receipt negligence, etc.)
if (!cols.includes('amount')) db.exec("ALTER TABLE violations ADD COLUMN amount TEXT");
// Employee notes column (free-text, does not affect scoring)
const empCols = db.prepare('PRAGMA table_info(employees)').all().map(c => c.name);
+1
View File
@@ -25,6 +25,7 @@ CREATE TABLE IF NOT EXISTS violations (
prior_tier_label TEXT, -- optional human-readable tier
acknowledged_by TEXT, -- employee name who acknowledged receipt
acknowledged_date TEXT, -- date of acknowledgment (YYYY-MM-DD)
amount TEXT, -- dollar amount in question for financial violations (record-keeping / repayment)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
+5
View File
@@ -243,6 +243,11 @@ function buildHtml(v, score) {
<div class="field-label">Submitted By</div>
<div class="field-value">${v.submitted_by || 'System'}</div>
</div>
${v.amount ? `
<div class="field" style="grid-column: 1 / -1;">
<div class="field-label">Amount in Question</div>
<div class="field-value prominent">${v.amount}</div>
</div>` : ''}
${v.location ? `
<div class="field" style="grid-column: 1 / -1;">
<div class="field-label">Location / Context</div>
+8 -5
View File
@@ -266,7 +266,8 @@ app.post('/api/violations', (req, res) => {
employee_id, violation_type, violation_name, category,
points, incident_date, incident_time, location,
details, submitted_by, witness_name,
acknowledged_by, acknowledged_date
acknowledged_by, acknowledged_date,
amount
} = req.body;
if (!employee_id || !violation_type || !points || !incident_date) {
@@ -282,15 +283,17 @@ app.post('/api/violations', (req, res) => {
points, incident_date, incident_time, location,
details, submitted_by, witness_name,
prior_active_points,
acknowledged_by, acknowledged_date
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
acknowledged_by, acknowledged_date,
amount
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`).run(
employee_id, violation_type, violation_name || violation_type,
category || 'General', ptsInt, incident_date,
incident_time || null, location || null,
details || null, submitted_by || null, witness_name || null,
priorPts,
acknowledged_by || null, acknowledged_date || null
acknowledged_by || null, acknowledged_date || null,
amount || null
);
audit('violation_created', 'violation', result.lastInsertRowid, submitted_by, {
@@ -302,7 +305,7 @@ app.post('/api/violations', (req, res) => {
// ── Violation Amendment (edit) ───────────────────────────────────────────────
// PATCH /api/violations/:id/amend — edit mutable fields; logs a diff per changed field
const AMENDABLE_FIELDS = ['incident_time', 'location', 'details', 'submitted_by', 'witness_name', 'acknowledged_by', 'acknowledged_date'];
const AMENDABLE_FIELDS = ['incident_time', 'location', 'details', 'submitted_by', 'witness_name', 'acknowledged_by', 'acknowledged_date', 'amount'];
// Pre-build one prepared UPDATE statement per amendable field combination is not
// practical (2^n combos), so instead we validate columns against the static