Passed
Pull Request — master (#371)
by Jason
11:20
created

ProductCategory::validate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 8
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 6
1
<?php
2
3
namespace Dynamic\FoxyStripe\Model;
4
5
use SilverStripe\Forms\DropdownField;
6
use SilverStripe\Forms\FieldList;
7
use SilverStripe\Forms\HeaderField;
8
use SilverStripe\Forms\OptionsetField;
9
use SilverStripe\Forms\ReadonlyField;
10
use SilverStripe\ORM\DataObject;
11
use SilverStripe\Security\Permission;
12
13
/**
14
 * Class ProductCategory
15
 * @package Dynamic\FoxyStripe\Model
16
 *
17
 * @property \SilverStripe\ORM\FieldType\DBVarchar Title
18
 * @property \SilverStripe\ORM\FieldType\DBVarchar Code
19
 * @property \SilverStripe\ORM\FieldType\DBVarchar DeliveryType
20
 * @property \SilverStripe\ORM\FieldType\DBInt MaxDownloads
21
 * @property \SilverStripe\ORM\FieldType\DBInt MaxDownloadsTime
22
 * @property \SilverStripe\ORM\FieldType\DBFloat DefaultWeight
23
 * @property \SilverStripe\ORM\FieldType\DBEnum DefaultWeightUnit
24
 * @property \SilverStripe\ORM\FieldType\DBEnum DefaultLengthUnit
25
 * @property \SilverStripe\ORM\FieldType\DBCurrency ShippingFlatRate
26
 * @property \SilverStripe\ORM\FieldType\DBVarchar ShippingFlatRateType
27
 * @property \SilverStripe\ORM\FieldType\DBVarchar HandlingFeeType
28
 * @property \SilverStripe\ORM\FieldType\DBCurrency HandlingFee
29
 * @property \SilverStripe\ORM\FieldType\DBDecimal HandlingFeePercentage
30
 * @property \SilverStripe\ORM\FieldType\DBCurrency HandlingFeeMinimum
31
 * @property \SilverStripe\ORM\FieldType\DBVarchar DiscountType
32
 * @property \SilverStripe\ORM\FieldType\DBVarchar DiscountName
33
 * @property \SilverStripe\ORM\FieldType\DBVarchar DiscountDetails
34
 * @property \SilverStripe\ORM\FieldType\DBCurrency CustomsValue
35
 */
36
class ProductCategory extends DataObject
37
{
38
    /**
39
     * @var array
40
     */
41
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
42
        'Title' => 'Varchar(255)',
43
        'Code' => 'Varchar(50)',
44
        'DeliveryType' => 'Varchar(50)',
45
        'MaxDownloads' => 'Int',
46
        'MaxDownloadsTime' => 'Int',
47
        'DefaultWeight' => 'Float',
48
        'DefaultWeightUnit' => 'Enum("LBS, KBS", "LBS")',
49
        'DefaultLengthUnit' => 'Enum("in, cm", "in")',
50
        'ShippingFlatRate' => 'Currency',
51
        'ShippingFlatRateType' => 'Varchar(50)',
52
        'HandlingFeeType' => 'Varchar(50)',
53
        'HandlingFee' => 'Currency',
54
        'HandlingFeePercentage' => 'Decimal',
55
        'HandlingFeeMinimum' => 'Currency',
56
        'DiscountType' => 'Varchar(50)',
57
        'DiscountName' => 'Varchar(50)',
58
        'DiscountDetails' => 'Varchar(200)',
59
        'CustomsValue' => 'Currency',
60
    ];
61
62
    /**
63
     * @var string
64
     */
65
    private static $singular_name = 'FoxyCart Category';
0 ignored issues
show
introduced by
The private property $singular_name is not used, and could be removed.
Loading history...
66
67
    /**
68
     * @var string
69
     */
70
    private static $plural_name = 'FoxyCart Categories';
0 ignored issues
show
introduced by
The private property $plural_name is not used, and could be removed.
Loading history...
71
72
    /**
73
     * @var string
74
     */
75
    private static $description = 'Set the FoxyCart Category on a Product';
0 ignored issues
show
introduced by
The private property $description is not used, and could be removed.
Loading history...
76
77
    /**
78
     * @var array
79
     */
80
    private static $summary_fields = [
0 ignored issues
show
introduced by
The private property $summary_fields is not used, and could be removed.
Loading history...
81
        'Title' => 'Name',
82
        'Code' => 'Code',
83
    ];
84
85
    /**
86
     * @var array
87
     */
88
    private static $indexes = [
0 ignored issues
show
introduced by
The private property $indexes is not used, and could be removed.
Loading history...
89
        'Code' => [
90
            'type' => 'unique',
91
            'columns' => ['Code'],
92
        ],
93
    ];
94
95
    /**
96
     * @var string
97
     */
98
    private static $table_name = 'ProductCategory';
0 ignored issues
show
introduced by
The private property $table_name is not used, and could be removed.
Loading history...
99
100 1
    /**
101
     * @return FieldList
102 1
     */
103
    public function getCMSFields()
104 1
    {
105 1
        $fields = parent::getCMSFields();
106
107
        if ($this->ID) {
108
            if ($this->Title == 'Default') {
0 ignored issues
show
introduced by
The condition $this->Title == 'Default' is always false.
Loading history...
109
                $fields->replaceField(
110
                    'Title',
111
                    ReadonlyField::create('Title')
112 1
                );
113 1
            }
114 1
115
            $fields->replaceField(
116
                'Code',
117
                ReadonlyField::create('Code')
118 1
            );
119
        }
120 1
121 1
        $fields->insertBefore(HeaderField::create('DeliveryHD', 'Delivery Options', 3), 'DeliveryType');
0 ignored issues
show
Bug introduced by
'DeliveryType' of type string is incompatible with the type SilverStripe\Forms\FormField expected by parameter $item of SilverStripe\Forms\FieldList::insertBefore(). ( Ignorable by Annotation )

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

121
        $fields->insertBefore(HeaderField::create('DeliveryHD', 'Delivery Options', 3), /** @scrutinizer ignore-type */ 'DeliveryType');
Loading history...
122 1
123
        $fields->replaceField(
124
            'DeliveryType',
125 1
            OptionsetField::create('DeliveryType', 'Delivery Type', $this->getShippingOptions())
126 1
        );
127
128 1
        $fields->dataFieldByName('MaxDownloads')
129 1
            ->displayIf('DeliveryType')->isEqualTo('downloaded');
130
131 1
        $fields->dataFieldByName('MaxDownloadsTime')
132 1
            ->displayIf('DeliveryType')->isEqualTo('downloaded');
133
134 1
        $fields->dataFieldByName('DefaultWeight')
135 1
            ->displayIf('DeliveryType')->isEqualTo('shipped');
136
137 1
        $fields->dataFieldByName('DefaultWeightUnit')
138 1
            ->displayIf('DeliveryType')->isEqualTo('shipped');
139
140 1
        $fields->dataFieldByName('DefaultLengthUnit')
141 1
            ->displayIf('DeliveryType')->isEqualTo('shipped');
142
143 1
        $fields->dataFieldByName('ShippingFlatRate')
144 1
            ->displayIf('DeliveryType')->isEqualTo('flat_rate');
145 1
146 1
        $fields->replaceField(
147 1
            'ShippingFlatRateType',
148
            DropdownField::create('ShippingFlatRateType', 'Flat Rate Type', $this->getShippingFlatRateTypes())
149
                ->setEmptyString('')
150 1
                ->displayIf('DeliveryType')->isEqualTo('flat_rate')->end()
151
        );
152 1
153 1
        $fields->insertBefore(HeaderField::create('HandlingHD', 'Handling Fees and Discounts', 3), 'HandlingFeeType');
154 1
155 1
        $fields->replaceField(
156 1
            'HandlingFeeType',
157
            DropdownField::create('HandlingFeeType', 'Handling Fee Type', $this->getHandlingFeeTypes())
158
                ->setEmptyString('')
159 1
                ->setDescription('This determines what type of Handling Fee you would like to use.')
160 1
        );
161
162 1
        $fields->dataFieldByName('HandlingFee')
163 1
            ->displayIf('HandlingFeeType')->isNotEqualTo('');
164
165 1
        $fields->dataFieldByName('HandlingFeeMinimum')
166 1
            ->displayIf('HandlingFeeType')->isEqualTo('flat_percent_with_minimum');
167 1
168
        $fields->dataFieldByName('HandlingFeePercentage')
169 1
            ->displayIf('HandlingFeeType')->isEqualTo('flat_percent_with_minimum')
170 1
            ->orIf('HandlingFeeType')->isEqualTo('flat_percent');
171 1
172 1
        $fields->replaceField(
173 1
            'DiscountType',
174
            DropdownField::create('DiscountType', 'Discount Type', $this->getDiscountTypes())
175
                ->setEmptyString('')
176 1
                ->setDescription('This determines what type of per category discount you would like to use, if any.')
177 1
        );
178
179 1
        $fields->dataFieldByName('DiscountName')
180 1
            ->displayIf('DiscountType')->isNotEqualTo('');
181
182 1
        $fields->dataFieldByName('DiscountDetails')
183 1
            ->displayIf('DiscountType')->isNotEqualTo('');
184
185
        $fields->dataFieldByName('CustomsValue')
186
            ->setDescription('Enter a dollar amount here for the declared customs value for international 
187
            shipments. If you leave this blank, the sale price of the item will be used.');
188
189
        return $fields;
190
    }
191
192
    /**
193
     * @return \SilverStripe\ORM\ValidationResult
194
     */
195
    public function validate() {
196
        $result = parent::validate();
197
198
        if(ProductCategory::get()->filter('Code', $this->Code)->first()) {
199
            $result->addError('Code must be unique for each category.');
200
        }
201
202
        return $result;
203
    }
204
205
    /**
206
     * @throws \SilverStripe\ORM\ValidationException
207
     */
208
    public function requireDefaultRecords()
209
    {
210
        parent::requireDefaultRecords();
211
        $allCats = self::get();
212
        if (!$allCats->count()) {
213
            $cat = new self();
214
            $cat->Title = 'Default';
0 ignored issues
show
Documentation Bug introduced by
It seems like 'Default' of type string is incompatible with the declared type SilverStripe\ORM\FieldType\DBVarchar of property $Title.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
215
            $cat->Code = 'DEFAULT';
0 ignored issues
show
Documentation Bug introduced by
It seems like 'DEFAULT' of type string is incompatible with the declared type SilverStripe\ORM\FieldType\DBVarchar of property $Code.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
216 1
            $cat->write();
217
        }
218
    }
219
220
    /**
221
     * @param bool $member
222
     *
223
     * @return bool
224
     */
225
    public function canView($member = false)
226
    {
227
        return true;
228
    }
229
230
    /**
231
     * @param null $member
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $member is correct as it would always require null to be passed?
Loading history...
232
     *
233
     * @return bool|int
234
     */
235
    public function canEdit($member = null)
236
    {
237
        return Permission::check('Product_CANCRUD', 'any', $member);
238
    }
239 12
240
    /**
241 12
     * @param null $member
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $member is correct as it would always require null to be passed?
Loading history...
242
     *
243
     * @return bool|int
244
     */
245
    public function canDelete($member = null)
246
    {
247
248
        //don't allow deletion of DEFAULT category
249 1
        return ($this->Code == 'DEFAULT') ? false : Permission::check('Product_CANCRUD', 'any', $member);
0 ignored issues
show
introduced by
The condition $this->Code == 'DEFAULT' is always false.
Loading history...
250
    }
251 1
252
    /**
253
     * @param null $member
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $member is correct as it would always require null to be passed?
Loading history...
254
     *
255
     * @param array $context
256
     *
257
     * @return bool|int
258
     */
259 2
    public function canCreate($member = null, $context = [])
260
    {
261
        return Permission::check('Product_CANCRUD', 'any', $member);
262
    }
263 2
264
    /**
265
     * @return array
266
     */
267
    public function getShippingOptions()
268
    {
269
        return [
270
            'shipped' => 'Shipped using live shipping rates',
271
            'downloaded' => 'Downloaded by the customer',
272
            'flat_rate' => 'Shipped using a flat rate fee',
273 1
            'pickup' => 'Picked up by the customer',
274
            'notshipped' => 'No Shipping',
275 1
        ];
276
    }
277
278
    /**
279
     * @return array
280
     */
281 2
    public function getShippingFlatRateTypes()
282
    {
283
        return [
284 2
            'per_order' => 'Charge per order',
285
            'per_item' => 'Charge per item',
286
        ];
287
    }
288
289
    /**
290
     * @return array
291
     */
292
    public function getHandlingFeeTypes()
293
    {
294
        return [
295 2
            'flat_per_order' => 'Flat fee per order with products in this category',
296
            'flat_per_item' => 'Flat fee per product in this category',
297
            'flat_percent' => 'Flat fee per shipment + % of price for products in this category',
298 2
            'flat_percent_with_minimum' => 'Flat fee per shipment OR % of order total with products in this category. 
299
                Whichever is greater.',
300
        ];
301
    }
302
303
    /**
304
     * @return array
305
     */
306 2
    public function getDiscountTypes()
307
    {
308
        return [
309 2
            'quantity_amount' => 'Discount by an amount based on the quantity',
310
            'quantity_percentage' => 'Discount by a percentage based on the quantity',
311
            'price_amount' => 'Discount by an amount based on the price in this category',
312
            'price_percentage' => 'Discount by a percentage based on the price in this category',
313
        ];
314
    }
315
316
    /**
317
     * @return array
318
     */
319
    public function getDataMap()
320 2
    {
321
        return [
322
            'name' => $this->Title,
323 2
            'code' => $this->Code,
324
            'item_delivery_type' => $this->DeliveryType,
325
            'max_downloads_per_customer' => $this->MaxDownloads,
326
            'max_downloads_time_period' => $this->MaxDownloadsTime,
327
            'customs_value' => $this->CustomsValue,
328
            'default_weight' => $this->DefaultWeight,
329
            'default_weight_unit' => $this->DefaultWeightUnit,
330
            'default_length_unit' => $this->DefautlLengthUnit,
0 ignored issues
show
Bug Best Practice introduced by
The property DefautlLengthUnit does not exist on Dynamic\FoxyStripe\Model\ProductCategory. Since you implemented __get, consider adding a @property annotation.
Loading history...
331
            'shipping_flat_rate' => $this->ShippingFlatRate,
332
            'shipping_flat_rate_type' => $this->ShippingFlatRateType,
333 11
            'handling_fee_type' => $this->HandlingFeeType,
334
            'handling_fee' => $this->HandlingFee,
335
            'handling_fee_minimum' => $this->HandlingFeeMinimum,
336 11
            'handling_fee_percentage' => $this->HandlingFeePercentage,
337 11
            'discount_type' => $this->DiscountType,
338 11
            'discount_name' => $this->DiscountName,
339 11
            'discount_details' => $this->DiscountDetails,
340 11
        ];
341 11
    }
342 11
343 11
    /**
344 11
     * @throws \Psr\Container\NotFoundExceptionInterface
345 11
     */
346 11
    public function onAfterWrite()
347 11
    {
348 11
        parent::onAfterWrite();
349 11
350 11
        if ($this->isChanged()) {
351 11
            if ($fc = new FoxyStripeClient()) {
352 11
                $fc->putCategory($this->getDataMap());
353 11
            }
354
        }
355
    }
356
357
    /**
358
     * @throws \Psr\Container\NotFoundExceptionInterface
359
     */
360 9
    public function onAfterDelete()
361
    {
362 9
        parent::onAfterDelete();
363
364 9
        if ($fc = new FoxyStripeClient()) {
365 9
            $fc->deleteCategory($this->getDataMap());
366 9
        }
367
    }
368
}
369