Completed
Branch FET/event-question-group-refac... (0d8185)
by
unknown
20:08 queued 10:56
created

EE_Ticket::increaseReserved()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 34
rs 9.376
c 0
b 0
f 0
1
<?php
2
3
use EventEspresso\core\exceptions\InvalidDataTypeException;
4
use EventEspresso\core\exceptions\InvalidInterfaceException;
5
use EventEspresso\core\exceptions\UnexpectedEntityException;
6
7
/**
8
 * EE_Ticket class
9
 *
10
 * @package            Event Espresso
11
 * @subpackage         includes/classes/EE_Ticket.class.php
12
 * @author             Darren Ethier
13
 */
14
class EE_Ticket extends EE_Soft_Delete_Base_Class implements EEI_Line_Item_Object, EEI_Event_Relation, EEI_Has_Icon
15
{
16
17
    /**
18
     * The following constants are used by the ticket_status() method to indicate whether a ticket is on sale or not.
19
     */
20
    const sold_out = 'TKS';
21
22
    /**
23
     *
24
     */
25
    const expired = 'TKE';
26
27
    /**
28
     *
29
     */
30
    const archived = 'TKA';
31
32
    /**
33
     *
34
     */
35
    const pending = 'TKP';
36
37
    /**
38
     *
39
     */
40
    const onsale = 'TKO';
41
42
    /**
43
     * extra meta key for tracking ticket reservations
44
     *
45
     * @type string
46
     */
47
    const META_KEY_TICKET_RESERVATIONS = 'ticket_reservations';
48
49
    /**
50
     * cached result from method of the same name
51
     *
52
     * @var float $_ticket_total_with_taxes
53
     */
54
    private $_ticket_total_with_taxes;
55
56
57
    /**
58
     * @param array  $props_n_values          incoming values
59
     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
60
     *                                        used.)
61
     * @param array  $date_formats            incoming date_formats in an array where the first value is the
62
     *                                        date_format and the second value is the time format
63
     * @return EE_Ticket
64
     * @throws EE_Error
65
     */
66
    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
67
    {
68
        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
69
        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
70
    }
71
72
73
    /**
74
     * @param array  $props_n_values  incoming values from the database
75
     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
76
     *                                the website will be used.
77
     * @return EE_Ticket
78
     * @throws EE_Error
79
     */
80
    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
81
    {
82
        return new self($props_n_values, true, $timezone);
83
    }
84
85
86
    /**
87
     * @return bool
88
     * @throws EE_Error
89
     */
90
    public function parent()
91
    {
92
        return $this->get('TKT_parent');
93
    }
94
95
96
    /**
97
     * return if a ticket has quantities available for purchase
98
     *
99
     * @param  int $DTT_ID the primary key for a particular datetime
100
     * @return boolean
101
     * @throws EE_Error
102
     */
103
    public function available($DTT_ID = 0)
104
    {
105
        // are we checking availability for a particular datetime ?
106
        if ($DTT_ID) {
107
            // get that datetime object
108
            $datetime = $this->get_first_related('Datetime', array(array('DTT_ID' => $DTT_ID)));
109
            // if  ticket sales for this datetime have exceeded the reg limit...
110
            if ($datetime instanceof EE_Datetime && $datetime->sold_out()) {
111
                return false;
112
            }
113
        }
114
        // datetime is still open for registration, but is this ticket sold out ?
115
        return $this->qty() < 1 || $this->qty() > $this->sold() ? true : false;
116
    }
117
118
119
    /**
120
     * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
121
     *
122
     * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the
123
     *                               relevant status const
124
     * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save
125
     *               further processing
126
     * @return mixed status int if the display string isn't requested
127
     * @throws EE_Error
128
     */
129
    public function ticket_status($display = false, $remaining = null)
130
    {
131
        $remaining = is_bool($remaining) ? $remaining : $this->is_remaining();
132
        if (! $remaining) {
133
            return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, false, 'sentence') : EE_Ticket::sold_out;
134
        }
135
        if ($this->get('TKT_deleted')) {
136
            return $display ? EEH_Template::pretty_status(EE_Ticket::archived, false, 'sentence') : EE_Ticket::archived;
137
        }
138
        if ($this->is_expired()) {
139
            return $display ? EEH_Template::pretty_status(EE_Ticket::expired, false, 'sentence') : EE_Ticket::expired;
140
        }
141
        if ($this->is_pending()) {
142
            return $display ? EEH_Template::pretty_status(EE_Ticket::pending, false, 'sentence') : EE_Ticket::pending;
143
        }
144
        if ($this->is_on_sale()) {
145
            return $display ? EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence') : EE_Ticket::onsale;
146
        }
147
        return '';
148
    }
149
150
151
    /**
152
     * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale
153
     * considering ALL the factors used for figuring that out.
154
     *
155
     * @access public
156
     * @param  int $DTT_ID if an int above 0 is included here then we get a specific dtt.
157
     * @return boolean         true = tickets remaining, false not.
158
     * @throws EE_Error
159
     */
160
    public function is_remaining($DTT_ID = 0)
161
    {
162
        $num_remaining = $this->remaining($DTT_ID);
163
        if ($num_remaining === 0) {
164
            return false;
165
        }
166
        if ($num_remaining > 0 && $num_remaining < $this->min()) {
167
            return false;
168
        }
169
        return true;
170
    }
171
172
173
    /**
174
     * return the total number of tickets available for purchase
175
     *
176
     * @param  int $DTT_ID the primary key for a particular datetime.
177
     *                     set to 0 for all related datetimes
178
     * @return int
179
     * @throws EE_Error
180
     */
181
    public function remaining($DTT_ID = 0)
182
    {
183
        return $this->real_quantity_on_ticket('saleable', $DTT_ID);
184
    }
185
186
187
    /**
188
     * Gets min
189
     *
190
     * @return int
191
     * @throws EE_Error
192
     */
193
    public function min()
194
    {
195
        return $this->get('TKT_min');
196
    }
197
198
199
    /**
200
     * return if a ticket is no longer available cause its available dates have expired.
201
     *
202
     * @return boolean
203
     * @throws EE_Error
204
     */
205
    public function is_expired()
206
    {
207
        return ($this->get_raw('TKT_end_date') < time());
208
    }
209
210
211
    /**
212
     * Return if a ticket is yet to go on sale or not
213
     *
214
     * @return boolean
215
     * @throws EE_Error
216
     */
217
    public function is_pending()
218
    {
219
        return ($this->get_raw('TKT_start_date') > time());
220
    }
