Completed
Push — master ( 3838fd...656106 )
by Scott
02:37
created

Discount::scopeIsNotExpired()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
1
<?php namespace Bedard\Shop\Models;
2
3
use Carbon\Carbon;
4
use Flash;
5
use Lang;
6
use Model;
7
use October\Rain\Database\ModelException;
8
9
/**
10
 * Discount Model.
11
 */
12
class Discount extends Model
13
{
14
    use \Bedard\Shop\Traits\Subqueryable,
15
        \Bedard\Shop\Traits\Timeable,
16
        \October\Rain\Database\Traits\Purgeable,
17
        \October\Rain\Database\Traits\Validation;
18
19
    /**
20
     * @var string The database table used by the model.
21
     */
22
    public $table = 'bedard_shop_discounts';
23
24
    /**
25
     * @var array Default attributes
26
     */
27
    public $attributes = [
28
        'is_percentage' => true,
29
    ];
30
31
    /**
32
     * @var array Attribute casting
33
     */
34
    protected $casts = [
35
        //
36
    ];
37
38
    /**
39
     * @var array Date casting
40
     */
41
    protected $dates = [
42
        'end_at',
43
        'start_at',
44
    ];
45
46
    /**
47
     * @var array Guarded fields
48
     */
49
    protected $guarded = ['*'];
50
51
    /**
52
     * @var array Fillable fields
53
     */
54
    protected $fillable = [
55
        'amount',
56
        'amount_exact',
57
        'amount_percentage',
58
        'end_at',
59
        'is_percentage',
60
        'name',
61
        'start_at',
62
    ];
63
64
    /**
65
     * @var array Purgeable vields
66
     */
67
    protected $purgeable = [
68
        'amount_exact',
69
        'amount_percentage',
70
    ];
71
72
    /**
73
     * @var array Relations
74
     */
75
    public $belongsToMany = [
76
        'categories' => [
77
            'Bedard\Shop\Models\Category',
78
            'table' => 'bedard_shop_category_discount',
79
        ],
80
        'products' => [
81
            'Bedard\Shop\Models\Product',
82
            'table' => 'bedard_shop_discount_product',
83
        ],
84
    ];
85
86
    public $hasMany = [
87
        'prices' => [
88
            'Bedard\Shop\Models\Price',
89
            'delete' => true,
90
        ],
91
    ];
92
93
    /**
94
     * @var  array Validation rules
95
     */
96
    public $rules = [
97
        'end_at' => 'date',
98
        'name' => 'required',
99
        'start_at' => 'date',
100
        'amount_exact' => 'numeric|min:0',
101
        'amount_percentage' => 'integer|min:0',
102
    ];
103
104
    /**
105
     * After validate.
106
     *
107
     * @return void
108
     */
109
    public function afterValidate()
110
    {
111
        $this->validateDates();
112
    }
113
114
    /**
115
     * Before save.
116
     *
117
     * @return void
118
     */
119
    public function beforeSave()
120
    {
121
        $this->setAmount();
122
    }
123
124
    /**
125
     * Filter form fields.
126
     *
127
     * @param  object   $fields
128
     * @return void
129
     */
130
    public function filterFields($fields)
131
    {
132
        $fields->amount_exact->hidden = $this->is_percentage;
133
        $fields->amount_percentage->hidden = ! $this->is_percentage;
134
    }
135
136
    /**
137
     * This exists to makes statuses sortable by assigning them a value.
138
     *
139
     * Expired  0
140
     * Running  1
141
     * Upcoming 2
142
     *
143
     * @param  \October\Rain\Database\Builder   $query
144
     * @return \October\Rain\Database\Builder
145
     */
146
    public function scopeSelectStatus($query)
147
    {
148
        $grammar = $query->getQuery()->getGrammar();
149
        $start_at = $grammar->wrap($this->table.'.start_at');
150
        $end_at = $grammar->wrap($this->table.'.end_at');
151
        $now = Carbon::now();
152
153
        $subquery = 'CASE '.
154
            "WHEN ({$end_at} IS NOT NULL AND {$end_at} < '{$now}') THEN 0 ".
155
            "WHEN ({$start_at} IS NOT NULL AND {$start_at} > '{$now}') THEN 2 ".
156
            'ELSE 1 '.
157
        'END';
158
159
        return $query->selectSubquery($subquery, 'status');
160
    }
161
162
    /**
163
     * Set the discount amount.
164
     *
165
     * @return  void
166
     */
167
    public function setAmount()
168
    {
169
        $exact = $this->getOriginalPurgeValue('amount_exact');
170
        $percentage = $this->getOriginalPurgeValue('amount_percentage');
171
172
        $this->amount = $this->is_percentage
173
            ? $percentage
174
            : $exact;
175
    }
176
177
    /**
178
     * Ensure the start and end dates are valid.
179
     *
180
     * @return void
181
     */
182
    public function validateDates()
183
    {
184
        // Start date must be after the end date
185
        if ($this->start_at !== null &&
186
            $this->end_at !== null &&
187
            $this->start_at >= $this->end_at) {
188
            Flash::error(Lang::get('bedard.shop::lang.discounts.form.start_at_invalid'));
189
            throw new ModelException($this);
190
        }
191
    }
192
}
193