Update Routes/Model/Controller/Migrations Zones & Show Patient(getPatient)

This commit is contained in:
mikael-zakaria 2025-10-23 09:41:49 +07:00
parent aace3a3f2b
commit c31d3ab149
5 changed files with 175 additions and 100 deletions

View File

@ -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');
$routes->get('/api/zones/synchronize', 'Zones::synchronize');
$routes->get('/api/zones/provinces', 'Zones::getProvinces');
$routes->get('/api/zones/cities', 'Zones::getCities');

View File

@ -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) {

View File

@ -0,0 +1,25 @@
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateZonessTable extends Migration {
public function up() {
$this->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');
}
}

View File

@ -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();

View File

@ -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']}"
);
}
}
}