221
222
223
    /**
224
     * Return if a ticket is on sale or not
225
     *
226
     * @return boolean
227
     * @throws EE_Error
228
     */
229
    public function is_on_sale()
230
    {
231
        return ($this->get_raw('TKT_start_date') < time() && $this->get_raw('TKT_end_date') > time());
232
    }
233
234
235
    /**
236
     * This returns the chronologically last datetime that this ticket is associated with
237
     *
238
     * @param string $dt_frmt
239
     * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with
240
     *                            the end date ie: Jan 01 "to" Dec 31
241
     * @return string
242
     * @throws EE_Error
243
     */
244
    public function date_range($dt_frmt = '', $conjunction = ' - ')
245
    {
246
        $first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date($dt_frmt)
247
            : '';
248
        $last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date($dt_frmt) : '';
249
250
        return $first_date && $last_date ? $first_date . $conjunction . $last_date : '';
251
    }
252
253
254
    /**
255
     * This returns the chronologically first datetime that this ticket is associated with
256
     *
257
     * @return EE_Datetime
258
     * @throws EE_Error
259
     */
260
    public function first_datetime()
261
    {
262
        $datetimes = $this->datetimes(array('limit' => 1));
263
        return reset($datetimes);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression reset($datetimes); of type EE_Base_Class|false adds false to the return on line 263 which is incompatible with the return type documented by EE_Ticket::first_datetime of type EE_Datetime. It seems like you forgot to handle an error condition.
Loading history...
264
    }
265
266
267
    /**
268
     * Gets all the datetimes this ticket can be used for attending.
269
     * Unless otherwise specified, orders datetimes by start date.
270
     *
271
     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
272
     * @return EE_Datetime[]|EE_Base_Class[]
273
     * @throws EE_Error
274
     */
275
    public function datetimes($query_params = array())
276
    {
277
        if (! isset($query_params['order_by'])) {
278
            $query_params['order_by']['DTT_order'] = 'ASC';
279
        }
280
        return $this->get_many_related('Datetime', $query_params);
281
    }
282
283
284
    /**
285
     * This returns the chronologically last datetime that this ticket is associated with
286
     *
287
     * @return EE_Datetime
288
     * @throws EE_Error
289
     */
290
    public function last_datetime()
291
    {
292
        $datetimes = $this->datetimes(array('limit' => 1, 'order_by' => array('DTT_EVT_start' => 'DESC')));
293
        return end($datetimes);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression end($datetimes); of type EE_Base_Class|false adds false to the return on line 293 which is incompatible with the return type documented by EE_Ticket::last_datetime of type EE_Datetime. It seems like you forgot to handle an error condition.
Loading history...
294
    }
295
296
297
    /**
298
     * This returns the total tickets sold depending on the given parameters.
299
     *
300
     * @param  string $what   Can be one of two options: 'ticket', 'datetime'.
301
     *                        'ticket' = total ticket sales for all datetimes this ticket is related to
302
     *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
303
     *                        'datetime' = total ticket sales in the datetime_ticket table.
304
     *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
305
     *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
306
     * @param  int    $dtt_id [optional] include the dtt_id with $what = 'datetime'.
307
     * @return mixed (array|int)          how many tickets have sold
308
     * @throws EE_Error
309
     */
310
    public function tickets_sold($what = 'ticket', $dtt_id = null)
311
    {
312
        $total = 0;
313
        $tickets_sold = $this->_all_tickets_sold();
314
        switch ($what) {
315
            case 'ticket':
316
                return $tickets_sold['ticket'];
317
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
318
            case 'datetime':
319
                if (empty($tickets_sold['datetime'])) {
320
                    return $total;
321
                }
322
                if (! empty($dtt_id) && ! isset($tickets_sold['datetime'][ $dtt_id ])) {
323
                    EE_Error::add_error(
324
                        __(
325
                            'You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included.  Are you SURE that is a datetime related to this ticket?',
326
                            'event_espresso'
327
                        ),
328
                        __FILE__,
329
                        __FUNCTION__,
330
                        __LINE__
331
                    );
332
                    return $total;
333
                }
334
                return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][ $dtt_id ];
335
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
336
            default:
337
                return $total;
338
        }
339
    }
340
341
342
    /**
343
     * This returns an array indexed by datetime_id for tickets sold with this ticket.
344
     *
345
     * @return EE_Ticket[]
346
     * @throws EE_Error
347
     */
348
    protected function _all_tickets_sold()
349
    {
350
        $datetimes = $this->get_many_related('Datetime');
351
        $tickets_sold = array();
352
        if (! empty($datetimes)) {
353
            foreach ($datetimes as $datetime) {
354
                $tickets_sold['datetime'][ $datetime->ID() ] = $datetime->get('DTT_sold');
355
            }
356
        }
357
        // Tickets sold
358
        $tickets_sold['ticket'] = $this->sold();
359
        return $tickets_sold;
360
    }
361
362
363
    /**
364
     * This returns the base price object for the ticket.
365
     *
366
     * @param  bool $return_array whether to return as an array indexed by price id or just the object.
367
     * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
368
     * @throws EE_Error
369
     */
370
    public function base_price($return_array = false)
