feat: fix delete validation pending notification at rekam medis, tindakan and obat
This commit is contained in:
parent
cbcf4ad897
commit
12e190961c
|
|
@ -367,6 +367,14 @@ export class ObatService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async countObat() {
|
async countObat() {
|
||||||
return this.prisma.pemberian_obat.count();
|
return this.prisma.pemberian_obat.count({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ deleted_status: null },
|
||||||
|
{ deleted_status: 'DELETE_VALIDATION' },
|
||||||
|
{ deleted_status: { not: 'DELETED' } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -563,6 +563,11 @@ export class RekammedisService {
|
||||||
waktu_visit: {
|
waktu_visit: {
|
||||||
gte: sevenDaysAgo,
|
gte: sevenDaysAgo,
|
||||||
},
|
},
|
||||||
|
OR: [
|
||||||
|
{ deleted_status: null },
|
||||||
|
{ deleted_status: 'DELETE_VALIDATION' },
|
||||||
|
{ deleted_status: { not: 'DELETED' } },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
_count: {
|
_count: {
|
||||||
id_visit: true,
|
id_visit: true,
|
||||||
|
|
@ -596,6 +601,14 @@ export class RekammedisService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async countRekamMedis() {
|
async countRekamMedis() {
|
||||||
return this.prisma.rekam_medis.count();
|
return this.prisma.rekam_medis.count({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ deleted_status: null },
|
||||||
|
{ deleted_status: 'DELETE_VALIDATION' },
|
||||||
|
{ deleted_status: { not: 'DELETED' } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,11 @@ export class TindakanDokterService {
|
||||||
kategori_tindakanArray.length > 0
|
kategori_tindakanArray.length > 0
|
||||||
? { in: kategori_tindakanArray }
|
? { in: kategori_tindakanArray }
|
||||||
: undefined,
|
: undefined,
|
||||||
|
OR: [
|
||||||
|
{ deleted_status: null },
|
||||||
|
{ deleted_status: 'DELETE_VALIDATION' },
|
||||||
|
{ deleted_status: { not: 'DELETED' } },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -411,6 +416,14 @@ export class TindakanDokterService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async countTindakanDokter() {
|
async countTindakanDokter() {
|
||||||
return this.prisma.pemberian_tindakan.count();
|
return this.prisma.pemberian_tindakan.count({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ deleted_status: null },
|
||||||
|
{ deleted_status: 'DELETE_VALIDATION' },
|
||||||
|
{ deleted_status: { not: 'DELETED' } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -221,19 +221,81 @@ export class ValidationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
determineIdType(tableName: string, recordId: string) {
|
||||||
|
if (tableName === 'rekam_medis') {
|
||||||
|
return recordId;
|
||||||
|
} else if (
|
||||||
|
tableName === 'pemberian_tindakan' ||
|
||||||
|
tableName === 'pemberian_obat'
|
||||||
|
) {
|
||||||
|
return Number(recordId); // numeric ID
|
||||||
|
} else {
|
||||||
|
throw new Error('Unsupported table for ID determination');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async rejectValidation(id: number, user: ActiveUserPayload) {
|
async rejectValidation(id: number, user: ActiveUserPayload) {
|
||||||
const validationQueue = await this.getValidationQueueById(id);
|
const validationQueue = await this.getValidationQueueById(id);
|
||||||
if (!validationQueue) {
|
if (!validationQueue) {
|
||||||
throw new Error('Validation queue not found');
|
throw new Error('Validation queue not found');
|
||||||
}
|
}
|
||||||
const updated = await this.prisma.validation_queue.update({
|
|
||||||
where: { id: validationQueue.id },
|
let recordId: number | string = '';
|
||||||
data: {
|
|
||||||
status: 'REJECTED',
|
if (
|
||||||
user_id_process: Number(user.sub),
|
validationQueue.status === 'PENDING' &&
|
||||||
processed_at: new Date(),
|
validationQueue.action === 'DELETE'
|
||||||
},
|
) {
|
||||||
});
|
recordId = this.determineIdType(
|
||||||
return updated;
|
validationQueue.table_name,
|
||||||
|
validationQueue.record_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rejectedResponse = await this.prisma.$transaction(async (tx) => {
|
||||||
|
let updatedDeleteStatus = null;
|
||||||
|
if (validationQueue.action === 'DELETE') {
|
||||||
|
switch (validationQueue.table_name) {
|
||||||
|
case 'rekam_medis':
|
||||||
|
updatedDeleteStatus = await tx.rekam_medis.update({
|
||||||
|
where: { id_visit: recordId as string },
|
||||||
|
data: { deleted_status: null },
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'pemberian_tindakan':
|
||||||
|
updatedDeleteStatus = await tx.pemberian_tindakan.update({
|
||||||
|
where: { id: recordId as number },
|
||||||
|
data: { deleted_status: null },
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'pemberian_obat':
|
||||||
|
updatedDeleteStatus = await tx.pemberian_obat.update({
|
||||||
|
where: { id: recordId as number },
|
||||||
|
data: { deleted_status: null },
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported table for delete rejection');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const updatedQueue = await tx.validation_queue.update({
|
||||||
|
where: { id: validationQueue.id },
|
||||||
|
data: {
|
||||||
|
status: 'REJECTED',
|
||||||
|
user_id_process: Number(user.sub),
|
||||||
|
processed_at: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
...updatedQueue,
|
||||||
|
updatedDeleteStatus,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return rejectedResponse;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error rejecting validation:', (error as Error).message);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ const hasUserIdProcessColumn = () =>
|
||||||
|
|
||||||
const formatCellValue = (item: T, columnKey: keyof T) => {
|
const formatCellValue = (item: T, columnKey: keyof T) => {
|
||||||
const value = item[columnKey];
|
const value = item[columnKey];
|
||||||
|
|
||||||
if (columnKey === "event" && typeof value === "string") {
|
if (columnKey === "event" && typeof value === "string") {
|
||||||
const segments = value.split("_");
|
const segments = value.split("_");
|
||||||
|
|
||||||
|
|
@ -123,10 +122,12 @@ const handleDeleteCancel = () => {
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:class="[
|
:class="[
|
||||||
'hover:bg-dark hover:text-light transition-colors',
|
'hover:bg-dark hover:text-light transition-colors',
|
||||||
(item as Record<string, any>).isTampered ? 'bg-red-300 text-dark' : ''
|
(item as Record<string, any>).isTampered ? 'bg-red-300 text-dark' : item.deleted_status ?
|
||||||
|
item.deleted_status === 'DELETE_VALIDATION' ? 'bg-yellow-100 text-dark' : 'bg-gray-300 text-dark' : '',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
|
v-if="item.deleted_status !== 'DELETE_VALIDATION'"
|
||||||
v-for="column in columns"
|
v-for="column in columns"
|
||||||
:key="String(column.key)"
|
:key="String(column.key)"
|
||||||
:class="[
|
:class="[
|
||||||
|
|
@ -147,6 +148,102 @@ const handleDeleteCancel = () => {
|
||||||
Review
|
Review
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</td>
|
</td>
|
||||||
|
<td
|
||||||
|
v-if="item.deleted_status === 'DELETE_VALIDATION'"
|
||||||
|
v-for="column in columns"
|
||||||
|
:key="String(column.key)"
|
||||||
|
:class="[
|
||||||
|
column.key === 'txId' || column.key === 'hash'
|
||||||
|
? 'font-mono overflow-hidden text-ellipsis max-w-10 hover:max-w-150 transition-all duration-500 ease-out text-xs'
|
||||||
|
: '',
|
||||||
|
hasStatusColumn() ? 'text-xs' : '',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
column.key === 'id_visit' &&
|
||||||
|
columns[2]?.key !== 'obat' &&
|
||||||
|
columns[2]?.key !== 'tindakan'
|
||||||
|
"
|
||||||
|
:class="[
|
||||||
|
column.key === 'id_visit' &&
|
||||||
|
(columns[2]?.key !== 'obat' || columns[2]?.key !== 'tindakan')
|
||||||
|
? 'tooltip tooltip-right flex items-center justify-center'
|
||||||
|
: '',
|
||||||
|
]"
|
||||||
|
data-tip="Data ini sedang dalam proses validasi untuk dihapus"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
:class="[
|
||||||
|
column.key === 'id_visit' ||
|
||||||
|
columns[2]?.key !== 'obat' ||
|
||||||
|
columns[2]?.key !== 'tindakan'
|
||||||
|
? 'inline-flex items-center gap-1'
|
||||||
|
: 'hidden',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
{{ formatCellValue(item, column.key) }}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="w-3 h-3 mt-1"
|
||||||
|
>
|
||||||
|
<circle cx="12" cy="12" r="10"></circle>
|
||||||
|
<path d="M12 16v-4"></path>
|
||||||
|
<path d="M12 8h.01"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
column.key === 'id' &&
|
||||||
|
(columns[2]?.key === 'obat' || columns[2]?.key === 'tindakan')
|
||||||
|
"
|
||||||
|
:class="[
|
||||||
|
column.key === 'id' &&
|
||||||
|
(columns[2]?.key === 'obat' || columns[2]?.key === 'tindakan')
|
||||||
|
? 'tooltip tooltip-right flex items-center'
|
||||||
|
: '',
|
||||||
|
]"
|
||||||
|
data-tip="Data ini sedang dalam proses validasi untuk dihapus"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
:class="[
|
||||||
|
column.key === 'id' ||
|
||||||
|
columns[2]?.key === 'obat' ||
|
||||||
|
columns[2]?.key === 'tindakan'
|
||||||
|
? 'inline-flex items-center gap-1'
|
||||||
|
: 'hidden',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
{{ formatCellValue(item, column.key) }}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="w-3 h-3 mt-1"
|
||||||
|
>
|
||||||
|
<circle cx="12" cy="12" r="10"></circle>
|
||||||
|
<path d="M12 16v-4"></path>
|
||||||
|
<path d="M12 8h.01"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{
|
||||||
|
column.key !== columns[0]?.key
|
||||||
|
? formatCellValue(item, column.key)
|
||||||
|
: ""
|
||||||
|
}}
|
||||||
|
</td>
|
||||||
<td v-if="!hasStatusColumn()">
|
<td v-if="!hasStatusColumn()">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<!-- Details Button -->
|
<!-- Details Button -->
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user