fix: handle contact details on create
Separate nested contact details from the base payload, propagate sync failures to the API response, and add a regression test covering contact creation with details.
This commit is contained in:
parent
ee7b677ae4
commit
1c1808fdb9
@ -68,16 +68,25 @@ class ContactController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
public function create() {
|
||||
$input = $this->request->getJSON(true);
|
||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); }
|
||||
try {
|
||||
$id = $this->model->saveContact($input,true);
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'data created successfully', 'data' => $id ], 201);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->failServerError('Something went wrong: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
public function create() {
|
||||
$input = $this->request->getJSON(true);
|
||||
if (!$this->validateData($input, $this->rules)) { return $this->failValidationErrors($this->validator->getErrors()); }
|
||||
try {
|
||||
$result = $this->model->saveContact($input);
|
||||
|
||||
if (($result['status'] ?? 'error') !== 'success') {
|
||||
return $this->respond([
|
||||
'status' => 'failed',
|
||||
'message' => $result['message'] ?? 'Failed to create contact',
|
||||
'data' => []
|
||||
], 400);
|
||||
}
|
||||
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'data created successfully', 'data' => $result ], 201);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->failServerError('Something went wrong: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update($ContactID = null) {
|
||||
$input = $this->requirePatchPayload($this->request->getJSON(true));
|
||||
|
||||
@ -74,37 +74,41 @@ class ContactModel extends BaseModel {
|
||||
return $contact;
|
||||
}
|
||||
|
||||
public function saveContact(array $data): array {
|
||||
$db = \Config\Database::connect();
|
||||
$db->transStart();
|
||||
|
||||
try {
|
||||
if (!empty($data['ContactID'])) {
|
||||
$contactId = $data['ContactID'];
|
||||
$this->update($contactId, $data);
|
||||
} else {
|
||||
$contactId = $this->insert($data, true);
|
||||
public function saveContact(array $data): array {
|
||||
$db = \Config\Database::connect();
|
||||
$db->transStart();
|
||||
|
||||
try {
|
||||
$details = $data['Details'] ?? [];
|
||||
unset($data['Details']);
|
||||
|
||||
if (!empty($data['ContactID'])) {
|
||||
$contactId = $data['ContactID'];
|
||||
$this->update($contactId, $data);
|
||||
} else {
|
||||
$contactId = $this->insert($data, true);
|
||||
}
|
||||
|
||||
if (!$contactId) {
|
||||
throw new \RuntimeException('Failed to save contact');
|
||||
}
|
||||
|
||||
if (!empty($data['Details'])) {
|
||||
$modelDetail = new \App\Models\Contact\ContactDetailModel();
|
||||
$result = $modelDetail->syncDetails($contactId, $data['Details']);
|
||||
|
||||
if ($result['status'] !== 'success') {
|
||||
throw new \RuntimeException('SyncDetails failed: ' . $result['message']);
|
||||
}
|
||||
}
|
||||
if (!$contactId) {
|
||||
throw new \RuntimeException('Failed to save contact');
|
||||
}
|
||||
|
||||
if (!empty($details)) {
|
||||
$modelDetail = new \App\Models\Contact\ContactDetailModel();
|
||||
$result = $modelDetail->syncDetails($contactId, $details);
|
||||
|
||||
if ($result['status'] !== 'success') {
|
||||
throw new \RuntimeException('SyncDetails failed: ' . $result['message']);
|
||||
}
|
||||
}
|
||||
|
||||
$db->transComplete();
|
||||
|
||||
return [
|
||||
'status' => 'success',
|
||||
'ContactID' => $contactId,
|
||||
];
|
||||
return [
|
||||
'status' => 'success',
|
||||
'ContactID' => $contactId,
|
||||
'DetailsCount' => count($details),
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
$db->transRollback();
|
||||
|
||||
|
||||
@ -105,10 +105,54 @@ class ContactControllerTest extends CIUnitTestCase
|
||||
$json = $result->getJSON();
|
||||
$data = json_decode($json, true);
|
||||
|
||||
$this->assertEquals('success', $data['status']);
|
||||
$this->assertIsArray($data['data']);
|
||||
$this->assertEquals('success', $data['data']['status']);
|
||||
$this->assertIsInt($data['data']['ContactID']);
|
||||
$this->assertEquals('success', $data['status']);
|
||||
$this->assertIsArray($data['data']);
|
||||
$this->assertEquals('success', $data['data']['status']);
|
||||
$this->assertIsInt($data['data']['ContactID']);
|
||||
}
|
||||
|
||||
public function testCreateContactWithDetails()
|
||||
{
|
||||
$contactData = [
|
||||
'NameFirst' => 'TestContact' . time(),
|
||||
'NameLast' => 'LastName',
|
||||
'Initial' => 'TC',
|
||||
'Details' => [
|
||||
[
|
||||
'SiteID' => '1',
|
||||
'ContactCode' => 'CODE1',
|
||||
'ContactEmail' => 'code1@example.com',
|
||||
'OccupationID' => '1',
|
||||
'JobTitle' => 'Doctor',
|
||||
'Department' => 'General',
|
||||
],
|
||||
[
|
||||
'SiteID' => '2',
|
||||
'ContactCode' => 'CODE2',
|
||||
'ContactEmail' => 'code2@example.com',
|
||||
'OccupationID' => '2',
|
||||
'JobTitle' => 'Specialist',
|
||||
'Department' => 'Laboratory',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$result = $this->withHeaders(['Cookie' => 'token=' . $this->token])
|
||||
->withBody(json_encode($contactData))
|
||||
->call('post', 'api/contact');
|
||||
|
||||
$result->assertStatus(201);
|
||||
$data = json_decode($result->getJSON(), true);
|
||||
$contactId = $data['data']['ContactID'] ?? null;
|
||||
|
||||
$this->assertIsInt($contactId);
|
||||
|
||||
$show = $this->callProtected('get', 'api/contact/' . $contactId);
|
||||
$show->assertStatus(200);
|
||||
$showData = json_decode($show->getJSON(), true)['data'];
|
||||
|
||||
$this->assertCount(2, $showData['Details']);
|
||||
$this->assertEqualsCanonicalizing(['1', '2'], array_column($showData['Details'], 'SiteID'));
|
||||
}
|
||||
|
||||
public function testPartialUpdateContactWithSingleField()
|
||||
@ -121,7 +165,7 @@ class ContactControllerTest extends CIUnitTestCase
|
||||
'NameFirst' => 'Patched'
|
||||
]);
|
||||
|
||||
$patch->assertStatus(201);
|
||||
$patch->assertStatus(200);
|
||||
$response = json_decode($patch->getJSON(), true);
|
||||
$this->assertEquals('success', $response['status']);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user