371
    {
372
        $_where = array('Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price);
373
        return $return_array
374
            ? $this->get_many_related('Price', array($_where))
375
            : $this->get_first_related('Price', array($_where));
376
    }
377
378
379
    /**
380
     * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
381
     *
382
     * @access public
383
     * @return EE_Price[]
384
     * @throws EE_Error
385
     */
386
    public function price_modifiers()
387
    {
388
        $query_params = array(
389
            0 => array(
390
                'Price_Type.PBT_ID' => array(
391
                    'NOT IN',
392
                    array(EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax),
393
                ),
394
            ),
395
        );
396
        return $this->prices($query_params);
397
    }
398
399
400
    /**
401
     * Gets all the prices that combine to form the final price of this ticket
402
     *
403
     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
404
     * @return EE_Price[]|EE_Base_Class[]
405
     * @throws EE_Error
406
     */
407
    public function prices($query_params = array())
408
    {
409
        return $this->get_many_related('Price', $query_params);
410
    }
411
412
413
    /**
414
     * Gets all the ticket applicabilities (ie, relations between datetimes and tickets)
415
     *
416
     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
417
     * @return EE_Datetime_Ticket|EE_Base_Class[]
418
     * @throws EE_Error
419
     */
420
    public function datetime_tickets($query_params = array())
421
    {
422
        return $this->get_many_related('Datetime_Ticket', $query_params);
423
    }
424
425
426
    /**
427
     * Gets all the datetimes from the db ordered by DTT_order
428
     *
429
     * @param boolean $show_expired
430
     * @param boolean $show_deleted
431
     * @return EE_Datetime[]
432
     * @throws EE_Error
433
     */
434
    public function datetimes_ordered($show_expired = true, $show_deleted = false)
435
    {
436
        return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_ticket_ordered_by_DTT_order(
437
            $this->ID(),
438
            $show_expired,
439
            $show_deleted
440
        );
441
    }
442
443
444
    /**
445
     * Gets ID
446
     *
447
     * @return string
448
     * @throws EE_Error
449
     */
450
    public function ID()
451
    {
452
        return $this->get('TKT_ID');
453
    }
454
455
456
    /**
457
     * get the author of the ticket.
458
     *
459
     * @since 4.5.0
460
     * @return int
461
     * @throws EE_Error
462
     */
463
    public function wp_user()
464
    {
465
        return $this->get('TKT_wp_user');
466
    }
467
468
469
    /**
470
     * Gets the template for the ticket
471
     *
472
     * @return EE_Ticket_Template|EE_Base_Class
473
     * @throws EE_Error
474
     */
475
    public function template()
476
    {
477
        return $this->get_first_related('Ticket_Template');
478
    }
479
480
481
    /**
482
     * Simply returns an array of EE_Price objects that are taxes.
483
     *
484
     * @return EE_Price[]
485
     * @throws EE_Error
486
     */
487
    public function get_ticket_taxes_for_admin()
488
    {
489
        return EE_Taxes::get_taxes_for_admin();
490
    }
491
492
493
    /**
494
     * @return float
495
     * @throws EE_Error
496
     */
497
    public function ticket_price()
498
    {
499
        return $this->get('TKT_price');
500
    }
501
502
503
    /**
504
     * @return mixed
505
     * @throws EE_Error
506
     */
507
    public function pretty_price()
508
    {
509
        return $this->get_pretty('TKT_price');
510
    }
511
512
513
    /**
514
     * @return bool
515
     * @throws EE_Error
516
     */
517
    public function is_free()
518
    {
519
        return $this->get_ticket_total_with_taxes() === (float) 0;
520
    }
521
522
523
    /**
524
     * get_ticket_total_with_taxes
525
     *
526
     * @param bool $no_cache
527
     * @return float
528
     * @throws EE_Error
529
     */
530
    public function get_ticket_total_with_taxes($no_cache = false)
531
    {
532
        if ($this->_ticket_total_with_taxes === null || $no_cache) {
533
            $this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
534
        }
535
        return (float) $this->_ticket_total_with_taxes;
536
    }
537
538
539
    public function ensure_TKT_Price_correct()
540
    {
541
        $this->set('TKT_price', EE_Taxes::get_subtotal_for_admin($this));
542
        $this->save();
543
    }
544
545
546
    /**
547
     * @return float
548
     * @throws EE_Error
549
     */
550
    public function get_ticket_subtotal()
551
    {
552
        return EE_Taxes::get_subtotal_for_admin($this);
553
    }
554
555
556
    /**
557
     * Returns the total taxes applied to this ticket
558
     *
559
     * @return float
560
     * @throws EE_Error
561
     */
562
    public function get_ticket_taxes_total_for_admin()
563
    {
564
        return EE_Taxes::get_total_taxes_for_admin($this);
565
    }
566
567
568
    /**
569
     * Sets name
570
     *
571
     * @param string $name
572
     * @throws EE_Error
573
     */
574
    public function set_name($name)
575
    {
576
        $this->set('TKT_name', $name);
577
    }
578
579
580
    /**
581
     * Gets description
582
     *
583
     * @return string
584
     * @throws EE_Error
585
     */
586
    public function description()
587
    {
588
        return $this->get('TKT_description');
589
    }
590
591
592
    /**
593
     * Sets description
594
     *
595
     * @param string $description
596
     * @throws EE_Error
597
     */
598
    public function set_description($description)
599
    {
600
        $this->set('TKT_description', $description);
601
    }
602
603
604
    /**
605
     * Gets start_date
606
     *
607
     * @param string $dt_frmt
608
     * @param string $tm_frmt
609
     * @return string
610
     * @throws EE_Error
611
     */
612
    public function start_date($dt_frmt = '', $tm_frmt = '')
613
    {
614
        return $this->_get_datetime('TKT_start_date', $dt_frmt, $tm_frmt);
615
    }
616
617
618
    /**
619
     * Sets start_date
620
     *
621
     * @param string $start_date
622
     * @return void
623
     * @throws EE_Error
624
     */
625
    public function set_start_date($start_date)
626
    {
627
        $this->_set_date_time('B', $start_date, 'TKT_start_date');
628
    }
629
630
631
    /**
632
     * Gets end_date
633
     *
634
     * @param string $dt_frmt
635
     * @param string $tm_frmt
636
     * @return string
637
     * @throws EE_Error
638
     */
639
    public function end_date($dt_frmt = '', $tm_frmt = '')
640
    {
641
        return $this->_get_datetime('TKT_end_date', $dt_frmt, $tm_frmt);
642
    }
643
644
645
    /**
646
     * Sets end_date
647
     *
648
     * @param string $end_date
649
     * @return void
650
     * @throws EE_Error
651
     */
652
    public function set_end_date($end_date)
653
    {
654
        $this->_set_date_time('B', $end_date, 'TKT_end_date');
655
    }
656
657
658
    /**
659
     * Sets sell until time
660
     *
661
     * @since 4.5.0
662
     * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
663
     * @throws EE_Error
664
     */
665
    public function set_end_time($time)
666
    {
667
        $this->_set_time_for($time, 'TKT_end_date');
668
    }
669
670
671
    /**
672
     * Sets min
673
     *
674
     * @param int $min
675
     * @return void
676
     * @throws EE_Error
677
     */
678
    public function set_min($min)
679
    {
680
        $this->set('TKT_min', $min);
681
    }
682
683
684
    /**
685
     * Gets max
686
     *
687
     * @return int
688
     * @throws EE_Error
689
     */
690
    public function max()
691
    {
692
        return $this->get('TKT_max');
693
    }
694
695
696
    /**
697
     * Sets max
698
     *
699
     * @param int $max
700
     * @return void
701
     * @throws EE_Error
702
     */
703
    public function set_max($max)
704
    {
705
        $this->set('TKT_max', $max);
706
    }
707
708
709
    /**
710
     * Sets price
711
     *
712
     * @param float $price
713
     * @return void
714
     * @throws EE_Error
715
     */
716
    public function set_price($price)
717
    {
718
        $this->set('TKT_price', $price);
719
    }
720
721
722
    /**
723
     * Gets sold
724
     *
725
     * @return int
726
     * @throws EE_Error
727
     */
728
    public function sold()
729
    {
730
        return $this->get_raw('TKT_sold');
731
    }
732
733
734
    /**
735
     * Sets sold
736
     *
737
     * @param int $sold
738
     * @return void
739
     * @throws EE_Error
740
     */
741
    public function set_sold($sold)
742
    {
743
        // sold can not go below zero
744
        $sold = max(0, $sold);
745
        $this->set('TKT_sold', $sold);
746
    }
747
748
749
    /**
750
     * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its
751
     * associated datetimes.
752
     *
753
     * @since $VID:$
754
     * @param int $qty
755
     * @return boolean
756
     * @throws EE_Error
757
     * @throws InvalidArgumentException
758
     * @throws InvalidDataTypeException
759
     * @throws InvalidInterfaceException
760
     * @throws ReflectionException
761
     */
762 View Code Duplication
    public function increaseSold($qty = 1)
763
    {
764
        $qty = absint($qty);
765
        // increment sold and decrement reserved datetime quantities simultaneously
766
        // don't worry about failures, because they must have already had a spot reserved
767
        $this->increaseSoldForDatetimes($qty);
768
        // Increment and decrement ticket quantities simultaneously
769
        $success = $this->adjustNumericFieldsInDb(
770
            [
771
                'TKT_reserved' => $qty * -1,
772
                'TKT_sold' => $qty
773
            ]
774
        );
775
        do_action(
776
            'AHEE__EE_Ticket__increase_sold',
777
            $this,
778
            $qty,
779
            $this->sold(),
780
            $success
781
        );
782
        return $success;
783
    }
784
785
    /**
786
     * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty.
787
     *
788
     * @since $VID:$
789
     * @param int $qty positive or negative. Positive means to increase sold counts (and decrease reserved counts),
790
     *             Negative means to decreases old counts (and increase reserved counts).
791
     * @param EE_Datetime[] $datetimes
792
     * @throws EE_Error
793
     * @throws InvalidArgumentException
794
     * @throws InvalidDataTypeException
795
     * @throws InvalidInterfaceException
796
     * @throws ReflectionException
797
     */
798
    protected function increaseSoldForDatetimes($qty, array $datetimes = [])
799
    {
800
        $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
801
        foreach ($datetimes as $datetime) {
802
            $datetime->increaseSold($qty);
803
        }
804
    }
805
806
807
808
    /**
809
     * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the
810
     * DB and then updates the model objects.
811
     * Does not affect the reserved counts.
812
     *
813
     * @since $VID:$
814
     * @param int $qty
815
     * @return boolean
816
     * @throws EE_Error
817
     * @throws InvalidArgumentException
818
     * @throws InvalidDataTypeException
819
     * @throws InvalidInterfaceException
820
     * @throws ReflectionException
821
     */
822 View Code Duplication
    public function decreaseSold($qty = 1)
823
    {
824
        $qty = absint($qty);
825
        $this->decreaseSoldForDatetimes($qty);
826
        $success = $this->adjustNumericFieldsInDb(
827
            [
828
                'TKT_sold' => $qty * -1
829
            ]
830
        );
831
        do_action(
832
            'AHEE__EE_Ticket__decrease_sold',
833
            $this,
834
            $qty,
835
            $this->sold(),
836
            $success
837
        );
838
        return $success;
839
    }
840
841
842
    /**
843
     * Decreases sold on related datetimes
844
     *
845
     * @since $VID:$
846
     * @param int $qty
847
     * @param EE_Datetime[] $datetimes
848
     * @return void
849
     * @throws EE_Error
850
     * @throws InvalidArgumentException
851
     * @throws InvalidDataTypeException
852
     * @throws InvalidInterfaceException
853
     * @throws ReflectionException
854
     */
855 View Code Duplication
    protected function decreaseSoldForDatetimes($qty = 1, array $datetimes = [])
856
    {
857
        $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
858
        if (is_array($datetimes)) {
859
            foreach ($datetimes as $datetime) {
860
                if ($datetime instanceof EE_Datetime) {
861
                    $datetime->decreaseSold($qty);
862
                }
863
            }
864
        }
865
    }
866
867
868
    /**
869
     * Gets qty of reserved tickets
870
     *
871
     * @return int
872
     * @throws EE_Error
873
     */
874
    public function reserved()
875
    {
876
        return $this->get_raw('TKT_reserved');
877
    }
878
879
880
    /**
881
     * Sets reserved
882
     *
883
     * @param int $reserved
884
     * @return void
885
     * @throws EE_Error
886
     */
887
    public function set_reserved($reserved)
888
    {
889
        // reserved can not go below zero
890
        $reserved = max(0, (int) $reserved);
891
        $this->set('TKT_reserved', $reserved);
892
    }
893
894
895
    /**
896
     * Increments reserved by amount passed by $qty, and persists it immediately to the database.
897
     *
898
     * @since $VID:$
899
     * @param int    $qty
900
     * @param string $source
901
     * @return bool whether we successfully reserved the ticket or not.
902
     * @throws EE_Error
903
     * @throws InvalidArgumentException
904
     * @throws ReflectionException
905
     * @throws InvalidDataTypeException
906
     * @throws InvalidInterfaceException
907
     */
908
    public function increaseReserved($qty = 1, $source = 'unknown')
909
    {
910
        $qty = absint($qty);
911
        do_action(
912
            'AHEE__EE_Ticket__increase_reserved__begin',
913
            $this,
914
            $qty,
915
            $source
916
        );
917
        $this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "{$qty} from {$source}");
918
        $success = false;
919
        $datetimes_adjusted_successfully = $this->increaseReservedForDatetimes($qty);
920
        if ($datetimes_adjusted_successfully) {
921
            $success = $this->incrementFieldConditionallyInDb(
922
                'TKT_reserved',
923
                'TKT_sold',
924
                'TKT_qty',
925
                $qty
926
            );
927
            if (! $success) {
928
                // The datetimes were successfully bumped, but not the
929
                // ticket. So we need to manually rollback the datetimes.
930
                $this->decreaseReservedForDatetimes($qty);
931
            }
932
        }
933
        do_action(
934
            'AHEE__EE_Ticket__increase_reserved',
935
            $this,
936
            $qty,
937
            $this->reserved(),
938
            $success
939
        );
940
        return $success;
941
    }
