Compare commits
166 Commits
f2f1aed4b2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3c743aeea | ||
|
|
43342bf361 | ||
|
|
cf648ac9ba | ||
|
|
b7c752df84 | ||
|
|
0cf019ddf7 | ||
|
|
5e1371a248 | ||
|
|
b713289b82 | ||
|
|
8e72a9f067 | ||
|
|
cb45fabe1c | ||
|
|
5695a40fe1 | ||
|
|
b653f0e987 | ||
|
|
4a9406cd28 | ||
|
|
1601ec6573 | ||
|
|
567f85a0b9 | ||
|
|
9eb92eb340 | ||
|
|
ebd2217921 | ||
|
|
17acf294ba | ||
|
|
b08ddb68b1 | ||
|
|
e8f598c98d | ||
|
|
d0547e38bb | ||
|
|
83045fac9a | ||
|
|
fac5dcb34d | ||
|
|
0550497a16 | ||
|
|
667d8d2a1d | ||
|
|
6a1bee3656 | ||
|
|
c80bd8b6c1 | ||
|
|
917115684c | ||
|
|
e3be8d6b14 | ||
|
|
1b8e00b57e | ||
|
|
d57bbaec38 | ||
|
|
d04d8add35 | ||
|
|
414a3765f7 | ||
|
|
b18dfa3495 | ||
|
|
39f4626cdf | ||
|
|
e5d5dfd48a | ||
|
|
cd795497a7 | ||
|
|
e1b91403ed | ||
|
|
ce2068d24a | ||
|
|
f1bbb2a932 | ||
|
|
520c77484b | ||
|
|
e3c9909c84 | ||
|
|
11860743b8 | ||
|
|
77a595eba4 | ||
|
|
6858814948 | ||
|
|
0e2df4612a | ||
|
|
98748620dd | ||
|
|
1bdb54d1c2 | ||
|
|
f8d487079b | ||
|
|
83bd46d521 | ||
|
|
49df769c58 | ||
|
|
9e68c1cedd | ||
|
|
16316aaa31 | ||
|
|
a90b0f96c7 | ||
|
|
ece137df06 | ||
|
|
2692c98ef2 | ||
|
|
7c8b1ad36b | ||
|
|
c1f874b96b | ||
|
|
e73fccee17 | ||
|
|
2978ecc93d | ||
|
|
9430b00ee6 | ||
|
|
0e590f5959 | ||
|
|
710dbaaec1 | ||
|
|
1e87def6a7 | ||
|
|
c78f53fc18 | ||
|
|
67bb072e0d | ||
|
|
655757599a | ||
|
|
ee3ec98f44 | ||
|
|
b45f284784 | ||
|
|
beb11cc40f | ||
|
|
2a936217c7 | ||
|
|
f39b28361e | ||
|
|
270f71f5ea | ||
|
|
25f17896d4 | ||
|
|
71d64c6637 | ||
|
|
eed0c8fe0d | ||
|
|
beac903397 | ||
|
|
16fcf81c00 | ||
|
|
e456ce6354 | ||
|
|
45e668def3 | ||
|
|
a599f15ec2 | ||
|
|
ad632ec17c | ||
|
|
5e3695a54b | ||
|
|
dc586c63f4 | ||
|
|
ae28375cc3 | ||
|
|
e7894e869d | ||
|
|
5d9c170bf4 | ||
|
|
eb4af1c67c | ||
|
|
8282acadd5 | ||
|
|
01994365d4 | ||
|
|
9dd4afed4a | ||
|
|
f1801157c2 | ||
|
|
0c9c67d30f | ||
|
|
32131fdaad | ||
|
|
473b90b697 | ||
|
|
82c3ea5ff0 | ||
|
|
e301eedbeb | ||
|
|
a5d7174b68 | ||
|
|
0f54702aa7 | ||
|
|
04591d6c32 | ||
|
|
48c61fcfd7 | ||
|
|
e37512624c | ||
|
|
de1fb927de | ||
|
|
e3f51591a6 | ||
|
|
085a2dc14a | ||
|
|
686db5ed43 | ||
|
|
6c7aaf0dd0 | ||
|
|
934a779770 | ||
|
|
fcd125a252 | ||
|
|
24c5d2d94f | ||
|
|
910e1cd08a | ||
|
|
1cce2b52dc | ||
|
|
bff1943054 | ||
|
|
77c00e0dd0 | ||
|
|
c4e590d153 | ||
|
|
e797013148 | ||
|
|
212e27ff72 | ||
|
|
7e3cd75ce5 | ||
|
|
edf60f5574 | ||
|
|
3138c7f508 | ||
|
|
0e408f2cf4 | ||
|
|
1863697315 | ||
|
|
2f162c3613 | ||
|
|
dcdfb0e7cc | ||
|
|
d5b358003f | ||
|
|
943f037ad9 | ||
|
|
9eba521e2f | ||
|
|
ca1327a6c2 | ||
|
|
33fe960269 | ||
|
|
23c5c7c67c | ||
|
|
bd0790b768 | ||
|
|
c2c9def40d | ||
|
|
87c621a5fc | ||
|
|
9d224ffabf | ||
|
|
6e0a706b34 | ||
|
|
1830710859 | ||
|
|
68cda67c56 | ||
|
|
065e3ebb34 | ||
|
|
8c49b3356f | ||
|
|
6ec3f338ee | ||
|
|
620c8b051d | ||
|
|
d4ecd7f06d | ||
|
|
a88360b1b1 | ||
|
|
5c9daffb38 | ||
|
|
d7930d5dbc | ||
|
|
34d90c95b6 | ||
|
|
09c5f70284 | ||
|
|
90c156e51a | ||
|
|
de7444d5d5 | ||
|
|
c1b9891727 | ||
|
|
18501d07b8 | ||
|
|
f744a25be8 | ||
|
|
f667050200 | ||
|
|
ab7ed1c667 | ||
|
|
a2d69d1618 | ||
|
|
5350ab51cc | ||
|
|
82640c3d3b | ||
|
|
e990609523 | ||
|
|
6c0394aea3 | ||
|
|
17a788baac | ||
|
|
c63afddaa0 | ||
|
|
2d7151b154 | ||
|
|
c410d7bbd9 | ||
|
|
cf8ef0e590 | ||
|
|
a3f9e04787 | ||
|
|
84e0d60d23 | ||
|
|
fd9511171b |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,6 @@
|
||||
.DS_Store
|
||||
.env
|
||||
# Added by code-review-graph
|
||||
.code-review-graph/
|
||||
build/
|
||||
services/ibl_merge_report_service/ibl-merge-report-service
|
||||
|
||||
68
AGENTS.md
68
AGENTS.md
@@ -10,6 +10,74 @@
|
||||
- Before every `commit` and `push`, always check first whether local branch needs to pull/rebase from remote.
|
||||
- To upload to IBL, run `bash scripts/upload_ibl_committed_files.sh`. Only run this when the user explicitly asks to upload to IBL. Do not run automatically after commit/push.
|
||||
|
||||
## PDP Encryption & BIRT Report
|
||||
|
||||
UU PDP No. 27/2022 mengharuskan enkripsi PII pasien. `M_PatientDOB`, `M_PatientName`, dll
|
||||
di-mask NULL di kolom plain, nilai asli ada di kolom `_enc` (AES-256-GCM).
|
||||
|
||||
### Pola wajib: PHP Proxy Stream
|
||||
|
||||
BIRT membaca dari tabel `patient_print_cache`. Cache harus di-populate PHP sebelum BIRT
|
||||
dipanggil, dan dihapus segera setelah PDF di-stream.
|
||||
|
||||
```
|
||||
FE → PHP proxy → populate cache → fetch BIRT → delete cache → stream PDF
|
||||
```
|
||||
|
||||
**Jangan pernah** buat FE langsung build URL `/birt/frameset?...` lalu set ke iframe/window.open
|
||||
tanpa lewat PHP proxy — cache tidak akan pernah terisi, data pasien kosong di report.
|
||||
|
||||
### Endpoint proxy yang tersedia
|
||||
|
||||
```
|
||||
GET /one-api-lab/tools/birt_proxy/stream_by_code
|
||||
Params: token, report_code (print_transaction code), PT_OrderHeaderID
|
||||
Return: binary PDF
|
||||
```
|
||||
|
||||
Untuk BE yang perlu return URL ke FE, gunakan `Reporturl` library:
|
||||
```php
|
||||
$this->load->library('reporturl');
|
||||
[$ok, $url] = $this->reporturl->get_report_url_by_code($report_code, [
|
||||
'PT_OrderHeaderID' => $order_id,
|
||||
'PUsername' => $username,
|
||||
]);
|
||||
// $url sudah mengarah ke stream_by_code — tidak perlu populate/delete cache manual
|
||||
```
|
||||
|
||||
### Daftar print_transaction code
|
||||
|
||||
| Group | Print siap | Print belum siap | Email |
|
||||
|-------|-----------|-----------------|-------|
|
||||
| LAB | `LAB-RESULT-P-01` | `LAB-RESULT-NP-01` | `LAB-RESULT-P-02` |
|
||||
| LAB (Inggris) | `LABEN-RESULT-P-01` | `LABEN-RESULT-NP-01` | `LABEN-RESULT-P-02` |
|
||||
| Mikro (terlampir) | `MIKRO-RESULT-P-01` | `MIKRO-RESULT-NP-01` | `MIKRO-RESULT-P-02` |
|
||||
| Mikro (tidak terlampir) | `LAB-RESULT-P-01` | `LAB-RESULT-NP-01` | `LAB-RESULT-P-02` |
|
||||
| Mikro (Inggris) | `MIKROEN-RESULT-P-01` | `MIKROEN-RESULT-NP-01` | `MIKROEN-RESULT-P-02` |
|
||||
| FNA | `FNA-RESULT-P-01` | `FNA-RESULT-NP-01` | `FNA-RESULT-P-02` |
|
||||
| Patologi Anatomi | `PA-RESULT-P-01` | `PA-RESULT-NP-01` | `PA-RESULT-P-02` |
|
||||
| Papsmear | `PAP-RESULT-P-01` | `PAP-RESULT-NP-01` | `PAP-RESULT-P-02` |
|
||||
| Pap Smear LCP | `PAPLCP-RESULT-P-01` | `PAPLCP-RESULT-NP-01` | `PAPLCP-RESULT-P-02` |
|
||||
| Pap Smear LCP (Inggris) | `PAPLEN-RESULT-P-01` | `PAPLEN-RESULT-NP-01` | `PAPLEN-RESULT-P-02` |
|
||||
| Preparasi Sperma | `PS-RESULT-P-01` | `PS-RESULT-NP-01` | `PS-RESULT-P-02` |
|
||||
| DFI | `DFI-RESULT-P-01` | `DFI-RESULT-NP-01` | `DFI-RESULT-P-02` |
|
||||
| Cytologi | `CT-RESULT-P-01` | `CT-RESULT-NP-01` | `CT-RESULT-P-02` |
|
||||
|
||||
### Deteksi modul yang belum difix
|
||||
|
||||
Cari pola ini di FE:
|
||||
```
|
||||
/birt/frameset?__report=
|
||||
```
|
||||
Kalau ditemukan di JS/Vue yang langsung set ke iframe/object/window.open tanpa lewat PHP
|
||||
proxy, itu harus diganti ke `stream_by_code`.
|
||||
|
||||
### Library terkait
|
||||
|
||||
- `application/libraries/Ibl_patient_decrypt.php` — populate/delete `patient_print_cache`
|
||||
- `application/libraries/Ibl_sampling_normal.php` — pengganti `fn_sampling_get_normal` MySQL function (semua `Re_px.php` sudah diupdate)
|
||||
- `application/controllers/tools/Birt_proxy.php` — proxy stream handler
|
||||
|
||||
## graphify
|
||||
|
||||
This project has a graphify knowledge graph at graphify-out/.
|
||||
|
||||
72
CLAUDE.md
72
CLAUDE.md
@@ -19,6 +19,78 @@
|
||||
- SSH command: `ssh -i /Users/fajrihardhitamurti/id_rsa -o BatchMode=yes -o StrictHostKeyChecking=accept-new one@10.9.20.31`
|
||||
- BIRT reports path: `/home/one/project/birt/onelab/reports/`
|
||||
|
||||
## PDP Encryption & BIRT Report
|
||||
|
||||
Dokumentasi lengkap ada di **`docs/pdp-encryption-runbook.md`**.
|
||||
|
||||
Poin penting yang sering terlewat:
|
||||
- `M_PatientNIK_bidx` diisi dari **`M_PatientIDNumber`**, bukan kolom `M_PatientNIK`
|
||||
- `M_PatientDOB` bertipe `VARCHAR(20)` (bukan DATE) agar masked value `**-**-YYYY` tersimpan
|
||||
- `Mcu_PreregisterPatientsDOB` juga `VARCHAR(20)` — tidak punya `_enc`, data asli di `m_patient`
|
||||
|
||||
### Pola wajib: PHP Proxy Stream
|
||||
|
||||
BIRT membaca dari tabel `patient_print_cache`. Cache harus di-populate PHP sebelum BIRT
|
||||
dipanggil, dan dihapus segera setelah PDF di-stream.
|
||||
|
||||
```
|
||||
FE → PHP proxy → populate cache → fetch BIRT → delete cache → stream PDF
|
||||
```
|
||||
|
||||
**Jangan pernah** buat FE langsung build URL `/birt/frameset?...` lalu set ke iframe/window.open
|
||||
tanpa lewat PHP proxy — cache tidak akan pernah terisi, data pasien kosong di report.
|
||||
|
||||
### Endpoint proxy yang tersedia
|
||||
|
||||
```
|
||||
GET /one-api-lab/tools/birt_proxy/stream_by_code
|
||||
Params: token, report_code (print_transaction code), PT_OrderHeaderID
|
||||
Return: binary PDF
|
||||
```
|
||||
|
||||
Untuk BE yang perlu return URL ke FE, gunakan `Reporturl` library:
|
||||
```php
|
||||
$this->load->library('reporturl');
|
||||
[$ok, $url] = $this->reporturl->get_report_url_by_code($report_code, [
|
||||
'PT_OrderHeaderID' => $order_id,
|
||||
'PUsername' => $username,
|
||||
]);
|
||||
// $url sudah mengarah ke stream_by_code — tidak perlu populate/delete cache manual
|
||||
```
|
||||
|
||||
### Daftar print_transaction code
|
||||
|
||||
| Group | Print siap | Print belum siap | Email |
|
||||
|-------|-----------|-----------------|-------|
|
||||
| LAB | `LAB-RESULT-P-01` | `LAB-RESULT-NP-01` | `LAB-RESULT-P-02` |
|
||||
| LAB (Inggris) | `LABEN-RESULT-P-01` | `LABEN-RESULT-NP-01` | `LABEN-RESULT-P-02` |
|
||||
| Mikro (terlampir) | `MIKRO-RESULT-P-01` | `MIKRO-RESULT-NP-01` | `MIKRO-RESULT-P-02` |
|
||||
| Mikro (tidak terlampir) | `LAB-RESULT-P-01` | `LAB-RESULT-NP-01` | `LAB-RESULT-P-02` |
|
||||
| Mikro (Inggris) | `MIKROEN-RESULT-P-01` | `MIKROEN-RESULT-NP-01` | `MIKROEN-RESULT-P-02` |
|
||||
| FNA | `FNA-RESULT-P-01` | `FNA-RESULT-NP-01` | `FNA-RESULT-P-02` |
|
||||
| Patologi Anatomi | `PA-RESULT-P-01` | `PA-RESULT-NP-01` | `PA-RESULT-P-02` |
|
||||
| Papsmear | `PAP-RESULT-P-01` | `PAP-RESULT-NP-01` | `PAP-RESULT-P-02` |
|
||||
| Pap Smear LCP | `PAPLCP-RESULT-P-01` | `PAPLCP-RESULT-NP-01` | `PAPLCP-RESULT-P-02` |
|
||||
| Pap Smear LCP (Inggris) | `PAPLEN-RESULT-P-01` | `PAPLEN-RESULT-NP-01` | `PAPLEN-RESULT-P-02` |
|
||||
| Preparasi Sperma | `PS-RESULT-P-01` | `PS-RESULT-NP-01` | `PS-RESULT-P-02` |
|
||||
| DFI | `DFI-RESULT-P-01` | `DFI-RESULT-NP-01` | `DFI-RESULT-P-02` |
|
||||
| Cytologi | `CT-RESULT-P-01` | `CT-RESULT-NP-01` | `CT-RESULT-P-02` |
|
||||
|
||||
### Deteksi modul yang belum difix
|
||||
|
||||
Cari pola ini di FE:
|
||||
```
|
||||
/birt/frameset?__report=
|
||||
```
|
||||
Kalau ditemukan di JS/Vue yang langsung set ke iframe/object/window.open tanpa lewat PHP
|
||||
proxy, itu harus diganti ke `stream_by_code`.
|
||||
|
||||
### Library terkait
|
||||
|
||||
- `application/libraries/Ibl_patient_decrypt.php` — populate/delete `patient_print_cache`
|
||||
- `application/libraries/Ibl_sampling_normal.php` — pengganti `fn_sampling_get_normal` MySQL function (semua `Re_px.php` sudah diupdate)
|
||||
- `application/controllers/tools/Birt_proxy.php` — proxy stream handler
|
||||
|
||||
## graphify
|
||||
|
||||
This project has a graphify knowledge graph at graphify-out/.
|
||||
|
||||
@@ -52,4 +52,5 @@ defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
$route['default_controller'] = 'welcome';
|
||||
$route['404_override'] = '';
|
||||
$route['translate_uri_dashes'] = FALSE;
|
||||
$route['report/qr/(:num)'] = 'tools/merge_report/preview_qr/$1';
|
||||
$route['report/(:num)'] = 'tools/merge_report/preview/$1';
|
||||
|
||||
@@ -124,11 +124,20 @@ EOF;
|
||||
}
|
||||
public function v3($orderHeaderID)
|
||||
{
|
||||
$sql = "SELECT QR_PrintOutReportURL
|
||||
FROM qr_printout
|
||||
WHERE QR_PrintOutT_OrderHeaderID = ?
|
||||
AND QR_PrintOutIsActive = 1
|
||||
ORDER BY QR_PrintOutID DESC
|
||||
$sql = "SELECT IFNULL(qp.QR_PrintOutVerifyURL, '') AS verify_url
|
||||
FROM one_lab.qr_printout qp
|
||||
JOIN one_lab.t_orderheader_group_result r
|
||||
ON r.T_OrderHeaderGroupResultT_OrderHeaderID = qp.QR_PrintOutT_OrderHeaderID
|
||||
AND r.T_OrderHeaderGroupResultGroup_ResultID = qp.QR_PrintOutGroup_ResultID
|
||||
AND r.T_OrderHeaderGroupResultT_TestID = qp.QR_PrintOutT_TestID
|
||||
JOIN one_lab.t_orderheader_group_result_details d
|
||||
ON d.T_OrderHeaderGroupResultDetailsT_OrderHeaderGroupResultID = r.T_OrderHeaderGroupResultID
|
||||
WHERE d.T_OrderHeaderGroupResultDetailsT_OrderHeaderID = ?
|
||||
AND d.T_OrderHeaderGroupResultDetailsIsActive = 'Y'
|
||||
AND r.T_OrderHeaderGroupResultIsActive = 'Y'
|
||||
AND qp.QR_PrintOutIsActive = 1
|
||||
AND IFNULL(qp.QR_PrintOutVerifyURL, '') <> ''
|
||||
ORDER BY qp.QR_PrintOutID DESC
|
||||
LIMIT 1";
|
||||
$rs = $this->get_one_row($sql, array($orderHeaderID));
|
||||
if ($rs["status"] == -1) {
|
||||
@@ -140,8 +149,8 @@ EOF;
|
||||
exit;
|
||||
}
|
||||
|
||||
$reportUrl = $rs["data"]["QR_PrintOutReportURL"];
|
||||
$img_qrcode = $this->post("http://localhost/charts/qrtext.php", $reportUrl);
|
||||
$verifyUrl = $rs["data"]["verify_url"];
|
||||
$img_qrcode = $this->post("http://localhost/charts/qrtext.php", $verifyUrl);
|
||||
header("Content-type: image/png");
|
||||
echo $img_qrcode;
|
||||
exit;
|
||||
@@ -149,7 +158,7 @@ EOF;
|
||||
public function v3_nonlab($resultEntryID)
|
||||
{
|
||||
$sql = " SELECT
|
||||
qp.QR_PrintOutReportURL
|
||||
IFNULL(qp.QR_PrintOutVerifyURL, '') AS verify_url
|
||||
FROM one_lab.so_resultentry se
|
||||
JOIN one_lab.t_orderheader oh
|
||||
ON oh.T_OrderHeaderID = se.SO_ResultEntryT_OrderHeaderID
|
||||
@@ -170,8 +179,8 @@ EOF;
|
||||
exit;
|
||||
}
|
||||
|
||||
$reportUrl = $rs["data"]["QR_PrintOutReportURL"];
|
||||
$img_qrcode = $this->post("http://localhost/charts/qrtext.php", $reportUrl);
|
||||
$verifyUrl = $rs["data"]["verify_url"];
|
||||
$img_qrcode = $this->post("http://localhost/charts/qrtext.php", $verifyUrl);
|
||||
header("Content-type: image/png");
|
||||
echo $img_qrcode;
|
||||
exit;
|
||||
|
||||
@@ -7,6 +7,7 @@ class Patient extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
function index()
|
||||
@@ -40,20 +41,33 @@ class Patient extends MY_Controller
|
||||
|
||||
$where = " orderIsActive = 'Y' $filter_date";
|
||||
|
||||
$bidx_where = '';
|
||||
if ($search != "") {
|
||||
$where .= " AND (orderNumber LIKE '{$search}' OR M_PatientName LIKE '{$search}')";
|
||||
$raw_search = trim($prm['search']);
|
||||
$tokens = $this->ibl_encryptor->query_tokens($raw_search);
|
||||
if ($tokens) {
|
||||
$bidx_conds = implode(' AND ', array_map(function($h) {
|
||||
return "JSON_CONTAINS(M_PatientName_bidx, '\"$h\"')";
|
||||
}, $tokens));
|
||||
$bidx_where = " AND (orderNumber LIKE '{$search}' OR ({$bidx_conds}))";
|
||||
} else {
|
||||
$bidx_where = " AND orderNumber LIKE '{$search}'";
|
||||
}
|
||||
$where .= $bidx_where;
|
||||
}
|
||||
|
||||
$sql_total = "SELECT COUNT(*) as total FROM (
|
||||
SELECT `order`.*,S_MenuUrl,
|
||||
DATE_FORMAT(orderDate, '%d-%m-%Y %H:%i') as order_date,
|
||||
CONCAT(M_TitleName,'. ',M_PatientName) as patient_fullname,
|
||||
M_PatientName_enc as patient_name_enc,
|
||||
M_PatientName as patient_name_masked,
|
||||
M_PatientPrefix, M_PatientSuffix, M_TitleName,
|
||||
IFNULL(T_OrderHeaderLabNumber,'-') as labnumber
|
||||
FROM one_klinik.order
|
||||
JOIN m_patient ON orderM_PatientID = M_PatientID
|
||||
AND M_PatientIsActive = 'Y'
|
||||
JOIN s_menu ON S_MenuName = 'Registration' AND S_MenuIsActive = 'Y'
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
AND M_TitleIsActive = 'Y'
|
||||
LEFT JOIN t_orderheader ON orderT_OrderHeaderID = T_OrderHeaderID
|
||||
WHERE $where
|
||||
@@ -74,13 +88,15 @@ class Patient extends MY_Controller
|
||||
$sql = "SELECT * FROM (
|
||||
SELECT `order`.*,S_MenuUrl,
|
||||
DATE_FORMAT(orderDate, '%d-%m-%Y %H:%i') as order_date,
|
||||
CONCAT(M_TitleName,'. ',M_PatientName) as patient_fullname,
|
||||
M_PatientName_enc as patient_name_enc,
|
||||
M_PatientName as patient_name_masked,
|
||||
M_PatientPrefix, M_PatientSuffix, M_TitleName,
|
||||
IFNULL(T_OrderHeaderLabNumber,'-') as labnumber
|
||||
FROM one_klinik.order
|
||||
JOIN m_patient ON orderM_PatientID = M_PatientID
|
||||
AND M_PatientIsActive = 'Y'
|
||||
JOIN s_menu ON S_MenuName = 'Registration' AND S_MenuIsActive = 'Y'
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
AND M_TitleIsActive = 'Y'
|
||||
LEFT JOIN t_orderheader ON orderT_OrderHeaderID = T_OrderHeaderID
|
||||
WHERE $where
|
||||
@@ -89,12 +105,17 @@ class Patient extends MY_Controller
|
||||
limit 0, $tot_count";
|
||||
|
||||
$qry = $this->db->query($sql);
|
||||
$last_query = $this->db->last_query();
|
||||
// echo $last_query;
|
||||
// exit;
|
||||
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
$enc = $this->ibl_encryptor;
|
||||
$rows = array_map(function($row) use ($enc) {
|
||||
$name = $enc->decrypt($row['patient_name_enc'] ?? '') ?: $row['patient_name_masked'];
|
||||
$title = $row['M_TitleName'] ? $row['M_TitleName'] . '. ' : '';
|
||||
$prefix = $row['M_PatientPrefix'] ? $row['M_PatientPrefix'] . ' ' : '';
|
||||
$suffix = $row['M_PatientSuffix'] ? ' ' . $row['M_PatientSuffix'] : '';
|
||||
$row['patient_fullname'] = trim($title . $prefix . $name . $suffix);
|
||||
unset($row['patient_name_enc'], $row['patient_name_masked']);
|
||||
return $row;
|
||||
}, $qry->result_array());
|
||||
} else {
|
||||
$this->sys_error_db("Select order error", $this->db);
|
||||
exit;
|
||||
@@ -232,11 +253,45 @@ class Patient extends MY_Controller
|
||||
|
||||
$row_results = [];
|
||||
$rtn_mou = [];
|
||||
$sql = "SELECT M_CompanyID,
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
|
||||
if ($orderid) {
|
||||
$sql = "SELECT M_CompanyID, M_CompanyName, m.M_MouID as settingM_MouID
|
||||
FROM one_klinik.`order` o
|
||||
JOIN m_mou m ON o.orderM_MouID = m.M_MouID
|
||||
JOIN m_company ON m.M_MouM_CompanyID = M_CompanyID
|
||||
WHERE o.orderID = ?
|
||||
LIMIT 1";
|
||||
$qry_order = $this->db->query($sql, [$orderid]);
|
||||
if ($qry_order && $qry_order->num_rows() > 0) {
|
||||
$order_row = $qry_order->row_array();
|
||||
$mous = $this->db->query(
|
||||
"SELECT M_MouID, M_MouName FROM m_mou
|
||||
WHERE M_MouIsActive = 'Y' AND M_MouIsApproved = 'Y' AND M_MouIsReleased = 'Y'
|
||||
AND M_MouStartDate <= date(now()) AND M_MouEndDate >= date(now())
|
||||
AND M_MouM_CompanyID = ?",
|
||||
[$order_row['M_CompanyID']]
|
||||
)->result_array();
|
||||
$row_results[] = [
|
||||
'M_CompanyID' => $order_row['M_CompanyID'],
|
||||
'M_CompanyName' => $order_row['M_CompanyName'],
|
||||
'mous' => $mous,
|
||||
];
|
||||
foreach ($mous as $v) {
|
||||
if ($v['M_MouID'] == $order_row['settingM_MouID']) {
|
||||
$rtn_mou = $v;
|
||||
}
|
||||
}
|
||||
$this->sys_ok(['total_display' => 1, 'records' => $row_results, 'mou' => $rtn_mou]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SELECT M_CompanyID,
|
||||
M_CompanyName, '' as mous, settingM_MouID
|
||||
FROM m_company
|
||||
JOIN one_klinik.setting ON settingIsActive = 'Y'
|
||||
JOIN m_mou ON M_MouID = settingM_MouID AND M_MouM_CompanyID = M_CompanyID AND
|
||||
JOIN m_mou ON M_MouID = settingM_MouID AND M_MouM_CompanyID = M_CompanyID AND
|
||||
M_MouIsActive = 'Y' AND M_MouIsApproved = 'Y' AND M_MouIsReleased = 'Y'
|
||||
AND M_MouStartDate <= date(now()) AND M_MouEndDate >= date(now())
|
||||
WHERE M_CompanyIsActive = 'Y'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
321
application/controllers/klinik/Ttv.php
Normal file
321
application/controllers/klinik/Ttv.php
Normal file
@@ -0,0 +1,321 @@
|
||||
<?php
|
||||
class Ttv extends MY_Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
echo "TTV API";
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->db_oneklinik = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// POST /klinik/ttv/search
|
||||
// Listing order yang sudah selesai screening (orderIsScreening='D')
|
||||
// -----------------------------------------------------------------------
|
||||
public function search()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$limit = 20;
|
||||
$offset = (max(1, intval($prm['current_page'] ?? 1)) - 1) * $limit;
|
||||
|
||||
$where = ["o.orderIsScreening = 'D'", "o.orderIsActive = 'Y'"];
|
||||
$binds = [];
|
||||
|
||||
// Filter tanggal
|
||||
$start_date = $prm['start_date'] ?? date('Y-m-d');
|
||||
$where[] = "DATE(o.orderDate) = ?";
|
||||
$binds[] = $start_date;
|
||||
|
||||
// Filter status TTV
|
||||
$status = $prm['status'] ?? '';
|
||||
if ($status !== '') {
|
||||
$where[] = "o.orderIsTTV = ?";
|
||||
$binds[] = $status;
|
||||
}
|
||||
|
||||
// Filter noreg
|
||||
$noreg = trim($prm['noreg'] ?? '');
|
||||
if ($noreg !== '') {
|
||||
$where[] = "p.M_PatientNoReg LIKE ?";
|
||||
$binds[] = '%' . $noreg . '%';
|
||||
}
|
||||
|
||||
// Filter nama / HP via trigram index (PDP-safe)
|
||||
$search = trim($prm['search'] ?? '');
|
||||
if ($search !== '') {
|
||||
$where[] = "(p.M_PatientName_bidx LIKE ? OR p.M_PatientHP_bidx LIKE ?)";
|
||||
$binds[] = '%' . $search . '%';
|
||||
$binds[] = '%' . $search . '%';
|
||||
}
|
||||
|
||||
$where_sql = implode(' AND ', $where);
|
||||
|
||||
$sql = "SELECT
|
||||
'N' AS divider,
|
||||
p.M_PatientName, p.M_PatientName_enc,
|
||||
p.M_PatientHP, p.M_PatientHP_enc,
|
||||
p.M_PatientDOB, p.M_PatientDOB_enc,
|
||||
p.M_PatientEmail, p.M_PatientEmail_enc,
|
||||
p.M_PatientPhone, p.M_PatientPhone_enc,
|
||||
p.M_PatientPOB, p.M_PatientPOB_enc,
|
||||
p.M_PatientIDNumber, p.M_PatientIDNumber_enc,
|
||||
p.M_PatientNIK, p.M_PatientNIK_enc,
|
||||
p.M_PatientPhoto,
|
||||
p.M_PatientPhotoThumb,
|
||||
p.M_PatientNoReg,
|
||||
p.M_PatientJob,
|
||||
p.M_PatientM_SexID,
|
||||
p.M_PatientM_TitleID,
|
||||
p.M_PatientM_IdTypeID,
|
||||
o.*,
|
||||
DATE_FORMAT(o.orderDate, '%d-%m-%Y') AS date_order,
|
||||
'' AS kode_status,
|
||||
s.M_SexName,
|
||||
t.M_TitleName
|
||||
FROM one_klinik.`order` o
|
||||
JOIN m_patient p ON p.M_PatientID = o.orderM_PatientID AND p.M_PatientIsActive = 'Y'
|
||||
JOIN m_sex s ON s.M_SexID = p.M_PatientM_SexID
|
||||
JOIN m_title t ON t.M_TitleID = p.M_PatientM_TitleID
|
||||
WHERE $where_sql
|
||||
ORDER BY o.orderDate ASC
|
||||
LIMIT $limit OFFSET $offset";
|
||||
|
||||
$query = $this->db_oneklinik->query($sql, $binds);
|
||||
if (!$query) {
|
||||
$this->sys_error_db("ttv search", $this->db_oneklinik);
|
||||
return;
|
||||
}
|
||||
|
||||
$rows = $query->result_array();
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
foreach ($rows as $k => $v) {
|
||||
$rows[$k]['M_PatientName'] = $enc->decrypt($v['M_PatientName_enc'] ?? '') ?: $v['M_PatientName'];
|
||||
$rows[$k]['M_PatientHP'] = $enc->decrypt($v['M_PatientHP_enc'] ?? '') ?: $v['M_PatientHP'];
|
||||
$rows[$k]['M_PatientDOB'] = $enc->decrypt($v['M_PatientDOB_enc'] ?? '') ?: $v['M_PatientDOB'];
|
||||
$rows[$k]['M_PatientEmail'] = $enc->decrypt($v['M_PatientEmail_enc'] ?? '') ?: $v['M_PatientEmail'];
|
||||
$rows[$k]['M_PatientPhone'] = $enc->decrypt($v['M_PatientPhone_enc'] ?? '') ?: $v['M_PatientPhone'];
|
||||
$rows[$k]['M_PatientPOB'] = $enc->decrypt($v['M_PatientPOB_enc'] ?? '') ?: $v['M_PatientPOB'];
|
||||
$rows[$k]['M_PatientIDNumber'] = $enc->decrypt($v['M_PatientIDNumber_enc'] ?? '') ?: $v['M_PatientIDNumber'];
|
||||
$rows[$k]['M_PatientNIK'] = $enc->decrypt($v['M_PatientNIK_enc'] ?? '') ?: $v['M_PatientNIK'];
|
||||
$rows[$k]['patient_name'] = trim(($v['M_TitleName'] ?? '') . ' ' . $rows[$k]['M_PatientName']);
|
||||
|
||||
foreach (array_keys($rows[$k]) as $col) {
|
||||
if (substr($col, -4) === '_enc') unset($rows[$k][$col]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->sys_ok(['total' => count($rows), 'records' => $rows]);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// POST /klinik/ttv/getttv
|
||||
// Load data TTV yang sudah pernah disimpan untuk satu order
|
||||
// -----------------------------------------------------------------------
|
||||
public function getttv()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
|
||||
if (!$orderid) {
|
||||
$this->sys_error("orderid required");
|
||||
return;
|
||||
}
|
||||
|
||||
$row = $this->db_oneklinik->query(
|
||||
"SELECT orderDoctorVitalSign, orderDoctorSaran AS xnote
|
||||
FROM one_klinik.order_doctor
|
||||
WHERE orderDoctorOrderID = ?
|
||||
ORDER BY orderDoctorID DESC LIMIT 1",
|
||||
[$orderid]
|
||||
)->row_array();
|
||||
|
||||
$fisiks = null;
|
||||
$xnote = '';
|
||||
|
||||
if ($row) {
|
||||
$fisiks = $row['orderDoctorVitalSign']
|
||||
? json_decode($row['orderDoctorVitalSign'], true)
|
||||
: null;
|
||||
$xnote = $row['xnote'] ?? '';
|
||||
}
|
||||
|
||||
$this->sys_ok(['fisiks' => $fisiks, 'xnote' => $xnote]);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// POST /klinik/ttv/savettv
|
||||
// Simpan TTV ke order_doctor + order_tanda_vital, set orderIsTTV='D'
|
||||
// -----------------------------------------------------------------------
|
||||
public function savettv()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$userID = $this->sys_user['M_UserID'];
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
$fisiks = $prm['fisiks'] ?? [];
|
||||
$xnote = $prm['xnote'] ?? '';
|
||||
|
||||
if (!$orderid) {
|
||||
$this->sys_error("orderid required");
|
||||
return;
|
||||
}
|
||||
|
||||
$fisiks_json = json_encode($fisiks);
|
||||
|
||||
// 1. Upsert order_doctor
|
||||
$exists = $this->db_oneklinik->query(
|
||||
"SELECT orderDoctorID FROM one_klinik.order_doctor WHERE orderDoctorOrderID = ? LIMIT 1",
|
||||
[$orderid]
|
||||
)->row_array();
|
||||
|
||||
if ($exists) {
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.order_doctor
|
||||
SET orderDoctorVitalSign = ?,
|
||||
orderDoctorSaran = ?,
|
||||
orderDoctorLastUpdated = NOW()
|
||||
WHERE orderDoctorOrderID = ?",
|
||||
[$fisiks_json, $xnote, $orderid]
|
||||
);
|
||||
} else {
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"INSERT INTO one_klinik.order_doctor
|
||||
(orderDoctorOrderID, orderDoctorVitalSign, orderDoctorSaran,
|
||||
orderDoctorType, orderDoctorIsActive, orderDoctorUserID, orderDoctorCreated)
|
||||
VALUES (?, ?, ?, 'FORM', 'Y', ?, NOW())",
|
||||
[$orderid, $fisiks_json, $xnote, $userID]
|
||||
);
|
||||
}
|
||||
|
||||
if (!$ok) {
|
||||
$this->sys_error_db("upsert order_doctor", $this->db_oneklinik);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Parse fisiks → nilai terstruktur untuk order_tanda_vital
|
||||
$ttv = [
|
||||
'pulse' => 0,
|
||||
'sistole' => 0,
|
||||
'diastole' => 0,
|
||||
'temperature' => 0,
|
||||
'weight' => 0,
|
||||
'height' => 0,
|
||||
'saturation' => 0,
|
||||
];
|
||||
|
||||
foreach ((array)$fisiks as $item) {
|
||||
$code = $item['id_code'] ?? '';
|
||||
$value = trim($item['value'] ?? '');
|
||||
switch ($code) {
|
||||
case 'tanda_vital_1': $ttv['pulse'] = intval($value); break;
|
||||
case 'tanda_vital_5':
|
||||
$parts = explode('/', $value);
|
||||
$ttv['sistole'] = intval($parts[0] ?? 0);
|
||||
$ttv['diastole'] = intval($parts[1] ?? 0);
|
||||
break;
|
||||
case 'tanda_vital_6': $ttv['temperature'] = intval($value); break;
|
||||
case 'tanda_vital_7': $ttv['saturation'] = intval($value); break;
|
||||
case 'status_gizi_1': $ttv['weight'] = intval($value); break;
|
||||
case 'status_gizi_2': $ttv['height'] = intval($value); break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Upsert order_tanda_vital
|
||||
$tv_exists = $this->db_oneklinik->query(
|
||||
"SELECT orderTandaVitalID FROM one_klinik.order_tanda_vital WHERE orderTandaVitalOrderID = ? LIMIT 1",
|
||||
[$orderid]
|
||||
)->row_array();
|
||||
|
||||
if ($tv_exists) {
|
||||
$this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.order_tanda_vital SET
|
||||
orderTandaVitalPulse = ?,
|
||||
orderTandaVitalSistole = ?,
|
||||
orderTandaVitalDiastole = ?,
|
||||
orderTandaVitalTemperature = ?,
|
||||
orderTandaVitalWeight = ?,
|
||||
orderTandaVitalHeight = ?,
|
||||
orderTandaVitalSaturation = ?,
|
||||
orderTandaVitalUserID = ?,
|
||||
orderTandaVitalLastUpdated = NOW()
|
||||
WHERE orderTandaVitalOrderID = ?",
|
||||
[$ttv['pulse'], $ttv['sistole'], $ttv['diastole'],
|
||||
$ttv['temperature'], $ttv['weight'], $ttv['height'],
|
||||
$ttv['saturation'], $userID, $orderid]
|
||||
);
|
||||
} else {
|
||||
$this->db_oneklinik->query(
|
||||
"INSERT INTO one_klinik.order_tanda_vital
|
||||
(orderTandaVitalOrderID, orderTandaVitalPulse, orderTandaVitalSistole,
|
||||
orderTandaVitalDiastole, orderTandaVitalTemperature, orderTandaVitalWeight,
|
||||
orderTandaVitalHeight, orderTandaVitalSaturation,
|
||||
orderTandaVitalIsActive, orderTandaVitalUserID, orderTandaVitalCreated)
|
||||
VALUES (?,?,?,?,?,?,?,?,'Y',?,NOW())",
|
||||
[$orderid, $ttv['pulse'], $ttv['sistole'], $ttv['diastole'],
|
||||
$ttv['temperature'], $ttv['weight'], $ttv['height'],
|
||||
$ttv['saturation'], $userID]
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Update status order
|
||||
$this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.`order` SET orderIsTTV = 'D', orderUserID = ? WHERE orderID = ?",
|
||||
[$userID, $orderid]
|
||||
);
|
||||
|
||||
$this->sys_ok(['process' => 'OK']);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// POST /klinik/ttv/getsexreg
|
||||
// Return kartuidentitass, sexes, titles, religions
|
||||
// -----------------------------------------------------------------------
|
||||
public function getsexreg()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
return;
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
|
||||
$rows['kartuidentitass'] = $this->db_onedev->query(
|
||||
"SELECT * FROM m_idtype WHERE M_IdTypeIsActive = 'Y'"
|
||||
)->result_array();
|
||||
|
||||
$rows['sexes'] = $this->db_onedev->query(
|
||||
"SELECT * FROM m_sex WHERE M_SexIsActive = 'Y'"
|
||||
)->result_array();
|
||||
|
||||
$rows['titles'] = $this->db_onedev->query(
|
||||
"SELECT * FROM m_title WHERE M_TitleIsActive = 'Y'"
|
||||
)->result_array();
|
||||
|
||||
$rows['religions'] = $this->db_onedev->query(
|
||||
"SELECT * FROM m_religion WHERE M_ReligionIsActive = 'Y'"
|
||||
)->result_array();
|
||||
|
||||
$this->sys_ok($rows);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class Patient extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
//$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
public function add_notes($orderid){
|
||||
@@ -61,62 +61,66 @@ class Patient extends MY_Controller
|
||||
*/
|
||||
|
||||
$number_limit = 10;
|
||||
$number_offset = ($prm['current_page'] - 1) * $number_limit ;
|
||||
$where = " ( DATE(orderDate) = '{$startdate}' ) AND ";
|
||||
if($search != ''){
|
||||
$where = "( M_PatientName LIKE '%{$search}%' OR orderNumber LIKE '%{$search}%' ) AND ";
|
||||
if(strlen($search) == 11){
|
||||
$number_offset = ($prm['current_page'] - 1) * $number_limit;
|
||||
$where = " ( DATE(orderDate) BETWEEN '{$startdate}' AND '{$enddate}' ) AND ";
|
||||
if ($search != '') {
|
||||
if (strlen($search) == 11) {
|
||||
$where = "orderNumber = '{$search}' AND ";
|
||||
} else {
|
||||
$tokens = $this->ibl_encryptor->query_tokens($search);
|
||||
if ($tokens) {
|
||||
$bidx_conds = implode(' AND ', array_map(function($h) {
|
||||
return "JSON_CONTAINS(M_PatientName_bidx, '\"$h\"')";
|
||||
}, $tokens));
|
||||
$where = "( orderNumber LIKE '%{$search}%' OR ({$bidx_conds}) ) AND ";
|
||||
} else {
|
||||
$where = "orderNumber LIKE '%{$search}%' AND ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$sql = " SELECT count(*) as total
|
||||
$sql = "SELECT count(*) as total
|
||||
FROM one_klinik.`order`
|
||||
JOIN m_patient ON orderM_PatientID = M_PatientID
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
WHERE
|
||||
$where
|
||||
( ('{$status}' = 'N' AND orderIsLunas = 'N') OR ('{$status}' = 'Y' AND orderIsLunas = 'Y') )";
|
||||
|
||||
$query = $this->db_onedev->query($sql, $sql_param);
|
||||
|
||||
//echo $this->db_onedev->last_query();
|
||||
|
||||
$query = $this->db_onedev->query($sql);
|
||||
$tot_count = 0;
|
||||
$tot_page = 0;
|
||||
$tot_page = 0;
|
||||
if ($query) {
|
||||
$tot_count = $query->result_array()[0]["total"];
|
||||
$tot_page = ceil($tot_count/$number_limit);
|
||||
$tot_page = ceil($tot_count / $number_limit);
|
||||
} else {
|
||||
$this->sys_error_db("t_samplestorage count", $this->db_onedev);
|
||||
$this->sys_error_db("patient count", $this->db_onedev);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$sql = "SELECT orderID,
|
||||
}
|
||||
|
||||
$sql = "SELECT orderID,
|
||||
orderDate,
|
||||
orderNumber,
|
||||
orderM_PatientID,
|
||||
M_PatientNoReg,
|
||||
orderKeluhan,
|
||||
DATE_FORMAT(orderDate,'%d-%m-%Y %H:%i') as order_date,
|
||||
CONCAT(M_TitleName,'. ',M_PatientName) as M_PatientName,
|
||||
CONCAT(M_TitleLangName,'. ',M_PatientName) as M_PatientName_eng,
|
||||
M_TitleName,
|
||||
M_PatientName_enc,
|
||||
M_PatientName AS patient_name_masked,
|
||||
M_PatientPrefix, M_PatientSuffix,
|
||||
M_TitleName, M_TitleLangName,
|
||||
orderTotal as totalbill,
|
||||
0 as paid,
|
||||
0 as unpaid,
|
||||
orderIsLunas as flaglunas,
|
||||
'' as notes,
|
||||
100 as mindp_percent,
|
||||
100 as mindp_percent,
|
||||
settingPriceDefault as mindp_amount,
|
||||
0 as F_BillDetailID
|
||||
FROM one_klinik.`order`
|
||||
JOIN m_patient ON orderM_PatientID = M_PatientID
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
JOIN one_klinik.`setting` ON settingIsActive = 'Y'
|
||||
WHERE
|
||||
@@ -124,23 +128,36 @@ class Patient extends MY_Controller
|
||||
( ('{$status}' = 'N' AND orderIsLunas = 'N') OR ('{$status}' = 'Y' AND orderIsLunas = 'Y') )
|
||||
GROUP BY orderID
|
||||
ORDER BY orderID ASC
|
||||
limit $number_limit offset $number_offset";
|
||||
//echo $sql;
|
||||
$query = $this->db_onedev->query($sql, $sql_param);
|
||||
//echo $this->db_onedev->last_query();
|
||||
$rows = $query->result_array();
|
||||
if($rows){
|
||||
foreach($rows as $k => $v){
|
||||
$sql = "SELECT IFNULL(SUM(PaymentTotal),0) as total
|
||||
FROM one_klinik.payment
|
||||
WHERE
|
||||
PaymentOrderID = ? AND PaymentIsActive = 'Y'";
|
||||
$data_payment = $this->db_onedev->query($sql, array($v['orderID']))->row();
|
||||
$unpaid = $v['totalbill'] - $data_payment->total;
|
||||
$rows[$k]['unpaid'] = $unpaid;
|
||||
$rows[$k]['paid'] = $data_payment->total;
|
||||
LIMIT $number_limit OFFSET $number_offset";
|
||||
|
||||
$rows[$k]['notes'] = $this->add_notes($v['orderID']);
|
||||
$query = $this->db_onedev->query($sql);
|
||||
if (!$query) {
|
||||
$this->sys_error_db("patient rows", $this->db_onedev);
|
||||
exit;
|
||||
}
|
||||
$rows = $query->result_array();
|
||||
$enc = $this->ibl_encryptor;
|
||||
if ($rows) {
|
||||
foreach ($rows as $k => $v) {
|
||||
$p_name = $enc->decrypt($v['M_PatientName_enc'] ?? '') ?: $v['patient_name_masked'];
|
||||
$title = $v['M_TitleName'] ? $v['M_TitleName'] . '. ' : '';
|
||||
$title_e = $v['M_TitleLangName'] ? $v['M_TitleLangName'] . '. ': '';
|
||||
$prefix = $v['M_PatientPrefix'] ? $v['M_PatientPrefix'] . ' ' : '';
|
||||
$suffix = $v['M_PatientSuffix'] ? ' ' . $v['M_PatientSuffix'] : '';
|
||||
$rows[$k]['M_PatientName'] = trim($title . $prefix . $p_name . $suffix);
|
||||
$rows[$k]['M_PatientName_eng'] = trim($title_e . $prefix . $p_name . $suffix);
|
||||
unset($rows[$k]['M_PatientName_enc'], $rows[$k]['patient_name_masked'],
|
||||
$rows[$k]['M_PatientPrefix'], $rows[$k]['M_PatientSuffix'],
|
||||
$rows[$k]['M_TitleLangName']);
|
||||
|
||||
$data_payment = $this->db_onedev->query(
|
||||
"SELECT IFNULL(SUM(PaymentTotal),0) as total FROM one_klinik.payment
|
||||
WHERE PaymentOrderID = ? AND PaymentIsActive = 'Y'",
|
||||
[$v['orderID']]
|
||||
)->row();
|
||||
$rows[$k]['unpaid'] = $v['totalbill'] - $data_payment->total;
|
||||
$rows[$k]['paid'] = $data_payment->total;
|
||||
$rows[$k]['notes'] = $this->add_notes($v['orderID']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ class Anamnesedoctor extends MY_Controller
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->db_oneklinik = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
$this->IP_SOCKET_IO = "localhost";
|
||||
}
|
||||
|
||||
@@ -35,17 +36,27 @@ class Anamnesedoctor extends MY_Controller
|
||||
'N' divider,
|
||||
M_PatientID,
|
||||
M_PatientNoReg,
|
||||
M_PatientPhoto,
|
||||
M_PatientPhotoThumb,
|
||||
M_PatientPrefix,
|
||||
M_PatientName,
|
||||
M_PatientName_enc,
|
||||
M_PatientSuffix,
|
||||
M_PatientHP,
|
||||
M_PatientHP_enc,
|
||||
M_PatientEmail,
|
||||
M_PatientEmail_enc,
|
||||
M_PatientPOB,
|
||||
M_PatientPOB_enc,
|
||||
M_PatientPhone,
|
||||
M_PatientPhone_enc,
|
||||
M_PatientIDNumber,
|
||||
M_PatientIDNumber_enc,
|
||||
DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as M_PatientDOB,
|
||||
M_PatientDOB_enc,
|
||||
M_PatientNote,
|
||||
M_PatientNIK,
|
||||
M_PatientNIK_enc,
|
||||
M_PatientJabatan,
|
||||
M_PatientKedudukan,
|
||||
M_PatientPJ,
|
||||
@@ -61,9 +72,12 @@ class Anamnesedoctor extends MY_Controller
|
||||
M_IdTypeName,
|
||||
M_PatientIDNumber,
|
||||
IF(ISNULL(M_PatientSuspendID),'active','suspend' ) as status,
|
||||
M_PatientAddressM_KelurahanID M_KelurahanID,
|
||||
0 M_DistrictID,
|
||||
0 M_CityID,
|
||||
M_PatientAddressM_KelurahanID M_KelurahanID,
|
||||
M_PatientAddressRegionalCd,
|
||||
M_PatientAddressDescription,
|
||||
M_PatientAddressDescription_enc,
|
||||
0 M_DistrictID,
|
||||
0 M_CityID,
|
||||
0 M_ProvinceID
|
||||
FROM one_klinik.order
|
||||
JOIN m_patient ON M_PatientID = orderM_PatientID AND M_PatientIsActive = 'Y'
|
||||
@@ -86,40 +100,90 @@ class Anamnesedoctor extends MY_Controller
|
||||
$rows = $query->result_array();
|
||||
|
||||
foreach ($rows as $k => $v) {
|
||||
$rows[$k]['M_PatientName'] = stripslashes($rows[$k]['M_PatientName']);
|
||||
$rows[$k]['M_PatientAddressDescription'] = stripslashes($v['M_PatientAddressDescription']);
|
||||
$patient_name = str_replace("'", "\\'", $prm['M_PatientName']);
|
||||
$sql = "SELECT *, concat('{$rows[$k]['M_PatientAddressDescription']}', '\n\n',
|
||||
m_kelurahanname, ', ',
|
||||
m_districtname,'\n',
|
||||
m_cityname, ', ',
|
||||
m_provincename) as xaddress
|
||||
FROM m_kelurahan
|
||||
JOIN m_district ON M_KelurahanM_DistrictID = M_DistrictID
|
||||
JOIN m_city ON M_DistrictM_CityID = M_CityID
|
||||
JOIN m_province ON M_CityM_ProvinceID = M_ProvinceID
|
||||
WHERE
|
||||
M_KelurahanID = {$v['M_KelurahanID']} ";
|
||||
//echo $sql;
|
||||
$row_address = $this->db_onedev->query($sql)->row_array();
|
||||
$rows[$k]['M_PatientAddress'] = stripslashes($row_address['xaddress']);
|
||||
$rows[$k]['M_DistrictID'] = $row_address['M_DistrictID'];
|
||||
$rows[$k]['M_CityID'] = $row_address['M_CityID'];
|
||||
$rows[$k]['M_ProvinceID'] = $row_address['M_ProvinceID'];
|
||||
$info = $this->db_onedev->query("SELECT fn_fo_patient_visit(?) info", [$v['M_PatientID']])->row();
|
||||
$rows[$k]['info'] = json_decode($info->info);
|
||||
}
|
||||
$enc = $this->ibl_encryptor;
|
||||
$rows[$k]['M_PatientName'] = $enc->decrypt($v['M_PatientName_enc'] ?? '') ?: stripslashes($v['M_PatientName']);
|
||||
$rows[$k]['M_PatientHP'] = $enc->decrypt($v['M_PatientHP_enc'] ?? '') ?: $v['M_PatientHP'];
|
||||
$rows[$k]['M_PatientEmail'] = $enc->decrypt($v['M_PatientEmail_enc'] ?? '') ?: $v['M_PatientEmail'];
|
||||
$rows[$k]['M_PatientPOB'] = $enc->decrypt($v['M_PatientPOB_enc'] ?? '') ?: $v['M_PatientPOB'];
|
||||
$rows[$k]['M_PatientPhone'] = $enc->decrypt($v['M_PatientPhone_enc'] ?? '') ?: $v['M_PatientPhone'];
|
||||
$rows[$k]['M_PatientIDNumber'] = $enc->decrypt($v['M_PatientIDNumber_enc'] ?? '') ?: $v['M_PatientIDNumber'];
|
||||
$rows[$k]['M_PatientDOB'] = $enc->decrypt($v['M_PatientDOB_enc'] ?? '') ?: $v['M_PatientDOB'];
|
||||
$rows[$k]['M_PatientNIK'] = $enc->decrypt($v['M_PatientNIK_enc'] ?? '') ?: $v['M_PatientNIK'];
|
||||
$rows[$k]['M_PatientAddressDescription'] = $enc->decrypt($v['M_PatientAddressDescription_enc'] ?? '') ?: stripslashes($v['M_PatientAddressDescription'] ?? '');
|
||||
|
||||
$reg_cd = $v['M_PatientAddressRegionalCd'] ?? '';
|
||||
if ($reg_cd) {
|
||||
$reg = $this->db_onedev->query(
|
||||
"SELECT r_kel.regional_nm as kel_name, r_kec.regional_nm as kec_name, r_kab.regional_nm as kab_name, r_pro.regional_nm as pro_name
|
||||
FROM regional r_kel
|
||||
LEFT JOIN regional r_kec ON r_kec.regional_cd = CONCAT(r_kel.pro_cd, r_kel.kab_cd, r_kel.kec_cd, '000')
|
||||
LEFT JOIN regional r_kab ON r_kab.regional_cd = CONCAT(r_kel.pro_cd, r_kel.kab_cd, '000', '000')
|
||||
LEFT JOIN regional r_pro ON r_pro.regional_cd = CONCAT(r_kel.pro_cd, '00', '000', '000')
|
||||
WHERE r_kel.regional_cd = ?", [$reg_cd]
|
||||
)->row_array();
|
||||
$rows[$k]['M_PatientAddress'] = $rows[$k]['M_PatientAddressDescription'] . "\n\n" .
|
||||
implode(', ', array_filter([$reg['kel_name'] ?? '', $reg['kec_name'] ?? '', $reg['kab_name'] ?? '', $reg['pro_name'] ?? '']));
|
||||
} else {
|
||||
$rows[$k]['M_PatientAddress'] = $rows[$k]['M_PatientAddressDescription'];
|
||||
}
|
||||
|
||||
$rows[$k]['info'] = $this->build_patient_visit_info($v['M_PatientID'], $rows[$k]['M_PatientDOB']);
|
||||
}
|
||||
|
||||
$result = array("total" => 1, "records" => $rows, "sql" => $this->db_onedev->last_query());
|
||||
$this->sys_ok($result);
|
||||
} else {
|
||||
$this->sys_error_db("m_patient rows", $this->db_onedev);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_data()
|
||||
}
|
||||
}
|
||||
|
||||
protected function build_patient_visit_info($patient_id, $patient_dob)
|
||||
{
|
||||
$visit = 1;
|
||||
$birthday = 'N';
|
||||
|
||||
$visit_query = $this->db_onedev->query(
|
||||
"SELECT COUNT(DISTINCT T_OrderHeaderID) AS n
|
||||
FROM t_orderheader
|
||||
JOIN t_orderdetail ON T_OrderHeaderID = T_OrderDetailT_OrderHeaderID AND T_OrderDetailIsActive = 'Y'
|
||||
WHERE T_OrderHeaderIsActive = 'Y'
|
||||
AND T_OrderHeaderM_PatientID = ?",
|
||||
[$patient_id]
|
||||
);
|
||||
|
||||
if ($visit_query) {
|
||||
$visit_row = $visit_query->row_array();
|
||||
$visit += (int) ($visit_row['n'] ?? 0);
|
||||
}
|
||||
|
||||
$init_visit_query = $this->db_onedev->query(
|
||||
"SELECT M_PatientInitialVisit
|
||||
FROM m_patient
|
||||
WHERE M_PatientID = ?",
|
||||
[$patient_id]
|
||||
);
|
||||
|
||||
if ($init_visit_query) {
|
||||
$init_visit_row = $init_visit_query->row_array();
|
||||
if (!empty($init_visit_row['M_PatientInitialVisit'])) {
|
||||
$visit += (int) $init_visit_row['M_PatientInitialVisit'];
|
||||
}
|
||||
}
|
||||
|
||||
$dob_time = empty($patient_dob) ? false : strtotime($patient_dob);
|
||||
if ($dob_time !== false) {
|
||||
$birthday = date('m-d', $dob_time) === date('m-d') ? 'Y' : 'N';
|
||||
}
|
||||
|
||||
return json_decode(json_encode([
|
||||
'visit' => $visit,
|
||||
'birthday' => $birthday,
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
function get_data()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
@@ -1785,34 +1849,38 @@ class Anamnesedoctor extends MY_Controller
|
||||
$status = $prm['status'];
|
||||
|
||||
$sql = "SELECT 'N' divider,
|
||||
CONCAT(M_TitleName,' ',IF(ISNULL(M_PatientPrefix),'',CONCAT(M_PatientPrefix,' ')),M_PatientName,IF(ISNULL(M_PatientSuffix),'',CONCAT(M_PatientSuffix,' '))) as patient_name,
|
||||
`order`.*,DATE_FORMAT(orderDate,'%d-%m-%Y') as date_order,
|
||||
'' as kode_status, '' as status
|
||||
`order`.*,
|
||||
DATE_FORMAT(orderDate,'%d-%m-%Y') as date_order,
|
||||
'' as kode_status, '' as status,
|
||||
M_PatientName as patient_name_masked,
|
||||
M_PatientName_enc as patient_name_enc,
|
||||
M_PatientPrefix,
|
||||
M_PatientSuffix,
|
||||
M_TitleName
|
||||
FROM one_klinik.`order`
|
||||
JOIN m_patient ON orderM_PatientID = M_PatientID
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
LEFT JOIN s_menu ON ( S_MenuUrl LIKE CONCAT('%test/vuex/one-klinik-fo-registration-v') OR S_MenuName = 'Periksa dokter')
|
||||
WHERE
|
||||
orderIsActive = 'Y' AND DATE(orderDate) = ? AND orderIsScreening = 'D' AND orderIsCheck = ?
|
||||
WHERE
|
||||
orderIsActive = 'Y' AND DATE(orderDate) = ? AND orderIsScreening = 'D' AND orderIsCheck = ?
|
||||
LIMIT $number_limit offset $number_offset";
|
||||
//echo $sql;
|
||||
$query = $this->db_oneklinik->query($sql, array($xdate, $status));
|
||||
//echo $this->db_oneklinik->last_query();
|
||||
|
||||
if ($query) {
|
||||
$rows = $query->result_array();
|
||||
foreach ($rows as $key => $value) {
|
||||
$sql = "SELECT
|
||||
FROM one_klinik.order_status
|
||||
WHERE
|
||||
orderStatusOrderID = ?
|
||||
ORDER BY ";
|
||||
}
|
||||
$enc = $this->ibl_encryptor;
|
||||
$rows = array_map(function($row) use ($enc) {
|
||||
$name = $enc->decrypt($row['patient_name_enc'] ?? '') ?: $row['patient_name_masked'];
|
||||
$prefix = $row['M_PatientPrefix'] ? $row['M_PatientPrefix'] . ' ' : '';
|
||||
$suffix = $row['M_PatientSuffix'] ? ' ' . $row['M_PatientSuffix'] : '';
|
||||
$title = $row['M_TitleName'] ? $row['M_TitleName'] . ' ' : '';
|
||||
$row['patient_name'] = trim($title . $prefix . $name . $suffix);
|
||||
unset($row['patient_name_masked'], $row['patient_name_enc']);
|
||||
return $row;
|
||||
}, $query->result_array());
|
||||
|
||||
$result = array("total" => $tot_page, "records" => $rows, "sql" => $this->db_onedev->last_query());
|
||||
$result = array("total" => count($rows), "records" => $rows);
|
||||
$this->sys_ok($result);
|
||||
} else {
|
||||
$this->sys_error_db("m_patient rows", $this->db_onedev);
|
||||
$this->sys_error_db("list_patient", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -2368,6 +2436,8 @@ function get_resume_medic(){
|
||||
$receipt = [];
|
||||
$saran = [];
|
||||
$tindakan = [];
|
||||
$vaksinasi_list = [];
|
||||
$tindakan_medis_list = [];
|
||||
$doctor = [];
|
||||
$pemeriksaan_penunjang = [];
|
||||
|
||||
@@ -2562,6 +2632,40 @@ function get_resume_medic(){
|
||||
$receipt[] = $data_periksa_doctor['text']['receipt'];
|
||||
$saran[] = $data_periksa_doctor['text']['saran'];
|
||||
$tindakan[] = $data_periksa_doctor['text']['tindakan'];
|
||||
|
||||
// Vaksinasi per order
|
||||
$qv = $this->db_oneklinik->query(
|
||||
"SELECT ov.*,
|
||||
t.T_TestName as jenis_vaksin_name,
|
||||
t.T_TestSasCode as jenis_vaksin_code,
|
||||
ins.M_InjectionSiteName as injection_site_name,
|
||||
rv.M_RouteVaccineName as route_name,
|
||||
s.M_StaffName as petugas_name
|
||||
FROM one_klinik.order_vaccine ov
|
||||
LEFT JOIN one_lab.t_test t ON ov.orderVaccineT_TestID = t.T_TestID
|
||||
LEFT JOIN one_klinik.m_injection_site ins ON ov.orderVaccineInjectionSiteCode = ins.M_InjectionSiteCode
|
||||
LEFT JOIN one_klinik.m_route_vaccine rv ON ov.orderVaccineRouteCode = rv.M_RouteVaccineCode
|
||||
LEFT JOIN one_lab.m_staff s ON ov.orderVaccinePetugasM_StaffID = s.M_StaffID
|
||||
WHERE ov.orderVaccineOrderID = ? AND ov.orderVaccineIsActive = 'Y'
|
||||
ORDER BY ov.orderVaccineCreated ASC",
|
||||
[$value['orderID']]
|
||||
);
|
||||
$vaksinasi_list[] = $qv ? $qv->result_array() : [];
|
||||
|
||||
// Tindakan medis per order
|
||||
$qt = $this->db_oneklinik->query(
|
||||
"SELECT ot.*,
|
||||
t.T_TestName as jenis_tindakan_name,
|
||||
t.T_TestSasCode as jenis_tindakan_code,
|
||||
d.M_DoctorName as dokter_name
|
||||
FROM one_klinik.order_tindakan ot
|
||||
LEFT JOIN one_lab.t_test t ON ot.orderTindakanT_TestID = t.T_TestID
|
||||
LEFT JOIN one_lab.m_doctor d ON ot.orderTindakanM_DoctorID = d.M_DoctorID
|
||||
WHERE ot.orderTindakanOrderID = ? AND ot.orderTindakanIsActive = 'Y'
|
||||
ORDER BY ot.orderTindakanCreated ASC",
|
||||
[$value['orderID']]
|
||||
);
|
||||
$tindakan_medis_list[] = $qt ? $qt->result_array() : [];
|
||||
}
|
||||
|
||||
$data_orders['date_orders'] = $date_orders;
|
||||
@@ -2598,6 +2702,8 @@ function get_resume_medic(){
|
||||
$data_orders['receipt'] = $receipt;
|
||||
$data_orders['saran'] = $saran;
|
||||
$data_orders['tindakan'] = $tindakan;
|
||||
$data_orders['vaksinasi_list'] = $vaksinasi_list;
|
||||
$data_orders['tindakan_medis_list'] = $tindakan_medis_list;
|
||||
$data_orders['pemeriksaan_penunjang'] = $pemeriksaan_penunjang;
|
||||
|
||||
$this->sys_ok($data_orders);
|
||||
@@ -3096,5 +3202,491 @@ function get_data_order_anamnesis($orderID){
|
||||
return array('text'=>$doctor_text,'form'=>$doctor_form);
|
||||
}
|
||||
|
||||
// ─── Vaksin ────────────────────────────────────────────────────────────────
|
||||
|
||||
// Master statis: injection_sites, routes (dipanggil sekali saat form dibuka)
|
||||
function get_vaccine_masters()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
// Lokasi suntik
|
||||
$q = $this->db_oneklinik->query(
|
||||
"SELECT M_InjectionSiteCode as code, M_InjectionSiteName as name
|
||||
FROM one_klinik.m_injection_site
|
||||
WHERE M_InjectionSiteIsActive = 'Y'
|
||||
ORDER BY M_InjectionSiteID"
|
||||
);
|
||||
if (!$q) { $this->sys_error_db("get m_injection_site", $this->db_oneklinik); exit; }
|
||||
$result['injection_sites'] = $q->result_array();
|
||||
|
||||
// Rute vaksin
|
||||
$q = $this->db_oneklinik->query(
|
||||
"SELECT M_RouteVaccineCode as code, M_RouteVaccineName as name
|
||||
FROM one_klinik.m_route_vaccine
|
||||
WHERE M_RouteVaccineIsActive = 'Y'
|
||||
ORDER BY M_RouteVaccineID"
|
||||
);
|
||||
if (!$q) { $this->sys_error_db("get m_route_vaccine", $this->db_oneklinik); exit; }
|
||||
$result['routes'] = $q->result_array();
|
||||
|
||||
$this->sys_ok($result);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Autocomplete petugas penyuntik dari one_lab.m_staff, param: search
|
||||
function get_vaccine_petugas()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$search = trim($this->sys_input['search'] ?? '');
|
||||
$search_esc = $this->db_onedev->escape_str($search);
|
||||
|
||||
$sql = "SELECT M_StaffID as id, M_StaffName as name, M_StaffCode as code
|
||||
FROM one_lab.m_staff
|
||||
WHERE M_StaffIsActive = 'Y'
|
||||
AND M_StaffName LIKE CONCAT('%', '{$search_esc}', '%')
|
||||
ORDER BY M_StaffName
|
||||
LIMIT 30";
|
||||
|
||||
$q = $this->db_onedev->query($sql);
|
||||
if (!$q) { $this->sys_error_db("get m_staff", $this->db_onedev); exit; }
|
||||
|
||||
$this->sys_ok(['records' => $q->result_array()]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Autocomplete jenis vaksin: filter by MOU order, param: orderid + search
|
||||
function get_vaccines()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
$search = trim($prm['search'] ?? '');
|
||||
|
||||
if (!$orderid) { $this->sys_error("orderid required"); exit; }
|
||||
|
||||
// Ambil MOU dari order
|
||||
$order_row = $this->db_oneklinik->query(
|
||||
"SELECT orderM_MouID FROM one_klinik.`order` WHERE orderID = ? LIMIT 1",
|
||||
[$orderid]
|
||||
)->row_array();
|
||||
|
||||
if (!$order_row || !$order_row['orderM_MouID']) {
|
||||
$this->sys_ok(['records' => []]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$mou_id = intval($order_row['orderM_MouID']);
|
||||
$search_esc = $this->db_onedev->escape_str($search);
|
||||
|
||||
$sql = "SELECT
|
||||
spm.Ss_PriceMouID as ss_price_mou_id,
|
||||
spm.Ss_PriceMouM_MouID as mouid,
|
||||
0 as xid,
|
||||
spm.Nat_TestID as nat_testid,
|
||||
spm.nat_test,
|
||||
spm.is_packet,
|
||||
spm.packet_id,
|
||||
spm.px_type as type,
|
||||
spm.T_TestID as pxid,
|
||||
t.T_TestCode as pxcode,
|
||||
t.T_TestSasCode as pxsascode,
|
||||
t.T_TestName as test_name,
|
||||
CONCAT(t.T_TestSasCode,' ',t.T_TestName) as pxname,
|
||||
t.T_TestIsResult as isresult,
|
||||
JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceAmount')) as bruto,
|
||||
JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDisc')) as discountpersen,
|
||||
JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDiscRp')) as discountrp,
|
||||
if(JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDisc')) <> 0,
|
||||
(((JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDisc')) / 100)
|
||||
* JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceAmount')))
|
||||
+ JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDiscRp'))),
|
||||
JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDiscRp'))
|
||||
) as discount,
|
||||
( JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceAmount'))
|
||||
- ((JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDisc')) / 100)
|
||||
* JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceAmount')))
|
||||
- JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDiscRp'))
|
||||
) as total,
|
||||
spm.child_test
|
||||
FROM one_lab.ss_price_mou spm
|
||||
JOIN one_lab.t_test t ON spm.T_TestID = t.T_TestID AND t.T_TestIsActive = 'Y'
|
||||
WHERE spm.Ss_PriceMouM_MouID = {$mou_id}
|
||||
AND spm.is_packet = 'N'
|
||||
AND spm.px_type = 'PX'
|
||||
AND CONCAT(t.T_TestSasCode,' ',t.T_TestName) LIKE CONCAT('%', '{$search_esc}', '%')
|
||||
ORDER BY t.T_TestName
|
||||
LIMIT 50";
|
||||
|
||||
$q = $this->db_onedev->query($sql);
|
||||
if (!$q) { $this->sys_error_db("get jenis vaksin", $this->db_onedev); exit; }
|
||||
|
||||
$records = array_map(function($row) {
|
||||
$row['nat_test'] = json_decode($row['nat_test'] ?? '[]', true) ?: [];
|
||||
$row['child_test'] = json_decode($row['child_test'] ?? '[]', true) ?: [];
|
||||
return $row;
|
||||
}, $q->result_array());
|
||||
|
||||
$this->sys_ok(['records' => $records]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// List vaksin yang sudah tersimpan untuk satu order
|
||||
function list_order_vaccines()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
if (!$orderid) { $this->sys_error("orderid required"); exit; }
|
||||
|
||||
$sql = "SELECT
|
||||
ov.*,
|
||||
t.T_TestName as jenis_vaksin_name,
|
||||
t.T_TestSasCode as jenis_vaksin_code,
|
||||
ins.M_InjectionSiteName as injection_site_name,
|
||||
rv.M_RouteVaccineName as route_name,
|
||||
s.M_StaffName as petugas_name
|
||||
FROM one_klinik.order_vaccine ov
|
||||
LEFT JOIN one_lab.t_test t ON ov.orderVaccineT_TestID = t.T_TestID
|
||||
LEFT JOIN one_klinik.m_injection_site ins
|
||||
ON ov.orderVaccineInjectionSiteCode = ins.M_InjectionSiteCode
|
||||
LEFT JOIN one_klinik.m_route_vaccine rv
|
||||
ON ov.orderVaccineRouteCode = rv.M_RouteVaccineCode
|
||||
LEFT JOIN one_lab.m_staff s ON ov.orderVaccinePetugasM_StaffID = s.M_StaffID
|
||||
WHERE ov.orderVaccineOrderID = ?
|
||||
AND ov.orderVaccineIsActive = 'Y'
|
||||
ORDER BY ov.orderVaccineCreated ASC";
|
||||
|
||||
$q = $this->db_oneklinik->query($sql, [$orderid]);
|
||||
if (!$q) { $this->sys_error_db("list order_vaccine", $this->db_oneklinik); exit; }
|
||||
|
||||
$this->sys_ok(['records' => $q->result_array()]);
|
||||
exit;
|
||||
}
|
||||
|
||||
function save_vaccine()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$userID = $this->sys_user['M_UserID'];
|
||||
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
$vaccine_id = intval($prm['vaccine_id'] ?? 0); // orderVaccineID; 0 = insert baru
|
||||
$t_test_id = intval($prm['t_test_id'] ?? 0);
|
||||
|
||||
if (!$orderid || !$t_test_id) {
|
||||
$this->sys_error("orderid dan t_test_id wajib diisi");
|
||||
exit;
|
||||
}
|
||||
|
||||
$batch = trim($prm['batch_number'] ?? '');
|
||||
$expired = trim($prm['expired_date'] ?? '');
|
||||
$dosis = max(1, intval($prm['dosis'] ?? 1));
|
||||
$site_code = trim($prm['injection_site_code'] ?? '');
|
||||
$route_code = trim($prm['route_code'] ?? '');
|
||||
$petugas_id = isset($prm['petugas_id']) && $prm['petugas_id'] ? intval($prm['petugas_id']) : null;
|
||||
$given_at = trim($prm['given_at'] ?? '');
|
||||
$next_date = trim($prm['next_date'] ?? '');
|
||||
$catatan = trim($prm['catatan'] ?? '');
|
||||
$kipi = trim($prm['kipi'] ?? '');
|
||||
$observasi15 = ($prm['observasi_15'] ?? false) ? 'Y' : 'N';
|
||||
$reaksi_alergi = ($prm['reaksi_alergi'] ?? false) ? 'Y' : 'N';
|
||||
$ss_price_mou_id = isset($prm['ss_price_mou_id']) && $prm['ss_price_mou_id'] ? intval($prm['ss_price_mou_id']) : null;
|
||||
$bruto = floatval($prm['bruto'] ?? 0);
|
||||
$disc_persen = floatval($prm['discountpersen'] ?? 0);
|
||||
$disc_rp = floatval($prm['discountrp'] ?? 0);
|
||||
$total = floatval($prm['total'] ?? 0);
|
||||
|
||||
$given_at_sql = ($given_at && strtotime($given_at)) ? date('Y-m-d H:i:s', strtotime($given_at)) : date('Y-m-d H:i:s');
|
||||
$expired_val = ($expired && strtotime($expired)) ? date('Y-m-d', strtotime($expired)) : null;
|
||||
$next_date_val = ($next_date && strtotime($next_date)) ? date('Y-m-d', strtotime($next_date)) : null;
|
||||
|
||||
if ($vaccine_id > 0) {
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.order_vaccine SET
|
||||
orderVaccineT_TestID = ?,
|
||||
orderVaccineSsPriceMouID = ?,
|
||||
orderVaccineBruto = ?,
|
||||
orderVaccineDiscPersen = ?,
|
||||
orderVaccineDiscRp = ?,
|
||||
orderVaccineTotal = ?,
|
||||
orderVaccineBatchNumber = ?,
|
||||
orderVaccineExpiredDate = ?,
|
||||
orderVaccineDosis = ?,
|
||||
orderVaccineInjectionSiteCode = ?,
|
||||
orderVaccineRouteCode = ?,
|
||||
orderVaccinePetugasM_StaffID = ?,
|
||||
orderVaccineGivenAt = ?,
|
||||
orderVaccineNextDate = ?,
|
||||
orderVaccineCatatan = ?,
|
||||
orderVaccineKipi = ?,
|
||||
orderVaccineObservasi15 = ?,
|
||||
orderVaccineReaksiAlergi = ?,
|
||||
orderVaccineUserID = ?
|
||||
WHERE orderVaccineID = ? AND orderVaccineOrderID = ?",
|
||||
[
|
||||
$t_test_id, $ss_price_mou_id, $bruto, $disc_persen, $disc_rp, $total,
|
||||
$batch ?: null, $expired_val, $dosis,
|
||||
$site_code ?: null, $route_code ?: null, $petugas_id,
|
||||
$given_at_sql, $next_date_val, $catatan ?: null,
|
||||
$kipi ?: null, $observasi15, $reaksi_alergi,
|
||||
$userID, $vaccine_id, $orderid
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"INSERT INTO one_klinik.order_vaccine
|
||||
(orderVaccineOrderID, orderVaccineT_TestID,
|
||||
orderVaccineSsPriceMouID, orderVaccineBruto, orderVaccineDiscPersen,
|
||||
orderVaccineDiscRp, orderVaccineTotal,
|
||||
orderVaccineBatchNumber, orderVaccineExpiredDate, orderVaccineDosis,
|
||||
orderVaccineInjectionSiteCode, orderVaccineRouteCode,
|
||||
orderVaccinePetugasM_StaffID, orderVaccineGivenAt,
|
||||
orderVaccineNextDate, orderVaccineCatatan,
|
||||
orderVaccineKipi, orderVaccineObservasi15, orderVaccineReaksiAlergi,
|
||||
orderVaccineUserID)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||
[
|
||||
$orderid, $t_test_id,
|
||||
$ss_price_mou_id, $bruto, $disc_persen, $disc_rp, $total,
|
||||
$batch ?: null, $expired_val, $dosis,
|
||||
$site_code ?: null, $route_code ?: null, $petugas_id,
|
||||
$given_at_sql, $next_date_val, $catatan ?: null,
|
||||
$kipi ?: null, $observasi15, $reaksi_alergi, $userID
|
||||
]
|
||||
);
|
||||
$vaccine_id = $this->db_oneklinik->insert_id();
|
||||
}
|
||||
|
||||
if (!$ok) { $this->sys_error_db("save order_vaccine", $this->db_oneklinik); exit; }
|
||||
|
||||
$this->sys_ok(['orderVaccineID' => $vaccine_id]);
|
||||
exit;
|
||||
}
|
||||
|
||||
function delete_vaccine()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$vaccine_id = intval($prm['orderVaccineID'] ?? 0);
|
||||
$userID = $this->sys_user['M_UserID'];
|
||||
|
||||
if (!$vaccine_id) { $this->sys_error("orderVaccineID required"); exit; }
|
||||
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.order_vaccine SET orderVaccineIsActive = 'N', orderVaccineUserID = ?
|
||||
WHERE orderVaccineID = ?",
|
||||
[$userID, $vaccine_id]
|
||||
);
|
||||
if (!$ok) { $this->sys_error_db("delete order_vaccine", $this->db_oneklinik); exit; }
|
||||
|
||||
$this->sys_ok(['msg' => 'deleted']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── TINDAKAN MEDIS ────────────────────────────────────────────────────────
|
||||
|
||||
// Autocomplete jenis tindakan dari ss_price_mou berdasarkan MOU order
|
||||
function get_tindakan()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
$search = trim($prm['search'] ?? '');
|
||||
|
||||
if (!$orderid) { $this->sys_error("orderid required"); exit; }
|
||||
|
||||
$order_row = $this->db_oneklinik->query(
|
||||
"SELECT orderM_MouID FROM one_klinik.`order` WHERE orderID = ? LIMIT 1",
|
||||
[$orderid]
|
||||
)->row_array();
|
||||
|
||||
if (!$order_row || !$order_row['orderM_MouID']) {
|
||||
$this->sys_ok(['records' => []]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$mou_id = intval($order_row['orderM_MouID']);
|
||||
$search_esc = $this->db_onedev->escape_str($search);
|
||||
|
||||
$sql = "SELECT
|
||||
spm.Ss_PriceMouID as ss_price_mou_id,
|
||||
spm.Ss_PriceMouM_MouID as mouid,
|
||||
0 as xid,
|
||||
spm.Nat_TestID as nat_testid,
|
||||
spm.nat_test,
|
||||
spm.is_packet,
|
||||
spm.packet_id,
|
||||
spm.px_type as type,
|
||||
spm.T_TestID as pxid,
|
||||
t.T_TestCode as pxcode,
|
||||
t.T_TestSasCode as pxsascode,
|
||||
t.T_TestName as test_name,
|
||||
CONCAT(t.T_TestSasCode,' ',t.T_TestName) as pxname,
|
||||
t.T_TestIsResult as isresult,
|
||||
JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceAmount')) as bruto,
|
||||
JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDisc')) as discountpersen,
|
||||
JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDiscRp')) as discountrp,
|
||||
if(JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDisc')) <> 0,
|
||||
(((JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDisc')) / 100)
|
||||
* JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceAmount')))
|
||||
+ JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDiscRp'))),
|
||||
JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDiscRp'))
|
||||
) as discount,
|
||||
( JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceAmount'))
|
||||
- ((JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDisc')) / 100)
|
||||
* JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceAmount')))
|
||||
- JSON_UNQUOTE(JSON_EXTRACT(one_json_sum(spm.Ss_PriceMouID),'$.T_PriceDiscRp'))
|
||||
) as total,
|
||||
spm.child_test
|
||||
FROM one_lab.ss_price_mou spm
|
||||
JOIN one_lab.t_test t ON spm.T_TestID = t.T_TestID AND t.T_TestIsActive = 'Y'
|
||||
WHERE spm.Ss_PriceMouM_MouID = {$mou_id}
|
||||
AND spm.is_packet = 'N'
|
||||
AND spm.px_type = 'PX'
|
||||
AND CONCAT(t.T_TestSasCode,' ',t.T_TestName) LIKE CONCAT('%', '{$search_esc}', '%')
|
||||
ORDER BY t.T_TestName
|
||||
LIMIT 50";
|
||||
|
||||
$q = $this->db_onedev->query($sql);
|
||||
if (!$q) { $this->sys_error_db("get jenis tindakan", $this->db_onedev); exit; }
|
||||
|
||||
$records = array_map(function($row) {
|
||||
$row['nat_test'] = json_decode($row['nat_test'] ?? '[]', true) ?: [];
|
||||
$row['child_test'] = json_decode($row['child_test'] ?? '[]', true) ?: [];
|
||||
return $row;
|
||||
}, $q->result_array());
|
||||
|
||||
$this->sys_ok(['records' => $records]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// List tindakan yang sudah tersimpan untuk satu order
|
||||
function list_order_tindakan()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
if (!$orderid) { $this->sys_error("orderid required"); exit; }
|
||||
|
||||
$sql = "SELECT
|
||||
ot.*,
|
||||
t.T_TestName as jenis_tindakan_name,
|
||||
t.T_TestSasCode as jenis_tindakan_code,
|
||||
d.M_DoctorName as dokter_name
|
||||
FROM one_klinik.order_tindakan ot
|
||||
LEFT JOIN one_lab.t_test t ON ot.orderTindakanT_TestID = t.T_TestID
|
||||
LEFT JOIN one_lab.m_doctor d ON ot.orderTindakanM_DoctorID = d.M_DoctorID
|
||||
WHERE ot.orderTindakanOrderID = ?
|
||||
AND ot.orderTindakanIsActive = 'Y'
|
||||
ORDER BY ot.orderTindakanCreated ASC";
|
||||
|
||||
$q = $this->db_oneklinik->query($sql, [$orderid]);
|
||||
if (!$q) { $this->sys_error_db("list order_tindakan", $this->db_oneklinik); exit; }
|
||||
|
||||
$this->sys_ok(['records' => $q->result_array()]);
|
||||
exit;
|
||||
}
|
||||
|
||||
function save_tindakan()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$userID = $this->sys_user['M_UserID'];
|
||||
|
||||
$orderid = intval($prm['orderid'] ?? 0);
|
||||
$tindakan_id = intval($prm['tindakan_id'] ?? 0); // orderTindakanID; 0 = insert baru
|
||||
$t_test_id = intval($prm['t_test_id'] ?? 0);
|
||||
|
||||
if (!$orderid || !$t_test_id) {
|
||||
$this->sys_error("orderid dan t_test_id wajib diisi");
|
||||
exit;
|
||||
}
|
||||
|
||||
$doctor_id = isset($prm['doctor_id']) && $prm['doctor_id'] ? intval($prm['doctor_id']) : null;
|
||||
$performed_at = trim($prm['performed_at'] ?? '');
|
||||
$catatan = trim($prm['catatan'] ?? '');
|
||||
$ss_price_mou_id = isset($prm['ss_price_mou_id']) && $prm['ss_price_mou_id'] ? intval($prm['ss_price_mou_id']) : null;
|
||||
$bruto = floatval($prm['bruto'] ?? 0);
|
||||
$disc_persen = floatval($prm['discountpersen'] ?? 0);
|
||||
$disc_rp = floatval($prm['discountrp'] ?? 0);
|
||||
$total = floatval($prm['total'] ?? 0);
|
||||
|
||||
$performed_at_sql = ($performed_at && strtotime($performed_at))
|
||||
? date('Y-m-d H:i:s', strtotime($performed_at))
|
||||
: date('Y-m-d H:i:s');
|
||||
|
||||
if ($tindakan_id > 0) {
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.order_tindakan SET
|
||||
orderTindakanT_TestID = ?,
|
||||
orderTindakanSsPriceMouID = ?,
|
||||
orderTindakanBruto = ?,
|
||||
orderTindakanDiscPersen = ?,
|
||||
orderTindakanDiscRp = ?,
|
||||
orderTindakanTotal = ?,
|
||||
orderTindakanM_DoctorID = ?,
|
||||
orderTindakanPerformedAt = ?,
|
||||
orderTindakanCatatan = ?,
|
||||
orderTindakanUserID = ?
|
||||
WHERE orderTindakanID = ? AND orderTindakanOrderID = ?",
|
||||
[
|
||||
$t_test_id, $ss_price_mou_id, $bruto, $disc_persen, $disc_rp, $total,
|
||||
$doctor_id, $performed_at_sql, $catatan ?: null,
|
||||
$userID, $tindakan_id, $orderid
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"INSERT INTO one_klinik.order_tindakan
|
||||
(orderTindakanOrderID, orderTindakanT_TestID,
|
||||
orderTindakanSsPriceMouID, orderTindakanBruto, orderTindakanDiscPersen,
|
||||
orderTindakanDiscRp, orderTindakanTotal,
|
||||
orderTindakanM_DoctorID, orderTindakanPerformedAt,
|
||||
orderTindakanCatatan, orderTindakanUserID)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?)",
|
||||
[
|
||||
$orderid, $t_test_id,
|
||||
$ss_price_mou_id, $bruto, $disc_persen, $disc_rp, $total,
|
||||
$doctor_id, $performed_at_sql, $catatan ?: null, $userID
|
||||
]
|
||||
);
|
||||
$tindakan_id = $this->db_oneklinik->insert_id();
|
||||
}
|
||||
|
||||
if (!$ok) { $this->sys_error_db("save order_tindakan", $this->db_oneklinik); exit; }
|
||||
|
||||
$this->sys_ok(['orderTindakanID' => $tindakan_id]);
|
||||
exit;
|
||||
}
|
||||
|
||||
function delete_tindakan()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$tindakan_id = intval($prm['orderTindakanID'] ?? 0);
|
||||
$userID = $this->sys_user['M_UserID'];
|
||||
|
||||
if (!$tindakan_id) { $this->sys_error("orderTindakanID required"); exit; }
|
||||
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.order_tindakan SET orderTindakanIsActive = 'N', orderTindakanUserID = ?
|
||||
WHERE orderTindakanID = ?",
|
||||
[$userID, $tindakan_id]
|
||||
);
|
||||
if (!$ok) { $this->sys_error_db("delete order_tindakan", $this->db_oneklinik); exit; }
|
||||
|
||||
$this->sys_ok(['msg' => 'deleted']);
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -12,34 +12,29 @@ class Screening extends MY_Controller
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->db_oneklinik = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$id = $prm['id'];
|
||||
$id = $this->db_onedev->escape_str($prm['id']);
|
||||
|
||||
$sql = "SELECT orderID,
|
||||
orderDate,
|
||||
$sql = "SELECT orderID,
|
||||
orderDate,
|
||||
orderNumber,
|
||||
orderIsScreening,
|
||||
orderIsAnamnese,
|
||||
orderIsCheck,
|
||||
orderAge as patient_age,
|
||||
DATE_FORMAT(orderDate,'%d-%m-%Y') as order_date,
|
||||
orderM_ClinicUnitID,
|
||||
'N' divider,
|
||||
M_PatientID,
|
||||
M_PatientNoReg,
|
||||
M_PatientPrefix,
|
||||
M_PatientName,
|
||||
M_PatientSuffix,
|
||||
M_PatientHP,
|
||||
M_PatientEmail,
|
||||
M_PatientPOB,
|
||||
M_PatientPhone,
|
||||
M_PatientIDNumber,
|
||||
DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as M_PatientDOB,
|
||||
concat(M_TitleName,' ',IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) M_PatientNameRaw,
|
||||
M_PatientNote,
|
||||
M_PatientNIK,
|
||||
M_PatientJabatan,
|
||||
@@ -49,78 +44,178 @@ class Screening extends MY_Controller
|
||||
M_PatientJob,
|
||||
M_PatientM_SexID,
|
||||
M_SexName,
|
||||
M_TitleID, M_TitleName,
|
||||
M_PatientM_TitleID,
|
||||
M_TitleName,
|
||||
M_PatientM_ReligionID,
|
||||
M_ReligionName,
|
||||
IFNULL(M_ReligionName,'-') M_ReligionName,
|
||||
M_PatientM_IdTypeID,
|
||||
M_IdTypeName,
|
||||
M_PatientIDNumber,
|
||||
IF(ISNULL(M_PatientSuspendID),'active','suspend' ) as status,
|
||||
M_PatientAddressM_KelurahanID M_KelurahanID,
|
||||
0 M_DistrictID,
|
||||
0 M_CityID,
|
||||
0 M_ProvinceID
|
||||
FROM one_klinik.order
|
||||
IF(ISNULL(M_PatientSuspendID),'active','suspend') as status,
|
||||
M_PatientAddressRegionalCd,
|
||||
M_PatientName_enc, M_PatientHP_enc, M_PatientDOB_enc,
|
||||
M_PatientEmail_enc, M_PatientPhone_enc, M_PatientPOB_enc,
|
||||
M_PatientIDNumber_enc, M_PatientNIK_enc, M_PatientAddressDescription_enc
|
||||
FROM one_klinik.`order`
|
||||
JOIN m_patient ON M_PatientID = orderM_PatientID AND M_PatientIsActive = 'Y'
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
JOIN m_branch ON M_BranchIsActive = 'Y' AND M_BranchIsDefault = 'Y'
|
||||
JOIN m_patientaddress ON M_PatientAddressM_PatientID = M_PatientID AND M_PatientAddressIsActive = 'Y'
|
||||
LEFT JOIN m_idtype ON M_IdTypeID = M_PatientM_IdTypeID AND M_IdTypeIsActive = 'Y'
|
||||
LEFT JOIN m_religion ON m_patientm_religionid = m_religionid
|
||||
LEFT JOIN m_religion ON M_PatientM_ReligionID = M_ReligionID
|
||||
LEFT JOIN m_patientsuspend ON M_PatientSuspendM_PatientID = M_PatientID AND M_PatientSuspendIsActive = 'Y'
|
||||
WHERE
|
||||
orderNumber = '{$id}' AND
|
||||
M_PatientSuspendID IS NULL
|
||||
|
||||
WHERE orderNumber = '{$id}' AND M_PatientSuspendID IS NULL
|
||||
GROUP BY M_PatientID";
|
||||
//echo $sql;
|
||||
|
||||
$query = $this->db_onedev->query($sql);
|
||||
|
||||
if ($query) {
|
||||
$rows = $query->result_array();
|
||||
|
||||
foreach ($rows as $k => $v)
|
||||
{
|
||||
$rows[$k]['M_PatientName'] = stripslashes($rows[$k]['M_PatientName']);
|
||||
$rows[$k]['M_PatientAddressDescription'] = stripslashes($v['M_PatientAddressDescription']);
|
||||
$patient_name = str_replace("'", "\\'", $prm['M_PatientName']);
|
||||
$sql = "SELECT *, concat('{$rows[$k]['M_PatientAddressDescription'] }', '\n\n',
|
||||
m_kelurahanname, ', ',
|
||||
m_districtname,'\n',
|
||||
m_cityname, ', ',
|
||||
m_provincename) as xaddress
|
||||
FROM m_kelurahan
|
||||
JOIN m_district ON M_KelurahanM_DistrictID = M_DistrictID
|
||||
JOIN m_city ON M_DistrictM_CityID = M_CityID
|
||||
JOIN m_province ON M_CityM_ProvinceID = M_ProvinceID
|
||||
WHERE
|
||||
M_KelurahanID = {$v['M_KelurahanID']} ";
|
||||
//echo $sql;
|
||||
$row_address = $this->db_onedev->query($sql)->row_array();
|
||||
$rows[$k]['M_PatientAddress'] = stripslashes($row_address['xaddress']);
|
||||
$rows[$k]['M_DistrictID'] = $row_address['M_DistrictID'];
|
||||
$rows[$k]['M_CityID'] = $row_address['M_CityID'];
|
||||
$rows[$k]['M_ProvinceID'] = $row_address['M_ProvinceID'];
|
||||
$info = $this->db_onedev->query("SELECT fn_fo_patient_visit(?) info", [$v['M_PatientID']])->row();
|
||||
$rows[$k]['info'] = json_decode($info->info);
|
||||
|
||||
}
|
||||
|
||||
$result = array("total" => 1, "records" => $rows, "sql"=> $this->db_onedev->last_query());
|
||||
$this->sys_ok($result);
|
||||
}
|
||||
else {
|
||||
$this->sys_error_db("m_patient rows",$this->db_onedev);
|
||||
exit;
|
||||
if (!$query) {
|
||||
$this->sys_error_db("order rows", $this->db_onedev);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
$rows = $query->result_array();
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
foreach ($rows as $k => $v) {
|
||||
$rows[$k]['M_PatientName'] = $enc->decrypt($v['M_PatientName_enc']) ?? $v['M_PatientNameRaw'];
|
||||
$rows[$k]['M_PatientHP'] = $enc->decrypt($v['M_PatientHP_enc']) ?? '';
|
||||
$rows[$k]['M_PatientEmail'] = $enc->decrypt($v['M_PatientEmail_enc']) ?? '';
|
||||
$rows[$k]['M_PatientPOB'] = $enc->decrypt($v['M_PatientPOB_enc']) ?? '';
|
||||
$rows[$k]['M_PatientPhone'] = $enc->decrypt($v['M_PatientPhone_enc']) ?? '';
|
||||
$rows[$k]['M_PatientIDNumber'] = $enc->decrypt($v['M_PatientIDNumber_enc']) ?? '';
|
||||
$rows[$k]['M_PatientNIK'] = $enc->decrypt($v['M_PatientNIK_enc']) ?? '';
|
||||
$rows[$k]['M_PatientDOB'] = $enc->decrypt($v['M_PatientDOB_enc']) ?? '';
|
||||
$rows[$k]['dob_ina'] = $rows[$k]['M_PatientDOB'];
|
||||
$rows[$k]['M_PatientAddressDescription'] = $enc->decrypt($v['M_PatientAddressDescription_enc']) ?? '';
|
||||
$rows[$k]['M_PatientAddress'] = $rows[$k]['M_PatientAddressDescription'];
|
||||
|
||||
function get_data(){
|
||||
foreach (array_keys($rows[$k]) as $col) {
|
||||
if (substr($col, -4) === '_enc') unset($rows[$k][$col]);
|
||||
}
|
||||
unset($rows[$k]['M_PatientNameRaw']);
|
||||
|
||||
$rows[$k]['info'] = $this->build_patient_visit_info($v['M_PatientID'], $rows[$k]['M_PatientDOB']);
|
||||
|
||||
// Screening template berdasarkan poli order
|
||||
$cu_id = $v['orderM_ClinicUnitID'] ?? null;
|
||||
$rows[$k]['screening_template'] = null;
|
||||
$rows[$k]['screening_forms'] = null;
|
||||
$rows[$k]['order_screening'] = null;
|
||||
|
||||
if ($cu_id) {
|
||||
$tpl = $this->db_oneklinik->query(
|
||||
"SELECT st.M_ScreeningTemplateID, st.M_ScreeningTemplateCode, st.M_ScreeningTemplateName
|
||||
FROM one_klinik.m_clinic_unit cu
|
||||
JOIN one_klinik.m_screening_template st
|
||||
ON st.M_ScreeningTemplateID = cu.M_ClinicUnitM_ScreeningTemplateID
|
||||
WHERE cu.M_ClinicUnitID = ?", [$cu_id]
|
||||
)->row_array();
|
||||
|
||||
$rows[$k]['screening_template'] = $tpl ?: null;
|
||||
|
||||
if ($tpl && $tpl['M_ScreeningTemplateCode'] !== 'DEFAULT') {
|
||||
// Template dinamis (VAKSINASI / KHITAN): ambil form + jawaban yang sudah ada
|
||||
$forms = $this->db_oneklinik->query(
|
||||
"SELECT sf.M_ScreeningFormID,
|
||||
sf.M_ScreeningFormQuestion,
|
||||
sf.M_ScreeningFormAnswerType,
|
||||
sf.M_ScreeningFormOptions,
|
||||
sf.M_ScreeningFormSortOrder,
|
||||
sf.M_ScreeningFormIsRequired,
|
||||
sa.T_ScreeningAnswerValue AS answer
|
||||
FROM one_klinik.m_screening_form sf
|
||||
LEFT JOIN one_klinik.t_screening_answer sa
|
||||
ON sa.T_ScreeningAnswerM_ScreeningFormID = sf.M_ScreeningFormID
|
||||
AND sa.T_ScreeningAnswerOrderID = ?
|
||||
AND sa.T_ScreeningAnswerIsActive = 'Y'
|
||||
WHERE sf.M_ScreeningFormM_ScreeningTemplateID = ?
|
||||
AND sf.M_ScreeningFormIsActive = 'Y'
|
||||
ORDER BY sf.M_ScreeningFormSortOrder",
|
||||
[$v['orderID'], $tpl['M_ScreeningTemplateID']]
|
||||
)->result_array();
|
||||
|
||||
foreach ($forms as &$f) {
|
||||
$f['M_ScreeningFormOptions'] = $f['M_ScreeningFormOptions']
|
||||
? json_decode($f['M_ScreeningFormOptions'], true)
|
||||
: null;
|
||||
$f['answer'] = $f['answer'] !== null
|
||||
? json_decode($f['answer'], true)
|
||||
: null;
|
||||
|
||||
// Tandai option terpilih dengan value:true agar FE bisa render form pre-filled
|
||||
if ($f['answer'] && $f['M_ScreeningFormOptions'] && $f['M_ScreeningFormAnswerType'] !== 'text') {
|
||||
if ($f['M_ScreeningFormAnswerType'] === 'single') {
|
||||
$selected = [$f['answer']['id'] ?? ''];
|
||||
} else {
|
||||
$selected = array_column((array)$f['answer'], 'id');
|
||||
}
|
||||
foreach ($f['M_ScreeningFormOptions'] as &$opt) {
|
||||
$opt['value'] = in_array($opt['id'], $selected);
|
||||
}
|
||||
unset($opt);
|
||||
}
|
||||
}
|
||||
unset($f);
|
||||
|
||||
$rows[$k]['screening_forms'] = $forms;
|
||||
} else {
|
||||
// DEFAULT: pakai order_screening lama
|
||||
$rows[$k]['order_screening'] = $this->db_oneklinik->query(
|
||||
"SELECT * FROM one_klinik.order_screening
|
||||
WHERE orderScreeningOrderID = ? AND orderScreeningIsActive = 'Y'",
|
||||
[$v['orderID']]
|
||||
)->row_array() ?: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->sys_ok(["total" => count($rows), "records" => $rows]);
|
||||
}
|
||||
|
||||
protected function build_patient_visit_info($patient_id, $patient_dob)
|
||||
{
|
||||
$visit = 1;
|
||||
$birthday = 'N';
|
||||
|
||||
$visit_query = $this->db_onedev->query(
|
||||
"SELECT COUNT(DISTINCT T_OrderHeaderID) AS n
|
||||
FROM t_orderheader
|
||||
JOIN t_orderdetail ON T_OrderHeaderID = T_OrderDetailT_OrderHeaderID AND T_OrderDetailIsActive = 'Y'
|
||||
WHERE T_OrderHeaderIsActive = 'Y'
|
||||
AND T_OrderHeaderM_PatientID = ?",
|
||||
[$patient_id]
|
||||
);
|
||||
|
||||
if ($visit_query) {
|
||||
$visit_row = $visit_query->row_array();
|
||||
$visit += (int) ($visit_row['n'] ?? 0);
|
||||
}
|
||||
|
||||
$init_visit_query = $this->db_onedev->query(
|
||||
"SELECT M_PatientInitialVisit
|
||||
FROM m_patient
|
||||
WHERE M_PatientID = ?",
|
||||
[$patient_id]
|
||||
);
|
||||
|
||||
if ($init_visit_query) {
|
||||
$init_visit_row = $init_visit_query->row_array();
|
||||
if (!empty($init_visit_row['M_PatientInitialVisit'])) {
|
||||
$visit += (int) $init_visit_row['M_PatientInitialVisit'];
|
||||
}
|
||||
}
|
||||
|
||||
$dob_time = empty($patient_dob) ? false : strtotime($patient_dob);
|
||||
if ($dob_time !== false) {
|
||||
$birthday = date('m-d', $dob_time) === date('m-d') ? 'Y' : 'N';
|
||||
}
|
||||
|
||||
return json_decode(json_encode([
|
||||
'visit' => $visit,
|
||||
'birthday' => $birthday,
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
function get_data(){
|
||||
if (! $this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
@@ -154,6 +249,48 @@ class Screening extends MY_Controller
|
||||
}
|
||||
|
||||
|
||||
function getsexreg()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
$rows = [];
|
||||
$rows['default_location'] = [];
|
||||
|
||||
$rows['doctors'] = $this->db_onedev->query(
|
||||
"SELECT M_DoctorID as id, M_DoctorCode as code, M_DoctorName as name,
|
||||
M_DoctorMcuDefaultKlinik as is_default, M_DoctorMcuPriceKlinik as price
|
||||
FROM m_doctormcu JOIN m_doctor ON M_DoctorMcuM_DoctorID = M_DoctorID
|
||||
WHERE M_DoctorMcuIsActive = 'Y'"
|
||||
)->result_array();
|
||||
|
||||
$rows['default_doctor'] = [];
|
||||
foreach ($rows['doctors'] as $value) {
|
||||
if ($value['is_default'] == 'Y') { $rows['default_doctor'] = $value; break; }
|
||||
}
|
||||
|
||||
$rows['titles'] = $this->db_onedev->query("SELECT * FROM m_title WHERE M_TitleIsActive = 'Y'")->result_array();
|
||||
$rows['sexes'] = $this->db_onedev->query("SELECT * FROM m_sex WHERE M_SexIsActive = 'Y'")->result_array();
|
||||
$rows['religions'] = $this->db_onedev->query("SELECT * FROM m_religion WHERE M_ReligionIsActive = 'Y'")->result_array();
|
||||
$rows['kartuidentitass'] = $this->db_onedev->query("SELECT * FROM m_idtype WHERE M_IdTypeIsActive = 'Y'")->result_array();
|
||||
|
||||
$branch = $this->db_onedev->query("SELECT * FROM m_branch WHERE M_BranchIsDefault = 'Y' AND M_BranchIsActive = 'Y'")->row_array();
|
||||
if ($branch) {
|
||||
$rows['default_location']['city_address'] = $this->db_onedev->query("SELECT * FROM m_city WHERE M_CityIsActive = 'Y' AND M_CityID = ?", [$branch['M_BranchM_CityID']])->row_array();
|
||||
$rows['default_location']['cities'] = $this->db_onedev->query("SELECT * FROM m_city WHERE M_CityIsActive = 'Y' AND M_CityM_ProvinceID = ?", [$rows['default_location']['city_address']['M_CityM_ProvinceID']])->result_array();
|
||||
$rows['default_location']['province_address'] = $this->db_onedev->query("SELECT * FROM m_province WHERE M_ProvinceIsActive = 'Y' AND M_ProvinceID = ?", [$rows['default_location']['city_address']['M_CityM_ProvinceID']])->row_array();
|
||||
$rows['default_location']['provinces'] = $this->db_onedev->query("SELECT * FROM m_province WHERE M_ProvinceIsActive = 'Y'")->result_array();
|
||||
$rows['default_location']['districts'] = $this->db_onedev->query("SELECT * FROM m_district WHERE M_DistrictIsActive = 'Y' AND M_DistrictM_CityID = ?", [$branch['M_BranchM_CityID']])->result_array();
|
||||
$rows['default_location']['district_address'] = $this->db_onedev->query("SELECT * FROM m_district WHERE M_DistrictIsActive = 'Y' AND M_DistrictID = ?", [$branch['M_BranchM_DistrictID']])->row_array();
|
||||
$rows['default_location']['kelurahans'] = $this->db_onedev->query("SELECT * FROM m_kelurahan WHERE M_KelurahanIsActive = 'Y' AND M_KelurahanM_DistrictID = ?", [$branch['M_BranchM_DistrictID']])->result_array();
|
||||
$rows['default_location']['kelurahan_address'] = $this->db_onedev->query("SELECT * FROM m_kelurahan WHERE M_KelurahanIsActive = 'Y' AND M_KelurahanID = ?", [$branch['M_BranchM_KelurahanID']])->row_array();
|
||||
}
|
||||
|
||||
$this->sys_ok(["total" => count($rows), "records" => $rows]);
|
||||
exit;
|
||||
}
|
||||
|
||||
protected function objToArray($obj)
|
||||
{
|
||||
// Not an object or array
|
||||
@@ -184,26 +321,47 @@ class Screening extends MY_Controller
|
||||
$status = $prm['status'];
|
||||
|
||||
$sql = "SELECT 'N' divider,
|
||||
CONCAT(IF(ISNULL(M_TitleName),'',CONCAT(M_TitleName,'. ')),M_PatientName) as patient_name,
|
||||
M_PatientName, M_PatientName_enc,
|
||||
M_PatientHP, M_PatientHP_enc,
|
||||
M_PatientDOB, M_PatientDOB_enc,
|
||||
M_PatientEmail, M_PatientEmail_enc,
|
||||
M_PatientPhone, M_PatientPhone_enc,
|
||||
M_PatientPOB, M_PatientPOB_enc,
|
||||
M_PatientIDNumber, M_PatientIDNumber_enc,
|
||||
M_PatientNIK, M_PatientNIK_enc,
|
||||
M_PatientPhoto, M_PatientPhotoThumb,
|
||||
`order`.*,DATE_FORMAT(orderDate,'%d-%m-%Y') as date_order,
|
||||
'' as kode_status, '' as status
|
||||
'' as kode_status, '' as status,
|
||||
M_TitleName, M_PatientNoReg, M_PatientM_SexID
|
||||
FROM one_klinik.`order`
|
||||
JOIN m_patient ON orderM_PatientID = M_PatientID
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
WHERE
|
||||
orderIsActive = 'Y' AND DATE(orderDate) = ? AND orderIsScreening = ?
|
||||
WHERE
|
||||
orderIsActive = 'Y' AND DATE(orderDate) = ? AND orderIsScreening = ?
|
||||
LIMIT $number_limit offset $number_offset";
|
||||
//echo $sql;
|
||||
$query = $this->db_oneklinik->query($sql,array($xdate,$status));
|
||||
//echo $this->db_oneklinik->last_query();
|
||||
|
||||
if ($query) {
|
||||
if ($query) {
|
||||
$rows = $query->result_array();
|
||||
$result = array("total" => $tot_page, "records" => $rows, "sql"=> $this->db_onedev->last_query());
|
||||
$enc = $this->ibl_encryptor;
|
||||
foreach ($rows as $k => $v) {
|
||||
$rows[$k]['M_PatientName'] = $enc->decrypt($v['M_PatientName_enc'] ?? '') ?: $v['M_PatientName'];
|
||||
$rows[$k]['M_PatientHP'] = $enc->decrypt($v['M_PatientHP_enc'] ?? '') ?: $v['M_PatientHP'];
|
||||
$rows[$k]['M_PatientDOB'] = $enc->decrypt($v['M_PatientDOB_enc'] ?? '') ?: $v['M_PatientDOB'];
|
||||
$rows[$k]['M_PatientEmail'] = $enc->decrypt($v['M_PatientEmail_enc'] ?? '') ?: $v['M_PatientEmail'];
|
||||
$rows[$k]['M_PatientPhone'] = $enc->decrypt($v['M_PatientPhone_enc'] ?? '') ?: $v['M_PatientPhone'];
|
||||
$rows[$k]['M_PatientPOB'] = $enc->decrypt($v['M_PatientPOB_enc'] ?? '') ?: $v['M_PatientPOB'];
|
||||
$rows[$k]['M_PatientIDNumber'] = $enc->decrypt($v['M_PatientIDNumber_enc'] ?? '') ?: $v['M_PatientIDNumber'];
|
||||
$rows[$k]['M_PatientNIK'] = $enc->decrypt($v['M_PatientNIK_enc'] ?? '') ?: $v['M_PatientNIK'];
|
||||
$rows[$k]['patient_name'] = trim(($v['M_TitleName'] ?? '') . ' ' . $rows[$k]['M_PatientName']);
|
||||
}
|
||||
$result = array("total" => $tot_page, "records" => $rows, "sql"=> $this->db_oneklinik->last_query());
|
||||
$this->sys_ok($result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$this->sys_error_db("m_patient rows",$this->db_onedev);
|
||||
$this->sys_error_db("m_patient rows",$this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -297,124 +455,7 @@ class Screening extends MY_Controller
|
||||
}
|
||||
|
||||
function end_session(){
|
||||
if (! $this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$userID = $this->sys_user['M_UserID'];
|
||||
//print_r($prm['subgroup']);
|
||||
|
||||
$sql = "SELECT COUNT(*) as xcount
|
||||
FROM one_klinik.order_screening
|
||||
WHERE
|
||||
orderScreeningOrderID = ? AND orderScreeningIsActive = 'Y'";
|
||||
$query = $this->db_oneklinik->query($sql,array($prm['orderID']));
|
||||
if(!$query){
|
||||
|
||||
$this->sys_error("count exist");
|
||||
echo $this->db_oneklinik->last_query();
|
||||
}
|
||||
|
||||
$check_exist = $query->row()->xcount;
|
||||
|
||||
if($check_exist == 0){
|
||||
$sql = "INSERT one_klinik.order_screening (
|
||||
orderScreeningOrderID,
|
||||
orderScreeningKesanUmum,
|
||||
orderScreeningValueKesadaran,
|
||||
orderScreeningValuePernafasan,
|
||||
orderScreeningValueResikoJatuh,
|
||||
orderScreeningValueNyeriDada,
|
||||
orderScreeningValueSkalaNyeri,
|
||||
orderScreeningValueBatuk,
|
||||
orderScreeningValueKeputusan,
|
||||
orderScreeningCreated,
|
||||
orderScreeningUserID
|
||||
)
|
||||
VALUES(
|
||||
?,?,?,?,?,?,?,?,?,NOW(),?
|
||||
)";
|
||||
$query = $this->db_oneklinik->query($sql,array(
|
||||
$prm['orderID'],
|
||||
$prm['kesan_umum'],
|
||||
$prm['kesadaran'],
|
||||
$prm['pernafasan'],
|
||||
$prm['resiko_jatuh'],
|
||||
$prm['nyeri_dada'],
|
||||
$prm['skala_nyeri'],
|
||||
$prm['batuk'],
|
||||
$prm['keputusan'],
|
||||
$userID)
|
||||
);
|
||||
if(!$query){
|
||||
$this->sys_error("Gagal insert");
|
||||
}
|
||||
}else{
|
||||
$sql = "UPDATE one_klinik.order_screening SET
|
||||
orderScreeningKesanUmum = ?,
|
||||
orderScreeningValueKesadaran = ?,
|
||||
orderScreeningValuePernafasan = ?,
|
||||
orderScreeningValueResikoJatuh = ?,
|
||||
orderScreeningValueNyeriDada = ?,
|
||||
orderScreeningValueSkalaNyeri = ?,
|
||||
orderScreeningValueBatuk = ?,
|
||||
orderScreeningValueKeputusan = ?,
|
||||
orderScreeningUserID = ?
|
||||
WHERE
|
||||
orderScreeningOrderID = ?
|
||||
";
|
||||
$query = $this->db_oneklinik->query($sql,[
|
||||
$prm['kesan_umum'],
|
||||
$prm['kesadaran'],
|
||||
$prm['pernafasan'],
|
||||
$prm['resiko_jatuh'],
|
||||
$prm['nyeri_dada'],
|
||||
$prm['skala_nyeri'],
|
||||
$prm['batuk'],
|
||||
$prm['keputusan'],
|
||||
$userID,
|
||||
$prm['orderID']
|
||||
]);
|
||||
if(!$query){
|
||||
echo $this->db_oneklinik->last_query();
|
||||
$this->sys_error("Gagal Update");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sql = "INSERT INTO one_klinik.order_status (
|
||||
orderStatusOrderID,
|
||||
orderStatusCode,
|
||||
orderStatusValue,
|
||||
orderStatusUserID
|
||||
)
|
||||
VALUES(
|
||||
?,?,?,?
|
||||
)";
|
||||
|
||||
$query = $this->db_oneklinik->query($sql,array($prm['orderID'],'S','D',$userID));
|
||||
if(!$query){
|
||||
$this->sys_error("Gagal End");
|
||||
}
|
||||
|
||||
$sql = "UPDATE one_klinik.`order` SET orderIsScreening = 'D', orderUserID = ?
|
||||
WHERE
|
||||
orderID = ?";
|
||||
|
||||
$query = $this->db_oneklinik->query($sql,array($userID,$prm['orderID']));
|
||||
if(!$query){
|
||||
$this->sys_error("Gagal ENd");
|
||||
}
|
||||
|
||||
|
||||
$result = array('process'=>'OK');
|
||||
|
||||
|
||||
|
||||
$this->sys_ok($result);
|
||||
exit;
|
||||
$this->endsession();
|
||||
}
|
||||
|
||||
|
||||
@@ -422,4 +463,149 @@ class Screening extends MY_Controller
|
||||
|
||||
|
||||
|
||||
|
||||
public function endsession()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$userID = $this->sys_user['M_UserID'];
|
||||
$orderID = intval($prm['orderID'] ?? 0);
|
||||
|
||||
if (!$orderID) {
|
||||
$this->sys_error("orderID required");
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Tandai order selesai screening + catat status
|
||||
$ok = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.`order` SET orderIsScreening = 'D', orderUserID = ? WHERE orderID = ?",
|
||||
[$userID, $orderID]
|
||||
);
|
||||
if (!$ok) {
|
||||
$this->sys_error_db("update order", $this->db_oneklinik);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->db_oneklinik->query(
|
||||
"INSERT INTO one_klinik.order_status
|
||||
(orderStatusOrderID, orderStatusCode, orderStatusValue, orderStatusUserID)
|
||||
VALUES (?, 'S', 'D', ?)",
|
||||
[$orderID, $userID]
|
||||
);
|
||||
|
||||
// 2. Tentukan template: ada screening_template_id dan bukan DEFAULT?
|
||||
$template_id = intval($prm['screening_template_id'] ?? 0);
|
||||
$is_default = true;
|
||||
|
||||
if ($template_id) {
|
||||
$tpl = $this->db_oneklinik->query(
|
||||
"SELECT M_ScreeningTemplateCode FROM one_klinik.m_screening_template
|
||||
WHERE M_ScreeningTemplateID = ?",
|
||||
[$template_id]
|
||||
)->row_array();
|
||||
|
||||
if ($tpl && $tpl['M_ScreeningTemplateCode'] !== 'DEFAULT') {
|
||||
$is_default = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_default) {
|
||||
// 3. DEFAULT: simpan ke order_screening (INSERT atau UPDATE)
|
||||
$exists = $this->db_oneklinik->query(
|
||||
"SELECT COUNT(*) AS c FROM one_klinik.order_screening
|
||||
WHERE orderScreeningOrderID = ? AND orderScreeningIsActive = 'Y'",
|
||||
[$orderID]
|
||||
)->row()->c;
|
||||
|
||||
if ($exists == 0) {
|
||||
$ins = $this->db_oneklinik->query(
|
||||
"INSERT INTO one_klinik.order_screening
|
||||
(orderScreeningOrderID, orderScreeningKesanUmum,
|
||||
orderScreeningValueKesadaran, orderScreeningValuePernafasan,
|
||||
orderScreeningValueResikoJatuh, orderScreeningValueNyeriDada,
|
||||
orderScreeningValueSkalaNyeri, orderScreeningValueBatuk,
|
||||
orderScreeningValueKeputusan, orderScreeningCreated, orderScreeningUserID)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,NOW(),?)",
|
||||
[$orderID,
|
||||
$prm['kesan_umum'] ?? '',
|
||||
$prm['kesadaran'] ?? '',
|
||||
$prm['pernafasan'] ?? '',
|
||||
$prm['resiko_jatuh'] ?? null,
|
||||
$prm['nyeri_dada'] ?? '',
|
||||
$prm['skala_nyeri'] ?? '',
|
||||
$prm['batuk'] ?? '',
|
||||
$prm['keputusan'] ?? '',
|
||||
$userID]
|
||||
);
|
||||
if (!$ins) {
|
||||
$this->sys_error_db("insert order_screening", $this->db_oneklinik);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$upd = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.order_screening SET
|
||||
orderScreeningKesanUmum = ?,
|
||||
orderScreeningValueKesadaran = ?,
|
||||
orderScreeningValuePernafasan = ?,
|
||||
orderScreeningValueResikoJatuh = ?,
|
||||
orderScreeningValueNyeriDada = ?,
|
||||
orderScreeningValueSkalaNyeri = ?,
|
||||
orderScreeningValueBatuk = ?,
|
||||
orderScreeningValueKeputusan = ?,
|
||||
orderScreeningUserID = ?
|
||||
WHERE orderScreeningOrderID = ?",
|
||||
[$prm['kesan_umum'] ?? '',
|
||||
$prm['kesadaran'] ?? '',
|
||||
$prm['pernafasan'] ?? '',
|
||||
$prm['resiko_jatuh'] ?? null,
|
||||
$prm['nyeri_dada'] ?? '',
|
||||
$prm['skala_nyeri'] ?? '',
|
||||
$prm['batuk'] ?? '',
|
||||
$prm['keputusan'] ?? '',
|
||||
$userID,
|
||||
$orderID]
|
||||
);
|
||||
if (!$upd) {
|
||||
$this->sys_error_db("update order_screening", $this->db_oneklinik);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 4. Template dinamis (VAKSINASI/KHITAN): replace semua jawaban
|
||||
$this->db_oneklinik->query(
|
||||
"DELETE FROM one_klinik.t_screening_answer WHERE T_ScreeningAnswerOrderID = ?",
|
||||
[$orderID]
|
||||
);
|
||||
|
||||
$answers = is_array($prm['screening_answers']) ? $prm['screening_answers'] : [];
|
||||
foreach ($answers as $item) {
|
||||
$form_id = intval($item['M_ScreeningFormID'] ?? 0);
|
||||
if (!$form_id) continue;
|
||||
|
||||
// Simpan sebagai JSON object
|
||||
$answer_type = $item['answer_type'] ?? 'single';
|
||||
if ($answer_type === 'text') {
|
||||
$stored_value = json_encode(['value' => $item['answer_label'] ?? '']);
|
||||
} else {
|
||||
$stored_value = json_encode(['id' => $item['answer_id'] ?? '', 'label' => $item['answer_label'] ?? '']);
|
||||
}
|
||||
|
||||
$this->db_oneklinik->query(
|
||||
"INSERT INTO one_klinik.t_screening_answer
|
||||
(T_ScreeningAnswerOrderID, T_ScreeningAnswerM_ScreeningFormID,
|
||||
T_ScreeningAnswerValue, T_ScreeningAnswerUserID)
|
||||
VALUES (?,?,?,?)",
|
||||
[$orderID, $form_id, $stored_value, $userID]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->sys_ok(['process' => 'OK']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -513,14 +513,29 @@ module.exports = {
|
||||
this.urlprintnote = "/birt/run?__report=report/one/fo/rpt_t_002.rptdesign&__format=pdf&username="+user.M_UserUsername+"&PID="+idx
|
||||
this.$store.commit("payment/update_open_print_note",true)
|
||||
},
|
||||
printInvoice(){
|
||||
this.printwidth = 800
|
||||
this.printtitle = ""
|
||||
let idx = this.$store.state.patient.selected_patient.T_OrderHeaderID
|
||||
let user = one_user()
|
||||
this.urlprintnote = "/birt/run?__report=report/one/fo/rpt_t_001.rptdesign&__format=pdf&username="+user.M_UserUsername+"&PID="+idx
|
||||
this.$store.commit("payment/update_open_print_note",true)
|
||||
}
|
||||
async printInvoice(){
|
||||
this.printwidth = 800
|
||||
this.printtitle = ""
|
||||
let idx = this.$store.state.patient.selected_patient.T_OrderHeaderID
|
||||
let user = one_user()
|
||||
this.urlprintnote = "/birt/run?__report=report/one/fo/rpt_t_001.rptdesign&__format=pdf&username="+user.M_UserUsername+"&PID="+idx
|
||||
try{
|
||||
let resp = await axios.post('/one-api/mockup/fo/cashier/payment/get_report_url_by_code', {
|
||||
token: one_token(),
|
||||
code_report: 'FO-INV-P-INA-02',
|
||||
params: {
|
||||
PUsername: user.M_UserUsername,
|
||||
PT_OrderHeaderID: idx,
|
||||
TS: '#TS'
|
||||
}
|
||||
})
|
||||
if(resp.status === 200 && resp.data.status === "OK" && resp.data.data.url){
|
||||
this.urlprintnote = resp.data.data.url
|
||||
}
|
||||
}
|
||||
catch(e){}
|
||||
this.$store.commit("payment/update_open_print_note",true)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,11 +6,12 @@ class Patient extends MY_Controller
|
||||
{
|
||||
echo "Patient API";
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
public function add_notes($orderid)
|
||||
{
|
||||
@@ -112,15 +113,17 @@ class Patient extends MY_Controller
|
||||
}
|
||||
|
||||
|
||||
$sql = "SELECT t_orderheader.*,
|
||||
M_PatientNoReg,
|
||||
DATE_FORMAT(T_OrderHeaderDate,'%d-%m-%Y %H:%i') as order_date,
|
||||
CONCAT(M_TitleName,'. ',M_PatientName) as M_PatientName,
|
||||
CONCAT(M_TitleLangName,'. ',M_PatientName) as M_PatientName_eng,
|
||||
M_PatientIDNumber,
|
||||
M_TitleName,
|
||||
M_CompanyName,
|
||||
M_MouName,
|
||||
$sql = "SELECT t_orderheader.*,
|
||||
M_PatientNoReg,
|
||||
DATE_FORMAT(T_OrderHeaderDate,'%d-%m-%Y %H:%i') as order_date,
|
||||
CONCAT(M_TitleName,'. ',M_PatientName) as M_PatientName,
|
||||
CONCAT(M_TitleLangName,'. ',M_PatientName) as M_PatientName_eng,
|
||||
M_PatientName_enc,
|
||||
M_PatientIDNumber,
|
||||
M_TitleName,
|
||||
M_TitleLangName,
|
||||
M_CompanyName,
|
||||
M_MouName,
|
||||
T_OrderHeaderTotal as totalbill,
|
||||
IFNULL(Last_StatusPaymentPaid,0) as paid,
|
||||
(T_OrderHeaderTotal + fn_fo_chasier_get_admin_charge(T_OrderHeaderID) )- ifnull(fn_fo_chasier_get_total_payment(T_OrderHeaderID),0) as unpaid,
|
||||
@@ -152,12 +155,20 @@ class Patient extends MY_Controller
|
||||
// echo $sql;
|
||||
$query = $this->db_onedev->query($sql, $sql_param);
|
||||
$rows = $query->result_array();
|
||||
$qrySrc = $this->db_onedev->last_query();
|
||||
if ($rows) {
|
||||
foreach ($rows as $k => $v) {
|
||||
$rows[$k]['notes'] = $this->add_notes($v['T_OrderHeaderID']);
|
||||
}
|
||||
}
|
||||
$qrySrc = $this->db_onedev->last_query();
|
||||
if ($rows) {
|
||||
foreach ($rows as $k => $v) {
|
||||
$plainName = trim($this->ibl_encryptor->decrypt($v['M_PatientName_enc'] ?? '') ?? '');
|
||||
if ($plainName === '') {
|
||||
$plainName = trim((string)($v['M_PatientName'] ?? ''));
|
||||
}
|
||||
$rows[$k]['M_PatientName'] = $plainName;
|
||||
$rows[$k]['M_PatientName_print'] = trim(($v['M_TitleName'] ?? '') . '. ' . $plainName);
|
||||
$rows[$k]['M_PatientName_print_eng'] = trim(($v['M_TitleLangName'] ?? '') . '. ' . $plainName);
|
||||
unset($rows[$k]['M_PatientName_enc']);
|
||||
$rows[$k]['notes'] = $this->add_notes($v['T_OrderHeaderID']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$result = array("total" => $tot_page, "records" => $rows, "sql" => $qrySrc);
|
||||
|
||||
@@ -28,3 +28,24 @@ Content-Type: application/json
|
||||
{
|
||||
"token": "{{token}}"
|
||||
}
|
||||
|
||||
###
|
||||
POST https://{{url}}/one-api-lab/mockup/fo/cashiernewpayment-v27/payment/get_report_url_by_code
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"order_id": 570,
|
||||
"code": "FO-INV-P-INA-02"
|
||||
}
|
||||
|
||||
###
|
||||
POST https://{{url}}/one-api-lab/mockup/fo/cashiernewpayment-v27/payment/get_report_url_by_code
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"order_id": 570,
|
||||
"payment_id": 123,
|
||||
"code": "FO-NR-P-INA-01"
|
||||
}
|
||||
|
||||
@@ -755,11 +755,11 @@ class Payment extends MY_Controller
|
||||
}
|
||||
}
|
||||
|
||||
function get_print_transaction_fo_kk_ina()
|
||||
{
|
||||
if (! $this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
function get_print_transaction_fo_kk_ina()
|
||||
{
|
||||
if (! $this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM print_transaction WHERE Print_TransactionCode = 'FO-KK-INA'";
|
||||
@@ -771,9 +771,330 @@ class Payment extends MY_Controller
|
||||
"records" => $rows
|
||||
);
|
||||
$this->sys_ok($result);
|
||||
} else {
|
||||
$this->sys_error_db("get_print_transaction_fo_kk_ina", $this->db_onedev);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->sys_error_db("get_print_transaction_fo_kk_ina", $this->db_onedev);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function get_report_url_by_code()
|
||||
{
|
||||
if (! $this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$reportCode = trim($prm['code'] ?? $prm['code_report'] ?? '');
|
||||
$orderId = intval($prm['order_id'] ?? 0);
|
||||
$paymentId = intval($prm['payment_id'] ?? 0);
|
||||
|
||||
if ($reportCode === '') {
|
||||
$this->sys_error("code wajib diisi");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($orderId <= 0 && $paymentId <= 0) {
|
||||
$this->sys_error("order_id atau payment_id wajib diisi");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($orderId <= 0 && $paymentId > 0) {
|
||||
$orderId = $this->resolve_order_id_by_payment($paymentId);
|
||||
}
|
||||
|
||||
if ($orderId <= 0) {
|
||||
$this->sys_error("order_id tidak ditemukan");
|
||||
exit;
|
||||
}
|
||||
|
||||
$token = $this->resolve_request_token();
|
||||
$url = $this->build_report_proxy_url($token, $reportCode, $orderId, $paymentId);
|
||||
|
||||
$this->sys_ok(array(
|
||||
"url" => $url
|
||||
));
|
||||
exit;
|
||||
}
|
||||
|
||||
function stream_report_by_code()
|
||||
{
|
||||
if (! $this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$reportCode = trim($prm['code'] ?? $prm['code_report'] ?? '');
|
||||
$orderId = intval($prm['order_id'] ?? 0);
|
||||
$paymentId = intval($prm['payment_id'] ?? 0);
|
||||
|
||||
if ($reportCode === '') {
|
||||
$this->sys_error("code wajib diisi");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($orderId <= 0 && $paymentId > 0) {
|
||||
$orderId = $this->resolve_order_id_by_payment($paymentId);
|
||||
}
|
||||
|
||||
if ($orderId <= 0) {
|
||||
$this->sys_error("order_id tidak ditemukan");
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
$cacheId = $this->ibl_patient_decrypt->populate_cache_by_order($orderId);
|
||||
$patientName = $this->resolve_patient_name_by_cache($cacheId);
|
||||
if ($patientName === '') {
|
||||
$patientName = $this->resolve_patient_name_by_order($orderId);
|
||||
}
|
||||
if ($patientName === '') {
|
||||
$patientName = $this->resolve_patient_name_from_enc_by_order($orderId);
|
||||
}
|
||||
|
||||
$url = $this->build_birt_url_by_code($reportCode, $orderId, $paymentId, $patientName);
|
||||
if ($url === false) {
|
||||
$this->ibl_patient_decrypt->delete_cache($cacheId);
|
||||
$this->sys_error("print transaction tidak ditemukan: " . $reportCode);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pdf = @file_get_contents($this->resolve_fetch_url($url), false, stream_context_create(array(
|
||||
'http' => array(
|
||||
'timeout' => 120,
|
||||
'method' => 'GET',
|
||||
),
|
||||
)));
|
||||
|
||||
$this->ibl_patient_decrypt->delete_cache($cacheId);
|
||||
|
||||
if ($pdf === false) {
|
||||
$this->sys_error('Gagal generate report dari BIRT server');
|
||||
exit;
|
||||
}
|
||||
|
||||
$filename = $reportCode . '_' . $orderId . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
exit;
|
||||
}
|
||||
|
||||
private function resolve_order_id_by_payment($paymentId)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT F_PaymentT_OrderHeaderID
|
||||
FROM f_payment
|
||||
WHERE F_PaymentID = ?
|
||||
LIMIT 1",
|
||||
array($paymentId)
|
||||
)->row_array();
|
||||
|
||||
return intval($row['F_PaymentT_OrderHeaderID'] ?? 0);
|
||||
}
|
||||
|
||||
private function resolve_payment_id_by_order($orderId)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT F_PaymentID
|
||||
FROM f_payment
|
||||
WHERE F_PaymentT_OrderHeaderID = ?
|
||||
AND IFNULL(F_PaymentIsActive, 'Y') = 'Y'
|
||||
ORDER BY F_PaymentID DESC
|
||||
LIMIT 1",
|
||||
array($orderId)
|
||||
)->row_array();
|
||||
|
||||
return intval($row['F_PaymentID'] ?? 0);
|
||||
}
|
||||
|
||||
private function resolve_patient_name_by_order($orderId)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_order_id = ?
|
||||
ORDER BY ppc_id DESC
|
||||
LIMIT 1",
|
||||
array($orderId)
|
||||
)->row_array();
|
||||
|
||||
return trim($row['ppc_name'] ?? '');
|
||||
}
|
||||
|
||||
private function resolve_patient_name_by_cache($cacheId)
|
||||
{
|
||||
if (!$cacheId) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_id = ?
|
||||
LIMIT 1",
|
||||
array($cacheId)
|
||||
)->row_array();
|
||||
|
||||
return trim($row['ppc_name'] ?? '');
|
||||
}
|
||||
|
||||
private function resolve_patient_name_from_enc_by_order($orderId)
|
||||
{
|
||||
$this->load->library('ibl_encryptor');
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT M_PatientName_enc
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ?
|
||||
LIMIT 1",
|
||||
array($orderId)
|
||||
)->row_array();
|
||||
|
||||
return trim($this->ibl_encryptor->decrypt($row['M_PatientName_enc'] ?? '') ?? '');
|
||||
}
|
||||
|
||||
private function resolve_report_username()
|
||||
{
|
||||
if (!empty($this->sys_user['M_StaffName'])) {
|
||||
return trim($this->sys_user['M_StaffName']);
|
||||
}
|
||||
if (!empty($this->sys_user['M_UserUsername'])) {
|
||||
return trim($this->sys_user['M_UserUsername']);
|
||||
}
|
||||
if (!empty($this->sys_user['userName'])) {
|
||||
return trim($this->sys_user['userName']);
|
||||
}
|
||||
return 'ADMIN';
|
||||
}
|
||||
|
||||
private function build_report_proxy_url($token, $reportCode, $orderId, $paymentId)
|
||||
{
|
||||
$query = array(
|
||||
'token' => $token,
|
||||
'code' => $reportCode,
|
||||
'order_id' => $orderId,
|
||||
);
|
||||
|
||||
if ($paymentId > 0) {
|
||||
$query['payment_id'] = $paymentId;
|
||||
}
|
||||
|
||||
return '/one-api-lab/mockup/fo/cashiernewpayment-v27/payment/stream_report_by_code?' . http_build_query($query);
|
||||
}
|
||||
|
||||
private function resolve_request_token()
|
||||
{
|
||||
$rawInput = json_decode($this->input->raw_input_stream, true);
|
||||
if (is_array($rawInput) && !empty($rawInput['token'])) {
|
||||
return trim($rawInput['token']);
|
||||
}
|
||||
|
||||
$postToken = $this->input->post('token', true);
|
||||
if (!empty($postToken)) {
|
||||
return trim($postToken);
|
||||
}
|
||||
|
||||
$getToken = $this->input->get('token', true);
|
||||
if (!empty($getToken)) {
|
||||
return trim($getToken);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function build_birt_url_by_code($reportCode, $orderId, $paymentId, $patientName)
|
||||
{
|
||||
$printTransaction = $this->db_onedev->query(
|
||||
"SELECT Print_TransactionUrl
|
||||
FROM print_transaction
|
||||
WHERE Print_TransactionCode = ?
|
||||
LIMIT 1",
|
||||
array($reportCode)
|
||||
)->row_array();
|
||||
|
||||
if (!$printTransaction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$username = $this->resolve_report_username();
|
||||
$ts = round(microtime(true) * 1000);
|
||||
$resolvedPaymentId = $paymentId > 0 ? $paymentId : $this->resolve_payment_id_by_order($orderId);
|
||||
$isInternalAppUrl = $this->is_internal_app_url($printTransaction['Print_TransactionUrl']);
|
||||
|
||||
$replacements = array(
|
||||
'PUsername' => $this->format_report_string_param($username, $isInternalAppUrl),
|
||||
'PT_OrderHeaderID' => $orderId,
|
||||
'PPaymentID' => $resolvedPaymentId,
|
||||
'PAn' => $this->format_report_string_param($patientName, $isInternalAppUrl),
|
||||
'TS' => $ts,
|
||||
);
|
||||
|
||||
$url = $printTransaction['Print_TransactionUrl'];
|
||||
foreach ($replacements as $placeholder => $value) {
|
||||
if ($value === null) {
|
||||
$value = '';
|
||||
}
|
||||
$url = str_replace($placeholder, $value, $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
private function resolve_fetch_url($url)
|
||||
{
|
||||
$url = trim((string) $url);
|
||||
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('#^https?://#i', $url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/birt/') === 0) {
|
||||
return 'http://localhost:8080' . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/one-api-lab/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/tools/') === 0 || strpos($url, '/index.php/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . '/one-api-lab' . $url;
|
||||
}
|
||||
|
||||
return 'http://localhost:8080' . $url;
|
||||
}
|
||||
|
||||
private function is_internal_app_url($url)
|
||||
{
|
||||
$url = (string) $url;
|
||||
|
||||
return (
|
||||
strpos($url, '/one-api-lab/') === 0 ||
|
||||
strpos($url, '/tools/') === 0 ||
|
||||
strpos($url, '/index.php/') === 0
|
||||
);
|
||||
}
|
||||
|
||||
private function format_report_string_param($value, $isInternalAppUrl = false)
|
||||
{
|
||||
$value = (string) $value;
|
||||
|
||||
if ($isInternalAppUrl) {
|
||||
return rawurlencode($value);
|
||||
}
|
||||
|
||||
return rawurlencode("'" . $value . "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ class Delivery extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_smartone = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
public function search()
|
||||
{
|
||||
@@ -64,7 +65,20 @@ class Delivery extends MY_Controller
|
||||
}
|
||||
$prm = $this->sys_input;
|
||||
$type = $prm['type'];
|
||||
$id = $prm['id'];
|
||||
$id = $prm['id'];
|
||||
|
||||
if ($type == 'patient') {
|
||||
$prow = $this->db_smartone->query(
|
||||
"SELECT M_PatientEmail_enc, M_PatientHP_enc FROM m_patient WHERE M_PatientID = ? LIMIT 1", [$id]
|
||||
)->row_array();
|
||||
$patient_email = $this->db_smartone->escape(
|
||||
$this->ibl_encryptor->decrypt($prow['M_PatientEmail_enc'] ?? '') ?: 'Belum ada email pasien'
|
||||
);
|
||||
$patient_hp = $this->db_smartone->escape(
|
||||
$this->ibl_encryptor->decrypt($prow['M_PatientHP_enc'] ?? '') ?: 'Belum ada WA pasien'
|
||||
);
|
||||
}
|
||||
|
||||
if($type == 'patient'){
|
||||
$sql = "
|
||||
SELECT '' as regionalcd,
|
||||
@@ -110,7 +124,7 @@ class Delivery extends MY_Controller
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientEmail,'Belum ada email pasien') as description,
|
||||
IFNULL({$patient_email},'Belum ada email pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -129,7 +143,7 @@ class Delivery extends MY_Controller
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientEmail,'Belum ada email pasien') as description,
|
||||
IFNULL({$patient_email},'Belum ada email pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -148,7 +162,7 @@ class Delivery extends MY_Controller
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientHP,'Belum ada WA pasien') as description,
|
||||
IFNULL({$patient_hp},'Belum ada WA pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -167,7 +181,7 @@ class Delivery extends MY_Controller
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientHP,'Belum ada telegram pasien') as description,
|
||||
IFNULL({$patient_hp},'Belum ada telegram pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -310,6 +324,16 @@ class Delivery extends MY_Controller
|
||||
foreach($rows as $k => $v){
|
||||
$xval = $v['chex'] === 'N'?false:true;
|
||||
//$rows[$k]['chex'] = $xval;
|
||||
if ($v['delivery_code'] === 'ADDRESS' && $type === 'patient' && !empty($v['address_id'])) {
|
||||
$addr_row = $this->db_smartone->query(
|
||||
'SELECT M_PatientAddressDescription_enc, M_PatientAddressVillage, M_PatientAddressDistrict, M_PatientAddressCity FROM m_patientaddress WHERE M_PatientAddressID = ? LIMIT 1',
|
||||
[$v['address_id']]
|
||||
)->row_array();
|
||||
if ($addr_row) {
|
||||
$desc = $this->ibl_encryptor->decrypt($addr_row['M_PatientAddressDescription_enc'] ?? '') ?: '';
|
||||
$rows[$k]['description'] = $desc . ' ' . $addr_row['M_PatientAddressVillage'] . ', ' . $addr_row['M_PatientAddressDistrict'] . ', ' . $addr_row['M_PatientAddressCity'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$result = array("records" => $rows);
|
||||
|
||||
@@ -12,6 +12,20 @@ class History extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
// Ambil email & HP pasien (sudah didekripsi) untuk dipakai di UNION delivery query
|
||||
private function _get_patient_contact($patient_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT M_PatientEmail_enc, M_PatientHP_enc FROM m_patient WHERE M_PatientID = ? LIMIT 1",
|
||||
[$patient_id]
|
||||
)->row_array();
|
||||
return [
|
||||
'email' => $this->ibl_encryptor->decrypt($row['M_PatientEmail_enc'] ?? '') ?: '',
|
||||
'hp' => $this->ibl_encryptor->decrypt($row['M_PatientHP_enc'] ?? '') ?: '',
|
||||
];
|
||||
}
|
||||
|
||||
public function search()
|
||||
@@ -329,9 +343,15 @@ class History extends MY_Controller
|
||||
|
||||
function search_deliveries($prm)
|
||||
{
|
||||
|
||||
$type = $prm['type'];
|
||||
$id = $prm['id'];
|
||||
$id = $prm['id'];
|
||||
|
||||
if ($type == 'patient') {
|
||||
$contact = $this->_get_patient_contact($id);
|
||||
$patient_email = $this->db_onedev->escape($contact['email'] ?: 'Belum ada email pasien');
|
||||
$patient_hp = $this->db_onedev->escape($contact['hp'] ?: 'Belum ada WA pasien');
|
||||
}
|
||||
|
||||
if($type == 'patient'){
|
||||
$sql = "
|
||||
SELECT 0 as kelurahan,
|
||||
@@ -377,7 +397,7 @@ class History extends MY_Controller
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientEmail,'Belum ada email pasien') as description,
|
||||
IFNULL({$patient_email},'Belum ada email pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -394,7 +414,7 @@ class History extends MY_Controller
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientEmail,'Belum ada email pasien') as description,
|
||||
IFNULL({$patient_email},'Belum ada email pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -411,7 +431,7 @@ class History extends MY_Controller
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientHP,'Belum ada WA pasien') as description,
|
||||
IFNULL({$patient_hp},'Belum ada WA pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -428,7 +448,7 @@ class History extends MY_Controller
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientHP,'Belum ada telegram pasien') as description,
|
||||
IFNULL({$patient_hp},'Belum ada telegram pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
|
||||
@@ -12,6 +12,7 @@ class Order extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_smartone = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
function get_time_start(){
|
||||
@@ -747,7 +748,8 @@ function endshowtime()
|
||||
T_OrderHeaderSubTotal as order_subtotal,
|
||||
T_OrderHeaderRounding as order_rounding,
|
||||
T_OrderHeaderTotal as order_total,
|
||||
concat(if(M_TitleID is null, '', concat(M_TitleName, ' ')),IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) as patient_name,
|
||||
M_PatientName_enc, IFNULL(M_TitleName,'') M_TitleName,
|
||||
IFNULL(M_PatientPrefix,'') M_PatientPrefix, IFNULL(M_PatientSuffix,'') M_PatientSuffix,
|
||||
M_PatientNoReg as patient_mr,
|
||||
M_MouName as order_mou,
|
||||
CorporateName as order_company,
|
||||
@@ -767,9 +769,14 @@ function endshowtime()
|
||||
where T_OrderHeaderID = {$id}";
|
||||
//echo $sql;
|
||||
$query = $this->db_smartone->query($sql);
|
||||
$rows = $query->row();
|
||||
$rows = $query->row_array();
|
||||
$pname = $this->ibl_encryptor->decrypt($rows['M_PatientName_enc'] ?? '');
|
||||
$rows['patient_name'] = trim(implode(' ', array_filter([
|
||||
$rows['M_TitleName'], $rows['M_PatientPrefix'], $pname, $rows['M_PatientSuffix']
|
||||
])));
|
||||
unset($rows['M_PatientName_enc'], $rows['M_TitleName'], $rows['M_PatientPrefix'], $rows['M_PatientSuffix']);
|
||||
//echo $this->db_smartone->last_query();
|
||||
return $rows;
|
||||
return (object) $rows;
|
||||
}
|
||||
|
||||
function get_delivery($id){
|
||||
@@ -876,9 +883,21 @@ function endshowtime()
|
||||
|
||||
function search_deliveries($prm)
|
||||
{
|
||||
|
||||
$type = $prm['type'];
|
||||
$id = $prm['id'];
|
||||
$id = $prm['id'];
|
||||
|
||||
if ($type == 'patient') {
|
||||
$prow = $this->db_smartone->query(
|
||||
"SELECT M_PatientEmail_enc, M_PatientHP_enc FROM m_patient WHERE M_PatientID = ? LIMIT 1", [$id]
|
||||
)->row_array();
|
||||
$patient_email = $this->db_smartone->escape(
|
||||
$this->ibl_encryptor->decrypt($prow['M_PatientEmail_enc'] ?? '') ?: 'Belum ada email pasien'
|
||||
);
|
||||
$patient_hp = $this->db_smartone->escape(
|
||||
$this->ibl_encryptor->decrypt($prow['M_PatientHP_enc'] ?? '') ?: 'Belum ada WA pasien'
|
||||
);
|
||||
}
|
||||
|
||||
if($type == 'patient'){
|
||||
$sql = "
|
||||
SELECT 0 as kelurahan,
|
||||
@@ -924,7 +943,7 @@ function endshowtime()
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientEmail,'Belum ada email pasien') as description,
|
||||
IFNULL({$patient_email},'Belum ada email pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -941,7 +960,7 @@ function endshowtime()
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientEmail,'Belum ada email pasien') as description,
|
||||
IFNULL({$patient_email},'Belum ada email pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -958,7 +977,7 @@ function endshowtime()
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientHP,'Belum ada WA pasien') as description,
|
||||
IFNULL({$patient_hp},'Belum ada WA pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -975,7 +994,7 @@ function endshowtime()
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientHP,'Belum ada telegram pasien') as description,
|
||||
IFNULL({$patient_hp},'Belum ada telegram pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
|
||||
@@ -13,6 +13,7 @@ class Order extends MY_Controller
|
||||
parent::__construct();
|
||||
$this->db_smartone = $this->load->database("onedev", true);
|
||||
$this->db_log = $this->load->database("one_lab_log", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
$this->load->helper("uuid");
|
||||
}
|
||||
|
||||
@@ -54,17 +55,61 @@ class Order extends MY_Controller
|
||||
return $rst;
|
||||
}
|
||||
|
||||
function convert_to_normal_text($text)
|
||||
{
|
||||
function convert_to_normal_text($text)
|
||||
{
|
||||
|
||||
$normal_characters = "a-zA-Z0-9\s`~!@#$%^&*()_+-={}|:;<>?,.\/\"\'\\\[\]";
|
||||
$normal_text = preg_replace("/[^$normal_characters]/", '', $text);
|
||||
|
||||
return $normal_text;
|
||||
}
|
||||
|
||||
function genqrcode($nomorlab, $id)
|
||||
{
|
||||
return $normal_text;
|
||||
}
|
||||
|
||||
protected function build_patient_visit_info($patient_id, $patient_dob)
|
||||
{
|
||||
$visit = 1;
|
||||
$birthday = 'N';
|
||||
|
||||
$visit_query = $this->db_onedev->query(
|
||||
"SELECT COUNT(DISTINCT T_OrderHeaderID) AS n
|
||||
FROM t_orderheader
|
||||
JOIN t_orderdetail ON T_OrderHeaderID = T_OrderDetailT_OrderHeaderID AND T_OrderDetailIsActive = 'Y'
|
||||
WHERE T_OrderHeaderIsActive = 'Y'
|
||||
AND T_OrderHeaderM_PatientID = ?",
|
||||
[$patient_id]
|
||||
);
|
||||
|
||||
if ($visit_query) {
|
||||
$visit_row = $visit_query->row_array();
|
||||
$visit += (int) ($visit_row['n'] ?? 0);
|
||||
}
|
||||
|
||||
$init_visit_query = $this->db_onedev->query(
|
||||
"SELECT M_PatientInitialVisit
|
||||
FROM m_patient
|
||||
WHERE M_PatientID = ?",
|
||||
[$patient_id]
|
||||
);
|
||||
|
||||
if ($init_visit_query) {
|
||||
$init_visit_row = $init_visit_query->row_array();
|
||||
if (!empty($init_visit_row['M_PatientInitialVisit'])) {
|
||||
$visit += (int) $init_visit_row['M_PatientInitialVisit'];
|
||||
}
|
||||
}
|
||||
|
||||
$dob_time = empty($patient_dob) ? false : strtotime($patient_dob);
|
||||
if ($dob_time !== false) {
|
||||
$birthday = date('m-d', $dob_time) === date('m-d') ? 'Y' : 'N';
|
||||
}
|
||||
|
||||
return json_decode(json_encode([
|
||||
'visit' => $visit,
|
||||
'birthday' => $birthday,
|
||||
]));
|
||||
}
|
||||
|
||||
function genqrcode($nomorlab, $id)
|
||||
{
|
||||
$this->load->library('ciqrcode'); //pemanggilan library QR CODE
|
||||
$home_dir = "/home/one/project/one/";
|
||||
$target_dir = $home_dir . "one-media/one-qrcontrolcard/";
|
||||
@@ -163,47 +208,47 @@ class Order extends MY_Controller
|
||||
return lab_uuid_v4();
|
||||
}
|
||||
|
||||
function generate_code_form($preid, $orderid)
|
||||
{
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
$sql = "SELECT FormRiwayatPasienID, FormRiwayatPasienCode, FormRiwayatPasienUUID, FormRiwayatPasienT_OrderHeaderID
|
||||
FROM form_riwayat_pasien
|
||||
WHERE FormRiwayatPasienPreregisterID = ? AND
|
||||
FormRiwayatPasienIsActive = 'Y'
|
||||
ORDER BY FormRiwayatPasienID DESC
|
||||
LIMIT 1";
|
||||
$qry = $this->db_onedev->query($sql, [$preid]);
|
||||
if (!$qry) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$exist = $qry->row_array();
|
||||
if ($exist) {
|
||||
if ((int) $exist['FormRiwayatPasienT_OrderHeaderID'] !== (int) $orderid) {
|
||||
$sql = "UPDATE form_riwayat_pasien
|
||||
SET FormRiwayatPasienT_OrderHeaderID = ?,
|
||||
FormRiwayatPasienLasUpdated = NOW(),
|
||||
FormRiwayatPasienLasUpdatedUserID = ?
|
||||
WHERE FormRiwayatPasienID = ?";
|
||||
$qry = $this->db_onedev->query($sql, [$orderid, $userid, $exist['FormRiwayatPasienID']]);
|
||||
if (!$qry) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return array('uuid' => $exist['FormRiwayatPasienUUID'], 'code' => $exist['FormRiwayatPasienCode']);
|
||||
}
|
||||
|
||||
$sql = "SELECT COUNT(*) as total
|
||||
FROM form_riwayat_pasien
|
||||
WHERE FormRiwayatPasienT_OrderHeaderID = ? AND
|
||||
FormRiwayatPasienIsActive = 'Y'
|
||||
";
|
||||
$qry = $this->db_onedev->query($sql, [$orderid]);
|
||||
if ($qry) {
|
||||
$total = $qry->result_array()[0]['total'];
|
||||
if ($total == 0) {
|
||||
$code = $this->generate_code_string();
|
||||
$uuid = $this->generate_uuid();
|
||||
function generate_code_form($preid, $orderid)
|
||||
{
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
$sql = "SELECT FormRiwayatPasienID, FormRiwayatPasienCode, FormRiwayatPasienUUID, FormRiwayatPasienT_OrderHeaderID
|
||||
FROM form_riwayat_pasien
|
||||
WHERE FormRiwayatPasienPreregisterID = ? AND
|
||||
FormRiwayatPasienIsActive = 'Y'
|
||||
ORDER BY FormRiwayatPasienID DESC
|
||||
LIMIT 1";
|
||||
$qry = $this->db_onedev->query($sql, [$preid]);
|
||||
if (!$qry) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$exist = $qry->row_array();
|
||||
if ($exist) {
|
||||
if ((int) $exist['FormRiwayatPasienT_OrderHeaderID'] !== (int) $orderid) {
|
||||
$sql = "UPDATE form_riwayat_pasien
|
||||
SET FormRiwayatPasienT_OrderHeaderID = ?,
|
||||
FormRiwayatPasienLasUpdated = NOW(),
|
||||
FormRiwayatPasienLasUpdatedUserID = ?
|
||||
WHERE FormRiwayatPasienID = ?";
|
||||
$qry = $this->db_onedev->query($sql, [$orderid, $userid, $exist['FormRiwayatPasienID']]);
|
||||
if (!$qry) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return array('uuid' => $exist['FormRiwayatPasienUUID'], 'code' => $exist['FormRiwayatPasienCode']);
|
||||
}
|
||||
|
||||
$sql = "SELECT COUNT(*) as total
|
||||
FROM form_riwayat_pasien
|
||||
WHERE FormRiwayatPasienT_OrderHeaderID = ? AND
|
||||
FormRiwayatPasienIsActive = 'Y'
|
||||
";
|
||||
$qry = $this->db_onedev->query($sql, [$orderid]);
|
||||
if ($qry) {
|
||||
$total = $qry->result_array()[0]['total'];
|
||||
if ($total == 0) {
|
||||
$code = $this->generate_code_string();
|
||||
$uuid = $this->generate_uuid();
|
||||
|
||||
$sql = "INSERT INTO form_riwayat_pasien (
|
||||
FormRiwayatPasienPreregisterID,
|
||||
@@ -216,14 +261,14 @@ class Order extends MY_Controller
|
||||
$qry = $this->db_onedev->query($sql, [$preid, $code, $uuid, $orderid, $userid]);
|
||||
//echo $this->db_onedev->last_query();
|
||||
//exit;
|
||||
if (!$qry) {
|
||||
return '';
|
||||
}
|
||||
return array('uuid' => $uuid, 'code' => $code);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
if (!$qry) {
|
||||
return '';
|
||||
}
|
||||
return array('uuid' => $uuid, 'code' => $code);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function check_duplicate_nat_tests($data)
|
||||
{
|
||||
@@ -535,6 +580,15 @@ class Order extends MY_Controller
|
||||
}
|
||||
}
|
||||
|
||||
// Link ke order klinik jika klinik_number dikirim
|
||||
$klinik_number = trim($header['klinik_number'] ?? '');
|
||||
if ($klinik_number !== '') {
|
||||
$this->db_smartone->query(
|
||||
"UPDATE one_klinik.`order` SET orderT_OrderHeaderID = ? WHERE OrderNumber = ?",
|
||||
[$header_id, $klinik_number]
|
||||
);
|
||||
}
|
||||
|
||||
$sql = "SELECT t_orderheader.*
|
||||
FROM t_orderheader
|
||||
WHERE
|
||||
@@ -734,8 +788,13 @@ class Order extends MY_Controller
|
||||
|
||||
|
||||
|
||||
// Strip PII dari header sebelum masuk log (identitas pasien di m_patient, sudah terenkripsi)
|
||||
$header_for_log = is_array($order_header) ? $order_header : (array)$order_header;
|
||||
foreach (['patient_name','patient_address','patient_phone','patient_email','patient_hp'] as $_pii) {
|
||||
unset($header_for_log[$_pii]);
|
||||
}
|
||||
$data_log = $sanitize_for_json(array(
|
||||
'header' => $order_header,
|
||||
'header' => $header_for_log,
|
||||
'detail_order' => $order_detail,
|
||||
'delivery' => $order_delivery,
|
||||
'promise' => $order_promise,
|
||||
@@ -792,13 +851,27 @@ class Order extends MY_Controller
|
||||
$this->sys_error($url_preregister['message']);
|
||||
exit;
|
||||
}
|
||||
$url_preregister = $url_preregister['data'];
|
||||
|
||||
|
||||
$dt_order = [
|
||||
'status' => 'OK',
|
||||
'order_id' => $x_data_array['T_OrderHeaderID'],
|
||||
'order_date' => $x_data_array['T_OrderHeaderDate'],
|
||||
$url_preregister = $url_preregister['data'];
|
||||
|
||||
$order_klinik = null;
|
||||
if ($klinik_number !== '') {
|
||||
$query_order_klinik = $this->db_onedev->query(
|
||||
"SELECT *
|
||||
FROM one_klinik.`order`
|
||||
WHERE OrderNumber = ?
|
||||
LIMIT 1",
|
||||
[$klinik_number]
|
||||
);
|
||||
if ($query_order_klinik) {
|
||||
$order_klinik = $query_order_klinik->row_array();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$dt_order = [
|
||||
'status' => 'OK',
|
||||
'order_id' => $x_data_array['T_OrderHeaderID'],
|
||||
'order_date' => $x_data_array['T_OrderHeaderDate'],
|
||||
'noreg' => $lab_number,
|
||||
'qrcode' => $genqrcode,
|
||||
'patient_qrcode' => $genpatientqrcode,
|
||||
@@ -812,11 +885,12 @@ class Order extends MY_Controller
|
||||
'order_detail' => $order_detail,
|
||||
'order_header' => $order_header,
|
||||
'inform_consent' => isset($order_header['inform_consent']) ? $order_header['inform_consent'] : [],
|
||||
'order_promise' => $order_promise,
|
||||
'order_details' => $order_details,
|
||||
'report_url' => $report_url,
|
||||
'location_warning' => $location_warning,
|
||||
];
|
||||
'order_promise' => $order_promise,
|
||||
'order_details' => $order_details,
|
||||
'order_klinik' => $order_klinik,
|
||||
'report_url' => $report_url,
|
||||
'location_warning' => $location_warning,
|
||||
];
|
||||
|
||||
if ($internal)
|
||||
return ['status' => 'OK', 'data' => $dt_order];
|
||||
@@ -979,7 +1053,8 @@ class Order extends MY_Controller
|
||||
$sql = "SELECT M_DeliveryTypeCode as xtype,
|
||||
M_DeliverySource as source,
|
||||
M_DeliveryName as label,
|
||||
IFNULL(T_OrderDeliveryNoteValue,T_OrderDeliveryDestination) as xdesc
|
||||
T_OrderDeliveryDestination_enc,
|
||||
IFNULL(T_OrderDeliveryNoteValue, T_OrderDeliveryDestination) as xdesc_fallback
|
||||
FROM t_orderdelivery
|
||||
JOIN m_deliverytype ON T_OrderDeliveryM_DeliveryTypeID = M_DeliveryTypeID
|
||||
JOIN m_delivery ON T_OrderDeliveryM_DeliveryID = M_DeliveryID
|
||||
@@ -1004,11 +1079,13 @@ class Order extends MY_Controller
|
||||
$data = $query->result_array();
|
||||
$rst = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$dest_enc = $value['T_OrderDeliveryDestination_enc'] ?? '';
|
||||
$dest = $dest_enc ? ($this->ibl_encryptor->decrypt($dest_enc) ?: $value['xdesc_fallback']) : $value['xdesc_fallback'];
|
||||
$rst[] = array(
|
||||
'type' => $value['xtype'],
|
||||
'type' => $value['xtype'],
|
||||
'source' => $value['source'],
|
||||
'label' => $value['label'],
|
||||
'desc' => $value['xdesc']
|
||||
'label' => $value['label'],
|
||||
'desc' => $dest
|
||||
);
|
||||
}
|
||||
$return['data'] = $rst;
|
||||
@@ -1039,19 +1116,24 @@ class Order extends MY_Controller
|
||||
T_OrderHeaderSubTotal as order_subtotal,
|
||||
T_OrderHeaderTotal as order_total,
|
||||
M_PatientNoReg as patient_mr,
|
||||
M_PatientName as patient_name,
|
||||
CONCAT(M_PatientAddressDescription,'<br>',IF(M_PatientAddressVillage IS NULL,'',CONCAT(M_PatientAddressVillage,', ')),IF(M_PatientAddressDistrict IS NULL,'',CONCAT(M_PatientAddressDistrict,', ')),IF(M_PatientAddressCity IS NULL,'',M_PatientAddressCity)) as patient_address,
|
||||
M_PatientPhone as patient_phone,
|
||||
M_PatientEmail as patient_email,
|
||||
M_PatientName_enc, M_PatientAddressDescription_enc,
|
||||
M_PatientPhone_enc, M_PatientEmail_enc,
|
||||
t_orderheader.*,
|
||||
IFNULL(Nat_CitoName,'') as cito_name,
|
||||
IFNULL(Mgm_McuNumber,'') as mcu_number,
|
||||
IFNULL(Mgm_McuLabel,'') as mcu_label,
|
||||
IFNULL(latest_sig.Patient_SignatureUrl,'') as image_signature
|
||||
IFNULL(latest_sig.Patient_SignatureUrl,'') as image_signature
|
||||
FROM `t_orderheader`
|
||||
JOIN `t_orderheaderaddon` ON T_OrderHeaderAddOnT_OrderHeaderID = T_OrderHeaderID AND T_OrderHeaderAddOnIsActive = 'Y'
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
JOIN m_patientaddress ON M_PatientAddressM_PatientID = M_PatientID AND M_PatientAddressIsActive = 'Y' AND M_PatientAddressNote = 'Utama'
|
||||
LEFT JOIN m_patientaddress ON M_PatientAddressID = (
|
||||
SELECT pa.M_PatientAddressID
|
||||
FROM m_patientaddress pa
|
||||
WHERE pa.M_PatientAddressM_PatientID = M_PatientID
|
||||
AND pa.M_PatientAddressIsActive = 'Y'
|
||||
ORDER BY (pa.M_PatientAddressNote = 'Utama') DESC, pa.M_PatientAddressID DESC
|
||||
LIMIT 1
|
||||
)
|
||||
JOIN m_company ON T_OrderHeaderM_CompanyID = M_CompanyID
|
||||
JOIN m_mou ON T_OrderHeaderM_MouID = M_MouID
|
||||
JOIN m_doctor pj1 ON T_OrderHeaderPjM_DoctorID = pj1.M_DoctorID
|
||||
@@ -1060,16 +1142,16 @@ class Order extends MY_Controller
|
||||
LEFT JOIN m_doctoraddress sender_address ON T_OrderHeaderSenderM_DoctorAddressID = M_DoctorAddressID
|
||||
LEFT JOIN nat_cito ON T_OrderHeaderNat_CitoID = Nat_CitoID
|
||||
LEFT JOIN mgm_mcu ON T_OrderHeaderMgm_McuID = Mgm_McuID
|
||||
LEFT JOIN (
|
||||
SELECT ps.Patient_SignatureM_PatientID, ps.Patient_SignatureUrl
|
||||
FROM patient_signature ps
|
||||
JOIN (
|
||||
SELECT Patient_SignatureM_PatientID, MAX(Patient_SignatureID) as Patient_SignatureID
|
||||
FROM patient_signature
|
||||
WHERE Patient_SignatureIsActive = 'Y'
|
||||
GROUP BY Patient_SignatureM_PatientID
|
||||
) latest_sig_id ON latest_sig_id.Patient_SignatureID = ps.Patient_SignatureID
|
||||
) latest_sig ON latest_sig.Patient_SignatureM_PatientID = M_PatientID AND latest_sig.Patient_SignatureM_PatientID = T_OrderHeaderM_PatientID
|
||||
LEFT JOIN (
|
||||
SELECT ps.Patient_SignatureM_PatientID, ps.Patient_SignatureUrl
|
||||
FROM patient_signature ps
|
||||
JOIN (
|
||||
SELECT Patient_SignatureM_PatientID, MAX(Patient_SignatureID) as Patient_SignatureID
|
||||
FROM patient_signature
|
||||
WHERE Patient_SignatureIsActive = 'Y'
|
||||
GROUP BY Patient_SignatureM_PatientID
|
||||
) latest_sig_id ON latest_sig_id.Patient_SignatureID = ps.Patient_SignatureID
|
||||
) latest_sig ON latest_sig.Patient_SignatureM_PatientID = M_PatientID AND latest_sig.Patient_SignatureM_PatientID = T_OrderHeaderM_PatientID
|
||||
WHERE `T_OrderHeaderID` = ?
|
||||
GROUP BY T_OrderHeaderID";
|
||||
$query = $this->db_smartone->query($sql, [$order_id]);
|
||||
@@ -1093,6 +1175,20 @@ class Order extends MY_Controller
|
||||
|
||||
$data = $query->row_array();
|
||||
if (is_array($data) && count($data) > 0) {
|
||||
$enc = $this->ibl_encryptor;
|
||||
$addr_raw = $enc->decrypt($data['M_PatientAddressDescription_enc'] ?? '');
|
||||
$data['patient_name'] = $enc->decrypt($data['M_PatientName_enc'] ?? '');
|
||||
$data['patient_address'] = implode('<br>', array_filter([
|
||||
$addr_raw,
|
||||
$data['M_PatientAddressVillage'] ?? '',
|
||||
$data['M_PatientAddressDistrict'] ?? '',
|
||||
$data['M_PatientAddressCity'] ?? '',
|
||||
]));
|
||||
$data['patient_phone'] = $enc->decrypt($data['M_PatientPhone_enc'] ?? '');
|
||||
$data['patient_email'] = $enc->decrypt($data['M_PatientEmail_enc'] ?? '');
|
||||
foreach (array_keys($data) as $col) {
|
||||
if (substr($col, -4) === '_enc') unset($data[$col]);
|
||||
}
|
||||
$data['inform_consent'] = $this->get_inform_consent_by_order($order_id);
|
||||
}
|
||||
$return['data'] = $data;
|
||||
@@ -1404,9 +1500,9 @@ class Order extends MY_Controller
|
||||
|
||||
|
||||
|
||||
$sql = "SELECT
|
||||
CONCAT(IF(M_TitleID is null, '', concat(M_TitleName, ' ')),IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) as full_patient_name
|
||||
FROM m_patient
|
||||
$sql = "SELECT M_PatientName_enc, IFNULL(M_TitleName,'') M_TitleName,
|
||||
IFNULL(M_PatientPrefix,'') M_PatientPrefix, IFNULL(M_PatientSuffix,'') M_PatientSuffix
|
||||
FROM m_patient
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
WHERE M_PatientID = ? LIMIT 1";
|
||||
$query_patient = $this->db_smartone->query($sql, [$header['patient_id']]);
|
||||
@@ -1417,6 +1513,10 @@ class Order extends MY_Controller
|
||||
$this->db_smartone->trans_rollback();
|
||||
}
|
||||
$rows_patient = $query_patient->row_array();
|
||||
$pname = $this->ibl_encryptor->decrypt($rows_patient['M_PatientName_enc'] ?? '');
|
||||
$rows_patient['full_patient_name'] = trim(implode(' ', array_filter([
|
||||
$rows_patient['M_TitleName'], $rows_patient['M_PatientPrefix'], $pname, $rows_patient['M_PatientSuffix']
|
||||
])));
|
||||
$full_patient_name = $rows_patient['full_patient_name'];
|
||||
|
||||
$sql = "INSERT INTO t_orderheaderaddon (
|
||||
@@ -2410,16 +2510,18 @@ class Order extends MY_Controller
|
||||
T_OrderDeliveryM_DeliveryID,
|
||||
T_OrderDeliveryM_DeliveryTypeID,
|
||||
T_OrderDeliveryDestination,
|
||||
T_OrderDeliveryDestination_enc,
|
||||
T_OrderDeliveryAddressID,
|
||||
T_OrderDeliveryRegionalCd,
|
||||
T_OrderDeliveryCreated,
|
||||
T_OrderDeliveryCreatedUserID
|
||||
) VALUES (?,?,?,?,?,?,NOW(),?)";
|
||||
) VALUES (?,?,?,?,?,?,?,NOW(),?)";
|
||||
$prm_orderdelivery = [
|
||||
$header_id,
|
||||
$delivery['delivery_id'],
|
||||
$delivery['delivery_type_id'],
|
||||
$destination,
|
||||
$this->ibl_encryptor->encrypt($destination),
|
||||
$delivery['address_id'],
|
||||
$delivery['regional_cd'],
|
||||
$userid
|
||||
@@ -2480,18 +2582,23 @@ class Order extends MY_Controller
|
||||
|
||||
// START
|
||||
if ($delivery['delivery_type_id'] == 3) {
|
||||
$sql_header_info = "SELECT
|
||||
CONCAT(IFNULL(M_TitleName,''),'. ', IFNULL(M_PatientPrefix,''),M_PatientName, IFNULL(M_PatientSuffix,'')) as patient_fullname,
|
||||
$sql_header_info = "SELECT
|
||||
M_PatientName_enc, IFNULL(M_TitleName,'') M_TitleName,
|
||||
IFNULL(M_PatientPrefix,'') M_PatientPrefix, IFNULL(M_PatientSuffix,'') M_PatientSuffix,
|
||||
M_CompanyName as corporate_name,
|
||||
CONCAT(IFNULL(M_DoctorPrefix,''),IFNULL(M_DoctorPrefix2,''),' ',M_DoctorName,IFNULL(M_DoctorSufix,''),IFNULL(M_DoctorSufix2,''),IFNULL(M_DoctorSufix3,'')) as doctor_fullname
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_company ON T_OrderHeaderM_CompanyID = M_CompanyID
|
||||
JOIN m_doctor ON T_OrderHeaderSenderM_DoctorID = M_DoctorID
|
||||
WHERE T_OrderHeaderID = ?";
|
||||
$q_h = $this->db_smartone->query($sql_header_info, [$header_id]);
|
||||
$d_h = $q_h->row_array();
|
||||
$pname_del = $this->ibl_encryptor->decrypt($d_h['M_PatientName_enc'] ?? '');
|
||||
$d_h['patient_fullname'] = trim(implode(' ', array_filter([
|
||||
$d_h['M_TitleName'], $d_h['M_PatientPrefix'], $pname_del, $d_h['M_PatientSuffix']
|
||||
])));
|
||||
|
||||
$sql_del_source = "SELECT M_DeliverySource FROM m_delivery WHERE M_DeliveryID = ?";
|
||||
$q_d = $this->db_smartone->query($sql_del_source, [$delivery['delivery_id']]);
|
||||
@@ -3490,7 +3597,8 @@ GROUP BY T_SampleStationID ";
|
||||
T_OrderHeaderSubTotal as order_subtotal,
|
||||
T_OrderHeaderRounding as order_rounding,
|
||||
T_OrderHeaderTotal as order_total,
|
||||
concat(if(M_TitleID is null, '', concat(M_TitleName, ' ')),IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) as patient_name,
|
||||
M_PatientName_enc, IFNULL(M_TitleName,'') M_TitleName,
|
||||
IFNULL(M_PatientPrefix,'') M_PatientPrefix, IFNULL(M_PatientSuffix,'') M_PatientSuffix,
|
||||
M_PatientNoReg as patient_mr,
|
||||
M_MouName as order_mou,
|
||||
CorporateName as order_company,
|
||||
@@ -3510,9 +3618,13 @@ GROUP BY T_SampleStationID ";
|
||||
where T_OrderHeaderID = {$id}";
|
||||
//echo $sql;
|
||||
$query = $this->db_smartone->query($sql);
|
||||
$rows = $query->row();
|
||||
//echo $this->db_smartone->last_query();
|
||||
return $rows;
|
||||
$rows = $query->row_array();
|
||||
$pname = $this->ibl_encryptor->decrypt($rows['M_PatientName_enc'] ?? '');
|
||||
$rows['patient_name'] = trim(implode(' ', array_filter([
|
||||
$rows['M_TitleName'], $rows['M_PatientPrefix'], $pname, $rows['M_PatientSuffix']
|
||||
])));
|
||||
unset($rows['M_PatientName_enc'], $rows['M_TitleName'], $rows['M_PatientPrefix'], $rows['M_PatientSuffix']);
|
||||
return (object) $rows;
|
||||
}
|
||||
|
||||
function get_delivery($id)
|
||||
@@ -3619,7 +3731,19 @@ GROUP BY T_SampleStationID ";
|
||||
{
|
||||
|
||||
$type = $prm['type'];
|
||||
$id = $prm['id'];
|
||||
$id = $prm['id'];
|
||||
|
||||
if ($type == 'patient') {
|
||||
$prow = $this->db_smartone->query(
|
||||
"SELECT M_PatientEmail_enc, M_PatientHP_enc FROM m_patient WHERE M_PatientID = ? LIMIT 1", [$id]
|
||||
)->row_array();
|
||||
$patient_email = $this->db_smartone->escape(
|
||||
$this->ibl_encryptor->decrypt($prow['M_PatientEmail_enc'] ?? '') ?: 'Belum ada email'
|
||||
);
|
||||
$patient_hp = $this->db_smartone->escape(
|
||||
$this->ibl_encryptor->decrypt($prow['M_PatientHP_enc'] ?? '') ?: 'Belum ada WA pasien'
|
||||
);
|
||||
}
|
||||
if ($type == 'patient') {
|
||||
$sql = "SELECT 0 as kelurahan,
|
||||
'' as regional_cd,
|
||||
@@ -3664,7 +3788,7 @@ GROUP BY T_SampleStationID ";
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientEmail,'Belum ada email') as description,
|
||||
IFNULL({$patient_email},'Belum ada email') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -3682,7 +3806,7 @@ GROUP BY T_SampleStationID ";
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientEmail,'Belum ada email') as description,
|
||||
IFNULL({$patient_email},'Belum ada email') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -3700,7 +3824,7 @@ GROUP BY T_SampleStationID ";
|
||||
M_DeliveryM_DeliveryTypeID as delivery_type,
|
||||
M_DeliveryID as delivery_id,
|
||||
M_DeliveryName as delivery_name,
|
||||
IFNULL(M_PatientHP,'Belum ada WA pasien') as description,
|
||||
IFNULL({$patient_hp},'Belum ada WA pasien') as description,
|
||||
'N' as chex,
|
||||
'' as note,
|
||||
'origin' as typeform,
|
||||
@@ -3937,8 +4061,7 @@ GROUP BY T_SampleStationID ";
|
||||
$patient = $query->row_array();
|
||||
$patient['M_PatientName'] = stripslashes($patient['M_PatientName']);
|
||||
$patient['M_PatientAddress'] = stripslashes($patient['full_address']);
|
||||
$info = $this->db_onedev->query("SELECT fn_fo_patient_visit(?) info", [$patient['M_PatientID']])->row();
|
||||
$patient['info'] = json_decode($info->info);
|
||||
$patient['info'] = $this->build_patient_visit_info($patient['M_PatientID'], $patient['M_PatientDOB']);
|
||||
$rst['patient'] = $patient;
|
||||
|
||||
}
|
||||
@@ -4592,4 +4715,208 @@ GROUP BY T_SampleStationID ";
|
||||
exit;
|
||||
}
|
||||
|
||||
function load_klinik()
|
||||
{
|
||||
if (!$this->isLogin) { $this->sys_error("Invalid Token"); exit; }
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$klinik_number = trim($prm['klinik_number'] ?? '');
|
||||
|
||||
if (!$klinik_number) { $this->sys_error("klinik_number required"); exit; }
|
||||
|
||||
// Ambil header order klinik
|
||||
$row_header = $this->db_onedev->query(
|
||||
"SELECT o.*, s.*, od.orderDoctorDiagnosePrimer
|
||||
FROM one_klinik.`order` o
|
||||
JOIN one_klinik.setting s ON s.settingIsActive = 'Y'
|
||||
LEFT JOIN one_klinik.order_doctor od
|
||||
ON od.orderDoctorOrderID = o.orderID
|
||||
AND od.orderDoctorIsActive = 'Y'
|
||||
AND od.orderDoctorType = 'TEXT'
|
||||
WHERE o.OrderNumber = ?
|
||||
LIMIT 1",
|
||||
[$klinik_number]
|
||||
)->row_array();
|
||||
|
||||
if (!$row_header) { $this->sys_error("Order tidak ditemukan"); exit; }
|
||||
|
||||
$rst = [];
|
||||
$rst['klinik'] = $row_header;
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
// Patient
|
||||
$patient_row = $this->db_onedev->query(
|
||||
"SELECT m_patient.*,
|
||||
M_TitleID, M_TitleName,
|
||||
M_SexID, M_SexName,
|
||||
M_PatientAddressM_KelurahanID as M_KelurahanID,
|
||||
M_PatientAddressDescription,
|
||||
IFNULL(M_ReligionName,'-') as M_ReligionName
|
||||
FROM m_patient
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
LEFT JOIN m_patientaddress ON M_PatientAddressM_PatientID = M_PatientID AND M_PatientAddressIsActive = 'Y'
|
||||
LEFT JOIN m_religion ON M_PatientM_ReligionID = M_ReligionID
|
||||
WHERE M_PatientID = ?
|
||||
GROUP BY M_PatientID
|
||||
LIMIT 1",
|
||||
[$row_header['orderM_PatientID']]
|
||||
)->row_array();
|
||||
|
||||
if ($patient_row) {
|
||||
$p_name = $enc->decrypt($patient_row['M_PatientName_enc'] ?? '') ?: $patient_row['M_PatientName'];
|
||||
$p_hp = $enc->decrypt($patient_row['M_PatientHP_enc'] ?? '') ?: $patient_row['M_PatientHP'];
|
||||
$p_email = $enc->decrypt($patient_row['M_PatientEmail_enc'] ?? '') ?: $patient_row['M_PatientEmail'];
|
||||
$p_idnum = $enc->decrypt($patient_row['M_PatientIDNumber_enc']?? '') ?: $patient_row['M_PatientIDNumber'];
|
||||
$p_dob_raw = $enc->decrypt($patient_row['M_PatientDOB_enc'] ?? '');
|
||||
// p_dob_raw is d-m-Y; convert to Y-m-d for M_PatientDOB, keep d-m-Y for dob_ina
|
||||
$p_dob_ina = $p_dob_raw ?: $patient_row['M_PatientDOB'];
|
||||
$p_dob_sql = '';
|
||||
if ($p_dob_raw) {
|
||||
$parts = explode('-', $p_dob_raw);
|
||||
$p_dob_sql = count($parts) === 3 ? "{$parts[2]}-{$parts[1]}-{$parts[0]}" : '';
|
||||
}
|
||||
|
||||
$title = $patient_row['M_TitleName'] ? $patient_row['M_TitleName'] . ' ' : '';
|
||||
$prefix = $patient_row['M_PatientPrefix'] ? $patient_row['M_PatientPrefix'] . ' ': '';
|
||||
$suffix = $patient_row['M_PatientSuffix'] ? ' ' . $patient_row['M_PatientSuffix']: '';
|
||||
|
||||
$patient_row['M_PatientName'] = trim($title . $prefix . $p_name . $suffix);
|
||||
$patient_row['M_PatientRealName'] = $p_name;
|
||||
$patient_row['M_PatientHP'] = $p_hp;
|
||||
$patient_row['M_PatientEmail'] = $p_email;
|
||||
$patient_row['M_PatientIDNumber'] = $p_idnum;
|
||||
$patient_row['M_PatientDOB'] = $p_dob_sql ?: $patient_row['M_PatientDOB'];
|
||||
$patient_row['dob_ina'] = $p_dob_ina;
|
||||
$patient_row['divider'] = 'N';
|
||||
$patient_row['hp'] = $p_hp;
|
||||
$patient_row['M_PatientAddress'] = '';
|
||||
$patient_row['M_DistrictID'] = 0;
|
||||
$patient_row['M_CityID'] = 0;
|
||||
$patient_row['M_ProvinceID'] = 0;
|
||||
|
||||
if ($patient_row['M_KelurahanID']) {
|
||||
$addr = $this->db_onedev->query(
|
||||
"SELECT *, CONCAT(IFNULL(?,''),'\n\n',M_KelurahanName,', ',M_DistrictName,'\n',M_CityName,', ',M_ProvinceName) as xaddress
|
||||
FROM m_kelurahan
|
||||
JOIN m_district ON M_KelurahanM_DistrictID = M_DistrictID
|
||||
JOIN m_city ON M_DistrictM_CityID = M_CityID
|
||||
JOIN m_province ON M_CityM_ProvinceID = M_ProvinceID
|
||||
WHERE M_KelurahanID = ?",
|
||||
[$patient_row['M_PatientAddressDescription'], $patient_row['M_KelurahanID']]
|
||||
)->row_array();
|
||||
if ($addr) {
|
||||
$patient_row['M_PatientAddress'] = stripslashes($addr['xaddress']);
|
||||
$patient_row['M_DistrictID'] = $addr['M_DistrictID'];
|
||||
$patient_row['M_CityID'] = $addr['M_CityID'];
|
||||
$patient_row['M_ProvinceID'] = $addr['M_ProvinceID'];
|
||||
}
|
||||
}
|
||||
|
||||
$patient_row['info'] = $this->build_patient_visit_info($patient_row['M_PatientID'], $patient_row['M_PatientDOB']);
|
||||
|
||||
// Hapus kolom enc sebelum return
|
||||
foreach (['M_PatientName_enc','M_PatientName_bidx','M_PatientHP_enc','M_PatientHP_bidx',
|
||||
'M_PatientEmail_enc','M_PatientIDNumber_enc','M_PatientNIK_bidx',
|
||||
'M_PatientDOB_enc','M_PatientDOB_bidx'] as $col) {
|
||||
unset($patient_row[$col]);
|
||||
}
|
||||
|
||||
$rst['patient'] = $patient_row;
|
||||
} else {
|
||||
$rst['patient'] = [];
|
||||
}
|
||||
|
||||
// MOU & Company dari order
|
||||
$mou_id = intval($row_header['orderM_MouID'] ?? 0);
|
||||
$row_mou = $this->db_onedev->query(
|
||||
"SELECT M_MouM_CompanyID, M_MouStatus, M_MouEmail, M_MouEmailIsDefault,
|
||||
M_MouEndDate, M_MouID, M_MouIsBill, M_MouIsDefault, M_MouName,
|
||||
M_MouNote, M_MouStartDate
|
||||
FROM m_mou WHERE M_MouID = ?",
|
||||
[$mou_id]
|
||||
)->row_array();
|
||||
|
||||
$row_company = [];
|
||||
if ($row_mou) {
|
||||
$row_company = $this->db_onedev->query(
|
||||
"SELECT * FROM m_company WHERE M_CompanyID = ?",
|
||||
[$row_mou['M_MouM_CompanyID']]
|
||||
)->row_array();
|
||||
$row_company['mou'] = $this->db_onedev->query(
|
||||
"SELECT M_MouStatus, M_MouEmail, M_MouEmailIsDefault, M_MouEndDate, M_MouID,
|
||||
M_MouIsBill, M_MouIsDefault, M_MouName, M_MouNote, M_MouStartDate
|
||||
FROM m_mou
|
||||
WHERE M_MouM_CompanyID = ? AND M_MouStatus = 'R' AND M_MouIsActive = 'Y'",
|
||||
[$row_company['M_CompanyID']]
|
||||
)->result_array();
|
||||
}
|
||||
|
||||
$rst['selected_mou'] = $row_mou ?: [];
|
||||
$rst['selected_company'] = $row_company ?: [];
|
||||
$rst['companies'] = $row_company ? [$row_company] : [];
|
||||
|
||||
$rst['tests'] = [];
|
||||
$sql = "SELECT ss_price_mou.*
|
||||
FROM one_klinik.order_penunjang
|
||||
JOIN t_test
|
||||
ON orderPenunjangT_TestID = t_test.T_TestID
|
||||
AND t_test.T_TestIsActive = 'Y'
|
||||
JOIN ss_price_mou
|
||||
ON Ss_PriceMouM_MouID = ?
|
||||
AND t_test.T_TestID = ss_price_mou.T_TestID
|
||||
AND is_packet = 'N'
|
||||
WHERE orderPenunjangOrderID = ?
|
||||
AND orderPenunjangIsActive = 'Y'
|
||||
GROUP BY ss_price_mou.T_TestID";
|
||||
$qry_tests = $this->db_onedev->query($sql, [
|
||||
$row_header['settingM_MouID'],
|
||||
$row_header['orderID']
|
||||
]);
|
||||
if (!$qry_tests) {
|
||||
$this->sys_error_db("tests query: " . $this->db_onedev->error()['message'], $this->db_onedev);
|
||||
exit;
|
||||
}
|
||||
$get_tests_from_detail = $qry_tests->result_array();
|
||||
if ($get_tests_from_detail) {
|
||||
foreach ($get_tests_from_detail as $value) {
|
||||
$data_ss_price = $value;
|
||||
$data_ss_price['requirement'] = [];
|
||||
if ($data_ss_price['px_type'] == "PX") {
|
||||
$x = $this->db_smartone->query(
|
||||
"SELECT fn_fo_requirement_get(?) x",
|
||||
[$data_ss_price['T_TestID']]
|
||||
)->row();
|
||||
if ($x && $x->x != null) {
|
||||
$data_ss_price['requirement'] = json_decode($x->x);
|
||||
}
|
||||
}
|
||||
|
||||
if ($data_ss_price['is_packet'] == 'N') {
|
||||
$tests = $data_ss_price['T_PriceT_TestID'];
|
||||
$panels = '';
|
||||
} else {
|
||||
$tests = '';
|
||||
$panels = $data_ss_price['T_PriceT_TestID'];
|
||||
}
|
||||
|
||||
$x = $this->db_smartone->query(
|
||||
"SELECT fn_fo_find_promise_by_px(?, ?) as x",
|
||||
[$tests, $panels]
|
||||
)->row();
|
||||
if ($x && $x->x != null) {
|
||||
$data_ss_price['promise'] = $x->x;
|
||||
}
|
||||
|
||||
$data_ss_price['nat_test'] = json_decode($data_ss_price['nat_test']);
|
||||
$data_ss_price['child_test'] = json_decode($data_ss_price['child_test']);
|
||||
$rst['tests'][] = $data_ss_price;
|
||||
}
|
||||
}
|
||||
$rst['diagnose'] = $row_header['orderDoctorDiagnosePrimer'] ?? '';
|
||||
|
||||
$this->sys_ok(['records' => $rst]);
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,34 @@ class Patient extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_smartone = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
// Masking untuk kolom plaintext lama (data asli di _enc)
|
||||
private function _mask_name($v) {
|
||||
if (!$v) return $v;
|
||||
$v = trim($v);
|
||||
$words = preg_split('/\s+/', $v);
|
||||
if (count($words) === 1) {
|
||||
$l = mb_strlen($v, 'UTF-8');
|
||||
if ($l <= 2) return $v;
|
||||
return mb_substr($v, 0, 2, 'UTF-8') . str_repeat('*', $l - 2);
|
||||
}
|
||||
// Multi kata: kata pertama penuh + inisial kata berikutnya + *
|
||||
$first = $words[0];
|
||||
$rest = array_slice($words, 1);
|
||||
$masked = array_map(function($w) {
|
||||
if (!$w) return '';
|
||||
$init = mb_substr($w, 0, 1, 'UTF-8');
|
||||
return $init . str_repeat('*', max(3, mb_strlen($w, 'UTF-8') - 1));
|
||||
}, $rest);
|
||||
return $first . ' ' . implode(' ', $masked);
|
||||
}
|
||||
private function _mask_phone($v) { if (!$v) return $v; $d=preg_replace('/[^0-9]/','',trim($v)); $l=strlen($d); if($l<=4) return '****'; if($l<=8) return substr($d,0,4).str_repeat('*',$l-4); return substr($d,0,4).str_repeat('*',$l-7).substr($d,-3); }
|
||||
private function _mask_email($v) { if (!$v||strpos($v,'@')===false) return $v; [$loc,$dom]=explode('@',$v,2); return mb_substr($loc,0,min(2,mb_strlen($loc,'UTF-8')),'UTF-8').'***@'.$dom; }
|
||||
private function _mask_short($v) { if (!$v) return $v; $v=trim($v); $l=mb_strlen($v,'UTF-8'); if($l<=2) return '***'; return mb_substr($v,0,2,'UTF-8').'***'; }
|
||||
private function _mask_id($v) { if (!$v) return $v; $v=trim($v); $l=strlen($v); if($l<=4) return '****'; return substr($v,0,4).str_repeat('*',max(3,$l-6)).($l>6?substr($v,-2):''); }
|
||||
private function _mask_address($v) { if (!$v) return $v; $v=trim($v); $l=mb_strlen($v,'UTF-8'); if($l<=5) return '***'; return mb_substr($v,0,5,'UTF-8').'***'; }
|
||||
function _add_address(&$pat) {
|
||||
if (count($pat) == "0") {
|
||||
return array();
|
||||
@@ -76,113 +103,194 @@ class Patient extends MY_Controller
|
||||
{
|
||||
$prm = $this->sys_input;
|
||||
|
||||
$max_rst = 100;
|
||||
$tot_count =0;
|
||||
$number_limit = 10;
|
||||
$number_offset = (!isset($prm['current_page'])?1:$prm['current_page'] - 1) * $number_limit ;
|
||||
$number_limit = 10;
|
||||
$number_offset = (!isset($prm['current_page']) ? 1 : $prm['current_page'] - 1) * $number_limit;
|
||||
|
||||
$q = [
|
||||
'noreg' => "",
|
||||
'name' => '',
|
||||
'hp' => '',
|
||||
'dob' => '',
|
||||
'address' => ''
|
||||
];
|
||||
$where_noreg = '';
|
||||
$where_name = '';
|
||||
$where_hp = '';
|
||||
$where_dob = '';
|
||||
$where_nik = '';
|
||||
|
||||
$search_address = '';
|
||||
if (!empty($prm['noreg'])) {
|
||||
$noreg = $this->db_smartone->escape_like_str($prm['noreg']);
|
||||
$where_noreg = "AND M_PatientNoReg LIKE '%{$noreg}%'";
|
||||
}
|
||||
|
||||
if ($prm['noreg'] != '')
|
||||
$q['noreg'] = "AND M_PatientNoReg like '%{$prm['noreg']}%'";
|
||||
|
||||
if ($prm['search'] != '')
|
||||
{
|
||||
if (!empty($prm['search'])) {
|
||||
$e = explode('+', $prm['search']);
|
||||
if (isset($e[0])){
|
||||
$e[0] = str_replace("'", "\\'", $e[0]);
|
||||
$q['name'] = "AND M_PatientName LIKE '%{$e[0]}%'";
|
||||
}
|
||||
if (isset($e[1]))
|
||||
$q['hp'] = "AND ((M_PatientHP LIKE '%{$e[1]}%' and M_PatientHP IS NOT NULL) OR (M_PatientHP IS NULL AND '{$e[1]}' = ''))";
|
||||
if (isset($e[2]))
|
||||
$q['dob'] = "AND ((DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$e[2]}%' and M_PatientDOB IS NOT NULL) OR (M_PatientDOB IS NULL AND '{$e[2]}' = ''))";
|
||||
if (isset($e[3]))
|
||||
$q['address'] = "AND M_PatientAddressDescription LIKE '%{$e[3]}%'";
|
||||
|
||||
// nama — trigram blind index (min 3 karakter)
|
||||
if (!empty($e[0]) && mb_strlen(trim($e[0])) >= 3) {
|
||||
$toks = $this->ibl_encryptor->query_tokens($e[0]);
|
||||
$conds = [];
|
||||
foreach ($toks as $tok) {
|
||||
$tok_esc = $this->db_smartone->escape_str($tok);
|
||||
$conds[] = "JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
if ($conds) $where_name = 'AND (' . implode(' AND ', $conds) . ')';
|
||||
}
|
||||
|
||||
// hp — trigram blind index
|
||||
if (!empty($e[1]) && mb_strlen(trim($e[1])) >= 3) {
|
||||
$toks = $this->ibl_encryptor->query_tokens($e[1]);
|
||||
$conds = [];
|
||||
foreach ($toks as $tok) {
|
||||
$tok_esc = $this->db_smartone->escape_str($tok);
|
||||
$conds[] = "JSON_CONTAINS(M_PatientHP_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
if ($conds) $where_hp = 'AND (' . implode(' AND ', $conds) . ')';
|
||||
}
|
||||
|
||||
// dob — trigram blind index (format dd-mm-yyyy)
|
||||
if (!empty($e[2]) && mb_strlen(trim($e[2])) >= 3) {
|
||||
$toks = $this->ibl_encryptor->query_tokens($e[2]);
|
||||
$conds = [];
|
||||
foreach ($toks as $tok) {
|
||||
$tok_esc = $this->db_smartone->escape_str($tok);
|
||||
$conds[] = "JSON_CONTAINS(M_PatientDOB_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
if ($conds) $where_dob = 'AND (' . implode(' AND ', $conds) . ')';
|
||||
}
|
||||
|
||||
// nik — trigram blind index
|
||||
if (!empty($e[3]) && mb_strlen(trim($e[3])) >= 3) {
|
||||
$toks = $this->ibl_encryptor->query_tokens($e[3]);
|
||||
$conds = [];
|
||||
foreach ($toks as $tok) {
|
||||
$tok_esc = $this->db_smartone->escape_str($tok);
|
||||
$conds[] = "JSON_CONTAINS(M_PatientNIK_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
if ($conds) $where_nik = 'AND (' . implode(' AND ', $conds) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
if($q['address'] == ''){
|
||||
$q['address'] = "AND M_PatientAddressNote = 'Utama'";
|
||||
}
|
||||
|
||||
|
||||
$sql = "SELECT 'N' divider,M_PatientID, M_PatientNoReg,M_PatientEmail,M_PatientPrefix,M_PatientSuffix,
|
||||
concat(M_TitleName,' ',IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) M_PatientName,
|
||||
M_PatientName M_PatientRealName, M_TitleID, M_TitleName, M_SexID, M_SexName,
|
||||
M_PatientHP, M_PatientPOB, M_PatientDOB, DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as dob_ina,
|
||||
$sql = "SELECT 'N' divider, M_PatientID, M_PatientNoReg, M_PatientPrefix, M_PatientSuffix,
|
||||
concat(M_TitleName,' ',IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) M_PatientNameRaw,
|
||||
M_TitleID, M_TitleName, M_SexID, M_SexName,
|
||||
M_PatientDOB,
|
||||
'' M_PatientAddress,
|
||||
M_PatientAddressID,
|
||||
M_PatientAddressDescription, M_PatientM_IdTypeID, M_PatientIDNumber,
|
||||
M_PatientAddressRegionalCd,
|
||||
M_PatientAddressLocation,
|
||||
M_PatientAddressCity,
|
||||
M_PatientAddressVillage,
|
||||
M_PatientAddressDistrict,
|
||||
M_PatientAddressState,
|
||||
M_PatientAddressCountry,
|
||||
M_PatientAddressCountryCode,
|
||||
IFNULL(M_PatientNote, '') M_PatientNote, M_PatientPhoto, IF(M_PatientPhone IS NULL OR M_PatientPhone = '', M_PatientHP, M_PatientPhone) hp,
|
||||
-- fn_fo_patient_visit(M_PatientID) info,
|
||||
M_PatientAddressM_KelurahanID M_KelurahanID, 0 M_DistrictID, 0 M_CityID, 0 M_ProvinceID, M_PatientM_ReligionID,
|
||||
IFNULL(M_ReligionName, '-') M_ReligionName,
|
||||
M_PatientAddressRegionalCd, M_PatientAddressLocation, M_PatientAddressCity,
|
||||
M_PatientAddressVillage, M_PatientAddressDistrict, M_PatientAddressState,
|
||||
M_PatientAddressCountry, M_PatientAddressCountryCode,
|
||||
M_PatientAddressM_KelurahanID M_KelurahanID, 0 M_DistrictID, 0 M_CityID, 0 M_ProvinceID,
|
||||
M_PatientM_ReligionID, IFNULL(M_ReligionName, '-') M_ReligionName,
|
||||
IFNULL(Patient_SignatureUrl, '') image_signature,
|
||||
M_PatientNote
|
||||
FROM m_patient
|
||||
join m_title on M_PatientM_TitleID = M_TitleID
|
||||
join m_sex on M_PatientM_SexID = M_SexID
|
||||
join m_patientaddress on M_PatientAddressM_PatientID = M_PatientID and M_PatientAddressIsActive = 'Y' {$q['address']}
|
||||
left join m_religion on m_patientm_religionid = m_religionid
|
||||
left join patient_signature on Patient_SignatureM_PatientID = M_PatientID and Patient_SignatureIsActive = 'Y'
|
||||
where M_PatientIsActive = 'Y'
|
||||
{$q['noreg']}
|
||||
{$q['name']}
|
||||
{$q['hp']}
|
||||
{$q['dob']}
|
||||
|
||||
group by M_PatientID
|
||||
limit $number_limit offset $number_offset";
|
||||
//echo $sql;
|
||||
IFNULL(M_PatientNote, '') M_PatientNote, M_PatientPhoto,
|
||||
M_PatientM_IdTypeID,
|
||||
M_PatientName_enc, M_PatientHP_enc, M_PatientDOB_enc,
|
||||
M_PatientEmail_enc, M_PatientPhone_enc, M_PatientPOB_enc,
|
||||
M_PatientIDNumber_enc, M_PatientNIK_enc, M_PatientAddressDescription_enc
|
||||
FROM m_patient
|
||||
JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
JOIN m_patientaddress ON M_PatientAddressM_PatientID = M_PatientID
|
||||
AND M_PatientAddressIsActive = 'Y' AND M_PatientAddressNote = 'Utama'
|
||||
LEFT JOIN m_religion ON M_PatientM_ReligionID = M_ReligionID
|
||||
LEFT JOIN patient_signature ON Patient_SignatureM_PatientID = M_PatientID
|
||||
AND Patient_SignatureIsActive = 'Y'
|
||||
WHERE M_PatientIsActive = 'Y'
|
||||
{$where_noreg}
|
||||
{$where_name}
|
||||
{$where_hp}
|
||||
{$where_dob}
|
||||
{$where_nik}
|
||||
GROUP BY M_PatientID
|
||||
LIMIT {$number_limit} OFFSET {$number_offset}";
|
||||
|
||||
$query = $this->db_smartone->query($sql);
|
||||
|
||||
if ($query) {
|
||||
$rows = $query->result_array();
|
||||
|
||||
foreach ($rows as $k => $v)
|
||||
{
|
||||
$rows[$k]['M_PatientName'] = stripslashes($rows[$k]['M_PatientName']);
|
||||
$rows[$k]['M_PatientAddress'] = stripslashes($rows[$k]['M_PatientAddressDescription']);
|
||||
$info = $this->db_smartone->query("SELECT fn_fo_patient_visit(?) info", [$v['M_PatientID']])->row();
|
||||
$rows[$k]['info'] = json_decode($info->info);
|
||||
|
||||
$references = [];
|
||||
$sql = "SELECT M_ReferenceID, M_ReferenceName
|
||||
FROM m_patient_reference
|
||||
join m_reference on M_PatientReferenceM_ReferenceID = M_ReferenceID
|
||||
WHERE M_PatientReferenceM_PatientID = ? AND M_PatientReferenceIsActive = 'Y'";
|
||||
$query = $this->db_smartone->query($sql, [$v['M_PatientID']]);
|
||||
if ($query) {
|
||||
$references = $query->result_array();
|
||||
}
|
||||
$rows[$k]['references'] = $references;
|
||||
}
|
||||
|
||||
$result = array("total" => $tot_page, "records" => $rows, "sql"=> $this->db_smartone->last_query());
|
||||
$this->sys_ok($result);
|
||||
}
|
||||
else {
|
||||
$this->sys_error_db("m_patient rows",$this->db_smartone);
|
||||
exit;
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_patient rows", $this->db_smartone);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$rows = $query->result_array();
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
foreach ($rows as $k => $v) {
|
||||
$name = $enc->decrypt($v['M_PatientName_enc']) ?? $v['M_PatientNameRaw'];
|
||||
$hp = $enc->decrypt($v['M_PatientHP_enc']) ?? '';
|
||||
$phone = $enc->decrypt($v['M_PatientPhone_enc']) ?? '';
|
||||
$dob_dec = $enc->decrypt($v['M_PatientDOB_enc']) ?? date('d-m-Y', strtotime($v['M_PatientDOB']));
|
||||
$addr = $enc->decrypt($v['M_PatientAddressDescription_enc']) ?? '';
|
||||
|
||||
$rows[$k]['M_PatientName'] = $name;
|
||||
$rows[$k]['M_PatientAddress'] = $addr;
|
||||
$rows[$k]['M_PatientAddressDescription'] = $addr;
|
||||
$rows[$k]['M_PatientHP'] = $hp;
|
||||
$rows[$k]['M_PatientEmail'] = $enc->decrypt($v['M_PatientEmail_enc']) ?? '';
|
||||
$rows[$k]['M_PatientPhone'] = $phone;
|
||||
$rows[$k]['M_PatientPOB'] = $enc->decrypt($v['M_PatientPOB_enc']) ?? '';
|
||||
$rows[$k]['M_PatientIDNumber'] = $enc->decrypt($v['M_PatientIDNumber_enc']) ?? '';
|
||||
$rows[$k]['M_PatientNIK'] = $enc->decrypt($v['M_PatientNIK_enc']) ?? '';
|
||||
$rows[$k]['dob_ina'] = $dob_dec;
|
||||
$rows[$k]['hp'] = $phone ?: $hp;
|
||||
|
||||
// bersihkan kolom _enc dari response
|
||||
foreach (array_keys($rows[$k]) as $col) {
|
||||
if (substr($col, -4) === '_enc') unset($rows[$k][$col]);
|
||||
}
|
||||
unset($rows[$k]['M_PatientNameRaw'], $rows[$k]['M_PatientDOB']);
|
||||
|
||||
$rows[$k]['info'] = $this->build_patient_visit_info($v['M_PatientID'], $dob_dec);
|
||||
|
||||
$ref_query = $this->db_smartone->query(
|
||||
"SELECT M_ReferenceID, M_ReferenceName
|
||||
FROM m_patient_reference
|
||||
JOIN m_reference ON M_PatientReferenceM_ReferenceID = M_ReferenceID
|
||||
WHERE M_PatientReferenceM_PatientID = ? AND M_PatientReferenceIsActive = 'Y'",
|
||||
[$v['M_PatientID']]
|
||||
);
|
||||
$rows[$k]['references'] = $ref_query ? $ref_query->result_array() : [];
|
||||
}
|
||||
|
||||
$this->sys_ok(["total" => 0, "records" => $rows]);
|
||||
}
|
||||
|
||||
protected function build_patient_visit_info($patient_id, $patient_dob)
|
||||
{
|
||||
$visit = 1;
|
||||
$birthday = 'N';
|
||||
|
||||
$visit_query = $this->db_smartone->query(
|
||||
"SELECT COUNT(DISTINCT T_OrderHeaderID) AS n
|
||||
FROM t_orderheader
|
||||
JOIN t_orderdetail ON T_OrderHeaderID = T_OrderDetailT_OrderHeaderID AND T_OrderDetailIsActive = 'Y'
|
||||
WHERE T_OrderHeaderIsActive = 'Y'
|
||||
AND T_OrderHeaderM_PatientID = ?",
|
||||
[$patient_id]
|
||||
);
|
||||
|
||||
if ($visit_query) {
|
||||
$visit_row = $visit_query->row_array();
|
||||
$visit += (int) ($visit_row['n'] ?? 0);
|
||||
}
|
||||
|
||||
$init_visit_query = $this->db_smartone->query(
|
||||
"SELECT M_PatientInitialVisit
|
||||
FROM m_patient
|
||||
WHERE M_PatientID = ?",
|
||||
[$patient_id]
|
||||
);
|
||||
|
||||
if ($init_visit_query) {
|
||||
$init_visit_row = $init_visit_query->row_array();
|
||||
if (!empty($init_visit_row['M_PatientInitialVisit'])) {
|
||||
$visit += (int) $init_visit_row['M_PatientInitialVisit'];
|
||||
}
|
||||
}
|
||||
|
||||
$dob_time = empty($patient_dob) ? false : strtotime($patient_dob);
|
||||
if ($dob_time !== false) {
|
||||
$birthday = date('m-d', $dob_time) === date('m-d') ? 'Y' : 'N';
|
||||
}
|
||||
|
||||
return json_decode(json_encode([
|
||||
'visit' => $visit,
|
||||
'birthday' => $birthday,
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
@@ -199,24 +307,36 @@ class Patient extends MY_Controller
|
||||
$M_IdTypeID = $prm['M_PatientM_IdTypeID'];
|
||||
}
|
||||
$patient_name = str_replace("'", "\\'", $prm['M_PatientName']);
|
||||
$dob_str = date('d-m-Y', strtotime($prm['M_PatientDOB']));
|
||||
$ptn = [
|
||||
'M_PatientName' => $patient_name,
|
||||
'M_PatientM_TitleID' => $prm['M_PatientM_TitleID'],
|
||||
'M_PatientPrefix' => $prm['M_PatientPrefix'],
|
||||
'M_PatientSuffix' => $prm['M_PatientSuffix'],
|
||||
'M_PatientM_SexID' => $prm['M_PatientM_SexID'],
|
||||
'M_PatientM_ReligionID' => $prm['M_PatientM_ReligionID'],
|
||||
'M_PatientDOB' => $prm['M_PatientDOB'],
|
||||
'M_PatientPOB' => $prm['M_PatientPOB'],
|
||||
'M_PatientHP' => $prm['M_PatientHP'],
|
||||
'M_PatientPhone' => $prm['M_PatientPhone'],
|
||||
'M_PatientEmail' => $prm['M_PatientEmail'],
|
||||
'M_PatientM_IdTypeID' => $M_IdTypeID ,
|
||||
'M_PatientIDNumber' => $prm['M_PatientIDNumber'],
|
||||
'M_PatientNote' => $prm['M_PatientNote'],
|
||||
'M_PatientUserID' => $userid,
|
||||
'M_PatientCreated' => date('Y-m-d H:i:s'),
|
||||
'M_PatientCreatedUserID' => $userid
|
||||
'M_PatientName' => $this->_mask_name($patient_name),
|
||||
'M_PatientName_enc' => $this->ibl_encryptor->encrypt($patient_name),
|
||||
'M_PatientName_bidx' => $this->ibl_encryptor->search_bidx($patient_name),
|
||||
'M_PatientM_TitleID' => $prm['M_PatientM_TitleID'],
|
||||
'M_PatientPrefix' => $prm['M_PatientPrefix'],
|
||||
'M_PatientSuffix' => $prm['M_PatientSuffix'],
|
||||
'M_PatientM_SexID' => $prm['M_PatientM_SexID'],
|
||||
'M_PatientM_ReligionID' => $prm['M_PatientM_ReligionID'],
|
||||
'M_PatientDOB' => $prm['M_PatientDOB'],
|
||||
'M_PatientDOB_enc' => $this->ibl_encryptor->encrypt($dob_str),
|
||||
'M_PatientDOB_bidx' => $this->ibl_encryptor->search_bidx($dob_str),
|
||||
'M_PatientPOB' => $this->_mask_short($prm['M_PatientPOB']),
|
||||
'M_PatientPOB_enc' => $this->ibl_encryptor->encrypt($prm['M_PatientPOB']),
|
||||
'M_PatientHP' => $this->_mask_phone($prm['M_PatientHP']),
|
||||
'M_PatientHP_enc' => $this->ibl_encryptor->encrypt($prm['M_PatientHP']),
|
||||
'M_PatientHP_bidx' => $this->ibl_encryptor->search_bidx($prm['M_PatientHP']),
|
||||
'M_PatientPhone' => $this->_mask_phone($prm['M_PatientPhone']),
|
||||
'M_PatientPhone_enc' => $this->ibl_encryptor->encrypt($prm['M_PatientPhone']),
|
||||
'M_PatientEmail' => $this->_mask_email($prm['M_PatientEmail']),
|
||||
'M_PatientEmail_enc' => $this->ibl_encryptor->encrypt($prm['M_PatientEmail']),
|
||||
'M_PatientM_IdTypeID' => $M_IdTypeID,
|
||||
'M_PatientIDNumber' => $this->_mask_id($prm['M_PatientIDNumber']),
|
||||
'M_PatientIDNumber_enc' => $this->ibl_encryptor->encrypt($prm['M_PatientIDNumber']),
|
||||
'M_PatientNIK_bidx' => $this->ibl_encryptor->search_bidx($prm['M_PatientNIK'] ?? ''),
|
||||
'M_PatientNote' => $prm['M_PatientNote'],
|
||||
'M_PatientUserID' => $userid,
|
||||
'M_PatientCreated' => date('Y-m-d H:i:s'),
|
||||
'M_PatientCreatedUserID' => $userid
|
||||
];
|
||||
$this->db_smartone->insert('m_patient', $ptn);
|
||||
|
||||
@@ -235,21 +355,21 @@ class Patient extends MY_Controller
|
||||
$address_description = str_replace("'", "\\'", $prm['M_PatientAddressDescription']);
|
||||
// save address
|
||||
$add = [
|
||||
'M_PatientAddressM_PatientID' => $id,
|
||||
'M_PatientAddressDescription' => $address_description,
|
||||
'M_PatientAddressUserID'=> $userid,
|
||||
'M_PatientAddressRegionalCd' => $prm['M_PatientAddressRegionalCd'],
|
||||
'M_PatientAddressLocation' => $prm['M_PatientAddressLocation'],
|
||||
'M_PatientAddressCity' => $prm['M_PatientAddressCity'],
|
||||
'M_PatientAddressVillage' => $prm['M_PatientAddressVillage'],
|
||||
'M_PatientAddressDistrict' => $prm['M_PatientAddressDistrict'],
|
||||
'M_PatientAddressState' => $prm['M_PatientAddressState'],
|
||||
'M_PatientAddressCountry' => $prm['M_PatientAddressCountry'],
|
||||
'M_PatientAddressCountryCode' => $prm['M_PatientAddressCountryCode'],
|
||||
'M_PatientAddressNote' => isset($prm['M_PatientAddressNote']) ? $prm['M_PatientAddressNote'] : 'Utama',
|
||||
'M_PatientAddressCreated' => date('Y-m-d H:i:s'),
|
||||
'M_PatientAddressCreatedUserID' => $userid
|
||||
|
||||
'M_PatientAddressM_PatientID' => $id,
|
||||
'M_PatientAddressDescription' => $this->_mask_address($address_description),
|
||||
'M_PatientAddressDescription_enc' => $this->ibl_encryptor->encrypt($address_description),
|
||||
'M_PatientAddressUserID' => $userid,
|
||||
'M_PatientAddressRegionalCd' => $prm['M_PatientAddressRegionalCd'],
|
||||
'M_PatientAddressLocation' => $prm['M_PatientAddressLocation'],
|
||||
'M_PatientAddressCity' => $prm['M_PatientAddressCity'],
|
||||
'M_PatientAddressVillage' => $prm['M_PatientAddressVillage'],
|
||||
'M_PatientAddressDistrict' => $prm['M_PatientAddressDistrict'],
|
||||
'M_PatientAddressState' => $prm['M_PatientAddressState'],
|
||||
'M_PatientAddressCountry' => $prm['M_PatientAddressCountry'],
|
||||
'M_PatientAddressCountryCode' => $prm['M_PatientAddressCountryCode'],
|
||||
'M_PatientAddressNote' => isset($prm['M_PatientAddressNote']) ? $prm['M_PatientAddressNote'] : 'Utama',
|
||||
'M_PatientAddressCreated' => date('Y-m-d H:i:s'),
|
||||
'M_PatientAddressCreatedUserID' => $userid
|
||||
];
|
||||
$this->db_smartone->insert('m_patientaddress', $add);
|
||||
$err = $this->db_smartone->error();
|
||||
@@ -290,23 +410,35 @@ class Patient extends MY_Controller
|
||||
$prm = $this->sys_input;
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
$prm['M_PatientDOB'] = date('Y-m-d', strtotime($prm['M_PatientDOB']));
|
||||
$patient_name = str_replace("'", "\\'", $prm['M_PatientName']);
|
||||
|
||||
$this->db_smartone->set('M_PatientName', $patient_name)
|
||||
$patient_name = str_replace("'", "\\'", $prm['M_PatientName']);
|
||||
$dob_str = date('d-m-Y', strtotime($prm['M_PatientDOB']));
|
||||
|
||||
$this->db_smartone->set('M_PatientName', $this->_mask_name($patient_name))
|
||||
->set('M_PatientName_enc', $this->ibl_encryptor->encrypt($patient_name))
|
||||
->set('M_PatientName_bidx', $this->ibl_encryptor->search_bidx($patient_name))
|
||||
->set('M_PatientM_TitleID', $prm['M_PatientM_TitleID'])
|
||||
->set('M_PatientPrefix', $prm['M_PatientPrefix'])
|
||||
->set('M_PatientSuffix', $prm['M_PatientSuffix'])
|
||||
->set('M_PatientSuffix', $prm['M_PatientSuffix'])
|
||||
->set('M_PatientM_SexID', $prm['M_PatientM_SexID'])
|
||||
->set('M_PatientM_ReligionID', $prm['M_PatientM_ReligionID'])
|
||||
->set('M_PatientDOB', $prm['M_PatientDOB'])
|
||||
->set('M_PatientPOB', $prm['M_PatientPOB'])
|
||||
->set('M_PatientHP', $prm['M_PatientHP'])
|
||||
->set('M_PatientPhone', $prm['M_PatientPhone'])
|
||||
->set('M_PatientEmail', $prm['M_PatientEmail'])
|
||||
->set('M_PatientDOB_enc', $this->ibl_encryptor->encrypt($dob_str))
|
||||
->set('M_PatientDOB_bidx', $this->ibl_encryptor->search_bidx($dob_str))
|
||||
->set('M_PatientPOB', $this->_mask_short($prm['M_PatientPOB']))
|
||||
->set('M_PatientPOB_enc', $this->ibl_encryptor->encrypt($prm['M_PatientPOB']))
|
||||
->set('M_PatientHP', $this->_mask_phone($prm['M_PatientHP']))
|
||||
->set('M_PatientHP_enc', $this->ibl_encryptor->encrypt($prm['M_PatientHP']))
|
||||
->set('M_PatientHP_bidx', $this->ibl_encryptor->search_bidx($prm['M_PatientHP']))
|
||||
->set('M_PatientPhone', $this->_mask_phone($prm['M_PatientPhone']))
|
||||
->set('M_PatientPhone_enc', $this->ibl_encryptor->encrypt($prm['M_PatientPhone']))
|
||||
->set('M_PatientEmail', $this->_mask_email($prm['M_PatientEmail']))
|
||||
->set('M_PatientEmail_enc', $this->ibl_encryptor->encrypt($prm['M_PatientEmail']))
|
||||
->set('M_PatientM_IdTypeID', $prm['M_PatientM_IdTypeID'])
|
||||
->set('M_PatientIDNumber', $prm['M_PatientIDNumber'])
|
||||
->set('M_PatientIDNumber', $this->_mask_id($prm['M_PatientIDNumber']))
|
||||
->set('M_PatientIDNumber_enc', $this->ibl_encryptor->encrypt($prm['M_PatientIDNumber']))
|
||||
->set('M_PatientNIK_bidx', $this->ibl_encryptor->search_bidx($prm['M_PatientIDNumber'] ?? ''))
|
||||
->set('M_PatientNote', $prm['M_PatientNote'])
|
||||
->set('M_PatientUserID', $userid)
|
||||
->set('M_PatientUserID', $userid)
|
||||
->set('M_PatientLastUpdatedUserID', $userid)
|
||||
->where('M_PatientID', $prm['id'])
|
||||
->update('m_patient');
|
||||
@@ -325,7 +457,7 @@ class Patient extends MY_Controller
|
||||
$ptn = json_encode($prm);
|
||||
$id_address = isset($prm['M_PatientAddressID']) && $prm['M_PatientAddressID'] > 0 ? $prm['M_PatientAddressID']:0;
|
||||
|
||||
$address_description = str_replace("'", "\\'", $prm['M_PatientAddressDescription']);
|
||||
$address_description = str_replace("'", "\\'", $prm['M_PatientAddressDescription']);
|
||||
$this->db_smartone->set('M_PatientAddressRegionalCd', $prm['M_PatientAddressRegionalCd'])
|
||||
->set('M_PatientAddressLocation', $prm['M_PatientAddressLocation'])
|
||||
->set('M_PatientAddressCity', $prm['M_PatientAddressCity'])
|
||||
@@ -334,8 +466,9 @@ class Patient extends MY_Controller
|
||||
->set('M_PatientAddressState', $prm['M_PatientAddressState'])
|
||||
->set('M_PatientAddressCountry', $prm['M_PatientAddressCountry'])
|
||||
->set('M_PatientAddressCountryCode', $prm['M_PatientAddressCountryCode'])
|
||||
->set('M_PatientAddressDescription', $address_description )
|
||||
->set('M_PatientAddressUserID', $userid )
|
||||
->set('M_PatientAddressDescription', $this->_mask_address($address_description))
|
||||
->set('M_PatientAddressDescription_enc', $this->ibl_encryptor->encrypt($address_description))
|
||||
->set('M_PatientAddressUserID', $userid)
|
||||
->set('M_PatientAddressLastUpdatedUserID', $userid)
|
||||
->where('M_PatientAddressID', $id_address)
|
||||
->update('m_patientaddress');
|
||||
|
||||
@@ -12,6 +12,279 @@ class Payment extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_smartone = $this->load->database("onedev", true);
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
private function get_payment_type_code($payment_type_id)
|
||||
{
|
||||
$query = $this->db_onedev->query(
|
||||
"SELECT M_PaymentTypeCode
|
||||
FROM m_paymenttype
|
||||
WHERE M_PaymentTypeID = ?
|
||||
LIMIT 1",
|
||||
[intval($payment_type_id)]
|
||||
);
|
||||
|
||||
if (!$query) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return strtoupper($query->row()->M_PaymentTypeCode ?? '');
|
||||
}
|
||||
|
||||
private function normalize_payment($payment)
|
||||
{
|
||||
if (isset($payment['leftvalue']) || isset($payment['rightvalue']) || isset($payment['code'])) {
|
||||
$payment['id'] = strval($payment['id'] ?? $payment['type'] ?? 0);
|
||||
$payment['code'] = strtoupper($payment['code'] ?? $this->get_payment_type_code($payment['id']));
|
||||
$payment['leftvalue'] = floatval($payment['leftvalue'] ?? 0);
|
||||
$payment['rightvalue'] = floatval($payment['rightvalue'] ?? 0);
|
||||
$payment['chex'] = isset($payment['chex']) ? (bool) $payment['chex'] : ($this->payment_amount_net($payment) > 0);
|
||||
return $payment;
|
||||
}
|
||||
|
||||
$normalized = $payment;
|
||||
$normalized['id'] = strval($payment['type'] ?? $payment['id'] ?? 0);
|
||||
$normalized['code'] = $this->get_payment_type_code($normalized['id']);
|
||||
$normalized['leftvalue'] = floatval($payment['actual'] ?? $payment['amount'] ?? 0);
|
||||
$normalized['rightvalue'] = floatval($payment['changes'] ?? 0);
|
||||
$normalized['chex'] = $normalized['leftvalue'] > 0;
|
||||
$normalized['selected_card'] = ['id' => intval($payment['card'] ?? 0), 'name' => ''];
|
||||
$normalized['selected_edc'] = ['id' => intval($payment['edc'] ?? 0), 'name' => ''];
|
||||
$normalized['selected_account'] = ['id' => intval($payment['account'] ?? 0), 'name' => ''];
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
private function denormalize_payment($original_payment, $normalized_payment)
|
||||
{
|
||||
if (isset($original_payment['leftvalue']) || isset($original_payment['rightvalue']) || isset($original_payment['code'])) {
|
||||
$original_payment['id'] = $normalized_payment['id'];
|
||||
$original_payment['code'] = $normalized_payment['code'];
|
||||
$original_payment['leftvalue'] = $normalized_payment['leftvalue'];
|
||||
$original_payment['rightvalue'] = $normalized_payment['rightvalue'];
|
||||
$original_payment['chex'] = !empty($normalized_payment['chex']);
|
||||
return $original_payment;
|
||||
}
|
||||
|
||||
$original_payment['type'] = strval($normalized_payment['id']);
|
||||
$original_payment['amount'] = floatval($this->payment_amount_net($normalized_payment));
|
||||
$original_payment['actual'] = floatval($normalized_payment['leftvalue']);
|
||||
$original_payment['changes'] = floatval($normalized_payment['rightvalue']);
|
||||
$original_payment['card'] = strval($this->get_selected_lookup_id($normalized_payment['selected_card'] ?? null));
|
||||
$original_payment['edc'] = strval($this->get_selected_lookup_id($normalized_payment['selected_edc'] ?? null));
|
||||
$original_payment['account'] = strval($this->get_selected_lookup_id($normalized_payment['selected_account'] ?? null));
|
||||
return $original_payment;
|
||||
}
|
||||
|
||||
private function payment_amount_net($payment)
|
||||
{
|
||||
$left = floatval($payment['leftvalue'] ?? 0);
|
||||
$right = floatval($payment['rightvalue'] ?? 0);
|
||||
$code = strtoupper($payment['code'] ?? '');
|
||||
if ($code === 'CASH') {
|
||||
return max(0, $left - $right);
|
||||
}
|
||||
return max(0, $left);
|
||||
}
|
||||
|
||||
private function build_zero_payment($payment)
|
||||
{
|
||||
$payment['chex'] = false;
|
||||
$payment['leftvalue'] = 0;
|
||||
$payment['rightvalue'] = 0;
|
||||
return $payment;
|
||||
}
|
||||
|
||||
private function get_selected_lookup_id($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return intval($value['id'] ?? 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function split_payments_for_klinik($payments, $clinic_amount)
|
||||
{
|
||||
$remaining_clinic = max(0, floatval($clinic_amount));
|
||||
$clinic_payments = [];
|
||||
$ibl_payments = [];
|
||||
|
||||
foreach ($payments as $payment) {
|
||||
$normalized_payment = $this->normalize_payment($payment);
|
||||
$code = strtoupper($normalized_payment['code'] ?? '');
|
||||
$net_amount = $this->payment_amount_net($normalized_payment);
|
||||
$allocated = min($remaining_clinic, $net_amount);
|
||||
|
||||
$clinic_payment = $this->build_zero_payment($normalized_payment);
|
||||
$ibl_payment = $normalized_payment;
|
||||
|
||||
if ($allocated > 0) {
|
||||
$clinic_payment['chex'] = true;
|
||||
if ($code === 'CASH') {
|
||||
$clinic_payment['leftvalue'] = $allocated;
|
||||
$clinic_payment['rightvalue'] = 0;
|
||||
|
||||
$ibl_payment['leftvalue'] = max(0, floatval($normalized_payment['leftvalue']) - $allocated);
|
||||
$ibl_payment['chex'] = ($this->payment_amount_net($ibl_payment) > 0);
|
||||
} else {
|
||||
$clinic_payment['leftvalue'] = $allocated;
|
||||
$ibl_payment['leftvalue'] = max(0, floatval($normalized_payment['leftvalue']) - $allocated);
|
||||
$ibl_payment['chex'] = (floatval($ibl_payment['leftvalue']) > 0);
|
||||
}
|
||||
|
||||
$remaining_clinic -= $allocated;
|
||||
} else {
|
||||
$ibl_payment['chex'] = ($net_amount > 0) ? !empty($normalized_payment['chex']) : false;
|
||||
}
|
||||
|
||||
$clinic_payments[] = $clinic_payment;
|
||||
$ibl_payments[] = $this->denormalize_payment($payment, $ibl_payment);
|
||||
}
|
||||
|
||||
return [
|
||||
'clinic_payments' => $clinic_payments,
|
||||
'ibl_payments' => $ibl_payments,
|
||||
'allocated_total' => max(0, floatval($clinic_amount) - $remaining_clinic)
|
||||
];
|
||||
}
|
||||
|
||||
private function get_order_klinik_outstanding($order_klinik_id)
|
||||
{
|
||||
$sql = "SELECT
|
||||
o.orderID,
|
||||
o.orderTotal,
|
||||
IFNULL(SUM(CASE WHEN p.PaymentIsActive = 'Y' THEN p.PaymentTotal ELSE 0 END), 0) AS paid_total
|
||||
FROM one_klinik.`order` o
|
||||
LEFT JOIN one_klinik.`payment` p ON p.PaymentOrderID = o.orderID
|
||||
WHERE o.orderID = ?
|
||||
GROUP BY o.orderID, o.orderTotal
|
||||
LIMIT 1";
|
||||
$query = $this->db_onedev->query($sql, [$order_klinik_id]);
|
||||
if (!$query) {
|
||||
return [false, "Gagal mengambil data order klinik"];
|
||||
}
|
||||
|
||||
$row = $query->row_array();
|
||||
if (!$row) {
|
||||
return [false, "Order klinik tidak ditemukan"];
|
||||
}
|
||||
|
||||
$outstanding = max(0, floatval($row['orderTotal']) - floatval($row['paid_total']));
|
||||
$row['outstanding_total'] = $outstanding;
|
||||
return [true, $row];
|
||||
}
|
||||
|
||||
private function save_payment_klinik($orderid, $payments, $xuserid)
|
||||
{
|
||||
$sql = "INSERT INTO one_klinik.`payment`(PaymentOrderID,PaymentDate,PaymentCreated,PaymentM_UserID) VALUES (?,CURDATE(),NOW(),?)";
|
||||
$query = $this->db_onedev->query($sql, [$orderid, $xuserid]);
|
||||
|
||||
if (!$query) {
|
||||
return [false, "payment klinik insert"];
|
||||
}
|
||||
|
||||
$headerid = $this->db_onedev->insert_id();
|
||||
|
||||
foreach ($payments as $v) {
|
||||
if (empty($v['chex'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$actual = 0;
|
||||
$change = 0;
|
||||
$amount = floatval($v['leftvalue'] ?? 0);
|
||||
if (($v['code'] ?? '') == 'CASH') {
|
||||
$actual = floatval($v['leftvalue'] ?? 0);
|
||||
$change = floatval($v['rightvalue'] ?? 0);
|
||||
$amount = ($actual > 0) ? ($actual - $change) : $actual;
|
||||
|
||||
$sql = "INSERT INTO one_klinik.`paymentdetail`(
|
||||
PaymentDetailPaymentID,
|
||||
PaymentDetailM_PaymentTypeID,
|
||||
PaymentDetailAmount,
|
||||
PaymentDetailActual,
|
||||
PaymentDetailChange,
|
||||
PaymentDetailCreated,
|
||||
PaymentDetailLastUpdated,
|
||||
PaymentDetailUserID
|
||||
) VALUES (?, ?, ?, ?, ?, now(), now(), ?)";
|
||||
$query = $this->db_onedev->query($sql, [
|
||||
$headerid,
|
||||
$v['id'],
|
||||
$amount,
|
||||
$actual,
|
||||
$change,
|
||||
$xuserid
|
||||
]);
|
||||
if (!$query) {
|
||||
return [false, "payment klinik detail cash insert"];
|
||||
}
|
||||
} else {
|
||||
$selected_card = 0;
|
||||
$selected_edc = 0;
|
||||
if (($v['code'] ?? '') == 'DEBIT' || ($v['code'] ?? '') == 'CREDIT' || ($v['code'] ?? '') == 'TRANSFER') {
|
||||
$selected_card = $this->get_selected_lookup_id($v['selected_card'] ?? null);
|
||||
$selected_edc = $this->get_selected_lookup_id($v['selected_edc'] ?? null);
|
||||
if (($v['code'] ?? '') == 'TRANSFER') {
|
||||
$selected_edc = $this->get_selected_lookup_id($v['selected_account'] ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO one_klinik.`paymentdetail`(
|
||||
PaymentDetailPaymentID,
|
||||
PaymentDetailM_PaymentTypeID,
|
||||
PaymentDetailAmount,
|
||||
PaymentDetailActual,
|
||||
PaymentDetailChange,
|
||||
PaymentDetailCardNat_BankID,
|
||||
PaymentDetailEDCNat_BankID,
|
||||
PaymentDetailM_BankAccountID,
|
||||
PaymentDetailCreated,
|
||||
PaymentDetailLastUpdated,
|
||||
PaymentDetailUserID
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, now(), now(), ?)";
|
||||
$query = $this->db_onedev->query($sql, [
|
||||
$headerid,
|
||||
$v['id'],
|
||||
$amount,
|
||||
0,
|
||||
0,
|
||||
$selected_card,
|
||||
0,
|
||||
$selected_edc,
|
||||
$xuserid
|
||||
]);
|
||||
if (!$query) {
|
||||
return [false, "payment klinik detail non cash insert"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SELECT SUM(PaymentDetailAmount) as total
|
||||
FROM one_klinik.`paymentdetail`
|
||||
WHERE PaymentDetailPaymentID = ? AND PaymentDetailIsActive = 'Y'";
|
||||
$total_paid = floatval($this->db_onedev->query($sql, [$headerid])->row()->total ?? 0);
|
||||
|
||||
$sql = "UPDATE one_klinik.`payment` SET PaymentTotal = ? WHERE PaymentID = ?";
|
||||
$this->db_onedev->query($sql, [$total_paid, $headerid]);
|
||||
|
||||
$sql = "SELECT SUM(PaymentTotal) as paid, orderTotal as total
|
||||
FROM one_klinik.`payment`
|
||||
JOIN one_klinik.`order` ON orderID = PaymentOrderID
|
||||
WHERE PaymentOrderID = ? AND PaymentIsActive = 'Y'";
|
||||
$xtotal_all_paid = $this->db_onedev->query($sql, [$orderid])->row_array();
|
||||
if ($xtotal_all_paid && floatval($xtotal_all_paid['paid']) >= floatval($xtotal_all_paid['total'])) {
|
||||
$sql = "UPDATE one_klinik.`order` SET orderIsLunas = 'Y' WHERE orderID = ?";
|
||||
$this->db_onedev->query($sql, [$orderid]);
|
||||
}
|
||||
|
||||
$xdata = $this->db_onedev->query(
|
||||
"SELECT PaymentID as idx, PaymentNumber as numberx FROM one_klinik.payment WHERE PaymentID = ?",
|
||||
[$headerid]
|
||||
)->row();
|
||||
|
||||
return [true, ['payment_id' => $headerid, 'payment_total' => $total_paid, 'data' => $xdata]];
|
||||
}
|
||||
|
||||
public function get_order() {
|
||||
@@ -26,7 +299,7 @@ class Payment extends MY_Controller
|
||||
T_OrderHeaderSubTotal as order_subtotal,
|
||||
T_OrderHeaderRounding as order_rounding,
|
||||
T_OrderHeaderTotal as order_total,
|
||||
concat(if(M_TitleID is null, '', concat(M_TitleName, ' ')), M_PatientName) as patient_name,
|
||||
M_PatientName_enc, M_TitleName,
|
||||
M_PatientNoReg as patient_mr,
|
||||
M_MouName as order_mou,
|
||||
M_CompanyName as order_company,
|
||||
@@ -47,6 +320,10 @@ class Payment extends MY_Controller
|
||||
$query = $this->db_smartone->query($sql, array($prm['id']));
|
||||
if ($query) {
|
||||
$rows = (array) $query->row();
|
||||
$name = $this->ibl_encryptor->decrypt($rows['M_PatientName_enc']);
|
||||
$title = !empty($rows['M_TitleName']) ? $rows['M_TitleName'] . ' ' : '';
|
||||
$rows['patient_name'] = $title . ($name ?? '');
|
||||
unset($rows['M_PatientName_enc'], $rows['M_TitleName']);
|
||||
$rst['order_header'] = $rows;
|
||||
// $result = array("status" => "OK" , "data" => $rst);
|
||||
// $this->sys_ok($result);
|
||||
@@ -175,8 +452,55 @@ class Payment extends MY_Controller
|
||||
function save()
|
||||
{
|
||||
$prm = $this->sys_input;
|
||||
$payment_json = json_encode($prm['payments']);
|
||||
$payments_ibl = $prm['payments'];
|
||||
$klinik_payment_result = null;
|
||||
|
||||
if (!empty($prm['order_klinik_id'])) {
|
||||
list($ok_order_klinik, $order_klinik_data) = $this->get_order_klinik_outstanding($prm['order_klinik_id']);
|
||||
if (!$ok_order_klinik) {
|
||||
$this->sys_error($order_klinik_data);
|
||||
exit;
|
||||
}
|
||||
|
||||
$split = $this->split_payments_for_klinik($prm['payments'], $order_klinik_data['outstanding_total']);
|
||||
if ($split['allocated_total'] > 0) {
|
||||
list($ok_payment_klinik, $payment_klinik_data) = $this->save_payment_klinik(
|
||||
$prm['order_klinik_id'],
|
||||
$split['clinic_payments'],
|
||||
$this->sys_user['M_UserID']
|
||||
);
|
||||
if (!$ok_payment_klinik) {
|
||||
$this->sys_error_db($payment_klinik_data, $this->db_onedev);
|
||||
exit;
|
||||
}
|
||||
$klinik_payment_result = $payment_klinik_data;
|
||||
}
|
||||
$payments_ibl = $split['ibl_payments'];
|
||||
}
|
||||
|
||||
$has_ibl_payment = false;
|
||||
foreach ($payments_ibl as $payment) {
|
||||
$normalized_payment = $this->normalize_payment($payment);
|
||||
if (!empty($normalized_payment['chex']) && $this->payment_amount_net($normalized_payment) > 0) {
|
||||
$has_ibl_payment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$has_ibl_payment) {
|
||||
$result = [
|
||||
'status' => 'OK',
|
||||
'data' => [
|
||||
'status' => 'OK',
|
||||
'order_klinik_payment' => $klinik_payment_result,
|
||||
'ibl_payment' => null
|
||||
]
|
||||
];
|
||||
$this->sys_ok($result['data']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$payment_json = json_encode($payments_ibl);
|
||||
$sql = "CALL sp_fo_payment('{$prm['order_id']}', '{$payment_json}', '{$this->sys_user['M_UserID']}');";
|
||||
$query = $this->db_smartone->query($sql);
|
||||
|
||||
@@ -184,6 +508,9 @@ class Payment extends MY_Controller
|
||||
{
|
||||
$rst = $query->row();
|
||||
$rst->data = json_decode($rst->data);
|
||||
if (is_object($rst->data)) {
|
||||
$rst->data->order_klinik_payment = $klinik_payment_result;
|
||||
}
|
||||
echo json_encode($rst);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -11,6 +11,54 @@ class Patientv4 extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
private function _mask_name($v) {
|
||||
if (!$v) return $v;
|
||||
$v = trim($v);
|
||||
$words = preg_split('/\s+/', $v);
|
||||
if (count($words) === 1) {
|
||||
$l = mb_strlen($v, 'UTF-8');
|
||||
if ($l <= 2) return $v;
|
||||
return mb_substr($v, 0, 2, 'UTF-8') . str_repeat('*', $l - 2);
|
||||
}
|
||||
$first = $words[0];
|
||||
$rest = array_slice($words, 1);
|
||||
$masked = array_map(function($w) {
|
||||
if (!$w) return '';
|
||||
$init = mb_substr($w, 0, 1, 'UTF-8');
|
||||
return $init . str_repeat('*', max(3, mb_strlen($w, 'UTF-8') - 1));
|
||||
}, $rest);
|
||||
return $first . ' ' . implode(' ', $masked);
|
||||
}
|
||||
private function _mask_phone($v) { if (!$v) return $v; $d=preg_replace('/[^0-9]/','',trim($v)); $l=strlen($d); if($l<=4) return '****'; if($l<=8) return substr($d,0,4).str_repeat('*',$l-4); return substr($d,0,4).str_repeat('*',$l-7).substr($d,-3); }
|
||||
private function _mask_email($v) { if (!$v||strpos($v,'@')===false) return $v; [$loc,$dom]=explode('@',$v,2); return mb_substr($loc,0,min(2,mb_strlen($loc,'UTF-8')),'UTF-8').'***@'.$dom; }
|
||||
private function _mask_short($v) { if (!$v) return $v; $v=trim($v); $l=mb_strlen($v,'UTF-8'); if($l<=2) return '***'; return mb_substr($v,0,2,'UTF-8').'***'; }
|
||||
private function _mask_id($v) { if (!$v) return $v; $v=trim($v); $l=strlen($v); if($l<=4) return '****'; return substr($v,0,4).str_repeat('*',max(3,$l-6)).($l>6?substr($v,-2):''); }
|
||||
private function _mask_address($v) { if (!$v) return $v; $v=trim($v); $l=mb_strlen($v,'UTF-8'); if($l<=5) return '***'; return mb_substr($v,0,5,'UTF-8').'***'; }
|
||||
|
||||
private function _decrypt_row(array $row): array {
|
||||
$enc = $this->ibl_encryptor;
|
||||
if (!empty($row['M_PatientName_enc'])) $row['M_PatientName'] = $enc->decrypt($row['M_PatientName_enc']) ?? $row['M_PatientName'];
|
||||
if (!empty($row['M_PatientHP_enc'])) $row['M_PatientHP'] = $enc->decrypt($row['M_PatientHP_enc']) ?? '';
|
||||
if (!empty($row['M_PatientEmail_enc'])) $row['M_PatientEmail'] = $enc->decrypt($row['M_PatientEmail_enc']) ?? '';
|
||||
if (!empty($row['M_PatientPhone_enc'])) $row['M_PatientPhone'] = $enc->decrypt($row['M_PatientPhone_enc']) ?? '';
|
||||
if (!empty($row['M_PatientPOB_enc'])) $row['M_PatientPOB'] = $enc->decrypt($row['M_PatientPOB_enc']) ?? '';
|
||||
if (!empty($row['M_PatientIDNumber_enc'])) $row['M_PatientIDNumber'] = $enc->decrypt($row['M_PatientIDNumber_enc']) ?? '';
|
||||
if (!empty($row['M_PatientNIK_enc'])) $row['M_PatientNIK'] = $enc->decrypt($row['M_PatientNIK_enc']) ?? '';
|
||||
if (!empty($row['M_PatientDOB_enc'])) $row['M_PatientDOB'] = $enc->decrypt($row['M_PatientDOB_enc']) ?? $row['M_PatientDOB'];
|
||||
foreach (array_keys($row) as $k) { if (substr($k,-4)==='_enc'||substr($k,-5)==='_bidx') unset($row[$k]); }
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function _decrypt_addr_row(array $row): array {
|
||||
$enc = $this->ibl_encryptor;
|
||||
if (!empty($row['M_PatientAddressDescription_enc'])) $row['M_PatientAddressDescription'] = $enc->decrypt($row['M_PatientAddressDescription_enc']) ?? $row['M_PatientAddressDescription'];
|
||||
if (!empty($row['M_PatientAddressEmail_enc'])) $row['M_PatientAddressEmail'] = $enc->decrypt($row['M_PatientAddressEmail_enc']) ?? '';
|
||||
if (!empty($row['M_PatientAddressPhone_enc'])) $row['M_PatientAddressPhone'] = $enc->decrypt($row['M_PatientAddressPhone_enc']) ?? '';
|
||||
foreach (array_keys($row) as $k) { if (substr($k,-4)==='_enc'||substr($k,-5)==='_bidx') unset($row[$k]); }
|
||||
return $row;
|
||||
}
|
||||
|
||||
public function search()
|
||||
@@ -25,89 +73,53 @@ class Patientv4 extends MY_Controller
|
||||
|
||||
// echo $norm;
|
||||
|
||||
$sql_where = "WHERE M_PatientIsActive = 'Y' ";
|
||||
$sql_param = array();
|
||||
$sql_where = "WHERE M_PatientIsActive = 'Y'";
|
||||
$sql_param = array();
|
||||
$number_limit = 100;
|
||||
$number_offset = max(0, ($prm['current_page'] - 1)) * $number_limit;
|
||||
|
||||
// Search nama via trigram blind index (kolom plaintext sudah dimasking)
|
||||
if ($nama != "") {
|
||||
if ($sql_where != "") {
|
||||
$sql_where .=" and ";
|
||||
}
|
||||
$sql_where .= " M_PatientName like ? ";
|
||||
$sql_param[] = "%$nama%";
|
||||
}
|
||||
if ($norm != "") {
|
||||
if ($sql_where != "") {
|
||||
$sql_where .=" and ";
|
||||
}
|
||||
$sql_where .= " M_PatientNoReg like ? ";
|
||||
$sql_param[] = "%$norm%";
|
||||
}
|
||||
|
||||
$limit = '';
|
||||
if($all == 'N'){
|
||||
$limit = ' LIMIT 100';
|
||||
}
|
||||
$number_limit = 100;
|
||||
$number_offset = ($prm['current_page'] - 1) * $number_limit ;
|
||||
|
||||
//echo $this->db_onedev->last_query();
|
||||
$tot_count = 0;
|
||||
$tot_page = 0;
|
||||
|
||||
|
||||
$sql = "SELECT
|
||||
M_PatientID,
|
||||
M_PatientNoReg,
|
||||
M_PatientPrefix,
|
||||
M_PatientName,
|
||||
M_PatientSuffix,
|
||||
M_PatientHP,
|
||||
M_PatientEmail,
|
||||
M_PatientPOB,
|
||||
M_PatientPhone,
|
||||
M_PatientIDNumber,
|
||||
DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as M_PatientDOB,
|
||||
M_PatientNote,
|
||||
M_PatientNIK,
|
||||
M_PatientJabatan,
|
||||
M_PatientKedudukan,
|
||||
M_PatientPJ,
|
||||
M_PatientLocation,
|
||||
M_PatientJob,
|
||||
M_PatientM_SexID,
|
||||
M_SexName,
|
||||
M_PatientM_TitleID,
|
||||
M_TitleName,
|
||||
M_PatientM_ReligionID,
|
||||
M_ReligionName,
|
||||
M_PatientM_IdTypeID,
|
||||
M_IdTypeName,
|
||||
M_PatientIDNumber,
|
||||
IF(ISNULL(M_PatientSuspendID),'active','suspend' ) as status
|
||||
FROM m_patient
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
LEFT JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
LEFT JOIN m_religion ON M_PatientM_ReligionID = M_ReligionID
|
||||
LEFT JOIN m_idtype ON M_PatientM_IdTypeID = M_IdTypeID
|
||||
LEFT JOIN m_patientsuspend ON M_PatientSuspendM_PatientID = M_PatientID AND M_PatientSuspendIsActive = 'Y'
|
||||
$sql_where
|
||||
ORDER BY M_PatientName DESC
|
||||
limit 100
|
||||
";
|
||||
// $sql;
|
||||
$query = $this->db_onedev->query($sql, $sql_param);
|
||||
$rows = $query->result_array();
|
||||
if($rows){
|
||||
foreach($rows as $k => $v){
|
||||
$rows[$k]['M_PatientName'] = stripslashes($rows[$k]['M_PatientName']);
|
||||
$rows[$k]['M_PatientPOB'] = stripslashes($rows[$k]['M_PatientPOB']);
|
||||
//$rows[$k]['verification_px'] = $this->add_verification_test($v['M_PatientID']);
|
||||
|
||||
$toks = $this->ibl_encryptor->query_tokens($nama);
|
||||
foreach ($toks as $tok) {
|
||||
$tok_esc = $this->db_onedev->escape_str($tok);
|
||||
$sql_where .= " AND JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
}
|
||||
if ($norm != "") {
|
||||
$sql_where .= " AND M_PatientNoReg LIKE ?";
|
||||
$sql_param[] = "%$norm%";
|
||||
}
|
||||
|
||||
$sql = "SELECT
|
||||
M_PatientID, M_PatientNoReg, M_PatientPrefix, M_PatientSuffix,
|
||||
M_PatientNote, M_PatientJabatan, M_PatientKedudukan,
|
||||
M_PatientPJ, M_PatientLocation, M_PatientJob,
|
||||
M_PatientM_SexID, M_SexName,
|
||||
M_PatientM_TitleID, M_TitleName,
|
||||
M_PatientM_ReligionID, M_ReligionName,
|
||||
M_PatientM_IdTypeID, M_IdTypeName,
|
||||
IF(ISNULL(M_PatientSuspendID),'active','suspend') as status,
|
||||
M_PatientName_enc, M_PatientHP_enc, M_PatientEmail_enc,
|
||||
M_PatientPhone_enc, M_PatientPOB_enc, M_PatientIDNumber_enc,
|
||||
M_PatientNIK_enc, M_PatientDOB_enc
|
||||
FROM m_patient
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
LEFT JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
LEFT JOIN m_religion ON M_PatientM_ReligionID = M_ReligionID
|
||||
LEFT JOIN m_idtype ON M_PatientM_IdTypeID = M_IdTypeID
|
||||
LEFT JOIN m_patientsuspend ON M_PatientSuspendM_PatientID = M_PatientID AND M_PatientSuspendIsActive = 'Y'
|
||||
{$sql_where}
|
||||
ORDER BY M_PatientID DESC
|
||||
LIMIT {$number_limit} OFFSET {$number_offset}";
|
||||
|
||||
//$this->_add_address($rows);
|
||||
$result = array("total" => 1, "records" => $rows, "sql"=> $this->db_onedev->last_query());
|
||||
$query = $this->db_onedev->query($sql, $sql_param);
|
||||
$rows = $query->result_array();
|
||||
foreach ($rows as $k => $v) {
|
||||
$rows[$k] = $this->_decrypt_row($v);
|
||||
}
|
||||
|
||||
$result = array("total" => count($rows), "records" => $rows);
|
||||
$this->sys_ok($result);
|
||||
exit;
|
||||
}
|
||||
@@ -342,25 +354,38 @@ $rows['titles'] = $this->db_onedev->query($query)->result_array();
|
||||
$sql = "SELECT * FROM m_patient WHERE M_PatientID = {$prm['M_PatientID']}";
|
||||
$rows_before = $this->db_onedev->query($sql)->row_array();
|
||||
|
||||
$pdob = date('Y-m-d',strtotime($prm['M_PatientDOB']));
|
||||
$prm['M_PatientName'] = str_replace("'", "\\'", $prm['M_PatientName']);
|
||||
$prm['M_PatientPOB'] = str_replace("'", "\\'", $prm['M_PatientPOB']);
|
||||
$sql ="UPDATE m_patient SET
|
||||
$pdob = date('Y-m-d', strtotime($prm['M_PatientDOB']));
|
||||
$dob_str = date('d-m-Y', strtotime($prm['M_PatientDOB']));
|
||||
$name = $prm['M_PatientName'];
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
$sql = "UPDATE m_patient SET
|
||||
M_PatientM_TitleID = ?,
|
||||
M_PatientPrefix = ?,
|
||||
M_PatientName = ?,
|
||||
M_PatientName_enc = ?,
|
||||
M_PatientName_bidx = ?,
|
||||
M_PatientSuffix = ?,
|
||||
M_PatientDOB = ?,
|
||||
M_PatientDOB_enc = ?,
|
||||
M_PatientDOB_bidx = ?,
|
||||
M_PatientM_SexID = ?,
|
||||
M_PatientM_ReligionID = ?,
|
||||
M_PatientEmail = ?,
|
||||
M_PatientEmail_enc = ?,
|
||||
M_PatientPOB = ?,
|
||||
M_PatientPOB_enc = ?,
|
||||
M_PatientHP = ?,
|
||||
M_PatientHP_enc = ?,
|
||||
M_PatientHP_bidx = ?,
|
||||
M_PatientPhone = ?,
|
||||
M_PatientPhone_enc = ?,
|
||||
M_PatientM_IdTypeID = ?,
|
||||
M_PatientIDNumber = ?,
|
||||
M_PatientIDNumber_enc = ?,
|
||||
M_PatientNote = ?,
|
||||
M_PatientNIK = ?,
|
||||
M_PatientNIK_enc = ?,
|
||||
M_PatientJabatan = ?,
|
||||
M_PatientKedudukan = ?,
|
||||
M_PatientPJ = ?,
|
||||
@@ -369,33 +394,30 @@ $rows['titles'] = $this->db_onedev->query($query)->result_array();
|
||||
M_PatientUserID = ?,
|
||||
M_PatientLastUpdatedUserID = ?,
|
||||
M_PatientLastUpdated = NOW()
|
||||
WHERE
|
||||
M_PatientID = ?
|
||||
";
|
||||
//echo $query;
|
||||
WHERE M_PatientID = ?";
|
||||
|
||||
$query = $this->db_onedev->query($sql, array(
|
||||
$prm['M_PatientM_TitleID'],
|
||||
$prm['M_PatientPrefix'],
|
||||
$prm['M_PatientName'],
|
||||
$this->_mask_name($name), $enc->encrypt($name), $enc->search_bidx($name),
|
||||
$prm['M_PatientSuffix'],
|
||||
$pdob,
|
||||
$pdob, $enc->encrypt($dob_str), $enc->search_bidx($dob_str),
|
||||
$prm['M_PatientM_SexID'],
|
||||
$prm['M_PatientM_ReligionID'],
|
||||
$prm['M_PatientEmail'],
|
||||
$prm['M_PatientPOB'],
|
||||
$prm['M_PatientHP'],
|
||||
$prm['M_PatientPhone'],
|
||||
$this->_mask_email($prm['M_PatientEmail']), $enc->encrypt($prm['M_PatientEmail']),
|
||||
$this->_mask_short($prm['M_PatientPOB']), $enc->encrypt($prm['M_PatientPOB']),
|
||||
$this->_mask_phone($prm['M_PatientHP']), $enc->encrypt($prm['M_PatientHP']), $enc->search_bidx($prm['M_PatientHP']),
|
||||
$this->_mask_phone($prm['M_PatientPhone']), $enc->encrypt($prm['M_PatientPhone']),
|
||||
$prm['M_PatientM_IdTypeID'],
|
||||
$prm['M_PatientIDNumber'],
|
||||
$this->_mask_id($prm['M_PatientIDNumber']), $enc->encrypt($prm['M_PatientIDNumber']),
|
||||
$prm['M_PatientNote'],
|
||||
$prm['M_PatientNIK'],
|
||||
$this->_mask_id($prm['M_PatientNIK']), $enc->encrypt($prm['M_PatientNIK']),
|
||||
$prm['M_PatientJabatan'],
|
||||
$prm['M_PatientKedudukan'],
|
||||
$prm['M_PatientPJ'],
|
||||
$prm['M_PatientLocation'],
|
||||
$prm['M_PatientJob'],
|
||||
$userid,
|
||||
$userid,
|
||||
$userid, $userid,
|
||||
$prm['M_PatientID']
|
||||
));
|
||||
|
||||
@@ -423,63 +445,65 @@ $rows['titles'] = $this->db_onedev->query($query)->result_array();
|
||||
$prm = $this->sys_input;
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
$pdob = date('Y-m-d',strtotime($prm['M_PatientDOB']));
|
||||
$prm['M_PatientName'] = str_replace("'", "\\'", $prm['M_PatientName']);
|
||||
$query ="INSERT INTO m_patient (
|
||||
M_PatientM_TitleID,
|
||||
M_PatientPrefix,
|
||||
M_PatientName,
|
||||
$pdob = date('Y-m-d', strtotime($prm['M_PatientDOB']));
|
||||
$dob_str = date('d-m-Y', strtotime($prm['M_PatientDOB']));
|
||||
$name = $prm['M_PatientName'];
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
$query = "INSERT INTO m_patient (
|
||||
M_PatientM_TitleID, M_PatientPrefix,
|
||||
M_PatientName, M_PatientName_enc, M_PatientName_bidx,
|
||||
M_PatientSuffix,
|
||||
M_PatientDOB,
|
||||
M_PatientM_SexID,
|
||||
M_PatientM_ReligionID,
|
||||
M_PatientEmail,
|
||||
M_PatientPOB,
|
||||
M_PatientHP,
|
||||
M_PatientPhone,
|
||||
M_PatientDOB, M_PatientDOB_enc, M_PatientDOB_bidx,
|
||||
M_PatientM_SexID, M_PatientM_ReligionID,
|
||||
M_PatientEmail, M_PatientEmail_enc,
|
||||
M_PatientPOB, M_PatientPOB_enc,
|
||||
M_PatientHP, M_PatientHP_enc, M_PatientHP_bidx,
|
||||
M_PatientPhone, M_PatientPhone_enc,
|
||||
M_PatientM_IdTypeID,
|
||||
M_PatientIDNumber,
|
||||
M_PatientIDNumber, M_PatientIDNumber_enc,
|
||||
M_PatientNote,
|
||||
M_PatientNIK,
|
||||
M_PatientJabatan,
|
||||
M_PatientKedudukan,
|
||||
M_PatientPJ,
|
||||
M_PatientLocation,
|
||||
M_PatientJob,
|
||||
M_PatientUserID,
|
||||
M_PatientCreatedUserID,
|
||||
M_PatientCreated
|
||||
)
|
||||
VALUES(
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,NOW()
|
||||
)
|
||||
";
|
||||
//echo $query;
|
||||
$rows = $this->db_onedev->query($query,array(
|
||||
$prm['M_PatientM_TitleID'],
|
||||
$prm['M_PatientPrefix'],
|
||||
$prm['M_PatientName'],
|
||||
M_PatientNIK, M_PatientNIK_enc,
|
||||
M_PatientJabatan, M_PatientKedudukan, M_PatientPJ,
|
||||
M_PatientLocation, M_PatientJob,
|
||||
M_PatientUserID, M_PatientCreatedUserID, M_PatientCreated
|
||||
) VALUES (
|
||||
?, ?,
|
||||
?, ?, ?,
|
||||
?,
|
||||
?, ?, ?,
|
||||
?, ?,
|
||||
?, ?,
|
||||
?, ?,
|
||||
?, ?, ?,
|
||||
?, ?,
|
||||
?,
|
||||
?, ?,
|
||||
?,
|
||||
?, ?,
|
||||
?, ?, ?,
|
||||
?, ?,
|
||||
?, ?, NOW()
|
||||
)";
|
||||
|
||||
$rows = $this->db_onedev->query($query, array(
|
||||
$prm['M_PatientM_TitleID'], $prm['M_PatientPrefix'],
|
||||
$this->_mask_name($name), $enc->encrypt($name), $enc->search_bidx($name),
|
||||
$prm['M_PatientSuffix'],
|
||||
$pdob,
|
||||
$prm['M_PatientM_SexID'],
|
||||
$prm['M_PatientM_ReligionID'],
|
||||
$prm['M_PatientEmail'],
|
||||
$prm['M_PatientPOB'],
|
||||
$prm['M_PatientHP'],
|
||||
$prm['M_PatientPhone'],
|
||||
$pdob, $enc->encrypt($dob_str), $enc->search_bidx($dob_str),
|
||||
$prm['M_PatientM_SexID'], $prm['M_PatientM_ReligionID'],
|
||||
$this->_mask_email($prm['M_PatientEmail']), $enc->encrypt($prm['M_PatientEmail']),
|
||||
$this->_mask_short($prm['M_PatientPOB']), $enc->encrypt($prm['M_PatientPOB']),
|
||||
$this->_mask_phone($prm['M_PatientHP']), $enc->encrypt($prm['M_PatientHP']), $enc->search_bidx($prm['M_PatientHP']),
|
||||
$this->_mask_phone($prm['M_PatientPhone']), $enc->encrypt($prm['M_PatientPhone']),
|
||||
$prm['M_PatientM_IdTypeID'],
|
||||
$prm['M_PatientIDNumber'],
|
||||
$this->_mask_id($prm['M_PatientIDNumber']), $enc->encrypt($prm['M_PatientIDNumber']),
|
||||
$prm['M_PatientNote'],
|
||||
$prm['M_PatientNIK'],
|
||||
$prm['M_PatientJabatan'],
|
||||
$prm['M_PatientKedudukan'],
|
||||
$prm['M_PatientPJ'],
|
||||
$prm['M_PatientLocation'],
|
||||
$prm['M_PatientJob'],
|
||||
$userid,
|
||||
$userid
|
||||
$this->_mask_id($prm['M_PatientNIK']), $enc->encrypt($prm['M_PatientNIK']),
|
||||
$prm['M_PatientJabatan'], $prm['M_PatientKedudukan'], $prm['M_PatientPJ'],
|
||||
$prm['M_PatientLocation'], $prm['M_PatientJob'],
|
||||
$userid, $userid
|
||||
));
|
||||
$rows = $this->db_onedev->query($query);
|
||||
$last_id = $this->db_onedev->insert_id();
|
||||
$result = array(
|
||||
"total" => 1 ,
|
||||
@@ -533,19 +557,13 @@ $rows['titles'] = $this->db_onedev->query($query)->result_array();
|
||||
M_PatientAddressIsActive = 'Y' AND M_PatientAddressM_PatientID = ?
|
||||
";
|
||||
//echo $query;
|
||||
$rows = $this->db_onedev->query($query,array($prm['id']))->result_array();
|
||||
if($rows){
|
||||
foreach($rows as $k => $v){
|
||||
$rows[$k]['M_PatientAddressDescription'] = stripslashes($v['M_PatientAddressDescription']);
|
||||
$rows[$k]['action'] = '<v-icon color="error" @click="deleteAddress(props.item)">delete</v-icon>';
|
||||
$rows[$k]['action'] .= '<v-icon color="primary" @click="deleteAddress(props.item)">edit</v-icon>';
|
||||
|
||||
}
|
||||
$rows = $this->db_onedev->query($query, array($prm['id']))->result_array();
|
||||
foreach ($rows as $k => $v) {
|
||||
$rows[$k] = $this->_decrypt_addr_row($v);
|
||||
$rows[$k]['action'] = '<v-icon color="error" @click="deleteAddress(props.item)">delete</v-icon>';
|
||||
$rows[$k]['action'] .= '<v-icon color="primary" @click="deleteAddress(props.item)">edit</v-icon>';
|
||||
}
|
||||
$result = array(
|
||||
"total" => count($rows) ,
|
||||
"records" => $rows,
|
||||
);
|
||||
$result = array("total" => count($rows), "records" => $rows);
|
||||
$this->sys_ok($result);
|
||||
exit;
|
||||
}
|
||||
@@ -570,46 +588,27 @@ $rows['titles'] = $this->db_onedev->query($query)->result_array();
|
||||
$prm['M_PatientAddressNote'] = 'Utama_'.$rx;
|
||||
}
|
||||
}
|
||||
$prm['M_PatientAddressDescription'] = str_replace("'", "\\'", $prm['M_PatientAddressDescription']);
|
||||
$sql ="INSERT INTO m_patientaddress (
|
||||
M_PatientAddressM_PatientID,
|
||||
M_PatientAddressNote,
|
||||
M_PatientAddressDescription,
|
||||
M_PatientAddressRegionalCd,
|
||||
M_PatientAddressState,
|
||||
M_PatientAddressCity,
|
||||
M_PatientAddressDistrict,
|
||||
M_PatientAddressVillage,
|
||||
M_PatientAddressCreated,
|
||||
M_PatientAddressUserID,
|
||||
M_PatientAddressCreatedUserID
|
||||
)
|
||||
VALUES(
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
NOW(),
|
||||
?,
|
||||
?
|
||||
)
|
||||
";
|
||||
//echo $query;
|
||||
$query = $this->db_onedev->query($sql,array(
|
||||
$addr_desc = $prm['M_PatientAddressDescription'];
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
$sql = "INSERT INTO m_patientaddress (
|
||||
M_PatientAddressM_PatientID, M_PatientAddressNote,
|
||||
M_PatientAddressDescription, M_PatientAddressDescription_enc, M_PatientAddressDescription_bidx,
|
||||
M_PatientAddressRegionalCd, M_PatientAddressState,
|
||||
M_PatientAddressCity, M_PatientAddressDistrict, M_PatientAddressVillage,
|
||||
M_PatientAddressCreated, M_PatientAddressUserID, M_PatientAddressCreatedUserID
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), ?, ?)";
|
||||
|
||||
$query = $this->db_onedev->query($sql, array(
|
||||
$prm['M_PatientAddressM_PatientID'],
|
||||
$prm['M_PatientAddressNote'],
|
||||
$prm['M_PatientAddressDescription'],
|
||||
$this->_mask_address($addr_desc), $enc->encrypt($addr_desc), $enc->search_bidx($addr_desc),
|
||||
$prm['region']['id'],
|
||||
$prm['region']['pro_nm'],
|
||||
$prm['region']['kab_nm'],
|
||||
$prm['region']['kec_nm'],
|
||||
$prm['region']['kel_nm'],
|
||||
$userid,
|
||||
$userid
|
||||
$userid, $userid
|
||||
));
|
||||
//echo $this->db_onedev->last_query();
|
||||
if(!$query){
|
||||
@@ -633,13 +632,15 @@ $rows['titles'] = $this->db_onedev->query($query)->result_array();
|
||||
}
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
$prm = $this->sys_input;
|
||||
$prm['M_PatientAddressDescription'] = str_replace("'", "\\'", $prm['M_PatientAddressDescription']);
|
||||
$sql = "SELECT * FROM m_patientaddress WHERE M_PatientAddressID = {$prm['M_PatientAddressID']}";
|
||||
$rows_before = $this->db_onedev->query($sql)->row_array();
|
||||
$query ="UPDATE m_patientaddress SET
|
||||
$addr_desc = $prm['M_PatientAddressDescription'];
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
$query = "UPDATE m_patientaddress SET
|
||||
M_PatientAddressM_PatientID = ?,
|
||||
M_PatientAddressNote = ?,
|
||||
M_PatientAddressDescription = ?,
|
||||
M_PatientAddressDescription_enc = ?,
|
||||
M_PatientAddressDescription_bidx = ?,
|
||||
M_PatientAddressRegionalCd = ?,
|
||||
M_PatientAddressState = ?,
|
||||
M_PatientAddressCity = ?,
|
||||
@@ -648,21 +649,18 @@ $rows['titles'] = $this->db_onedev->query($query)->result_array();
|
||||
M_PatientAddressUpdated = NOW(),
|
||||
M_PatientAddressUpdatedUserID = ?,
|
||||
M_PatientAddressUserID = ?
|
||||
WHERE
|
||||
M_PatientAddressID = ?
|
||||
";
|
||||
//echo $query;
|
||||
$rows = $this->db_onedev->query($query,array(
|
||||
WHERE M_PatientAddressID = ?";
|
||||
|
||||
$rows = $this->db_onedev->query($query, array(
|
||||
$prm['M_PatientAddressM_PatientID'],
|
||||
$prm['M_PatientAddressNote'],
|
||||
$prm['M_PatientAddressDescription'],
|
||||
$this->_mask_address($addr_desc), $enc->encrypt($addr_desc), $enc->search_bidx($addr_desc),
|
||||
$prm['region']['id'],
|
||||
$prm['region']['pro_nm'],
|
||||
$prm['region']['kab_nm'],
|
||||
$prm['region']['kec_nm'],
|
||||
$prm['region']['kel_nm'],
|
||||
$userid,
|
||||
$userid,
|
||||
$userid, $userid,
|
||||
$prm['M_PatientAddressID']
|
||||
));
|
||||
|
||||
|
||||
73
application/controllers/mockup/masterdata/Poli.http
Normal file
73
application/controllers/mockup/masterdata/Poli.http
Normal file
@@ -0,0 +1,73 @@
|
||||
@baseUrl = https://devone.aplikasi.web.id/one-api-lab
|
||||
@token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJNX1VzZXJJRCI6IjMiLCJNX1VzZXJVc2VybmFtZSI6ImFkbWluICIsIk1fVXNlckdyb3VwRGFzaGJvYXJkIjoib25lLXVpLWxhYlwvdGVzdFwvdnVleFwvb25lLXBhdGllbnQtbGlzdC1iYXJjb2RlLXZ2LTYtY3BvbmVcLyIsIk1fVXNlckRlZmF1bHRUX1NhbXBsZVN0YXRpb25JRCI6IjAiLCJNX1N0YWZmTmFtZSI6IkFCSVRBIEpVV0lUQSBTQVJJIiwiaXNfY291cmllciI6Ik4iLCJ0aW1lX2F1dG9sb2dvdXQiOiIxMDAwMDAwIiwiaXAiOiIxMDMuMy4yMjAuMjIxIiwiYWdlbnQiOiJNb3ppbGxhXC81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXRcLzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZVwvMTQ5LjAuMC4wIFNhZmFyaVwvNTM3LjM2IiwidmVyc2lvbiI6InYyIiwibGFzdC1sb2dpbiI6IjIwMjYtMDYtMjIgMTE6MjM6MjkiLCJNX1NhdGVsbGl0ZUlEIjowfQ.wkQFPGQ52TeceDQARm8auj6jEb159V46BzTZ9NEE_vM
|
||||
@poliId = 1
|
||||
|
||||
### Search Poli
|
||||
POST {{baseUrl}}/mockup/masterdata/poli/search
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"search": "",
|
||||
"page": 1,
|
||||
"row_per_page": 10,
|
||||
"order_by": "id",
|
||||
"order": "asc"
|
||||
}
|
||||
|
||||
### Search Poli By Name
|
||||
POST {{baseUrl}}/mockup/masterdata/poli/search
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"search": "khitan",
|
||||
"page": 1,
|
||||
"row_per_page": 10,
|
||||
"order_by": "name",
|
||||
"order": "asc"
|
||||
}
|
||||
|
||||
### Get Screening Templates
|
||||
POST {{baseUrl}}/mockup/masterdata/poli/gettemplates
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}"
|
||||
}
|
||||
|
||||
### Add Poli
|
||||
POST {{baseUrl}}/mockup/masterdata/poli/add
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"code": "POLI_TEST",
|
||||
"name": "Poli Test",
|
||||
"description": "Poli untuk test API",
|
||||
"satusehat_location_id": "",
|
||||
"screening_template_id": null
|
||||
}
|
||||
|
||||
### Update Poli
|
||||
POST {{baseUrl}}/mockup/masterdata/poli/update
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"id": {{poliId}},
|
||||
"code": "POLI_TEST",
|
||||
"name": "Poli Test Update",
|
||||
"description": "Poli untuk test API update",
|
||||
"satusehat_location_id": "",
|
||||
"screening_template_id": null
|
||||
}
|
||||
|
||||
### Delete Poli
|
||||
POST {{baseUrl}}/mockup/masterdata/poli/delete
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"id": {{poliId}}
|
||||
}
|
||||
323
application/controllers/mockup/masterdata/Poli.php
Normal file
323
application/controllers/mockup/masterdata/Poli.php
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
class Poli extends MY_Controller
|
||||
{
|
||||
var $db_oneklinik;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_oneklinik = $this->load->database("onedev", true);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
echo "POLI API";
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$search = isset($prm['search']) ? trim($prm['search']) : (isset($prm['name']) ? trim($prm['name']) : '');
|
||||
$like = '%' . $search . '%';
|
||||
$row_per_page = isset($prm['row_per_page']) && intval($prm['row_per_page']) > 0 ? intval($prm['row_per_page']) : 10;
|
||||
$page = 1;
|
||||
if (isset($prm['page']) && intval($prm['page']) > 0) {
|
||||
$page = intval($prm['page']);
|
||||
} elseif (isset($prm['current_page']) && intval($prm['current_page']) > 0) {
|
||||
$page = intval($prm['current_page']);
|
||||
}
|
||||
$offset = ($page - 1) * $row_per_page;
|
||||
|
||||
$allowed_order_by = array(
|
||||
'id' => 'cu.M_ClinicUnitID',
|
||||
'code' => 'cu.M_ClinicUnitCode',
|
||||
'name' => 'cu.M_ClinicUnitName',
|
||||
'description' => 'cu.M_ClinicUnitDescription',
|
||||
'screening_template_name' => 'st.M_ScreeningTemplateName'
|
||||
);
|
||||
$order_by = 'cu.M_ClinicUnitID';
|
||||
if (isset($prm['order_by']) && isset($allowed_order_by[$prm['order_by']])) {
|
||||
$order_by = $allowed_order_by[$prm['order_by']];
|
||||
}
|
||||
$order = isset($prm['order']) && strtolower($prm['order']) === 'desc' ? 'DESC' : 'ASC';
|
||||
|
||||
$sql_count = "SELECT COUNT(*) AS total
|
||||
FROM one_klinik.m_clinic_unit cu
|
||||
LEFT JOIN one_klinik.m_screening_template st
|
||||
ON st.M_ScreeningTemplateID = cu.M_ClinicUnitM_ScreeningTemplateID
|
||||
AND st.M_ScreeningTemplateIsActive = 'Y'
|
||||
WHERE cu.M_ClinicUnitIsActive = 'Y'
|
||||
AND (
|
||||
cu.M_ClinicUnitCode LIKE ?
|
||||
OR cu.M_ClinicUnitName LIKE ?
|
||||
OR IFNULL(cu.M_ClinicUnitDescription, '') LIKE ?
|
||||
OR IFNULL(cu.M_ClinicUnitSatusehatLocationID, '') LIKE ?
|
||||
OR IFNULL(st.M_ScreeningTemplateName, '') LIKE ?
|
||||
)";
|
||||
$query_count = $this->db_oneklinik->query($sql_count, array($like, $like, $like, $like, $like));
|
||||
if (!$query_count) {
|
||||
$this->sys_error_db("m_clinic_unit count", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$total_filter = intval($query_count->row()->total);
|
||||
$total_page = ceil($total_filter / $row_per_page);
|
||||
|
||||
$sql = "SELECT
|
||||
cu.M_ClinicUnitID AS id,
|
||||
cu.M_ClinicUnitCode AS code,
|
||||
cu.M_ClinicUnitName AS name,
|
||||
cu.M_ClinicUnitDescription AS description,
|
||||
cu.M_ClinicUnitSatusehatLocationID AS satusehat_location_id,
|
||||
cu.M_ClinicUnitM_ScreeningTemplateID AS screening_template_id,
|
||||
st.M_ScreeningTemplateCode AS screening_template_code,
|
||||
st.M_ScreeningTemplateName AS screening_template_name,
|
||||
cu.M_ClinicUnitIsActive AS is_active,
|
||||
cu.M_ClinicUnitCreated AS created,
|
||||
cu.M_ClinicUnitLastUpdated AS last_updated
|
||||
FROM one_klinik.m_clinic_unit cu
|
||||
LEFT JOIN one_klinik.m_screening_template st
|
||||
ON st.M_ScreeningTemplateID = cu.M_ClinicUnitM_ScreeningTemplateID
|
||||
AND st.M_ScreeningTemplateIsActive = 'Y'
|
||||
WHERE cu.M_ClinicUnitIsActive = 'Y'
|
||||
AND (
|
||||
cu.M_ClinicUnitCode LIKE ?
|
||||
OR cu.M_ClinicUnitName LIKE ?
|
||||
OR IFNULL(cu.M_ClinicUnitDescription, '') LIKE ?
|
||||
OR IFNULL(cu.M_ClinicUnitSatusehatLocationID, '') LIKE ?
|
||||
OR IFNULL(st.M_ScreeningTemplateName, '') LIKE ?
|
||||
)
|
||||
ORDER BY {$order_by} {$order}
|
||||
LIMIT ? OFFSET ?";
|
||||
$query = $this->db_oneklinik->query($sql, array($like, $like, $like, $like, $like, $row_per_page, $offset));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_clinic_unit select", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$rows = $query->result_array();
|
||||
$this->sys_ok(array(
|
||||
"total" => $total_page,
|
||||
"total_filter" => $total_filter,
|
||||
"records" => $rows
|
||||
));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function gettemplates()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "SELECT
|
||||
M_ScreeningTemplateID AS id,
|
||||
M_ScreeningTemplateCode AS code,
|
||||
M_ScreeningTemplateName AS name,
|
||||
M_ScreeningTemplateDescription AS description
|
||||
FROM one_klinik.m_screening_template
|
||||
WHERE M_ScreeningTemplateIsActive = 'Y'
|
||||
ORDER BY M_ScreeningTemplateName ASC";
|
||||
$query = $this->db_oneklinik->query($sql);
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_template select", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$rows = $query->result_array();
|
||||
$this->sys_ok(array("total" => count($rows), "records" => $rows));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$code = isset($prm['code']) ? trim($prm['code']) : '';
|
||||
$name = isset($prm['name']) ? trim($prm['name']) : '';
|
||||
$description = isset($prm['description']) ? trim($prm['description']) : null;
|
||||
$satusehat_location_id = isset($prm['satusehat_location_id']) ? trim($prm['satusehat_location_id']) : null;
|
||||
$screening_template_id = isset($prm['screening_template_id']) && $prm['screening_template_id'] !== '' ? intval($prm['screening_template_id']) : null;
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
if ($code === '' || $name === '') {
|
||||
$this->sys_error("code and name are mandatory");
|
||||
exit;
|
||||
}
|
||||
|
||||
$duplicate = $this->db_oneklinik->query(
|
||||
"SELECT COUNT(*) AS total
|
||||
FROM one_klinik.m_clinic_unit
|
||||
WHERE M_ClinicUnitCode = ?
|
||||
OR (M_ClinicUnitIsActive = 'Y' AND M_ClinicUnitName = ?)",
|
||||
array($code, $name)
|
||||
);
|
||||
if (!$duplicate) {
|
||||
$this->sys_error_db("m_clinic_unit duplicate check", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
if (intval($duplicate->row()->total) > 0) {
|
||||
$this->sys_ok(array(
|
||||
"total" => -1,
|
||||
"errors" => array(array("field" => "code", "msg" => "Kode atau nama sudah ada")),
|
||||
"records" => 0
|
||||
));
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO one_klinik.m_clinic_unit (
|
||||
M_ClinicUnitCode,
|
||||
M_ClinicUnitName,
|
||||
M_ClinicUnitDescription,
|
||||
M_ClinicUnitSatusehatLocationID,
|
||||
M_ClinicUnitM_ScreeningTemplateID,
|
||||
M_ClinicUnitUserID,
|
||||
M_ClinicUnitCreated,
|
||||
M_ClinicUnitLastUpdated
|
||||
) VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())";
|
||||
$query = $this->db_oneklinik->query($sql, array(
|
||||
$code,
|
||||
$name,
|
||||
$description,
|
||||
$satusehat_location_id,
|
||||
$screening_template_id,
|
||||
$userid
|
||||
));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_clinic_unit insert", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array(
|
||||
"total" => 1,
|
||||
"records" => array("xid" => $this->db_oneklinik->insert_id())
|
||||
));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$id = isset($prm['id']) ? intval($prm['id']) : 0;
|
||||
$code = isset($prm['code']) ? trim($prm['code']) : '';
|
||||
$name = isset($prm['name']) ? trim($prm['name']) : '';
|
||||
$description = isset($prm['description']) ? trim($prm['description']) : null;
|
||||
$satusehat_location_id = isset($prm['satusehat_location_id']) ? trim($prm['satusehat_location_id']) : null;
|
||||
$screening_template_id = isset($prm['screening_template_id']) && $prm['screening_template_id'] !== '' ? intval($prm['screening_template_id']) : null;
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
if (!$id || $code === '' || $name === '') {
|
||||
$this->sys_error("id, code and name are mandatory");
|
||||
exit;
|
||||
}
|
||||
|
||||
$duplicate = $this->db_oneklinik->query(
|
||||
"SELECT COUNT(*) AS total
|
||||
FROM one_klinik.m_clinic_unit
|
||||
WHERE M_ClinicUnitID <> ?
|
||||
AND (M_ClinicUnitCode = ?
|
||||
OR (M_ClinicUnitIsActive = 'Y' AND M_ClinicUnitName = ?))",
|
||||
array($id, $code, $name)
|
||||
);
|
||||
if (!$duplicate) {
|
||||
$this->sys_error_db("m_clinic_unit duplicate check", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
if (intval($duplicate->row()->total) > 0) {
|
||||
$this->sys_ok(array(
|
||||
"total" => -1,
|
||||
"errors" => array(array("field" => "code", "msg" => "Kode atau nama sudah ada")),
|
||||
"records" => 0
|
||||
));
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "UPDATE one_klinik.m_clinic_unit SET
|
||||
M_ClinicUnitCode = ?,
|
||||
M_ClinicUnitName = ?,
|
||||
M_ClinicUnitDescription = ?,
|
||||
M_ClinicUnitSatusehatLocationID = ?,
|
||||
M_ClinicUnitM_ScreeningTemplateID = ?,
|
||||
M_ClinicUnitUserID = ?,
|
||||
M_ClinicUnitLastUpdated = NOW()
|
||||
WHERE M_ClinicUnitID = ?
|
||||
AND M_ClinicUnitIsActive = 'Y'";
|
||||
$query = $this->db_oneklinik->query($sql, array(
|
||||
$code,
|
||||
$name,
|
||||
$description,
|
||||
$satusehat_location_id,
|
||||
$screening_template_id,
|
||||
$userid,
|
||||
$id
|
||||
));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_clinic_unit update", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array("total" => 1, "records" => array("xid" => $id)));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$id = isset($prm['id']) ? intval($prm['id']) : 0;
|
||||
if (!$id) {
|
||||
$this->sys_error("id is mandatory");
|
||||
exit;
|
||||
}
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
$sql = "UPDATE one_klinik.m_clinic_unit SET
|
||||
M_ClinicUnitIsActive = 'N',
|
||||
M_ClinicUnitUserID = ?,
|
||||
M_ClinicUnitLastUpdated = NOW()
|
||||
WHERE M_ClinicUnitID = ?";
|
||||
$query = $this->db_oneklinik->query($sql, array($userid, $id));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_clinic_unit delete", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array("total" => 1, "records" => array("xid" => $id)));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
138
application/controllers/mockup/masterdata/Screeningtemplate.http
Normal file
138
application/controllers/mockup/masterdata/Screeningtemplate.http
Normal file
@@ -0,0 +1,138 @@
|
||||
@baseUrl = https://devone.aplikasi.web.id/one-api-lab
|
||||
@token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJNX1VzZXJJRCI6IjMiLCJNX1VzZXJVc2VybmFtZSI6ImFkbWluICIsIk1fVXNlckdyb3VwRGFzaGJvYXJkIjoib25lLXVpLWxhYlwvdGVzdFwvdnVleFwvb25lLXBhdGllbnQtbGlzdC1iYXJjb2RlLXZ2LTYtY3BvbmVcLyIsIk1fVXNlckRlZmF1bHRUX1NhbXBsZVN0YXRpb25JRCI6IjAiLCJNX1N0YWZmTmFtZSI6IkFCSVRBIEpVV0lUQSBTQVJJIiwiaXNfY291cmllciI6Ik4iLCJ0aW1lX2F1dG9sb2dvdXQiOiIxMDAwMDAwIiwiaXAiOiIxMDMuMy4yMjAuMjIxIiwiYWdlbnQiOiJNb3ppbGxhXC81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXRcLzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZVwvMTQ5LjAuMC4wIFNhZmFyaVwvNTM3LjM2IiwidmVyc2lvbiI6InYyIiwibGFzdC1sb2dpbiI6IjIwMjYtMDYtMjIgMTE6MjM6MjkiLCJNX1NhdGVsbGl0ZUlEIjowfQ.wkQFPGQ52TeceDQARm8auj6jEb159V46BzTZ9NEE_vM
|
||||
@templateId = 1
|
||||
@formId = 1
|
||||
|
||||
### Search Screening Template
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/search
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"search": "",
|
||||
"page": 1,
|
||||
"row_per_page": 10,
|
||||
"order_by": "id",
|
||||
"order": "asc"
|
||||
}
|
||||
|
||||
### Search Screening Template By Name
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/search
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"search": "khitan",
|
||||
"page": 1,
|
||||
"row_per_page": 10,
|
||||
"order_by": "name",
|
||||
"order": "asc"
|
||||
}
|
||||
|
||||
### Get Template Detail With Forms
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/getdetail
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"id": {{templateId}}
|
||||
}
|
||||
|
||||
### Get Forms By Template
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/getforms
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"template_id": {{templateId}}
|
||||
}
|
||||
|
||||
### Add Screening Template
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/add
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"code": "SCREENING_TEST",
|
||||
"name": "Screening Test",
|
||||
"description": "Template screening untuk test API"
|
||||
}
|
||||
|
||||
### Update Screening Template
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/update
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"id": {{templateId}},
|
||||
"code": "SCREENING_TEST",
|
||||
"name": "Screening Test Update",
|
||||
"description": "Template screening untuk test API update"
|
||||
}
|
||||
|
||||
### Delete Screening Template
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/delete
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"id": {{templateId}}
|
||||
}
|
||||
|
||||
### Add Screening Form - Single
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/addform
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"template_id": {{templateId}},
|
||||
"question": "Apakah pasien sedang demam?",
|
||||
"answer_type": "single",
|
||||
"options": [
|
||||
{"label": "Ya", "value": false, "id": "o01"},
|
||||
{"label": "Tidak", "value": false, "id": "o02"}
|
||||
],
|
||||
"sort_order": 1,
|
||||
"is_required": "Y"
|
||||
}
|
||||
|
||||
### Add Screening Form - Text
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/addform
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"template_id": {{templateId}},
|
||||
"question": "Catatan petugas screening",
|
||||
"answer_type": "text",
|
||||
"options": null,
|
||||
"sort_order": 2,
|
||||
"is_required": "N"
|
||||
}
|
||||
|
||||
### Update Screening Form
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/updateform
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"id": {{formId}},
|
||||
"template_id": {{templateId}},
|
||||
"question": "Apakah pasien sedang demam tinggi?",
|
||||
"answer_type": "single",
|
||||
"options": [
|
||||
{"label": "Ya", "value": false, "id": "o01"},
|
||||
{"label": "Tidak", "value": false, "id": "o02"}
|
||||
],
|
||||
"sort_order": 1,
|
||||
"is_required": "Y"
|
||||
}
|
||||
|
||||
### Delete Screening Form
|
||||
POST {{baseUrl}}/mockup/masterdata/screeningtemplate/deleteform
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"id": {{formId}}
|
||||
}
|
||||
549
application/controllers/mockup/masterdata/Screeningtemplate.php
Normal file
549
application/controllers/mockup/masterdata/Screeningtemplate.php
Normal file
@@ -0,0 +1,549 @@
|
||||
<?php
|
||||
|
||||
class Screeningtemplate extends MY_Controller
|
||||
{
|
||||
var $db_oneklinik;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_oneklinik = $this->load->database("onedev", true);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
echo "SCREENING TEMPLATE API";
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$search = isset($prm['search']) ? trim($prm['search']) : '';
|
||||
$like = '%' . $search . '%';
|
||||
$row_per_page = isset($prm['row_per_page']) && intval($prm['row_per_page']) > 0 ? intval($prm['row_per_page']) : 10;
|
||||
$page = isset($prm['page']) && intval($prm['page']) > 0 ? intval($prm['page']) : 1;
|
||||
$offset = ($page - 1) * $row_per_page;
|
||||
|
||||
$allowed_order_by = array(
|
||||
'id' => 't.M_ScreeningTemplateID',
|
||||
'code' => 't.M_ScreeningTemplateCode',
|
||||
'name' => 't.M_ScreeningTemplateName',
|
||||
'description' => 't.M_ScreeningTemplateDescription'
|
||||
);
|
||||
$order_by = 't.M_ScreeningTemplateID';
|
||||
if (isset($prm['order_by']) && isset($allowed_order_by[$prm['order_by']])) {
|
||||
$order_by = $allowed_order_by[$prm['order_by']];
|
||||
}
|
||||
$order = isset($prm['order']) && strtolower($prm['order']) === 'desc' ? 'DESC' : 'ASC';
|
||||
|
||||
$sql_count = "SELECT COUNT(*) AS total
|
||||
FROM one_klinik.m_screening_template t
|
||||
WHERE t.M_ScreeningTemplateIsActive = 'Y'
|
||||
AND (
|
||||
t.M_ScreeningTemplateCode LIKE ?
|
||||
OR t.M_ScreeningTemplateName LIKE ?
|
||||
OR IFNULL(t.M_ScreeningTemplateDescription, '') LIKE ?
|
||||
)";
|
||||
$query_count = $this->db_oneklinik->query($sql_count, array($like, $like, $like));
|
||||
if (!$query_count) {
|
||||
$this->sys_error_db("m_screening_template count", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$total_filter = intval($query_count->row()->total);
|
||||
$total_page = ceil($total_filter / $row_per_page);
|
||||
|
||||
$sql = "SELECT
|
||||
t.M_ScreeningTemplateID AS id,
|
||||
t.M_ScreeningTemplateCode AS code,
|
||||
t.M_ScreeningTemplateName AS name,
|
||||
t.M_ScreeningTemplateDescription AS description,
|
||||
t.M_ScreeningTemplateIsActive AS is_active,
|
||||
t.M_ScreeningTemplateCreated AS created,
|
||||
t.M_ScreeningTemplateLastUpdated AS last_updated,
|
||||
COUNT(f.M_ScreeningFormID) AS form_count
|
||||
FROM one_klinik.m_screening_template t
|
||||
LEFT JOIN one_klinik.m_screening_form f
|
||||
ON f.M_ScreeningFormM_ScreeningTemplateID = t.M_ScreeningTemplateID
|
||||
AND f.M_ScreeningFormIsActive = 'Y'
|
||||
WHERE t.M_ScreeningTemplateIsActive = 'Y'
|
||||
AND (
|
||||
t.M_ScreeningTemplateCode LIKE ?
|
||||
OR t.M_ScreeningTemplateName LIKE ?
|
||||
OR IFNULL(t.M_ScreeningTemplateDescription, '') LIKE ?
|
||||
)
|
||||
GROUP BY
|
||||
t.M_ScreeningTemplateID
|
||||
ORDER BY {$order_by} {$order}
|
||||
LIMIT ? OFFSET ?";
|
||||
$query = $this->db_oneklinik->query($sql, array($like, $like, $like, $row_per_page, $offset));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_template select", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array(
|
||||
"total" => $total_page,
|
||||
"total_filter" => $total_filter,
|
||||
"records" => $query->result_array()
|
||||
));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function getdetail()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$id = isset($prm['id']) ? intval($prm['id']) : 0;
|
||||
if (!$id) {
|
||||
$this->sys_error("id is mandatory");
|
||||
exit;
|
||||
}
|
||||
|
||||
$query = $this->db_oneklinik->query(
|
||||
"SELECT
|
||||
M_ScreeningTemplateID AS id,
|
||||
M_ScreeningTemplateCode AS code,
|
||||
M_ScreeningTemplateName AS name,
|
||||
M_ScreeningTemplateDescription AS description,
|
||||
M_ScreeningTemplateIsActive AS is_active,
|
||||
M_ScreeningTemplateCreated AS created,
|
||||
M_ScreeningTemplateLastUpdated AS last_updated
|
||||
FROM one_klinik.m_screening_template
|
||||
WHERE M_ScreeningTemplateID = ?
|
||||
AND M_ScreeningTemplateIsActive = 'Y'",
|
||||
array($id)
|
||||
);
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_template select detail", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$row = $query->row_array();
|
||||
if (!$row) {
|
||||
$this->sys_ok(array("total" => 0, "records" => null));
|
||||
exit;
|
||||
}
|
||||
|
||||
$row['forms'] = $this->get_form_rows($id);
|
||||
$this->sys_ok(array("total" => 1, "records" => $row));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function getforms()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$template_id = isset($prm['template_id']) ? intval($prm['template_id']) : (isset($prm['id']) ? intval($prm['id']) : 0);
|
||||
if (!$template_id) {
|
||||
$this->sys_error("template_id is mandatory");
|
||||
exit;
|
||||
}
|
||||
|
||||
$rows = $this->get_form_rows($template_id);
|
||||
$this->sys_ok(array("total" => count($rows), "records" => $rows));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$code = isset($prm['code']) ? trim($prm['code']) : '';
|
||||
$name = isset($prm['name']) ? trim($prm['name']) : '';
|
||||
$description = isset($prm['description']) ? trim($prm['description']) : null;
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
if ($code === '' || $name === '') {
|
||||
$this->sys_error("code and name are mandatory");
|
||||
exit;
|
||||
}
|
||||
|
||||
$duplicate = $this->db_oneklinik->query(
|
||||
"SELECT COUNT(*) AS total
|
||||
FROM one_klinik.m_screening_template
|
||||
WHERE M_ScreeningTemplateCode = ?
|
||||
OR (M_ScreeningTemplateIsActive = 'Y' AND M_ScreeningTemplateName = ?)",
|
||||
array($code, $name)
|
||||
);
|
||||
if (!$duplicate) {
|
||||
$this->sys_error_db("m_screening_template duplicate check", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
if (intval($duplicate->row()->total) > 0) {
|
||||
$this->sys_ok(array(
|
||||
"total" => -1,
|
||||
"errors" => array(array("field" => "code", "msg" => "Kode atau nama sudah ada")),
|
||||
"records" => 0
|
||||
));
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO one_klinik.m_screening_template (
|
||||
M_ScreeningTemplateCode,
|
||||
M_ScreeningTemplateName,
|
||||
M_ScreeningTemplateDescription,
|
||||
M_ScreeningTemplateUserID,
|
||||
M_ScreeningTemplateCreated,
|
||||
M_ScreeningTemplateLastUpdated
|
||||
) VALUES (?, ?, ?, ?, NOW(), NOW())";
|
||||
$query = $this->db_oneklinik->query($sql, array($code, $name, $description, $userid));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_template insert", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array(
|
||||
"total" => 1,
|
||||
"records" => array("xid" => $this->db_oneklinik->insert_id())
|
||||
));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$id = isset($prm['id']) ? intval($prm['id']) : 0;
|
||||
$code = isset($prm['code']) ? trim($prm['code']) : '';
|
||||
$name = isset($prm['name']) ? trim($prm['name']) : '';
|
||||
$description = isset($prm['description']) ? trim($prm['description']) : null;
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
if (!$id || $code === '' || $name === '') {
|
||||
$this->sys_error("id, code and name are mandatory");
|
||||
exit;
|
||||
}
|
||||
|
||||
$duplicate = $this->db_oneklinik->query(
|
||||
"SELECT COUNT(*) AS total
|
||||
FROM one_klinik.m_screening_template
|
||||
WHERE M_ScreeningTemplateID <> ?
|
||||
AND (M_ScreeningTemplateCode = ?
|
||||
OR (M_ScreeningTemplateIsActive = 'Y' AND M_ScreeningTemplateName = ?))",
|
||||
array($id, $code, $name)
|
||||
);
|
||||
if (!$duplicate) {
|
||||
$this->sys_error_db("m_screening_template duplicate check", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
if (intval($duplicate->row()->total) > 0) {
|
||||
$this->sys_ok(array(
|
||||
"total" => -1,
|
||||
"errors" => array(array("field" => "code", "msg" => "Kode atau nama sudah ada")),
|
||||
"records" => 0
|
||||
));
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "UPDATE one_klinik.m_screening_template SET
|
||||
M_ScreeningTemplateCode = ?,
|
||||
M_ScreeningTemplateName = ?,
|
||||
M_ScreeningTemplateDescription = ?,
|
||||
M_ScreeningTemplateUserID = ?,
|
||||
M_ScreeningTemplateLastUpdated = NOW()
|
||||
WHERE M_ScreeningTemplateID = ?
|
||||
AND M_ScreeningTemplateIsActive = 'Y'";
|
||||
$query = $this->db_oneklinik->query($sql, array($code, $name, $description, $userid, $id));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_template update", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array("total" => 1, "records" => array("xid" => $id)));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$id = isset($prm['id']) ? intval($prm['id']) : 0;
|
||||
if (!$id) {
|
||||
$this->sys_error("id is mandatory");
|
||||
exit;
|
||||
}
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
$this->db_oneklinik->trans_begin();
|
||||
|
||||
$query = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.m_screening_form SET
|
||||
M_ScreeningFormIsActive = 'N',
|
||||
M_ScreeningFormUserID = ?,
|
||||
M_ScreeningFormLastUpdated = NOW()
|
||||
WHERE M_ScreeningFormM_ScreeningTemplateID = ?",
|
||||
array($userid, $id)
|
||||
);
|
||||
if (!$query) {
|
||||
$this->db_oneklinik->trans_rollback();
|
||||
$this->sys_error_db("m_screening_form delete by template", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$query = $this->db_oneklinik->query(
|
||||
"UPDATE one_klinik.m_screening_template SET
|
||||
M_ScreeningTemplateIsActive = 'N',
|
||||
M_ScreeningTemplateUserID = ?,
|
||||
M_ScreeningTemplateLastUpdated = NOW()
|
||||
WHERE M_ScreeningTemplateID = ?",
|
||||
array($userid, $id)
|
||||
);
|
||||
if (!$query) {
|
||||
$this->db_oneklinik->trans_rollback();
|
||||
$this->sys_error_db("m_screening_template delete", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->db_oneklinik->trans_complete();
|
||||
$this->sys_ok(array("total" => 1, "records" => array("xid" => $id)));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function addform()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$template_id = isset($prm['template_id']) ? intval($prm['template_id']) : 0;
|
||||
$question = isset($prm['question']) ? trim($prm['question']) : '';
|
||||
$answer_type = isset($prm['answer_type']) ? trim($prm['answer_type']) : 'single';
|
||||
$options = isset($prm['options']) ? $this->normalize_options($prm['options'], $answer_type) : null;
|
||||
$sort_order = isset($prm['sort_order']) ? intval($prm['sort_order']) : 0;
|
||||
$is_required = isset($prm['is_required']) && $prm['is_required'] === 'N' ? 'N' : 'Y';
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
if (!$template_id || $question === '') {
|
||||
$this->sys_error("template_id and question are mandatory");
|
||||
exit;
|
||||
}
|
||||
if (!$this->is_valid_answer_type($answer_type)) {
|
||||
$this->sys_error("answer_type must be single, multi, or text");
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO one_klinik.m_screening_form (
|
||||
M_ScreeningFormM_ScreeningTemplateID,
|
||||
M_ScreeningFormQuestion,
|
||||
M_ScreeningFormAnswerType,
|
||||
M_ScreeningFormOptions,
|
||||
M_ScreeningFormSortOrder,
|
||||
M_ScreeningFormIsRequired,
|
||||
M_ScreeningFormUserID,
|
||||
M_ScreeningFormCreated,
|
||||
M_ScreeningFormLastUpdated
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";
|
||||
$query = $this->db_oneklinik->query($sql, array(
|
||||
$template_id,
|
||||
$question,
|
||||
$answer_type,
|
||||
$options,
|
||||
$sort_order,
|
||||
$is_required,
|
||||
$userid
|
||||
));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_form insert", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array(
|
||||
"total" => 1,
|
||||
"records" => array("xid" => $this->db_oneklinik->insert_id())
|
||||
));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function updateform()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$id = isset($prm['id']) ? intval($prm['id']) : 0;
|
||||
$template_id = isset($prm['template_id']) ? intval($prm['template_id']) : 0;
|
||||
$question = isset($prm['question']) ? trim($prm['question']) : '';
|
||||
$answer_type = isset($prm['answer_type']) ? trim($prm['answer_type']) : 'single';
|
||||
$options = isset($prm['options']) ? $this->normalize_options($prm['options'], $answer_type) : null;
|
||||
$sort_order = isset($prm['sort_order']) ? intval($prm['sort_order']) : 0;
|
||||
$is_required = isset($prm['is_required']) && $prm['is_required'] === 'N' ? 'N' : 'Y';
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
if (!$id || !$template_id || $question === '') {
|
||||
$this->sys_error("id, template_id and question are mandatory");
|
||||
exit;
|
||||
}
|
||||
if (!$this->is_valid_answer_type($answer_type)) {
|
||||
$this->sys_error("answer_type must be single, multi, or text");
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "UPDATE one_klinik.m_screening_form SET
|
||||
M_ScreeningFormM_ScreeningTemplateID = ?,
|
||||
M_ScreeningFormQuestion = ?,
|
||||
M_ScreeningFormAnswerType = ?,
|
||||
M_ScreeningFormOptions = ?,
|
||||
M_ScreeningFormSortOrder = ?,
|
||||
M_ScreeningFormIsRequired = ?,
|
||||
M_ScreeningFormUserID = ?,
|
||||
M_ScreeningFormLastUpdated = NOW()
|
||||
WHERE M_ScreeningFormID = ?
|
||||
AND M_ScreeningFormIsActive = 'Y'";
|
||||
$query = $this->db_oneklinik->query($sql, array(
|
||||
$template_id,
|
||||
$question,
|
||||
$answer_type,
|
||||
$options,
|
||||
$sort_order,
|
||||
$is_required,
|
||||
$userid,
|
||||
$id
|
||||
));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_form update", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array("total" => 1, "records" => array("xid" => $id)));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteform()
|
||||
{
|
||||
try {
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error("Invalid Token");
|
||||
exit;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$id = isset($prm['id']) ? intval($prm['id']) : 0;
|
||||
if (!$id) {
|
||||
$this->sys_error("id is mandatory");
|
||||
exit;
|
||||
}
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
$sql = "UPDATE one_klinik.m_screening_form SET
|
||||
M_ScreeningFormIsActive = 'N',
|
||||
M_ScreeningFormUserID = ?,
|
||||
M_ScreeningFormLastUpdated = NOW()
|
||||
WHERE M_ScreeningFormID = ?";
|
||||
$query = $this->db_oneklinik->query($sql, array($userid, $id));
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_form delete", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->sys_ok(array("total" => 1, "records" => array("xid" => $id)));
|
||||
} catch (Exception $exc) {
|
||||
$this->sys_error($exc->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function get_form_rows($template_id)
|
||||
{
|
||||
$query = $this->db_oneklinik->query(
|
||||
"SELECT
|
||||
M_ScreeningFormID AS id,
|
||||
M_ScreeningFormM_ScreeningTemplateID AS template_id,
|
||||
M_ScreeningFormQuestion AS question,
|
||||
M_ScreeningFormAnswerType AS answer_type,
|
||||
M_ScreeningFormOptions AS options,
|
||||
M_ScreeningFormSortOrder AS sort_order,
|
||||
M_ScreeningFormIsRequired AS is_required,
|
||||
M_ScreeningFormIsActive AS is_active,
|
||||
M_ScreeningFormCreated AS created,
|
||||
M_ScreeningFormLastUpdated AS last_updated
|
||||
FROM one_klinik.m_screening_form
|
||||
WHERE M_ScreeningFormM_ScreeningTemplateID = ?
|
||||
AND M_ScreeningFormIsActive = 'Y'
|
||||
ORDER BY M_ScreeningFormSortOrder ASC, M_ScreeningFormID ASC",
|
||||
array($template_id)
|
||||
);
|
||||
if (!$query) {
|
||||
$this->sys_error_db("m_screening_form select", $this->db_oneklinik);
|
||||
exit;
|
||||
}
|
||||
|
||||
$rows = $query->result_array();
|
||||
foreach ($rows as $k => $row) {
|
||||
$rows[$k]['options_json'] = $row['options'] ? json_decode($row['options'], true) : null;
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
private function is_valid_answer_type($answer_type)
|
||||
{
|
||||
return in_array($answer_type, array('single', 'multi', 'text'));
|
||||
}
|
||||
|
||||
private function normalize_options($options, $answer_type)
|
||||
{
|
||||
if ($answer_type === 'text') {
|
||||
return null;
|
||||
}
|
||||
if ($options === null) {
|
||||
return null;
|
||||
}
|
||||
if (is_array($options)) {
|
||||
return json_encode($options);
|
||||
}
|
||||
$options = trim($options);
|
||||
return $options === '' ? null : $options;
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,33 @@ class Preregisterapp extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
private function _mask_name($v) {
|
||||
if (!$v) return $v;
|
||||
$v = trim($v);
|
||||
$words = preg_split('/\s+/', $v);
|
||||
if (count($words) === 1) {
|
||||
$l = mb_strlen($v, 'UTF-8');
|
||||
if ($l <= 2) return $v;
|
||||
return mb_substr($v, 0, 2, 'UTF-8') . str_repeat('*', $l - 2);
|
||||
}
|
||||
$first = $words[0];
|
||||
$rest = array_slice($words, 1);
|
||||
$masked = array_map(function($w) {
|
||||
if (!$w) return '';
|
||||
$init = mb_substr($w, 0, 1, 'UTF-8');
|
||||
return $init . str_repeat('*', max(3, mb_strlen($w, 'UTF-8') - 1));
|
||||
}, $rest);
|
||||
return $first . ' ' . implode(' ', $masked);
|
||||
}
|
||||
private function _mask_phone($v) { if (!$v) return $v; $d=preg_replace('/[^0-9]/','',trim($v)); $l=strlen($d); if($l<=4) return '****'; if($l<=8) return substr($d,0,4).str_repeat('*',$l-4); return substr($d,0,4).str_repeat('*',$l-7).substr($d,-3); }
|
||||
private function _mask_email($v) { if (!$v||strpos($v,'@')===false) return $v; [$loc,$dom]=explode('@',$v,2); return mb_substr($loc,0,min(2,mb_strlen($loc,'UTF-8')),'UTF-8').'***@'.$dom; }
|
||||
private function _mask_short($v) { if (!$v) return $v; $v=trim($v); $l=mb_strlen($v,'UTF-8'); if($l<=2) return '***'; return mb_substr($v,0,2,'UTF-8').'***'; }
|
||||
private function _mask_id($v) { if (!$v) return $v; $v=trim($v); $l=strlen($v); if($l<=4) return '****'; return substr($v,0,4).str_repeat('*',max(3,$l-6)).($l>6?substr($v,-2):''); }
|
||||
private function _mask_address($v) { if (!$v) return $v; $v=trim($v); $l=mb_strlen($v,'UTF-8'); if($l<=5) return '***'; return mb_substr($v,0,5,'UTF-8').'***'; }
|
||||
|
||||
|
||||
|
||||
function searchcompany(){
|
||||
@@ -477,59 +502,78 @@ class Preregisterapp extends MY_Controller
|
||||
|
||||
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
if ($prm['search'] != '')
|
||||
{
|
||||
$e = explode('+', $prm['search']);
|
||||
if (isset($e[0]))
|
||||
$q['name'] = "AND M_PatientName LIKE '%{$e[0]}%'";
|
||||
if (isset($e[0]) && strlen($e[0]) >= 3) {
|
||||
$toks = $enc->query_tokens($e[0]);
|
||||
$conds = [];
|
||||
foreach ($toks as $tok) { $tok_esc = $this->db_onedev->escape_str($tok); $conds[] = "JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')"; }
|
||||
if ($conds) $q['name'] = "AND (" . implode(' AND ', $conds) . ")";
|
||||
}
|
||||
if (isset($e[1]))
|
||||
$q['dob'] = "AND ((DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$e[1]}%' and M_PatientDOB IS NOT NULL) OR (M_PatientDOB IS NULL AND '{$e[1]}' = ''))";
|
||||
if (isset($e[2]))
|
||||
$q['nik'] = "AND M_PatientNIK LIKE '%{$e[2]}%'";
|
||||
if (isset($e[2]) && strlen($e[2]) >= 3) {
|
||||
$toks = $enc->query_tokens($e[2]);
|
||||
$conds = [];
|
||||
foreach ($toks as $tok) { $tok_esc = $this->db_onedev->escape_str($tok); $conds[] = "JSON_CONTAINS(M_PatientNIK_bidx, '\"$tok_esc\"')"; }
|
||||
if ($conds) $q['nik'] = "AND (" . implode(' AND ', $conds) . ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sql = "SELECT m_patient.*,
|
||||
$sql = "SELECT m_patient.*,
|
||||
'N' divider,
|
||||
concat(M_TitleName,' ',IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) M_PatientName,
|
||||
M_PatientName M_PatientRealName, M_TitleID, M_TitleName, M_SexID, M_SexName,
|
||||
concat(M_TitleName,' ',IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) M_PatientNameDisplay,
|
||||
M_TitleID, M_TitleName, M_SexID, M_SexName,
|
||||
DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as dob_ina,
|
||||
IFNULL(M_ReligionName, '-') M_ReligionName,
|
||||
M_PatientNoReg as Mcu_PreregisterDetailsPID,
|
||||
M_PatientNIK as Mcu_PreregisterDetailsNIK,
|
||||
M_PatientID as Mcu_PreregisterDetailsM_PatientID,
|
||||
M_TitleID as Mcu_PreregisterDetailsM_TitleID,
|
||||
M_PatientName as Mcu_PreregisterDetailsPatientName,
|
||||
M_SexCode as Mcu_PreregisterDetailsM_SexCode,
|
||||
M_PatientDOB as Mcu_PreregisterDetailsDOB,
|
||||
IFNULL(M_ReligionID,0) as Mcu_PreregisterDetailsM_ReligionID,
|
||||
M_PatientJabatan as Mcu_PreregisterDetailsJabatan,
|
||||
M_PatientEmail as Mcu_PreregisterDetailsEmail,
|
||||
M_PatientHP as Mcu_PreregisterDetailsHp,
|
||||
M_PatientKedudukan as Mcu_PreregisterDetailsKedudukan,
|
||||
M_PatientLocation as Mcu_PreregisterDetailsLocation,
|
||||
M_PatientJob as Mcu_PreregisterDetailsJob
|
||||
from
|
||||
m_patient
|
||||
from
|
||||
m_patient
|
||||
$join_company
|
||||
join m_title on M_PatientM_TitleID = M_TitleID
|
||||
join m_sex on M_PatientM_SexID = M_SexID
|
||||
left join m_religion on m_patientm_religionid = m_religionid
|
||||
where M_PatientIsActive = 'Y'
|
||||
where M_PatientIsActive = 'Y'
|
||||
{$q['name']}
|
||||
{$q['dob']}
|
||||
{$q['nik']}
|
||||
|
||||
group by M_PatientID
|
||||
limit $number_limit offset $number_offset";
|
||||
//echo $sql;
|
||||
$query = $this->db_onedev->query($sql);
|
||||
|
||||
if ($query) {
|
||||
if ($query) {
|
||||
$rows = $query->result_array();
|
||||
if($rows){
|
||||
$per_divider = 1;
|
||||
foreach($rows as $k => $v){
|
||||
$name = $enc->decrypt($v['M_PatientName_enc'] ?? '') ?? $v['M_PatientName'];
|
||||
$hp = $enc->decrypt($v['M_PatientHP_enc'] ?? '') ?? $v['M_PatientHP'];
|
||||
$email = $enc->decrypt($v['M_PatientEmail_enc'] ?? '') ?? $v['M_PatientEmail'];
|
||||
$nik = $enc->decrypt($v['M_PatientNIK_enc'] ?? '') ?? $v['M_PatientNIK'];
|
||||
$rows[$k]['M_PatientName'] = $name;
|
||||
$rows[$k]['M_PatientHP'] = $hp;
|
||||
$rows[$k]['M_PatientEmail'] = $email;
|
||||
$rows[$k]['M_PatientNIK'] = $nik;
|
||||
$rows[$k]['Mcu_PreregisterDetailsPatientName'] = $name;
|
||||
$rows[$k]['Mcu_PreregisterDetailsNIK'] = $nik;
|
||||
$rows[$k]['Mcu_PreregisterDetailsEmail'] = $email;
|
||||
$rows[$k]['Mcu_PreregisterDetailsHp'] = $hp;
|
||||
foreach (array_keys($rows[$k]) as $col) {
|
||||
if (substr($col, -4) === '_enc' || substr($col, -5) === '_bidx') unset($rows[$k][$col]);
|
||||
}
|
||||
if($per_divider == 10){
|
||||
$rows[$k]['divider'] = 'Y';
|
||||
}
|
||||
@@ -569,71 +613,86 @@ class Preregisterapp extends MY_Controller
|
||||
$name = $prm['name'];
|
||||
$dob = $prm['dob'];
|
||||
$nik = $prm['nik'];
|
||||
$add_where = '';
|
||||
if($nik != ''){
|
||||
$add_where = " AND M_PatientNIK = '{$nik}'";
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
$name_where = '1=1';
|
||||
if (strlen($name) >= 3) {
|
||||
$toks = $enc->query_tokens($name);
|
||||
$conds = [];
|
||||
foreach ($toks as $tok) { $tok_esc = $this->db_onedev->escape_str($tok); $conds[] = "JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')"; }
|
||||
if ($conds) $name_where = implode(' AND ', $conds);
|
||||
}
|
||||
$nik_where = '';
|
||||
if ($nik != '' && strlen($nik) >= 3) {
|
||||
$toks = $enc->query_tokens($nik);
|
||||
$conds = [];
|
||||
foreach ($toks as $tok) { $tok_esc = $this->db_onedev->escape_str($tok); $conds[] = "JSON_CONTAINS(M_PatientNIK_bidx, '\"$tok_esc\"')"; }
|
||||
if ($conds) $nik_where = "AND (" . implode(' AND ', $conds) . ")";
|
||||
}
|
||||
$setup = $prm['setup'];
|
||||
$join_company = "";
|
||||
if(isset($prm['company']) && intval($prm['company']) > 0){
|
||||
$join_company = "JOIN t_orderheader ON T_OrderHeaderM_PatientID = M_PatientID AND
|
||||
T_OrderHeaderIsActive = 'Y' AND
|
||||
$join_company = "JOIN t_orderheader ON T_OrderHeaderM_PatientID = M_PatientID AND
|
||||
T_OrderHeaderIsActive = 'Y' AND
|
||||
T_OrderHeaderM_CompanyID = {$prm['company']}";
|
||||
}
|
||||
|
||||
|
||||
$sql = "SELECT COUNT(*) as total
|
||||
FROM (
|
||||
SELECT *
|
||||
SELECT M_PatientID
|
||||
FROM m_patient
|
||||
$join_company
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
LEFT JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
WHERE
|
||||
M_PatientIsActive = 'Y' AND
|
||||
M_PatientName LIKE CONCAT('%','{$name}','%') AND
|
||||
(DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$dob}%' and M_PatientDOB IS NOT NULL)
|
||||
{$add_where}
|
||||
M_PatientIsActive = 'Y' AND ({$name_where})
|
||||
AND (DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$dob}%' and M_PatientDOB IS NOT NULL)
|
||||
{$nik_where}
|
||||
GROUP BY M_PatientID
|
||||
) x
|
||||
";
|
||||
//echo $sql;
|
||||
) x";
|
||||
$countx = $this->db_onedev->query($sql)->row()->total;
|
||||
$sql = "SELECT *, DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') as dob_ina,
|
||||
|
||||
$sql = "SELECT m_patient.*, DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') as dob_ina,
|
||||
M_PatientNoReg as Mcu_PreregisterDetailsPID,
|
||||
M_PatientNIK as Mcu_PreregisterDetailsNIK,
|
||||
M_PatientID as Mcu_PreregisterDetailsM_PatientID,
|
||||
M_TitleID as Mcu_PreregisterDetailsM_TitleID,
|
||||
M_PatientName as Mcu_PreregisterDetailsPatientName,
|
||||
M_SexCode as Mcu_PreregisterDetailsM_SexCode,
|
||||
M_PatientDOB as Mcu_PreregisterDetailsDOB,
|
||||
IFNULL(M_ReligionID,0) as Mcu_PreregisterDetailsM_ReligionID,
|
||||
M_PatientJabatan as Mcu_PreregisterDetailsJabatan,
|
||||
M_PatientEmail as Mcu_PreregisterDetailsEmail,
|
||||
M_PatientHP as Mcu_PreregisterDetailsHp,
|
||||
M_PatientKedudukan as Mcu_PreregisterDetailsKedudukan,
|
||||
M_PatientLocation as Mcu_PreregisterDetailsLocation,
|
||||
M_PatientJob as Mcu_PreregisterDetailsJob
|
||||
FROM m_patient
|
||||
$join_company
|
||||
LEFT join m_title on M_PatientM_TitleID = M_TitleID
|
||||
LEFT join m_sex on M_PatientM_SexID = M_SexID
|
||||
left join m_religion on m_patientm_religionid = m_religionid
|
||||
LEFT join m_sex on M_PatientM_SexID = M_SexID
|
||||
left join m_religion on m_patientm_religionid = m_religionid
|
||||
WHERE
|
||||
M_PatientIsActive = 'Y' AND
|
||||
M_PatientName LIKE CONCAT('%','{$name}','%') AND
|
||||
(DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$dob}%' and M_PatientDOB IS NOT NULL)
|
||||
{$add_where}
|
||||
M_PatientIsActive = 'Y' AND ({$name_where})
|
||||
AND (DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$dob}%' and M_PatientDOB IS NOT NULL)
|
||||
{$nik_where}
|
||||
GROUP BY M_PatientID
|
||||
LIMIT 10 OFFSET 0
|
||||
";
|
||||
|
||||
//echo $sql;
|
||||
LIMIT 10 OFFSET 0";
|
||||
|
||||
$rows = $this->db_onedev->query($sql)->result_array();
|
||||
|
||||
$result = array(
|
||||
"total" => $countx ,
|
||||
"records" => $rows
|
||||
);
|
||||
foreach ($rows as $k => $v) {
|
||||
$name_dec = $enc->decrypt($v['M_PatientName_enc'] ?? '') ?? $v['M_PatientName'];
|
||||
$hp_dec = $enc->decrypt($v['M_PatientHP_enc'] ?? '') ?? $v['M_PatientHP'];
|
||||
$email_dec = $enc->decrypt($v['M_PatientEmail_enc'] ?? '') ?? $v['M_PatientEmail'];
|
||||
$nik_dec = $enc->decrypt($v['M_PatientNIK_enc'] ?? '') ?? $v['M_PatientNIK'];
|
||||
$rows[$k]['M_PatientName'] = $name_dec;
|
||||
$rows[$k]['M_PatientHP'] = $hp_dec;
|
||||
$rows[$k]['M_PatientEmail'] = $email_dec;
|
||||
$rows[$k]['M_PatientNIK'] = $nik_dec;
|
||||
$rows[$k]['Mcu_PreregisterDetailsPatientName'] = $name_dec;
|
||||
$rows[$k]['Mcu_PreregisterDetailsNIK'] = $nik_dec;
|
||||
$rows[$k]['Mcu_PreregisterDetailsEmail'] = $email_dec;
|
||||
$rows[$k]['Mcu_PreregisterDetailsHp'] = $hp_dec;
|
||||
foreach (array_keys($rows[$k]) as $col) {
|
||||
if (substr($col, -4) === '_enc' || substr($col, -5) === '_bidx') unset($rows[$k][$col]);
|
||||
}
|
||||
}
|
||||
|
||||
$result = array("total" => $countx, "records" => $rows);
|
||||
$this->sys_ok($result);
|
||||
exit;
|
||||
}
|
||||
@@ -1014,6 +1073,11 @@ class Preregisterapp extends MY_Controller
|
||||
unset($datas[0]);
|
||||
foreach($datas as $k => $v){
|
||||
$pdob = date('Y-m-d',strtotime($v['TANGGAL_LAHIR']));
|
||||
$m_nama = $this->db_onedev->escape_str($this->_mask_name($v['NAMA']));
|
||||
$m_ktp = $this->_mask_id($v['KTP']);
|
||||
$m_nik = $this->_mask_id($v['NIK']);
|
||||
$m_email = $this->_mask_email($v['EMAIL']);
|
||||
$m_hp = $this->_mask_phone($v['HP']);
|
||||
$query = " INSERT INTO mcu_preregister_patients (
|
||||
Mcu_PreregisterDetailsMcuOfflinePrepareID,
|
||||
Mcu_PreregisterDetailsPID,
|
||||
@@ -1036,11 +1100,11 @@ class Preregisterapp extends MY_Controller
|
||||
VALUES(
|
||||
'{$prm['xid']}',
|
||||
'{$v['PID']}',
|
||||
'{$v['NIK']}',
|
||||
'{$v['KTP']}',
|
||||
'{$v['NAMA']}',
|
||||
'{$v['EMAIL']}',
|
||||
'{$v['HP']}',
|
||||
'{$m_nik}',
|
||||
'{$m_ktp}',
|
||||
'{$m_nama}',
|
||||
'{$m_email}',
|
||||
'{$m_hp}',
|
||||
'{$pdob}',
|
||||
'{$v['KEDUDUKAN']}',
|
||||
'{$v['JABATAN']}',
|
||||
@@ -1071,31 +1135,29 @@ class Preregisterapp extends MY_Controller
|
||||
}
|
||||
}
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
if($v['KTP'] != ''){
|
||||
$sql = "SELECT *
|
||||
FROM m_patient
|
||||
WHERE
|
||||
M_PatientM_IdTypeID = 1 AND
|
||||
M_PatientIDNumber = '{$v['KTP']}' AND
|
||||
M_PatientIsActive = 'Y'
|
||||
LIMIT 1";
|
||||
$exist_r = $this->db_onedev->query($sql)->row_array();
|
||||
if($exist_r){
|
||||
$patient_id = $exist_r["M_PatientID"];
|
||||
$ktp_toks = $enc->query_tokens($v['KTP']);
|
||||
$ktp_conds = [];
|
||||
foreach ($ktp_toks as $tok) { $tok_esc = $this->db_onedev->escape_str($tok); $ktp_conds[] = "JSON_CONTAINS(M_PatientNIK_bidx, '\"$tok_esc\"')"; }
|
||||
if ($ktp_conds) {
|
||||
$sql = "SELECT M_PatientID FROM m_patient
|
||||
WHERE M_PatientIsActive = 'Y' AND (" . implode(' AND ', $ktp_conds) . ")
|
||||
LIMIT 1";
|
||||
$exist_r = $this->db_onedev->query($sql)->row_array();
|
||||
if($exist_r) $patient_id = $exist_r["M_PatientID"];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($patient_id == 0){
|
||||
$sql = "SELECT *
|
||||
FROM m_patient
|
||||
WHERE
|
||||
M_PatientName = '{$v['NAMA']}' AND
|
||||
M_PatientDOB = '{$pdob}' AND
|
||||
M_PatientIsActive = 'Y' LIMIT 1";
|
||||
$name_toks = $enc->query_tokens($v['NAMA']);
|
||||
$name_conds = [];
|
||||
foreach ($name_toks as $tok) { $tok_esc = $this->db_onedev->escape_str($tok); $name_conds[] = "JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')"; }
|
||||
$name_where = $name_conds ? implode(' AND ', $name_conds) : '0';
|
||||
$sql = "SELECT M_PatientID FROM m_patient
|
||||
WHERE ({$name_where}) AND M_PatientDOB = '{$pdob}' AND M_PatientIsActive = 'Y' LIMIT 1";
|
||||
$exist_r = $this->db_onedev->query($sql)->row_array();
|
||||
if($exist_r){
|
||||
$patient_id = $exist_r["M_PatientID"];
|
||||
}
|
||||
if($exist_r) $patient_id = $exist_r["M_PatientID"];
|
||||
}
|
||||
|
||||
|
||||
@@ -1148,28 +1210,40 @@ class Preregisterapp extends MY_Controller
|
||||
)";
|
||||
//echo $sql;
|
||||
$this->db_onedev->query($sql);*/
|
||||
$data_insert_patient = array(
|
||||
'M_PatientName' => $v["NAMA"] ,
|
||||
'M_PatientM_TitleID' => $title_id ,
|
||||
'M_PatientM_SexID' => $sex_id,
|
||||
'M_PatientM_ReligionID' => $religion_id ,
|
||||
'M_PatientPOB' => '-',
|
||||
'M_PatientDOB' => $pdob,
|
||||
'M_PatientNIK' => $v["NIK"] ,
|
||||
'M_PatientJabatan' => $v['JABATAN'],
|
||||
'M_PatientLocation' => $v['LOKASI'],
|
||||
'M_PatientKedudukan' => $v['KEDUDUKAN'] ,
|
||||
'M_PatientJob' => $v['JOB'],
|
||||
'M_PatientEmail' => $v['EMAIL'],
|
||||
'M_PatientHP' => $v['HP'],
|
||||
'M_PatientUserID' => $userid
|
||||
);
|
||||
$enc = $this->ibl_encryptor;
|
||||
$dob_str = date('d-m-Y', strtotime($pdob));
|
||||
$data_insert_patient = [
|
||||
'M_PatientName' => $this->_mask_name($v["NAMA"]),
|
||||
'M_PatientName_enc' => $enc->encrypt($v["NAMA"]),
|
||||
'M_PatientName_bidx' => $enc->search_bidx($v["NAMA"]),
|
||||
'M_PatientM_TitleID' => $title_id,
|
||||
'M_PatientM_SexID' => $sex_id,
|
||||
'M_PatientM_ReligionID' => $religion_id,
|
||||
'M_PatientPOB' => '***',
|
||||
'M_PatientPOB_enc' => $enc->encrypt('-'),
|
||||
'M_PatientDOB' => $pdob,
|
||||
'M_PatientDOB_enc' => $enc->encrypt($dob_str),
|
||||
'M_PatientDOB_bidx' => $enc->search_bidx($dob_str),
|
||||
'M_PatientNIK' => $v["NIK"],
|
||||
'M_PatientNIK_bidx' => $enc->search_bidx($v["NIK"] ?? ''),
|
||||
'M_PatientJabatan' => $v['JABATAN'],
|
||||
'M_PatientLocation' => $v['LOKASI'],
|
||||
'M_PatientKedudukan' => $v['KEDUDUKAN'],
|
||||
'M_PatientJob' => $v['JOB'],
|
||||
'M_PatientEmail' => $this->_mask_email($v['EMAIL']),
|
||||
'M_PatientEmail_enc' => $enc->encrypt($v['EMAIL']),
|
||||
'M_PatientHP' => $this->_mask_phone($v['HP']),
|
||||
'M_PatientHP_enc' => $enc->encrypt($v['HP']),
|
||||
'M_PatientHP_bidx' => $enc->search_bidx($v['HP']),
|
||||
'M_PatientUserID' => $userid,
|
||||
];
|
||||
if(isset($v["KTP"]) && $v["KTP"] != ''){
|
||||
$data_insert_patient['M_PatientM_IdTypeID'] = 1;
|
||||
$data_insert_patient['M_PatientIDNumber'] = $v["KTP"];
|
||||
$data_insert_patient['M_PatientM_IdTypeID'] = 1;
|
||||
$data_insert_patient['M_PatientIDNumber'] = $this->_mask_id($v["KTP"]);
|
||||
$data_insert_patient['M_PatientIDNumber_enc'] = $enc->encrypt($v["KTP"]);
|
||||
}
|
||||
|
||||
$this->db->insert('m_patient', $data_insert_patient);
|
||||
$this->db_onedev->insert('m_patient', $data_insert_patient);
|
||||
$patient_id = $this->db_onedev->insert_id();
|
||||
$sql = "SELECT * FROM m_patient WHERE M_PatientID = {$patient_id}";
|
||||
$ptn = $this->db_onedev->query($sql)->row_array();
|
||||
@@ -1244,56 +1318,46 @@ class Preregisterapp extends MY_Controller
|
||||
$prm = $this->sys_input;
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
$pdob = date('Y-m-d',strtotime($prm['M_PatientDOB']));
|
||||
$query ="INSERT INTO m_patient (
|
||||
M_PatientM_TitleID,
|
||||
M_PatientPrefix,
|
||||
M_PatientName,
|
||||
M_PatientSuffix,
|
||||
M_PatientDOB,
|
||||
M_PatientM_SexID,
|
||||
M_PatientM_ReligionID,
|
||||
M_PatientEmail,
|
||||
M_PatientPOB,
|
||||
M_PatientHP,
|
||||
M_PatientPhone,
|
||||
M_PatientM_IdTypeID,
|
||||
M_PatientIDNumber,
|
||||
M_PatientNote,
|
||||
M_PatientNIK,
|
||||
M_PatientJabatan,
|
||||
M_PatientKedudukan,
|
||||
M_PatientPJ,
|
||||
M_PatientLocation,
|
||||
M_PatientJob,
|
||||
M_PatientUserID
|
||||
)
|
||||
VALUES(
|
||||
'{$prm['M_PatientM_TitleID']}',
|
||||
'{$prm['M_PatientPrefix']}',
|
||||
'{$prm['M_PatientName']}',
|
||||
'{$prm['M_PatientSuffix']}',
|
||||
'{$pdob}',
|
||||
'{$prm['M_PatientM_SexID']}',
|
||||
'{$prm['M_PatientM_ReligionID']}',
|
||||
'{$prm['M_PatientEmail']}',
|
||||
'{$prm['M_PatientPOB']}',
|
||||
'{$prm['M_PatientHP']}',
|
||||
'{$prm['M_PatientPhone']}',
|
||||
'{$prm['M_PatientM_IdTypeID']}',
|
||||
'{$prm['M_PatientIDNumber']}',
|
||||
'{$prm['M_PatientNote']}',
|
||||
'{$prm['M_PatientNIK']}',
|
||||
'{$prm['M_PatientJabatan']}',
|
||||
'{$prm['M_PatientKedudukan']}',
|
||||
'{$prm['M_PatientPJ']}',
|
||||
'{$prm['M_PatientLocation']}',
|
||||
'{$prm['M_PatientJob']}',
|
||||
$userid
|
||||
)
|
||||
";
|
||||
//echo $query;
|
||||
$rows = $this->db_onedev->query($query);
|
||||
$pdob = date('Y-m-d', strtotime($prm['M_PatientDOB']));
|
||||
$dob_str = date('d-m-Y', strtotime($prm['M_PatientDOB']));
|
||||
$patient_name = $prm['M_PatientName'];
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
$ptn = [
|
||||
'M_PatientName' => $this->_mask_name($patient_name),
|
||||
'M_PatientName_enc' => $enc->encrypt($patient_name),
|
||||
'M_PatientName_bidx' => $enc->search_bidx($patient_name),
|
||||
'M_PatientM_TitleID' => $prm['M_PatientM_TitleID'],
|
||||
'M_PatientPrefix' => $prm['M_PatientPrefix'],
|
||||
'M_PatientSuffix' => $prm['M_PatientSuffix'],
|
||||
'M_PatientDOB' => $pdob,
|
||||
'M_PatientDOB_enc' => $enc->encrypt($dob_str),
|
||||
'M_PatientDOB_bidx' => $enc->search_bidx($dob_str),
|
||||
'M_PatientM_SexID' => $prm['M_PatientM_SexID'],
|
||||
'M_PatientM_ReligionID' => $prm['M_PatientM_ReligionID'],
|
||||
'M_PatientEmail' => $this->_mask_email($prm['M_PatientEmail']),
|
||||
'M_PatientEmail_enc' => $enc->encrypt($prm['M_PatientEmail']),
|
||||
'M_PatientPOB' => $this->_mask_short($prm['M_PatientPOB']),
|
||||
'M_PatientPOB_enc' => $enc->encrypt($prm['M_PatientPOB']),
|
||||
'M_PatientHP' => $this->_mask_phone($prm['M_PatientHP']),
|
||||
'M_PatientHP_enc' => $enc->encrypt($prm['M_PatientHP']),
|
||||
'M_PatientHP_bidx' => $enc->search_bidx($prm['M_PatientHP']),
|
||||
'M_PatientPhone' => $this->_mask_phone($prm['M_PatientPhone']),
|
||||
'M_PatientPhone_enc' => $enc->encrypt($prm['M_PatientPhone']),
|
||||
'M_PatientM_IdTypeID' => $prm['M_PatientM_IdTypeID'],
|
||||
'M_PatientIDNumber' => $this->_mask_id($prm['M_PatientIDNumber']),
|
||||
'M_PatientIDNumber_enc' => $enc->encrypt($prm['M_PatientIDNumber']),
|
||||
'M_PatientNIK' => $prm['M_PatientNIK'],
|
||||
'M_PatientNIK_bidx' => $enc->search_bidx($prm['M_PatientNIK'] ?? ''),
|
||||
'M_PatientNote' => $prm['M_PatientNote'],
|
||||
'M_PatientJabatan' => $prm['M_PatientJabatan'],
|
||||
'M_PatientKedudukan' => $prm['M_PatientKedudukan'],
|
||||
'M_PatientPJ' => $prm['M_PatientPJ'],
|
||||
'M_PatientLocation' => $prm['M_PatientLocation'],
|
||||
'M_PatientJob' => $prm['M_PatientJob'],
|
||||
'M_PatientUserID' => $userid,
|
||||
];
|
||||
$this->db_onedev->insert('m_patient', $ptn);
|
||||
$last_id = $this->db_onedev->insert_id();
|
||||
$result = array(
|
||||
"total" => 1 ,
|
||||
@@ -1502,6 +1566,10 @@ class Preregisterapp extends MY_Controller
|
||||
$default_tests = $data_prepare['McuOfflinePrepareTests'];
|
||||
$v['Mcu_PreregisterDetailsPatientName'] = str_replace("'", "\\'", $v['Mcu_PreregisterDetailsPatientName']);
|
||||
$pdob = date('Y-m-d',strtotime($v['Mcu_PreregisterDetailsDOB']));
|
||||
$m_nama = $this->db_onedev->escape_str($this->_mask_name($v['Mcu_PreregisterDetailsPatientName']));
|
||||
$m_nik = $this->_mask_id($v['Mcu_PreregisterDetailsNIK']);
|
||||
$m_email = $this->_mask_email($v['Mcu_PreregisterDetailsEmail']);
|
||||
$m_hp = $this->_mask_phone($v['Mcu_PreregisterDetailsHp']);
|
||||
$query = " INSERT INTO mcu_preregister_patients (
|
||||
Mcu_PreregisterDetailsMcuOfflinePrepareID,
|
||||
Mcu_PreregisterDetailsM_PatientID,
|
||||
@@ -1527,12 +1595,12 @@ class Preregisterapp extends MY_Controller
|
||||
VALUES(
|
||||
'{$setup['McuOfflinePrepareID']}',
|
||||
'{$v['Mcu_PreregisterDetailsM_PatientID']}',
|
||||
'{$v['Mcu_PreregisterDetailsNIK']}',
|
||||
'{$m_nik}',
|
||||
'{$v['Mcu_PreregisterDetailsPatientPrefix']}',
|
||||
'{$v['Mcu_PreregisterDetailsPatientName']}',
|
||||
'{$m_nama}',
|
||||
'{$v['Mcu_PreregisterDetailsPatientSuffix']}',
|
||||
'{$v['Mcu_PreregisterDetailsEmail']}',
|
||||
'{$v['Mcu_PreregisterDetailsHp']}',
|
||||
'{$m_email}',
|
||||
'{$m_hp}',
|
||||
'{$pdob}',
|
||||
'{$v['Mcu_PreregisterDetailsKedudukan']}',
|
||||
'{$v['Mcu_PreregisterDetailsJabatan']}',
|
||||
|
||||
@@ -12,8 +12,26 @@ class Preregisterapp extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
private function _mask_name($v) {
|
||||
if (!$v) return $v;
|
||||
$v = trim($v);
|
||||
$words = preg_split('/\s+/', $v);
|
||||
$out = [];
|
||||
foreach ($words as $w) {
|
||||
$l = mb_strlen($w, 'UTF-8');
|
||||
if ($l <= 2) { $out[] = '***'; continue; }
|
||||
$out[] = mb_substr($w, 0, 2, 'UTF-8') . str_repeat('*', max(3, $l - 2));
|
||||
}
|
||||
return implode(' ', $out);
|
||||
}
|
||||
private function _mask_phone($v) { if (!$v) return $v; $d=preg_replace('/[^0-9]/','',trim($v)); $l=strlen($d); if($l<=4) return '****'; if($l<=8) return substr($d,0,4).str_repeat('*',$l-4); return substr($d,0,4).str_repeat('*',$l-7).substr($d,-3); }
|
||||
private function _mask_email($v) { if (!$v||strpos($v,'@')===false) return $v; [$loc,$dom]=explode('@',$v,2); return mb_substr($loc,0,min(2,mb_strlen($loc,'UTF-8')),'UTF-8').'***@'.$dom; }
|
||||
private function _mask_id($v) { if (!$v) return $v; $v=trim($v); $l=strlen($v); if($l<=4) return '****'; return substr($v,0,4).str_repeat('*',max(3,$l-6)).($l>6?substr($v,-2):''); }
|
||||
private function _mask_dob($v) { if (!$v) return $v; $p=explode('-',$v); return (count($p)===3) ? '**-**-'.$p[2] : '****-**-**'; }
|
||||
|
||||
public function get_setup_by_id()
|
||||
{
|
||||
try {
|
||||
@@ -270,8 +288,8 @@ class Preregisterapp extends MY_Controller
|
||||
Mcu_PreregisterPatientsPatientName,
|
||||
' ',
|
||||
IFNULL(Mcu_PreregisterPatientsPatientSuffix,'')) as patient_fullname,
|
||||
DATE_FORMAT(Mcu_PreregisterPatientsDOB,'%d-%m-%Y') as dob,
|
||||
DATE_FORMAT(Mcu_PreregisterPatientsDOB,'%d-%m-%Y') as Mcu_PreregisterPatientsDOB,
|
||||
Mcu_PreregisterPatientsDOB as dob,
|
||||
Mcu_PreregisterPatientsDOB,
|
||||
IFNULL(M_PatientAddressDescription, '') as M_PatientAddress,
|
||||
M_PatientAddressCity,
|
||||
IFNULL(M_PatientAddressCountry, 'ID') as M_PatientAddressCountry,
|
||||
@@ -440,11 +458,25 @@ class Preregisterapp extends MY_Controller
|
||||
|
||||
if ($prm['search'] != '') {
|
||||
$e = explode('+', $prm['search']);
|
||||
if (isset($e[0]))
|
||||
$q['name'] = "AND M_PatientName LIKE '%{$e[0]}%'";
|
||||
if (isset($e[1]))
|
||||
$q['dob'] = "AND ((DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$e[1]}%' and M_PatientDOB IS NOT NULL) OR (M_PatientDOB IS NULL AND '{$e[1]}' = ''))";
|
||||
if (isset($e[2]))
|
||||
if (isset($e[0]) && $e[0] != '') {
|
||||
$name_toks = $this->ibl_encryptor->query_tokens($e[0]);
|
||||
$name_conds = [];
|
||||
foreach ($name_toks as $tok) {
|
||||
$tok_esc = $this->db_onedev->escape_str($tok);
|
||||
$name_conds[] = "JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
if ($name_conds) $q['name'] = "AND " . implode(' AND ', $name_conds);
|
||||
}
|
||||
if (isset($e[1]) && $e[1] != '') {
|
||||
$dob_toks = $this->ibl_encryptor->query_tokens($e[1]);
|
||||
$dob_conds = [];
|
||||
foreach ($dob_toks as $tok) {
|
||||
$tok_esc = $this->db_onedev->escape_str($tok);
|
||||
$dob_conds[] = "JSON_CONTAINS(M_PatientDOB_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
if ($dob_conds) $q['dob'] = "AND " . implode(' AND ', $dob_conds);
|
||||
}
|
||||
if (isset($e[2]) && $e[2] != '')
|
||||
$q['nik'] = "AND M_PatientNIP LIKE '%{$e[2]}%'";
|
||||
}
|
||||
|
||||
@@ -453,7 +485,7 @@ class Preregisterapp extends MY_Controller
|
||||
'N' divider,
|
||||
concat(IFNULL(M_TitleName,''),' ',IFNULL(M_PatientPrefix,''),' ',M_PatientName,' ',IFNULL(M_PatientSuffix,'')) M_PatientName,
|
||||
M_PatientName M_PatientRealName, M_TitleID, M_TitleName, M_PatientM_SexID,
|
||||
DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as dob_ina,
|
||||
M_PatientDOB as dob_ina,
|
||||
IFNULL(M_PatientReligionCode, '-') M_PatientReligionCode,
|
||||
M_PatientNoReg as Mcu_PreregisterPatientsPID,
|
||||
M_PatientIdentifierValue as Mcu_PreregisterPatientsKTP,
|
||||
@@ -601,20 +633,21 @@ class Preregisterapp extends MY_Controller
|
||||
?
|
||||
)";
|
||||
//echo $query;
|
||||
$m_dob_ptp = $this->_mask_dob(date('d-m-Y', strtotime($pdob)));
|
||||
$rows = $this->db_onedev->query($query, [
|
||||
$setup['Mgm_McuID'],
|
||||
$v['Mcu_PreregisterPatientsPID'],
|
||||
$v['M_PatientID'],
|
||||
$v['Mcu_PreregisterPatientsKTP'],
|
||||
$v['Mcu_PreregisterPatientsKTP'] ? $this->_mask_id($v['Mcu_PreregisterPatientsKTP']) : '',
|
||||
$v['M_PatientPrefix'],
|
||||
$v['M_PatientRealName'],
|
||||
$this->_mask_name($v['M_PatientRealName']),
|
||||
$v['M_PatientSuffix'],
|
||||
$v['M_PatientM_SexID'],
|
||||
$pdob,
|
||||
$m_dob_ptp,
|
||||
$v['M_PatientReligionCode'],
|
||||
$v['Mcu_PreregisterPatientsJob'],
|
||||
$v['Mcu_PreregisterPatientsEmail'],
|
||||
$v['Mcu_PreregisterPatientsHp'],
|
||||
$this->_mask_email($v['Mcu_PreregisterPatientsEmail']),
|
||||
$this->_mask_phone($v['Mcu_PreregisterPatientsHp']),
|
||||
$v['Mcu_PreregisterPatientsPosisi'],
|
||||
$v['Mcu_PreregisterPatientsDivisi'],
|
||||
$v['Mcu_PreregisterPatientsLocation'],
|
||||
@@ -660,22 +693,39 @@ class Preregisterapp extends MY_Controller
|
||||
$IdentifierSystem = 'http://terminology.hl7.org/CodeSystem/v2-0203';
|
||||
}
|
||||
|
||||
$enc_new = $this->ibl_encryptor;
|
||||
$plain_name_new = $v['Mcu_PreregisterPatientsPatientName'];
|
||||
$plain_ktp_new = $v['Mcu_PreregisterPatientsKTP'];
|
||||
$plain_email_new = $v['Mcu_PreregisterPatientsEmail'];
|
||||
$plain_hp_new = $v['Mcu_PreregisterPatientsHp'];
|
||||
$dob_str_new = date('d-m-Y', strtotime($pdob));
|
||||
|
||||
$sql = "INSERT INTO m_patient (
|
||||
M_PatientPrefix,
|
||||
M_PatientName,
|
||||
M_PatientName_enc,
|
||||
M_PatientName_bidx,
|
||||
M_PatientSuffix,
|
||||
M_PatientM_TitleID,
|
||||
M_PatientM_SexID,
|
||||
M_PatientDOB,
|
||||
M_PatientDOB_enc,
|
||||
M_PatientDOB_bidx,
|
||||
M_PatientIdentifierCode,
|
||||
M_PatientIdentifierSystem,
|
||||
M_PatientIdentifierValue,
|
||||
M_PatientIDNumber,
|
||||
M_PatientIDNumber_enc,
|
||||
M_PatientNIK_bidx,
|
||||
M_PatientPosisi,
|
||||
M_PatientDivisi,
|
||||
M_PatientLocation,
|
||||
M_PatientJob,
|
||||
M_PatientEmail,
|
||||
M_PatientEmail_enc,
|
||||
M_PatientHP,
|
||||
M_PatientHP_enc,
|
||||
M_PatientHP_bidx,
|
||||
M_PatientCreatedUserID,
|
||||
M_PatientNIP,
|
||||
M_PatientDepartement,
|
||||
@@ -683,31 +733,39 @@ class Preregisterapp extends MY_Controller
|
||||
M_PatientCreated,
|
||||
M_PatientRegisteredByCompanyID
|
||||
)
|
||||
VALUES(
|
||||
'{$v["Mcu_PreregisterPatientsPatientPrefix"]}',
|
||||
'{$nameNewPn}',
|
||||
'{$v["Mcu_PreregisterPatientsPatientSuffix"]}',
|
||||
'{$title_id}',
|
||||
'{$v["M_PatientM_SexID"]}',
|
||||
'{$pdob}',
|
||||
'{$typeIdentifier}',
|
||||
'{$IdentifierSystem}',
|
||||
'{$v["Mcu_PreregisterPatientsKTP"]}',
|
||||
'{$v['Mcu_PreregisterPatientsPosisi']}',
|
||||
'{$v['Mcu_PreregisterPatientsDivisi']}',
|
||||
'{$v['Mcu_PreregisterPatientsLocation']}',
|
||||
'{$v['Mcu_PreregisterPatientsJob']}',
|
||||
'{$v['Mcu_PreregisterPatientsEmail']}',
|
||||
'{$v['Mcu_PreregisterPatientsHp']}',
|
||||
'{$userid}',
|
||||
'{$v['Mcu_PreregisterPatientsNIK']}',
|
||||
'{$v['Mcu_PreregisterPatientsDepartment']}',
|
||||
'{$number}',
|
||||
NOW(),
|
||||
'{$setup['Mgm_McuM_CompanyID']}'
|
||||
)";
|
||||
//echo $sql;
|
||||
$rows = $this->db_onedev->query($sql);
|
||||
VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),?)";
|
||||
$rows = $this->db_onedev->query($sql, [
|
||||
$v['Mcu_PreregisterPatientsPatientPrefix'],
|
||||
$this->_mask_name($plain_name_new),
|
||||
$enc_new->encrypt($plain_name_new),
|
||||
$enc_new->search_bidx($plain_name_new),
|
||||
$v['Mcu_PreregisterPatientsPatientSuffix'],
|
||||
$title_id,
|
||||
$v['M_PatientM_SexID'],
|
||||
$this->_mask_dob($dob_str_new),
|
||||
$enc_new->encrypt($dob_str_new),
|
||||
$enc_new->search_bidx($dob_str_new),
|
||||
$typeIdentifier,
|
||||
$IdentifierSystem,
|
||||
$plain_ktp_new ? $this->_mask_id($plain_ktp_new) : '',
|
||||
$plain_ktp_new ? $this->_mask_id($plain_ktp_new) : null,
|
||||
$plain_ktp_new ? $enc_new->encrypt($plain_ktp_new) : null,
|
||||
$enc_new->search_bidx($plain_ktp_new ?? ''),
|
||||
$v['Mcu_PreregisterPatientsPosisi'],
|
||||
$v['Mcu_PreregisterPatientsDivisi'],
|
||||
$v['Mcu_PreregisterPatientsLocation'],
|
||||
$v['Mcu_PreregisterPatientsJob'],
|
||||
$plain_email_new ? $this->_mask_email($plain_email_new) : '',
|
||||
$plain_email_new ? $enc_new->encrypt($plain_email_new) : null,
|
||||
$plain_hp_new ? $this->_mask_phone($plain_hp_new) : '',
|
||||
$plain_hp_new ? $enc_new->encrypt($plain_hp_new) : null,
|
||||
$enc_new->search_bidx($plain_hp_new ?? ''),
|
||||
$userid,
|
||||
$v['Mcu_PreregisterPatientsNIK'],
|
||||
$v['Mcu_PreregisterPatientsDepartment'],
|
||||
$number,
|
||||
$setup['Mgm_McuM_CompanyID']
|
||||
]);
|
||||
if (!$rows) {
|
||||
$message = $this->db_onedev->error();
|
||||
$message['qry'] = $this->db_onedev->last_query();
|
||||
@@ -1039,7 +1097,7 @@ class Preregisterapp extends MY_Controller
|
||||
}
|
||||
|
||||
|
||||
$pdob = date('Y-m-d', strtotime($v['Mcu_PreregisterPatientsDOB']));
|
||||
$pdob_input = $v['Mcu_PreregisterPatientsDOB'];
|
||||
|
||||
$Mcu_PreregisterPatientsTests = '';
|
||||
$packettests = array();
|
||||
@@ -1069,9 +1127,23 @@ class Preregisterapp extends MY_Controller
|
||||
}
|
||||
$dataPatientBefore = $rows->row_array();
|
||||
|
||||
$enc_upd = $this->ibl_encryptor;
|
||||
$pdob_ts = strtotime($pdob_input);
|
||||
if ($pdob_ts && $pdob_ts > 0 && strpos($pdob_input, '*') === false) {
|
||||
$dob_str_upd = date('d-m-Y', $pdob_ts);
|
||||
$pdob = date('Y-m-d', $pdob_ts);
|
||||
} else {
|
||||
$dob_str_upd = $enc_upd->decrypt($dataPatientBefore['M_PatientDOB_enc'] ?? '') ?: '';
|
||||
$pdob = $dob_str_upd ? date('Y-m-d', strtotime($dob_str_upd)) : '';
|
||||
}
|
||||
$plain_name_upd = $v['Mcu_PreregisterPatientsPatientName'];
|
||||
$plain_ktp_upd = $v['Mcu_PreregisterPatientsKTP'];
|
||||
$plain_email_upd = $v['Mcu_PreregisterPatientsEmail'];
|
||||
$plain_hp_upd = $v['Mcu_PreregisterPatientsHp'];
|
||||
|
||||
$this->db_onedev->trans_begin();
|
||||
|
||||
$query = " UPDATE mcu_preregister_patients SET
|
||||
$query = " UPDATE mcu_preregister_patients SET
|
||||
Mcu_PreregisterPatientsM_PatientID = ?,
|
||||
Mcu_PreregisterPatientsKTP = ?,
|
||||
Mcu_PreregisterPatientsNIP = ?,
|
||||
@@ -1099,14 +1171,14 @@ class Preregisterapp extends MY_Controller
|
||||
//echo $query;
|
||||
$rows = $this->db_onedev->query($query, [
|
||||
$v['Mcu_PreregisterPatientsM_PatientID'],
|
||||
$v['Mcu_PreregisterPatientsKTP'],
|
||||
$plain_ktp_upd ? $this->_mask_id($plain_ktp_upd) : '',
|
||||
$v['Mcu_PreregisterPatientsNIP'],
|
||||
$v['Mcu_PreregisterPatientsPatientPrefix'],
|
||||
$v['Mcu_PreregisterPatientsPatientName'],
|
||||
$this->_mask_name($plain_name_upd),
|
||||
$v['Mcu_PreregisterPatientsPatientSuffix'],
|
||||
$v['Mcu_PreregisterPatientsEmail'],
|
||||
$v['Mcu_PreregisterPatientsHp'],
|
||||
$pdob,
|
||||
$plain_email_upd ? $this->_mask_email($plain_email_upd) : '',
|
||||
$plain_hp_upd ? $this->_mask_phone($plain_hp_upd) : '',
|
||||
$this->_mask_dob($dob_str_upd),
|
||||
$v['Mcu_PreregisterPatientsPosisi'],
|
||||
$v['Mcu_PreregisterPatientsDivisi'],
|
||||
$v['Mcu_PreregisterPatientsJob'],
|
||||
@@ -1129,24 +1201,30 @@ class Preregisterapp extends MY_Controller
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql_ktp = '';
|
||||
if (isset($v['Mcu_PreregisterPatientsKTP']) && $v['Mcu_PreregisterPatientsKTP'] != '') {
|
||||
$sql_ktp = "M_PatientIdentifierCode = 'NNIDN', M_PatientIdentifierSystem='http://terminology.hl7.org/CodeSystem/v2-0203', M_PatientIdentifierValue = '{$v['Mcu_PreregisterPatientsKTP']}',";
|
||||
//echo $sql_ktp;
|
||||
} else {
|
||||
$sql_ktp = "M_PatientIdentifierCode = '', M_PatientIdentifierSystem='', M_PatientIdentifierValue = '',";
|
||||
}
|
||||
$ktp_mask_upd = $plain_ktp_upd ? $this->_mask_id($plain_ktp_upd) : '';
|
||||
$sql = "UPDATE m_patient SET
|
||||
$sql_ktp
|
||||
M_PatientIdentifierCode = ?,
|
||||
M_PatientIdentifierSystem = ?,
|
||||
M_PatientIdentifierValue = ?,
|
||||
M_PatientIDNumber = ?,
|
||||
M_PatientIDNumber_enc = ?,
|
||||
M_PatientNIK_bidx = ?,
|
||||
M_PatientDOB = ?,
|
||||
M_PatientDOB_enc = ?,
|
||||
M_PatientDOB_bidx = ?,
|
||||
M_PatientM_TitleID = ?,
|
||||
M_PatientNIP = ?,
|
||||
M_PatientM_SexID = ?,
|
||||
M_PatientPrefix = ?,
|
||||
M_PatientName = ?,
|
||||
M_PatientName_enc = ?,
|
||||
M_PatientName_bidx = ?,
|
||||
M_PatientSuffix = ?,
|
||||
M_PatientEmail = ?,
|
||||
M_PatientEmail_enc = ?,
|
||||
M_PatientHP = ?,
|
||||
M_PatientHP_enc = ?,
|
||||
M_PatientHP_bidx = ?,
|
||||
M_PatientDivisi = ?,
|
||||
M_PatientPosisi = ?,
|
||||
M_PatientLocation = ?,
|
||||
@@ -1159,17 +1237,29 @@ class Preregisterapp extends MY_Controller
|
||||
WHERE
|
||||
M_PatientID = ?
|
||||
";
|
||||
//echo $sql;
|
||||
$qry = $this->db_onedev->query($sql, [
|
||||
$pdob,
|
||||
$plain_ktp_upd ? 'NNIDN' : '',
|
||||
$plain_ktp_upd ? 'http://terminology.hl7.org/CodeSystem/v2-0203' : '',
|
||||
$ktp_mask_upd,
|
||||
$ktp_mask_upd,
|
||||
$plain_ktp_upd ? $enc_upd->encrypt($plain_ktp_upd) : null,
|
||||
$enc_upd->search_bidx($plain_ktp_upd ?? ''),
|
||||
$this->_mask_dob($dob_str_upd),
|
||||
$enc_upd->encrypt($dob_str_upd),
|
||||
$enc_upd->search_bidx($dob_str_upd),
|
||||
$v['Mcu_PreregisterPatientsM_TitleID'],
|
||||
$v['Mcu_PreregisterPatientsNIP'],
|
||||
$v['Mcu_PreregisterPatientsM_SexID'],
|
||||
$v['Mcu_PreregisterPatientsPatientPrefix'],
|
||||
$v['Mcu_PreregisterPatientsPatientName'],
|
||||
$this->_mask_name($plain_name_upd),
|
||||
$enc_upd->encrypt($plain_name_upd),
|
||||
$enc_upd->search_bidx($plain_name_upd),
|
||||
$v['Mcu_PreregisterPatientsPatientSuffix'],
|
||||
$v['Mcu_PreregisterPatientsEmail'],
|
||||
$v['Mcu_PreregisterPatientsHp'],
|
||||
$plain_email_upd ? $this->_mask_email($plain_email_upd) : '',
|
||||
$plain_email_upd ? $enc_upd->encrypt($plain_email_upd) : null,
|
||||
$plain_hp_upd ? $this->_mask_phone($plain_hp_upd) : '',
|
||||
$plain_hp_upd ? $enc_upd->encrypt($plain_hp_upd) : null,
|
||||
$enc_upd->search_bidx($plain_hp_upd ?? ''),
|
||||
$v['Mcu_PreregisterPatientsDivisi'],
|
||||
$v['Mcu_PreregisterPatientsPosisi'],
|
||||
$v['Mcu_PreregisterPatientsLocation'],
|
||||
@@ -1725,16 +1815,41 @@ class Preregisterapp extends MY_Controller
|
||||
$add_where .= " AND M_PatientNIP = '{$nik}'";
|
||||
}
|
||||
if ($ktp != '') {
|
||||
$add_where .= " AND M_PatientIdentifierValue = '{$nik}' AND M_PatientIdentifierCode = 'NNIDN'";
|
||||
$ktp_toks = $this->ibl_encryptor->query_tokens($ktp);
|
||||
foreach ($ktp_toks as $ktok) {
|
||||
$ktok_esc = $this->db_onedev->escape_str($ktok);
|
||||
$add_where .= " AND JSON_CONTAINS(M_PatientNIK_bidx, '\"$ktok_esc\"')";
|
||||
}
|
||||
}
|
||||
$setup = $prm['setup'];
|
||||
$join_company = "";
|
||||
if (isset($prm['company']) && intval($prm['company']) > 0) {
|
||||
$join_company = "JOIN t_orderheader ON T_OrderHeaderM_PatientID = M_PatientID AND
|
||||
T_OrderHeaderIsActive = 'Y' AND
|
||||
$join_company = "JOIN t_orderheader ON T_OrderHeaderM_PatientID = M_PatientID AND
|
||||
T_OrderHeaderIsActive = 'Y' AND
|
||||
T_OrderHeaderM_CompanyID = {$prm['company']}";
|
||||
}
|
||||
|
||||
$name_where = '1=1';
|
||||
if ($name != '') {
|
||||
$name_toks = $this->ibl_encryptor->query_tokens($name);
|
||||
$nconds = [];
|
||||
foreach ($name_toks as $ntok) {
|
||||
$ntok_esc = $this->db_onedev->escape_str($ntok);
|
||||
$nconds[] = "JSON_CONTAINS(M_PatientName_bidx, '\"$ntok_esc\"')";
|
||||
}
|
||||
if ($nconds) $name_where = implode(' AND ', $nconds);
|
||||
}
|
||||
$dob_where = '1=1';
|
||||
if ($dob != '') {
|
||||
$dob_toks = $this->ibl_encryptor->query_tokens($dob);
|
||||
$dconds = [];
|
||||
foreach ($dob_toks as $dtok) {
|
||||
$dtok_esc = $this->db_onedev->escape_str($dtok);
|
||||
$dconds[] = "JSON_CONTAINS(M_PatientDOB_bidx, '\"$dtok_esc\"')";
|
||||
}
|
||||
if ($dconds) $dob_where = implode(' AND ', $dconds);
|
||||
}
|
||||
|
||||
$sql = "SELECT COUNT(*) as total
|
||||
FROM (
|
||||
SELECT *
|
||||
@@ -1742,16 +1857,15 @@ class Preregisterapp extends MY_Controller
|
||||
$join_company
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
WHERE
|
||||
M_PatientIsActive = 'Y'
|
||||
M_PatientIsActive = 'Y'
|
||||
AND M_PatientRegisteredByCompanyID = {$setup['Mgm_McuM_CompanyID']}
|
||||
AND M_PatientName LIKE CONCAT('%',?,'%') AND
|
||||
(DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$dob}%' and M_PatientDOB IS NOT NULL)
|
||||
AND ({$name_where})
|
||||
AND ({$dob_where})
|
||||
{$add_where}
|
||||
GROUP BY M_PatientID
|
||||
) x
|
||||
";
|
||||
//echo $sql;
|
||||
$qry = $this->db_onedev->query($sql, [$name]);
|
||||
$qry = $this->db_onedev->query($sql);
|
||||
if (!$qry) {
|
||||
$message = $this->db_onedev->error();
|
||||
$message['qry'] = $this->db_onedev->last_query();
|
||||
@@ -1759,7 +1873,7 @@ class Preregisterapp extends MY_Controller
|
||||
exit;
|
||||
}
|
||||
$countx = $qry->row()->total;
|
||||
$sql = "SELECT *, DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') as dob_ina,
|
||||
$sql = "SELECT *, M_PatientDOB as dob_ina,
|
||||
M_PatientNoReg as Mcu_PreregisterPatientsPID,
|
||||
M_PatientIdentifierValue as Mcu_PreregisterPatientsKTP,
|
||||
M_PatientID as Mcu_PreregisterPatientsM_PatientID,
|
||||
@@ -1781,16 +1895,15 @@ class Preregisterapp extends MY_Controller
|
||||
LEFT join m_title on M_PatientM_TitleID = M_TitleID
|
||||
WHERE
|
||||
M_PatientRegisteredByCompanyID = {$setup['Mgm_McuM_CompanyID']}
|
||||
AND M_PatientIsActive = 'Y' AND
|
||||
M_PatientName LIKE CONCAT('%',?,'%') AND
|
||||
(DATE_FORMAT(M_PatientDOB, '%d-%m-%Y') LIKE '%{$dob}%' and M_PatientDOB IS NOT NULL)
|
||||
AND M_PatientIsActive = 'Y'
|
||||
AND ({$name_where})
|
||||
AND ({$dob_where})
|
||||
{$add_where}
|
||||
GROUP BY M_PatientID
|
||||
LIMIT 10 OFFSET 0
|
||||
";
|
||||
|
||||
//echo $sql;
|
||||
$qry = $this->db_onedev->query($sql, [$name]);
|
||||
$qry = $this->db_onedev->query($sql);
|
||||
if (!$qry) {
|
||||
$message = $this->db_onedev->error();
|
||||
$message['qry'] = $this->db_onedev->last_query();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -69,13 +69,8 @@ class Re_px extends MY_Controller
|
||||
return array(0,"");
|
||||
}
|
||||
function get_normal_value($methodeID, $natTestID, $sexID, $ageInDay ) {
|
||||
$sql = "select fn_sampling_get_normal($methodeID, $natTestID, $sexID, $ageInDay) as normalValueID";
|
||||
$qry = $this->db->query($sql);
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) return $rows[0]["normalValueID"];
|
||||
}
|
||||
return 0;
|
||||
$this->load->library('ibl_sampling_normal');
|
||||
return $this->ibl_sampling_normal->get_normal_value_id($methodeID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
function fn_fix_normal($order_id) {
|
||||
|
||||
|
||||
@@ -69,13 +69,8 @@ class Re_px extends MY_Controller
|
||||
return array(0,"");
|
||||
}
|
||||
function get_normal_value($methodeID, $natTestID, $sexID, $ageInDay ) {
|
||||
$sql = "select fn_sampling_get_normal($methodeID, $natTestID, $sexID, $ageInDay) as normalValueID";
|
||||
$qry = $this->db->query($sql);
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) return $rows[0]["normalValueID"];
|
||||
}
|
||||
return 0;
|
||||
$this->load->library('ibl_sampling_normal');
|
||||
return $this->ibl_sampling_normal->get_normal_value_id($methodeID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
function fn_fix_normal($order_id) {
|
||||
$sql = "select
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -69,13 +69,8 @@ class Re_px extends MY_Controller
|
||||
return array(0,"");
|
||||
}
|
||||
function get_normal_value($methodeID, $natTestID, $sexID, $ageInDay ) {
|
||||
$sql = "select fn_sampling_get_normal($methodeID, $natTestID, $sexID, $ageInDay) as normalValueID";
|
||||
$qry = $this->db->query($sql);
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) return $rows[0]["normalValueID"];
|
||||
}
|
||||
return 0;
|
||||
$this->load->library('ibl_sampling_normal');
|
||||
return $this->ibl_sampling_normal->get_normal_value_id($methodeID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
function fn_fix_normal($order_id) {
|
||||
$sql = "select
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -440,59 +440,63 @@ class Rv_patient extends MY_Controller
|
||||
foreach ($rows['groups'] as $k => $v) {
|
||||
$ready_print = $v['ready_print'];
|
||||
$gn = $v['group_name'];
|
||||
|
||||
// MAPPING GROUP NAME KE REPORT CODE
|
||||
|
||||
$report_codes = $this->get_report_codes_by_group($gn);
|
||||
|
||||
|
||||
if ($report_codes) {
|
||||
// Gunakan database untuk ambil report name
|
||||
$rpt = $this->get_report_name_from_db($report_codes['P'], $ready_print);
|
||||
$e_rpt = $this->get_report_name_from_db($report_codes['E'], $ready_print);
|
||||
$rptqrcode = isset($report_codes['Q']) ? $this->get_report_name_from_db($report_codes['Q'], $ready_print) : '';
|
||||
|
||||
// Jika QR tidak ada, gunakan P
|
||||
if (empty($rptqrcode)) {
|
||||
$rptqrcode = $rpt;
|
||||
}
|
||||
$rpt_code = $ready_print == 'Y' ? $report_codes['P'] : ($report_codes['NP'] ?? $report_codes['P']);
|
||||
$e_rpt_code = $ready_print == 'Y' ? ($report_codes['E'] ?? $report_codes['P']) : ($report_codes['NE'] ?? $report_codes['NP'] ?? $report_codes['E'] ?? $report_codes['P']);
|
||||
$rptq_code = $ready_print == 'Y' ? ($report_codes['Q'] ?? $report_codes['P']) : ($report_codes['NQ'] ?? $report_codes['NP'] ?? $report_codes['P']);
|
||||
|
||||
$rpt = $this->get_report_name_from_code($rpt_code);
|
||||
$e_rpt = $this->get_report_name_from_code($e_rpt_code);
|
||||
$rptqrcode = $this->get_report_name_from_code($rptq_code);
|
||||
if (empty($rptqrcode)) $rptqrcode = $rpt;
|
||||
} else {
|
||||
// FALLBACK untuk group yang belum ada di database
|
||||
$rpt = $this->get_fallback_report($gn, 'P', $ready_print);
|
||||
$e_rpt = $this->get_fallback_report($gn, 'E', $ready_print);
|
||||
$rpt_code = $e_rpt_code = '';
|
||||
$rpt = $this->get_fallback_report($gn, 'P', $ready_print);
|
||||
$e_rpt = $this->get_fallback_report($gn, 'E', $ready_print);
|
||||
$rptqrcode = $this->get_fallback_report($gn, 'Q', $ready_print);
|
||||
if (empty($rptqrcode)) $rptqrcode = $rpt;
|
||||
}
|
||||
|
||||
|
||||
// LOGIC KHUSUS MIKRO
|
||||
if ($gn == 'Mikro') {
|
||||
$sql = "SELECT T_OrderDetailResult as result
|
||||
FROM t_orderdetail
|
||||
$sql = "SELECT T_OrderDetailResult as result
|
||||
FROM t_orderdetail
|
||||
JOIN t_test ON T_OrderDetailT_TestID = T_TestID AND T_TestIsResult = 'Y'
|
||||
JOIN group_resultdetail ON Group_ResultDetailT_TestID = T_OrderDetailT_TestID AND Group_ResultDetailIsActive = 'Y'
|
||||
JOIN group_result ON Group_ResultDetailGroup_ResultID = Group_ResultID AND Group_ResultFlagNonLab = 'N' AND
|
||||
JOIN group_result ON Group_ResultDetailGroup_ResultID = Group_ResultID AND Group_ResultFlagNonLab = 'N' AND
|
||||
Group_ResultName = 'Mikro'
|
||||
WHERE T_OrderDetailID = {$v['id']} AND T_OrderDetailIsActive = 'Y' LIMIT 1";
|
||||
|
||||
|
||||
$xresult = $this->db_smartone->query($sql)->row()->result;
|
||||
|
||||
|
||||
if ($xresult != 'Terlampir') {
|
||||
$rpt = $this->get_report_name_from_db('LAB-RESULT-P-01', $ready_print);
|
||||
$e_rpt = $this->get_report_name_from_db('LAB-RESULT-E-01', $ready_print);
|
||||
$rpt_code = $ready_print == 'Y' ? 'LAB-RESULT-P-01' : 'LAB-RESULT-NP-01';
|
||||
$e_rpt_code = $ready_print == 'Y' ? 'LAB-RESULT-P-02' : 'LAB-RESULT-NP-02';
|
||||
$rpt = $this->get_report_name_from_code($rpt_code);
|
||||
$e_rpt = $this->get_report_name_from_code($e_rpt_code);
|
||||
}
|
||||
|
||||
|
||||
if ($xresult == 'Terlampir' && $exist_lab == 'N') {
|
||||
$rows['groups'][$k]['group_name'] = 'Lampiran Mikro';
|
||||
$new_group = $rows['groups'][$k];
|
||||
$new_group['group_name'] = 'Mikro';
|
||||
$new_group['rpt'] = $this->get_report_name_from_db('LAB-RESULT-P-01', 'Y');
|
||||
$new_group['e_rpt'] = $this->get_report_name_from_db('LAB-RESULT-E-01', 'Y');
|
||||
$new_group['rptqrcode'] = $new_group['rpt'];
|
||||
$new_group['rpt_code'] = 'LAB-RESULT-P-01';
|
||||
$new_group['e_rpt_code'] = 'LAB-RESULT-P-02';
|
||||
$new_group['rpt'] = $this->get_report_name_from_code('LAB-RESULT-P-01');
|
||||
$new_group['e_rpt'] = $this->get_report_name_from_code('LAB-RESULT-P-02');
|
||||
$new_group['rptqrcode'] = $new_group['rpt'];
|
||||
array_push($rows['groups'], $new_group);
|
||||
}
|
||||
}
|
||||
|
||||
$rows['groups'][$k]['rpt'] = $rpt;
|
||||
$rows['groups'][$k]['e_rpt'] = $e_rpt;
|
||||
$rows['groups'][$k]['rptqrcode'] = $rptqrcode;
|
||||
|
||||
$rows['groups'][$k]['rpt'] = $rpt;
|
||||
$rows['groups'][$k]['e_rpt'] = $e_rpt;
|
||||
$rows['groups'][$k]['rptqrcode'] = $rptqrcode;
|
||||
$rows['groups'][$k]['rpt_code'] = $rpt_code;
|
||||
$rows['groups'][$k]['e_rpt_code'] = $e_rpt_code;
|
||||
}
|
||||
|
||||
$rows['groups'][0]['selected'] = 'Y';
|
||||
@@ -529,43 +533,55 @@ class Rv_patient extends MY_Controller
|
||||
}
|
||||
|
||||
private function get_report_codes_by_group($group_name)
|
||||
{
|
||||
$mapping = [
|
||||
'LAB' => ['P' => 'LAB-RESULT-P-01', 'E' => 'LAB-RESULT-E-01', 'Q' => 'LAB-RESULT-Q-01'],
|
||||
'LAB_EN' => ['P' => 'LAB-RESULT-EN-P-01', 'E' => 'LAB-RESULT-EN-E-01'],
|
||||
'Mikro_EN' => ['P' => 'LAB-RESULT-EN-P-01', 'E' => 'LAB-RESULT-EN-E-01'],
|
||||
'FNA' => ['P' => 'FNA-P-01', 'E' => 'FNA-E-01'],
|
||||
'Patologi Anatomi' => ['P' => 'PA-P-01', 'E' => 'PA-E-01'],
|
||||
'Papsmear' => ['P' => 'PAP-P-01', 'E' => 'PAP-E-01'],
|
||||
'Pap Smear (Liquid C Prep)' => ['P' => 'LCP-P-01', 'E' => 'LCP-E-01', 'Q' => 'LCP-Q-01'],
|
||||
'Pap Smear (Liquid C Prep)_EN' => ['P' => 'LCP-P-01', 'E' => 'LCP-E-01', 'Q' => 'LCP-Q-01'],
|
||||
'Papsmear_EN' => ['P' => 'LCP-P-01', 'E' => 'LCP-E-01', 'Q' => 'LCP-Q-01']
|
||||
];
|
||||
|
||||
return isset($mapping[$group_name]) ? $mapping[$group_name] : null;
|
||||
}
|
||||
{
|
||||
// P = siap cetak, NP = belum siap cetak, E = email siap, NE = email belum siap
|
||||
$mapping = [
|
||||
'LAB' => ['P' => 'LAB-RESULT-P-01', 'NP' => 'LAB-RESULT-NP-01', 'E' => 'LAB-RESULT-P-02', 'NE' => 'LAB-RESULT-NP-02'],
|
||||
'LAB_EN' => ['P' => 'LABEN-RESULT-P-01', 'NP' => 'LABEN-RESULT-NP-01', 'E' => 'LABEN-RESULT-P-02'],
|
||||
'Mikro' => ['P' => 'MIKRO-RESULT-P-01', 'NP' => 'MIKRO-RESULT-NP-01', 'E' => 'MIKRO-RESULT-P-02'],
|
||||
'Mikro_EN' => ['P' => 'MIKROEN-RESULT-P-01', 'NP' => 'MIKROEN-RESULT-NP-01', 'E' => 'MIKROEN-RESULT-P-02'],
|
||||
'FNA' => ['P' => 'FNA-RESULT-P-01', 'NP' => 'FNA-RESULT-NP-01', 'E' => 'FNA-RESULT-P-02'],
|
||||
'Patologi Anatomi' => ['P' => 'PA-RESULT-P-01', 'NP' => 'PA-RESULT-NP-01', 'E' => 'PA-RESULT-P-02'],
|
||||
'Papsmear' => ['P' => 'PAP-RESULT-P-01', 'NP' => 'PAP-RESULT-NP-01', 'E' => 'PAP-RESULT-P-02'],
|
||||
'Pap Smear (Liquid C Prep)' => ['P' => 'PAPLCP-RESULT-P-01', 'NP' => 'PAPLCP-RESULT-NP-01', 'E' => 'PAPLCP-RESULT-P-02'],
|
||||
'Pap Smear (Liquid C Prep)_EN' => ['P' => 'PAPLEN-RESULT-P-01', 'NP' => 'PAPLEN-RESULT-NP-01', 'E' => 'PAPLEN-RESULT-P-02'],
|
||||
'Papsmear_EN' => ['P' => 'PAPLEN-RESULT-P-01', 'NP' => 'PAPLEN-RESULT-NP-01', 'E' => 'PAPLEN-RESULT-P-02'],
|
||||
'Preparasi Sperma' => ['P' => 'PS-RESULT-P-01', 'NP' => 'PS-RESULT-NP-01', 'E' => 'PS-RESULT-P-02'],
|
||||
'dfi' => ['P' => 'DFI-RESULT-P-01', 'NP' => 'DFI-RESULT-NP-01', 'E' => 'DFI-RESULT-P-02'],
|
||||
'DFI' => ['P' => 'DFI-RESULT-P-01', 'NP' => 'DFI-RESULT-NP-01', 'E' => 'DFI-RESULT-P-02'],
|
||||
'Cytologi' => ['P' => 'CT-RESULT-P-01', 'NP' => 'CT-RESULT-NP-01', 'E' => 'CT-RESULT-P-02'],
|
||||
];
|
||||
|
||||
private function get_report_name_from_db($report_code, $ready_print = 'Y')
|
||||
{
|
||||
if (empty($report_code)) return '';
|
||||
|
||||
$sql = "SELECT Print_TransactionUrl FROM print_transaction WHERE Print_TransactionCode = ? LIMIT 1";
|
||||
$row = $this->db_smartone->query($sql, [$report_code])->row();
|
||||
|
||||
if (!$row) return '';
|
||||
|
||||
// Extract report name from URL
|
||||
$url = $row->Print_TransactionUrl;
|
||||
preg_match('/\/([^\/]+)\.rptdesign/', $url, $matches);
|
||||
$report_name = isset($matches[1]) ? $matches[1] : '';
|
||||
|
||||
// Tambahkan suffix jika belum ready print
|
||||
if ($ready_print != 'Y' && !empty($report_name)) {
|
||||
$report_name .= '_not_print';
|
||||
}
|
||||
|
||||
return $report_name;
|
||||
}
|
||||
return $mapping[$group_name] ?? null;
|
||||
}
|
||||
|
||||
private function get_report_name_from_code($report_code)
|
||||
{
|
||||
if (empty($report_code)) return '';
|
||||
$row = $this->db_smartone->query(
|
||||
"SELECT Print_TransactionUrl FROM print_transaction WHERE Print_TransactionCode = ? LIMIT 1",
|
||||
[$report_code]
|
||||
)->row();
|
||||
if (!$row) return '';
|
||||
preg_match('/\/([^\/]+)\.rptdesign/', $row->Print_TransactionUrl, $matches);
|
||||
return $matches[1] ?? '';
|
||||
}
|
||||
|
||||
private function get_report_name_from_db($report_code, $ready_print = 'Y')
|
||||
{
|
||||
if (empty($report_code)) return '';
|
||||
$row = $this->db_smartone->query(
|
||||
"SELECT Print_TransactionUrl FROM print_transaction WHERE Print_TransactionCode = ? LIMIT 1",
|
||||
[$report_code]
|
||||
)->row();
|
||||
if (!$row) return '';
|
||||
preg_match('/\/([^\/]+)\.rptdesign/', $row->Print_TransactionUrl, $matches);
|
||||
$report_name = $matches[1] ?? '';
|
||||
if ($ready_print != 'Y' && !empty($report_name)) {
|
||||
$report_name .= '_not_print';
|
||||
}
|
||||
return $report_name;
|
||||
}
|
||||
|
||||
private function get_fallback_report($group_name, $type, $ready_print)
|
||||
{
|
||||
@@ -790,6 +806,10 @@ private function get_fallback_report($group_name, $type, $ready_print)
|
||||
$url = "/birt/{$mode}?__report=report/onelab/{$folder}/{$rpt_name}.rptdesign&__format=pdf&username={$username}&PID={$order_id}&tm={$tm}";
|
||||
}
|
||||
|
||||
// Populate decrypt cache sebelum frontend buka URL ke BIRT
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
$this->ibl_patient_decrypt->pre_cache_and_get_url($url);
|
||||
|
||||
$this->sys_ok($url);
|
||||
}
|
||||
|
||||
@@ -871,6 +891,17 @@ private function get_fallback_report($group_name, $type, $ready_print)
|
||||
$final_url = str_replace($key, $value, $final_url);
|
||||
}
|
||||
|
||||
// Populate patient_print_cache agar sp_rpt_hasil_header baca DOB/name dari cache
|
||||
$order_id = intval($params['PT_OrderHeaderID'] ?? 0);
|
||||
if ($order_id <= 0) {
|
||||
parse_str(parse_url($final_url, PHP_URL_QUERY) ?? '', $_url_params);
|
||||
$order_id = intval($_url_params['PID'] ?? 0);
|
||||
}
|
||||
if ($order_id > 0) {
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
$this->ibl_patient_decrypt->populate_cache_by_order($order_id);
|
||||
}
|
||||
|
||||
$this->sys_ok([
|
||||
'status' => true,
|
||||
'url' => $final_url,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -99,17 +99,17 @@ class Rv_patient extends MY_Controller
|
||||
);
|
||||
exit;
|
||||
}
|
||||
$sql = "INSERT INTO mcu_resume_results(
|
||||
Mcu_ResumeResultsType,
|
||||
Mcu_ResumeResultsT_OrderHeaderID,
|
||||
Mcu_ResumeResultsGroupResultID,
|
||||
Mcu_ResumeResultsT_TestID,
|
||||
Mcu_ResumeResultsName,
|
||||
Mcu_ResumeResultsJSON,
|
||||
Mcu_ResumeResultsCreated,
|
||||
Mcu_ResumeResultsUserID)
|
||||
VALUES('KHUSUS',?,?,?,?,?,NOW(),?)";
|
||||
$qry = $this->db_smartone->query($sql, array($order_id, $groupResultID, 0, $groupResultName, $j_data_result_lab, $userID));
|
||||
$sql = "INSERT INTO mcu_resume_results(
|
||||
Mcu_ResumeResultsType,
|
||||
Mcu_ResumeResultsT_OrderHeaderID,
|
||||
Mcu_ResumeResultsGroupResultID,
|
||||
Mcu_ResumeResultsT_TestID,
|
||||
Mcu_ResumeResultsName,
|
||||
Mcu_ResumeResultsJSON,
|
||||
Mcu_ResumeResultsCreated,
|
||||
Mcu_ResumeResultsUserID)
|
||||
VALUES('KHUSUS',?,?,?,?,?,NOW(),?)";
|
||||
$qry = $this->db_smartone->query($sql, array($order_id, $groupResultID, 0, $groupResultName, $j_data_result_lab, $userID));
|
||||
if (!$qry) {
|
||||
echo json_encode(
|
||||
array("status" => "ERR", "message" => "Error: insert mcu results")
|
||||
@@ -183,7 +183,8 @@ class Rv_patient extends MY_Controller
|
||||
$sql_get = "SELECT T_OrderHeaderGroupResultID,
|
||||
T_OrderHeaderGroupResultGroup_ResultID,
|
||||
T_OrderHeaderGroupResultT_TestID,
|
||||
T_OrderHeaderGroupResultGroup_ResultName
|
||||
T_OrderHeaderGroupResultGroup_ResultName,
|
||||
Group_ResultName
|
||||
FROM t_orderheader_group_result
|
||||
JOIN group_result ON T_OrderHeaderGroupResultGroup_ResultID = Group_ResultID
|
||||
AND Group_ResultFlagNonLab = 'N'
|
||||
@@ -196,25 +197,12 @@ class Rv_patient extends MY_Controller
|
||||
}
|
||||
$data = $qry_get->result_array();
|
||||
|
||||
$sql_url = "SELECT Print_TransactionID,
|
||||
Print_TransactionType,
|
||||
Print_TransactionCode,
|
||||
Print_TransactionName,
|
||||
Print_TransactionUrl,
|
||||
Print_TransactionUrlWatermark,
|
||||
Print_TransactionUrlEletronic,
|
||||
Print_TransactionParams
|
||||
FROM print_transaction
|
||||
WHERE Print_TransactionCode = 'LAB-RESULT-P-01'
|
||||
LIMIT 1";
|
||||
$qry_url = $this->db_smartone->query($sql_url);
|
||||
if (!$qry_url) {
|
||||
$this->sys_error_db('error print_transaction', $this->db_smartone);
|
||||
exit;
|
||||
}
|
||||
$rst_url = $qry_url->row_array();
|
||||
$template_url = $rst_url['Print_TransactionUrlWatermark'];
|
||||
$template_url_electronic = isset($rst_url['Print_TransactionUrlEletronic']) ? $rst_url['Print_TransactionUrlEletronic'] : '';
|
||||
// mapping test kode print
|
||||
$map = [
|
||||
'LAB' => 'LAB-RESULT-P-01',
|
||||
'Papsmear' => 'PAP-P-01',
|
||||
'FNA' => 'FNA-P-01'
|
||||
];
|
||||
|
||||
$sql_branch = "SELECT M_BranchID,
|
||||
M_BranchCode,
|
||||
@@ -228,42 +216,8 @@ class Rv_patient extends MY_Controller
|
||||
$this->sys_error_db('error m_branch', $this->db_smartone);
|
||||
exit;
|
||||
}
|
||||
$branch = $qry_branch->row_array();
|
||||
$base = "http://localhost/";
|
||||
|
||||
// Tambah base_url di depan
|
||||
$full_url = $base . ltrim($template_url, '/');
|
||||
|
||||
// Ganti nama report jadi _watermark
|
||||
$full_url = str_replace(
|
||||
'rpt_test.rptdesign',
|
||||
'rpt_test_watermark.rptdesign',
|
||||
$full_url
|
||||
);
|
||||
|
||||
// Ganti parameter
|
||||
$full_url = str_replace(
|
||||
['PUsername', 'PT_OrderHeaderID', 'TS'],
|
||||
[
|
||||
trim($this->sys_user['M_UserUsername']),
|
||||
$order_id,
|
||||
time()
|
||||
],
|
||||
$full_url
|
||||
);
|
||||
$full_url_electronic = '';
|
||||
if ($template_url_electronic !== '') {
|
||||
$full_url_electronic = $base . ltrim($template_url_electronic, '/');
|
||||
$full_url_electronic = str_replace(
|
||||
['PUsername', 'PT_OrderHeaderID', 'TS'],
|
||||
[
|
||||
trim($this->sys_user['M_UserUsername']),
|
||||
$order_id,
|
||||
time()
|
||||
],
|
||||
$full_url_electronic
|
||||
);
|
||||
}
|
||||
$branch = $qry_branch->row_array();
|
||||
$base = "http://localhost/";
|
||||
|
||||
// ambil endpoint URL dari DB
|
||||
$sql_url = "SELECT QR_ReportEndpointID,
|
||||
@@ -288,6 +242,65 @@ class Rv_patient extends MY_Controller
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
|
||||
$group_result_name = $value['Group_ResultName'];
|
||||
|
||||
// kalau tidak ada di mapping skip
|
||||
if (!isset($map[$group_result_name])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$printCode = $map[$group_result_name];
|
||||
|
||||
// ambil URL print
|
||||
$sql_url = "SELECT Print_TransactionUrlWatermark, Print_TransactionUrlEletronic
|
||||
FROM print_transaction
|
||||
WHERE Print_TransactionCode = ?
|
||||
LIMIT 1";
|
||||
$qry_url = $this->db_onedev->query($sql_url, [$printCode]);
|
||||
if (!$qry_url) {
|
||||
$this->sys_error_db('error print_transaction', $this->db_onedev);
|
||||
exit;
|
||||
}
|
||||
|
||||
$rst_url = $qry_url->row_array();
|
||||
$template_url = $rst_url['Print_TransactionUrlWatermark'];
|
||||
$template_url_electronic = isset($rst_url['Print_TransactionUrlEletronic']) ? $rst_url['Print_TransactionUrlEletronic'] : '';
|
||||
|
||||
// Tambah base_url di depan
|
||||
$full_url = $base . ltrim($template_url, '/');
|
||||
|
||||
// ubah semua report jadi versi watermark
|
||||
$full_url = str_replace(
|
||||
'.rptdesign',
|
||||
'_watermark.rptdesign',
|
||||
$full_url
|
||||
);
|
||||
|
||||
// Ganti parameter
|
||||
$full_url = str_replace(
|
||||
['PUsername', 'PT_OrderHeaderID', 'TS'],
|
||||
[
|
||||
trim($this->sys_user['M_UserUsername']),
|
||||
$order_id,
|
||||
time()
|
||||
],
|
||||
$full_url
|
||||
);
|
||||
|
||||
$full_url_electronic = '';
|
||||
if ($template_url_electronic !== '') {
|
||||
$full_url_electronic = $base . ltrim($template_url_electronic, '/');
|
||||
$full_url_electronic = str_replace(
|
||||
['PUsername', 'PT_OrderHeaderID', 'TS'],
|
||||
[
|
||||
trim($this->sys_user['M_UserUsername']),
|
||||
$order_id,
|
||||
time()
|
||||
],
|
||||
$full_url_electronic
|
||||
);
|
||||
}
|
||||
|
||||
// cek sudah ada atau belum
|
||||
$sql_check = "SELECT QR_PrintOutID, QR_PrintOutUploadStatus
|
||||
FROM qr_printout
|
||||
@@ -308,19 +321,19 @@ class Rv_patient extends MY_Controller
|
||||
$params = [
|
||||
'orderHeaderID' => $order_id,
|
||||
'groupResultID' => $value['T_OrderHeaderGroupResultGroup_ResultID'],
|
||||
'testID' => $value['T_OrderHeaderGroupResultT_TestID'],
|
||||
'groupResultName' => $value['T_OrderHeaderGroupResultGroup_ResultName'],
|
||||
'verifyBaseURL' => $verify_url,
|
||||
'QR_PrintOutReportURL' => $full_url,
|
||||
'QR_PrintOutReportURLElectronic' => $full_url_electronic,
|
||||
'createdByUserID' => $userID
|
||||
];
|
||||
'testID' => $value['T_OrderHeaderGroupResultT_TestID'],
|
||||
'groupResultName' => $value['T_OrderHeaderGroupResultGroup_ResultName'],
|
||||
'verifyBaseURL' => $verify_url,
|
||||
'QR_PrintOutReportURL' => $full_url,
|
||||
'QR_PrintOutReportURLElectronic' => $full_url_electronic,
|
||||
'createdByUserID' => $userID
|
||||
];
|
||||
|
||||
$this->generateqrreport->saveQRPrintout($params);
|
||||
}
|
||||
}
|
||||
|
||||
echo $this->sys_ok(array("status" => "OK"));
|
||||
$this->sys_ok(array("status" => "OK"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,17 +382,17 @@ class Rv_patient extends MY_Controller
|
||||
|
||||
// Insert new record
|
||||
$j_data_result = json_encode($rows_result);
|
||||
$sql = "INSERT INTO mcu_resume_results(
|
||||
Mcu_ResumeResultsType,
|
||||
Mcu_ResumeResultsT_OrderHeaderID,
|
||||
Mcu_ResumeResultsGroupResultID,
|
||||
Mcu_ResumeResultsT_TestID,
|
||||
Mcu_ResumeResultsName,
|
||||
Mcu_ResumeResultsJSON,
|
||||
Mcu_ResumeResultsCreated,
|
||||
Mcu_ResumeResultsUserID)
|
||||
VALUES('KHUSUS',?,?,?,?,?,NOW(),?)";
|
||||
$qry = $this->db_smartone->query($sql, array($order_id, $groupResultID, 0, $groupResultName, $j_data_result, $userID));
|
||||
$sql = "INSERT INTO mcu_resume_results(
|
||||
Mcu_ResumeResultsType,
|
||||
Mcu_ResumeResultsT_OrderHeaderID,
|
||||
Mcu_ResumeResultsGroupResultID,
|
||||
Mcu_ResumeResultsT_TestID,
|
||||
Mcu_ResumeResultsName,
|
||||
Mcu_ResumeResultsJSON,
|
||||
Mcu_ResumeResultsCreated,
|
||||
Mcu_ResumeResultsUserID)
|
||||
VALUES('KHUSUS',?,?,?,?,?,NOW(),?)";
|
||||
$qry = $this->db_smartone->query($sql, array($order_id, $groupResultID, 0, $groupResultName, $j_data_result, $userID));
|
||||
if (!$qry) {
|
||||
echo json_encode(
|
||||
array("status" => "ERR", "message" => "Error: insert into mcu result 2")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@ class Patient extends MY_Controller
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('Nonlabtemplate');
|
||||
$this->load->library('ibl_encryptor');
|
||||
$this->IP_SOCKET_IO = "127.0.0.1";
|
||||
}
|
||||
|
||||
@@ -127,16 +128,16 @@ class Patient extends MY_Controller
|
||||
SELECT DATE_FORMAT(T_OrderHeaderDate,'%d-%m-%Y %H:%i') as order_date,
|
||||
T_OrderHeaderLabNumber as labnumber,
|
||||
T_OrderHeaderM_PatientAge as patient_age,
|
||||
M_PatientName as patient_name,
|
||||
M_PatientName_enc as patient_name_enc,
|
||||
M_PatientNoReg as noreg,
|
||||
M_SexName as gender,
|
||||
DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as dob,
|
||||
M_PatientDOB_enc as dob_enc, M_PatientDOB as dob_raw,
|
||||
M_PatientJob as job,
|
||||
M_PatientPosisi as posisi,
|
||||
IF(M_PatientDivisi = '','-',M_PatientDivisi) as divisi,
|
||||
M_PatientHp as hp,
|
||||
M_PatientNIP as nip,
|
||||
M_PatientEmail as email,
|
||||
M_PatientHP_enc as hp_enc,
|
||||
M_PatientNIP_enc as nip_enc,
|
||||
M_PatientEmail_enc as email_enc,
|
||||
M_PatientPhoto as photo,
|
||||
T_OrderHeaderID as xid,
|
||||
0 as testid,
|
||||
@@ -208,6 +209,15 @@ class Patient extends MY_Controller
|
||||
}
|
||||
|
||||
$data_patient = $query->row_array();
|
||||
if ($data_patient) {
|
||||
$enc = $this->ibl_encryptor;
|
||||
$data_patient['patient_name'] = $enc->decrypt($data_patient['patient_name_enc'] ?? '') ?? '';
|
||||
$data_patient['hp'] = $enc->decrypt($data_patient['hp_enc'] ?? '') ?? '';
|
||||
$data_patient['email'] = $enc->decrypt($data_patient['email_enc'] ?? '') ?? '';
|
||||
$data_patient['nip'] = $enc->decrypt($data_patient['nip_enc'] ?? '') ?? '';
|
||||
$data_patient['dob'] = $enc->decrypt($data_patient['dob_enc'] ?? '') ?? date('d-m-Y', strtotime($data_patient['dob_raw'] ?? 'now'));
|
||||
unset($data_patient['patient_name_enc'], $data_patient['hp_enc'], $data_patient['email_enc'], $data_patient['nip_enc'], $data_patient['dob_enc'], $data_patient['dob_raw']);
|
||||
}
|
||||
if (intval($stationid) == 11 || intval($stationid) == 35) {
|
||||
$sql = "SELECT
|
||||
T_SamplingAdditionalFisikBBTBID,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@ class Samplingcall extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database("onedev", true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
// $this->IP_SOCKET_IO = "devone.aplikasi.web.id";
|
||||
$this->IP_SOCKET_IO = "localhost";
|
||||
}
|
||||
@@ -181,17 +182,17 @@ class Samplingcall extends MY_Controller
|
||||
$sql_where = "WHERE T_OrderHeaderIsActive = 'Y' AND ( DATE(T_OrderHeaderAddonIsComingDate) = '{$xdate}' OR DATE(T_OrderHeaderDate) = '{$xdate}' ) {$where_status}";
|
||||
|
||||
//$sql_param = array();
|
||||
if ($name != "") {
|
||||
if ($sql_where != "") {
|
||||
$sql_where .= " and ";
|
||||
if ($name != "" && mb_strlen(trim($name)) >= 3) {
|
||||
$toks = $this->ibl_encryptor->query_tokens($name);
|
||||
foreach ($toks as $tok) {
|
||||
$tok_esc = $this->db_onedev->escape_str($tok);
|
||||
$sql_where .= " AND JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
$sql_where .= " M_PatientName like '%$name%' ";
|
||||
//$sql_param[] = "%$nama%";
|
||||
}
|
||||
$filter_search = '';
|
||||
if ($nolab != "") {
|
||||
|
||||
$filter_search = "WHERE ( T_OrderHeaderLabNumber like '%$nolab%' OR M_PatientName like '%$nolab%' OR T_OrderHeaderLabNumberExt like '%$nolab%' )";
|
||||
// Hanya cari by nomor lab — nama pasien sudah dimasking
|
||||
$filter_search = "WHERE ( T_OrderHeaderLabNumber like '%$nolab%' OR T_OrderHeaderLabNumberExt like '%$nolab%' )";
|
||||
}
|
||||
|
||||
if ($search != '') {
|
||||
@@ -207,11 +208,10 @@ class Samplingcall extends MY_Controller
|
||||
IFNULL(M_PatientPhotoThumb,'') as M_PatientPhotoThumb,
|
||||
M_SexName as M_SexName,
|
||||
M_TitleName as M_TitleName,
|
||||
CONCAT(M_TitleName,' ',M_PatientName) as patient_fullname,
|
||||
M_PatientName as M_PatientName,
|
||||
M_PatientName_enc, M_PatientDOB_enc,
|
||||
M_CompanyName,
|
||||
fn_sampling_queue_status_name(T_OrderHeaderID,T_SampleStationID) as status,
|
||||
DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as patient_dob,
|
||||
M_PatientDOB as patient_dob_raw,
|
||||
fn_sampling_queue_status_id(T_OrderHeaderID,T_SampleStationID) as statusid, T_SampleStationID, T_SampleTypeID,
|
||||
T_SampleStationID as stationid,
|
||||
fn_fo_get_laststatus(T_OrderHeaderID) as last_status_fo,
|
||||
@@ -257,13 +257,17 @@ class Samplingcall extends MY_Controller
|
||||
$query = $this->db_onedev->query($sql);
|
||||
//echo $this->db_onedev->last_query();
|
||||
$rows = $query->result_array();
|
||||
//$rst = array_merge($rows_cito,$rows_not_cito);
|
||||
//$this->_add_address($rows);
|
||||
if($rows){
|
||||
if ($rows) {
|
||||
$enc = $this->ibl_encryptor;
|
||||
$count_arr = count($rows);
|
||||
foreach ($rows as $key => $value) {
|
||||
if($key+1 != $count_arr){
|
||||
$rows[$key]['skip_time'] = $rows[$key+1]['antri_time'];
|
||||
$name = $enc->decrypt($value['M_PatientName_enc']) ?? '';
|
||||
$rows[$key]['M_PatientName'] = $name;
|
||||
$rows[$key]['patient_fullname'] = trim(($value['M_TitleName'] ? $value['M_TitleName'] . ' ' : '') . $name);
|
||||
$rows[$key]['patient_dob'] = $enc->decrypt($value['M_PatientDOB_enc']) ?? date('d-m-Y', strtotime($value['patient_dob_raw']));
|
||||
unset($rows[$key]['M_PatientName_enc'], $rows[$key]['M_PatientDOB_enc'], $rows[$key]['patient_dob_raw']);
|
||||
if ($key + 1 != $count_arr) {
|
||||
$rows[$key]['skip_time'] = $rows[$key + 1]['antri_time'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,9 +404,9 @@ class Samplingcall extends MY_Controller
|
||||
|
||||
$sql_where = "WHERE T_OrderHeaderLabNumber LIKE '{$search}' AND T_OrderHeaderIsActive = 'Y' {$where_status}";
|
||||
$rows = [];
|
||||
$query = "SELECT t_orderheader.*,m_patient.*, IFNULL(M_PatientPhoto,'') as M_PatientPhotoThumb,
|
||||
M_SexName, M_TitleName, CONCAT(M_TitleName,' ',M_PatientName) as patient_fullname, M_CompanyName,
|
||||
IF(ISNULL(T_SamplingQueueLastStatusID), 'New',T_SamplingQueueStatusName) as status, DATE_FORMAT(M_PatientDOB,'%d-%m-%Y') as patient_dob,
|
||||
$query = "SELECT t_orderheader.*, IFNULL(M_PatientPhoto,'') as M_PatientPhotoThumb,
|
||||
M_SexName, M_TitleName, M_PatientName_enc, M_PatientDOB_enc, M_PatientDOB as patient_dob_raw, M_CompanyName,
|
||||
IF(ISNULL(T_SamplingQueueLastStatusID), 'New',T_SamplingQueueStatusName) as status,
|
||||
IF(ISNULL(T_SamplingQueueLastStatusID), 0,T_SamplingQueueLastStatusT_SamplingQueueStatusID) as statusid, T_SampleStationID, T_SampleTypeID,
|
||||
{$stationid} as stationid,
|
||||
fn_global_check_is_cito(T_OrderHeaderID) as iscito
|
||||
@@ -431,12 +435,16 @@ class Samplingcall extends MY_Controller
|
||||
ORDER BY T_OrderHeaderID DESC
|
||||
limit 1";
|
||||
//echo $query;
|
||||
$rows = $this->db_onedev->query($query)->row();
|
||||
|
||||
$result = array(
|
||||
"total" => count($rows),
|
||||
"records" => $rows,
|
||||
);
|
||||
$row = $this->db_onedev->query($query)->row_array();
|
||||
if ($row) {
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($row['M_PatientName_enc']) ?? '';
|
||||
$row['M_PatientName'] = $name;
|
||||
$row['patient_fullname'] = trim(($row['M_TitleName'] ? $row['M_TitleName'] . ' ' : '') . $name);
|
||||
$row['patient_dob'] = $enc->decrypt($row['M_PatientDOB_enc']) ?? date('d-m-Y', strtotime($row['patient_dob_raw']));
|
||||
unset($row['M_PatientName_enc'], $row['M_PatientDOB_enc'], $row['patient_dob_raw']);
|
||||
}
|
||||
$result = array("total" => 1, "records" => $row);
|
||||
$this->sys_ok($result);
|
||||
exit;
|
||||
}
|
||||
@@ -562,7 +570,7 @@ class Samplingcall extends MY_Controller
|
||||
$userid = $prm['staff']['userid'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$sql = "SELECT T_OrderHeaderQueue AS queueNumber ,
|
||||
M_LocationID AS locationID,
|
||||
@@ -578,7 +586,7 @@ class Samplingcall extends MY_Controller
|
||||
$splitedLocationName = explode(" ", $locationName);
|
||||
$locationName = $splitedLocationName[0];
|
||||
|
||||
|
||||
|
||||
|
||||
if ($prm['act'] == 'call') {
|
||||
$sql = "SELECT T_SamplingQueueLastStatusID, T_SamplingQueueStatusName, T_SampleStationName, T_SampleStationID, T_SampleStationIsNonLab
|
||||
@@ -1002,18 +1010,18 @@ class Samplingcall extends MY_Controller
|
||||
$rows = $this->db_onedev->query($query);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if ($status_call['status'] == 'NOTCALL') {
|
||||
$rst_data = $status_call;
|
||||
}
|
||||
|
||||
if ($prm['act'] == 'skip' || $status_call['status'] == 'NOTCALL') {
|
||||
$skip_time = date('Y-m-d H:i:s', strtotime($prm['skiptime'])+10);
|
||||
$skip_time = date('Y-m-d H:i:s', strtotime($prm['skiptime']) + 10);
|
||||
$sql = "UPDATE antrian_samplestation SET AntrianSampleStationIsActive = 'N'
|
||||
WHERE
|
||||
AntrianSampleStationT_OrderLocationID = ?";
|
||||
$query = $this->db_onedev->query($sql,array($prm['orderlocationid']));
|
||||
$query = $this->db_onedev->query($sql, array($prm['orderlocationid']));
|
||||
/* start dipaggil 3 kali skpi ururtan jd ke bawah */
|
||||
/*$sql = "SELECT COUNT(*) as x_count
|
||||
FROM antrian_samplestation
|
||||
@@ -1037,8 +1045,7 @@ class Samplingcall extends MY_Controller
|
||||
VALUES(
|
||||
?,?,?,NOW()
|
||||
)";
|
||||
$query = $this->db_onedev->query($sql,array($prm['orderlocationid'],$skip_time,$userid));
|
||||
|
||||
$query = $this->db_onedev->query($sql, array($prm['orderlocationid'], $skip_time, $userid));
|
||||
}
|
||||
|
||||
if (intval($next_status) == 1) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,9 +8,35 @@ class Preregister extends MY_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->library('ibl_encryptor');
|
||||
// $this->db = $this->load->database("cpone", true);
|
||||
}
|
||||
|
||||
private function _mask_name($v) {
|
||||
if (!$v) return $v;
|
||||
$v = trim($v);
|
||||
$words = preg_split('/\s+/', $v);
|
||||
if (count($words) === 1) {
|
||||
$l = mb_strlen($v, 'UTF-8');
|
||||
if ($l <= 2) return $v;
|
||||
return mb_substr($v, 0, 2, 'UTF-8') . str_repeat('*', $l - 2);
|
||||
}
|
||||
$first = $words[0];
|
||||
$rest = array_slice($words, 1);
|
||||
$masked = array_map(function($w) {
|
||||
if (!$w) return '';
|
||||
$init = mb_substr($w, 0, 1, 'UTF-8');
|
||||
return $init . str_repeat('*', max(3, mb_strlen($w, 'UTF-8') - 1));
|
||||
}, $rest);
|
||||
return $first . ' ' . implode(' ', $masked);
|
||||
}
|
||||
private function _mask_phone($v) { if (!$v) return $v; $d=preg_replace('/[^0-9]/','',trim($v)); $l=strlen($d); if($l<=4) return '****'; if($l<=8) return substr($d,0,4).str_repeat('*',$l-4); return substr($d,0,4).str_repeat('*',$l-7).substr($d,-3); }
|
||||
private function _mask_email($v) { if (!$v||strpos($v,'@')===false) return $v; [$loc,$dom]=explode('@',$v,2); return mb_substr($loc,0,min(2,mb_strlen($loc,'UTF-8')),'UTF-8').'***@'.$dom; }
|
||||
private function _mask_short($v) { if (!$v) return $v; $v=trim($v); $l=mb_strlen($v,'UTF-8'); if($l<=2) return '***'; return mb_substr($v,0,2,'UTF-8').'***'; }
|
||||
private function _mask_id($v) { if (!$v) return $v; $v=trim($v); $l=strlen($v); if($l<=4) return '****'; return substr($v,0,4).str_repeat('*',max(3,$l-6)).($l>6?substr($v,-2):''); }
|
||||
private function _mask_address($v) { if (!$v) return $v; $v=trim($v); $l=mb_strlen($v,'UTF-8'); if($l<=5) return '***'; return mb_substr($v,0,5,'UTF-8').'***'; }
|
||||
private function _mask_dob($v) { if (!$v) return $v; $p=explode('-',$v); return (count($p)===3) ? '**-**-'.$p[2] : '****-**-**'; }
|
||||
|
||||
public function index()
|
||||
{
|
||||
// $cek = $this->db->query("select database() as current_db")->result();
|
||||
@@ -59,8 +85,8 @@ class Preregister extends MY_Controller
|
||||
}
|
||||
}
|
||||
|
||||
function cekKTP($nik, $tanggal, $bulan, $tahun)
|
||||
{
|
||||
function cekKTP($nik, $tanggal, $bulan, $tahun)
|
||||
{
|
||||
if (strlen($nik) != 16) {
|
||||
return false;
|
||||
}
|
||||
@@ -88,30 +114,30 @@ class Preregister extends MY_Controller
|
||||
return false;
|
||||
}
|
||||
//setelah berhasil melewati rintangan, berarti nomornya valid (tidak 100% valid)
|
||||
return true;
|
||||
}
|
||||
|
||||
function normalize_schedule_date($rawDate)
|
||||
{
|
||||
$rawDate = trim((string) $rawDate);
|
||||
if ($rawDate === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$formats = array('d-m-Y', 'Y-m-d', 'd/m/Y', 'Y/m/d');
|
||||
foreach ($formats as $format) {
|
||||
$dt = DateTime::createFromFormat($format, $rawDate);
|
||||
if ($dt && $dt->format($format) === $rawDate) {
|
||||
return $dt->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
$timestamp = strtotime($rawDate);
|
||||
if ($timestamp === false) {
|
||||
return '';
|
||||
}
|
||||
return date('Y-m-d', $timestamp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function normalize_schedule_date($rawDate)
|
||||
{
|
||||
$rawDate = trim((string) $rawDate);
|
||||
if ($rawDate === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$formats = array('d-m-Y', 'Y-m-d', 'd/m/Y', 'Y/m/d');
|
||||
foreach ($formats as $format) {
|
||||
$dt = DateTime::createFromFormat($format, $rawDate);
|
||||
if ($dt && $dt->format($format) === $rawDate) {
|
||||
return $dt->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
$timestamp = strtotime($rawDate);
|
||||
if ($timestamp === false) {
|
||||
return '';
|
||||
}
|
||||
return date('Y-m-d', $timestamp);
|
||||
}
|
||||
|
||||
function savecsv()
|
||||
{
|
||||
@@ -149,7 +175,7 @@ class Preregister extends MY_Controller
|
||||
|
||||
$exist_patients_arr = [];
|
||||
$exist_pat = [];
|
||||
foreach ($datas as $k => $v) {
|
||||
foreach ($datas as $k => $v) {
|
||||
$timestamp = strtotime($v['TANGGAL_LAHIR']);
|
||||
$pdob = date('Y-m-d', $timestamp);
|
||||
$v['NAMA'] = trim(str_replace("'", "\\'", $v['NAMA']));
|
||||
@@ -205,15 +231,16 @@ class Preregister extends MY_Controller
|
||||
|
||||
|
||||
if ($exist_r) {
|
||||
$enc_csv = $this->ibl_encryptor;
|
||||
$patient_id = $exist_r["M_PatientID"];
|
||||
$v['NAMA'] = addslashes($exist_r["M_PatientName"]);
|
||||
$v['NAMA'] = $enc_csv->decrypt($exist_r['M_PatientName_enc'] ?? '') ?: $exist_r["M_PatientName"];
|
||||
$pdob = date('Y-m-d', strtotime($exist_r['M_PatientDOB']));
|
||||
$title_id = $exist_r["M_PatientM_TitleID"];
|
||||
$sex_id = $exist_r["M_PatientM_SexID"];
|
||||
$religion_id = $exist_r["M_PatientReligionCode"];
|
||||
$v['NIK'] = $v['NIK'] ? $v['NIK'] : $exist_r["M_PatientNIK"];
|
||||
$v['EMAIL'] = $v['EMAIL'] ? $v['EMAIL'] : $exist_r["M_PatientEmail"];
|
||||
$v['HP'] = $v['HP'] ? $v['HP'] : $exist_r["M_PatientHP"];
|
||||
$v['KTP'] = $v['KTP'] ? $v['KTP'] : ($enc_csv->decrypt($exist_r['M_PatientIDNumber_enc'] ?? '') ?: '');
|
||||
$v['EMAIL'] = $v['EMAIL'] ? $v['EMAIL'] : ($enc_csv->decrypt($exist_r['M_PatientEmail_enc'] ?? '') ?: '');
|
||||
$v['HP'] = $v['HP'] ? $v['HP'] : ($enc_csv->decrypt($exist_r['M_PatientHP_enc'] ?? '') ?: '');
|
||||
$v['JOB'] = $v['JOB'] ? addslashes($v['JOB']) : addslashes($exist_r["M_PatientJob"]);
|
||||
$v['POSISI'] = $v['POSISI'] ? addslashes($v['POSISI']) : addslashes($exist_r["M_PatientPosisi"]);
|
||||
$v['DIVISI'] = $v['DIVISI'] ? addslashes($v['DIVISI']) : addslashes($exist_r["M_PatientDivisi"]);
|
||||
@@ -302,11 +329,17 @@ class Preregister extends MY_Controller
|
||||
$this->sys_error("select mcu_preregister_patients : " . $last_qry);
|
||||
exit;
|
||||
}
|
||||
$exist_r = $qry_pre->result_array();
|
||||
$preregister_patient_id = 0;
|
||||
|
||||
if (count($exist_r) == 0) {
|
||||
$query = " INSERT INTO mcu_preregister_patients (
|
||||
$exist_r = $qry_pre->result_array();
|
||||
$preregister_patient_id = 0;
|
||||
|
||||
if (count($exist_r) == 0) {
|
||||
$m_nama = $this->db->escape_str($this->_mask_name($v['NAMA']));
|
||||
$m_ktp = $this->_mask_id($v['KTP']);
|
||||
$m_nip = $this->_mask_id($v['NIP']);
|
||||
$m_email = $this->_mask_email($v['EMAIL']);
|
||||
$m_hp = $this->_mask_phone($v['HP']);
|
||||
$m_dob = $this->_mask_dob(date('d-m-Y', strtotime($pdob)));
|
||||
$query = " INSERT INTO mcu_preregister_patients (
|
||||
Mcu_PreregisterPatientsMgm_McuID,
|
||||
Mcu_PreregisterPatientsCompanyNumber,
|
||||
Mcu_PreregisterPatientsNIP,
|
||||
@@ -331,16 +364,16 @@ class Preregister extends MY_Controller
|
||||
VALUES(
|
||||
'{$prm['xid']}',
|
||||
'{$rowcor["M_CompanyNumber"]}',
|
||||
'{$v['NIP']}',
|
||||
'{$v['KTP']}',
|
||||
'{$m_nip}',
|
||||
'{$m_ktp}',
|
||||
'{$patient_id}',
|
||||
'{$title_id}',
|
||||
'{$v['NAMA']}',
|
||||
'{$m_nama}',
|
||||
{$sex_id},
|
||||
'{$pdob}',
|
||||
'{$m_dob}',
|
||||
'{$v['JOB']}',
|
||||
'{$v['EMAIL']}',
|
||||
'{$v['HP']}',
|
||||
'{$m_email}',
|
||||
'{$m_hp}',
|
||||
'{$v['POSISI']}',
|
||||
'{$v['DIVISI']}',
|
||||
'{$v['LOKASI']}',
|
||||
@@ -360,31 +393,34 @@ class Preregister extends MY_Controller
|
||||
$this->sys_error("insert mcu_preregister_patients : " . $last_qry);
|
||||
exit;
|
||||
}
|
||||
if ($rows) {
|
||||
$last_id_x = $this->db->insert_id();
|
||||
$preregister_patient_id = intval($last_id_x);
|
||||
|
||||
if ($patient_id == 0) {
|
||||
$sql = "SELECT *
|
||||
FROM m_patient
|
||||
WHERE
|
||||
M_PatientName = '{$v['NAMA']}' AND
|
||||
M_PatientDOB = '{$pdob}' AND
|
||||
M_PatientNIP = '{$v['NIP']}' AND
|
||||
M_PatientIsActive = 'Y' LIMIT 1";
|
||||
$query = $this->db->query($sql);
|
||||
if (!$query) {
|
||||
$last_qry = $this->db->last_query();
|
||||
$this->db->trans_rollback();
|
||||
if ($rows) {
|
||||
$last_id_x = $this->db->insert_id();
|
||||
$preregister_patient_id = intval($last_id_x);
|
||||
|
||||
$this->sys_error("select m_patient : " . $last_qry);
|
||||
if ($patient_id == 0) {
|
||||
$enc_csv = $this->ibl_encryptor;
|
||||
$name_toks = $enc_csv->query_tokens($v['NAMA']);
|
||||
$name_conds = [];
|
||||
foreach ($name_toks as $tok) {
|
||||
$tok_esc = $this->db->escape_str($tok);
|
||||
$name_conds[] = "JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
$name_where = $name_conds ? implode(' AND ', $name_conds) : '0';
|
||||
$sql = "SELECT M_PatientID FROM m_patient
|
||||
WHERE ({$name_where})
|
||||
AND M_PatientDOB = ?
|
||||
AND M_PatientNIP = ?
|
||||
AND M_PatientIsActive = 'Y' LIMIT 1";
|
||||
$query = $this->db->query($sql, [$pdob, $v['NIP']]);
|
||||
if (!$query) {
|
||||
$this->db->trans_rollback();
|
||||
$this->sys_error("select m_patient : " . $this->db->last_query());
|
||||
exit;
|
||||
}
|
||||
$exist_r = $query->row_array();
|
||||
if ($exist_r) {
|
||||
$patient_id = $exist_r["M_PatientID"];
|
||||
$patient_id = $exist_r["M_PatientID"];
|
||||
}
|
||||
//echo $sql;
|
||||
}
|
||||
|
||||
$sql_cor = "SELECT *
|
||||
@@ -426,51 +462,41 @@ class Preregister extends MY_Controller
|
||||
|
||||
//echo $patient_id;
|
||||
if ($patient_id == 0) {
|
||||
//echo 'insert new patient';
|
||||
//$pdob = date('Y-m-d',strtotime($prm['Mcu_PreregisterDetailsDOB']));
|
||||
$sql = "INSERT INTO m_patient (
|
||||
M_PatientRegisteredByCompanyID,
|
||||
M_PatientNoReg,
|
||||
M_PatientName,
|
||||
M_PatientM_SexID,
|
||||
M_PatientM_TitleID,
|
||||
M_PatientDOB,
|
||||
M_PatientIdentifierValue,
|
||||
M_PatientNIP,
|
||||
M_PatientJob,
|
||||
M_PatientPosisi,
|
||||
M_PatientDivisi,
|
||||
M_PatientLocation,
|
||||
M_PatientDepartement,
|
||||
M_PatientHP,
|
||||
M_PatientEmail,
|
||||
M_PatientCreatedUserID
|
||||
)
|
||||
VALUES(
|
||||
'{$company_id}',
|
||||
`fn_numbering_ibl`('PA'),
|
||||
'{$v["NAMA"]}',
|
||||
{$sex_id},
|
||||
{$title_id},
|
||||
'{$pdob}',
|
||||
'{$v['KTP']}',
|
||||
'{$v['NIP']}',
|
||||
'{$v['JOB']}',
|
||||
'{$v['POSISI']}',
|
||||
'{$v['DIVISI']}',
|
||||
'{$v['LOKASI']}',
|
||||
'{$v['DEPARTEMENT']}',
|
||||
'{$v['HP']}',
|
||||
'{$v['EMAIL']}',
|
||||
'{$userid}'
|
||||
)";
|
||||
// echo $sql;
|
||||
// exit;
|
||||
$query = $this->db->query($sql);
|
||||
$enc_csv = $this->ibl_encryptor;
|
||||
$dob_str_csv = date('d-m-Y', strtotime($pdob));
|
||||
$noreg_row = $this->db->query("SELECT `fn_numbering_ibl`('PA') AS noreg")->row_array();
|
||||
$ins_ptn = [
|
||||
'M_PatientRegisteredByCompanyID' => $company_id,
|
||||
'M_PatientNoReg' => $noreg_row['noreg'] ?? '',
|
||||
'M_PatientName' => $this->_mask_name($v["NAMA"]),
|
||||
'M_PatientName_enc' => $enc_csv->encrypt($v["NAMA"]),
|
||||
'M_PatientName_bidx' => $enc_csv->search_bidx($v["NAMA"]),
|
||||
'M_PatientM_SexID' => $sex_id,
|
||||
'M_PatientM_TitleID' => $title_id,
|
||||
'M_PatientDOB' => $this->_mask_dob($dob_str_csv),
|
||||
'M_PatientDOB_enc' => $enc_csv->encrypt($dob_str_csv),
|
||||
'M_PatientDOB_bidx' => $enc_csv->search_bidx($dob_str_csv),
|
||||
'M_PatientM_IdTypeID' => $v['KTP'] ? 1 : 0,
|
||||
'M_PatientIDNumber' => $v['KTP'] ? $this->_mask_id($v['KTP']) : null,
|
||||
'M_PatientIDNumber_enc' => $v['KTP'] ? $enc_csv->encrypt($v['KTP']) : null,
|
||||
'M_PatientNIK_bidx' => $enc_csv->search_bidx($v['KTP'] ?? ''),
|
||||
'M_PatientNIP' => $v['NIP'],
|
||||
'M_PatientJob' => $v['JOB'],
|
||||
'M_PatientPosisi' => $v['POSISI'],
|
||||
'M_PatientDivisi' => $v['DIVISI'],
|
||||
'M_PatientLocation' => $v['LOKASI'],
|
||||
'M_PatientDepartement' => $v['DEPARTEMENT'],
|
||||
'M_PatientHP' => $this->_mask_phone($v['HP']),
|
||||
'M_PatientHP_enc' => $enc_csv->encrypt($v['HP']),
|
||||
'M_PatientHP_bidx' => $enc_csv->search_bidx($v['HP']),
|
||||
'M_PatientEmail' => $this->_mask_email($v['EMAIL']),
|
||||
'M_PatientEmail_enc' => $enc_csv->encrypt($v['EMAIL']),
|
||||
'M_PatientCreatedUserID'=> $userid,
|
||||
];
|
||||
$query = $this->db->insert('m_patient', $ins_ptn);
|
||||
if (!$query) {
|
||||
$last_qry = $this->db->last_query();
|
||||
$this->db->trans_rollback();
|
||||
$this->sys_error("insert m_patient : " . $last_qry);
|
||||
$this->sys_error("insert m_patient : " . $this->db->last_query());
|
||||
exit;
|
||||
}
|
||||
$patient_id = $this->db->insert_id();
|
||||
@@ -521,10 +547,16 @@ class Preregister extends MY_Controller
|
||||
|
||||
if ($prm['companyID'] != '')
|
||||
$data_update_patient['M_PatientRegisteredByCompanyID'] = $prm['companyID'];
|
||||
if ($v['EMAIL'] != '')
|
||||
$data_update_patient['M_PatientEmail'] = $v['EMAIL'];
|
||||
if ($v['HP'] != '')
|
||||
$data_update_patient['M_PatientHP'] = $v['HP'];
|
||||
$enc_csv = $this->ibl_encryptor;
|
||||
if ($v['EMAIL'] != '') {
|
||||
$data_update_patient['M_PatientEmail'] = $this->_mask_email($v['EMAIL']);
|
||||
$data_update_patient['M_PatientEmail_enc'] = $enc_csv->encrypt($v['EMAIL']);
|
||||
}
|
||||
if ($v['HP'] != '') {
|
||||
$data_update_patient['M_PatientHP'] = $this->_mask_phone($v['HP']);
|
||||
$data_update_patient['M_PatientHP_enc'] = $enc_csv->encrypt($v['HP']);
|
||||
$data_update_patient['M_PatientHP_bidx'] = $enc_csv->search_bidx($v['HP']);
|
||||
}
|
||||
if ($v['JOB'] != '')
|
||||
$data_update_patient['M_PatientJob'] = $v['JOB'];
|
||||
if ($v['POSISI'] != '')
|
||||
@@ -543,50 +575,50 @@ class Preregister extends MY_Controller
|
||||
|
||||
$sql = "UPDATE mcu_preregister_patients SET Mcu_PreregisterPatientsM_PatientID = {$patient_id}
|
||||
WHERE Mcu_PreregisterPatientsID = {$last_id_x}";
|
||||
$query = $this->db->query($sql);
|
||||
if (!$query) {
|
||||
$last_qry = $this->db->last_query();
|
||||
$this->db->trans_rollback();
|
||||
$this->sys_error("update mcu_preregister_patients : " . $last_qry);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$preregister_patient_id = intval($exist_r[0]['Mcu_PreregisterPatientsID']);
|
||||
}
|
||||
|
||||
// Simpan jadwal MCU per preregister patient jika parameter TANGGAL_MCU dikirim
|
||||
$scheduleDate = isset($v['TANGGAL_MCU']) ? $this->normalize_schedule_date($v['TANGGAL_MCU']) : '';
|
||||
if ($preregister_patient_id > 0 && $scheduleDate !== '') {
|
||||
$sqlSchedule = "INSERT INTO mcu_preregister_date (
|
||||
Mcu_PreregisterDateMcu_PreregisterPatientsID,
|
||||
Mcu_PreregisterDateCheckinSchedule,
|
||||
Mcu_PreregisterDateIsActive,
|
||||
Mcu_PreregisterDateCreated,
|
||||
Mcu_PreregisterDateCreatedUserID,
|
||||
Mcu_PreregisterDateLastUpdated,
|
||||
Mcu_PreregisterDateLastUpdatedUserID
|
||||
) VALUES (
|
||||
?, ?, 'Y', NOW(), ?, NOW(), ?
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
Mcu_PreregisterDateIsActive = 'Y',
|
||||
Mcu_PreregisterDateLastUpdated = NOW(),
|
||||
Mcu_PreregisterDateLastUpdatedUserID = VALUES(Mcu_PreregisterDateLastUpdatedUserID)";
|
||||
$qrySchedule = $this->db->query($sqlSchedule, array(
|
||||
$preregister_patient_id,
|
||||
$scheduleDate,
|
||||
$userid,
|
||||
$userid
|
||||
));
|
||||
if (!$qrySchedule) {
|
||||
$last_qry = $this->db->last_query();
|
||||
$this->db->trans_rollback();
|
||||
$this->sys_error("insert mcu_preregister_date : " . $last_qry);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
$query = $this->db->query($sql);
|
||||
if (!$query) {
|
||||
$last_qry = $this->db->last_query();
|
||||
$this->db->trans_rollback();
|
||||
$this->sys_error("update mcu_preregister_patients : " . $last_qry);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$preregister_patient_id = intval($exist_r[0]['Mcu_PreregisterPatientsID']);
|
||||
}
|
||||
|
||||
// Simpan jadwal MCU per preregister patient jika parameter TANGGAL_MCU dikirim
|
||||
$scheduleDate = isset($v['TANGGAL_MCU']) ? $this->normalize_schedule_date($v['TANGGAL_MCU']) : '';
|
||||
if ($preregister_patient_id > 0 && $scheduleDate !== '') {
|
||||
$sqlSchedule = "INSERT INTO mcu_preregister_date (
|
||||
Mcu_PreregisterDateMcu_PreregisterPatientsID,
|
||||
Mcu_PreregisterDateCheckinSchedule,
|
||||
Mcu_PreregisterDateIsActive,
|
||||
Mcu_PreregisterDateCreated,
|
||||
Mcu_PreregisterDateCreatedUserID,
|
||||
Mcu_PreregisterDateLastUpdated,
|
||||
Mcu_PreregisterDateLastUpdatedUserID
|
||||
) VALUES (
|
||||
?, ?, 'Y', NOW(), ?, NOW(), ?
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
Mcu_PreregisterDateIsActive = 'Y',
|
||||
Mcu_PreregisterDateLastUpdated = NOW(),
|
||||
Mcu_PreregisterDateLastUpdatedUserID = VALUES(Mcu_PreregisterDateLastUpdatedUserID)";
|
||||
$qrySchedule = $this->db->query($sqlSchedule, array(
|
||||
$preregister_patient_id,
|
||||
$scheduleDate,
|
||||
$userid,
|
||||
$userid
|
||||
));
|
||||
if (!$qrySchedule) {
|
||||
$last_qry = $this->db->last_query();
|
||||
$this->db->trans_rollback();
|
||||
$this->sys_error("insert mcu_preregister_date : " . $last_qry);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->db->trans_status() === FALSE) {
|
||||
$this->db->trans_rollback();
|
||||
@@ -960,32 +992,36 @@ class Preregister extends MY_Controller
|
||||
}
|
||||
|
||||
if ($v['KTP'] != '') {
|
||||
$sql = "SELECT *
|
||||
FROM m_patient
|
||||
$enc = $this->ibl_encryptor;
|
||||
$ktp_toks = $enc->query_tokens($v['KTP']);
|
||||
$ktp_conds = [];
|
||||
foreach ($ktp_toks as $tok) {
|
||||
$tok_esc = $this->db_onedev->escape_str($tok);
|
||||
$ktp_conds[] = "JSON_CONTAINS(M_PatientNIK_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
$ktp_where = $ktp_conds ? implode(' AND ', $ktp_conds) : '0';
|
||||
$sql = "SELECT m_patient.*, M_SexCode
|
||||
FROM m_patient
|
||||
JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
WHERE M_PatientM_IdTypeID = 1 AND
|
||||
M_PatientIDNumber = '{$v['KTP']}' AND
|
||||
M_PatientIsActive = 'Y'
|
||||
WHERE M_PatientIsActive = 'Y' AND ({$ktp_where})
|
||||
LIMIT 1";
|
||||
$exist_r = $this->db_onedev->query($sql)->row_array();
|
||||
if ($exist_r) {
|
||||
$patient_id = $exist_r["M_PatientID"];
|
||||
$v['NAMA'] = $exist_r["M_PatientName"];
|
||||
//$pdob = date('Y-m-d',strtotime($exist_r['M_PatientDOB']));
|
||||
$v['NAMA'] = $enc->decrypt($exist_r['M_PatientName_enc']) ?? $exist_r["M_PatientName"];
|
||||
$title_id = $exist_r["M_PatientM_TitleID"];
|
||||
$sex_id = $exist_r["M_PatientM_SexID"];
|
||||
$religion_id = $exist_r["M_PatientM_ReligionID"];
|
||||
$v['NIK'] = $v['NIK'] ? $v['NIK'] : $exist_r["M_PatientNIK"];
|
||||
$v['EMAIL'] = $v['EMAIL'] ? $v['EMAIL'] : $exist_r["M_PatientEmail"];
|
||||
$v['HP'] = $v['HP'] ? $v['HP'] : $exist_r["M_PatientHP"];
|
||||
$v['NIK'] = $v['NIK'] ? $v['NIK'] : ($enc->decrypt($exist_r['M_PatientNIK_enc'] ?? '') ?? $exist_r["M_PatientNIK"]);
|
||||
$v['EMAIL'] = $v['EMAIL'] ? $v['EMAIL'] : ($enc->decrypt($exist_r['M_PatientEmail_enc'] ?? '') ?? $exist_r["M_PatientEmail"]);
|
||||
$v['HP'] = $v['HP'] ? $v['HP'] : ($enc->decrypt($exist_r['M_PatientHP_enc'] ?? '') ?? $exist_r["M_PatientHP"]);
|
||||
$v['KEDUDUKAN'] = $v['KEDUDUKAN'] ? $v['KEDUDUKAN'] : $exist_r["M_PatientKedudukan"];
|
||||
$v['JABATAN'] = $v['JABATAN'] ? $v['JABATAN'] : $exist_r["M_PatientJabatan"];
|
||||
$v['JOB'] = $v['JOB'] ? $v['JOB'] : $exist_r["M_PatientJob"];
|
||||
$v['LOKASI'] = $v['LOKASI'] ? addslashes($v['LOKASI']) : addslashes($exist_r["M_PatientLocation"]);
|
||||
$v['JENIS_KELAMIN'] = $exist_r["M_SexCode"];
|
||||
$v['KTP'] = $v['KTP'] ? $v['KTP'] : $exist_r["M_PatientIDNumber"];
|
||||
$v['KTP'] = $v['KTP'] ? $v['KTP'] : ($enc->decrypt($exist_r['M_PatientIDNumber_enc'] ?? '') ?? $exist_r["M_PatientIDNumber"]);
|
||||
}
|
||||
//echo $sql;
|
||||
}
|
||||
|
||||
if ($patient_id == 0) {
|
||||
@@ -1005,6 +1041,11 @@ class Preregister extends MY_Controller
|
||||
$sql = "SELECT * FROM m_religion WHERE M_ReligionName = 'OTHERS' AND M_ReligionIsActive = 'Y' LIMIT 1";
|
||||
$religion_id = $this->db_onedev->query($sql)->row()->M_ReligionID;
|
||||
}
|
||||
$m_nama = $this->db_onedev->escape_str($this->_mask_name($v['NAMA']));
|
||||
$m_ktp = $this->_mask_id($v['KTP']);
|
||||
$m_nik = $this->_mask_id($v['NIK']);
|
||||
$m_email = $this->_mask_email($v['EMAIL']);
|
||||
$m_hp = $this->_mask_phone($v['HP']);
|
||||
$query = " INSERT INTO mcu_preregister_patients (
|
||||
Mcu_PreregisterDetailsMcuOfflinePrepareID,
|
||||
Mcu_PreregisterDetailsPID,
|
||||
@@ -1029,13 +1070,13 @@ class Preregister extends MY_Controller
|
||||
VALUES(
|
||||
'{$prm['xid']}',
|
||||
'{$v['PID']}',
|
||||
'{$v['KTP']}',
|
||||
'{$v['NIK']}',
|
||||
'{$m_ktp}',
|
||||
'{$m_nik}',
|
||||
'{$title_id}',
|
||||
'{$v['NAMA']}',
|
||||
'{$m_nama}',
|
||||
'{$religion_id}',
|
||||
'{$v['EMAIL']}',
|
||||
'{$v['HP']}',
|
||||
'{$m_email}',
|
||||
'{$m_hp}',
|
||||
'{$pdob}',
|
||||
'{$v['KEDUDUKAN']}',
|
||||
'{$v['JABATAN']}',
|
||||
@@ -1060,18 +1101,22 @@ class Preregister extends MY_Controller
|
||||
//print_r($row_header);
|
||||
|
||||
if ($patient_id == 0) {
|
||||
$sql = "SELECT *
|
||||
FROM m_patient
|
||||
WHERE
|
||||
M_PatientName = '{$v['NAMA']}' AND
|
||||
M_PatientDOB = '{$pdob}' AND
|
||||
M_PatientNIP = '{$v['NIK']}' AND
|
||||
M_PatientIsActive = 'Y' LIMIT 1";
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name_toks = $enc->query_tokens($v['NAMA']);
|
||||
$name_conds = [];
|
||||
foreach ($name_toks as $tok) {
|
||||
$tok_esc = $this->db_onedev->escape_str($tok);
|
||||
$name_conds[] = "JSON_CONTAINS(M_PatientName_bidx, '\"$tok_esc\"')";
|
||||
}
|
||||
$name_where = $name_conds ? implode(' AND ', $name_conds) : '0';
|
||||
$sql = "SELECT M_PatientID FROM m_patient
|
||||
WHERE ({$name_where})
|
||||
AND M_PatientDOB = '{$pdob}'
|
||||
AND M_PatientIsActive = 'Y' LIMIT 1";
|
||||
$exist_r = $this->db_onedev->query($sql)->row_array();
|
||||
if ($exist_r) {
|
||||
$patient_id = $exist_r["M_PatientID"];
|
||||
$patient_id = $exist_r["M_PatientID"];
|
||||
}
|
||||
//echo $sql;
|
||||
}
|
||||
|
||||
//echo $patient_id;
|
||||
@@ -1084,85 +1129,53 @@ class Preregister extends MY_Controller
|
||||
$M_PatientM_IdTypeID = 1;
|
||||
$M_PatientIDNumber = $v["KTP"];
|
||||
}
|
||||
$sql = "INSERT INTO m_patient (
|
||||
M_PatientName,
|
||||
M_PatientM_TitleID,
|
||||
M_PatientM_SexID,
|
||||
M_PatientM_ReligionID,
|
||||
M_PatientPOB,
|
||||
M_PatientDOB,
|
||||
M_PatientNIK,
|
||||
M_PatientM_IdTypeID,
|
||||
M_PatientIDNumber,
|
||||
M_PatientJabatan,
|
||||
M_PatientLocation,
|
||||
M_PatientKedudukan,
|
||||
M_PatientJob,
|
||||
M_PatientEmail,
|
||||
M_PatientHP,
|
||||
M_PatientUserID
|
||||
)
|
||||
VALUES(
|
||||
'{$v["NAMA"]}',
|
||||
{$title_id},
|
||||
{$sex_id},
|
||||
{$religion_id},
|
||||
'-',
|
||||
'{$pdob}',
|
||||
'{$v["NIK"]}',
|
||||
'{$M_PatientM_IdTypeID}',
|
||||
'{$M_PatientIDNumber}',
|
||||
'{$v['JABATAN']}',
|
||||
'{$v['LOKASI']}',
|
||||
'{$v['KEDUDUKAN']}',
|
||||
'{$v['JOB']}',
|
||||
'{$v['EMAIL']}',
|
||||
'{$v['HP']}',
|
||||
'{$userid}'
|
||||
)";
|
||||
//echo $sql;
|
||||
$this->db_onedev->query($sql);
|
||||
$data_insert_patient = array(
|
||||
'M_PatientName' => $v["NAMA"],
|
||||
'M_PatientM_TitleID' => $title_id,
|
||||
'M_PatientM_SexID' => $sex_id,
|
||||
$enc = $this->ibl_encryptor;
|
||||
$dob_str = date('d-m-Y', strtotime($pdob));
|
||||
$data_insert_patient = [
|
||||
'M_PatientName' => $this->_mask_name($v["NAMA"]),
|
||||
'M_PatientName_enc' => $enc->encrypt($v["NAMA"]),
|
||||
'M_PatientName_bidx' => $enc->search_bidx($v["NAMA"]),
|
||||
'M_PatientM_TitleID' => $title_id,
|
||||
'M_PatientM_SexID' => $sex_id,
|
||||
'M_PatientM_ReligionID' => $religion_id,
|
||||
'M_PatientPOB' => '-',
|
||||
'M_PatientDOB' => $pdob,
|
||||
'M_PatientNIK' => $v["NIK"],
|
||||
'M_PatientJabatan' => $v['JABATAN'],
|
||||
'M_PatientLocation' => $v['LOKASI'],
|
||||
'M_PatientKedudukan' => $v['KEDUDUKAN'],
|
||||
'M_PatientJob' => $v['JOB'],
|
||||
'M_PatientEmail' => $v['EMAIL'],
|
||||
'M_PatientHP' => $v['HP'],
|
||||
'M_PatientUserID' => $userid
|
||||
);
|
||||
|
||||
|
||||
//$this->db->insert('m_patient', $data_insert_patient);
|
||||
//echo $this->db_onedev->last_query();
|
||||
'M_PatientPOB' => '***',
|
||||
'M_PatientPOB_enc' => $enc->encrypt('-'),
|
||||
'M_PatientDOB' => $pdob,
|
||||
'M_PatientDOB_enc' => $enc->encrypt($dob_str),
|
||||
'M_PatientDOB_bidx' => $enc->search_bidx($dob_str),
|
||||
'M_PatientNIK' => $v["NIK"],
|
||||
'M_PatientNIK_bidx' => $enc->search_bidx($v["NIK"] ?? ''),
|
||||
'M_PatientM_IdTypeID' => $M_PatientM_IdTypeID,
|
||||
'M_PatientIDNumber' => $M_PatientIDNumber ? $this->_mask_id($M_PatientIDNumber) : null,
|
||||
'M_PatientIDNumber_enc' => $M_PatientIDNumber ? $enc->encrypt($M_PatientIDNumber) : null,
|
||||
'M_PatientJabatan' => $v['JABATAN'],
|
||||
'M_PatientLocation' => $v['LOKASI'],
|
||||
'M_PatientKedudukan' => $v['KEDUDUKAN'],
|
||||
'M_PatientJob' => $v['JOB'],
|
||||
'M_PatientEmail' => $this->_mask_email($v['EMAIL']),
|
||||
'M_PatientEmail_enc' => $enc->encrypt($v['EMAIL']),
|
||||
'M_PatientHP' => $this->_mask_phone($v['HP']),
|
||||
'M_PatientHP_enc' => $enc->encrypt($v['HP']),
|
||||
'M_PatientHP_bidx' => $enc->search_bidx($v['HP']),
|
||||
'M_PatientUserID' => $userid,
|
||||
];
|
||||
$this->db_onedev->insert('m_patient', $data_insert_patient);
|
||||
$patient_id = $this->db_onedev->insert_id();
|
||||
|
||||
//$sql = "SELECT LAST_INSERT_ID() as xid";
|
||||
//$patient_id = $this->db_onedev->query($sql)->row()->xid;
|
||||
//echo $patient_id ;
|
||||
|
||||
$sql = "INSERT INTO m_patientaddress (
|
||||
M_PatientAddressM_PatientID,
|
||||
M_PatientAddressDescription,
|
||||
M_PatientAddressM_KelurahanID,
|
||||
M_PatientAddressCreated,
|
||||
M_PatientAddressUserID
|
||||
)
|
||||
VALUES(
|
||||
{$patient_id},
|
||||
'{$row_header['M_CompanyAddress']}',
|
||||
'{$row_header['M_CompanyM_KelurahanID']}',
|
||||
NOW(),
|
||||
'{$userid}'
|
||||
)";
|
||||
$this->db_onedev->query($sql);
|
||||
$enc = $this->ibl_encryptor;
|
||||
$addr_desc = $row_header['M_CompanyAddress'];
|
||||
$this->db_onedev->insert('m_patientaddress', [
|
||||
'M_PatientAddressM_PatientID' => $patient_id,
|
||||
'M_PatientAddressDescription' => $this->_mask_address($addr_desc),
|
||||
'M_PatientAddressDescription_enc' => $enc->encrypt($addr_desc),
|
||||
'M_PatientAddressM_KelurahanID' => $row_header['M_CompanyM_KelurahanID'],
|
||||
'M_PatientAddressCreated' => date('Y-m-d H:i:s'),
|
||||
'M_PatientAddressUserID' => $userid,
|
||||
]);
|
||||
//echo $sql;
|
||||
//$patient_addr_id = $this->db_onedev->insert_id();
|
||||
//$sql = "SELECT * FROM m_patientaddress WHERE M_PatientAddressID = {$patient_addr_id}";
|
||||
@@ -1174,20 +1187,31 @@ class Preregister extends MY_Controller
|
||||
} else {
|
||||
//echo 'masuk';
|
||||
//$pdob = date('Y-m-d',strtotime($prm['Mcu_PreregisterDetailsDOB']));
|
||||
$data_update_patient = array(
|
||||
'M_PatientDOB' => $pdob
|
||||
);
|
||||
$enc = $this->ibl_encryptor;
|
||||
$dob_str2 = date('d-m-Y', strtotime($pdob));
|
||||
$data_update_patient = [
|
||||
'M_PatientDOB' => $pdob,
|
||||
'M_PatientDOB_enc' => $enc->encrypt($dob_str2),
|
||||
'M_PatientDOB_bidx'=> $enc->search_bidx($dob_str2),
|
||||
];
|
||||
if ($v['JENIS_KELAMIN'] == 'L')
|
||||
$data_update_patient['M_PatientM_TitleID'] = 2;
|
||||
else
|
||||
$data_update_patient['M_PatientM_TitleID'] = 4;
|
||||
|
||||
if ($v['EMAIL'] != '')
|
||||
$data_update_patient['M_PatientEmail'] = $v['EMAIL'];
|
||||
if ($v['HP'] != '')
|
||||
$data_update_patient['M_PatientHP'] = $v['HP'];
|
||||
if ($v['NIK'] != '')
|
||||
$data_update_patient['M_PatientNIK'] = $v['NIK'];
|
||||
if ($v['EMAIL'] != '') {
|
||||
$data_update_patient['M_PatientEmail'] = $this->_mask_email($v['EMAIL']);
|
||||
$data_update_patient['M_PatientEmail_enc'] = $enc->encrypt($v['EMAIL']);
|
||||
}
|
||||
if ($v['HP'] != '') {
|
||||
$data_update_patient['M_PatientHP'] = $this->_mask_phone($v['HP']);
|
||||
$data_update_patient['M_PatientHP_enc'] = $enc->encrypt($v['HP']);
|
||||
$data_update_patient['M_PatientHP_bidx'] = $enc->search_bidx($v['HP']);
|
||||
}
|
||||
if ($v['NIK'] != '') {
|
||||
$data_update_patient['M_PatientNIK'] = $v['NIK'];
|
||||
$data_update_patient['M_PatientNIK_bidx'] = $enc->search_bidx($v['NIK']);
|
||||
}
|
||||
if ($v['JABATAN'] != '')
|
||||
$data_update_patient['M_PatientJabatan'] = $v['JABATAN'];
|
||||
if ($v['KEDUDUKAN'] != '')
|
||||
@@ -1198,8 +1222,9 @@ class Preregister extends MY_Controller
|
||||
$data_update_patient['M_PatientJob'] = $v['JOB'];
|
||||
|
||||
if (isset($v["KTP"]) && $v["KTP"] != '') {
|
||||
$data_update_patient['M_PatientM_IdTypeID'] = 1;
|
||||
$data_update_patient['M_PatientIDNumber'] = $v["KTP"];
|
||||
$data_update_patient['M_PatientM_IdTypeID'] = 1;
|
||||
$data_update_patient['M_PatientIDNumber'] = $this->_mask_id($v["KTP"]);
|
||||
$data_update_patient['M_PatientIDNumber_enc'] = $enc->encrypt($v["KTP"]);
|
||||
}
|
||||
|
||||
$this->db_onedev->where('M_PatientID', $patient_id);
|
||||
@@ -1247,56 +1272,46 @@ class Preregister extends MY_Controller
|
||||
$prm = $this->sys_input;
|
||||
$userid = $this->sys_user["M_UserID"];
|
||||
|
||||
$pdob = date('Y-m-d', strtotime($prm['M_PatientDOB']));
|
||||
$query = "INSERT INTO m_patient (
|
||||
M_PatientM_TitleID,
|
||||
M_PatientPrefix,
|
||||
M_PatientName,
|
||||
M_PatientSuffix,
|
||||
M_PatientDOB,
|
||||
M_PatientM_SexID,
|
||||
M_PatientM_ReligionID,
|
||||
M_PatientEmail,
|
||||
M_PatientPOB,
|
||||
M_PatientHP,
|
||||
M_PatientPhone,
|
||||
M_PatientM_IdTypeID,
|
||||
M_PatientIDNumber,
|
||||
M_PatientNote,
|
||||
M_PatientNIK,
|
||||
M_PatientJabatan,
|
||||
M_PatientKedudukan,
|
||||
M_PatientPJ,
|
||||
M_PatientLocation,
|
||||
M_PatientJob,
|
||||
M_PatientUserID
|
||||
)
|
||||
VALUES(
|
||||
'{$prm['M_PatientM_TitleID']}',
|
||||
'{$prm['M_PatientPrefix']}',
|
||||
'{$prm['M_PatientName']}',
|
||||
'{$prm['M_PatientSuffix']}',
|
||||
'{$pdob}',
|
||||
'{$prm['M_PatientM_SexID']}',
|
||||
'{$prm['M_PatientM_ReligionID']}',
|
||||
'{$prm['M_PatientEmail']}',
|
||||
'{$prm['M_PatientPOB']}',
|
||||
'{$prm['M_PatientHP']}',
|
||||
'{$prm['M_PatientPhone']}',
|
||||
'{$prm['M_PatientM_IdTypeID']}',
|
||||
'{$prm['M_PatientIDNumber']}',
|
||||
'{$prm['M_PatientNote']}',
|
||||
'{$prm['M_PatientNIK']}',
|
||||
'{$prm['M_PatientJabatan']}',
|
||||
'{$prm['M_PatientKedudukan']}',
|
||||
'{$prm['M_PatientPJ']}',
|
||||
'{$prm['M_PatientLocation']}',
|
||||
'{$prm['M_PatientJob']}',
|
||||
$userid
|
||||
)
|
||||
";
|
||||
//echo $query;
|
||||
$rows = $this->db_onedev->query($query);
|
||||
$pdob = date('Y-m-d', strtotime($prm['M_PatientDOB']));
|
||||
$dob_str = date('d-m-Y', strtotime($prm['M_PatientDOB']));
|
||||
$patient_name = $prm['M_PatientName'];
|
||||
$enc = $this->ibl_encryptor;
|
||||
|
||||
$ptn = [
|
||||
'M_PatientName' => $this->_mask_name($patient_name),
|
||||
'M_PatientName_enc' => $enc->encrypt($patient_name),
|
||||
'M_PatientName_bidx' => $enc->search_bidx($patient_name),
|
||||
'M_PatientM_TitleID' => $prm['M_PatientM_TitleID'],
|
||||
'M_PatientPrefix' => $prm['M_PatientPrefix'],
|
||||
'M_PatientSuffix' => $prm['M_PatientSuffix'],
|
||||
'M_PatientDOB' => $pdob,
|
||||
'M_PatientDOB_enc' => $enc->encrypt($dob_str),
|
||||
'M_PatientDOB_bidx' => $enc->search_bidx($dob_str),
|
||||
'M_PatientM_SexID' => $prm['M_PatientM_SexID'],
|
||||
'M_PatientM_ReligionID' => $prm['M_PatientM_ReligionID'],
|
||||
'M_PatientEmail' => $this->_mask_email($prm['M_PatientEmail']),
|
||||
'M_PatientEmail_enc' => $enc->encrypt($prm['M_PatientEmail']),
|
||||
'M_PatientPOB' => $this->_mask_short($prm['M_PatientPOB']),
|
||||
'M_PatientPOB_enc' => $enc->encrypt($prm['M_PatientPOB']),
|
||||
'M_PatientHP' => $this->_mask_phone($prm['M_PatientHP']),
|
||||
'M_PatientHP_enc' => $enc->encrypt($prm['M_PatientHP']),
|
||||
'M_PatientHP_bidx' => $enc->search_bidx($prm['M_PatientHP']),
|
||||
'M_PatientPhone' => $this->_mask_phone($prm['M_PatientPhone']),
|
||||
'M_PatientPhone_enc' => $enc->encrypt($prm['M_PatientPhone']),
|
||||
'M_PatientM_IdTypeID' => $prm['M_PatientM_IdTypeID'],
|
||||
'M_PatientIDNumber' => $this->_mask_id($prm['M_PatientIDNumber']),
|
||||
'M_PatientIDNumber_enc' => $enc->encrypt($prm['M_PatientIDNumber']),
|
||||
'M_PatientNIK' => $prm['M_PatientNIK'],
|
||||
'M_PatientNIK_bidx' => $enc->search_bidx($prm['M_PatientNIK'] ?? ''),
|
||||
'M_PatientNote' => $prm['M_PatientNote'],
|
||||
'M_PatientJabatan' => $prm['M_PatientJabatan'],
|
||||
'M_PatientKedudukan' => $prm['M_PatientKedudukan'],
|
||||
'M_PatientPJ' => $prm['M_PatientPJ'],
|
||||
'M_PatientLocation' => $prm['M_PatientLocation'],
|
||||
'M_PatientJob' => $prm['M_PatientJob'],
|
||||
'M_PatientUserID' => $userid,
|
||||
];
|
||||
$this->db_onedev->insert('m_patient', $ptn);
|
||||
$last_id = $this->db_onedev->insert_id();
|
||||
$result = array(
|
||||
"total" => 1,
|
||||
|
||||
@@ -6,6 +6,7 @@ class Hasil extends MY_Controller
|
||||
{
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
/* WA ------ */
|
||||
function update_track() {
|
||||
@@ -524,14 +525,13 @@ class Hasil extends MY_Controller
|
||||
}
|
||||
}
|
||||
function dl_report($prm, $name) {
|
||||
$url = "http://localhost/birt/frameset?" ;
|
||||
$qry = "";
|
||||
$qry = "";
|
||||
foreach($prm as $k => $v) {
|
||||
if ($qry != "" ) $qry .= "&";
|
||||
if ($qry != "") $qry .= "&";
|
||||
$qry .= $k . "=" . urlencode($v);
|
||||
}
|
||||
$url .= $qry ;
|
||||
$data = file_get_contents($url);
|
||||
}
|
||||
$relative_url = "/birt/frameset?" . $qry;
|
||||
$data = $this->ibl_patient_decrypt->fetch_birt_pdf($relative_url);
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename=' . $name);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
600
application/controllers/tools/Birt_proxy.php
Normal file
600
application/controllers/tools/Birt_proxy.php
Normal file
@@ -0,0 +1,600 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Birt_proxy — PHP proxy untuk semua BIRT report call
|
||||
*
|
||||
* Flow:
|
||||
* 1. Terima request dari frontend (report_code + params)
|
||||
* 2. Decrypt patient PII dari _enc
|
||||
* 3. INSERT ke patient_print_cache
|
||||
* 4. Call BIRT via file_get_contents (internal)
|
||||
* 5. DELETE cache
|
||||
* 6. Stream PDF ke frontend
|
||||
*
|
||||
* Endpoint: POST /tools/birt_proxy/stream
|
||||
* Params : report_code, PT_OrderHeaderID, PUsername, (optional) PID_patient
|
||||
*/
|
||||
class Birt_proxy extends MY_Controller
|
||||
{
|
||||
public $db_onedev;
|
||||
private $birt_base = 'http://localhost:8080';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
// GET/POST /tools/birt_proxy/stream_by_code
|
||||
// Gunakan ini untuk flow browser print yang butuh URL langsung,
|
||||
// tapi cache PDP harus tetap dihapus segera setelah PDF di-stream.
|
||||
public function stream_by_code()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = trim($prm['report_code'] ?? $prm['code_report'] ?? $prm['code'] ?? '');
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? $prm['order_id'] ?? 0);
|
||||
$payment_id = intval($prm['PPaymentID'] ?? $prm['payment_id'] ?? 0);
|
||||
|
||||
if (!$report_code) {
|
||||
$this->sys_error('report_code wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($order_id <= 0 && $payment_id > 0) {
|
||||
$order_id = $this->_resolve_order_id_by_payment($payment_id);
|
||||
}
|
||||
|
||||
if ($payment_id <= 0 && $order_id > 0) {
|
||||
$payment_id = $this->_resolve_payment_id_by_order($order_id);
|
||||
}
|
||||
|
||||
if ($order_id <= 0) {
|
||||
$this->sys_error('order_id tidak ditemukan');
|
||||
return;
|
||||
}
|
||||
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->_delete_cache($cache_id);
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$full_url = $this->_resolve_fetch_url($url);
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 120,
|
||||
'method' => 'GET',
|
||||
]
|
||||
]);
|
||||
|
||||
$pdf = @file_get_contents($full_url, false, $context);
|
||||
$this->_delete_cache($cache_id);
|
||||
|
||||
if ($pdf === false) {
|
||||
$this->sys_error('Gagal generate report dari BIRT server');
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $report_code . '_' . $order_id . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
exit;
|
||||
}
|
||||
|
||||
// POST /tools/birt_proxy/stream
|
||||
public function stream()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = $prm['report_code'] ?? '';
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? 0);
|
||||
$payment_id = intval($prm['PPaymentID'] ?? 0);
|
||||
|
||||
if (!$report_code) {
|
||||
$this->sys_error('report_code wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($payment_id <= 0 && $order_id > 0) {
|
||||
$payment_id = $this->_resolve_payment_id_by_order($order_id);
|
||||
}
|
||||
|
||||
$patient_name = '';
|
||||
if ($order_id > 0) {
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
} else {
|
||||
$cache_id = null;
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$full_url = $this->_resolve_fetch_url($url);
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 120,
|
||||
'method' => 'GET',
|
||||
]
|
||||
]);
|
||||
|
||||
$pdf = @file_get_contents($full_url, false, $context);
|
||||
|
||||
if ($cache_id) {
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_id = ?",
|
||||
[$cache_id]
|
||||
);
|
||||
}
|
||||
|
||||
if ($pdf === false) {
|
||||
$this->sys_error('Gagal generate report dari BIRT server');
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $report_code . '_' . $order_id . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
exit;
|
||||
}
|
||||
|
||||
// Hanya return URL (untuk iframe/window.open) — tanpa stream
|
||||
// Frontend membuka URL ini secara langsung
|
||||
public function get_url()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = $prm['report_code'] ?? '';
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? 0);
|
||||
$patient_name = '';
|
||||
if ($order_id > 0) {
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, 0, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->sys_ok(['url' => $url]);
|
||||
}
|
||||
|
||||
// Decrypt patient PII dan simpan ke cache
|
||||
private function _populate_cache($order_id)
|
||||
{
|
||||
// Ambil _enc columns dari m_patient via t_orderheader
|
||||
$patient = $this->db_onedev->query(
|
||||
"SELECT M_PatientID,
|
||||
M_PatientName_enc, M_PatientDOB_enc, M_PatientHP_enc,
|
||||
M_PatientEmail_enc, M_PatientDOB
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ? LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
if (!$patient) return null;
|
||||
|
||||
$addr = $this->db_onedev->query(
|
||||
"SELECT M_PatientAddressDescription_enc
|
||||
FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = ?
|
||||
AND M_PatientAddressIsActive = 'Y'
|
||||
AND M_PatientAddressNote = 'Utama'
|
||||
LIMIT 1",
|
||||
[$patient['M_PatientID']]
|
||||
)->row_array();
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? '';
|
||||
$dob = $enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now'));
|
||||
$hp = $enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? '';
|
||||
$email= $enc->decrypt($patient['M_PatientEmail_enc']?? '') ?? '';
|
||||
$address = $enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? '';
|
||||
|
||||
// Hapus cache lama untuk order ini + cleanup expired
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_order_id = ? OR ppc_created < NOW() - INTERVAL 5 MINUTE",
|
||||
[$order_id]
|
||||
);
|
||||
|
||||
// Insert cache baru
|
||||
$this->db_onedev->query(
|
||||
"INSERT INTO patient_print_cache
|
||||
(ppc_order_id, ppc_patient_id, ppc_name, ppc_dob, ppc_hp, ppc_email, ppc_address, ppc_created)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, NOW())",
|
||||
[$order_id, $patient['M_PatientID'], $name, $dob, $hp, $email, $address]
|
||||
);
|
||||
|
||||
return $this->db_onedev->insert_id();
|
||||
}
|
||||
|
||||
private function _delete_cache($cache_id)
|
||||
{
|
||||
if ($cache_id) {
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_id = ?",
|
||||
[$cache_id]
|
||||
);
|
||||
}
|
||||
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_created < NOW() - INTERVAL 5 MINUTE"
|
||||
);
|
||||
}
|
||||
|
||||
private function _resolve_fetch_url($url)
|
||||
{
|
||||
$url = trim((string) $url);
|
||||
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('#^https?://#i', $url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/birt/') === 0) {
|
||||
return $this->birt_base . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/one-api-lab/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/tools/') === 0 || strpos($url, '/index.php/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . '/one-api-lab' . $url;
|
||||
}
|
||||
|
||||
return $this->birt_base . $url;
|
||||
}
|
||||
|
||||
private function _resolve_order_id_by_payment($payment_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT F_PaymentT_OrderHeaderID
|
||||
FROM f_payment
|
||||
WHERE F_PaymentID = ?
|
||||
LIMIT 1",
|
||||
[$payment_id]
|
||||
)->row_array();
|
||||
|
||||
return intval($row['F_PaymentT_OrderHeaderID'] ?? 0);
|
||||
}
|
||||
|
||||
private function _resolve_payment_id_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT F_PaymentID
|
||||
FROM f_payment
|
||||
WHERE F_PaymentT_OrderHeaderID = ?
|
||||
ORDER BY F_PaymentID DESC
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return intval($row['F_PaymentID'] ?? 0);
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_by_cache($cache_id)
|
||||
{
|
||||
if (!$cache_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_id = ?
|
||||
LIMIT 1",
|
||||
[$cache_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($row['ppc_name'] ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_order_id = ?
|
||||
ORDER BY ppc_id DESC
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($row['ppc_name'] ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_from_enc_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT M_PatientName_enc
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ?
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($this->ibl_encryptor->decrypt($row['M_PatientName_enc'] ?? '') ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_report_username()
|
||||
{
|
||||
if (!empty($this->sys_user['M_StaffName'])) {
|
||||
return trim($this->sys_user['M_StaffName']);
|
||||
}
|
||||
|
||||
if (!empty($this->sys_user['M_UserUsername'])) {
|
||||
return trim($this->sys_user['M_UserUsername']);
|
||||
}
|
||||
|
||||
if (!empty($this->sys_user['userName'])) {
|
||||
return trim($this->sys_user['userName']);
|
||||
}
|
||||
|
||||
return 'ADMIN';
|
||||
}
|
||||
|
||||
private function _build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT Print_TransactionUrl
|
||||
FROM print_transaction
|
||||
WHERE Print_TransactionCode = ?
|
||||
LIMIT 1",
|
||||
[$report_code]
|
||||
)->row_array();
|
||||
|
||||
if (!$row) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$url_template = $this->_apply_report_template_hotfix($report_code, $row['Print_TransactionUrl']);
|
||||
$username = $this->_resolve_report_username();
|
||||
$tm = round(microtime(true) * 1000);
|
||||
$resolved_payment_id = $payment_id > 0 ? $payment_id : $this->_resolve_payment_id_by_order($order_id);
|
||||
$is_internal_app_url = $this->_is_internal_app_url($url_template);
|
||||
|
||||
$replacements = [
|
||||
'PUsername' => $this->_format_report_string_param($username, $is_internal_app_url),
|
||||
'PT_OrderHeaderID' => $order_id,
|
||||
'PPaymentID' => $resolved_payment_id,
|
||||
'PAn' => $this->_format_report_string_param($patient_name, $is_internal_app_url),
|
||||
'TS' => $tm,
|
||||
];
|
||||
|
||||
$url = $url_template;
|
||||
foreach ($replacements as $placeholder => $value) {
|
||||
if ($value === null) {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
$url = str_replace($placeholder, $value, $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
private function _apply_report_template_hotfix($report_code, $url_template)
|
||||
{
|
||||
$print_report_hotfix = [
|
||||
'LAB-RESULT-P-01' => [
|
||||
'from' => 'rpt_test.rptdesign',
|
||||
'to' => 'rpt_test_bkp020626.rptdesign',
|
||||
],
|
||||
'MIKROO-RESULT-P-01' => [
|
||||
'from' => 'rpt_test.rptdesign',
|
||||
'to' => 'rpt_test_bkp020626.rptdesign',
|
||||
],
|
||||
];
|
||||
|
||||
if (!isset($print_report_hotfix[$report_code])) {
|
||||
return $url_template;
|
||||
}
|
||||
|
||||
$hotfix = $print_report_hotfix[$report_code];
|
||||
|
||||
$resolved_url = str_replace($hotfix['from'], $hotfix['to'], $url_template);
|
||||
|
||||
if (strpos($resolved_url, 'username=') === false) {
|
||||
$resolved_url .= (strpos($resolved_url, '?') === false ? '?' : '&') . 'username=PUsername';
|
||||
}
|
||||
|
||||
return $resolved_url;
|
||||
}
|
||||
|
||||
// GET /tools/birt_proxy/header_json?PID=<order_id>
|
||||
// Hanya bisa diakses dari localhost (127.0.0.1) — dipanggil oleh BIRT scripted dataset
|
||||
// Return JSON semua kolom sp_rpt_hasil_header, PII sudah di-decrypt
|
||||
public function header_json()
|
||||
{
|
||||
$order_id = intval($this->input->get('PID') ?? 0);
|
||||
if ($order_id <= 0) {
|
||||
echo json_encode(['error' => 'PID required']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$row = $this->db_onedev->query("
|
||||
SELECT
|
||||
DATE_FORMAT(T_OrderHeaderDate, '%d-%m-%Y') AS T_OrderHeaderDate,
|
||||
T_OrderHeaderLabNumber,
|
||||
M_TitleName,
|
||||
M_PatientName,
|
||||
M_PatientName_enc,
|
||||
m_sexname AS Gender,
|
||||
M_PatientNoReg,
|
||||
M_PatientDOB,
|
||||
M_PatientDOB_enc,
|
||||
T_OrderHeaderM_PatientAge,
|
||||
M_CompanyName AS CorporateName,
|
||||
M_PatientHp,
|
||||
M_PatientHP_enc,
|
||||
M_PatientEmail,
|
||||
M_PatientEmail_enc,
|
||||
'' AS M_PatientAddressCity,
|
||||
'' AS M_PatientAddressState,
|
||||
M_CompanyName AS CorporateAddress,
|
||||
M_CompanyEmail AS CorporateEmail,
|
||||
M_CompanyPhone AS CorporatePhone,
|
||||
M_CompanyAddressCity AS CorporateAddressCity,
|
||||
'' AS CorporateAddressState,
|
||||
TRIM(CONCAT(IFNULL(pj.M_DoctorPrefix,''),' ',IFNULL(pj.M_DoctorPrefix2,''),' ',IFNULL(pj.M_DoctorName,''),' ',IFNULL(pj.M_DoctorSufix,''),' ',IFNULL(pj.M_DoctorSufix2,''))) AS M_DoctorName,
|
||||
TRIM(CONCAT(IFNULL(pjj.M_DoctorPrefix,''),' ',IFNULL(pjj.M_DoctorPrefix2,''),' ',IFNULL(pjj.M_DoctorName,''),' ',IFNULL(pjj.M_DoctorSufix,''),' ',IFNULL(pjj.M_DoctorSufix2,''))) AS M_DoctorName2,
|
||||
M_PatientID,
|
||||
M_PatientNIP, M_PatientJob, M_PatientPosisi, M_PatientDivisi, M_PatientLocation,
|
||||
CONCAT(IFNULL(M_PatientDepartement,''),' - ',IFNULL(M_PatientNIP,'')) AS M_PatientDepartement
|
||||
FROM t_orderheader
|
||||
LEFT JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID AND M_PatientIsActive = 'Y'
|
||||
LEFT JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID AND M_TitleIsActive = 'Y'
|
||||
JOIN m_company ON T_OrderHeaderM_CompanyID = M_CompanyID AND M_CompanyIsActive = 'Y'
|
||||
LEFT JOIN m_doctor pjj ON T_OrderHeaderPj2M_DoctorID = pjj.M_DoctorID AND pjj.M_DoctorIsActive = 'Y'
|
||||
LEFT JOIN m_doctor pj ON T_OrderHeaderPjM_DoctorID = pj.M_DoctorID AND pj.M_DoctorIsActive = 'Y'
|
||||
WHERE T_OrderHeaderID = ? AND T_OrderHeaderIsActive = 'Y'
|
||||
", [$order_id])->row_array();
|
||||
|
||||
if (!$row) {
|
||||
echo json_encode(['error' => 'order not found']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($row['M_PatientName_enc'] ?? '') ?: ($row['M_PatientName'] ?? '');
|
||||
$dob = $enc->decrypt($row['M_PatientDOB_enc'] ?? '') ?: date('d-m-Y', strtotime($row['M_PatientDOB'] ?? 'now'));
|
||||
$hp = $enc->decrypt($row['M_PatientHP_enc'] ?? '') ?: ($row['M_PatientHp'] ?? '');
|
||||
$email= $enc->decrypt($row['M_PatientEmail_enc']?? '') ?: ($row['M_PatientEmail'] ?? '');
|
||||
|
||||
$addr_row = $this->db_onedev->query("
|
||||
SELECT CONCAT(
|
||||
IFNULL(M_PatientAddressDescription,''),' ',
|
||||
IFNULL((SELECT regional_nm FROM regional WHERE regional_cd = NULLIF(TRIM(M_PatientAddressRegionalCd),'') LIMIT 1),'')
|
||||
) AS addr,
|
||||
M_PatientAddressDescription_enc
|
||||
FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = ? AND M_PatientAddressIsActive = 'Y'
|
||||
ORDER BY M_PatientAddressID LIMIT 1
|
||||
", [$row['M_PatientID']])->row_array();
|
||||
|
||||
$address = '';
|
||||
if ($addr_row) {
|
||||
$address = $enc->decrypt($addr_row['M_PatientAddressDescription_enc'] ?? '') ?: trim($addr_row['addr'] ?? '');
|
||||
}
|
||||
|
||||
$umur = $dob . ' / ' . ($row['T_OrderHeaderM_PatientAge'] ?? '');
|
||||
|
||||
$this->_populate_cache($order_id);
|
||||
|
||||
$data = [
|
||||
'T_OrderHeaderDate' => $row['T_OrderHeaderDate'] ?? '',
|
||||
'T_OrderHeaderLabNumber' => $row['T_OrderHeaderLabNumber'] ?? '',
|
||||
'M_PatientName' => trim(($row['M_TitleName'] ?? '') . '. ' . $name),
|
||||
'Gender' => $row['Gender'] ?? '',
|
||||
'M_PatientNoReg' => $row['M_PatientNoReg'] ?? '',
|
||||
'M_PatientDOB' => $dob,
|
||||
'T_OrderHeaderM_PatientAge' => $row['T_OrderHeaderM_PatientAge'] ?? '',
|
||||
'CorporateName' => $row['CorporateName'] ?? '',
|
||||
'M_PatientAddress' => $address,
|
||||
'M_PatientHp' => $hp,
|
||||
'M_PatientEmail' => $email,
|
||||
'M_PatientAddressCity' => '',
|
||||
'M_PatientAddressState' => '',
|
||||
'CorporateAddress' => $row['CorporateAddress'] ?? '',
|
||||
'CorporateEmail' => $row['CorporateEmail'] ?? '',
|
||||
'CorporatePhone' => $row['CorporatePhone'] ?? '',
|
||||
'CorporateAddressCity' => $row['CorporateAddressCity'] ?? '',
|
||||
'CorporateAddressState' => '',
|
||||
'M_DoctorName' => $row['M_DoctorName'] ?? '',
|
||||
'M_DoctorName2' => $row['M_DoctorName2'] ?? '',
|
||||
'Umur' => $umur,
|
||||
'M_PatientNIP' => $row['M_PatientNIP'] ?? '',
|
||||
'M_PatientJob' => $row['M_PatientJob'] ?? '',
|
||||
'M_PatientPosisi' => $row['M_PatientPosisi'] ?? '',
|
||||
'M_PatientDivisi' => $row['M_PatientDivisi'] ?? '',
|
||||
'M_PatientLocation' => $row['M_PatientLocation'] ?? '',
|
||||
'M_PatientDepartement' => $row['M_PatientDepartement'] ?? '',
|
||||
];
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($data);
|
||||
exit;
|
||||
}
|
||||
|
||||
private function _is_internal_app_url($url)
|
||||
{
|
||||
$url = (string) $url;
|
||||
|
||||
return (
|
||||
strpos($url, '/one-api-lab/') === 0 ||
|
||||
strpos($url, '/tools/') === 0 ||
|
||||
strpos($url, '/index.php/') === 0
|
||||
);
|
||||
}
|
||||
|
||||
private function _format_report_string_param($value, $is_internal_app_url = false)
|
||||
{
|
||||
$value = (string) $value;
|
||||
|
||||
if ($is_internal_app_url) {
|
||||
return rawurlencode($value);
|
||||
}
|
||||
|
||||
return rawurlencode("'" . $value . "'");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,598 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Birt_proxy — PHP proxy untuk semua BIRT report call
|
||||
*
|
||||
* Flow:
|
||||
* 1. Terima request dari frontend (report_code + params)
|
||||
* 2. Decrypt patient PII dari _enc
|
||||
* 3. INSERT ke patient_print_cache
|
||||
* 4. Call BIRT via file_get_contents (internal)
|
||||
* 5. DELETE cache
|
||||
* 6. Stream PDF ke frontend
|
||||
*
|
||||
* Endpoint: POST /tools/birt_proxy/stream
|
||||
* Params : report_code, PT_OrderHeaderID, PUsername, (optional) PID_patient
|
||||
*/
|
||||
class Birt_proxy extends MY_Controller
|
||||
{
|
||||
public $db_onedev;
|
||||
private $birt_base = 'http://localhost:8080';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
// GET/POST /tools/birt_proxy/stream_by_code
|
||||
// Gunakan ini untuk flow browser print yang butuh URL langsung,
|
||||
// tapi cache PDP harus tetap dihapus segera setelah PDF di-stream.
|
||||
public function stream_by_code()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = trim($prm['report_code'] ?? $prm['code_report'] ?? $prm['code'] ?? '');
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? $prm['order_id'] ?? 0);
|
||||
$payment_id = intval($prm['PPaymentID'] ?? $prm['payment_id'] ?? 0);
|
||||
|
||||
if (!$report_code) {
|
||||
$this->sys_error('report_code wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($order_id <= 0 && $payment_id > 0) {
|
||||
$order_id = $this->_resolve_order_id_by_payment($payment_id);
|
||||
}
|
||||
|
||||
if ($payment_id <= 0 && $order_id > 0) {
|
||||
$payment_id = $this->_resolve_payment_id_by_order($order_id);
|
||||
}
|
||||
|
||||
if ($order_id <= 0) {
|
||||
$this->sys_error('order_id tidak ditemukan');
|
||||
return;
|
||||
}
|
||||
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->_delete_cache($cache_id);
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$full_url = $this->_resolve_fetch_url($url);
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 120,
|
||||
'method' => 'GET',
|
||||
]
|
||||
]);
|
||||
|
||||
$pdf = @file_get_contents($full_url, false, $context);
|
||||
$this->_delete_cache($cache_id);
|
||||
|
||||
if ($pdf === false) {
|
||||
$this->sys_error('Gagal generate report dari BIRT server');
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $report_code . '_' . $order_id . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
exit;
|
||||
}
|
||||
|
||||
// POST /tools/birt_proxy/stream
|
||||
public function stream()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = $prm['report_code'] ?? '';
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? 0);
|
||||
$payment_id = intval($prm['PPaymentID'] ?? 0);
|
||||
|
||||
if (!$report_code) {
|
||||
$this->sys_error('report_code wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($payment_id <= 0 && $order_id > 0) {
|
||||
$payment_id = $this->_resolve_payment_id_by_order($order_id);
|
||||
}
|
||||
|
||||
$patient_name = '';
|
||||
if ($order_id > 0) {
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
} else {
|
||||
$cache_id = null;
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$full_url = $this->_resolve_fetch_url($url);
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 120,
|
||||
'method' => 'GET',
|
||||
]
|
||||
]);
|
||||
|
||||
$pdf = @file_get_contents($full_url, false, $context);
|
||||
|
||||
if ($cache_id) {
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_id = ?",
|
||||
[$cache_id]
|
||||
);
|
||||
}
|
||||
|
||||
if ($pdf === false) {
|
||||
$this->sys_error('Gagal generate report dari BIRT server');
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $report_code . '_' . $order_id . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
exit;
|
||||
}
|
||||
|
||||
// Hanya return URL (untuk iframe/window.open) — tanpa stream
|
||||
// Frontend membuka URL ini secara langsung
|
||||
public function get_url()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = $prm['report_code'] ?? '';
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? 0);
|
||||
$patient_name = '';
|
||||
if ($order_id > 0) {
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, 0, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->sys_ok(['url' => $url]);
|
||||
}
|
||||
|
||||
// Decrypt patient PII dan simpan ke cache
|
||||
private function _populate_cache($order_id)
|
||||
{
|
||||
// Ambil _enc columns dari m_patient via t_orderheader
|
||||
$patient = $this->db_onedev->query(
|
||||
"SELECT M_PatientID,
|
||||
M_PatientName_enc, M_PatientDOB_enc, M_PatientHP_enc,
|
||||
M_PatientEmail_enc, M_PatientDOB
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ? LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
if (!$patient) return null;
|
||||
|
||||
$addr = $this->db_onedev->query(
|
||||
"SELECT M_PatientAddressDescription_enc
|
||||
FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = ?
|
||||
AND M_PatientAddressIsActive = 'Y'
|
||||
AND M_PatientAddressNote = 'Utama'
|
||||
LIMIT 1",
|
||||
[$patient['M_PatientID']]
|
||||
)->row_array();
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? '';
|
||||
$dob = $enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now'));
|
||||
$hp = $enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? '';
|
||||
$email= $enc->decrypt($patient['M_PatientEmail_enc']?? '') ?? '';
|
||||
$address = $enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? '';
|
||||
|
||||
// Hapus cache lama untuk order ini + cleanup expired
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_order_id = ? OR ppc_created < NOW() - INTERVAL 5 MINUTE",
|
||||
[$order_id]
|
||||
);
|
||||
|
||||
// Insert cache baru
|
||||
$this->db_onedev->query(
|
||||
"INSERT INTO patient_print_cache
|
||||
(ppc_order_id, ppc_patient_id, ppc_name, ppc_dob, ppc_hp, ppc_email, ppc_address, ppc_created)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, NOW())",
|
||||
[$order_id, $patient['M_PatientID'], $name, $dob, $hp, $email, $address]
|
||||
);
|
||||
|
||||
return $this->db_onedev->insert_id();
|
||||
}
|
||||
|
||||
private function _delete_cache($cache_id)
|
||||
{
|
||||
if ($cache_id) {
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_id = ?",
|
||||
[$cache_id]
|
||||
);
|
||||
}
|
||||
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_created < NOW() - INTERVAL 5 MINUTE"
|
||||
);
|
||||
}
|
||||
|
||||
private function _resolve_fetch_url($url)
|
||||
{
|
||||
$url = trim((string) $url);
|
||||
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('#^https?://#i', $url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/birt/') === 0) {
|
||||
return $this->birt_base . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/one-api-lab/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/tools/') === 0 || strpos($url, '/index.php/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . '/one-api-lab' . $url;
|
||||
}
|
||||
|
||||
return $this->birt_base . $url;
|
||||
}
|
||||
|
||||
private function _resolve_order_id_by_payment($payment_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT F_PaymentT_OrderHeaderID
|
||||
FROM f_payment
|
||||
WHERE F_PaymentID = ?
|
||||
LIMIT 1",
|
||||
[$payment_id]
|
||||
)->row_array();
|
||||
|
||||
return intval($row['F_PaymentT_OrderHeaderID'] ?? 0);
|
||||
}
|
||||
|
||||
private function _resolve_payment_id_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT F_PaymentID
|
||||
FROM f_payment
|
||||
WHERE F_PaymentT_OrderHeaderID = ?
|
||||
ORDER BY F_PaymentID DESC
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return intval($row['F_PaymentID'] ?? 0);
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_by_cache($cache_id)
|
||||
{
|
||||
if (!$cache_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_id = ?
|
||||
LIMIT 1",
|
||||
[$cache_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($row['ppc_name'] ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_order_id = ?
|
||||
ORDER BY ppc_id DESC
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($row['ppc_name'] ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_from_enc_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT M_PatientName_enc
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ?
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($this->ibl_encryptor->decrypt($row['M_PatientName_enc'] ?? '') ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_report_username()
|
||||
{
|
||||
if (!empty($this->sys_user['M_StaffName'])) {
|
||||
return trim($this->sys_user['M_StaffName']);
|
||||
}
|
||||
|
||||
if (!empty($this->sys_user['M_UserUsername'])) {
|
||||
return trim($this->sys_user['M_UserUsername']);
|
||||
}
|
||||
|
||||
if (!empty($this->sys_user['userName'])) {
|
||||
return trim($this->sys_user['userName']);
|
||||
}
|
||||
|
||||
return 'ADMIN';
|
||||
}
|
||||
|
||||
private function _build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT Print_TransactionUrl
|
||||
FROM print_transaction
|
||||
WHERE Print_TransactionCode = ?
|
||||
LIMIT 1",
|
||||
[$report_code]
|
||||
)->row_array();
|
||||
|
||||
if (!$row) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$url_template = $this->_apply_report_template_hotfix($report_code, $row['Print_TransactionUrl']);
|
||||
$username = $this->_resolve_report_username();
|
||||
$tm = round(microtime(true) * 1000);
|
||||
$resolved_payment_id = $payment_id > 0 ? $payment_id : $this->_resolve_payment_id_by_order($order_id);
|
||||
$is_internal_app_url = $this->_is_internal_app_url($url_template);
|
||||
|
||||
$replacements = [
|
||||
'PUsername' => $this->_format_report_string_param($username, $is_internal_app_url),
|
||||
'PT_OrderHeaderID' => $order_id,
|
||||
'PPaymentID' => $resolved_payment_id,
|
||||
'PAn' => $this->_format_report_string_param($patient_name, $is_internal_app_url),
|
||||
'TS' => $tm,
|
||||
];
|
||||
|
||||
$url = $url_template;
|
||||
foreach ($replacements as $placeholder => $value) {
|
||||
if ($value === null) {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
$url = str_replace($placeholder, $value, $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
private function _apply_report_template_hotfix($report_code, $url_template)
|
||||
{
|
||||
$print_report_hotfix = [
|
||||
'LAB-RESULT-P-01' => [
|
||||
'from' => 'rpt_test.rptdesign',
|
||||
'to' => 'rpt_test_bkp020626.rptdesign',
|
||||
],
|
||||
'MIKROO-RESULT-P-01' => [
|
||||
'from' => 'rpt_test.rptdesign',
|
||||
'to' => 'rpt_test_bkp020626.rptdesign',
|
||||
],
|
||||
];
|
||||
|
||||
if (!isset($print_report_hotfix[$report_code])) {
|
||||
return $url_template;
|
||||
}
|
||||
|
||||
$hotfix = $print_report_hotfix[$report_code];
|
||||
|
||||
$resolved_url = str_replace($hotfix['from'], $hotfix['to'], $url_template);
|
||||
|
||||
if (strpos($resolved_url, 'username=') === false) {
|
||||
$resolved_url .= (strpos($resolved_url, '?') === false ? '?' : '&') . 'username=PUsername';
|
||||
}
|
||||
|
||||
return $resolved_url;
|
||||
}
|
||||
|
||||
// GET /tools/birt_proxy/header_json?PID=<order_id>
|
||||
// Hanya bisa diakses dari localhost (127.0.0.1) — dipanggil oleh BIRT scripted dataset
|
||||
// Return JSON semua kolom sp_rpt_hasil_header, PII sudah di-decrypt
|
||||
public function header_json()
|
||||
{
|
||||
$order_id = intval($this->input->get('PID') ?? 0);
|
||||
if ($order_id <= 0) {
|
||||
echo json_encode(['error' => 'PID required']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$row = $this->db_onedev->query("
|
||||
SELECT
|
||||
DATE_FORMAT(T_OrderHeaderDate, '%d-%m-%Y') AS T_OrderHeaderDate,
|
||||
T_OrderHeaderLabNumber,
|
||||
M_TitleName,
|
||||
M_PatientName,
|
||||
M_PatientName_enc,
|
||||
m_sexname AS Gender,
|
||||
M_PatientNoReg,
|
||||
M_PatientDOB,
|
||||
M_PatientDOB_enc,
|
||||
T_OrderHeaderM_PatientAge,
|
||||
M_CompanyName AS CorporateName,
|
||||
M_PatientHp,
|
||||
M_PatientHP_enc,
|
||||
M_PatientEmail,
|
||||
M_PatientEmail_enc,
|
||||
'' AS M_PatientAddressCity,
|
||||
'' AS M_PatientAddressState,
|
||||
M_CompanyName AS CorporateAddress,
|
||||
M_CompanyEmail AS CorporateEmail,
|
||||
M_CompanyPhone AS CorporatePhone,
|
||||
M_CompanyAddressCity AS CorporateAddressCity,
|
||||
'' AS CorporateAddressState,
|
||||
TRIM(CONCAT(IFNULL(pj.M_DoctorPrefix,''),' ',IFNULL(pj.M_DoctorPrefix2,''),' ',IFNULL(pj.M_DoctorName,''),' ',IFNULL(pj.M_DoctorSufix,''),' ',IFNULL(pj.M_DoctorSufix2,''))) AS M_DoctorName,
|
||||
TRIM(CONCAT(IFNULL(pjj.M_DoctorPrefix,''),' ',IFNULL(pjj.M_DoctorPrefix2,''),' ',IFNULL(pjj.M_DoctorName,''),' ',IFNULL(pjj.M_DoctorSufix,''),' ',IFNULL(pjj.M_DoctorSufix2,''))) AS M_DoctorName2,
|
||||
M_PatientID,
|
||||
M_PatientNIP, M_PatientJob, M_PatientPosisi, M_PatientDivisi, M_PatientLocation,
|
||||
CONCAT(IFNULL(M_PatientDepartement,''),' - ',IFNULL(M_PatientNIP,'')) AS M_PatientDepartement
|
||||
FROM t_orderheader
|
||||
LEFT JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID AND M_PatientIsActive = 'Y'
|
||||
LEFT JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID AND M_TitleIsActive = 'Y'
|
||||
JOIN m_company ON T_OrderHeaderM_CompanyID = M_CompanyID AND M_CompanyIsActive = 'Y'
|
||||
LEFT JOIN m_doctor pjj ON T_OrderHeaderPj2M_DoctorID = pjj.M_DoctorID AND pjj.M_DoctorIsActive = 'Y'
|
||||
LEFT JOIN m_doctor pj ON T_OrderHeaderPjM_DoctorID = pj.M_DoctorID AND pj.M_DoctorIsActive = 'Y'
|
||||
WHERE T_OrderHeaderID = ? AND T_OrderHeaderIsActive = 'Y'
|
||||
", [$order_id])->row_array();
|
||||
|
||||
if (!$row) {
|
||||
echo json_encode(['error' => 'order not found']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($row['M_PatientName_enc'] ?? '') ?: ($row['M_PatientName'] ?? '');
|
||||
$dob = $enc->decrypt($row['M_PatientDOB_enc'] ?? '') ?: date('d-m-Y', strtotime($row['M_PatientDOB'] ?? 'now'));
|
||||
$hp = $enc->decrypt($row['M_PatientHP_enc'] ?? '') ?: ($row['M_PatientHp'] ?? '');
|
||||
$email= $enc->decrypt($row['M_PatientEmail_enc']?? '') ?: ($row['M_PatientEmail'] ?? '');
|
||||
|
||||
$addr_row = $this->db_onedev->query("
|
||||
SELECT CONCAT(
|
||||
IFNULL(M_PatientAddressDescription,''),' ',
|
||||
IFNULL((SELECT regional_nm FROM regional WHERE regional_cd = NULLIF(TRIM(M_PatientAddressRegionalCd),'') LIMIT 1),'')
|
||||
) AS addr,
|
||||
M_PatientAddressDescription_enc
|
||||
FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = ? AND M_PatientAddressIsActive = 'Y'
|
||||
ORDER BY M_PatientAddressID LIMIT 1
|
||||
", [$row['M_PatientID']])->row_array();
|
||||
|
||||
$address = '';
|
||||
if ($addr_row) {
|
||||
$address = $enc->decrypt($addr_row['M_PatientAddressDescription_enc'] ?? '') ?: trim($addr_row['addr'] ?? '');
|
||||
}
|
||||
|
||||
$umur = $dob . ' / ' . ($row['T_OrderHeaderM_PatientAge'] ?? '');
|
||||
|
||||
$data = [
|
||||
'T_OrderHeaderDate' => $row['T_OrderHeaderDate'] ?? '',
|
||||
'T_OrderHeaderLabNumber' => $row['T_OrderHeaderLabNumber'] ?? '',
|
||||
'M_PatientName' => trim(($row['M_TitleName'] ?? '') . '. ' . $name),
|
||||
'Gender' => $row['Gender'] ?? '',
|
||||
'M_PatientNoReg' => $row['M_PatientNoReg'] ?? '',
|
||||
'M_PatientDOB' => $dob,
|
||||
'T_OrderHeaderM_PatientAge' => $row['T_OrderHeaderM_PatientAge'] ?? '',
|
||||
'CorporateName' => $row['CorporateName'] ?? '',
|
||||
'M_PatientAddress' => $address,
|
||||
'M_PatientHp' => $hp,
|
||||
'M_PatientEmail' => $email,
|
||||
'M_PatientAddressCity' => '',
|
||||
'M_PatientAddressState' => '',
|
||||
'CorporateAddress' => $row['CorporateAddress'] ?? '',
|
||||
'CorporateEmail' => $row['CorporateEmail'] ?? '',
|
||||
'CorporatePhone' => $row['CorporatePhone'] ?? '',
|
||||
'CorporateAddressCity' => $row['CorporateAddressCity'] ?? '',
|
||||
'CorporateAddressState' => '',
|
||||
'M_DoctorName' => $row['M_DoctorName'] ?? '',
|
||||
'M_DoctorName2' => $row['M_DoctorName2'] ?? '',
|
||||
'Umur' => $umur,
|
||||
'M_PatientNIP' => $row['M_PatientNIP'] ?? '',
|
||||
'M_PatientJob' => $row['M_PatientJob'] ?? '',
|
||||
'M_PatientPosisi' => $row['M_PatientPosisi'] ?? '',
|
||||
'M_PatientDivisi' => $row['M_PatientDivisi'] ?? '',
|
||||
'M_PatientLocation' => $row['M_PatientLocation'] ?? '',
|
||||
'M_PatientDepartement' => $row['M_PatientDepartement'] ?? '',
|
||||
];
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($data);
|
||||
exit;
|
||||
}
|
||||
|
||||
private function _is_internal_app_url($url)
|
||||
{
|
||||
$url = (string) $url;
|
||||
|
||||
return (
|
||||
strpos($url, '/one-api-lab/') === 0 ||
|
||||
strpos($url, '/tools/') === 0 ||
|
||||
strpos($url, '/index.php/') === 0
|
||||
);
|
||||
}
|
||||
|
||||
private function _format_report_string_param($value, $is_internal_app_url = false)
|
||||
{
|
||||
$value = (string) $value;
|
||||
|
||||
if ($is_internal_app_url) {
|
||||
return rawurlencode($value);
|
||||
}
|
||||
|
||||
return rawurlencode("'" . $value . "'");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,598 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Birt_proxy — PHP proxy untuk semua BIRT report call
|
||||
*
|
||||
* Flow:
|
||||
* 1. Terima request dari frontend (report_code + params)
|
||||
* 2. Decrypt patient PII dari _enc
|
||||
* 3. INSERT ke patient_print_cache
|
||||
* 4. Call BIRT via file_get_contents (internal)
|
||||
* 5. DELETE cache
|
||||
* 6. Stream PDF ke frontend
|
||||
*
|
||||
* Endpoint: POST /tools/birt_proxy/stream
|
||||
* Params : report_code, PT_OrderHeaderID, PUsername, (optional) PID_patient
|
||||
*/
|
||||
class Birt_proxy extends MY_Controller
|
||||
{
|
||||
public $db_onedev;
|
||||
private $birt_base = 'http://localhost:8080';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
// GET/POST /tools/birt_proxy/stream_by_code
|
||||
// Gunakan ini untuk flow browser print yang butuh URL langsung,
|
||||
// tapi cache PDP harus tetap dihapus segera setelah PDF di-stream.
|
||||
public function stream_by_code()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = trim($prm['report_code'] ?? $prm['code_report'] ?? $prm['code'] ?? '');
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? $prm['order_id'] ?? 0);
|
||||
$payment_id = intval($prm['PPaymentID'] ?? $prm['payment_id'] ?? 0);
|
||||
|
||||
if (!$report_code) {
|
||||
$this->sys_error('report_code wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($order_id <= 0 && $payment_id > 0) {
|
||||
$order_id = $this->_resolve_order_id_by_payment($payment_id);
|
||||
}
|
||||
|
||||
if ($payment_id <= 0 && $order_id > 0) {
|
||||
$payment_id = $this->_resolve_payment_id_by_order($order_id);
|
||||
}
|
||||
|
||||
if ($order_id <= 0) {
|
||||
$this->sys_error('order_id tidak ditemukan');
|
||||
return;
|
||||
}
|
||||
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->_delete_cache($cache_id);
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$full_url = $this->_resolve_fetch_url($url);
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 120,
|
||||
'method' => 'GET',
|
||||
]
|
||||
]);
|
||||
|
||||
$pdf = @file_get_contents($full_url, false, $context);
|
||||
$this->_delete_cache($cache_id);
|
||||
|
||||
if ($pdf === false) {
|
||||
$this->sys_error('Gagal generate report dari BIRT server');
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $report_code . '_' . $order_id . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
exit;
|
||||
}
|
||||
|
||||
// POST /tools/birt_proxy/stream
|
||||
public function stream()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = $prm['report_code'] ?? '';
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? 0);
|
||||
$payment_id = intval($prm['PPaymentID'] ?? 0);
|
||||
|
||||
if (!$report_code) {
|
||||
$this->sys_error('report_code wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($payment_id <= 0 && $order_id > 0) {
|
||||
$payment_id = $this->_resolve_payment_id_by_order($order_id);
|
||||
}
|
||||
|
||||
$patient_name = '';
|
||||
if ($order_id > 0) {
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
} else {
|
||||
$cache_id = null;
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$full_url = $this->_resolve_fetch_url($url);
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 120,
|
||||
'method' => 'GET',
|
||||
]
|
||||
]);
|
||||
|
||||
$pdf = @file_get_contents($full_url, false, $context);
|
||||
|
||||
if ($cache_id) {
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_id = ?",
|
||||
[$cache_id]
|
||||
);
|
||||
}
|
||||
|
||||
if ($pdf === false) {
|
||||
$this->sys_error('Gagal generate report dari BIRT server');
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $report_code . '_' . $order_id . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
exit;
|
||||
}
|
||||
|
||||
// Hanya return URL (untuk iframe/window.open) — tanpa stream
|
||||
// Frontend membuka URL ini secara langsung
|
||||
public function get_url()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = $prm['report_code'] ?? '';
|
||||
$order_id = intval($prm['PT_OrderHeaderID'] ?? 0);
|
||||
$patient_name = '';
|
||||
if ($order_id > 0) {
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
$patient_name = $this->_resolve_patient_name_by_cache($cache_id);
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_by_order($order_id);
|
||||
}
|
||||
if ($patient_name === '') {
|
||||
$patient_name = $this->_resolve_patient_name_from_enc_by_order($order_id);
|
||||
}
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $order_id, 0, $patient_name);
|
||||
if ($url === false) {
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->sys_ok(['url' => $url]);
|
||||
}
|
||||
|
||||
// Decrypt patient PII dan simpan ke cache
|
||||
private function _populate_cache($order_id)
|
||||
{
|
||||
// Ambil _enc columns dari m_patient via t_orderheader
|
||||
$patient = $this->db_onedev->query(
|
||||
"SELECT M_PatientID,
|
||||
M_PatientName_enc, M_PatientDOB_enc, M_PatientHP_enc,
|
||||
M_PatientEmail_enc, M_PatientDOB
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ? LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
if (!$patient) return null;
|
||||
|
||||
$addr = $this->db_onedev->query(
|
||||
"SELECT M_PatientAddressDescription_enc
|
||||
FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = ?
|
||||
AND M_PatientAddressIsActive = 'Y'
|
||||
AND M_PatientAddressNote = 'Utama'
|
||||
LIMIT 1",
|
||||
[$patient['M_PatientID']]
|
||||
)->row_array();
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? '';
|
||||
$dob = $enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now'));
|
||||
$hp = $enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? '';
|
||||
$email= $enc->decrypt($patient['M_PatientEmail_enc']?? '') ?? '';
|
||||
$address = $enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? '';
|
||||
|
||||
// Hapus cache lama untuk order ini + cleanup expired
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_order_id = ? OR ppc_created < NOW() - INTERVAL 5 MINUTE",
|
||||
[$order_id]
|
||||
);
|
||||
|
||||
// Insert cache baru
|
||||
$this->db_onedev->query(
|
||||
"INSERT INTO patient_print_cache
|
||||
(ppc_order_id, ppc_patient_id, ppc_name, ppc_dob, ppc_hp, ppc_email, ppc_address, ppc_created)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, NOW())",
|
||||
[$order_id, $patient['M_PatientID'], $name, $dob, $hp, $email, $address]
|
||||
);
|
||||
|
||||
return $this->db_onedev->insert_id();
|
||||
}
|
||||
|
||||
private function _delete_cache($cache_id)
|
||||
{
|
||||
if ($cache_id) {
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_id = ?",
|
||||
[$cache_id]
|
||||
);
|
||||
}
|
||||
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_created < NOW() - INTERVAL 5 MINUTE"
|
||||
);
|
||||
}
|
||||
|
||||
private function _resolve_fetch_url($url)
|
||||
{
|
||||
$url = trim((string) $url);
|
||||
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('#^https?://#i', $url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/birt/') === 0) {
|
||||
return $this->birt_base . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/one-api-lab/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/tools/') === 0 || strpos($url, '/index.php/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . '/one-api-lab' . $url;
|
||||
}
|
||||
|
||||
return $this->birt_base . $url;
|
||||
}
|
||||
|
||||
private function _resolve_order_id_by_payment($payment_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT F_PaymentT_OrderHeaderID
|
||||
FROM f_payment
|
||||
WHERE F_PaymentID = ?
|
||||
LIMIT 1",
|
||||
[$payment_id]
|
||||
)->row_array();
|
||||
|
||||
return intval($row['F_PaymentT_OrderHeaderID'] ?? 0);
|
||||
}
|
||||
|
||||
private function _resolve_payment_id_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT F_PaymentID
|
||||
FROM f_payment
|
||||
WHERE F_PaymentT_OrderHeaderID = ?
|
||||
ORDER BY F_PaymentID DESC
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return intval($row['F_PaymentID'] ?? 0);
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_by_cache($cache_id)
|
||||
{
|
||||
if (!$cache_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_id = ?
|
||||
LIMIT 1",
|
||||
[$cache_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($row['ppc_name'] ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_order_id = ?
|
||||
ORDER BY ppc_id DESC
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($row['ppc_name'] ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_patient_name_from_enc_by_order($order_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT M_PatientName_enc
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ?
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
return trim($this->ibl_encryptor->decrypt($row['M_PatientName_enc'] ?? '') ?? '');
|
||||
}
|
||||
|
||||
private function _resolve_report_username()
|
||||
{
|
||||
if (!empty($this->sys_user['M_StaffName'])) {
|
||||
return trim($this->sys_user['M_StaffName']);
|
||||
}
|
||||
|
||||
if (!empty($this->sys_user['M_UserUsername'])) {
|
||||
return trim($this->sys_user['M_UserUsername']);
|
||||
}
|
||||
|
||||
if (!empty($this->sys_user['userName'])) {
|
||||
return trim($this->sys_user['userName']);
|
||||
}
|
||||
|
||||
return 'ADMIN';
|
||||
}
|
||||
|
||||
private function _build_birt_url_by_code($report_code, $order_id, $payment_id, $patient_name)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT Print_TransactionUrl
|
||||
FROM print_transaction
|
||||
WHERE Print_TransactionCode = ?
|
||||
LIMIT 1",
|
||||
[$report_code]
|
||||
)->row_array();
|
||||
|
||||
if (!$row) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$url_template = $this->_apply_report_template_hotfix($report_code, $row['Print_TransactionUrl']);
|
||||
$username = $this->_resolve_report_username();
|
||||
$tm = round(microtime(true) * 1000);
|
||||
$resolved_payment_id = $payment_id > 0 ? $payment_id : $this->_resolve_payment_id_by_order($order_id);
|
||||
$is_internal_app_url = $this->_is_internal_app_url($url_template);
|
||||
|
||||
$replacements = [
|
||||
'PUsername' => $this->_format_report_string_param($username, $is_internal_app_url),
|
||||
'PT_OrderHeaderID' => $order_id,
|
||||
'PPaymentID' => $resolved_payment_id,
|
||||
'PAn' => $this->_format_report_string_param($patient_name, $is_internal_app_url),
|
||||
'TS' => $tm,
|
||||
];
|
||||
|
||||
$url = $url_template;
|
||||
foreach ($replacements as $placeholder => $value) {
|
||||
if ($value === null) {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
$url = str_replace($placeholder, $value, $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
private function _apply_report_template_hotfix($report_code, $url_template)
|
||||
{
|
||||
$print_report_hotfix = [
|
||||
'LAB-RESULT-P-01' => [
|
||||
'from' => 'rpt_test.rptdesign',
|
||||
'to' => 'rpt_test_bkp020626.rptdesign',
|
||||
],
|
||||
'MIKROO-RESULT-P-01' => [
|
||||
'from' => 'rpt_test.rptdesign',
|
||||
'to' => 'rpt_test_bkp020626.rptdesign',
|
||||
],
|
||||
];
|
||||
|
||||
if (!isset($print_report_hotfix[$report_code])) {
|
||||
return $url_template;
|
||||
}
|
||||
|
||||
$hotfix = $print_report_hotfix[$report_code];
|
||||
|
||||
$resolved_url = str_replace($hotfix['from'], $hotfix['to'], $url_template);
|
||||
|
||||
if (strpos($resolved_url, 'username=') === false) {
|
||||
$resolved_url .= (strpos($resolved_url, '?') === false ? '?' : '&') . 'username=PUsername';
|
||||
}
|
||||
|
||||
return $resolved_url;
|
||||
}
|
||||
|
||||
// GET /tools/birt_proxy/header_json?PID=<order_id>
|
||||
// Hanya bisa diakses dari localhost (127.0.0.1) — dipanggil oleh BIRT scripted dataset
|
||||
// Return JSON semua kolom sp_rpt_hasil_header, PII sudah di-decrypt
|
||||
public function header_json()
|
||||
{
|
||||
$order_id = intval($this->input->get('PID') ?? 0);
|
||||
if ($order_id <= 0) {
|
||||
echo json_encode(['error' => 'PID required']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$row = $this->db_onedev->query("
|
||||
SELECT
|
||||
DATE_FORMAT(T_OrderHeaderDate, '%d-%m-%Y') AS T_OrderHeaderDate,
|
||||
T_OrderHeaderLabNumber,
|
||||
M_TitleName,
|
||||
M_PatientName,
|
||||
M_PatientName_enc,
|
||||
m_sexname AS Gender,
|
||||
M_PatientNoReg,
|
||||
M_PatientDOB,
|
||||
M_PatientDOB_enc,
|
||||
T_OrderHeaderM_PatientAge,
|
||||
M_CompanyName AS CorporateName,
|
||||
M_PatientHp,
|
||||
M_PatientHP_enc,
|
||||
M_PatientEmail,
|
||||
M_PatientEmail_enc,
|
||||
'' AS M_PatientAddressCity,
|
||||
'' AS M_PatientAddressState,
|
||||
M_CompanyName AS CorporateAddress,
|
||||
M_CompanyEmail AS CorporateEmail,
|
||||
M_CompanyPhone AS CorporatePhone,
|
||||
M_CompanyAddressCity AS CorporateAddressCity,
|
||||
'' AS CorporateAddressState,
|
||||
TRIM(CONCAT(IFNULL(pj.M_DoctorPrefix,''),' ',IFNULL(pj.M_DoctorPrefix2,''),' ',IFNULL(pj.M_DoctorName,''),' ',IFNULL(pj.M_DoctorSufix,''),' ',IFNULL(pj.M_DoctorSufix2,''))) AS M_DoctorName,
|
||||
TRIM(CONCAT(IFNULL(pjj.M_DoctorPrefix,''),' ',IFNULL(pjj.M_DoctorPrefix2,''),' ',IFNULL(pjj.M_DoctorName,''),' ',IFNULL(pjj.M_DoctorSufix,''),' ',IFNULL(pjj.M_DoctorSufix2,''))) AS M_DoctorName2,
|
||||
M_PatientID,
|
||||
M_PatientNIP, M_PatientJob, M_PatientPosisi, M_PatientDivisi, M_PatientLocation,
|
||||
CONCAT(IFNULL(M_PatientDepartement,''),' - ',IFNULL(M_PatientNIP,'')) AS M_PatientDepartement
|
||||
FROM t_orderheader
|
||||
LEFT JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID AND M_PatientIsActive = 'Y'
|
||||
LEFT JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID AND M_TitleIsActive = 'Y'
|
||||
JOIN m_company ON T_OrderHeaderM_CompanyID = M_CompanyID AND M_CompanyIsActive = 'Y'
|
||||
LEFT JOIN m_doctor pjj ON T_OrderHeaderPj2M_DoctorID = pjj.M_DoctorID AND pjj.M_DoctorIsActive = 'Y'
|
||||
LEFT JOIN m_doctor pj ON T_OrderHeaderPjM_DoctorID = pj.M_DoctorID AND pj.M_DoctorIsActive = 'Y'
|
||||
WHERE T_OrderHeaderID = ? AND T_OrderHeaderIsActive = 'Y'
|
||||
", [$order_id])->row_array();
|
||||
|
||||
if (!$row) {
|
||||
echo json_encode(['error' => 'order not found']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($row['M_PatientName_enc'] ?? '') ?: ($row['M_PatientName'] ?? '');
|
||||
$dob = $enc->decrypt($row['M_PatientDOB_enc'] ?? '') ?: date('d-m-Y', strtotime($row['M_PatientDOB'] ?? 'now'));
|
||||
$hp = $enc->decrypt($row['M_PatientHP_enc'] ?? '') ?: ($row['M_PatientHp'] ?? '');
|
||||
$email= $enc->decrypt($row['M_PatientEmail_enc']?? '') ?: ($row['M_PatientEmail'] ?? '');
|
||||
|
||||
$addr_row = $this->db_onedev->query("
|
||||
SELECT CONCAT(
|
||||
IFNULL(M_PatientAddressDescription,''),' ',
|
||||
IFNULL((SELECT regional_nm FROM regional WHERE regional_cd = NULLIF(TRIM(M_PatientAddressRegionalCd),'') LIMIT 1),'')
|
||||
) AS addr,
|
||||
M_PatientAddressDescription_enc
|
||||
FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = ? AND M_PatientAddressIsActive = 'Y'
|
||||
ORDER BY M_PatientAddressID LIMIT 1
|
||||
", [$row['M_PatientID']])->row_array();
|
||||
|
||||
$address = '';
|
||||
if ($addr_row) {
|
||||
$address = $enc->decrypt($addr_row['M_PatientAddressDescription_enc'] ?? '') ?: trim($addr_row['addr'] ?? '');
|
||||
}
|
||||
|
||||
$umur = $dob . ' / ' . ($row['T_OrderHeaderM_PatientAge'] ?? '');
|
||||
|
||||
$data = [
|
||||
'T_OrderHeaderDate' => $row['T_OrderHeaderDate'] ?? '',
|
||||
'T_OrderHeaderLabNumber' => $row['T_OrderHeaderLabNumber'] ?? '',
|
||||
'M_PatientName' => trim(($row['M_TitleName'] ?? '') . '. ' . $name),
|
||||
'Gender' => $row['Gender'] ?? '',
|
||||
'M_PatientNoReg' => $row['M_PatientNoReg'] ?? '',
|
||||
'M_PatientDOB' => $dob,
|
||||
'T_OrderHeaderM_PatientAge' => $row['T_OrderHeaderM_PatientAge'] ?? '',
|
||||
'CorporateName' => $row['CorporateName'] ?? '',
|
||||
'M_PatientAddress' => $address,
|
||||
'M_PatientHp' => $hp,
|
||||
'M_PatientEmail' => $email,
|
||||
'M_PatientAddressCity' => '',
|
||||
'M_PatientAddressState' => '',
|
||||
'CorporateAddress' => $row['CorporateAddress'] ?? '',
|
||||
'CorporateEmail' => $row['CorporateEmail'] ?? '',
|
||||
'CorporatePhone' => $row['CorporatePhone'] ?? '',
|
||||
'CorporateAddressCity' => $row['CorporateAddressCity'] ?? '',
|
||||
'CorporateAddressState' => '',
|
||||
'M_DoctorName' => $row['M_DoctorName'] ?? '',
|
||||
'M_DoctorName2' => $row['M_DoctorName2'] ?? '',
|
||||
'Umur' => $umur,
|
||||
'M_PatientNIP' => $row['M_PatientNIP'] ?? '',
|
||||
'M_PatientJob' => $row['M_PatientJob'] ?? '',
|
||||
'M_PatientPosisi' => $row['M_PatientPosisi'] ?? '',
|
||||
'M_PatientDivisi' => $row['M_PatientDivisi'] ?? '',
|
||||
'M_PatientLocation' => $row['M_PatientLocation'] ?? '',
|
||||
'M_PatientDepartement' => $row['M_PatientDepartement'] ?? '',
|
||||
];
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($data);
|
||||
exit;
|
||||
}
|
||||
|
||||
private function _is_internal_app_url($url)
|
||||
{
|
||||
$url = (string) $url;
|
||||
|
||||
return (
|
||||
strpos($url, '/one-api-lab/') === 0 ||
|
||||
strpos($url, '/tools/') === 0 ||
|
||||
strpos($url, '/index.php/') === 0
|
||||
);
|
||||
}
|
||||
|
||||
private function _format_report_string_param($value, $is_internal_app_url = false)
|
||||
{
|
||||
$value = (string) $value;
|
||||
|
||||
if ($is_internal_app_url) {
|
||||
return rawurlencode($value);
|
||||
}
|
||||
|
||||
return rawurlencode("'" . $value . "'");
|
||||
}
|
||||
}
|
||||
450
application/controllers/tools/Birt_proxy_nonlab.php
Normal file
450
application/controllers/tools/Birt_proxy_nonlab.php
Normal file
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* BIRT proxy untuk report nonlab.
|
||||
*
|
||||
* Endpoint:
|
||||
* - GET/POST /tools/birt_proxy_nonlab/stream_by_code
|
||||
* - POST /tools/birt_proxy_nonlab/stream
|
||||
* - GET/POST /tools/birt_proxy_nonlab/get_url
|
||||
* - GET /tools/birt_proxy_nonlab/header_json
|
||||
*
|
||||
* Params:
|
||||
* - report_code, code_report, atau code. Default: RONTGEN-RESULT-P-01
|
||||
* - PID, PSo_ResultEntryID, So_ResultEntryID, result_entry_id, atau PT_OrderHeaderID
|
||||
*/
|
||||
class Birt_proxy_nonlab extends MY_Controller
|
||||
{
|
||||
public $db_onedev;
|
||||
private $birt_base = 'http://localhost:8080';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_encryptor');
|
||||
}
|
||||
|
||||
public function stream_by_code()
|
||||
{
|
||||
$this->_stream_by_code();
|
||||
}
|
||||
|
||||
public function stream()
|
||||
{
|
||||
$this->_stream_by_code();
|
||||
}
|
||||
|
||||
public function get_url()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = $this->_resolve_report_code($prm);
|
||||
$pid = $this->_resolve_pid($prm);
|
||||
|
||||
if ($pid <= 0) {
|
||||
$this->sys_error('PID wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
$order_id = $this->_resolve_order_id_by_result_entry($pid);
|
||||
if ($order_id > 0) {
|
||||
$this->_populate_cache($order_id);
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $pid);
|
||||
if ($url === false) {
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$this->sys_ok(['url' => $url]);
|
||||
}
|
||||
|
||||
public function header_json()
|
||||
{
|
||||
$pid = intval($this->input->get('PID') ?? $this->input->get('So_ResultEntryID') ?? 0);
|
||||
if ($pid <= 0) {
|
||||
echo json_encode(['error' => 'PID required']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$row = $this->db_onedev->query("
|
||||
SELECT
|
||||
T_OrderHeaderID,
|
||||
DATE_FORMAT(T_OrderHeaderDate, '%d-%m-%Y') AS T_OrderHeaderDate,
|
||||
T_OrderHeaderLabNumber,
|
||||
M_TitleName,
|
||||
M_PatientName,
|
||||
M_PatientName_enc,
|
||||
m_sexname AS Gender,
|
||||
M_PatientNoReg,
|
||||
M_PatientDOB,
|
||||
M_PatientDOB_enc,
|
||||
T_OrderHeaderM_PatientAge,
|
||||
M_CompanyName AS CorporateName,
|
||||
M_PatientHp,
|
||||
M_PatientHP_enc,
|
||||
M_PatientEmail,
|
||||
M_PatientEmail_enc,
|
||||
M_CompanyAddress AS CorporateAddress,
|
||||
M_CompanyEmail AS CorporateEmail,
|
||||
M_CompanyPhone AS CorporatePhone,
|
||||
M_CompanyAddressCity AS CorporateAddressCity,
|
||||
TRIM(CONCAT(IFNULL(pj.M_DoctorPrefix, ''), ' ', IFNULL(pj.M_DoctorPrefix2, ''), ' ', IFNULL(pj.M_DoctorName, ''), ' ', IFNULL(pj.M_DoctorSufix, ''), ' ', IFNULL(pj.M_DoctorSufix2, ''))) AS M_DoctorName,
|
||||
TRIM(CONCAT(IFNULL(pjj.M_DoctorPrefix, ''), ' ', IFNULL(pjj.M_DoctorPrefix2, ''), ' ', IFNULL(pjj.M_DoctorName, ''), ' ', IFNULL(pjj.M_DoctorSufix, ''), ' ', IFNULL(pjj.M_DoctorSufix2, ''))) AS M_DoctorName2,
|
||||
M_PatientID,
|
||||
M_PatientNIP,
|
||||
M_PatientJob,
|
||||
M_PatientPosisi,
|
||||
M_PatientDivisi,
|
||||
M_PatientLocation,
|
||||
CONCAT(IFNULL(M_PatientDepartement, ''), ' - ', IFNULL(M_PatientNIP, '')) AS M_PatientDepartement
|
||||
FROM t_orderheader
|
||||
JOIN so_resultentry ON So_ResultEntryT_OrderHeaderID = T_OrderHeaderID
|
||||
AND So_ResultEntryIsActive = 'Y'
|
||||
LEFT JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
AND M_PatientIsActive = 'Y'
|
||||
LEFT JOIN m_title ON M_PatientM_TitleID = M_TitleID
|
||||
AND M_TitleIsActive = 'Y'
|
||||
LEFT JOIN m_company ON T_OrderHeaderM_CompanyID = M_CompanyID
|
||||
AND M_CompanyIsActive = 'Y'
|
||||
LEFT JOIN m_sex ON M_PatientM_SexID = M_SexID
|
||||
LEFT JOIN m_doctor pjj ON T_OrderHeaderPj2M_DoctorID = pjj.M_DoctorID
|
||||
AND pjj.M_DoctorIsActive = 'Y'
|
||||
LEFT JOIN m_doctor pj ON T_OrderHeaderPjM_DoctorID = pj.M_DoctorID
|
||||
AND pj.M_DoctorIsActive = 'Y'
|
||||
WHERE So_ResultEntryID = ?
|
||||
AND T_OrderHeaderIsActive = 'Y'
|
||||
GROUP BY T_OrderHeaderID
|
||||
LIMIT 1
|
||||
", [$pid])->row_array();
|
||||
|
||||
if (!$row) {
|
||||
echo json_encode(['error' => 'result entry not found']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($row['M_PatientName_enc'] ?? '') ?: ($row['M_PatientName'] ?? '');
|
||||
$dob = $enc->decrypt($row['M_PatientDOB_enc'] ?? '') ?: date('d-m-Y', strtotime($row['M_PatientDOB'] ?? 'now'));
|
||||
$hp = $enc->decrypt($row['M_PatientHP_enc'] ?? '') ?: ($row['M_PatientHp'] ?? '');
|
||||
$email = $enc->decrypt($row['M_PatientEmail_enc'] ?? '') ?: ($row['M_PatientEmail'] ?? '');
|
||||
|
||||
$addr_row = $this->db_onedev->query("
|
||||
SELECT
|
||||
CONCAT(
|
||||
IFNULL(M_PatientAddressDescription, ''), ' ',
|
||||
IFNULL(M_DistrictName, ''), ' ',
|
||||
IFNULL(M_CityName, '')
|
||||
) AS addr,
|
||||
M_PatientAddressDescription_enc
|
||||
FROM m_patientaddress AS p
|
||||
LEFT JOIN (
|
||||
SELECT regional_cd, regional_nm AS M_KelurahanName, pro_cd, kab_cd, kec_cd
|
||||
FROM regional
|
||||
) reg_kel ON NULLIF(TRIM(p.M_PatientAddressRegionalCd), '') = reg_kel.regional_cd
|
||||
LEFT JOIN (
|
||||
SELECT regional_cd, regional_nm AS M_DistrictName
|
||||
FROM regional
|
||||
) reg_kec ON CONCAT(reg_kel.pro_cd, reg_kel.kab_cd, reg_kel.kec_cd, '000') = reg_kec.regional_cd
|
||||
LEFT JOIN (
|
||||
SELECT regional_cd, regional_nm AS M_CityName
|
||||
FROM regional
|
||||
) reg_kab ON CONCAT(reg_kel.pro_cd, reg_kel.kab_cd, '000000') = reg_kab.regional_cd
|
||||
WHERE M_PatientAddressM_PatientID = ?
|
||||
AND M_PatientAddressIsActive = 'Y'
|
||||
ORDER BY (M_PatientAddressNote = 'Utama') DESC, M_PatientAddressID
|
||||
LIMIT 1
|
||||
", [$row['M_PatientID']])->row_array();
|
||||
|
||||
$address = '';
|
||||
if ($addr_row) {
|
||||
$address = $enc->decrypt($addr_row['M_PatientAddressDescription_enc'] ?? '') ?: trim($addr_row['addr'] ?? '');
|
||||
}
|
||||
|
||||
if (!empty($row['T_OrderHeaderID'])) {
|
||||
$this->_populate_cache((int) $row['T_OrderHeaderID']);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'T_OrderHeaderID' => (int) ($row['T_OrderHeaderID'] ?? 0),
|
||||
'T_OrderHeaderDate' => $row['T_OrderHeaderDate'] ?? '',
|
||||
'T_OrderHeaderLabNumber' => $row['T_OrderHeaderLabNumber'] ?? '',
|
||||
'M_PatientName' => trim(($row['M_TitleName'] ?? '') . '. ' . $name),
|
||||
'Gender' => $row['Gender'] ?? '',
|
||||
'M_PatientNoReg' => $row['M_PatientNoReg'] ?? '',
|
||||
'M_PatientDOB' => $dob,
|
||||
'T_OrderHeaderM_PatientAge' => $row['T_OrderHeaderM_PatientAge'] ?? '',
|
||||
'CorporateName' => $row['CorporateName'] ?? '',
|
||||
'M_PatientAddress' => $address,
|
||||
'M_PatientHp' => $hp,
|
||||
'M_PatientEmail' => $email,
|
||||
'M_PatientAddressCity' => '',
|
||||
'M_PatientAddressState' => $address,
|
||||
'CorporateAddress' => $row['CorporateAddress'] ?? '',
|
||||
'CorporateEmail' => $row['CorporateEmail'] ?? '',
|
||||
'CorporatePhone' => $row['CorporatePhone'] ?? '',
|
||||
'CorporateAddressCity' => $row['CorporateAddressCity'] ?? '',
|
||||
'CorporateAddressState' => '',
|
||||
'M_DoctorName' => $row['M_DoctorName'] ?? '',
|
||||
'M_DoctorName2' => $row['M_DoctorName2'] ?? '',
|
||||
'Umur' => $dob . ' / ' . ($row['T_OrderHeaderM_PatientAge'] ?? ''),
|
||||
'M_PatientNIP' => $row['M_PatientNIP'] ?? '',
|
||||
'M_PatientJob' => $row['M_PatientJob'] ?? '',
|
||||
'M_PatientPosisi' => $row['M_PatientPosisi'] ?? '',
|
||||
'M_PatientDivisi' => $row['M_PatientDivisi'] ?? '',
|
||||
'M_PatientLocation' => $row['M_PatientLocation'] ?? '',
|
||||
'M_PatientDepartement' => $row['M_PatientDepartement'] ?? '',
|
||||
];
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($data);
|
||||
exit;
|
||||
}
|
||||
|
||||
private function _stream_by_code()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
return;
|
||||
}
|
||||
|
||||
$prm = $this->sys_input;
|
||||
$report_code = $this->_resolve_report_code($prm);
|
||||
$pid = $this->_resolve_pid($prm);
|
||||
|
||||
if ($pid <= 0) {
|
||||
$this->sys_error('PID wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
$cache_id = null;
|
||||
$order_id = $this->_resolve_order_id_by_result_entry($pid);
|
||||
if ($order_id > 0) {
|
||||
$cache_id = $this->_populate_cache($order_id);
|
||||
}
|
||||
|
||||
$url = $this->_build_birt_url_by_code($report_code, $pid);
|
||||
if ($url === false) {
|
||||
$this->_delete_cache($cache_id);
|
||||
$this->sys_error("Report code tidak ditemukan: {$report_code}");
|
||||
return;
|
||||
}
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'timeout' => 120,
|
||||
'method' => 'GET',
|
||||
],
|
||||
]);
|
||||
|
||||
$pdf = @file_get_contents($this->_resolve_fetch_url($url), false, $context);
|
||||
$this->_delete_cache($cache_id);
|
||||
|
||||
if ($pdf === false) {
|
||||
$this->sys_error('Gagal generate report dari BIRT server');
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = $report_code . '_' . $pid . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
exit;
|
||||
}
|
||||
|
||||
private function _resolve_report_code($prm)
|
||||
{
|
||||
$report_code = trim($prm['report_code'] ?? $prm['code_report'] ?? $prm['code'] ?? '');
|
||||
|
||||
return $report_code !== '' ? $report_code : 'RONTGEN-RESULT-P-01';
|
||||
}
|
||||
|
||||
private function _resolve_pid($prm)
|
||||
{
|
||||
return intval(
|
||||
$prm['PID'] ??
|
||||
$prm['PSo_ResultEntryID'] ??
|
||||
$prm['So_ResultEntryID'] ??
|
||||
$prm['result_entry_id'] ??
|
||||
$prm['PT_OrderHeaderID'] ??
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
private function _build_birt_url_by_code($report_code, $pid)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT Print_TransactionUrl
|
||||
FROM print_transaction
|
||||
WHERE Print_TransactionCode = ?
|
||||
LIMIT 1",
|
||||
[$report_code]
|
||||
)->row_array();
|
||||
|
||||
if (!$row) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$username = $this->_resolve_report_username();
|
||||
$tm = round(microtime(true) * 1000);
|
||||
$url = $row['Print_TransactionUrl'];
|
||||
|
||||
$replacements = [
|
||||
'PUsername' => $this->_format_report_string_param($username),
|
||||
'PT_OrderHeaderID' => $pid,
|
||||
'PSo_ResultEntryID' => $pid,
|
||||
'TS' => $tm,
|
||||
];
|
||||
|
||||
foreach ($replacements as $placeholder => $value) {
|
||||
$url = str_replace($placeholder, $value, $url);
|
||||
}
|
||||
|
||||
$url = preg_replace('/([?&]PID=)PID([&#]|$)/', '${1}' . $pid . '$2', $url);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
private function _resolve_fetch_url($url)
|
||||
{
|
||||
$url = trim((string) $url);
|
||||
|
||||
if ($url === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (preg_match('#^https?://#i', $url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/birt/') === 0) {
|
||||
return $this->birt_base . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/one-api-lab/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '/tools/') === 0 || strpos($url, '/index.php/') === 0) {
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
|
||||
return $scheme . '://' . $host . '/one-api-lab' . $url;
|
||||
}
|
||||
|
||||
return $this->birt_base . $url;
|
||||
}
|
||||
|
||||
private function _resolve_order_id_by_result_entry($result_entry_id)
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT So_ResultEntryT_OrderHeaderID
|
||||
FROM so_resultentry
|
||||
WHERE So_ResultEntryID = ?
|
||||
AND So_ResultEntryIsActive = 'Y'
|
||||
LIMIT 1",
|
||||
[$result_entry_id]
|
||||
)->row_array();
|
||||
|
||||
return intval($row['So_ResultEntryT_OrderHeaderID'] ?? 0);
|
||||
}
|
||||
|
||||
private function _populate_cache($order_id)
|
||||
{
|
||||
$patient = $this->db_onedev->query(
|
||||
"SELECT M_PatientID,
|
||||
M_PatientName_enc, M_PatientDOB_enc, M_PatientHP_enc,
|
||||
M_PatientEmail_enc, M_PatientDOB
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ?
|
||||
AND T_OrderHeaderIsActive = 'Y'
|
||||
LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
if (!$patient) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$addr = $this->db_onedev->query(
|
||||
"SELECT M_PatientAddressDescription_enc
|
||||
FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = ?
|
||||
AND M_PatientAddressIsActive = 'Y'
|
||||
ORDER BY (M_PatientAddressNote = 'Utama') DESC, M_PatientAddressID
|
||||
LIMIT 1",
|
||||
[$patient['M_PatientID']]
|
||||
)->row_array();
|
||||
|
||||
$enc = $this->ibl_encryptor;
|
||||
$name = $enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? '';
|
||||
$dob = $enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now'));
|
||||
$hp = $enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? '';
|
||||
$email = $enc->decrypt($patient['M_PatientEmail_enc'] ?? '') ?? '';
|
||||
$address = $enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? '';
|
||||
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache
|
||||
WHERE ppc_order_id = ?
|
||||
OR ppc_created < NOW() - INTERVAL 5 MINUTE",
|
||||
[$order_id]
|
||||
);
|
||||
|
||||
$this->db_onedev->query(
|
||||
"INSERT INTO patient_print_cache
|
||||
(ppc_order_id, ppc_patient_id, ppc_name, ppc_dob, ppc_hp, ppc_email, ppc_address, ppc_created)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, NOW())",
|
||||
[$order_id, $patient['M_PatientID'], $name, $dob, $hp, $email, $address]
|
||||
);
|
||||
|
||||
return $this->db_onedev->insert_id();
|
||||
}
|
||||
|
||||
private function _delete_cache($cache_id)
|
||||
{
|
||||
if ($cache_id) {
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_id = ?",
|
||||
[$cache_id]
|
||||
);
|
||||
}
|
||||
|
||||
$this->db_onedev->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_created < NOW() - INTERVAL 5 MINUTE"
|
||||
);
|
||||
}
|
||||
|
||||
private function _resolve_report_username()
|
||||
{
|
||||
if (!empty($this->sys_user['M_StaffName'])) {
|
||||
return trim($this->sys_user['M_StaffName']);
|
||||
}
|
||||
|
||||
if (!empty($this->sys_user['M_UserUsername'])) {
|
||||
return trim($this->sys_user['M_UserUsername']);
|
||||
}
|
||||
|
||||
if (!empty($this->sys_user['userName'])) {
|
||||
return trim($this->sys_user['userName']);
|
||||
}
|
||||
|
||||
return 'ADMIN';
|
||||
}
|
||||
|
||||
private function _format_report_string_param($value)
|
||||
{
|
||||
return rawurlencode("'" . (string) $value . "'");
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,15 @@ Content-Type: application/json
|
||||
"T_OrderHeaderLabNumber": "{{lab_number}}"
|
||||
}
|
||||
|
||||
### Merge langsung dari qr_printout (T_OrderHeaderID)
|
||||
POST http://10.9.20.31/one-api-lab/tools/ibl_merge_report_admin/merge_from_qr
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"token": "{{token}}",
|
||||
"T_OrderHeaderID": {{order_header_id}}
|
||||
}
|
||||
|
||||
### Admin preview via backend tools
|
||||
POST http://10.9.20.31/one-api-lab/tools/ibl_merge_report_admin/preview
|
||||
Content-Type: application/json
|
||||
|
||||
@@ -47,6 +47,37 @@ class Ibl_merge_report_admin extends MY_Controller
|
||||
exit;
|
||||
}
|
||||
|
||||
public function merge_from_qr()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
$this->sys_error('Invalid Token');
|
||||
exit;
|
||||
}
|
||||
|
||||
$auth = $this->ibl_merge_report_gateway->is_admin_group_allowed($this->sys_user['M_UserID']);
|
||||
if ($auth['status'] !== 'OK') {
|
||||
$this->sys_error($auth['code'] . ' - ' . $auth['message']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$orderHeaderId = isset($this->sys_input['T_OrderHeaderID']) ? (int) $this->sys_input['T_OrderHeaderID'] : 0;
|
||||
if ($orderHeaderId <= 0) {
|
||||
$this->sys_error('T_ORDERHEADERID_REQUIRED - T_OrderHeaderID wajib diisi.');
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $this->ibl_merge_report_gateway->stream_from_qr_printout($orderHeaderId);
|
||||
if ($result['status'] !== 'OK') {
|
||||
$this->sys_error($result['code'] . ' - ' . $result['message']);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $result['data']['payload']['name'] . '"');
|
||||
echo $result['data']['body'];
|
||||
exit;
|
||||
}
|
||||
|
||||
public function preview()
|
||||
{
|
||||
if (!$this->isLogin) {
|
||||
|
||||
@@ -10,6 +10,7 @@ class Inform_consent extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -62,22 +63,19 @@ class Inform_consent extends MY_Controller
|
||||
|
||||
private function get_patient_data($orderHeaderId)
|
||||
{
|
||||
$cacheId = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = "SELECT
|
||||
h.T_OrderHeaderID,
|
||||
h.T_OrderHeaderDate,
|
||||
DATE_FORMAT(h.T_OrderHeaderDate, '%d-%m-%Y') as tanggal,
|
||||
DATE_FORMAT(h.T_OrderHeaderDate, '%H:%i') as jam,
|
||||
p.M_PatientID,
|
||||
p.M_PatientNoReg,
|
||||
CONCAT(
|
||||
IF(TRIM(IFNULL(t.M_TitleName,''))='', '', CONCAT(TRIM(IFNULL(t.M_TitleName,'')), '. ')),
|
||||
TRIM(IFNULL(p.M_PatientPrefix,'')), ' ', TRIM(IFNULL(p.M_PatientName,'')), ' ', TRIM(IFNULL(p.M_PatientSuffix,''))
|
||||
) AS patient_name,
|
||||
p.M_PatientNoReg, p.M_PatientPrefix, p.M_PatientSuffix,
|
||||
t.M_TitleName,
|
||||
s.M_SexCode,
|
||||
IFNULL(p.M_PatientPOB,'') as pob,
|
||||
DATE_FORMAT(p.M_PatientDOB, '%d-%m-%Y') as dob,
|
||||
IFNULL(pa.M_PatientAddressDescription,'') as alamat,
|
||||
IFNULL(p.M_PatientHP,'') as phone,
|
||||
p.M_PatientName_enc, p.M_PatientDOB_enc, p.M_PatientPOB_enc,
|
||||
p.M_PatientDOB, p.M_PatientHP_enc,
|
||||
pa.M_PatientAddressDescription_enc,
|
||||
IFNULL(c.M_CompanyName,'') as company_name,
|
||||
(
|
||||
SELECT ps.Patient_SignatureUrl
|
||||
@@ -98,10 +96,39 @@ class Inform_consent extends MY_Controller
|
||||
WHERE h.T_OrderHeaderID = ?
|
||||
LIMIT 1";
|
||||
$qry = $this->db_onedev->query($sql, [$orderHeaderId]);
|
||||
if (!$qry) {
|
||||
return false;
|
||||
}
|
||||
return $qry->row_array();
|
||||
if (!$qry) return false;
|
||||
$row = $qry->row_array();
|
||||
if (!$row) return false;
|
||||
|
||||
$row = $this->ibl_patient_decrypt->decrypt_row($row);
|
||||
$title = trim($row['M_TitleName'] ?? '');
|
||||
$cacheRow = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_order_id = ?
|
||||
ORDER BY ppc_id DESC
|
||||
LIMIT 1",
|
||||
[$orderHeaderId]
|
||||
)->row_array();
|
||||
$printName = trim($cacheRow['ppc_name'] ?? '');
|
||||
$namePart = trim($printName !== '' ? $printName : ($row['M_PatientName'] ?? ''));
|
||||
$row['patient_name'] = trim(
|
||||
($title ? $title . ' ' : '') .
|
||||
trim($row['M_PatientPrefix'] ?? '') . ' ' .
|
||||
$namePart . ' ' .
|
||||
trim($row['M_PatientSuffix'] ?? '')
|
||||
);
|
||||
$row['patient_sign_name'] = trim(
|
||||
trim($row['M_PatientPrefix'] ?? '') . ' ' .
|
||||
$namePart . ' ' .
|
||||
trim($row['M_PatientSuffix'] ?? '')
|
||||
);
|
||||
$row['dob'] = $row['M_PatientDOB'];
|
||||
$row['pob'] = $row['M_PatientPOB'] ?? '';
|
||||
$row['phone'] = $row['M_PatientHP'] ?? '';
|
||||
$row['alamat'] = $row['M_PatientAddressDescription'] ?? '';
|
||||
$this->ibl_patient_decrypt->delete_cache($cacheId);
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function get_consent_content()
|
||||
@@ -243,7 +270,7 @@ class Inform_consent extends MY_Controller
|
||||
if ($signaturePath !== null) {
|
||||
$pdf->Image($signaturePath, $rightX - 6, $signBottom - 23, 42, 12);
|
||||
}
|
||||
$this->draw_full_name_block($pdf, $rightX, $signBottom - 9, $rightW, trim(preg_replace('/\s+/', ' ', $patient['patient_name'])));
|
||||
$this->draw_full_name_block($pdf, $rightX, $signBottom - 9, $rightW, trim(preg_replace('/\s+/', ' ', $patient['patient_sign_name'])));
|
||||
|
||||
$boxEndY = min($this->pageContentBottom, $signBottom + 2);
|
||||
$pdf->Rect(10, $boxStartY, 190, max(10, $boxEndY - $boxStartY));
|
||||
|
||||
@@ -8,6 +8,7 @@ class Inform_consent_cpmi extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -59,12 +60,17 @@ class Inform_consent_cpmi extends MY_Controller
|
||||
|
||||
private function get_patient_data($orderHeaderId)
|
||||
{
|
||||
$cacheId = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = "SELECT
|
||||
h.T_OrderHeaderID,
|
||||
DATE_FORMAT(h.T_OrderHeaderDate, '%d-%m-%Y') as tanggal,
|
||||
IFNULL(h.T_OrderHeaderM_PatientAge, '') as age,
|
||||
p.M_PatientID,
|
||||
CONCAT(TRIM(IFNULL(t.M_TitleName,'')), ' ', TRIM(IFNULL(p.M_PatientPrefix,'')), ' ', TRIM(IFNULL(p.M_PatientName,'')), ' ', TRIM(IFNULL(p.M_PatientSuffix,''))) AS patient_name,
|
||||
IFNULL(t.M_TitleName, '') as M_TitleName,
|
||||
IFNULL(p.M_PatientPrefix, '') as M_PatientPrefix,
|
||||
IFNULL(p.M_PatientName, '') as M_PatientName,
|
||||
IFNULL(p.M_PatientSuffix, '') as M_PatientSuffix,
|
||||
IFNULL(s.M_SexCode, '') as sex_code,
|
||||
DATE_FORMAT(p.M_PatientDOB, '%d-%m-%Y') as dob,
|
||||
IFNULL(pa.M_PatientAddressDescription,'') as alamat,
|
||||
@@ -86,7 +92,40 @@ class Inform_consent_cpmi extends MY_Controller
|
||||
WHERE h.T_OrderHeaderID = ?
|
||||
LIMIT 1";
|
||||
$qry = $this->db_onedev->query($sql, [$orderHeaderId]);
|
||||
return $qry ? $qry->row_array() : null;
|
||||
if (!$qry) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$row = $qry->row_array();
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cacheRow = $this->db_onedev->query(
|
||||
"SELECT ppc_name
|
||||
FROM patient_print_cache
|
||||
WHERE ppc_order_id = ?
|
||||
ORDER BY ppc_id DESC
|
||||
LIMIT 1",
|
||||
[$orderHeaderId]
|
||||
)->row_array();
|
||||
$printName = trim($cacheRow['ppc_name'] ?? '');
|
||||
$namePart = trim($printName !== '' ? $printName : ($row['M_PatientName'] ?? ''));
|
||||
$title = trim((string)($row['M_TitleName'] ?? ''));
|
||||
$row['patient_name'] = trim(
|
||||
($title ? $title . ' ' : '') .
|
||||
trim((string)($row['M_PatientPrefix'] ?? '')) . ' ' .
|
||||
$namePart . ' ' .
|
||||
trim((string)($row['M_PatientSuffix'] ?? ''))
|
||||
);
|
||||
$row['patient_sign_name'] = trim(
|
||||
trim((string)($row['M_PatientPrefix'] ?? '')) . ' ' .
|
||||
$namePart . ' ' .
|
||||
trim((string)($row['M_PatientSuffix'] ?? ''))
|
||||
);
|
||||
|
||||
$this->ibl_patient_decrypt->delete_cache($cacheId);
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function get_consent_content()
|
||||
@@ -178,7 +217,7 @@ class Inform_consent_cpmi extends MY_Controller
|
||||
}
|
||||
$pdf->SetFont('Arial', 'U', 8.5);
|
||||
$pdf->SetXY(149, $y);
|
||||
$pdf->Cell(54, 5, $this->safe_text(trim(preg_replace('/\s+/', ' ', $patient['patient_name']))), 0, 1, 'C');
|
||||
$pdf->Cell(54, 5, $this->safe_text(trim(preg_replace('/\s+/', ' ', $patient['patient_sign_name']))), 0, 1, 'C');
|
||||
|
||||
$y += 8;
|
||||
$pdf->Line(14, $y, 196, $y);
|
||||
|
||||
@@ -9,6 +9,7 @@ class Kartu_kontrol extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_lab = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -53,10 +54,15 @@ class Kartu_kontrol extends MY_Controller
|
||||
|
||||
private function get_data($pid)
|
||||
{
|
||||
// Populate decrypt cache sebelum call SP
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($pid);
|
||||
|
||||
$qry = $this->db_lab->query("CALL sp_rpt_fo_001(?, 'fpdf')", [$pid]);
|
||||
if (!$qry) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Hapus cache setelah SP selesai
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
|
||||
if (!$qry) return [];
|
||||
return $qry->result_array();
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ class Medical_checkup_report extends MY_Controller
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('Generateqrreport');
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -221,18 +222,10 @@ class Medical_checkup_report extends MY_Controller
|
||||
IFNULL(NULLIF(TRIM(IFNULL(p.M_PatientDivisi, '')), ''), '-')
|
||||
) AS departemen_npk,
|
||||
IFNULL(s.M_SexName, '-') AS jenis_kelamin,
|
||||
CONCAT(
|
||||
IF(TRIM(IFNULL(t.M_TitleName, '')) = '', '', CONCAT(TRIM(t.M_TitleName), '. ')),
|
||||
TRIM(IFNULL(p.M_PatientPrefix, '')), ' ',
|
||||
TRIM(IFNULL(p.M_PatientName, '')), ' ',
|
||||
TRIM(IFNULL(p.M_PatientSuffix, ''))
|
||||
) AS nama_pasien,
|
||||
CONCAT(
|
||||
IFNULL(DATE_FORMAT(p.M_PatientDOB, '%d-%m-%Y'), '-'),
|
||||
' / ',
|
||||
IFNULL(NULLIF(TRIM(IFNULL(h.T_OrderHeaderM_PatientAge, '')), ''), '-')
|
||||
) AS tgl_lahir_usia,
|
||||
IFNULL(pa.M_PatientAddressDescription, '-') AS alamat_pasien
|
||||
p.M_PatientPrefix, p.M_PatientSuffix, t.M_TitleName,
|
||||
p.M_PatientName_enc, p.M_PatientDOB_enc,
|
||||
p.M_PatientDOB, h.T_OrderHeaderM_PatientAge,
|
||||
pa.M_PatientAddressDescription_enc
|
||||
FROM t_orderheader h
|
||||
JOIN m_patient p ON p.M_PatientID = h.T_OrderHeaderM_PatientID
|
||||
LEFT JOIN m_title t ON t.M_TitleID = p.M_PatientM_TitleID
|
||||
@@ -244,10 +237,22 @@ class Medical_checkup_report extends MY_Controller
|
||||
WHERE h.T_OrderHeaderID = ?
|
||||
LIMIT 1";
|
||||
$qry = $this->db_onedev->query($sql, [$orderHeaderId]);
|
||||
if (!$qry) {
|
||||
return false;
|
||||
}
|
||||
return $qry->row_array();
|
||||
if (!$qry) return false;
|
||||
$row = $qry->row_array();
|
||||
if (!$row) return false;
|
||||
|
||||
$row = $this->ibl_patient_decrypt->decrypt_row($row);
|
||||
$title = trim($row['M_TitleName'] ?? '');
|
||||
$row['nama_pasien'] = trim(
|
||||
($title ? $title . '. ' : '') .
|
||||
trim($row['M_PatientPrefix'] ?? '') . ' ' .
|
||||
trim($row['M_PatientName'] ?? '') . ' ' .
|
||||
trim($row['M_PatientSuffix'] ?? '')
|
||||
);
|
||||
$row['tgl_lahir_usia'] = trim($row['M_PatientDOB'] ?? '-') . ' / ' .
|
||||
trim($row['T_OrderHeaderM_PatientAge'] ?? '-');
|
||||
$row['alamat_pasien'] = $row['M_PatientAddressDescription'] ?? '-';
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function get_result_rows($orderHeaderId)
|
||||
|
||||
@@ -12,6 +12,25 @@ class Merge_report extends MY_Controller {
|
||||
$this->preview($id);
|
||||
}
|
||||
|
||||
public function preview_qr($id = null) {
|
||||
if ($id === null || !is_numeric($id)) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['status' => 'ERR', 'message' => 'T_ORDER_HEADER_ID_INVALID - ID tidak valid.']);
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->ibl_merge_report_gateway->stream_from_qr_printout((int) $id);
|
||||
if ($result['status'] !== 'OK') {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['status' => 'ERR', 'message' => $result['code'] . ' - ' . $result['message']]);
|
||||
return;
|
||||
}
|
||||
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $result['data']['payload']['name'] . '"');
|
||||
echo $result['data']['body'];
|
||||
}
|
||||
|
||||
public function preview($id = null) {
|
||||
if ($id === null || !is_numeric($id)) {
|
||||
header('Content-Type: application/json');
|
||||
|
||||
430
application/controllers/tools/Outgoingref_v3.php
Normal file
430
application/controllers/tools/Outgoingref_v3.php
Normal file
@@ -0,0 +1,430 @@
|
||||
<?php
|
||||
class OutgoingRef_v3 extends MY_Controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db = $this->load->database("onedev", true);
|
||||
}
|
||||
function get_nonlab($type, $xid)
|
||||
{
|
||||
//mikro
|
||||
if ($type == "mikro") {
|
||||
$sql = "select * from other_mikro where Other_MikroID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "mikro";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
$sql = "select * from other_mikrodetails where Other_MikroDetailsOther_MikroID=? and
|
||||
Other_MikroDetailsIsActive = 'Y' ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
//cytologi
|
||||
if ($type == "cytologi") {
|
||||
$sql = "select * from other_cytologi where Other_CytologiID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "cytologi";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
$sql = "select * from other_cytologidetails where Other_CytologiDetailsOther_CytologiID=? and
|
||||
Other_CytologiDetailsIsActive = 'Y' ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
//fna
|
||||
if ($type == "fna") {
|
||||
$sql = "select * from other_fna where Other_FnaID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "fna";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
$sql = "select * from other_fnadetails where Other_FnaDetailsOther_FnaID=? and
|
||||
Other_FnaDetailsIsActive = 'Y' ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
//papsmear
|
||||
//
|
||||
if ($type == "papsmear") {
|
||||
$sql = "select * from other_papsmear where Other_PapSmearID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "papsmear";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
$result["detail"] = array();
|
||||
//bahan
|
||||
$sql = "select * from other_papsmearbahan where Other_PapSmearBahanOther_PapSmearID = ?
|
||||
and Other_PapSmearBahanIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["bahan"] = $qry->result_array();
|
||||
}
|
||||
//category
|
||||
$sql = "select * from other_papsmearcategory
|
||||
where Other_PapsmearCategoryOther_PapSmearID = ?
|
||||
and Other_PapsmearCategoryIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["category"] = $qry->result_array();
|
||||
}
|
||||
// check
|
||||
$sql = "select * from other_papsmearcheck
|
||||
where Other_PapSmearCheckOther_PapSmearID= ?
|
||||
and Other_PapSmearCheckIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["check"] = $qry->result_array();
|
||||
}
|
||||
// details
|
||||
$sql = "select * from other_papsmeardetails
|
||||
where Other_PapSmearDetailsOther_PapSmearID= ?
|
||||
and Other_PapSmearDetailsIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["details"] = $qry->result_array();
|
||||
}
|
||||
// maturasi
|
||||
$sql = "select * from other_papsmearmaturasi
|
||||
where Other_PapSmearMaturasiOther_PapSmearID = ?
|
||||
and Other_PapSmearMaturasiIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["maturasi"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
//lcprep
|
||||
//
|
||||
if ($type == "lcprep") {
|
||||
$sql = "select * from other_lcprep where Other_LcprepID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "lcprep";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
$result["detail"] = array();
|
||||
//adekuasi
|
||||
$sql = "select * from other_lcprepadekuasi where Other_LcprepAdekuasiOther_LcprepID = ?
|
||||
and Other_LcprepAdekuasiIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["adekuasi"] = $qry->result_array();
|
||||
}
|
||||
//interpretasi
|
||||
$sql = "select * from other_lcprepinterpretasi
|
||||
where Other_PapsmearInterpretasiOther_LcprepID = ?
|
||||
and Other_PapsmearInterpretasiIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["interpretasi"] = $qry->result_array();
|
||||
}
|
||||
// details
|
||||
$sql = "select * from other_lcprepdetails
|
||||
where Other_LcprepDetailsOther_LcprepID= ?
|
||||
and Other_LcprepDetailsIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["details"] = $qry->result_array();
|
||||
}
|
||||
// kategoriumum
|
||||
$sql = "select * from other_lcprepkategoriumum
|
||||
where Other_LcprepKategoriUmumOther_LcprepID = ?
|
||||
and Other_LcprepKategoriUmumIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["kategoriumum"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
function process_nonlab($incomingRefDetailID)
|
||||
{
|
||||
//mikro
|
||||
$sql = "select ifnull(Other_MikroID,0) mikroID
|
||||
from incoming_ref_detail
|
||||
join t_orderdetail on T_OrderDetailT_OrderHeaderID = incomingRefDetailNewT_OrderHeaderID
|
||||
and T_OrderDetailT_TestID = incomingRefDetailT_TestID and T_OrderDetailIsActive = 'Y'
|
||||
left join other_mikro on T_OrderDetailID = Other_MikroT_OrderDetailID and
|
||||
Other_MikroIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$mikroID = $rows[0]["mikroID"];
|
||||
$nl = "";
|
||||
if ($mikroID > 0) {
|
||||
$nl = $this->get_nonlab("mikro", $mikroID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
|
||||
//papsmear
|
||||
$sql = "select ifnull(Other_PapSmearID,0) papsmearID
|
||||
from incoming_ref_detail
|
||||
join t_orderdetail on T_OrderDetailT_OrderHeaderID = incomingRefDetailNewT_OrderHeaderID
|
||||
and T_OrderDetailT_TestID = incomingRefDetailT_TestID and T_OrderDetailIsActive = 'Y'
|
||||
left join other_papsmear on T_OrderDetailID = Other_PapSmearT_OrderDetailID and
|
||||
Other_PapSmearIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$papsmearID = $rows[0]["papsmearID"];
|
||||
$nl = "";
|
||||
if ($papsmear > 0) {
|
||||
$nl = $this->get_nonlab("papsmear", $papsmearID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
|
||||
//lcprep
|
||||
$sql = "select ifnull(Other_LcprepID,0) lcprepID
|
||||
from incoming_ref_detail
|
||||
join t_orderdetail on T_OrderDetailT_OrderHeaderID = incomingRefDetailNewT_OrderHeaderID
|
||||
and T_OrderDetailT_TestID = incomingRefDetailT_TestID and T_OrderDetailIsActive = 'Y'
|
||||
left join other_lcprep on T_OrderDetailID = Other_LcprepT_OrderDetailID and
|
||||
Other_LcprepIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$lcprepID = $rows[0]["lcprepID"];
|
||||
$nl = "";
|
||||
if ($lcprepID > 0) {
|
||||
$nl = $this->get_nonlab("lcprep", $lcprepID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
|
||||
//fna
|
||||
$sql = "select ifnull(Other_FnaID,0) fnaID
|
||||
from incoming_ref_detail
|
||||
join t_orderdetail on T_OrderDetailT_OrderHeaderID = incomingRefDetailNewT_OrderHeaderID
|
||||
and T_OrderDetailT_TestID = incomingRefDetailT_TestID and T_OrderDetailIsActive = 'Y'
|
||||
left join other_fna on T_OrderDetailID = Other_FnaT_OrderDetailID and
|
||||
Other_FnaIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$fnaID = $rows[0]["fnaID"];
|
||||
$nl = "";
|
||||
if ($fnaID > 0) {
|
||||
$nl = $this->get_nonlab("fna", $fnaID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
//
|
||||
//cytology
|
||||
$sql = "select ifnull(Other_CytologiID,0) cytologiID
|
||||
from incoming_ref_detail
|
||||
join t_orderdetail on T_OrderDetailT_OrderHeaderID = incomingRefDetailNewT_OrderHeaderID
|
||||
and T_OrderDetailT_TestID = incomingRefDetailT_TestID and T_OrderDetailIsActive = 'Y'
|
||||
left join other_cytologi on T_OrderDetailID = Other_CytologiT_OrderDetailID and
|
||||
Other_CytologiIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$cytologiID = $rows[0]["cytologiID"];
|
||||
$nl = "";
|
||||
if ($cytologiID > 0) {
|
||||
$nl = $this->get_nonlab("cytologi", $cytologiID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
function process()
|
||||
{
|
||||
$sql = "select tx_branch_status.*, M_BranchName
|
||||
from tx_branch_status
|
||||
join m_branch on TxBranchStatusM_BranchID = M_BranchID
|
||||
where TxBranchStatusIsSent = 'N' and TxBranchStatusRetry < 5
|
||||
limit 0,20";
|
||||
$qry = $this->db->query($sql);
|
||||
$sql_update = "update tx_branch_status set TxBranchStatusIsSent=?,
|
||||
TxBranchStatusRetry = TxBranchStatusRetry + 1
|
||||
where TxBranchStatusID = ?";
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
foreach ($rows as $r) {
|
||||
$param = $r["TxBranchStatusJson"];
|
||||
$stage = $r["TxBranchStatusStage"];
|
||||
$ipAddress = $r["TxBranchStatusM_BranchIP"];
|
||||
$branchName = $r["M_BranchName"];
|
||||
$txID = $r["TxBranchStatusID"];
|
||||
if ($stage == "VALIDATION") {
|
||||
//cek nonlab
|
||||
$j_param = json_decode($param, true);
|
||||
foreach ($j_param as $idx => $j) {
|
||||
if (isset($j["incomingRefDetailID"])) {
|
||||
$nonlab_result = $this->process_nonlab($j["incomingRefDetailID"]);
|
||||
if ($nonlab_result != array()) {
|
||||
$j_param[$idx]["nonlab_result"] = $nonlab_result;
|
||||
$param = json_encode($j_param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$url = "http://$ipAddress/one-api-lab/tools/xstatusbranch_v3/update";
|
||||
$rst = $this->post($url, $param);
|
||||
if ($rst["status"] == "OK") {
|
||||
$this->xlog("Update status $stage to $branchName @ $ipAddress [OK]");
|
||||
$this->db->query($sql_update, array('Y', $txID));
|
||||
} else {
|
||||
$err_msg = print_r($rst, true);
|
||||
$this->xlog("Update status $stage to $branchName @ $ipAddress [ERR] : $err_msg");
|
||||
$this->db->query($sql_update, array('N', $txID));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->xlog("Err: " . print_r($this->db->error(), true));
|
||||
}
|
||||
}
|
||||
function xlog($message)
|
||||
{
|
||||
$dt = date("Y-m-d H:i:s");
|
||||
echo "$dt $message\n";
|
||||
}
|
||||
function status($incomingRefID)
|
||||
{
|
||||
$sql = "select * from incoming_ref where incomingRefID = ?";
|
||||
$qry = $this->db->query($sql, array($incomingRefID));
|
||||
$rows = array();
|
||||
$branchID = 0;
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) $branchID = $rows[0]["incomingRefM_BranchID"];
|
||||
}
|
||||
$ip_address = "";
|
||||
if ($branchID > 0) {
|
||||
$sql = "select *
|
||||
from m_branch where M_BranchID = ?";
|
||||
$qry = $this->db->query($sql, array($branchID));
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) $ip_address = $rows[0]["M_BranchIPAddress"];
|
||||
}
|
||||
}
|
||||
if ($ip_address == "") {
|
||||
echo "No IP Address from $branchID ";
|
||||
exit;
|
||||
}
|
||||
$sql = "select
|
||||
incomingRefT_RefDeliveryOrderID,
|
||||
incomingRefDetailT_OrderDetailID,
|
||||
incomingRefDetailStatus,
|
||||
T_OrderDetailResult,
|
||||
T_OrderDetailNat_NormalValueID,
|
||||
T_OrderDetailVerification,
|
||||
T_OrderDetailValidation
|
||||
from incoming_ref_detail
|
||||
join incoming_ref on incomingRefID = incomingRefDetailIncomingRefID
|
||||
and incomingRefID = ?
|
||||
left join t_orderdetail on incomingRefDetailNewT_OrderHeaderID = T_OrderDetailT_OrderHeaderID
|
||||
and T_OrderDetailIsActive = 'Y' and incomingRefDetailT_TestID = T_OrderDetailT_TestID";
|
||||
$qry = $this->db->query($sql, array($incomingRefID));
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
$param = json_encode($rows);
|
||||
$url = "http://$ip_address/one-api/tools/xstatusbranch_v2/update";
|
||||
$result = $this->post($url, $param);
|
||||
}
|
||||
}
|
||||
function post($url, $data)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
//curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
curl_setopt(
|
||||
$ch,
|
||||
CURLOPT_HTTPHEADER,
|
||||
array(
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($data)
|
||||
)
|
||||
);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if ($result === false) {
|
||||
return array(
|
||||
"status" => "ERR",
|
||||
"message" => curl_error($ch)
|
||||
);
|
||||
}
|
||||
$rst = json_decode($result, true);
|
||||
return $rst;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,23 @@
|
||||
<?php
|
||||
class OutgoingRef_v4 extends MY_Controller
|
||||
{
|
||||
function __construct() {
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db = $this->load->database("onedev", true);
|
||||
}
|
||||
function get_nonlab($type,$xid) {
|
||||
function get_nonlab($type, $xid)
|
||||
{
|
||||
//mikro
|
||||
if ($type == "mikro") {
|
||||
$sql = "select * from other_mikro where Other_MikroID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array() ;
|
||||
if ($qry ) {
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "mikro";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) {
|
||||
$result["header"]= $rows[0];
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
@@ -23,8 +25,8 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
Other_MikroDetailsIsActive = 'Y' ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -33,12 +35,12 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
if ($type == "cytologi") {
|
||||
$sql = "select * from other_cytologi where Other_CytologiID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array() ;
|
||||
if ($qry ) {
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "cytologi";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) {
|
||||
$result["header"]= $rows[0];
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
@@ -46,8 +48,8 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
Other_CytologiDetailsIsActive = 'Y' ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -56,12 +58,12 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
if ($type == "fna") {
|
||||
$sql = "select * from other_fna where Other_FnaID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array() ;
|
||||
if ($qry ) {
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "fna";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) {
|
||||
$result["header"]= $rows[0];
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
@@ -69,8 +71,8 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
Other_FnaDetailsIsActive = 'Y' ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -80,12 +82,12 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
if ($type == "papsmear") {
|
||||
$sql = "select * from other_papsmear where Other_PapSmearID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array() ;
|
||||
if ($qry ) {
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "papsmear";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) {
|
||||
$result["header"]= $rows[0];
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
@@ -95,40 +97,40 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
and Other_PapSmearBahanIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["bahan"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"]["bahan"] = $qry->result_array();
|
||||
}
|
||||
//category
|
||||
$sql = "select * from other_papsmearcategory
|
||||
where Other_PapsmearCategoryOther_PapSmearID = ?
|
||||
and Other_PapsmearCategoryIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["category"] = $qry->result_array();
|
||||
$result["detail"]["category"] = $qry->result_array();
|
||||
}
|
||||
// check
|
||||
// check
|
||||
$sql = "select * from other_papsmearcheck
|
||||
where Other_PapSmearCheckOther_PapSmearID= ?
|
||||
and Other_PapSmearCheckIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["check"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"]["check"] = $qry->result_array();
|
||||
}
|
||||
// details
|
||||
$sql = "select * from other_papsmeardetails
|
||||
where Other_PapSmearDetailsOther_PapSmearID= ?
|
||||
and Other_PapSmearDetailsIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["details"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"]["details"] = $qry->result_array();
|
||||
}
|
||||
// maturasi
|
||||
$sql = "select * from other_papsmearmaturasi
|
||||
where Other_PapSmearMaturasiOther_PapSmearID = ?
|
||||
and Other_PapSmearMaturasiIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["maturasi"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"]["maturasi"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -138,12 +140,12 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
if ($type == "lcprep") {
|
||||
$sql = "select * from other_lcprep where Other_LcprepID=? ";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
$result = array() ;
|
||||
if ($qry ) {
|
||||
$result = array();
|
||||
if ($qry) {
|
||||
$result["type"] = "lcprep";
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) {
|
||||
$result["header"]= $rows[0];
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0) {
|
||||
$result["header"] = $rows[0];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
@@ -153,15 +155,15 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
and Other_LcprepAdekuasiIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["adekuasi"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"]["adekuasi"] = $qry->result_array();
|
||||
}
|
||||
//interpretasi
|
||||
$sql = "select * from other_lcprepinterpretasi
|
||||
where Other_PapsmearInterpretasiOther_LcprepID = ?
|
||||
and Other_PapsmearInterpretasiIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["interpretasi"] = $qry->result_array();
|
||||
$result["detail"]["interpretasi"] = $qry->result_array();
|
||||
}
|
||||
// details
|
||||
$sql = "select * from other_lcprepdetails
|
||||
@@ -169,23 +171,24 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
and Other_LcprepDetailsIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["details"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"]["details"] = $qry->result_array();
|
||||
}
|
||||
// kategoriumum
|
||||
$sql = "select * from other_lcprepkategoriumum
|
||||
where Other_LcprepKategoriUmumOther_LcprepID = ?
|
||||
and Other_LcprepKategoriUmumIsActive='Y'";
|
||||
$qry = $this->db->query($sql, array($xid));
|
||||
if ($qry) {
|
||||
$result["detail"]["kategoriumum"] = $qry->result_array();
|
||||
}
|
||||
$result["detail"]["kategoriumum"] = $qry->result_array();
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
function process_nonlab($incomingRefDetailID) {
|
||||
function process_nonlab($incomingRefDetailID)
|
||||
{
|
||||
//mikro
|
||||
$sql = "select ifnull(Other_MikroID,0) mikroID
|
||||
from incoming_ref_detail
|
||||
@@ -194,19 +197,19 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
left join other_mikro on T_OrderDetailID = Other_MikroT_OrderDetailID and
|
||||
Other_MikroIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql,array($incomingRefDetailID));
|
||||
if ( ! $qry ) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(),true) . "\n";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if ( count($rows) > 0 ) {
|
||||
if (count($rows) > 0) {
|
||||
$mikroID = $rows[0]["mikroID"];
|
||||
$nl = "";
|
||||
if ($mikroID > 0 ) {
|
||||
if ($mikroID > 0) {
|
||||
$nl = $this->get_nonlab("mikro", $mikroID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//papsmear
|
||||
@@ -217,19 +220,19 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
left join other_papsmear on T_OrderDetailID = Other_PapSmearT_OrderDetailID and
|
||||
Other_PapSmearIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql,array($incomingRefDetailID));
|
||||
if ( ! $qry ) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(),true) . "\n";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if ( count($rows) > 0 ) {
|
||||
if (count($rows) > 0) {
|
||||
$papsmearID = $rows[0]["papsmearID"];
|
||||
$nl = "";
|
||||
if ($papsmear> 0 ) {
|
||||
if ($papsmear > 0) {
|
||||
$nl = $this->get_nonlab("papsmear", $papsmearID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//lcprep
|
||||
@@ -240,19 +243,19 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
left join other_lcprep on T_OrderDetailID = Other_LcprepT_OrderDetailID and
|
||||
Other_LcprepIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql,array($incomingRefDetailID));
|
||||
if ( ! $qry ) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(),true) . "\n";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if ( count($rows) > 0 ) {
|
||||
if (count($rows) > 0) {
|
||||
$lcprepID = $rows[0]["lcprepID"];
|
||||
$nl = "";
|
||||
if ($lcprepID > 0 ) {
|
||||
if ($lcprepID > 0) {
|
||||
$nl = $this->get_nonlab("lcprep", $lcprepID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//fna
|
||||
@@ -263,19 +266,19 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
left join other_fna on T_OrderDetailID = Other_FnaT_OrderDetailID and
|
||||
Other_FnaIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql,array($incomingRefDetailID));
|
||||
if ( ! $qry ) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(),true) . "\n";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if ( count($rows) > 0 ) {
|
||||
if (count($rows) > 0) {
|
||||
$fnaID = $rows[0]["fnaID"];
|
||||
$nl = "";
|
||||
if ($fnaID > 0 ) {
|
||||
if ($fnaID > 0) {
|
||||
$nl = $this->get_nonlab("fna", $fnaID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//cytology
|
||||
@@ -286,22 +289,23 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
left join other_cytologi on T_OrderDetailID = Other_CytologiT_OrderDetailID and
|
||||
Other_CytologiIsActive = 'Y'
|
||||
where incomingRefDetailID = ? ";
|
||||
$qry = $this->db->query($sql,array($incomingRefDetailID));
|
||||
if ( ! $qry ) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(),true) . "\n";
|
||||
$qry = $this->db->query($sql, array($incomingRefDetailID));
|
||||
if (! $qry) {
|
||||
echo "ERR : process_nonlab : $incomingRefDetailID : " . print_r($this->db->error(), true) . "\n";
|
||||
return "";
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if ( count($rows) > 0 ) {
|
||||
if (count($rows) > 0) {
|
||||
$cytologiID = $rows[0]["cytologiID"];
|
||||
$nl = "";
|
||||
if ($cytologiID > 0 ) {
|
||||
if ($cytologiID > 0) {
|
||||
$nl = $this->get_nonlab("cytologi", $cytologiID);
|
||||
return $nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function cek() {
|
||||
function cek()
|
||||
{
|
||||
$sql = "select tx_branch_status.*, M_BranchName
|
||||
from tx_branch_status
|
||||
join m_branch on TxBranchStatusM_BranchID = M_BranchID
|
||||
@@ -318,7 +322,8 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
print_r($rows);
|
||||
}
|
||||
}
|
||||
function process() {
|
||||
function process()
|
||||
{
|
||||
$sql = "select tx_branch_status.*, M_BranchName
|
||||
from tx_branch_status
|
||||
join m_branch on TxBranchStatusM_BranchID = M_BranchID
|
||||
@@ -338,7 +343,7 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
where TxBranchStatusID = ?";
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
foreach($rows as $r) {
|
||||
foreach ($rows as $r) {
|
||||
$param = $r["TxBranchStatusJson"];
|
||||
$stage = $r["TxBranchStatusStage"];
|
||||
$ipAddress = $r["TxBranchStatusM_BranchIP"];
|
||||
@@ -346,57 +351,69 @@ class OutgoingRef_v4 extends MY_Controller
|
||||
$txID = $r["TxBranchStatusID"];
|
||||
if ($stage == "VALIDATION") {
|
||||
//cek nonlab
|
||||
$j_param = json_decode($param,true);
|
||||
foreach($j_param as $idx => $j ) {
|
||||
$j_param = json_decode($param, true);
|
||||
foreach ($j_param as $idx => $j) {
|
||||
if (isset($j["incomingRefDetailID"])) {
|
||||
$nonlab_result = $this->process_nonlab( $j["incomingRefDetailID"] );
|
||||
if ($nonlab_result != array() ) {
|
||||
$nonlab_result = $this->process_nonlab($j["incomingRefDetailID"]);
|
||||
if ($nonlab_result != array()) {
|
||||
$j_param[$idx]["nonlab_result"] = $nonlab_result;
|
||||
$param = json_encode($j_param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$url = "http://$ipAddress/one-api/tools/xstatusbranch_v4/update";
|
||||
$rst = $this->post($url,$param);
|
||||
|
||||
if ($rst["status"] == "OK" ) {
|
||||
$url = "http://$ipAddress/one-api-lab/tools/xstatusbranch_v4/update";
|
||||
$rst = $this->post($url, $param);
|
||||
|
||||
if ($rst["status"] == "OK") {
|
||||
$this->xlog("Update status $stage to $branchName @ $ipAddress [OK]");
|
||||
$this->db->query($sql_update, array('Y',$txID));
|
||||
$this->db->query($sql_update, array('Y', $txID));
|
||||
} else {
|
||||
$err_msg = print_r($rst,true);
|
||||
$err_msg = print_r($rst, true);
|
||||
$this->xlog("Update status $stage to $branchName @ $ipAddress [ERR] : $err_msg");
|
||||
$this->db->query($sql_update, array('N',$txID));
|
||||
}
|
||||
$this->db->query($sql_update, array('N', $txID));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->xlog("Err: " . print_r($this->db->error(),true));
|
||||
$this->xlog("Err: " . print_r($this->db->error(), true));
|
||||
}
|
||||
}
|
||||
|
||||
function xlog($message) {
|
||||
function xlog($message)
|
||||
{
|
||||
$dt = date("Y-m-d H:i:s");
|
||||
echo "$dt $message\n";
|
||||
}
|
||||
function post($url,$data) {
|
||||
$zdata = gzdeflate($data,9);
|
||||
$ch = curl_init($url);
|
||||
$this->xlog("Post to : " . $url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $zdata);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($zdata))
|
||||
);
|
||||
function post($url, $data)
|
||||
{
|
||||
$zdata = gzdeflate($data, 9);
|
||||
$ch = curl_init($url);
|
||||
$this->xlog("Post to : " . $url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $zdata);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
|
||||
curl_setopt(
|
||||
$ch,
|
||||
CURLOPT_HTTPHEADER,
|
||||
array(
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($zdata)
|
||||
)
|
||||
);
|
||||
$result = curl_exec($ch);
|
||||
$curl_error = curl_error($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if ($result === false ) {
|
||||
return array("status" => "ERR" ,
|
||||
"message" => curl_error($ch)
|
||||
if ($result === false) {
|
||||
return array(
|
||||
"status" => "ERR",
|
||||
"message" => $curl_error,
|
||||
"http_code" => $http_code
|
||||
);
|
||||
}
|
||||
$rst = json_decode($result,true);
|
||||
return $rst;
|
||||
}
|
||||
}
|
||||
$rst = json_decode($result, true);
|
||||
return $rst;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ class Qr_report_uploader extends MY_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->db_log = $this->load->database('one_lab_log', true);
|
||||
}
|
||||
@@ -120,7 +121,11 @@ class Qr_report_uploader extends MY_Controller
|
||||
$orderHeaderID = (int)$row['QR_PrintOutT_OrderHeaderID'];
|
||||
$reportUrl = $row['QR_PrintOutReportURL'];
|
||||
|
||||
// Populate cache sebelum fetch dari BIRT
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderID);
|
||||
$pdfContent = $this->download_file($reportUrl);
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
|
||||
if ($pdfContent === false) {
|
||||
return $this->mark_failed($row, $orderHeaderID, '', 'DOWNLOAD_FAILED');
|
||||
}
|
||||
|
||||
542
application/controllers/tools/Rpt_lab_result.php
Normal file
542
application/controllers/tools/Rpt_lab_result.php
Normal file
@@ -0,0 +1,542 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Rpt_lab_result — FPDF-based lab result report
|
||||
* Endpoint: GET /tools/rpt_lab_result/pdf?token=...&PT_OrderHeaderID=...
|
||||
*
|
||||
* Menggunakan sp_rpt_hasil_header untuk data pasien,
|
||||
* query langsung untuk detail hasil pemeriksaan.
|
||||
* Cache PDP di-populate sebelum call SP lalu dihapus setelah selesai.
|
||||
*/
|
||||
class Rpt_lab_result extends MY_Controller
|
||||
{
|
||||
public $db_onedev;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->sys_ok(['message' => 'Use /tools/rpt_lab_result/pdf?PT_OrderHeaderID=<id>']);
|
||||
}
|
||||
|
||||
public function pdf()
|
||||
{
|
||||
try {
|
||||
$order_id = $this->_get_order_id();
|
||||
if ($order_id <= 0) {
|
||||
$this->sys_error('PT_OrderHeaderID wajib diisi');
|
||||
return;
|
||||
}
|
||||
|
||||
$username = trim($this->input->get('username', true) ?? $this->input->post('username', true) ?? '');
|
||||
if ($username === '') {
|
||||
$username = $this->sys_user['M_StaffName'] ?? $this->sys_user['M_UserUsername'] ?? 'ADMIN';
|
||||
}
|
||||
|
||||
// Populate cache PDP
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($order_id);
|
||||
|
||||
// Header data via SP
|
||||
$header = $this->_fetch_header($order_id, $username);
|
||||
if (!$header) {
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
$this->sys_error('Data order tidak ditemukan');
|
||||
return;
|
||||
}
|
||||
|
||||
// Detail hasil pemeriksaan
|
||||
$details = $this->_fetch_details($order_id, $username);
|
||||
|
||||
// Sampling data
|
||||
$sampling = $this->_fetch_sampling($order_id);
|
||||
|
||||
// Company info (address, phone IBL)
|
||||
$company_info = $this->_fetch_company_info();
|
||||
|
||||
// Delete cache setelah data diambil
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
|
||||
// Generate PDF
|
||||
$pdf_bytes = $this->_build_pdf($header, $details, $sampling, $company_info, $username);
|
||||
|
||||
$filename = 'lab_result_' . $order_id . '_' . date('Ymd') . '.pdf';
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Content-Length: ' . strlen($pdf_bytes));
|
||||
echo $pdf_bytes;
|
||||
exit;
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->sys_error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Data fetching
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function data()
|
||||
{
|
||||
$order_id = $this->_get_order_id();
|
||||
if ($order_id <= 0) { $this->sys_error('PT_OrderHeaderID wajib'); return; }
|
||||
$username = $this->input->get('username', true) ?: 'ADMIN';
|
||||
$details = $this->_fetch_details($order_id, $username);
|
||||
$this->sys_ok(['count' => count($details), 'rows' => array_slice($details, 0, 5), 'last_query' => $this->db_onedev->last_query()]);
|
||||
}
|
||||
|
||||
private function _fetch_header($order_id, $username)
|
||||
{
|
||||
$qry = $this->db_onedev->query('CALL sp_rpt_hasil_header(?, ?)', [$order_id, $username]);
|
||||
if (!$qry) return null;
|
||||
$row = $qry->row_array();
|
||||
if (method_exists($this, 'clean_mysqli_connection')) {
|
||||
$this->clean_mysqli_connection($this->db_onedev->conn_id);
|
||||
} else {
|
||||
$this->_clean_multi_result();
|
||||
}
|
||||
return $row ?: null;
|
||||
}
|
||||
|
||||
private function _fetch_sampling($order_id)
|
||||
{
|
||||
$qry = $this->db_onedev->query('CALL sp_rpt_hasil_lab_sampling(?, ?)', [$order_id, '']);
|
||||
if (!$qry) return [];
|
||||
$rows = $qry->result_array();
|
||||
if (method_exists($this, 'clean_mysqli_connection')) {
|
||||
$this->clean_mysqli_connection($this->db_onedev->conn_id);
|
||||
} else {
|
||||
$this->_clean_multi_result();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
private function _fetch_details($order_id, $username = '')
|
||||
{
|
||||
$qry = $this->db_onedev->query('CALL sp_rpt_hasil_lab(?, ?)', [$order_id, $username]);
|
||||
if (!$qry) return [];
|
||||
$rows = $qry->result_array();
|
||||
if (method_exists($this, 'clean_mysqli_connection')) {
|
||||
$this->clean_mysqli_connection($this->db_onedev->conn_id);
|
||||
} else {
|
||||
$this->_clean_multi_result();
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
private function _fetch_company_info()
|
||||
{
|
||||
$row = $this->db_onedev->query(
|
||||
"SELECT S_SystemsCompanyAddress, S_SystemsCompanyCity, S_SystemsCompanyPhone, S_SystemsCompanyName FROM conf_systems LIMIT 1"
|
||||
)->row_array();
|
||||
return $row ?: [];
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// PDF builder
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private function _build_pdf(array $h, array $details, array $sampling, array $co, $username)
|
||||
{
|
||||
require_once APPPATH . 'third_party/fpdf/fpdf.php';
|
||||
|
||||
// Footer data
|
||||
$validator_name = '';
|
||||
foreach ($details as $d) {
|
||||
if (!empty($d['M_StaffName'])) { $validator_name = $d['M_StaffName']; }
|
||||
}
|
||||
$lab_number = $this->_s($h['T_OrderHeaderLabNumber'] ?? '');
|
||||
$print_username = $this->_s($username);
|
||||
$print_datetime = date('d-m-Y H:i:s');
|
||||
$pv = $validator_name;
|
||||
$pu = $print_username;
|
||||
$pd = $print_datetime;
|
||||
$pln = $lab_number;
|
||||
|
||||
$pdf = new class($pu, $pd, $pln, $pv) extends FPDF {
|
||||
private $pu, $pd, $pln, $pv;
|
||||
public function __construct($pu, $pd, $pln, $pv) {
|
||||
parent::__construct('P', 'mm', 'A4');
|
||||
$this->pu = $pu; $this->pd = $pd; $this->pln = $pln; $this->pv = $pv;
|
||||
}
|
||||
public function Footer() {
|
||||
$ml = 10; $cw = $this->GetPageWidth() - 20;
|
||||
$this->SetFont('Helvetica', '', 10);
|
||||
|
||||
// Validasi Oleh (kanan)
|
||||
$this->SetY(-38);
|
||||
$this->SetX($ml);
|
||||
$this->Cell($cw, 5, 'Validasi Oleh', 0, 1, 'R');
|
||||
$this->Ln(8);
|
||||
|
||||
// Garis tanda tangan (kanan 40%)
|
||||
$this->SetX($ml + $cw * 0.62);
|
||||
$this->Cell($cw * 0.38, 0.3, '', 'T', 1);
|
||||
|
||||
// Nama validator (kanan)
|
||||
$this->SetX($ml);
|
||||
$this->Cell($cw, 5, iconv('UTF-8', 'windows-1252//TRANSLIT', (string) $this->pv), 0, 1, 'R');
|
||||
$this->Ln(2);
|
||||
|
||||
// Printed by (kiri)
|
||||
$printed = 'Printed by : ' . $this->pu . ' / ' . $this->pd . ' / ' . $this->pln;
|
||||
$this->SetX($ml);
|
||||
$this->Cell($cw, 5, $printed, 0, 0, 'L');
|
||||
$this->Ln();
|
||||
|
||||
// Page number (tengah)
|
||||
$this->SetX($ml);
|
||||
$this->Cell($cw, 5, $this->PageNo() . ' / {nb}', 0, 0, 'C');
|
||||
}
|
||||
};
|
||||
$pdf->AliasNbPages('{nb}');
|
||||
$pdf->SetMargins(9, 8, 9);
|
||||
$pdf->SetAutoPageBreak(true, 42);
|
||||
$pdf->AddPage();
|
||||
|
||||
$pw = $pdf->GetPageWidth(); // 210
|
||||
$ml = 9;
|
||||
$mr = 9;
|
||||
$cw = $pw - $ml - $mr; // 190
|
||||
|
||||
// Form revision number
|
||||
$form_row = $this->db_onedev->query(
|
||||
"SELECT IFNULL(M_No_FormRev,'') AS M_No_FormRev FROM m_no_form WHERE M_No_FormName='LAB' AND M_No_FormIsActive='Y' LIMIT 1"
|
||||
);
|
||||
$form_rev = $form_row ? $this->_s($form_row->row_array()['M_No_FormRev'] ?? '') : '';
|
||||
|
||||
// ── Pojok kanan atas: lab number + form rev ───────────────────────────
|
||||
$pdf->SetFont('Arial', '', 7);
|
||||
$pdf->SetXY($ml, 4);
|
||||
$top_right = trim($lab_number . ($form_rev ? ' ' . $form_rev : ''));
|
||||
$pdf->Cell($cw, 5, $top_right, 0, 1, 'R');
|
||||
|
||||
// ── Kop atas ──────────────────────────────────────────────────────────
|
||||
$company_addr = $this->_s($co['S_SystemsCompanyAddress'] ?? 'Jl. LL. RE. Martadinata No. 135');
|
||||
$company_city = $this->_s($co['S_SystemsCompanyCity'] ?? 'Bandung');
|
||||
$company_phone = $this->_s($co['S_SystemsCompanyPhone'] ?? '(022)7271946');
|
||||
$addr_line = $company_addr . ' ' . $company_city . ' Telp. ' . $company_phone;
|
||||
$pj_name = $this->_s($h['M_DoctorName'] ?? '');
|
||||
|
||||
$pdf->SetFont('Arial', '', 9);
|
||||
$pdf->SetXY($ml, 8);
|
||||
$pdf->Cell($cw / 2, 5, $addr_line, 0, 0, 'L');
|
||||
$pdf->SetX($ml + $cw / 2);
|
||||
$pdf->Cell($cw / 2, 5, 'Penanggung Jawab : ' . $pj_name, 0, 1, 'R');
|
||||
$pdf->SetLineWidth(0.8);
|
||||
$pdf->Line($ml, 13.5, $ml + $cw, 13.5);
|
||||
$pdf->SetLineWidth(0.2);
|
||||
$pdf->SetY(15);
|
||||
|
||||
// ── Patient info (2 columns) ──────────────────────────────────────────
|
||||
$lw = 94;
|
||||
$rw = $cw - $lw;
|
||||
$lbl_w = 30;
|
||||
$col_w = 4;
|
||||
$val_w = $lw - $lbl_w - $col_w;
|
||||
$lbl_rw = 30;
|
||||
$val_rw = $rw - $lbl_rw - $col_w;
|
||||
|
||||
$pid = $this->_s($h['T_OrderHeaderLabNumber'] ?? '-');
|
||||
$left_rows = [
|
||||
['NO. REG', $this->_s($h['M_PatientNoReg'] ?? '-')],
|
||||
['NAMA', $this->_s($h['M_PatientName'] ?? '-')],
|
||||
['PENGIRIM', $this->_s($h['M_DoctorName2'] ?? '-')],
|
||||
['KEL. PELANGGAN*', $this->_s($h['CorporateName'] ?? '-')],
|
||||
['ALAMAT', $this->_s($h['M_PatientAddress'] ?? '-')],
|
||||
];
|
||||
$right_rows = [
|
||||
['TANGGAL REG', $this->_s($h['T_OrderHeaderDate'] ?? '-')],
|
||||
['PID', $pid],
|
||||
['JENIS KELAMIN', $this->_s($h['Gender'] ?? '-')],
|
||||
['TGL. LAHIR / USIA', $this->_s($h['Umur'] ?? '-')],
|
||||
['NO. TLP. / HP', $this->_s($h['M_PatientHp'] ?? '-')],
|
||||
];
|
||||
|
||||
$fnt = 'Arial';
|
||||
$fs = 8.5;
|
||||
|
||||
$y_info_start = $pdf->GetY();
|
||||
$barcode_x = $ml + $lw + 4;
|
||||
$barcode_y = $y_info_start;
|
||||
$barcode_w = 58;
|
||||
$barcode_h = 8;
|
||||
$this->_draw_fake_barcode($pdf, $barcode_x, $barcode_y, $barcode_w, $barcode_h, $pid);
|
||||
|
||||
$y_left_cur = $y_info_start + 1;
|
||||
$y_right_cur = $y_info_start + 10;
|
||||
|
||||
foreach ($left_rows as $r) {
|
||||
$y_left_cur = $this->_draw_header_row($pdf, $ml, $y_left_cur, $lbl_w, $col_w, $val_w, $r[0], $r[1], $fnt, $fs);
|
||||
}
|
||||
|
||||
foreach ($right_rows as $r) {
|
||||
$y_right_cur = $this->_draw_header_row($pdf, $ml + $lw + 4, $y_right_cur, $lbl_rw, $col_w, $val_rw - 4, $r[0], $r[1], $fnt, $fs);
|
||||
}
|
||||
|
||||
$pdf->SetY(max($y_left_cur, $y_right_cur) + 10);
|
||||
|
||||
// ── Table header ─────────────────────────────────────────────────────
|
||||
$col = ['JENIS PEMERIKSAAN' => 64, 'HASIL' => 24, 'NILAI RUJUKAN' => 43, 'SATUAN' => 24, 'METODE' => 37];
|
||||
$col_w_arr = array_values($col);
|
||||
$row_h = 5.2;
|
||||
|
||||
$y_table_start = $pdf->GetY();
|
||||
|
||||
$pdf->SetFont($fnt, 'B', 8.8);
|
||||
$pdf->SetX($ml);
|
||||
foreach ($col as $label => $w) {
|
||||
$pdf->Cell($w, $row_h + 1.8, $label, '1', 0, 'C');
|
||||
}
|
||||
$pdf->Ln();
|
||||
|
||||
// ── Table rows ────────────────────────────────────────────────────────
|
||||
// Strategy:
|
||||
// - Group/SubSubGroup rows : full-width text only, tanpa border bawah
|
||||
// - Test rows : text per kolom + separator full-width manual
|
||||
// - Outer L/R/T/B : drawn via Rect() after all rows
|
||||
|
||||
$prev_subgroup = null;
|
||||
$prev_subsubgroup = null;
|
||||
$qr_url = '';
|
||||
|
||||
foreach ($details as $d) {
|
||||
$subgroup = strtoupper(trim($d['Nat_SubGroupName'] ?? ''));
|
||||
$subsubgroup = trim($d['Nat_SubSubGroupName'] ?? '');
|
||||
$sascode_len = strlen(trim($d['T_TestSasCode'] ?? ''));
|
||||
$test_name = $this->_s(trim($d['T_TestName'] ?? ''));
|
||||
$result = $this->_s(trim(strip_tags($d['T_OrderDetailResult'] ?? '')));
|
||||
$normal = $this->_s(trim($d['T_OrderDetailNormalValueNote'] ?? $d['T_OrderDetailNormalValueDescription'] ?? ''));
|
||||
$unit = $this->_s(trim($d['T_OrderDetailNat_UnitName'] ?? ''));
|
||||
$method = $this->_s(trim($d['T_OrderdetailNat_MethodeName'] ?? $d['methodeName'] ?? ''));
|
||||
$flag = trim($d['T_OrderDetailResultFlag'] ?? '');
|
||||
$is_abnormal = ($flag !== '' && $flag !== 'N');
|
||||
if (empty($qr_url) && !empty($d['qrreport'])) {
|
||||
$qr_url = $d['qrreport'];
|
||||
}
|
||||
|
||||
// Level 1: SubGroup — bold, full-width, tanpa separator
|
||||
if ($subgroup !== '' && $subgroup !== $prev_subgroup) {
|
||||
$pdf->SetX($ml);
|
||||
$pdf->SetFont($fnt, 'B', 8.8);
|
||||
$pdf->Cell($cw, $row_h, $subgroup, 0, 1, 'L');
|
||||
$prev_subgroup = $subgroup; $prev_subsubgroup = null;
|
||||
}
|
||||
|
||||
// Level 2: SubSubGroup — italic, full-width, tanpa separator
|
||||
if ($subsubgroup !== '' && $subsubgroup !== $prev_subsubgroup) {
|
||||
$pdf->SetX($ml);
|
||||
$pdf->SetFont($fnt, 'I', 8.6);
|
||||
$pdf->Cell($cw, $row_h, ' ' . $this->_s($subsubgroup), 0, 1, 'L');
|
||||
$prev_subsubgroup = $subsubgroup;
|
||||
}
|
||||
|
||||
// Level 3: Test row — indent via spaces, separator full-width
|
||||
$sp = 0; $prefix = '';
|
||||
if ($sascode_len >= 10 && $sascode_len < 12) { $sp = 2; }
|
||||
elseif ($sascode_len >= 12 && $sascode_len < 14) { $sp = 4; $prefix = chr(183) . ' '; }
|
||||
elseif ($sascode_len >= 14) { $sp = 6; $prefix = chr(183) . ' '; }
|
||||
$display_name = str_repeat(' ', $sp) . $prefix . $test_name;
|
||||
|
||||
$pdf->SetFont($fnt, $is_abnormal ? 'B' : '', 8.2);
|
||||
$y_start = $pdf->GetY();
|
||||
|
||||
// Hitung row height
|
||||
$row_height = $row_h;
|
||||
$texts = [$display_name, $result, $normal, $unit, $method];
|
||||
foreach ($texts as $i => $txt) {
|
||||
$lines = $this->_estimate_text_lines($pdf, $col_w_arr[$i] - 2, $txt);
|
||||
$row_height = max($row_height, $lines * $row_h);
|
||||
}
|
||||
|
||||
// Render cells tanpa border, lalu gambar separator full-width manual
|
||||
$x_cur = $ml;
|
||||
foreach ($texts as $i => $txt) {
|
||||
$w = $col_w_arr[$i];
|
||||
$align = ($i === 1) ? 'C' : 'L';
|
||||
$pdf->SetXY($x_cur, $y_start);
|
||||
$pdf->Cell($w, $row_height, $txt, 0, 0, $align);
|
||||
$x_cur += $w;
|
||||
}
|
||||
$pdf->Line($ml, $y_start + $row_height, $ml + $cw, $y_start + $row_height);
|
||||
$pdf->SetXY($ml, $y_start + $row_height);
|
||||
}
|
||||
|
||||
// Outer rectangle — clean single-weight border for entire table
|
||||
$y_table_end = $pdf->GetY();
|
||||
$pdf->Rect($ml, $y_table_start, $cw, $y_table_end - $y_table_start);
|
||||
|
||||
// ── Catatan ───────────────────────────────────────────────────────────
|
||||
$pdf->Ln(3);
|
||||
$pdf->SetFont($fnt, '', 8.2);
|
||||
$pdf->SetX($ml);
|
||||
$pdf->Cell($cw, $row_h, 'Catatan :', 0, 1, 'L');
|
||||
$pdf->Ln(2);
|
||||
|
||||
// ── Waktu Pengambilan Spesimen ────────────────────────────────────────
|
||||
if (!empty($sampling)) {
|
||||
$pdf->SetFont($fnt, '', 8.2);
|
||||
$pdf->SetX($ml);
|
||||
$pdf->Cell($cw, $row_h, 'Waktu Pengambilan Spesimen', 0, 1, 'L');
|
||||
foreach ($sampling as $s) {
|
||||
$bahan = $this->_s($s['T_BahanName'] ?? '');
|
||||
$tgl = $this->_s($s['sampling_date'] ?? '');
|
||||
$jam = $this->_s($s['sample_time'] ?? '');
|
||||
$pdf->SetX($ml);
|
||||
$pdf->Cell(35, $row_h, $bahan, 0, 0, 'L');
|
||||
$pdf->Cell(4, $row_h, ':', 0, 0, 'C');
|
||||
$pdf->Cell(35, $row_h, $tgl, 0, 0, 'L');
|
||||
$pdf->Cell(30, $row_h, $jam, 0, 1, 'L');
|
||||
}
|
||||
}
|
||||
|
||||
// ── QR code (absolute, 20mm di atas footer = -42-3 = -45 dari bawah) ──
|
||||
if (!empty($qr_url)) {
|
||||
$tmp = $this->_fetch_image_to_temp($qr_url);
|
||||
if ($tmp) {
|
||||
$page_h = $pdf->GetPageHeight();
|
||||
$qr_y = $page_h - 42 - 3 - 20; // footer_margin=42, gap=3, qr_h=20
|
||||
$pdf->Image($tmp, $ml, $qr_y, 20, 20);
|
||||
@unlink($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
return $pdf->Output('S');
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private function _get_order_id()
|
||||
{
|
||||
foreach (['PT_OrderHeaderID', 'PID', 'order_id'] as $k) {
|
||||
$v = $this->input->get($k, true) ?? $this->input->post($k, true) ?? ($this->sys_input[$k] ?? null);
|
||||
if ($v !== null && $v !== '') return intval($v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function _draw_header_row($pdf, $x, $y, $label_w, $colon_w, $value_w, $label, $value, $font, $font_size)
|
||||
{
|
||||
$label = $this->_s($label);
|
||||
$value = $this->_s($value);
|
||||
$line_h = 5.2;
|
||||
|
||||
$pdf->SetFont($font, 'B', $font_size);
|
||||
$pdf->SetXY($x, $y);
|
||||
$pdf->Cell($label_w, $line_h, $label, 0, 0, 'L');
|
||||
$pdf->SetFont($font, '', $font_size);
|
||||
$pdf->Cell($colon_w, $line_h, ':', 0, 0, 'C');
|
||||
|
||||
$value_lines = $this->_estimate_text_lines($pdf, $value_w, $value);
|
||||
$row_h = max(1, $value_lines) * $line_h;
|
||||
|
||||
$pdf->SetXY($x + $label_w + $colon_w, $y);
|
||||
$pdf->MultiCell($value_w, $line_h, $value, 0, 'L');
|
||||
|
||||
return $y + $row_h;
|
||||
}
|
||||
|
||||
private function _estimate_text_lines($pdf, $width, $text)
|
||||
{
|
||||
$text = str_replace("\r", '', (string) $text);
|
||||
if ($text === '') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$lines = explode("\n", $text);
|
||||
$count = 0;
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
if ($line === '') {
|
||||
$count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$words = preg_split('/\s+/', $line);
|
||||
$current = '';
|
||||
foreach ($words as $word) {
|
||||
$candidate = $current === '' ? $word : $current . ' ' . $word;
|
||||
if ($pdf->GetStringWidth($candidate) <= $width) {
|
||||
$current = $candidate;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($current !== '') {
|
||||
$count++;
|
||||
$current = $word;
|
||||
} else {
|
||||
$count += max(1, (int) ceil($pdf->GetStringWidth($word) / max($width, 1)));
|
||||
$current = '';
|
||||
}
|
||||
}
|
||||
|
||||
if ($current !== '') {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
return max(1, $count);
|
||||
}
|
||||
|
||||
private function _draw_fake_barcode($pdf, $x, $y, $w, $h, $text)
|
||||
{
|
||||
$text = preg_replace('/[^A-Za-z0-9]/', '', (string) $text);
|
||||
if ($text === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$sequence = '1010';
|
||||
$chars = str_split(strtoupper($text));
|
||||
foreach ($chars as $char) {
|
||||
$bits = str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
|
||||
$sequence .= $bits . '0';
|
||||
}
|
||||
$sequence .= '10101';
|
||||
|
||||
$module_w = $w / strlen($sequence);
|
||||
$pdf->SetFillColor(0, 0, 0);
|
||||
for ($i = 0, $len = strlen($sequence); $i < $len; $i++) {
|
||||
if ($sequence[$i] !== '1') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$bar_x = $x + ($i * $module_w);
|
||||
$bar_h = ($i % 7 === 0) ? $h : ($h - 1.2);
|
||||
$pdf->Rect($bar_x, $y, max(0.35, $module_w * 0.92), $bar_h, 'F');
|
||||
}
|
||||
}
|
||||
|
||||
private function _s($text)
|
||||
{
|
||||
return iconv('UTF-8', 'windows-1252//TRANSLIT', (string) $text);
|
||||
}
|
||||
|
||||
private function _fetch_image_to_temp($url)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, CURLOPT_FOLLOWLOCATION => true]);
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
if (!$data) return null;
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'qr_') . '.png';
|
||||
file_put_contents($tmp, $data);
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
private function _clean_multi_result()
|
||||
{
|
||||
if (isset($this->db_onedev->conn_id) && $this->db_onedev->conn_id instanceof mysqli) {
|
||||
while ($this->db_onedev->conn_id->more_results()) {
|
||||
$this->db_onedev->conn_id->next_result();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ class Rpt_t_002 extends MY_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -34,8 +35,10 @@ class Rpt_t_002 extends MY_Controller
|
||||
if ($an === null) {
|
||||
$an = '';
|
||||
}
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = 'CALL sp_rpt_t_002(?, ?, ?)';
|
||||
$qry = $this->db->query($sql, [$orderHeaderId, $an, $username]);
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
$lastQry = $this->db->last_query();
|
||||
|
||||
if (!$qry) {
|
||||
@@ -75,8 +78,10 @@ class Rpt_t_002 extends MY_Controller
|
||||
if ($an === null) {
|
||||
$an = '';
|
||||
}
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = 'CALL sp_rpt_t_002(?, ?, ?)';
|
||||
$qry = $this->db->query($sql, [$orderHeaderId, $an, $username]);
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
$lastQry = $this->db->last_query();
|
||||
if (!$qry) {
|
||||
$this->sys_error_db([
|
||||
|
||||
@@ -4,6 +4,7 @@ class Rpt_t_002_eng extends MY_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -35,8 +36,10 @@ class Rpt_t_002_eng extends MY_Controller
|
||||
$an = '';
|
||||
}
|
||||
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = 'CALL sp_rpt_t_002_eng(?, ?, ?)';
|
||||
$qry = $this->db->query($sql, [$orderHeaderId, $an, $username]);
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
$lastQry = $this->db->last_query();
|
||||
|
||||
if (!$qry) {
|
||||
@@ -77,6 +80,7 @@ class Rpt_t_002_eng extends MY_Controller
|
||||
$an = '';
|
||||
}
|
||||
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = 'CALL sp_rpt_t_002_eng(?, ?, ?)';
|
||||
$qry = $this->db->query($sql, [$orderHeaderId, $an, $username]);
|
||||
$lastQry = $this->db->last_query();
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<?php
|
||||
class Xferbranch_v4 extends CI_Controller
|
||||
{
|
||||
function __construct() {
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db = $this->load->database("onedev", true);
|
||||
}
|
||||
function index() {
|
||||
function index()
|
||||
{
|
||||
echo "Xfer Branch API";
|
||||
}
|
||||
|
||||
function batch() {
|
||||
function batch()
|
||||
{
|
||||
$this->fix();
|
||||
|
||||
$sql = "select T_RefDeliveryOrderID, T_RefDeliveryOrderNumber,
|
||||
@@ -25,13 +28,13 @@ class Xferbranch_v4 extends CI_Controller
|
||||
$tot_upload = 0;
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
foreach($rows as $r) {
|
||||
foreach ($rows as $r) {
|
||||
$date = date("Y-m-d H:i:s ");
|
||||
$branch = $r["M_BranchName"];
|
||||
$ip_address = $r["M_BranchIPAddress"];
|
||||
$number = $r["T_RefDeliveryOrderNumber"];
|
||||
|
||||
if ( $this->do($r["T_RefDeliveryOrderID"])) {
|
||||
if ($this->do($r["T_RefDeliveryOrderID"])) {
|
||||
echo "$date [OK] uploaded {$number} to {$branch} @ $ip_address\n";
|
||||
} else {
|
||||
echo "$date [ERR] uploaded {$number} to {$branch} @ $ip_address\n";
|
||||
@@ -39,13 +42,14 @@ class Xferbranch_v4 extends CI_Controller
|
||||
$tot_upload++;
|
||||
}
|
||||
}
|
||||
if ($tot_upload == 0 ) {
|
||||
if ($tot_upload == 0) {
|
||||
$date = date("Y-m-d H:i:s ");
|
||||
echo "$date [OK] No upload data\n";
|
||||
}
|
||||
}
|
||||
|
||||
function do($deliveryID) {
|
||||
function do($deliveryID)
|
||||
{
|
||||
$sql = "select distinct
|
||||
T_RefDeliveryOrderID,
|
||||
T_RefDeliveryOrderDate,
|
||||
@@ -81,20 +85,20 @@ class Xferbranch_v4 extends CI_Controller
|
||||
where T_RefDeliveryOrderID = ?
|
||||
and T_RefDeliveryOrderDetailIsConfirm = 'Y'
|
||||
";
|
||||
$qry = $this->db->query($sql, array($deliveryID) );
|
||||
$qry = $this->db->query($sql, array($deliveryID));
|
||||
$rows = array();
|
||||
$branch_ip_address = "";
|
||||
if($qry) {
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
|
||||
if (count($rows) == 0 ) {
|
||||
echo "No Detail Records. => ";
|
||||
$this->db->query("update t_ref_deliveryorder set T_RefDeliveryOrderIsConfirm = 'Z' where T_RefDeliveryOrderID = ?", array($deliveryID));
|
||||
if (count($rows) == 0) {
|
||||
echo "No Detail Records. => ";
|
||||
$this->db->query("update t_ref_deliveryorder set T_RefDeliveryOrderIsConfirm = 'Z' where T_RefDeliveryOrderID = ?", array($deliveryID));
|
||||
return false;
|
||||
}
|
||||
$sqlp = "select * from m_patient where M_PatientID = ?";
|
||||
$sqlpa = "select * from m_patientaddress where M_PatientAddressM_PatientID = ?";
|
||||
$sqlpt = "select * from m_title where M_TitleID = ?";
|
||||
$sqlp = "select * from m_patient where M_PatientID = ?";
|
||||
$sqlpa = "select * from m_patientaddress where M_PatientAddressM_PatientID = ?";
|
||||
$sqlpt = "select * from m_title where M_TitleID = ?";
|
||||
|
||||
$sqlt = "select
|
||||
T_OrderDetailT_TestID T_TestID,
|
||||
@@ -124,88 +128,88 @@ class Xferbranch_v4 extends CI_Controller
|
||||
left join t_orderpromise on T_OrderDetailT_OrderPromiseID = T_OrderPromiseID";
|
||||
|
||||
$arr_price_test = array();
|
||||
foreach($rows as $idx => $r) {
|
||||
foreach ($rows as $idx => $r) {
|
||||
//patient & address
|
||||
$branch_ip_address = $r["DestinationIPAddress"];
|
||||
$patientID = $r["T_OrderHeaderM_PatientID"];
|
||||
$headerID = $r["T_OrderHeaderID"];
|
||||
$detailID= $r["T_OrderDetailID"];
|
||||
$detailID = $r["T_OrderDetailID"];
|
||||
$deliveryDetailID = $r["T_RefDeliveryOrderDetailID"];
|
||||
$qryp = $this->db->query($sqlp, array($patientID));
|
||||
$patient = array();
|
||||
if ($qryp) {
|
||||
$rowsp = $qryp->result_array();
|
||||
if( count($rowsp) > 0 ) {
|
||||
if (count($rowsp) > 0) {
|
||||
$patient = $rowsp[0];
|
||||
$titleID = $patient["M_PatientM_TitleID"];
|
||||
$qrypa = $this->db->query($sqlpa, array($patientID));
|
||||
if ($qrypa) {
|
||||
$patient["address"] = $qrypa->result_array();
|
||||
$patient["address"] = $qrypa->result_array();
|
||||
}
|
||||
$qrypt = $this->db->query($sqlpt, array($titleID));
|
||||
if ($qrypt) {
|
||||
$rowspt = $qrypt->result_array();
|
||||
if (count($rowspt) > 0 ) $patient["title"] = $rowspt[0];
|
||||
$rowspt = $qrypt->result_array();
|
||||
if (count($rowspt) > 0) $patient["title"] = $rowspt[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$rows[$idx]["patient"] = $patient;
|
||||
// test
|
||||
$qryt = $this->db->query($sqlt,array($detailID));
|
||||
$qryt = $this->db->query($sqlt, array($detailID));
|
||||
$arr_test = array();
|
||||
|
||||
|
||||
if ($qryt) {
|
||||
$rowst = $qryt->result_array();
|
||||
if (! isset($arr_price_test[$headerID])) {
|
||||
$arr_price_test[$headerID] = array();
|
||||
}
|
||||
foreach($rowst as $r ) {
|
||||
$sasCode = substr($r["T_TestSasCode"],0,8);
|
||||
foreach ($rowst as $r) {
|
||||
$sasCode = substr($r["T_TestSasCode"], 0, 8);
|
||||
$curSasCode = $r["T_TestSasCode"];
|
||||
if ( ! isset($arr_price_test[$headerID][$sasCode]) ) {
|
||||
if(strlen($curSasCode) == 8) $arr_price_test[$headerID][$sasCode] = true;
|
||||
if (! isset($arr_price_test[$headerID][$sasCode])) {
|
||||
if (strlen($curSasCode) == 8) $arr_price_test[$headerID][$sasCode] = true;
|
||||
$rows[$idx]["test"][] = $r;
|
||||
$arr_test[]=$r["T_TestID"];
|
||||
$arr_test[] = $r["T_TestID"];
|
||||
}
|
||||
}
|
||||
}
|
||||
// $child_test
|
||||
$qryct = $this->db->query($sqlct,array($deliveryDetailID));
|
||||
$qryct = $this->db->query($sqlct, array($deliveryDetailID));
|
||||
if ($qryct) {
|
||||
$rowsct = $qryct->result_array();
|
||||
$rows[$idx]["child_test"] = $rowsct;
|
||||
}
|
||||
|
||||
$reqs = array();
|
||||
if (count($arr_test) > 0 ) {
|
||||
if (count($arr_test) > 0) {
|
||||
$sqlr = "select * from t_orderreq where T_OrderReqT_OrderHeaderID = ?";
|
||||
$qryr = $this->db->query($sqlr, array($headerID));
|
||||
if ($qryr) {
|
||||
$rowsr = $qryr->result_array();
|
||||
foreach($rowsr as $r) {
|
||||
foreach ($rowsr as $r) {
|
||||
$a_test_r = json_decode($r["T_OrderReqT_TestID"]);
|
||||
$a_x = array_intersect($arr_test,$a_test_r);
|
||||
if( count($a_x) > 0 ) $reqs[] = $r;
|
||||
$a_x = array_intersect($arr_test, $a_test_r);
|
||||
if (count($a_x) > 0) $reqs[] = $r;
|
||||
}
|
||||
}
|
||||
}
|
||||
$rows[$idx]["requirements"] = $reqs;
|
||||
}
|
||||
$o_rows=$rows;
|
||||
$o_rows = $rows;
|
||||
$rows = array();
|
||||
foreach($o_rows as $r) {
|
||||
if (isset($r["test"]) ) {
|
||||
foreach ($o_rows as $r) {
|
||||
if (isset($r["test"])) {
|
||||
$rows[] = $r;
|
||||
}
|
||||
}
|
||||
$param = json_encode($rows);
|
||||
|
||||
$url = "http://$branch_ip_address/one-api/tools/incomingref_v4/receive";
|
||||
|
||||
$result = $this->post($url,$param);
|
||||
echo "to $url \nresponse : $result\n";
|
||||
$result = json_decode($result,true);
|
||||
if ($result["status"] == "OK" ) {
|
||||
$url = "http://$branch_ip_address/one-api-lab/tools/incomingref_v4/receive";
|
||||
|
||||
$result = $this->post($url, $param);
|
||||
echo "to $url \nresponse : $result\n";
|
||||
$result = json_decode($result, true);
|
||||
if ($result["status"] == "OK") {
|
||||
$sqlu = "update t_ref_deliveryorder set T_RefDeliveryOrderIsConfirm = 'S'
|
||||
where T_RefDeliveryOrderID = ?";
|
||||
$this->db->query($sqlu, array($deliveryID));
|
||||
@@ -214,13 +218,13 @@ class Xferbranch_v4 extends CI_Controller
|
||||
print_r($result);
|
||||
}
|
||||
} else {
|
||||
print_r($this->db->error());
|
||||
print_r($this->db->error());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function fix()
|
||||
{
|
||||
$sql = "SELECT
|
||||
{
|
||||
$sql = "SELECT
|
||||
T_RefDeliveryOrderID,
|
||||
T_RefDeliveryOrderDetailT_WorklistRefConfirmDetailID,
|
||||
T_RefDeliveryOrderDate,
|
||||
@@ -242,34 +246,39 @@ WHERE T_RefDeliveryOrderDetailIsActive = 'Y' AND
|
||||
T_RefDeliveryOrderDetailT_BarcodeLabBarcode <> T_BarcodeLabBarcode AND
|
||||
T_RefDeliveryOrderDate >= '2024-08-01'";
|
||||
|
||||
$qry = $this->db->query($sql);
|
||||
$rows = $qry->result_array();
|
||||
|
||||
if (count($rows) > 0) {
|
||||
foreach ($rows as $k => $v) {
|
||||
$sql = "UPDATE t_ref_deliveryorder_detail
|
||||
$qry = $this->db->query($sql);
|
||||
$rows = $qry->result_array();
|
||||
|
||||
if (count($rows) > 0) {
|
||||
foreach ($rows as $k => $v) {
|
||||
$sql = "UPDATE t_ref_deliveryorder_detail
|
||||
SET T_RefDeliveryOrderDetailT_BarcodeLabBarcode = '{$v['T_BarcodeLabBarcode']}'
|
||||
WHERE T_RefDeliveryOrderDetailID = {$v['T_RefDeliveryOrderDetailID']}";
|
||||
$qry = $this->db->query($sql);
|
||||
|
||||
$sql = "UPDATE t_worklist_ref_confirmdetail
|
||||
$qry = $this->db->query($sql);
|
||||
|
||||
$sql = "UPDATE t_worklist_ref_confirmdetail
|
||||
SET T_WorklistRefConfirmDetailT_BarcodeLabBarcode = '{$v['T_BarcodeLabBarcode']}'
|
||||
WHERE T_WorklistRefConfirmDetailID = {$v['T_RefDeliveryOrderDetailT_WorklistRefConfirmDetailID']}";
|
||||
$qry = $this->db->query($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
function post($url,$data) {
|
||||
$qry = $this->db->query($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
function post($url, $data)
|
||||
{
|
||||
$zdata = gzdeflate($data);
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $zdata);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $zdata);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
//curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($zdata))
|
||||
);
|
||||
curl_setopt(
|
||||
$ch,
|
||||
CURLOPT_HTTPHEADER,
|
||||
array(
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($zdata)
|
||||
)
|
||||
);
|
||||
$result = curl_exec($ch);
|
||||
//echo "RST : $result ";
|
||||
return $result;
|
||||
|
||||
639
application/controllers/tools/Xstatusbranch_v3.php
Normal file
639
application/controllers/tools/Xstatusbranch_v3.php
Normal file
@@ -0,0 +1,639 @@
|
||||
<?php
|
||||
class Xstatusbranch_v3 extends MY_Controller
|
||||
{
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
$this->db = $this->load->database("onedev", true);
|
||||
}
|
||||
function index() {
|
||||
echo "API";
|
||||
}
|
||||
//mikro
|
||||
function update_mikro($detailID, $header, $detail ) {
|
||||
$sql = "select * from t_orderdetail where T_OrderDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Mikro cek Validation " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) == 0 ) return;
|
||||
if ($rows[0]["T_OrderDetailValidation"] == "Y" ) return;
|
||||
$sql = "select Other_MikroID from other_mikro where Other_MikroT_OrderDetailID = ? and Other_MikroIsActive = 'Y'";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Mikro cek Existence " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
$mikroID = 0;
|
||||
if (count($rows) > 0 ) $mikroID = $rows[0]["Other_MikroID"];
|
||||
if ( $mikroID > 0 ) {
|
||||
$sql = "update other_mikro set Other_MikroIsActive = 'N' where Other_MikroID = ? ";
|
||||
$qry = $this->db->query($sql, array($mikroID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Mikro set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$sql = "update other_mikrodetails set Other_MikroDetailsIsActive = 'N' where Other_MikroDetailsOther_MikroID= ? ";
|
||||
$qry = $this->db->query($sql, array($mikroID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Mikro Details set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
unset($header["Other_MikroID"]);
|
||||
$header["Other_MikroCreated"] = date("Y-m-d h:i:s");
|
||||
$header["Other_MikroLastUpdated"] =date("Y-m-d h:i:s");
|
||||
$header["Other_MikroUserID"] = 3;
|
||||
$header["Other_MikroIsActive"] = "Y";
|
||||
$header["Other_MikroT_OrderDetailID"] = $detailID;
|
||||
$qry = $this->db->insert("other_mikro",$header);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Mikro Add Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$mikroID = $this->db->insert_id();
|
||||
if ($mikroID == 0 ) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Mikro ID Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
foreach($detail as $idx => $d ) {
|
||||
$detail[$idx]["Other_MikroDetailsOther_MikroID"] = $mikroID ;
|
||||
$detail[$idx]["Other_MikroDetailsUserID"] = 3;
|
||||
$detail[$idx]["Other_MikroDetailsIsActive"] = "Y";
|
||||
unset($detail[$idx]["Other_MikroDetailsID"]);
|
||||
unset($detail[$idx]["Other_MikroDetailsCreated"]);
|
||||
unset($detail[$idx]["Other_MikroDetailsLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_mikrodetails",$detail);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Mikro Add Detail" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//cytologi
|
||||
function update_cytologi($detailID, $header, $detail ) {
|
||||
$sql = "select * from t_orderdetail where T_OrderDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Cytologi cek Validation " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) == 0 ) return;
|
||||
if ($rows[0]["T_OrderDetailValidation"] == "Y" ) return;
|
||||
$sql = "select Other_CytologiID from other_cytologi where Other_CytologiT_OrderDetailID = ? and Other_CytologiIsActive = 'Y'";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Cytologi cek Existence " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
$cytologiID = 0;
|
||||
if (count($rows) > 0 ) $cytologiID = $rows[0]["Other_CytologiID"];
|
||||
if ( $cytologiID > 0 ) {
|
||||
$sql = "update other_cytologi set Other_CytologiIsActive = 'N' where Other_CytologiID = ? ";
|
||||
$qry = $this->db->query($sql, array($cytologiID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Cytologi set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$sql = "update other_cytologidetails set Other_CytologiDetailsIsActive = 'N' where Other_CytologiDetailsOther_CytologiID= ? ";
|
||||
$qry = $this->db->query($sql, array($cytologiID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Cytologi Details set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
unset($header["Other_CytologiID"]);
|
||||
$header["Other_CytologiCreated"] = date("Y-m-d h:i:s");
|
||||
$header["Other_CytologiLastUpdated"] =date("Y-m-d h:i:s");
|
||||
$header["Other_CytologiUserID"] = 3;
|
||||
$header["Other_CytologiIsActive"] = "Y";
|
||||
$header["Other_CytologiT_OrderDetailID"] = $detailID;
|
||||
$qry = $this->db->insert("other_cytologi",$header);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Cytologi Add Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$cytologiID = $this->db->insert_id();
|
||||
if ($cytologiID == 0 ) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Cytologi ID Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
foreach($detail as $idx => $d ) {
|
||||
$detail[$idx]["Other_CytologiDetailsOther_CytologiID"] = $cytologiID ;
|
||||
$detail[$idx]["Other_CytologiDetailsUserID"] = 3;
|
||||
$detail[$idx]["Other_CytologiDetailsIsActive"] = "Y";
|
||||
unset($detail[$idx]["Other_CytologiDetailsID"]);
|
||||
unset($detail[$idx]["Other_CytologiDetailsCreated"]);
|
||||
unset($detail[$idx]["Other_CytologiDetailsLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_cytologidetails",$detail);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Cytologi Add Detail" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//fna
|
||||
function update_fna($detailID, $header, $detail ) {
|
||||
$sql = "select * from t_orderdetail where T_OrderDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError FNA cek Validation " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) == 0 ) return;
|
||||
if ($rows[0]["T_OrderDetailValidation"] == "Y" ) return;
|
||||
$sql = "select Other_FNAID from other_fna where Other_FNAT_OrderDetailID = ? and Other_FNAIsActive = 'Y'";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError FNA cek Existence " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
$fnaID = 0;
|
||||
if (count($rows) > 0 ) $fnaID = $rows[0]["Other_FNAID"];
|
||||
if ( $fnaID > 0 ) {
|
||||
$sql = "update other_fna set Other_FNAIsActive = 'N' where Other_FNAID = ? ";
|
||||
$qry = $this->db->query($sql, array($fnaID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError FNA set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$sql = "update other_fnadetails set Other_FNADetailsIsActive = 'N' where Other_FNADetailsOther_FNAID= ? ";
|
||||
$qry = $this->db->query($sql, array($fnaID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError FNA Details set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
unset($header["Other_FNAID"]);
|
||||
$header["Other_FNACreated"] = date("Y-m-d h:i:s");
|
||||
$header["Other_FNALastUpdated"] =date("Y-m-d h:i:s");
|
||||
$header["Other_FNAUserID"] = 3;
|
||||
$header["Other_FNAIsActive"] = "Y";
|
||||
$header["Other_FNAT_OrderDetailID"] = $detailID;
|
||||
$qry = $this->db->insert("other_fna",$header);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError FNA Add Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$fnaID = $this->db->insert_id();
|
||||
if ($fnaID == 0 ) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError FNA ID Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
foreach($detail as $idx => $d ) {
|
||||
$detail[$idx]["Other_FNADetailsOther_FNAID"] = $fnaID ;
|
||||
$detail[$idx]["Other_FNADetailsUserID"] = 3;
|
||||
$detail[$idx]["Other_FNADetailsIsActive"] = "Y";
|
||||
unset($detail[$idx]["Other_FNADetailsID"]);
|
||||
unset($detail[$idx]["Other_FNADetailsCreated"]);
|
||||
unset($detail[$idx]["Other_FNADetailsLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_fnadetails",$detail);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError FNA Add Detail" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update papsmear
|
||||
function update_papsmear ($detailID, $header, $detail ) {
|
||||
$sql = "select * from t_orderdetail where T_OrderDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear cek Validation " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) == 0 ) return;
|
||||
if ($rows[0]["T_OrderDetailValidation"] == "Y" ) return;
|
||||
$sql = "select Other_PapSmearID from other_papsmear where Other_PapSmearT_OrderDetailID = ? and Other_PapSmearIsActive = 'Y'";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear cek Existence " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
$papsmearID = 0;
|
||||
if (count($rows) > 0 ) $papsmearID = $rows[0]["Other_PapSmearID"];
|
||||
if ( $papsmearID > 0 ) {
|
||||
$sql = "update other_papsmear set Other_PapSmearIsActive = 'N' where Other_PapSmearID = ? ";
|
||||
$qry = $this->db->query($sql, array($papsmearID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$sql = "update other_papsmearbahan set Other_PapSmearBahanIsActive = 'N' where Other_PapSmearBahanOther_PapSmearID= ? ";
|
||||
$qry = $this->db->query($sql, array($papsmearID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Details set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "update other_papsmearcategory set Other_PapSmearCategoryIsActive = 'N' where Other_PapSmearCategoryOther_PapSmearID= ? ";
|
||||
$qry = $this->db->query($sql, array($papsmearID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Category set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "update other_papsmearcheck set Other_PapSmearCheckIsActive = 'N' where Other_PapSmearCheckOther_PapSmearID= ? ";
|
||||
$qry = $this->db->query($sql, array($papsmearID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Check set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "update other_papsmeardetails set Other_PapSmearDetailsIsActive = 'N' where Other_PapSmearDetailsOther_PapSmearID= ? ";
|
||||
$qry = $this->db->query($sql, array($papsmearID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Details set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "update other_papsmearmaturasi set Other_PapSmearMaturasiIsActive = 'N' where Other_PapSmearMaturasiOther_PapSmearID= ? ";
|
||||
$qry = $this->db->query($sql, array($papsmearID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Details set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
unset($header["Other_PapSmearID"]);
|
||||
$header["Other_PapSmearCreated"] = date("Y-m-d h:i:s");
|
||||
$header["Other_PapSmearLastUpdated"] =date("Y-m-d h:i:s");
|
||||
$header["Other_PapSmearUserID"] = 3;
|
||||
$header["Other_PapSmearIsActive"] = "Y";
|
||||
$header["Other_PapSmearT_OrderDetailID"] = $detailID;
|
||||
$qry = $this->db->insert("other_papsmear",$header);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Add Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$papsmearID= $this->db->insert_id();
|
||||
if ($papsmearID == 0 ) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear ID Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
foreach($detail as $key => $d ) {
|
||||
if ($key == "bahan") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_PapSmearBahanOther_PapSmearID"] = $papsmearID ;
|
||||
$detail[$key][$idx]["Other_PapSmearBahanUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_PapSmearBahanIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_PapSmearBahanID"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearBahanCreated"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearBahanLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_papsmearbahan",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Add Bahan " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($key == "category") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_PapSmearCategoryOther_PapSmearID"] = $papsmearID ;
|
||||
$detail[$key][$idx]["Other_PapSmearCategoryUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_PapSmearCategoryIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_PapSmearCategoryID"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearCategoryCreated"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearCategoryLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_papsmearcategory",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Add Category " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($key == "check") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_PapSmearCheckOther_PapSmearID"] = $papsmearID ;
|
||||
$detail[$key][$idx]["Other_PapSmearCheckUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_PapSmearCheckIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_PapSmearCheckID"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearCheckCreated"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearCheckLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_papsmearcheck",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Add Check " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($key == "details") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_PapSmearDetailsOther_PapSmearID"] = $papsmearID ;
|
||||
$detail[$key][$idx]["Other_PapSmearDetailsUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_PapSmearDetailsIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_PapSmearDetailsID"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearDetailsCreated"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearDetailsLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_papsmeardetails",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Add Details " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($key == "maturasi") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_PapSmearMaturasiOther_PapSmearID"] = $papsmearID ;
|
||||
$detail[$key][$idx]["Other_PapSmearMaturasiUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_PapSmearMaturasiIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_PapSmearMaturasiID"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearMaturasiCreated"]);
|
||||
unset($detail[$key][$idx]["Other_PapSmearMaturasiLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_papsmearmaturasi",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError PapSmear Add Maturasi " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function update_lcprep($detailID, $header, $detail ) {
|
||||
$sql = "select * from t_orderdetail where T_OrderDetailID = ? ";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep cek Validation " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) == 0 ) return;
|
||||
if ($rows[0]["T_OrderDetailValidation"] == "Y" ) return;
|
||||
$sql = "select Other_LcprepID from other_lcprep where Other_LcprepT_orderDetailID = ? and Other_LcprepIsActive = 'Y'";
|
||||
$qry = $this->db->query($sql, array($detailID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep cek Existence " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$rows = $qry->result_array();
|
||||
$lcprepID = 0;
|
||||
if (count($rows) > 0 ) $lcprepID = $rows[0]["Other_LcprepID"];
|
||||
if ( $lcprepID > 0 ) {
|
||||
$sql = "update other_lcprep set Other_LcprepIsActive = 'N' where Other_LcprepID = ? ";
|
||||
$qry = $this->db->query($sql, array($lcprepID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$sql = "update other_lcprepadekuasi set Other_LcprepAdekuasiIsActive = 'N' where Other_LcprepAdekuasiOther_LcprepID= ? ";
|
||||
$qry = $this->db->query($sql, array($lcprepID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep Adekuasi set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "update other_lcprepinterpretasi set Other_LcprepInterpretasiIsActive = 'N' where Other_LcprepInterpretasiOther_LcprepID= ? ";
|
||||
$qry = $this->db->query($sql, array($lcprepID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep Interpretasi set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "update other_lcprepdetails set Other_LcprepDetailsIsActive = 'N' where Other_LcprepDetailsOther_LcprepID= ? ";
|
||||
$qry = $this->db->query($sql, array($lcprepID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep Details set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "update other_lcprepkategoriumum set Other_LcprepKategoriUmumIsActive = 'N' where Other_LcprepKategoriUmumOther_LcprepID= ? ";
|
||||
$qry = $this->db->query($sql, array($lcprepID));
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep KategoriUmum set Inactive" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
unset($header["Other_LcprepID"]);
|
||||
$header["Other_LcprepCreated"] = date("Y-m-d h:i:s");
|
||||
$header["Other_LcprepLastUpdated"] =date("Y-m-d h:i:s");
|
||||
$header["Other_LcprepUserID"] = 3;
|
||||
$header["Other_LcprepIsActive"] = "Y";
|
||||
$header["Other_LcprepT_orderDetailID"] = $detailID;
|
||||
$qry = $this->db->insert("other_lcprep",$header);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep Add Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
$lcprepID= $this->db->insert_id();
|
||||
if ($lcprepID == 0 ) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep ID Header" . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
foreach($detail as $key => $d ) {
|
||||
if ($key == "adekuasi") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_LcprepAdekuasiOther_LcprepID"] = $lcprepID ;
|
||||
$detail[$key][$idx]["Other_LcprepAdekuasiUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_LcprepAdekuasiIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_LcprepAdekuasiID"]);
|
||||
unset($detail[$key][$idx]["Other_LcprepAdekuasiCreated"]);
|
||||
unset($detail[$key][$idx]["Other_LcprepAdekuasiLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_lcprepadekuasi",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep Add Adekuasi " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($key == "interpretasi") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_LcprepInterpretasiOther_LcprepID"] = $lcprepID ;
|
||||
$detail[$key][$idx]["Other_LcprepInterpretasiUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_LcprepInterpretasiIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_LcprepInterpretasiID"]);
|
||||
unset($detail[$key][$idx]["Other_LcprepInterpretasiCreated"]);
|
||||
unset($detail[$key][$idx]["Other_LcprepInterpretasiLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_lcprepinterpretasi",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep Add Interpretasi " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($key == "details") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_LcprepDetailsOther_LcprepID"] = $lcprepID ;
|
||||
$detail[$key][$idx]["Other_LcprepDetailsUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_LcprepDetailsIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_LcprepDetailsID"]);
|
||||
unset($detail[$key][$idx]["Other_LcprepDetailsCreated"]);
|
||||
unset($detail[$key][$idx]["Other_LcprepDetailsLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_lcprepdetails",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep Add Details " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($key == "kategoriumum") {
|
||||
foreach($d as $idx => $xd) {
|
||||
$detail[$key][$idx]["Other_LcprepKategoriUmumOther_LcprepID"] = $lcprepID ;
|
||||
$detail[$key][$idx]["Other_LcprepKategoriUmumUserID"] = 3;
|
||||
$detail[$key][$idx]["Other_LcprepKategoriUmumIsActive"] = "Y";
|
||||
unset($detail[$key][$idx]["Other_LcprepKategoriUmumID"]);
|
||||
unset($detail[$key][$idx]["Other_LcprepKategoriUmumCreated"]);
|
||||
unset($detail[$key][$idx]["Other_LcprepKategoriUmumLastUpdated"]);
|
||||
}
|
||||
$qry = $this->db->insert_batch("other_lcprepkategoriumum",$detail[$key]);
|
||||
if(!$qry) {
|
||||
file_put_contents("/xtmp/dbg-xstatus_branch-v3.log", "\nError Lcprep Add KategoriUmum " . print_r($this->db->error(),true),FILE_APPEND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
$prm = $this->sys_input;
|
||||
foreach($prm as $p) {
|
||||
$deliveryOrderID = $p["incomingRefT_RefDeliveryOrderID"];
|
||||
$detailID = $p["incomingRefDetailT_OrderDetailID"];
|
||||
$normalValueID = $p["T_OrderDetailNat_NormalValueID"];
|
||||
$result = $p["T_OrderDetailResult"];
|
||||
$resultnote = $p["T_OrderDetailNote"];
|
||||
$validation = $p["T_OrderDetailValidation"];
|
||||
$verification = $p["T_OrderDetailVerification"];
|
||||
$status = $p["incomingRefDetailStatus"];
|
||||
$note = '';
|
||||
if (isset($p["note"])) $note = $p["note"];
|
||||
if ($validation == "Y") {
|
||||
$ret = $this->update_delivery($deliveryOrderID,$detailID,"$result","VALIDATION",$note);
|
||||
if ($ret) $ret = $this->update_order($detailID,$result,$resultnote,$normalValueID);
|
||||
if (isset($p["nonlab_result"])) {
|
||||
$type = $p["nonlab_result"]["type"];
|
||||
$header = $p["nonlab_result"]["header"];
|
||||
$detail = $p["nonlab_result"]["detail"];
|
||||
|
||||
if ($type == "mikro" ) {
|
||||
$this->update_mikro($detailID,$header,$detail);
|
||||
}
|
||||
if ($type == "papsmear" ) {
|
||||
$this->update_papsmear($detailID,$header,$detail);
|
||||
}
|
||||
if ($type == "lcprep" ) {
|
||||
$this->update_lcprep($detailID,$header,$detail);
|
||||
}
|
||||
if ($type == "fna" ) {
|
||||
$this->update_fna($detailID,$header,$detail);
|
||||
}
|
||||
if ($type == "cytologi" ) {
|
||||
$this->update_cytologi($detailID,$header,$detail);
|
||||
}
|
||||
}
|
||||
} elseif($verification == "Y") {
|
||||
$ret = $this->update_delivery($deliveryOrderID,$detailID,"$result","VERIFICATION",$note);
|
||||
} elseif($status != "N") {
|
||||
$ret = $this->update_delivery($deliveryOrderID,$detailID,"Diterima");
|
||||
} else {
|
||||
$ret = $this->update_delivery($deliveryOrderID,$detailID,"Ditolak");
|
||||
}
|
||||
if (! $ret ) {
|
||||
echo json_encode( array("status"=>"ERR", "message"=> print_r($this->db->error(),true) ));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
echo json_encode( array("status"=>"OK", "message"=>""));
|
||||
}
|
||||
function update_delivery($deliveryOrderID,$detailID,$value,$stage = "", $note = "" ) {
|
||||
$sql = "select T_RefDeliveryOrderDetailT_OrderDetailID ,
|
||||
T_RefDeliveryOrderDetailID,
|
||||
T_RefDeliveryOrderChildID
|
||||
from t_ref_deliveryorder_child
|
||||
join t_ref_deliveryorder_detail on
|
||||
T_RefDeliveryOrderChildT_RefDeliveryOrderDetailID = T_RefDeliveryOrderDetailID
|
||||
where T_RefDeliveryOrderDetailT_RefDeliveryOrderID = ?
|
||||
and T_RefDeliveryOrderChildT_OrderDetailID = ?";
|
||||
$qry = $this->db->query($sql, array($deliveryOrderID, $detailID));
|
||||
$flag_child = false;
|
||||
$child_id = 0;
|
||||
$refDeliveryOrderDetailID = 0;
|
||||
if ($qry) {
|
||||
$rows = $qry->result_array();
|
||||
if (count($rows) > 0 ) {
|
||||
$flag_child = true;
|
||||
$child_id = $rows[0]["T_RefDeliveryOrderChildID"];
|
||||
$parentDetailID = $rows[0]["T_RefDeliveryOrderDetailID"];
|
||||
}
|
||||
}
|
||||
if ($flag_child) {
|
||||
$sql = "update t_ref_deliveryorder_child
|
||||
set T_RefDeliveryOrderChildResult = ?,
|
||||
T_RefDeliveryOrderChildStage= ? ,
|
||||
T_RefDeliveryOrderChildNote = ?
|
||||
where T_RefDeliveryOrderChildID=?";
|
||||
|
||||
$qry = $this->db->query($sql, array($value, $state, $note, $child_id));
|
||||
$value = "...";
|
||||
$detailID = $parentDetailID;
|
||||
}
|
||||
|
||||
if ($flag_child) {
|
||||
$sql = "update t_ref_deliveryorder_detail
|
||||
set T_RefDeliveryOrderDetailResult = ?,
|
||||
T_RefDeliveryOrderDetailStage = ?,
|
||||
T_RefDeliveryOrderDetailNote = ?
|
||||
where T_RefDeliveryOrderDetailT_RefDeliveryOrderID = ?
|
||||
and T_RefDeliveryOrderDetailID = ?";
|
||||
} else {
|
||||
$sql = "update t_ref_deliveryorder_detail
|
||||
set T_RefDeliveryOrderDetailResult = ?,
|
||||
T_RefDeliveryOrderDetailStage = ?,
|
||||
T_RefDeliveryOrderDetailNote = ?
|
||||
where T_RefDeliveryOrderDetailT_RefDeliveryOrderID = ?
|
||||
and T_RefDeliveryOrderDetailT_OrderDetailID = ?";
|
||||
}
|
||||
|
||||
$qry = $this->db->query($sql, array($value, $stage, $note, $deliveryOrderID, $detailID));
|
||||
|
||||
return $qry;
|
||||
}
|
||||
function update_order($detailID,$value,$resultnote,$normalValueID) {
|
||||
$verUserID = 3;
|
||||
|
||||
$sql = "update t_orderdetail
|
||||
set T_OrderDetailResult = ?,
|
||||
T_OrderDetailNote = ?,
|
||||
T_OrderDetailNat_NormalValueID = ?,
|
||||
T_OrderDetailVerification = 'Y',
|
||||
T_OrderDetailVerDate = now(),
|
||||
T_OrderDetailVerUserID = $verUserID
|
||||
where T_OrderDetailID = ?";
|
||||
$qry = $this->db->query($sql, array($value,$resultnote, $normalValueID, $detailID));
|
||||
|
||||
if ( $qry) {
|
||||
$sql = "update t_orderdetail, nat_normalvalue, nat_methode
|
||||
set T_OrderDetailNat_MethodeID = Nat_NormalValueNat_MethodeID ,
|
||||
T_OrderDetailNat_MethodeName = Nat_MethodeName,
|
||||
T_OrderDetailNormalValueNote = Nat_NormalValueNote,
|
||||
T_OrderDetailNormalValueDescription = Nat_NormalValueDescription,
|
||||
T_OrderDetailMinValue = Nat_NormalValueMinValue,
|
||||
T_OrderDetailMaxValue = Nat_NormalValueMaxValue,
|
||||
T_OrderDetailMinValueInclusive = Nat_NormalValueMinValueInclusive,
|
||||
T_OrderDetailMaxValueInclusive = Nat_NormalValueMaxValueInclusive
|
||||
where T_OrderDetailID = ?
|
||||
and T_OrderDetailNat_NormalValueID = Nat_NormalValueID
|
||||
and Nat_NormalValueNat_MethodeID = Nat_MethodeID";
|
||||
$qryn = $this->db->query($sql, array($detailID));
|
||||
//if (! $qryn ) print_r($this->db->error());
|
||||
if (! $qryn ) return false;
|
||||
$sql = "call sp_set_normal_value_flag(?)";
|
||||
$qryu = $this->db->query($sql, array($detailID));
|
||||
//if (! $qryu ) print_r($this->db->error());
|
||||
if (! $qryu ) return false;
|
||||
$this->clean_mysqli_connection($this->db->conn_id);
|
||||
}
|
||||
return $qry;
|
||||
}
|
||||
}
|
||||
87
application/libraries/Ibl_encryptor.php
Normal file
87
application/libraries/Ibl_encryptor.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
class Ibl_encryptor
|
||||
{
|
||||
private $key;
|
||||
private $search_key;
|
||||
private $cipher = 'aes-256-gcm';
|
||||
private $tag_length = 16;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$passphrase = $_ENV['IBL_ENCRYPT_KEY'] ?? '';
|
||||
$passphrase_s = $_ENV['IBL_ENCRYPT_SEARCH_KEY'] ?? '';
|
||||
|
||||
if ($passphrase === '' || $passphrase_s === '') {
|
||||
log_message('error', 'Ibl_encryptor: IBL_ENCRYPT_KEY atau IBL_ENCRYPT_SEARCH_KEY kosong di .env');
|
||||
}
|
||||
|
||||
// Derive 32-byte key dari passphrase via SHA-256
|
||||
$this->key = hash('sha256', $passphrase, true);
|
||||
$this->search_key = hash('sha256', $passphrase_s, true);
|
||||
}
|
||||
|
||||
// Enkripsi plaintext → base64(iv[12] + tag[16] + ciphertext)
|
||||
public function encrypt($plaintext)
|
||||
{
|
||||
if ($plaintext === null || $plaintext === '') return null;
|
||||
$iv = random_bytes(12);
|
||||
$tag = '';
|
||||
$ct = openssl_encrypt((string)$plaintext, $this->cipher, $this->key, OPENSSL_RAW_DATA, $iv, $tag, '', $this->tag_length);
|
||||
if ($ct === false) return null;
|
||||
return base64_encode($iv . $tag . $ct);
|
||||
}
|
||||
|
||||
// Dekripsi base64(iv + tag + ciphertext) → plaintext
|
||||
public function decrypt($ciphertext)
|
||||
{
|
||||
if ($ciphertext === null || $ciphertext === '') return null;
|
||||
$raw = base64_decode($ciphertext);
|
||||
if (strlen($raw) < 12 + $this->tag_length) return null;
|
||||
$iv = substr($raw, 0, 12);
|
||||
$tag = substr($raw, 12, $this->tag_length);
|
||||
$ct = substr($raw, 12 + $this->tag_length);
|
||||
$pt = openssl_decrypt($ct, $this->cipher, $this->key, OPENSSL_RAW_DATA, $iv, $tag);
|
||||
return $pt === false ? null : $pt;
|
||||
}
|
||||
|
||||
// Hasilkan JSON array trigram token untuk kolom _bidx (partial search)
|
||||
public function search_bidx($value)
|
||||
{
|
||||
if ($value === null || $value === '') return null;
|
||||
$norm = mb_strtolower(trim((string)$value), 'UTF-8');
|
||||
$len = mb_strlen($norm, 'UTF-8');
|
||||
$tokens = [];
|
||||
if ($len <= 3) {
|
||||
$tokens[] = $this->_token($norm);
|
||||
} else {
|
||||
for ($i = 0; $i <= $len - 3; $i++) {
|
||||
$tokens[] = $this->_token(mb_substr($norm, $i, 3, 'UTF-8'));
|
||||
}
|
||||
}
|
||||
return json_encode(array_values(array_unique($tokens)));
|
||||
}
|
||||
|
||||
// Hasilkan array trigram token dari query string (untuk WHERE JSON_CONTAINS)
|
||||
public function query_tokens($value)
|
||||
{
|
||||
if ($value === null || $value === '') return [];
|
||||
$norm = mb_strtolower(trim((string)$value), 'UTF-8');
|
||||
$len = mb_strlen($norm, 'UTF-8');
|
||||
$tokens = [];
|
||||
if ($len <= 3) {
|
||||
$tokens[] = $this->_token($norm);
|
||||
} else {
|
||||
for ($i = 0; $i <= $len - 3; $i++) {
|
||||
$tokens[] = $this->_token(mb_substr($norm, $i, 3, 'UTF-8'));
|
||||
}
|
||||
}
|
||||
return array_values(array_unique($tokens));
|
||||
}
|
||||
|
||||
private function _token($str)
|
||||
{
|
||||
return hash_hmac('sha256', $str, $this->search_key);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ class Ibl_merge_report_gateway
|
||||
{
|
||||
$this->CI = &get_instance();
|
||||
$this->db_onedev = $this->CI->load->database('onedev', true);
|
||||
$this->CI->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function create_merge_request_from_lab_number($labNumber, $creatorUserId, $customName = '')
|
||||
@@ -561,6 +562,56 @@ class Ibl_merge_report_gateway
|
||||
);
|
||||
}
|
||||
|
||||
public function stream_from_qr_printout($orderHeaderId)
|
||||
{
|
||||
$query = $this->db_onedev->query(
|
||||
"SELECT QR_PrintOutReportURLElectronic
|
||||
FROM qr_printout
|
||||
WHERE QR_PrintOutT_OrderHeaderID = ?
|
||||
AND QR_PrintOutReportURLElectronic != ''
|
||||
AND QR_PrintOutIsActive = 1
|
||||
ORDER BY QR_PrintOutGroup_ResultID ASC",
|
||||
array((int) $orderHeaderId)
|
||||
);
|
||||
|
||||
if (!$query || $query->num_rows() === 0) {
|
||||
return $this->error('QR_PRINTOUT_NOT_FOUND', 'Tidak ada URL report di qr_printout untuk order ini.');
|
||||
}
|
||||
|
||||
$urls = array();
|
||||
$seen = array();
|
||||
foreach ($query->result_array() as $row) {
|
||||
$url = trim($row['QR_PrintOutReportURLElectronic']);
|
||||
if ($url === '' || isset($seen[$url])) {
|
||||
continue;
|
||||
}
|
||||
$seen[$url] = true;
|
||||
$url = str_replace('http://localhost/', 'http://127.0.0.1/', $url);
|
||||
$urls[] = $url;
|
||||
}
|
||||
|
||||
if (count($urls) === 0) {
|
||||
return $this->error('QR_PRINTOUT_EMPTY', 'URL report kosong setelah normalisasi.');
|
||||
}
|
||||
|
||||
// Populate decrypt cache sebelum Go merge service fetch PDF dari BIRT
|
||||
$cache_id = $this->CI->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
|
||||
$payload = array(
|
||||
'name' => 'merge-' . (int) $orderHeaderId . '.pdf',
|
||||
'urls' => $urls,
|
||||
'mergeRequestID' => (int) $orderHeaderId,
|
||||
'T_OrderHeaderID' => (int) $orderHeaderId,
|
||||
);
|
||||
|
||||
$result = $this->call_merge_service($payload);
|
||||
|
||||
// Hapus cache setelah merge service selesai
|
||||
$this->CI->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function call_merge_service(array $payload)
|
||||
{
|
||||
$config = $this->get_system_config();
|
||||
|
||||
132
application/libraries/Ibl_patient_decrypt.php
Normal file
132
application/libraries/Ibl_patient_decrypt.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Helper untuk decrypt PII pasien sebelum call SP/BIRT
|
||||
* Populate patient_print_cache, run callback, delete cache
|
||||
*/
|
||||
class Ibl_patient_decrypt
|
||||
{
|
||||
private $db;
|
||||
private $enc;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$CI = &get_instance();
|
||||
$this->db = $CI->load->database('onedev', true);
|
||||
$CI->load->library('ibl_encryptor');
|
||||
$this->enc = $CI->ibl_encryptor;
|
||||
}
|
||||
|
||||
// Populate cache, return cache_id untuk cleanup
|
||||
public function populate_cache_by_order($order_id)
|
||||
{
|
||||
$order_id = intval($order_id);
|
||||
if (!$order_id) return null;
|
||||
|
||||
$patient = $this->db->query(
|
||||
"SELECT M_PatientID, M_PatientName_enc, M_PatientDOB_enc,
|
||||
M_PatientHP_enc, M_PatientEmail_enc, M_PatientDOB
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ? LIMIT 1",
|
||||
[$order_id]
|
||||
)->row_array();
|
||||
|
||||
if (!$patient) return null;
|
||||
|
||||
$addr = $this->db->query(
|
||||
"SELECT M_PatientAddressDescription_enc FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = ?
|
||||
AND M_PatientAddressIsActive = 'Y'
|
||||
AND M_PatientAddressNote = 'Utama'
|
||||
LIMIT 1",
|
||||
[$patient['M_PatientID']]
|
||||
)->row_array();
|
||||
|
||||
$enc = $this->enc;
|
||||
$this->_insert_cache(
|
||||
$order_id,
|
||||
$patient['M_PatientID'],
|
||||
$enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? '',
|
||||
$enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now')),
|
||||
$enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? '',
|
||||
$enc->decrypt($patient['M_PatientEmail_enc']?? '') ?? '',
|
||||
$enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? ''
|
||||
);
|
||||
|
||||
return $this->db->insert_id();
|
||||
}
|
||||
|
||||
// Decrypt langsung dari query result (untuk controller dengan SQL sendiri)
|
||||
public function decrypt_row(array $row): array
|
||||
{
|
||||
$enc = $this->enc;
|
||||
if (!empty($row['M_PatientName_enc'])) $row['M_PatientName'] = $enc->decrypt($row['M_PatientName_enc']) ?? $row['M_PatientName'] ?? '';
|
||||
if (!empty($row['M_PatientDOB_enc'])) $row['M_PatientDOB'] = $enc->decrypt($row['M_PatientDOB_enc']) ?? $row['M_PatientDOB'] ?? '';
|
||||
if (!empty($row['M_PatientHP_enc'])) $row['M_PatientHP'] = $enc->decrypt($row['M_PatientHP_enc']) ?? '';
|
||||
if (!empty($row['M_PatientEmail_enc'])) $row['M_PatientEmail'] = $enc->decrypt($row['M_PatientEmail_enc']) ?? '';
|
||||
if (!empty($row['M_PatientPOB_enc'])) $row['M_PatientPOB'] = $enc->decrypt($row['M_PatientPOB_enc']) ?? '';
|
||||
if (!empty($row['M_PatientAddressDescription_enc'])) $row['M_PatientAddressDescription'] = $enc->decrypt($row['M_PatientAddressDescription_enc']) ?? '';
|
||||
if (!empty($row['phone_enc'])) $row['phone'] = $enc->decrypt($row['phone_enc']) ?? '';
|
||||
if (!empty($row['alamat_enc'])) $row['alamat'] = $enc->decrypt($row['alamat_enc']) ?? '';
|
||||
if (!empty($row['dob_enc'])) $row['dob'] = $enc->decrypt($row['dob_enc']) ?? '';
|
||||
foreach (array_keys($row) as $k) { if (substr($k, -4) === '_enc') unset($row[$k]); }
|
||||
return $row;
|
||||
}
|
||||
|
||||
// Hapus cache by id
|
||||
public function delete_cache($cache_id)
|
||||
{
|
||||
if ($cache_id) {
|
||||
$this->db->query("DELETE FROM patient_print_cache WHERE ppc_id = ?", [$cache_id]);
|
||||
}
|
||||
// Cleanup expired juga
|
||||
$this->db->query("DELETE FROM patient_print_cache WHERE ppc_created < NOW() - INTERVAL 5 MINUTE");
|
||||
}
|
||||
|
||||
// Fetch PDF dari BIRT dengan auto decrypt cache
|
||||
// Ganti semua file_get_contents($birt_url) dengan ini
|
||||
public function fetch_birt_pdf($birt_relative_url)
|
||||
{
|
||||
// Parse PID dari URL query string
|
||||
parse_str(parse_url($birt_relative_url, PHP_URL_QUERY) ?? '', $params);
|
||||
$order_id = intval($params['PID'] ?? 0);
|
||||
|
||||
$cache_id = $order_id ? $this->populate_cache_by_order($order_id) : null;
|
||||
|
||||
// Build full internal URL ke BIRT server
|
||||
$full_url = 'http://localhost:8080' . $birt_relative_url;
|
||||
$context = stream_context_create(['http' => ['timeout' => 120]]);
|
||||
$pdf = @file_get_contents($full_url, false, $context);
|
||||
|
||||
$this->delete_cache($cache_id);
|
||||
|
||||
return $pdf;
|
||||
}
|
||||
|
||||
// Populate cache lalu return URL (untuk controller yang return URL ke frontend)
|
||||
// Cache hidup 5 menit — cukup untuk browser buka BIRT
|
||||
public function pre_cache_and_get_url($birt_relative_url)
|
||||
{
|
||||
parse_str(parse_url($birt_relative_url, PHP_URL_QUERY) ?? '', $params);
|
||||
$order_id = intval($params['PID'] ?? 0);
|
||||
if ($order_id) {
|
||||
$this->populate_cache_by_order($order_id);
|
||||
}
|
||||
return $birt_relative_url;
|
||||
}
|
||||
|
||||
private function _insert_cache($order_id, $patient_id, $name, $dob, $hp, $email, $address)
|
||||
{
|
||||
$this->db->query(
|
||||
"DELETE FROM patient_print_cache WHERE ppc_order_id = ? OR ppc_created < NOW() - INTERVAL 5 MINUTE",
|
||||
[$order_id]
|
||||
);
|
||||
$this->db->query(
|
||||
"INSERT INTO patient_print_cache (ppc_order_id, ppc_patient_id, ppc_name, ppc_dob, ppc_hp, ppc_email, ppc_address, ppc_created)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, NOW())",
|
||||
[$order_id, $patient_id, $name, $dob, $hp, $email, $address]
|
||||
);
|
||||
}
|
||||
}
|
||||
546
application/libraries/Ibl_sampling_normal.php
Normal file
546
application/libraries/Ibl_sampling_normal.php
Normal file
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
defined('BASEPATH') or exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Pengganti fn_sampling_get_normal, sp_sampling_check_normal_setting,
|
||||
* dan sp_sampling_fix_normal_by_orderdetail (MySQL).
|
||||
*
|
||||
* Alasan: SP/fungsi MySQL membaca M_PatientDOB langsung dari m_patient,
|
||||
* yang NULL setelah enkripsi PDP. Library ini decrypt M_PatientDOB_enc
|
||||
* di PHP sebelum menghitung usia.
|
||||
*/
|
||||
class Ibl_sampling_normal
|
||||
{
|
||||
private $db;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$CI = &get_instance();
|
||||
$this->db = $CI->load->database('onedev', true);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Cari Nat_NormalValueID sesuai methode, test, sex, dan umur (dalam hari).
|
||||
* Urutan prioritas:
|
||||
* Type 1 — sex + age range
|
||||
* Type 2 — age range saja
|
||||
* Type 3 — sex saja
|
||||
* Type 4 — fallback
|
||||
*/
|
||||
public function get_normal_value_id($methodeID, $natTestID, $sexID, $ageInDay)
|
||||
{
|
||||
$methodeID = intval($methodeID);
|
||||
$natTestID = intval($natTestID);
|
||||
$sexID = intval($sexID);
|
||||
$ageInDay = intval($ageInDay);
|
||||
|
||||
$min_days = $this->_age_sql('Nat_NormalValueMinAge');
|
||||
$max_days = $this->_age_sql('Nat_NormalValueMaxAge');
|
||||
|
||||
$age_filter = "
|
||||
AND (
|
||||
(Nat_NormalValueMinAgeInclusive = 'Y' AND ($min_days) <= $ageInDay)
|
||||
OR (Nat_NormalValueMinAgeInclusive = 'N' AND ($min_days) < $ageInDay)
|
||||
)
|
||||
AND (
|
||||
(Nat_NormalValueMaxAgeInclusive = 'Y' AND ($max_days) >= $ageInDay)
|
||||
OR (Nat_NormalValueMaxAgeInclusive = 'N' AND ($max_days) > $ageInDay)
|
||||
)";
|
||||
|
||||
$base = "FROM nat_normalvalue
|
||||
WHERE (Nat_NormalValueValidDate IS NULL OR Nat_NormalValueValidDate < NOW())
|
||||
AND Nat_NormalValueIsActive = 'Y'
|
||||
AND Nat_NormalValueIsAbnormal = 'N'
|
||||
AND Nat_NormalValueNat_MethodeID = $methodeID
|
||||
AND Nat_NormalValueNat_TestID = $natTestID
|
||||
AND Nat_NormalValueNat_FlagID = 1";
|
||||
|
||||
$id = $this->_query_one("SELECT Nat_NormalValueID $base
|
||||
AND Nat_NormalValueNat_NormalValueTypeID = 1
|
||||
AND Nat_NormalValueNat_SexID = $sexID
|
||||
$age_filter LIMIT 1");
|
||||
if ($id) return $id;
|
||||
|
||||
$id = $this->_query_one("SELECT Nat_NormalValueID $base
|
||||
AND Nat_NormalValueNat_NormalValueTypeID = 2
|
||||
$age_filter LIMIT 1");
|
||||
if ($id) return $id;
|
||||
|
||||
$id = $this->_query_one("SELECT Nat_NormalValueID $base
|
||||
AND Nat_NormalValueNat_NormalValueTypeID = 3
|
||||
AND Nat_NormalValueNat_SexID = $sexID
|
||||
LIMIT 1");
|
||||
if ($id) return $id;
|
||||
|
||||
$id = $this->_query_one("SELECT Nat_NormalValueID $base
|
||||
AND Nat_NormalValueNat_NormalValueTypeID = 4
|
||||
LIMIT 1");
|
||||
if ($id) return $id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pengganti sp_sampling_check_normal_setting.
|
||||
* Mengembalikan array compat dengan call_multi_result_procedure():
|
||||
* ok, message, result_sets[0]=summary, [1]=checks, [2]=branches, [3]=candidates
|
||||
*/
|
||||
public function check_setting_by_order_detail($orderDetailID)
|
||||
{
|
||||
$orderDetailID = intval($orderDetailID);
|
||||
$data = $this->_load_order_detail_data($orderDetailID);
|
||||
if ($data === null) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'message' => "T_OrderDetailID {$orderDetailID} tidak ditemukan atau tidak aktif",
|
||||
'result_sets' => [],
|
||||
];
|
||||
}
|
||||
|
||||
list($sexID, $dobStr, $orderDate, $ageInDay,
|
||||
$orderHeaderID, $patientID, $natTestID,
|
||||
$row) = $data;
|
||||
|
||||
$methods = $this->_resolve_method_sources($natTestID);
|
||||
list($selID, $selName, $selSource) = $this->_pick_method($methods);
|
||||
|
||||
$normalValueID = 0;
|
||||
if ($selID > 0 && $natTestID > 0 && $sexID > 0 && $ageInDay !== null) {
|
||||
$normalValueID = $this->get_normal_value_id($selID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
|
||||
$summary = [[
|
||||
'T_OrderDetailID' => $orderDetailID,
|
||||
'T_OrderHeaderID' => $orderHeaderID,
|
||||
'M_PatientID' => $patientID,
|
||||
'M_PatientM_SexID' => $sexID ?: null,
|
||||
'M_PatientDOB' => $dobStr ?: null,
|
||||
'T_OrderHeaderDate' => $row['order_date'],
|
||||
'AgeInDay' => $ageInDay,
|
||||
'T_TestID' => intval($row['t_test_id']),
|
||||
'T_TestName' => $row['t_test_name'],
|
||||
'Nat_TestID' => $natTestID ?: null,
|
||||
'Nat_TestCode' => $row['nat_test_code'],
|
||||
'Nat_TestName' => $row['nat_test_name'],
|
||||
'T_OrderDetailNat_MethodeID'=> intval($row['order_detail_methode_id']),
|
||||
'MethodeIDFromPriority' => $methods['priority_id'] ?: null,
|
||||
'MethodeNameFromPriority' => $methods['priority_name'],
|
||||
'MethodeIDFromInstrument' => $methods['instrument_id'] ?: null,
|
||||
'MethodeNameFromInstrument' => $methods['instrument_name'],
|
||||
'MethodeIDFromNormalValue' => $methods['normalvalue_id'] ?: null,
|
||||
'MethodeNameFromNormalValue'=> $methods['normalvalue_name'],
|
||||
'SelectedMethodeID' => $selID,
|
||||
'SelectedMethodeName' => $selName,
|
||||
'SelectedMethodeSource' => $selSource,
|
||||
'FnSamplingGetNormalResult' => $normalValueID,
|
||||
]];
|
||||
|
||||
$nvCount = 0;
|
||||
if ($natTestID > 0) {
|
||||
$r = $this->db->query(
|
||||
"SELECT COUNT(*) AS cnt FROM nat_normalvalue
|
||||
WHERE Nat_NormalValueNat_TestID = ?
|
||||
AND Nat_NormalValueNat_MethodeID = ?
|
||||
AND Nat_NormalValueIsActive = 'Y'
|
||||
AND Nat_NormalValueIsAbnormal = 'N'",
|
||||
[$natTestID, $selID ?: 0]
|
||||
)->row_array();
|
||||
$nvCount = intval($r['cnt'] ?? 0);
|
||||
}
|
||||
|
||||
$checks = [
|
||||
$this->_chk('ORDER_DETAIL_ACTIVE', true, (string) $orderDetailID, 't_orderdetail aktif harus ditemukan'),
|
||||
$this->_chk('PATIENT_SEX', $sexID > 0, (string) ($sexID ?: 'NULL'), 'Dipakai pada type 1 dan type 3'),
|
||||
$this->_chk('PATIENT_DOB', $dobStr !== '', ($dobStr ?: 'NULL'), 'DOB dipakai untuk hitung AgeInDay'),
|
||||
$this->_chk('ORDER_DATE', !empty($row['order_date']), ($row['order_date'] ?: 'NULL'), 'Tanggal order dipakai untuk hitung AgeInDay'),
|
||||
$this->_chk('AGE_IN_DAY', $ageInDay !== null, ($ageInDay !== null ? (string) $ageInDay : 'NULL'), 'Dipakai pada type 1 dan type 2'),
|
||||
$this->_chk('NAT_TEST', $natTestID > 0, (string) ($natTestID ?: 'NULL'), 'Harus ada mapping T_TestNat_TestID'),
|
||||
$this->_chk('METHOD_PRIORITY', $methods['priority_id'] > 0, (string) ($methods['priority_id'] ?: 'NULL'), 'Sumber metode prioritas pertama'),
|
||||
$this->_chk('METHOD_INSTRUMENT', $methods['instrument_id'] > 0, (string) ($methods['instrument_id'] ?: 'NULL'), 'Fallback metode kedua'),
|
||||
$this->_chk('METHOD_NORMALVALUE', $methods['normalvalue_id'] > 0, (string) ($methods['normalvalue_id'] ?: 'NULL'), 'Fallback metode ketiga'),
|
||||
$this->_chk('SELECTED_METHOD', $selID > 0, (string) ($selID ?: 'NULL'), ($selSource ?: 'Tidak ada metode yang bisa dipakai')),
|
||||
$this->_chk('NORMALVALUE_TEST_METHOD_ACTIVE', $nvCount > 0, (string) $nvCount, 'Jumlah nat_normalvalue aktif non-abnormal untuk test + metode terpilih'),
|
||||
['check_name' => 'FN_RESULT', 'check_status' => ($normalValueID > 0 ? 'OK' : 'NOT_FOUND'), 'check_value' => (string) $normalValueID, 'check_note' => 'Hasil akhir fn_sampling_get_normal'],
|
||||
];
|
||||
|
||||
$branches = $selID > 0
|
||||
? $this->_query_branches($selID, $natTestID, $sexID, $ageInDay)
|
||||
: [['branch_name' => 'NO_SELECTED_METHOD', 'matched_count' => 0, 'first_normalvalue_id' => null]];
|
||||
$candidates = $natTestID > 0 ? $this->_query_candidates($selID, $natTestID, $sexID, $ageInDay) : [];
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'message' => '',
|
||||
'result_sets' => [$summary, $checks, $branches, $candidates],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pengganti sp_sampling_fix_normal_by_orderdetail.
|
||||
* Mengembalikan array compat dengan call_multi_result_procedure():
|
||||
* ok, message, result_sets[0]=result_row, [1]=order_detail_row
|
||||
*/
|
||||
public function fix_by_order_detail($orderDetailID)
|
||||
{
|
||||
$orderDetailID = intval($orderDetailID);
|
||||
$data = $this->_load_order_detail_data($orderDetailID);
|
||||
if ($data === null) {
|
||||
$errRow = [[
|
||||
'status' => 'ERR',
|
||||
'message' => "T_OrderDetailID {$orderDetailID} tidak ditemukan atau tidak aktif",
|
||||
'selected_methode_id' => null,
|
||||
'selected_methode_name'=> null,
|
||||
'selected_methode_source' => null,
|
||||
'nat_normalvalue_id' => null,
|
||||
'updated_rows' => 0,
|
||||
]];
|
||||
return ['ok' => true, 'message' => '', 'result_sets' => [$errRow, []]];
|
||||
}
|
||||
|
||||
list($sexID, $dobStr, $orderDate, $ageInDay,
|
||||
$orderHeaderID, $patientID, $natTestID,
|
||||
$row) = $data;
|
||||
|
||||
$methods = $this->_resolve_method_sources($natTestID);
|
||||
list($selID, $selName, $selSource) = $this->_pick_method($methods);
|
||||
|
||||
$normalValueID = 0;
|
||||
if ($selID > 0 && $natTestID > 0 && $sexID > 0 && $ageInDay !== null) {
|
||||
$normalValueID = $this->get_normal_value_id($selID, $natTestID, $sexID, $ageInDay);
|
||||
}
|
||||
|
||||
if ($normalValueID > 0) {
|
||||
$this->db->query(
|
||||
"UPDATE t_orderdetail od
|
||||
JOIN nat_normalvalue nn ON nn.Nat_NormalValueID = ?
|
||||
SET od.T_OrderDetailNat_NormalValueID = nn.Nat_NormalValueID,
|
||||
od.T_OrderDetailNormalValueNote = nn.Nat_NormalValueNote,
|
||||
od.T_OrderDetailNormalValueDescription = nn.Nat_NormalValueDescription,
|
||||
od.T_OrderDetailMinValue = nn.Nat_NormalValueMinValue,
|
||||
od.T_OrderDetailMaxValue = nn.Nat_NormalValueMaxValue,
|
||||
od.T_OrderDetailMinValueInclusive = nn.Nat_NormalValueMinValueInclusive,
|
||||
od.T_OrderDetailMaxValueInclusive = nn.Nat_NormalValueMaxValueInclusive,
|
||||
od.T_OrderDetailNat_MethodeID = ?,
|
||||
od.T_OrderdetailNat_MethodeName = ?
|
||||
WHERE od.T_OrderDetailID = ?
|
||||
AND od.T_OrderDetailIsActive = 'Y'",
|
||||
[$normalValueID, $selID, $selName, $orderDetailID]
|
||||
);
|
||||
$updatedRows = $this->db->affected_rows();
|
||||
$resultRow = [[
|
||||
'status' => 'OK',
|
||||
'message' => "Normal value berhasil diupdate untuk T_OrderDetailID {$orderDetailID}",
|
||||
'selected_methode_id' => $selID,
|
||||
'selected_methode_name'=> $selName,
|
||||
'selected_methode_source' => $selSource,
|
||||
'nat_normalvalue_id' => $normalValueID,
|
||||
'updated_rows' => $updatedRows,
|
||||
]];
|
||||
} else {
|
||||
$resultRow = [[
|
||||
'status' => 'NOT_FOUND',
|
||||
'message' => "Normal value tidak ditemukan untuk T_OrderDetailID {$orderDetailID}",
|
||||
'selected_methode_id' => $selID,
|
||||
'selected_methode_name'=> $selName,
|
||||
'selected_methode_source' => $selSource,
|
||||
'nat_normalvalue_id' => $normalValueID,
|
||||
'updated_rows' => 0,
|
||||
]];
|
||||
}
|
||||
|
||||
$odRow = $this->db->query(
|
||||
"SELECT T_OrderDetailID, T_OrderDetailNat_NormalValueID, T_OrderDetailNat_MethodeID,
|
||||
T_OrderdetailNat_MethodeName, T_OrderDetailNormalValueDescription,
|
||||
T_OrderDetailMinValue, T_OrderDetailMaxValue,
|
||||
T_OrderDetailMinValueInclusive, T_OrderDetailMaxValueInclusive
|
||||
FROM t_orderdetail WHERE T_OrderDetailID = ? LIMIT 1",
|
||||
[$orderDetailID]
|
||||
)->result_array();
|
||||
|
||||
return ['ok' => true, 'message' => '', 'result_sets' => [$resultRow, $odRow]];
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private helpers
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Inline pengganti fn_normal_get_age: konversi kolom usia ke hari di SQL. */
|
||||
private function _age_sql($col)
|
||||
{
|
||||
return "CASE Nat_NormalValueAgeUnit
|
||||
WHEN 'HARI' THEN {$col}
|
||||
WHEN 'BULAN' THEN {$col} * 30
|
||||
WHEN 'TAHUN' THEN {$col} * 365
|
||||
ELSE {$col}
|
||||
END";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ambil data dasar order detail termasuk DOB terenkripsi.
|
||||
* Return [sexID, dobStr, orderDate, ageInDay, orderHeaderID, patientID, natTestID, $row]
|
||||
* atau null jika tidak ditemukan.
|
||||
*/
|
||||
private function _load_order_detail_data($orderDetailID)
|
||||
{
|
||||
$row = $this->db->query(
|
||||
"SELECT
|
||||
od.T_OrderDetailT_OrderHeaderID AS order_header_id,
|
||||
oh.T_OrderHeaderM_PatientID AS patient_id,
|
||||
p.M_PatientM_SexID AS sex_id,
|
||||
p.M_PatientDOB_enc,
|
||||
p.M_PatientDOB,
|
||||
DATE(oh.T_OrderHeaderDate) AS order_date,
|
||||
od.T_OrderDetailT_TestID AS t_test_id,
|
||||
tt.T_TestName AS t_test_name,
|
||||
tt.T_TestNat_TestID AS nat_test_id,
|
||||
nt.Nat_TestCode AS nat_test_code,
|
||||
nt.Nat_TestName AS nat_test_name,
|
||||
od.T_OrderDetailNat_MethodeID AS order_detail_methode_id
|
||||
FROM t_orderdetail od
|
||||
JOIN t_orderheader oh ON oh.T_OrderHeaderID = od.T_OrderDetailT_OrderHeaderID
|
||||
JOIN m_patient p ON p.M_PatientID = oh.T_OrderHeaderM_PatientID
|
||||
LEFT JOIN t_test tt ON tt.T_TestID = od.T_OrderDetailT_TestID
|
||||
LEFT JOIN nat_test nt ON nt.Nat_TestID = tt.T_TestNat_TestID
|
||||
WHERE od.T_OrderDetailID = ?
|
||||
AND od.T_OrderDetailIsActive = 'Y'
|
||||
LIMIT 1",
|
||||
[$orderDetailID]
|
||||
)->row_array();
|
||||
|
||||
if (!$row) return null;
|
||||
|
||||
$dobStr = '';
|
||||
if (!empty($row['M_PatientDOB_enc'])) {
|
||||
$CI = &get_instance();
|
||||
$CI->load->library('ibl_encryptor');
|
||||
$dobStr = (string) ($CI->ibl_encryptor->decrypt($row['M_PatientDOB_enc']) ?? '');
|
||||
}
|
||||
if ($dobStr === '' && !empty($row['M_PatientDOB'])) {
|
||||
$dobStr = $row['M_PatientDOB'];
|
||||
}
|
||||
|
||||
$ageInDay = null;
|
||||
if ($dobStr !== '' && !empty($row['order_date'])) {
|
||||
try {
|
||||
$dob = new DateTime($dobStr);
|
||||
$oDate = new DateTime($row['order_date']);
|
||||
$ageInDay = (int) $oDate->diff($dob)->days;
|
||||
} catch (Exception $e) {}
|
||||
}
|
||||
|
||||
return [
|
||||
intval($row['sex_id']),
|
||||
$dobStr,
|
||||
$row['order_date'],
|
||||
$ageInDay,
|
||||
intval($row['order_header_id']),
|
||||
intval($row['patient_id']),
|
||||
intval($row['nat_test_id']),
|
||||
$row,
|
||||
];
|
||||
}
|
||||
|
||||
/** Resolusi metode dari 3 sumber: priority → instrument → normalvalue. */
|
||||
private function _resolve_method_sources($natTestID)
|
||||
{
|
||||
$r = $this->db->query(
|
||||
"SELECT mp.M_MethodePriorityNat_MethodeID, nm.Nat_MethodeName
|
||||
FROM m_methode_priority mp
|
||||
JOIN nat_methode nm ON nm.Nat_MethodeID = mp.M_MethodePriorityNat_MethodeID AND nm.Nat_MethodeIsActive = 'Y'
|
||||
JOIN m_instrumentmethode im ON im.M_InstrumentMethodeNat_MethodeID = nm.Nat_MethodeID AND im.M_InstrumentMethodeIsActive = 'Y'
|
||||
JOIN nat_instrument ni ON ni.Nat_InstrumentID = im.M_InstrumentMethodeNat_InstrumentID AND ni.Nat_InstrumentIsActive = 'Y'
|
||||
WHERE mp.M_MethodePriorityIsActive = 'Y'
|
||||
AND mp.M_MethodePriorityNat_TestID = ?
|
||||
AND mp.M_MethodePriorityM_DayOfWeekID = DAYOFWEEK(NOW())
|
||||
ORDER BY mp.M_MethodePriorityNumber DESC LIMIT 1",
|
||||
[$natTestID]
|
||||
)->row_array();
|
||||
$priorityID = intval($r['M_MethodePriorityNat_MethodeID'] ?? 0);
|
||||
$priorityName = $r['Nat_MethodeName'] ?? null;
|
||||
|
||||
$r = $this->db->query(
|
||||
"SELECT im.M_InstrumentMethodeNat_MethodeID, nm.Nat_MethodeName
|
||||
FROM m_instrumentmethode im
|
||||
JOIN nat_methode nm ON nm.Nat_MethodeID = im.M_InstrumentMethodeNat_MethodeID AND nm.Nat_MethodeIsActive = 'Y'
|
||||
JOIN nat_instrument ni ON ni.Nat_InstrumentID = im.M_InstrumentMethodeNat_InstrumentID AND ni.Nat_InstrumentIsActive = 'Y'
|
||||
WHERE im.M_InstrumentMethodeNat_TestID = ?
|
||||
AND im.M_InstrumentMethodeIsActive = 'Y'
|
||||
ORDER BY im.M_InstrumentMethodePriority DESC LIMIT 1",
|
||||
[$natTestID]
|
||||
)->row_array();
|
||||
$instrumentID = intval($r['M_InstrumentMethodeNat_MethodeID'] ?? 0);
|
||||
$instrumentName = $r['Nat_MethodeName'] ?? null;
|
||||
|
||||
$r = $this->db->query(
|
||||
"SELECT nn.Nat_NormalValueNat_MethodeID, nm.Nat_MethodeName
|
||||
FROM nat_normalvalue nn
|
||||
JOIN nat_methode nm ON nm.Nat_MethodeID = nn.Nat_NormalValueNat_MethodeID AND nm.Nat_MethodeIsActive = 'Y'
|
||||
WHERE nn.Nat_NormalValueNat_TestID = ?
|
||||
AND nn.Nat_NormalValueIsActive = 'Y'
|
||||
ORDER BY nn.Nat_NormalValueID LIMIT 1",
|
||||
[$natTestID]
|
||||
)->row_array();
|
||||
$normalID = intval($r['Nat_NormalValueNat_MethodeID'] ?? 0);
|
||||
$normalName = $r['Nat_MethodeName'] ?? null;
|
||||
|
||||
return [
|
||||
'priority_id' => $priorityID,
|
||||
'priority_name' => $priorityName,
|
||||
'instrument_id' => $instrumentID,
|
||||
'instrument_name'=> $instrumentName,
|
||||
'normalvalue_id' => $normalID,
|
||||
'normalvalue_name' => $normalName,
|
||||
];
|
||||
}
|
||||
|
||||
/** Pilih metode terbaik dari hasil _resolve_method_sources(). */
|
||||
private function _pick_method(array $methods)
|
||||
{
|
||||
if ($methods['priority_id'] > 0) {
|
||||
return [$methods['priority_id'], $methods['priority_name'], 'm_methode_priority'];
|
||||
}
|
||||
if ($methods['instrument_id'] > 0) {
|
||||
return [$methods['instrument_id'], $methods['instrument_name'], 'm_instrumentmethode'];
|
||||
}
|
||||
if ($methods['normalvalue_id'] > 0) {
|
||||
return [$methods['normalvalue_id'], $methods['normalvalue_name'], 'nat_normalvalue'];
|
||||
}
|
||||
return [0, null, null];
|
||||
}
|
||||
|
||||
/** Hitung matched_count per TYPE (1..4) untuk branch summary. */
|
||||
private function _query_branches($methodeID, $natTestID, $sexID, $ageInDay)
|
||||
{
|
||||
$min = $this->_age_sql('Nat_NormalValueMinAge');
|
||||
$max = $this->_age_sql('Nat_NormalValueMaxAge');
|
||||
$base = "FROM nat_normalvalue
|
||||
WHERE (Nat_NormalValueValidDate IS NULL OR Nat_NormalValueValidDate < NOW())
|
||||
AND Nat_NormalValueIsActive = 'Y'
|
||||
AND Nat_NormalValueIsAbnormal = 'N'
|
||||
AND Nat_NormalValueNat_FlagID = 1
|
||||
AND Nat_NormalValueNat_MethodeID = $methodeID
|
||||
AND Nat_NormalValueNat_TestID = $natTestID";
|
||||
|
||||
$ageFilter = "
|
||||
AND ((Nat_NormalValueMinAgeInclusive='Y' AND ($min)<=$ageInDay) OR (Nat_NormalValueMinAgeInclusive='N' AND ($min)<$ageInDay))
|
||||
AND ((Nat_NormalValueMaxAgeInclusive='Y' AND ($max)>=$ageInDay) OR (Nat_NormalValueMaxAgeInclusive='N' AND ($max)>$ageInDay))";
|
||||
|
||||
$types = [
|
||||
['TYPE_1', "AND Nat_NormalValueNat_NormalValueTypeID=1 AND Nat_NormalValueNat_SexID=$sexID $ageFilter"],
|
||||
['TYPE_2', "AND Nat_NormalValueNat_NormalValueTypeID=2 $ageFilter"],
|
||||
['TYPE_3', "AND Nat_NormalValueNat_NormalValueTypeID=3 AND Nat_NormalValueNat_SexID=$sexID"],
|
||||
['TYPE_4', "AND Nat_NormalValueNat_NormalValueTypeID=4"],
|
||||
];
|
||||
|
||||
$branches = [];
|
||||
foreach ($types as list($label, $filter)) {
|
||||
$r = $this->db->query("SELECT COUNT(*) AS cnt, MIN(Nat_NormalValueID) AS first_id $base $filter")->row_array();
|
||||
$branches[] = [
|
||||
'branch_name' => $label,
|
||||
'matched_count' => intval($r['cnt'] ?? 0),
|
||||
'first_normalvalue_id'=> $r['first_id'] ?? null,
|
||||
];
|
||||
}
|
||||
return $branches;
|
||||
}
|
||||
|
||||
/** Ambil semua kandidat nat_normalvalue dengan kolom diagnostik match/fail. */
|
||||
private function _query_candidates($methodeID, $natTestID, $sexID, $ageInDay)
|
||||
{
|
||||
if (!$natTestID) return [];
|
||||
|
||||
$min = $this->_age_sql('Nat_NormalValueMinAge');
|
||||
$max = $this->_age_sql('Nat_NormalValueMaxAge');
|
||||
$a = intval($ageInDay);
|
||||
$s = intval($sexID);
|
||||
$m = intval($methodeID);
|
||||
|
||||
$matchMinAge = "(
|
||||
(Nat_NormalValueMinAgeInclusive='Y' AND ($min)<=$a)
|
||||
OR (Nat_NormalValueMinAgeInclusive='N' AND ($min)<$a))";
|
||||
$matchMaxAge = "(
|
||||
(Nat_NormalValueMaxAgeInclusive='Y' AND ($max)>=$a)
|
||||
OR (Nat_NormalValueMaxAgeInclusive='N' AND ($max)>$a))";
|
||||
|
||||
$sql = "SELECT
|
||||
nn.Nat_NormalValueID,
|
||||
nn.Nat_NormalValueNat_TestID,
|
||||
nn.Nat_NormalValueNat_MethodeID,
|
||||
nm.Nat_MethodeName,
|
||||
nn.Nat_NormalValueNat_NormalValueTypeID,
|
||||
nn.Nat_NormalValueNat_SexID,
|
||||
nn.Nat_NormalValueValidDate,
|
||||
nn.Nat_NormalValueMinAge,
|
||||
nn.Nat_NormalValueMaxAge,
|
||||
nn.Nat_NormalValueAgeUnit,
|
||||
nn.Nat_NormalValueMinAgeInclusive,
|
||||
nn.Nat_NormalValueMaxAgeInclusive,
|
||||
($min) AS MinAgeInDay,
|
||||
($max) AS MaxAgeInDay,
|
||||
nn.Nat_NormalValueNat_FlagID,
|
||||
nn.Nat_NormalValueIsAbnormal,
|
||||
nn.Nat_NormalValueIsActive,
|
||||
IF((nn.Nat_NormalValueValidDate IS NULL OR nn.Nat_NormalValueValidDate < NOW()),'Y','N') AS MatchValidDate,
|
||||
IF(nn.Nat_NormalValueIsActive='Y','Y','N') AS MatchActive,
|
||||
IF(nn.Nat_NormalValueIsAbnormal='N','Y','N') AS MatchNotAbnormal,
|
||||
IF(nn.Nat_NormalValueNat_FlagID=1,'Y','N') AS MatchFlag,
|
||||
IF(nn.Nat_NormalValueNat_TestID=$natTestID,'Y','N') AS MatchNatTest,
|
||||
IF($m>0 AND nn.Nat_NormalValueNat_MethodeID=$m,'Y','N') AS MatchSelectedMethod,
|
||||
IF(nn.Nat_NormalValueNat_SexID=$s,'Y','N') AS MatchSex,
|
||||
IF($matchMinAge,'Y','N') AS MatchMinAge,
|
||||
IF($matchMaxAge,'Y','N') AS MatchMaxAge,
|
||||
CASE nn.Nat_NormalValueNat_NormalValueTypeID
|
||||
WHEN 1 THEN IF(nn.Nat_NormalValueNat_SexID=$s AND $matchMinAge AND $matchMaxAge,'Y','N')
|
||||
WHEN 2 THEN IF($matchMinAge AND $matchMaxAge,'Y','N')
|
||||
WHEN 3 THEN IF(nn.Nat_NormalValueNat_SexID=$s,'Y','N')
|
||||
WHEN 4 THEN 'Y'
|
||||
ELSE 'N'
|
||||
END AS MatchTypeRule,
|
||||
CONCAT_WS('; ',
|
||||
IF(NOT(nn.Nat_NormalValueValidDate IS NULL OR nn.Nat_NormalValueValidDate<NOW()),'valid_date_not_passed',NULL),
|
||||
IF(nn.Nat_NormalValueIsActive<>'Y','inactive',NULL),
|
||||
IF(nn.Nat_NormalValueIsAbnormal<>'N','abnormal_row',NULL),
|
||||
IF(nn.Nat_NormalValueNat_FlagID<>1,'flag_not_1',NULL),
|
||||
IF(nn.Nat_NormalValueNat_TestID<>$natTestID,'nat_test_mismatch',NULL),
|
||||
IF($m>0 AND nn.Nat_NormalValueNat_MethodeID<>$m,'methode_mismatch',NULL),
|
||||
IF(nn.Nat_NormalValueNat_NormalValueTypeID IN(1,3) AND nn.Nat_NormalValueNat_SexID<>$s,'sex_mismatch',NULL),
|
||||
IF(nn.Nat_NormalValueNat_NormalValueTypeID IN(1,2) AND NOT $matchMinAge,'age_below_min',NULL),
|
||||
IF(nn.Nat_NormalValueNat_NormalValueTypeID IN(1,2) AND NOT $matchMaxAge,'age_above_max',NULL)
|
||||
) AS FailReason
|
||||
FROM nat_normalvalue nn
|
||||
LEFT JOIN nat_methode nm ON nm.Nat_MethodeID = nn.Nat_NormalValueNat_MethodeID
|
||||
WHERE nn.Nat_NormalValueNat_TestID = $natTestID
|
||||
AND nn.Nat_NormalValueIsActive = 'Y'
|
||||
AND nn.Nat_NormalValueIsAbnormal = 'N'
|
||||
ORDER BY
|
||||
CASE WHEN $m>0 AND nn.Nat_NormalValueNat_MethodeID=$m THEN 0 ELSE 1 END,
|
||||
nn.Nat_NormalValueNat_MethodeID,
|
||||
nn.Nat_NormalValueNat_NormalValueTypeID,
|
||||
nn.Nat_NormalValueID";
|
||||
|
||||
$qry = $this->db->query($sql);
|
||||
return $qry ? $qry->result_array() : [];
|
||||
}
|
||||
|
||||
private function _chk($name, $ok, $value, $note)
|
||||
{
|
||||
return [
|
||||
'check_name' => $name,
|
||||
'check_status' => $ok ? 'OK' : 'MISSING',
|
||||
'check_value' => $value,
|
||||
'check_note' => $note,
|
||||
];
|
||||
}
|
||||
|
||||
private function _query_one($sql)
|
||||
{
|
||||
$qry = $this->db->query($sql);
|
||||
if (!$qry) return 0;
|
||||
$row = $qry->row_array();
|
||||
return intval($row['Nat_NormalValueID'] ?? 0);
|
||||
}
|
||||
}
|
||||
@@ -222,33 +222,69 @@ class ReportUrl
|
||||
return $rows_return;
|
||||
}
|
||||
|
||||
// Inject decrypted patient PII ke params jika ada PT_OrderHeaderID
|
||||
// SP header BIRT akan terima PDecryptName, PDecryptDOB, dll sebagai parameter IN
|
||||
private function _inject_patient_decrypt($params) {
|
||||
$order_id = isset($params['PT_OrderHeaderID']) ? intval($params['PT_OrderHeaderID']) : 0;
|
||||
if (!$order_id) return $params;
|
||||
|
||||
$CI = &get_instance();
|
||||
$CI->load->library('ibl_encryptor');
|
||||
|
||||
$sql = "SELECT M_PatientName_enc, M_PatientHP_enc, M_PatientEmail_enc,
|
||||
M_PatientDOB_enc, M_PatientPOB_enc, M_PatientNIK_enc,
|
||||
M_PatientIDNumber_enc, M_PatientDOB
|
||||
FROM t_orderheader
|
||||
JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID
|
||||
WHERE T_OrderHeaderID = ? LIMIT 1";
|
||||
$row = $this->db->query($sql, [$order_id])->row_array();
|
||||
if (!$row) return $params;
|
||||
|
||||
$enc = $CI->ibl_encryptor;
|
||||
$addr_sql = "SELECT M_PatientAddressDescription_enc FROM m_patientaddress
|
||||
WHERE M_PatientAddressM_PatientID = (
|
||||
SELECT T_OrderHeaderM_PatientID FROM t_orderheader WHERE T_OrderHeaderID = ?
|
||||
) AND M_PatientAddressIsActive = 'Y' AND M_PatientAddressNote = 'Utama' LIMIT 1";
|
||||
$addr_row = $this->db->query($addr_sql, [$order_id])->row_array();
|
||||
|
||||
$params['PDecryptName'] = urlencode($enc->decrypt($row['M_PatientName_enc'] ?? '') ?? '');
|
||||
$params['PDecryptDOB'] = urlencode($enc->decrypt($row['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($row['M_PatientDOB'] ?? 'now')));
|
||||
$params['PDecryptHP'] = urlencode($enc->decrypt($row['M_PatientHP_enc'] ?? '') ?? '');
|
||||
$params['PDecryptEmail'] = urlencode($enc->decrypt($row['M_PatientEmail_enc'] ?? '') ?? '');
|
||||
$params['PDecryptNIK'] = urlencode($enc->decrypt($row['M_PatientNIK_enc'] ?? '') ?? '');
|
||||
$params['PDecryptIDNum'] = urlencode($enc->decrypt($row['M_PatientIDNumber_enc']?? '') ?? '');
|
||||
$params['PDecryptAddr'] = urlencode($enc->decrypt($addr_row['M_PatientAddressDescription_enc'] ?? '') ?? '');
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
function get_report_url_by_code($report_code, $params = array()){
|
||||
$CI = &get_instance();
|
||||
$this->db = $CI->load->database("onedev", true);
|
||||
|
||||
// Get report data by code
|
||||
$report_data = $this->get_report_by_code($report_code, $params);
|
||||
|
||||
|
||||
if (!$report_data || empty($report_data)) {
|
||||
return array(false, "Report code not found: " . $report_code);
|
||||
}
|
||||
|
||||
// Inject decrypted patient PII jika ada order ID
|
||||
$params = $this->_inject_patient_decrypt($params);
|
||||
|
||||
// Get URL template
|
||||
$url_template = $report_data['Print_TransactionUrl'];
|
||||
|
||||
|
||||
if (empty($url_template)) {
|
||||
return array(false, "URL template is empty for report code: " . $report_code);
|
||||
}
|
||||
|
||||
// Replace placeholders with actual parameter values
|
||||
$final_url = $url_template;
|
||||
|
||||
|
||||
foreach ($params as $param_key => $param_value) {
|
||||
// Determine if value should be quoted (string) or not (numeric)
|
||||
$replacement_value = is_numeric($param_value) ? $param_value : "'" . $param_value . "'";
|
||||
|
||||
// Replace placeholder in URL
|
||||
$final_url = str_replace($param_key, $replacement_value, $final_url);
|
||||
$replacement_value = is_numeric($param_value) ? $param_value : urldecode($param_value);
|
||||
$final_url = str_replace($param_key, urlencode($replacement_value), $final_url);
|
||||
}
|
||||
|
||||
return array(true, $final_url);
|
||||
|
||||
@@ -56,21 +56,57 @@ class Reporturl
|
||||
}
|
||||
|
||||
if($show == 'N'){
|
||||
return array(true, $final_url);
|
||||
return array(true, $this->build_proxy_stream_url($report_code, $params));
|
||||
}
|
||||
else{
|
||||
$final_url = 'http'.($_SERVER['HTTPS'] == 'on' ? 's' : '').'://'.$_SERVER['HTTP_HOST'].$final_url;
|
||||
|
||||
$response = file_get_contents($final_url);
|
||||
$CI->load->library('ibl_patient_decrypt');
|
||||
$pdf = $CI->ibl_patient_decrypt->fetch_birt_pdf($final_url);
|
||||
header("Content-type: application/pdf");
|
||||
header(
|
||||
'Content-Disposition: inline; filename="' .
|
||||
$output_file_name .
|
||||
'"'
|
||||
);
|
||||
echo ($response);
|
||||
header('Content-Disposition: inline; filename="' . ($output_file_name ?? 'report.pdf') . '"');
|
||||
echo $pdf;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function build_proxy_stream_url($report_code, $params = array())
|
||||
{
|
||||
$CI = &get_instance();
|
||||
$token = $this->resolve_request_token($CI);
|
||||
|
||||
$query = array(
|
||||
'report_code' => $report_code,
|
||||
'token' => $token,
|
||||
'PT_OrderHeaderID' => $params['PT_OrderHeaderID'] ?? 0,
|
||||
);
|
||||
|
||||
if (isset($params['PPaymentID'])) {
|
||||
$query['PPaymentID'] = $params['PPaymentID'];
|
||||
}
|
||||
|
||||
if (isset($params['PUsername'])) {
|
||||
$query['PUsername'] = $params['PUsername'];
|
||||
}
|
||||
|
||||
return '/one-api-lab/tools/birt_proxy/stream_by_code?' . http_build_query($query);
|
||||
}
|
||||
|
||||
private function resolve_request_token($CI)
|
||||
{
|
||||
$rawInput = json_decode($CI->input->raw_input_stream, true);
|
||||
if (is_array($rawInput) && !empty($rawInput['token'])) {
|
||||
return trim($rawInput['token']);
|
||||
}
|
||||
|
||||
$postToken = $CI->input->post('token', true);
|
||||
if (!empty($postToken)) {
|
||||
return trim($postToken);
|
||||
}
|
||||
|
||||
$getToken = $CI->input->get('token', true);
|
||||
if (!empty($getToken)) {
|
||||
return trim($getToken);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
/*
|
||||
CREATE TABLE `print_transaction` (
|
||||
|
||||
24
catatan_meeting_klinik_internal.md
Normal file
24
catatan_meeting_klinik_internal.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Catatan Meeting Klinik Internal
|
||||
|
||||
## Task List IBL
|
||||
|
||||
### Registrasi Klinik (`klinik/Registrationv3.php`)
|
||||
- [x] Tambah `searchregion` dan `search_countries` (samakan dg `ibl_registration/Patient.php`)
|
||||
- [x] Fix `search()` — hapus kelurahan sub-query, tambah PDP decrypt inline
|
||||
- [x] Fix `getaddress()` — gunakan tabel `regional` via `M_PatientAddressRegionalCd`
|
||||
- [x] Fix `newpatient()` — simpan `M_PatientAddressRegionalCd`, City, State, District, Village, Country, CountryCode, Note
|
||||
- [x] Fix `editpatient()` — terapkan `_mask_dob()` ke `M_PatientDOB`
|
||||
- [x] Tambah `_mask_dob()` — masking DOB sesuai PDP UU No. 27/2022
|
||||
|
||||
### Screening Klinik (`klinik/screening/Screening.php`)
|
||||
- [x] Fix `search()` — hapus kelurahan sub-query, tambah PDP decrypt
|
||||
- [x] Tambah `getsexreg()` — samakan dg Registrationv3
|
||||
|
||||
### Sampling Call (`mockup/doctorclinicv2/Samplingcall.php`)
|
||||
- [x] Tambah UNION SELECT dari `one_klinik.order` agar antrian klinik muncul
|
||||
- [ ] Debug: order klinik masih belum muncul di antrian — cek params `locationid`, `stationid`, `xdate`
|
||||
|
||||
### Pending / Belum Dikerjakan
|
||||
- [ ]
|
||||
- [ ]
|
||||
- [ ]
|
||||
475
docs/pdp-encryption-runbook.md
Normal file
475
docs/pdp-encryption-runbook.md
Normal file
@@ -0,0 +1,475 @@
|
||||
# Runbook: Implementasi Enkripsi PII Pasien (UU PDP) — Production
|
||||
|
||||
> Dibuat: 2026-05-31 | Task: FHM31052601IBL
|
||||
> Teknologi: AES-256-GCM, Trigram Blind Index, PHP CodeIgniter 3, MariaDB
|
||||
|
||||
---
|
||||
|
||||
## Arsitektur
|
||||
|
||||
```
|
||||
.env (passphrase)
|
||||
│
|
||||
▼
|
||||
Ibl_encryptor library
|
||||
├── encrypt/decrypt → kolom _enc (AES-256-GCM)
|
||||
└── search_bidx → kolom _bidx (HMAC-SHA256 trigram, untuk search)
|
||||
|
||||
m_patient (plaintext kolom lama = MASKED)
|
||||
├── M_PatientName → "FAJRI H*******" (masked)
|
||||
├── M_PatientName_enc → "base64ciphertext" (encrypted, real value)
|
||||
├── M_PatientName_bidx→ ["tok1","tok2",...] (search index)
|
||||
└── ...field lainnya
|
||||
|
||||
Search patient: nama + HP + DOB + NIK via JSON_CONTAINS(_bidx)
|
||||
Read patient : decrypt _enc di PHP sebelum return ke client
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pre-flight Checklist
|
||||
|
||||
```bash
|
||||
# 1. Pastikan disk minimal 10GB free
|
||||
df -h /
|
||||
|
||||
# 2. Catat ukuran DB sebelum (untuk verifikasi)
|
||||
mysql -e "SELECT table_name, ROUND((data_length+index_length)/1024/1024,1) MB
|
||||
FROM information_schema.tables WHERE table_schema='one_lab'
|
||||
ORDER BY (data_length+index_length) DESC LIMIT 15;"
|
||||
|
||||
# 3. Pastikan tidak ada proses berat berjalan
|
||||
pgrep -a php
|
||||
```
|
||||
|
||||
> ⚠️ **Disk Space**: Enkripsi menambah ~1-2GB ke database (kolom _enc + _bidx).
|
||||
> Jika disk penuh, lihat bagian **Troubleshooting** di bawah.
|
||||
|
||||
---
|
||||
|
||||
## Urutan Eksekusi di Production
|
||||
|
||||
### Step 1 — Buat file `.env`
|
||||
|
||||
```bash
|
||||
cat > /path/to/one-api-lab/.env << 'EOF'
|
||||
IBL_ENCRYPT_KEY=<passphrase-kamu>
|
||||
IBL_ENCRYPT_SEARCH_KEY=<passphrase-search-kamu>
|
||||
EOF
|
||||
chmod 600 /path/to/one-api-lab/.env
|
||||
```
|
||||
|
||||
> ⚠️ **WAJIB** simpan kedua passphrase di password manager sebelum lanjut.
|
||||
> Key hilang = data di `_enc` tidak bisa didekripsi selamanya.
|
||||
|
||||
---
|
||||
|
||||
### Step 2 — Backup Database
|
||||
|
||||
```bash
|
||||
bash scripts/backup_pdp_tables.sh
|
||||
# Backup tersimpan di: ~/backup_pdp_YYYY_MM_DD_HHMMSS/
|
||||
# Verifikasi backup ada dan tidak kosong
|
||||
ls -lh ~/backup_pdp_*/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 3 — Jalankan SQL Migration (tambah kolom + update trigger)
|
||||
|
||||
```bash
|
||||
# Tambah kolom _enc dan _bidx
|
||||
mysql one_lab < sql/manual_changes/2026-05-31-pdp-encrypt-columns.sql
|
||||
|
||||
# Update trigger m_patient & m_patientaddress (pakai _enc di log JSON)
|
||||
mysql one_lab < sql/manual_changes/2026-05-31-pdp-update-triggers-enc.sql
|
||||
|
||||
# Ubah M_PatientDOB dari DATE ke VARCHAR(20) agar masked value tersimpan
|
||||
mysql one_lab < sql/manual_changes/2026-06-11-alter-m-patient-dob-to-varchar.sql
|
||||
|
||||
# Ubah Mcu_PreregisterPatientsDOB dari DATE ke VARCHAR(20) (sama)
|
||||
mysql one_lab < sql/manual_changes/2026-06-11-alter-mcu-preregister-dob-to-varchar.sql
|
||||
|
||||
# Verifikasi kolom terbentuk
|
||||
mysql -e "SHOW COLUMNS FROM one_lab.m_patient LIKE '%_enc';"
|
||||
mysql -e "SHOW COLUMNS FROM one_lab.m_patient LIKE '%_bidx';"
|
||||
mysql -e "SHOW COLUMNS FROM one_lab.m_patientaddress LIKE '%_enc';"
|
||||
mysql -e "SHOW COLUMNS FROM one_lab.m_patient WHERE Field = 'M_PatientDOB'\G"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 4 — Encrypt Data Pasien (m_patient)
|
||||
|
||||
```bash
|
||||
# Estimasi: 30-60 menit untuk 178K rows
|
||||
php scripts/migrate_encrypt_patient.php
|
||||
|
||||
# Verifikasi
|
||||
mysql -e "SELECT COUNT(*) total, COUNT(M_PatientName_enc) done
|
||||
FROM one_lab.m_patient;"
|
||||
# Expected: total == done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 5 — Populate NIK Bidx
|
||||
|
||||
```bash
|
||||
# Isi search index untuk NIK (dari _enc yang sudah ada)
|
||||
# Estimasi: 5-10 menit
|
||||
php scripts/migrate_nik_bidx.php
|
||||
|
||||
# Verifikasi
|
||||
mysql -e "SELECT COUNT(*) total, COUNT(M_PatientNIK_bidx) done
|
||||
FROM one_lab.m_patient WHERE M_PatientNIK_enc IS NOT NULL;"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 6 — Encrypt Alamat Pasien (m_patientaddress)
|
||||
|
||||
```bash
|
||||
# Enkripsi alamat TANPA bidx (hemat disk)
|
||||
# Estimasi: 15-30 menit untuk 133K rows
|
||||
php scripts/migrate_address_enc.php
|
||||
|
||||
# Verifikasi
|
||||
mysql -e "SELECT COUNT(*) total, COUNT(M_PatientAddressDescription_enc) done
|
||||
FROM one_lab.m_patientaddress;"
|
||||
# Expected: total == done
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 6b — Encrypt Address (m_patientaddress)
|
||||
|
||||
```bash
|
||||
# 357 baris tersisa di dev — jalankan sampai selesai di prod
|
||||
php scripts/migrate_address_enc.php
|
||||
|
||||
# Verifikasi
|
||||
mysql -e "SELECT COUNT(*) total, COUNT(M_PatientAddressDescription_enc) done FROM one_lab.m_patientaddress;"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 7 — Encrypt Tujuan Pengiriman Hasil (t_orderdelivery)
|
||||
|
||||
```bash
|
||||
# HANYA t_orderdelivery — berisi email/HP pasien (PII nyata, bisa dimasking)
|
||||
# Tabel hasil lab (t_orderdetail, so_resultentry*, dll) TIDAK dienkripsi —
|
||||
# lihat bagian "Keputusan Arsitektur" di bawah
|
||||
php scripts/migrate_encrypt_orderdelivery.php
|
||||
|
||||
# Verifikasi
|
||||
mysql -e "SELECT COUNT(*) total, COUNT(T_OrderDeliveryDestination_enc) done
|
||||
FROM one_lab.t_orderdelivery;"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 8 — Masking Kolom Plaintext
|
||||
|
||||
```bash
|
||||
# Masking semua kolom PII lama di m_patient & m_patientaddress
|
||||
# Format nama: "FAJRI H*******" (kata pertama penuh + inisial)
|
||||
php scripts/mask_patient_plaintext.php
|
||||
|
||||
# Re-mask nama dengan format terbaru (jika sudah pernah dimasking sebelumnya)
|
||||
php scripts/remask_patient_name.php
|
||||
|
||||
# Verifikasi: cek beberapa baris
|
||||
mysql -e "SELECT M_PatientID, M_PatientName, M_PatientHP, M_PatientEmail
|
||||
FROM one_lab.m_patient ORDER BY RAND() LIMIT 5;"
|
||||
# Expected: tampil "BUDI S******", "0812*****890", "bu***@gmail.com"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 8b — Buat patient_print_cache (untuk BIRT decrypt)
|
||||
|
||||
```bash
|
||||
mysql one_lab < sql/manual_changes/2026-05-31-pdp-birt-sp-cache-join.sql
|
||||
```
|
||||
|
||||
Tabel ini dibutuhkan oleh:
|
||||
- 6 SP header BIRT (sp_rpt_hasil_header, _2, _eng, sp_rpt_fo_001, sp_rpt_card_patient, sp_rpt_t_002)
|
||||
- Birt_proxy.php controller
|
||||
- Ibl_patient_decrypt library
|
||||
- Qr_report_uploader, Ibl_merge_report_gateway, send_email.php
|
||||
|
||||
---
|
||||
|
||||
### Step 8c — Update sp_rpt_t_002_eng (jika dipakai)
|
||||
|
||||
```bash
|
||||
# Cek apakah sp_rpt_t_002_eng ada
|
||||
mysql -e "SHOW PROCEDURE STATUS WHERE Db='one_lab' AND Name='sp_rpt_t_002_eng'\G"
|
||||
# Jika ada, update manual dengan LEFT JOIN ke patient_print_cache
|
||||
# (sama seperti sp_rpt_t_002 di 2026-05-31-pdp-birt-sp-cache-join.sql)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Catatan Disk Space untuk Production
|
||||
|
||||
> ⚠️ **Sangat penting**: Pastikan disk minimal **10GB free** sebelum mulai.
|
||||
> Trigger m_patient + m_patientaddress nulis ke log_patient setiap UPDATE.
|
||||
> Untuk migration + masking 178K+133K rows → log bisa 2-3GB.
|
||||
>
|
||||
> **Strategi aman**:
|
||||
> 1. DROP trigger dulu (`vm_patient_ai`, `vm_patient_bu`, `m_patientaddress_ai`, `m_patientaddress_bu`)
|
||||
> 2. Jalankan semua migration + masking scripts
|
||||
> 3. Recreate trigger: `mysql one_lab < sql/manual_changes/2026-05-31-pdp-update-triggers-enc.sql`
|
||||
>
|
||||
> File trigger SQL ada di: `sql/manual_changes/2026-05-31-pdp-update-triggers-enc.sql`
|
||||
|
||||
---
|
||||
|
||||
### Step 9 — Truncate Log Lama (Opsional tapi Direkomendasikan)
|
||||
|
||||
```bash
|
||||
# log_patient berisi JSON plaintext PII dari sebelum enkripsi
|
||||
# Truncate meningkatkan compliance (hapus data PII lama yang tidak terenkripsi)
|
||||
mysql one_lab_log -e 'TRUNCATE TABLE log_patient;'
|
||||
|
||||
# Verifikasi
|
||||
mysql -e "SELECT COUNT(*) FROM one_lab_log.log_patient;"
|
||||
# Expected: 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 10 — Verifikasi End-to-End
|
||||
|
||||
```bash
|
||||
# 1. Cek search patient berjalan
|
||||
curl -s -X POST https://[SERVER]/mockup/fo/ibl_registration/patient/search \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"token":"[VALID_TOKEN]","search":"BUDI","noreg":"","current_page":1}' \
|
||||
| python3 -m json.tool | head -20
|
||||
|
||||
# 2. Cek data terdekripsi dengan benar (nama muncul lengkap, bukan masked)
|
||||
# Expected di response: "M_PatientName": "BUDI SANTOSO" (bukan "BUDI S******")
|
||||
|
||||
# 3. Cek disk usage akhir
|
||||
df -h /
|
||||
|
||||
# 4. Cek MySQL masih sehat
|
||||
mysql -e "SHOW STATUS LIKE 'Threads_connected';"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Field yang Dienkripsi
|
||||
|
||||
### `one_lab.m_patient`
|
||||
| Field | Tipe kolom plain | `_enc` | `_bidx` (search) | Catatan |
|
||||
|-------|:---:|:------:|:----------------:|---------|
|
||||
| M_PatientName | VARCHAR | ✅ | ✅ | |
|
||||
| M_PatientHP | VARCHAR | ✅ | ✅ | |
|
||||
| M_PatientDOB | **VARCHAR(20)** | ✅ | ✅ | Diubah dari DATE → VARCHAR agar mask `**-**-YYYY` tersimpan |
|
||||
| M_PatientNIK | VARCHAR | ✅ | ✅ | ⚠️ `M_PatientNIK_bidx` diisi dari **`M_PatientIDNumber`**, bukan NIK |
|
||||
| M_PatientEmail | VARCHAR | ✅ | — | |
|
||||
| M_PatientPhone | VARCHAR | ✅ | — | |
|
||||
| M_PatientPOB | VARCHAR | ✅ | — | |
|
||||
| M_PatientIDNumber | VARCHAR | ✅ | — | Masked plain, bidx-nya lewat `M_PatientNIK_bidx` |
|
||||
| M_PatientNIP | VARCHAR | ✅ | — | |
|
||||
|
||||
### `one_lab.m_patientaddress`
|
||||
| Field | `_enc` | `_bidx` |
|
||||
|-------|:------:|:-------:|
|
||||
| M_PatientAddressDescription | ✅ | — (dihapus, hemat disk) |
|
||||
| M_PatientAddressEmail | ✅ | — |
|
||||
| M_PatientAddressPhone | ✅ | — |
|
||||
|
||||
### Tujuan Pengiriman Hasil (PII nyata)
|
||||
| Tabel | Field |
|
||||
|-------|-------|
|
||||
| `t_orderdelivery` | T_OrderDeliveryDestination (email/HP) |
|
||||
|
||||
### Log
|
||||
| Tabel | Field |
|
||||
|-------|-------|
|
||||
| `one_lab_log.log_patient` | Log_PatientJsonBefore/After (**di-truncate di production**) |
|
||||
| `one_lab_log.log_fo` | Log_FoJson |
|
||||
| `one_lab_log.log_resultentry` | Log_ResultEntryJSONBefore/After |
|
||||
|
||||
### TIDAK Dienkripsi (keputusan disengaja)
|
||||
| Tabel | Alasan |
|
||||
|-------|--------|
|
||||
| `t_orderdetail`, `t_orderheader` | Nilai hasil lab bukan PII tanpa identitas pasien. Trigger butuh plaintext untuk flag H/L/N. |
|
||||
| `so_resultentry_*`, `member_eligible` | Nilai klinis, bukan PII langsung. Plaintext dibutuhkan proses operasional. |
|
||||
| `mcu_resume_results` | JSON nilai lab tanpa PII. Enkripsi memberatkan global MCU report. |
|
||||
|
||||
**Perlindungan hasil lab** tetap via: identitas pasien terenkripsi di `m_patient` + access control + audit log.
|
||||
|
||||
---
|
||||
|
||||
## Format Masking Kolom Plaintext
|
||||
|
||||
| Field | Format | Contoh |
|
||||
|-------|--------|--------|
|
||||
| Nama (multi kata) | Kata pertama penuh + inisial+bintang per kata | `FAJRI H******* M****` |
|
||||
| Nama (satu kata) | 2 karakter pertama + bintang sisanya | `SI**` / `BI*****` |
|
||||
| HP/Phone | 4 digit pertama + bintang + 3 digit akhir | `0812*****890` |
|
||||
| Email | 2 huruf pertama + *** + @domain | `fa***@gmail.com` |
|
||||
| NIK/IDNumber | 4 digit pertama + *** + 2 digit akhir | `3201***01` |
|
||||
| POB | 2 huruf pertama + *** | `JA***` |
|
||||
| Alamat | 5 karakter pertama + *** | `Jl. S***` |
|
||||
|
||||
---
|
||||
|
||||
## Search Pasien
|
||||
|
||||
Parameter via `+` separator di field `search`:
|
||||
```
|
||||
search=NAMA+HP+DOB+NIK
|
||||
```
|
||||
| Posisi | Field | Contoh |
|
||||
|--------|-------|--------|
|
||||
| `e[0]` | Nama (min 3 karakter) | `BUD` |
|
||||
| `e[1]` | HP (min 3 karakter) | `081` |
|
||||
| `e[2]` | DOB format dd-mm-yyyy | `25-0` |
|
||||
| `e[3]` | NIK (min 3 karakter) | `320` |
|
||||
|
||||
---
|
||||
|
||||
## BIRT Report & FPDF
|
||||
|
||||
### Strategi Decrypt untuk Report
|
||||
|
||||
**BIRT Reports** (`print_transaction`):
|
||||
- PHP `Birt_proxy.php` → decrypt PII → INSERT `patient_print_cache` → call BIRT
|
||||
- 6 SP header yang diupdate dengan LEFT JOIN ke cache: `sp_rpt_hasil_header`, `sp_rpt_hasil_header_2`, `sp_rpt_hasil_header_eng`, `sp_rpt_fo_001`, `sp_rpt_card_patient`, `sp_rpt_t_002`
|
||||
- SP signature tidak berubah — `.rptdesign` tidak perlu diupdate
|
||||
- Cache TTL: 5 menit, auto-cleanup di request berikutnya
|
||||
|
||||
**Endpoint Birt_proxy:**
|
||||
- `POST /tools/birt_proxy/stream` — return PDF binary langsung
|
||||
- `POST /tools/birt_proxy/get_url` — return URL untuk buka di browser
|
||||
|
||||
**FPDF Controllers** (`tools/`):
|
||||
- `Inform_consent.php`, `Medical_checkup_report.php` — decrypt langsung dari `_enc` (direct SQL)
|
||||
- `Kartu_kontrol.php`, `Rpt_t_002.php`, `Rpt_t_002_eng.php` — populate cache → call SP → delete cache
|
||||
|
||||
**SQL produksi yang perlu dijalankan:**
|
||||
```bash
|
||||
mysql one_lab < sql/manual_changes/2026-05-31-pdp-birt-sp-cache-join.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Controller yang Sudah Diupdate (Decrypt + Encrypt)
|
||||
|
||||
| Controller | Fungsi |
|
||||
|-----------|--------|
|
||||
| `mockup/fo/ibl_registration/Patient.php` | Search, add, edit pasien FO |
|
||||
| `mockup/fo/ibl_registration/Order.php` | Order management (nama, email, HP) |
|
||||
| `mockup/fo/ibl_registration/Payment.php` | Kasir (nama pasien) |
|
||||
| `mockup/fo/ibl_registration/History.php` | History delivery (email/HP) |
|
||||
| `mockup/fo/ibl_registration/Delivery.php` | Pengiriman hasil (email/HP) |
|
||||
| `mockup/fo/ibl_registration/Order copy.php` | Order MCU |
|
||||
| `mockup/masterdata/Patientv4.php` | Masterdata pasien — tampil data **lengkap** |
|
||||
| `klinik/Registrationv3.php` | Registrasi & edit pasien klinik (`save()`, `newpatient()`) |
|
||||
| `mockup/setupmcuoffline-ibl/Preregister.php` | MCU offline IBL — batch CSV & newpatient |
|
||||
| `mockup/mcuoffline/Preregisterapp.php` | MCU offline app — batch CSV, search, newpatient |
|
||||
|
||||
## mcu_preregister_patients — Masking
|
||||
|
||||
Data PII yang dimasking saat INSERT ke staging table `mcu_preregister_patients`:
|
||||
|
||||
| Field | Tipe kolom | Mask |
|
||||
|-------|:---:|------|
|
||||
| `*PatientName` | VARCHAR | `_mask_name()` |
|
||||
| `*KTP` | VARCHAR | `_mask_id()` |
|
||||
| `*NIP` / `*NIK` | VARCHAR | `_mask_id()` |
|
||||
| `*Email` | VARCHAR | `_mask_email()` |
|
||||
| `*Hp` | VARCHAR | `_mask_phone()` |
|
||||
| `*DOB` | **VARCHAR(20)** | `_mask_dob()` — diubah dari DATE → VARCHAR agar mask `**-**-YYYY` tersimpan |
|
||||
|
||||
Tidak ada kolom `_enc` di tabel ini — data asli bisa diambil dari `m_patient` via `*M_PatientID`.
|
||||
|
||||
4 lokasi INSERT yang sudah diupdate: `savecsv()` & `save()` di setupmcuoffline-ibl, `save()` & `savenewform()` di mcuoffline/Preregisterapp.
|
||||
|
||||
## one_lab_dashboard.mcu_patient — Enkripsi via SP
|
||||
|
||||
Kolom `Mcu_PatientName` dan `Mcu_PatientDOB` diubah ke `TEXT` dan menyimpan
|
||||
nilai `_enc` dari `one_lab.m_patient` (JOIN via `Mcu_PreregisterPatientsM_PatientID`).
|
||||
|
||||
SP yang diupdate:
|
||||
- `sp_upsert_mcu_patient_by_preregister_id`
|
||||
- `sp_upsert_mcu_patient_by_mgm_mcuid`
|
||||
|
||||
SQL: `sql/manual_changes/2026-05-31-pdp-mcu-patient-dashboard-enc-sp.sql`
|
||||
|
||||
```bash
|
||||
mysql one_lab < sql/manual_changes/2026-05-31-pdp-mcu-patient-dashboard-enc-sp.sql
|
||||
```
|
||||
|
||||
## Controller yang Belum Diupdate (Tampil Data Masked)
|
||||
|
||||
Semua ~300+ controller lain otomatis tampilkan data termasking karena kolom
|
||||
plaintext sudah dimasking. Tidak perlu update satu-satu untuk compliance dasar.
|
||||
|
||||
**Sprint berikutnya** — update controller prioritas yang butuh data lengkap:
|
||||
- Sampling (samplinglab-vvii, samplingelectromedisnew)
|
||||
- Result entry (resultentrysoothers-v20, resultentrysoxray-v8, resultentrysoelectromedis-v8)
|
||||
- Result verification
|
||||
- MCU resume (resumeindividufacelift)
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Disk Penuh Saat Migration
|
||||
|
||||
```bash
|
||||
# Cek pemakai disk terbesar
|
||||
du -sh /home/one/* /tmp/* 2>/dev/null | sort -rh | head -20
|
||||
|
||||
# Bersihkan file lama yang aman dihapus:
|
||||
# - /home/one/project/one/dump_*.sql (backup lama)
|
||||
# - /home/one/project/one/*.tar.gz (archive lama)
|
||||
# - /tmp/intelephense (cache IDE)
|
||||
|
||||
# Bersihkan journal (butuh sudo)
|
||||
sudo journalctl --vacuum-size=300M
|
||||
sudo truncate -s 0 /var/log/btmp
|
||||
```
|
||||
|
||||
### MySQL Crash (Disk Penuh)
|
||||
|
||||
```bash
|
||||
# Restart MySQL setelah disk dibebaskan
|
||||
sudo systemctl start mariadb
|
||||
# atau
|
||||
sudo service mysql start
|
||||
```
|
||||
|
||||
### Migration Lambat (Trigger Overhead)
|
||||
|
||||
Trigger `m_patientaddress_bu` nulis ke `log_patient` setiap UPDATE.
|
||||
Jika log_patient sangat besar (>1GB) dan disk hampir penuh:
|
||||
|
||||
```bash
|
||||
# Truncate log lama (aman — data PII lama di log justru harus dihapus untuk compliance)
|
||||
mysql one_lab_log -e 'TRUNCATE TABLE log_patient;'
|
||||
```
|
||||
|
||||
### Restore jika Ada Masalah
|
||||
|
||||
```bash
|
||||
mysql one_lab < ~/backup_pdp_YYYY_MM_DD_HHMMSS/one_lab_tables.sql
|
||||
mysql one_lab_log < ~/backup_pdp_YYYY_MM_DD_HHMMSS/one_lab_log_tables.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Catatan Key Management
|
||||
|
||||
- Key disimpan di `.env` — **JANGAN commit ke git** (sudah ada di `.gitignore`)
|
||||
- Backup passphrase di: password manager + file enkripsi di lokasi terpisah dari server
|
||||
- Key rotation di masa depan: perlu re-encrypt semua data (decrypt lama → encrypt baru)
|
||||
- Tidak ada recovery jika key hilang
|
||||
109
docs/pdp-implementation-prompt.md
Normal file
109
docs/pdp-implementation-prompt.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Prompt Implementasi UU PDP — IBL Production Server
|
||||
|
||||
> Gunakan prompt ini untuk menginstruksikan agent/Claude saat implementasi di IBL server produksi.
|
||||
> Branch: `main` | Repo: `BE_IBL/one-api-lab`
|
||||
|
||||
---
|
||||
|
||||
## Prompt untuk Agent
|
||||
|
||||
```
|
||||
Kamu akan mengimplementasikan enkripsi PII pasien (UU PDP) ke IBL production server.
|
||||
|
||||
PENTING: Baca seluruh runbook di `docs/pdp-encryption-runbook.md` sebelum memulai.
|
||||
|
||||
KONTEKS:
|
||||
- Server IBL: SSH config "devibl" (atau sesuai config SSH yang tersedia)
|
||||
- Project path di server: /home/one/project/one/one-api-lab/ (atau sesuai deployment IBL)
|
||||
- Database: one_lab, one_lab_log
|
||||
- Enkripsi: AES-256-GCM, key dari .env (passphrase, bukan hex)
|
||||
- PHP: 7.2 (hindari syntax fn() arrow function)
|
||||
|
||||
LANGKAH WAJIB SEBELUM APAPUN:
|
||||
1. Cek disk space: minimal 10GB free
|
||||
- Jika kurang, hapus file lama di /home/one/ (bukan backup PDP, bukan MySQL data)
|
||||
- Journal logs butuh sudo: sudo journalctl --vacuum-size=300M
|
||||
|
||||
2. BACKUP DATABASE DULU:
|
||||
bash scripts/backup_pdp_tables.sh
|
||||
Verifikasi backup ada dan tidak kosong sebelum lanjut.
|
||||
|
||||
3. Buat .env di server (isi passphrase dari password manager IBL):
|
||||
IBL_ENCRYPT_KEY=<passphrase-dari-password-manager>
|
||||
IBL_ENCRYPT_SEARCH_KEY=<passphrase-search-dari-password-manager>
|
||||
chmod 600 .env
|
||||
|
||||
URUTAN EKSEKUSI (ikuti runbook):
|
||||
1. Backup database
|
||||
2. Buat .env
|
||||
3. Jalankan SQL migration:
|
||||
- sql/manual_changes/2026-05-31-pdp-encrypt-columns.sql
|
||||
- sql/manual_changes/2026-05-31-pdp-update-triggers-enc.sql
|
||||
- sql/manual_changes/2026-05-31-pdp-birt-sp-cache-join.sql (buat patient_print_cache)
|
||||
- sql/manual_changes/2026-06-08-pdp-fo-birt-sp-patient-print-cache.sql (update keluarga SP report FO lama: invoice, kwitansi, nota, billing)
|
||||
4. DROP triggers sebelum migration data:
|
||||
mysql one_lab -e 'DROP TRIGGER IF EXISTS vm_patient_ai; DROP TRIGGER IF EXISTS vm_patient_bu; DROP TRIGGER IF EXISTS m_patient_au; DROP TRIGGER IF EXISTS m_patientaddress_ai; DROP TRIGGER IF EXISTS m_patientaddress_bu;'
|
||||
5. Encrypt m_patient: php scripts/migrate_encrypt_patient.php
|
||||
6. Populate NIK bidx: php scripts/migrate_nik_bidx.php
|
||||
7. Encrypt address: php scripts/migrate_address_enc.php
|
||||
8. Encrypt orderdelivery: php scripts/migrate_encrypt_orderdelivery.php
|
||||
9. Masking plaintext (setelah encrypt selesai):
|
||||
php scripts/mask_patient_plaintext.php
|
||||
php scripts/remask_patient_name.php
|
||||
10. Recreate triggers:
|
||||
mysql one_lab < sql/manual_changes/2026-05-31-pdp-update-triggers-enc.sql
|
||||
11. Truncate log lama: mysql one_lab_log -e 'TRUNCATE TABLE log_patient; TRUNCATE TABLE order_log;'
|
||||
12. Verifikasi: cek sample data, cek disk, cek MySQL
|
||||
|
||||
PERHATIAN DISK:
|
||||
- Setiap kali masking banyak baris, log_patient bisa penuh
|
||||
- Jika disk penuh: sudo systemctl start mariadb (setelah hapus file), truncate log_patient, drop trigger, lanjut
|
||||
- Selalu DROP trigger sebelum masking, recreate sesudahnya
|
||||
- Jangan hapus: backup_pdp_*, one_lab_tables.sql
|
||||
|
||||
VERIFIKASI SETIAP STEP:
|
||||
- Setelah encrypt: SELECT COUNT(*), COUNT(M_PatientName_enc) FROM m_patient;
|
||||
- Setelah masking: SELECT M_PatientName, M_PatientHP FROM m_patient LIMIT 5; (harus tampil "NAMA A***", "0812***")
|
||||
- Cek disk: df -h /
|
||||
- Test search patient: pastikan search by nama (3+ karakter) masih bekerja via API
|
||||
|
||||
JANGAN LAKUKAN:
|
||||
- Jangan hapus backup_pdp_* files
|
||||
- Jangan delete MySQL data files (/var/lib/mysql/ibdata*)
|
||||
- Jangan commit .env ke git
|
||||
- Jangan lanjut kalau disk < 2GB free
|
||||
- Jangan skip backup
|
||||
|
||||
File referensi lengkap: docs/pdp-encryption-runbook.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist Pre-Implementasi
|
||||
|
||||
Sebelum mulai, pastikan:
|
||||
|
||||
- [ ] SSH ke IBL server bisa
|
||||
- [ ] Disk minimal 10GB free
|
||||
- [ ] Passphrase key sudah disiapkan (dari password manager)
|
||||
- [ ] Ada window maintenance (user tidak aktif)
|
||||
- [ ] Backup terverifikasi sebelum lanjut ke step berikutnya
|
||||
- [ ] Tim tahu ada maintenance (beri tahu jika ada downtime)
|
||||
|
||||
## File Penting
|
||||
|
||||
| File | Fungsi |
|
||||
|------|--------|
|
||||
| `docs/pdp-encryption-runbook.md` | Runbook lengkap step by step |
|
||||
| `.env` | Key enkripsi (buat manual di server, JANGAN commit) |
|
||||
| `scripts/backup_pdp_tables.sh` | Script backup sebelum migration |
|
||||
| `sql/manual_changes/2026-05-31-pdp-encrypt-columns.sql` | Tambah kolom _enc + _bidx |
|
||||
| `sql/manual_changes/2026-05-31-pdp-update-triggers-enc.sql` | Update trigger pakai _enc |
|
||||
| `sql/manual_changes/2026-05-31-pdp-birt-sp-cache-join.sql` | patient_print_cache + update 6 SP BIRT |
|
||||
| `sql/manual_changes/2026-06-08-pdp-fo-birt-sp-patient-print-cache.sql` | Update keluarga SP report FO lama agar baca `patient_print_cache` |
|
||||
| `scripts/migrate_encrypt_patient.php` | Encrypt 178K patient rows |
|
||||
| `scripts/migrate_nik_bidx.php` | Populate NIK search index |
|
||||
| `scripts/migrate_address_enc.php` | Encrypt address rows |
|
||||
| `scripts/migrate_encrypt_orderdelivery.php` | Encrypt delivery destination |
|
||||
| `scripts/mask_patient_plaintext.php` | Masking HP/email/POB/NIK/alamat |
|
||||
| `scripts/remask_patient_name.php` | Remask nama format "NAMA A***" |
|
||||
878
docs/superpowers/plans/2026-05-29-ibl-merge-report-service.md
Normal file
878
docs/superpowers/plans/2026-05-29-ibl-merge-report-service.md
Normal file
@@ -0,0 +1,878 @@
|
||||
# ibl_merge_report_service Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Build a standalone Go HTTP service (`ibl_merge_report_service`) that fetches multiple PDF URLs, merges them into one PDF, and streams the result — called internally by the one-api-lab PHP gateway.
|
||||
|
||||
**Architecture:** The service exposes a single `POST /merge` endpoint. It validates the `X-Internal-Secret` request header, parses the JSON body, fetches each PDF URL sequentially, merges them with pdfcpu, then writes the merged PDF as `application/pdf`. If any source fetch fails, the entire request fails with a mapped HTTP status code. No files are cached on disk.
|
||||
|
||||
**Tech Stack:** Go 1.21+, `github.com/pdfcpu/pdfcpu` for in-memory PDF merging, standard library `net/http`.
|
||||
|
||||
---
|
||||
|
||||
## File Map
|
||||
|
||||
| File | Responsibility |
|
||||
|------|---------------|
|
||||
| `services/ibl_merge_report_service/go.mod` | Module definition |
|
||||
| `services/ibl_merge_report_service/main.go` | Entry point — read env config, register route, start HTTP server |
|
||||
| `services/ibl_merge_report_service/handler.go` | `mergeRequest` struct, `mergeHandler`, validation, `writeError` |
|
||||
| `services/ibl_merge_report_service/handler_test.go` | Unit tests for all handler branches using a mock `mergeFunc` |
|
||||
| `services/ibl_merge_report_service/merger.go` | `fetchPDF`, `mergePDFs`, `fetchError` type |
|
||||
| `services/ibl_merge_report_service/merger_test.go` | httptest-based tests for `fetchPDF` error paths |
|
||||
| `scripts/build-merge-service.sh` | Cross-compile for Linux amd64, output binary to `up/` |
|
||||
| `services/ibl_merge_report_service/ibl-merge-report.service` | Systemd unit template for IBL server |
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Scaffold — module init + empty stubs
|
||||
|
||||
**Files:**
|
||||
- Create: `services/ibl_merge_report_service/go.mod`
|
||||
- Create: `services/ibl_merge_report_service/main.go`
|
||||
- Create: `services/ibl_merge_report_service/handler.go`
|
||||
- Create: `services/ibl_merge_report_service/merger.go`
|
||||
|
||||
- [ ] **Step 1.1: Create go.mod**
|
||||
|
||||
```bash
|
||||
mkdir -p /Users/fajrihardhitamurti/REPO_GITEA_IBL/BE_IBL/one-api-lab/services/ibl_merge_report_service
|
||||
```
|
||||
|
||||
`services/ibl_merge_report_service/go.mod`:
|
||||
```
|
||||
module ibl-merge-report-service
|
||||
|
||||
go 1.21
|
||||
```
|
||||
|
||||
- [ ] **Step 1.2: Create handler.go stub**
|
||||
|
||||
`services/ibl_merge_report_service/handler.go`:
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type mergeRequest struct {
|
||||
Name string `json:"name"`
|
||||
URLs []string `json:"urls"`
|
||||
MergeRequestID int64 `json:"mergeRequestID"`
|
||||
TOrderHeaderID int64 `json:"T_OrderHeaderID"`
|
||||
}
|
||||
|
||||
type mergeFunc func(urls []string) ([]byte, error)
|
||||
|
||||
type mergeHandler struct {
|
||||
secret string
|
||||
merge mergeFunc
|
||||
}
|
||||
|
||||
func newMergeHandler(secret string, merge mergeFunc) http.Handler {
|
||||
return &mergeHandler{secret: secret, merge: merge}
|
||||
}
|
||||
|
||||
func (h *mergeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: implement in Task 3
|
||||
writeError(w, http.StatusNotImplemented, "not implemented")
|
||||
}
|
||||
|
||||
func validateMergeRequest(req *mergeRequest) error {
|
||||
// TODO: implement in Task 2
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeError(w http.ResponseWriter, code int, msg string) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(code)
|
||||
_ = json.NewEncoder(w).Encode(map[string]string{"error": msg})
|
||||
}
|
||||
|
||||
// suppress unused-import errors until tasks fill in usage
|
||||
var _ = errors.As
|
||||
var _ = fmt.Errorf
|
||||
```
|
||||
|
||||
- [ ] **Step 1.3: Create merger.go stub**
|
||||
|
||||
`services/ibl_merge_report_service/merger.go`:
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
var httpClient = &http.Client{Timeout: 25 * time.Second}
|
||||
|
||||
type fetchError struct {
|
||||
URL string
|
||||
HTTPStatus int // 0 = network/timeout
|
||||
}
|
||||
|
||||
func (e *fetchError) Error() string {
|
||||
if e.HTTPStatus != 0 {
|
||||
return fmt.Sprintf("source %s returned HTTP %d", e.URL, e.HTTPStatus)
|
||||
}
|
||||
return fmt.Sprintf("failed to fetch source %s", e.URL)
|
||||
}
|
||||
|
||||
func fetchPDF(url string) ([]byte, error) {
|
||||
// TODO: implement in Task 4
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func mergePDFs(urls []string) ([]byte, error) {
|
||||
// TODO: implement in Task 5
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 1.4: Create main.go**
|
||||
|
||||
`services/ibl_merge_report_service/main.go`:
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
secret := os.Getenv("MERGE_INTERNAL_SECRET")
|
||||
if secret == "" {
|
||||
secret = "ibl-merge-secret"
|
||||
}
|
||||
addr := os.Getenv("MERGE_LISTEN_ADDR")
|
||||
if addr == "" {
|
||||
addr = "127.0.0.1:8005"
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/merge", func(w http.ResponseWriter, r *http.Request) {
|
||||
newMergeHandler(secret, mergePDFs).ServeHTTP(w, r)
|
||||
})
|
||||
|
||||
log.Printf("ibl_merge_report_service listening on %s", addr)
|
||||
if err := http.ListenAndServe(addr, mux); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "fatal: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 1.5: Add pdfcpu dependency and verify build**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go get github.com/pdfcpu/pdfcpu@latest && go mod tidy
|
||||
```
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go build ./...
|
||||
```
|
||||
|
||||
Expected: builds without errors (stubs compile).
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Validate request TDD
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/ibl_merge_report_service/handler.go` — implement `validateMergeRequest`
|
||||
- Create: `services/ibl_merge_report_service/handler_test.go`
|
||||
|
||||
- [ ] **Step 2.1: Write failing tests for validateMergeRequest**
|
||||
|
||||
`services/ibl_merge_report_service/handler_test.go`:
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValidateMergeRequest_MissingName(t *testing.T) {
|
||||
req := &mergeRequest{URLs: []string{"http://x"}, MergeRequestID: 1, TOrderHeaderID: 1}
|
||||
if err := validateMergeRequest(req); err == nil {
|
||||
t.Fatal("expected error for missing name")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMergeRequest_EmptyURLs(t *testing.T) {
|
||||
req := &mergeRequest{Name: "a.pdf", URLs: []string{}, MergeRequestID: 1, TOrderHeaderID: 1}
|
||||
if err := validateMergeRequest(req); err == nil {
|
||||
t.Fatal("expected error for empty urls")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMergeRequest_NilURLs(t *testing.T) {
|
||||
req := &mergeRequest{Name: "a.pdf", URLs: nil, MergeRequestID: 1, TOrderHeaderID: 1}
|
||||
if err := validateMergeRequest(req); err == nil {
|
||||
t.Fatal("expected error for nil urls")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMergeRequest_MissingMergeRequestID(t *testing.T) {
|
||||
req := &mergeRequest{Name: "a.pdf", URLs: []string{"http://x"}, MergeRequestID: 0, TOrderHeaderID: 1}
|
||||
if err := validateMergeRequest(req); err == nil {
|
||||
t.Fatal("expected error for missing mergeRequestID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMergeRequest_MissingTOrderHeaderID(t *testing.T) {
|
||||
req := &mergeRequest{Name: "a.pdf", URLs: []string{"http://x"}, MergeRequestID: 1, TOrderHeaderID: 0}
|
||||
if err := validateMergeRequest(req); err == nil {
|
||||
t.Fatal("expected error for missing T_OrderHeaderID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateMergeRequest_Valid(t *testing.T) {
|
||||
req := &mergeRequest{Name: "a.pdf", URLs: []string{"http://x"}, MergeRequestID: 1, TOrderHeaderID: 1}
|
||||
if err := validateMergeRequest(req); err != nil {
|
||||
t.Fatalf("expected no error, got: %v", err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2.2: Run tests — verify they fail**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go test ./... -run TestValidate -v
|
||||
```
|
||||
|
||||
Expected: `TestValidateMergeRequest_Valid` fails (stub returns nil for everything).
|
||||
|
||||
- [ ] **Step 2.3: Implement validateMergeRequest**
|
||||
|
||||
Replace the `validateMergeRequest` stub in `handler.go`:
|
||||
```go
|
||||
func validateMergeRequest(req *mergeRequest) error {
|
||||
if req.Name == "" {
|
||||
return fmt.Errorf("name is required")
|
||||
}
|
||||
if len(req.URLs) == 0 {
|
||||
return fmt.Errorf("urls must not be empty")
|
||||
}
|
||||
if req.MergeRequestID <= 0 {
|
||||
return fmt.Errorf("mergeRequestID is required")
|
||||
}
|
||||
if req.TOrderHeaderID <= 0 {
|
||||
return fmt.Errorf("T_OrderHeaderID is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
Remove the now-unused stub lines at the bottom of handler.go:
|
||||
```go
|
||||
// Remove these two lines:
|
||||
var _ = errors.As
|
||||
var _ = fmt.Errorf
|
||||
```
|
||||
|
||||
- [ ] **Step 2.4: Run tests — verify they pass**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go test ./... -run TestValidate -v
|
||||
```
|
||||
|
||||
Expected: all 6 `TestValidateMergeRequest_*` tests PASS.
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Handler ServeHTTP TDD
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/ibl_merge_report_service/handler.go` — implement `ServeHTTP`
|
||||
- Modify: `services/ibl_merge_report_service/handler_test.go` — add handler tests
|
||||
|
||||
- [ ] **Step 3.1: Write failing handler tests**
|
||||
|
||||
Append to `handler_test.go`:
|
||||
```go
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
)
|
||||
|
||||
func TestHandler_WrongMethod(t *testing.T) {
|
||||
h := newMergeHandler("secret", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "/merge", nil)
|
||||
req.Header.Set("X-Internal-Secret", "secret")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusMethodNotAllowed {
|
||||
t.Fatalf("expected 405, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_WrongSecret(t *testing.T) {
|
||||
h := newMergeHandler("correct", nil)
|
||||
req := httptest.NewRequest(http.MethodPost, "/merge", bytes.NewBufferString("{}"))
|
||||
req.Header.Set("X-Internal-Secret", "wrong")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("expected 401, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_InvalidJSON(t *testing.T) {
|
||||
h := newMergeHandler("s", nil)
|
||||
req := httptest.NewRequest(http.MethodPost, "/merge", bytes.NewBufferString("{bad"))
|
||||
req.Header.Set("X-Internal-Secret", "s")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Fatalf("expected 400, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_ValidationError(t *testing.T) {
|
||||
h := newMergeHandler("s", nil)
|
||||
body, _ := json.Marshal(mergeRequest{Name: "", URLs: []string{"http://x"}, MergeRequestID: 1, TOrderHeaderID: 1})
|
||||
req := httptest.NewRequest(http.MethodPost, "/merge", bytes.NewBuffer(body))
|
||||
req.Header.Set("X-Internal-Secret", "s")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusUnprocessableEntity {
|
||||
t.Fatalf("expected 422, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_FetchError404(t *testing.T) {
|
||||
mockMerge := func(urls []string) ([]byte, error) {
|
||||
return nil, &fetchError{URL: urls[0], HTTPStatus: http.StatusNotFound}
|
||||
}
|
||||
h := newMergeHandler("s", mockMerge)
|
||||
body, _ := json.Marshal(mergeRequest{Name: "x.pdf", URLs: []string{"http://x"}, MergeRequestID: 1, TOrderHeaderID: 1})
|
||||
req := httptest.NewRequest(http.MethodPost, "/merge", bytes.NewBuffer(body))
|
||||
req.Header.Set("X-Internal-Secret", "s")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("expected 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_FetchErrorNetwork(t *testing.T) {
|
||||
mockMerge := func(urls []string) ([]byte, error) {
|
||||
return nil, &fetchError{URL: urls[0], HTTPStatus: 0}
|
||||
}
|
||||
h := newMergeHandler("s", mockMerge)
|
||||
body, _ := json.Marshal(mergeRequest{Name: "x.pdf", URLs: []string{"http://x"}, MergeRequestID: 1, TOrderHeaderID: 1})
|
||||
req := httptest.NewRequest(http.MethodPost, "/merge", bytes.NewBuffer(body))
|
||||
req.Header.Set("X-Internal-Secret", "s")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusBadGateway {
|
||||
t.Fatalf("expected 502, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_MergeError(t *testing.T) {
|
||||
mockMerge := func(urls []string) ([]byte, error) {
|
||||
return nil, fmt.Errorf("pdfcpu: corrupt PDF")
|
||||
}
|
||||
h := newMergeHandler("s", mockMerge)
|
||||
body, _ := json.Marshal(mergeRequest{Name: "x.pdf", URLs: []string{"http://x"}, MergeRequestID: 1, TOrderHeaderID: 1})
|
||||
req := httptest.NewRequest(http.MethodPost, "/merge", bytes.NewBuffer(body))
|
||||
req.Header.Set("X-Internal-Secret", "s")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusInternalServerError {
|
||||
t.Fatalf("expected 500, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_Success(t *testing.T) {
|
||||
fakeBytes := []byte("%PDF-1.4 fake-merged")
|
||||
mockMerge := func(urls []string) ([]byte, error) { return fakeBytes, nil }
|
||||
h := newMergeHandler("s", mockMerge)
|
||||
body, _ := json.Marshal(mergeRequest{
|
||||
Name: "result.pdf", URLs: []string{"http://x"}, MergeRequestID: 1, TOrderHeaderID: 1,
|
||||
})
|
||||
req := httptest.NewRequest(http.MethodPost, "/merge", bytes.NewBuffer(body))
|
||||
req.Header.Set("X-Internal-Secret", "s")
|
||||
w := httptest.NewRecorder()
|
||||
h.ServeHTTP(w, req)
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d", w.Code)
|
||||
}
|
||||
if ct := w.Header().Get("Content-Type"); ct != "application/pdf" {
|
||||
t.Fatalf("expected application/pdf, got %s", ct)
|
||||
}
|
||||
if !bytes.Equal(w.Body.Bytes(), fakeBytes) {
|
||||
t.Fatal("response body does not match expected PDF bytes")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The top of `handler_test.go` must have a single `import` block with all imports. Replace the import at the top of the file with:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 3.2: Run tests — verify they fail**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go test ./... -run TestHandler -v
|
||||
```
|
||||
|
||||
Expected: all 8 `TestHandler_*` tests FAIL (stub returns 501).
|
||||
|
||||
- [ ] **Step 3.3: Implement ServeHTTP**
|
||||
|
||||
Replace the stub `ServeHTTP` in `handler.go` with:
|
||||
|
||||
```go
|
||||
func (h *mergeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
|
||||
if r.Header.Get("X-Internal-Secret") != h.secret {
|
||||
writeError(w, http.StatusUnauthorized, "unauthorized")
|
||||
return
|
||||
}
|
||||
|
||||
var req mergeRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeError(w, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
|
||||
if err := validateMergeRequest(&req); err != nil {
|
||||
writeError(w, http.StatusUnprocessableEntity, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
pdfBytes, err := h.merge(req.URLs)
|
||||
if err != nil {
|
||||
var fe *fetchError
|
||||
if errors.As(err, &fe) {
|
||||
if fe.HTTPStatus == http.StatusNotFound {
|
||||
writeError(w, http.StatusNotFound, "source PDF not found")
|
||||
return
|
||||
}
|
||||
writeError(w, http.StatusBadGateway, "source PDF unavailable")
|
||||
return
|
||||
}
|
||||
writeError(w, http.StatusInternalServerError, "merge failed")
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/pdf")
|
||||
w.Header().Set("Content-Disposition", `inline; filename="`+req.Name+`"`)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(pdfBytes)
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3.4: Run tests — verify all pass**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go test ./... -run TestHandler -v
|
||||
```
|
||||
|
||||
Expected: all 8 `TestHandler_*` tests PASS.
|
||||
|
||||
- [ ] **Step 3.5: Commit**
|
||||
|
||||
```bash
|
||||
cd /Users/fajrihardhitamurti/REPO_GITEA_IBL/BE_IBL/one-api-lab
|
||||
git add services/ibl_merge_report_service/
|
||||
git commit -m "TASKCODE - scaffold ibl_merge_report_service with handler logic and tests"
|
||||
```
|
||||
|
||||
(Replace TASKCODE with the actual task code from user before committing.)
|
||||
|
||||
---
|
||||
|
||||
### Task 4: fetchPDF TDD
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/ibl_merge_report_service/merger.go` — implement `fetchPDF`
|
||||
- Create: `services/ibl_merge_report_service/merger_test.go`
|
||||
|
||||
- [ ] **Step 4.1: Write failing fetchPDF tests**
|
||||
|
||||
`services/ibl_merge_report_service/merger_test.go`:
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFetchPDF_Returns404Error(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
_, err := fetchPDF(srv.URL)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for 404 response")
|
||||
}
|
||||
|
||||
var fe *fetchError
|
||||
if !errors.As(err, &fe) {
|
||||
t.Fatalf("expected *fetchError, got %T: %v", err, err)
|
||||
}
|
||||
if fe.HTTPStatus != http.StatusNotFound {
|
||||
t.Fatalf("expected HTTPStatus 404, got %d", fe.HTTPStatus)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchPDF_Returns500Error(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
_, err := fetchPDF(srv.URL)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for 500 response")
|
||||
}
|
||||
|
||||
var fe *fetchError
|
||||
if !errors.As(err, &fe) {
|
||||
t.Fatalf("expected *fetchError, got %T", err)
|
||||
}
|
||||
if fe.HTTPStatus != http.StatusInternalServerError {
|
||||
t.Fatalf("expected HTTPStatus 500, got %d", fe.HTTPStatus)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchPDF_ReturnsBytes(t *testing.T) {
|
||||
expected := []byte("%PDF-1.4 test content")
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/pdf")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(expected)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
got, err := fetchPDF(srv.URL)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if string(got) != string(expected) {
|
||||
t.Fatalf("expected %q, got %q", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchPDF_NetworkError(t *testing.T) {
|
||||
// Port that's almost certainly not listening
|
||||
_, err := fetchPDF("http://127.0.0.1:19999/notexist")
|
||||
if err == nil {
|
||||
t.Fatal("expected error for unreachable host")
|
||||
}
|
||||
var fe *fetchError
|
||||
if !errors.As(err, &fe) {
|
||||
t.Fatalf("expected *fetchError, got %T: %v", err, err)
|
||||
}
|
||||
if fe.HTTPStatus != 0 {
|
||||
t.Fatalf("expected HTTPStatus 0 for network error, got %d", fe.HTTPStatus)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4.2: Run tests — verify they fail**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go test ./... -run TestFetchPDF -v
|
||||
```
|
||||
|
||||
Expected: all 4 `TestFetchPDF_*` tests FAIL (stub returns generic error).
|
||||
|
||||
- [ ] **Step 4.3: Implement fetchPDF**
|
||||
|
||||
Replace the `fetchPDF` stub in `merger.go`:
|
||||
|
||||
```go
|
||||
func fetchPDF(url string) ([]byte, error) {
|
||||
resp, err := httpClient.Get(url)
|
||||
if err != nil {
|
||||
return nil, &fetchError{URL: url, HTTPStatus: 0}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, &fetchError{URL: url, HTTPStatus: resp.StatusCode}
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, &fetchError{URL: url, HTTPStatus: 0}
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
```
|
||||
|
||||
Add `"io"` to the import block in `merger.go`.
|
||||
|
||||
- [ ] **Step 4.4: Run tests — verify all pass**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go test ./... -run TestFetchPDF -v
|
||||
```
|
||||
|
||||
Expected: all 4 `TestFetchPDF_*` tests PASS.
|
||||
|
||||
---
|
||||
|
||||
### Task 5: mergePDFs implementation
|
||||
|
||||
**Files:**
|
||||
- Modify: `services/ibl_merge_report_service/merger.go` — implement `mergePDFs`
|
||||
|
||||
No unit test is written for `mergePDFs` because testing requires valid PDF binaries which are awkward to embed. Error propagation from `fetchPDF` is already covered by `TestFetchPDF_*`. End-to-end correctness is verified manually in Task 8.
|
||||
|
||||
- [ ] **Step 5.1: Implement mergePDFs**
|
||||
|
||||
Replace the `mergePDFs` stub in `merger.go`:
|
||||
|
||||
```go
|
||||
func mergePDFs(urls []string) ([]byte, error) {
|
||||
readers := make([]io.ReadSeeker, 0, len(urls))
|
||||
for _, url := range urls {
|
||||
data, err := fetchPDF(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
readers = append(readers, bytes.NewReader(data))
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := api.MergeRaw(readers, &buf, nil); err != nil {
|
||||
return nil, fmt.Errorf("PDF merge error: %w", err)
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
```
|
||||
|
||||
Add `"bytes"` and `"github.com/pdfcpu/pdfcpu/pkg/api"` to the import block in `merger.go`.
|
||||
|
||||
Remove the now-unused `"time"` import only if `httpClient` is still using it — keep `time` because `httpClient` uses `25 * time.Second`.
|
||||
|
||||
The full import block for `merger.go` after this step:
|
||||
```go
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/pdfcpu/pdfcpu/pkg/api"
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 5.2: Run all tests**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go test ./... -v
|
||||
```
|
||||
|
||||
Expected: all previously passing tests still pass. No new tests in this task.
|
||||
|
||||
- [ ] **Step 5.3: Build to verify no compile errors**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go build ./...
|
||||
```
|
||||
|
||||
Expected: compiles cleanly.
|
||||
|
||||
- [ ] **Step 5.4: Commit**
|
||||
|
||||
```bash
|
||||
cd /Users/fajrihardhitamurti/REPO_GITEA_IBL/BE_IBL/one-api-lab
|
||||
git add services/ibl_merge_report_service/
|
||||
git commit -m "TASKCODE - implement fetchPDF and mergePDFs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Deployment files
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/build-merge-service.sh`
|
||||
- Create: `services/ibl_merge_report_service/ibl-merge-report.service`
|
||||
|
||||
- [ ] **Step 6.1: Create build script**
|
||||
|
||||
`scripts/build-merge-service.sh`:
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
SRC_DIR="$REPO_ROOT/services/ibl_merge_report_service"
|
||||
OUT_DIR="$REPO_ROOT/up"
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
echo "Building ibl_merge_report_service for linux/amd64..."
|
||||
cd "$SRC_DIR"
|
||||
GOOS=linux GOARCH=amd64 go build -o "$OUT_DIR/ibl-merge-report-service" .
|
||||
echo "Binary written to: $OUT_DIR/ibl-merge-report-service"
|
||||
```
|
||||
|
||||
Make executable:
|
||||
```bash
|
||||
chmod +x scripts/build-merge-service.sh
|
||||
```
|
||||
|
||||
- [ ] **Step 6.2: Create systemd unit template**
|
||||
|
||||
`services/ibl_merge_report_service/ibl-merge-report.service`:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=IBL Merge Report Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=one
|
||||
WorkingDirectory=/home/one/project/ibl_merge_report_service
|
||||
ExecStart=/home/one/project/ibl_merge_report_service/ibl-merge-report-service
|
||||
Environment=MERGE_LISTEN_ADDR=127.0.0.1:8005
|
||||
Environment=MERGE_INTERNAL_SECRET=REPLACE_WITH_VALUE_FROM_DB
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
`MERGE_INTERNAL_SECRET` must match the value of `S_SystemsMergeReportServiceSecret` in `conf_systems`.
|
||||
|
||||
Deployment steps on IBL server:
|
||||
1. Build: `bash scripts/build-merge-service.sh`
|
||||
2. Copy binary: `scp -i /Users/fajrihardhitamurti/id_rsa up/ibl-merge-report-service one@10.9.20.31:/home/one/project/ibl_merge_report_service/`
|
||||
3. Copy unit file: `scp -i /Users/fajrihardhitamurti/id_rsa services/ibl_merge_report_service/ibl-merge-report.service one@10.9.20.31:/tmp/`
|
||||
4. On server: `sudo mv /tmp/ibl-merge-report.service /etc/systemd/system/`
|
||||
5. On server: edit `/etc/systemd/system/ibl-merge-report.service` to set the real `MERGE_INTERNAL_SECRET`
|
||||
6. On server: `sudo systemctl daemon-reload && sudo systemctl enable ibl-merge-report && sudo systemctl start ibl-merge-report`
|
||||
7. Verify: `sudo systemctl status ibl-merge-report`
|
||||
|
||||
- [ ] **Step 6.3: Run build script to verify it compiles for Linux**
|
||||
|
||||
```bash
|
||||
cd /Users/fajrihardhitamurti/REPO_GITEA_IBL/BE_IBL/one-api-lab && bash scripts/build-merge-service.sh
|
||||
```
|
||||
|
||||
Expected: `up/ibl-merge-report-service` is created (Linux ELF binary).
|
||||
|
||||
- [ ] **Step 6.4: Commit**
|
||||
|
||||
```bash
|
||||
cd /Users/fajrihardhitamurti/REPO_GITEA_IBL/BE_IBL/one-api-lab
|
||||
git add scripts/build-merge-service.sh services/ibl_merge_report_service/ibl-merge-report.service up/ibl-merge-report-service
|
||||
git commit -m "TASKCODE - add build script and systemd unit for merge report service"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: Run all tests and final verification
|
||||
|
||||
- [ ] **Step 7.1: Run full test suite**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go test ./... -v
|
||||
```
|
||||
|
||||
Expected: all tests pass. Final count: 6 `TestValidate*` + 8 `TestHandler*` + 4 `TestFetchPDF*` = 18 tests.
|
||||
|
||||
- [ ] **Step 7.2: Run go vet**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go vet ./...
|
||||
```
|
||||
|
||||
Expected: no output (no issues).
|
||||
|
||||
- [ ] **Step 7.3: Smoke test locally (macOS)**
|
||||
|
||||
```bash
|
||||
cd services/ibl_merge_report_service && go run . &
|
||||
sleep 1
|
||||
curl -s -o /dev/null -w "%{http_code}" -X POST http://127.0.0.1:8005/merge \
|
||||
-H "X-Internal-Secret: ibl-merge-secret" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"test.pdf","urls":["http://127.0.0.1:9999/nope"],"mergeRequestID":1,"T_OrderHeaderID":1}'
|
||||
```
|
||||
|
||||
Expected: HTTP `502` (source unavailable — correct error code for unreachable source).
|
||||
|
||||
Kill background process: `kill %1`
|
||||
|
||||
- [ ] **Step 7.4: Verify secret validation**
|
||||
|
||||
```bash
|
||||
curl -s -o /dev/null -w "%{http_code}" -X POST http://127.0.0.1:8005/merge \
|
||||
-H "X-Internal-Secret: wrong-secret" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}'
|
||||
```
|
||||
|
||||
Expected: `401`.
|
||||
|
||||
---
|
||||
|
||||
## Error Code Reference
|
||||
|
||||
| Go returns | PHP maps to | Meaning |
|
||||
|------------|------------|---------|
|
||||
| `401` | `MERGE_SERVICE_UNAUTHORIZED` | Bad secret |
|
||||
| `404` | `MERGE_SOURCE_NOT_FOUND` | Source PDF returned 404 |
|
||||
| `422` | `MERGE_SERVICE_REJECTED` | Validation error |
|
||||
| `500` | `MERGE_SERVICE_FAILED` | pdfcpu merge error |
|
||||
| `502` | `MERGE_SERVICE_FAILED` | Source fetch network/non-404 error |
|
||||
|
||||
---
|
||||
|
||||
## Self-Review: Spec Coverage
|
||||
|
||||
- [x] Service listens on `127.0.0.1:8005` (configurable via `MERGE_LISTEN_ADDR`)
|
||||
- [x] `POST /merge` endpoint
|
||||
- [x] Validates `X-Internal-Secret` header → 401
|
||||
- [x] Validates JSON body fields (name, urls, mergeRequestID, T_OrderHeaderID) → 422
|
||||
- [x] Fetches each URL sequentially — if any fails, entire request fails
|
||||
- [x] Merges with pdfcpu, streams as `application/pdf`
|
||||
- [x] No cache / no file artifacts (in-memory only)
|
||||
- [x] Error responses use HTTP status codes that map correctly to PHP gateway error codes
|
||||
- [x] Build script for Linux amd64
|
||||
- [x] Systemd unit for IBL server deployment
|
||||
1117
docs/superpowers/plans/2026-05-31-pdp-patient-encryption.md
Normal file
1117
docs/superpowers/plans/2026-05-31-pdp-patient-encryption.md
Normal file
File diff suppressed because it is too large
Load Diff
1
graphify-out/cache/0a24bd39376636424b0bb46e8a4c77732d2ba908c4ad5570fec920bf60b6d4ed.json
vendored
Normal file
1
graphify-out/cache/0a24bd39376636424b0bb46e8a4c77732d2ba908c4ad5570fec920bf60b6d4ed.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
graphify-out/cache/0ea8b06157c432af803d5f4c884a29664385f9a1a1643f41be789b59d8803076.json
vendored
Normal file
1
graphify-out/cache/0ea8b06157c432af803d5f4c884a29664385f9a1a1643f41be789b59d8803076.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
graphify-out/cache/110e9857484f76fa18a5e532f09ab09629bee2dc40b0f5063fd11bcea3a56827.json
vendored
Normal file
1
graphify-out/cache/110e9857484f76fa18a5e532f09ab09629bee2dc40b0f5063fd11bcea3a56827.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
graphify-out/cache/11b9bab91246cc1484e706850659311b828918d70a78cd516763ad871aa49f73.json
vendored
Normal file
1
graphify-out/cache/11b9bab91246cc1484e706850659311b828918d70a78cd516763ad871aa49f73.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
graphify-out/cache/124530e229508b0312663a40929dc73230c197b09ca38bc11d43a6a9b1d77434.json
vendored
Normal file
1
graphify-out/cache/124530e229508b0312663a40929dc73230c197b09ca38bc11d43a6a9b1d77434.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"nodes": [{"id": "users_fajrihardhitamurti_repo_gitea_ibl_be_ibl_one_api_lab_application_third_party_fpdf_font_helveticab_php", "label": "helveticab.php", "file_type": "code", "source_file": "/Users/fajrihardhitamurti/REPO_GITEA_IBL/BE_IBL/one-api-lab/application/third_party/fpdf/font/helveticab.php", "source_location": "L1"}], "edges": [], "raw_calls": []}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user