Done for now
This commit is contained in:
parent
7b1e5bbc13
commit
efdd28afbd
@ -1,4 +1,34 @@
|
||||
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",
|
||||
description: "",
|
||||
@ -122,36 +152,7 @@ export default [
|
||||
],
|
||||
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",
|
||||
description: "",
|
||||
|
@ -159,7 +159,7 @@ const showTooltip = (codeId, message) => {
|
||||
}"
|
||||
:options-advanced="{
|
||||
sortable: true,
|
||||
responsive: true,
|
||||
|
||||
filterable: false,
|
||||
}"
|
||||
advanced
|
||||
@ -217,7 +217,7 @@ const showTooltip = (codeId, message) => {
|
||||
}"
|
||||
:options-advanced="{
|
||||
sortable: true,
|
||||
responsive: true,
|
||||
|
||||
filterable: false,
|
||||
}"
|
||||
advanced
|
||||
|
@ -46,7 +46,6 @@
|
||||
label="Ringkasan Kenyataan Kes"
|
||||
v-model="ringkasanKenyataanKes"
|
||||
validation="required"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
type="number"
|
||||
@ -55,72 +54,56 @@
|
||||
validation="required|number"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Jenis Barang"
|
||||
v-model="jenisBarang"
|
||||
validation="required"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Tanda Barang"
|
||||
v-model="tandaBarang"
|
||||
validation="required"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
type="text"
|
||||
label="Keadaan Barang"
|
||||
v-model="keadaanBarang"
|
||||
validation="required"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
type="number"
|
||||
label="Kuantiti Barang"
|
||||
v-model="kuantitiBarang"
|
||||
validation="required|number"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
type="select"
|
||||
label="Jenis Barang"
|
||||
v-model="jenisBarangDetail"
|
||||
:options="jenisBarangDetailOptions"
|
||||
validation="required"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
type="select"
|
||||
label="Jenis Barang Siber"
|
||||
v-model="jenisBarangSiber"
|
||||
:options="jenisBarangSiberOptions"
|
||||
validation="required"
|
||||
disabled
|
||||
/>
|
||||
|
||||
<!-- Barang Section -->
|
||||
<div class="mb-4">
|
||||
<h3 class="mb-2">Senarai Barang</h3>
|
||||
<table
|
||||
v-if="barangList.length > 0"
|
||||
class="w-full border-collapse border border-gray-300 mb-2"
|
||||
>
|
||||
<thead>
|
||||
<tr class="bg-gray-100">
|
||||
<th class="border border-gray-300 p-2">Jenis Barang</th>
|
||||
<th class="border border-gray-300 p-2">Kuantiti</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(barang, index) in barangList" :key="index">
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{
|
||||
barang.jenisBarangDetailLabel
|
||||
? barang.jenisBarangDetailLabel
|
||||
: barang.jenisBarangDetail
|
||||
}}
|
||||
</td>
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ barang.kuantitiBarang }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-else class="text-gray-500 mb-2">Tiada barang ditambah</div>
|
||||
</div>
|
||||
|
||||
<FormKit
|
||||
type="text"
|
||||
label="No Kertas Siasatan"
|
||||
v-model="noKertasSiasatan"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
type="text"
|
||||
label="No Laporan Polis"
|
||||
v-model="noLaporanPolis"
|
||||
disabled
|
||||
/>
|
||||
<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
|
||||
>
|
||||
<rs-button type="button" @click="confirmBatal" variant="primary"
|
||||
<!-- <rs-button type="button" @click="confirmBatal" variant="primary"
|
||||
>Tolak</rs-button
|
||||
>
|
||||
<rs-button type="submit" @click="confirmSah" variant="success"
|
||||
>Sah</rs-button
|
||||
>
|
||||
> -->
|
||||
<rs-button btn-type="submit" variant="success">Hantar</rs-button>
|
||||
</div>
|
||||
</FormKit>
|
||||
</rs-card>
|
||||
@ -128,11 +111,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const { $swal } = useNuxtApp();
|
||||
|
||||
const noSiri = ref(route.params.noSiri);
|
||||
|
||||
@ -143,26 +124,11 @@ const namaPenghantar = ref("");
|
||||
const pangkatPenghantar = ref("");
|
||||
const ringkasanKenyataanKes = ref("");
|
||||
const bilangan = ref(0);
|
||||
const jenisBarang = ref("");
|
||||
const tandaBarang = ref("");
|
||||
const keadaanBarang = ref("");
|
||||
const kuantitiBarang = ref(0);
|
||||
const jenisBarangDetail = ref("");
|
||||
const jenisBarangSiber = ref("");
|
||||
const barangList = ref([]);
|
||||
const noKertasSiasatan = ref("");
|
||||
const noLaporanPolis = ref("");
|
||||
|
||||
const jenisBarangDetailOptions = [
|
||||
"PASPORT",
|
||||
"MALPASS",
|
||||
"CAP KESELAMATAN",
|
||||
"CAP JARI",
|
||||
"PEMERIKSAAN",
|
||||
"I-KAD",
|
||||
"LAIN-LAIN",
|
||||
];
|
||||
|
||||
const jenisBarangSiberOptions = ["SIBER", "TULISAN TANGAN"];
|
||||
const jenisBarangDetailOptions = ref([]);
|
||||
|
||||
const navigateBack = () => {
|
||||
router.back();
|
||||
@ -177,12 +143,6 @@ const isFormValid = () => {
|
||||
pangkatPenghantar,
|
||||
ringkasanKenyataanKes,
|
||||
bilangan,
|
||||
jenisBarang,
|
||||
tandaBarang,
|
||||
keadaanBarang,
|
||||
kuantitiBarang,
|
||||
jenisBarangDetail,
|
||||
jenisBarangSiber,
|
||||
noKertasSiasatan,
|
||||
noLaporanPolis,
|
||||
];
|
||||
@ -192,35 +152,38 @@ const isFormValid = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const simpan = () => {
|
||||
const submitForm = async () => {
|
||||
if (isFormValid()) {
|
||||
console.log("Form data saved");
|
||||
} else {
|
||||
console.error("Please fill in all required fields.");
|
||||
}
|
||||
};
|
||||
try {
|
||||
const response = await $fetch(`/api/kaunter-permohonan/${noSiri.value}`, {
|
||||
method: "PUT",
|
||||
body: {
|
||||
ringkasanKenyataanKes: ringkasanKenyataanKes.value,
|
||||
noKertasSiasatan: noKertasSiasatan.value,
|
||||
noLaporanPolis: noLaporanPolis.value,
|
||||
},
|
||||
});
|
||||
|
||||
const submitForm = () => {
|
||||
if (isFormValid()) {
|
||||
console.log({
|
||||
namaPemohon: namaPemohon.value,
|
||||
pangkatPemohon: pangkatPemohon.value,
|
||||
noPegawaiPemohon: noPegawaiPemohon.value,
|
||||
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,
|
||||
});
|
||||
if (response.statusCode === 200) {
|
||||
await $swal.fire({
|
||||
title: "Berjaya!",
|
||||
text: "Permohonan telah berjaya dikemaskini.",
|
||||
icon: "success",
|
||||
confirmButtonText: "OK",
|
||||
});
|
||||
|
||||
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 {
|
||||
$swal.fire({
|
||||
title: "Ralat!",
|
||||
@ -260,75 +223,64 @@ const confirmSah = () => {
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
submitForm();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function generateSampleData(noSiri) {
|
||||
const randomNumber = (min, max) =>
|
||||
Math.floor(Math.random() * (max - min + 1) + min);
|
||||
const randomChoice = (arr) => arr[Math.floor(Math.random() * arr.length)];
|
||||
const fetchLookupData = async (type) => {
|
||||
try {
|
||||
const response = await $fetch(`/api/lookup?type=${type}`);
|
||||
if (response.statusCode === 200) {
|
||||
return response.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error fetching ${type} lookup data:`, error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const namaPemohon = [
|
||||
"Ali bin Abu",
|
||||
"Siti binti Ahmad",
|
||||
"Muthu a/l Rajan",
|
||||
"Lim Wei Ling",
|
||||
];
|
||||
const pangkat = ["Inspektor", "Sarjan", "Koperal", "Konstabel"];
|
||||
const jenisBarangOptions = [
|
||||
"Dokumen",
|
||||
"Peralatan Elektronik",
|
||||
"Senjata",
|
||||
"Dadah",
|
||||
"Barang Kemas",
|
||||
];
|
||||
const keadaanBarangOptions = ["Baik", "Sederhana", "Rosak"];
|
||||
const fetchExistingData = async (noSiri) => {
|
||||
try {
|
||||
const response = await $fetch(`/api/permohonan/${noSiri}`);
|
||||
if (response.statusCode === 200) {
|
||||
return response.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching existing data:", error);
|
||||
$swal.fire({
|
||||
title: "Ralat!",
|
||||
text: "Gagal mendapatkan data permohonan.",
|
||||
icon: "error",
|
||||
confirmButtonText: "OK",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
noSiri: noSiri,
|
||||
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(async () => {
|
||||
const existingData = await fetchExistingData(noSiri.value);
|
||||
|
||||
onMounted(() => {
|
||||
const sampleData = generateSampleData(noSiri.value);
|
||||
if (existingData) {
|
||||
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;
|
||||
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;
|
||||
jenisBarangDetailOptions.value = await fetchLookupData("jenis_barang");
|
||||
});
|
||||
|
||||
const { $swal } = useNuxtApp();
|
||||
const getJenisBarangLabel = (value) => {
|
||||
const option = jenisBarangDetailOptions.value.find(
|
||||
(opt) => opt.__original === value
|
||||
);
|
||||
return option ? option.label : value;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -62,7 +62,7 @@
|
||||
<div class="space-y-4">
|
||||
<h2 class="text-xl font-semibold">Butiran Pegawai</h2>
|
||||
<div
|
||||
v-for="role in ['PENYIASAT', 'PENGHANTAR', 'PENERIMA', 'PEMERIKSA']"
|
||||
v-for="role in ['PENYIASAT', 'PENGHANTAR', 'PEMERIKSA', 'PENERIMA']"
|
||||
:key="role"
|
||||
class="grid grid-cols-1 md:grid-cols-3 gap-4"
|
||||
>
|
||||
@ -71,8 +71,6 @@
|
||||
:name="`pegawai.${role}.nama`"
|
||||
:label="`${role} - Nama`"
|
||||
v-model="generatedData.pegawai[role].nama"
|
||||
validation="required"
|
||||
:validation-messages="{ required: 'Nama diperlukan' }"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
@ -80,8 +78,6 @@
|
||||
:name="`pegawai.${role}.pangkat`"
|
||||
:label="`${role} - Pangkat`"
|
||||
v-model="generatedData.pegawai[role].pangkat"
|
||||
validation="required"
|
||||
:validation-messages="{ required: 'Pangkat diperlukan' }"
|
||||
disabled
|
||||
/>
|
||||
<FormKit
|
||||
@ -89,8 +85,6 @@
|
||||
:name="`pegawai.${role}.noPegawai`"
|
||||
:label="`${role} - No Pegawai`"
|
||||
v-model="generatedData.pegawai[role].noPegawai"
|
||||
validation="required"
|
||||
:validation-messages="{ required: 'No Pegawai diperlukan' }"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
@ -99,6 +93,7 @@
|
||||
<!-- Peralatan and Langkah2 -->
|
||||
<div class="space-y-4">
|
||||
<FormKit
|
||||
v-model="generatedData.peralatan"
|
||||
type="textarea"
|
||||
name="peralatan"
|
||||
label="Peralatan"
|
||||
@ -107,6 +102,7 @@
|
||||
:rows="3"
|
||||
/>
|
||||
<FormKit
|
||||
v-model="generatedData.langkah2"
|
||||
type="textarea"
|
||||
name="langkah2"
|
||||
label="Langkah-langkah"
|
||||
@ -118,10 +114,11 @@
|
||||
|
||||
<!-- Dapatan -->
|
||||
<FormKit
|
||||
v-model="generatedData.dapatan.value"
|
||||
type="radio"
|
||||
name="dapatan"
|
||||
label="Dapatan"
|
||||
:options="['Tulen', 'Palsu', 'Tidak dapat dikenalpasti']"
|
||||
:options="dapatanOptions"
|
||||
validation="required"
|
||||
:validation-messages="{ required: 'Dapatan diperlukan' }"
|
||||
/>
|
||||
@ -130,7 +127,7 @@
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold mb-2">Document Tambahan</h2>
|
||||
<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">
|
||||
<FormKit
|
||||
type="text"
|
||||
@ -152,7 +149,7 @@
|
||||
</div>
|
||||
|
||||
<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
|
||||
>
|
||||
<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 { jsPDF } from "jspdf";
|
||||
|
||||
const { $swal } = useNuxtApp();
|
||||
const route = useRoute();
|
||||
const bahanBukti = route.params.bahanBukti;
|
||||
const reportID = route.params.reportID;
|
||||
|
||||
const generatedData = ref({
|
||||
kesId: "",
|
||||
@ -178,89 +176,119 @@ const generatedData = ref({
|
||||
pegawai: {
|
||||
PENYIASAT: { nama: "", pangkat: "", noPegawai: "" },
|
||||
PENGHANTAR: { nama: "", pangkat: "", noPegawai: "" },
|
||||
PENERIMA: { nama: "", pangkat: "", noPegawai: "" },
|
||||
PEMERIKSA: { nama: "", pangkat: "", noPegawai: "" },
|
||||
PENERIMA: { nama: "", pangkat: "", noPegawai: "" },
|
||||
},
|
||||
peralatan: "",
|
||||
langkah2: "",
|
||||
dapatan: "",
|
||||
documentTambahan: [],
|
||||
});
|
||||
// State to store dapatan options
|
||||
const dapatanOptions = ref([]);
|
||||
|
||||
onMounted(() => {
|
||||
// Simulate fetching system-generated data
|
||||
generatedData.value = {
|
||||
kesId: `KES${Math.floor(Math.random() * 1000000)
|
||||
.toString()
|
||||
.padStart(6, "0")}`,
|
||||
tagNo: `TAG${Math.floor(Math.random() * 10000)
|
||||
.toString()
|
||||
.padStart(4, "0")}`,
|
||||
jenisBrg: ["Dokumen", "Elektronik", "Senjata"][
|
||||
Math.floor(Math.random() * 3)
|
||||
],
|
||||
jenisPemeriksaan: ["Forensik", "Visual", "Kimia"][
|
||||
Math.floor(Math.random() * 3)
|
||||
],
|
||||
pegawai: {
|
||||
PENYIASAT: generatePegawai("KB"),
|
||||
PENGHANTAR: generatePegawai(),
|
||||
PENERIMA: generatePegawai(),
|
||||
PEMERIKSA: generatePegawai(),
|
||||
},
|
||||
};
|
||||
// Fetch dapatan options from the lookup API
|
||||
const fetchDapatanOptions = async () => {
|
||||
try {
|
||||
const { data } = await useFetch("/api/lookup?type=dapatan");
|
||||
if (data.value.statusCode === 200) {
|
||||
dapatanOptions.value = data.value.data.map((item) => ({
|
||||
label: item.label,
|
||||
value: item.value,
|
||||
}));
|
||||
} else {
|
||||
$swal.fire("Error", "Failed to fetch dapatan options.", "error");
|
||||
}
|
||||
} catch (error) {
|
||||
$swal.fire("Error", "Failed to load dapatan options.", "error");
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
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 = "") {
|
||||
const names = ["Ahmad", "Siti", "Mohd", "Nurul", "Lim", "Raj"];
|
||||
const surnames = ["Abdullah", "Tan", "Kumar", "Lee", "Muthu", "Hassan"];
|
||||
const pangkat = ["Inspektor", "Sarjan", "Koperal", "Konstabel"];
|
||||
// function generatePegawai(role = "") {
|
||||
// const names = ["Ahmad", "Siti", "Mohd", "Nurul", "Lim", "Raj"];
|
||||
// const surnames = ["Abdullah", "Tan", "Kumar", "Lee", "Muthu", "Hassan"];
|
||||
// const pangkat = ["Inspektor", "Sarjan", "Koperal", "Konstabel"];
|
||||
|
||||
return {
|
||||
nama: `${names[Math.floor(Math.random() * names.length)]} ${
|
||||
surnames[Math.floor(Math.random() * surnames.length)]
|
||||
}`,
|
||||
pangkat:
|
||||
role === "KB"
|
||||
? "Ketua Bahagian"
|
||||
: pangkat[Math.floor(Math.random() * pangkat.length)],
|
||||
noPegawai: `P${Math.floor(Math.random() * 100000)
|
||||
.toString()
|
||||
.padStart(5, "0")}`,
|
||||
};
|
||||
}
|
||||
// return {
|
||||
// nama: `${names[Math.floor(Math.random() * names.length)]} ${
|
||||
// surnames[Math.floor(Math.random() * surnames.length)]
|
||||
// }`,
|
||||
// pangkat:
|
||||
// role === "KB"
|
||||
// ? "Ketua Bahagian"
|
||||
// : pangkat[Math.floor(Math.random() * pangkat.length)],
|
||||
// noPegawai: `P${Math.floor(Math.random() * 100000)
|
||||
// .toString()
|
||||
// .padStart(5, "0")}`,
|
||||
// };
|
||||
// }
|
||||
|
||||
const submitForm = async (formData) => {
|
||||
console.log("Form submitted:", formData);
|
||||
// Implement your API call or form submission logic here
|
||||
try {
|
||||
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 doc = new jsPDF();
|
||||
|
||||
|
||||
// Set font sizes
|
||||
const titleSize = 16;
|
||||
const subtitleSize = 14;
|
||||
const normalSize = 10;
|
||||
|
||||
|
||||
// Add title
|
||||
doc.setFontSize(titleSize);
|
||||
doc.text("Laporan Bahan Bukti", 105, 20, { align: "center" });
|
||||
|
||||
|
||||
// Add case details
|
||||
doc.setFontSize(subtitleSize);
|
||||
doc.text("Butiran Kes", 20, 40);
|
||||
|
||||
|
||||
doc.setFontSize(normalSize);
|
||||
doc.text(`KES ID: ${generatedData.value.kesId}`, 30, 50);
|
||||
doc.text(`TAG NO: ${generatedData.value.tagNo}`, 30, 60);
|
||||
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
|
||||
doc.setFontSize(subtitleSize);
|
||||
doc.text("Butiran Pegawai", 20, 100);
|
||||
|
||||
|
||||
doc.setFontSize(normalSize);
|
||||
let yPos = 110;
|
||||
for (const [role, officer] of Object.entries(generatedData.value.pegawai)) {
|
||||
@ -270,28 +298,39 @@ const generatePDF = () => {
|
||||
doc.text(`No Pegawai: ${officer.noPegawai}`, 40, yPos + 30);
|
||||
yPos += 45;
|
||||
}
|
||||
|
||||
|
||||
// Add examination details
|
||||
doc.setFontSize(subtitleSize);
|
||||
doc.text("Butiran Pemeriksaan", 20, yPos);
|
||||
|
||||
|
||||
doc.setFontSize(normalSize);
|
||||
doc.text(`Peralatan: ${generatedData.value.peralatan || "N/A"}`, 30, yPos + 10);
|
||||
doc.text(`Langkah-langkah: ${generatedData.value.langkah2 || "N/A"}`, 30, yPos + 20);
|
||||
doc.text(
|
||||
`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);
|
||||
|
||||
|
||||
// Add additional documents
|
||||
if (generatedData.value.documentTambahan && generatedData.value.documentTambahan.length > 0) {
|
||||
yPos += 50;
|
||||
doc.setFontSize(subtitleSize);
|
||||
doc.text("Dokumen Tambahan", 20, yPos);
|
||||
|
||||
doc.setFontSize(normalSize);
|
||||
generatedData.value.documentTambahan.forEach((doc, index) => {
|
||||
doc.text(`${index + 1}. ${doc.nama}`, 30, yPos + 10 + (index * 10));
|
||||
});
|
||||
}
|
||||
|
||||
// if (
|
||||
// generatedData.value.documentTambahan &&
|
||||
// generatedData.value.documentTambahan.length > 0
|
||||
// ) {
|
||||
// yPos += 50;
|
||||
// doc.setFontSize(subtitleSize);
|
||||
// doc.text("Dokumen Tambahan", 20, yPos);
|
||||
|
||||
// doc.setFontSize(normalSize);
|
||||
// generatedData.value.documentTambahan.forEach((doc, index) => {
|
||||
// doc.text(`${index + 1}. ${doc.nama}`, 30, yPos + 10 + index * 10);
|
||||
// });
|
||||
// }
|
||||
|
||||
// Generate and download the PDF
|
||||
doc.save(`Laporan_${generatedData.value.kesId}.pdf`);
|
||||
};
|
@ -4,21 +4,25 @@
|
||||
<rs-card class="p-6">
|
||||
<div class="flex justify-between items-center">
|
||||
<h3 class="text-lg font-semibold">Status Semakan</h3>
|
||||
<rs-badge :variant="statusSemakan === 'Selesai' ? 'success' : 'warning'">
|
||||
<rs-badge
|
||||
:variant="statusSemakan === 'Selesai' ? 'success' : 'warning'"
|
||||
>
|
||||
{{ statusSemakan }}
|
||||
</rs-badge>
|
||||
</div>
|
||||
<div class="flex justify-between items-center mt-4">
|
||||
<h3 class="text-lg font-semibold">Status Penerimaan</h3>
|
||||
<rs-badge :variant="statusPenerimaan === 'Diterima' ? 'success' : 'danger'">
|
||||
<rs-badge
|
||||
:variant="statusPenerimaan === 'Diterima' ? 'success' : 'danger'"
|
||||
>
|
||||
{{ statusPenerimaan }}
|
||||
</rs-badge>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 justify-end mt-5">
|
||||
<rs-button @click="openSemakModal">Semak</rs-button>
|
||||
<rs-button @click="openTerimaModal">Terima</rs-button>
|
||||
<rs-button @click="openTolakModal">Tolak</rs-button>
|
||||
<div class="flex gap-2 mt-5">
|
||||
<rs-button @click="openSemakModal" variant="primary">Semak</rs-button>
|
||||
<rs-button @click="openTerimaModal" variant="success">Terima</rs-button>
|
||||
<rs-button @click="openTolakModal" variant="danger">Tolak</rs-button>
|
||||
</div>
|
||||
</rs-card>
|
||||
|
||||
@ -45,7 +49,7 @@
|
||||
}"
|
||||
:options-advanced="{
|
||||
sortable: true,
|
||||
responsive: true,
|
||||
|
||||
filterable: false,
|
||||
}"
|
||||
advanced
|
||||
@ -70,13 +74,17 @@
|
||||
<template v-slot:tindakan="data">
|
||||
<div class="flex gap-2">
|
||||
<rs-button
|
||||
@click="openEditModal(data.text, data.index)"
|
||||
@click="openEditModal(data.text.userID, data.text.assignID)"
|
||||
variant="info"
|
||||
size="sm"
|
||||
>
|
||||
<Icon name="ic:baseline-edit" size="1.2rem" />
|
||||
</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" />
|
||||
</rs-button>
|
||||
</div>
|
||||
@ -91,6 +99,7 @@
|
||||
<rs-card class="p-6">
|
||||
<h3 class="text-lg font-semibold mb-4">Bahan Bukti</h3>
|
||||
<rs-table
|
||||
v-if="evidences.length > 0"
|
||||
:data="evidences"
|
||||
:options="{
|
||||
variant: 'default',
|
||||
@ -99,7 +108,7 @@
|
||||
}"
|
||||
:options-advanced="{
|
||||
sortable: true,
|
||||
responsive: true,
|
||||
|
||||
filterable: false,
|
||||
}"
|
||||
advanced
|
||||
@ -114,9 +123,6 @@
|
||||
<th>Tindakan</th>
|
||||
</tr>
|
||||
</template>
|
||||
<template v-slot:no="data">
|
||||
{{ data.text }}
|
||||
</template>
|
||||
<template v-slot:jenisBarang="data">
|
||||
{{ data.text }}
|
||||
</template>
|
||||
@ -140,6 +146,9 @@
|
||||
</rs-button>
|
||||
</template>
|
||||
</rs-table>
|
||||
<div v-else class="text-center p-10">
|
||||
<p>Tidak ada bahan bukti yang terlibat.</p>
|
||||
</div>
|
||||
</rs-card>
|
||||
|
||||
<!-- Add/Edit Modal -->
|
||||
@ -172,7 +181,6 @@
|
||||
<template #footer> </template>
|
||||
</rs-modal>
|
||||
|
||||
<!-- Semak Modal -->
|
||||
<rs-modal v-model="showSemakModal" @close="closeSemakModal">
|
||||
<template #header>
|
||||
<h3>Semak Maklumat</h3>
|
||||
@ -227,8 +235,10 @@
|
||||
validation="required"
|
||||
/>
|
||||
<div class="flex justify-end gap-2 mt-4">
|
||||
<rs-button variant="danger" @click="closeSemakModal">Batal</rs-button>
|
||||
<rs-button variant="primary" type="submit">Hantar</rs-button>
|
||||
<rs-button variant="danger" @click="closeSemakModal"
|
||||
>Batal</rs-button
|
||||
>
|
||||
<rs-button variant="primary" btn-type="submit">Hantar</rs-button>
|
||||
</div>
|
||||
</FormKit>
|
||||
|
||||
@ -255,8 +265,10 @@
|
||||
}"
|
||||
/>
|
||||
<div class="flex justify-end gap-2 mt-4">
|
||||
<rs-button variant="danger" @click="closeSemakModal">Batal</rs-button>
|
||||
<rs-button variant="primary" type="submit">Hantar</rs-button>
|
||||
<rs-button variant="danger" @click="closeSemakModal"
|
||||
>Batal</rs-button
|
||||
>
|
||||
<rs-button variant="primary" btn-type="submit">Hantar</rs-button>
|
||||
</div>
|
||||
</FormKit>
|
||||
</template>
|
||||
@ -314,8 +326,10 @@
|
||||
validation="required"
|
||||
/>
|
||||
<div class="flex justify-end gap-2 mt-4">
|
||||
<rs-button variant="danger" @click="closeTerimaModal">Batal</rs-button>
|
||||
<rs-button variant="primary" type="submit">Hantar</rs-button>
|
||||
<rs-button variant="danger" @click="closeTerimaModal"
|
||||
>Batal</rs-button
|
||||
>
|
||||
<rs-button variant="primary" btn-type="submit">Hantar</rs-button>
|
||||
</div>
|
||||
</FormKit>
|
||||
</template>
|
||||
@ -335,12 +349,7 @@
|
||||
type="select"
|
||||
name="sebabPenolakan"
|
||||
label="Sebab penolakan permohonan"
|
||||
:options="[
|
||||
'Dokumen tidak lengkap',
|
||||
'Maklumat tidak tepat',
|
||||
'Tidak memenuhi syarat',
|
||||
'Lain-lain',
|
||||
]"
|
||||
:options="sebabPenolakanOptions"
|
||||
validation="required"
|
||||
:validation-messages="{
|
||||
required: 'Sila pilih sebab penolakan',
|
||||
@ -356,8 +365,10 @@
|
||||
}"
|
||||
/>
|
||||
<div class="flex justify-end gap-2 mt-4">
|
||||
<rs-button variant="secondary" @click="closeTolakModal">Batal</rs-button>
|
||||
<rs-button variant="danger" type="submit">Hantar</rs-button>
|
||||
<rs-button variant="secondary" @click="closeTolakModal"
|
||||
>Batal</rs-button
|
||||
>
|
||||
<rs-button variant="danger" btn-type="submit">Hantar</rs-button>
|
||||
</div>
|
||||
</FormKit>
|
||||
</template>
|
||||
@ -369,127 +380,294 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
|
||||
definePageMeta({
|
||||
layout: "default",
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const { $swal } = useNuxtApp();
|
||||
|
||||
// Status data
|
||||
const statusSemakan = ref("Selesai");
|
||||
const statusPenerimaan = ref("Diterima");
|
||||
|
||||
// Forensic Officers Data
|
||||
// State variables
|
||||
const showModal = ref(false);
|
||||
const forensicOfficers = ref([]);
|
||||
|
||||
// Evidence Data
|
||||
const evidences = ref([
|
||||
{
|
||||
no: 1,
|
||||
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 pegawaiOption = ref([]);
|
||||
const selectedPegawai = ref(null);
|
||||
const editMode = ref(false);
|
||||
const currentOfficerID = ref(null);
|
||||
const currentAssignID = ref(null);
|
||||
const isKetuaBahagian = ref(true);
|
||||
const isKetuaJabatan = ref(false);
|
||||
|
||||
// Modal Controls
|
||||
const showModal = ref(false);
|
||||
const editMode = ref(false);
|
||||
const selectedPegawai = ref(null);
|
||||
const sebabPenolakanOptions = ref([]);
|
||||
|
||||
// Sample pegawai listing (simulating API response)
|
||||
const pegawaiList = ref([]);
|
||||
const pegawaiOption = ref([
|
||||
{
|
||||
value: null,
|
||||
label: "Pilih Pegawai",
|
||||
},
|
||||
]);
|
||||
// Evidence Data
|
||||
const evidences = ref([]);
|
||||
|
||||
// Fetch pegawai list (simulated API call)
|
||||
const fetchPegawaiList = () => {
|
||||
// In a real scenario, this would be an API call
|
||||
pegawaiList.value = [
|
||||
{
|
||||
id: "PG001",
|
||||
nama: "Ahmad bin Ali",
|
||||
pangkat: "Inspektor",
|
||||
noPegawai: "PG12345",
|
||||
tindakan: 1,
|
||||
},
|
||||
{
|
||||
id: "PG002",
|
||||
nama: "Siti binti Omar",
|
||||
pangkat: "Sarjan",
|
||||
noPegawai: "PG67890",
|
||||
tindakan: 2,
|
||||
},
|
||||
{
|
||||
id: "PG003",
|
||||
nama: "Muthu a/l Rajan",
|
||||
pangkat: "Koperal",
|
||||
noPegawai: "PG24680",
|
||||
tindakan: 3,
|
||||
},
|
||||
];
|
||||
// Fetch the status data
|
||||
const fetchStatusData = async () => {
|
||||
try {
|
||||
const { data } = await useFetch(
|
||||
`/api/permohonan/${route.params.noSiri}/status`
|
||||
);
|
||||
|
||||
if (data.value.statusCode === 200) {
|
||||
statusSemakan.value = data.value.data.statusSemakan || "Belum Disemak";
|
||||
statusPenerimaan.value =
|
||||
data.value.data.statusPenerimaan || "Belum Diterima";
|
||||
} else {
|
||||
$swal.fire(
|
||||
"Error",
|
||||
"Gagal mendapatkan status semakan dan penerimaan.",
|
||||
"error"
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
$swal.fire("Error", "Gagal memuatkan data status.", "error");
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchPegawaiList();
|
||||
// Fetch reports (Bahan Bukti)
|
||||
const fetchReports = async () => {
|
||||
try {
|
||||
const { data } = await useFetch(
|
||||
`/api/permohonan/${route.params.noSiri}/reports`
|
||||
);
|
||||
|
||||
for (let index = 0; index < pegawaiList.value.length; index++) {
|
||||
pegawaiOption.value.push({
|
||||
value: pegawaiList.value[index].tindakan,
|
||||
label: `${pegawaiList.value[index].pangkat} ${pegawaiList.value[index].nama} (${pegawaiList.value[index].noPegawai})`,
|
||||
});
|
||||
if (data.value.statusCode === 200) {
|
||||
evidences.value = data.value.data || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching reports:", error);
|
||||
$swal.fire("Error", "Gagal mendapatkan senarai bahan bukti.", "error");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Computed property for form validation
|
||||
const isFormValid = computed(() => {
|
||||
return (
|
||||
// filter pegawaiList based on selectedPegawai
|
||||
pegawaiList.value.filter((p) => p.tindakan === selectedPegawai.value)
|
||||
);
|
||||
});
|
||||
// Fetch existing forensic officers and available officers
|
||||
const fetchAssignedOfficers = async () => {
|
||||
try {
|
||||
const { data } = await useFetch(
|
||||
`/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 = () => {
|
||||
editMode.value = false;
|
||||
selectedPegawai.value = null;
|
||||
fetchAvailableOfficers();
|
||||
showModal.value = true;
|
||||
};
|
||||
|
||||
const openEditModal = (pegawai, index) => {
|
||||
const openEditModal = (userID, assignID) => {
|
||||
editMode.value = true;
|
||||
selectedPegawai.value = pegawai;
|
||||
|
||||
console.log(selectedPegawai.value);
|
||||
console.log("index", index);
|
||||
currentOfficerID.value = userID;
|
||||
currentAssignID.value = assignID;
|
||||
selectedPegawai.value = null;
|
||||
fetchAvailableOfficers(); // Get updated available officers for edit mode
|
||||
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 = () => {
|
||||
showModal.value = false;
|
||||
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 = () => {
|
||||
if (editMode.value) {
|
||||
updatePegawai();
|
||||
@ -498,93 +676,15 @@ const handleSubmit = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const addNewPegawai = () => {
|
||||
console.log(selectedPegawai.value);
|
||||
if (selectedPegawai.value) {
|
||||
const selectedPegawai_ = pegawaiList.value.find(
|
||||
(p) => p.tindakan === selectedPegawai.value
|
||||
);
|
||||
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");
|
||||
}
|
||||
};
|
||||
// Fetch officers when the component mounts
|
||||
onMounted(() => {
|
||||
fetchStatusData();
|
||||
fetchAssignedOfficers();
|
||||
fetchReports(); // Fetch reports related to the permohonan
|
||||
});
|
||||
|
||||
const generateReport = (bahanBukti) => {
|
||||
console.log("Generate Report for:", bahanBukti);
|
||||
|
||||
navigateTo(`/kemaskini-daftar/laporan/${bahanBukti}`);
|
||||
};
|
||||
|
||||
@ -600,26 +700,11 @@ const closeSemakModal = () => {
|
||||
};
|
||||
|
||||
// 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
|
||||
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
|
||||
const showTerimaModal = ref(false);
|
||||
|
||||
@ -631,53 +716,19 @@ const closeTerimaModal = () => {
|
||||
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
|
||||
const showTolakModal = ref(false);
|
||||
|
||||
const openTolakModal = () => {
|
||||
const openTolakModal = async () => {
|
||||
await fetchSebabPenolakanOptions();
|
||||
showTolakModal.value = true;
|
||||
};
|
||||
|
||||
const closeTolakModal = () => {
|
||||
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>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped>
|
||||
/* Your existing styles */
|
||||
</style>
|
||||
|
@ -7,16 +7,16 @@
|
||||
<rs-card class="mt-4 py-2">
|
||||
<rs-table
|
||||
:data="tableData"
|
||||
:options='{
|
||||
variant: "default",
|
||||
:options="{
|
||||
variant: 'default',
|
||||
striped: true,
|
||||
borderless: true
|
||||
}'
|
||||
:options-advanced='{
|
||||
borderless: true,
|
||||
}"
|
||||
:options-advanced="{
|
||||
sortable: true,
|
||||
responsive: true,
|
||||
filterable: false
|
||||
}'
|
||||
|
||||
filterable: false,
|
||||
}"
|
||||
advanced
|
||||
>
|
||||
<template v-slot:header>
|
||||
@ -73,50 +73,29 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
const { $swal } = useNuxtApp();
|
||||
|
||||
definePageMeta({
|
||||
title: "Senarai Permohonan",
|
||||
});
|
||||
|
||||
const tableData = ref([
|
||||
{
|
||||
no: 1,
|
||||
noSiri: "1234567890",
|
||||
tarikhMasa: "2024-01-01 12:00:00",
|
||||
status: "Aktif",
|
||||
butiran: 1,
|
||||
},
|
||||
{
|
||||
no: 2,
|
||||
noSiri: "0987654321",
|
||||
tarikhMasa: "2024-02-01 14:30:00",
|
||||
status: "Aktif",
|
||||
butiran: 2,
|
||||
},
|
||||
{
|
||||
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,
|
||||
},
|
||||
]);
|
||||
// Reactive variable to store table data
|
||||
const tableData = ref([]);
|
||||
|
||||
// Fetch permohonan list from API
|
||||
const fetchPermohonan = async () => {
|
||||
try {
|
||||
const response = await useFetch("/api/permohonan");
|
||||
if (response.data.value.statusCode === 200) {
|
||||
// Populate tableData with the fetched permohonan list
|
||||
tableData.value = response.data.value.data;
|
||||
} else {
|
||||
console.error(response.data.value.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching permohonan data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const permohonanBaru = () => {
|
||||
navigateTo("/permohonan-temujanji/baru");
|
||||
@ -131,29 +110,40 @@ const lihat = (item) => {
|
||||
navigateTo(`/kemaskini-daftar/maklumat/${item}`);
|
||||
};
|
||||
|
||||
const hapus = (item) => {
|
||||
$swal
|
||||
.fire({
|
||||
title: "Anda pasti?",
|
||||
text: "Anda tidak akan dapat memulihkan semula data ini!",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonText: "Ya, hapuskan!",
|
||||
cancelButtonText: "Batal",
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// Perform deletion logic here
|
||||
console.log("Deleting item:", item);
|
||||
// Remove the item from the tableData
|
||||
const index = tableData.value.findIndex((row) => row.noSiri === item);
|
||||
if (index !== -1) {
|
||||
tableData.value.splice(index, 1);
|
||||
}
|
||||
$swal.fire("Dihapuskan!", "Data telah dihapuskan.", "success");
|
||||
const hapus = async (noSiri) => {
|
||||
const confirmation = await $swal.fire({
|
||||
title: "Anda pasti?",
|
||||
text: "Anda tidak akan dapat memulihkan semula data ini!",
|
||||
icon: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
cancelButtonColor: "#d33",
|
||||
confirmButtonText: "Ya, hapuskan!",
|
||||
cancelButtonText: "Batal",
|
||||
});
|
||||
|
||||
if (confirmation.isConfirmed) {
|
||||
try {
|
||||
const response = await useFetch(`/api/permohonan/${noSiri}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
if (response.data.value.statusCode === 200) {
|
||||
// Remove the deleted permohonan from tableData
|
||||
tableData.value = tableData.value.filter(
|
||||
(row) => row.noSiri !== noSiri
|
||||
);
|
||||
$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>
|
||||
|
@ -98,7 +98,11 @@
|
||||
<tbody>
|
||||
<tr v-for="(barang, index) in barangList" :key="index">
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ getJenisBarangLabel(barang.jenisBarangDetail) }}
|
||||
{{
|
||||
barang.jenisBarangDetailLabel
|
||||
? barang.jenisBarangDetailLabel
|
||||
: barang.jenisBarangDetail
|
||||
}}
|
||||
</td>
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ barang.kuantitiBarang }}
|
||||
@ -369,9 +373,19 @@ const cancelBarangModal = () => {
|
||||
|
||||
const saveBarangModal = () => {
|
||||
if (editingBarangIndex.value === null) {
|
||||
barangList.value.push({ ...currentBarang.value });
|
||||
barangList.value.push({
|
||||
...currentBarang.value,
|
||||
jenisBarangDetailLabel: getJenisBarangLabel(
|
||||
currentBarang.value.jenisBarangDetail
|
||||
),
|
||||
});
|
||||
} else {
|
||||
barangList.value[editingBarangIndex.value] = { ...currentBarang.value };
|
||||
barangList.value[editingBarangIndex.value] = {
|
||||
...currentBarang.value,
|
||||
jenisBarangDetailLabel: getJenisBarangLabel(
|
||||
currentBarang.value.jenisBarangDetail
|
||||
),
|
||||
};
|
||||
}
|
||||
isBarangModalOpen.value = false;
|
||||
};
|
||||
@ -445,10 +459,10 @@ const submitData = async (isDraft) => {
|
||||
icon: "success",
|
||||
confirmButtonText: "OK",
|
||||
});
|
||||
|
||||
|
||||
// Redirect to senarai page after successful submission
|
||||
if (!isDraft) {
|
||||
router.push('/permohonan-temujanji/senarai');
|
||||
router.push("/permohonan-temujanji/senarai");
|
||||
}
|
||||
} else {
|
||||
$swal.fire({
|
||||
|
@ -97,7 +97,11 @@
|
||||
<tbody>
|
||||
<tr v-for="(barang, index) in barangList" :key="index">
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ getJenisBarangLabel(barang.jenisBarangDetail) }}
|
||||
{{
|
||||
barang.jenisBarangDetailLabel
|
||||
? barang.jenisBarangDetailLabel
|
||||
: barang.jenisBarangDetail
|
||||
}}
|
||||
</td>
|
||||
<td class="border border-gray-300 p-2">
|
||||
{{ barang.kuantitiBarang }}
|
||||
@ -406,9 +410,19 @@ const cancelBarangModal = () => {
|
||||
|
||||
const saveBarangModal = () => {
|
||||
if (editingBarangIndex.value === null) {
|
||||
barangList.value.push({ ...currentBarang.value });
|
||||
barangList.value.push({
|
||||
...currentBarang.value,
|
||||
jenisBarangDetailLabel: getJenisBarangLabel(
|
||||
currentBarang.value.jenisBarangDetail
|
||||
),
|
||||
});
|
||||
} else {
|
||||
barangList.value[editingBarangIndex.value] = { ...currentBarang.value };
|
||||
barangList.value[editingBarangIndex.value] = {
|
||||
...currentBarang.value,
|
||||
jenisBarangDetailLabel: getJenisBarangLabel(
|
||||
currentBarang.value.jenisBarangDetail
|
||||
),
|
||||
};
|
||||
}
|
||||
isBarangModalOpen.value = false;
|
||||
};
|
||||
|
@ -20,7 +20,6 @@
|
||||
}"
|
||||
:options-advanced="{
|
||||
sortable: true,
|
||||
responsive: true,
|
||||
filterable: false,
|
||||
}"
|
||||
advanced
|
||||
@ -62,10 +61,7 @@
|
||||
<template v-slot:butiran="data">
|
||||
<div
|
||||
class="flex flex-wrap gap-2"
|
||||
v-if="
|
||||
data.value.status !== 'Sah' &&
|
||||
data.value.status !== 'Permohonan Dihantar'
|
||||
"
|
||||
v-if="data.value.status === 'Permohonan Draf'"
|
||||
>
|
||||
<!-- Button to navigate to the "Kemaskini" page for the selected permohonan -->
|
||||
<rs-button
|
||||
|
@ -106,8 +106,8 @@ model permohonan {
|
||||
penghantar penghantar? @relation(fields: [penghantarID], references: [id], onDelete: Cascade, onUpdate: Restrict, map: "permohonan_ibfk_1")
|
||||
permohonan_assign_forensik permohonan_assign_forensik[]
|
||||
permohonan_jenis_barang permohonan_jenis_barang[]
|
||||
permohonan_penerimaan permohonan_penerimaan[]
|
||||
permohonan_semakan permohonan_semakan[]
|
||||
permohonan_penerimaan permohonan_penerimaan?
|
||||
permohonan_semakan permohonan_semakan?
|
||||
report report[]
|
||||
|
||||
@@index([pemohonID], map: "idx_pemohon")
|
||||
@ -129,25 +129,24 @@ model permohonan_assign_forensik {
|
||||
|
||||
model permohonan_penerimaan {
|
||||
penerimaanID Int @id @default(autoincrement())
|
||||
permohonanID Int
|
||||
permohonanID Int @unique(map: "permohonanID")
|
||||
peralatan_keadaan_baik Int
|
||||
pegawai_berkelayakan Int
|
||||
kaedah_dpt_dilakukan Int
|
||||
subkontrak_diperlukan Int
|
||||
tugasan_diterima Int
|
||||
ulasan_pegawai Int?
|
||||
ulasan_pegawai String? @db.Text
|
||||
create_at DateTime @db.DateTime(0)
|
||||
diterima_oleh Int
|
||||
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")
|
||||
|
||||
@@index([diterima_oleh], map: "diterima_oleh")
|
||||
@@index([permohonanID], map: "permohonanID")
|
||||
}
|
||||
|
||||
model permohonan_penolakan {
|
||||
penolakanID Int @id @default(autoincrement())
|
||||
permohonanID Int
|
||||
permohonanID Int @unique(map: "permohonanID")
|
||||
sebab_penolakan Int
|
||||
lain_sebab String? @db.VarChar(255)
|
||||
create_at DateTime? @db.DateTime(0)
|
||||
@ -161,20 +160,19 @@ model permohonan_penolakan {
|
||||
|
||||
model permohonan_semakan {
|
||||
semakanID Int @id @default(autoincrement())
|
||||
permohonanID Int
|
||||
peralatan_keadaan_baik Int
|
||||
pegawai_berkelayakan Int
|
||||
kaedah_dpt_dilakukan Int
|
||||
subkontrak_diperlukan Int
|
||||
tugasan_diterima Int
|
||||
permohonanID Int @unique(map: "permohonanID")
|
||||
peralatan_keadaan_baik Int?
|
||||
pegawai_berkelayakan Int?
|
||||
kaedah_dpt_dilakukan Int?
|
||||
subkontrak_diperlukan Int?
|
||||
tugasan_diterima Int?
|
||||
ulasan_pegawai String? @db.Text
|
||||
create_at Int
|
||||
disemak_oleh Int
|
||||
create_at DateTime? @db.DateTime(0)
|
||||
disemak_oleh Int?
|
||||
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([permohonanID], map: "permohonanID")
|
||||
}
|
||||
|
||||
model role {
|
||||
@ -275,8 +273,11 @@ model report {
|
||||
reportID Int @id @default(autoincrement())
|
||||
permohonanID Int
|
||||
jenis_barang Int
|
||||
tanda_barang String? @db.VarChar(255)
|
||||
keadaan_barang String? @db.VarChar(255)
|
||||
kuantiti_barang Int?
|
||||
peralatan String? @db.VarChar(255)
|
||||
langkah_langkah Int?
|
||||
langkah_langkah String? @db.VarChar(255)
|
||||
gambarID Int?
|
||||
ulasan String? @db.Text
|
||||
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) => {
|
||||
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,
|
||||
},
|
||||
});
|
||||
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
|
||||
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) => ({
|
||||
label: lookup.lookupValue,
|
||||
value: lookup.lookupID,
|
||||
|
@ -22,7 +22,20 @@ export default defineEventHandler(async (event) => {
|
||||
},
|
||||
},
|
||||
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 || "",
|
||||
bilangan: permohonan.bilangan || 0,
|
||||
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 || "",
|
||||
keadaanBarang: barang.keadaan_barang || "",
|
||||
kuantitiBarang: barang.kuantiti_barang || 0,
|
||||
|
@ -127,21 +127,13 @@ export default defineEventHandler(async (event) => {
|
||||
});
|
||||
|
||||
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({
|
||||
data: {
|
||||
permohonanID: updatedPermohonan.id,
|
||||
jenis_barang: barang.jenisBarangDetail,
|
||||
kuantiti_barang: parseInt(barang.kuantitiBarang),
|
||||
tanda_barang: barang.tandaBarang,
|
||||
keadaan_barang: barang.keadaanBarang,
|
||||
create_by: userID,
|
||||
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
|
||||
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({
|
||||
data: {
|
||||
permohonanID: newPermohonan.id,
|
||||
jenis_barang: barang.jenisBarangDetail,
|
||||
kuantiti_barang: parseInt(barang.kuantitiBarang),
|
||||
tanda_barang: barang.tandaBarang,
|
||||
keadaan_barang: barang.keadaanBarang,
|
||||
create_by: userID,
|
||||
create_at: new Date(),
|
||||
},
|
||||
|
@ -2,24 +2,38 @@
|
||||
export default defineEventHandler(async () => {
|
||||
try {
|
||||
const permohonan = await prisma.permohonan.findMany({
|
||||
where: {
|
||||
status_permohonan: {
|
||||
notIn: ["Permohonan Ditolak"],
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
no_siri: true,
|
||||
create_at: true,
|
||||
status_permohonan: true,
|
||||
},
|
||||
orderBy: {
|
||||
create_at: "desc",
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
message: "Success",
|
||||
data: permohonan.map((item, index) => ({
|
||||
no: index + 1,
|
||||
noSiri: item.no_siri,
|
||||
tarikhMasa: item.create_at.toISOString().replace("T", " ").slice(0, 19),
|
||||
status: item.status_permohonan,
|
||||
butiran: item.id,
|
||||
})),
|
||||
data: permohonan.map((item, index) => {
|
||||
// Convert UTC to GMT+8
|
||||
const gmt8Date = new Date(
|
||||
item.create_at.getTime() + 8 * 60 * 60 * 1000
|
||||
);
|
||||
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) {
|
||||
return {
|
||||
|
Loading…
x
Reference in New Issue
Block a user