942
943
944
    /**
945
     * Increases reserved counts on related datetimes
946
     *
947
     * @since $VID:$
948
     * @param int $qty
949
     * @param EE_Datetime[] $datetimes
950
     * @return boolean indicating success
951
     * @throws EE_Error
952
     * @throws InvalidArgumentException
953
     * @throws InvalidDataTypeException
954
     * @throws InvalidInterfaceException
955
     * @throws ReflectionException
956
     */
957
    protected function increaseReservedForDatetimes($qty = 1, array $datetimes = [])
958
    {
959
        $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
960
        $datetimes_updated = [];
961
        $limit_exceeded = false;
962
        if (is_array($datetimes)) {
963
            foreach ($datetimes as $datetime) {
964
                if ($datetime instanceof EE_Datetime) {
965
                    if ($datetime->increaseReserved($qty)) {
966
                        $datetimes_updated[] = $datetime;
967
                    } else {
968
                        $limit_exceeded = true;
969
                        break;
970
                    }
971
                }
972
            }
973
            // If somewhere along the way we detected a datetime whose
974
            // limit was exceeded, do a manual rollback.
975
            if ($limit_exceeded) {
976
                $this->decreaseReservedForDatetimes($qty, $datetimes_updated);
977
                return false;
978
            }
979
        }
980
        return true;
981
    }
