Пример #1
0
 public function load($staff_id)
 {
     $data = $this->wpdb->get_results('
         SELECT c.name AS category_name, s.*
         FROM ' . AB_Category::getTableName() . ' c
         INNER JOIN ' . AB_Service::getTableName() . ' s ON c.id = s.category_id
     ', ARRAY_A);
     if (!$data) {
         $data = array();
     }
     $this->uncategorized_services = AB_Service::query('s')->where('s.category_id', null)->fetchArray();
     $staff_services = AB_StaffService::query('ss')->select('ss.service_id, ss.price, ss.capacity')->where('ss.staff_id', $staff_id)->fetchArray();
     if ($staff_services) {
         foreach ($staff_services as $staff_service) {
             $this->selected[$staff_service['service_id']] = array('price' => $staff_service['price'], 'capacity' => $staff_service['capacity']);
         }
     }
     foreach ($data as $row) {
         if (!isset($this->collection[$row['category_id']])) {
             $abCategory = new AB_Category();
             $abCategory->set('id', $row['category_id']);
             $abCategory->set('name', $row['category_name']);
             $this->collection[$row['category_id']] = $abCategory;
         }
         unset($row['category_name']);
         $abService = new AB_Service($row);
         $this->category_services[$row['category_id']][] = $abService->get('id');
         $this->collection[$row['category_id']]->addService($abService);
     }
 }
Пример #2
0
 /**
  * Get color of service
  *
  * @param string $default
  * @return string
  */
 public function getColor($default = '#DDDDDD')
 {
     if (!$this->isLoaded()) {
         return $default;
     }
     $service = new AB_Service();
     if ($service->load($this->get('service_id'))) {
         return $service->get('color');
     }
     return $default;
 }
 public function load($staff_id)
 {
     $data = $this->wpdb->get_results('
         SELECT c.name AS category_name, s.*
         FROM ab_category c
         INNER JOIN ab_service s ON c.id = s.category_id
     ', ARRAY_A);
     if (!$data) {
         $data = array();
     }
     $uncategorized_services = $this->wpdb->get_results('SELECT * FROM ab_service WHERE category_id IS NULL');
     foreach ($uncategorized_services as $uncategorized_service) {
         $abService = new AB_Service();
         $abService->setData($uncategorized_service);
         $this->uncategorized_services[] = $abService;
     }
     $rows = $this->wpdb->get_results($this->wpdb->prepare('
         SELECT s.service_id, s.price, s.capacity
         FROM ab_staff_service s
         WHERE s.staff_id = %d
     ', $staff_id));
     if ($rows) {
         foreach ($rows as $row) {
             $this->selected[$row->service_id] = array('price' => $row->price, 'capacity' => $row->capacity);
         }
     }
     foreach ($data as $row) {
         if (!isset($this->collection[$row['category_id']])) {
             $abCategory = new AB_Category();
             $abCategory->set('id', $row['category_id']);
             $abCategory->set('name', $row['category_name']);
             $this->collection[$row['category_id']] = $abCategory;
         }
         unset($row['category_name']);
         $abService = new AB_Service();
         $abService->setData($row);
         $this->category_services[$row['category_id']][] = $abService->get('id');
         $this->collection[$row['category_id']]->addService($abService);
     }
 }
Пример #4
0
 /**
  * Get array with appointments data for customer profile.
  *
  * @return array
  */
 public function getAppointmentsForProfile()
 {
     $records = array();
     if ($this->get('id')) {
         $result = $this->wpdb->get_results($this->wpdb->prepare('SELECT `c`.`name`               `category`,
                     `sv`.`title`             `service`,
                     `s`.`full_name`          `staff`,
                     `a`.`start_date`         `start_date`,
                     `ss`.`price`             `price`,
                     `ca`.`number_of_persons` `number_of_persons`,
                     `ca`.`coupon_discount`   `coupon_discount`,
                     `ca`.`coupon_deduction`  `coupon_deduction`,
                     `ca`.`time_zone_offset`  `time_zone_offset`,
                     `ca`.`token`             `token`
              FROM `' . AB_Appointment::getTableName() . '` `a`
              LEFT JOIN `' . AB_Staff::getTableName() . '` `s` ON `s`.`id` = `a`.`staff_id`
              LEFT JOIN `' . AB_Service::getTableName() . '` `sv` ON `sv`.`id` = `a`.`service_id`
              LEFT JOIN `' . AB_Category::getTableName() . '` `c` ON `c`.`id` = `sv`.`category_id`
              LEFT JOIN `' . AB_StaffService::getTableName() . '` `ss` ON `ss`.`staff_id` = `a`.`staff_id` AND `ss`.`service_id` = `a`.`service_id`
              INNER JOIN `' . AB_CustomerAppointment::getTableName() . '` `ca` ON `ca`.`appointment_id` = `a`.`id` AND `ca`.`customer_id` = %d', $this->get('id')), ARRAY_A);
         if ($result) {
             foreach ($result as $row) {
                 if ($row['time_zone_offset'] !== null) {
                     $row['start_date'] = AB_DateTimeUtils::applyTimeZoneOffset($row['start_date'], $row['time_zone_offset']);
                 }
                 if ($row['coupon_discount'] or $row['coupon_deduction']) {
                     $coupon = new AB_Coupon();
                     $coupon->set('discount', $row['coupon_discount']);
                     $coupon->set('deduction', $row['coupon_deduction']);
                     $row['price'] = $coupon->apply($row['price']);
                 }
                 $row['price'] *= $row['number_of_persons'];
                 unset($row['time_zone_offset'], $row['coupon_discount'], $row['coupon_deduction'], $row['number_of_persons']);
                 $records[] = $row;
             }
         }
     }
     return $records;
 }
Пример #5
0
                echo AB_Service::durationToString($service['duration']);
                ?>
                                </option>
                            <?php 
            }
            ?>

                            <option value="<?php 
            echo $j * 60;
            ?>
" <?php 
            selected($service['duration'], $j * 60);
            ?>
>
                                <?php 
            echo AB_Service::durationToString($j * 60);
            ?>
                            </option>
                        <?php 
        }
        ?>
                        <option value="86400" <?php 
        selected($service['duration'], 86400);
        ?>
>
                            <?php 
        _e('All day', 'bookly');
        ?>
                        </option>
                    </select>
                </td>
Пример #6
0
 /**
  * @param AB_Appointment $appointment
  */
 private function handleEventData(AB_Appointment $appointment)
 {
     $start_datetime = new Google_Service_Calendar_EventDateTime();
     $start_datetime->setDateTime(DateTime::createFromFormat('Y-m-d H:i:s', $appointment->get('start_date'), new DateTimeZone(AB_Utils::getTimezoneString()))->format(DateTime::RFC3339));
     $end_datetime = new Google_Service_Calendar_EventDateTime();
     $end_datetime->setDateTime(DateTime::createFromFormat('Y-m-d H:i:s', $appointment->get('end_date'), new DateTimeZone(AB_Utils::getTimezoneString()))->format(DateTime::RFC3339));
     $service = new AB_Service();
     $service->load($appointment->get('service_id'));
     $description = __('Service', 'bookly') . ": " . $service->get('title') . PHP_EOL;
     $client_names = array();
     foreach ($appointment->getCustomerAppointments() as $ca) {
         $description .= sprintf("%s: %s\n%s: %s\n%s: %s\n", __('Name', 'bookly'), $ca->customer->get('name'), __('Email', 'bookly'), $ca->customer->get('email'), __('Phone', 'bookly'), $ca->customer->get('phone'));
         $description .= $ca->getFormattedCustomFields('text');
         $description .= PHP_EOL;
         $client_names[] = $ca->customer->get('name');
     }
     $staff = new AB_Staff();
     $staff->load($appointment->get('staff_id'));
     $title = strtr(get_option('ab_settings_google_event_title', '[[SERVICE_NAME]]'), array('[[SERVICE_NAME]]' => $service->get('title'), '[[CLIENT_NAMES]]' => implode(', ', $client_names), '[[STAFF_NAME]]' => $staff->get('full_name')));
     $this->event->setStart($start_datetime);
     $this->event->setEnd($end_datetime);
     $this->event->setSummary($title);
     $this->event->setDescription($description);
     $extended_property = new Google_Service_Calendar_EventExtendedProperties();
     $extended_property->setPrivate(array('customers' => json_encode(array_map(function ($ca) {
         return $ca->customer->get('id');
     }, $appointment->getCustomerAppointments())), 'service_id' => $service->get('id'), 'appointment_id' => $appointment->get('id')));
     $this->event->setExtendedProperties($extended_property);
 }
 /**
  * @return AB_Appointment
  */
 public function save()
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     // #11094: if customer with such name & e-mail exists, append new booking to him, otherwise - create new customer
     $customer_exists = $wpdb->get_row($wpdb->prepare('SELECT * FROM ab_customer WHERE name = %s AND email = %s', $this->name, $this->email));
     $customer = new AB_Customer();
     if ($customer_exists) {
         $customer->set('id', $customer_exists->id);
         $customer->set('name', $customer_exists->name);
         $customer->set('email', $customer_exists->email);
         $customer->set('phone', $customer_exists->phone);
     } else {
         $customer->set('name', $this->name);
         $customer->set('email', $this->email);
         $customer->set('phone', $this->phone);
         $customer->save();
     }
     $this->customer_id = $customer->get('id');
     $service = new AB_Service();
     $service->load($this->service_id);
     $category = new AB_Category();
     $category->load($service->get('category_id'));
     /**
      * Get appointment, with same params.
      * If it is -> create connection to this appointment,
      * otherwise create appointment and connect customer to new appointment
      */
     $booking = $wpdb->get_row($wpdb->prepare("SELECT * from ab_appointment a WHERE a.staff_id = %d and a.service_id = %d and a.start_date = %s LIMIT 1;", $this->getStaffId(), $this->service_id, $this->booked_datetime));
     $appointment = new AB_Appointment();
     if ($booking) {
         $appointment->load($booking->id);
     } else {
         $appointment->set('staff_id', $this->getStaffId());
         $appointment->set('service_id', $this->service_id);
         $appointment->set('start_date', date('Y-m-d H:i:s', strtotime($this->booked_datetime)));
         $endDate = new DateTime($this->booked_datetime);
         $di = "+ {$service->get('duration')} sec";
         $endDate->modify($di);
         $appointment->set('end_date', $endDate->format('Y-m-d H:i:s'));
         $appointment->save();
     }
     $customer_appointment = new AB_Customer_Appointment();
     $customer_appointment->set('appointment_id', $appointment->get('id'));
     $customer_appointment->set('customer_id', $customer->get('id'));
     $customer_appointment->set('token', md5($this->form_id));
     $customer_appointment->set('notes', $this->notes);
     $customer_appointment->save();
     $staff = new AB_Staff();
     $staff->load($this->getStaffId());
     return $appointment;
 }
Пример #8
0
 /**
  * @param AB_Notification $notification
  */
 public function processNotification(AB_Notification $notification)
 {
     /** @var $wpdb wpdb */
     global $wpdb;
     $date = new DateTime();
     switch ($notification->get('type')) {
         case 'staff_agenda':
             if ($date->format('H') >= 18) {
                 $rows = $wpdb->get_results('SELECT
                         `a`.*,
                         `c`.`name`       AS `customer_name`,
                         `s`.`title`      AS `service_title`,
                         `st`.`email`     AS `staff_email`,
                         `st`.`phone`     AS `staff_phone`,
                         `st`.`full_name` AS `staff_name`
                     FROM `' . AB_CustomerAppointment::getTableName() . '` `ca`
                     LEFT JOIN `' . AB_Appointment::getTableName() . '` `a`   ON `a`.`id` = `ca`.`appointment_id`
                     LEFT JOIN `' . AB_Customer::getTableName() . '` `c`      ON `c`.`id` = `ca`.`customer_id`
                     LEFT JOIN `' . AB_Service::getTableName() . '` `s`       ON `s`.`id` = `a`.`service_id`
                     LEFT JOIN `' . AB_Staff::getTableName() . '` `st`        ON `st`.`id` = `a`.`staff_id`
                     LEFT JOIN `' . AB_StaffService::getTableName() . '` `ss` ON `ss`.`staff_id` = `a`.`staff_id` AND `ss`.`service_id` = `a`.`service_id`
                     WHERE DATE(DATE_ADD("' . $this->mysql_now . '", INTERVAL 1 DAY)) = DATE(`a`.`start_date`) AND NOT EXISTS (
                         SELECT * FROM `' . AB_SentNotification::getTableName() . '` `sn` WHERE
                             DATE(`sn`.`created`) = DATE("' . $this->mysql_now . '") AND
                             `sn`.`gateway`       = "' . $notification->get('gateway') . '" AND
                             `sn`.`type`          = "staff_agenda" AND
                             `sn`.`staff_id`      = `a`.`staff_id`
                     )');
                 if ($rows) {
                     $appointments = array();
                     foreach ($rows as $row) {
                         $appointments[$row->staff_id][] = $row;
                     }
                     foreach ($appointments as $staff_id => $collection) {
                         $sent = false;
                         $staff_email = null;
                         $staff_phone = null;
                         $table = $notification->get('gateway') == 'email' ? '<table>%s</table>' : '%s';
                         $tr = $notification->get('gateway') == 'email' ? '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' : "%s %s %s\n";
                         $agenda = '';
                         foreach ($collection as $appointment) {
                             $startDate = new DateTime($appointment->start_date);
                             $endDate = new DateTime($appointment->end_date);
                             $agenda .= sprintf($tr, $startDate->format('H:i') . '-' . $endDate->format('H:i'), $appointment->service_title, $appointment->customer_name);
                             $staff_email = $appointment->staff_email;
                             $staff_phone = $appointment->staff_phone;
                         }
                         $agenda = sprintf($table, $agenda);
                         if ($staff_email || $staff_phone) {
                             $replacement = new AB_NotificationCodes();
                             $replacement->set('next_day_agenda', $agenda);
                             $replacement->set('appointment_datetime', $appointment->start_date);
                             $replacement->set('staff_name', $appointment->staff_name);
                             if ($notification->get('gateway') == 'email' && $staff_email) {
                                 $message = $replacement->replace($notification->get('message'));
                                 $subject = $replacement->replace($notification->get('subject'));
                                 // Send email.
                                 $sent = wp_mail($staff_email, $subject, wpautop($message), AB_Utils::getEmailHeaders());
                             } else {
                                 if ($notification->get('gateway') == 'sms' && $staff_phone) {
                                     $message = $replacement->replace($notification->get('message'), $notification->get('gateway'));
                                     // Send sms.
                                     $sent = $this->sms->sendSms($staff_phone, $message);
                                 }
                             }
                         }
                         if ($sent) {
                             $sent_notification = new AB_SentNotification();
                             $sent_notification->set('staff_id', $staff_id);
                             $sent_notification->set('gateway', $notification->get('gateway'));
                             $sent_notification->set('type', 'staff_agenda');
                             $sent_notification->set('created', $date->format('Y-m-d H:i:s'));
                             $sent_notification->save();
                         }
                     }
                 }
             }
             break;
         case 'client_follow_up':
             if ($date->format('H') >= 21) {
                 $rows = $wpdb->get_results('SELECT
                         `a`.*,
                         `ca`.*
                     FROM `' . AB_CustomerAppointment::getTableName() . '` `ca`
                     LEFT JOIN `' . AB_Appointment::getTableName() . '` `a` ON `a`.`id` = `ca`.`appointment_id`
                     WHERE DATE("' . $this->mysql_now . '") = DATE(`a`.`start_date`) AND NOT EXISTS (
                         SELECT * FROM `' . AB_SentNotification::getTableName() . '` `sn` WHERE
                             DATE(`sn`.`created`)           = DATE("' . $this->mysql_now . '") AND
                             `sn`.`gateway`                 = "' . $notification->get('gateway') . '" AND
                             `sn`.`type`                    = "client_follow_up" AND
                             `sn`.`customer_appointment_id` = `ca`.`id`
                     )', ARRAY_A);
                 if ($rows) {
                     foreach ($rows as $row) {
                         $customer_appointment = new AB_CustomerAppointment();
                         $customer_appointment->load($row['id']);
                         if (AB_NotificationSender::sendFromCron(AB_NotificationSender::CRON_FOLLOW_UP_EMAIL, $notification, $customer_appointment)) {
                             $sent_notification = new AB_SentNotification();
                             $sent_notification->set('customer_appointment_id', $customer_appointment->get('id'));
                             $sent_notification->set('gateway', $notification->get('gateway'));
                             $sent_notification->set('type', 'client_follow_up');
                             $sent_notification->set('created', $date->format('Y-m-d H:i:s'));
                             $sent_notification->save();
                         }
                     }
                 }
             }
             break;
         case 'client_reminder':
             if ($date->format('H') >= 18) {
                 $rows = $wpdb->get_results('SELECT
                         `ca`.`id`
                     FROM `' . AB_CustomerAppointment::getTableName() . '` `ca`
                     LEFT JOIN `' . AB_Appointment::getTableName() . '` `a` ON `a`.`id` = `ca`.`appointment_id`
                     WHERE DATE(DATE_ADD("' . $this->mysql_now . '", INTERVAL 1 DAY)) = DATE(`a`.`start_date`) AND NOT EXISTS (
                         SELECT * FROM `' . AB_SentNotification::getTableName() . '` `sn` WHERE
                             DATE(`sn`.`created`)           = DATE("' . $this->mysql_now . '") AND
                             `sn`.`gateway`                 = "' . $notification->get('gateway') . '" AND
                             `sn`.`type`                    = "client_reminder" AND
                             `sn`.`customer_appointment_id` = `ca`.`id`
                     )', ARRAY_A);
                 if ($rows) {
                     foreach ($rows as $row) {
                         $customer_appointment = new AB_CustomerAppointment();
                         $customer_appointment->load($row['id']);
                         if (AB_NotificationSender::sendFromCron(AB_NotificationSender::CRON_NEXT_DAY_APPOINTMENT, $notification, $customer_appointment)) {
                             $sent_notification = new AB_SentNotification();
                             $sent_notification->set('customer_appointment_id', $customer_appointment->get('id'));
                             $sent_notification->set('gateway', $notification->get('gateway'));
                             $sent_notification->set('type', 'client_reminder');
                             $sent_notification->set('created', $date->format('Y-m-d H:i:s'));
                             $sent_notification->save();
                         }
                     }
                 }
             }
             break;
     }
 }
Пример #9
0
 /**
  * @param int $id
  * @return mixed
  */
 private function getServiceCollection($id = 0)
 {
     $services = AB_Service::query('s')->select('s.*, COUNT(staff.id) AS total_staff, GROUP_CONCAT(DISTINCT staff.id) AS staff_ids')->leftJoin('AB_StaffService', 'ss', 'ss.service_id = s.id')->leftJoin('AB_Staff', 'staff', 'staff.id = ss.staff_id')->whereRaw('s.category_id = %d OR !%d', array($id, $id))->groupBy('s.id')->sortBy('ISNULL(s.position), s.position');
     return $services->fetchArray();
 }
Пример #10
0
?>
><?php 
_e('Disabled', 'bookly');
?>
</option>
                    <?php 
foreach (array_merge(range(1, 12), array(24, 48)) as $hour) {
    ?>
                        <option value="<?php 
    echo $hour;
    ?>
" <?php 
    selected(get_option('ab_settings_minimum_time_prior_booking'), $hour);
    ?>
><?php 
    echo AB_Service::durationToString($hour * 3600);
    ?>
</option>
                    <?php 
}
?>
                </select>
            </td>
            <td class="ab-valign-top">
                <?php 
AB_Utils::popover(__('Set a minimum amount of time before the chosen appointment (for example, require the customer to book at least 1 hour before the appointment time).', 'bookly'));
?>
            </td>
        </tr>
        <tr>
            <td>
Пример #11
0
 /**
  * Prepare data for email.
  *
  * @param AB_CustomerAppointment $ca
  * @return array
  */
 private static function _prepareData(AB_CustomerAppointment $ca)
 {
     $appointment = new AB_Appointment();
     $appointment->load($ca->get('appointment_id'));
     $customer = new AB_Customer();
     $customer->load($ca->get('customer_id'));
     $staff = new AB_Staff();
     $staff->load($appointment->get('staff_id'));
     $service = new AB_Service();
     $service->load($appointment->get('service_id'));
     $staff_service = new AB_StaffService();
     $staff_service->loadBy(array('staff_id' => $staff->get('id'), 'service_id' => $service->get('id')));
     $price = $staff_service->get('price');
     if ($ca->get('coupon_discount') or $ca->get('coupon_deduction')) {
         $coupon = new AB_Coupon();
         $coupon->set('discount', $ca->get('coupon_discount'));
         $coupon->set('deduction', $ca->get('coupon_deduction'));
         $price = $coupon->apply($price);
     }
     $codes = new AB_NotificationCodes();
     $codes->set('appointment_datetime', $appointment->get('start_date'));
     $codes->set('appointment_token', $ca->get('token'));
     $codes->set('category_name', $service->getCategoryName());
     $codes->set('client_name', $customer->get('name'));
     $codes->set('client_phone', $customer->get('phone'));
     $codes->set('client_email', $customer->get('email'));
     $codes->set('custom_fields', $ca->getFormattedCustomFields('text'));
     $codes->set('custom_fields_2c', $ca->getFormattedCustomFields('html'));
     $codes->set('number_of_persons', $ca->get('number_of_persons'));
     $codes->set('service_name', $service->getTitle());
     $codes->set('service_price', $price);
     $codes->set('staff_name', $staff->get('full_name'));
     $codes->set('staff_email', $staff->get('email'));
     $codes->set('staff_phone', $staff->get('phone'));
     $codes->set('staff_photo', $staff->get('avatar_url'));
     return array($codes, $staff, $appointment, $customer);
 }
 public function executeRenderPayment()
 {
     $form_id = $this->getParameter('form_id');
     $response = null;
     if ($form_id) {
         $payment_disabled = AB_BookingConfiguration::isPaymentDisabled();
         $this->userData = new AB_UserBookingData($form_id);
         $this->userData->load();
         if ($this->userData->hasData()) {
             if ($this->userData->getServicePrice() <= 0) {
                 $payment_disabled = true;
             }
         }
         if ($payment_disabled == false) {
             $this->form_id = $form_id;
             $this->info_text = nl2br(esc_html(get_option('ab_appearance_text_info_fourth_step')));
             $this->info_text_coupon = $this->_prepareInfoText(4, $this->userData);
             if ($this->userData->hasData()) {
                 $employee = new AB_Staff();
                 $employee->load($this->userData->getStaffId());
                 $service = new AB_Service();
                 $service->load($this->userData->getServiceId());
                 $price = $this->getWpdb()->get_var($this->getWpdb()->prepare('
                     SELECT price FROM ab_staff_service WHERE staff_id = %d AND service_id = %d', $employee->get('id'), $service->get('id')));
                 $this->_prepareProgressTracker(4, $price);
                 // Set response.
                 $response = array('status' => 'success', 'html' => $this->render('payment', array(), false));
             } else {
                 if (isset($_SESSION['tmp_booking_data'])) {
                     $tmp_booking_data = AB_CommonUtils::getTemporaryBookingData();
                     if (!empty($tmp_booking_data)) {
                         $tmp_form_id = $tmp_booking_data['form_id'];
                         if (isset($_SESSION['appointment_booking'][$tmp_form_id]) && $_SESSION['appointment_booking'][$tmp_form_id]['cancelled'] === true) {
                             $employee = new AB_Staff();
                             $employee->load($tmp_booking_data['staff_id'][0]);
                             $service = new AB_Service();
                             $service->load($tmp_booking_data['service_id']);
                             $price = $this->getWpdb()->get_var($this->getWpdb()->prepare('
                             SELECT price FROM ab_staff_service WHERE staff_id = %d AND service_id = %d', $employee->get('id'), $service->get('id')));
                             // create a paypal object
                             $paypal = new PayPal();
                             $product = new stdClass();
                             $product->name = $service->get('title');
                             $product->desc = $service->getTitleWithDuration();
                             $product->price = $price;
                             $product->qty = 1;
                             $paypal->addProduct($product);
                             // get the products information from the $_POST and create the Product objects
                             $this->paypal = $paypal;
                             $this->_prepareProgressTracker(4, $price);
                             $error_msg = isset($_SESSION['appointment_booking'][$tmp_form_id]['paypal_error']) ? $_SESSION['appointment_booking'][$tmp_form_id]['paypal_error'] : "";
                             unset($_SESSION['appointment_booking'][$tmp_form_id]['paypal_error']);
                             // Set response.
                             $response = array('status' => 'success', 'html' => $this->render('payment', array('form_id' => $tmp_form_id, 'error_msg' => $error_msg), false));
                         }
                     }
                 }
             }
         }
     }
     // Output JSON response.
     if ($response === null) {
         $response = array('status' => 'no-data');
     }
     header('Content-Type: application/json');
     echo json_encode($response);
     exit(0);
 }
 public function executeAssignStaff()
 {
     $service_id = $this->getParameter('service_id', 0);
     $staff_ids = $this->getParameter('staff_ids', array());
     if ($service_id) {
         $this->getWpdb()->delete('ab_staff_service', array('service_id' => $service_id), array('%d'));
         $service = new AB_Service();
         if (!empty($staff_ids) && $service->load($service_id)) {
             foreach ($staff_ids as $staff_id) {
                 $staff_service = new AB_StaffService();
                 $staff_service->set('staff_id', $staff_id);
                 $staff_service->set('service_id', $service_id);
                 $staff_service->set('price', $service->get('price'));
                 $staff_service->save();
             }
         }
         echo count($staff_ids);
         exit;
     }
 }
Пример #14
0
 /**
  * Constructor.
  */
 public function __construct()
 {
     global $wpdb;
     // Select all services (with categories and staff members)
     // which have at least one staff member assigned.
     $rows = $wpdb->get_results($wpdb->prepare('
         SELECT
             IFNULL(`c`.`id`,0)    AS `category_id`,
             IFNULL(`c`.`name`,%s) AS `category_name`,
             `c`.`position`        AS `category_position`,
             `s`.`id`              AS `service_id`,
             `s`.`position`        AS `service_position`,
             `s`.`title`           AS `service_name`,
             `st`.`id`             AS `staff_id`,
             `st`.`position`       AS `staff_position`,
             `st`.`full_name`      AS `staff_name`,
             `ss`.`capacity`       AS `capacity`,
             `ss`.`price`          AS `price`
         FROM `' . AB_Service::getTableName() . '` `s`
             INNER JOIN `' . AB_StaffService::getTableName() . '` `ss` ON `s`.`id` = `ss`.`service_id`
             LEFT JOIN `' . AB_Category::getTableName() . '` `c`        ON `s`.`category_id` = `c`.`id`
             LEFT JOIN `' . AB_Staff::getTableName() . '` `st`          ON `ss`.`staff_id` = `st`.`id`
         ORDER BY `service_name`
     ', __('Uncategorized', 'bookly')), ARRAY_A);
     foreach ($rows as $row) {
         if (!isset($this->services[$row['service_id']])) {
             $this->services[$row['service_id']] = array('id' => $row['service_id'], 'name' => AB_Utils::getTranslatedString('service_' . $row['service_id'], $row['service_name']), 'category_id' => $row['category_id'], 'staff' => array(), 'max_capacity' => $row['capacity'], 'position' => $row['service_position']);
         } else {
             if ($this->services[$row['service_id']]['max_capacity'] < $row['capacity']) {
                 // Detect the max capacity for each service
                 //(it is the max capacity from all staff members who provides this service).
                 $this->services[$row['service_id']]['max_capacity'] = $row['capacity'];
             }
         }
         if (!isset($this->staff[$row['staff_id']])) {
             $this->staff[$row['staff_id']] = array('id' => $row['staff_id'], 'name' => AB_Utils::getTranslatedString('staff_' . $row['staff_id'], $row['staff_name']), 'services' => array(), 'position' => $row['staff_position']);
         }
         if ($row['category_id'] != '' && !isset($this->categories[$row['category_id']])) {
             $this->categories[$row['category_id']] = array('id' => $row['category_id'], 'name' => AB_Utils::getTranslatedString('category_' . $row['category_id'], $row['category_name']), 'services' => array(), 'position' => $row['category_position']);
         }
         if (!isset($this->services[$row['service_id']]['staff'][$row['staff_id']])) {
             $staff_member = $this->staff[$row['staff_id']];
             unset($staff_member['services']);
             if (self::isPaymentDisabled() == false) {
                 $staff_member['name'] .= ' (' . AB_Utils::formatPrice($row['price']) . ')';
             }
             $this->services[$row['service_id']]['staff'][$row['staff_id']] = $staff_member;
         }
         if (!isset($this->staff[$row['staff_id']]['services'][$row['service_id']])) {
             $service = $this->services[$row['service_id']];
             unset($service['staff']);
             $service['max_capacity'] = $row['capacity'];
             $this->staff[$row['staff_id']]['services'][$row['service_id']] = $service;
         }
         if (!isset($this->categories[intval($row['category_id'])]['staff'][$row['staff_id']])) {
             $staff_member = $this->staff[$row['staff_id']];
             unset($staff_member['services']);
             $this->categories[intval($row['category_id'])]['staff'][$row['staff_id']] = $staff_member;
         }
         if (!isset($this->categories[intval($row['category_id'])]['services'][$row['service_id']])) {
             $service = $this->services[$row['service_id']];
             unset($service['staff']);
             $this->categories[intval($row['category_id'])]['services'][$row['service_id']] = $service;
         }
     }
 }
Пример #15
0
 function update_7_0()
 {
     global $wpdb;
     $wpdb->query('ALTER TABLE `ab_customer_appointment` ADD `coupon_deduction` DECIMAL(10,2) DEFAULT NULL AFTER `coupon_discount`');
     $wpdb->query('ALTER TABLE `ab_coupons` CHANGE COLUMN `used` `used` INT UNSIGNED NOT NULL DEFAULT 0,
                    ADD COLUMN `deduction` DECIMAL(10,2) NOT NULL DEFAULT 0 AFTER `discount`,
                    ADD COLUMN `usage_limit` INT UNSIGNED NOT NULL DEFAULT 1');
     $wpdb->query('ALTER TABLE `ab_notifications` CHANGE `slug` `type` VARCHAR(255) NOT NULL DEFAULT ""');
     // SMS.
     $wpdb->query('ALTER TABLE `ab_notifications` ADD `gateway` ENUM("email","sms") NOT NULL DEFAULT "email"');
     $wpdb->query('UPDATE `ab_notifications` SET `gateway` = "email"');
     $sms_notifies = array(array('type' => 'client_new_appointment', 'message' => __("Dear [[CLIENT_NAME]].\nThis is confirmation that you have booked [[SERVICE_NAME]].\nWe are waiting you at [[COMPANY_ADDRESS]] on [[APPOINTMENT_DATE]] at [[APPOINTMENT_TIME]].\nThank you for choosing our company.\n[[COMPANY_NAME]]\n[[COMPANY_PHONE]]\n[[COMPANY_WEBSITE]]", 'bookly'), 'active' => 1), array('type' => 'staff_new_appointment', 'message' => __("Hello.\nYou have new booking.\nService: [[SERVICE_NAME]]\nDate: [[APPOINTMENT_DATE]]\nTime: [[APPOINTMENT_TIME]]\nClient name: [[CLIENT_NAME]]\nClient phone: [[CLIENT_PHONE]]\nClient email: [[CLIENT_EMAIL]]", 'bookly'), 'active' => 0), array('type' => 'client_reminder', 'message' => __("Dear [[CLIENT_NAME]].\nWe would like to remind you that you have booked [[SERVICE_NAME]] tomorrow on [[APPOINTMENT_TIME]]. We are waiting you at [[COMPANY_ADDRESS]].\nThank you for choosing our company.\n[[COMPANY_NAME]]\n[[COMPANY_PHONE]]\n[[COMPANY_WEBSITE]]", 'bookly'), 'active' => 0), array('type' => 'client_follow_up', 'message' => __("Dear [[CLIENT_NAME]].\nThank you for choosing [[COMPANY_NAME]]. We hope you were satisfied with your [[SERVICE_NAME]].\nThank you and we look forward to seeing you again soon.\n[[COMPANY_NAME]]\n[[COMPANY_PHONE]]\n[[COMPANY_WEBSITE]]", 'bookly'), 'active' => 0), array('type' => 'staff_agenda', 'message' => __("Hello.\nYour agenda for tomorrow is:\n[[NEXT_DAY_AGENDA]]", 'bookly'), 'active' => 0), array('type' => 'staff_cancelled_appointment', 'message' => __("Hello.\nThe following booking has been cancelled.\nService: [[SERVICE_NAME]]\nDate: [[APPOINTMENT_DATE]]\nTime: [[APPOINTMENT_TIME]]\nClient name: [[CLIENT_NAME]]\nClient phone: [[CLIENT_PHONE]]\nClient email: [[CLIENT_EMAIL]]", 'bookly'), 'active' => 0), array('type' => 'client_new_wp_user', 'message' => __("Hello.\nAn account was created for you at [[SITE_ADDRESS]]\nYour user details:\nuser: [[NEW_USERNAME]]\npassword: [[NEW_PASSWORD]]\n\nThanks.", 'bookly'), 'active' => 1));
     // Insert notifications.
     foreach ($sms_notifies as $data) {
         $wpdb->insert('ab_notifications', array('gateway' => 'sms', 'type' => $data['type'], 'subject' => '', 'message' => $data['message'], 'active' => $data['active']));
     }
     // Rename notifications.
     $notifications = array('client_info' => 'client_new_appointment', 'provider_info' => 'staff_new_appointment', 'evening_next_day' => 'client_reminder', 'evening_after' => 'client_follow_up', 'event_next_day' => 'staff_agenda', 'cancel_appointment' => 'staff_cancelled_appointment', 'new_wp_user' => 'client_new_wp_user');
     foreach ($notifications as $from => $to) {
         $wpdb->query("UPDATE `ab_notifications` SET `type` = '{$to}' WHERE `type` = '{$from}'");
     }
     $this->drop('ab_email_notification');
     // Rename tables.
     $ab_tables = array('ab_appointment' => AB_Appointment::getTableName(), 'ab_category' => AB_Category::getTableName(), 'ab_coupons' => AB_Coupon::getTableName(), 'ab_customer' => AB_Customer::getTableName(), 'ab_customer_appointment' => AB_CustomerAppointment::getTableName(), 'ab_holiday' => AB_Holiday::getTableName(), 'ab_notifications' => AB_Notification::getTableName(), 'ab_payment' => AB_Payment::getTableName(), 'ab_schedule_item_break' => AB_ScheduleItemBreak::getTableName(), 'ab_service' => AB_Service::getTableName(), 'ab_staff' => AB_Staff::getTableName(), 'ab_staff_schedule_item' => AB_StaffScheduleItem::getTableName(), 'ab_staff_service' => AB_StaffService::getTableName());
     foreach ($ab_tables as $from => $to) {
         $wpdb->query("ALTER TABLE `{$from}` RENAME TO `{$to}`");
     }
     $wpdb->query("CREATE TABLE IF NOT EXISTS  `" . AB_SentNotification::getTableName() . "` (\n                `id`                      INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,\n                `customer_appointment_id` INT UNSIGNED,\n                `staff_id`                INT UNSIGNED,\n                `gateway`                 ENUM('email','sms') NOT NULL DEFAULT 'email',\n                `type`                    VARCHAR(60) NOT NULL,\n                `created`                 DATETIME NOT NULL,\n                CONSTRAINT fk_" . AB_SentNotification::getTableName() . "_" . AB_CustomerAppointment::getTableName() . "_id\n                    FOREIGN KEY (customer_appointment_id)\n                    REFERENCES  " . AB_CustomerAppointment::getTableName() . "(id)\n                    ON DELETE   CASCADE\n                    ON UPDATE   CASCADE,\n                CONSTRAINT fk_" . AB_SentNotification::getTableName() . "_" . AB_Staff::getTableName() . "_id\n                    FOREIGN KEY (staff_id)\n                    REFERENCES  " . AB_Staff::getTableName() . "(id)\n                    ON DELETE   CASCADE\n                    ON UPDATE   CASCADE\n              ) ENGINE = INNODB\n              DEFAULT CHARACTER SET = utf8\n              COLLATE = utf8_general_ci");
     // Google Calendar.
     add_option('ab_settings_google_event_title', '[[SERVICE_NAME]]');
     // Link assets.
     add_option('ab_settings_link_assets_method', 'enqueue');
     // SMS.
     add_option('ab_sms_default_country_code', '');
 }
Пример #16
0
 private function _drop_tables()
 {
     /** @var wpdb $wpdb */
     global $wpdb;
     $ab_tables = array(AB_Appointment::getTableName(), AB_Category::getTableName(), AB_Coupon::getTableName(), AB_Customer::getTableName(), AB_CustomerAppointment::getTableName(), AB_Holiday::getTableName(), AB_Notification::getTableName(), AB_Payment::getTableName(), AB_ScheduleItemBreak::getTableName(), AB_SentNotification::getTableName(), AB_Service::getTableName(), AB_Staff::getTableName(), AB_StaffScheduleItem::getTableName(), AB_StaffService::getTableName());
     $this->_drop_fk($ab_tables);
     $wpdb->query('DROP TABLE IF EXISTS `' . implode('`, `', $ab_tables) . '` CASCADE;');
 }
Пример #17
0
 /**
  * Get item data for cart.
  *
  * @param $other_data
  * @param $cart_item
  *
  * @return array
  */
 function getItemData($other_data, $cart_item)
 {
     if (isset($cart_item['bookly'])) {
         $info_name = get_option('ab_woocommerce_cart_info_name');
         $info_value = get_option('ab_woocommerce_cart_info_value');
         $staff = new AB_Staff();
         $staff->load($cart_item['bookly']['staff_ids'][0]);
         $service = new AB_Service();
         $service->load($cart_item['bookly']['service_id']);
         $info_value = strtr($info_value, array('[[APPOINTMENT_TIME]]' => AB_DateTimeUtils::formatTime($cart_item['bookly']['appointment_datetime']), '[[APPOINTMENT_DATE]]' => AB_DateTimeUtils::formatDate($cart_item['bookly']['appointment_datetime']), '[[CATEGORY_NAME]]' => $service->getCategoryName(), '[[SERVICE_NAME]]' => $service->getTitle(), '[[SERVICE_PRICE]]' => $service->get('price'), '[[STAFF_NAME]]' => $staff->get('full_name')));
         $other_data[] = array('name' => $info_name, 'value' => $info_value);
     }
     return $other_data;
 }
 /**
  * Export Appointment to CSV
  */
 public function executeExportToCSV()
 {
     $start_date = new DateTime($this->getParameter('date_start'));
     $start_date = $start_date->format('Y-m-d H:i:s');
     $end_date = new DateTime($this->getParameter('date_end'));
     $end_date = $end_date->modify('+1 day')->format('Y-m-d H:i:s');
     $delimiter = $this->getParameter('delimiter', ',');
     header('Content-Type: text/csv; charset=utf-8');
     header('Content-Disposition: attachment; filename=Appointments.csv');
     $header = array(__('Booking Time', 'bookly'), __('Staff Member', 'bookly'), __('Service', 'bookly'), __('Duration', 'bookly'), __('Price', 'bookly'), __('Customer', 'bookly'), __('Phone', 'bookly'), __('Email', 'bookly'));
     $custom_fields = array();
     $fields_data = json_decode(get_option('ab_custom_fields'));
     foreach ($fields_data as $field_data) {
         $custom_fields[$field_data->id] = '';
         $header[] = $field_data->label;
     }
     $output = fopen('php://output', 'w');
     fwrite($output, pack("CCC", 0xef, 0xbb, 0xbf));
     fputcsv($output, $header, $delimiter);
     $rows = AB_CustomerAppointment::query()->select('r.id,
            r.number_of_persons,
            r.coupon_discount,
            r.coupon_deduction,
            st.full_name  AS staff_name,
            s.title       AS service_title,
            s.duration    AS service_duration,
            c.name        AS customer_name,
            c.phone       AS customer_phone,
            c.email       AS customer_email,
            ss.price,
            a.start_date')->leftJoin('AB_Appointment', 'a', 'a.id = r.appointment_id')->leftJoin('AB_Service', 's', 's.id = a.service_id')->leftJoin('AB_Staff', 'st', 'st.id = a.staff_id')->leftJoin('AB_Customer', 'c', 'c.id = r.customer_id')->leftJoin('AB_StaffService', 'ss', 'ss.staff_id = st.id AND ss.service_id = s.id')->whereBetween('a.start_date', $start_date, $end_date)->sortBy('a.start_date')->order(AB_Query::ORDER_DESCENDING)->fetchArray();
     foreach ($rows as $row) {
         if ($row['coupon_discount'] or $row['coupon_deduction']) {
             $coupon = new AB_Coupon();
             $coupon->set('discount', $row['coupon_discount']);
             $coupon->set('deduction', $row['coupon_deduction']);
             $row['price'] = $coupon->apply($row['price']);
         }
         $row['price'] *= $row['number_of_persons'];
         $row_data = array($row['start_date'], $row['staff_name'], $row['service_title'], AB_Service::durationToString($row['service_duration']), AB_Utils::formatPrice($row['price']), $row['customer_name'], $row['customer_phone'], $row['customer_email']);
         $customer_appointment = new AB_CustomerAppointment();
         $customer_appointment->load($row['id']);
         foreach ($customer_appointment->getCustomFields() as $custom_field) {
             $custom_fields[$custom_field['id']] = $custom_field['value'];
         }
         fputcsv($output, array_merge($row_data, $custom_fields), $delimiter);
         $custom_fields = array_map(function () {
             return '';
         }, $custom_fields);
     }
     fclose($output);
     exit;
 }
Пример #19
0
 /**
  * Get service.
  *
  * @return AB_Service
  */
 public function getService()
 {
     $service = new AB_Service();
     $service->load($this->get('service_id'));
     return $service;
 }
Пример #20
0
        </div>
    <?php 
}
?>

    <table class="form-horizontal">
        <tr>
            <td><?php 
_e('Time slot length', 'ab');
?>
</td>
            <td>
                <select name="ab_settings_time_slot_length" style="width: 200px;">
                    <?php 
foreach (array(5, 10, 12, 15, 20, 30, 60) as $duration) {
    $duration_output = AB_Service::durationToString($duration * 60);
    ?>
                        <option value="<?php 
    echo $duration;
    ?>
" <?php 
    selected(get_option('ab_settings_time_slot_length'), $duration);
    ?>
>
                            <?php 
    echo $duration_output;
    ?>
                        </option>
                    <?php 
}
?>
 public function executeCheckAppointmentDateSelection()
 {
     $start_date = $this->getParameter('start_date');
     $end_date = $this->getParameter('end_date');
     $staff_id = $this->getParameter('staff_id');
     $service_id = $this->getParameter('service_id');
     $appointment_id = $this->getParameter('appointment_id');
     $timestamp_diff = strtotime($end_date) - strtotime($start_date);
     $result = array('date_interval_not_available' => false, 'date_interval_warning' => false);
     if (!$this->dateIntervalIsAvailableForAppointment($start_date, $end_date, $staff_id, $appointment_id)) {
         $result['date_interval_not_available'] = true;
     }
     if ($service_id) {
         $service = new AB_Service();
         $service->load($service_id);
         $duration = $service->get('duration');
         // service duration interval is not equal to
         $result['date_interval_warning'] = $timestamp_diff != $duration;
     }
     echo json_encode($result);
     exit;
 }