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 / models / subscrpayment.php
vikappointments / site / models Last commit date
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
subscrpayment.php
355 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 user subscription payment view model.
18 *
19 * @since 1.7
20 */
21 class VikAppointmentsModelSubscrpayment extends JModelVAP
22 {
23 /**
24 * Completes the booking process by saving the purchased subscription.
25 *
26 * @param array $data An array containing some booking options.
27 *
28 * @return mixed The landing page URL on success, false otherwise.
29 */
30 public function save($data)
31 {
32 $dispatcher = VAPFactory::getEventDispatcher();
33
34 // get cart model
35 $cart = JModelVAP::getInstance('subscrcart');
36
37 ////////////////////////////////////////////////////////////
38 ////////////////////// INITIALIZATION //////////////////////
39 ////////////////////////////////////////////////////////////
40
41 $user = JFactory::getUser();
42
43 if ($user->guest)
44 {
45 // the user must be logged in
46 $this->setError(JText::translate('VAPPACKLOGINREQERR'));
47 return false;
48 }
49
50 try
51 {
52 /**
53 * Trigger event to manipulate the cart instance.
54 *
55 * @param mixed $cart The cart instance.
56 *
57 * @return void
58 *
59 * @since 1.7
60 * @since 1.7.8 It is now possible to throw exceptions to abort the saving process.
61 */
62 $dispatcher->trigger('onInitSaveSubscriptionOrder', [$cart]);
63 }
64 catch (Exception $e)
65 {
66 $this->setError($e->getMessage());
67 return false;
68 }
69
70 // prepare order array
71 $order = array();
72
73 ////////////////////////////////////////////////////////////
74 //////////////////// FETCH SUBSCRIPTION ////////////////////
75 ////////////////////////////////////////////////////////////
76
77 try
78 {
79 // get selected subscription
80 $subscr = $cart->getSubscription();
81 }
82 catch (Exception $e)
83 {
84 // an error occurred, register message and abort
85 $this->setError($e);
86 return false;
87 }
88
89 $order['id_subscr'] = $subscr['id'];
90
91 ////////////////////////////////////////////////////////////
92 //////////////////// FETCH CUSTOM FIELDS ///////////////////
93 ////////////////////////////////////////////////////////////
94
95 // register current language tag
96 $order['langtag'] = JFactory::getLanguage()->getTag();
97
98 // import custom fields requestor and loader (as dependency)
99 VAPLoader::import('libraries.customfields.requestor');
100
101 // get relevant custom fields only
102 $_cf = VAPCustomFieldsLoader::getInstance()
103 ->setLanguageFilter($order['langtag'])
104 ->noSeparator()
105 ->fetch();
106
107 try
108 {
109 // load custom fields from request
110 $order['custom_f'] = VAPCustomFieldsRequestor::loadForm($_cf, $tmp, $strict = true);
111 }
112 catch (Exception $e)
113 {
114 // catch exception and register it as error message
115 $this->setError($e->getMessage());
116 return false;
117 }
118
119 // merge custom fields and uploaded files
120 $order['custom_f'] = array_merge($order['custom_f'], $tmp['uploads']);
121
122 /**
123 * Trigger event to manipulate the custom fields array and the
124 * billing information of the customer, extrapolated from the rules
125 * of the custom fields.
126 *
127 * @param array &$fields The custom fields values.
128 * @param array &$args The billing array.
129 *
130 * @return void
131 *
132 * @since 1.7
133 */
134 $dispatcher->trigger('onPrepareFieldsSaveSubscriptionOrder', array(&$order['custom_f'], &$tmp));
135
136 // register data fetched by the custom fields so that the subscription order
137 // model is able to use them for saving purposes
138 $order['fields_data'] = $tmp;
139
140 if (empty($order['fields_data']['purchaser_nominative']))
141 {
142 // use name of the currently logged-in user
143 $order['fields_data']['purchaser_nominative'] = $user->name;
144 }
145
146 if (empty($order['fields_data']['purchaser_mail']))
147 {
148 // use e-mail of the currently logged-in user
149 $order['fields_data']['purchaser_mail'] = $user->email;
150 }
151
152 ////////////////////////////////////////////////////////////
153 ///////////////////// FETCH TOTAL COSTS ////////////////////
154 ////////////////////////////////////////////////////////////
155
156 $totals = $cart->getTotals();
157
158 // set up order totals
159 $order['total_cost'] = $totals->gross;
160 $order['total_net'] = $totals->net;
161 $order['total_tax'] = $totals->tax;
162 $order['discount'] = $totals->discount;
163
164 ////////////////////////////////////////////////////////////
165 ///////////////////// VALIDATE PAYMENT /////////////////////
166 ////////////////////////////////////////////////////////////
167
168 $payment = null;
169
170 $order['id_payment'] = 0;
171
172 if ($order['total_cost'] > 0)
173 {
174 // get selected payment
175 $payment = $cart->getPayment();
176
177 if ($payment)
178 {
179 if (!empty($totals->payment))
180 {
181 // include payment charge
182 $order['payment_charge'] = $totals->payment->net;
183 $order['payment_tax'] = $totals->payment->tax;
184 }
185
186 $order['id_payment'] = $payment['id'];
187
188 // auto-confirm orders according to the configuration of
189 // the payment, otherwise force PENDING status to let the
190 // customers be able to start a transaction
191 if ($payment['setconfirmed'])
192 {
193 // auto-confirm order
194 $order['status'] = JHtml::fetch('vaphtml.status.confirmed', 'subscriptions', 'code');
195 }
196 }
197 }
198
199 ////////////////////////////////////////////////////////////
200 /////////////////////// ORDER STATUS ///////////////////////
201 ////////////////////////////////////////////////////////////
202
203 if (empty($order['status']))
204 {
205 // auto-confirm in case of no cost
206 $status = $order['total_cost'] > 0 ? 'pending' : 'confirmed';
207
208 // status not yet specified, use the default one
209 $order['status'] = JHtml::fetch('vaphtml.status.' . $status, 'subscriptions', 'code');
210 }
211
212 $order['status_comment'] = null;
213
214 /**
215 * Trigger event to manipulate the order status at runtime.
216 *
217 * @param string &$status The currently fetched order status.
218 * @param string &$comment An optional status comment to be used.
219 *
220 * @return void
221 *
222 * @since 1.7
223 */
224 $dispatcher->trigger('onFetchStatusSaveSubscriptionOrder', array(&$order['status'], &$order['status_comment']));
225
226 // check whether the status has been immediately confirmed and we have an empty comment
227 if (empty($order['status_comment']) && JHtml::fetch('vaphtml.status.isconfirmed', 'subscriptions', $order['status']))
228 {
229 if ($order['total_cost'] == 0)
230 {
231 // no cost, automatically confirmed
232 $order['status_comment'] = 'VAP_STATUS_CONFIRMED_AS_NO_COST';
233 }
234 else if (!$payment)
235 {
236 // no configured payments
237 $order['status_comment'] = 'VAP_STATUS_CONFIRMED_AS_NO_PAYMENT';
238 }
239 else
240 {
241 // auto-approved through the configuration of the payment
242 $order['status_comment'] = 'VAP_STATUS_CONFIRMED_RESULT_OF_PAYMENT';
243 }
244 }
245
246 ////////////////////////////////////////////////////////////
247 ///////////////////// FETCH COUPON CODE ////////////////////
248 ////////////////////////////////////////////////////////////
249
250 // check whether the coupon code was set
251 $coupon = $cart->getDiscount('coupon');
252
253 if ($coupon)
254 {
255 // assign coupon code to the order
256 $order['coupon'] = (array) $coupon->get('couponData');
257 // redeem coupon code
258 VikAppointments::couponUsed($order['coupon']);
259 }
260
261 ////////////////////////////////////////////////////////////
262 ///////////////////// USER REGISTRATION ////////////////////
263 ////////////////////////////////////////////////////////////
264
265 // create customer data
266 $customer = array(
267 'id' => 0,
268 'jid' => $user->id,
269 'fields' => $order['custom_f'],
270 );
271
272 // inject fetched billing details
273 $customer = array_merge($customer, $order['fields_data']);
274
275 // get customer model
276 $customerModel = JModelVAP::getInstance('customer');
277
278 // insert/update customer
279 if ($id_user = $customerModel->save($customer))
280 {
281 // assign order to saved customer
282 $order['id_user'] = $id_user;
283 }
284
285 ////////////////////////////////////////////////////////////
286 //////////////////// SAVE ORDER DETAILS ////////////////////
287 ////////////////////////////////////////////////////////////
288
289 $ordnum = $ordkey = null;
290
291 // get subscription order model
292 $orderModel = JModelVAP::getInstance('subscrorder');
293
294 // save the order
295 if (!$orderModel->save($order))
296 {
297 // an error occurred while trying to save the order
298 $error = $orderModel->getError();
299 // propagate the error found or use a generic one
300 $this->setError($error ? $error : JText::translate('VAPSUBSCRINSERTERR'));
301 return false;
302 }
303
304 // get order saved data
305 $orderData = $orderModel->getData();
306
307 // use order number/key pair of saved order
308 $ordnum = $orderData['id'];
309 $ordkey = $orderData['sid'];
310
311 // empty cart on success
312 $cart->emptyCart();
313
314 ////////////////////////////////////////////////////////////
315 ////////////////////// NOTIFICATIONS ///////////////////////
316 ////////////////////////////////////////////////////////////
317
318 // $mailOptions = array();
319 // validate e-mail rules before sending
320 // $mailOptions['check'] = true;
321
322 // send e-mail notification to the customer
323 // $orderModel->sendEmailNotification($ordnum, $mailOptions);
324
325 // send e-mail notification to the administrator(s)
326 // $mailOptions['client'] = 'subscradmin';
327 // $orderModel->sendEmailNotification($ordnum, $mailOptions);
328
329 $redirect_url = "index.php?option=com_vikappointments&view=subscrpayment&ordnum={$ordnum}&ordkey={$ordkey}";
330
331 if (!empty($data['itemid']))
332 {
333 $redirect_url .= "&Itemid={$data['itemid']}";
334 }
335
336 /**
337 * Trigger event to manipulate the redirect URL after completing
338 * the subscription purchase process.
339 *
340 * Use VAPOrderFactory::getCustomerSubscription($ordnum) to access the order details.
341 *
342 * @param string &$url The redirect URL (plain).
343 * @param integer $order The order id.
344 *
345 * @return void
346 *
347 * @since 1.7
348 */
349 $dispatcher->trigger('onRedirectSubscriptionOrder', array(&$redirect_url, $ordnum));
350
351 // rewrite landing page
352 return JRoute::rewrite($redirect_url, false);
353 }
354 }
355