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