allorders.php
1 day ago
calendarweek.php
1 day ago
cart.php
1 day ago
confirmapp.php
1 day ago
empaccountstat.php
1 day ago
empattachser.php
1 day ago
empcoupons.php
1 day ago
empcustfields.php
1 day ago
empeditcoupon.php
1 day ago
empeditcustfield.php
1 day ago
empeditlocation.php
1 day ago
empeditpay.php
1 day ago
empeditprofile.php
1 day ago
empeditservice.php
1 day ago
empeditwdays.php
1 day ago
emplocations.php
1 day ago
emplocwdays.php
1 day ago
emplogin.php
1 day ago
employeesearch.php
1 day ago
employeeslist.php
1 day ago
empmanres.php
1 day ago
emppaylist.php
1 day ago
empserviceslist.php
1 day ago
empsettingsman.php
1 day ago
empsubscrcart.php
1 day ago
empsubscrhistory.php
1 day ago
empsubscrorder.php
1 day ago
empwdays.php
1 day ago
index.html
1 day ago
packages.php
1 day ago
packagescart.php
1 day ago
packagesconfirm.php
1 day ago
packorders.php
1 day ago
servicesearch.php
1 day ago
serviceslist.php
1 day ago
subscrcart.php
1 day ago
subscrhistory.php
1 day ago
subscrpayment.php
1 day ago
empmanres.php
387 lines
| 1 | <?php |
| 2 | /** |
| 3 | * @package VikAppointments |
| 4 | * @subpackage core |
| 5 | * @author E4J s.r.l. |
| 6 | * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved. |
| 7 | * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL |
| 8 | * @link https://vikwp.com |
| 9 | */ |
| 10 | |
| 11 | // No direct access |
| 12 | defined('ABSPATH') or die('No script kiddies please!'); |
| 13 | |
| 14 | VAPLoader::import('libraries.mvc.model'); |
| 15 | |
| 16 | /** |
| 17 | * VikAppointments employee area reservation management model. |
| 18 | * |
| 19 | * @since 1.7 |
| 20 | */ |
| 21 | class VikAppointmentsModelEmpmanres extends JModelVAP |
| 22 | { |
| 23 | /** |
| 24 | * Basic item loading implementation. |
| 25 | * |
| 26 | * @param mixed $pk An optional primary key value to load the row by, or an array of fields to match. |
| 27 | * If not set the instance property value is used. |
| 28 | * @param boolean $new True to return an empty object if missing. |
| 29 | * |
| 30 | * @return mixed The record object on success, null otherwise. |
| 31 | */ |
| 32 | public function getItem($pk, $new = false) |
| 33 | { |
| 34 | // load item through parent |
| 35 | $item = parent::getItem($pk, $new); |
| 36 | |
| 37 | if ($item) |
| 38 | { |
| 39 | $item->id_employee = VAPEmployeeAuth::getInstance()->id; |
| 40 | |
| 41 | $item->userNote = null; |
| 42 | |
| 43 | if ($item->id) |
| 44 | { |
| 45 | // decode custom fields and uploads |
| 46 | $item->custom_f = (array) json_decode($item->custom_f, true); |
| 47 | $item->attendees = (array) json_decode($item->attendees, true); |
| 48 | $item->uploads = (array) json_decode($item->uploads, true); |
| 49 | // merge them together |
| 50 | $item->custom_f = array_merge($item->custom_f, $item->uploads); |
| 51 | |
| 52 | $dbo = JFactory::getDbo(); |
| 53 | |
| 54 | // load assigned options |
| 55 | $q = $dbo->getQuery(true) |
| 56 | ->select('a.*') |
| 57 | ->select($dbo->qn('o.name')) |
| 58 | ->select($dbo->qn('v.name', 'var_name')) |
| 59 | ->from($dbo->qn('#__vikappointments_option', 'o')) |
| 60 | ->leftjoin($dbo->qn('#__vikappointments_res_opt_assoc', 'a') . ' ON ' . $dbo->qn('o.id') . ' = ' . $dbo->qn('a.id_option')) |
| 61 | ->leftjoin($dbo->qn('#__vikappointments_option_value', 'v') . ' ON ' . $dbo->qn('v.id') . ' = ' . $dbo->qn('a.id_variation')) |
| 62 | ->where($dbo->qn('a.id_reservation') . ' = ' . $item->id) |
| 63 | ->order($dbo->qn('a.id') . ' ASC'); |
| 64 | |
| 65 | $dbo->setQuery($q); |
| 66 | $item->options = $dbo->loadObjectList(); |
| 67 | |
| 68 | /** |
| 69 | * Loads the last note assigned to this reservation. |
| 70 | * |
| 71 | * @since 1.7 |
| 72 | */ |
| 73 | $q = $dbo->getQuery(true) |
| 74 | ->select('*') |
| 75 | ->from($dbo->qn('#__vikappointments_user_notes')) |
| 76 | ->where($dbo->qn('id_parent') . ' = ' . $item->id) |
| 77 | ->where($dbo->qn('group') . ' = ' . $dbo->q('appointments')) |
| 78 | ->order(sprintf( |
| 79 | 'IFNULL(%s, %s) %s', |
| 80 | $dbo->qn('modifiedon'), |
| 81 | $dbo->qn('createdon'), |
| 82 | 'DESC' |
| 83 | )); |
| 84 | |
| 85 | $dbo->setQuery($q, 0, 1); |
| 86 | $item->userNote = $dbo->loadObject(); |
| 87 | } |
| 88 | else |
| 89 | { |
| 90 | // new record |
| 91 | $item->custom_f = array(); |
| 92 | $item->attendees = array(); |
| 93 | $item->options = array(); |
| 94 | $item->jid = 0; |
| 95 | } |
| 96 | |
| 97 | if (!$item->userNote) |
| 98 | { |
| 99 | // load an empty object |
| 100 | $item->userNote = JModelVAP::getInstance('usernote')->getItem(0, $blank = true); |
| 101 | } |
| 102 | |
| 103 | // load customer details |
| 104 | $item->userData = JModelVAP::getInstance('customer')->getItem($item->id_user); |
| 105 | } |
| 106 | |
| 107 | return $item; |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * Basic save implementation. |
| 112 | * |
| 113 | * @param mixed $data Either an array or an object of data to save. |
| 114 | * |
| 115 | * @return mixed The ID of the record on success, false otherwise. |
| 116 | */ |
| 117 | public function save($data) |
| 118 | { |
| 119 | $data = (array) $data; |
| 120 | |
| 121 | $app = JFactory::getApplication(); |
| 122 | $auth = VAPEmployeeAuth::getInstance(); |
| 123 | |
| 124 | // get reservation model |
| 125 | $appModel = JModelVAP::getInstance('reservation'); |
| 126 | |
| 127 | // force author and owner |
| 128 | $data['createdby'] = JFactory::getUser()->id; |
| 129 | $data['id_employee'] = $auth->id; |
| 130 | |
| 131 | /** |
| 132 | * If the status was already confirmed, resconfirm() will return |
| 133 | * true even if the rule is disabled. |
| 134 | * |
| 135 | * @since 1.6 |
| 136 | */ |
| 137 | if (JHtml::fetch('vaphtml.status.isapproved', 'appointments', $data['status']) && !$auth->confirmReservation($data['id'])) |
| 138 | { |
| 139 | // the employee cannot confirm the reservation, use default PENDING status |
| 140 | $data['status'] = JHtml::fetch('vaphtml.status.pending', 'appointments', 'code'); |
| 141 | } |
| 142 | |
| 143 | $data['people'] = max(array(1, $data['people'])); |
| 144 | |
| 145 | // make sure the selected payment can be used by this employee |
| 146 | if (empty($data['id_payment']) || !VikAppointments::getPayment($data['id_payment'])) |
| 147 | { |
| 148 | // nope, unset it |
| 149 | $data['id_payment'] = 0; |
| 150 | } |
| 151 | |
| 152 | if ($data['notifycust']) |
| 153 | { |
| 154 | $input = $app->input; |
| 155 | |
| 156 | /** |
| 157 | * Loads any additional custom text to include within the e-mail notification. |
| 158 | * |
| 159 | * @since 1.6.5 |
| 160 | */ |
| 161 | $custMail = array(); |
| 162 | $custMail['id'] = $input->getUint('custmail_id', 0); |
| 163 | $custMail['name'] = $input->getString('custmail_name', ''); |
| 164 | $custMail['position'] = $input->getString('custmail_position', ''); |
| 165 | $custMail['content'] = JComponentHelper::filterText($input->getRaw('custmail_content', '')); |
| 166 | $custMail['id_employee'] = $data['id_employee']; |
| 167 | |
| 168 | if (!empty($custMail['name']) && !empty($custMail['content'])) |
| 169 | { |
| 170 | // create new custom e-mail template (unpublished) |
| 171 | $custMail['published'] = 0; |
| 172 | |
| 173 | // get e-mail text model |
| 174 | $custMailModel = JModelVAP::getInstance('mailtext'); |
| 175 | // attempt to create new mail text |
| 176 | $mail_id = $custMailModel->save($custMail); |
| 177 | |
| 178 | if ($mail_id) |
| 179 | { |
| 180 | // inject selected custom e-mail within order details |
| 181 | // for being retrieved while generating the notification |
| 182 | $data['mail_custom_text'] = $mail_id; |
| 183 | |
| 184 | /** |
| 185 | * Added the possibility to exclude the default mail custom texts. |
| 186 | * |
| 187 | * @since 1.6.6 |
| 188 | */ |
| 189 | $data['exclude_default_mail_texts'] = $input->getBool('exclude_default_mail_texts', false); |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | // import custom fields requestor and loader (as dependency) |
| 195 | VAPLoader::import('libraries.customfields.requestor'); |
| 196 | |
| 197 | // get relevant custom fields only |
| 198 | $_cf = VAPCustomFieldsLoader::getInstance() |
| 199 | ->ofEmployee($data['id_employee']) |
| 200 | ->forService($data['id_service']) |
| 201 | ->noSeparator() |
| 202 | ->noRequiredCheckbox() |
| 203 | ->fetch(); |
| 204 | |
| 205 | // load custom fields from request |
| 206 | $data['custom_f'] = VAPCustomFieldsRequestor::loadForm($_cf, $tmp, $strict = false); |
| 207 | |
| 208 | // copy uploads into the apposite column |
| 209 | $data['uploads'] = $tmp['uploads']; |
| 210 | |
| 211 | // register data fetched by the custom fields so that the reservation |
| 212 | // model is able to use them for saving purposes |
| 213 | $data['fields_data'] = $tmp; |
| 214 | |
| 215 | $data['attendees'] = array(); |
| 216 | |
| 217 | /** |
| 218 | * Recover attendees custom fields. |
| 219 | * |
| 220 | * @since 1.7 |
| 221 | */ |
| 222 | for ($people = 0; $people < $data['people'] - 1; $people++) |
| 223 | { |
| 224 | // reset attendee array |
| 225 | $attendee = array(); |
| 226 | |
| 227 | // load custom fields from request for other attendees |
| 228 | $tmp = VAPCustomFieldsRequestor::loadFormAttendee($people + 1, $_cf, $attendee, $strict = false); |
| 229 | // inject attendee custom fields within the array containing the fetched rules |
| 230 | $attendee['fields'] = $tmp; |
| 231 | |
| 232 | // register attendee |
| 233 | $data['attendees'][] = $attendee; |
| 234 | } |
| 235 | |
| 236 | // set user state for being recovered again |
| 237 | $app->setUserState('vap.emparea.reservation.data', $data); |
| 238 | |
| 239 | // make sure the employee is allowed to book an appointment for the selected service |
| 240 | if (!$auth->manageServices($data['id_service'], $readOnly = true)) |
| 241 | { |
| 242 | // register error and abort |
| 243 | $this->setError(JText::translate('VAPRESERVATIONEDITED0')); |
| 244 | return false; |
| 245 | } |
| 246 | |
| 247 | if (empty($data['notes']) && !empty($data['id_notes'])) |
| 248 | { |
| 249 | // we need to delete the note has the employee cleared the description |
| 250 | JModelVAP::getInstance('usernote')->delete($data['id_notes']); |
| 251 | } |
| 252 | |
| 253 | /** |
| 254 | * Scan the user fields to check whether we should automatically create a |
| 255 | * new customer record. |
| 256 | * |
| 257 | * @since 1.7.1 |
| 258 | */ |
| 259 | if ((empty($data['id_user']) || $data['id_user'] < 0) && $data['fields_data']) |
| 260 | { |
| 261 | // The reservation hasn't been assigned to any customers... |
| 262 | // Try to save a new customer record. |
| 263 | $id_user = JModelVAP::getInstance('customer')->save($data['fields_data']); |
| 264 | |
| 265 | if ($id_user) |
| 266 | { |
| 267 | // assign the reservation to the created/updated user |
| 268 | $data['id_user'] = (int) $id_user; |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | // delegate save to reservation model |
| 273 | return $appModel->save($data); |
| 274 | } |
| 275 | |
| 276 | /** |
| 277 | * Extend delete implementation to delete any related records |
| 278 | * stored within a separated table. |
| 279 | * |
| 280 | * @param mixed $ids Either the record ID or a list of records. |
| 281 | * |
| 282 | * @return boolean True on success, false otherwise. |
| 283 | */ |
| 284 | public function delete($ids) |
| 285 | { |
| 286 | $auth = VAPEmployeeAuth::getInstance(); |
| 287 | |
| 288 | if (!$auth->isEmployee()) |
| 289 | { |
| 290 | throw new Exception(JText::translate('JERROR_ALERTNOAUTHOR'), 403); |
| 291 | } |
| 292 | |
| 293 | $result = false; |
| 294 | |
| 295 | $shouldNotify = $auth->isNotifyOnReservationDelete(); |
| 296 | |
| 297 | // only int values are accepted |
| 298 | $ids = array_map('intval', (array) $ids); |
| 299 | |
| 300 | $model = JModelVAP::getInstance('reservation'); |
| 301 | |
| 302 | foreach ($ids as $id) |
| 303 | { |
| 304 | if (!$auth->removeReservation($id)) |
| 305 | { |
| 306 | // not allowed, go ahead |
| 307 | continue; |
| 308 | } |
| 309 | |
| 310 | if ($shouldNotify) |
| 311 | { |
| 312 | // load appointment details before deleting it |
| 313 | VAPLoader::import('libraries.order.factory'); |
| 314 | $order = VAPOrderFactory::getAppointments($id); |
| 315 | } |
| 316 | |
| 317 | if ($model->delete($id)) |
| 318 | { |
| 319 | $result = true; |
| 320 | |
| 321 | if ($shouldNotify) |
| 322 | { |
| 323 | // send a notification to the administrator |
| 324 | $this->sendAdminNotification($order); |
| 325 | } |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | if (!$result) |
| 330 | { |
| 331 | throw new Exception(JText::translate('JERROR_ALERTNOAUTHOR'), 403); |
| 332 | } |
| 333 | |
| 334 | return true; |
| 335 | } |
| 336 | |
| 337 | /** |
| 338 | * Sends a notification to the administrator every time an employee |
| 339 | * deletes an appointment. |
| 340 | * |
| 341 | * @param object $order |
| 342 | * |
| 343 | * @return void |
| 344 | */ |
| 345 | protected function sendAdminNotification($order) |
| 346 | { |
| 347 | $appointment = $order->appointments[0]; |
| 348 | |
| 349 | $mail_sub = JText::sprintf('VAPREMRESMAILSUBJECT', $appointment->employee->id); |
| 350 | |
| 351 | $mail_cont = JText::translate('VAPMANAGERESERVATION1') . ": {$order->id} - {$order->sid}<br />"; |
| 352 | $mail_cont .= "{$appointment->service->name} - {$appointment->employee->nickname}<br />"; |
| 353 | $mail_cont .= $appointment->systemCheckin->lc3 . ' - ' . VAPFactory::getCurrency()->format($order->totals->gross) . '<br />'; |
| 354 | $mail_cont .= JText::translate('VAPMANAGERESERVATION12'). ': ' . JHtml::fetch('vaphtml.status.display', $order->status); |
| 355 | |
| 356 | $mail_cont = JText::sprintf('VAPREMRESMAILCONT', $mail_cont); |
| 357 | |
| 358 | $vik = VAPApplication::getInstance(); |
| 359 | |
| 360 | $company_name = VAPFactory::getConfig()->get('agencyname'); |
| 361 | $admin_mail_list = VikAppointments::getAdminMailList(); |
| 362 | $sender_mail = VikAppointments::getSenderMail(); |
| 363 | |
| 364 | // send e-mail notification |
| 365 | foreach ($admin_mail_list as $_m) |
| 366 | { |
| 367 | $vik->sendMail($sender_mail, $company_name, $_m, $sender_mail, $mail_sub, $mail_cont, $attachments = null, $is_html = true); |
| 368 | } |
| 369 | } |
| 370 | |
| 371 | /** |
| 372 | * Method to get a table object. |
| 373 | * |
| 374 | * @param string $name The table name. |
| 375 | * @param string $prefix The class prefix. |
| 376 | * @param array $options Configuration array for table. |
| 377 | * |
| 378 | * @return JTable A table object. |
| 379 | * |
| 380 | * @throws Exception |
| 381 | */ |
| 382 | public function getTable($name = 'reservation', $prefix = '', $options = array()) |
| 383 | { |
| 384 | return parent::getTable($name, $prefix, $options); |
| 385 | } |
| 386 | } |
| 387 |