Done for now
This commit is contained in:
parent
7b1e5bbc13
commit
efdd28afbd
@ -1,4 +1,34 @@
|
|||||||
export default [
|
export default [
|
||||||
|
{
|
||||||
|
header: "Forensik",
|
||||||
|
description: "",
|
||||||
|
child: [
|
||||||
|
{
|
||||||
|
title: "FOR-01",
|
||||||
|
icon: "ph:number-circle-one-fill",
|
||||||
|
child: [
|
||||||
|
{
|
||||||
|
title: "Permohonan Temujanji",
|
||||||
|
path: "/permohonan-temujanji/senarai",
|
||||||
|
child: [],
|
||||||
|
meta: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Kaunter Semakan ",
|
||||||
|
path: "/kemaskini-daftar/senarai",
|
||||||
|
child: [],
|
||||||
|
meta: {},
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// title: "Kemaskini Daftar",
|
||||||
|
// path: "/kemaskini-daftar/senarai",
|
||||||
|
// child: [],
|
||||||
|
// meta: {},
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
header: "Utama",
|
header: "Utama",
|
||||||
description: "",
|
description: "",
|
||||||
@ -122,36 +152,7 @@ export default [
|
|||||||
],
|
],
|
||||||
meta: {},
|
meta: {},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
header: "Prototaip Forensik",
|
|
||||||
description: "",
|
|
||||||
child: [
|
|
||||||
{
|
|
||||||
title: "FOR-01",
|
|
||||||
icon: "ph:number-circle-one-fill",
|
|
||||||
child: [
|
|
||||||
{
|
|
||||||
title: "Permohonan Temujanji",
|
|
||||||
path: "/permohonan-temujanji/senarai",
|
|
||||||
child: [],
|
|
||||||
meta: {},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Kaunter Semakan ",
|
|
||||||
path: "/kemaskini-daftar/senarai",
|
|
||||||
child: [],
|
|
||||||
meta: {},
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// title: "Kemaskini Daftar",
|
|
||||||
// path: "/kemaskini-daftar/senarai",
|
|
||||||
// child: [],
|
|
||||||
// meta: {},
|
|
||||||
// },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
header: "Pengurusan",
|
header: "Pengurusan",
|
||||||
description: "",
|
description: "",
|
||||||
|
@ -159,7 +159,7 @@ const showTooltip = (codeId, message) => {
|
|||||||
}"
|
}"
|
||||||
:options-advanced="{
|
:options-advanced="{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
responsive: true,
|
|
||||||
filterable: false,
|
filterable: false,
|
||||||
}"
|
}"
|
||||||
advanced
|
advanced
|
||||||
@ -217,7 +217,7 @@ const showTooltip = (codeId, message) => {
|
|||||||
}"
|
}"
|
||||||
:options-advanced="{
|
:options-advanced="{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
responsive: true,
|
|
||||||
filterable: false,
|
filterable: false,
|
||||||
}"
|
}"
|
||||||
advanced
|
advanced
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
label="Ringkasan Kenyataan Kes"
|
label="Ringkasan Kenyataan Kes"
|
||||||
v-model="ringkasanKenyataanKes"
|
v-model="ringkasanKenyataanKes"
|
||||||
validation="required"
|
validation="required"
|
||||||
disabled
|
|
||||||
/>
|
/>
|
||||||
<FormKit
|
<FormKit
|
||||||
type="number"
|
type="number"
|
||||||
@ -55,72 +54,56 @@
|
|||||||
validation="required|number"
|
validation="required|number"
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
<FormKit
|
|
||||||
type="text"
|
<!-- Barang Section -->
|
||||||
label="Jenis Barang"
|
<div class="mb-4">
|
||||||
v-model="jenisBarang"
|
<h3 class="mb-2">Senarai Barang</h3>
|
||||||
validation="required"
|
<table
|
||||||
disabled
|
v-if="barangList.length > 0"
|
||||||
/>
|
class="w-full border-collapse border border-gray-300 mb-2"
|
||||||
<FormKit
|
>
|
||||||
type="text"
|
<thead>
|
||||||
label="Tanda Barang"
|
<tr class="bg-gray-100">
|
||||||
v-model="tandaBarang"
|
<th class="border border-gray-300 p-2">Jenis Barang</th>
|
||||||
validation="required"
|
<th class="border border-gray-300 p-2">Kuantiti</th>
|
||||||
disabled
|
</tr>
|
||||||
/>
|
</thead>
|
||||||
<FormKit
|
<tbody>
|
||||||
type="text"
|
<tr v-for="(barang, index) in barangList" :key="index">
|
||||||
label="Keadaan Barang"
|
<td class="border border-gray-300 p-2">
|
||||||
v-model="keadaanBarang"
|
{{
|
||||||
validation="required"
|
barang.jenisBarangDetailLabel
|
||||||
disabled
|
? barang.jenisBarangDetailLabel
|
||||||
/>
|
: barang.jenisBarangDetail
|
||||||
<FormKit
|
}}
|
||||||
type="number"
|
</td>
|
||||||
label="Kuantiti Barang"
|
<td class="border border-gray-300 p-2">
|
||||||
v-model="kuantitiBarang"
|
{{ barang.kuantitiBarang }}
|
||||||
validation="required|number"
|
</td>
|
||||||
disabled
|
</tr>
|
||||||
/>
|
</tbody>
|
||||||
<FormKit
|
</table>
|
||||||
type="select"
|
<div v-else class="text-gray-500 mb-2">Tiada barang ditambah</div>
|
||||||
label="Jenis Barang"
|
</div>
|
||||||
v-model="jenisBarangDetail"
|
|
||||||
:options="jenisBarangDetailOptions"
|
|
||||||
validation="required"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
<FormKit
|
|
||||||
type="select"
|
|
||||||
label="Jenis Barang Siber"
|
|
||||||
v-model="jenisBarangSiber"
|
|
||||||
:options="jenisBarangSiberOptions"
|
|
||||||
validation="required"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
<FormKit
|
<FormKit
|
||||||
type="text"
|
type="text"
|
||||||
label="No Kertas Siasatan"
|
label="No Kertas Siasatan"
|
||||||
v-model="noKertasSiasatan"
|
v-model="noKertasSiasatan"
|
||||||
disabled
|
|
||||||
/>
|
/>
|
||||||
<FormKit
|
<FormKit
|
||||||
type="text"
|
type="text"
|
||||||
label="No Laporan Polis"
|
label="No Laporan Polis"
|
||||||
v-model="noLaporanPolis"
|
v-model="noLaporanPolis"
|
||||||
disabled
|
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-end gap-2 mt-4">
|
<div class="flex justify-end gap-2 mt-4">
|
||||||
<rs-button type="button" @click="navi" variant="danger"
|
<rs-button type="button" @click="navigateBack" variant="danger"
|
||||||
>Kembali</rs-button
|
>Kembali</rs-button
|
||||||
>
|
>
|
||||||
<rs-button type="button" @click="confirmBatal" variant="primary"
|
<!-- <rs-button type="button" @click="confirmBatal" variant="primary"
|
||||||
>Tolak</rs-button
|
>Tolak</rs-button
|
||||||
>
|
> -->
|
||||||
<rs-button type="submit" @click="confirmSah" variant="success"
|
<rs-button btn-type="submit" variant="success">Hantar</rs-button>
|
||||||
>Sah</rs-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
</rs-card>
|
</rs-card>
|
||||||
@ -128,11 +111,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from "vue";
|
|
||||||
import { useRouter, useRoute } from "vue-router";
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const { $swal } = useNuxtApp();
|
||||||
|
|
||||||
const noSiri = ref(route.params.noSiri);
|
const noSiri = ref(route.params.noSiri);
|
||||||
|
|
||||||
@ -143,26 +124,11 @@ const namaPenghantar = ref("");
|
|||||||
const pangkatPenghantar = ref("");
|
const pangkatPenghantar = ref("");
|
||||||
const ringkasanKenyataanKes = ref("");
|
const ringkasanKenyataanKes = ref("");
|
||||||
const bilangan = ref(0);
|
const bilangan = ref(0);
|
||||||
const jenisBarang = ref("");
|
const barangList = ref([]);
|
||||||
const tandaBarang = ref("");
|
|
||||||
const keadaanBarang = ref("");
|
|
||||||
const kuantitiBarang = ref(0);
|
|
||||||
const jenisBarangDetail = ref("");
|
|
||||||
const jenisBarangSiber = ref("");
|
|
||||||
const noKertasSiasatan = ref("");
|
const noKertasSiasatan = ref("");
|
||||||
const noLaporanPolis = ref("");
|
const noLaporanPolis = ref("");
|
||||||
|
|
||||||
const jenisBarangDetailOptions = [
|
const jenisBarangDetailOptions = ref([]);
|
||||||
"PASPORT",
|
|
||||||
"MALPASS",
|
|
||||||
"CAP KESELAMATAN",
|
|
||||||
"CAP JARI",
|
|
||||||
"PEMERIKSAAN",
|
|
||||||
"I-KAD",
|
|
||||||
"LAIN-LAIN",
|
|
||||||
];
|
|
||||||
|
|
||||||
const jenisBarangSiberOptions = ["SIBER", "TULISAN TANGAN"];
|
|
||||||
|
|
||||||
const navigateBack = () => {
|
const navigateBack = () => {
|
||||||
router.back();
|
router.back();
|
||||||
@ -177,12 +143,6 @@ const isFormValid = () => {
|
|||||||
pangkatPenghantar,
|
pangkatPenghantar,
|
||||||
ringkasanKenyataanKes,
|
ringkasanKenyataanKes,
|
||||||
bilangan,
|
bilangan,
|
||||||
jenisBarang,
|
|
||||||
tandaBarang,
|
|
||||||
keadaanBarang,
|
|
||||||
kuantitiBarang,
|
|
||||||
jenisBarangDetail,
|
|
||||||
jenisBarangSiber,
|
|
||||||
noKertasSiasatan,
|
noKertasSiasatan,
|
||||||
noLaporanPolis,
|
noLaporanPolis,
|
||||||
];
|
];
|
||||||
@ -192,35 +152,38 @@ const isFormValid = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const simpan = () => {
|
const submitForm = async () => {
|
||||||
if (isFormValid()) {
|
if (isFormValid()) {
|
||||||
console.log("Form data saved");
|
try {
|
||||||
} else {
|
const response = await $fetch(`/api/kaunter-permohonan/${noSiri.value}`, {
|
||||||
console.error("Please fill in all required fields.");
|
method: "PUT",
|
||||||
}
|
body: {
|
||||||
};
|
ringkasanKenyataanKes: ringkasanKenyataanKes.value,
|
||||||
|
noKertasSiasatan: noKertasSiasatan.value,
|
||||||
|
noLaporanPolis: noLaporanPolis.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const submitForm = () => {
|
if (response.statusCode === 200) {
|
||||||
if (isFormValid()) {
|
await $swal.fire({
|
||||||
console.log({
|
title: "Berjaya!",
|
||||||
namaPemohon: namaPemohon.value,
|
text: "Permohonan telah berjaya dikemaskini.",
|
||||||
pangkatPemohon: pangkatPemohon.value,
|
icon: "success",
|
||||||
noPegawaiPemohon: noPegawaiPemohon.value,
|
confirmButtonText: "OK",
|
||||||
namaPenghantar: namaPenghantar.value,
|
});
|
||||||
pangkatPenghantar: pangkatPenghantar.value,
|
|
||||||
ringkasanKenyataanKes: ringkasanKenyataanKes.value,
|
|
||||||
bilangan: bilangan.value,
|
|
||||||
jenisBarang: jenisBarang.value,
|
|
||||||
tandaBarang: tandaBarang.value,
|
|
||||||
keadaanBarang: keadaanBarang.value,
|
|
||||||
kuantitiBarang: kuantitiBarang.value,
|
|
||||||
jenisBarangDetail: jenisBarangDetail.value,
|
|
||||||
jenisBarangSiber: jenisBarangSiber.value,
|
|
||||||
noKertasSiasatan: noKertasSiasatan.value,
|
|
||||||
noLaporanPolis: noLaporanPolis.value,
|
|
||||||
});
|
|
||||||
|
|
||||||
navigateTo(`/kemaskini-daftar/kemaskini/sah/${noSiri.value}`);
|
router.push("/kemaskini-daftar/senarai");
|
||||||
|
} else {
|
||||||
|
throw new Error(response.message);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire({
|
||||||
|
title: "Ralat!",
|
||||||
|
text: error.message || "Gagal mengemaskini permohonan. Sila cuba lagi.",
|
||||||
|
icon: "error",
|
||||||
|
confirmButtonText: "OK",
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$swal.fire({
|
$swal.fire({
|
||||||
title: "Ralat!",
|
title: "Ralat!",
|
||||||
@ -260,75 +223,64 @@ const confirmSah = () => {
|
|||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
submitForm();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateSampleData(noSiri) {
|
const fetchLookupData = async (type) => {
|
||||||
const randomNumber = (min, max) =>
|
try {
|
||||||
Math.floor(Math.random() * (max - min + 1) + min);
|
const response = await $fetch(`/api/lookup?type=${type}`);
|
||||||
const randomChoice = (arr) => arr[Math.floor(Math.random() * arr.length)];
|
if (response.statusCode === 200) {
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error fetching ${type} lookup data:`, error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const namaPemohon = [
|
const fetchExistingData = async (noSiri) => {
|
||||||
"Ali bin Abu",
|
try {
|
||||||
"Siti binti Ahmad",
|
const response = await $fetch(`/api/permohonan/${noSiri}`);
|
||||||
"Muthu a/l Rajan",
|
if (response.statusCode === 200) {
|
||||||
"Lim Wei Ling",
|
return response.data;
|
||||||
];
|
}
|
||||||
const pangkat = ["Inspektor", "Sarjan", "Koperal", "Konstabel"];
|
} catch (error) {
|
||||||
const jenisBarangOptions = [
|
console.error("Error fetching existing data:", error);
|
||||||
"Dokumen",
|
$swal.fire({
|
||||||
"Peralatan Elektronik",
|
title: "Ralat!",
|
||||||
"Senjata",
|
text: "Gagal mendapatkan data permohonan.",
|
||||||
"Dadah",
|
icon: "error",
|
||||||
"Barang Kemas",
|
confirmButtonText: "OK",
|
||||||
];
|
});
|
||||||
const keadaanBarangOptions = ["Baik", "Sederhana", "Rosak"];
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
onMounted(async () => {
|
||||||
noSiri: noSiri,
|
const existingData = await fetchExistingData(noSiri.value);
|
||||||
namaPemohon: randomChoice(namaPemohon),
|
|
||||||
pangkatPemohon: randomChoice(pangkat),
|
|
||||||
noPegawaiPemohon: `PG${randomNumber(10000, 99999)}`,
|
|
||||||
namaPenghantar: randomChoice(namaPemohon),
|
|
||||||
pangkatPenghantar: randomChoice(pangkat),
|
|
||||||
ringkasanKenyataanKes: `Kes ${noSiri}: Penemuan barang bukti dalam serbuan di lokasi ${randomChoice(
|
|
||||||
["A", "B", "C", "D"]
|
|
||||||
)}`,
|
|
||||||
bilangan: randomNumber(1, 10),
|
|
||||||
jenisBarang: randomChoice(jenisBarangOptions),
|
|
||||||
tandaBarang: `TB-${randomNumber(1000, 9999)}`,
|
|
||||||
keadaanBarang: randomChoice(keadaanBarangOptions),
|
|
||||||
kuantitiBarang: randomNumber(1, 100),
|
|
||||||
jenisBarangDetail: randomChoice(jenisBarangDetailOptions),
|
|
||||||
jenisBarangSiber: randomChoice(jenisBarangSiberOptions),
|
|
||||||
noKertasSiasatan: `KS-${randomNumber(10000, 99999)}`,
|
|
||||||
noLaporanPolis: `RPT-${randomNumber(100000, 999999)}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
if (existingData) {
|
||||||
const sampleData = generateSampleData(noSiri.value);
|
namaPemohon.value = existingData.namaPemohon;
|
||||||
|
pangkatPemohon.value = existingData.pangkatPemohon;
|
||||||
|
noPegawaiPemohon.value = existingData.noPegawaiPemohon;
|
||||||
|
namaPenghantar.value = existingData.namaPenghantar;
|
||||||
|
pangkatPenghantar.value = existingData.pangkatPenghantar;
|
||||||
|
ringkasanKenyataanKes.value = existingData.ringkasanKenyataanKes;
|
||||||
|
bilangan.value = existingData.bilangan;
|
||||||
|
barangList.value = existingData.barangList;
|
||||||
|
noKertasSiasatan.value = existingData.noKertasSiasatan;
|
||||||
|
noLaporanPolis.value = existingData.noLaporanPolis;
|
||||||
|
}
|
||||||
|
|
||||||
namaPemohon.value = sampleData.namaPemohon;
|
jenisBarangDetailOptions.value = await fetchLookupData("jenis_barang");
|
||||||
pangkatPemohon.value = sampleData.pangkatPemohon;
|
|
||||||
noPegawaiPemohon.value = sampleData.noPegawaiPemohon;
|
|
||||||
namaPenghantar.value = sampleData.namaPenghantar;
|
|
||||||
pangkatPenghantar.value = sampleData.pangkatPenghantar;
|
|
||||||
ringkasanKenyataanKes.value = sampleData.ringkasanKenyataanKes;
|
|
||||||
bilangan.value = sampleData.bilangan;
|
|
||||||
jenisBarang.value = sampleData.jenisBarang;
|
|
||||||
tandaBarang.value = sampleData.tandaBarang;
|
|
||||||
keadaanBarang.value = sampleData.keadaanBarang;
|
|
||||||
kuantitiBarang.value = sampleData.kuantitiBarang;
|
|
||||||
jenisBarangDetail.value = sampleData.jenisBarangDetail;
|
|
||||||
jenisBarangSiber.value = sampleData.jenisBarangSiber;
|
|
||||||
noKertasSiasatan.value = sampleData.noKertasSiasatan;
|
|
||||||
noLaporanPolis.value = sampleData.noLaporanPolis;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { $swal } = useNuxtApp();
|
const getJenisBarangLabel = (value) => {
|
||||||
|
const option = jenisBarangDetailOptions.value.find(
|
||||||
|
(opt) => opt.__original === value
|
||||||
|
);
|
||||||
|
return option ? option.label : value;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<h2 class="text-xl font-semibold">Butiran Pegawai</h2>
|
<h2 class="text-xl font-semibold">Butiran Pegawai</h2>
|
||||||
<div
|
<div
|
||||||
v-for="role in ['PENYIASAT', 'PENGHANTAR', 'PENERIMA', 'PEMERIKSA']"
|
v-for="role in ['PENYIASAT', 'PENGHANTAR', 'PEMERIKSA', 'PENERIMA']"
|
||||||
:key="role"
|
:key="role"
|
||||||
class="grid grid-cols-1 md:grid-cols-3 gap-4"
|
class="grid grid-cols-1 md:grid-cols-3 gap-4"
|
||||||
>
|
>
|
||||||
@ -71,8 +71,6 @@
|
|||||||
:name="`pegawai.${role}.nama`"
|
:name="`pegawai.${role}.nama`"
|
||||||
:label="`${role} - Nama`"
|
:label="`${role} - Nama`"
|
||||||
v-model="generatedData.pegawai[role].nama"
|
v-model="generatedData.pegawai[role].nama"
|
||||||
validation="required"
|
|
||||||
:validation-messages="{ required: 'Nama diperlukan' }"
|
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
<FormKit
|
<FormKit
|
||||||
@ -80,8 +78,6 @@
|
|||||||
:name="`pegawai.${role}.pangkat`"
|
:name="`pegawai.${role}.pangkat`"
|
||||||
:label="`${role} - Pangkat`"
|
:label="`${role} - Pangkat`"
|
||||||
v-model="generatedData.pegawai[role].pangkat"
|
v-model="generatedData.pegawai[role].pangkat"
|
||||||
validation="required"
|
|
||||||
:validation-messages="{ required: 'Pangkat diperlukan' }"
|
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
<FormKit
|
<FormKit
|
||||||
@ -89,8 +85,6 @@
|
|||||||
:name="`pegawai.${role}.noPegawai`"
|
:name="`pegawai.${role}.noPegawai`"
|
||||||
:label="`${role} - No Pegawai`"
|
:label="`${role} - No Pegawai`"
|
||||||
v-model="generatedData.pegawai[role].noPegawai"
|
v-model="generatedData.pegawai[role].noPegawai"
|
||||||
validation="required"
|
|
||||||
:validation-messages="{ required: 'No Pegawai diperlukan' }"
|
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -99,6 +93,7 @@
|
|||||||
<!-- Peralatan and Langkah2 -->
|
<!-- Peralatan and Langkah2 -->
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<FormKit
|
<FormKit
|
||||||
|
v-model="generatedData.peralatan"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
name="peralatan"
|
name="peralatan"
|
||||||
label="Peralatan"
|
label="Peralatan"
|
||||||
@ -107,6 +102,7 @@
|
|||||||
:rows="3"
|
:rows="3"
|
||||||
/>
|
/>
|
||||||
<FormKit
|
<FormKit
|
||||||
|
v-model="generatedData.langkah2"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
name="langkah2"
|
name="langkah2"
|
||||||
label="Langkah-langkah"
|
label="Langkah-langkah"
|
||||||
@ -118,10 +114,11 @@
|
|||||||
|
|
||||||
<!-- Dapatan -->
|
<!-- Dapatan -->
|
||||||
<FormKit
|
<FormKit
|
||||||
|
v-model="generatedData.dapatan.value"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="dapatan"
|
name="dapatan"
|
||||||
label="Dapatan"
|
label="Dapatan"
|
||||||
:options="['Tulen', 'Palsu', 'Tidak dapat dikenalpasti']"
|
:options="dapatanOptions"
|
||||||
validation="required"
|
validation="required"
|
||||||
:validation-messages="{ required: 'Dapatan diperlukan' }"
|
:validation-messages="{ required: 'Dapatan diperlukan' }"
|
||||||
/>
|
/>
|
||||||
@ -130,7 +127,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<h2 class="text-xl font-semibold mb-2">Document Tambahan</h2>
|
<h2 class="text-xl font-semibold mb-2">Document Tambahan</h2>
|
||||||
<FormKit type="list" name="documentTambahan" :value="[]">
|
<FormKit type="list" name="documentTambahan" :value="[]">
|
||||||
<FormKit type="group" :repeatable="true" :key="index">
|
<FormKit type="group" :repeatable="true">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<FormKit
|
<FormKit
|
||||||
type="text"
|
type="text"
|
||||||
@ -152,7 +149,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end gap-2">
|
<div class="flex justify-end gap-2">
|
||||||
<rs-button btn-type="reset" @click="previousPage()"
|
<rs-button variant="danger" btn-type="reset" @click="previousPage()"
|
||||||
>Kembali</rs-button
|
>Kembali</rs-button
|
||||||
>
|
>
|
||||||
<rs-button type="submit" btn-type="submit">Hantar Laporan</rs-button>
|
<rs-button type="submit" btn-type="submit">Hantar Laporan</rs-button>
|
||||||
@ -167,8 +164,9 @@ import { useRoute } from "vue-router";
|
|||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { jsPDF } from "jspdf";
|
import { jsPDF } from "jspdf";
|
||||||
|
|
||||||
|
const { $swal } = useNuxtApp();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const bahanBukti = route.params.bahanBukti;
|
const reportID = route.params.reportID;
|
||||||
|
|
||||||
const generatedData = ref({
|
const generatedData = ref({
|
||||||
kesId: "",
|
kesId: "",
|
||||||
@ -178,61 +176,87 @@ const generatedData = ref({
|
|||||||
pegawai: {
|
pegawai: {
|
||||||
PENYIASAT: { nama: "", pangkat: "", noPegawai: "" },
|
PENYIASAT: { nama: "", pangkat: "", noPegawai: "" },
|
||||||
PENGHANTAR: { nama: "", pangkat: "", noPegawai: "" },
|
PENGHANTAR: { nama: "", pangkat: "", noPegawai: "" },
|
||||||
PENERIMA: { nama: "", pangkat: "", noPegawai: "" },
|
|
||||||
PEMERIKSA: { nama: "", pangkat: "", noPegawai: "" },
|
PEMERIKSA: { nama: "", pangkat: "", noPegawai: "" },
|
||||||
|
PENERIMA: { nama: "", pangkat: "", noPegawai: "" },
|
||||||
},
|
},
|
||||||
peralatan: "",
|
peralatan: "",
|
||||||
langkah2: "",
|
langkah2: "",
|
||||||
dapatan: "",
|
dapatan: "",
|
||||||
documentTambahan: [],
|
documentTambahan: [],
|
||||||
});
|
});
|
||||||
|
// State to store dapatan options
|
||||||
|
const dapatanOptions = ref([]);
|
||||||
|
|
||||||
onMounted(() => {
|
// Fetch dapatan options from the lookup API
|
||||||
// Simulate fetching system-generated data
|
const fetchDapatanOptions = async () => {
|
||||||
generatedData.value = {
|
try {
|
||||||
kesId: `KES${Math.floor(Math.random() * 1000000)
|
const { data } = await useFetch("/api/lookup?type=dapatan");
|
||||||
.toString()
|
if (data.value.statusCode === 200) {
|
||||||
.padStart(6, "0")}`,
|
dapatanOptions.value = data.value.data.map((item) => ({
|
||||||
tagNo: `TAG${Math.floor(Math.random() * 10000)
|
label: item.label,
|
||||||
.toString()
|
value: item.value,
|
||||||
.padStart(4, "0")}`,
|
}));
|
||||||
jenisBrg: ["Dokumen", "Elektronik", "Senjata"][
|
} else {
|
||||||
Math.floor(Math.random() * 3)
|
$swal.fire("Error", "Failed to fetch dapatan options.", "error");
|
||||||
],
|
}
|
||||||
jenisPemeriksaan: ["Forensik", "Visual", "Kimia"][
|
} catch (error) {
|
||||||
Math.floor(Math.random() * 3)
|
$swal.fire("Error", "Failed to load dapatan options.", "error");
|
||||||
],
|
}
|
||||||
pegawai: {
|
};
|
||||||
PENYIASAT: generatePegawai("KB"),
|
|
||||||
PENGHANTAR: generatePegawai(),
|
onMounted(async () => {
|
||||||
PENERIMA: generatePegawai(),
|
try {
|
||||||
PEMERIKSA: generatePegawai(),
|
const { data } = await useFetch(`/api/laporan/${reportID}`);
|
||||||
},
|
if (data.value.statusCode === 200) {
|
||||||
};
|
generatedData.value = {
|
||||||
|
...generatedData.value, // Keep the default structure
|
||||||
|
...data.value.data, // Merge API data
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", "Failed to fetch report data.", "error");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch dapatan options on mount
|
||||||
|
await fetchDapatanOptions();
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Failed to load data.", "error");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function generatePegawai(role = "") {
|
// function generatePegawai(role = "") {
|
||||||
const names = ["Ahmad", "Siti", "Mohd", "Nurul", "Lim", "Raj"];
|
// const names = ["Ahmad", "Siti", "Mohd", "Nurul", "Lim", "Raj"];
|
||||||
const surnames = ["Abdullah", "Tan", "Kumar", "Lee", "Muthu", "Hassan"];
|
// const surnames = ["Abdullah", "Tan", "Kumar", "Lee", "Muthu", "Hassan"];
|
||||||
const pangkat = ["Inspektor", "Sarjan", "Koperal", "Konstabel"];
|
// const pangkat = ["Inspektor", "Sarjan", "Koperal", "Konstabel"];
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
nama: `${names[Math.floor(Math.random() * names.length)]} ${
|
// nama: `${names[Math.floor(Math.random() * names.length)]} ${
|
||||||
surnames[Math.floor(Math.random() * surnames.length)]
|
// surnames[Math.floor(Math.random() * surnames.length)]
|
||||||
}`,
|
// }`,
|
||||||
pangkat:
|
// pangkat:
|
||||||
role === "KB"
|
// role === "KB"
|
||||||
? "Ketua Bahagian"
|
// ? "Ketua Bahagian"
|
||||||
: pangkat[Math.floor(Math.random() * pangkat.length)],
|
// : pangkat[Math.floor(Math.random() * pangkat.length)],
|
||||||
noPegawai: `P${Math.floor(Math.random() * 100000)
|
// noPegawai: `P${Math.floor(Math.random() * 100000)
|
||||||
.toString()
|
// .toString()
|
||||||
.padStart(5, "0")}`,
|
// .padStart(5, "0")}`,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
const submitForm = async (formData) => {
|
const submitForm = async (formData) => {
|
||||||
console.log("Form submitted:", formData);
|
try {
|
||||||
// Implement your API call or form submission logic here
|
const { data } = await useFetch(`/api/laporan/${reportID}`, {
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (data.value.statusCode === 200) {
|
||||||
|
$swal.fire("Success", "Report updated successfully", "success");
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", data.value.message, "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Failed to submit report", "error");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const generatePDF = () => {
|
const generatePDF = () => {
|
||||||
@ -255,7 +279,11 @@ const generatePDF = () => {
|
|||||||
doc.text(`KES ID: ${generatedData.value.kesId}`, 30, 50);
|
doc.text(`KES ID: ${generatedData.value.kesId}`, 30, 50);
|
||||||
doc.text(`TAG NO: ${generatedData.value.tagNo}`, 30, 60);
|
doc.text(`TAG NO: ${generatedData.value.tagNo}`, 30, 60);
|
||||||
doc.text(`Jenis Barang: ${generatedData.value.jenisBrg}`, 30, 70);
|
doc.text(`Jenis Barang: ${generatedData.value.jenisBrg}`, 30, 70);
|
||||||
doc.text(`Jenis Pemeriksaan: ${generatedData.value.jenisPemeriksaan}`, 30, 80);
|
doc.text(
|
||||||
|
`Jenis Pemeriksaan: ${generatedData.value.jenisPemeriksaan}`,
|
||||||
|
30,
|
||||||
|
80
|
||||||
|
);
|
||||||
|
|
||||||
// Add officer details
|
// Add officer details
|
||||||
doc.setFontSize(subtitleSize);
|
doc.setFontSize(subtitleSize);
|
||||||
@ -276,21 +304,32 @@ const generatePDF = () => {
|
|||||||
doc.text("Butiran Pemeriksaan", 20, yPos);
|
doc.text("Butiran Pemeriksaan", 20, yPos);
|
||||||
|
|
||||||
doc.setFontSize(normalSize);
|
doc.setFontSize(normalSize);
|
||||||
doc.text(`Peralatan: ${generatedData.value.peralatan || "N/A"}`, 30, yPos + 10);
|
doc.text(
|
||||||
doc.text(`Langkah-langkah: ${generatedData.value.langkah2 || "N/A"}`, 30, yPos + 20);
|
`Peralatan: ${generatedData.value.peralatan || "N/A"}`,
|
||||||
|
30,
|
||||||
|
yPos + 10
|
||||||
|
);
|
||||||
|
doc.text(
|
||||||
|
`Langkah-langkah: ${generatedData.value.langkah2 || "N/A"}`,
|
||||||
|
30,
|
||||||
|
yPos + 20
|
||||||
|
);
|
||||||
doc.text(`Dapatan: ${generatedData.value.dapatan || "N/A"}`, 30, yPos + 30);
|
doc.text(`Dapatan: ${generatedData.value.dapatan || "N/A"}`, 30, yPos + 30);
|
||||||
|
|
||||||
// Add additional documents
|
// Add additional documents
|
||||||
if (generatedData.value.documentTambahan && generatedData.value.documentTambahan.length > 0) {
|
// if (
|
||||||
yPos += 50;
|
// generatedData.value.documentTambahan &&
|
||||||
doc.setFontSize(subtitleSize);
|
// generatedData.value.documentTambahan.length > 0
|
||||||
doc.text("Dokumen Tambahan", 20, yPos);
|
// ) {
|
||||||
|
// yPos += 50;
|
||||||
|
// doc.setFontSize(subtitleSize);
|
||||||
|
// doc.text("Dokumen Tambahan", 20, yPos);
|
||||||
|
|
||||||
doc.setFontSize(normalSize);
|
// doc.setFontSize(normalSize);
|
||||||
generatedData.value.documentTambahan.forEach((doc, index) => {
|
// generatedData.value.documentTambahan.forEach((doc, index) => {
|
||||||
doc.text(`${index + 1}. ${doc.nama}`, 30, yPos + 10 + (index * 10));
|
// doc.text(`${index + 1}. ${doc.nama}`, 30, yPos + 10 + index * 10);
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Generate and download the PDF
|
// Generate and download the PDF
|
||||||
doc.save(`Laporan_${generatedData.value.kesId}.pdf`);
|
doc.save(`Laporan_${generatedData.value.kesId}.pdf`);
|
@ -4,21 +4,25 @@
|
|||||||
<rs-card class="p-6">
|
<rs-card class="p-6">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<h3 class="text-lg font-semibold">Status Semakan</h3>
|
<h3 class="text-lg font-semibold">Status Semakan</h3>
|
||||||
<rs-badge :variant="statusSemakan === 'Selesai' ? 'success' : 'warning'">
|
<rs-badge
|
||||||
|
:variant="statusSemakan === 'Selesai' ? 'success' : 'warning'"
|
||||||
|
>
|
||||||
{{ statusSemakan }}
|
{{ statusSemakan }}
|
||||||
</rs-badge>
|
</rs-badge>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-center mt-4">
|
<div class="flex justify-between items-center mt-4">
|
||||||
<h3 class="text-lg font-semibold">Status Penerimaan</h3>
|
<h3 class="text-lg font-semibold">Status Penerimaan</h3>
|
||||||
<rs-badge :variant="statusPenerimaan === 'Diterima' ? 'success' : 'danger'">
|
<rs-badge
|
||||||
|
:variant="statusPenerimaan === 'Diterima' ? 'success' : 'danger'"
|
||||||
|
>
|
||||||
{{ statusPenerimaan }}
|
{{ statusPenerimaan }}
|
||||||
</rs-badge>
|
</rs-badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-2 justify-end mt-5">
|
<div class="flex gap-2 mt-5">
|
||||||
<rs-button @click="openSemakModal">Semak</rs-button>
|
<rs-button @click="openSemakModal" variant="primary">Semak</rs-button>
|
||||||
<rs-button @click="openTerimaModal">Terima</rs-button>
|
<rs-button @click="openTerimaModal" variant="success">Terima</rs-button>
|
||||||
<rs-button @click="openTolakModal">Tolak</rs-button>
|
<rs-button @click="openTolakModal" variant="danger">Tolak</rs-button>
|
||||||
</div>
|
</div>
|
||||||
</rs-card>
|
</rs-card>
|
||||||
|
|
||||||
@ -45,7 +49,7 @@
|
|||||||
}"
|
}"
|
||||||
:options-advanced="{
|
:options-advanced="{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
responsive: true,
|
|
||||||
filterable: false,
|
filterable: false,
|
||||||
}"
|
}"
|
||||||
advanced
|
advanced
|
||||||
@ -70,13 +74,17 @@
|
|||||||
<template v-slot:tindakan="data">
|
<template v-slot:tindakan="data">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<rs-button
|
<rs-button
|
||||||
@click="openEditModal(data.text, data.index)"
|
@click="openEditModal(data.text.userID, data.text.assignID)"
|
||||||
variant="info"
|
variant="info"
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
<Icon name="ic:baseline-edit" size="1.2rem" />
|
<Icon name="ic:baseline-edit" size="1.2rem" />
|
||||||
</rs-button>
|
</rs-button>
|
||||||
<rs-button @click="confirmDelete(data.text)" variant="danger" size="sm">
|
<rs-button
|
||||||
|
@click="confirmDelete(data.text.userID, data.text.assignID)"
|
||||||
|
variant="danger"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
<Icon name="ic:baseline-delete" size="1.2rem" />
|
<Icon name="ic:baseline-delete" size="1.2rem" />
|
||||||
</rs-button>
|
</rs-button>
|
||||||
</div>
|
</div>
|
||||||
@ -91,6 +99,7 @@
|
|||||||
<rs-card class="p-6">
|
<rs-card class="p-6">
|
||||||
<h3 class="text-lg font-semibold mb-4">Bahan Bukti</h3>
|
<h3 class="text-lg font-semibold mb-4">Bahan Bukti</h3>
|
||||||
<rs-table
|
<rs-table
|
||||||
|
v-if="evidences.length > 0"
|
||||||
:data="evidences"
|
:data="evidences"
|
||||||
:options="{
|
:options="{
|
||||||
variant: 'default',
|
variant: 'default',
|
||||||
@ -99,7 +108,7 @@
|
|||||||
}"
|
}"
|
||||||
:options-advanced="{
|
:options-advanced="{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
responsive: true,
|
|
||||||
filterable: false,
|
filterable: false,
|
||||||
}"
|
}"
|
||||||
advanced
|
advanced
|
||||||
@ -114,9 +123,6 @@
|
|||||||
<th>Tindakan</th>
|
<th>Tindakan</th>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:no="data">
|
|
||||||
{{ data.text }}
|
|
||||||
</template>
|
|
||||||
<template v-slot:jenisBarang="data">
|
<template v-slot:jenisBarang="data">
|
||||||
{{ data.text }}
|
{{ data.text }}
|
||||||
</template>
|
</template>
|
||||||
@ -140,6 +146,9 @@
|
|||||||
</rs-button>
|
</rs-button>
|
||||||
</template>
|
</template>
|
||||||
</rs-table>
|
</rs-table>
|
||||||
|
<div v-else class="text-center p-10">
|
||||||
|
<p>Tidak ada bahan bukti yang terlibat.</p>
|
||||||
|
</div>
|
||||||
</rs-card>
|
</rs-card>
|
||||||
|
|
||||||
<!-- Add/Edit Modal -->
|
<!-- Add/Edit Modal -->
|
||||||
@ -172,7 +181,6 @@
|
|||||||
<template #footer> </template>
|
<template #footer> </template>
|
||||||
</rs-modal>
|
</rs-modal>
|
||||||
|
|
||||||
<!-- Semak Modal -->
|
|
||||||
<rs-modal v-model="showSemakModal" @close="closeSemakModal">
|
<rs-modal v-model="showSemakModal" @close="closeSemakModal">
|
||||||
<template #header>
|
<template #header>
|
||||||
<h3>Semak Maklumat</h3>
|
<h3>Semak Maklumat</h3>
|
||||||
@ -227,8 +235,10 @@
|
|||||||
validation="required"
|
validation="required"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-end gap-2 mt-4">
|
<div class="flex justify-end gap-2 mt-4">
|
||||||
<rs-button variant="danger" @click="closeSemakModal">Batal</rs-button>
|
<rs-button variant="danger" @click="closeSemakModal"
|
||||||
<rs-button variant="primary" type="submit">Hantar</rs-button>
|
>Batal</rs-button
|
||||||
|
>
|
||||||
|
<rs-button variant="primary" btn-type="submit">Hantar</rs-button>
|
||||||
</div>
|
</div>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
|
|
||||||
@ -255,8 +265,10 @@
|
|||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-end gap-2 mt-4">
|
<div class="flex justify-end gap-2 mt-4">
|
||||||
<rs-button variant="danger" @click="closeSemakModal">Batal</rs-button>
|
<rs-button variant="danger" @click="closeSemakModal"
|
||||||
<rs-button variant="primary" type="submit">Hantar</rs-button>
|
>Batal</rs-button
|
||||||
|
>
|
||||||
|
<rs-button variant="primary" btn-type="submit">Hantar</rs-button>
|
||||||
</div>
|
</div>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
</template>
|
</template>
|
||||||
@ -314,8 +326,10 @@
|
|||||||
validation="required"
|
validation="required"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-end gap-2 mt-4">
|
<div class="flex justify-end gap-2 mt-4">
|
||||||
<rs-button variant="danger" @click="closeTerimaModal">Batal</rs-button>
|
<rs-button variant="danger" @click="closeTerimaModal"
|
||||||
<rs-button variant="primary" type="submit">Hantar</rs-button>
|
>Batal</rs-button
|
||||||
|
>
|
||||||
|
<rs-button variant="primary" btn-type="submit">Hantar</rs-button>
|
||||||
</div>
|
</div>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
</template>
|
</template>
|
||||||
@ -335,12 +349,7 @@
|
|||||||
type="select"
|
type="select"
|
||||||
name="sebabPenolakan"
|
name="sebabPenolakan"
|
||||||
label="Sebab penolakan permohonan"
|
label="Sebab penolakan permohonan"
|
||||||
:options="[
|
:options="sebabPenolakanOptions"
|
||||||
'Dokumen tidak lengkap',
|
|
||||||
'Maklumat tidak tepat',
|
|
||||||
'Tidak memenuhi syarat',
|
|
||||||
'Lain-lain',
|
|
||||||
]"
|
|
||||||
validation="required"
|
validation="required"
|
||||||
:validation-messages="{
|
:validation-messages="{
|
||||||
required: 'Sila pilih sebab penolakan',
|
required: 'Sila pilih sebab penolakan',
|
||||||
@ -356,8 +365,10 @@
|
|||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-end gap-2 mt-4">
|
<div class="flex justify-end gap-2 mt-4">
|
||||||
<rs-button variant="secondary" @click="closeTolakModal">Batal</rs-button>
|
<rs-button variant="secondary" @click="closeTolakModal"
|
||||||
<rs-button variant="danger" type="submit">Hantar</rs-button>
|
>Batal</rs-button
|
||||||
|
>
|
||||||
|
<rs-button variant="danger" btn-type="submit">Hantar</rs-button>
|
||||||
</div>
|
</div>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
</template>
|
</template>
|
||||||
@ -369,127 +380,294 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from "vue";
|
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: "default",
|
layout: "default",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
const { $swal } = useNuxtApp();
|
const { $swal } = useNuxtApp();
|
||||||
|
|
||||||
// Status data
|
// Status data
|
||||||
const statusSemakan = ref("Selesai");
|
const statusSemakan = ref("Selesai");
|
||||||
const statusPenerimaan = ref("Diterima");
|
const statusPenerimaan = ref("Diterima");
|
||||||
|
|
||||||
// Forensic Officers Data
|
// State variables
|
||||||
|
const showModal = ref(false);
|
||||||
const forensicOfficers = ref([]);
|
const forensicOfficers = ref([]);
|
||||||
|
const pegawaiOption = ref([]);
|
||||||
// Evidence Data
|
const selectedPegawai = ref(null);
|
||||||
const evidences = ref([
|
const editMode = ref(false);
|
||||||
{
|
const currentOfficerID = ref(null);
|
||||||
no: 1,
|
const currentAssignID = ref(null);
|
||||||
jenisBarang: "Dokumen",
|
|
||||||
tagNo: "TAG001",
|
|
||||||
keadaan: "Baik",
|
|
||||||
kuantiti: 3,
|
|
||||||
tindakan: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
no: 2,
|
|
||||||
jenisBarang: "Peralatan Elektronik",
|
|
||||||
tagNo: "TAG002",
|
|
||||||
keadaan: "Rosak",
|
|
||||||
kuantiti: 5,
|
|
||||||
tindakan: 2,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// User Roles
|
|
||||||
const isKetuaBahagian = ref(true);
|
const isKetuaBahagian = ref(true);
|
||||||
const isKetuaJabatan = ref(false);
|
const isKetuaJabatan = ref(false);
|
||||||
|
|
||||||
// Modal Controls
|
const sebabPenolakanOptions = ref([]);
|
||||||
const showModal = ref(false);
|
|
||||||
const editMode = ref(false);
|
|
||||||
const selectedPegawai = ref(null);
|
|
||||||
|
|
||||||
// Sample pegawai listing (simulating API response)
|
// Evidence Data
|
||||||
const pegawaiList = ref([]);
|
const evidences = ref([]);
|
||||||
const pegawaiOption = ref([
|
|
||||||
{
|
|
||||||
value: null,
|
|
||||||
label: "Pilih Pegawai",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Fetch pegawai list (simulated API call)
|
// Fetch the status data
|
||||||
const fetchPegawaiList = () => {
|
const fetchStatusData = async () => {
|
||||||
// In a real scenario, this would be an API call
|
try {
|
||||||
pegawaiList.value = [
|
const { data } = await useFetch(
|
||||||
{
|
`/api/permohonan/${route.params.noSiri}/status`
|
||||||
id: "PG001",
|
);
|
||||||
nama: "Ahmad bin Ali",
|
|
||||||
pangkat: "Inspektor",
|
if (data.value.statusCode === 200) {
|
||||||
noPegawai: "PG12345",
|
statusSemakan.value = data.value.data.statusSemakan || "Belum Disemak";
|
||||||
tindakan: 1,
|
statusPenerimaan.value =
|
||||||
},
|
data.value.data.statusPenerimaan || "Belum Diterima";
|
||||||
{
|
} else {
|
||||||
id: "PG002",
|
$swal.fire(
|
||||||
nama: "Siti binti Omar",
|
"Error",
|
||||||
pangkat: "Sarjan",
|
"Gagal mendapatkan status semakan dan penerimaan.",
|
||||||
noPegawai: "PG67890",
|
"error"
|
||||||
tindakan: 2,
|
);
|
||||||
},
|
}
|
||||||
{
|
} catch (error) {
|
||||||
id: "PG003",
|
$swal.fire("Error", "Gagal memuatkan data status.", "error");
|
||||||
nama: "Muthu a/l Rajan",
|
}
|
||||||
pangkat: "Koperal",
|
|
||||||
noPegawai: "PG24680",
|
|
||||||
tindakan: 3,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
// Fetch reports (Bahan Bukti)
|
||||||
fetchPegawaiList();
|
const fetchReports = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await useFetch(
|
||||||
|
`/api/permohonan/${route.params.noSiri}/reports`
|
||||||
|
);
|
||||||
|
|
||||||
for (let index = 0; index < pegawaiList.value.length; index++) {
|
if (data.value.statusCode === 200) {
|
||||||
pegawaiOption.value.push({
|
evidences.value = data.value.data || [];
|
||||||
value: pegawaiList.value[index].tindakan,
|
}
|
||||||
label: `${pegawaiList.value[index].pangkat} ${pegawaiList.value[index].nama} (${pegawaiList.value[index].noPegawai})`,
|
} catch (error) {
|
||||||
});
|
console.error("Error fetching reports:", error);
|
||||||
|
$swal.fire("Error", "Gagal mendapatkan senarai bahan bukti.", "error");
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
// Computed property for form validation
|
// Fetch existing forensic officers and available officers
|
||||||
const isFormValid = computed(() => {
|
const fetchAssignedOfficers = async () => {
|
||||||
return (
|
try {
|
||||||
// filter pegawaiList based on selectedPegawai
|
const { data } = await useFetch(
|
||||||
pegawaiList.value.filter((p) => p.tindakan === selectedPegawai.value)
|
`/api/permohonan/${route.params.noSiri}/forensik/list`
|
||||||
);
|
);
|
||||||
});
|
if (data.value.statusCode === 200) {
|
||||||
|
forensicOfficers.value = data.value.data || [];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching forensic officers:", error);
|
||||||
|
$swal.fire("Error", "Gagal mendapatkan senarai pegawai forensik.", "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Actions
|
const fetchAvailableOfficers = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await useFetch(
|
||||||
|
`/api/permohonan/${route.params.noSiri}/forensik/available`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (data.value.statusCode === 200) {
|
||||||
|
pegawaiOption.value = data.value.data || [];
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching available officers:", error);
|
||||||
|
$swal.fire("Error", "Gagal mendapatkan senarai pegawai tersedia.", "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchSebabPenolakanOptions = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await useFetch("/api/lookup?type=sebab_penolakan");
|
||||||
|
if (data.value.statusCode === 200) {
|
||||||
|
sebabPenolakanOptions.value = data.value.data;
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", "Failed to fetch sebab penolakan options", "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Failed to load lookup data", "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Open modals
|
||||||
const openAddModal = () => {
|
const openAddModal = () => {
|
||||||
editMode.value = false;
|
editMode.value = false;
|
||||||
selectedPegawai.value = null;
|
selectedPegawai.value = null;
|
||||||
|
fetchAvailableOfficers();
|
||||||
showModal.value = true;
|
showModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const openEditModal = (pegawai, index) => {
|
const openEditModal = (userID, assignID) => {
|
||||||
editMode.value = true;
|
editMode.value = true;
|
||||||
selectedPegawai.value = pegawai;
|
currentOfficerID.value = userID;
|
||||||
|
currentAssignID.value = assignID;
|
||||||
console.log(selectedPegawai.value);
|
selectedPegawai.value = null;
|
||||||
console.log("index", index);
|
fetchAvailableOfficers(); // Get updated available officers for edit mode
|
||||||
showModal.value = true;
|
showModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const confirmDelete = (userID, assignID) => {
|
||||||
|
$swal
|
||||||
|
.fire({
|
||||||
|
title: "Apakah anda pasti?",
|
||||||
|
text: "Anda tidak akan dapat mengembalikannya!",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#3085d6",
|
||||||
|
cancelButtonColor: "#d33",
|
||||||
|
confirmButtonText: "Ya, hapus!",
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
deletePegawai(userID, assignID);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Close modal
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
showModal.value = false;
|
showModal.value = false;
|
||||||
selectedPegawai.value = null;
|
selectedPegawai.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add new officer
|
||||||
|
const addNewPegawai = async () => {
|
||||||
|
try {
|
||||||
|
const response = await useFetch(
|
||||||
|
`/api/permohonan/${route.params.noSiri}/forensik/add`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: { pegawaiID: selectedPegawai.value },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.data.value.statusCode === 200) {
|
||||||
|
await fetchAssignedOfficers();
|
||||||
|
$swal.fire("Berjaya", "Pegawai baru telah ditambah", "success");
|
||||||
|
closeModal();
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", response.data.message, "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Gagal menambah pegawai.", "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Edit existing officer
|
||||||
|
const updatePegawai = async () => {
|
||||||
|
try {
|
||||||
|
const response = await useFetch(
|
||||||
|
`/api/permohonan/${route.params.noSiri}/forensik/edit`,
|
||||||
|
{
|
||||||
|
method: "PUT",
|
||||||
|
body: {
|
||||||
|
assignID: currentAssignID.value,
|
||||||
|
newPegawaiID: selectedPegawai.value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.data.value.statusCode === 200) {
|
||||||
|
await fetchAssignedOfficers(); // Refresh the list of officers
|
||||||
|
$swal.fire("Berjaya", "Maklumat pegawai telah dikemaskini", "success");
|
||||||
|
closeModal();
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", response.data.message, "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Gagal mengemaskini maklumat pegawai.", "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Delete officer
|
||||||
|
const deletePegawai = async (officer, assignID) => {
|
||||||
|
try {
|
||||||
|
const response = await useFetch(
|
||||||
|
`/api/permohonan/${route.params.noSiri}/forensik/delete`,
|
||||||
|
{
|
||||||
|
method: "DELETE",
|
||||||
|
body: { assignID: assignID },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.data.value.statusCode === 200) {
|
||||||
|
await fetchAssignedOfficers();
|
||||||
|
$swal.fire("Dihapuskan!", "Pegawai telah dipadam.", "success");
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", response.data.message, "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Gagal memadam pegawai.", "error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Submit Semak form
|
||||||
|
const handleSemakSubmit = async (formData) => {
|
||||||
|
try {
|
||||||
|
const response = await useFetch(
|
||||||
|
`/api/permohonan/${route.params.noSiri}/semak`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (response.data.value.statusCode === 200) {
|
||||||
|
$swal.fire("Berjaya", "Maklumat semakan telah disimpan", "success");
|
||||||
|
await fetchStatusData();
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", response.data.message, "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Gagal menyimpan semakan.", "error");
|
||||||
|
}
|
||||||
|
closeSemakModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Submit Terima form
|
||||||
|
const handleTerimaSubmit = async (formData) => {
|
||||||
|
try {
|
||||||
|
const response = await useFetch(
|
||||||
|
`/api/permohonan/${route.params.noSiri}/terima`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (response.data.value.statusCode === 200) {
|
||||||
|
$swal.fire("Berjaya", "Permohonan telah diterima", "success");
|
||||||
|
await fetchStatusData();
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", response.data.message, "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Gagal menerima permohonan.", "error");
|
||||||
|
}
|
||||||
|
closeTerimaModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Submit Tolak form
|
||||||
|
const handleTolakSubmit = async (formData) => {
|
||||||
|
try {
|
||||||
|
const response = await useFetch(
|
||||||
|
`/api/permohonan/${route.params.noSiri}/tolak`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (response.data.value.statusCode === 200) {
|
||||||
|
$swal.fire("Berjaya", "Permohonan telah ditolak", "success");
|
||||||
|
navigateTo("/kemaskini-daftar/senarai");
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error", response.data.message, "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
$swal.fire("Error", "Gagal menolak permohonan.", "error");
|
||||||
|
}
|
||||||
|
closeTolakModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle form submission (add/edit)
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
if (editMode.value) {
|
if (editMode.value) {
|
||||||
updatePegawai();
|
updatePegawai();
|
||||||
@ -498,93 +676,15 @@ const handleSubmit = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const addNewPegawai = () => {
|
// Fetch officers when the component mounts
|
||||||
console.log(selectedPegawai.value);
|
onMounted(() => {
|
||||||
if (selectedPegawai.value) {
|
fetchStatusData();
|
||||||
const selectedPegawai_ = pegawaiList.value.find(
|
fetchAssignedOfficers();
|
||||||
(p) => p.tindakan === selectedPegawai.value
|
fetchReports(); // Fetch reports related to the permohonan
|
||||||
);
|
});
|
||||||
if (selectedPegawai_) {
|
|
||||||
const newPegawai = {
|
|
||||||
...selectedPegawai_,
|
|
||||||
tindakan: selectedPegawai_.tindakan,
|
|
||||||
};
|
|
||||||
forensicOfficers.value.push(newPegawai);
|
|
||||||
$swal.fire("Berjaya", "Pegawai baru telah ditambah", "success");
|
|
||||||
closeModal();
|
|
||||||
} else {
|
|
||||||
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$swal.fire("Ralat", "Sila pilih pegawai", "error");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const updatePegawai = () => {
|
|
||||||
console.log("masuk uodate");
|
|
||||||
if (selectedPegawai.value) {
|
|
||||||
console.log(selectedPegawai.value);
|
|
||||||
const selectedPegawai_ = pegawaiList.value.find(
|
|
||||||
(p) => p.tindakan == selectedPegawai.value
|
|
||||||
);
|
|
||||||
console.log("selectedPegawai_", selectedPegawai_);
|
|
||||||
if (selectedPegawai_) {
|
|
||||||
const pegawaiFromSelectedPegawais = forensicOfficers.value.findIndex(
|
|
||||||
(officer) => officer.tindakan === selectedPegawai.value
|
|
||||||
);
|
|
||||||
console.log("pegawaiFromSelectedPegawais", pegawaiFromSelectedPegawais);
|
|
||||||
if (pegawai_ !== -1) {
|
|
||||||
forensicOfficers.value[pegawai_] = {
|
|
||||||
...selectedPegawai_,
|
|
||||||
tindakan: selectedPegawai_.tindakan,
|
|
||||||
};
|
|
||||||
$swal.fire("Berjaya", "Maklumat pegawai telah dikemaskini", "success");
|
|
||||||
closeModal();
|
|
||||||
} else {
|
|
||||||
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$swal.fire("Ralat", "Sila pilih pegawai", "error");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const confirmDelete = (pegawai) => {
|
|
||||||
$swal
|
|
||||||
.fire({
|
|
||||||
title: "Anda pasti?",
|
|
||||||
text: "Pegawai ini akan dipadamkan.",
|
|
||||||
icon: "warning",
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonColor: "#d33",
|
|
||||||
cancelButtonColor: "#3085d6",
|
|
||||||
confirmButtonText: "Ya, padam",
|
|
||||||
cancelButtonText: "Batal",
|
|
||||||
})
|
|
||||||
.then((result) => {
|
|
||||||
if (result.isConfirmed) {
|
|
||||||
deletePegawai(pegawai);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const deletePegawai = (pegawai) => {
|
|
||||||
const index = forensicOfficers.value.findIndex(
|
|
||||||
(officer) => officer.tindakan === pegawai
|
|
||||||
);
|
|
||||||
if (index !== -1) {
|
|
||||||
forensicOfficers.value.splice(index, 1);
|
|
||||||
$swal.fire("Dihapuskan!", "Pegawai telah dipadam.", "success");
|
|
||||||
} else {
|
|
||||||
$swal.fire("Ralat", "Pegawai tidak dijumpai", "error");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateReport = (bahanBukti) => {
|
const generateReport = (bahanBukti) => {
|
||||||
console.log("Generate Report for:", bahanBukti);
|
console.log("Generate Report for:", bahanBukti);
|
||||||
|
|
||||||
navigateTo(`/kemaskini-daftar/laporan/${bahanBukti}`);
|
navigateTo(`/kemaskini-daftar/laporan/${bahanBukti}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -600,26 +700,11 @@ const closeSemakModal = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// User role (you might want to fetch this from your auth system)
|
// User role (you might want to fetch this from your auth system)
|
||||||
const userRole = ref("Pegawai Kaunter"); // Change this to 'ketuaBahagian' to test the other form
|
const userRole = ref("Pegawai Kaunter"); // Change this to 'Ketua Bahagian' to test the other form
|
||||||
|
|
||||||
// For ketua bahagian form
|
// For ketua bahagian form
|
||||||
const kelulusanKetuaBahagian = ref(null);
|
const kelulusanKetuaBahagian = ref(null);
|
||||||
|
|
||||||
const handleSemakSubmit = (formData) => {
|
|
||||||
console.log("Semak form submitted:", formData);
|
|
||||||
// Here you would typically send the data to your API
|
|
||||||
let successMessage = "";
|
|
||||||
if (userRole.value === "Pegawai Kaunter") {
|
|
||||||
successMessage = "Maklumat semakan telah disimpan";
|
|
||||||
} else if (userRole.value === "Ketua Bahagian") {
|
|
||||||
const decision =
|
|
||||||
formData.kelulusanKetuaBahagian === "Diterima" ? "diterima" : "ditolak";
|
|
||||||
successMessage = `Permohonan telah ${decision}. Ulasan: ${formData.ulasanKetuaBahagian}`;
|
|
||||||
}
|
|
||||||
$swal.fire("Berjaya", successMessage, "success");
|
|
||||||
closeSemakModal();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Terima Modal Controls
|
// Terima Modal Controls
|
||||||
const showTerimaModal = ref(false);
|
const showTerimaModal = ref(false);
|
||||||
|
|
||||||
@ -631,53 +716,19 @@ const closeTerimaModal = () => {
|
|||||||
showTerimaModal.value = false;
|
showTerimaModal.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTerimaSubmit = (formData) => {
|
|
||||||
console.log("Terima form submitted:", formData);
|
|
||||||
// Here you would typically send the data to your API
|
|
||||||
let successMessage = "Permohonan telah diterima.";
|
|
||||||
|
|
||||||
// Check if any of the radio button answers are 'Tidak'
|
|
||||||
const hasNegativeResponse = [
|
|
||||||
"peralatanBaik",
|
|
||||||
"pegawaiBerkelayakan",
|
|
||||||
"kaedahDapatDilakukan",
|
|
||||||
"tugasanDiterima",
|
|
||||||
].some((field) => formData[field] === "Tidak");
|
|
||||||
|
|
||||||
if (hasNegativeResponse) {
|
|
||||||
successMessage += " Namun, terdapat beberapa perkara yang perlu diberi perhatian.";
|
|
||||||
}
|
|
||||||
|
|
||||||
successMessage += ` Ulasan: ${formData.ulasanPegawaiKaunter}`;
|
|
||||||
|
|
||||||
$swal.fire("Berjaya", successMessage, "success");
|
|
||||||
closeTerimaModal();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Tolak Modal Controls
|
// Tolak Modal Controls
|
||||||
const showTolakModal = ref(false);
|
const showTolakModal = ref(false);
|
||||||
|
|
||||||
const openTolakModal = () => {
|
const openTolakModal = async () => {
|
||||||
|
await fetchSebabPenolakanOptions();
|
||||||
showTolakModal.value = true;
|
showTolakModal.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeTolakModal = () => {
|
const closeTolakModal = () => {
|
||||||
showTolakModal.value = false;
|
showTolakModal.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTolakSubmit = (formData) => {
|
|
||||||
console.log("Tolak form submitted:", formData);
|
|
||||||
// Here you would typically send the data to your API
|
|
||||||
let rejectionReason = formData.sebabPenolakan;
|
|
||||||
if (rejectionReason === "Lain-lain") {
|
|
||||||
rejectionReason += `: ${formData.lainLainSebab}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const successMessage = `Permohonan telah ditolak. Sebab: ${rejectionReason}`;
|
|
||||||
|
|
||||||
$swal.fire("Berjaya", successMessage, "success");
|
|
||||||
closeTolakModal();
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style scoped>
|
||||||
|
/* Your existing styles */
|
||||||
|
</style>
|
||||||
|
@ -7,16 +7,16 @@
|
|||||||
<rs-card class="mt-4 py-2">
|
<rs-card class="mt-4 py-2">
|
||||||
<rs-table
|
<rs-table
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
:options='{
|
:options="{
|
||||||
variant: "default",
|
variant: 'default',
|
||||||
striped: true,
|
striped: true,
|
||||||
borderless: true
|
borderless: true,
|
||||||
}'
|
}"
|
||||||
:options-advanced='{
|
:options-advanced="{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
responsive: true,
|
|
||||||
filterable: false
|
filterable: false,
|
||||||
}'
|
}"
|
||||||
advanced
|
advanced
|
||||||
>
|
>
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
@ -73,50 +73,29 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
|
||||||
const { $swal } = useNuxtApp();
|
const { $swal } = useNuxtApp();
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
title: "Senarai Permohonan",
|
title: "Senarai Permohonan",
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableData = ref([
|
// Reactive variable to store table data
|
||||||
{
|
const tableData = ref([]);
|
||||||
no: 1,
|
|
||||||
noSiri: "1234567890",
|
// Fetch permohonan list from API
|
||||||
tarikhMasa: "2024-01-01 12:00:00",
|
const fetchPermohonan = async () => {
|
||||||
status: "Aktif",
|
try {
|
||||||
butiran: 1,
|
const response = await useFetch("/api/permohonan");
|
||||||
},
|
if (response.data.value.statusCode === 200) {
|
||||||
{
|
// Populate tableData with the fetched permohonan list
|
||||||
no: 2,
|
tableData.value = response.data.value.data;
|
||||||
noSiri: "0987654321",
|
} else {
|
||||||
tarikhMasa: "2024-02-01 14:30:00",
|
console.error(response.data.value.message);
|
||||||
status: "Aktif",
|
}
|
||||||
butiran: 2,
|
} catch (error) {
|
||||||
},
|
console.error("Error fetching permohonan data:", error);
|
||||||
{
|
}
|
||||||
no: 3,
|
};
|
||||||
noSiri: "1122334455",
|
|
||||||
tarikhMasa: "2024-03-01 09:15:00",
|
|
||||||
status: "Aktif",
|
|
||||||
butiran: 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
no: 4,
|
|
||||||
noSiri: "5566778899",
|
|
||||||
tarikhMasa: "2024-04-01 16:45:00",
|
|
||||||
status: "Aktif",
|
|
||||||
butiran: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
no: 5,
|
|
||||||
noSiri: "6677889900",
|
|
||||||
tarikhMasa: "2024-05-01 11:00:00",
|
|
||||||
status: "Aktif",
|
|
||||||
butiran: 5,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const permohonanBaru = () => {
|
const permohonanBaru = () => {
|
||||||
navigateTo("/permohonan-temujanji/baru");
|
navigateTo("/permohonan-temujanji/baru");
|
||||||
@ -131,29 +110,40 @@ const lihat = (item) => {
|
|||||||
navigateTo(`/kemaskini-daftar/maklumat/${item}`);
|
navigateTo(`/kemaskini-daftar/maklumat/${item}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hapus = (item) => {
|
const hapus = async (noSiri) => {
|
||||||
$swal
|
const confirmation = await $swal.fire({
|
||||||
.fire({
|
title: "Anda pasti?",
|
||||||
title: "Anda pasti?",
|
text: "Anda tidak akan dapat memulihkan semula data ini!",
|
||||||
text: "Anda tidak akan dapat memulihkan semula data ini!",
|
icon: "warning",
|
||||||
icon: "warning",
|
showCancelButton: true,
|
||||||
showCancelButton: true,
|
confirmButtonColor: "#3085d6",
|
||||||
confirmButtonColor: "#3085d6",
|
cancelButtonColor: "#d33",
|
||||||
cancelButtonColor: "#d33",
|
confirmButtonText: "Ya, hapuskan!",
|
||||||
confirmButtonText: "Ya, hapuskan!",
|
cancelButtonText: "Batal",
|
||||||
cancelButtonText: "Batal",
|
});
|
||||||
})
|
|
||||||
.then((result) => {
|
if (confirmation.isConfirmed) {
|
||||||
if (result.isConfirmed) {
|
try {
|
||||||
// Perform deletion logic here
|
const response = await useFetch(`/api/permohonan/${noSiri}`, {
|
||||||
console.log("Deleting item:", item);
|
method: "DELETE",
|
||||||
// Remove the item from the tableData
|
});
|
||||||
const index = tableData.value.findIndex((row) => row.noSiri === item);
|
if (response.data.value.statusCode === 200) {
|
||||||
if (index !== -1) {
|
// Remove the deleted permohonan from tableData
|
||||||
tableData.value.splice(index, 1);
|
tableData.value = tableData.value.filter(
|
||||||
}
|
(row) => row.noSiri !== noSiri
|
||||||
$swal.fire("Dihapuskan!", "Data telah dihapuskan.", "success");
|
);
|
||||||
|
$swal.fire("Dihapuskan!", response.data.value.message, "success");
|
||||||
|
} else {
|
||||||
|
$swal.fire("Error!", response.data.value.message, "error");
|
||||||
}
|
}
|
||||||
});
|
} catch (error) {
|
||||||
|
$swal.fire("Error!", "Failed to delete permohonan.", "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Fetch the permohonan list when the component is mounted
|
||||||
|
onMounted(() => {
|
||||||
|
fetchPermohonan();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -98,7 +98,11 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(barang, index) in barangList" :key="index">
|
<tr v-for="(barang, index) in barangList" :key="index">
|
||||||
<td class="border border-gray-300 p-2">
|
<td class="border border-gray-300 p-2">
|
||||||
{{ getJenisBarangLabel(barang.jenisBarangDetail) }}
|
{{
|
||||||
|
barang.jenisBarangDetailLabel
|
||||||
|
? barang.jenisBarangDetailLabel
|
||||||
|
: barang.jenisBarangDetail
|
||||||
|
}}
|
||||||
</td>
|
</td>
|
||||||
<td class="border border-gray-300 p-2">
|
<td class="border border-gray-300 p-2">
|
||||||
{{ barang.kuantitiBarang }}
|
{{ barang.kuantitiBarang }}
|
||||||
@ -369,9 +373,19 @@ const cancelBarangModal = () => {
|
|||||||
|
|
||||||
const saveBarangModal = () => {
|
const saveBarangModal = () => {
|
||||||
if (editingBarangIndex.value === null) {
|
if (editingBarangIndex.value === null) {
|
||||||
barangList.value.push({ ...currentBarang.value });
|
barangList.value.push({
|
||||||
|
...currentBarang.value,
|
||||||
|
jenisBarangDetailLabel: getJenisBarangLabel(
|
||||||
|
currentBarang.value.jenisBarangDetail
|
||||||
|
),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
barangList.value[editingBarangIndex.value] = { ...currentBarang.value };
|
barangList.value[editingBarangIndex.value] = {
|
||||||
|
...currentBarang.value,
|
||||||
|
jenisBarangDetailLabel: getJenisBarangLabel(
|
||||||
|
currentBarang.value.jenisBarangDetail
|
||||||
|
),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
isBarangModalOpen.value = false;
|
isBarangModalOpen.value = false;
|
||||||
};
|
};
|
||||||
@ -448,7 +462,7 @@ const submitData = async (isDraft) => {
|
|||||||
|
|
||||||
// Redirect to senarai page after successful submission
|
// Redirect to senarai page after successful submission
|
||||||
if (!isDraft) {
|
if (!isDraft) {
|
||||||
router.push('/permohonan-temujanji/senarai');
|
router.push("/permohonan-temujanji/senarai");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$swal.fire({
|
$swal.fire({
|
||||||
|
@ -97,7 +97,11 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(barang, index) in barangList" :key="index">
|
<tr v-for="(barang, index) in barangList" :key="index">
|
||||||
<td class="border border-gray-300 p-2">
|
<td class="border border-gray-300 p-2">
|
||||||
{{ getJenisBarangLabel(barang.jenisBarangDetail) }}
|
{{
|
||||||
|
barang.jenisBarangDetailLabel
|
||||||
|
? barang.jenisBarangDetailLabel
|
||||||
|
: barang.jenisBarangDetail
|
||||||
|
}}
|
||||||
</td>
|
</td>
|
||||||
<td class="border border-gray-300 p-2">
|
<td class="border border-gray-300 p-2">
|
||||||
{{ barang.kuantitiBarang }}
|
{{ barang.kuantitiBarang }}
|
||||||
@ -406,9 +410,19 @@ const cancelBarangModal = () => {
|
|||||||
|
|
||||||
const saveBarangModal = () => {
|
const saveBarangModal = () => {
|
||||||
if (editingBarangIndex.value === null) {
|
if (editingBarangIndex.value === null) {
|
||||||
barangList.value.push({ ...currentBarang.value });
|
barangList.value.push({
|
||||||
|
...currentBarang.value,
|
||||||
|
jenisBarangDetailLabel: getJenisBarangLabel(
|
||||||
|
currentBarang.value.jenisBarangDetail
|
||||||
|
),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
barangList.value[editingBarangIndex.value] = { ...currentBarang.value };
|
barangList.value[editingBarangIndex.value] = {
|
||||||
|
...currentBarang.value,
|
||||||
|
jenisBarangDetailLabel: getJenisBarangLabel(
|
||||||
|
currentBarang.value.jenisBarangDetail
|
||||||
|
),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
isBarangModalOpen.value = false;
|
isBarangModalOpen.value = false;
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
}"
|
}"
|
||||||
:options-advanced="{
|
:options-advanced="{
|
||||||
sortable: true,
|
sortable: true,
|
||||||
responsive: true,
|
|
||||||
filterable: false,
|
filterable: false,
|
||||||
}"
|
}"
|
||||||
advanced
|
advanced
|
||||||
@ -62,10 +61,7 @@
|
|||||||
<template v-slot:butiran="data">
|
<template v-slot:butiran="data">
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap gap-2"
|
class="flex flex-wrap gap-2"
|
||||||
v-if="
|
v-if="data.value.status === 'Permohonan Draf'"
|
||||||
data.value.status !== 'Sah' &&
|
|
||||||
data.value.status !== 'Permohonan Dihantar'
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<!-- Button to navigate to the "Kemaskini" page for the selected permohonan -->
|
<!-- Button to navigate to the "Kemaskini" page for the selected permohonan -->
|
||||||
<rs-button
|
<rs-button
|
||||||
|
@ -106,8 +106,8 @@ model permohonan {
|
|||||||
penghantar penghantar? @relation(fields: [penghantarID], references: [id], onDelete: Cascade, onUpdate: Restrict, map: "permohonan_ibfk_1")
|
penghantar penghantar? @relation(fields: [penghantarID], references: [id], onDelete: Cascade, onUpdate: Restrict, map: "permohonan_ibfk_1")
|
||||||
permohonan_assign_forensik permohonan_assign_forensik[]
|
permohonan_assign_forensik permohonan_assign_forensik[]
|
||||||
permohonan_jenis_barang permohonan_jenis_barang[]
|
permohonan_jenis_barang permohonan_jenis_barang[]
|
||||||
permohonan_penerimaan permohonan_penerimaan[]
|
permohonan_penerimaan permohonan_penerimaan?
|
||||||
permohonan_semakan permohonan_semakan[]
|
permohonan_semakan permohonan_semakan?
|
||||||
report report[]
|
report report[]
|
||||||
|
|
||||||
@@index([pemohonID], map: "idx_pemohon")
|
@@index([pemohonID], map: "idx_pemohon")
|
||||||
@ -129,25 +129,24 @@ model permohonan_assign_forensik {
|
|||||||
|
|
||||||
model permohonan_penerimaan {
|
model permohonan_penerimaan {
|
||||||
penerimaanID Int @id @default(autoincrement())
|
penerimaanID Int @id @default(autoincrement())
|
||||||
permohonanID Int
|
permohonanID Int @unique(map: "permohonanID")
|
||||||
peralatan_keadaan_baik Int
|
peralatan_keadaan_baik Int
|
||||||
pegawai_berkelayakan Int
|
pegawai_berkelayakan Int
|
||||||
kaedah_dpt_dilakukan Int
|
kaedah_dpt_dilakukan Int
|
||||||
subkontrak_diperlukan Int
|
subkontrak_diperlukan Int
|
||||||
tugasan_diterima Int
|
tugasan_diterima Int
|
||||||
ulasan_pegawai Int?
|
ulasan_pegawai String? @db.Text
|
||||||
create_at DateTime @db.DateTime(0)
|
create_at DateTime @db.DateTime(0)
|
||||||
diterima_oleh Int
|
diterima_oleh Int
|
||||||
permohonan permohonan @relation(fields: [permohonanID], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "permohonan_penerimaan_ibfk_1")
|
permohonan permohonan @relation(fields: [permohonanID], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "permohonan_penerimaan_ibfk_1")
|
||||||
user user @relation(fields: [diterima_oleh], references: [userID], onDelete: NoAction, onUpdate: NoAction, map: "permohonan_penerimaan_ibfk_2")
|
user user @relation(fields: [diterima_oleh], references: [userID], onDelete: NoAction, onUpdate: NoAction, map: "permohonan_penerimaan_ibfk_2")
|
||||||
|
|
||||||
@@index([diterima_oleh], map: "diterima_oleh")
|
@@index([diterima_oleh], map: "diterima_oleh")
|
||||||
@@index([permohonanID], map: "permohonanID")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model permohonan_penolakan {
|
model permohonan_penolakan {
|
||||||
penolakanID Int @id @default(autoincrement())
|
penolakanID Int @id @default(autoincrement())
|
||||||
permohonanID Int
|
permohonanID Int @unique(map: "permohonanID")
|
||||||
sebab_penolakan Int
|
sebab_penolakan Int
|
||||||
lain_sebab String? @db.VarChar(255)
|
lain_sebab String? @db.VarChar(255)
|
||||||
create_at DateTime? @db.DateTime(0)
|
create_at DateTime? @db.DateTime(0)
|
||||||
@ -161,20 +160,19 @@ model permohonan_penolakan {
|
|||||||
|
|
||||||
model permohonan_semakan {
|
model permohonan_semakan {
|
||||||
semakanID Int @id @default(autoincrement())
|
semakanID Int @id @default(autoincrement())
|
||||||
permohonanID Int
|
permohonanID Int @unique(map: "permohonanID")
|
||||||
peralatan_keadaan_baik Int
|
peralatan_keadaan_baik Int?
|
||||||
pegawai_berkelayakan Int
|
pegawai_berkelayakan Int?
|
||||||
kaedah_dpt_dilakukan Int
|
kaedah_dpt_dilakukan Int?
|
||||||
subkontrak_diperlukan Int
|
subkontrak_diperlukan Int?
|
||||||
tugasan_diterima Int
|
tugasan_diterima Int?
|
||||||
ulasan_pegawai String? @db.Text
|
ulasan_pegawai String? @db.Text
|
||||||
create_at Int
|
create_at DateTime? @db.DateTime(0)
|
||||||
disemak_oleh Int
|
disemak_oleh Int?
|
||||||
permohonan permohonan @relation(fields: [permohonanID], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "permohonan_semakan_ibfk_1")
|
permohonan permohonan @relation(fields: [permohonanID], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "permohonan_semakan_ibfk_1")
|
||||||
user user @relation(fields: [disemak_oleh], references: [userID], onDelete: NoAction, onUpdate: NoAction, map: "permohonan_semakan_ibfk_2")
|
user user? @relation(fields: [disemak_oleh], references: [userID], onDelete: NoAction, onUpdate: NoAction, map: "permohonan_semakan_ibfk_2")
|
||||||
|
|
||||||
@@index([disemak_oleh], map: "disemak_oleh")
|
@@index([disemak_oleh], map: "disemak_oleh")
|
||||||
@@index([permohonanID], map: "permohonanID")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model role {
|
model role {
|
||||||
@ -275,8 +273,11 @@ model report {
|
|||||||
reportID Int @id @default(autoincrement())
|
reportID Int @id @default(autoincrement())
|
||||||
permohonanID Int
|
permohonanID Int
|
||||||
jenis_barang Int
|
jenis_barang Int
|
||||||
|
tanda_barang String? @db.VarChar(255)
|
||||||
|
keadaan_barang String? @db.VarChar(255)
|
||||||
|
kuantiti_barang Int?
|
||||||
peralatan String? @db.VarChar(255)
|
peralatan String? @db.VarChar(255)
|
||||||
langkah_langkah Int?
|
langkah_langkah String? @db.VarChar(255)
|
||||||
gambarID Int?
|
gambarID Int?
|
||||||
ulasan String? @db.Text
|
ulasan String? @db.Text
|
||||||
dapatan Int?
|
dapatan Int?
|
||||||
|
54
server/api/kaunter-permohonan/[noSiri].put.js
Normal file
54
server/api/kaunter-permohonan/[noSiri].put.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params; // Extract the noSiri from the URL
|
||||||
|
const body = await readBody(event); // Read the request body
|
||||||
|
|
||||||
|
const { ringkasanKenyataanKes, noKertasSiasatan, noLaporanPolis } = body;
|
||||||
|
|
||||||
|
// 1. Validate the input fields (all three fields must be provided)
|
||||||
|
if (!ringkasanKenyataanKes || !noKertasSiasatan || !noLaporanPolis) {
|
||||||
|
return {
|
||||||
|
statusCode: 400,
|
||||||
|
message:
|
||||||
|
"Setiap medan mandatori yang bertanda * telah diisi. (Ralat CMN-E001)",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 2. Check if the permohonan exists by its `no_siri`
|
||||||
|
const existingPermohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
});
|
||||||
|
|
||||||
|
// If no `permohonan` is found, return a 404 error
|
||||||
|
if (!existingPermohonan) {
|
||||||
|
return {
|
||||||
|
statusCode: 404,
|
||||||
|
message: `Permohonan with noSiri ${noSiri} not found.`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Proceed to update only the allowed fields (ringkasanKenyataanKes, noKertasSiasatan, noLaporanPolis)
|
||||||
|
const updatedPermohonan = await prisma.permohonan.update({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
data: {
|
||||||
|
ringkasan_kenyataan_kes: ringkasanKenyataanKes,
|
||||||
|
no_kertas_siasatan: noKertasSiasatan,
|
||||||
|
no_laporan_polis: noLaporanPolis,
|
||||||
|
modified_at: new Date(), // Update the modified_at timestamp
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. Return success response
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: "Permohonan telah berjaya dikemaskini.",
|
||||||
|
data: updatedPermohonan,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error updating permohonan:", error);
|
||||||
|
return {
|
||||||
|
statusCode: 500,
|
||||||
|
message: "Gagal mengemaskini permohonan. Sila cuba lagi.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
103
server/api/laporan/[reportID].get.js
Normal file
103
server/api/laporan/[reportID].get.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Path: /api/report/[reportID].get.js
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { reportID } = event.context.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const report = await prisma.report.findUnique({
|
||||||
|
where: { reportID: parseInt(reportID) },
|
||||||
|
include: {
|
||||||
|
permohonan: {
|
||||||
|
include: {
|
||||||
|
penghantar: true,
|
||||||
|
pemohon: {
|
||||||
|
include: {
|
||||||
|
user: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lookup_report_jenis_barangTolookup: true,
|
||||||
|
lookup_report_dapatanTolookup: {
|
||||||
|
select: {
|
||||||
|
lookupID: true,
|
||||||
|
lookupValue: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
report_doc_support: {
|
||||||
|
include: {
|
||||||
|
document: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(report);
|
||||||
|
|
||||||
|
if (!report) {
|
||||||
|
return { statusCode: 404, message: "Report not found" };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the data for the frontend
|
||||||
|
const reportData = {
|
||||||
|
kesId: report.permohonan.no_siri,
|
||||||
|
tagNo: report.tanda_barang,
|
||||||
|
jenisBrg: report.lookup_report_jenis_barangTolookup.lookupValue,
|
||||||
|
jenisPemeriksaan: "Forensik", // Assuming it's static for now
|
||||||
|
pegawai: {
|
||||||
|
PENYIASAT: {
|
||||||
|
nama: report.permohonan.pemohon?.user?.userFullName || "",
|
||||||
|
pangkat: report.permohonan.pemohon?.pangkat_pemohon || "",
|
||||||
|
noPegawai: report.permohonan.pemohon?.no_pegawai_pemohon || "",
|
||||||
|
},
|
||||||
|
PENGHANTAR: {
|
||||||
|
nama: report.permohonan.penghantar_sama_dengan_pemohon
|
||||||
|
? report.permohonan.pemohon?.user?.userFullName || ""
|
||||||
|
: report.permohonan.penghantar?.nama_penghantar || "",
|
||||||
|
pangkat: report.permohonan.penghantar_sama_dengan_pemohon
|
||||||
|
? report.permohonan.pemohon?.pangkat_pemohon || ""
|
||||||
|
: report.permohonan.penghantar?.pangkat_penghantar || "",
|
||||||
|
noPegawai: report.permohonan.penghantar_sama_dengan_pemohon
|
||||||
|
? report.permohonan.pemohon?.no_pegawai_pemohon || ""
|
||||||
|
: report.permohonan.penghantar?.no_pegawai_penghantar || "",
|
||||||
|
},
|
||||||
|
PEMERIKSA: {
|
||||||
|
nama: report.permohonan.pemerikasa?.user?.userFullName || "",
|
||||||
|
pangkat: report.permohonan.pemerikasa?.pangkat_pemerikasa || "",
|
||||||
|
noPegawai: report.permohonan.pemerikasa?.no_pegawai_pemerikasa || "",
|
||||||
|
},
|
||||||
|
PENERIMA: {
|
||||||
|
nama: report.permohonan.penerima?.user?.userFullName || "",
|
||||||
|
pangkat: report.permohonan.penerima?.pangkat_penerima || "",
|
||||||
|
noPegawai: report.permohonan.penerima?.no_pegawai_penerima || "",
|
||||||
|
},
|
||||||
|
|
||||||
|
// Fill in other roles accordingly
|
||||||
|
},
|
||||||
|
peralatan: report.peralatan,
|
||||||
|
langkah2: report.langkah_langkah,
|
||||||
|
dapatan: {
|
||||||
|
value: report.lookup_report_dapatanTolookup?.lookupID,
|
||||||
|
label: report.lookup_report_dapatanTolookup?.lookupValue,
|
||||||
|
},
|
||||||
|
documentTambahan: report.report_doc_support
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
nama: report.report_doc_support[0].document.documentName,
|
||||||
|
file: report.report_doc_support[0].document.documentURL,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
nama: "",
|
||||||
|
file: "",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
return { statusCode: 200, data: reportData };
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return { statusCode: 500, message: error.message };
|
||||||
|
}
|
||||||
|
});
|
63
server/api/laporan/[reportID].post.js
Normal file
63
server/api/laporan/[reportID].post.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Path: /api/report/[reportID].post.js
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { reportID } = event.context.params;
|
||||||
|
const body = await readBody(event);
|
||||||
|
|
||||||
|
const {
|
||||||
|
peralatan,
|
||||||
|
langkah2,
|
||||||
|
dapatan, // This should correspond to lookupID in the `lookup` table
|
||||||
|
documentTambahan, // Array of documents
|
||||||
|
} = body;
|
||||||
|
|
||||||
|
console.log(body);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Update the report in the database
|
||||||
|
const updatedReport = await prisma.report.update({
|
||||||
|
where: { reportID: parseInt(reportID) },
|
||||||
|
data: {
|
||||||
|
peralatan,
|
||||||
|
langkah_langkah: langkah2,
|
||||||
|
dapatan: parseInt(dapatan), // Assuming this is a lookupID from the `lookup` table
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle document uploads (if necessary)
|
||||||
|
if (documentTambahan && documentTambahan.length > 0) {
|
||||||
|
// Create documents first
|
||||||
|
const createdDocuments = await prisma.document.createMany({
|
||||||
|
data: documentTambahan.map((doc) => ({
|
||||||
|
documentName: doc.nama,
|
||||||
|
})),
|
||||||
|
skipDuplicates: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the IDs of the newly created documents
|
||||||
|
const newDocumentIds = await prisma.document.findMany({
|
||||||
|
where: {
|
||||||
|
documentName: {
|
||||||
|
in: documentTambahan.map((doc) => doc.nama),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
documentID: true,
|
||||||
|
documentName: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update report_doc_support table
|
||||||
|
await prisma.report_doc_support.createMany({
|
||||||
|
data: newDocumentIds.map((doc) => ({
|
||||||
|
reportID: updatedReport.reportID,
|
||||||
|
documentID: doc.documentID,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { statusCode: 200, message: "Report updated successfully" };
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return { statusCode: 500, message: "Failed to update report" };
|
||||||
|
}
|
||||||
|
});
|
@ -1,3 +1,4 @@
|
|||||||
|
// path: /api/lookup?type=jenis_barang
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
const { type } = getQuery(event); // Get lookup type from query params, e.g., jenis_barang, dapatan
|
const { type } = getQuery(event); // Get lookup type from query params, e.g., jenis_barang, dapatan
|
||||||
|
|
||||||
@ -20,10 +21,22 @@ export default defineEventHandler(async (event) => {
|
|||||||
lookupValue: true,
|
lookupValue: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
if (!lookups) {
|
||||||
|
return {
|
||||||
|
statusCode: 404,
|
||||||
|
message: "Lookup data not found",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert snake_case to Title Case: e.g., jenis_barang_siber -> Jenis Barang Siber
|
||||||
|
const defaultTitle = type
|
||||||
|
.split("_")
|
||||||
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||||
|
.join(" ");
|
||||||
|
|
||||||
// Transform the lookups data to the required format
|
// Transform the lookups data to the required format
|
||||||
const transformedLookups = [
|
const transformedLookups = [
|
||||||
{ label: "", value: null }, // Add an empty option as the first item
|
{ label: `Sila Pilih ${defaultTitle}`, value: null }, // Add an empty option as the first item
|
||||||
...lookups.map((lookup) => ({
|
...lookups.map((lookup) => ({
|
||||||
label: lookup.lookupValue,
|
label: lookup.lookupValue,
|
||||||
value: lookup.lookupID,
|
value: lookup.lookupID,
|
||||||
|
@ -22,7 +22,20 @@ export default defineEventHandler(async (event) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
penghantar: true,
|
penghantar: true,
|
||||||
report: true, // Assuming 'report' is where the `barang` (items) are stored
|
report: {
|
||||||
|
select: {
|
||||||
|
jenis_barang: true,
|
||||||
|
lookup_report_jenis_barangTolookup: {
|
||||||
|
select: {
|
||||||
|
lookupID: true,
|
||||||
|
lookupValue: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tanda_barang: true,
|
||||||
|
keadaan_barang: true,
|
||||||
|
kuantiti_barang: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -47,7 +60,10 @@ export default defineEventHandler(async (event) => {
|
|||||||
ringkasanKenyataanKes: permohonan.ringkasan_kenyataan_kes || "",
|
ringkasanKenyataanKes: permohonan.ringkasan_kenyataan_kes || "",
|
||||||
bilangan: permohonan.bilangan || 0,
|
bilangan: permohonan.bilangan || 0,
|
||||||
barangList: permohonan.report.map((barang) => ({
|
barangList: permohonan.report.map((barang) => ({
|
||||||
jenisBarangDetail: barang.jenis_barang || "",
|
jenisBarangDetail:
|
||||||
|
barang.lookup_report_jenis_barangTolookup.lookupID || "",
|
||||||
|
jenisBarangDetailLabel:
|
||||||
|
barang.lookup_report_jenis_barangTolookup.lookupValue || "",
|
||||||
tandaBarang: barang.tanda_barang || "",
|
tandaBarang: barang.tanda_barang || "",
|
||||||
keadaanBarang: barang.keadaan_barang || "",
|
keadaanBarang: barang.keadaan_barang || "",
|
||||||
kuantitiBarang: barang.kuantiti_barang || 0,
|
kuantitiBarang: barang.kuantiti_barang || 0,
|
||||||
|
@ -127,21 +127,13 @@ export default defineEventHandler(async (event) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const barang of barangList) {
|
for (const barang of barangList) {
|
||||||
// await prisma.report.create({
|
|
||||||
// data: {
|
|
||||||
// permohonanID: updatedPermohonan.id,
|
|
||||||
// jenis_barang: barang.jenisBarangDetail,
|
|
||||||
// kuantiti_barang: barang.kuantitiBarang,
|
|
||||||
// tanda_barang: barang.tandaBarang,
|
|
||||||
// keadaan_barang: barang.keadaanBarang,
|
|
||||||
// create_by: userID,
|
|
||||||
// create_at: new Date(),
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
await prisma.report.create({
|
await prisma.report.create({
|
||||||
data: {
|
data: {
|
||||||
permohonanID: updatedPermohonan.id,
|
permohonanID: updatedPermohonan.id,
|
||||||
jenis_barang: barang.jenisBarangDetail,
|
jenis_barang: barang.jenisBarangDetail,
|
||||||
|
kuantiti_barang: parseInt(barang.kuantitiBarang),
|
||||||
|
tanda_barang: barang.tandaBarang,
|
||||||
|
keadaan_barang: barang.keadaanBarang,
|
||||||
create_by: userID,
|
create_by: userID,
|
||||||
create_at: new Date(),
|
create_at: new Date(),
|
||||||
},
|
},
|
||||||
|
42
server/api/permohonan/[noSiri]/forensik/add.post.js
Normal file
42
server/api/permohonan/[noSiri]/forensik/add.post.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
const body = await readBody(event);
|
||||||
|
const { pegawaiID } = body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Ensure that the permohonan exists
|
||||||
|
const permohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!permohonan) {
|
||||||
|
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the pegawai is not already assigned
|
||||||
|
const existingAssignment =
|
||||||
|
await prisma.permohonan_assign_forensik.findFirst({
|
||||||
|
where: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
pegawai_forensikID: pegawaiID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingAssignment) {
|
||||||
|
return { statusCode: 400, message: "Pegawai sudah ditugaskan." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the pegawai to this permohonan
|
||||||
|
await prisma.permohonan_assign_forensik.create({
|
||||||
|
data: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
pegawai_forensikID: pegawaiID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { statusCode: 200, message: "Pegawai berjaya ditambah." };
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return { statusCode: 500, message: "Error adding forensic officer." };
|
||||||
|
}
|
||||||
|
});
|
51
server/api/permohonan/[noSiri]/forensik/available.get.js
Normal file
51
server/api/permohonan/[noSiri]/forensik/available.get.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch the list of assigned officers
|
||||||
|
const assignedOfficers = await prisma.permohonan_assign_forensik.findMany({
|
||||||
|
where: { permohonan: { no_siri: noSiri } },
|
||||||
|
select: { pegawai_forensikID: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
const assignedOfficerIDs = assignedOfficers.map(
|
||||||
|
(officer) => officer.pegawai_forensikID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fetch all pegawai forensik that are not assigned to this permohonan
|
||||||
|
const availablePegawai = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
userID: { notIn: assignedOfficerIDs },
|
||||||
|
userStatus: "ACTIVE",
|
||||||
|
userrole: {
|
||||||
|
some: {
|
||||||
|
role: {
|
||||||
|
roleName: "Pegawai Forensik",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
userID: true,
|
||||||
|
userFullName: true,
|
||||||
|
userUsername: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
data: [
|
||||||
|
{ value: "", label: "Sila Pilih Pegawai" },
|
||||||
|
...availablePegawai.map((pegawai) => ({
|
||||||
|
value: pegawai.userID,
|
||||||
|
label: `${pegawai.userFullName}`,
|
||||||
|
})),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
statusCode: 500,
|
||||||
|
message: "Error fetching available forensic officers.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
27
server/api/permohonan/[noSiri]/forensik/delete.delete.js
Normal file
27
server/api/permohonan/[noSiri]/forensik/delete.delete.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
const body = await readBody(event);
|
||||||
|
const { assignID } = body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch the existing permohonan
|
||||||
|
const permohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!permohonan) {
|
||||||
|
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the pegawai assignment
|
||||||
|
await prisma.permohonan_assign_forensik.delete({
|
||||||
|
where: {
|
||||||
|
assignID: assignID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { statusCode: 200, message: "Pegawai berjaya dipadamkan." };
|
||||||
|
} catch (error) {
|
||||||
|
return { statusCode: 500, message: "Error deleting forensic officer." };
|
||||||
|
}
|
||||||
|
});
|
46
server/api/permohonan/[noSiri]/forensik/edit.put.js
Normal file
46
server/api/permohonan/[noSiri]/forensik/edit.put.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
const body = await readBody(event);
|
||||||
|
const { oldPegawaiID, newPegawaiID, assignID } = body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch the existing permohonan
|
||||||
|
const permohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!permohonan) {
|
||||||
|
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the new pegawai is already assigned
|
||||||
|
const existingAssignment =
|
||||||
|
await prisma.permohonan_assign_forensik.findFirst({
|
||||||
|
where: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
pegawai_forensikID: newPegawaiID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("existingAssignment", existingAssignment);
|
||||||
|
|
||||||
|
if (existingAssignment) {
|
||||||
|
return { statusCode: 400, message: "Pegawai baru sudah ditugaskan." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the old pegawai with the new pegawai
|
||||||
|
await prisma.permohonan_assign_forensik.update({
|
||||||
|
where: {
|
||||||
|
assignID: assignID,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
pegawai_forensikID: newPegawaiID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { statusCode: 200, message: "Pegawai berjaya dikemaskini." };
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return { statusCode: 500, message: "Error updating forensic officer." };
|
||||||
|
}
|
||||||
|
});
|
45
server/api/permohonan/[noSiri]/forensik/list.get.js
Normal file
45
server/api/permohonan/[noSiri]/forensik/list.get.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch the permohonan by noSiri
|
||||||
|
const permohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
select: {
|
||||||
|
permohonan_assign_forensik: {
|
||||||
|
include: {
|
||||||
|
user: {
|
||||||
|
select: {
|
||||||
|
userID: true,
|
||||||
|
userFullName: true,
|
||||||
|
userUsername: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!permohonan) {
|
||||||
|
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the list of assigned forensic officers
|
||||||
|
const forensicOfficers = permohonan.permohonan_assign_forensik.map(
|
||||||
|
(assignment) => ({
|
||||||
|
nama: assignment.user.userFullName,
|
||||||
|
tindakan: {
|
||||||
|
userID: assignment.user.userID,
|
||||||
|
assignID: assignment.assignID,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
data: forensicOfficers,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return { statusCode: 500, message: "Error fetching forensic officers." };
|
||||||
|
}
|
||||||
|
});
|
38
server/api/permohonan/[noSiri]/reports.get.js
Normal file
38
server/api/permohonan/[noSiri]/reports.get.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// File: /api/permohonan/[noSiri]/reports.get.js
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const permohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
select: {
|
||||||
|
report: {
|
||||||
|
include: {
|
||||||
|
lookup_report_jenis_barangTolookup: true, // To get the jenis barang lookup data
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!permohonan) {
|
||||||
|
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map reports to the frontend format
|
||||||
|
const reports = permohonan.report.map((report) => ({
|
||||||
|
jenisBarang: report.lookup_report_jenis_barangTolookup.lookupValue,
|
||||||
|
tagNo: report.tanda_barang,
|
||||||
|
keadaan: report.keadaan_barang,
|
||||||
|
kuantiti: report.kuantiti_barang,
|
||||||
|
tindakan: report.reportID,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
data: reports,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return { statusCode: 500, message: "Error fetching reports." };
|
||||||
|
}
|
||||||
|
});
|
61
server/api/permohonan/[noSiri]/semak.post.js
Normal file
61
server/api/permohonan/[noSiri]/semak.post.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// File: /api/permohonan/[noSiri]/semak.put.js
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
const body = await readBody(event); // Get form data from frontend
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get the current user (assuming user authentication is handled)
|
||||||
|
const user = event.context.user;
|
||||||
|
|
||||||
|
// Find the permohonan by its noSiri
|
||||||
|
const permohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!permohonan) {
|
||||||
|
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update or create the permohonan semakan entry
|
||||||
|
await prisma.permohonan_semakan.upsert({
|
||||||
|
where: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
peralatan_keadaan_baik: body.peralatanBaik === "Ya" ? 1 : 0,
|
||||||
|
pegawai_berkelayakan: body.pegawaiBerkelayakan === "Ya" ? 1 : 0,
|
||||||
|
kaedah_dpt_dilakukan: body.kaedahDapatDilakukan === "Ya" ? 1 : 0,
|
||||||
|
subkontrak_diperlukan: body.subkontrakDiperlukan === "Ya" ? 1 : 0,
|
||||||
|
tugasan_diterima: body.tugasanDiterima === "Ya" ? 1 : 0,
|
||||||
|
ulasan_pegawai: body.ulasanPegawaiKaunter,
|
||||||
|
disemak_oleh: user.userID, // Use the authenticated user ID
|
||||||
|
create_at: new Date(),
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
peralatan_keadaan_baik: body.peralatanBaik === "Ya" ? 1 : 0,
|
||||||
|
pegawai_berkelayakan: body.pegawaiBerkelayakan === "Ya" ? 1 : 0,
|
||||||
|
kaedah_dpt_dilakukan: body.kaedahDapatDilakukan === "Ya" ? 1 : 0,
|
||||||
|
subkontrak_diperlukan: body.subkontrakDiperlukan === "Ya" ? 1 : 0,
|
||||||
|
tugasan_diterima: body.tugasanDiterima === "Ya" ? 1 : 0,
|
||||||
|
ulasan_pegawai: body.ulasanPegawaiKaunter,
|
||||||
|
disemak_oleh: user.userID,
|
||||||
|
create_at: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the status of the permohonan to "Permohonan Disemak"
|
||||||
|
await prisma.permohonan.update({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
data: { status_permohonan: "Permohonan Disemak" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: "Maklumat semakan berjaya dikemaskini.",
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return { statusCode: 500, message: "Gagal mengemaskini maklumat semakan." };
|
||||||
|
}
|
||||||
|
});
|
49
server/api/permohonan/[noSiri]/status.get.js
Normal file
49
server/api/permohonan/[noSiri]/status.get.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
// Extract the `noSiri` from the URL params
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch the Semakan status
|
||||||
|
const semakan = await prisma.permohonan_semakan.findFirst({
|
||||||
|
where: {
|
||||||
|
permohonan: {
|
||||||
|
no_siri: noSiri,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
semakanID: true, // Checking if semakan exists
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fetch the Penerimaan status
|
||||||
|
const penerimaan = await prisma.permohonan_penerimaan.findFirst({
|
||||||
|
where: {
|
||||||
|
permohonan: {
|
||||||
|
no_siri: noSiri,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
penerimaanID: true, // Checking if penerimaan exists
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Determine statuses based on existence
|
||||||
|
const statusSemakan = semakan ? "Selesai" : "Belum Disemak";
|
||||||
|
const statusPenerimaan = penerimaan ? "Diterima" : "Belum Diterima";
|
||||||
|
|
||||||
|
// Return the statuses
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
data: {
|
||||||
|
statusSemakan,
|
||||||
|
statusPenerimaan,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
// Return an error if something goes wrong
|
||||||
|
return {
|
||||||
|
statusCode: 500,
|
||||||
|
message: "Gagal mendapatkan status",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
64
server/api/permohonan/[noSiri]/terima.post.js
Normal file
64
server/api/permohonan/[noSiri]/terima.post.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// File: /api/permohonan/[noSiri]/terima.put.js
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
const body = await readBody(event); // Get form data from frontend
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get the current user (assuming user authentication is handled)
|
||||||
|
const user = event.context.user;
|
||||||
|
|
||||||
|
// Find the permohonan by its noSiri
|
||||||
|
const permohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!permohonan) {
|
||||||
|
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create or update the permohonan penerimaan entry
|
||||||
|
await prisma.permohonan_penerimaan.upsert({
|
||||||
|
where: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
peralatan_keadaan_baik: body.peralatanBaik === "Ya" ? 1 : 0,
|
||||||
|
pegawai_berkelayakan: body.pegawaiBerkelayakan === "Ya" ? 1 : 0,
|
||||||
|
kaedah_dpt_dilakukan: body.kaedahDapatDilakukan === "Ya" ? 1 : 0,
|
||||||
|
subkontrak_diperlukan: body.subkontrakDiperlukan === "Ya" ? 1 : 0,
|
||||||
|
tugasan_diterima: body.tugasanDiterima === "Ya" ? 1 : 0,
|
||||||
|
ulasan_pegawai: body.ulasanPegawaiKaunter,
|
||||||
|
diterima_oleh: user.userID,
|
||||||
|
create_at: new Date(), // Store current date
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
peralatan_keadaan_baik: body.peralatanBaik === "Ya" ? 1 : 0,
|
||||||
|
pegawai_berkelayakan: body.pegawaiBerkelayakan === "Ya" ? 1 : 0,
|
||||||
|
kaedah_dpt_dilakukan: body.kaedahDapatDilakukan === "Ya" ? 1 : 0,
|
||||||
|
subkontrak_diperlukan: body.subkontrakDiperlukan === "Ya" ? 1 : 0,
|
||||||
|
tugasan_diterima: body.tugasanDiterima === "Ya" ? 1 : 0,
|
||||||
|
ulasan_pegawai: body.ulasanPegawaiKaunter,
|
||||||
|
diterima_oleh: user.userID,
|
||||||
|
create_at: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the status of the permohonan to "Diterima"
|
||||||
|
await prisma.permohonan.update({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
data: { status_permohonan: "Permohonan Diterima" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: "Maklumat penerimaan berjaya dikemaskini.",
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return {
|
||||||
|
statusCode: 500,
|
||||||
|
message: "Gagal mengemaskini maklumat penerimaan.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
56
server/api/permohonan/[noSiri]/tolak.post.js
Normal file
56
server/api/permohonan/[noSiri]/tolak.post.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// File: /api/permohonan/[noSiri]/tolak.put.js
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { noSiri } = event.context.params;
|
||||||
|
const body = await readBody(event); // Get form data from frontend
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get the current user (assuming user authentication is handled)
|
||||||
|
const user = event.context.user;
|
||||||
|
|
||||||
|
// Find the permohonan by its noSiri
|
||||||
|
const permohonan = await prisma.permohonan.findUnique({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!permohonan) {
|
||||||
|
return { statusCode: 404, message: "Permohonan tidak dijumpai." };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create or update the permohonan penolakan entry
|
||||||
|
await prisma.permohonan_penolakan.upsert({
|
||||||
|
where: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
sebab_penolakan: parseInt(body.sebabPenolakan), // Assuming lookupID is passed
|
||||||
|
lain_sebab: body.lainLainSebab || null,
|
||||||
|
ditolak_oleh: user.userID,
|
||||||
|
create_at: new Date(),
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
permohonanID: permohonan.id,
|
||||||
|
sebab_penolakan: parseInt(body.sebabPenolakan),
|
||||||
|
lain_sebab: body.lainLainSebab || null,
|
||||||
|
ditolak_oleh: user.userID,
|
||||||
|
create_at: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the status of the permohonan to "Permohonan Ditolak"
|
||||||
|
await prisma.permohonan.update({
|
||||||
|
where: { no_siri: noSiri },
|
||||||
|
data: { status_permohonan: "Permohonan Ditolak" },
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
message: "Maklumat penolakan berjaya dikemaskini.",
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return {
|
||||||
|
statusCode: 500,
|
||||||
|
message: "Gagal mengemaskini maklumat penolakan.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
@ -119,22 +119,13 @@ export default defineEventHandler(async (event) => {
|
|||||||
|
|
||||||
// Insert related `report` and `document` data
|
// Insert related `report` and `document` data
|
||||||
for (const barang of barangList) {
|
for (const barang of barangList) {
|
||||||
// await prisma.report.create({
|
|
||||||
// data: {
|
|
||||||
// permohonanID: newPermohonan.id,
|
|
||||||
// jenis_barang: barang.jenisBarangDetail,
|
|
||||||
// kuantiti_barang: barang.kuantitiBarang,
|
|
||||||
// tanda_barang: barang.tandaBarang,
|
|
||||||
// keadaan_barang: barang.keadaanBarang,
|
|
||||||
// create_by: userID,
|
|
||||||
// create_at: new Date(),
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
|
|
||||||
await prisma.report.create({
|
await prisma.report.create({
|
||||||
data: {
|
data: {
|
||||||
permohonanID: newPermohonan.id,
|
permohonanID: newPermohonan.id,
|
||||||
jenis_barang: barang.jenisBarangDetail,
|
jenis_barang: barang.jenisBarangDetail,
|
||||||
|
kuantiti_barang: parseInt(barang.kuantitiBarang),
|
||||||
|
tanda_barang: barang.tandaBarang,
|
||||||
|
keadaan_barang: barang.keadaanBarang,
|
||||||
create_by: userID,
|
create_by: userID,
|
||||||
create_at: new Date(),
|
create_at: new Date(),
|
||||||
},
|
},
|
||||||
|
@ -2,24 +2,38 @@
|
|||||||
export default defineEventHandler(async () => {
|
export default defineEventHandler(async () => {
|
||||||
try {
|
try {
|
||||||
const permohonan = await prisma.permohonan.findMany({
|
const permohonan = await prisma.permohonan.findMany({
|
||||||
|
where: {
|
||||||
|
status_permohonan: {
|
||||||
|
notIn: ["Permohonan Ditolak"],
|
||||||
|
},
|
||||||
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
no_siri: true,
|
no_siri: true,
|
||||||
create_at: true,
|
create_at: true,
|
||||||
status_permohonan: true,
|
status_permohonan: true,
|
||||||
},
|
},
|
||||||
|
orderBy: {
|
||||||
|
create_at: "desc",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
message: "Success",
|
message: "Success",
|
||||||
data: permohonan.map((item, index) => ({
|
data: permohonan.map((item, index) => {
|
||||||
no: index + 1,
|
// Convert UTC to GMT+8
|
||||||
noSiri: item.no_siri,
|
const gmt8Date = new Date(
|
||||||
tarikhMasa: item.create_at.toISOString().replace("T", " ").slice(0, 19),
|
item.create_at.getTime() + 8 * 60 * 60 * 1000
|
||||||
status: item.status_permohonan,
|
);
|
||||||
butiran: item.id,
|
return {
|
||||||
})),
|
no: index + 1,
|
||||||
|
noSiri: item.no_siri,
|
||||||
|
tarikhMasa: gmt8Date.toISOString().replace("T", " ").slice(0, 19),
|
||||||
|
status: item.status_permohonan,
|
||||||
|
butiran: item.id,
|
||||||
|
};
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user