Compare commits

...

199 Commits

Author SHA1 Message Date
mikael-zakaria
d323d8a5c9 update printLabel to add commented label if changing printer 2026-02-18 09:12:56 +08:00
mikael-zakaria
5c0f876d05 Update + 15 untuk sudut Y untuk printer Lab Bali v2 2026-01-05 15:27:32 +07:00
mikael-zakaria
8e2d75d1d6 Update + 15 untuk sudut Y untuk printer Lab Bali 2026-01-05 15:16:13 +07:00
mikael-zakaria
43a860d108 Update Urutan BIOCHEMISTRY_23 diatas ENDOCHRONOLOGY_63 2025-11-10 15:30:20 +07:00
mikael-zakaria
9f348e05b8 Update Colspan Free text menjad 4 baris 2025-11-07 14:26:23 +08:00
mikael-zakaria
ca8955fa4e Update View Dashboard(fo,sampling,admin) : Patient#, Patient Name dan HIS# bisa di copy hanya dengan 2 klik 2025-10-01 15:18:39 +07:00
mikael-zakaria
dcb1981e70 Update Ip Printer Label Sampling Baliv2 2025-06-25 12:47:55 +07:00
mikael-zakaria
d449975a54 Update Ip Printer Label Sampling Bali 2025-06-25 12:43:47 +07:00
mikael-zakaria
e31cee76a7 Update indeirect bilirubin, rasio albumin, globulin dan chol menjadi serum 2025-06-05 13:30:30 +07:00
mikael-zakaria
f6b390f7f0 Update agar test BILIN tidak ditampilkan pada Laporan Hasil 2025-05-13 12:34:09 +07:00
mikael-zakaria
8070f5cdb5 Update Test FE pada Hematologi Bisa Merah 2025-05-10 11:06:36 +08:00
mikael-zakaria
7c3fcdcb2c Revert Back 2025-05-04 20:34:01 +07:00
mikael-zakaria
b0ba2a4df2 Update Untuk STC2 yang testcodenya Null v2 2025-05-04 20:31:04 +07:00
mikael-zakaria
c529c5e0b3 Update Untuk STC2 yang testcodenya Null 2025-05-04 20:29:44 +07:00
mikael-zakaria
9ec94ad3e1 Update Menghilangkan Excluded Red Pada Test : Anti HIV, Anti HCV, Anti HBs 2025-05-01 13:12:35 +07:00
mikael-zakaria
5e5b0047b4 Update Printer Lab ke Sampling Surabaya v2 2025-04-28 14:22:13 +07:00
mikael-zakaria
90483835bc Update Printer Lab ke Sampling Surabaya 2025-04-28 14:19:47 +07:00
mikael-zakaria
a4a2c74f1d Update Untuk Printer Barcode Surabaya Ruang Sampling 2025-04-24 15:27:38 +07:00
mikael-zakaria
7493768c5b Update Range L Reactive tidak Merah 2025-04-24 11:50:25 +08:00
mikael-zakaria
58be9960eb Update Tidak Menampilkan Test Group (ALB dan GLOB) 2025-04-14 14:22:29 +08:00
mikael-zakaria
3d9a34c713 Update Perbaikan Background Untuk PBMC Surabaya v2 2025-04-11 13:55:44 +07:00
mikael-zakaria
9709192ae8 Update Perbaikan Background Untuk PBMC Surabaya 2025-04-11 11:12:33 +07:00
mikael-zakaria
e4c6ff7cb1 update tidak menampilkan flagging untuk tes Hematology 2025-04-07 08:55:30 +07:00
mikael-zakaria
31824206fd Update Untuk Test HBSAB Jika High Maka Buat Merah 2025-04-06 04:03:49 +08:00
mikael-zakaria
76d9b1bbd7 Update test VDRL jika Reactive Warnai Merah 2025-04-04 16:49:27 +08:00
mikael-zakaria
75bfadc077 Update Hasil React HBSAG menjadi Merah dan Menampilkan test Malaria 2025-04-02 10:52:04 +08:00
mikael-zakaria
74a8c24138 Update Comment dan AHIV,AHCV,HBSAG,AHBS,HBSAB dan VDRL Agar Tidak Merah Saat Nilai Tidak Normal 2025-03-27 18:26:59 +07:00
mikael-zakaria
64514cfdc8 Update AHIV,AHCV,HBSAG,AHBS,HBSAB dan VDRL Agar Tidak Merah Saat Nilai Tidak Normal 2025-03-27 18:17:55 +07:00
mikael-zakaria
69270d1962 Update AHIV,AHCV,HBSAG,AHBS,HBSAB dan VDRL Agar Tidak Merah Saat Nilai Tidak Normal 2025-03-27 18:11:40 +07:00
mikael-zakaria
83310f88a4 Update AHIV,AHCV,HBSAG,AHBS,HBSAB dan VDRL Agar Tidak Merah Saat Nilai Tidak Normal 2025-03-27 17:32:00 +07:00
mikael-zakaria
e66c10d5e6 Update AHIV,AHCV,HBSAG,AHBS,HBSAB,VDRL Agar Tidak Merah Saat Nilai Tidak Normal 2025-03-27 17:24:47 +07:00
mikael-zakaria
45090dd254 Update Perbaikan PATID Menggunakan TD dan Nama Menggunakan TM Done 2025-03-19 14:04:12 +07:00
mikael-zakaria
0efe3bfcc0 Update API DASHBOARD 2025-03-19 13:41:24 +08:00
mikael-zakaria
1cd92dce7c Update Laporan Hasil Agar Bisa Menampilkan sampai 27 baris test 2025-03-19 10:15:19 +07:00
mikael-zakaria
b5d95eb695 Perbaikan untuk Waktu Pada Header Laporan Hasil 2025-03-19 08:49:30 +07:00
mikael-zakaria
67fc5c9a6b Update Laporan Hasil Menyembunyikan testcode EGFR, Baris ganda, test ganda ganda v3 2025-03-18 14:08:33 +07:00
mikael-zakaria
968b7677ac Update Laporan Hasil Menyembunyikan EGFR dengan kode 15, Baris kosong, test ganda ganda 2025-03-18 14:00:08 +07:00
mikael-zakaria
6bc67edca6 Update Hasil Serat Fiberv4 2025-03-17 18:29:18 +07:00
mikael-zakaria
9a53d00468 Update Hasil Serat Fiberv2 2025-03-17 18:28:11 +07:00
mikael-zakaria
3e79feb1a6 Update Hasil Serat Fiberv2 2025-03-17 18:25:11 +07:00
mikael-zakaria
0c509735e6 Update Hasil Serat Fiber 2025-03-17 18:18:21 +07:00
mikael-zakaria
e0565bfa21 Update DL flaging merah dirubah jadihitam dan Fat/lemak diubah flagging stool itu positive tetap hitam 2025-03-17 16:40:39 +08:00
mikael-zakaria
3fb064375b Update Nama Pasien Pada Laporan Hasil, Dashboard dan Viewaccess PatNumber 2025-03-17 14:29:39 +08:00
mikael-zakaria
1bbc38a481 Update Nama Dashboard Yang Kurang(Tidak pakai tabel Patients TD dan memakai TM PATIENTS) 2025-03-17 14:06:51 +08:00
mikael-zakaria
3ef0a7bbb0 Update Nilai test Fiber FMIFI Tidak Perlu merah jika hasil positive 2025-03-17 11:07:34 +08:00
mikael-zakaria
b4648c67b3 Update RM dan VN Pada Collection Label v2 2025-03-15 14:30:09 +08:00
mikael-zakaria
ff29d10f24 Update RM dan VN Pada Collection Label 2025-03-15 13:51:02 +08:00
mikael-zakaria
e85db5f5b2 Update Nama Sample Collection Pada Laporan Hasil 2025-03-15 12:58:01 +08:00
mikael-zakaria
be68c655f5 Update Nama Sample Laporan Hasil dan Label Sampling 2025-03-15 12:55:40 +08:00
mikael-zakaria
4dc20ac087 Update Menampilkan Reffid Pada Halaman Dashboard 2025-03-15 12:30:22 +08:00
mikael-zakaria
9157d8061a Update Sorting Datatable Dari yg Paling Baru 2025-03-15 08:45:55 +08:00
mikael-zakaria
fd72ab2534 Update menampilkan order yang cancelled dan juga menampilkan kembali unrichieved 2025-03-15 00:50:57 +08:00
mikael-zakaria
aa31a93939 Update Laporan Hasil(Header :, Ubah Format tgl, Ubah TTD dr Komang) 2025-03-15 00:05:50 +08:00
mikael-zakaria
69fcc8e464 Update Tanggal Dashboard 2025-03-14 22:43:54 +08:00
mikael-zakaria
3ff3840378 Update Header Logo Padma SBY dan Bali 2025-03-13 17:45:35 +08:00
mikael-zakaria
57b039cf83 Update Result Order Date agar tidak menampilkan tahun 1900 2025-03-13 14:13:16 +08:00
mikael-zakaria
b2692fd797 Update Perbaikan Surabaya 2025-03-13 10:06:01 +08:00
mikael-zakaria
b99321e56b Update Flags dan Nama Dr Komang dan Jarak Tabel ke Header 2025-03-13 09:41:44 +08:00
mikael-zakaria
d1e489ea45 Update Pebaikan Footer Agar Sesuai 2025-03-13 05:54:32 +08:00
mikael-zakaria
06a0f9943e Update Pebaikan Padding Table 2025-03-13 05:49:50 +08:00
mikael-zakaria
b8cc6f5977 Update Footer Laporan Hasil (Nama dan Posisi TTD Hasil) 2025-03-13 05:42:12 +08:00
mikael-zakaria
55569e96d1 Change Dashboard(Reff# menjadi Visit#, Hilangkan 0 pada Patnumber) dan Header Laporan REF menjadi Visit 2025-03-12 23:10:34 +08:00
mikael-zakaria
fefe36db53 Change Dashboard(Reff# menjadi Visit#, Hilangkan 0 pada Patnumber) dan Header Laporan REF menjadi Visit 2025-03-12 23:09:53 +08:00
mikael-zakaria
206ee53221 Update Laporan Result Agar ke kanan, Update Waktu Label Collection-Reception Laporan Hasil, Update Menghilangkan Fitur Unreceive pada Web Access 2025-03-12 11:28:39 +08:00
mikael-zakaria
670a3367a6 Perbaikan Collection Datetime dan Laporan Hasil 2025-03-10 16:37:58 +07:00
mikael-zakaria
4fc51b8250 Update Menampilkan Nilai Normal Pada Laporan Hasil 2025-03-10 14:02:56 +07:00
mikael-zakaria
1ef987c7c6 Update Nama Header RM Number Agar Tidak menampilkan 0 didepan 2025-03-10 08:40:47 +07:00
mikael-zakaria
63149e105d Update Minor Laporan Hasil Sesuai Dengan TM v3 2025-03-09 22:34:08 +07:00
mikael-zakaria
d675620e5f Update Minor Laporan Hasil Sesuai Dengan TM v2 2025-03-09 22:31:41 +07:00
mikael-zakaria
e2b6d6ae29 Update Laporan Hasil Sesuai Dengan TM 2025-03-09 22:28:56 +07:00
mikael-zakaria
4c99e3e017 Update Printer Barcode Ruang Sampling Bali, Nama File Barcode dan Views Sidebar All Role 2025-03-07 01:02:05 +07:00
mikael-zakaria
28dd621273 Update Order Testing dengan REFF_ID Z-->B dan X-->S 2025-03-06 13:36:50 +07:00
mikael-zakaria
c7cdb0a204 adding composer.json 2025-03-05 16:28:00 +08:00
mikael-zakaria
c55de1a7a3 Update Result Date Untuk Tiap Chapter Yang Dipisah 2025-03-04 12:40:54 +07:00
mikael-zakaria
bcd846799d Update menampilkan Units, jika CMOD tidak ada units maka otomatis tampilkan dari TD 2025-03-03 13:47:25 +07:00
mikael-zakaria
c4fcc468f4 Perbaikan Update Rescomment 2025-02-27 16:11:19 +07:00
mikael-zakaria
922b6c3e35 Update Rescomment pada Laporan Hasil 2025-02-27 15:42:43 +07:00
mikael-zakaria
106fc04a3d Update Desain & Birthdate Label untuk PBMC Bali 2025-02-26 11:17:40 +07:00
mikael-zakaria
318c79582c Update Normal Range & Unit Agar Bisa Menampilkan Enter 2025-02-25 11:44:33 +07:00
mikael-zakaria
8cb80adf9a Update Copy element Access# dan Reff# pada Dashboard 2025-02-11 14:48:20 +07:00
mikael-zakaria
def21a53e5 Update nama Reff dan Lokasi Laporan Berdasar Site 2025-02-10 16:23:39 +07:00
mikael-zakaria
79936abdff Update Penggantian VisitNumber ke ReffNumber 2025-02-10 11:43:25 +07:00
mikael-zakaria
2cd93e222a Update DoB Label Surabaya 2025-02-10 09:46:52 +07:00
mikael-zakaria
6188d39124 Update Label Sby Collection (Menambahkan DoB) 2025-02-07 14:49:06 +07:00
mikael-zakaria
748b668a80 Update Dashboard View Description & Dashboard Visit diganti menjadi Reffid 2025-02-07 12:42:51 +07:00
mikael-zakaria
55052b966e Update view dashboard admin visit type v2 2025-02-07 11:34:17 +07:00
mikael-zakaria
271c8d00f1 Update view dashboard admin visit type 2025-02-07 11:32:33 +07:00
mikael-zakaria
760f3ff06f Update view dashboard admin 2025-02-07 11:24:56 +07:00
mikael-zakaria
aa776d9c16 Update Nama pada Laporan dan Dashboard 2025-02-07 10:16:59 +07:00
mikael-zakaria
d469a71db2 update tampilan nama pasien di dashboard 2025-02-07 10:07:18 +07:00
mikael-zakaria
ec856e8f30 update barcode DoB dan Nama v3 2025-02-07 10:02:33 +07:00
mikael-zakaria
1c196d0b24 update barcode DoB dan Nama v2 2025-02-07 09:57:35 +07:00
mikael-zakaria
5c14c8f86a update barcode DoB dan Nama 2025-02-07 09:51:19 +07:00
mikael-zakaria
10b702443c update Api untuk menampilkan semua hostnumber berdasar B bali dan S Surabaya 2025-02-07 07:57:38 +07:00
mikael-zakaria
6aeb3aa672 Merge branch 'main' of https://github.com/mahdahar/cmod 2025-02-07 08:55:25 +08:00
mikael-zakaria
67337c4563 update api results 2025-02-07 08:55:10 +08:00
mikael-zakaria
234493ffb5 update nilai rentang pada laporan hasil 2025-02-07 07:09:53 +07:00
mikael-zakaria
eb225b5301 update layout tampilan laporan hasil 2025-02-06 10:17:20 +07:00
mikael-zakaria
adeea8daba update laporan hasil validasi, reffid(otw), TimeZones untuk user admin,lisfse,system ke wita, Tampilan data untuk api dashboard menjadi 25 2025-02-05 17:08:23 +07:00
mikael-zakaria
348b779a9f Update Hasil Laporan apabila tidak ada validasi maka jangan tampilkan footer dokter dan order index 2025-02-04 14:14:40 +07:00
mikael-zakaria
6a78b8c04a update minor 2025-02-04 10:47:51 +07:00
mikael-zakaria
c370b43bdc perbaikan dashboard home 2025-01-30 20:16:09 +07:00
mikael-zakaria
ddbc7c0623 Perbaikan user yang CityID bukan bali dan surabaya pada PDF 2025-01-28 16:00:43 +07:00
mikael-zakaria
0af3f4d7eb Menampilkan nama lengkap pasien di dashboard dan dashboard view cukup tekan status saja 2025-01-28 14:57:55 +07:00
mikael-zakaria
3e6db15d58 Update Users pada role Admin, Perbaikan pada User Afrita dan Login 2025-01-28 13:48:24 +07:00
14a05c0efb create TM Request Dashboard 2025-01-24 16:51:34 +07:00
mikael-zakaria
d4d2d9c64d Merge branch 'zakaria' 2025-01-21 16:39:48 +07:00
mikael-zakaria
fd9358d173 Perbaikan Format pada Collection Date dari 12 jam menjadi 24 jam 2025-01-21 16:39:09 +07:00
mikael-zakaria
16d7b38ef2 Merge branch 'zakaria' 2025-01-21 17:21:33 +08:00
mikael-zakaria
780d433c22 Update Waktu Collection(Bawah Laporan) dan Result(Atas) pada laporan Hasil Sesuai User Login (Bali/WITA) dan (Sby/WIB) 2025-01-21 17:20:46 +08:00
mikael-zakaria
86a0a3d858 add EGFR BW BH 2025-01-21 13:24:39 +08:00
mikael-zakaria
059cda06cd Perbaikan Order Time dan Result Time 2025-01-21 11:05:09 +07:00
mikael-zakaria
a0fe7505ec Perbaikan perbaikan null print result dan Create order sesuaikan berdasarkan lokasi user pada bagian Visir# dan Location 2025-01-20 10:57:53 +07:00
mikael-zakaria
4f0d34c635 update api_his back to default 2025-01-17 08:18:46 +07:00
mikael-zakaria
48e4f24be8 Merge branch 'zakaria' of https://github.com/mahdahar/cmod into zakaria 2025-01-17 08:17:26 +07:00
mikael-zakaria
39e0420f1e update ttd dokter dan no registrasi/sp number 2025-01-17 08:15:58 +07:00
mikael-zakaria
c54909e3b6 update ttd dokter dan no registrasi/sp number 2025-01-17 08:09:26 +07:00
mikael-zakaria
0479a51f2b Update nama dokter pada laporan hasil dan user yang melakukan validasi khusus untuk site surabaya 2025-01-14 10:05:36 +07:00
mikael-zakaria
32e34a6d77 Update Color Value Nilai Tidak Normal2 2025-01-13 22:41:37 +07:00
mikael-zakaria
e91137f1ea Update Color Value Nilai Tidak Normal 2025-01-13 22:39:45 +07:00
mikael-zakaria
85c609db1a Update Barcode TMS 24I Premium Success 2025-01-13 14:56:34 +07:00
mikael-zakaria
401b737a57 Update pembeda tampilan dashboard dan his orders untuk user bali dan sby. Update label untuk sample surabaya 2025-01-13 13:31:54 +07:00
mikael-zakaria
d7f10d279f Update orders_edit 2025-01-13 09:41:32 +07:00
mikael-zakaria
65302d0c5a Merge branch 'main' into zakaria 2025-01-10 13:08:49 +07:00
3d2b8d9402 express loc changer 2025-01-10 11:32:28 +07:00
mikael-zakaria
4ca00844ff update mayor agar user analis bisa membuat order dan print sby - bali berbeda 2025-01-09 22:14:52 +07:00
mikael-zakaria
60c6356e5a Update Khusus untuk user sby, routes, auth, controller printlabelsby, dashboarduser 2025-01-09 14:32:07 +07:00
da40324dee add dict_mapping tubeid 2025-01-07 16:11:44 +07:00
mikael-zakaria
187f5191fb Merge branch 'main' into zakaria 2025-01-07 08:30:43 +07:00
mikael-zakaria
e75a3308dd perbaikan laporan hasil kolom & free text 2025-01-07 08:29:50 +07:00
5d5a296f1f add crud dictTubes 2025-01-06 16:44:47 +07:00
mikael-zakaria
b7d9cf2bbe perbaikan hasil free text 2025-01-06 16:39:12 +07:00
mikael-zakaria
da67dda940 update red value, printable, panjang char untuk ditampilkan di hasil 2025-01-06 13:03:33 +07:00
mikael-zakaria
91df417ac0 Update Dict Mapping agar bisa isi sampai 44 hasil 2025-01-03 13:14:25 +07:00
mikael-zakaria
40b51769be Merge branch 'main' into zakaria
merge main to zakaria
2025-01-02 16:58:40 +07:00
mikael-zakaria
e7fae4a384 Update Minor_3 Hasil Test Pasien 2025-01-02 16:23:29 +07:00
mikael-zakaria
291f74766b Update Minor_2 Hasil Test Pasien 2025-01-02 16:14:56 +07:00
mikael-zakaria
4f2e45fe72 update minor hasil test pasien 2024-12-30 11:26:28 +07:00
mikael-zakaria
ca1d128f56 update minor hasil laporan 2024-12-30 09:29:14 +07:00
f6013827f6 change login page to use single bootstrap css 2024-12-26 16:51:31 +07:00
mikael-zakaria
f5514db2d5 Update Dashboard Access(Memunculkan Informasi Pasien dan Pemerikasaan) dan Perbaikan Patnumber null pada tampilan Dashboard 2024-12-26 10:44:41 +07:00
mikael-zakaria
d87278c017 update printlabel, barcode dan tampilan dashboard access 2024-12-20 09:18:45 +08:00
mikael-zakaria
97ee2d4e2c update font size barcode pada sam# dan req# 2024-12-19 22:10:07 +08:00
mikael-zakaria
76b0f69a56 Merge branch 'main' into zakaria
merge
2024-12-19 09:24:24 +08:00
mikael-zakaria
b67a68f8a9 update label collection 2024-12-19 09:23:12 +08:00
97e1190f52 result fix coll receive, fix unittext 2024-12-19 08:13:27 +07:00
mikael-zakaria
871a5e1cde Penggantian Label untuk LAB alat TMS30 2024-12-18 23:08:34 +08:00
605b02505a fix unreceive, update tubestatus=0 2024-12-18 20:55:11 +07:00
mikael-zakaria
059f5ce04a Merge branch 'main' into zakaria
merge
2024-12-18 10:23:59 +08:00
b8a4f35eff fix patnumber empty, change merge sample if datetime is the same coll/recv 2024-12-18 09:18:38 +07:00
mikael-zakaria
ad0d06ced7 Merge branch 'main' into zakaria
ok
2024-12-18 09:31:44 +08:00
mikael-zakaria
52168d545e Update penulisan Serum-imun dan Serum-kimia Label 2024-12-18 09:29:45 +08:00
8f0d1e3c2e replace unit, with cm_dict_test unit 2024-12-17 09:52:07 +07:00
mikael-zakaria
736ea4d356 Perbaikan Label(RM, VN, Colldate) dan Hasil Result 2024-12-17 08:42:59 +08:00
mikael-zakaria
a184263214 Merge branch 'main' into zakaria 2024-12-16 11:09:59 +08:00
mikael-zakaria
c2dc8cae56 Perbaikan printer label ke Lab dan Sampling 2024-12-16 09:03:51 +08:00
2b8832e32e remove pat* from APIorder, add resend success alert 2024-12-15 16:25:39 +07:00
mikael-zakaria
f52c4196b9 Merge branch 'main' into zakaria
gas
2024-12-15 15:43:36 +08:00
e5b46367a5 change edit patient -> patient editor, add order editor 2024-12-15 14:36:57 +07:00
mikael-zakaria
f4fa370a64 Merge branch 'main' into zakaria 2024-12-15 08:28:40 +08:00
1500275f6f fixing tiny HIS 2024-12-14 16:39:06 +07:00
mikael-zakaria
315a5a5157 Merge branch 'main' into zakaria 2024-12-14 14:30:52 +08:00
9291f23b32 fix order creation 2024-12-14 13:21:01 +07:00
mikael-zakaria
ef0d4df513 Merge branch 'main' into zakaria 2024-12-14 12:05:09 +08:00
mikael-zakaria
acb94a7d5a update shadow card 2024-12-14 12:03:43 +08:00
7ed98aa9f6 add column on mapping profile 2024-12-14 10:00:45 +07:00
mikael-zakaria
3e0e284362 Perbaikan Laporan Hasil Feces Tidak Sesuai 2024-12-13 17:01:48 +08:00
12783ee72e add HIS order CRUD 2024-12-13 14:20:14 +07:00
mikael-zakaria
4edc2ca96f Perbaikan Laporan Hasil, Menambahlan ResFlag, Menambahkan Depth dan menampilkan Serum Type 2024-12-12 22:17:15 +08:00
mikael-zakaria
e39ea6544a perbaikan nama <tr> tabel dan dashboard access 2024-12-12 12:48:51 +08:00
mikael-zakaria
35f480c341 update Header, Result tambah Sample 2024-12-11 17:54:38 +08:00
mikael-zakaria
f2a2ff7650 perbaikan penambahan padding tabel agar elemen lebih ke kekanan 2024-12-09 21:00:15 +08:00
mikael-zakaria
1598e01c89 update serum dibawah note 2024-12-09 20:53:46 +08:00
mikael-zakaria
5efe2b1218 Merge branch 'main' into zakaria 2024-12-09 15:06:23 +08:00
mikael-zakaria
191a050644 Update Tampilan View Access Pasien 2024-12-09 15:05:47 +08:00
924ed2354a first refactor printLabel printResult 2024-12-09 13:10:16 +07:00
c12efe19d2 update dashboard f5 2024-12-08 16:53:13 +07:00
mikael-zakaria
a5b31960d7 perbaikan hasil laporan 2024-12-08 17:31:18 +08:00
mikael-zakaria
4a3ce59b11 update2 NOTE pada Hasil Test -zaka edisi salah commit 2024-12-08 16:09:54 +08:00
mikael-zakaria
ae44159ccd update NOTE pada Hasil Test -zaka edisi salah commit 2024-12-08 16:06:11 +08:00
mikael-zakaria
d8cc5730b4 Merge branch 'main' into zakaria 2024-12-08 15:16:14 +08:00
c9be0ecace fix dictChapters view 2024-12-08 14:15:24 +07:00
mikael-zakaria
8958d08dfe perbaikan pdf array, memisahkan test feces, urine, others berdasarkan chapid, membuat laporan hasil menjadi garis border 2024-12-08 15:14:05 +08:00
66d2211b05 fix counter dashboard, fix css layout sidenav on 992px 2024-12-08 09:16:02 +07:00
mikael-zakaria
0a687cf760 Update Tamplian, User, FO, Admin, Sampling 2024-12-07 19:46:42 +08:00
mikael-zakaria
55762ca7fb perbaikan semua dashboard admin_user_fo 2024-12-07 17:00:21 +08:00
mikael-zakaria
86046bdff7 Merge branch 'main' into zakaria
gas
2024-12-07 15:52:01 +08:00
mikael-zakaria
8cfeb44ae0 Update Tampilan Dashboard & View Acces Admin 2024-12-07 15:37:03 +08:00
4648370363 add dict chapters, fix dict test 2024-12-07 13:35:34 +07:00
532316aa76 add date on dashboard 2024-12-07 09:25:13 +07:00
mikael-zakaria
4254ab3924 Merge branch 'main' into zakaria 2024-12-07 08:59:56 +08:00
f9d7317dea fix mapping profile 2024-12-06 16:10:12 +07:00
mikael-zakaria
57a23a307e Perbaikan Printer FO dan Tampilan Hasil Test 2024-12-06 11:40:27 +08:00
mikael-zakaria
344633f0ea Menambahkan Fitur Print and Preview PDF 2024-12-06 10:47:51 +08:00
968938a100 change mapping desc to varchar 250/textarea 2024-12-06 08:51:48 +07:00
mikael-zakaria
8ee919d733 Add Feature Printer Barcode - Single & All Sample Print 2024-12-05 18:58:52 +08:00
mikael-zakaria
3d36283095 Add Feature Printer Barcode - Single Sample Print 2024-12-05 16:59:28 +08:00
a262c66059 dict mapping order done 2024-12-05 14:49:27 +07:00
8fdad44f80 rbac done 2024-12-04 11:11:02 +07:00
103 changed files with 8221 additions and 480 deletions

4
.gitignore vendored
View File

@ -4,5 +4,5 @@
!cmod.7z
!.gitignore
!env
!cmod.sql
!cmod.bak
!_message/
!composer.json

View File

@ -133,7 +133,7 @@ class App extends BaseConfig
* @see https://www.php.net/manual/en/timezones.php for list of timezones
* supported by PHP.
*/
public string $appTimezone = 'UTC';
public string $appTimezone = 'Asia/Makassar';
/**
* --------------------------------------------------------------------------

View File

@ -34,7 +34,7 @@ class Filters extends BaseFilters
'forcehttps' => ForceHTTPS::class,
'pagecache' => PageCache::class,
'performance' => PerformanceMetrics::class,
'auth' => \App\Filters\Auth::class,
'role' => \App\Filters\RoleFilter::class,
];
/**
@ -70,14 +70,17 @@ class Filters extends BaseFilters
*/
public array $globals = [
'before' => [
'auth' => [ 'except' => [
'role' => [ 'except' => [
'auth/*', 'setup', 'api/*'
]]
]],
// 'honeypot',
// 'csrf',
// 'invalidchars',
],
'after' => [
'toolbar' => [
'except' => ['api/*', 'prints/*', 'prints/result_test/*'],
],
// 'honeypot',
// 'secureheaders',
],

View File

@ -5,47 +5,137 @@ use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
/*
// Pages
$routes->get('/', 'Pages::dashboard_index');
$routes->get('/userroles/', 'Pages::userroles_index');
$routes->get('/users/', 'Pages::users_index');
$routes->get('/changePass/', 'Pages::changePass');
$routes->get('/dictTests/', 'Pages::dictTests_index');
// Tubes
$routes->get('/tubes/collect/(:any)/(:any)', 'Tubes::collect/$1/$2');
$routes->get('/tubes/collectAll/(:any)', 'Tubes::collectAll/$1');
$routes->get('/tubes/uncollect/(:any)/(:any)', 'Tubes::uncollect/$1/$2');
$routes->get('/tubes/uncollectAll/(:any)', 'Tubes::uncollectAll/$1');
$routes->get('/tubes/unreceive/(:any)/(:any)', 'Tubes::unreceive/$1/$2');
$routes->get('/tubes/unreceiveAll/(:any)', 'Tubes::unreceiveAll/$1');
$routes->post('/tubes/comment/(:any)/(:any)', 'Tubes::comment/$1/$2');
$routes->get('/dashboard/viewAccess/(:any)', 'Dashboard::viewAccess/$1');
*/
// Auth
$routes->get('/auth/logout', 'Auth::logout');
$routes->get('/auth/loginTD', 'Auth::loginTD');
$routes->match(['get','post'], '/auth/login', 'Auth::login');
$routes->match(['get','post'], '/auth/setpass/(:any)', 'Auth::setpass/$1');
$routes->get('/', 'Auth::redirects');
$routes->get('changePass/', 'Auth::changePass');
// API - Dashboard
$routes->get('/api/dashboard/index', 'Dashboard::index');
$routes->POST('/api/dashboard/index', 'API_Dashboard::index');
// API - Tubes
$routes->get('/tubes/collect/(:any)/(:any)', 'API_Tubes::collect/$1/$2');
$routes->get('/tubes/collectAll/(:any)', 'API_Tubes::collectAll/$1');
$routes->get('/tubes/uncollect/(:any)/(:any)', 'API_Tubes::uncollect/$1/$2');
$routes->get('/tubes/uncollectAll/(:any)', 'API_Tubes::uncollectAll/$1');
$routes->get('/tubes/unreceive/(:any)/(:any)', 'API_Tubes::unreceive/$1/$2');
$routes->get('/tubes/unreceiveAll/(:any)', 'API_Tubes::unreceiveAll/$1');
$routes->post('/tubes/comment/(:any)/(:any)', 'API_Tubes::comment/$1/$2');
// API - Userroles
$routes->get('/api/userroles/index', 'Userroles::index');
$routes->get('/api/userroles/detail/(:any)', 'Userroles::detail/$1');
$routes->post('/api/userroles/save/(:any)', 'Userroles::save/$1');
$routes->get('/api/userroles/index', 'API_Userroles::index');
$routes->get('/api/userroles/detail/(:any)', 'API_Userroles::detail/$1');
$routes->post('/api/userroles/save/(:any)', 'API_Userroles::save/$1');
// API - Users
$routes->get('/api/users/index', 'Users::index');
$routes->get('/api/users/detail/(:any)', 'Users::detail/$1');
$routes->post('/api/users/savePass/(:any)', 'Users::savePass/$1');
$routes->post('/api/users/saveRole/(:any)', 'Users::saveRole/$1');
$routes->get('/api/users/index', 'API_Users::index');
$routes->get('/api/users/detail/(:any)', 'API_Users::detail/$1');
$routes->post('/api/users/savePass/(:any)', 'API_Users::savePass/$1');
$routes->post('/api/users/saveRole/(:any)', 'API_Users::saveRole/$1');
// API - DictTests
$routes->POST('/api/dictTests/search', 'DictTests::search');
$routes->POST('/api/dictTests/save', 'DictTests::save');
$routes->get('/api/dictTests/index', 'DictTests::index');
$routes->get('/api/dictTests/detail/(:any)', 'DictTests::detail/$1');
$routes->POST('api/dictTests/search', 'API_DictTests::search');
$routes->POST('api/dictTests/save', 'API_DictTests::save');
$routes->get('api/dictTests/index', 'API_DictTests::index');
$routes->get('api/dictTests/detail/(:any)', 'API_DictTests::detail/$1');
// API - DictTubes
$routes->POST('api/dictTubes/save', 'API_DictTubes::save');
$routes->get('api/dictTubes/index', 'API_DictTubes::index');
$routes->get('api/dictTubes/detail/(:any)', 'API_DictTubes::detail/$1');
// API - DictMappings
$routes->POST('api/dictMappings/search', 'API_DictMappings::search');
$routes->get('api/dictMappings/index', 'API_DictMappings::index');
$routes->POST('api/dictMappings/saveSingle', 'API_DictMappings::saveSingle');
$routes->POST('api/dictMappings/saveProfile', 'API_DictMappings::saveProfile');
$routes->get('api/dictMappings/detail/(:any)', 'API_DictMappings::detail/$1');
// API - DictChapters
$routes->get('api/dictChapters/index', 'API_DictChapters::index');
$routes->POST('api/dictChapters/save', 'API_DictChapters::save');
$routes->get('api/dictChapters/detail/(:any)', 'API_DictChapters::detail/$1');
// API - Orders
$routes->POST('api/orders/index', 'API_HISOrders::index');
$routes->POST('api/orders/save', 'API_HISOrders::save');
$routes->GET('api/orders/resend/(:any)', 'API_HISOrders::resend/$1');
$routes->get('api/orders/detail/(:any)', 'API_HISOrders::detail/$1');
// API - Patients
$routes->get('api/patients/patnumberSearch/(:any)', 'API_HISPatients::patnumberSearch/$1');
$routes->POST('api/patients/search/', 'API_HISPatients::search');
$routes->get('api/patients/detail/(:any)', 'API_HISPatients::detail/$1');
$routes->POST('api/patients/save', 'API_HISPatients::save');
// API - For TM
$routes->get('api/his/dictTests', 'API_HIS::dictTests');
$routes->get('api/his/results/(:any)', 'API_HIS::results/$1');
$routes->POST('api/his/requests', 'API_HIS::requests');
// API - TM Request
$routes->post('api/tm/index', 'API_DashboardTM::index');
// admin
$routes->group('admin', ['filter' => 'role:admin'], static function ($routes) {
$routes->get('', 'AdminController::index');
$routes->get('dashboard/viewAccess/(:any)', 'AdminController::viewAccess/$1');
$routes->get('orders/', 'AdminController::orders_index');
$routes->get('orders/create/', 'AdminController::orders_edit/0');
$routes->get('orders/edit/(:any)', 'AdminController::orders_edit/$1');
$routes->get('patients/', 'AdminController::patients_index');
$routes->get('userroles/', 'AdminController::userroles_index');
$routes->get('users/', 'AdminController::users_index');
$routes->get('dictTests/', 'AdminController::dictTests_index');
$routes->get('dictChapters/', 'AdminController::dictChapters_index');
$routes->get('dictMappings/', 'AdminController::dictMappings_index');
$routes->get('dictTubes/', 'AdminController::dictTubes_index');
$routes->get('tm/', 'AdminController::tm_index');
});
// user
$routes->group('user', ['filter' => 'role:user'], static function ($routes) {
$routes->get('', 'UserController::index');
$routes->get('dashboard/viewAccess/(:any)', 'UserController::viewAccess/$1');
$routes->get('orders/', 'UserController::orders_index');
$routes->get('orders/create/', 'UserController::orders_edit/0');
$routes->get('orders/edit/(:any)', 'UserController::orders_edit/$1');
$routes->get('patients/', 'UserController::patients_index');
});
// sampling
$routes->group('sampling', ['filter' => 'role:sampling'], static function ($routes) {
$routes->get('', 'samplingController::index');
$routes->get('dashboard/viewAccess/(:any)', 'SamplingController::viewAccess/$1');
});
// fo
$routes->group('fo', ['filter' => 'role:fo'], static function ($routes) {
$routes->get('', 'FoController::index');
$routes->get('dashboard/viewAccess/(:any)', 'FoController::viewAccess/$1');
});
// Printers Bali
$routes->get('printLabel/collection/(:any)', 'PrintLabel::labelCollection/$1');
$routes->get('printLabel/single/(:any)/(:any)', 'PrintLabel::printSingle/$1/$2');
$routes->get('printLabel/all/(:any)', 'PrintLabel::printAll/$1');
// Printers Surabaya
$routes->get('printLabelSby/collection/(:any)', 'PrintLabelSby::labelZebraCollection/$1');
$routes->get('printLabelSby/single/(:any)/(:any)', 'PrintLabelSby::printSingle/$1/$2');
$routes->get('printLabelSby/all/(:any)', 'PrintLabelSby::printAll/$1');
$routes->get('printResult/(:any)', 'PrintResult::printResultTest/$1');

View File

@ -119,4 +119,5 @@ class Toolbar extends BaseConfig
public array $watchedExtensions = [
'php', 'css', 'js', 'html', 'svg', 'json', 'env',
];
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class API_Dashboard extends ResourceController {
protected $format = 'json';
public function index() {
// Mengetahui Apakah User Login adalah Bali atau Surabaya
$cityid = session()->get('usercityid');
if ($cityid == 1) {
$filter_query = " AND (tr.REQNUMBER LIKE 'B%' OR tr.REQNUMBER LIKE 'Z%')";
} elseif ($cityid == 2) {
$filter_query = " AND (tr.REQNUMBER LIKE 'S%' OR tr.REQNUMBER LIKE 'X%')";
} else { $filter_query = " "; }
$db = \Config\Database::connect();
$date1 = $this->request->getPost('date1');
$date2 = $this->request->getPost('date2');
$sql = "SELECT
sr.COLLECTIONDATE, sr.SP_ACCESSNUMBER, sr.HOSTORDERNUMBER as REFFID, tr.REQNUMBER as HOSTORDERNUMBER, tr.REQSTATUS, p.PATNUMBER, concat(tp.FIRSTNAME, ' ', tp.lastname) as NAME,
TESTS=stuff(( select ', '+'('+T.SP_TESTCODE+')' from
( select T.SP_TESTCODE from SP_TESTS T
where T.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
and T.DEPTH=0 AND T.SP_TESTCODE <> 'Q'
) as T
for xml path('')),1,1,''),
case
when exists (select 1 from AUDIT_TRAIL at where at.ATR_ACCESSNUMBER=sr.SP_ACCESSNUMBER and at.STEPTYPE=2 and at.LIS_SESSION='RFC' ) then
case
when exists (select 1 from SP_TUBES st where st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER and st.TUBESTATUS=0 ) then 'PartRecv'
when exists (select 1 from TESTS T where T.REQUESTID=r.REQUESTID and T.RESTYPE IN (null,'0') ) then 'Inc'
--when exists (select 1 from TESTS T where T.REQUESTID=r.REQUESTID and T.RESTYPE IN (null,'0') and T.TESTID='1805' ) then 'Inc'
else 'Comp'
end
-- inc
when exists (select 1 from TESTS T where T.RESTYPE not in (0,4) and T.REQUESTID=r.REQUESTID ) then
case
when exists ( select 1 from cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER and T.COLLSTATUS=0 ) then 'PartColl'
when exists (select 1 from SP_TUBES st where st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER and st.TUBESTATUS=0 ) then 'PartRecv'
else 'Inc'
end
--rcv
when not exists (select 1 from SP_TUBES st where st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER and st.TUBESTATUS=0 ) then
case
when exists (select 1 from cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER and T.COLLSTATUS=0 ) then 'PartColl'
else 'Recv'
end
--coll
when exists (select 1 FROM cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER ) then
case
when exists (select 1 from SP_TUBES st where st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER and st.TUBESTATUS=4 ) then 'PartRecv'
when not exists (select 1 from cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER and T.COLLSTATUS=0 ) then 'Coll'
when exists (select 1 from cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER and T.COLLSTATUS=1 ) then 'PartColl'
else 'Pend'
end
else 'Pend'
end STATS
from SP_REQUESTS sr
left join REQUESTS r on r.ACCESSNUMBER=sr.SP_ACCESSNUMBER
left join cmod.dbo.CM_TM_REQUESTS tr on tr.REFFID = sr.HOSTORDERNUMBER
--left join cmod.dbo.CM_TM_PATIENTS tp on tr.PATID = tp.PATID
left join PATIENTS p on sr.PATID = p.PATID
left join cmod.dbo.CM_TM_PATIENTS tp on tp.PATNUMBER = LTRIM(p.patnumber, '0')
where sr.COLLECTIONDATE between '$date1 00:00' and '$date2 23:59'"
.$filter_query.
"order by sr.COLLECTIONDATE desc";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['data'] = $results;
$data['count'] = array_count_values(array_column($results, 'STATS'));
return $this->respond($data,200);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class API_DashboardTM extends ResourceController {
protected $format = 'json';
public function index() {
$db = \Config\Database::connect();
$date1 = $this->request->getPost('date1');
$date2 = $this->request->getPost('date2');
$sql = "select r.REQID, r.REFFID, sr.SP_ACCESSNUMBER, r.REQTYPE, p.PATNUMBER, p.FIRSTNAME, p.LASTNAME, r.REQDATE, r.LOGDATE,
TESTS = STUFF((
SELECT ', ',HISCODE
FROM cmod.dbo.CM_TM_TESTS
WHERE REQID= r.REQID
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
from cmod.dbo.CM_TM_REQUESTS r
left join cmod.dbo.CM_TM_PATIENTS p on r.PATID=p.PATID
left join SP_REQUESTS sr on sr.HOSTORDERNUMBER=r.REFFID
--where r.REQDATE between '$date1 00:00' and '$date2 23:59'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['data'] = $results;
return $this->respond($data,200);
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class API_DictChapters extends ResourceController {
protected $format = 'json';
public function index() {
$db = \Config\Database::connect();
$sql = "select dc.CHAPCODE, dc.SHORTTEXT, cdc.TEXT1, cdc.TEXT2 from DICT_CHAPTERS dc
left join cmod.dbo.CM_DICT_CHAPTERS cdc on dc.CHAPCODE=cdc.CHAPCODE
where left(dc.SHORTTEXT,2)<>'CH'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['dictChapters'] = $results;
return $this->respond($data, 200);
}
public function detail($chapcode) {
$data = array();
$db = \Config\Database::connect();
$sql = "select dc.CHAPCODE, dc.SHORTTEXT, cdc.TEXT1, cdc.TEXT2 from DICT_CHAPTERS dc
left join cmod.dbo.CM_DICT_CHAPTERS cdc on dc.CHAPCODE=cdc.CHAPCODE
where dc.CHAPCODE='$chapcode'";
$query = $db->query($sql);
$results = $query->getResultArray();
if(isset($results[0])) { $data = $results[0]; }
return $this->respond($data, 200);
}
public function save() {
$chapcode = $this->request->getPost('chapcode');
$text1 = $this->request->getPost('text1');
$text2 = $this->request->getPost('text2');
$db = \Config\Database::connect();
$sql = "MERGE INTO cmod.dbo.CM_DICT_CHAPTERS AS t
USING ( VALUES ('$chapcode', '$text1', '$text2')
) AS s (CHAPCODE, TEXT1, TEXT2) on t.CHAPCODE=s.CHAPCODE
WHEN NOT MATCHED BY TARGET THEN
INSERT (CHAPCODE, TEXT1, TEXT2)
VALUES (s.CHAPCODE, s.TEXT1, s.TEXT2)
WHEN MATCHED THEN
UPDATE set TEXT1=s.TEXT1, TEXT2=s.TEXT2;";
//echo "<pre>$sql</pre>";
if( $db->query($sql) ) {
return $this->respond(['message' => 'Save Success'],201);
} else {
$response = [
'errors' => $db->errors(),
'message' => 'Invalid Inputs'
];
return $this->fail($response , 409);
}
}
}

View File

@ -0,0 +1,166 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class API_DictMappings extends ResourceController {
protected $format = 'json';
public function index() {
$db = \Config\Database::connect();
$sql = "select m.*, t.TUBECODE, t.TUBENAME from cmod.dbo.CM_DICT_MAPPINGS m
left join cmod.dbo.CM_DICT_TUBES t on m.TUBEID=t.TUBEID";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['dictMappings'] = $results;
return $this->respond($data, 200);
}
public function search(){
$db = \Config\Database::connect();
$liscode = $this->request->getPost('liscode');
$hiscode = $this->request->getPost('hiscode');
$descs = $this->request->getPost('maptext');
$sql = "select m.*, t.TUBECODE, t.TUBENAME from cmod.dbo.CM_DICT_MAPPINGS m
left join cmod.dbo.CM_DICT_TUBES t on m.TUBEID=t.TUBEID";
$where = "";
if (!empty($liscode) || !empty($hiscode) || !empty($maptext) ) {
$where = ' WHERE ';
$x = 0;
if (!empty($liscode)) { $where .= "m.LISCODE like '%$liscode%'"; $x = 1; }
if (!empty($hiscode)) {
if ($x == 1) { $where .= ' OR '; }
$where .= "m.HISCODE LIKE '%$hiscode%'"; $x = 1;
}
if (!empty($maptext)) {
if ($x == 1) { $where .= ' OR '; }
$where .= "LOWER(m.DESCS) LIKE '%$maptext%'";
}
}
$sql .= $where;
$query = $db->query($sql);
$results = $query->getResultArray();
$data['dictMappings'] = $results;
return $this->respond($data, 200);
}
public function detail($mapid) {
$data = array();
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_DICT_MAPPINGS where MAPID='$mapid'";
$query = $db->query($sql);
$results = $query->getResultArray();
if(isset($results[0])) {
$data = $results[0];
if($data['MAPTYPE']=='P') {
$sql = "select * from cmod.dbo.CM_DICT_MAPPING_PROFILES where MAPID='$mapid'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['mliscodes'] = $results;
}
}
return $this->respond($data, 200);
}
public function saveSingle() {
$update = $this->request->getPost('update');
$liscode = $this->request->getPost('liscode');
$hiscode = $this->request->getPost('hiscode');
$descs = $this->request->getPost('descs');
$tubeid = $this->request->getPost('tubeid');
// check if hiscode is exists
$db = \Config\Database::connect();
$sql = "select 1 from cmod.dbo.CM_DICT_MAPPINGS where HISCODE='$hiscode' and MAPTYPE in ('S','P') and MAPID<>'$update'";
$query = $db->query($sql);
$results = $query->getResultArray();
if(isset($results[0])) {
$response = [
'errors' => 'HISCODE already exists',
'message' => 'HISCODE already exists'
];
return $this->fail($response , 409);
}
if($update == '0') { $sql = "INSERT INTO cmod.dbo.CM_DICT_MAPPINGS (MAPTYPE, HISCODE, LISCODE, DESCS, TUBEID ) VALUES ('S', '$hiscode', '$liscode', '$descs', '$tubeid')"; }
else { $sql = "UPDATE cmod.dbo.CM_DICT_MAPPINGS set HISCODE='$hiscode', LISCODE='$liscode', DESCS='$descs', TUBEID='$tubeid' where MAPID='$update'"; }
if( $db->query($sql) ) {
return $this->respond(['message' => 'Save Success'],201);
} else {
$response = [
'errors' => $db->errors(),
'message' => 'Invalid Inputs'
];
return $this->fail($response , 409);
}
}
public function saveProfile() {
$db = \Config\Database::connect();
$update = $this->request->getPost('update');
$hiscode = $this->request->getPost('hiscode');
$tubeid = $this->request->getPost('tubeid');
$descs = $this->request->getPost('descs');
$mliscode = [];
for ($i = 1; $i <= 44; $i++) {
$key = "mliscode{$i}";
if (isset($_POST[$key])) {
$mliscode[$key] = $this->request->getPost($key);
}
}
// check if hiscode is exists
$sql = "select 1 from cmod.dbo.CM_DICT_MAPPINGS where HISCODE='$hiscode' and MAPTYPE in ('P','S') and MAPID<>'$update'";
$query = $db->query($sql);
$results = $query->getResultArray();
if(isset($results[0])) {
$response = [
'errors' => $db->errors(),
'message' => 'HISCODE already exists'
];
return $this->fail($response , 409);
}
// dict_mappings
if($update == '0') { $sql = "INSERT INTO cmod.dbo.CM_DICT_MAPPINGS (MAPTYPE, HISCODE, LISCODE, DESCS, TUBEID) VALUES ('P', '$hiscode', null, '$descs', '$tubeid')"; }
else { $sql = "UPDATE cmod.dbo.CM_DICT_MAPPINGS set HISCODE='$hiscode', LISCODE=null, DESCS='$descs', TUBEID='$tubeid' where MAPID='$update'"; }
if( !$db->query($sql) ) {
$response = [
'errors' => $db->errors(),
'message' => 'Invalid Inputs'
];
return $this->fail($response , 409);
}
// getting mapid after
if($update == 0) { $update = $db->insertID(); }
// dict_mapping_profiles
$datasource = '';
foreach($mliscode as $liscode) { $datasource .= "('$update','$liscode'),"; }
$datasource = rtrim($datasource,',');
$sql = "MERGE INTO cmod.dbo.CM_DICT_MAPPING_PROFILES AS t
USING ( VALUES
$datasource
) AS s (MAPID, LISCODE) on s.MAPID=t.MAPID and s.LISCODE=t.LISCODE
WHEN NOT MATCHED BY TARGET THEN
INSERT (MAPID, LISCODE)
VALUES (s.MAPID, s.LISCODE)
WHEN NOT MATCHED BY SOURCE and t.MAPID='$update' THEN
DELETE;";
if( $db->query($sql) ) {
return $this->respond(['message' => 'Save Success'],201);
} else {
$response = [
'errors' => $db->errors(),
'message' => 'Invalid Inputs'
];
return $this->fail($response , 409);
}
}
}

View File

@ -3,7 +3,7 @@ namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class DictTests extends ResourceController {
class API_DictTests extends ResourceController {
protected $format = 'json';
public function index() {
@ -61,8 +61,14 @@ class DictTests extends ResourceController {
$refftext = $this->request->getPost('refftext');
$db = \Config\Database::connect();
$sql = "INSERT INTO cmod.dbo.CM_DICT_TESTS (TESTCODE, TEXT1, TEXT2, REFFTEXT, LOGDATE ) VALUES ('$testcode', '$text1', '$text2', '$refftext' GETDATE())";
$sql = "UPDATE cmod.dbo.CM_DICT_TESTS set TEXT1='$text1', TEXT2='$text2', REFFTEXT='$refftext', LOGDATE=GETDATE() where TESTCODE='$testcode'";
$sql = "MERGE INTO cmod.dbo.CM_DICT_TESTS AS t
USING ( VALUES ('$testcode', '$text1', '$text2', '$unit', '$refftext')
) AS s (TESTCODE, TEXT1, TEXT2, UNIT, REFFTEXT) on t.TESTCODE=s.TESTCODE
WHEN NOT MATCHED BY TARGET THEN
INSERT (TESTCODE, TEXT1, TEXT2, UNIT, REFFTEXT, LOGDATE)
VALUES (s.TESTCODE, s.TEXT1, s.TEXT2, s.UNIT, s.REFFTEXT, GETDATE())
WHEN MATCHED THEN
UPDATE set TEXT1=s.TEXT1, TEXT2=s.TEXT2, UNIT=s.UNIT, REFFTEXT=s.REFFTEXT;";
if( $db->query($sql) ) {
return $this->respond(['message' => 'Save Success'],201);

View File

@ -0,0 +1,50 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class API_DictTubes extends ResourceController {
protected $format = 'json';
public function index() {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_DICT_TUBES";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['dictTubes'] = $results;
return $this->respond($data, 200);
}
public function detail($tubeid) {
$data = array();
$db = \Config\Database::connect();
$sql = "select TUBECODE, TUBENAME from cmod.dbo.CM_DICT_TUBES where TUBEID='$tubeid'";
$query = $db->query($sql);
$results = $query->getResultArray();
if(isset($results[0])) { $data = $results[0]; }
return $this->respond($data, 200);
}
public function save() {
$tubecode = $this->request->getPost('tubecode');
$tubename = $this->request->getPost('tubename');
$tubeid = $this->request->getPost('tubeid');
$db = \Config\Database::connect();
if($tubeid == 0) {
$sql = "insert into cmod.dbo.CM_DICT_TUBES (TUBECODE, TUBENAME) VALUES ( '$tubecode', '$tubename' )";
} else {
$sql = "update cmod.dbo.CM_DICT_TUBES set TUBECODE='$tubecode', TUBENAME='$tubename' where TUBEID='$tubeid'";
}
if( $db->query($sql) ) {
return $this->respond(['message' => 'Save Success'],201);
} else {
$response = [
'errors' => $db->errors(),
'message' => 'Invalid Inputs'
];
return $this->fail($response , 409);
}
}
}

111
app/Controllers/API_HIS.php Normal file
View File

@ -0,0 +1,111 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class API_HIS extends ResourceController {
protected $format = 'json';
public function requests() {
/*
"reference_id": "4f52-8e25-48009b4f52-8e25-48009b4f52-8e25-48009b",
"created": "2024-10-19T00:47:06.424654Z",
"company_name": "company_name",
"branch": "PBMC Bali",
"total_patient_export_count": 2,
"total_test_export_count": 4,
"patient": {
"rm_number": "1B0912243",
"patient_first_name": "Jenifer",
"patient_last_name": "Ngo",
"patient_dob": "1999-11-12",
"patient_sex": "F",
"patient_phone": "62815456655885",
"visit_number": "BV002304",
"visit_description": null,
"visit_date_time": "2024-10-19T00:47:06.424654Z",
"agent_name": "Apollo Group",
"agent": true/false,
"treating_doctor": "Frida Susanti Sp.Ked",
"visit_type": "MCU",
"tests": [
{
"test_ref_id": "4f52-8e25-48009b04f52-8e25-4800900",
"service_id": "SL00140"
},
{
"test_ref_id": "4f52-8e25-48009b04f52-8e25-4800901",
"service_id": "SL00142"
}
]
}
{
"reference_id": "4f52-8e25-48009b4f52-8e25-48009b4f52-8e25-48009b",
"created": "2024-10-19T00:47:06.424654Z",
"company_name": "company_name",
"branch": "PBMC Bali",
"total_patient_export_count": 2,
"total_test_export_count": 4,
"patient": {
"rm_number": "1B0912243",
"patient_first_name": "Jenifer",
"patient_last_name": "Ngo",
"patient_dob": "1999-11-12",
"patient_sex": "F",
"patient_phone": "62815456655885",
"visit_number": "BV002304",
"visit_description": null,
"visit_date_time": "2024-10-19T00:47:06.424654Z",
"agent_name": "Apollo Group",
"agent": true,
"treating_doctor": "Frida Susanti Sp.Ked",
"visit_type": "MCU",
"tests": [
{
"test_ref_id": "4f52-8e25-48009b04f52-8e25-4800900",
"service_id": "SL00140"
},
{
"test_ref_id": "4f52-8e25-48009b04f52-8e25-4800901",
"service_id": "SL00142"
}
]
}
}
*/
$input = $this->request->getRawInput();
if (empty($input)) { return $this->fail('No JSON data received', 400); }
var_dump($input);
//return $this->respond($input, 200);
}
public function dictTests() {
$db = \Config\Database::connect();
$sql = "select top 5 HISCODE as ServiceCode, DESCS as ServiceName from cmod.dbo.CM_DICT_MAPPINGS";
$query = $db->query($sql);
$results = $query->getResultArray();
$data = $results;
return $this->respond($data,200);
}
public function results($accessnumber) {
$db = \Config\Database::connect();
$sql = "select HOSTORDERNUMBER as HISNO from SP_REQUESTS where SP_ACCESSNUMBER='$accessnumber'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['LISNO'] = $accessnumber;
$data['HISNO'] = $results[0]['HISNO'];
$sql = "select TESTCODE, TESTORDER, RESTYPE, RESVALUE, RESFLAG, UNIT, REFRANGE, USERVAL, RESDATE
from cmod.dbo.CM_RESULTS r
where ACCESSNUMBER='$accessnumber'
order by TESTORDER";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['results'] = $results;
return $this->respond($data,200);
}
}

View File

@ -0,0 +1,131 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class API_HISOrders extends ResourceController {
protected $format = 'json';
public function index() {
// Mengetahui Apakah User Login adalah Bali atau Surabaya
$cityid = session()->get('usercityid');
if ($cityid == 1) {
$filter_query = " AND o.VISITNUMBER LIKE 'BV%' ";
} elseif ($cityid == 2) {
$filter_query = " AND o.VISITNUMBER LIKE 'SV%' ";
} else {
$filter_query = " ";
}
$db = \Config\Database::connect();
$date1 = $this->request->getPost('date1');
$date2 = $this->request->getPost('date2');
$sql = "select o.ORDERID, o.LOC, o.VISITNUMBER, o.VISITDATE, o.PAYERNAME, o.TREATDOC, p.PATNUMBER, p.SEX, p.PATNAME,
TESTS=stuff(( select ', '+t.HISCODE from
( select t.HISCODE from cmod.dbo.CM_HIS_TESTS t
where t.ORDERID=o.ORDERID and t.TESTSTATUS is null
) as T
for xml path('')),1,1,'')
from cmod.dbo.CM_HIS_ORDERS o
left join cmod.dbo.CM_HIS_PATIENTS p on p.PATID=o.PATID
where o.VISITDATE between '$date1 00:00' and '$date2 23:59' " . $filter_query;
$query = $db->query($sql);
$results = $query->getResultArray();
$data['data'] = $results;
return $this->respond($data,200);
}
public function detail($orderid) {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_HIS_ORDERS o where o.ORDERID='$orderid'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['orders'] = $results;
$sql = "select * from cmod.dbo.CM_HIS_TESTS where ORDERID='$orderid' and TESTSTATUS is null";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['tests'] = $results;
return $this->respond($data,200);
}
public function save() {
$db = \Config\Database::connect();
//Object { patid: "9", visitnumber: "9989", visitdate: "2024-12-13", treatdoc: "alam", payername: "mala", tests: (2) […] }
$orderid = $this->request->getPost('orderid');
$patid = $this->request->getPost('patid');
$loc = $this->request->getPost('loc');
$visitnumber = $this->request->getPost('visitnumber');
$visitdate = $this->request->getPost('visitdate');
$treatdoc = $this->request->getPost('treatdoc');
$payername = $this->request->getPost('payername');
$tests = $this->request->getPost('tests');
// $reffid = $this->request->getPost('reffid');
if($orderid == '0') {
$sql = "INSERT INTO cmod.dbo.CM_HIS_ORDERS (PATID, LOC, VISITNUMBER, VISITDATE, TREATDOC, PAYERNAME)
VALUES ('$patid', '$loc', '$visitnumber', '$visitdate', '$treatdoc', '$payername')";
} else {
$sql = "UPDATE cmod.dbo.CM_HIS_ORDERS set PATID='$patid', LOC='$loc', VISITNUMBER='$visitnumber', VISITDATE='$visitdate',
TREATDOC='$treatdoc', PAYERNAME='$payername' where ORDERID='$orderid'";
}
// query HIS_ORDERS
if( $db->query($sql) ) {
if($orderid == '0') { // new order
$orderid = $db->insertID();
$test = '';
foreach($tests as $qtest) { $test .= "('$orderid', '$qtest'),"; }
$test = rtrim($test, ",");
$sql = "INSERT into cmod.dbo.CM_HIS_TESTS(ORDERID,HISCODE) VALUES $test";
} else { // update
$test = '';
foreach($tests as $qtest) { $test .= "('$orderid', '$qtest'),"; }
$test = rtrim($test, ",");
$sql = "MERGE INTO cmod.dbo.CM_HIS_TESTS AS t
USING ( VALUES
$test
) AS s (ORDERID, HISCODE) on s.ORDERID=t.ORDERID and s.HISCODE=t.HISCODE
WHEN MATCHED THEN
UPDATE SET TESTSTATUS=null
WHEN NOT MATCHED BY TARGET THEN
INSERT (ORDERID, HISCODE)
VALUES (s.ORDERID, s.HISCODE)
WHEN NOT MATCHED BY SOURCE and t.ORDERID='$orderid' THEN
UPDATE SET TESTSTATUS=1;";
}
// done
if( $db->query($sql) ) {
return $this->respond(['message' => 'Save Success', 'sql' => $sql],201);
} else {
$response = [
'errors' => $db->errors(),
'message' => 'Query test error',
'sql' => $sql
];
return $this->fail($response , 409);
}
} else {
$response = [
'errors' => $db->errors(),
'message' => 'Query order error'
];
return $this->fail($response , 409);
}
}
public function resend($visitnumber) {
$db = \Config\Database::connect();
$sql = "update cmod.dbo.CM_HIS_ORDERS set ISTAKEN=null where VISITNUMBER='$visitnumber'";
if( $db->query($sql) ) {
return $this->respond(['message' => 'Update Success'],201);
} else {
$response = [
'errors' => $db->errors(),
'message' => 'Query error'
];
return $this->fail($response , 409);
}
}
}

View File

@ -0,0 +1,91 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class API_HISPatients extends ResourceController {
protected $format = 'json';
public function index() {
$db = \Config\Database::connect();
$date1 = $this->request->getPost('date1');
$date2 = $this->request->getPost('date2');
$sql = "select o.VISITNUMBER, o.VISITDATE, o.PAYERNAME, o.TREATDOC, p.PATNUMBER, p.SEX, p.PATNAME,
TESTS=stuff(( select ', '+t.HISCODE from
( select t.HISCODE from cmod.dbo.CM_HIS_TESTS t
where t.ORDERID=o.ORDERID
) as T
for xml path('')),1,1,'')
from cmod.dbo.CM_HIS_ORDERS o
left join cmod.dbo.CM_HIS_PATIENTS p on p.PATID=o.PATID";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['data'] = $results;
return $this->respond($data,200);
}
public function patnumberSearch($patnumber) {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_HIS_PATIENTS where PATNUMBER like '%$patnumber%'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['patients'] = $results;
return $this->respond($data,200);
}
public function search() {
$db = \Config\Database::connect();
$patnumber = $this->request->getPost('patnumber');
$patname = strtolower( $this->request->getPost('patname') );
$sql = "select * from cmod.dbo.CM_HIS_PATIENTS";
// Initialize a WHERE clause
$where= '';
if (!empty($patnumber) || !empty($patname)) {
$where= ' WHERE ';
if (!empty($patnumber)) { $where .= "PATNUMBER like '%$patnumber%'"; }
if (!empty($shorttext)) {
if (!empty($testcode)) { $where .= ' OR '; }
$where .= "LOWER(PATNAME) LIKE '%$patname%'";
}
}
$sql .= $where;
$query = $db->query($sql);
$results = $query->getResultArray();
$data['patients'] = $results;
return $this->respond($data, 200);
}
public function detail($patid) {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_HIS_PATIENTS where PATID='$patid'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['patient'] = $results[0];
return $this->respond($data,200);
}
public function save() {
$db = \Config\Database::connect();
$patid = $this->request->getPost('patid');
$patnumber = $this->request->getPost('patnumber');
$patname = $this->request->getPost('patname');
$sex = $this->request->getPost('sex');
$birthdate = $this->request->getPost('birthdate');
$address = $this->request->getPost('address');
$phone = $this->request->getPost('phone');
if($patid == 0) {
$sql = "INSERT INTO cmod.dbo.CM_HIS_PATIENTS (PATNUMBER, PATNAME, SEX, BIRTHDATE, ADDRESS, PHONE)
VALUES ('$patnumber', '$patname', '$sex', '$birthdate', '$address','$phone')";
} else {
$sql = "update cmod.dbo.CM_HIS_PATIENTS set PATNUMBER='$patnumber', PATNAME='$patname',
SEX='$sex', BIRTHDATE='$birthdate', ADDRESS='$address', PHONE='$phone' Where PATID='$patid'";
}
$query = $db->query($sql);
if($patid == 0 ) { $patid = $db->insertID(); }
$data['patid'] = $patid;
$data['patnumber'] = $patnumber;
$data['sql'] = $sql;
return $this->respond($data , 200);
}
}

View File

@ -2,7 +2,7 @@
namespace App\Controllers;
class Tubes extends BaseController {
class API_Tubes extends BaseController {
public function collect($access, $sample) {
$userid = session()->userid;
@ -21,13 +21,13 @@ class Tubes extends BaseController {
public function uncollect($access, $sample) {
$db = \Config\Database::connect();
$sql = "UPDATE cmod.dbo.CM_TUBES set COLLSTATUS=0 where ACCESSNUMBER='$access' and SAMPLETYPE='$sample'";
$sql = "UPDATE cmod.dbo.CM_TUBES set COLLSTATUS=0, COLLECTIONDATE=null where ACCESSNUMBER='$access' and SAMPLETYPE='$sample'";
$query = $db->query($sql);
}
public function unreceive($access, $sample) {
$db = \Config\Database::connect();
$sql = "UPDATE SP_TUBES set TUBESTATUS=null where SP_ACCESSNUMBER='$access' and SAMPLETYPE='$sample'";
$sql = "UPDATE SP_TUBES set TUBESTATUS=0 where SP_ACCESSNUMBER='$access' and SAMPLETYPE='$sample'";
$query = $db->query($sql);
}
@ -58,7 +58,7 @@ class Tubes extends BaseController {
public function unreceiveAll($access) {
$db = \Config\Database::connect();
$sql = "UPDATE SP_TUBES set TUBESTATUS=null where SP_ACCESSNUMBER='$access'";
$sql = "UPDATE SP_TUBES set TUBESTATUS=0 where SP_ACCESSNUMBER='$access'";
$query = $db->query($sql);
}

View File

@ -3,7 +3,7 @@ namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class Userroles extends ResourceController {
class API_Userroles extends ResourceController {
protected $format = 'json';
public function index() {
@ -26,14 +26,13 @@ class Userroles extends ResourceController {
}
public function save($userroleid) {
$userrolecode = $this->request->getPost('userrolecode');
$userrolename = $this->request->getPost('userrolename');
$db = \Config\Database::connect();
if($userroleid == 0) { // new
$sql = "INSERT INTO cmod.dbo.CM_USERROLES(USERROLECODE, USERROLENAME, CREATEDATE) VALUES ('$userrolecode', '$userrolename', GETDATE())";
$sql = "INSERT INTO cmod.dbo.CM_USERROLES(USERROLENAME, CREATEDATE) VALUES ('$userrolename', GETDATE())";
} else { //update
$sql = "UPDATE cmod.dbo.CM_USERROLES set USERROLENAME='$userrolename', USERROLECODE='$userrolecode' where USERROLEID='$userroleid'";
$sql = "UPDATE cmod.dbo.CM_USERROLES set USERROLENAME='$userrolename' where USERROLEID='$userroleid'";
}
if( $db->query($sql) ) {

View File

@ -3,15 +3,24 @@ namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class Users extends ResourceController {
class API_Users extends ResourceController {
protected $format = 'json';
public function index() {
$db = \Config\Database::connect();
$sql = "select u.USERID, u.USERNAME, u1.USERROLEID, ur.USERROLENAME from cmod.dbo.CM_USERS u1
full join USERS u on u.USERID=u1.USERID
left join cmod.dbo.CM_USERROLES ur on ur.USERROLEID=u1.USERROLEID
where ( u.LOCKEDACCOUNT is null or u.LOCKEDACCOUNT=0 )";
$usercityid = session()->get('usercityid');
if($usercityid==1){$filterquery=" AND uc.CITYID = 1";}
else if($usercityid==2){$filterquery=" AND uc.CITYID = 2";}
else{$filterquery=" ";}
$sql = "select u.USERID, u.USERNAME, uc.CITYNAME ,u1.USERROLEID, ur.USERROLENAME
from cmod.dbo.CM_USERS u1
full join USERS u on u.USERID=u1.USERID
left join cmod.dbo.CM_USERS us on us.USERID=u.USERID
left join cmod.dbo.CM_USERSCITY uc on uc.CITYID=us.CITYID
left join cmod.dbo.CM_USERROLES ur on ur.USERROLEID=u1.USERROLEID
where ( u.LOCKEDACCOUNT is null or u.LOCKEDACCOUNT=0 ) $filterquery";
$query = $db->query($sql);
$results = $query->getResultArray();

View File

@ -0,0 +1,135 @@
<?php
namespace App\Controllers;
class AdminController extends BaseController {
public function index() {
return view('admin/dashboard');
}
public function tm_index() {
return view('admin/dashboardTM');
}
public function viewAccess($accessnumber): string {
// Mengetahui Apakah User Bali atau Surabaya
$data['usercityid'] = session()->get('usercityid');
$db = \Config\Database::connect();
$sql = "SELECT sr.HOSTORDERNUMBER, tu.SAMPLETYPE, ds.FULLTEXT as SHORTTEXT, tu.TUBESTATUS, ct.COLLSTATUS, ct.TUBECOMMENT from SP_TUBES tu
left join SP_REQUESTS sr on tu.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
left join DICT_SAMPLES_TYPES ds on ds.SAMPCODE= tu.SAMPLETYPE
left join cmod.dbo.CM_TUBES ct on ct.SAMPLETYPE=tu.SAMPLETYPE and ct.ACCESSNUMBER=tu.SP_ACCESSNUMBER
where tu.SP_ACCESSNUMBER='$accessnumber'";
$query = $db->query($sql);
$results = $query->getResultArray();
$visit_number = $results[0]['HOSTORDERNUMBER'];
$data['data'] = $results;
// $sql = "select hp.PATNUMBER, hp.PATNAME, ho.PAYERNAME, ho.TREATDOC
// from cmod.dbo.CM_HIS_ORDERS ho
// left join cmod.dbo.CM_HIS_PATIENTS hp on hp.PATID=ho.PATID
// WHERE ho.VISITNUMBER='$visit_number'";
$sql = "SELECT ctp.PATNUMBER, CONCAT(ctp.FIRSTNAME, ' ', ctp.LASTNAME) as PATNAME, ctr.AGENT as PAYERNAME, ctr.DOC as TREATDOC, ctr.VISITTYPE
from cmod.dbo.CM_TM_REQUESTS ctr
left join cmod.dbo.CM_TM_PATIENTS ctp on ctr.PATID = ctp.PATID
where ctr.REFFID='$visit_number'";
$query = $db->query($sql);
$results = $query->getResultArray();
if($results != null) {
$data['patnumber'] = $results[0]['PATNUMBER'];
$data['patient_fullname'] = $results[0]['PATNAME'];
$data['visit_description'] = $results[0]['VISITTYPE'];
$data['treating_doctor'] = $results[0]['TREATDOC'];
$data['payer_name'] = $results[0]['PAYERNAME'];
} else {
$data['patnumber'] = "";
$data['patient_fullname'] = "";
$data['visit_description'] = "";
$data['treating_doctor'] = "";
$data['payer_name'] = "";
}
$data['accessnumber'] = $accessnumber;
return view('admin/dashboard_viewAccess', $data);
}
public function userroles_index(): string {
return view('admin/userroles_index');
}
public function users_index(): string {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_USERROLES";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['userroles'] = $results;
return view('admin/users_index', $data);
}
public function changePass() {
if ($this->request->getMethod() === 'POST') {
$password1 = $this->request->getVar('password1');
$password2 = $this->request->getVar('password2');
$data['password1'] = $password1;
$data['password2'] = $password2;
if($password1 == $password2) {
$password = password_hash($password1,PASSWORD_DEFAULT);
$db = \Config\Database::connect();
$sql = "update cmod.dbo.CM_USERS set PASSWORD='$password' where USERID='$userid'";
$db->query($sql);
return redirect()->to("/");
} else {
return redirect()->to("/auth/setpass/$userid")->with('flash_error', 'password is not the same.');
}
}
return view('changePass');
}
public function dictTests_index() {
return view('admin/dictTests_index');
}
public function dictChapters_index() {
return view('admin/dictChapters_index');
}
public function dictTubes_index() {
return view('admin/dictTubes_index');
}
public function dictMappings_index() {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_DICT_TUBES";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['tubes'] = $results;
$sql = "select TESTCODE from DICT_TESTS where ENDVALIDDATE is null";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['tests'] = $results;
return view('admin/dictMappings_index', $data);
}
public function orders_index() {
return view('orders_index');
}
public function orders_edit($orderid) {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_DICT_MAPPINGS";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['tests'] = $results;
$data['orderid'] = $orderid;
return view('orders_edit', $data);
}
public function patients_index() {
return view('patients_index');
}
}

View File

@ -18,19 +18,21 @@ class Auth extends BaseController {
$data['password'] = $password;
$db = \Config\Database::connect();
$sql = "SELECT u.USERID, u.USERNAME, u1.PASSWORD, ur.USERROLECODE
FROM USERS u
left join cmod.dbo.CM_USERS u1 on u.USERID=u1.USERID
left join cmod.dbo.CM_USERROLES ur on u1.USERROLEID=ur.USERROLEID
WHERE u.USERID='$userid'";
$sql = "SELECT u.USERID, u.USERNAME, u1.PASSWORD, u1.CITYID, ur.USERROLENAME
FROM USERS u
left join cmod.dbo.CM_USERS u1 on u.USERID=u1.USERID
left join cmod.dbo.CM_USERROLES ur on u1.USERROLEID=ur.USERROLEID
WHERE u.USERID='$userid'";
$query = $db->query($sql);
$result = $query->getResultArray();
$row = $result[0];
if(isset($row)) {
if(isset($result[0])) {
$row = $result[0];
$qpassword = $row['PASSWORD'];
$userid = $row['USERID'];
$username = $row['USERNAME'];
$userrole = $row['USERROLECODE'];
$userrole = $row['USERROLENAME'];
$usercityid = $row['CITYID'];
// if pass empty then first login / reset password
$data['password']=$password;
$data['qpassword']=$qpassword;
@ -51,6 +53,7 @@ WHERE u.USERID='$userid'";
'userid' => $userid,
'userrole' => $userrole,
'username' => $username,
'usercityid' => $usercityid
];
session()->set( $sessiondata );
return redirect()->to('/');
@ -65,7 +68,12 @@ WHERE u.USERID='$userid'";
public function logout() {
session()->destroy();
return redirect()->to('/auth/login');;
return redirect()->to('/auth/login');
}
public function redirects() {
$role = session()->get('userrole');
return redirect()->to("/$role/");;
}
public function setpass($userid) {
@ -93,4 +101,8 @@ WHERE u.USERID='$userid'";
return redirect()->to('/');
}
public function noAccess() {
return view('noAccess');
}
}

View File

@ -1,75 +0,0 @@
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
class Dashboard extends ResourceController {
protected $format = 'json';
public function index() {
$db = \Config\Database::connect();
$sql = "select sr.COLLECTIONDATE, sr.SP_ACCESSNUMBER, sr.HOSTORDERNUMBER, p.PATNUMBER, p.NAME,
TESTS=stuff(( select ', '+'('+T.SP_TESTCODE+')' from
( select T.SP_TESTCODE from SP_TESTS T
where T.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
and T.DEPTH=0 AND T.SP_TESTCODE <> 'Q'
) as T
for xml path('')),1,1,''),
case
when exists (select 1 from AUDIT_TRAIL at where at.ATR_ACCESSNUMBER=sr.SP_ACCESSNUMBER and at.STEPTYPE=2 and at.LIS_SESSION='RFC' ) then
case
when exists (select 1 from SP_TUBES st where st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER and st.TUBESTATUS=0 ) then 'PartRecv'
when exists (select 1 from TESTS T where T.REQUESTID=r.REQUESTID and T.RESTYPE IN (null,'0') ) then 'Inc'
--when exists (select 1 from TESTS T where T.REQUESTID=r.REQUESTID and T.RESTYPE IN (null,'0') and T.TESTID='1805' ) then 'Inc'
else 'Comp'
end
-- inc
when exists (select 1 from TESTS T where T.RESTYPE not in (0,4) and T.REQUESTID=r.REQUESTID ) then
case
when exists ( select 1 from cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER and T.COLLSTATUS=0 ) then 'PartColl'
when exists (select 1 from SP_TUBES st where st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER and st.TUBESTATUS=0 ) then 'PartRecv'
else 'Inc'
end
--rcv
when not exists (select 1 from SP_TUBES st where st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER and st.TUBESTATUS=0 ) then
case
when exists (select 1 from cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER and T.COLLSTATUS=0 ) then 'PartColl'
else 'Recv'
end
--coll
when exists (select 1 FROM cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER ) then
case
when exists (select 1 from SP_TUBES st where st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER and st.TUBESTATUS=4 ) then 'PartRecv'
when not exists (select 1 from cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER and T.COLLSTATUS=0 ) then 'Coll'
when exists (select 1 from cmod.dbo.CM_TUBES T where T.ACCESSNUMBER=sr.SP_ACCESSNUMBER and T.COLLSTATUS=1 ) then 'PartColl'
else 'Pend'
end
else 'Pend'
end STATS
from SP_REQUESTS sr
left join PATIENTS p on p.PATID=sr.PATID
left join REQUESTS r on r.ACCESSNUMBER=sr.SP_ACCESSNUMBER
where sr.COLLECTIONDATE between '2024-11-13 00:00' and '2024-11-21 23:59'
order by sr.COLLECTIONDATE desc";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['data'] = $results;
$data['count'] = array_count_values(array_column($results, 'STATS'));
return $this->respond($data,200);
}
public function viewAccess($accessnumber): string {
$db = \Config\Database::connect();
$sql = "select p.PATNUMBER, p.NAME, sr.HOSTORDERNUMBER, tu.SAMPLETYPE, ds.SHORTTEXT, tu.TUBESTATUS, ct.COLLSTATUS, ct.TUBECOMMENT from SP_TUBES tu
left join SP_REQUESTS sr on tu.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
left join PATIENTS p on p.PATID=sr.PATID
left join DICT_SAMPLES_TYPES ds on ds.SAMPCODE= tu.SAMPLETYPE
left join cmod.dbo.CM_TUBES ct on ct.SAMPLETYPE=tu.SAMPLETYPE and ct.ACCESSNUMBER=tu.SP_ACCESSNUMBER
where tu.SP_ACCESSNUMBER='$accessnumber'";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['data'] = $results;
$data['accessnumber'] = $accessnumber;
return view('dashboard_viewAccess', $data);
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace App\Controllers;
class FoController extends BaseController {
public function index() {
return view('fo/dashboard');
}
public function viewAccess($accessnumber): string {
// Mengetahui Apakah User Bali atau Surabaya
$data['usercityid'] = session()->get('usercityid');
$db = \Config\Database::connect();
$sql = "SELECT sr.HOSTORDERNUMBER, tu.SAMPLETYPE, ds.FULLTEXT as SHORTTEXT, tu.TUBESTATUS, ct.COLLSTATUS, ct.TUBECOMMENT from SP_TUBES tu
left join SP_REQUESTS sr on tu.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
left join DICT_SAMPLES_TYPES ds on ds.SAMPCODE= tu.SAMPLETYPE
left join cmod.dbo.CM_TUBES ct on ct.SAMPLETYPE=tu.SAMPLETYPE and ct.ACCESSNUMBER=tu.SP_ACCESSNUMBER
where tu.SP_ACCESSNUMBER='$accessnumber'";
$query = $db->query($sql);
$results = $query->getResultArray();
$visit_number = $results[0]['HOSTORDERNUMBER'];
$data['data'] = $results;
// $sql = "select hp.PATNUMBER, hp.PATNAME, ho.PAYERNAME, ho.TREATDOC
// from cmod.dbo.CM_HIS_ORDERS ho
// left join cmod.dbo.CM_HIS_PATIENTS hp on hp.PATID=ho.PATID
// WHERE ho.VISITNUMBER='$visit_number'";
$sql = "SELECT ctp.PATNUMBER, CONCAT(ctp.FIRSTNAME, ' ', ctp.LASTNAME) as PATNAME, ctr.AGENT as PAYERNAME, ctr.DOC as TREATDOC, ctr.VISITTYPE
from cmod.dbo.CM_TM_REQUESTS ctr
left join cmod.dbo.CM_TM_PATIENTS ctp on ctr.PATID = ctp.PATID
where ctr.REFFID='$visit_number'";
$query = $db->query($sql);
$results = $query->getResultArray();
if($results != null) {
$data['patnumber'] = $results[0]['PATNUMBER'];
$data['patient_fullname'] = $results[0]['PATNAME'];
$data['visit_description'] = $results[0]['VISITTYPE'];
$data['treating_doctor'] = $results[0]['TREATDOC'];
$data['payer_name'] = $results[0]['PAYERNAME'];
} else {
$data['patnumber'] = "";
$data['patient_fullname'] = "";
$data['visit_description'] = "";
$data['treating_doctor'] = "";
$data['payer_name'] = "";
}
$data['accessnumber'] = $accessnumber;
return view('fo/dashboard_viewAccess', $data);
}
public function changePass() {
if ($this->request->getMethod() === 'POST') {
$password1 = $this->request->getVar('password1');
$password2 = $this->request->getVar('password2');
$data['password1'] = $password1;
$data['password2'] = $password2;
if($password1 == $password2) {
$password = password_hash($password1,PASSWORD_DEFAULT);
$db = \Config\Database::connect();
$sql = "update cmod.dbo.CM_USERS set PASSWORD='$password' where USERID='$userid'";
$db->query($sql);
return redirect()->to("/");
} else {
return redirect()->to("/auth/setpass/$userid")->with('flash_error', 'password is not the same.');
}
}
return view('changePass');
}
}

View File

@ -1,46 +0,0 @@
<?php
namespace App\Controllers;
class Pages extends BaseController {
public function dashboard_index() {
return view('dashboard');
}
public function userroles_index(): string {
return view('userroles_index');
}
public function users_index(): string {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_USERROLES";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['userroles'] = $results;
return view('users_index', $data);
}
public function changePass() {
if ($this->request->getMethod() === 'POST') {
$password1 = $this->request->getVar('password1');
$password2 = $this->request->getVar('password2');
$data['password1'] = $password1;
$data['password2'] = $password2;
if($password1 == $password2) {
$password = password_hash($password1,PASSWORD_DEFAULT);
$db = \Config\Database::connect();
$sql = "update cmod.dbo.CM_USERS set PASSWORD='$password' where USERID='$userid'";
$db->query($sql);
return redirect()->to("/");
} else {
return redirect()->to("/auth/setpass/$userid")->with('flash_error', 'password is not the same.');
}
}
return view('changePass');
}
public function dictTests_index() {
return view('dictTests_index');
}
}

View File

@ -0,0 +1,400 @@
<?php
namespace App\Controllers;
class PrintLabel extends BaseController {
public function printerLab() {
exec('net use L: \\\\10.148.5.20\\Labelshare /user:Administrator 2>&1', $output, $return_var);
$pathNetworkFolder = 'L:/Sampling_Labels/';
$letterPath = 'L:';
return array($pathNetworkFolder, $letterPath);
}
public function printerSampling() {
exec('net use K: \\\\10.148.5.68\\Labelshare /user:Administrator 2>&1', $output, $return_var);
$pathNetworkFolder = 'K:/Sampling_Labels/';
$letterPath = 'K:';
return array($pathNetworkFolder, $letterPath);
}
public function splitName($fullName) {
$words = explode(' ', $fullName); // Pisahkan nama berdasarkan spasi
$line1 = '';
$line2 = '';
// Tambahkan kata-kata ke baris pertama hingga mencapai batas 20 karakter
foreach ($words as $word) {
if (strlen($line1 . ' ' . $word) <= 27) {
$line1 .= (empty($line1) ? '' : ' ') . $word;
} else {
// Setelah line1 penuh, pindahkan kata ke line2
if (strlen($line2 . ' ' . $word) <= 19) {
$line2 .= (empty($line2) ? '' : ' ') . $word;
}
}
}
// Jika Line 2 lebih dari 19 karakter, hapus kata terakhir sampai sesuai
while (strlen($line2) > 19) {
$wordsLine2 = explode(' ', $line2);
array_pop($wordsLine2); // Hapus kata terakhir
$line2 = implode(' ', $wordsLine2); // Gabungkan kembali
}
// Kembalikan kedua baris sebagai array
return ['line1' => $line1, 'line2' => $line2];
}
// Untuk Ruang Laboratorium
public function labelCollection($access) {
$time = microtime(true);
$logTime = date('d-m-Y_H_i_s', $time) . sprintf('_%03d', ($time - floor($time)) * 1000);
$filename = "collection(".$access.")_".$logTime;
$networkPath = "";
$db = \Config\Database::connect();
$sql = "SELECT p.PATNUMBER as UHID, ctr.REQNUMBER as BV, concat (p.FIRSTNAMESK, ' ', p.NAME) as NAME, p.SEX,
DATEDIFF(YEAR, BirthDate, GETDATE()) -
CASE WHEN MONTH(BirthDate) > MONTH(GETDATE()) OR (MONTH(BirthDate) = MONTH(GETDATE()) AND DAY(BirthDate) > DAY(GETDATE())) THEN 1
ELSE 0 END AS AGE, sr.COLLECTIONDATE, p.BIRTHDATE
from SP_REQUESTS sr
left join cmod.dbo.CM_TM_REQUESTS ctr on ctr.REFFID=sr.HOSTORDERNUMBER
left join SP_REQUESTS st on sr.SP_ACCESSNUMBER=st.SP_ACCESSNUMBER
left join PATIENTS p on p.PATID=sr.PATID
where st.SP_ACCESSNUMBER='$access'";
$query = $db->query($sql);
$results = $query->getResultArray();
$item = $results[0];
$uhid = ltrim($item['UHID'], '0');
$bv = $item['BV'];
$sex = $item['SEX'] == 1 ? "M" : "F";
$title = $item['SEX'] == 1 ? "Mr" : "Mrs";
$name = $item['NAME'];
$age = $item['AGE'];
$birthdate = $item['BIRTHDATE'];
$date = \DateTime::createFromFormat('Y-m-d H:i:s.v', $birthdate);
if ($date) {
$birthdate = $date->format('d/m/Y');
} else {
$birthdate = "";
}
$collectiondate = $item['COLLECTIONDATE'];
$date = \DateTime::createFromFormat('Y-m-d H:i:s.v', $collectiondate);
if ($date) {
$collectiondate = $date->format('d/m/Y H:i');
} else {
$collectiondate = "";
}
$fixName = $this->splitName($name);
$name1 = $fixName['line1'];
$name2 = $fixName['line2'];
if ($sex == 'M') {
$jarak = '42';
} else {
$jarak = '53';
}
$label="";
$role = session()->get('userrole');
// Ruang Analis Printer POSTEK C168/200s + 16 untuk sudut
if ($role == 'admin' || $role == 'user') {
/*
$label = "N
OD
q400
Q200,10+0
I8,A,001
D10
A5,19,0,2,1,1,N,\"$title.$name1\"
A$jarak,36,0,2,1,1,N,\"$name2\"
A5,58,0,1,1,1,N,\"DoB: $birthdate\"
A337,58,0,1,1,1,N,\"$sex {$age}Y\"
B16,73,0,1,4,8,70,N,\"$access\"
A120,148,0,1,1,1,N,\"REQ# $access\"
A5,165,0,2,1,1,N,\"VN:$bv\"
A5,182,0,2,1,1,N,\"RM:$uhid\"
A195,182,0,2,1,1,N,\"$collectiondate\"
P1
";
*/
$label = "N
OD
q400
Q200,10+0
I8,A,001
D10
A5,4,0,2,1,1,N,\"$title.$name1\"
A$jarak,21,0,2,1,1,N,\"$name2\"
A5,43,0,1,1,1,N,\"DoB: $birthdate\"
A337,43,0,1,1,1,N,\"$sex {$age}Y\"
B16,58,0,1,4,8,70,N,\"$access\"
A120,133,0,1,1,1,N,\"REQ# $access\"
A5,150,0,2,1,1,N,\"VN:$bv\"
A5,167,0,2,1,1,N,\"RM:$uhid\"
A195,167,0,2,1,1,N,\"$collectiondate\"
P1
";
$printer = $this->printerLab();
} else if ($role == 'sampling') {
$label = "N
OD
q400
Q185,10+0
I8,A,001
D10
A4,3,0,2,1,1,N,\"$title.$name1\"
A$jarak,20,0,2,1,1,N,\"$name2\"
A4,42,0,1,1,1,N,\"DoB: $birthdate\"
A337,42,0,1,1,1,N,\"$sex {$age}Y\"
B15,57,0,1,4,8,70,N,\"$access\"
A120,132,0,1,1,1,N,\"REQ# $access\"
A4,164,0,2,1,1,N,\"RM:$uhid\"
A4,147,0,2,1,1,N,\"VN:$bv\"
A195,164,0,2,1,1,N,\"$collectiondate\"
P1
";
$printer = $this->printerSampling();
} else {
// Eksekusi Kode Berikut Apabila Role Bukan Analis atau Sampling
return $this->response->setJSON([
'message' => "Akses Tidak Berwenang",
'error' => "Hak Akses Anda Tidak Dikenali",
'status' => false,
]);
}
// $folder = "C:/data/";
$folder = $printer[0];
$fullPath = $folder . $filename;
// Tulis file ke folder tujuan
if (!file_put_contents($fullPath, $label)) {
//exec('net use '. $letterPath .' /delete 2>&1', $output, $return_var);
// Eksekusi Kode Berikut Apabila Ada Error
return $this->response->setJSON([
'error' => $output,
'message' => "Gagal Melakukan Print, Mohon Ulangi Atau Cek Koneksi Printer Anda",
'status' => false,
]);
} else {
// Hapus Koneksi
//exec('net use '. $letterPath .' /delete 2>&1', $output, $return_var);
return $this->response->setJSON( [
'message' => "Print Berhasil!" ,
'status' => true,
]);
}
}
// Untuk Ruang Laboratorium
public function labelPostek($sample, $title, $name, $sex, $age, $barcode, $uhid, $bv, $collection_date, $birthdate) {
$fixName = $this->splitName($name);
$name1 = $fixName['line1'];
$name2 = $fixName['line2'];
if ($sex == 'M') {
$jarak = '42';
} else {
$jarak = '53';
}
// Printer Posteck + 16 untuk sudut
/*
$sampleLabel ="N
OD
q400
Q200,10+0
I8,A,001
D10
A5,21,0,2,1,1,N,\"$title.$name1\"
A$jarak,38,0,2,1,1,N,\"$name2\"
A325,43,0,2,1,1,N,\"$sex {$age}Y\"
A5,65,0,2,1,1,N,\"$sample\"
A204,65,0,2,1,1,N,\"DoB: $birthdate\"
B37,86,0,1,4,8,70,N,\"$barcode\"
A115,161,0,2,1,1,N,\"SAM# $barcode\"
A5,183,0,2,1,1,N,\"RM:$uhid\"
A195,183,0,2,1,1,N,\"$collection_date\"
P1
";
*/
$sampleLabel ="N
OD
q400
Q200,10+0
I8,A,001
D10
A5,6,0,2,1,1,N,\"$title.$name1\"
A$jarak,23,0,2,1,1,N,\"$name2\"
A325,28,0,2,1,1,N,\"$sex {$age}Y\"
A5,50,0,2,1,1,N,\"$sample\"
A204,50,0,2,1,1,N,\"DoB: $birthdate\"
B37,71,0,1,4,8,70,N,\"$barcode\"
A115,146,0,2,1,1,N,\"SAM# $barcode\"
A5,168,0,2,1,1,N,\"RM:$uhid\"
A195,168,0,2,1,1,N,\"$collection_date\"
P1
";
return $sampleLabel;
}
// Untuk Ruang Sampling
public function labelZebra($sample, $title, $name, $sex, $age, $barcode, $uhid, $bv, $collection_date, $birthdate) {
$fixName = $this->splitName($name);
$name1 = $fixName['line1'];
$name2 = $fixName['line2'];
if ($sex == 'M') {
$jarak = '42';
} else {
$jarak = '53';
}
$sampleLabel ="N
OD
q400
Q185,10+0
I8,A,001
D10
A4,3,0,2,1,1,N,\"$title.$name1\"
A$jarak,20,0,2,1,1,N,\"$name2\"
A325,25,0,2,1,1,N,\"$sex {$age}Y\"
A4,47,0,2,1,1,N,\"$sample\"
A204,47,0,2,1,1,N,\"DoB: $birthdate\"
B37,68,0,1,4,8,70,N,\"$barcode\"
A115,143,0,2,1,1,N,\"SAM# $barcode\"
A4,165,0,2,1,1,N,\"RM:$uhid\"
A195,165,0,2,1,1,N,\"$collection_date\"
P1
";
return $sampleLabel;
}
public function printSingle($access, $sampletype) {
$time = microtime(true);
$logTime = date('d-m-Y_H_i_s', $time) . sprintf('_%03d', ($time - floor($time)) * 1000);
$filename = "sample(".$sampletype.")_".$logTime;
$role = session()->get('userrole');
$networkPath = "";
$db = \Config\Database::connect();
$sql = "select p.PATNUMBER as UHID, sr.HOSTORDERNUMBER as BV, concat (p.FIRSTNAMESK, ' ',p.NAME) as NAME, p.SEX,
DATEDIFF(YEAR, BirthDate, GETDATE()) -
CASE WHEN MONTH(BirthDate) > MONTH(GETDATE()) OR (MONTH(BirthDate) = MONTH(GETDATE()) AND DAY(BirthDate) > DAY(GETDATE())) THEN 1
ELSE 0 END AS AGE,
ds.SHORTTEXT AS FULLTEXT, st.SAMPLETYPE+right(sr.SP_ACCESSNUMBER,5) as BARCODE, sr.COLLECTIONDATE, p.BIRTHDATE
from SP_TUBES st
left join SP_REQUESTS sr on st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
left join PATIENTS p on p.PATID=sr.PATID
left join DICT_SAMPLES_TYPES ds on ds.SAMPCODE=st.SAMPLETYPE
where st.SP_ACCESSNUMBER='$access' AND ds.SAMPCODE = '$sampletype'";
$query = $db->query($sql);
$results = $query->getResultArray();
$item = $results[0];
$uhid = ltrim($item['UHID'], '0');
$bv = $item['BV'];
$sex = $item['SEX'] == 1 ? "M" : "F";
$title = $item['SEX'] == 1 ? "Mr" : "Mrs";
$name = $item['NAME'];
if ($sampletype == '200'){
$sample = 'SERUM KIMIA';
} else if ($sampletype == '250'){
$sample = 'SERUM IMUN';
} else {
$sample = $item['FULLTEXT'];
}
$barcode = $item['BARCODE'];
$age = $item['AGE'];
$birthdate = $item['BIRTHDATE'];
$date = \DateTime::createFromFormat('Y-m-d H:i:s.v', $birthdate);
if ($date) {
$birthdate = $date->format('d/m/Y');
} else {
$birthdate = "";
}
$collectiondate = $item['COLLECTIONDATE'];
$date = \DateTime::createFromFormat('Y-m-d H:i:s.v', $collectiondate);
if ($date) {
$collectiondate = $date->format('d/m/Y H:i');
} else {
$collectiondate = "";
}
// Ruang Analis Printer POSTEK C168/200s
if ($role === 'admin' || $role === 'user') {
$printer = $this->printerLab();
$label = $this->labelPostek($sample, $title, $name, $sex, $age, $barcode, $uhid, $bv, $collectiondate, $birthdate);
} else if ($role === 'sampling') {
$printer = $this->printerSampling();
$label = $this->labelZebra($sample, $title, $name, $sex, $age, $barcode, $uhid, $bv, $collectiondate, $birthdate);
} else {
// Eksekusi Kode Berikut Apabila Role Bukan Analis atau Sampling
return $this->response->setJSON([
'message' => "Akses Tidak Berwenang",
'error' => "Hak Akses Anda Tidak Dikenali",
'status' => false,
]);
}
// $folder = "C:/data/";
$folder = $printer[0];
$fullPath = $folder . $filename;
// Tulis file ke folder tujuan
if (!file_put_contents($fullPath, $label)) {
//exec('net use '. $letterPath .' /delete 2>&1', $output, $return_var);
// Eksekusi Kode Berikut Apabila Ada Error
return $this->response->setJSON([
'error' => $output,
'message' => "Gagal Melakukan Print, Mohon Ulangi Atau Cek Koneksi Printer Anda",
'status' => false,
]);
} else {
// Hapus Koneksi
//exec('net use '. $letterPath .' /delete 2>&1', $output, $return_var);
return $this->response->setJSON( [
'message' => "Print Berhasil!" ,
'status' => true,
]);
}
}
public function printAll($access) {
$db = \Config\Database::connect();
$sql = "select SAMPLETYPE from SP_TUBES where SP_ACCESSNUMBER='$access'";
$query = $db->query($sql);
$results = $query->getResultArray();
foreach($results as $data) {
$sample = $data['SAMPLETYPE'];
$this->printSingle($access, $sample);
}
$this->labelCollection($access);
}
}

View File

@ -0,0 +1,274 @@
<?php
namespace App\Controllers;
class PrintLabelSby extends BaseController {
public function splitName($fullName) {
$words = explode(' ', $fullName); // Pisahkan nama berdasarkan spasi
$line1 = '';
$line2 = '';
// Tambahkan kata-kata ke baris pertama hingga mencapai batas 20 karakter
foreach ($words as $word) {
if (strlen($line1 . ' ' . $word) <= 27) {
$line1 .= (empty($line1) ? '' : ' ') . $word;
} else {
// Setelah line1 penuh, pindahkan kata ke line2
if (strlen($line2 . ' ' . $word) <= 19) {
$line2 .= (empty($line2) ? '' : ' ') . $word;
}
}
}
// Jika Line 2 lebih dari 19 karakter, hapus kata terakhir sampai sesuai
while (strlen($line2) > 19) {
$wordsLine2 = explode(' ', $line2);
array_pop($wordsLine2); // Hapus kata terakhir
$line2 = implode(' ', $wordsLine2); // Gabungkan kembali
}
// Kembalikan kedua baris sebagai array
return ['line1' => $line1, 'line2' => $line2];
}
public function labelZebraCollection($access) {
$time = microtime(true);
$logTime = date('d-m-Y_H_i_s', $time) . sprintf('_%03d', ($time - floor($time)) * 1000);
$filename = "collection(".$access.")_".$logTime;
$role = session()->get('userrole');
$networkPath = "";
$db = \Config\Database::connect();
$sql = "select p.PATNUMBER as UHID, sr.HOSTORDERNUMBER as BV, concat (p.FIRSTNAMESK, ' ', p.NAME) as NAME, p.SEX,
DATEDIFF(YEAR, BirthDate, GETDATE()) -
CASE WHEN MONTH(BirthDate) > MONTH(GETDATE()) OR (MONTH(BirthDate) = MONTH(GETDATE()) AND DAY(BirthDate) > DAY(GETDATE())) THEN 1
ELSE 0 END AS AGE, sr.COLLECTIONDATE, p.BIRTHDATE
from SP_REQUESTS sr
left join SP_REQUESTS st on sr.SP_ACCESSNUMBER=st.SP_ACCESSNUMBER
left join PATIENTS p on p.PATID=sr.PATID
where st.SP_ACCESSNUMBER='$access'";
$query = $db->query($sql);
$results = $query->getResultArray();
$item = $results[0];
$uhid = substr($item['UHID'], -10);
$bv = $item['BV'];
$sex = $item['SEX'] == 1 ? "M" : "F";
$title = $item['SEX'] == 1 ? "Mr" : "Mrs";
$name = $item['NAME'];
$age = $item['AGE'];
$birthdate = $item['BIRTHDATE'];
$date = \DateTime::createFromFormat('Y-m-d H:i:s.v', $birthdate);
if ($date) {
$birthdate = $date->format('d/m/Y');
} else {
$birthdate = "";
}
$collectiondate = $item['COLLECTIONDATE'];
$date = \DateTime::createFromFormat('Y-m-d H:i:s.v', $collectiondate);
if ($date) {
$collectiondate = $date->format('d/m/Y H:i');
} else {
$collectiondate = "";
}
$fixName = $this->splitName($name);
$name1 = $fixName['line1'];
$name2 = $fixName['line2'];
if ($sex == 'M') {
$jarak = '42';
} else {
$jarak = '53';
}
$label = "^XA
^LH0,0
^LL400
^PW400
^FO4,10^ADN,18,10^FD$title.$name1^FS
^FO$jarak,27^ADN,18,10^FD$name2^FS
^FO325,42^ADN,18,10^FD$sex {$age}Y^FS
^FO4,47^ADN,18,10^FDDoB: $birthdate^FS
^FO50,67^BY2,2,70^BCN,70,N,N^FD$access^FS
^FO110,142^ADN,18,10^FDREQ# $access^FS
^FO4,181^ADN,18,10^FDRM:$uhid^FS
^FO4,164^ADN,18,10^FDVN:$bv^FS
^FO195,181^ADN,18,10^FD$collectiondate^FS
^XZ
";
$printer = $this->printerLab();
// $folder = "C:/data/";
$folder = $printer[0];
$fullPath = $folder . $filename;
// Tulis file ke folder tujuan
if (!file_put_contents($fullPath, $label)) {
//exec('net use '. $letterPath .' /delete 2>&1', $output, $return_var);
// Eksekusi Kode Berikut Apabila Ada Error
return $this->response->setJSON([
'error' => $output,
'message' => "Gagal Melakukan Print, Mohon Ulangi Atau Cek Koneksi Printer Anda",
'status' => false,
]);
} else {
// Hapus Koneksi
//exec('net use '. $letterPath .' /delete 2>&1', $output, $return_var);
return $this->response->setJSON( [
'message' => "Print Berhasil!" ,
'status' => true,
]);
}
}
public function labelZebra($sample, $title, $name, $sex, $age, $barcode, $uhid, $bv, $collection_date, $birthdate) {
$fixName = $this->splitName($name);
$name1 = $fixName['line1'];
$name2 = $fixName['line2'];
if ($sex == 'M') {
$jarak = '42';
} else {
$jarak = '53';
}
$sampleLabel = "^XA
^LH0,0
^LL400
^PW400
^FO4,20^ADN,18,10^FD$title.$name1^FS
^FO$jarak,37^ADN,18,10^FD$name2^FS
^FO325,42^ADN,18,10^FD$sex {$age}Y^FS
^FO4,54^ADN,18,10^FD$sample^FS
^FO205,64^ADN,18,10^FDDoB: $birthdate^FS
^FO65,85^BY2,3,70^BCN,70,N,N^FD$barcode^FS
^FO115,160^ADN,18,10^FDSAM# $barcode^FS
^FO4,182^ADN,18,10^FDRM:$uhid^FS
^FO195,182^ADN,18,10^FD$collection_date^FS
^XZ
";
return $sampleLabel;
}
public function printerLab() {
// IP PC Lab
// exec('net use Y: \\\\10.0.10.30\\Labelshare /user:Administrator 2>&1', $output, $return_var);
// $pathNetworkFolder = 'Y:/Sampling_Labels/';
// $letterPath = 'Y:';
// IP PC Sampling
exec('net use V: \\\\10.0.2.125\\Labelshare /user:Administrator 2>&1', $output, $return_var);
$pathNetworkFolder = 'V:/Sampling_Labels/';
$letterPath = 'V:';
return array($pathNetworkFolder, $letterPath);
}
public function printSingle($access, $sampletype) {
$time = microtime(true);
$logTime = date('d-m-Y_H_i_s', $time) . sprintf('_%03d', ($time - floor($time)) * 1000);
$filename = "sample(".$sampletype.")_".$logTime;
$role = session()->get('userrole');
$networkPath = "";
$db = \Config\Database::connect();
$sql = "select p.PATNUMBER as UHID, sr.HOSTORDERNUMBER as BV, concat (p.FIRSTNAMESK, ' ',p.NAME) as NAME, p.SEX,
DATEDIFF(YEAR, BirthDate, GETDATE()) -
CASE WHEN MONTH(BirthDate) > MONTH(GETDATE()) OR (MONTH(BirthDate) = MONTH(GETDATE()) AND DAY(BirthDate) > DAY(GETDATE())) THEN 1
ELSE 0 END AS AGE,
ds.SHORTTEXT AS FULLTEXT, st.SAMPLETYPE+right(sr.SP_ACCESSNUMBER,5) as BARCODE, sr.COLLECTIONDATE, p.BIRTHDATE
from SP_TUBES st
left join SP_REQUESTS sr on st.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
left join PATIENTS p on p.PATID=sr.PATID
left join DICT_SAMPLES_TYPES ds on ds.SAMPCODE=st.SAMPLETYPE
where st.SP_ACCESSNUMBER='$access' AND ds.SAMPCODE = '$sampletype'";
$query = $db->query($sql);
$results = $query->getResultArray();
$item = $results[0];
$uhid = substr($item['UHID'], -10);
$bv = $item['BV'];
$sex = $item['SEX'] == 1 ? "M" : "F";
$title = $item['SEX'] == 1 ? "Mr" : "Mrs";
$name = $item['NAME'];
if ($sampletype == '200'){
$sample = 'SERUM KIMIA';
} else if ($sampletype == '250'){
$sample = 'SERUM IMUN';
} else {
$sample = $item['FULLTEXT'];
}
$barcode = $item['BARCODE'];
$age = $item['AGE'];
$birthdate = $item['BIRTHDATE'];
$date = \DateTime::createFromFormat('Y-m-d H:i:s.v', $birthdate);
if ($date) {
$birthdate = $date->format('d/m/Y');
} else {
$birthdate = "";
}
$collectiondate = $item['COLLECTIONDATE'];
$date = \DateTime::createFromFormat('Y-m-d H:i:s.v', $collectiondate);
if ($date) {
$collectiondate = $date->format('d/m/Y H:i');
} else {
$collectiondate = "";
}
$printer = $this->printerLab();
$label = $this->labelZebra($sample, $title, $name, $sex, $age, $barcode, $uhid, $bv, $collectiondate, $birthdate);
// $folder = "C:/data/";
$folder = $printer[0];
$fullPath = $folder . $filename;
// Tulis file ke folder tujuan
if (!file_put_contents($fullPath, $label)) {
//exec('net use '. $letterPath .' /delete 2>&1', $output, $return_var);
// Eksekusi Kode Berikut Apabila Ada Error
return $this->response->setJSON([
'error' => $output,
'message' => "Gagal Melakukan Print, Mohon Ulangi Atau Cek Koneksi Printer Anda",
'status' => false,
]);
} else {
// Hapus Koneksi
//exec('net use '. $letterPath .' /delete 2>&1', $output, $return_var);
return $this->response->setJSON( [
'message' => "Print Berhasil!" ,
'status' => true,
]);
}
}
public function printAll($access) {
$db = \Config\Database::connect();
$sql = "select SAMPLETYPE from SP_TUBES where SP_ACCESSNUMBER='$access'";
$query = $db->query($sql);
$results = $query->getResultArray();
foreach($results as $data) {
$sample = $data['SAMPLETYPE'];
$this->printSingle($access, $sample);
}
$this->labelZebraCollection($access);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
<?php
namespace App\Controllers;
class SamplingController extends BaseController {
public function index() {
return view('sampling/dashboard');
}
public function viewAccess($accessnumber): string {
// Mengetahui Apakah User Bali atau Surabaya
$data['usercityid'] = session()->get('usercityid');
$db = \Config\Database::connect();
$sql = "SELECT sr.HOSTORDERNUMBER, tu.SAMPLETYPE, ds.FULLTEXT as SHORTTEXT, tu.TUBESTATUS, ct.COLLSTATUS, ct.TUBECOMMENT from SP_TUBES tu
left join SP_REQUESTS sr on tu.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
left join DICT_SAMPLES_TYPES ds on ds.SAMPCODE= tu.SAMPLETYPE
left join cmod.dbo.CM_TUBES ct on ct.SAMPLETYPE=tu.SAMPLETYPE and ct.ACCESSNUMBER=tu.SP_ACCESSNUMBER
where tu.SP_ACCESSNUMBER='$accessnumber'";
$query = $db->query($sql);
$results = $query->getResultArray();
$visit_number = $results[0]['HOSTORDERNUMBER'];
$data['data'] = $results;
// $sql = "select hp.PATNUMBER, hp.PATNAME, ho.PAYERNAME, ho.TREATDOC
// from cmod.dbo.CM_HIS_ORDERS ho
// left join cmod.dbo.CM_HIS_PATIENTS hp on hp.PATID=ho.PATID
// WHERE ho.VISITNUMBER='$visit_number'";
$sql = "SELECT ctp.PATNUMBER, CONCAT(ctp.FIRSTNAME, ' ', ctp.LASTNAME) as PATNAME, ctr.AGENT as PAYERNAME, ctr.DOC as TREATDOC, ctr.VISITTYPE
from cmod.dbo.CM_TM_REQUESTS ctr
left join cmod.dbo.CM_TM_PATIENTS ctp on ctr.PATID = ctp.PATID
where ctr.REFFID='$visit_number'";
$query = $db->query($sql);
$results = $query->getResultArray();
if($results != null) {
$data['patnumber'] = $results[0]['PATNUMBER'];
$data['patient_fullname'] = $results[0]['PATNAME'];
$data['visit_description'] = $results[0]['VISITTYPE'];
$data['treating_doctor'] = $results[0]['TREATDOC'];
$data['payer_name'] = $results[0]['PAYERNAME'];
} else {
$data['patnumber'] = "";
$data['patient_fullname'] = "";
$data['visit_description'] = "";
$data['treating_doctor'] = "";
$data['payer_name'] = "";
}
$data['accessnumber'] = $accessnumber;
return view('sampling/dashboard_viewAccess', $data);
}
public function changePass() {
if ($this->request->getMethod() === 'POST') {
$password1 = $this->request->getVar('password1');
$password2 = $this->request->getVar('password2');
$data['password1'] = $password1;
$data['password2'] = $password2;
if($password1 == $password2) {
$password = password_hash($password1,PASSWORD_DEFAULT);
$db = \Config\Database::connect();
$sql = "update cmod.dbo.CM_USERS set PASSWORD='$password' where USERID='$userid'";
$db->query($sql);
return redirect()->to("/");
} else {
return redirect()->to("/auth/setpass/$userid")->with('flash_error', 'password is not the same.');
}
}
return view('changePass');
}
}

View File

View File

@ -0,0 +1,93 @@
<?php
namespace App\Controllers;
class UserController extends BaseController {
public function index() {
return view('user/dashboard');
}
public function viewAccess($accessnumber): string {
// Mengetahui Apakah User Bali atau Surabaya
$data['usercityid'] = session()->get('usercityid');
$db = \Config\Database::connect();
$sql = "SELECT sr.HOSTORDERNUMBER, tu.SAMPLETYPE, ds.FULLTEXT as SHORTTEXT, tu.TUBESTATUS, ct.COLLSTATUS, ct.TUBECOMMENT from SP_TUBES tu
left join SP_REQUESTS sr on tu.SP_ACCESSNUMBER=sr.SP_ACCESSNUMBER
left join DICT_SAMPLES_TYPES ds on ds.SAMPCODE= tu.SAMPLETYPE
left join cmod.dbo.CM_TUBES ct on ct.SAMPLETYPE=tu.SAMPLETYPE and ct.ACCESSNUMBER=tu.SP_ACCESSNUMBER
where tu.SP_ACCESSNUMBER='$accessnumber'";
$query = $db->query($sql);
$results = $query->getResultArray();
$visit_number = $results[0]['HOSTORDERNUMBER'];
$data['data'] = $results;
// $sql = "select hp.PATNUMBER, hp.PATNAME, ho.PAYERNAME, ho.TREATDOC
// from cmod.dbo.CM_HIS_ORDERS ho
// left join cmod.dbo.CM_HIS_PATIENTS hp on hp.PATID=ho.PATID
// WHERE ho.VISITNUMBER='$visit_number'";
$sql = "SELECT ctp.PATNUMBER, CONCAT(ctp.FIRSTNAME, ' ', ctp.LASTNAME) as PATNAME, ctr.AGENT as PAYERNAME, ctr.DOC as TREATDOC, ctr.VISITTYPE
from cmod.dbo.CM_TM_REQUESTS ctr
left join cmod.dbo.CM_TM_PATIENTS ctp on ctr.PATID = ctp.PATID
where ctr.REFFID='$visit_number'";
$query = $db->query($sql);
$results = $query->getResultArray();
if($results != null) {
$data['patnumber'] = $results[0]['PATNUMBER'];
$data['patient_fullname'] = $results[0]['PATNAME'];
$data['visit_description'] = $results[0]['VISITTYPE'];
$data['treating_doctor'] = $results[0]['TREATDOC'];
$data['payer_name'] = $results[0]['PAYERNAME'];
} else {
$data['patnumber'] = "";
$data['patient_fullname'] = "";
$data['visit_description'] = "";
$data['treating_doctor'] = "";
$data['payer_name'] = "";
}
$data['accessnumber'] = $accessnumber;
return view('user/dashboard_viewAccess', $data);
}
public function orders_index() {
return view('orders_index');
}
public function orders_edit($orderid) {
$db = \Config\Database::connect();
$sql = "select * from cmod.dbo.CM_DICT_MAPPINGS";
$query = $db->query($sql);
$results = $query->getResultArray();
$data['tests'] = $results;
$data['orderid'] = $orderid;
return view('orders_edit', $data);
}
public function patients_index() {
return view('patients_index');
}
public function changePass() {
if ($this->request->getMethod() === 'POST') {
$password1 = $this->request->getVar('password1');
$password2 = $this->request->getVar('password2');
$data['password1'] = $password1;
$data['password2'] = $password2;
if($password1 == $password2) {
$password = password_hash($password1,PASSWORD_DEFAULT);
$db = \Config\Database::connect();
$sql = "update cmod.dbo.CM_USERS set PASSWORD='$password' where USERID='$userid'";
$db->query($sql);
return redirect()->to("/");
} else {
return redirect()->to("/auth/setpass/$userid")->with('flash_error', 'password is not the same.');
}
}
return view('changePass');
}
}

View File

@ -5,12 +5,17 @@ use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
class Auth implements FilterInterface {
class RoleFilter implements FilterInterface {
public function before(RequestInterface $request, $arguments = null) {
if (!session()->get('username')) {
return redirect()->to('/auth/login');
}
$userRole = session()->get('userrole');
if ($arguments && !in_array($userRole, $arguments)) {
return redirect()->to('/no-access');
}
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) {

View File

@ -0,0 +1,297 @@
<?= $this->extend('admin/layout/main.php') ?>
<?= $this->section('content') ?>
<style>
.pointercol {
cursor: pointer;
}
</style>
<div id='stats' class="d-flex justify-content-between p-0">
</div>
<div class="card border-0">
<!-- div.card-head -->
<div class="card-body">
<div class="row d-flex align-items-center">
<div class="col col-auto">
<b>Date</b>&nbsp; &nbsp;:&nbsp; &nbsp;<input class='date1' type='date' value=''> - <input class='date2' type='date'>
</div>
<div class="col col-auto">
<button class='btn btn-sm btn-primary py-1 px-2 d-flex align-items-center' onclick='index()'><i class="bi bi-calendar2-event"></i>&nbsp;&nbsp;Search</button>
</div>
</div>
<div class="table-responsive mt-3">
<table id="myTable" class="table table-hover">
<thead class='text-start'>
<th class='text-start' width="10%">Order Date</th>
<th width="12%">Patient#</th>
<th width="17%">Patient Name</th>
<th class='text-start' width="10%">Access#</th>
<th width="10%">Visit#</th>
<th width="10%">HIS#</th>
<th>Test</th>
<th width="5%">Status</th>
<th></th>
</thead>
<tbody id="table-body" class='text-start'>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
date = new Date();
//console.log (new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON());
//let curDate = new Date().toJSON().slice(0, 10);
let curDate = (new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON()).slice(0, 10);
$('.date1').val(curDate);
$('.date2').val(curDate);
index();
document.addEventListener('keydown', function(event) {
if (event.key === 'F5') { event.preventDefault(); index(); }
});
function index() {
let url = '<?=base_url('');?>api/dashboard/index';
date1 = $('.date1').val();
date2 = $('.date2').val();
$.ajax({
url: url,
method: 'POST',
data : {date1:date1, date2:date2},
success: function(response) {
/*
// counter
*/
$("#stats").html("");
var stats = ['Pend', 'PartColl', 'Coll', 'PartRecv', 'Recv', 'Inc', 'PartVal', 'Comp'];
var statcolor = ['text-orange', 'text-peach', 'text-pink', 'text-soft-blue', 'text-blue', 'text-grey', 'text-soft-green', 'text-green'];
var staticon = ['bi-clock-history','bi-tv', 'bi-collection', 'bi-file-medical', 'bi-journal-medical', 'bi-calendar3-week', 'bi-check2', 'bi-clipboard-check'];
var stattext = ['Pending', 'Part Collected', 'Collected', 'Part Received', 'Received', 'Incomplete', 'Part Validated', 'Validated'];
var count = response['count'];
var statcontent = '';
stats.forEach ( (item, index) => {
//console.log(item + ' ' + index);
if(!count[item]) { count[item] = 0; }
statcontent += '<div class="custom-card shadow" data-filtertype="'+index+'">' +
'<div class="custom-card-content">' +
'<div class="row p-0 d-flex justify-content-between">' +
'<div class="col-3 text-start '+statcolor[index]+'"> <h5 class="m-0"><i class="bi '+staticon[index]+'"></i></h5> </div>' +
'<div class="col-9 text-end pe-3"> <h2 class="m-0 custom-card-title">'+count[item]+'</h2> </div>' +
'</div>' +
"<hr class='"+statcolor[index]+"'>" +
'<h3 class="custom-card-text m-0 p-0 '+statcolor[index]+'">'+ stattext[index] +'</h3>' +
'</div>' +
'</div>';
});
$("#stats").html(statcontent);
/*
// table
*/
$("#myTable").DataTable().destroy();
$("#table-body").html("");
var data = response['data'];
// console.log(data);
for (var i = 0; i < data.length; i++) {
colldate = data[i].COLLECTIONDATE.slice(0,10);
colltime = data[i].COLLECTIONDATE.slice(10,16);
if (data[i].PATNUMBER != null) {
// patnumber = data[i].PATNUMBER;
patnumber = data[i].PATNUMBER.replace(/^0+/, '');
// patnumber = data[i].PATNUMBER.substr(-16,16);
// patnumber = patnumber.substring(patnumber.length - 10);
} else {
patnumber = ' NULL ';
}
accessnumber = data[i].SP_ACCESSNUMBER;
patname = data[i].NAME;
hon = data[i].HOSTORDERNUMBER;
// Khusus untuk data Testing
let testing_test = "";
if (hon != null) { // Jaga" Kalau ada yg Null
if (hon[0] === 'X' || hon[0] === 'Z') {
testing_test = "<div class='badge text-bg-warning'>testing tm</div><br>";
} else {
testing_test = "";
}
}
if (data[i].REFFID != null) {
// patnumber = data[i].PATNUMBER;
reffid = data[i].REFFID;
// patnumber = data[i].PATNUMBER.substr(-16,16);
// patnumber = patnumber.substring(patnumber.length - 10);
} else {
reffid = ' NULL ';
}
tests = data[i].TESTS;
stat = data[i].STATS;
reqstatus = String(data[i].REQSTATUS);
trcolor = '';
if (reqstatus != '1') {
if(stat == 'Pend') {
bgcolor = 'bg-orange';
datafilter = "data-filterrow='0'";
stattext = 'Pending';
} else if(stat == 'PartColl') {
bgcolor = 'bg-peach';
datafilter = "data-filterrow='1'";
stattext = 'Part Collected';
} else if(stat == 'Coll') {
bgcolor = 'bg-pink';
datafilter = "data-filterrow='2'";
stattext = 'Collected';
} else if(stat == 'PartRecv') {
bgcolor = 'bg-soft-blue';
datafilter = "data-filterrow='3'";
stattext = 'Part Received';
} else if(stat == 'Recv') {
bgcolor = 'bg-blue';
datafilter = "data-filterrow='4'";
stattext = 'Received';
} else if(stat == 'Inc') {
bgcolor = 'bg-grey';
datafilter = "data-filterrow='5'";
stattext = 'Incomplete';
} else if(stat == 'PartVal') {
bgcolor = 'bg-soft-green';
datafilter = "data-filterrow='6'";
stattext = 'Part Validated';
} else if(stat == 'Comp') {
bgcolor = 'bg-green';
datafilter = "data-filterrow='7'";
stattext = 'Validated';
}
} else {
trcolor = ' table-danger-custom ';
bgcolor = ' table-danger-custom ';
datafilter = "data-filterrow='8'";
stattext = 'Cancelled';
}
let datarow = "<tr class='align-middle" + trcolor +"'" + datafilter + " >" +
"<td class='text-start'>" + colldate + '<br>'+ colltime +'</td>'+
"<td class='text-start' style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + patnumber + "<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + patname.trim() + "<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td class='text-start' style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + accessnumber +"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + testing_test + hon +"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>"+
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>"+reffid+"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>"+
"<td>" + tests + '</td>' +
"<td role='button' class='"+bgcolor+" text-center align-middle pointercol' onclick='viewAccess("+accessnumber+")'>"+stattext+"</td>" +
"<td role='button' class='text-center align-middle' onclick='resultPdfAccess("+accessnumber+ ",event" +")'> <h4 class='p-0 m-0'><i class='bi bi-filetype-pdf'></i></h4> </td>" +
'</tr>';
$("#table-body").append(datarow);
}
$('#myTable').DataTable({
"order": [0, "desc"], // Urutan Tanggal Desc
"pageLength": 50, // Ganti sesuai kebutuhan
"lengthMenu": [50, 75, 100] // Pilihan dropdown entries per halaman
});
// datatable filter
const filterButton = document.querySelectorAll("[data-filtertype]");
const table = document.querySelector("#myTable");
const tr = table.getElementsByTagName("tr");
let activeButton = null;
filterButton.forEach((button) => {
button.addEventListener("click", () => {
const selectedButton = button.getAttribute("data-filtertype");
console.log(selectedButton);
if (activeButton === button) {
button.classList.remove("active", "border", "border-primary", "border-5");
activeButton = null;
for (let i = 1; i < tr.length; i++) {
tr[i].style.display = "";
}
} else {
filterButton.forEach((btn) => btn.classList.remove("active", "border", "border-info", "border-3"));
button.classList.add("active", "border", "border-info", "border-3");
activeButton = button;
for (let i = 1; i < tr.length; i++) {
const filterValue = tr[i].getAttribute("data-filterrow");
if (filterValue === selectedButton) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
});
});
},
error: function(response) { console.log(response.responseJSON); }
});
}
function viewAccess(access) {
let url = '<?=base_url();?>admin/dashboard/viewAccess/'+access;
$('.modal-content').load(url, function(){
$('#modal').modal('show');
});
}
function resultPdfAccess(access, event) {
event.stopPropagation(); // Mencegah klik pada <tr> dieksekusi
let url = '<?=base_url();?>printResult/'+access;
window.open(url, '_blank');
}
function copyToClipboard(element) {
let text = element.innerText.trim(); // Ambil teks dari elemen
text = text.replace("Teks sudah disalin", "").trim(); // Hilangkan teks notifikasi sebelumnya
if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(() => {
showCopyMessage(element);
}).catch(err => {
console.error("Gagal menyalin teks: ", err);
});
} else {
// Alternatif jika Clipboard API tidak didukung
let tempInput = document.createElement("textarea");
tempInput.value = text;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
showCopyMessage(element);
}
}
function showCopyMessage(element) {
let message = element.querySelector(".copy-message");
if (message) {
message.style.display = "inline"; // Tampilkan teks notifikasi
// Sembunyikan kembali setelah 2 detik
setTimeout(() => {
message.style.display = "none";
}, 500);
}
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,107 @@
<?= $this->extend('admin/layout/main.php') ?>
<?= $this->section('content') ?>
<style>
#myTable {
cursor: pointer;
}
</style>
<div id='stats' class="d-flex justify-content-between p-0">
</div>
<div class="card border-0">
<div class="card-body">
<div class='card-title'><u><h4>Request from Transmedic</h4></u></div>
<div class="row d-flex align-items-center">
<div class="col col-auto">
<b>Date</b>&nbsp; &nbsp;:&nbsp; &nbsp;<input class='date1' type='date' value=''> - <input class='date2' type='date'>
</div>
<div class="col col-auto">
<button class='btn btn-sm btn-primary py-1 px-2 d-flex align-items-center' onclick='index()'><i class="bi bi-calendar2-event"></i>&nbsp;&nbsp;Search</button>
</div>
</div>
<div class="table-responsive mt-3">
<table id="myTable" class="table table-hover">
<thead class='text-start'>
<th>(GMT)</th>
<th>Reff#</th>
<th>Access#</th>
<th>RM#</th>
<th>Patient Name</th>
<th>Test</th>
<th></th>
</thead>
<tbody id="table-body" class='text-start'>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
let curDate = new Date().toJSON().slice(0, 10);
$('.date1').val(curDate);
$('.date2').val(curDate);
index();
function index() {
let url = '<?=base_url();?>api/tm/index';
date1 = $('.date1').val();
date2 = $('.date2').val();
$.ajax({
url: url,
method: 'POST',
data : {date1:date1, date2:date2},
success: function(response) {
$("#myTable").DataTable().destroy();
$("#table-body").html("");
var data = response['data'];
for (var i = 0; i < data.length; i++) {
console.log(data[i]);
reqdate = data[i].REQDATE;
logdate = data[i].LOGDATE;
reffid = data[i].REFFID;
accessnumber = data[i].SP_ACCESSNUMBER;
patnumber = data[i].PATNUMBER;
patname = data[i].FIRSTNAME+' '+data[i].LASTNAME;
tests = data[i].TESTS;
let datarow = "<tr class='align-middle main_table'>" +
"<td> req : " + reqdate + '<br / >log : ' + logdate + '</td> <td>' + reffid + '</td> <td>' + accessnumber + '</td> <td>' + patnumber + '</td> <td>' + patname + '</td> <td>' + tests
+ '</td> </tr>';
$("#table-body").append(datarow);
}
//$('#myTable').DataTable();
},
error: function(response) { console.log(response.responseJSON); }
});
}
function viewAccess(access) {
let url = '<?=base_url();?>admin/dashboard/viewAccess/'+access;
$('.modal-content').load(url, function(){
$('#modal').modal('show');
});
}
function resultPdfAccess(access, event) {
event.stopPropagation(); // Mencegah klik pada <tr> dieksekusi
let url = '<?=base_url();?>printResult/'+access;
window.open(url, '_blank');
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,304 @@
<?php
if(isset($data[0])) {
$row = $data[0];
// if (strlen($patnumber) < 10) {
// $patnumber = str_pad($patnumber, 10, "0", STR_PAD_LEFT);
// }
?>
<div class="modal-header bg-soft-green text-white">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Detail Request </h1>
<button type="button" class="btn-close text-white" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<div class="row">
<div class="col">
<table class="table table-sm table-borderless">
<tr>
<th width='18%'>Access Number</th>
<th>:</th>
<td width='31%'><?=$accessnumber;?></td>
<th>Visit Description</th>
<th>:</th>
<td><?=$visit_description;?></td>
</tr>
<tr>
<th>Patient Number</th>
<th>:</th>
<td><?=$patnumber;?></td>
<th width='18%'>Payer Name</th>
<th>:</th>
<td width='31%'><?=$payer_name;?></td>
</tr>
<tr>
<th>Patient Name</th>
<th>:</th>
<td><?=$patient_fullname;?></td>
<th>Treating Doctor</th>
<th>:</th>
<td><?=$treating_doctor;?></td>
</tr>
</table>
</div>
</div>
<div class='row'>
<div class="col-12">
<div class="card bg-white">
<div class="card-body">
<div class="card-title"><h3>Sample List</h3></div>
<table class='table'>
<tr> <th class='text-center'>Coll.</th> <th class='text-center'>Recv.</th> <th>Sample Name</th> <th>Action</th> <th>Comment</th> </tr>
<tr>
<td></td> <td></td> <td>All</td>
<td>
<button type='button' class='btn btn-dark m-0 px-2 py-1' onclick="printAllLabel(<?=$accessnumber;?>, <?=$usercityid;?>)"> <h6 class='p-0 m-0'><i class='bi bi-printer'></i></h6> </button>
<button type='button' class='btn btn-success m-0 px-2 py-1' onclick='collectAll(<?=$accessnumber;?>)'><h6 class='p-0 m-0'>Coll.</h6></button>
<!-- <button class='badge bg-black text-white m-0 px-2 py-1' onclick='uncollectAll(<?=$accessnumber;?>)'>un-collect</button> -->
<!-- <button type='button' class='btn btn-primary m-0 px-2 py-1' onclick='unreceiveAll(<?=$accessnumber;?>)'><h6 class='p-0 m-0'>Un-Rec.</h6></button> -->
</td>
</tr>
<tr>
<td></td> <td></td> <td>Collection</td>
<td><button type='button' class='btn btn-dark m-0 px-2 py-1' onclick="printCollectionLabel(<?=$accessnumber;?>, <?=$usercityid;?>)"><h6 class='p-0 m-0'> <i class='bi bi-printer'></i></h6></button></td>
</tr>
<?php
foreach($data as $row) {
$sampletype = $row['SAMPLETYPE'];
$sampletext = $row['SHORTTEXT'];
if ($sampletype == "200") {
$sampletext = "Serum Kimia";
} else if ($sampletype == '250') {
$sampletext = "Serum Imun";
}
$tubestatus = $row['TUBESTATUS'];
$collstatus = $row['COLLSTATUS'];
$comment = $row['TUBECOMMENT'];
echo "\r\n <tr>";
if($collstatus==1) {
echo " <td class='text-center'><input type='checkbox' class='form-check-input' id='coll$sampletype' checked disabled></td>";
} else {
echo " <td class='text-center'><input type='checkbox' class='form-check-input' id='coll$sampletype' disabled></td>";
}
if($tubestatus==4) {
echo "<td class='text-center'><input type='checkbox' class='form-check-input' id='recv$sampletype' checked disabled></td>";
} else {
echo "<td class='text-center'><input type='checkbox' class='form-check-input' id='recv$sampletype' disabled></td>";
}
echo "<td>$sampletext ($sampletype)</td>";
echo "<td>
<button type='button' class='btn btn-dark m-0 px-2 py-1' " . "onclick='printSingleLabel($accessnumber, $sampletype, $usercityid)'" . "><h6 class='p-0 m-0'><i class='bi bi-printer'></i></h6></button>
<button type='button' class='btn btn-success m-0 px-2 py-1' onclick='collect($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Coll.</h6></button>
<button type='button' class='btn btn-warning m-0 px-2 py-1' onclick='uncollect($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Un-Coll.</h6></button>
<button type='button' class='btn btn-primary m-0 px-2 py-1' onclick='unreceive($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Un-Rec.</h6></button>
</td> ";
echo "<td id='comment$sampletype'>$comment <h6 class='p-0 m-0'><i class='bi bi-pencil-square' role='button' onclick='comment($sampletype, $accessnumber, \"$sampletext\", \"$comment\")'></i></h6></td>";
echo " </tr>";
}
?>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
function printCollectionLabel(access, usercityid){
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/collection/'+access.toString();
} else {
url = '<?=base_url();?>printLabel/collection/'+access.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function printSingleLabel(access, sample, usercityid) {
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/single/'+access.toString()+'/'+sample.toString();
} else {
url = '<?=base_url();?>printLabel/single/'+access.toString()+'/'+sample.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function printAllLabel(access, usercityid) {
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/all/'+access.toString();
} else {
url = '<?=base_url();?>printLabel/all/'+access.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function collect(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/collect/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#coll"+sample).prop("checked", true);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function collectAll(access) {
const url = '<?=base_url();?>tubes/collectAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="coll"]').prop('checked', true);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function uncollect(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/uncollect/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#coll"+sample).prop("checked", false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function uncollectAll(access) {
const url = '<?=base_url();?>tubes/uncollectAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="coll"]').prop('checked', false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function unreceive(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/unreceive/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#recv"+sample).prop("checked", false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function unreceiveAll(access) {
const url = '<?=base_url();?>tubes/unreceiveAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="recv"]').prop('checked', false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function comment(sample, access, sampletext, comments) {
const url = '<?=base_url();?>tubes/comment/'+access+'/'+sample;
let comment = prompt('Comment for sample '+sampletext, comments);
//$('#comment'+sample).html(comment +"<i class='bi bi-pencil-square' onclick='comment("+ sample +", "+ access +', "'+sampletext+'", "'+comment+'")\'></i>');
fetch(url, {
method: "POST",
body: JSON.stringify({ comment : comment }),
headers: { "Content-type": "application/json; charset=UTF-8" }
}).then(data => {
//console.log(data);
viewAccess(access);
})
.catch(error => { console.error('Error:',error); });
}
</script>
<?php
} else {
?>
<div class="modal-header bg-black text-white">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Detail Request </h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body">
<h3>Data not found</h3>
</div>
<?php
}
?>

View File

@ -0,0 +1,133 @@
<?= $this->extend('admin/layout/main.php') ?>
<?= $this->section('content') ?>
<div class="card border-0 m-1">
<div class="card-header bg-success text-white">
<div class='card-title m-0'><b>Dictionary Chapter</b></div>
</div>
<div class="card-body">
<div class="table-responsive">
<table id="myTable" class="table">
<thead>
<tr>
<th>Chapter code</th>
<th>Shorttext</th>
<th>Text</th>
<th>Action</th>
</tr>
</thead>
<tbody id='table-body'>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal_crud" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Edit Chapter</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<div class="row">
<div class="col-12">
<table class="table table-sm table-borderless">
<tr class="align-middle"> <th>Chaptercode</th> <th>:</th> <td id='chapcode'></td> </tr>
<tr class="align-middle"> <th>Shorttext</th> <th>:</th> <td id='chaptext'></td> </tr>
<tr class="align-middle"> <th>Text 1</th> <th>:</th> <td><textarea class='form-control' id='text1'/></textarea></td> </tr>
<tr class="align-middle"> <th>Text 2</th> <th>:</th> <td><textarea class='form-control' id='text2'/></textarea></td> </tr>
</table>
<button class='btn btn-sm btn-primary' onclick='save()'>Save</button>
<button class='btn btn-sm btn-secondary' data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
index();
function index() {
let url = '<?=base_url('');?>api/dictChapters/index';
$.ajax({
url: url,
method: 'GET',
success: function(response) {
$("#myTable").DataTable().destroy();
$("#table-body").html("");
var data = response['dictChapters'];
for (var i = 0; i < data.length; i++) {
chapcode = data[i].CHAPCODE;
shorttext = data[i].SHORTTEXT;
text1 = '';
text2 = '';
if(data[i].TEXT1 != null) { text1 = data[i].TEXT1; }
if(data[i].TEXT2 != null) { text2 = data[i].TEXT2; }
let editBtn = '<button class="btn btn-sm btn-success" ' + ' onclick="edit(\'' + chapcode + '\')">Edit' + '</button> ';
let datarow = '<tr class="align-middle">' +
'<td>' + chapcode + '</td>' + '<td>' + shorttext + '</td> <td> <pre class="m-0">' + text1 + '<hr/>' + text2 + '</pre> </td>' +
'<td>' + editBtn + '</td>' +
'</tr>';
$("#table-body").append(datarow);
}
$("#myTable").DataTable({
"pageLength" : 25,
});
},
error: function(response) { console.log(response.responseJSON); }
});
}
function edit(chapcode) {
let url = '<?=base_url('');?>api/dictChapters/detail/'+chapcode;
$("#chapcode").html('');
$("#chaptext").html('');
$.ajax({
url: url,
method: "GET",
success: function(response) {
let data = response;
$("#chapcode").html(data.CHAPCODE);
$("#chaptext").html(data.SHORTTEXT);
$("#text1").val(data.TEXT1);
$("#text2").val(data.TEXT2);
$("#modal_crud").modal('show');
},
error: function(response) {
console.log(response.responseJSON)
}
});
}
function save() {
let url = '<?=base_url('');?>api/dictChapters/save';
var chapcode = $("#chapcode").html();
var text1 = $("#text1").val();
var text2 = $("#text2").val();
let data = { chapcode: chapcode, text1:text1, text2:text2 };
$.ajax({
url: url,
method: "POST",
data: data,
success: function(response) {
$("#chapcode").val('');
$("#text1").val('');
$("#text2").val('');
$("#modal_crud").modal('hide');
index();
},
error: function(response) {
console.log(response.responseJSON)
}
});
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,321 @@
<?= $this->extend('admin/layout/main.php') ?>
<?= $this->section('content') ?>
<datalist id='liscode'>
<?php
echo "";
foreach($tests as $data) {
$testcode = $data['TESTCODE'];
echo "<option value='$testcode' />";
}
?>
</datalist>
<div class="card border-0 m-1">
<div class="card-header bg-success text-white">
<div class='card-title m-0'><b>Dictionary Mapping Order</b></div>
</div>
<div class="card-body">
<div class='row mb-2'>
<div class='col-2'>HIS code</div>
<div class='col-2'><input type='text' class='form-control form-control-sm' id='search_hiscode' oninput='this.value = this.value.toUpperCase();' /></div>
</div>
<div class='row mb-2'>
<div class='col-2'>LIS code</div>
<div class='col-2'><input type='text' class='form-control form-control-sm' id='search_liscode' oninput='this.value = this.value.toUpperCase();' /></div>
</div>
<div class='row mb-2'>
<div class='col-2'>Mapping text</div>
<div class='col-3'><input type='text' class='form-control form-control-sm' id='search_maptext' oninput='this.value = this.value.toLowerCase();' /></div>
</div>
<button class='btn btn-sm btn-success-2' onclick='search()'>Search</button>
</div>
</div>
<div class="card border-0 m-1">
<div class="card-body">
<!-- <div class='card-title'>Dictionary Mapping Order</div> -->
<button class='btn btn-sm btn-success-2' onclick="createSingle()"><i class="bi bi-plus-circle"></i> Create Single</button>
<button class='btn btn-sm btn-success-2' onclick="createProfile()"><i class="bi bi-journal-plus"></i> Create Profile</button>
<div class="table-responsive mt-3">
<table id="myTable" class="table">
<thead>
<tr>
<th>Type</th>
<th>Tube</th>
<th>HIS Code</th>
<th>LIS Code</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody id='table-body'>
</tbody>
</table>
</div>
</div>
</div>
<!-- Single -->
<div class="modal fade" id="modal_single" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Edit Single Test</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" id='modal_bodySingle' style='background-color:#F4F6FF'>
<div class="row">
<div class="col-12">
<table class="table table-sm table-borderless">
<input type='hidden' id='updateSingle' value='' />
<tr class="align-middle"> <th>HIS Code</th> <th>:</th> <td><input class='form-control' type='text' id='hiscodeSingle'/></td> </tr>
<tr class="align-middle"> <th>LIS Code</th> <th>:</th> <td><input list='liscode' class='form-control' type='text' id='liscodeSingle' oninput='this.value = this.value.toUpperCase();' /></td> </tr>
<tr class="align-middle"> <th>Tube</th> <th>:</th>
<td>
<select class='form-control' id='tubeidSingle'>
<option value=''></option>
<?php
foreach($tubes as $data) {
$tubeid = $data['TUBEID'];
$tubecode = $data['TUBECODE'];
$tubename = $data['TUBENAME'];
echo "<option value='$tubeid'>$tubecode - $tubename</option>";
}
?>
</select>
</td>
</tr>
<tr class="align-middle"> <th>Desc.</th> <th>:</th> <td><textarea class='form-control' id='descsSingle'></textarea></td> </tr>
</table>
<button class='btn btn-sm btn-primary' onclick='saveSingle()'>Save</button>
<button class='btn btn-sm btn-secondary' data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Profile -->
<div class="modal fade" id="modal_profile" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Edit Profile Test</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<div class="row">
<div class="col-6">
<table class="table table-sm table-borderless">
<input type='hidden' id='updateProfile' value='' />
<tr class="align-middle"> <th>HIS Code</th> <th>:</th> <td><input class='form-control' type='text' id='hiscodeProfile'/></td> </tr>
<tr class="align-middle"> <th>Tube</th> <th>:</th>
<td>
<select class='form-control' id='tubeidProfile'>
<option value=''></option>
<?php
foreach($tubes as $data) {
$tubeid = $data['TUBEID'];
$tubecode = $data['TUBECODE'];
$tubename = $data['TUBENAME'];
echo "<option value='$tubeid'>$tubecode - $tubename</option>";
}
?>
</select>
</td>
</tr>
<tr class="align-middle"> <th>Desc.</th> <th>:</th> <td><textarea class='form-control' id='descsProfile'></textarea></td> </tr>
</table>
</div>
<div class="col-6">
<p><b>LIS Code<b></p>
<table class="table table-sm table-borderless">
<tr class="align-top">
<?php $j=1; ?>
<td> <?php for($i=1;$i<=11;$i++) { echo "<input class='mliscode$j' list='liscode' type='text' maxlength='5' size='7' oninput='this.value = this.value.toUpperCase();' /> <br />\n";$j++; } ?> </td>
<td> <?php for($i=1;$i<=11;$i++) { echo "<input class='mliscode$j' list='liscode' type='text' maxlength='5' size='7' oninput='this.value = this.value.toUpperCase();' /> <br />\n";$j++; } ?> </td>
<td> <?php for($i=1;$i<=11;$i++) { echo "<input class='mliscode$j' list='liscode' type='text' maxlength='5' size='7' oninput='this.value = this.value.toUpperCase();' /> <br />\n";$j++; } ?> </td>
<td> <?php for($i=1;$i<=11;$i++) { echo "<input class='mliscode$j' list='liscode' type='text' maxlength='5' size='7' oninput='this.value = this.value.toUpperCase();' /> <br />\n";$j++; } ?> </td>
</tr>
</table>
</div>
</div>
<button class='btn btn-sm btn-primary' onclick='saveProfile()'>Save</button>
<button class='btn btn-sm btn-secondary' data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
function search() {
let url = '<?=base_url('');?>api/dictMappings/search';
var liscode = $('#search_liscode').val();
var hiscode = $('#search_hiscode').val();
var maptext = $('#search_maptext').val();
let data = { liscode:liscode, hiscode:hiscode, maptext:maptext };
$.ajax({
url: url,
method: 'POST',
data : data,
success: function(response) {
$("#table-body").html("");
var data = response['dictMappings'];
for (var i = 0; i < data.length; i++) {
liscode = data[i].LISCODE;
hiscode = data[i].HISCODE;
maptype = data[i].MAPTYPE;
mapid = data[i].MAPID;
descs = data[i].DESCS;
tubecode = data[i].TUBECODE;
editBtn = '';
if(data[i].LISCODE == null) { liscode = '-'; }
if(data[i].TUBECODE == null) { tubecode = '-'; }
if(maptype == 'S') {
editBtn = '<button class="btn btn-sm btn-success-2" ' + ' onclick="editSingle(' + mapid+ ')">Edit' + '</button> ';
} else {
editBtn = '<button class="btn btn-sm btn-success-2" ' + ' onclick="editProfile(' + mapid+ ')">Edit' + '</button> ';
}
let datarow = '<tr class="align-middle">' +
'<td>' + maptype + '</td>' + '<td>' + tubecode + '</td>' + '<td>' + hiscode+ '</td> <td>' + liscode + '</td>' + '<td>' + descs + '</td>' + '<td>' + editBtn + '</td>' +
'</tr>';
$("#table-body").append(datarow);
}
},
error: function(response) { console.log(response.responseJSON); }
});
}
function createSingle() {
$("#alertSingle").html();
$("#updateSingle").val("0");
$("#hiscodeSingle").val("");
$("#liscodeSingle").val("");
$("#descsSingle").val("");
$(`#tubeidSingle option[value='']`).prop('selected', true);
$("#modal_single").modal('show');
}
function editSingle(mapid) {
let url = '<?=base_url('');?>api/dictMappings/detail/'+mapid;
$.ajax({
url: url,
method: "GET",
success: function(response) {
let data = response;
$("#updateSingle").val(mapid);
$("#liscodeSingle").val(data.LISCODE);
$("#hiscodeSingle").val(data.HISCODE);
$("#descsSingle").val(data.DESCS);
$("#tubeidSingle").val(data.TUBEID);
$(`#tubeidSingle option[value='${data.TUBEID}']`).prop('selected', true);
$("#modal_single").modal('show');
},
error: function(response) {
console.log(response.responseJSON)
}
});
}
function createProfile() {
$("#updateProfile").val("0");
$("#hiscodeProfile").val("");
$("#descsProfile").val("");
$(`#tubeidProfile option[value='']`).prop('selected', true);
for (let i = 1; i <= 44; i++) {
let id = `.mliscode${i}`;
let element = $(id);
element.val('');
}
$("#modal_profile").modal('show');
}
function editProfile(mapid) {
let url = '<?=base_url('');?>api/dictMappings/detail/'+mapid;
$.ajax({
url: url,
method: "GET",
success: function(response) {
let data = response;
$("#updateProfile").val(mapid);
$("#hiscodeProfile").val(data.HISCODE);
$("#descsProfile").val(data.DESCS);
// empty mliscode
for (let i = 1; i <= 44; i++) {
let id = `.mliscode${i}`;
let element = $(id);
element.val('');
}
// populate mliscode
for (let i = 0; i < data.mliscodes.length; i++) {
const fieldId = `mliscode${i + 1}`;
$(`.${fieldId}`).val(data.mliscodes[i].LISCODE);
}
$("#modal_profile").modal('show');
},
error: function(response) {
console.log(response.responseJSON)
}
});
}
function saveSingle() {
let url = '<?=base_url('');?>api/dictMappings/saveSingle';
var update = $("#updateSingle").val();
var hiscode = $("#hiscodeSingle").val();
var liscode = $("#liscodeSingle").val();
var descs = $("#descsSingle").val();
var tubeid = $("#tubeidSingle").val();
let data = { update: update, hiscode: hiscode, liscode:liscode, descs:descs, tubeid:tubeid };
$.ajax({
url: url,
method: "POST",
data: data,
success: function(response) {
$(".liscodeSingle").val('');
$("#hiscodeSingle").val('');
$("#descsSingle").val('');
$("#updateSingle").val('');
$("#tubeidSingle").val('');
$("#modal_single").modal('hide');
search();
},
error: function(response) {
alert(response.responseJSON.messages.errors);
}
});
}
function saveProfile() {
let url = '<?=base_url('');?>api/dictMappings/saveProfile';
var update = $("#updateProfile").val();
var hiscode = $("#hiscodeProfile").val();
var tubeid = $("#tubeidProfile").val();
var descs = $("#descsProfile").val();
let data = { update: update, hiscode: hiscode, descs:descs, tubeid:tubeid };
for (let i = 1; i <= 44; i++) {
let className = `.mliscode${i}`;
let value = $(className).val();
if (value !== undefined && value != '') {
data[`mliscode${i}`] = value;
}
}
$.ajax({
url: url,
method: "POST",
data: data,
success: function(response) {
$("#modal_profile").modal('hide');
search();
},
error: function(response) {
alert(response.responseJSON.messages.errors);
}
});
}
</script>
<?= $this->endSection() ?>

View File

@ -1,9 +1,11 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->extend('admin/layout/main.php') ?>
<?= $this->section('content') ?>
<div class="card border-0 m-1">
<div class="card-body">
<div class='card-title'>Dictionary Test</div>
<div class="card-header bg-success text-white">
<div class='card-title m-0'><b>Dictionary Test</b></div>
</div>
<div class="card-body">
<div class='row mb-2'>
<div class='col-2'>Testcode</div>
<div class='col-2'><input type='text' class='form-control form-control-sm' id='search_testcode' oninput='this.value = this.value.toUpperCase();' /></div>
@ -12,7 +14,7 @@
<div class='col-2'>Shorttext</div>
<div class='col-3'><input type='text' class='form-control form-control-sm' id='search_shorttext' oninput='this.value = this.value.toLowerCase();' /></div>
</div>
<button class='btn btn-sm btn-primary' onclick='search()'>Search</button>
<button class='btn btn-sm btn-success-2' onclick='search()'>Search</button>
</div>
</div>

View File

@ -0,0 +1,131 @@
<?= $this->extend('admin/layout/main.php') ?>
<?= $this->section('content') ?>
<div class="card border-0 m-1">
<div class="card-body">
<div class="card-header bg-success text-white">
<div class='card-title m-0'><b>Dictionary Tubes</b></div>
</div>
<button class='btn btn-sm btn-success m-3' onclick="create()"><i class="bi bi-plus-circle"></i> Create</button>
<div class="table-responsive">
<table id="myTable" class="table">
<thead>
<tr>
<th>Tube code</th>
<th>Tube name</th>
<th>Action</th>
</tr>
</thead>
<tbody id='table-body'>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal_crud" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Edit Tube</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<div class="row">
<div class="col-12">
<table class="table table-sm table-borderless">
<input type='hidden' id='tubeid' value='0' />
<tr class="align-middle"> <th>Tubecode</th> <th>:</th> <td><input class='form-control' type='text' id='tubecode' oninput='this.value = this.value.toUpperCase();' /></td> </tr>
<tr class="align-middle"> <th>Tubename</th> <th>:</th> <td><input class='form-control' type='text' id='tubename' /></td> </tr>
</table>
<button class='btn btn-sm btn-primary' onclick='save()'>Save</button>
<button class='btn btn-sm btn-secondary' data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
index();
function index() {
let url = '<?=base_url('');?>api/dictTubes/index';
$.ajax({
url: url,
method: 'GET',
success: function(response) {
$("#table-body").html("");
var data = response['dictTubes'];
for (var i = 0; i < data.length; i++) {
tubeid = data[i].TUBEID;
tubecode = data[i].TUBECODE;
tubename = data[i].TUBENAME;
let editBtn = '<button class="btn btn-sm btn-success" ' + ' onclick="edit(\'' + tubeid + '\')">Edit' + '</button> ';
let datarow = '<tr class="align-middle">' +
'<td>' + tubecode + '</td>' + '<td>' + tubename+ '</td> ' + '<td>' + editBtn + '</td>' +
'</tr>';
$("#table-body").append(datarow);
}
},
error: function(response) { console.log(response.responseJSON); }
});
}
function create() {
$("#alertSingle").html();
$("#tubeid").val("0");
$("#tubecode").val("");
$("#tubename").val("");
$("#modal_crud").modal('show');
}
function edit(tubeid) {
let url = '<?=base_url('');?>api/dictTubes/detail/'+tubeid;
$.ajax({
url: url,
method: "GET",
success: function(response) {
let data = response;
$("#alert-div").html("");
$("#error-div").html("");
$("#tubeid").val(tubeid);
$("#tubecode").val(data.TUBECODE);
$("#tubename").val(data.TUBENAME);
$("#modal_crud").modal('show');
},
error: function(response) {
console.log(response.responseJSON)
}
});
}
function save() {
let url = '<?=base_url('');?>api/dictTubes/save';
var tubeid = $("#tubeid").val();
var tubecode = $("#tubecode").val();
var tubename = $("#tubename").val();
let data = { tubeid: tubeid, tubecode:tubecode, tubename:tubename };
$.ajax({
url: url,
method: "POST",
data: data,
success: function(response) {
$("#alert-div").html("");
$("#error-div").html("");
$("#tubeid").val('');
$("#tubecode").val('');
$("#tubename").val('');
$("#modal_crud").modal('hide');
index();
},
error: function(response) {
console.log(response.responseJSON)
}
});
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Analis Dashboard</title>
<link rel="stylesheet" href="<?=base_url();?>assets/css/icons/font/bootstrap-icons.min.css">
<link href="<?=base_url();?>assets/css/styles.css" rel="stylesheet" />
<link href="<?=base_url();?>assets/select2/select2.min.css" rel="stylesheet" />
<link href="<?=base_url();?>assets/flatpickr/flatpickr.min.css" rel="stylesheet" />
<style>
.sb-form {
min-height:calc(100vh);
}
</style>
</head>
<!-- <body class="sb-nav-fixed sb-sidenav-toggled"> -->
<body class='sb-form'>
<main>
<div class="container-fluid px-2 py-2">
<?= $this->renderSection('content'); ?>
</div>
</main>
<script src="<?=base_url();?>assets/jquery-3.7.1.min.js"></script>
<script src="<?=base_url();?>assets/js/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>assets/datatables/datatables.min.js"></script>
<script src="<?=base_url();?>assets/select2/select2.min.js"></script>
<script src="<?=base_url();?>assets/flatpickr/flatpickr.min.js"></script>
<script src="<?=base_url();?>assets/js/scripts.js"></script>
<?= $this->renderSection('script'); ?>
</body>
</html>

View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Analis Dashboard</title>
<link rel="stylesheet" href="<?=base_url();?>assets/css/icons/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="<?=base_url();?>assets/datatables/datatables.min.css">
<link href="<?=base_url();?>assets/css/styles.css" rel="stylesheet" />
</head>
<!-- <body class="sb-nav-fixed sb-sidenav-toggled"> -->
<body class="sb-nav-fixed">
<?= $this->include('admin/layout/topbar'); ?>
<div id="layoutSidenav">
<?= $this->include('admin/layout/sidebar'); ?>
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-2 py-2">
<?php
if(isset($_SESSION['alertmsg'])) {
?>
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<?=$_SESSION['alertmsg'];?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php
}
?>
<?= $this->renderSection('content'); ?>
</div>
</main>
<footer class="py-3 bg-light mt-auto">
<div class="container-fluid px-4">
<div class="d-flex align-items-center justify-content-between small">
<div class="text-muted ms-auto ">Copyright &copy; 4SKAI 2024</div>
</div>
</div>
</footer>
</div>
</div>
<script src="<?=base_url();?>assets/jquery-3.7.1.min.js"></script>
<script src="<?=base_url();?>assets/js/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>assets/datatables/datatables.min.js"></script>
<script src="<?=base_url();?>assets/js/scripts.js"></script>
<?= $this->renderSection('script'); ?>
</body>
</html>

View File

@ -0,0 +1,33 @@
<div id="layoutSidenav_nav">
<nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<div class="sb-sidenav-menu-heading">Main</div>
<a class="nav-link" href="<?=base_url();?>admin/"><div class="sb-nav-link-icon"><i class="bi bi-speedometer"></i></div>Dashboard</a>
<a class="nav-link" href="<?=base_url();?>admin/tm/"><div class="sb-nav-link-icon"><i class="bi bi-speedometer"></i></div>Dashboard TM</a>
<a class="nav-link" href="<?=base_url();?>changePass/"><div class="sb-nav-link-icon"><i class="bi bi-key"></i></div>Change Password</a>
<div class="sb-sidenav-menu-heading">HIS</div>
<a class="nav-link" href="<?=base_url();?>admin/patients/"><div class="sb-nav-link-icon"><i class="bi bi-person-fill"></i></div>Patient List</a>
<a class="nav-link" href="<?=base_url();?>admin/orders/"><div class="sb-nav-link-icon"><i class="bi bi-clipboard-pulse"></i></div>Order List</a>
<a class="nav-link" href="#" onclick='createOrder()'><div class="sb-nav-link-icon"><i class="bi bi-clipboard-plus"></i></div>Create Order</a>
<div class="sb-sidenav-menu-heading">Administration</div>
<a class="nav-link" href="<?=base_url();?>admin/dictMappings/"> <div class="sb-nav-link-icon"><i class="bi bi-diagram-2"></i></div> Dict. Mapping Order </a>
<a class="nav-link" href="<?=base_url();?>admin/dictTubes/"> <div class="sb-nav-link-icon"><i class="bi bi-eyedropper"></i></div> Dict. Tubes </a>
<a class="nav-link" href="<?=base_url();?>admin/dictChapters/"> <div class="sb-nav-link-icon"><i class="bi bi-journal-medical"></i></div> Dict. Chapter</a>
<a class="nav-link" href="<?=base_url();?>admin/dictTests/"> <div class="sb-nav-link-icon"><i class="bi bi-file-medical"></i></div> Dict. Test </a>
<a class="nav-link" href="<?=base_url();?>admin/users/"> <div class="sb-nav-link-icon"><i class="bi bi-person-circle"></i></div> Users </a>
<a class="nav-link" href="<?=base_url();?>admin/userroles/"> <div class="sb-nav-link-icon"><i class="bi bi-person-lock"></i></div> User Roles </a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">Logged in as: <b>Administrator</b></div>
</div>
</nav>
</div>
<script>
function createOrder() {
window.open("<?php echo base_url();echo $_SESSION['userrole']?>/orders/create",
'_blank', "width=1200,height=700,location=no,toolbar=no,menubar=no"
);
}
</script>

View File

@ -1,15 +1,17 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->extend('admin/layout/main.php') ?>
<?= $this->section('content') ?>
<div class="card border-0">
<div class="card-header bg-success text-white">
<div class='card-title m-0'><b>Users Role Manager</b></div>
</div>
<div class="card-body">
<button class='btn btn-sm btn-success mx-3 my-2' onclick='create()'><i class='bi bi-plus-circle'></i> Create</button>
<div class="table-responsive">
<button class='btn btn-sm btn-success-2 mx-3 my-2' onclick='create()'><i class='bi bi-plus-circle'></i> Create</button>
<div class="mt-2 table-responsive">
<table id="table_dashboard" class="table">
<thead>
<tr>
<th>#</th>
<th>Code</th>
<th>Name</th>
<th>Action</th>
</tr>
@ -33,7 +35,6 @@
<div class="col-12">
<input type='hidden' id='userroleid' value='' />
<table class="table table-sm table-borderless">
<tr class="align-middle"> <th>User Role Code</th> <th>:</th> <td><input class='form-control' type='text' id='userrolecode' oninput='this.value = this.value.toUpperCase();'/></td> </tr>
<tr class="align-middle"> <th>User Role Name</th> <th>:</th> <td><input class='form-control' type='text' id='userrolename'/></td> </tr>
</table>
<button class='btn btn-sm btn-primary' onclick='save()'>Save</button>
@ -58,10 +59,10 @@ function index() {
$("#table-body").html("");
var data = response['userroles'];
for (var i = 0; i < data.length; i++) {
let editBtn = '<button class="btn btn-sm btn-success" ' + ' onclick="edit(' + data[i].USERROLEID + ')">Edit' + '</button> ';
let editBtn = '<button class="btn btn-sm btn-success-2" ' + ' onclick="edit(' + data[i].USERROLEID + ')">Edit' + '</button> ';
//let deleteBtn = '<button class="btn btn-sm btn-danger" ' + ' onclick="delete(' + data[i].USERROLEID + ')">Delete' + '</button>';
let datarow = '<tr class="align-middle">' +
'<td>' + data[i].USERROLEID + '</td>' + '<td>' + data[i].USERROLECODE+ '</td>' + '<td>' + data[i].USERROLENAME+ '</td>' + '<td>' + editBtn + '</td>' +
'<td>' + data[i].USERROLEID + '</td>' + '<td>' + data[i].USERROLENAME+ '</td>' + '<td>' + editBtn + '</td>' +
'</tr>';
$("#table-body").append(datarow);
}
@ -74,7 +75,6 @@ function create() {
$("#alert-div").html("");
$("#error-div").html("");
$("#userroleid").val("0");
$("#userrolecode").val("");
$("#userrolename").val("");
$("#modal_crud").modal('show');
}
@ -89,7 +89,6 @@ function edit(userroleid) {
$("#alert-div").html("");
$("#error-div").html("");
$("#userroleid").val(userroleid);
$("#userrolecode").val(data.USERROLECODE);
$("#userrolename").val(data.USERROLENAME);
$("#modal_crud").modal('show');
},
@ -101,11 +100,9 @@ function edit(userroleid) {
function save() {
var userroleid = $("#userroleid").val();
var userrolecode = $("#userrolecode").val();
var userrolename = $("#userrolename").val();
//console.log(userroleid+' '+userrolecode+' '+userrolename);
let url = '<?=base_url('');?>api/userroles/save/'+userroleid ;
let data = { userroleid: userroleid, userrolecode: userrolecode, userrolename: userrolename };
let data = { userroleid: userroleid, userrolename: userrolename };
$.ajax({
url: url,
method: "POST",
@ -115,7 +112,6 @@ function save() {
$("#alert-div").html("");
$("#error-div").html("");
$("#userroleid").val("");
$("#userrolecode").val("");
$("#userrolename").val("");
index();
$("#modal_crud").modal('hide');

View File

@ -1,7 +1,10 @@
<?= $this->extend('layouts/main.php') ?>
<?= $this->extend('admin/layout/main.php') ?>
<?= $this->section('content') ?>
<div class="card border-0">
<div class="card-header bg-success text-white">
<div class='card-title m-0'><b>Users Manager</b></div>
</div>
<div class="card-body">
<div class="table-responsive">
<table id="myTable" class="table">
@ -10,6 +13,7 @@
<th>Userid</th>
<th>Name</th>
<th>Role</th>
<th>Site</th>
<th>Action</th>
</tr>
</thead>
@ -32,13 +36,12 @@
<tr class="align-middle"> <th>Role</th> <th>:</th>
<td>
<select id='userroleid' class='form-control'>
<option value='0'></option>
<option value=''></option>
<?php
foreach($userroles as $data) {
$userroleid = $data['USERROLEID'];
$userrolecode = $data['USERROLECODE'];
$userrolename = $data['USERROLENAME'];
echo "<option value='$userroleid'>$userrolecode - $userrolename</option>";
echo "<option value='$userroleid'>$userrolename</option>";
}
?>
</select>
@ -91,13 +94,15 @@ function index() {
for (var i = 0; i < data.length; i++) {
let userid = data[i].USERID;
let username = data[i].USERNAME;
let site = data[i].CITYNAME == null ? "-": data[i].CITYNAME;
let userroleid = data[i].USERROLEID;
if(userroleid === null) {userroleid = '';}
let userrolename = '';
if(data[i].USERROLENAME != null) { userrolename = data[i].USERROLENAME; }
let editBtn = '<button class="btn btn-sm btn-secondary" ' + ' onclick="editRole(\'' + userid + '\',\''+ userroleid +'\')">Edit Role' + '</button> ';
editBtn += '<button class="btn btn-sm btn-warning" ' + ' onclick="editPass(\'' + userid + '\')">Edit Password' + '</button> ';
let datarow = '<tr class="align-middle">' +
'<td>' + userid + '</td>' + '<td>' + username + '</td>' + '<td>' + userrolename + '</td>' + '<td>' + editBtn + '</td>' +
'<td>' + userid + '</td>' + '<td>' + username + '</td>' + '<td>' + userrolename + '</td>' + '<td>' + site + '</td>' + '<td>' + editBtn + '</td>' +
'</tr>';
$("#table-body").append(datarow);
}

View File

@ -1,61 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<title>CMOD - Login</title>
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" sizes="16x16" href="<?=base_url();?>favicon.ico">
<title>cmod</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700;900&display=swap" />
<link rel="stylesheet" href="<?=base_url();?>assets/css/bootstrap-login-form.min.css" />
<link href="<?=base_url();?>assets/css/styles.css" rel="stylesheet">
<link href="<?=base_url();?>assets/css/login.css" rel="stylesheet">
<style>
.bg-primary-luxury{ background-color: #1C2B19; }
.font-primary-luxury{ color: #E9E3C9;}
#icon-login { max-width: 80%; height: auto; }
.shadoww { box-shadow: 0 4px 8px #1c2b193f; /* Bayangan merah */ }
.login-form {width:490px;}
.bg-login { background-color:#1c1c1c; }
</style>
</head>
<body>
<body class='bg-login'>
<section class="vh-100">
<div class="container h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col col-xl-10 login-form">
<div class="card shadoww" style="border-radius: 1rem;" >
<div class="row g-0">
<div class="col d-flex align-items-center text-center">
<div class="card-body pb-md-5 px-md-5 text-black">
<div class="d-flex align-items-center m-0" bg='dark'>
<img src="<?=base_url();?>assets/img/login-logo.png" alt="" id="icon-login" class="mx-auto m-0">
<!-- <h1 class="mx-auto">Logo</h1> -->
</div>
<form class="m-0" method='POST'>
<h5 class="fw-normal mt-4 mb-2 pb-2" style="letter-spacing: 1px;">Sign into your account</h5>
<div class="form-outline mb-4">
<input type="text" id="userid" name='userid' value='<?=$userid?>' class="form-control form-control-lg" oninput="this.value = this.value.toUpperCase();" />
<label class="form-label" for="userid">UserID</label>
</div>
<div class="form-outline mb-4">
<input type="password" id="password" name='password' value='<?=$password;?>' class="form-control form-control-lg" />
<label class="form-label" for="password">Password</label>
</div>
<div class="pt-1 mb-4">
<button type='submit' class="btn bg-primary-luxury btn-lg btn-block" type="button">
<span class="font-primary-luxury"> Login </span>
</button>
</div>
</form>
</div>
</div>
<section id="wrapper" class="login-register login-sidebar bg-login">
<div class="login-box card rounded-0">
<div class="card-body">
<form class="form-horizontal form-material text-center" id="loginform" method='POST'>
<img class='img-fluid mt-5' src="<?=base_url();?>assets/img/login-logo.png" /></a>
<div class="form-group mt-3 mb-1">
<div class="col-xs-12">
<input class="form-control" type="text" id='userid' name='userid' placeholder="UserID" value='' required oninput="this.value = this.value.toUpperCase()" />
</div>
</div>
</div>
<div class="form-group mb-1">
<div class="col-xs-12">
<input class="form-control" type="password" name='password' placeholder="Password" value='' />
</div>
</div>
<div class="form-group text-center m-t-20">
<div class="col-xs-12">
<button class="btn bg-primary-luxury btn-block w-100" type="submit">
<span class="font-primary-luxury"> Login </span>
</button>
</div>
</div>
</form>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger mt-5">
<?= session()->getFlashdata('error') ?>
</div>
<?php endif; ?>
</div>
<div class='card-footer'>
<p class='ms-auto'>&copy; 4SKA1 2024 - 2025</p>
</div>
</div>
</section>
<script type="text/javascript" src="<?=base_url();?>assets/js/mdb.min.js"></script>
<script src="<?=base_url();?>assets/jquery-3.7.1.min.js"></script>
<script src="<?=base_url();?>assets/js/bootstrap.bundle.min.js"></script>
<script>
window.onload = function() {
document.getElementById("userid").focus();

View File

@ -41,7 +41,7 @@ function index() {
let url = '<?=base_url('');?>api/dashboard/index';
$.ajax({
url: url,
method: 'GET',
method: 'POST',
success: function(response) {
/*
// counter

291
app/Views/fo/dashboard.php Normal file
View File

@ -0,0 +1,291 @@
<?= $this->extend('fo/layout/main.php') ?>
<?= $this->section('content') ?>
<style>
.pointercol {
cursor: pointer;
}
</style>
<div id='stats' class="d-flex justify-content-between p-0">
</div>
<div class="card border-0">
<!-- div.card-head -->
<div class="card-body">
<div class="row d-flex align-items-center">
<div class="col col-auto">
<b>Date</b>&nbsp; &nbsp;:&nbsp; &nbsp;<input class='date1' type='date' value=''> - <input class='date2' type='date'>
</div>
<div class="col col-auto">
<button class='btn btn-sm btn-primary py-1 px-2 d-flex align-items-center' onclick='index()'><i class="bi bi-calendar2-event"></i>&nbsp;&nbsp;Search</button>
</div>
</div>
<div class="table-responsive mt-3">
<table id="myTable" class="table table-hover">
<thead class='text-start'>
<th class='text-start' width="10%">Order Date</th>
<th width="12%">Patient#</th>
<th width="17%">Patient Name</th>
<th class='text-start' width="10%">Access#</th>
<th width="10%">Visit#</th>
<th width="10%">HIS#</th>
<th>Test</th>
<th width="5%">Status</th>
<th></th>
</thead>
<tbody id="table-body" class='text-start'>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
// let curDate = new Date().toJSON().slice(0, 10);
date = new Date();
let curDate = (new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON()).slice(0, 10);
$('.date1').val(curDate);
$('.date2').val(curDate);
index();
document.addEventListener('keydown', function(event) {
if (event.key === 'F5') { event.preventDefault(); index(); }
});
function index() {
let url = '<?=base_url('');?>api/dashboard/index';
date1 = $('.date1').val();
date2 = $('.date2').val();
$.ajax({
url: url,
method: 'POST',
data : {date1:date1, date2:date2},
success: function(response) {
/*
// counter
*/
$("#stats").html("");
var stats = ['Pend', 'PartColl', 'Coll', 'PartRecv', 'Recv', 'Inc', 'PartVal', 'Comp'];
var statcolor = ['text-orange', 'text-peach', 'text-pink', 'text-soft-blue', 'text-blue', 'text-grey', 'text-soft-green', 'text-green'];
var staticon = ['bi-clock-history','bi-tv', 'bi-collection', 'bi-file-medical', 'bi-journal-medical', 'bi-calendar3-week', 'bi-check2', 'bi-clipboard-check'];
var stattext = ['Pending', 'Part Collected', 'Collected', 'Part Received', 'Received', 'Incomplete', 'Part Validated', 'Validated'];
var count = response['count'];
var statcontent = '';
stats.forEach ( (item, index) => {
//console.log(item + ' ' + index);
if(!count[item]) { count[item] = 0; }
statcontent += '<div class="custom-card shadow" data-filtertype="'+index+'">' +
'<div class="custom-card-content">' +
'<div class="row p-0 d-flex justify-content-between">' +
'<div class="col-3 text-start '+statcolor[index]+'"> <h5 class="m-0"><i class="bi '+staticon[index]+'"></i></h5> </div>' +
'<div class="col-9 text-end pe-3"> <h2 class="m-0 custom-card-title">'+count[item]+'</h2> </div>' +
'</div>' +
"<hr class='"+statcolor[index]+"'>" +
'<h3 class="custom-card-text m-0 p-0 '+statcolor[index]+'">'+ stattext[index] +'</h3>' +
'</div>' +
'</div>';
});
$("#stats").html(statcontent);
/*
// table
*/
$("#myTable").DataTable().destroy();
$("#table-body").html("");
var data = response['data'];
for (var i = 0; i < data.length; i++) {
colldate = data[i].COLLECTIONDATE.slice(0,10);
colltime = data[i].COLLECTIONDATE.slice(10,16);
if (data[i].PATNUMBER != null) {
patnumber = data[i].PATNUMBER.replace(/^0+/, '');
// patnumber = data[i].PATNUMBER.substr(-16,16);
// patnumber = patnumber.substring(patnumber.length - 10);
} else {
patnumber = ' NULL ';
}
accessnumber = data[i].SP_ACCESSNUMBER;
patname = data[i].NAME;
hon = data[i].HOSTORDERNUMBER;
let testing_test = "";
if (hon[0] === 'X' || hon[0] === 'Z') {
testing_test = "<div class='badge text-bg-warning'>testing tm</div><br>";
} else {
testing_test = "";
}
if (data[i].REFFID != null) {
// patnumber = data[i].PATNUMBER;
reffid = data[i].REFFID;
// patnumber = data[i].PATNUMBER.substr(-16,16);
// patnumber = patnumber.substring(patnumber.length - 10);
} else {
reffid = ' NULL ';
}
tests = data[i].TESTS;
stat = data[i].STATS;
reqstatus = String(data[i].REQSTATUS);
trcolor = '';
if (reqstatus != '1') {
if(stat == 'Pend') {
bgcolor = 'bg-orange';
datafilter = "data-filterrow='0'";
stattext = 'Pending';
} else if(stat == 'PartColl') {
bgcolor = 'bg-peach';
datafilter = "data-filterrow='1'";
stattext = 'Part Collected';
} else if(stat == 'Coll') {
bgcolor = 'bg-pink';
datafilter = "data-filterrow='2'";
stattext = 'Collected';
} else if(stat == 'PartRecv') {
bgcolor = 'bg-soft-blue';
datafilter = "data-filterrow='3'";
stattext = 'Part Received';
} else if(stat == 'Recv') {
bgcolor = 'bg-blue';
datafilter = "data-filterrow='4'";
stattext = 'Received';
} else if(stat == 'Inc') {
bgcolor = 'bg-grey';
datafilter = "data-filterrow='5'";
stattext = 'Incomplete';
} else if(stat == 'PartVal') {
bgcolor = 'bg-soft-green';
datafilter = "data-filterrow='6'";
stattext = 'Part Validated';
} else if(stat == 'Comp') {
bgcolor = 'bg-green';
datafilter = "data-filterrow='7'";
stattext = 'Validated';
}
} else {
trcolor = ' table-danger-custom ';
bgcolor = ' table-danger-custom ';
datafilter = "data-filterrow='8'";
stattext = 'Cancelled';
}
let datarow = "<tr class='align-middle" + trcolor +"'" + datafilter + " >" +
"<td class='text-start'>" + colldate + '<br>'+ colltime +'</td>'+
"<td class='text-start' style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + patnumber + "<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + patname.trim() + "<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td class='text-start' style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + accessnumber +"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + testing_test + hon +"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>"+
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>"+reffid+"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>"+
"<td>" + tests + '</td>' +
"<td role='button' class='"+bgcolor+" text-center align-middle pointercol' onclick='viewAccess("+accessnumber+")'>"+stattext+"</td>" +
"<td role='button' class='text-center align-middle' onclick='resultPdfAccess("+accessnumber+ ",event" +")'> <h4 class='p-0 m-0'><i class='bi bi-filetype-pdf'></i></h4> </td>" +
'</tr>';
$("#table-body").append(datarow);
}
$('#myTable').DataTable({
"order": [0, "desc"], // Urutan Tanggal Desc
"pageLength": 50, // Ganti sesuai kebutuhan
"lengthMenu": [50, 75, 100] // Pilihan dropdown entries per halaman
});
// datatable filter
const filterButton = document.querySelectorAll("[data-filtertype]");
const table = document.querySelector("#myTable");
const tr = table.getElementsByTagName("tr");
let activeButton = null;
filterButton.forEach((button) => {
button.addEventListener("click", () => {
const selectedButton = button.getAttribute("data-filtertype");
console.log(selectedButton);
if (activeButton === button) {
button.classList.remove("active", "border", "border-primary", "border-5");
activeButton = null;
for (let i = 1; i < tr.length; i++) {
tr[i].style.display = "";
}
} else {
filterButton.forEach((btn) => btn.classList.remove("active", "border", "border-info", "border-3"));
button.classList.add("active", "border", "border-info", "border-3");
activeButton = button;
for (let i = 1; i < tr.length; i++) {
const filterValue = tr[i].getAttribute("data-filterrow");
if (filterValue === selectedButton) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
});
});
},
error: function(response) { console.log(response.responseJSON); }
});
}
function viewAccess(access) {
let url = '<?=base_url();?>fo/dashboard/viewAccess/'+access;
$('.modal-content').load(url, function(){
$('#modal').modal('show');
});
}
function resultPdfAccess(access, event) {
event.stopPropagation(); // Mencegah klik pada <tr> dieksekusi
let url = '<?=base_url();?>printResult/'+access;
window.open(url, '_blank');
}
function copyToClipboard(element) {
let text = element.innerText.trim(); // Ambil teks dari elemen
text = text.replace("Teks sudah disalin", "").trim(); // Hilangkan teks notifikasi sebelumnya
if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(() => {
showCopyMessage(element);
}).catch(err => {
console.error("Gagal menyalin teks: ", err);
});
} else {
// Alternatif jika Clipboard API tidak didukung
let tempInput = document.createElement("textarea");
tempInput.value = text;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
showCopyMessage(element);
}
}
function showCopyMessage(element) {
let message = element.querySelector(".copy-message");
if (message) {
message.style.display = "inline"; // Tampilkan teks notifikasi
// Sembunyikan kembali setelah 2 detik
setTimeout(() => {
message.style.display = "none";
}, 500);
}
}
</script>
<?= $this->endSection() ?>

View File

@ -1,9 +1,11 @@
<?php
if(isset($data[0])) {
$row = $data[0];
$patnumber = $row['PATNUMBER'];
$host = $row['HOSTORDERNUMBER'];
$name = $row['NAME'];
$row = $data[0];
// if (strlen($patnumber) < 10) {
// $patnumber = str_pad($patnumber, 10, "0", STR_PAD_LEFT);
// }
?>
<div class="modal-header bg-soft-green text-white">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Detail Request </h1>
@ -13,8 +15,38 @@ $name = $row['NAME'];
<div class="row">
<div class="col">
<table class="table table-sm table-borderless">
<tr> <th>Access#</th> <th>:</th> <td><?=$accessnumber;?></td> </tr>
<tr> <th>Patient</th> <th>:</th> <td><?=$patnumber;?> - <?=$name;?></td> </tr>
<tr>
<th width='18%'>Access Number</th>
<th>:</th>
<td width='31%'><?=$accessnumber;?></td>
<th>Visit Description</th>
<th>:</th>
<td><?=$visit_description;?></td>
</tr>
<tr>
<th>Patient Number</th>
<th>:</th>
<td><?=$patnumber;?></td>
<th width='18%'>Payer Name</th>
<th>:</th>
<td width='31%'><?=$payer_name;?></td>
</tr>
<tr>
<th>Patient Name</th>
<th>:</th>
<td><?=$patient_fullname;?></td>
<th>Treating Doctor</th>
<th>:</th>
<td><?=$treating_doctor;?></td>
</tr>
</table>
</div>
</div>
@ -25,10 +57,29 @@ $name = $row['NAME'];
<div class="card-title"><h3>Sample List</h3></div>
<table class='table'>
<tr> <th class='text-center'>Coll.</th> <th class='text-center'>Recv.</th> <th>Sample Name</th> <th>Action</th> <th>Comment</th> </tr>
<tr>
<td></td> <td></td> <td>All</td>
<td>
<button type='button' class='btn btn-dark m-0 px-2 py-1' onclick="printAllLabel(<?=$accessnumber;?>, <?=$usercityid;?>)"> <h6 class='p-0 m-0'><i class='bi bi-printer'></i></h6> </button>
<button type='button' class='btn btn-success m-0 px-2 py-1' onclick='collectAll(<?=$accessnumber;?>)'><h6 class='p-0 m-0'>Coll.</h6></button>
<!-- <button class='badge bg-black text-white m-0 px-2 py-1' onclick='uncollectAll(<?=$accessnumber;?>)'>un-collect</button> -->
<button type='button' class='btn btn-primary m-0 px-2 py-1' onclick='unreceiveAll(<?=$accessnumber;?>)'><h6 class='p-0 m-0'>Un-Rec.</h6></button>
</td>
</tr>
<tr>
<td></td> <td></td> <td>Collection</td>
<td><button type='button' class='btn btn-dark m-0 px-2 py-1' onclick="printCollectionLabel(<?=$accessnumber;?>, <?=$usercityid;?>)"><h6 class='p-0 m-0'> <i class='bi bi-printer'></i></h6></button></td>
</tr>
<?php
foreach($data as $row) {
$sampletype = $row['SAMPLETYPE'];
$sampletext = $row['SHORTTEXT'];
if ($sampletype == "200") {
$sampletext = "Serum Kimia";
} else if ($sampletype == '250') {
$sampletext = "Serum Imun";
}
$tubestatus = $row['TUBESTATUS'];
$collstatus = $row['COLLSTATUS'];
$comment = $row['TUBECOMMENT'];
@ -43,30 +94,18 @@ $name = $row['NAME'];
} else {
echo "<td class='text-center'><input type='checkbox' class='form-check-input' id='recv$sampletype' disabled></td>";
}
echo "<td>$sampletext</td>";
echo "<td>$sampletext ($sampletype)</td>";
echo "<td>
<button class='badge text-bg-dark'><i class='bi bi-printer'></i></button>
<button class='badge text-bg-success' onclick='collect($sampletype, $accessnumber)'>Coll.</button>
<button class='badge text-bg-warning' onclick='uncollect($sampletype, $accessnumber)'>Un-Coll.</button>
<button class='badge text-bg-primary' onclick='unreceive($sampletype, $accessnumber)'>Un-Rec.</button>
<button type='button' class='btn btn-dark m-0 px-2 py-1' " . "onclick='printSingleLabel($accessnumber, $sampletype, $usercityid)'" . "><h6 class='p-0 m-0'><i class='bi bi-printer'></i></h6></button>
<button type='button' class='btn btn-success m-0 px-2 py-1' onclick='collect($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Coll.</h6></button>
<button type='button' class='btn btn-warning m-0 px-2 py-1' onclick='uncollect($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Un-Coll.</h6></button>
<button type='button' class='btn btn-primary m-0 px-2 py-1' onclick='unreceive($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Un-Rec.</h6></button>
</td> ";
echo "<td id='comment$sampletype'>$comment <i class='bi bi-pencil-square' role='button' onclick='comment($sampletype, $accessnumber, \"$sampletext\", \"$comment\")'></i></td>";
echo "<td id='comment$sampletype'>$comment <h6 class='p-0 m-0'><i class='bi bi-pencil-square' role='button' onclick='comment($sampletype, $accessnumber, \"$sampletext\", \"$comment\")'></i></h6></td>";
echo " </tr>";
}
?>
<tr>
<td></td> <td></td> <td>Collection</td>
<td> <button class='badge badge-dark'><i class='bi bi-printer'></i></button> </td>
</tr>
<tr>
<td></td> <td></td> <td>All</td>
<td>
<button class='badge text-bg-dark'><i class='bi bi-printer'></i></button>
<button class='badge text-bg-success' onclick='collectAll(<?=$accessnumber;?>)'>Coll.</button>
<!-- <button class='badge bg-black text-white' onclick='uncollectAll(<?=$accessnumber;?>)'>un-collect</button> -->
<button class='badge text-bg-primary' onclick='unreceiveAll(<?=$accessnumber;?>)'>Un-Rec.</button>
</td>
</tr>
</table>
</div>
</div>
@ -74,6 +113,89 @@ $name = $row['NAME'];
</div>
</div>
<script>
function printCollectionLabel(access, usercityid){
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/collection/'+access.toString();
} else {
url = '<?=base_url();?>printLabel/collection/'+access.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function printSingleLabel(access, sample, usercityid) {
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/single/'+access.toString()+'/'+sample.toString();
} else {
url = '<?=base_url();?>printLabel/single/'+access.toString()+'/'+sample.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function printAllLabel(access, usercityid) {
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/all/'+access.toString();
} else {
url = '<?=base_url();?>printLabel/all/'+access.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function collect(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/collect/'+access+'/'+sample;

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" sizes="16x16" href="<?=base_url();?>/assets/favicon.png">
<title>Summit CRM</title>
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/select2/select2.min.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/select2/select2-bootstrap-5-theme.min.css" rel="stylesheet">
<style>
.select2-results__option { font-size: 0.75rem !important; margin: 5px !important; padding: 5px !important; }
li.select2-selection__choice { background-color : #000 !important; padding:5px !improtant; }
.select2 {width:100%!important;}
</style>
<script src="<?=base_url();?>/assets/jquery/jquery.min.js"></script>
<script src="<?=base_url();?>/assets/select2/select2.min.js"></script>
<?= $this->renderSection('head'); ?>
</head>
<body class="skin-megna-dark fixed-layout">
<div class="preloader">
<div class="loader">
<div class="loader__figure"></div>
<p class="loader__label">Summit-CRM</p>
</div>
</div>
<div id="main-wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card mt-2">
<div class="card-body">
<?= $this->renderSection('content'); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="<?=base_url();?>/assets/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>/assets/perfect-scrollbar.jquery.min.js"></script>
<script src="<?=base_url();?>/assets/app.js"></script>
<?= $this->renderSection('script'); ?>
<script>
$('.select2').select2();
</script>
</body>
</html>

View File

@ -14,11 +14,11 @@
<!-- <body class="sb-nav-fixed sb-sidenav-toggled"> -->
<body class="sb-nav-fixed">
<?= $this->include('layouts/topbar'); ?>
<?= $this->include('fo/layout/topbar'); ?>
<div id="layoutSidenav">
<?= $this->include('layouts/sidebar'); ?>
<?= $this->include('fo/layout/sidebar'); ?>
<div id="layoutSidenav_content">
<main>

View File

@ -0,0 +1,14 @@
<div id="layoutSidenav_nav">
<nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<div class="sb-sidenav-menu-heading">Main</div>
<a class="nav-link" href="<?=base_url();?>fo/"><div class="sb-nav-link-icon"><i class="bi bi-speedometer"></i></div>Dashboard</a>
<a class="nav-link" href="<?=base_url();?>changePass/"><div class="sb-nav-link-icon"><i class="bi bi-key"></i></div>Change Password</a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">Logged in as: <b>Front CS</b></div>
</div>
</nav>
</div>

View File

@ -0,0 +1,23 @@
<nav class="sb-topnav navbar navbar-expand navbar-light bg-light shadow-sm text-luxury">
<a class="navbar-brand ps-3 d-none d-md-block" href="#"><img src='<?=base_url();?>assets/img/logo.png' width='30' /> CMOD</a>
<button class="btn btn-link me-2" id="sidebarToggle"><i class="bi bi-list "></i></button>
<div class="ms-auto">
<ul class="navbar-nav ms-md-0 me-3 me-lg-4">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i>
<?=$_SESSION['username'];?>
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#!">Profile</a></li>
<li><a class="dropdown-item" href="#!">Change Password</a></li>
<li><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item" href="<?=base_url();?>auth/logout">Logout</a></li>
</ul>
</li>
</ul>
</div>
</nav>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" sizes="16x16" href="<?=base_url();?>/assets/favicon.png">
<title>Summit CRM</title>
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/font-awesome-640/css/all.min.css" rel="stylesheet">
<?= $this->renderSection('head'); ?>
</head>
<body class="skin-megna-dark fixed-layout">
<div class="preloader">
<div class="loader">
<div class="loader__figure"></div>
<p class="loader__label">Summit-CRM</p>
</div>
</div>
<div>
<?= $this->renderSection('content'); ?>
</div>
<script src="<?=base_url();?>/assets/jquery/jquery.min.js"></script>
<script src="<?=base_url();?>/assets/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>/assets/app.js"></script>
<?= $this->renderSection('script'); ?>
<script>
$(document).ready(function() {
$('.select2').select2({
dropdownAutoWidth : true,
width: '100%',
});
});
</script>
</body>
</html>

View File

@ -1,69 +0,0 @@
<div id="layoutSidenav_nav">
<nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<div class="sb-sidenav-menu-heading">Core</div>
<a class="nav-link" href="index.html">
<div class="sb-nav-link-icon"><i class="fas fa-tachometer-alt"></i></div>
Dashboard
</a>
<div class="sb-sidenav-menu-heading">Interface</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#collapseLayouts" aria-expanded="false" aria-controls="collapseLayouts">
<div class="sb-nav-link-icon"><i class="fas fa-columns"></i></div>
Layouts
<div class="sb-sidenav-collapse-arrow"><i class="bi bi-chevron-down"></i></div>
</a>
<div class="collapse" id="collapseLayouts" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordion">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="layout-static.html">Static Navigation</a>
<a class="nav-link" href="layout-sidenav-light.html">Light Sidenav</a>
</nav>
</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#collapsePages" aria-expanded="false" aria-controls="collapsePages">
<div class="sb-nav-link-icon"><i class="fas fa-book-open"></i></div>
Pages
<div class="sb-sidenav-collapse-arrow"><i class="fas fa-angle-down"></i></div>
</a>
<div class="collapse" id="collapsePages" aria-labelledby="headingTwo" data-bs-parent="#sidenavAccordion">
<nav class="sb-sidenav-menu-nested nav accordion" id="sidenavAccordionPages">
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#pagesCollapseAuth" aria-expanded="false" aria-controls="pagesCollapseAuth">
Authentication
<div class="sb-sidenav-collapse-arrow"><i class="fas fa-angle-down"></i></div>
</a>
<div class="collapse" id="pagesCollapseAuth" data-bs-parent="#sidenavAccordionPages">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="login.html">Login</a>
<a class="nav-link" href="register.html">Register</a>
<a class="nav-link" href="password.html">Forgot Password</a>
</nav>
</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#pagesCollapseError" aria-expanded="false" aria-controls="pagesCollapseError">
Error
<div class="sb-sidenav-collapse-arrow"><i class="fas fa-angle-down"></i></div>
</a>
<div class="collapse" id="pagesCollapseError" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordionPages">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="401.html">401 Page</a>
<a class="nav-link" href="404.html">404 Page</a>
<a class="nav-link" href="500.html">500 Page</a>
</nav>
</div>
</nav>
</div>
<div class="sb-sidenav-menu-heading">Addons</div>
<a class="nav-link" href="charts.html">
<div class="sb-nav-link-icon"><i class="fas fa-chart-area"></i></div>
Charts
</a>
<a class="nav-link" href="tables.html">
<div class="sb-nav-link-icon"><i class="fas fa-table"></i></div>
Tables
</a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">Logged in as:</div>
Analis Lab
</div>
</nav>
</div>

View File

@ -1,18 +0,0 @@
<div id="layoutSidenav_nav">
<nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<div class="sb-sidenav-menu-heading">Main</div>
<a class="nav-link" href="<?=base_url();?>"><div class="sb-nav-link-icon"><i class="bi bi-speedometer"></i></div>Dashboard</a>
<a class="nav-link" href="<?=base_url();?>changePass/"><div class="sb-nav-link-icon"><i class="bi bi-key"></i></div>Change Password</a>
<div class="sb-sidenav-menu-heading">Administration</div>
<a class="nav-link" href="<?=base_url();?>dictTests/"> <div class="sb-nav-link-icon"><i class="bi bi-journal-album"></i></div> Dict. Test </a>
<a class="nav-link" href="<?=base_url();?>users/"> <div class="sb-nav-link-icon"><i class="bi bi-person-circle"></i></div> Users </a>
<a class="nav-link" href="<?=base_url();?>userroles/"> <div class="sb-nav-link-icon"><i class="bi bi-person-lock"></i></div> User Roles </a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">Logged in as:</div>
</div>
</nav>
</div>

53
app/Views/noAccess.php Normal file
View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>No Access</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f8f9fa;
color: #343a40;
text-align: center;
}
.container {
max-width: 600px;
padding: 20px;
background: white;
border: 1px solid #dee2e6;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2.5rem;
color: #dc3545;
}
p {
font-size: 1rem;
margin-top: 10px;
margin-bottom: 20px;
}
a {
text-decoration: none;
color: #007bff;
font-weight: bold;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h1>Access Denied</h1>
<p>Sorry, you do not have permission to access this page.</p>
<p><a href="/">Return to Homepage</a></p>
</div>
</body>
</html>

435
app/Views/orders_edit.php Normal file
View File

@ -0,0 +1,435 @@
<?= $this->extend($_SESSION['userrole'].'/layout/form.php') ?>
<?= $this->section('content') ?>
<?php
$usercityid = session()->get('usercityid');
if ($usercityid == 1) {
date_default_timezone_set('Asia/Makassar');
$valuevisitnumber = "value='BV'";
$locationdropdown = "
<option value='DPS'>Denpasar</option>
";
} else if ($usercityid == 2) {
date_default_timezone_set('Asia/Jakarta');
$valuevisitnumber = "value='SV'";
$locationdropdown = "
<option value='SBY'>Surabaya</option>
";
} else {
date_default_timezone_set('Asia/Makassar');
$valuevisitnumber = "";
$locationdropdown = "
<option value='DPS'>Denpasar</option>
<option value='SBY'>Surabaya</option>
";
}
$now = date('Y-m-d H:i');
$visitdate = $now;
?>
<style>
.table > tbody > tr > td {
vertical-align: middle;
}
.testtable {
height: 330px;
overflow-y: auto;
}
</style>
<div class="card border-0">
<div class="card-body">
<h3>Order Creation</h3>
<input type='hidden' id='orderid' value='<?=$orderid;?>' />
<div id='alert'>
</div>
<div class='row border gap-1 p-1'>
<div class='col border'>
<!-- Patient Data -->
<p>Patient Information</p>
<input type='hidden' id='patid' value='' />
<div class='table-responsive border-1'>
<table class='table table-sm table-borderless'>
<tr>
<td>MR#</td>
<td colspan='3'>
<div class="input-group">
<input type="text" id="patnumber" class="form-control form-control-sm" oninput="this.value = this.value.toUpperCase();patClear();">
<div class="input-group-append">
<button class='btn btn-sm btn-primary' onclick='patSearch()'><i class='bi bi-search'></i> Search</button>
</div>
</div>
</td>
</tr>
<tr> <td>Patient Name</td> <td id='patname'></td></tr>
<tr> <td>BirthDate</td> <td id='birthdate'></td> </tr>
<tr> <td>Sex</td> <td id='sex'></td> </tr>
<tr> <td>Address</td> <td id='address'></td></tr>
<tr> <td>Phone#</td> <td id='phone'></td></tr>
</table>
</div>
<!-- Order Data -->
<p>Order Information</p>
<div class='table-responsive border-1'>
<table class='table table-sm table-borderless'>
<tr>
<td>Visit#</td>
<td><input type="text" <?=$valuevisitnumber;?> id="visitnumber" class="form-control form-control-sm" oninput="this.value = this.value.toUpperCase();"></td>
<td>Visit Date</td>
<td><input type="datetime" id="visitdate" class="form-control form-control-sm" value='<?=$visitdate;?>'></td>
</tr>
<tr>
<td>Location</td>
<td>
<select id='loc' class='form-control'>
<?=$locationdropdown;?>
</select>
</td>
<td>Reff ID</td>
<td><input type="text" id="reffid" disabled class="form-control form-control-sm" value=''></td>
</tr>
<tr>
<td>Payer Name</td>
<td colspan='3'><input type="text" id="payername" class="form-control form-control-sm"></td>
</tr>
</table>
</div>
</div>
<div class='col border'>
<!-- Tests Data -->
<p>Tests</p>
<div class='table-responsive testtable border'>
<table class='table table-sm '>
<tbody>
<?php
for($i=0;$i<50;$i++) {
?>
<tr>
<td class='px-2'> <?=$i+1;?></td>
<td>
<select class='form-control form-control-sm test<?=$i+1;?>'>
<option value=''></option>
<?php
foreach($tests as $data) {
$qhiscode = $data['HISCODE'];
$qdesc = $data['DESCS'];
echo "<option value='$qhiscode'>$qhiscode - $qdesc</option> \r\n";
}
?>
</select>
</td>
<td> <button class='btn btn-sm btn-warning' onclick="testdel(<?=$i+1;?>)">X</button> </td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</div>
<p class='m-3'>
<button class='btn btn-success' onclick='save()'>Save</button>
<button class='btn btn-secondary' onclick='cancel()'>Cancel</button>
</p>
</div>
</div>
<div class="modal fade" id="modal_patEditor" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Edit Patient</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<table class="table table-sm table-borderless">
<input type='hidden' id='qpatid' value='' />
<tr class="align-middle"> <th>MR#</th> <th>:</th>
<td><input class='form-control' type='text' id='qpatnumber' oninput='this.value = this.value.toUpperCase();' /></td>
</tr>
<tr class="align-middle"> <th>Patient Name</th> <th>:</th> <td><input class='form-control' type='text' id='qpatname'/></td> </tr>
<tr class="align-middle"> <th>BirthDate</th> <th>:</th> <td><input class='form-control' type='date' id='qbirthdate'/></td> </tr>
<tr class="align-middle">
<th>Sex</th> <th>:</th>
<td>
<select class='form-control' id='qsex'>
<option value=''></option>
<option value='F'>Female</option>
<option value='M'>Male</option>
</select>
</td>
</tr>
<tr class="align-middle"> <th>Address</th> <th>:</th> <td><textarea class='form-control' id='qaddress'></textarea></td> </tr>
<tr class="align-middle"> <th>Phone</th> <th>:</th> <td><input class='form-control' type='text' id='qphone'/></td> </tr>
</table>
<button class='btn btn-sm btn-success' onclick='patSave()'>Save</button>
<button class='btn btn-sm btn-secondary' data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="modal_patList" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Patient List</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<table class="table table-sm table-borderless">
<tbody id='patList_tbody' >
</tbody>
</table>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
function testdel(testid) {
if(confirm('are you sure') == true) {
$('.test'+testid).val('').change();
}
}
function orderDetail(orderid) {
console.log(orderid);
let url = '<?=base_url('');?>api/orders/detail/'+orderid;
$.ajax({
url: url,
method: 'GET',
success: function(response) {
var data = response['orders'];
$('#payername').val(data[0].PAYERNAME);
$('#loc').val(data[0].LOC);
$('#visitdate').val(data[0].VISITDATE);
$('#visitnumber').val(data[0].VISITNUMBER);
patSelect(data[0].PATID);
var tests = response['tests'];
var j = 1;
for (const test of tests) {
console.log(test);
console.log(test.HISCODE);
$('.test'+j).val(test.HISCODE).trigger('change');
j++;
}
},
error: function(response) { console.log(response.responseJSON); }
});
}
function save() {
confirm('Are you sure?');
if(confirm) {
var orderid = $("#orderid").val();
var patid = $("#patid").val();
var loc = $("#loc").val();
var visitnumber = $("#visitnumber").val();
var visitdate = $("#visitdate").val();
var treatdoc = $("#treatdoc").val();
var payername = $("#payername").val();
let data = { orderid:orderid, loc:loc, patid:patid, visitnumber:visitnumber, visitdate:visitdate, treatdoc:treatdoc, payername:payername ,tests:new Array() };
for (let i = 1; i <= 50; i++) {
let className = `.test${i}`;
let value = $(className).val();
if (value !== undefined && value != '') {
data['tests'].push(value);
}
}
alert = '';
errorTxt = '';
if(patid == '') { errorTxt += '<br/>patient is empty. '; }
if(visitnumber == '') { errorTxt += '<br/>visitnumber is empty. '; }
if(visitdate == '') { errorTxt += '<br/>visitdate is empty. '; }
if(data['tests'].length == 0) { errorTxt += '<br/>tests is empty. '; }
if(errorTxt != '') {
alert = '<div class="alert alert-danger alert-dismissible fade show" role="alert">' +
'<strong>Error!</strong>' + errorTxt +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>'+
'</div>';
$('#alert').html(alert);
} else {
console.log(data);
let url = '<?=base_url('');?>api/orders/save';
$.ajax({
url: url,
method: "POST",
data: data,
success: function(response) {
console.log(response);
window.close();
if (window.opener) { window.opener.location.reload(); }
},
error: function(response) {
console.log(response);
}
});
}
}
}
function cancel() {
confirm('Your data will be discarded. Are you sure?');
if(confirm) {
window.close();
}
}
function patClear() {
$('#patid').val('');
$('#patname').html('');
$('#sex').html('');
$('#birthdate').html('');
$('#address').html('');
$('#phone').html('');
}
function patSelect(patid) {
$('#modal_patList').modal('hide');
$('#modal_patEditor').modal('hide');
let url = '<?=base_url('');?>api/patients/detail/'+patid;
$.ajax({
url: url,
method: "GET",
success: function(response) {
let data = response['patient'];
$("#patid").val(patid);
$("#patnumber").val(data.PATNUMBER);
$('#patname').html(data.PATNAME);
$('#sex').html(data.SEX);
$('#birthdate').html(data.BIRTHDATE);
$('#address').html(data.ADDRESS);
$('#phone').html(data.PHONE);
},
error: function(response) {
alert(response.responseJSON.messages.errors);
}
});
}
function patCreate() {
$('#modal_patList').modal('hide');
$("#qpatid").val('0');
$("#qpatnumber").val(patnumber);
$("#qpatname").val("");
$("#qsex").val("");
$("#qbirthdate").val("");
$("#qaddress").val('');
$('#modal_patEditor').modal('show');
}
function patEdit(patid) {
$('#modal_patList').modal('hide');
let url = '<?=base_url('');?>api/patients/detail/'+patid;
$.ajax({
url: url,
method: "GET",
success: function(response) {
let data = response['patient'];
$("#qpatnumber").val(data.PATNUMBER);
$("#qpatid").val(patid);
$("#qpatname").val(data.PATNAME);
$("#qsex").val(data.SEX);
$("#qbirthdate").val(data.BIRTHDATE);
$("#qaddress").val(data.ADDRESS);
$("#qphone").val(data.PHONE);
$("#modal_patEditor").modal('show');
},
error: function(response) {
alert(response.responseJSON.messages.errors);
}
});
}
function patSearch() {
patnumber = $("#patnumber").val();
let url = '<?=base_url('');?>api/patients/search';
$.ajax({
url: url,
method: "POST",
data: {patnumber:patnumber},
success: function(response) {
$("#patList_tbody").html("");
var data = response['patients'];
datarow = '<tr> <td><button class="btn btn-sm btn-primary" onclick="patCreate(\''+patnumber+'\')"><i class="bi bi-plus-circle"></i> Create</button></td> </tr>';
$("#patList_tbody").append(datarow);
if(data.length != 0) {
for (var i = 0; i < data.length; i++) {
patid = data[i].PATID;
qpatnumber = data[i].PATNUMBER;
patname = data[i].PATNAME;
sex = data[i].SEX;
birthdate = data[i].BIRTHDATE;
editBtn = '<button class="btn btn-sm btn-warning" ' + ' onclick="patEdit(\'' + patid + '\')">Edit' + '</button> ';
selectBtn = '<button class="btn btn-sm btn-success" ' + ' onclick="patSelect(\'' + patid + '\')">Select' + '</button> ';
if(data[i].LISCODE == null) { liscode = '-'; }
let datarow = '<tr class="align-middle">' +
'<td>' + qpatnumber + '</td>' + '<td>' + patname+ '</td> <td>' + sex + '</td>' + '<td>' + birthdate+ '</td>' + '<td>' + selectBtn + editBtn + '</td>' +
'</tr>';
$("#patList_tbody").append(datarow);
}
}
$('#modal_patList').modal('show');
},
error: function(response) {
alert(response.responseJSON.messages.errors);
}
});
}
function patSave() {
patid = $("#qpatid").val();
patnumber = $("#qpatnumber").val();
patname = $("#qpatname").val();
birthdate = $('#qbirthdate').val();
sex = $('#qsex').val();
address = $('#qaddress').val();
phone = $('#qphone').val();
let data = { patid: patid, patnumber: patnumber, patname:patname, birthdate:birthdate, sex:sex, address:address, phone:phone };
let url = '<?=base_url('');?>api/patients/save';
$.ajax({
url: url,
method: "POST",
data:data,
success: function(response) {
console.log(response);
patSelect(patnumber);
},
error: function(response) {
alert(response.responseJSON.messages.errors);
}
});
}
$(document).ready(function() {
<?php
for($i=1;$i<=50;$i++) {
echo "$('.test$i').select2();";
}
?>
flatpickr("#visitdate", { allowInput: true, enableTime: true, dateFormat: "Y-m-d H:i", time_24hr: true });
$("#patnumber").keydown(function(event) {
if (event.keyCode === 13) {
patSearch();
}
});
if( $('#orderid').val()!=0 ) {
orderDetail($('#orderid').val());
}
});
</script>
<?= $this->endSection() ?>

118
app/Views/orders_index.php Normal file
View File

@ -0,0 +1,118 @@
<?= $this->extend($_SESSION['userrole'].'/layout/main.php') ?>
<?= $this->section('content') ?>
<div id="alert">
</div>
<div class="card border-0">
<div class="card-body">
<div class='card-title'>Order List</div>
<p>
<b>Date</b> &nbsp; <input class='date1' type='date' value=''> - <input class='date2' type='date'> <button class='btn btn-sm btn-primary' onclick='index()'><i class="bi bi-calendar2-event"></i>&nbsp;Filter</button>
</p>
<p> <button class='btn btn-sm btn-success' onclick='create()'><i class="bi bi-plus-circle"></i>&nbsp;New Order</button> </p>
<div class="table-responsive">
<table id="myTable" class="table">
<thead>
<th>VisitDate</th>
<th>Loc.</th>
<th>Visit#</th>
<th>MR#</th>
<th>Patient Name</th>
<th>Payer Name</th>
<th>Test</th>
<th>Action</th>
</thead>
<tbody id="table-body">
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal_orderdetail" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
let curDate = new Date().toJSON().slice(0, 10);
$('.date1').val(curDate);
$('.date2').val(curDate);
index();
function index() {
let url = '<?=base_url('');?>api/orders/index';
date1 = $('.date1').val();
date2 = $('.date2').val();
$.ajax({
url: url,
method: 'POST',
data : {date1:date1, date2:date2},
success: function(response) {
$("#myTable").DataTable().destroy();
$("#table-body").html("");
var data = response['data'];
for (var i = 0; i < data.length; i++) {
orderid = data[i].ORDERID;
loc = data[i].LOC;
visitdate = data[i].VISITDATE;
visitnumber = data[i].VISITNUMBER;
patnumber = data[i].PATNUMBER;
patname = data[i].PATNAME;
payername = data[i].PAYERNAME;
tests = data[i].TESTS;
editBtn = '<button class="btn btn-sm btn-warning" onclick="edit(\''+ orderid +'\')"><i class="bi bi-pencil"></i> edit</button>';
resendBtn = '<button class="btn btn-sm btn-primary" onclick="resend(\''+ visitnumber +'\')"><i class="bi bi-send"></i> resend</button>';
let datarow = '<tr class="align-middle">' +
'<td>' + visitdate + '</td> <td>' + loc + '</td> <td>' + visitnumber + '</td> <td>' + patnumber + '</td> <td>' + patname +
'</td> <td>' + payername + '</td> <td>' + tests + '</td> ' +
'<td>' + resendBtn + ' ' + editBtn + '</td>' +
'</tr>';
$("#table-body").append(datarow);
}
// $('#myTable').DataTable();
$('#myTable').DataTable({
"pageLength": 25, // Ganti sesuai kebutuhan
"lengthMenu": [25, 50, 100] // Pilihan dropdown entries per halaman
});
},
error: function(response) { console.log(response.responseJSON); }
});
}
function create() {
window.open("<?php echo base_url();echo $_SESSION['userrole']?>/orders/create",
'_blank', "width=1200,height=700,location=no,toolbar=no,menubar=no"
);
}
function edit(orderid) {
window.open("<?php echo base_url();echo $_SESSION['userrole']?>/orders/edit/"+orderid,
'_blank', "width=1200,height=700,location=no,toolbar=no,menubar=no"
);
}
function resend(visitnumber) {
let url = '<?=base_url('');?>api/orders/resend/'+visitnumber;
$.ajax({
url: url,
method: 'GET',
success: function(response) {
alert = '<div class="alert alert-primary alert-dismissible fade show" role="alert">' +
'Re-send '+visitnumber+' success.' +
'<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>'+
'</div>';
$('#alert').html(alert);
},
error: function(response) { console.log(response.responseJSON); }
});
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,167 @@
<?= $this->extend($_SESSION['userrole'].'/layout/main.php') ?>
<?= $this->section('content') ?>
<div class="card border-0 m-1">
<div class="card-header bg-success text-white">Patients List</div>
<div class="card-body">
<div class='row mb-2'>
<div class='col-2'>MR#</div>
<div class='col-2'><input type='text' class='form-control form-control-sm' id='search_patnumber' oninput='this.value = this.value.toUpperCase();' /></div>
</div>
<div class='row mb-2'>
<div class='col-2'>Name</div>
<div class='col-3'><input type='text' class='form-control form-control-sm' id='search_patname' oninput='this.value = this.value.toLowerCase();' /></div>
</div>
<button class='btn btn-sm btn-success-2' onclick='search()'>Search</button>
</div>
</div>
<div class="card border-0 m-1">
<div class="card-body">
<button class='btn btn-sm btn-primary' onclick='create()'><i class='bi bi-plus-circle'></i> Create</button>
<div class="table-responsive">
<table id="myTable" class="table">
<thead>
<tr>
<th>MR#</th>
<th>Name</th>
<th>Sex</th>
<th>Birthdate</th>
<th>Action</th>
</tr>
</thead>
<tbody id='table-body'>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal_patEditor" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Patient Editor</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<table class="table table-sm table-borderless">
<input type='hidden' id='qpatid' value='' />
<tr class="align-middle"> <th>MR#</th> <th>:</th>
<td><input class='form-control' type='text' id='qpatnumber' oninput='this.value = this.value.toUpperCase();' /></td>
</tr>
<tr class="align-middle"> <th>Patient Name</th> <th>:</th> <td><input class='form-control' type='text' id='qpatname'/></td> </tr>
<tr class="align-middle"> <th>BirthDate</th> <th>:</th> <td><input class='form-control' type='date' id='qbirthdate'/></td> </tr>
<tr class="align-middle">
<th>Sex</th> <th>:</th>
<td>
<select class='form-control' id='qsex'>
<option value=''></option>
<option value='F'>Female</option>
<option value='M'>Male</option>
</select>
</td>
</tr>
<tr class="align-middle"> <th>Address</th> <th>:</th> <td><textarea class='form-control' id='qaddress'></textarea></td> </tr>
<tr class="align-middle"> <th>Phone</th> <th>:</th> <td><input class='form-control' type='text' id='qphone'/></td> </tr>
</table>
<button class='btn btn-sm btn-success' onclick='save()'>Save</button>
<button class='btn btn-sm btn-secondary' data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
function search() {
let url = '<?=base_url('');?>api/patients/search';
patnumber = $('#search_patnumber').val();
patname = $('#search_patname').val();
let data = { patnumber:patnumber, patname:patname };
$.ajax({
url: url,
method: 'POST',
data: data,
success: function(response) {
$("#myTable").DataTable().destroy();
$("#table-body").html("");
var data = response['patients'];
for (var i = 0; i < data.length; i++) {
patid = data[i].PATID;
patnumber = data[i].PATNUMBER;
patname = data[i].PATNAME;
sex = data[i].SEX;
birthdate = data[i].BIRTHDATE;
let editBtn = '<button class="btn btn-sm btn-success" ' + ' onclick="edit(\'' + patid + '\')">Edit' + '</button> ';
let datarow = '<tr class="align-middle">' +
'<td>' + patnumber + '</td>' + '<td>' + patname + '</td> <td>' + sex + '</td> <td>' + birthdate + '</td>' +
'<td>' + editBtn + '</td>' + '</tr>';
$("#table-body").append(datarow);
}
$("#myTable").DataTable();
},
error: function(response) { console.log(response.responseJSON); }
});
}
function create() {
$("#qpatid").val('0');
$("#qpatnumber").val();
$("#qpatname").val("");
$("#qsex").val("");
$("#qbirthdate").val("");
$("#qaddress").val('');
$('#modal_patEditor').modal('show');
}
function edit(patid) {
let url = '<?=base_url('');?>api/patients/detail/'+patid;
$.ajax({
url: url,
method: "GET",
success: function(response) {
let data = response['patient'];
$("#qpatid").val(patid);
$("#qpatnumber").val(data.PATNUMBER);
$("#qpatname").val(data.PATNAME);
$("#qsex").val(data.SEX);
$("#qbirthdate").val(data.BIRTHDATE);
$("#qaddress").val(data.ADDRESS);
$("#qphone").val(data.PHONE);
$("#modal_patEditor").modal('show');
},
error: function(response) {
alert(response.responseJSON.messages.errors);
}
});
}
function save() {
patid = $("#qpatid").val();
patnumber = $("#qpatnumber").val();
patname = $("#qpatname").val();
birthdate = $('#qbirthdate').val();
sex = $('#qsex').val();
address = $('#qaddress').val();
phone = $('#qphone').val();
let data = { patid: patid, patnumber: patnumber, patname:patname, birthdate:birthdate, sex:sex, address:address, phone:phone };
let url = '<?=base_url('');?>api/patients/save';
$.ajax({
url: url,
method: "POST",
data:data,
success: function(response) {
$("#modal_patEditor").modal('hide');
$('#search_patnumber').val(patnumber);
search();
},
error: function(response) {
alert(response.responseJSON.messages.errors);
}
});
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,24 @@
<?php
if ($site[0] == 'S' || $site[0] == 's' || $site[0] == 'X' || $site[0] == 'x') {
$image = 'sby_bcg_rev_2.png';
} else {
$image = 'bali_bcg.png';
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<link rel='stylesheet' href='<?=base_url();?>assets/css/pdf_new.css' />
<style>
#page {
background-image: url('<?=base_url();?>assets/img/<?=$image;?>');
}
</style>
</head>
<body style='-webkit-print-color-adjust:exact;'>
<?php echo $data; ?>
</body>
</html>

View File

@ -0,0 +1,290 @@
<?= $this->extend('sampling/layout/main.php') ?>
<?= $this->section('content') ?>
<style>
.pointercol {
cursor: pointer;
}
</style>
<div id='stats' class="d-flex justify-content-between p-0">
</div>
<div class="card border-0">
<!-- div.card-head -->
<div class="card-body">
<div class="row d-flex align-items-center">
<div class="col col-auto">
<b>Date</b>&nbsp; &nbsp;:&nbsp; &nbsp;<input class='date1' type='date' value=''> - <input class='date2' type='date'>
</div>
<div class="col col-auto">
<button class='btn btn-sm btn-primary py-1 px-2 d-flex align-items-center' onclick='index()'><i class="bi bi-calendar2-event"></i>&nbsp;&nbsp;Search</button>
</div>
</div>
<div class="table-responsive mt-3">
<table id="myTable" class="table table-hover">
<thead class='text-start'>
<th class='text-start' width="10%">Order Date</th>
<th width="12%">Patient#</th>
<th width="17%">Patient Name</th>
<th class='text-start' width="10%">Access#</th>
<th width="10%">Visit#</th>
<th width="10%">HIS#</th>
<th>Test</th>
<th width="5%">Status</th>
<th></th>
</thead>
<tbody id="table-body" class='text-start'>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
// let curDate = new Date().toJSON().slice(0, 10);
date = new Date();
let curDate = (new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON()).slice(0, 10);
$('.date1').val(curDate);
$('.date2').val(curDate);
index();
document.addEventListener('keydown', function(event) {
if (event.key === 'F5') { event.preventDefault(); index(); }
});
function index() {
let url = '<?=base_url('');?>api/dashboard/index';
date1 = $('.date1').val();
date2 = $('.date2').val();
$.ajax({
url: url,
method: 'POST',
data : {date1:date1, date2:date2},
success: function(response) {
/*
// counter
*/
$("#stats").html("");
var stats = ['Pend', 'PartColl', 'Coll', 'PartRecv', 'Recv', 'Inc', 'PartVal', 'Comp'];
var statcolor = ['text-orange', 'text-peach', 'text-pink', 'text-soft-blue', 'text-blue', 'text-grey', 'text-soft-green', 'text-green'];
var staticon = ['bi-clock-history','bi-tv', 'bi-collection', 'bi-file-medical', 'bi-journal-medical', 'bi-calendar3-week', 'bi-check2', 'bi-clipboard-check'];
var stattext = ['Pending', 'Part Collected', 'Collected', 'Part Received', 'Received', 'Incomplete', 'Part Validated', 'Validated'];
var count = response['count'];
var statcontent = '';
stats.forEach ( (item, index) => {
//console.log(item + ' ' + index);
if(!count[item]) { count[item] = 0; }
statcontent += '<div class="custom-card shadow" data-filtertype="'+index+'">' +
'<div class="custom-card-content">' +
'<div class="row p-0 d-flex justify-content-between">' +
'<div class="col-3 text-start '+statcolor[index]+'"> <h5 class="m-0"><i class="bi '+staticon[index]+'"></i></h5> </div>' +
'<div class="col-9 text-end pe-3"> <h2 class="m-0 custom-card-title">'+count[item]+'</h2> </div>' +
'</div>' +
"<hr class='"+statcolor[index]+"'>" +
'<h3 class="custom-card-text m-0 p-0 '+statcolor[index]+'">'+ stattext[index] +'</h3>' +
'</div>' +
'</div>';
});
$("#stats").html(statcontent);
/*
// table
*/
$("#myTable").DataTable().destroy();
$("#table-body").html("");
var data = response['data'];
for (var i = 0; i < data.length; i++) {
colldate = data[i].COLLECTIONDATE.slice(0,10);
colltime = data[i].COLLECTIONDATE.slice(10,16);
if (data[i].PATNUMBER != null) {
patnumber = data[i].PATNUMBER.replace(/^0+/, '');
// patnumber = data[i].PATNUMBER.substr(-16,16);
// patnumber = patnumber.substring(patnumber.length - 10);
} else {
patnumber = ' NULL ';
}
accessnumber = data[i].SP_ACCESSNUMBER;
patname = data[i].NAME;
hon = data[i].HOSTORDERNUMBER;
let testing_test = "";
if (hon[0] === 'X' || hon[0] === 'Z') {
testing_test = "<div class='badge text-bg-warning'>testing tm</div><br>";
} else {
testing_test = "";
}
if (data[i].REFFID != null) {
// patnumber = data[i].PATNUMBER;
reffid = data[i].REFFID;
// patnumber = data[i].PATNUMBER.substr(-16,16);
// patnumber = patnumber.substring(patnumber.length - 10);
} else {
reffid = ' NULL ';
}
tests = data[i].TESTS;
stat = data[i].STATS;
reqstatus = String(data[i].REQSTATUS);
trcolor = '';
if (reqstatus != '1') {
if(stat == 'Pend') {
bgcolor = 'bg-orange';
datafilter = "data-filterrow='0'";
stattext = 'Pending';
} else if(stat == 'PartColl') {
bgcolor = 'bg-peach';
datafilter = "data-filterrow='1'";
stattext = 'Part Collected';
} else if(stat == 'Coll') {
bgcolor = 'bg-pink';
datafilter = "data-filterrow='2'";
stattext = 'Collected';
} else if(stat == 'PartRecv') {
bgcolor = 'bg-soft-blue';
datafilter = "data-filterrow='3'";
stattext = 'Part Received';
} else if(stat == 'Recv') {
bgcolor = 'bg-blue';
datafilter = "data-filterrow='4'";
stattext = 'Received';
} else if(stat == 'Inc') {
bgcolor = 'bg-grey';
datafilter = "data-filterrow='5'";
stattext = 'Incomplete';
} else if(stat == 'PartVal') {
bgcolor = 'bg-soft-green';
datafilter = "data-filterrow='6'";
stattext = 'Part Validated';
} else if(stat == 'Comp') {
bgcolor = 'bg-green';
datafilter = "data-filterrow='7'";
stattext = 'Validated';
}
} else {
trcolor = ' table-danger-custom ';
bgcolor = ' table-danger-custom ';
datafilter = "data-filterrow='8'";
stattext = 'Cancelled';
}
let datarow = "<tr class='align-middle" + trcolor +"'" + datafilter + " >" +
"<td class='text-start'>" + colldate + '<br>'+ colltime +'</td>'+
"<td class='text-start' style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + patnumber + "<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + patname.trim() + "<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td class='text-start' style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + accessnumber +"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + testing_test + hon +"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>"+
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>"+reffid+"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>"+
"<td>" + tests + '</td>' +
"<td role='button' class='"+bgcolor+" text-center align-middle pointercol' onclick='viewAccess("+accessnumber+")'>"+stattext+"</td>" +
"<td role='button' class='text-center align-middle' onclick='resultPdfAccess("+accessnumber+ ",event" +")'> <h4 class='p-0 m-0'><i class='bi bi-filetype-pdf'></i></h4> </td>" +
'</tr>';
$("#table-body").append(datarow);
}
$('#myTable').DataTable({
"order": [0, "desc"], // Urutan Tanggal Desc
"pageLength": 50, // Ganti sesuai kebutuhan
"lengthMenu": [50, 75, 100] // Pilihan dropdown entries per halaman
});
// datatable filter
const filterButton = document.querySelectorAll("[data-filtertype]");
const table = document.querySelector("#myTable");
const tr = table.getElementsByTagName("tr");
let activeButton = null;
filterButton.forEach((button) => {
button.addEventListener("click", () => {
const selectedButton = button.getAttribute("data-filtertype");
console.log(selectedButton);
if (activeButton === button) {
button.classList.remove("active", "border", "border-primary", "border-5");
activeButton = null;
for (let i = 1; i < tr.length; i++) {
tr[i].style.display = "";
}
} else {
filterButton.forEach((btn) => btn.classList.remove("active", "border", "border-info", "border-3"));
button.classList.add("active", "border", "border-info", "border-3");
activeButton = button;
for (let i = 1; i < tr.length; i++) {
const filterValue = tr[i].getAttribute("data-filterrow");
if (filterValue === selectedButton) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
});
});
},
error: function(response) { console.log(response.responseJSON); }
});
}
function viewAccess(access) {
let url = '<?=base_url();?>sampling/dashboard/viewAccess/'+access;
$('.modal-content').load(url, function(){
$('#modal').modal('show');
});
}
function resultPdfAccess(access, event) {
event.stopPropagation(); // Mencegah klik pada <tr> dieksekusi
let url = '<?=base_url();?>printResult/'+access;
window.open(url, '_blank');
}
function copyToClipboard(element) {
let text = element.innerText.trim(); // Ambil teks dari elemen
text = text.replace("Teks sudah disalin", "").trim(); // Hilangkan teks notifikasi sebelumnya
if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(() => {
showCopyMessage(element);
}).catch(err => {
console.error("Gagal menyalin teks: ", err);
});
} else {
// Alternatif jika Clipboard API tidak didukung
let tempInput = document.createElement("textarea");
tempInput.value = text;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
showCopyMessage(element);
}
}
function showCopyMessage(element) {
let message = element.querySelector(".copy-message");
if (message) {
message.style.display = "inline"; // Tampilkan teks notifikasi
// Sembunyikan kembali setelah 2 detik
setTimeout(() => {
message.style.display = "none";
}, 500);
}
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,304 @@
<?php
if(isset($data[0])) {
$row = $data[0];
// if (strlen($patnumber) < 10) {
// $patnumber = str_pad($patnumber, 10, "0", STR_PAD_LEFT);
// }
?>
<div class="modal-header bg-soft-green text-white">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Detail Request </h1>
<button type="button" class="btn-close text-white" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<div class="row">
<div class="col">
<table class="table table-sm table-borderless">
<tr>
<th width='18%'>Access Number</th>
<th>:</th>
<td width='31%'><?=$accessnumber;?></td>
<th>Visit Description</th>
<th>:</th>
<td><?=$visit_description;?></td>
</tr>
<tr>
<th>Patient Number</th>
<th>:</th>
<td><?=$patnumber;?></td>
<th width='18%'>Payer Name</th>
<th>:</th>
<td width='31%'><?=$payer_name;?></td>
</tr>
<tr>
<th>Patient Name</th>
<th>:</th>
<td><?=$patient_fullname;?></td>
<th>Treating Doctor</th>
<th>:</th>
<td><?=$treating_doctor;?></td>
</tr>
</table>
</div>
</div>
<div class='row'>
<div class="col-12">
<div class="card bg-white">
<div class="card-body">
<div class="card-title"><h3>Sample List</h3></div>
<table class='table'>
<tr> <th class='text-center'>Coll.</th> <th class='text-center'>Recv.</th> <th>Sample Name</th> <th>Action</th> <th>Comment</th> </tr>
<tr>
<td></td> <td></td> <td>All</td>
<td>
<button type='button' class='btn btn-dark m-0 px-2 py-1' onclick="printAllLabel(<?=$accessnumber;?>, <?=$usercityid;?>)"> <h6 class='p-0 m-0'><i class='bi bi-printer'></i></h6> </button>
<button type='button' class='btn btn-success m-0 px-2 py-1' onclick='collectAll(<?=$accessnumber;?>)'><h6 class='p-0 m-0'>Coll.</h6></button>
<!-- <button class='badge bg-black text-white m-0 px-2 py-1' onclick='uncollectAll(<?=$accessnumber;?>)'>un-collect</button> -->
<!-- <button type='button' class='btn btn-primary m-0 px-2 py-1' onclick='unreceiveAll(<?=$accessnumber;?>)'><h6 class='p-0 m-0'>Un-Rec.</h6></button> -->
</td>
</tr>
<tr>
<td></td> <td></td> <td>Collection</td>
<td><button type='button' class='btn btn-dark m-0 px-2 py-1' onclick="printCollectionLabel(<?=$accessnumber;?>, <?=$usercityid;?>)"><h6 class='p-0 m-0'> <i class='bi bi-printer'></i></h6></button></td>
</tr>
<?php
foreach($data as $row) {
$sampletype = $row['SAMPLETYPE'];
$sampletext = $row['SHORTTEXT'];
if ($sampletype == "200") {
$sampletext = "Serum Kimia";
} else if ($sampletype == '250') {
$sampletext = "Serum Imun";
}
$tubestatus = $row['TUBESTATUS'];
$collstatus = $row['COLLSTATUS'];
$comment = $row['TUBECOMMENT'];
echo "\r\n <tr>";
if($collstatus==1) {
echo " <td class='text-center'><input type='checkbox' class='form-check-input' id='coll$sampletype' checked disabled></td>";
} else {
echo " <td class='text-center'><input type='checkbox' class='form-check-input' id='coll$sampletype' disabled></td>";
}
if($tubestatus==4) {
echo "<td class='text-center'><input type='checkbox' class='form-check-input' id='recv$sampletype' checked disabled></td>";
} else {
echo "<td class='text-center'><input type='checkbox' class='form-check-input' id='recv$sampletype' disabled></td>";
}
echo "<td>$sampletext ($sampletype)</td>";
echo "<td>
<button type='button' class='btn btn-dark m-0 px-2 py-1' " . "onclick='printSingleLabel($accessnumber, $sampletype, $usercityid)'" . "><h6 class='p-0 m-0'><i class='bi bi-printer'></i></h6></button>
<button type='button' class='btn btn-success m-0 px-2 py-1' onclick='collect($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Coll.</h6></button>
<button type='button' class='btn btn-warning m-0 px-2 py-1' onclick='uncollect($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Un-Coll.</h6></button>
<button type='button' class='btn btn-primary m-0 px-2 py-1' onclick='unreceive($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Un-Rec.</h6></button>
</td> ";
echo "<td id='comment$sampletype'>$comment <h6 class='p-0 m-0'><i class='bi bi-pencil-square' role='button' onclick='comment($sampletype, $accessnumber, \"$sampletext\", \"$comment\")'></i></h6></td>";
echo " </tr>";
}
?>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
function printCollectionLabel(access, usercityid){
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/collection/'+access.toString();
} else {
url = '<?=base_url();?>printLabel/collection/'+access.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function printSingleLabel(access, sample, usercityid) {
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/single/'+access.toString()+'/'+sample.toString();
} else {
url = '<?=base_url();?>printLabel/single/'+access.toString()+'/'+sample.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function printAllLabel(access, usercityid) {
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/all/'+access.toString();
} else {
url = '<?=base_url();?>printLabel/all/'+access.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function collect(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/collect/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#coll"+sample).prop("checked", true);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function collectAll(access) {
const url = '<?=base_url();?>tubes/collectAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="coll"]').prop('checked', true);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function uncollect(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/uncollect/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#coll"+sample).prop("checked", false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function uncollectAll(access) {
const url = '<?=base_url();?>tubes/uncollectAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="coll"]').prop('checked', false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function unreceive(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/unreceive/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#recv"+sample).prop("checked", false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function unreceiveAll(access) {
const url = '<?=base_url();?>tubes/unreceiveAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="recv"]').prop('checked', false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function comment(sample, access, sampletext, comments) {
const url = '<?=base_url();?>tubes/comment/'+access+'/'+sample;
let comment = prompt('Comment for sample '+sampletext, comments);
//$('#comment'+sample).html(comment +"<i class='bi bi-pencil-square' onclick='comment("+ sample +", "+ access +', "'+sampletext+'", "'+comment+'")\'></i>');
fetch(url, {
method: "POST",
body: JSON.stringify({ comment : comment }),
headers: { "Content-type": "application/json; charset=UTF-8" }
}).then(data => {
//console.log(data);
viewAccess(access);
})
.catch(error => { console.error('Error:',error); });
}
</script>
<?php
} else {
?>
<div class="modal-header bg-black text-white">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Detail Request </h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body">
<h3>Data not found</h3>
</div>
<?php
}
?>

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" sizes="16x16" href="<?=base_url();?>/assets/favicon.png">
<title>Summit CRM</title>
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/select2/select2.min.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/select2/select2-bootstrap-5-theme.min.css" rel="stylesheet">
<style>
.select2-results__option { font-size: 0.75rem !important; margin: 5px !important; padding: 5px !important; }
li.select2-selection__choice { background-color : #000 !important; padding:5px !improtant; }
.select2 {width:100%!important;}
</style>
<script src="<?=base_url();?>/assets/jquery/jquery.min.js"></script>
<script src="<?=base_url();?>/assets/select2/select2.min.js"></script>
<?= $this->renderSection('head'); ?>
</head>
<body class="skin-megna-dark fixed-layout">
<div class="preloader">
<div class="loader">
<div class="loader__figure"></div>
<p class="loader__label">Summit-CRM</p>
</div>
</div>
<div id="main-wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card mt-2">
<div class="card-body">
<?= $this->renderSection('content'); ?>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="<?=base_url();?>/assets/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>/assets/perfect-scrollbar.jquery.min.js"></script>
<script src="<?=base_url();?>/assets/app.js"></script>
<?= $this->renderSection('script'); ?>
<script>
$('.select2').select2();
</script>
</body>
</html>

View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Analis Dashboard</title>
<link rel="stylesheet" href="<?=base_url();?>assets/css/icons/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="<?=base_url();?>assets/datatables/datatables.min.css">
<link href="<?=base_url();?>assets/css/styles.css" rel="stylesheet" />
</head>
<!-- <body class="sb-nav-fixed sb-sidenav-toggled"> -->
<body class="sb-nav-fixed">
<?= $this->include('sampling/layout/topbar'); ?>
<div id="layoutSidenav">
<?= $this->include('sampling/layout/sidebar'); ?>
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-2 py-2">
<?php
if(isset($_SESSION['alertmsg'])) {
?>
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<?=$_SESSION['alertmsg'];?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php
}
?>
<?= $this->renderSection('content'); ?>
</div>
</main>
<footer class="py-3 bg-light mt-auto">
<div class="container-fluid px-4">
<div class="d-flex align-items-center justify-content-between small">
<div class="text-muted ms-auto ">Copyright &copy; 4SKAI 2024</div>
</div>
</div>
</footer>
</div>
</div>
<script src="<?=base_url();?>assets/jquery-3.6.0.min.js"></script>
<script src="<?=base_url();?>assets/js/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>assets/datatables/datatables.min.js"></script>
<script src="<?=base_url();?>assets/js/scripts.js"></script>
<?= $this->renderSection('script'); ?>
</body>
</html>

View File

@ -0,0 +1,14 @@
<div id="layoutSidenav_nav">
<nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<div class="sb-sidenav-menu-heading">Main</div>
<a class="nav-link" href="<?=base_url();?>sampling/"><div class="sb-nav-link-icon"><i class="bi bi-speedometer"></i></div>Dashboard</a>
<a class="nav-link" href="<?=base_url();?>changePass/"><div class="sb-nav-link-icon"><i class="bi bi-key"></i></div>Change Password</a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">Logged in as: <b>Sampling User</b></div>
</div>
</nav>
</div>

View File

@ -0,0 +1,23 @@
<nav class="sb-topnav navbar navbar-expand navbar-light bg-light shadow-sm text-luxury">
<a class="navbar-brand ps-3 d-none d-md-block" href="#"><img src='<?=base_url();?>assets/img/logo.png' width='30' /> CMOD</a>
<button class="btn btn-link me-2" id="sidebarToggle"><i class="bi bi-list "></i></button>
<div class="ms-auto">
<ul class="navbar-nav ms-md-0 me-3 me-lg-4">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i>
<?=$_SESSION['username'];?>
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#!">Profile</a></li>
<li><a class="dropdown-item" href="#!">Change Password</a></li>
<li><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item" href="<?=base_url();?>auth/logout">Logout</a></li>
</ul>
</li>
</ul>
</div>
</nav>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" sizes="16x16" href="<?=base_url();?>/assets/favicon.png">
<title>Summit CRM</title>
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/font-awesome-640/css/all.min.css" rel="stylesheet">
<?= $this->renderSection('head'); ?>
</head>
<body class="skin-megna-dark fixed-layout">
<div class="preloader">
<div class="loader">
<div class="loader__figure"></div>
<p class="loader__label">Summit-CRM</p>
</div>
</div>
<div>
<?= $this->renderSection('content'); ?>
</div>
<script src="<?=base_url();?>/assets/jquery/jquery.min.js"></script>
<script src="<?=base_url();?>/assets/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>/assets/app.js"></script>
<?= $this->renderSection('script'); ?>
<script>
$(document).ready(function() {
$('.select2').select2({
dropdownAutoWidth : true,
width: '100%',
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,290 @@
<?= $this->extend('user/layout/main.php') ?>
<?= $this->section('content') ?>
<style>
.pointercol {
cursor: pointer;
}
</style>
<div id='stats' class="d-flex justify-content-between p-0">
</div>
<div class="card border-0">
<!-- div.card-head -->
<div class="card-body">
<div class="row d-flex align-items-center">
<div class="col col-auto">
<b>Date</b>&nbsp; &nbsp;:&nbsp; &nbsp;<input class='date1' type='date' value=''> - <input class='date2' type='date'>
</div>
<div class="col col-auto">
<button class='btn btn-sm btn-primary py-1 px-2 d-flex align-items-center' onclick='index()'><i class="bi bi-calendar2-event"></i>&nbsp;&nbsp;Search</button>
</div>
</div>
<div class="table-responsive mt-3">
<table id="myTable" class="table table-hover">
<thead class='text-start'>
<th class='text-start' width="10%">Order Date</th>
<th width="12%">Patient#</th>
<th width="17%">Patient Name</th>
<th class='text-start' width="10%">Access#</th>
<th width="10%">Visit#</th>
<th width="10%">HIS#</th>
<th>Test</th>
<th width="5%">Status</th>
<th></th>
</thead>
<tbody id="table-body" class='text-start'>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modal" aria-hidden="true" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
// let curDate = new Date().toJSON().slice(0, 10);
date = new Date();
let curDate = (new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON()).slice(0, 10);
$('.date1').val(curDate);
$('.date2').val(curDate);
index();
document.addEventListener('keydown', function(event) {
if (event.key === 'F5') { event.preventDefault(); index(); }
});
function index() {
let url = '<?=base_url('');?>api/dashboard/index';
date1 = $('.date1').val();
date2 = $('.date2').val();
$.ajax({
url: url,
method: 'POST',
data : {date1:date1, date2:date2},
success: function(response) {
/*
// counter
*/
$("#stats").html("");
var stats = ['Pend', 'PartColl', 'Coll', 'PartRecv', 'Recv', 'Inc', 'PartVal', 'Comp'];
var statcolor = ['text-orange', 'text-peach', 'text-pink', 'text-soft-blue', 'text-blue', 'text-grey', 'text-soft-green', 'text-green'];
var staticon = ['bi-clock-history','bi-tv', 'bi-collection', 'bi-file-medical', 'bi-journal-medical', 'bi-calendar3-week', 'bi-check2', 'bi-clipboard-check'];
var stattext = ['Pending', 'Part Collected', 'Collected', 'Part Received', 'Received', 'Incomplete', 'Part Validated', 'Validated'];
var count = response['count'];
var statcontent = '';
stats.forEach ( (item, index) => {
//console.log(item + ' ' + index);
if(!count[item]) { count[item] = 0; }
statcontent += '<div class="custom-card shadow" data-filtertype="'+index+'">' +
'<div class="custom-card-content">' +
'<div class="row p-0 d-flex justify-content-between">' +
'<div class="col-3 text-start '+statcolor[index]+'"> <h5 class="m-0"><i class="bi '+staticon[index]+'"></i></h5> </div>' +
'<div class="col-9 text-end pe-3"> <h2 class="m-0 custom-card-title">'+count[item]+'</h2> </div>' +
'</div>' +
"<hr class='"+statcolor[index]+"'>" +
'<h3 class="custom-card-text m-0 p-0 '+statcolor[index]+'">'+ stattext[index] +'</h3>' +
'</div>' +
'</div>';
});
$("#stats").html(statcontent);
/*
// table
*/
$("#myTable").DataTable().destroy();
$("#table-body").html("");
var data = response['data'];
for (var i = 0; i < data.length; i++) {
colldate = data[i].COLLECTIONDATE.slice(0,10);
colltime = data[i].COLLECTIONDATE.slice(10,16);
if (data[i].PATNUMBER != null) {
patnumber = data[i].PATNUMBER.replace(/^0+/, '');
// patnumber = data[i].PATNUMBER.substr(-16,16);
// patnumber = patnumber.substring(patnumber.length - 10);
} else {
patnumber = ' NULL ';
}
accessnumber = data[i].SP_ACCESSNUMBER;
patname = data[i].NAME;
hon = data[i].HOSTORDERNUMBER;
let testing_test = "";
if (hon[0] === 'X' || hon[0] === 'Z') {
testing_test = "<div class='badge text-bg-warning'>testing tm</div><br>";
} else {
testing_test = "";
}
if (data[i].REFFID != null) {
// patnumber = data[i].PATNUMBER;
reffid = data[i].REFFID;
// patnumber = data[i].PATNUMBER.substr(-16,16);
// patnumber = patnumber.substring(patnumber.length - 10);
} else {
reffid = ' NULL ';
}
tests = data[i].TESTS;
stat = data[i].STATS;
reqstatus = String(data[i].REQSTATUS);
trcolor = '';
if (reqstatus != '1') {
if(stat == 'Pend') {
bgcolor = 'bg-orange';
datafilter = "data-filterrow='0'";
stattext = 'Pending';
} else if(stat == 'PartColl') {
bgcolor = 'bg-peach';
datafilter = "data-filterrow='1'";
stattext = 'Part Collected';
} else if(stat == 'Coll') {
bgcolor = 'bg-pink';
datafilter = "data-filterrow='2'";
stattext = 'Collected';
} else if(stat == 'PartRecv') {
bgcolor = 'bg-soft-blue';
datafilter = "data-filterrow='3'";
stattext = 'Part Received';
} else if(stat == 'Recv') {
bgcolor = 'bg-blue';
datafilter = "data-filterrow='4'";
stattext = 'Received';
} else if(stat == 'Inc') {
bgcolor = 'bg-grey';
datafilter = "data-filterrow='5'";
stattext = 'Incomplete';
} else if(stat == 'PartVal') {
bgcolor = 'bg-soft-green';
datafilter = "data-filterrow='6'";
stattext = 'Part Validated';
} else if(stat == 'Comp') {
bgcolor = 'bg-green';
datafilter = "data-filterrow='7'";
stattext = 'Validated';
}
} else {
trcolor = ' table-danger-custom ';
bgcolor = ' table-danger-custom ';
datafilter = "data-filterrow='8'";
stattext = 'Cancelled';
}
let datarow = "<tr class='align-middle" + trcolor +"'" + datafilter + " >" +
"<td class='text-start'>" + colldate + '<br>'+ colltime +'</td>'+
"<td class='text-start' style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + patnumber + "<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + patname.trim() + "<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td class='text-start' style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + accessnumber +"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>" +
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>" + testing_test + hon +"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>"+
"<td style='cursor: pointer;' ondblclick='copyToClipboard(this)'>"+reffid+"<br><span class='copy-message badge text-bg-success' style='display: none;'>Disalin</span></td>"+
"<td>" + tests + '</td>' +
"<td role='button' class='"+bgcolor+" text-center align-middle pointercol' onclick='viewAccess("+accessnumber+")'>"+stattext+"</td>" +
"<td role='button' class='text-center align-middle' onclick='resultPdfAccess("+accessnumber+ ",event" +")'> <h4 class='p-0 m-0'><i class='bi bi-filetype-pdf'></i></h4> </td>" +
'</tr>';
$("#table-body").append(datarow);
}
$('#myTable').DataTable({
"order": [0, "desc"], // Urutan Tanggal Desc
"pageLength": 50, // Ganti sesuai kebutuhan
"lengthMenu": [50, 75, 100] // Pilihan dropdown entries per halaman
});
// datatable filter
const filterButton = document.querySelectorAll("[data-filtertype]");
const table = document.querySelector("#myTable");
const tr = table.getElementsByTagName("tr");
let activeButton = null;
filterButton.forEach((button) => {
button.addEventListener("click", () => {
const selectedButton = button.getAttribute("data-filtertype");
console.log(selectedButton);
if (activeButton === button) {
button.classList.remove("active", "border", "border-primary", "border-5");
activeButton = null;
for (let i = 1; i < tr.length; i++) {
tr[i].style.display = "";
}
} else {
filterButton.forEach((btn) => btn.classList.remove("active", "border", "border-info", "border-3"));
button.classList.add("active", "border", "border-info", "border-3");
activeButton = button;
for (let i = 1; i < tr.length; i++) {
const filterValue = tr[i].getAttribute("data-filterrow");
if (filterValue === selectedButton) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
});
});
},
error: function(response) { console.log(response.responseJSON); }
});
}
function viewAccess(access) {
let url = '<?=base_url();?>user/dashboard/viewAccess/'+access;
$('.modal-content').load(url, function(){
$('#modal').modal('show');
});
}
function resultPdfAccess(access, event) {
event.stopPropagation(); // Mencegah klik pada <tr> dieksekusi
let url = '<?=base_url();?>printResult/'+access;
window.open(url, '_blank');
}
function copyToClipboard(element) {
let text = element.innerText.trim(); // Ambil teks dari elemen
text = text.replace("Teks sudah disalin", "").trim(); // Hilangkan teks notifikasi sebelumnya
if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(() => {
showCopyMessage(element);
}).catch(err => {
console.error("Gagal menyalin teks: ", err);
});
} else {
// Alternatif jika Clipboard API tidak didukung
let tempInput = document.createElement("textarea");
tempInput.value = text;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
showCopyMessage(element);
}
}
function showCopyMessage(element) {
let message = element.querySelector(".copy-message");
if (message) {
message.style.display = "inline"; // Tampilkan teks notifikasi
// Sembunyikan kembali setelah 2 detik
setTimeout(() => {
message.style.display = "none";
}, 500);
}
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,304 @@
<?php
if(isset($data[0])) {
$row = $data[0];
// if (strlen($patnumber) < 10) {
// $patnumber = str_pad($patnumber, 10, "0", STR_PAD_LEFT);
// }
?>
<div class="modal-header bg-soft-green text-white">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Detail Request </h1>
<button type="button" class="btn-close text-white" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body" style='background-color:#F4F6FF'>
<div class="row">
<div class="col">
<table class="table table-sm table-borderless">
<tr>
<th width='18%'>Access Number</th>
<th>:</th>
<td width='31%'><?=$accessnumber;?></td>
<th>Visit Description</th>
<th>:</th>
<td><?=$visit_description;?></td>
</tr>
<tr>
<th>Patient Number</th>
<th>:</th>
<td><?=$patnumber;?></td>
<th width='18%'>Payer Name</th>
<th>:</th>
<td width='31%'><?=$payer_name;?></td>
</tr>
<tr>
<th>Patient Name</th>
<th>:</th>
<td><?=$patient_fullname;?></td>
<th>Treating Doctor</th>
<th>:</th>
<td><?=$treating_doctor;?></td>
</tr>
</table>
</div>
</div>
<div class='row'>
<div class="col-12">
<div class="card bg-white">
<div class="card-body">
<div class="card-title"><h3>Sample List</h3></div>
<table class='table'>
<tr> <th class='text-center'>Coll.</th> <th class='text-center'>Recv.</th> <th>Sample Name</th> <th>Action</th> <th>Comment</th> </tr>
<tr>
<td></td> <td></td> <td>All</td>
<td>
<button type='button' class='btn btn-dark m-0 px-2 py-1' onclick="printAllLabel(<?=$accessnumber;?>, <?=$usercityid;?>)"> <h6 class='p-0 m-0'><i class='bi bi-printer'></i></h6> </button>
<button type='button' class='btn btn-success m-0 px-2 py-1' onclick='collectAll(<?=$accessnumber;?>)'><h6 class='p-0 m-0'>Coll.</h6></button>
<!-- <button class='badge bg-black text-white m-0 px-2 py-1' onclick='uncollectAll(<?=$accessnumber;?>)'>un-collect</button> -->
<!-- <button type='button' class='btn btn-primary m-0 px-2 py-1' onclick='unreceiveAll(<?=$accessnumber;?>)'><h6 class='p-0 m-0'>Un-Rec.</h6></button> -->
</td>
</tr>
<tr>
<td></td> <td></td> <td>Collection</td>
<td><button type='button' class='btn btn-dark m-0 px-2 py-1' onclick="printCollectionLabel(<?=$accessnumber;?>, <?=$usercityid;?>)"><h6 class='p-0 m-0'> <i class='bi bi-printer'></i></h6></button></td>
</tr>
<?php
foreach($data as $row) {
$sampletype = $row['SAMPLETYPE'];
$sampletext = $row['SHORTTEXT'];
if ($sampletype == "200") {
$sampletext = "Serum Kimia";
} else if ($sampletype == '250') {
$sampletext = "Serum Imun";
}
$tubestatus = $row['TUBESTATUS'];
$collstatus = $row['COLLSTATUS'];
$comment = $row['TUBECOMMENT'];
echo "\r\n <tr>";
if($collstatus==1) {
echo " <td class='text-center'><input type='checkbox' class='form-check-input' id='coll$sampletype' checked disabled></td>";
} else {
echo " <td class='text-center'><input type='checkbox' class='form-check-input' id='coll$sampletype' disabled></td>";
}
if($tubestatus==4) {
echo "<td class='text-center'><input type='checkbox' class='form-check-input' id='recv$sampletype' checked disabled></td>";
} else {
echo "<td class='text-center'><input type='checkbox' class='form-check-input' id='recv$sampletype' disabled></td>";
}
echo "<td>$sampletext ($sampletype)</td>";
echo "<td>
<button type='button' class='btn btn-dark m-0 px-2 py-1' " . "onclick='printSingleLabel($accessnumber, $sampletype, $usercityid)'" . "><h6 class='p-0 m-0'><i class='bi bi-printer'></i></h6></button>
<button type='button' class='btn btn-success m-0 px-2 py-1' onclick='collect($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Coll.</h6></button>
<button type='button' class='btn btn-warning m-0 px-2 py-1' onclick='uncollect($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Un-Coll.</h6></button>
<button type='button' class='btn btn-primary m-0 px-2 py-1' onclick='unreceive($sampletype, $accessnumber)'><h6 class='p-0 m-0'>Un-Rec.</h6></button>
</td> ";
echo "<td id='comment$sampletype'>$comment <h6 class='p-0 m-0'><i class='bi bi-pencil-square' role='button' onclick='comment($sampletype, $accessnumber, \"$sampletext\", \"$comment\")'></i></h6></td>";
echo " </tr>";
}
?>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
function printCollectionLabel(access, usercityid){
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/collection/'+access.toString();
} else {
url = '<?=base_url();?>printLabel/collection/'+access.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function printSingleLabel(access, sample, usercityid) {
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/single/'+access.toString()+'/'+sample.toString();
} else {
url = '<?=base_url();?>printLabel/single/'+access.toString()+'/'+sample.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function printAllLabel(access, usercityid) {
let url;
if (usercityid == 2) {
url = '<?=base_url();?>printLabelSby/all/'+access.toString();
} else {
url = '<?=base_url();?>printLabel/all/'+access.toString();
}
console.log(url);
fetch(url)
.then(response => response.json())
.then(data => {
if (data['status']) {
console.log(data['message']);
} else {
console.log(data['message']+"\n"+data['error']);
message = data['message']+"\n"+data['error'];
alert(message);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function collect(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/collect/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#coll"+sample).prop("checked", true);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function collectAll(access) {
const url = '<?=base_url();?>tubes/collectAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="coll"]').prop('checked', true);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function uncollect(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/uncollect/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#coll"+sample).prop("checked", false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function uncollectAll(access) {
const url = '<?=base_url();?>tubes/uncollectAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="coll"]').prop('checked', false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function unreceive(sample, access) {
sample = sample.toString().padStart(3,'0');
const url = '<?=base_url();?>tubes/unreceive/'+access+'/'+sample;
fetch(url)
.then(data => {
//console.log(data);
//$("#recv"+sample).prop("checked", false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function unreceiveAll(access) {
const url = '<?=base_url();?>tubes/unreceiveAll/'+access;
fetch(url)
.then(data => {
//console.log(data);
//$('input[id^="recv"]').prop('checked', false);
viewAccess(access);
index();
})
.catch(error => { console.error('Error:',error); });
}
function comment(sample, access, sampletext, comments) {
const url = '<?=base_url();?>tubes/comment/'+access+'/'+sample;
let comment = prompt('Comment for sample '+sampletext, comments);
//$('#comment'+sample).html(comment +"<i class='bi bi-pencil-square' onclick='comment("+ sample +", "+ access +', "'+sampletext+'", "'+comment+'")\'></i>');
fetch(url, {
method: "POST",
body: JSON.stringify({ comment : comment }),
headers: { "Content-type": "application/json; charset=UTF-8" }
}).then(data => {
//console.log(data);
viewAccess(access);
})
.catch(error => { console.error('Error:',error); });
}
</script>
<?php
} else {
?>
<div class="modal-header bg-black text-white">
<h1 class="modal-title fs-5" id="exampleModalToggleLabel">Detail Request </h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" ></button>
</div>
<div class="modal-body">
<h3>Data not found</h3>
</div>
<?php
}
?>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Analis Dashboard</title>
<link rel="stylesheet" href="<?=base_url();?>assets/css/icons/font/bootstrap-icons.min.css">
<link href="<?=base_url();?>assets/css/styles.css" rel="stylesheet" />
<link href="<?=base_url();?>assets/select2/select2.min.css" rel="stylesheet" />
<link href="<?=base_url();?>assets/flatpickr/flatpickr.min.css" rel="stylesheet" />
<style>
.sb-form {
min-height:calc(100vh);
}
</style>
</head>
<!-- <body class="sb-nav-fixed sb-sidenav-toggled"> -->
<body class='sb-form'>
<main>
<div class="container-fluid px-2 py-2">
<?= $this->renderSection('content'); ?>
</div>
</main>
<script src="<?=base_url();?>assets/jquery-3.7.1.min.js"></script>
<script src="<?=base_url();?>assets/js/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>assets/datatables/datatables.min.js"></script>
<script src="<?=base_url();?>assets/select2/select2.min.js"></script>
<script src="<?=base_url();?>assets/flatpickr/flatpickr.min.js"></script>
<script src="<?=base_url();?>assets/js/scripts.js"></script>
<?= $this->renderSection('script'); ?>
</body>
</html>

View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Analis Dashboard</title>
<link rel="stylesheet" href="<?=base_url();?>assets/css/icons/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="<?=base_url();?>assets/datatables/datatables.min.css">
<link href="<?=base_url();?>assets/css/styles.css" rel="stylesheet" />
</head>
<!-- <body class="sb-nav-fixed sb-sidenav-toggled"> -->
<body class="sb-nav-fixed">
<?= $this->include('user/layout/topbar'); ?>
<div id="layoutSidenav">
<?= $this->include('user/layout/sidebar'); ?>
<div id="layoutSidenav_content">
<main>
<div class="container-fluid px-2 py-2">
<?php
if(isset($_SESSION['alertmsg'])) {
?>
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<?=$_SESSION['alertmsg'];?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php
}
?>
<?= $this->renderSection('content'); ?>
</div>
</main>
<footer class="py-3 bg-light mt-auto">
<div class="container-fluid px-4">
<div class="d-flex align-items-center justify-content-between small">
<div class="text-muted ms-auto ">Copyright &copy; 4SKAI 2024</div>
</div>
</div>
</footer>
</div>
</div>
<script src="<?=base_url();?>assets/jquery-3.6.0.min.js"></script>
<script src="<?=base_url();?>assets/js/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>assets/datatables/datatables.min.js"></script>
<script src="<?=base_url();?>assets/js/scripts.js"></script>
<?= $this->renderSection('script'); ?>
</body>
</html>

View File

@ -0,0 +1,25 @@
<div id="layoutSidenav_nav">
<nav class="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<div class="sb-sidenav-menu-heading">Main</div>
<a class="nav-link" href="<?=base_url();?>user/"><div class="sb-nav-link-icon"><i class="bi bi-speedometer"></i></div>Dashboard</a>
<a class="nav-link" href="<?=base_url();?>changePass/"><div class="sb-nav-link-icon"><i class="bi bi-key"></i></div>Change Password</a>
<div class="sb-sidenav-menu-heading">HIS</div>
<a class="nav-link" href="<?=base_url();?>user/patients/"><div class="sb-nav-link-icon"><i class="bi bi-person-fill"></i></div>Patient List</a>
<a class="nav-link" href="<?=base_url();?>user/orders/"><div class="sb-nav-link-icon"><i class="bi bi-clipboard-pulse"></i></div>Order List</a>
<a class="nav-link" href="#" onclick='createOrder()'><div class="sb-nav-link-icon"><i class="bi bi-clipboard-plus"></i></div>Create Order</a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">Logged in as: <b>Analyst User</b></div>
</div>
</nav>
</div>
<script>
function createOrder() {
window.open("<?php echo base_url();echo $_SESSION['userrole']?>/orders/create",
'_blank', "width=1200,height=700,location=no,toolbar=no,menubar=no"
);
}
</script>

View File

@ -0,0 +1,23 @@
<nav class="sb-topnav navbar navbar-expand navbar-light bg-light shadow-sm text-luxury">
<a class="navbar-brand ps-3 d-none d-md-block" href="#"><img src='<?=base_url();?>assets/img/logo.png' width='30' /> CMOD</a>
<button class="btn btn-link me-2" id="sidebarToggle"><i class="bi bi-list "></i></button>
<div class="ms-auto">
<ul class="navbar-nav ms-md-0 me-3 me-lg-4">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i>
<?=$_SESSION['username'];?>
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#!">Profile</a></li>
<li><a class="dropdown-item" href="#!">Change Password</a></li>
<li><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item" href="<?=base_url();?>auth/logout">Logout</a></li>
</ul>
</li>
</ul>
</div>
</nav>

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" type="image/png" sizes="16x16" href="<?=base_url();?>/assets/favicon.png">
<title>Summit CRM</title>
<link href="<?=base_url();?>/assets/style.css" rel="stylesheet">
<link href="<?=base_url();?>/assets/font-awesome-640/css/all.min.css" rel="stylesheet">
<?= $this->renderSection('head'); ?>
</head>
<body class="skin-megna-dark fixed-layout">
<div class="preloader">
<div class="loader">
<div class="loader__figure"></div>
<p class="loader__label">Summit-CRM</p>
</div>
</div>
<div>
<?= $this->renderSection('content'); ?>
</div>
<script src="<?=base_url();?>/assets/jquery/jquery.min.js"></script>
<script src="<?=base_url();?>/assets/bootstrap.bundle.min.js"></script>
<script src="<?=base_url();?>/assets/app.js"></script>
<?= $this->renderSection('script'); ?>
<script>
$(document).ready(function() {
$('.select2').select2({
dropdownAutoWidth : true,
width: '100%',
});
});
</script>
</body>
</html>

BIN
cmod.7z

Binary file not shown.

BIN
cmod.bak

Binary file not shown.

View File

@ -1,56 +0,0 @@
USE [cmod]
GO
/****** Object: Table [dbo].[CM_TUBES] Script Date: 19/11/2024 16:26:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[CM_TUBES](
[TUBEID] [int] IDENTITY(1,1) NOT NULL,
[ACCESSNUMBER] [varchar](10) NULL,
[SAMPLETYPE] [varchar](10) NULL,
[COLLECTIONDATE] [datetime] NULL,
[COLL_USERID] [varchar](25) NULL,
[COLLSTATUS] [varchar](1) NULL,
[CREATEDATE] [datetime] NULL,
[TUBECOMMENT] [varchar](150) NULL,
CONSTRAINT [PK_TUBES] PRIMARY KEY CLUSTERED
(
[TUBEID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[CM_USERROLES] Script Date: 19/11/2024 16:26:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[CM_USERROLES](
[USERROLEID] [int] IDENTITY(1,1) NOT NULL,
[USERROLECODE] [varchar](5) NOT NULL,
[USERROLENAME] [varchar](50) NULL,
[CREATEDATE] [datetime] NULL,
CONSTRAINT [PK_CM_USERROLES] PRIMARY KEY CLUSTERED
(
[USERROLEID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[CM_USERS] Script Date: 19/11/2024 16:26:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[CM_USERS](
[USERID] [varchar](25) NOT NULL,
[PASSWORD] [varchar](100) NULL,
[USERROLEID] [int] NULL,
[CREATEDATE] [datetime] NULL,
CONSTRAINT [PK_USERS] PRIMARY KEY CLUSTERED
(
[USERID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[CM_TUBES] ADD CONSTRAINT [DF_TUBES_STATUS] DEFAULT ((0)) FOR [COLLSTATUS]
GO

66
composer.json Normal file
View File

@ -0,0 +1,66 @@
{
"name": "codeigniter4/framework",
"description": "The CodeIgniter framework v4",
"license": "MIT",
"type": "project",
"homepage": "https://codeigniter.com",
"support": {
"forum": "https://forum.codeigniter.com/",
"source": "https://github.com/codeigniter4/CodeIgniter4",
"slack": "https://codeigniterchat.slack.com"
},
"require": {
"php": "^8.1",
"ext-intl": "*",
"ext-mbstring": "*",
"laminas/laminas-escaper": "^2.13",
"psr/log": "^3.0"
},
"require-dev": {
"codeigniter/coding-standard": "^1.7",
"fakerphp/faker": "^1.9",
"friendsofphp/php-cs-fixer": "^3.47.1",
"kint-php/kint": "^5.0.4",
"mikey179/vfsstream": "^1.6",
"nexusphp/cs-config": "^3.6",
"phpunit/phpunit": "^10.5.16 || ^11.2",
"predis/predis": "^1.1 || ^2.0"
},
"suggest": {
"ext-curl": "If you use CURLRequest class",
"ext-dom": "If you use TestResponse",
"ext-exif": "If you run Image class tests",
"ext-fileinfo": "Improves mime type detection for files",
"ext-gd": "If you use Image class GDHandler",
"ext-imagick": "If you use Image class ImageMagickHandler",
"ext-libxml": "If you use TestResponse",
"ext-memcache": "If you use Cache class MemcachedHandler with Memcache",
"ext-memcached": "If you use Cache class MemcachedHandler with Memcached",
"ext-mysqli": "If you use MySQL",
"ext-oci8": "If you use Oracle Database",
"ext-pgsql": "If you use PostgreSQL",
"ext-readline": "Improves CLI::input() usability",
"ext-redis": "If you use Cache class RedisHandler",
"ext-simplexml": "If you format XML",
"ext-sodium": "If you use Encryption SodiumHandler",
"ext-sqlite3": "If you use SQLite3",
"ext-sqlsrv": "If you use SQL Server",
"ext-xdebug": "If you use CIUnitTestCase::assertHeaderEmitted()"
},
"autoload": {
"psr-4": {
"CodeIgniter\\": "system/"
},
"exclude-from-classmap": [
"**/Database/Migrations/**"
]
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"scripts": {
"test": "phpunit"
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,58 @@
/*
Template Name: Admin Template
Author: Wrappixel
File: scss
*/
@import url(https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700);
/*Theme Colors*/
/**
* Table Of Content
*
* 1. Color system
* 2. Options
* 3. Body
* 4. Typography
* 5. Breadcrumbs
* 6. Cards
* 7. Dropdowns
* 8. Buttons
* 9. Typography
* 10. Progress bars
* 11. Tables
* 12. Forms
* 14. Component
*/
/*******************
Login register and recover password Page
******************/
.login-register {
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
height: 100%;
width: 100%;
padding: 10% 0;
position: fixed; }
.login-box {
width: 400px;
margin: 0 auto; }
.login-box .footer {
width: 100%;
left: 0px;
right: 0px; }
.login-box .social {
display: block;
margin-bottom: 30px; }
#recoverform {
display: none; }
.login-sidebar {
padding: 0px;
margin-top: 0px; }
.login-sidebar .login-box {
right: 0px;
position: absolute;
height: 100%; }

View File

@ -0,0 +1,216 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
button,hr,input{overflow:visible}progress,sub,sup{vertical-align:baseline}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}details,main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}
/*html,pre,th,table { font-family:'Courier New', Courier, monospace; font-size:7.8pt; margin:0;}*/
html,pre,th,table { font-family: Arial; font-size:7.8pt; margin:0;}
body {
background-color: rgb(17, 16, 16);
}
.red_font {
color: red;
}
#page {
background: rgb(255, 255, 255);
/* background-image: url('../img/bali_bcg.jpg'); */
background-size: 102%; /* Menutupi seluruh layar */
background-position: center; /* Posisikan di tengah */
background-repeat: no-repeat; /* Jangan ulangi gambar */
height: 100vh; /* Gunakan tinggi 100% dari viewport */
display: block;
margin: 0 auto;
margin-bottom: 1px;
/* padding-top: 30px ; */
page-break-after:always;
width: 210mm;
height: 297mm;
}
.table-justify {
text-align: justify;
}
#dinfo {
margin-top: 118px;
background-size: 100% auto;
background-repeat: no-repeat;
}
#dresult {
margin: 0;
padding: 0;
/* height: 18.47cm; */
height: 19cm;
}
.result {
/* table-layout:fixed; */
/* border:solid 1px black; */
width:95%;
}
table {
align-items: center;
margin:0;
padding: 0;
width: 95%;
border-collapse:collapse;
/* border: 1px solid black; */
}
.t_center {
margin-left: auto;
margin-right: auto;
}
.t_right {
margin-left: auto;
}
th,td {
/* padding-left: 1rem; */
padding-top: 3.5px;
padding-bottom: 3.5px ;
line-height:1.5;
border: 1px solid rgb(0, 0, 0);
}
th.khusus-kanan-h {
border-right: none;
}
th.khusus-kiri-h {
border-left: none;
}
td.khusus-kanan-d {
border-right: none;
}
td.khusus-kiri-d {
border-left: none;
}
th.left-pad, td.left-pad {
padding-left: 0.5rem;
}
td.right-pad {
padding-right: 0.5rem;
text-align: right;
}
td.center-pad {
text-align: center;
}
.result th,td {
line-height: 1.1 ;
}
.t_background {
background-color: #f2f2f2;
}
.padmaColor {
/* background-color: rgba(190, 160, 160, 0.192); */
background-color: #f2f2f2;
/* line-height: 1.5; */
/* font-size: 1.2em; */
}
.info { border:solid 1px black; margin:-1cm 0 0 8.5cm; width:11cm;}
.flag { float:right; top:0; font-weight:bold; }
.textC { font-size:7pt; }
table.information {
border:1px solid rgba(0, 0, 0, 0.192);
/* border-collapse:collapse; */
}
table.result tr{
border:solid 1px rgba(0, 0, 0, 0.055);
}
/* table.result tr:nth-child(odd) {
background-color: #f2f2f2;
border:solid 1px rgba(0, 0, 0, 0.61);
} */
table.result tr {
/* background-color: #f2f2f2; */
/* border:solid 1px #b6b1b1; */
}
.chapter {
/* font-size: 5em; */
}
tr.chapter td {
border: none;
}
#notes { margin: 5mm 0 0 10mm; }
.table_collection tr td{
/* font-size: 2em; */
padding: 1px;
/* border:solid 1px black; */
border: none;
}
#footer {
/* background-color: rgb(201, 230, 192); */
/* float:left; */
margin:0;
padding: 0;
height:3.75cm;
}
.table_footer {
width: 95%;
/* border:solid 1px black; */
border-collapse:collapse;
}
.table_footer tr td {
padding: 2px;
border: none;
/* border:solid 1px black; */
}
.table_footer tr td.margin_right {
padding-right: 80px;
text-align: right;
/* background-color: aqua; */
}
.table_footer tr td.margin_right_img_bali {
padding-right: 55px;
text-align: right;
/* background-color: aqua; */
}
.table_footer tr td.margin_right_sby_img {
padding-right: 5px;
text-align: right;
/* background-color: aqua; */
}
.table_footer tr td.margin_right_sby {
padding-right: 50px;
text-align: right;
/* background-color: aqua; */
}
.text-left {
text-align: left;
}
.img { width:200mm; margin-left:0.5cm }
#ttd_p {
width: 25%;
}
#ttd_k {
width: 23%;
}
@media print {
@page { margin:0; size:210mm 297mm; }
}

View File

@ -0,0 +1,152 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
button,hr,input{overflow:visible}progress,sub,sup{vertical-align:baseline}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}details,main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}
/*html,pre,th,table { font-family:'Courier New', Courier, monospace; font-size:7.8pt; margin:0;}*/
html,pre,th,table { font-family: Arial; font-size:7.8pt; margin:0;}
body {
background-color: rgb(17, 16, 16);
}
.red_font {
color: red;
}
#page {
background: rgb(255, 255, 255);
/* background-image: url('../img/bali_bcg.jpg'); */
background-size: 102%; /* Menutupi seluruh layar */
background-position: center; /* Posisikan di tengah */
background-repeat: no-repeat; /* Jangan ulangi gambar */
height: 100vh; /* Gunakan tinggi 100% dari viewport */
display: block;
margin: 0 auto;
margin-bottom: 1px;
/* padding-top: 30px ; */
page-break-after:always;
width: 210mm;
height: 297mm;
}
.table-justify {
text-align: justify;
}
#dinfo {
margin-top: 140px;
background-size: 100% auto;
background-repeat: no-repeat;
}
#dresult {
margin: 0;
padding: 0;
height: 18.47cm;
}
.result {
table-layout:fixed;
border:solid 1px black;
width:95%;
}
table {
align-items: center;
margin:0;
padding: 0;
width: 95%;
border-collapse:collapse;
/* border: 1px solid black; */
}
.t_center {
margin-left: auto;
margin-right: auto;
}
th,td {
padding-left: 1rem;
padding-top: 4px ;
padding-bottom: 2px ;
line-height:1.5;
/* border: 1px solid black; */
}
.result th,td {
line-height: 1.1 ;
}
.t_background {
background-color: #f2f2f2;
}
.padmaColor {
/* background-color: rgba(190, 160, 160, 0.192); */
background-color: #f2f2f2;
/* line-height: 1.5; */
font-size: 1.2em;
}
.info { border:solid 1px black; margin:-1cm 0 0 8.5cm; width:11cm;}
.flag { float:right; top:0; font-weight:bold; }
.textC { font-size:7pt; }
table.information {
border:1px solid rgba(0, 0, 0, 0.192);
/* border-collapse:collapse; */
}
table.result tr{
border:solid 1px rgba(0, 0, 0, 0.055);
}
/* table.result tr:nth-child(odd) {
background-color: #f2f2f2;
border:solid 1px rgba(0, 0, 0, 0.61);
} */
table.result tr {
/* background-color: #f2f2f2; */
border:solid 1px #b6b1b1;
}
.chapter {
/* font-size: 5em; */
}
tr.chapter td {
border: none;
}
#notes { margin: 5mm 0 0 10mm; }
.table_collection tr{
/* font-size: 2em; */
/* border:solid 1px black; */
}
#footer {
/* background-color: rgb(201, 230, 192); */
/* float:left; */
margin:0;
padding: 0;
height:3.75cm;
}
.table_footer {
width: 95%;
/* border:solid 1px black; */
border-collapse:collapse;
}
.table_footer tr td {
padding: 4px;
/* border:solid 1px black; */
}
.img { width:200mm; margin-left:0.5cm }
#ttd_p {
width: 25%;
}
@media print {
@page { margin:0; size:210mm 297mm; }
}

View File

@ -1911,6 +1911,20 @@ progress {
border-color: var(--bs-table-border-color);
}
.table-danger-custom {
--bs-table-color: #000;
--bs-table-bg: #e72838d0;
--bs-table-border-color: #dfc2c4;
--bs-table-striped-bg: #eccccf;
--bs-table-striped-color: #000;
--bs-table-active-bg: #dfc2c4;
--bs-table-active-color: #000;
--bs-table-hover-bg: #e5c7ca;
--bs-table-hover-color: #000;
color: var(--bs-table-color);
border-color: var(--bs-table-border-color);
}
.table-light {
--bs-table-color: #000;
--bs-table-bg: #f8f9fa;
@ -8345,6 +8359,32 @@ textarea.form-control-lg {
background-color: rgba(127, 181, 110, var(--bs-bg-opacity)) !important;
color: white;
}
.bg-custom-green {
--bs-bg-opacity: 1;
background-color: rgba(76, 178, 105, var(--bs-bg-opacity)) !important;
color: white;
}
.bg-custom-2-green {
--bs-bg-opacity: 1;
background-color: rgba(39, 92, 54, var(--bs-bg-opacity)) !important;
color: white;
}
.btn-success-2 {
--bs-btn-color: #fff;
--bs-btn-bg: #4cb269;
--bs-btn-border-color: #4cb269;
--bs-btn-hover-color: #fff;
--bs-btn-hover-bg: #157347;
--bs-btn-hover-border-color: #146c43;
--bs-btn-focus-shadow-rgb: 60, 153, 110;
--bs-btn-active-color: #fff;
--bs-btn-active-bg: #146c43;
--bs-btn-active-border-color: #13653f;
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
--bs-btn-disabled-color: #fff;
--bs-btn-disabled-bg: #198754;
--bs-btn-disabled-border-color: #198754;
}
.bg-green {
--bs-bg-opacity: 1;
background-color: rgba(52, 102, 36, var(--bs-bg-opacity)) !important;
@ -11081,7 +11121,7 @@ body {
background-color: #F4F6FF;
}
@media (min-width: 992px) {
@media (min-width: 1300px) {
#layoutSidenav #layoutSidenav_nav {
transform: translateX(0);
}
@ -11099,6 +11139,7 @@ body {
display: none;
}
}
.sb-nav-fixed .sb-topnav {
z-index: 1039;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

2
public/assets/jquery-3.7.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More