public function record_appointment_location($appointment_id)
 {
     global $wpdb, $appointments;
     $appointment = $appointments->get_app($appointment_id);
     if (empty($appointment->worker)) {
         return false;
     }
     $location_id = self::worker_to_location_id($appointment->worker);
     if (!$location_id) {
         return false;
     }
     appointments_update_appointment($appointment_id, array('location' => $location_id));
 }
 function test_timetables_cache()
 {
     global $appointments;
     // Insert a worker
     $args = $this->factory->user->generate_args();
     $user_id_1 = $this->factory->user->create_object($args);
     $args = $this->factory->user->generate_args();
     $user_id_2 = $this->factory->user->create_object($args);
     $service_id = appointments_insert_service(array('name' => 'My Service'));
     $args = array('ID' => $user_id_1, 'price' => '19.7', 'services_provided' => array($service_id), 'dummy' => true);
     $result = appointments_insert_worker($args);
     $time = time();
     $date = date('Y-m-01', $time);
     $capacity = appointments_get_capacity();
     $date_start = strtotime("{$date} 00:00");
     $key = $date_start . '-' . $capacity . '-0' . '-' . date('Ym', $appointments->local_time);
     // WORKERS
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     // Insert another worker
     $args = array('ID' => $user_id_2, 'price' => '19.7', 'services_provided' => array($service_id), 'dummy' => true);
     appointments_insert_worker($args);
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     // Delete a worker
     appointments_delete_worker($user_id_2);
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     // Update worker
     appointments_update_worker($user_id_1, array('price' => '10'));
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
     // APPOINTMENTS
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     // Insert appointment
     $args = array('user' => $user_id_2, 'email' => '*****@*****.**', 'name' => 'Tester', 'phone' => '667788', 'address' => 'An address', 'city' => 'Madrid', 'service' => $service_id, 'worker' => $user_id_1, 'price' => '90', 'date' => 'December 18, 2024', 'time' => '07:30', 'note' => 'It\'s a note', 'status' => 'paid', 'location' => 5, 'gcal_updated' => '2015-12-01', 'gcal_ID' => 'test');
     $app_id = appointments_insert_appointment($args);
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     // Update Appointment
     appointments_update_appointment($app_id, array('address' => 'New address'));
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     // Delete appointment
     appointments_delete_appointment($app_id);
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
     // SERVICES
     // Insert a service
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     $service_id_2 = appointments_insert_service(array('name' => 'My Service 2'));
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     // Update service
     appointments_update_service($service_id_2, array('name' => 'My Service updated'));
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
     // Trigger the timetables cache
     appointments_get_timetable($date_start, $capacity);
     $timetables_cache = get_transient('app_timetables');
     $this->assertNotEmpty($timetables_cache[$key]);
     // Delete service
     appointments_delete_service($service_id_2);
     $timetables_cache = get_transient('app_timetables');
     $this->assertEmpty($timetables_cache[$key]);
 }
 /**
  * Inserts an appointment to the selected calendar as event
  * @param app_id: Appointment ID to be inserted
  * @test: Insert a test appointment
  */
 function insert_event($app_id, $test = false, $worker_id = 0)
 {
     if (!$this->connect($worker_id)) {
         return false;
     }
     global $appointments, $wpdb;
     if ($test) {
         $app = new stdClass();
         $app->name = __('Test client name', 'appointments');
         $app->phone = __('Test phone', 'appointments');
         $app->address = __('Test address', 'appointments');
         $app->city = __('Test city', 'appointments');
         $app->worker = 0;
         $app->price = 123;
         $app->start = date('Y-m-d H:i:s', $this->local_time + 600);
         $app->end = date('Y-m-d H:i:s', $this->local_time + 2400);
         $app->service = $appointments->get_first_service_id();
         $app->email = $appointments->get_admin_email();
         $app->note = __('This is a test appointment inserted by Appointments+', 'appointments');
     } else {
         $app = $appointments->get_app($app_id);
     }
     // Create Event object and set parameters
     $this->set_event_parameters($app, $app->worker);
     // Insert event
     try {
         $createdEvent = $this->service->events->insert($this->get_selected_calendar($worker_id), $this->event);
         if ($createdEvent && !is_object($createdEvent) && class_exists('App_Google_Service_Calendar_CalendarListEntry')) {
             $createdEvent = new App_Google_Service_Calendar_CalendarListEntry($createdEvent);
         }
         // Write Event ID to database
         $gcal_ID = $createdEvent->getId();
         if ($gcal_ID && !$test) {
             $args = array('gcal_updated' => date("Y-m-d H:i:s", $this->local_time), 'gcal_ID' => $gcal_ID);
             appointments_update_appointment($app_id, $args);
         } else {
             $appointments->log("The insert did not create a real result we can work with");
         }
         // Test result successful
         if ($gcal_ID) {
             return true;
         }
     } catch (Exception $e) {
         $appointments->log("Insert went wrong: " . $e->getMessage());
         return false;
     }
 }
 function inline_edit_save()
 {
     global $appointments, $wpdb, $current_user;
     $app_id = absint($_POST["app_id"]);
     $app = appointments_get_appointment($app_id);
     $data = array();
     $data['user'] = $_POST['user'];
     $data['email'] = !empty($_POST['email']) && is_email($_POST['email']) ? $_POST['email'] : '';
     $data['name'] = $_POST['name'];
     $data['phone'] = $_POST['phone'];
     $data['address'] = $_POST['address'];
     $data['city'] = $_POST['city'];
     $data['service'] = $_POST['service'];
     $data['worker'] = $_POST['worker'];
     $data['price'] = $_POST['price'];
     $data['note'] = $_POST['note'];
     $data['status'] = $_POST['status'];
     $data['date'] = $_POST['date'];
     $data['time'] = $_POST['time'];
     $resend = $_POST["resend"];
     $data = apply_filters('app-appointment-inline_edit-save_data', $data);
     $update_result = $insert_result = false;
     if ($app) {
         // Update
         $update_result = appointments_update_appointment($app_id, $data);
         if ($update_result) {
             if (('pending' == $data['status'] || 'removed' == $data['status'] || 'completed' == $data['status']) && is_object($appointments->gcal_api)) {
                 $appointments->gcal_api->delete($app_id);
             } else {
                 if (is_object($appointments->gcal_api) && $appointments->gcal_api->is_syncable_status($data['status'])) {
                     $appointments->gcal_api->update($app_id);
                     // This also checks for event insert
                 }
             }
         }
         if ($resend && 'removed' != $data['status']) {
             appointments_send_confirmation($app_id);
         }
     } else {
         // Insert
         $app_id = appointments_insert_appointment($data);
         if ($app_id) {
             $insert_result = true;
             if ($resend) {
                 appointments_send_confirmation($app_id);
             }
             $appointments->sms_new_appointment($app_id);
         }
     }
     do_action('app-appointment-inline_edit-after_save', $app_id, $data);
     do_action('app-appointment-inline_edit-before_response', $app_id, $data);
     $app = appointments_get_appointment($app_id);
     if (!$app) {
         $insert_result = false;
         $update_result = false;
     }
     // Move mail sending here so the fields can expand
     if ($insert_result && is_object($appointments->gcal_api) && $appointments->gcal_api->is_syncable_status($data['status'])) {
         $appointments->gcal_api->insert($app->ID);
     }
     $result = array('app_id' => 0, 'message' => '');
     if ($update_result) {
         // Log change of status
         if ($data['status'] != $app->status) {
             $appointments->log(sprintf(__('Status changed from %s to %s by %s for appointment ID:%d', 'appointments'), $app->status, $data["status"], $current_user->user_login, $app->ID));
         }
         $result = array('app_id' => $app->ID, 'message' => __('<span style="color:green;font-weight:bold">Changes saved.</span>', 'appointments'));
     } else {
         if ($insert_result) {
             $result = array('app_id' => $app->ID, 'message' => __('<span style="color:green;font-weight:bold">Changes saved.</span>', 'appointments'));
         } else {
             $message = $resend && !empty($data['status']) && 'removed' != $data['status'] ? sprintf('<span style="color:green;font-weight:bold">%s</span>', __('Confirmation message (re)sent', 'appointments')) : sprintf('<span style="color:red;font-weight:bold">%s</span>', __('Record could not be saved OR you did not make any changes!', 'appointments'));
             $result = array('app_id' => $app_id, 'message' => $message);
         }
     }
     $result = apply_filters('app-appointment-inline_edit-result', $result, $app_id, $data);
     die(json_encode($result));
 }
 function test_update_appointment()
 {
     $worker_id = $this->factory->user->create_object($this->factory->user->generate_args());
     $worker_id_2 = $this->factory->user->create_object($this->factory->user->generate_args());
     $user_id = $this->factory->user->create_object($this->factory->user->generate_args());
     $user_id_2 = $this->factory->user->create_object($this->factory->user->generate_args());
     $service_args = array('name' => 'My Service', 'duration' => 90);
     $service_id = appointments_insert_service($service_args);
     $service = appointments_get_service($service_id);
     $service_args = array('name' => 'My Service 2', 'duration' => 90);
     $service_id_2 = appointments_insert_service($service_args);
     $worker_args = array('ID' => $worker_id, 'services_provided' => array($service_id));
     appointments_insert_worker($worker_args);
     $worker_args = array('ID' => $worker_id_2, 'services_provided' => array($service_id));
     appointments_insert_worker($worker_args);
     $args = array('user' => $user_id, 'email' => '*****@*****.**', 'name' => 'Tester', 'phone' => '667788', 'address' => 'An address', 'city' => 'Madrid', 'service' => $service_id, 'worker' => $worker_id, 'price' => '90', 'date' => 'December 18, 2024', 'time' => '07:30', 'note' => 'It\'s a note', 'status' => 'paid', 'location' => 5, 'gcal_updated' => '2015-12-01', 'gcal_ID' => 'test');
     $app_id = appointments_insert_appointment($args);
     // Only change status
     $args = array('status' => 'confirmed');
     $result = appointments_update_appointment($app_id, $args);
     $this->assertTrue($result);
     $app = appointments_get_appointment($app_id);
     $this->assertEquals('confirmed', $app->status);
     // Change all fields except status
     $args = array('user' => $user_id_2, 'email' => '*****@*****.**', 'name' => 'Tester2', 'phone' => '6677882', 'address' => 'An address2', 'city' => 'Madrid2', 'service' => $service_id_2, 'worker' => $worker_id_2, 'price' => '120', 'date' => 'November 18, 2024', 'time' => '10:30', 'note' => 'It\'s a note2', 'location' => 6, 'gcal_updated' => '2018-12-01', 'gcal_ID' => 'test2');
     $result = appointments_update_appointment($app_id, $args);
     $this->assertTrue($result);
     $app = appointments_get_appointment($app_id);
     $this->assertEquals($app_id, $app->ID);
     $this->assertEquals($args['user'], $app->user);
     $this->assertEquals($args['name'], $app->name);
     $this->assertEquals($args['email'], $app->email);
     $this->assertEquals($args['phone'], $app->phone);
     $this->assertEquals($args['address'], $app->address);
     $this->assertEquals($args['city'], $app->city);
     $this->assertEquals($args['worker'], $app->worker);
     $this->assertEquals($args['price'], $app->price);
     $this->assertEquals($args['service'], $app->service);
     $this->assertEquals('2024-11-18 10:30:00', $app->start);
     $this->assertEquals('2024-11-18 12:00:00', $app->end);
     $this->assertEquals($args['note'], $app->note);
     $this->assertEquals('confirmed', $app->status);
     $this->assertEquals($args['location'], $app->location);
     $this->assertEquals($args['gcal_updated'] . ' 00:00:00', $app->gcal_updated);
     $this->assertEquals($args['gcal_ID'], $app->gcal_ID);
     $this->assertNotEmpty($app->created);
     // Wrong service
     $args = array('service' => 8888);
     $result = appointments_update_appointment($app_id, $args);
     $this->assertFalse($result);
     $app = appointments_get_appointment($app_id);
     $this->assertEquals($service_id_2, $app->service);
     // Wrong worker
     $args = array('worker' => 8888);
     $result = appointments_update_appointment($app_id, $args);
     $this->assertTrue($result);
     $app = appointments_get_appointment($app_id);
     $this->assertEquals(0, $app->worker);
     // Only location
     $result = appointments_update_appointment($app_id, array('location' => 20));
     $this->assertTrue($result);
     $app = appointments_get_appointment($app_id);
     $this->assertEquals(20, $app->location);
 }