982
983
984
    /**
985
     * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
986
     *
987
     * @since $VID:$
988
     * @param int    $qty
989
     * @param bool   $adjust_datetimes
990
     * @param string $source
991
     * @return boolean
992
     * @throws EE_Error
993
     * @throws InvalidArgumentException
994
     * @throws ReflectionException
995
     * @throws InvalidDataTypeException
996
     * @throws InvalidInterfaceException
997
     */
998
    public function decreaseReserved($qty = 1, $adjust_datetimes = true, $source = 'unknown')
999
    {
1000
        $qty = absint($qty);
1001
        $this->add_extra_meta(EE_Ticket::META_KEY_TICKET_RESERVATIONS, "-{$qty} from {$source}");
1002
        if ($adjust_datetimes) {
1003
            $this->decreaseReservedForDatetimes($qty);
1004
        }
1005
        $success = $this->adjustNumericFieldsInDb(
1006
            [
1007
                'TKT_reserved' => $qty * -1
1008
            ]
1009
        );
1010
        do_action(
1011
            'AHEE__EE_Ticket__decrease_reserved',
1012
            $this,
1013
            $qty,
1014
            $this->reserved(),
1015
            $success
1016
        );
1017
        return $success;
1018
    }
1019
1020
1021
    /**
1022
     * Decreases the reserved count on the specified datetimes.
1023
     *
1024
     * @since $VID:$
1025
     * @param int           $qty
1026
     * @param EE_Datetime[] $datetimes
1027
     * @throws EE_Error
1028
     * @throws InvalidArgumentException
1029
     * @throws ReflectionException
1030
     * @throws InvalidDataTypeException
1031
     * @throws InvalidInterfaceException
1032
     */
1033 View Code Duplication
    protected function decreaseReservedForDatetimes($qty = 1, array $datetimes = [])
1034
    {
1035
        $datetimes = ! empty($datetimes) ? $datetimes : $this->datetimes();
1036
        foreach ($datetimes as $datetime) {
1037
            if ($datetime instanceof EE_Datetime) {
1038
                $datetime->decreaseReserved($qty);
1039
            }
1040
        }
1041
    }
1042
1043
1044
    /**
1045
     * Gets ticket quantity
1046
     *
1047
     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
1048
     *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
1049
     *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
1050
     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
1051
     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
1052
     *                            is therefore the truest measure of tickets that can be purchased at the moment
1053
     * @return int
1054
     * @throws EE_Error
1055
     */
1056
    public function qty($context = '')
1057
    {
1058
        switch ($context) {
1059
            case 'reg_limit':
1060
                return $this->real_quantity_on_ticket();
1061
            case 'saleable':
1062
                return $this->real_quantity_on_ticket('saleable');
1063
            default:
1064
                return $this->get_raw('TKT_qty');
1065
        }
1066
    }
1067
1068
1069
    /**
1070
     * Gets ticket quantity
1071
     *
1072
     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
1073
     *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
1074
     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
1075
     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
1076
     *                            is therefore the truest measure of tickets that can be purchased at the moment
1077
     * @param  int   $DTT_ID      the primary key for a particular datetime.
1078
     *                            set to 0 for all related datetimes
1079
     * @return int
1080
     * @throws EE_Error
1081
     */
1082
    public function real_quantity_on_ticket($context = 'reg_limit', $DTT_ID = 0)
