diff --git a/src/application/controllers/backend.php b/src/application/controllers/backend.php index 7f7fcb4c..2c494371 100644 --- a/src/application/controllers/backend.php +++ b/src/application/controllers/backend.php @@ -42,7 +42,7 @@ class Backend extends CI_Controller { } /** - * Display the backend customers page + * Display the backend customers page. * * In this page the user can manage all the customer records of the system. */ @@ -65,10 +65,18 @@ class Backend extends CI_Controller { $this->load->view('backend/footer', $view); } + /** + * Displays the backend services page. + * + * Here the admin user will be able to organize and create the services + * that the user will be able to book appointments in frontend. + * + * NOTICE: The services that each provider is able to service is managed + * from the backend services page. + */ public function services() { // @task Require user to be logged in the application. - $this->load->model('providers_model'); $this->load->model('customers_model'); $this->load->model('services_model'); $this->load->model('settings_model'); @@ -83,15 +91,44 @@ class Backend extends CI_Controller { $this->load->view('backend/footer', $view); } - public function providers() { - echo '

Not implemented yet.

'; + /** + * Display the backend users page. + * + * In this page the admin user will be able to manage the system users. + * By this, we mean the provider, secretary and admin users. This is also + * the page where the admin defines which service can each provider provide. + */ + public function users() { + // @task Require user to be logged in the application. + + $this->load->model('providers_model'); + $this->load->model('secretaries_model'); + $this->load->model('admins_model'); + $this->load->model('services_model'); + $this->load->model('settings_model'); + + $view['base_url'] = $this->config->item('base_url'); + $view['company_name'] = $this->settings_model->get_setting('company_name'); + $view['providers'] = $this->providers_model->get_batch(); + $view['secretaries'] = $this->secretaries_model->get_batch(); + $view['admins'] = $this->admins_model->get_batch(); + $view['services'] = $this->services_model->get_batch(); + + $this->load->view('backend/header', $view); + $this->load->view('backend/users', $view); + $this->load->view('backend/footer', $view); } + /** + * Display the user/system settings. + * + * This page will display the user settings (name, password etc). If current user is + * an administrator, then he will be able to make change to the current Easy!Appointment + * installation (core settings like company name, book timeout etc). + */ public function settings() { echo '

Not implemented yet.

'; } - - } /* End of file backend.php */ diff --git a/src/application/libraries/Unit_tests/drivers/Unit_tests_providers_model.php b/src/application/libraries/Unit_tests/drivers/Unit_tests_providers_model.php index 64a4ff69..27b60f22 100644 --- a/src/application/libraries/Unit_tests/drivers/Unit_tests_providers_model.php +++ b/src/application/libraries/Unit_tests/drivers/Unit_tests_providers_model.php @@ -1,18 +1,18 @@ CI =& get_instance(); - $this->CI->load->library('Unit_test'); - $this->CI->load->model('providers_model'); + $this->ci =& get_instance(); + $this->ci->load->library('Unit_test'); + $this->ci->load->model('providers_model'); - $this->provider_role_id = $this->CI->db->get_where('ea_roles', + $this->provider_role_id = $this->ci->db->get_where('ea_roles', array('slug' => DB_SLUG_PROVIDER))->row()->id; } @@ -34,6 +34,94 @@ class Unit_tests_providers_model extends CI_Driver { ///////////////////////////////////////////////////////////////////////// // UNIT TESTS ///////////////////////////////////////////////////////////////////////// + // TEST ADD METHOD + private function test_add_insert() { + $provider = array( + 'first_name' => 'John', + 'last_name' => 'Doe', + 'mobile_number' => '000000', + 'phone_number' => '111111', + 'address' => 'Some Str', + 'city' => 'Some City', + 'state' => 'Some State', + 'zip_code' => '12345', + 'notes' => 'This is a test provider', + 'id_roles' => $this->provider_role_id + ); + + $provider['id'] = $this->ci->providers_model->add($provider); + $this->ci->unit->run($provider['id'], 'is_int', 'Check if add (insert) result is integer.'); + + $db_record = $this->ci->db->get_where('ea_users', array('id' => $provider['id']))->row_array(); + $this->ci->unit->run($provider, $db_record, 'Check if add(insert) has successfully ' + . 'inserted a provider record.'); + + $this->ci->db->delete('ea_users', array('id' => $provider['id'])); + } + + private function test_add_update() { + + } + + private function test_add_with_invalid_data() { + + } + + // TEST EXISTS METHOD + private function test_exists_with_record_that_exists() { + + } + + private function test_exists_with_invalid_data() { + + } + + private function test_exists_with_record_that_does_not_exist() { + + } + + // TEST FIND RECORD ID METHOD + private function test_find_record_id() { + + } + + private function test_find_record_id_with_invalid_data() { + + } + + private function test_find_record_id_with_record_that_does_not_exist() { + + } + + // TEST VALIDATE RECORD METHOD + private function test_validate() { + + } + + private function test_validate_with_record_that_does_not_exist() { + + } + + private function test_validate_with_missing_required_fields() { + + } + + private function test_validate_with_invalid_email_address() { + + } + + // TEST DELETE RECORD METHOD + private function test_delete() { + + } + + private function test_delete_with_invalid_record_id() { + + } + + private function test_delete_with_record_that_does_not_exist() { + + } // TEST GET ROW METHOD --------------------------------------------- private function test_get_row() { @@ -48,25 +136,25 @@ class Unit_tests_providers_model extends CI_Driver { 'zip_code' => '12345', 'id_roles' => $this->provider_role_id ); - $this->CI->db->insert('ea_users', $provider); - $provider['id'] = intval($this->CI->db->insert_id()); + $this->ci->db->insert('ea_users', $provider); + $provider['id'] = intval($this->ci->db->insert_id()); // Get the new customer record from db. - $no_model_data = $this->CI->db->get_where('ea_users', array('id' => $provider['id'])) + $no_model_data = $this->ci->db->get_where('ea_users', array('id' => $provider['id'])) ->row_array(); - $model_data = $this->CI->providers_model->get_row($provider['id']); + $model_data = $this->ci->providers_model->get_row($provider['id']); // Check that the row is the correct one. - $this->CI->unit->run($no_model_data, $model_data, 'Test get_row() method'); + $this->ci->unit->run($no_model_data, $model_data, 'Test get_row() method'); // Delete inserted customer record. - $this->CI->db->delete('ea_users', array('id' => $provider['id'])); + $this->ci->db->delete('ea_users', array('id' => $provider['id'])); } private function test_get_row_that_does_not_exist() { $random_record_id = 486868412; - $row_data = $this->CI->providers_model->get_row($random_record_id); - $this->CI->unit->run($row_data, NULL, 'Test get_row() with record id that does ' + $row_data = $this->ci->providers_model->get_row($random_record_id); + $this->ci->unit->run($row_data, NULL, 'Test get_row() with record id that does ' . 'not exist in the database.'); } @@ -75,12 +163,12 @@ class Unit_tests_providers_model extends CI_Driver { $has_thrown_exception = FALSE; try { - $this->CI->providers_model->get_row($invalid_id); + $this->ci->providers_model->get_row($invalid_id); } catch (Exception $exc) { $has_thrown_exception = TRUE; } - $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_row() with wrong argument.'); + $this->ci->unit->run($has_thrown_exception, TRUE, 'Test get_row() with wrong argument.'); } // TEST GET VALUE METHOD --------------------------------------------- @@ -96,17 +184,17 @@ class Unit_tests_providers_model extends CI_Driver { 'zip_code' => '12345', 'id_roles' => $this->provider_role_id ); - $this->CI->db->insert('ea_users', $provider); - $provider['id'] = intval($this->CI->db->insert_id()); + $this->ci->db->insert('ea_users', $provider); + $provider['id'] = intval($this->ci->db->insert_id()); // Get a specific value from the database. - $model_value = $this->CI->providers_model->get_value('email', $provider['id']); + $model_value = $this->ci->providers_model->get_value('email', $provider['id']); // Check if the value was correctly fetched from the database. - $this->CI->unit->run($model_value, $provider['email'], 'Test get_value() method.'); + $this->ci->unit->run($model_value, $provider['email'], 'Test get_value() method.'); // Delete inserted appointment record. - $this->CI->db->delete('ea_users', array('id' => $provider['id'])); + $this->ci->db->delete('ea_users', array('id' => $provider['id'])); } private function test_get_value_record_does_not_exist() { @@ -115,12 +203,12 @@ class Unit_tests_providers_model extends CI_Driver { $has_thrown_exception = FALSE; try { - $this->CI->providers_model->get_value('email', $random_record_id); + $this->ci->providers_model->get_value('email', $random_record_id); } catch (Exception $exc) { $has_thrown_exception = TRUE; } - $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that ' + $this->ci->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that ' . 'does not exist.'); } @@ -136,35 +224,35 @@ class Unit_tests_providers_model extends CI_Driver { 'zip_code' => '12345', 'id_roles' => $this->provider_role_id ); - $this->CI->db->insert('ea_users', $provider); - $provider['id'] = intval($this->CI->db->insert_id()); + $this->ci->db->insert('ea_users', $provider); + $provider['id'] = intval($this->ci->db->insert_id()); // Try to get record value with wrong field name. $wrong_field_name = 'THIS IS WRONG'; $has_thrown_exception = FALSE; try { - $this->CI->providers_model->get_value($wrong_field_name, $provider['id']); + $this->ci->providers_model->get_value($wrong_field_name, $provider['id']); } catch (Exception $exc) { $has_thrown_exception = TRUE; } - $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that ' + $this->ci->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that ' . 'does not exist.'); // Delete inserted appointment record. - $this->CI->db->delete('ea_users', array('id' => $provider['id'])); + $this->ci->db->delete('ea_users', array('id' => $provider['id'])); } // TEST GET BATCH METHOD --------------------------------------------- private function test_get_batch() { // Get all the customer rows without using the model. - $db_data = $this->CI->db->get_where('ea_users', + $db_data = $this->ci->db->get_where('ea_users', array('id_roles' => $this->provider_role_id))->result_array(); // Get all the customer rows by using the model. - $model_data = $this->CI->providers_model->get_batch(); + $model_data = $this->ci->providers_model->get_batch(); // Check that the two arrays are the same. - $this->CI->unit->run($db_data, $model_data, 'Test get_batch() method.'); + $this->ci->unit->run($db_data, $model_data, 'Test get_batch() method.'); } private function test_get_batch_with_where_clause() { @@ -179,21 +267,21 @@ class Unit_tests_providers_model extends CI_Driver { 'zip_code' => '12345', 'id_roles' => $this->provider_role_id ); - $this->CI->db->insert('ea_users', $provider); - $provider['id'] = intval($this->CI->db->insert_id()); + $this->ci->db->insert('ea_users', $provider); + $provider['id'] = intval($this->ci->db->insert_id()); // Get data without using the model. - $no_model_data = $this->CI->db->get_where('ea_users', array('id' => $provider['id'])) + $no_model_data = $this->ci->db->get_where('ea_users', array('id' => $provider['id'])) ->result_array(); // Get data by using the model. - $model_data = $this->CI->providers_model->get_batch(array('id' => $provider['id'])); + $model_data = $this->ci->providers_model->get_batch(array('id' => $provider['id'])); // Check that the data arrays are the same. - $this->CI->unit->run($no_model_data, $model_data, 'Test get_batch() with where clause.'); + $this->ci->unit->run($no_model_data, $model_data, 'Test get_batch() with where clause.'); // Delete inserted record from database. - $this->CI->db->delete('ea_users', array('id' => $provider['id'])); + $this->ci->db->delete('ea_users', array('id' => $provider['id'])); } private function unabled_test_get_batch_with_invalid_where_clause() { diff --git a/src/application/models/admins_model.php b/src/application/models/admins_model.php new file mode 100644 index 00000000..cc050f31 --- /dev/null +++ b/src/application/models/admins_model.php @@ -0,0 +1,55 @@ +get(); if ($result->num_rows() == 0) { - throw new Exception('Could not find appointment record id.'); + throw new Exception('Could not find customer record id.'); } return $result->row()->id; @@ -192,25 +192,20 @@ class Customers_Model extends CI_Model { /** * Delete an existing customer record from the database. * - * @expectedException InvalidArgumentException Raises when - * the $customer_id is not an integer. - * - * @param numeric $record_id The record id to be deleted. + * @param numeric $customer_id The record id to be deleted. * @return bool Returns the delete operation result. */ - public function delete($record_id) { - if (!is_numeric($record_id)) { - throw new Exception('Invalid argument type $customer_id : ' - . $record_id); + public function delete($customer_id) { + if (!is_numeric($customer_id)) { + throw new Exception('Invalid argument type $customer_id : ' . $customer_id); } - $num_rows = $this->db->get_where('ea_users', array('id' => $record_id))->num_rows(); + $num_rows = $this->db->get_where('ea_users', array('id' => $customer_id))->num_rows(); if ($num_rows == 0) { return FALSE; } - $this->db->where('id', $record_id); - return $this->db->delete('ea_users'); + return $this->db->delete('ea_users', array('id' => $customer_id)); } /** diff --git a/src/application/models/providers_model.php b/src/application/models/providers_model.php index 69647d3f..314142e1 100644 --- a/src/application/models/providers_model.php +++ b/src/application/models/providers_model.php @@ -8,6 +8,180 @@ class Providers_Model extends CI_Model { parent::__construct(); } + /** + * Add (insert/update) a service provider record. + * + * If the record already exists (id value provided) then it is going to be updated, + * otherwise inserted into the database. + * + * @param array $provider Contains the service provider data. + * @return int Returns the record id. + * @throws Exception When the record data validation fails. + */ + public function add($provider) { + if (!$this->validate($provider)) { + throw new Exception('Provider data are not valid :' . print_r($provider, TRUE)); + } + + if ($this->exists($provider) && !isset($provider['id'])) { + $provider['id'] = $this->find_record_id($provider); + } + + if (!isset($provider['id'])) { + $provider['id'] = $this->insert($provider); + } else { + $this->update($provider); + } + + return $provider['id']; + } + + /** + * Check whether a particular provider record already exists in the database. + * + * @param array $provider Contains the provider data. The 'email' value is required + * in order to check for a provider. + * @return bool Returns whether the provider record exists or not. + * @throws Exception When the 'email' value is not provided. + */ + public function exists($provider) { + if (!isset($provider['email'])) { + throw new Exception('Provider email is not provided :' . print_r($provider, TRUE)); + } + + // This method shouldn't depend on another method of this class. + $num_rows = $this->db + ->select('*') + ->from('ea_users') + ->join('ea_roles', 'ea_roles.id = ea_users.id_roles', 'inner') + ->where('ea_users.email', $provider['email']) + ->where('ea_roles.slug', DB_SLUG_PROVIDER) + ->get()->num_rows(); + + return ($num_rows > 0) ? TRUE : FALSE; + } + + /** + * Insert a new provider record into the database. + * + * @param array $provider Contains the provider data (must be already validated). + * @return int Returns the new record id. + * @throws Exception When the insert operation fails. + */ + public function insert($provider) { + // Get provider's role id. + $provider['id_roles'] = $this->get_providers_role_id(); + + if (!$this->db->insert('ea_users', $provider)) { + throw new Exception('Could not insert provider into the database'); + } + + return intval($this->db->insert_id()); + } + + /** + * Update an existing provider record in the database. + * + * @param array $provider Contains the provider data. + * @return int Returns the record id. + * @throws Exception When the update operation fails. + */ + public function update($provider) { + $this->db->where('id', $provider['id']); + + if (!$this->db->update('ea_users', $provider)) { + throw new Exception('Could not update provider record.'); + } + + return intval($provider['id']); + } + + /** + * Find the database record id of a provider. + * + * @param array $provider Contains the provider data. The 'email' value is required + * in order to find the record id. + * @return int Returns the record id. + * @throws Exception When the provider's email value is not provided. + */ + public function find_record_id($provider) { + if (!isset($provider['email'])) { + throw new Exception('Provider email was not provided :' . print_r($provider, TRUE)); + } + + // Get customer's role id + $result = $this->db + ->select('ea_users.id') + ->from('ea_users') + ->join('ea_roles', 'ea_roles.id = ea_users.id_roles', 'inner') + ->where('ea_users.email', $provider['email']) + ->where('ea_roles.slug', DB_SLUG_PROVIDER) + ->get(); + + if ($result->num_rows() == 0) { + throw new Exception('Could not find provider record id.'); + } + + return $result->row()->id; + } + + /** + * Validate provider data before the insert or update operation is executed. + * + * @param array $provider Contains the provider data. + * @return bool Returns the validation result. + */ + public function validate($provider) { + $this->load->helper('data_validation'); + + try { + // If a customer id is provided, check whether the record + // exist in the database. + if (isset($provider['id'])) { + $num_rows = $this->db->get_where('ea_users', + array('id' => $provider['id']))->num_rows(); + if ($num_rows == 0) { + throw new Exception('Provided record id does not exist in the database.'); + } + } + // Validate required fields + if (!isset($provider['last_name']) + || !isset($provider['email']) + || !isset($provider['phone_number'])) { + throw new Exception('Not all required fields are provided : ' . print_r($provider, TRUE)); + } + + // Validate email address + if (!filter_var($provider['email'], FILTER_VALIDATE_EMAIL)) { + throw new Exception('Invalid email address provided : ' . $provider['email']); + } + + return TRUE; + } catch (Exception $exc) { + return FALSE; + } + } + + /** + * Delete an existing provider record from the database. + * + * @param numeric $customer_id The record id to be deleted. + * @return bool Returns the delete operation result. + * @throws Exception When the provider id value is not numeric. + */ + public function delete($provider_id) { + if (!is_numeric($provider_id)) { + throw new Exception('Invalid argument type $customer_id : ' . $provider_id); + } + + $num_rows = $this->db->get_where('ea_users', array('id' => $provider_id))->num_rows(); + if ($num_rows == 0) { + return FALSE; // record does not exist + } + + return $this->db->delete('ea_users', array('id' => $provider_id)); + } + /** * Get a specific row from the providers table. * diff --git a/src/application/models/secretaries_model.php b/src/application/models/secretaries_model.php new file mode 100644 index 00000000..1fe27af0 --- /dev/null +++ b/src/application/models/secretaries_model.php @@ -0,0 +1,55 @@ + - - Providers + + Users +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +