From c31d3ab1498ec443c9aa859fafcff2d1937a5599 Mon Sep 17 00:00:00 2001 From: mikael-zakaria Date: Thu, 23 Oct 2025 09:41:49 +0700 Subject: [PATCH] Update Routes/Model/Controller/Migrations Zones & Show Patient(getPatient) --- app/Config/Routes.php | 7 +- app/Controllers/Zones.php | 121 ++++++------------ .../2025-10-22-100001_Zones_CRM.php | 25 ++++ app/Models/Patient/PatientModel.php | 6 +- app/Models/SyncCRM/ZonesModel.php | 116 +++++++++++++++-- 5 files changed, 175 insertions(+), 100 deletions(-) create mode 100644 app/Database/Migrations/2025-10-22-100001_Zones_CRM.php diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 7cd7baa..a9e8df8 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -92,7 +92,8 @@ $routes->post('/api/containerdef', 'Specimen\ContainerDef::create'); $routes->patch('/api/containerdef', 'Specimen\ContainerDef::update'); $routes->delete('/api/containerdef', 'Specimen\ContainerDef::delete'); +// Khusus $routes->get('/api/zones', 'Zones::index'); -$routes->get('/api/zones/syncronize', 'Zones::syncronize'); -// $routes->get('/api/provinces', 'Api\ZonesApi::getProvinces'); -// $routes->get('/api/cities', 'Api\ZonesApi::getCities'); \ No newline at end of file +$routes->get('/api/zones/synchronize', 'Zones::synchronize'); +$routes->get('/api/zones/provinces', 'Zones::getProvinces'); +$routes->get('/api/zones/cities', 'Zones::getCities'); \ No newline at end of file diff --git a/app/Controllers/Zones.php b/app/Controllers/Zones.php index a40f49f..298684f 100644 --- a/app/Controllers/Zones.php +++ b/app/Controllers/Zones.php @@ -3,57 +3,59 @@ namespace App\Controllers; use CodeIgniter\API\ResponseTrait; use App\Controllers\BaseController; -// use App\Models\PatVisit\PatVisitModel; +use App\Models\SyncCRM\ZonesModel; class Zones extends BaseController { use ResponseTrait; - // protected $model; + protected $model; public function __construct() { - // $this->model = new PatVisitModel(); + $this->model = new ZonesModel(); } - // public function __construct() { - // $this->db = \Config\Database::connect(); - // $this->model = new PatientModel(); - // $this->rules = [ - // 'PatientID' => 'required|max_length[50]', - // 'AlternatePID' => 'permit_empty|max_length[50]' - // ]; - // } - public function index() { - - // Buat instance HTTP client - $client = \Config\Services::curlrequest(); - try { - // $response = $client->get('https://services-summit.my.id/api/provinces'); - $response = $client->get('http://crmcomposer.local/api/zones'); + $rows = $this->model->getZones(); - // Ambil body responsenya - $body = $response->getBody(); - - // Decode JSON ke array PHP - $data = json_decode($body, true); - - return $this->respond(['status'=>'success', 'message'=>"data fetched successfully", 'data'=>$data['data']], 200); + if(empty($rows)){return $this->respond(['status'=>'success', 'message'=>"no data found.", 'data'=>$rows], 200);} + return $this->respond(['status'=>'success', 'message'=>"data fetched successfully", 'data'=>$rows], 200); } catch (\Exception $e) { - return $this->respond([ 'status' => 'error', 'message' => $e->getMessage() ], 200); } } - public function synchronize() - { + public function getProvinces() { + $filters = [ + 'zoneid' => $this->request->getVar('zoneid') ?? null, + 'zonename' => $this->request->getVar('zonename') ?? null + ]; + + $rows = $this->model->getProvinces(); + + if (empty($rows)) { return $this->respond([ 'status' => 'success', 'message' => "data not found", 'data' => [] ], 200); } + return $this->respond([ 'status' => 'success', 'message'=> "Data fetched successfully", 'data' => $rows ], 200); + } + + public function getCities() { + $filter = [ + 'zoneid' => $this->request->getVar('zoneid') ?? null + ]; + + $rows = $this->model->getCities($filter); + + if (empty($rows)) { return $this->respond([ 'status' => 'success', 'message' => "data not found", 'data' => [] ], 200); } + return $this->respond([ 'status' => 'success', 'message'=> "Data fetched successfully", 'data' => $rows ], 200); + } + + public function synchronize() { $client = \Config\Services::curlrequest(); - $zonesModel = new ZonesModel(); try { - // 1️⃣ Ambil data dari API pusat (CRM) + // Ambil data dari API pusat (CRM) $response = $client->get('https://services-summit.my.id/api/zones'); + // $response = $client->get('http://crmcomposer.local/api/zones'); $result = json_decode($response->getBody(), true); if (!isset($result['data']) || !is_array($result['data'])) { @@ -63,65 +65,16 @@ class Zones extends BaseController { ]); } - $crmData = $result['data']; - - // 2️⃣ Ambil semua data zoneid di database lokal - $localData = $zonesModel->findAll(); - $localIds = array_column($localData, 'zoneid'); - - // 3️⃣ Siapkan ID dari data CRM - $crmIds = array_column($crmData, 'zoneid'); - - // Hitung statistik - $inserted = 0; - $updated = 0; - $deleted = 0; - - // 4️⃣ Mulai transaksi agar aman - $db = \Config\Database::connect(); - $db->transStart(); - - // 5️⃣ Insert atau Update data - foreach ($crmData as $zone) { - if (!isset($zone['zoneid'])) continue; - - $exists = $zonesModel->find($zone['zoneid']); - - if ($exists) { - // Update jika sudah ada - $zonesModel->update($zone['zoneid'], [ - 'parentzoneid' => $zone['parentzoneid'], - 'zonecode' => $zone['zonecode'], - 'zoneclass' => $zone['zoneclass'], - 'zonename' => $zone['zonename'] - ]); - $updated++; - } else { - // Insert jika belum ada - $zonesModel->insert($zone); - $inserted++; - } - } - - // 6️⃣ Hapus data yang sudah tidak ada di CRM - foreach ($localIds as $localId) { - if (!in_array($localId, $crmIds)) { - $zonesModel->delete($localId); - $deleted++; - } - } - - // 7️⃣ Commit transaksi - $db->transComplete(); + $record = $this->model->synchronize($result['data']); return $this->response->setJSON([ 'status' => 'success', 'message' => 'Zones synchronized successfully', 'summary' => [ - 'inserted' => $inserted, - 'updated' => $updated, - 'deleted' => $deleted, - 'total' => count($crmData) + 'inserted' => $record['inserted'], + 'updated' => $record['updated'], + 'deleted' => $record['deleted'], + // 'total' => count($crmData) ] ]); } catch (\Exception $e) { diff --git a/app/Database/Migrations/2025-10-22-100001_Zones_CRM.php b/app/Database/Migrations/2025-10-22-100001_Zones_CRM.php new file mode 100644 index 0000000..051d1f3 --- /dev/null +++ b/app/Database/Migrations/2025-10-22-100001_Zones_CRM.php @@ -0,0 +1,25 @@ +forge->addField([ + 'zoneid' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true], + 'parentzoneid' => ['type' => 'INT', 'constraint' => 11, 'unsigned' => true, 'null' => true], + 'zonecode' => ['type' => 'VARCHAR', 'constraint' => 10, 'null' => false], + 'zoneclass' => ['type' => 'VARCHAR', 'constraint' => 5, 'null' => false], + 'zonename' => ['type' => 'VARCHAR', 'constraint' => 100, 'null' => false], + ]); + + $this->forge->addKey('zoneid', true); + $this->forge->createTable('zones'); + } + + public function down() { + $this->forge->dropTable('zones'); + } +} \ No newline at end of file diff --git a/app/Models/Patient/PatientModel.php b/app/Models/Patient/PatientModel.php index 98740bb..acb37ca 100644 --- a/app/Models/Patient/PatientModel.php +++ b/app/Models/Patient/PatientModel.php @@ -66,7 +66,9 @@ class PatientModel extends BaseModel { patcom.Comment as Comment, patidt.IdentifierType, patidt.Identifier, - patatt.Address + patatt.Address, + zones1.zonename as Province, + zones2.zonename as City ") ->join('valueset country', 'country.VID = patient.Country', 'left') ->join('valueset race', 'race.VID = patient.Race', 'left') @@ -78,6 +80,8 @@ class PatientModel extends BaseModel { ->join('patcom', 'patcom.InternalPID = patient.InternalPID', 'left') ->join('patidt', 'patidt.InternalPID = patient.InternalPID', 'left') ->join('patatt', 'patatt.InternalPID = patient.InternalPID and patatt.DelDate is null', 'left') + ->join('zones zones1', 'zones1.zoneid = patient.Province', 'left') + ->join('zones zones2', 'zones2.zoneid = patient.City', 'left') ->where('patient.InternalPID', (int) $InternalPID) ->findAll(); diff --git a/app/Models/SyncCRM/ZonesModel.php b/app/Models/SyncCRM/ZonesModel.php index 3efe4f0..f8c6d71 100644 --- a/app/Models/SyncCRM/ZonesModel.php +++ b/app/Models/SyncCRM/ZonesModel.php @@ -4,19 +4,111 @@ namespace App\Models\SyncCRM; use App\Models\BaseModel; class ZonesModel extends BaseModel { - protected $table = 'zones'; - protected $primaryKey = 'zoneid'; - protected $allowedFields = ['parentzoneid', 'zonecode', 'zoneclass', 'zonename']; + protected $table = 'zones'; + protected $primaryKey = 'zoneid'; + protected $allowedFields = ['parentzoneid', 'zonecode', 'zoneclass', 'zonename']; - // Check Error and Send Spesific Messages - private function checkDbError($db, string $context) { - $error = $db->error(); - if (!empty($error['code'])) { - throw new \Exception( - "{$context} failed: {$error['code']} - {$error['message']}" - ); - } - } + public function getZones() { + return $this->findAll(); + } + public function getProvinces() { + $this->select('zoneid, zonename')->where('parentzoneid IS NULL', null, false); + + if (!empty($filters['zoneid'])) { + $this->where('zoneid', $filters['zoneid']); + } + if (!empty($filters['zonename'])) { + $this->like('zonename', $filters['zonename'], 'both'); + } + + return $this->findAll(); + } + + public function getCities($filter = []) { + $rows = $this->select('zoneid, zonename')->where('parentzoneid IS NOT NULL', null, false); + + if (!empty($filter['zoneid'])) { + $this->where('parentzoneid', $filter['zoneid']); + } + + return $this->findAll(); + } + + // synchronize with crm.zones + public function synchronize($crmData) { + + $db = \Config\Database::connect(); + $db->transBegin(); + + try { + // Ambil semua data zoneid di database lokal + $localData = $this->findAll(); + $localIds = array_column($localData, 'zoneid'); + + // Siapkan ID dari data CRM + $crmIds = array_column($crmData, 'zoneid'); + + // Hitung statistik + $record = [ + 'inserted' => 0, + 'updated' => 0, + 'deleted' => 0, + ]; + + // Insert atau Update data + foreach ($crmData as $zone) { + if (!isset($zone['zoneid'])) continue; + + $exists = $this->find($zone['zoneid']); + + if ($exists) { + // Update jika sudah ada + $this->update($zone['zoneid'], [ + 'parentzoneid' => $zone['parentzoneid'], + 'zonecode' => $zone['zonecode'], + 'zoneclass' => $zone['zoneclass'], + 'zonename' => $zone['zonename'] + ]); + $this->checkDbError($db, 'Update Zones'); + $record['updated']++; + } else { + // Insert jika belum ada + $this->insert($zone); + $this->checkDbError($db, 'Insert Zones'); + $record['inserted']++; + } + } + + // Hapus data yang sudah tidak ada di CRM + foreach ($localIds as $localId) { + if (!in_array($localId, $crmIds)) { + $this->delete($localId); + $this->checkDbError($db, 'Delete Zones'); + $record['deleted']++;; + } + } + + $db->transCommit(); + + } catch (\Exception $e) { + $db->transRollback(); + throw $e; + } + + $db->transComplete(); + + return $record; + } + + // Check Error and Send Spesific Messages + private function checkDbError($db, string $context) { + $error = $db->error(); + if (!empty($error['code'])) { + throw new \Exception( + "{$context} failed: {$error['code']} - {$error['message']}" + ); + } + } } \ No newline at end of file