diff --git a/app/Controllers/Contact.php b/app/Controllers/Contact.php index 3ce9c9c..be634cd 100644 --- a/app/Controllers/Contact.php +++ b/app/Controllers/Contact.php @@ -3,24 +3,23 @@ namespace App\Controllers; use CodeIgniter\API\ResponseTrait; use CodeIgniter\Controller; -use CodeIgniter\Database\RawSql; + +use App\Models\ContactModel; class Contact extends Controller { use ResponseTrait; + protected $contactModel; + protected $contactRule; + public function __construct() { - $this->db = \Config\Database::connect(); - $this->rulesContact = [ - 'NameFirst' => 'required' - ]; + $this->contactModel = new ContactModel(); + $this->contactRule = [ 'NameFirst' => 'required' ]; } public function index() { - $sql = $this->db->table('contact c') - ->select("c.ContactID, cd.ContactCode, c.NameFirst, c.NameLast, c.Specialty") - ->join("contactdetail cd", "c.ContactID=cd.ContactID", "left") - ->join("occupation o","cd.OccupationID=o.OccupationID", "left"); - $rows = $sql->get()->getResultArray(); + $model = new ContactModel(); + $rows = $model->getContactsWithDetail(); if (empty($rows)) { return $this->respond([ @@ -38,13 +37,9 @@ class Contact extends Controller { } public function show($ContactID = null) { - $rows=$this->db->table('contact c') - ->select("*") - ->join("contactdetail cd", "c.ContactID=cd.ContactID", "left") - ->join("occupation o","o.OccupationID=cd.OccupationID", "left") - ->where('c.ContactID', (int) $ContactID) - ->get()->getResultArray(); - + $model = new ContactModel(); + $rows = $model->getContactWithDetail($ContactID); + if (empty($rows)) { return $this->respond([ 'status' => 'success', @@ -53,140 +48,63 @@ class Contact extends Controller { ], 200); } - // Rebuild into nested structure - $contact = [ - 'ContactID' => $rows[0]['ContactID'], - 'NameFirst' => $rows[0]['NameFirst'] ?? null, - 'NameLast' => $rows[0]['NameLast'] ?? null, - 'Title' => $rows[0]['Title'] ?? null, - 'Initial' => $rows[0]['Initial'] ?? null, - 'Birthdate' => $rows[0]['Birthdate'] ?? null, - 'EmailAddress1' => $rows[0]['EmailAddress1'] ?? null, - 'EmailAddress2' => $rows[0]['EmailAddress2'] ?? null, - 'Phone' => $rows[0]['Phone'] ?? null, - 'MobilePhone1' => $rows[0]['MobilePhone1'] ?? null, - 'MobilePhone2' => $rows[0]['MobilePhone2'] ?? null, - 'Specialty' => $rows[0]['Specialty'] ?? null, - 'SubSpecialty' => $rows[0]['SubSpecialty'] ?? null, - 'Details' => [] - ]; - - foreach ($rows as $row) { - if (!empty($row['ContactDetID'])) { - $contact['Details'][] = [ - 'ContactDetID' => $row['ContactDetID'], - 'ContactCode' => $row['ContactCode'] ?? null, - 'ContactEmail' => $row['DetailPhone'] ?? null, - 'OccupationID' => $row['OccupationID'] ?? null, - 'JobTitle' => $row['JobTitle'] ?? null, - 'Department' => $row['Department'] ?? null, - 'ContactStartDate' => $row['ContactStartDate'] ?? null, - 'ContactEndDate' => $row['ContactEndDate'] ?? null - ]; - } - } - return $this->respond([ - 'status' => 'success', + 'status' => 'success', 'message'=> "Data fetched successfully", - 'data' => $contact, + 'data' => $rows, ], 200); } public function create() { - try { - $input = $this->request->getJSON(true); + $input = $this->request->getJSON(true); + $dataContact = $this->prepareContactData($input); + $dataContactDetail = $this->prepareContactDetailData($input); - // Prepare data - $dataContact = $this->prepareContactData($input); - $dataContactDetail = $this->prepareContactDetailData($input); + if (!$this->validateData($dataContact, $this->contactRule)) { + return $this->failValidationErrors($this->validator->getErrors()); + } - if (!$this->validateData($dataContact, $this->rulesContact)) { - return $this->failValidationErrors($this->validator->getErrors()); + try{ + $result = $this->contactModel->create($dataContact, $dataContactDetail); + if ($result) { + return $this->respondCreated([ + 'status' => 'success', + 'message' => 'Contact created successfully', + 'data' => $dataContact, + ]); + } else { + return $this->failServerError('Failed to create contact'); } - - // Start transaction - $this->db->transStart(); - $this->db->table('contact')->insert($dataContact); - $newContactID = $this->db->insertID(); - - - if (!empty($dataContactDetail)) { - $dataContactDetail['ContactID'] = $newContactID; - $this->db->table('contactdetail')->insert($dataContactDetail); - } - - if ($this->db->transStatus() === false) { - $dbError = $this->db->error(); - return $this->failServerError( - 'Failed to create data (transaction rolled back): ' . ( $dbError['message'] ?? 'Unknown database error') - ); - } - - // Complete transaction - $this->db->transComplete(); - - return $this->respondCreated([ - 'status' => 'success', - 'message' => 'Contact created successfully', - 'data' => $dataContact, - ], 201); - } catch (\Throwable $e) { - // Ensure rollback if something goes wrong - if ($this->db->transStatus() !== false) { - $this->db->transRollback(); - } - return $this->failServerError('Something went wrong: ' . $e->getMessage()); + return $this->failServerError('Error: ' . $e->getMessage()); } } - public function update() { - try { - $input = $this->request->getJSON(true); + public function update() { + $input = $this->request->getJSON(true); + $ContactID = $input['ContactID']; + $dataContact = $this->prepareContactData($input); + $dataContactDetail = $this->prepareContactDetailData($input); - // Prepare data - $dataContact = $this->prepareContactData($input); - $dataContactDetail = $this->prepareContactDetailData($input); - - if (!$this->validateData($dataContact, $this->rulesContact)) { - return $this->failValidationErrors( $this->validator->getErrors()); - } - - // Start transaction - $this->db->transStart(); - - $this->db->table('contact')->where('ContactID', $dataContact["ContactID"])->update($dataContact); - - // Insert address if available - if (!empty($dataContactDetail)) { - $dataContactDetail['ContactID'] = $input["ContactID"]; - $this->db->table('contactdetail')->upsert($dataContactDetail); - } - - // Complete transaction - $this->db->transComplete(); - - if ($this->db->transStatus() === false) { - $dbError = $this->db->error(); - return $this->failServerError( - 'Failed to update contact data (transaction rolled back): ' . ($dbError['message'] ?? 'Unknown database error') - ); - } - - return $this->respondCreated([ - 'status' => 'success', - 'message' => 'Contact updated successfully', - 'data' => $dataContact, - ], 201); - - } catch (\Throwable $e) { - // Ensure rollback if something goes wrong - if ($this->db->transStatus() !== false) { - $this->db->transRollback(); - } - return $this->failServerError('Something went wrong: ' . $e->getMessage()); + if (!$this->validateData($dataContact, $this->contactRule)) { + return $this->failValidationErrors( $this->validator->getErrors()); } + + try{ + $result = $this->contactModel->update($ContactID, $dataContact, $dataContactDetail); + if ($result) { + return $this->respondCreated([ + 'status' => 'success', + 'message' => 'Contact created successfully', + 'data' => $dataContact, + ]); + } else { + return $this->failServerError('Failed to create contact'); + } + } catch (\Throwable $e) { + return $this->failServerError('Error: ' . $e->getMessage()); + } + } public function delete() { @@ -240,16 +158,17 @@ class Contact extends Controller { } private function prepareContactDetailData(array $input): array { - $data = [ - "ContactCode" => $input['ContactCode'] ?? null, - "ContactEmail" => $input['ContactEmail'] ?? null, - "OccupationID" => $input['OccupationID'] ?? null, - "JobTitle" => $input['JobTitle'] ?? null, - "Department" => $input['Department'] ?? null, - "ContactStartDate" => $input['ContactStartDate'] ?? null, - "ContactEndDate" => $input['ContactEndDate'] ?? null, - ]; - + foreach($input['ContactDetail'] as $detail) { + $data[] = [ + "ContactCode" => $detail['ContactCode'] ?? null, + "ContactEmail" => $detail['ContactEmail'] ?? null, + "OccupationID" => $detail['OccupationID'] ?? null, + "JobTitle" => $detail['JobTitle'] ?? null, + "Department" => $detail['Department'] ?? null, + "ContactStartDate" => $detail['ContactStartDate'] ?? null, + "ContactEndDate" => $detail['ContactEndDate'] ?? null, + ]; + } return $data; } } \ No newline at end of file diff --git a/app/Database/Migrations/2025-09-09-155526_Pat_Visit.php b/app/Database/Migrations/2025-09-09-155526_Pat_Visit.php index 2794ce5..51df1d9 100644 --- a/app/Database/Migrations/2025-09-09-155526_Pat_Visit.php +++ b/app/Database/Migrations/2025-09-09-155526_Pat_Visit.php @@ -19,7 +19,7 @@ class CreatePVTables extends Migration { ]); $this->forge->addField('CreateDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP'); $this->forge->addKey('InternalPVID', true); - $this->forge->addUniqueKey('PVID', true); + $this->forge->addUniqueKey('PVID'); $this->forge->createTable('patvisit'); // patdiag diff --git a/app/Database/Migrations/2025-09-12-011643_Contact.php b/app/Database/Migrations/2025-09-12-011643_Contact.php index 7799dde..89746ff 100644 --- a/app/Database/Migrations/2025-09-12-011643_Contact.php +++ b/app/Database/Migrations/2025-09-12-011643_Contact.php @@ -41,6 +41,7 @@ class CreateContactTable extends Migration { 'ContactEndDate' => [ 'type' => 'DATE', 'null' => true ], ]); $this->forge->addKey('ContactDetID', true); + $this->forge->addUniqueKey(['SiteID','ContactID']); $this->forge->createTable('contactdetail'); // Occupation @@ -53,45 +54,11 @@ class CreateContactTable extends Migration { $this->forge->addField('CreateDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP'); $this->forge->addKey('OccupationID', true); $this->forge->createTable('occupation'); - - /* - - // ContactTraining - $this->forge->addField([ - 'ContactID' => [ 'type' => 'INT', 'constraint' => 11 ], - 'TrainingType' => [ 'type' => 'VARCHAR', 'constraint' => 50, 'null' => true ], - 'TrainingTitle' => [ 'type' => 'VARCHAR', 'constraint' => 255, 'null' => true ], - 'StartDate' => [ 'type' => 'DATETIME', 'null' => true ], - 'EndDate' => [ 'type' => 'DATETIME', 'null' => true ], - 'Facilitator' => [ 'type' => 'VARCHAR', 'constraint' => 150, 'null' => true ], - 'CertificateLocation'=> [ 'type' => 'VARCHAR', 'constraint' => 255, 'null' => true ], - ]); - $this->forge->addField('CreateDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP'); - // $this->forge->addKey('ContactID', true); - $this->forge->createTable('ContactTraining'); - - // MedicalSpecialty - $this->forge->addField([ - 'SpecialtyID' => [ 'type' => 'INT', 'constraint' => 11 ], - 'SpecialtyText' => [ 'type' => 'VARCHAR', 'constraint' => 255, 'null' => true ], - 'Parent' => [ 'type' => 'VARCHAR', 'constraint' => 50, 'null' => true ], - 'Title' => [ 'type' => 'VARCHAR', 'constraint' => 50, 'null' => true ], - 'EndDate' => [ 'type' => 'DATETIME', 'null' => true ], - ]); - $this->forge->addField('CreateDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP'); - $this->forge->addKey('SpecialtyID', true); - $this->forge->createTable('MedicalSpecialty'); - - */ } public function down() { $this->forge->dropTable('Contact'); $this->forge->dropTable('ContactDetail'); $this->forge->dropTable('Occupation'); - /* - $this->forge->dropTable('ContactTraining'); - $this->forge->dropTable('MedicalSpecialty'); - */ } } diff --git a/app/Database/Seeds/DummySeeder.php b/app/Database/Seeds/DummySeeder.php index 2274d05..ea6fede 100644 --- a/app/Database/Seeds/DummySeeder.php +++ b/app/Database/Seeds/DummySeeder.php @@ -20,13 +20,18 @@ class DummySeeder extends Seeder { // contact $data = [ - ['ContactID'=>1, 'NameFirst'=>'Default', 'NameLast'=>'Doctor', 'Title'=>'', 'Initial'=>'DEFDOC', 'Birthdate'=>'', 'EmailAddress1'=>'', 'EmailAddress2'=>'', 'Phone'=>'', 'MobilePhone1'=>'', 'MobilePhone2'=>'', 'Specialty'=>'', 'SubSpecialty'=>'' ], - ['ContactID'=>2, 'NameFirst'=>'Dummy', 'NameLast'=>'Doctor', 'Title'=>'', 'Initial'=>'QDOC' ] + ['ContactID'=>1, 'NameFirst'=>'Default', 'NameLast'=>'Doctor', 'Title'=>'', 'Initial'=>'DEFDOC', + 'Birthdate'=>'', 'EmailAddress1'=>'', 'EmailAddress2'=>'', 'Phone'=>'', 'MobilePhone1'=>'', 'MobilePhone2'=>'', 'Specialty'=>'', 'SubSpecialty'=>'' ], + ['ContactID'=>2, 'NameFirst'=>'Dummy', 'NameLast'=>'Doctor', 'Title'=>'', 'Initial'=>'QDOC', + 'Birthdate'=>'', 'EmailAddress1'=>'', 'EmailAddress2'=>'', 'Phone'=>'', 'MobilePhone1'=>'', 'MobilePhone2'=>'', 'Specialty'=>'', 'SubSpecialty'=>'' ] ]; $this->db->table('contact')->insertBatch($data); $data = [ - ['ContactID'=>1, 'ContactCode'=>'DEFDOC', 'ContactEmail'=>'defdoc@email.com', 'OccupationID'=>'', 'JobTitle'=>'', 'Department'=>'Jantung Sehat', 'ContactStartDate'=>'2020-01-05', 'ContactEndDate'=>'2023-01-05' ], - ['ContactID'=>1, 'ContactCode'=>'QDOC', 'ContactEmail'=>'qdoc@email.com', 'OccupationID'=>'', 'JobTitle'=>'', 'Department'=>'Hati Sehat', 'ContactStartDate'=>'2023-01-05', 'ContactEndDate'=>'' ] + ['SiteID'=>1,'ContactID'=>1, 'ContactCode'=>'DEFDOC', 'ContactEmail'=>'defdoc@email.com', 'OccupationID'=>'', 'JobTitle'=>'', 'Department'=>'Jantung Sehat' ], + ['SiteID'=>2,'ContactID'=>1, 'ContactCode'=>'QDOC', 'ContactEmail'=>'qdoc@email.com', 'OccupationID'=>'', 'JobTitle'=>'', 'Department'=>'Hati Sehat' ], + ['SiteID'=>1,'ContactID'=>2, 'ContactCode'=>'S923', 'ContactEmail'=>'defdoc@email.com', 'OccupationID'=>'', 'JobTitle'=>'', 'Department'=>'Jantung Sehat' ], + ['SiteID'=>2,'ContactID'=>2, 'ContactCode'=>'B231', 'ContactEmail'=>'defdoc@email.com', 'OccupationID'=>'', 'JobTitle'=>'', 'Department'=>'Ginjal Sehat' ], + ['SiteID'=>3,'ContactID'=>2, 'ContactCode'=>'C342', 'ContactEmail'=>'qdoc@email.com', 'OccupationID'=>'', 'JobTitle'=>'', 'Department'=>'Hati Sehat' ] ]; $this->db->table('contactdetail')->insertBatch($data); diff --git a/app/Models/ContactDetailModel.php b/app/Models/ContactDetailModel.php new file mode 100644 index 0000000..9ca3d8b --- /dev/null +++ b/app/Models/ContactDetailModel.php @@ -0,0 +1,11 @@ +select("c.ContactID, cd.ContactCode, c.NameFirst, c.NameLast, c.Specialty") + ->join("contactdetail cd", "c.ContactID=cd.ContactID", "left") + ->join("occupation o","cd.OccupationID=o.OccupationID", "left") + ->get()->getResultArray(); + + return $rows; + } + + public function getContactWithDetail($ContactID) { + $rows = $this->where('c.ContactID', $ContactID)->join('contactdetail cd', 'c.ContactID=cd.ContactID','left')->get()->getResultArray(); + $contact = [ + 'ContactID' => $rows[0]['ContactID'], + 'NameFirst' => $rows[0]['NameFirst'] ?? null, + 'NameLast' => $rows[0]['NameLast'] ?? null, + 'Title' => $rows[0]['Title'] ?? null, + 'Initial' => $rows[0]['Initial'] ?? null, + 'Birthdate' => $rows[0]['Birthdate'] ?? null, + 'EmailAddress1' => $rows[0]['EmailAddress1'] ?? null, + 'EmailAddress2' => $rows[0]['EmailAddress2'] ?? null, + 'Phone' => $rows[0]['Phone'] ?? null, + 'MobilePhone1' => $rows[0]['MobilePhone1'] ?? null, + 'MobilePhone2' => $rows[0]['MobilePhone2'] ?? null, + 'Specialty' => $rows[0]['Specialty'] ?? null, + 'SubSpecialty' => $rows[0]['SubSpecialty'] ?? null, + 'Details' => [] + ]; + + foreach ($rows as $row) { + if (!empty($row['ContactDetID'])) { + $contact['Details'][] = [ + 'SiteID' => $row['SiteID'] ?? null, + 'ContactDetID' => $row['ContactDetID'], + 'ContactCode' => $row['ContactCode'] ?? null, + 'ContactEmail' => $row['DetailPhone'] ?? null, + 'OccupationID' => $row['OccupationID'] ?? null, + 'JobTitle' => $row['JobTitle'] ?? null, + 'Department' => $row['Department'] ?? null, + 'ContactStartDate' => $row['ContactStartDate'] ?? null, + 'ContactEndDate' => $row['ContactEndDate'] ?? null + ]; + } + } + + return $contact; + } + + public function createContact(array $contactData, array $contactDetails) { + $db = \Config\Database::connect(); + $db->transStart(); + + try { + if (!$this->insert($contactData)) { + throw new \Exception('Failed to insert contact'); + } + $ContactID = $this->getInsertID(); + + $detailModel = new \App\Models\ContactDetailModel(); + foreach ($contactDetails as $detail) { + $detail['ContactID'] = $ContactID; + if (!$detailModel->insert($detail)) { + throw new \Exception('Failed to insert contact details'); + } + } + + $db->transComplete(); + return $db->transStatus(); + } catch (\Exception $e) { + $db->transRollback(); + throw $e; + } + } + + public function updateContact(array $contactData, array $contactDetails) { + $db = \Config\Database::connect(); + $db->transStart(); + + try { + if (!$this->update($contactData)) { + throw new \Exception('Failed to insert contact'); + } + $ContactID = $this->getInsertID(); + + $detailModel = new \App\Models\ContactDetailModel(); + foreach ($contactDetails as $detail) { + $detail['ContactID'] = $ContactID; + if (!$detailModel->insert($detail)) { + throw new \Exception('Failed to insert contact details'); + } + } + + $db->transComplete(); + return $db->transStatus(); + } catch (\Exception $e) { + $db->transRollback(); + throw $e; + } + } +}