1083
    {
1084
        $raw = $this->get_raw('TKT_qty');
1085
        // return immediately if it's zero
1086
        if ($raw === 0) {
1087
            return $raw;
1088
        }
1089
        // echo "\n\n<br />Ticket: " . $this->name() . '<br />';
1090
        // ensure qty doesn't exceed raw value for THIS ticket
1091
        $qty = min(EE_INF, $raw);
1092
        // echo "\n . qty: " . $qty . '<br />';
1093
        // calculate this ticket's total sales and reservations
1094
        $sold_and_reserved_for_this_ticket = $this->sold() + $this->reserved();
1095
        // echo "\n . sold: " . $this->sold() . '<br />';
1096
        // echo "\n . reserved: " . $this->reserved() . '<br />';
1097
        // echo "\n . sold_and_reserved_for_this_ticket: " . $sold_and_reserved_for_this_ticket . '<br />';
1098
        // first we need to calculate the maximum number of tickets available for the datetime
1099
        // do we want data for one datetime or all of them ?
1100
        $query_params = $DTT_ID ? array(array('DTT_ID' => $DTT_ID)) : array();
1101
        $datetimes = $this->datetimes($query_params);
1102
        if (is_array($datetimes) && ! empty($datetimes)) {
1103
            foreach ($datetimes as $datetime) {
1104
                if ($datetime instanceof EE_Datetime) {
1105
                    $datetime->refresh_from_db();
1106
                    // echo "\n . . datetime name: " . $datetime->name() . '<br />';
1107
                    // echo "\n . . datetime ID: " . $datetime->ID() . '<br />';
1108
                    // initialize with no restrictions for each datetime
1109
                    // but adjust datetime qty based on datetime reg limit
1110
                    $datetime_qty = min(EE_INF, $datetime->reg_limit());
1111
                    // echo "\n . . . datetime reg_limit: " . $datetime->reg_limit() . '<br />';
1112
                    // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1113
                    // if we want the actual saleable amount, then we need to consider OTHER ticket sales
1114
                    // and reservations for this datetime, that do NOT include sales and reservations
1115
                    // for this ticket (so we add $this->sold() and $this->reserved() back in)
1116
                    if ($context === 'saleable') {
1117
                        $datetime_qty = max(
1118
                            $datetime_qty - $datetime->sold_and_reserved() + $sold_and_reserved_for_this_ticket,
1119
                            0
1120
                        );
1121
                        // echo "\n . . . datetime sold: " . $datetime->sold() . '<br />';
1122
                        // echo "\n . . . datetime reserved: " . $datetime->reserved() . '<br />';
1123
                        // echo "\n . . . datetime sold_and_reserved: " . $datetime->sold_and_reserved() . '<br />';
1124
                        // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1125
                        $datetime_qty = ! $datetime->sold_out() ? $datetime_qty : 0;
1126
                        // echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1127
                    }
1128
                    $qty = min($datetime_qty, $qty);
1129
                    // echo "\n . . qty: " . $qty . '<br />';
1130
                }
1131
            }
1132
        }
1133
        // NOW that we know the  maximum number of tickets available for the datetime
1134
        // we can finally factor in the details for this specific ticket
1135
        if ($qty > 0 && $context === 'saleable') {
1136
            // and subtract the sales for THIS ticket
1137
            $qty = max($qty - $sold_and_reserved_for_this_ticket, 0);
1138
            // echo "\n . qty: " . $qty . '<br />';
1139
        }
1140
        // echo "\nFINAL QTY: " . $qty . "<br /><br />";
1141
        return $qty;
1142
    }
1143
1144
1145
    /**
1146
     * Sets qty - IMPORTANT!!! Does NOT allow QTY to be set higher than the lowest reg limit of any related datetimes
1147
     *
1148
     * @param int $qty
1149
     * @return void
1150
     * @throws EE_Error
1151
     */
1152
    public function set_qty($qty)
1153
    {
1154
        $datetimes = $this->datetimes();
1155
        foreach ($datetimes as $datetime) {
1156
            if ($datetime instanceof EE_Datetime) {
1157
                $qty = min($qty, $datetime->reg_limit());
1158
            }
1159
        }
1160
        $this->set('TKT_qty', $qty);
1161
    }
1162
1163
1164
    /**
1165
     * Gets uses
1166
     *
1167
     * @return int
1168
     * @throws EE_Error
1169
     */
1170
    public function uses()
1171
    {
1172
        return $this->get('TKT_uses');
1173
    }
1174
1175
1176
    /**
1177
     * Sets uses
1178
     *
1179
     * @param int $uses
1180
     * @return void
1181
     * @throws EE_Error
1182
     */
1183
    public function set_uses($uses)
1184
    {
1185
        $this->set('TKT_uses', $uses);
1186
    }
1187
1188
1189
    /**
1190
     * returns whether ticket is required or not.
1191
     *
1192
     * @return boolean
1193
     * @throws EE_Error
1194
     */
1195
    public function required()
1196
    {
1197
        return $this->get('TKT_required');
1198
    }
1199
1200
1201
    /**
1202
     * sets the TKT_required property
1203
     *
1204
     * @param boolean $required
1205
     * @return void
1206
     * @throws EE_Error
1207
     */
1208
    public function set_required($required)
1209
    {
1210
        $this->set('TKT_required', $required);
1211
    }
1212
1213
1214
    /**
1215
     * Gets taxable
1216
     *
1217
     * @return boolean
1218
     * @throws EE_Error
1219
     */
1220
    public function taxable()
1221
    {
1222
        return $this->get('TKT_taxable');
1223
    }
1224
1225
1226
    /**
1227
     * Sets taxable
1228
     *
1229
     * @param boolean $taxable
1230
     * @return void
1231
     * @throws EE_Error
1232
     */
1233
    public function set_taxable($taxable)
1234
    {
1235
        $this->set('TKT_taxable', $taxable);
1236
    }
1237
1238
1239
    /**
1240
     * Gets is_default
1241
     *
1242
     * @return boolean
1243
     * @throws EE_Error
1244
     */
1245
    public function is_default()
1246
    {
1247
        return $this->get('TKT_is_default');
1248
    }
1249
1250
1251
    /**
1252
     * Sets is_default
1253
     *
1254
     * @param boolean $is_default
1255
     * @return void
1256
     * @throws EE_Error
1257
     */
1258
    public function set_is_default($is_default)
1259
    {
1260
        $this->set('TKT_is_default', $is_default);
1261
    }
1262
1263
1264
    /**
1265
     * Gets order
1266
     *
1267
     * @return int
1268
     * @throws EE_Error
1269
     */
1270
    public function order()
1271
    {
1272
        return $this->get('TKT_order');
1273
    }
1274
1275
1276
    /**
1277
     * Sets order
1278
     *
1279
     * @param int $order
1280
     * @return void
1281
     * @throws EE_Error
1282
     */
1283
    public function set_order($order)
1284
    {
1285
        $this->set('TKT_order', $order);
1286
    }
1287
1288
1289
    /**
1290
     * Gets row
1291
     *
1292
     * @return int
1293
     * @throws EE_Error
1294
     */
1295
    public function row()
1296
    {
1297
        return $this->get('TKT_row');
1298
    }
1299
1300
1301
    /**
1302
     * Sets row
1303
     *
1304
     * @param int $row
1305
     * @return void
1306
     * @throws EE_Error
1307
     */
1308
    public function set_row($row)
1309
    {
1310
        $this->set('TKT_row', $row);
1311
    }
1312
1313
1314
    /**
1315
     * Gets deleted
1316
     *
1317
     * @return boolean
1318
     * @throws EE_Error
1319
     */
1320
    public function deleted()
1321
    {
1322
        return $this->get('TKT_deleted');
1323
    }
1324
1325
1326
    /**
1327
     * Sets deleted
1328
     *
1329
     * @param boolean $deleted
1330
     * @return void
1331
     * @throws EE_Error
1332
     */
1333
    public function set_deleted($deleted)
1334
    {
1335
        $this->set('TKT_deleted', $deleted);
1336
    }
