Issues (42)

src/Model/Discount.php (13 issues)

1
<?php
2
3
namespace Dynamic\Foxy\Discounts\Model;
4
5
use SilverStripe\Forms\FieldList;
6
use SilverStripe\Forms\GridField\GridField;
7
use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter;
8
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
9
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
10
use SilverStripe\ORM\DataObject;
11
use SilverStripe\ORM\HasManyList;
12
use SilverStripe\ORM\ValidationException;
13
use SilverStripe\Security\Permission;
14
use SilverStripe\Versioned\Versioned;
15
16
/**
17
 * Class Discount
18
 * @package Dynamic\Foxy\Discounts\Model
19
 *
20
 * @property string $Title
21
 * @property string $StartTime
22
 * @property string $EndTime
23
 * @property string $Type
24
 * @method HasManyList DiscountTiers()
25
 */
26
class Discount extends DataObject
27
{
28
    /**
29
     * @var string
30
     */
31
    private static $singular_name = 'Discount';
0 ignored issues
show
The private property $singular_name is not used, and could be removed.
Loading history...
32
33
    /**
34
     * @var string
35
     */
36
    private static $plural_name = 'Discounts';
0 ignored issues
show
The private property $plural_name is not used, and could be removed.
Loading history...
37
38
    /**
39
     * This will relay the total amount based on discount, option and quantity if true.
40
     * If false, it will assume the quantity is 1
41
     *
42
     * @var bool
43
     */
44
    private static $calculate_total = false;
0 ignored issues
show
The private property $calculate_total is not used, and could be removed.
Loading history...
45
46
    /**
47
     * @var array
48
     */
49
    private static $db = [
0 ignored issues
show
The private property $db is not used, and could be removed.
Loading history...
50
        'Title' => 'Varchar(255)',
51
        'StartTime' => 'DBDatetime',
52
        'EndTime' => 'DBDatetime',
53
        'Type' => 'Enum("Percent, Amount")',
54
    ];
55
56
    /**
57
     * @var array
58
     */
59
    private static $has_many = [
0 ignored issues
show
The private property $has_many is not used, and could be removed.
Loading history...
60
        'DiscountTiers' => DiscountTier::class,
61
    ];
62
63
    /**
64
     * @var array
65
     */
66
    private static $summary_fields = [
0 ignored issues
show
The private property $summary_fields is not used, and could be removed.
Loading history...
67
        'Title',
68
        'StartTime.Nice' => 'Starts',
69
        'EndTime.Nice' => 'Ends',
70
        'IsActive' => 'Active',
71
        'IsGlobal' => 'Global',
72
        'Products.count' => 'Products',
73
    ];
74
75
    /**
76
     * @var array
77
     */
78
    private static $casting = [
0 ignored issues
show
The private property $casting is not used, and could be removed.
Loading history...
79
        'IsActive' => 'Boolean',
80
        'IsGlobal' => 'Boolean',
81
    ];
82
83
    /**
84
     * @var array
85
     */
86
    private static $extensions = [
0 ignored issues
show
The private property $extensions is not used, and could be removed.
Loading history...
87
        Versioned::class,
88
    ];
89
90
    /**
91
     * @var string
92
     */
93
    private static $table_name = 'FoxyDiscount';
0 ignored issues
show
The private property $table_name is not used, and could be removed.
Loading history...
94
95
    /**
96
     * @var array
97
     */
98
    private $type_mapping = [
99
        'Percent' => 'discount_quantity_percentage',
100
        'Amount' => 'discount_quantity_amount',
101
    ];
102
103
    /**
104
     * @return FieldList
105
     */
106
    public function getCMSFields()
107
    {
108
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
109
            if ($this->ID) {
110
                $fields->removeByName([
111
                    'DiscountTiers',
112
                ]);
113
114
                // ProductDiscountTiers
115
                $config = GridFieldConfig_RelationEditor::create();
116
                $config
117
                    ->removeComponentsByType([
118
                        GridFieldAddExistingAutocompleter::class,
119
                        GridFieldDeleteAction::class,
120
                    ])
121
                    ->addComponents([
122
                        new GridFieldDeleteAction(false),
123
                    ]);
124
                $discountGrid = GridField::create(
125
                    'DiscountTiers',
126
                    'Discount Tiers',
127
                    $this->owner->DiscountTiers(),
0 ignored issues
show
The method DiscountTiers() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

127
                    $this->owner->/** @scrutinizer ignore-call */ 
128
                                  DiscountTiers(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug Best Practice introduced by
The property owner does not exist on Dynamic\Foxy\Discounts\Model\Discount. Since you implemented __get, consider adding a @property annotation.
Loading history...
128
                    $config
129
                );
130
                $fields->addFieldToTab('Root.Main', $discountGrid);
131
            }
132
        });
133
134
        return parent::getCMSFields();
135
    }
