PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / order / classes / empsubscr.php
vikappointments / site / helpers / libraries / order / classes Last commit date
appointment.php 4 days ago empsubscr.php 4 days ago index.html 4 days ago package.php 4 days ago subscr.php 4 days ago
empsubscr.php
434 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.order.wrapper');
15
16 /**
17 * Employee subscription order class wrapper.
18 *
19 * @since 1.7
20 */
21 class VAPOrderEmpsubscr extends VAPOrderWrapper
22 {
23 /**
24 * @override
25 * Returns the subscription order object.
26 *
27 * @param integer $id The order ID.
28 * @param mixed $langtag The language tag. If null, the default one will be used.
29 * @param array $options An array of options to be passed to the order instance.
30 *
31 * @return mixed The array/object to load.
32 *
33 * @throws Exception
34 */
35 protected function load($id, $langtag = null, array $options = array())
36 {
37 $dbo = JFactory::getDbo();
38 $config = VAPFactory::getConfig();
39 $dispatcher = VAPFactory::getEventDispatcher();
40
41 // create query
42 $q = $dbo->getQuery(true);
43
44 // select all order columns
45 $q->select('o.*');
46 $q->from($dbo->qn('#__vikappointments_subscr_order', 'o'));
47
48 // select employee details
49 $q->select($dbo->qn('e.nickname', 'employee_name'));
50 $q->select($dbo->qn('e.email', 'employee_email'));
51 $q->select($dbo->qn('e.phone', 'employee_phone'));
52 $q->select($dbo->qn('e.image', 'employee_image'));
53 $q->select($dbo->qn('e.timezone'));
54 $q->select($dbo->qn('e.billing_json'));
55 $q->select($dbo->qn('e.active_to'));
56 $q->select($dbo->qn('e.active_to_date'));
57 $q->select($dbo->qn('e.active_since'));
58 $q->leftjoin($dbo->qn('#__vikappointments_employee', 'e') . ' ON ' . $dbo->qn('o.id_employee') . ' = ' . $dbo->qn('e.id'));
59
60 // select payment details
61 $q->select($dbo->qn('gp.name', 'payment_name'));
62 $q->select($dbo->qn('gp.file', 'payment_file'));
63 $q->select($dbo->qn('gp.note', 'payment_note'));
64 $q->select($dbo->qn('gp.prenote', 'payment_prenote'));
65 $q->select($dbo->qn('gp.icontype', 'payment_icontype'));
66 $q->select($dbo->qn('gp.icon', 'payment_icon'));
67 $q->leftjoin($dbo->qn('#__vikappointments_gpayments', 'gp') . ' ON ' . $dbo->qn('o.id_payment') . ' = ' . $dbo->qn('gp.id'));
68
69 // select purchased subscription
70 $q->select($dbo->qn('s.id', 'subscr_id'));
71 $q->select($dbo->qn('s.name', 'subscr_name'));
72 $q->select($dbo->qn('s.amount', 'subscr_amount'));
73 $q->select($dbo->qn('s.type', 'subscr_type'));
74 $q->select($dbo->qn('s.price', 'subscr_price'));
75 $q->select($dbo->qn('s.trial', 'subscr_trial'));
76 $q->leftjoin($dbo->qn('#__vikappointments_subscription', 's') . ' ON ' . $dbo->qn('o.id_subscr') . ' = ' . $dbo->qn('s.id'));
77
78 // filter by order key, if specified
79 if (isset($options['sid']))
80 {
81 $q->where($dbo->qn('o.sid') . ' = ' . $dbo->q($options['sid']));
82 }
83
84 // load order matching the specified ID
85 $q->where($dbo->qn('o.id') . ' = ' . (int) $id);
86
87 /**
88 * External plugins can attach to this hook in order to manipulate
89 * the query at runtime, in example to alter the default ordering.
90 *
91 * @param mixed &$query A query builder instance.
92 * @param integer $id The ID of the order.
93 * @param mixed $langtag The language tag. If null, the default one will be used.
94 * @param array $options An array of options to be passed to the order instance.
95 *
96 * @return void
97 *
98 * @since 1.7
99 */
100 $dispatcher->trigger('onLoadEmployeeSubscriptionOrderDetails', array(&$q, $id, $langtag, $options));
101
102 $dbo->setQuery($q, 0, 1);
103
104 // create parent order details
105 $order = $dbo->loadObject();
106
107 if (!$order)
108 {
109 // order not found raise error
110 throw new Exception(sprintf('Order [%d] not found', $id), 404);
111 }
112
113 $order->subscription = new stdClass;
114 $order->subscription->id = $this->detach($order, 'subscr_id');
115 $order->subscription->name = $this->detach($order, 'subscr_name');
116 $order->subscription->amount = $this->detach($order, 'subscr_amount');
117 $order->subscription->type = $this->detach($order, 'subscr_type');
118 $order->subscription->price = $this->detach($order, 'subscr_price');
119 $order->subscription->trial = $this->detach($order, 'subscr_trial');
120
121 // create employee object
122 $order->employee = new stdClass;
123 $order->employee->id = $this->detach($order, 'id_employee');
124 $order->employee->name = $this->detach($order, 'employee_name');
125 $order->employee->email = $this->detach($order, 'employee_email');
126 $order->employee->phone = $this->detach($order, 'employee_phone');
127 $order->employee->image = $this->detach($order, 'employee_image');
128 $order->employee->timezone = $this->detach($order, 'timezone');
129 $order->employee->billing_json = $this->detach($order, 'billing_json');
130
131 // create employee license
132 $order->employee->license = new stdClass;
133 $order->employee->license->active = $this->detach($order, 'active_to');
134 $order->employee->license->expDate = $this->detach($order, 'active_to_date');
135 $order->employee->license->since = $this->detach($order, 'active_since');
136
137 // fetch coupon
138 if ($order->coupon)
139 {
140 list($code, $type, $amount) = explode(';;', $this->detach($order, 'coupon'));
141
142 $order->coupon = new stdClass;
143 $order->coupon->code = $code;
144 $order->coupon->amount = $amount;
145 $order->coupon->type = $type;
146 }
147 else
148 {
149 $order->coupon = null;
150 $this->detach($order, 'coupon');
151 }
152
153 // fetch payment data
154 if ($order->payment_file)
155 {
156 $order->payment = new stdClass;
157 $order->payment->id = $this->detach($order, 'id_payment');
158 $order->payment->name = $this->detach($order, 'payment_name');
159 $order->payment->driver = $this->detach($order, 'payment_file');
160 $order->payment->iconType = $this->detach($order, 'payment_icontype');
161 $order->payment->icon = $this->detach($order, 'payment_icon');
162
163 if ($order->payment->iconType == 1)
164 {
165 // Font Icon
166 $order->payment->fontIcon = $order->payment->icon;
167 }
168 else
169 {
170 // Image Icon
171 $order->payment->iconURI = JUri::root() . $order->payment->icon;
172
173 // fetch Font Icon based on payment driver
174 switch ($order->payment->driver)
175 {
176 case 'bank_transfer.php':
177 $order->payment->fontIcon = 'fas fa-money-bill';
178 break;
179
180 case 'paypal.php':
181 $order->payment->fontIcon = 'fab fa-paypal';
182 break;
183
184 default:
185 $order->payment->fontIcon = 'fas fa-credit-card';
186 }
187 }
188
189 $order->payment->notes = new stdClass;
190 $order->payment->notes->beforePurchase = $this->detach($order, 'payment_prenote');
191 $order->payment->notes->afterPurchase = $this->detach($order, 'payment_note');
192 }
193 else
194 {
195 $order->payment = null;
196 }
197
198 // setup totals
199 $order->totals = new stdClass;
200 $order->totals->net = $this->detach($order, 'total_net');
201 $order->totals->tax = $this->detach($order, 'total_tax');
202 $order->totals->gross = $this->detach($order, 'total_cost');
203 $order->totals->discount = $this->detach($order, 'discount');
204 $order->totals->paid = $this->detach($order, 'tot_paid');
205 $order->totals->payCharge = $this->detach($order, 'payment_charge');
206 $order->totals->payTax = $this->detach($order, 'payment_tax');
207 $order->totals->due = $order->totals->gross - $order->totals->paid;
208
209 // fetch paid flag based on current order status
210 $order->paid = JHtml::fetch('vaphtml.status.ispaid', 'subscriptions', $order->status);
211
212 if ($order->paid)
213 {
214 // amount paid, no remaining balance
215 $order->totals->due = 0;
216 }
217
218 $order->statusRole = null;
219
220 // fetch status role
221 if (JHtml::fetch('vaphtml.status.ispending', 'subscriptions', $order->status))
222 {
223 $order->statusRole = 'PENDING';
224 }
225 else if (JHtml::fetch('vaphtml.status.isapproved', 'subscriptions', $order->status))
226 {
227 $order->statusRole = 'APPROVED';
228 }
229 else if (JHtml::fetch('vaphtml.status.iscancelled', 'subscriptions', $order->status))
230 {
231 $order->statusRole = 'CANCELLED';
232 }
233
234 /**
235 * External plugins can use this event to manipulate the object holding
236 * the details of the order. Useful to inject all the additional data
237 * fetched with the manipulation of the query.
238 *
239 * @param mixed $order The order details object.
240 *
241 * @return void
242 */
243 $dispatcher->trigger('onSetupEmployeeSubscriptionOrderDetails', array($order));
244
245 $unsetList = array(
246 'id_payment'
247 );
248
249 // get rid of not needed properties
250 foreach (get_object_vars($order) as $k => $v)
251 {
252 if (preg_match("/^(payment)_/", $k))
253 {
254 // get rid of blank payment
255 unset($order->{$k});
256 }
257 else if (preg_match("/^__/", $k))
258 {
259 // remove deprecated (back-up) property
260 unset($order->{$k});
261 }
262 else if (in_array($k, $unsetList))
263 {
264 // remove property if contained in the list
265 unset($order->{$k});
266 }
267 }
268
269 return $order;
270 }
271
272 /**
273 * @override
274 * Translates the internal properties.
275 *
276 * @param mixed $langtag The language tag. If null, the default one will be used.
277 *
278 * @return void
279 */
280 protected function translate($langtag = null)
281 {
282 $dispatcher = VAPFactory::getEventDispatcher();
283
284 if (!$langtag)
285 {
286 // use order lang tag in case it was not specified
287 $langtag = $this->get('langtag', null);
288
289 if (!$langtag)
290 {
291 // the order is not assigned to any lang tag, use the current one
292 $langtag = JFactory::getLanguage()->getTag();
293 }
294 }
295
296 // get translator
297 $translator = VAPFactory::getTranslator();
298
299 // get subscription translation
300 $sub_tx = $translator->translate('subscription', $this->subscription->id, $langtag);
301
302 if ($sub_tx)
303 {
304 // inject translation within order details
305 $this->subscription->name = $sub_tx->name;
306 }
307
308 // get employee translation
309 $emp_tx = $translator->translate('employee', $this->employee->id, $langtag);
310
311 if ($emp_tx)
312 {
313 // inject translation within order details
314 $this->employee->name = $emp_tx->nickname;
315 }
316
317 // translate payment if specified
318 if ($this->payment)
319 {
320 // get payment translation
321 $pay_tx = $translator->translate('payment', $this->payment->id, $langtag);
322
323 if ($pay_tx)
324 {
325 // inject translation within order details
326 $this->payment->name = $pay_tx->name;
327 $this->payment->notes->beforePurchase = $pay_tx->prenote;
328 $this->payment->notes->afterPurchase = $pay_tx->note;
329 }
330 }
331
332 /**
333 * External plugins can use this event to apply the translations to
334 * additional details manually included within the order object.
335 *
336 * @param mixed $order The order details object.
337 * @param string $langtag The requested language tag.
338 *
339 * @return void
340 *
341 * @since 1.7
342 */
343 $dispatcher->trigger('onTranslateEmployeeSubscriptionOrderDetails', array($this, $langtag));
344 }
345
346 /**
347 * @override
348 * Returns the billing details of the user that made the order.
349 *
350 * @return object
351 */
352 protected function getBilling()
353 {
354 // inject employee billing into a registry for a better ease of use
355 $data = new JRegistry($this->employee->billing_json ? json_decode($this->employee->billing_json) : array());
356
357 // rebuild billing array to be as compliant as possible with VAPCustomer instance
358 $customer = new stdClass;
359 $customer->billing_name = $this->employee->name;
360 $customer->billing_mail = $this->employee->email;
361 $customer->billing_phone = $this->employee->phone;
362 $customer->country_code = $data->get('country');
363 $customer->billing_state = $data->get('state');
364 $customer->billing_city = $data->get('city');
365 $customer->billing_address = $data->get('address');
366 $customer->billing_address_2 = '';
367 $customer->billing_zip = $data->get('zip');
368 $customer->company = $data->get('company');
369 $customer->vatnum = $data->get('vat');
370
371 return $customer;
372 }
373
374 /**
375 * @override
376 * Returns the account details of the order author.
377 *
378 * @return object
379 */
380 protected function getAuthor()
381 {
382 if ($this->createdby <= 0)
383 {
384 // no registered author, do not go ahead
385 return false;
386 }
387
388 $dbo = JFactory::getDbo();
389
390 $q = $dbo->getQuery(true)
391 ->select($dbo->qn('name'))
392 ->select($dbo->qn('username'))
393 ->select($dbo->qn('email'))
394 ->from($dbo->qn('#__users'))
395 ->where($dbo->qn('id') . ' = ' . (int) $this->createdby);
396
397 $dbo->setQuery($q, 0, 1);
398 return $dbo->loadObject() ?? false;
399 }
400
401 /**
402 * @override
403 * Returns the invoice details of the order.
404 *
405 * @return mixed The invoice object if exists, false otherwise.
406 */
407 protected function getInvoice()
408 {
409 return JModelVAP::getInstance('invoice')->getInvoice($this->id, 'employees');
410 }
411
412 /**
413 * @override
414 * Returns the history of the status codes set for the order.
415 *
416 * @return array
417 */
418 protected function getHistory()
419 {
420 return VAPOrderStatus::getInstance('subscr_order')->getOrderTrack($this->id, $locale = true);
421 }
422
423 /**
424 * @override
425 * Returns a list of notes assigned to this order.
426 *
427 * @return array
428 */
429 protected function getNotes()
430 {
431 return array();
432 }
433 }
434