1337
1338
1339
    /**
1340
     * Gets parent
1341
     *
1342
     * @return int
1343
     * @throws EE_Error
1344
     */
1345
    public function parent_ID()
1346
    {
1347
        return $this->get('TKT_parent');
1348
    }
1349
1350
1351
    /**
1352
     * Sets parent
1353
     *
1354
     * @param int $parent
1355
     * @return void
1356
     * @throws EE_Error
1357
     */
1358
    public function set_parent_ID($parent)
1359
    {
1360
        $this->set('TKT_parent', $parent);
1361
    }
1362
1363
1364
    /**
1365
     * Gets a string which is handy for showing in gateways etc that describes the ticket.
1366
     *
1367
     * @return string
1368
     * @throws EE_Error
1369
     */
1370
    public function name_and_info()
1371
    {
1372
        $times = array();
1373
        foreach ($this->datetimes() as $datetime) {
1374
            $times[] = $datetime->start_date_and_time();
1375
        }
1376
        return $this->name() . ' @ ' . implode(', ', $times) . ' for ' . $this->pretty_price();
1377
    }
1378
1379
1380
    /**
1381
     * Gets name
1382
     *
1383
     * @return string
1384
     * @throws EE_Error
1385
     */
1386
    public function name()
1387
    {
1388
        return $this->get('TKT_name');
1389
    }
1390
1391
1392
    /**
1393
     * Gets price
1394
     *
1395
     * @return float
1396
     * @throws EE_Error
1397
     */
1398
    public function price()
1399
    {
1400
        return $this->get('TKT_price');
1401
    }
1402
1403
1404
    /**
1405
     * Gets all the registrations for this ticket
1406
     *
1407
     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1408
     * @return EE_Registration[]|EE_Base_Class[]
1409
     * @throws EE_Error
1410
     */
1411
    public function registrations($query_params = array())
1412
    {
1413
        return $this->get_many_related('Registration', $query_params);
1414
    }
1415
1416
1417
    /**
1418
     * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1419
     *
1420
     * @return int
1421
     * @throws EE_Error
1422
     */
1423 View Code Duplication
    public function update_tickets_sold()
1424
    {
1425
        $count_regs_for_this_ticket = $this->count_registrations(
1426
            array(
1427
                array(
1428
                    'STS_ID'      => EEM_Registration::status_id_approved,
1429
                    'REG_deleted' => 0,
1430
                ),
1431
            )
1432
        );
1433
        $this->set_sold($count_regs_for_this_ticket);
1434
        $this->save();
1435
        return $count_regs_for_this_ticket;
1436
    }
1437
1438
1439
    /**
1440
     * Counts the registrations for this ticket
1441
     *
1442
     * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1443
     * @return int
1444
     */
1445
    public function count_registrations($query_params = array())
1446
    {
1447
        return $this->count_related('Registration', $query_params);
1448
    }
1449
1450
1451
    /**
1452
     * Implementation for EEI_Has_Icon interface method.
1453
     *
1454
     * @see EEI_Visual_Representation for comments
1455
     * @return string
1456
     */
1457
    public function get_icon()
1458
    {
1459
        return '<span class="dashicons dashicons-tickets-alt"></span>';
1460
    }
1461
1462
1463
    /**
1464
     * Implementation of the EEI_Event_Relation interface method
1465
     *
1466
     * @see EEI_Event_Relation for comments
1467
     * @return EE_Event
1468
     * @throws EE_Error
1469
     * @throws UnexpectedEntityException
1470
     */
1471
    public function get_related_event()