136
137
    /**
138
     * @throws ValidationException
139
     */
140
    public function onAfterWrite()
141
    {
142
        parent::onAfterWrite();
143
144
        if ($this->isChanged('Type')) {
145
            $this->DiscountTiers()->each(function (DiscountTier $tier) {
146
                $tier->write();
147
            });
148
        }
149
    }
150
151
    /**
152
     * @return bool
153
     */
154
    public function getIsActive()
155
    {
156
        $date = date('Y-m-d H:i:s', strtotime('now'));
157
158
        return ($this->owner->StartTime <= $date && $this->owner->EndTime >= $date) && $this->owner->isPublished();
0 ignored issues
show
Bug Best Practice introduced by
The property owner does not exist on Dynamic\Foxy\Discounts\Model\Discount. Since you implemented __get, consider adding a @property annotation.
Loading history...
159
    }
160
161
    /**
162
     * @return bool
163
     */
164
    public function getIsGlobal()
165
    {
166
        return $this->Products()->count() === 0;
0 ignored issues
show
The method Products() does not exist on Dynamic\Foxy\Discounts\Model\Discount. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

166
        return $this->/** @scrutinizer ignore-call */ Products()->count() === 0;
Loading history...
167
    }
168
169
    /**
170
     * @return mixed
171
     */
172
    public function getDiscountType()
173
    {
174
        $types = $this->type_mapping;
175
176
        return $types[$this->Type];
177
    }
178
179
    /**
180
     * Basic permissions, defaults to page perms where possible.
181
     *
182
     * @param \SilverStripe\Security\Member|null $member
183
     * @return boolean
184
     */
185
    public function canView($member = null)
186
    {
187
        $extended = $this->extendedCan(__FUNCTION__, $member);
188
        if ($extended !== null) {
189
            return $extended;
190
        }
191
192
        return Permission::check('CMS_ACCESS', 'any', $member);
193
    }
194
195
    /**
196
     * Basic permissions, defaults to page perms where possible.
197
     *
198
     * @param \SilverStripe\Security\Member|null $member
199
     *
200
     * @return boolean
201
     */
202
    public function canEdit($member = null)
203
    {
204
        $extended = $this->extendedCan(__FUNCTION__, $member);
205
        if ($extended !== null) {
206
            return $extended;
207
        }
208
209
        return Permission::check('CMS_ACCESS', 'any', $member);
210
    }
211
212
    /**
213
     * Basic permissions, defaults to page perms where possible.
214
     *
215
     * Uses archive not delete so that current stage is respected i.e if a
216
     * element is not published, then it can be deleted by someone who doesn't
217
     * have publishing permissions.
218
     *
219
     * @param \SilverStripe\Security\Member|null $member
220
     *
221
     * @return boolean
222
     */
223
    public function canDelete($member = null)
224
    {
225
        $extended = $this->extendedCan(__FUNCTION__, $member);
226
        if ($extended !== null) {
227
            return $extended;
228
        }
229
230
231
        return Permission::check('CMS_ACCESS', 'any', $member);
232
    }
233
234
    /**
235
     * Basic permissions, defaults to page perms where possible.
236
     *
237
     * @param \SilverStripe\Security\Member|null $member
238
     * @param array $context
239
     *
240
     * @return boolean
241
     */
242
    public function canCreate($member = null, $context = [])
243
    {
244
        $extended = $this->extendedCan(__FUNCTION__, $member);
245
        if ($extended !== null) {
246
            return $extended;
247
        }
248
249
        return Permission::check('CMS_ACCESS', 'any', $member);
250
    }
251
252
    /**
253
     * @param int $quantity
254
     * @return DataObject|null
255
     */
256
    public function getTierByQuantity($quantity = 1)
257
    {
258
        $sort = $this->Type == 'Percent' ? 'Percentage DESC' : 'Amount DESC';
259
        return $this->DiscountTiers()->filter('Quantity:LessThanOrEqual', $quantity)->sort($sort)->first();
260
    }
261
}
262