Add uncollect feature and security improvements
- Add DELETE /api/samples/collect/:accessnumber/:samplenumber endpoint - Convert SQL queries to parameterized queries for security - Add uncollect() method to SamplesController - Update collect view to support uncollecting samples - Fix checkbox logic to allow toggling collected samples - Update hasChanges() to detect both collect and uncollect actions
This commit is contained in:
parent
ee68d22d15
commit
c2d66d0082
@ -52,6 +52,7 @@ $routes->get('(:any)/audit', 'ApiRequestsAuditController::show/$1');
|
||||
// Collect & Show - All Roles
|
||||
$routes->group('', ['filter' => 'role:0,1,2,3,4'], function ($routes) {
|
||||
$routes->post('collect/(:any)/(:any)', 'SamplesController::collect/$1/$2');
|
||||
$routes->delete('collect/(:any)/(:any)', 'SamplesController::uncollect/$1/$2');
|
||||
$routes->get('(:any)', 'SamplesController::show/$1');
|
||||
});
|
||||
|
||||
|
||||
@ -68,14 +68,26 @@ class SamplesController extends BaseController
|
||||
{
|
||||
$db = \Config\Database::connect();
|
||||
$userid = session('userid');
|
||||
$sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='1', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'";
|
||||
$db->query($sql);
|
||||
$sql = "update GDC_CMOD.dbo.TUBES set USERID=?, STATUS='1', COLLECTIONDATE=getdate() where ACCESSNUMBER=? and TUBENUMBER=?";
|
||||
$db->query($sql, [$userid, $accessnumber, $samplenumber]);
|
||||
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
||||
VALUES ('$accessnumber', '$samplenumber', '$userid', '1', getdate())";
|
||||
$db->query($sql);
|
||||
VALUES (?, ?, ?, '1', getdate())";
|
||||
$db->query($sql, [$accessnumber, $samplenumber, $userid]);
|
||||
return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
|
||||
}
|
||||
|
||||
public function uncollect($accessnumber, $samplenumber)
|
||||
{
|
||||
$db = \Config\Database::connect();
|
||||
$userid = session('userid');
|
||||
$sql = "update GDC_CMOD.dbo.TUBES set STATUS='0', COLLECTIONDATE=NULL where ACCESSNUMBER=? and TUBENUMBER=?";
|
||||
$db->query($sql, [$accessnumber, $samplenumber]);
|
||||
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
||||
VALUES (?, ?, ?, '0', getdate())";
|
||||
$db->query($sql, [$accessnumber, $samplenumber, $userid]);
|
||||
return $this->respond(['status' => 'success', 'message' => 'Sample uncollected successfully', 'data' => "$accessnumber-$samplenumber"], 200);
|
||||
}
|
||||
|
||||
public function unreceive($accessnumber, $samplenumber)
|
||||
{
|
||||
$db = \Config\Database::connect();
|
||||
|
||||
@ -100,13 +100,11 @@ $roleConfig = $config['phlebo'];
|
||||
</thead>
|
||||
<tbody>
|
||||
<template x-for="sample in samples" :key="sample.sampcode">
|
||||
<tr :class="sample.colstatus == 1 ? 'bg-success/10' : (sample.selected ? 'bg-warning/10' : '')">
|
||||
<tr :class="sample.selected ? (sample.colstatus == 1 ? 'bg-success/10' : 'bg-warning/10') : ''">
|
||||
<td class="text-center p-2">
|
||||
<input type="checkbox"
|
||||
class="checkbox checkbox-xs checkbox-primary"
|
||||
x-model="sample.selected"
|
||||
:checked="sample.colstatus == 1"
|
||||
:disabled="sample.colstatus == 1">
|
||||
x-model="sample.selected">
|
||||
</td>
|
||||
<td class="font-mono text-xs p-2" x-text="sample.sampcode"></td>
|
||||
<td class="text-xs p-2" x-text="sample.name"></td>
|
||||
@ -141,7 +139,7 @@ $roleConfig = $config['phlebo'];
|
||||
</button>
|
||||
<button class="btn btn-sm btn-primary"
|
||||
@click="saveCollection()"
|
||||
:disabled="isSaving || !hasSelectedSamples()"
|
||||
:disabled="isSaving || !hasChanges()"
|
||||
:class="isSaving ? 'loading' : ''">
|
||||
<i class="fa fa-save mr-1" x-show="!isSaving"></i>
|
||||
<span x-text="isSaving ? 'Saving' : 'Save'"></span>
|
||||
@ -227,6 +225,12 @@ $roleConfig = $config['phlebo'];
|
||||
return this.samples.some(s => s.selected && s.colstatus != 1);
|
||||
},
|
||||
|
||||
hasChanges() {
|
||||
const toCollect = this.samples.some(s => s.selected && s.colstatus != 1);
|
||||
const toUncollect = this.samples.some(s => !s.selected && s.colstatus == 1);
|
||||
return toCollect || toUncollect;
|
||||
},
|
||||
|
||||
hasUncollectedSamples() {
|
||||
return this.samples.some(s => s.colstatus != 1 && !s.selected);
|
||||
},
|
||||
@ -271,15 +275,17 @@ $roleConfig = $config['phlebo'];
|
||||
|
||||
try {
|
||||
const samplesToCollect = this.samples.filter(s => s.selected && s.colstatus != 1);
|
||||
const samplesToUncollect = this.samples.filter(s => !s.selected && s.colstatus == 1);
|
||||
|
||||
for (const sample of samplesToCollect) {
|
||||
await fetch(`${BASEURL}/api/samples/collect/${this.patient.accessnumber}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
samplenumber: sample.sampcode,
|
||||
userid: this.userid
|
||||
})
|
||||
await fetch(`${BASEURL}/api/samples/collect/${this.patient.accessnumber}/${sample.sampcode}`, {
|
||||
method: 'POST'
|
||||
});
|
||||
}
|
||||
|
||||
for (const sample of samplesToUncollect) {
|
||||
await fetch(`${BASEURL}/api/samples/collect/${this.patient.accessnumber}/${sample.sampcode}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
@ -287,10 +293,11 @@ $roleConfig = $config['phlebo'];
|
||||
await this.saveComment();
|
||||
}
|
||||
|
||||
this.showToast(`Collected ${samplesToCollect.length} sample(s)`, 'success');
|
||||
const totalChanged = samplesToCollect.length + samplesToUncollect.length;
|
||||
this.showToast(`Updated ${totalChanged} sample(s)`, 'success');
|
||||
|
||||
setTimeout(() => {
|
||||
this.resetForm();
|
||||
this.fetchPatientData();
|
||||
}, 1000);
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user