1472
    {
1473
        // get one datetime to use for getting the event
1474
        $datetime = $this->first_datetime();
1475
        if (! $datetime instanceof \EE_Datetime) {
1476
            throw new UnexpectedEntityException(
1477
                $datetime,
1478
                'EE_Datetime',
1479
                sprintf(
1480
                    __('The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1481
                    $this->name()
1482
                )
1483
            );
1484
        }
1485
        $event = $datetime->event();
1486
        if (! $event instanceof \EE_Event) {
1487
            throw new UnexpectedEntityException(
1488
                $event,
1489
                'EE_Event',
1490
                sprintf(
1491
                    __('The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1492
                    $this->name()
1493
                )
1494
            );
1495
        }
1496
        return $event;
1497
    }
1498
1499
1500
    /**
1501
     * Implementation of the EEI_Event_Relation interface method
1502
     *
1503
     * @see EEI_Event_Relation for comments
1504
     * @return string
1505
     * @throws UnexpectedEntityException
1506
     * @throws EE_Error
1507
     */
1508
    public function get_event_name()
1509
    {
1510
        $event = $this->get_related_event();
1511
        return $event instanceof EE_Event ? $event->name() : '';
1512
    }
1513
1514
1515
    /**
1516
     * Implementation of the EEI_Event_Relation interface method
1517
     *
1518
     * @see EEI_Event_Relation for comments
1519
     * @return int
1520
     * @throws UnexpectedEntityException
1521
     * @throws EE_Error
1522
     */
1523
    public function get_event_ID()
1524
    {
1525
        $event = $this->get_related_event();
1526
        return $event instanceof EE_Event ? $event->ID() : 0;
1527
    }
1528
1529
1530
    /**
1531
     * This simply returns whether a ticket can be permanently deleted or not.
1532
     * The criteria for determining this is whether the ticket has any related registrations.
1533
     * If there are none then it can be permanently deleted.
1534
     *
1535
     * @return bool
1536
     */
1537
    public function is_permanently_deleteable()
1538
    {
1539
        return $this->count_registrations() === 0;
1540
    }
1541
1542
1543
    /*******************************************************************
1544
     ***********************  DEPRECATED METHODS  **********************
1545
     *******************************************************************/
1546
1547
1548
    /**
1549
     * Increments sold by amount passed by $qty AND decrements the reserved count on both this ticket and its
1550
     * associated datetimes.
1551
     *
1552
     * @deprecated $VID:$
1553
     * @param int $qty
1554
     * @return void
1555
     * @throws EE_Error
1556
     * @throws InvalidArgumentException
1557
     * @throws InvalidDataTypeException
1558
     * @throws InvalidInterfaceException
1559
     * @throws ReflectionException
1560
     */
1561
    public function increase_sold($qty = 1)
1562
    {
1563
        EE_Error::doing_it_wrong(
1564
            __FUNCTION__,
1565
            esc_html__('Please use EE_Ticket::increaseSold() instead', 'event_espresso'),
1566
            '$VID:$',
1567
            '5.0.0.p'
1568
        );
1569
        $this->increaseSold($qty);
1570
    }
1571
1572
1573
    /**
1574
     * On each datetime related to this ticket, increases its sold count and decreases its reserved count by $qty.
1575
     *
1576
     * @deprecated $VID:$
1577
     * @param int $qty positive or negative. Positive means to increase sold counts (and decrease reserved counts),
1578
     *                 Negative means to decreases old counts (and increase reserved counts).
1579
     * @throws EE_Error
1580
     * @throws InvalidArgumentException
1581
     * @throws InvalidDataTypeException
1582
     * @throws InvalidInterfaceException
1583
     * @throws ReflectionException
1584
     */
1585
    protected function _increase_sold_for_datetimes($qty)
1586
    {
1587
        EE_Error::doing_it_wrong(
1588
            __FUNCTION__,
1589
            esc_html__('Please use EE_Ticket::increaseSoldForDatetimes() instead', 'event_espresso'),
1590
            '$VID:$',
1591
            '5.0.0.p'
1592
        );
1593
        $this->increaseSoldForDatetimes($qty);
1594
    }
1595
1596
1597
    /**
1598
     * Decrements (subtracts) sold by amount passed by $qty on both the ticket and its related datetimes directly in the
1599
     * DB and then updates the model objects.
1600
     * Does not affect the reserved counts.
1601
     *
1602
     * @deprecated $VID:$
1603
     * @param int $qty
1604
     * @return void
1605
     * @throws EE_Error
1606
     * @throws InvalidArgumentException
1607
     * @throws InvalidDataTypeException
1608
     * @throws InvalidInterfaceException
1609
     * @throws ReflectionException
1610
     */
1611
    public function decrease_sold($qty = 1)
1612
    {
1613
        EE_Error::doing_it_wrong(
1614
            __FUNCTION__,
1615
            esc_html__('Please use EE_Ticket::decreaseSold() instead', 'event_espresso'),
1616
            '$VID:$',
1617
            '5.0.0.p'
1618
        );
1619
        $this->decreaseSold($qty);
1620
    }
1621
1622
1623
    /**
1624
     * Decreases sold on related datetimes
1625
     *
1626
     * @deprecated $VID:$
1627
     * @param int $qty
1628
     * @return void
1629
     * @throws EE_Error
1630
     * @throws InvalidArgumentException
1631
     * @throws InvalidDataTypeException
1632
     * @throws InvalidInterfaceException
1633
     * @throws ReflectionException
1634
     */
1635
    protected function _decrease_sold_for_datetimes($qty = 1)
1636
    {
1637
        EE_Error::doing_it_wrong(
1638
            __FUNCTION__,
1639
            esc_html__('Please use EE_Ticket::decreaseSoldForDatetimes() instead', 'event_espresso'),
1640
            '$VID:$',
1641
            '5.0.0.p'
1642
        );
1643
        $this->decreaseSoldForDatetimes($qty);
1644
    }
1645
1646
1647
    /**
1648
     * Increments reserved by amount passed by $qty, and persists it immediately to the database.
1649
     *
1650
     * @deprecated $VID:$
1651
     * @param int    $qty
1652
     * @param string $source
1653
     * @return bool whether we successfully reserved the ticket or not.
1654
     * @throws EE_Error
1655
     * @throws InvalidArgumentException
1656
     * @throws ReflectionException
1657
     * @throws InvalidDataTypeException
1658
     * @throws InvalidInterfaceException
1659
     */
1660
    public function increase_reserved($qty = 1, $source = 'unknown')
1661
    {
1662
        EE_Error::doing_it_wrong(
1663
            __FUNCTION__,
1664
            esc_html__('Please use EE_Ticket::increaseReserved() instead', 'event_espresso'),
1665
            '$VID:$',
1666
            '5.0.0.p'
1667
        );
1668
        return $this->increaseReserved($qty);
1669
    }
1670
1671
1672
    /**
1673
     * Increases sold on related datetimes
1674
     *
1675
     * @deprecated $VID:$
1676
     * @param int $qty
1677
     * @return boolean indicating success
1678
     * @throws EE_Error
1679
     * @throws InvalidArgumentException
1680
     * @throws InvalidDataTypeException
1681
     * @throws InvalidInterfaceException
1682
     * @throws ReflectionException
1683
     */
1684
    protected function _increase_reserved_for_datetimes($qty = 1)
1685
    {
1686
        EE_Error::doing_it_wrong(
1687
            __FUNCTION__,
1688
            esc_html__('Please use EE_Ticket::increaseReservedForDatetimes() instead', 'event_espresso'),
1689
            '$VID:$',
1690
            '5.0.0.p'
1691
        );
1692
        return $this->increaseReservedForDatetimes($qty);
1693
    }
1694
1695
1696
    /**
1697
     * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database.
1698
     *
1699
     * @deprecated $VID:$
1700
     * @param int    $qty
1701
     * @param bool   $adjust_datetimes
1702
     * @param string $source
1703
     * @return void
1704
     * @throws EE_Error
1705
     * @throws InvalidArgumentException
1706
     * @throws ReflectionException
1707
     * @throws InvalidDataTypeException
1708
     * @throws InvalidInterfaceException
1709
     */
1710
    public function decrease_reserved($qty = 1, $adjust_datetimes = true, $source = 'unknown')
1711
    {
1712
        EE_Error::doing_it_wrong(
1713
            __FUNCTION__,
1714
            esc_html__('Please use EE_Ticket::decreaseReserved() instead', 'event_espresso'),
1715
            '$VID:$',
1716
            '5.0.0.p'
1717
        );
1718
        $this->decreaseReserved($qty);
1719
    }
1720
1721
1722
    /**
1723
     * Decreases reserved on related datetimes
1724
     *
1725
     * @deprecated $VID:$
1726
     * @param int $qty
1727
     * @return void
1728
     * @throws EE_Error
1729
     * @throws InvalidArgumentException
1730
     * @throws ReflectionException
1731
     * @throws InvalidDataTypeException
1732
     * @throws InvalidInterfaceException
1733
     */
1734
    protected function _decrease_reserved_for_datetimes($qty = 1)
1735
    {
1736
        EE_Error::doing_it_wrong(
1737
            __FUNCTION__,
1738
            esc_html__('Please use EE_Ticket::decreaseReservedForDatetimes() instead', 'event_espresso'),
1739
            '$VID:$',
1740
            '5.0.0.p'
1741
        );
1742
        $this->decreaseReservedForDatetimes($qty);
1743
    }
1744
}
1745