From 501ef06592704b916f6b9cec41caf5f1a18428f7 Mon Sep 17 00:00:00 2001 From: mahdahar <89adham@gmail.com> Date: Thu, 25 Sep 2025 13:30:15 +0700 Subject: [PATCH] fixing contactdetail --- app/Config/Routes.php | 4 +- app/Controllers/Contact.php | 131 ++++++++++-------------------- app/Models/ContactDetailModel.php | 62 +++++++++----- app/Models/ContactModel.php | 76 +++++++++-------- 4 files changed, 125 insertions(+), 148 deletions(-) diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 6f6b622..4809e12 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -54,8 +54,8 @@ $routes->delete('/api/location', 'Location::delete'); $routes->get('/api/contact', 'Contact::index'); $routes->get('/api/contact/(:num)', 'Contact::show/$1'); -$routes->post('/api/contact', 'Contact::create'); -$routes->patch('/api/contact', 'Contact::update'); +$routes->post('/api/contact', 'Contact::save'); +$routes->patch('/api/contact', 'Contact::save'); $routes->delete('/api/contact', 'Contact::delete'); $routes->get('/api/occupation', 'Occupation::index'); diff --git a/app/Controllers/Contact.php b/app/Controllers/Contact.php index 54db284..2ea7e95 100644 --- a/app/Controllers/Contact.php +++ b/app/Controllers/Contact.php @@ -5,15 +5,16 @@ use CodeIgniter\API\ResponseTrait; use CodeIgniter\Controller; use App\Models\ContactModel; +use App\Models\ContactDetailModel; class Contact extends Controller { use ResponseTrait; - protected $contactModel; + protected $db; protected $contactRule; public function __construct() { - $this->contactModel = new ContactModel(); + $this->db = \Config\Database::connect(); $this->contactRule = [ 'NameFirst' => 'required' ]; } @@ -55,66 +56,14 @@ class Contact extends Controller { ], 200); } - public function create() { - $input = $this->request->getJSON(true); - $dataContact = $this->prepareContactData($input); - $dataContactDetail = $this->prepareContactDetailData($input); - - if (!$this->validateData($dataContact, $this->contactRule)) { - 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'); - } - } catch (\Throwable $e) { - return $this->failServerError('Error: ' . $e->getMessage()); - } - } - - public function update() { - $input = $this->request->getJSON(true); - $ContactID = $input['ContactID']; - $dataContact = $this->prepareContactData($input); - $dataContactDetail = $this->prepareContactDetailData($input); - - 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 updated successfully', - 'data' => $dataContact, - ]); - } else { - return $this->failServerError('Failed to create contact'); - } - } catch (\Throwable $e) { - return $this->failServerError('Error: ' . $e->getMessage()); - } - - } - public function delete() { try { $input = $this->request->getJSON(true); $ContactID = $input["ContactID"]; if (!$ContactID) { - return $this->failValidationError('ContactID is required.'); + return $this->failValidationErrors('ContactID is required.'); } - + $contact = $this->db->table('contact')->where('ContactID', $ContactID)->get()->getRow(); if (!$contact) { return $this->failNotFound("data with {$ContactID} not found."); @@ -136,40 +85,48 @@ class Contact extends Controller { } } - private function prepareContactData(array $input): array { - $data = [ - "NameFirst" => $input['NameFirst'] ?? null, - "NameLast" => $input['NameLast'] ?? null, - "Title" => $input['Title'] ?? null, - "Initial" => $input['Initial'] ?? null, - "Birthdate" => $input['Birthdate'] ?? null, - "EmailAddress1" => $input['EmailAddress1'] ?? null, - "EmailAddress2" => $input['EmailAddress2'] ?? null, - "Phone" => $input["Phone"] ?? null, - "MobilePhone1" => $input["MobilePhone1"] ?? null, - "MobilePhone2" => $input["MobilePhone2"] ?? null, - "Specialty" => $input["Specialty"] ?? null, - "SubSpecialty" => $input["SubSpecialty"] ?? null, - ]; + public function save() { + $input = $this->request->getJSON(true); + $contactModel = new ContactModel(); + $detailModel = new ContactDetailModel(); + $db = \Config\Database::connect(); - if(!empty($input["ContactID"])) { $data["ContactID"] = $input["ContactID"]; } + $db->transStart(); - return $data; - } + try { - private function prepareContactDetailData(array $input): array { - foreach($input['ContactDetail'] as $detail) { - $data[] = [ - "SiteID" => $detail['SiteID'] ?? null, - "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, - ]; + if (!empty($input['ContactID'])) { + $ContactID = $input['ContactID']; + if (!$contactModel->update($ContactID, $input)) { throw new \RuntimeException('Failed to update contact'); } + } else { + $ContactID = $contactModel->insert($input, true); + if (!$ContactID) { throw new \RuntimeException('Failed to insert contact'); } + } + + if (!empty($input['Details'])) { + $result = $detailModel->syncDetails($ContactID, $input['Details']); + if ($result['status'] !== 'success') { + throw new \RuntimeException('Failed to sync details: ' . $result['message']); + } + } + + $db->transComplete(); + + if ($db->transStatus() === false) { + throw new \RuntimeException('Transaction failed'); + } + + return $this->respondCreated([ + 'status' => 'success', + 'ContactID' => $ContactID, + ]); + } catch (\Throwable $e) { + $db->transRollback(); + log_message('error', 'saveContact error: ' . $e->getMessage()); + return $this->fail([ + 'status' => 'error', + 'message' => $e->getMessage(), + ], 500); } - return $data; } } \ No newline at end of file diff --git a/app/Models/ContactDetailModel.php b/app/Models/ContactDetailModel.php index 2059c93..9925594 100644 --- a/app/Models/ContactDetailModel.php +++ b/app/Models/ContactDetailModel.php @@ -9,29 +9,51 @@ class ContactDetailModel extends Model { protected $primaryKey = 'ContactDetID'; protected $allowedFields = ['ContactID', 'SiteID', 'ContactCode', 'ContactEmail', 'OccupationID', 'JobTitle', 'Department', 'ContactStartDate', 'ContactEndDate']; - public function syncDetails(int $contactId, array $details) { - $kept = []; + public function syncDetails(int $ContactID, array $contactDetails) { + try { + $keptSiteIDs = []; - foreach ($details as $detail) { - $detail['ContactID'] = $contactId; + foreach ($contactDetails as $detail) { + if (empty($detail['SiteID'])) { + continue; + } - $existing = $this->where('SiteID', $detail['SiteID']) - ->where('ContactID', $contactId) - ->first(); + $detail['ContactID'] = $ContactID; - if ($existing) { - $this->update($existing[$this->primaryKey], $detail); - $kept[] = $existing[$this->primaryKey]; - } else { - $newId = $this->insert($detail); - $kept[] = $newId; + $existing = $this->where('ContactID', $ContactID) + ->where('SiteID', $detail['SiteID']) + ->first(); + + if ($existing) { + $this->update($existing[$this->primaryKey], $detail); + } else { + $this->insert($detail); + } + + $keptSiteIDs[] = $detail['SiteID']; } - } - if (!empty($kept)) { - $this->where('ContactID', $contactId) - ->whereNotIn($this->primaryKey, $kept) - ->delete(); - } else { $this->where('ContactID', $contactId)->delete(); } - } + // Delete missing rows + if (!empty($keptSiteIDs)) { + $this->where('ContactID', $ContactID) + ->whereNotIn('SiteID', $keptSiteIDs) + ->delete(); + } else { + $this->where('ContactID', $ContactID)->delete(); + } + + return [ + 'status' => 'success', + 'inserted' => count($contactDetails) - count($keptSiteIDs), + 'kept' => count($keptSiteIDs), + ]; + } catch (\Throwable $e) { + log_message('error', 'syncDetails error: ' . $e->getMessage()); + + return [ + 'status' => 'error', + 'message' => $e->getMessage(), + ]; + } +} } diff --git a/app/Models/ContactModel.php b/app/Models/ContactModel.php index fcba800..1dd712d 100644 --- a/app/Models/ContactModel.php +++ b/app/Models/ContactModel.php @@ -5,13 +5,13 @@ namespace App\Models; use CodeIgniter\Model; class ContactModel extends Model { - protected $table = 'contact c'; + protected $table = 'contact'; protected $primaryKey = 'ContactID'; protected $allowedFields = ['NameFirst', 'NameLast', 'Title', 'Initial', 'Birthdate', 'EmailAddress1', 'EmailAddress2', 'Phone', 'MobilePhone1', 'MobilePhone2', 'Specialty', 'SubSpecialty']; public function getContactsWithDetail() { - $rows = $this->select("c.ContactID, cd.SiteID, cd.ContactCode, c.NameFirst, c.NameLast, c.Specialty") - ->join("contactdetail cd", "c.ContactID=cd.ContactID", "left") + $rows = $this->select("contact.ContactID, cd.SiteID, cd.ContactCode, NameFirst, NameLast, Specialty") + ->join("contactdetail cd", "contact.ContactID=cd.ContactID", "left") ->join("occupation o","cd.OccupationID=o.OccupationID", "left") ->get()->getResultArray(); @@ -19,7 +19,7 @@ class ContactModel extends Model { } public function getContactWithDetail($ContactID) { - $rows = $this->where('c.ContactID', $ContactID)->join('contactdetail cd', 'c.ContactID=cd.ContactID','left')->get()->getResultArray(); + $rows = $this->where('contact.ContactID', $ContactID)->join('contactdetail cd', 'contact.ContactID=cd.ContactID','left')->get()->getResultArray(); $contact = [ 'ContactID' => $rows[0]['ContactID'], 'NameFirst' => $rows[0]['NameFirst'] ?? null, @@ -56,49 +56,47 @@ class ContactModel extends Model { return $contact; } - public function createContact(array $contactData, array $contactDetails) { - $db = \Config\Database::connect(); - $db->transStart(); + public function saveWithDetails(array $data): array { + $db = \Config\Database::connect(); + $db->transStart(); - try { - if (!$this->insert($contactData)) { - throw new \Exception('Failed to insert contact'); + try { + if (!empty($data['ContactID'])) { + $contactId = $data['ContactID']; + $this->update($contactId, $data); + } else { + $contactId = $this->insert($data, true); } - $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'); + if (!$contactId) { + throw new \RuntimeException('Failed to save contact'); + } + + if (!empty($data['Details'])) { + $detailModel = new \App\Models\ContactDetailModel(); + $result = $detailModel->syncDetails($contactId, $data['Details']); + + if ($result['status'] !== 'success') { + throw new \RuntimeException('SyncDetails failed: ' . $result['message']); } } $db->transComplete(); - return $db->transStatus(); - } catch (\Exception $e) { + + return [ + 'status' => 'success', + 'ContactID' => $contactId, + ]; + } catch (\Throwable $e) { $db->transRollback(); - throw $e; - } + + log_message('error', 'saveWithDetails error: ' . $e->getMessage()); + + return [ + 'status' => 'error', + 'message' => $e->getMessage(), + ]; + } } - public function updateContact(int $ContactID, array $contactData, array $contactDetails) { - $db = \Config\Database::connect(); - $db->transStart(); - - try { - if (!$this->update($ContactID, $contactData)) { - throw new \Exception('Failed to update contact'); - } - - $detailModel = new \App\Models\ContactDetailModel(); - $detailModel->syncDetails($ContactID, $contactDetails); - - $db->transComplete(); - return $db->transStatus(); - } catch (\Exception $e) { - $db->transRollback(); - throw $e; - } - } }