Completed
Push — master ( 8cd82b...1a1c21 )
by Jason
03:22
created

ProductCategory::validate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
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 9
ccs 0
cts 5
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
    /**
101
     * @return FieldList
102
     */
103 1
    public function getCMSFields()
104
    {
105 1
        $fields = parent::getCMSFields();
106
107 1
        if ($this->ID) {
108 1
            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
                );
113
            }
114
115 1
            $fields->replaceField(
116 1
                'Code',
117 1
                ReadonlyField::create('Code')
118
            );
119
        }
120
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
123 1
        $fields->replaceField(
124 1
            'DeliveryType',
125 1
            OptionsetField::create('DeliveryType', 'Delivery Type', $this->getShippingOptions())
126
        );
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
146 1
        $fields->replaceField(
147 1
            'ShippingFlatRateType',
148 1
            DropdownField::create('ShippingFlatRateType', 'Flat Rate Type', $this->getShippingFlatRateTypes())
149 1
                ->setEmptyString('')
150 1
                ->displayIf('DeliveryType')->isEqualTo('flat_rate')->end()
151
        );
152
153 1
        $fields->insertBefore(HeaderField::create('HandlingHD', 'Handling Fees and Discounts', 3), 'HandlingFeeType');
154
155 1
        $fields->replaceField(
156 1
            'HandlingFeeType',
157 1
            DropdownField::create('HandlingFeeType', 'Handling Fee Type', $this->getHandlingFeeTypes())
158 1
                ->setEmptyString('')
159 1
                ->setDescription('This determines what type of Handling Fee you would like to use.')
160
        );
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
168 1
        $fields->dataFieldByName('HandlingFeePercentage')
169 1
            ->displayIf('HandlingFeeType')->isEqualTo('flat_percent_with_minimum')
170 1
            ->orIf('HandlingFeeType')->isEqualTo('flat_percent');
171
172 1
        $fields->replaceField(
173 1
            'DiscountType',
174 1
            DropdownField::create('DiscountType', 'Discount Type', $this->getDiscountTypes())
175 1
                ->setEmptyString('')
176 1
                ->setDescription('This determines what type of per category discount you would like to use, if any.')
177
        );
178
179 1
        $fields->dataFieldByName('DiscountName')
180 1
            ->displayIf('DiscountType')->isNotEqualTo('');
181
182 1
        $fields->dataFieldByName('DiscountDetails')
183 1
            ->displayIf('DiscountType')->isNotEqualTo('');
184
185 1
        $fields->dataFieldByName('CustomsValue')
186 1
            ->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 1
        return $fields;
190
    }
191
192
    /**
193
     * @return \SilverStripe\ORM\ValidationResult
194
     */
195
    public function validate()
196
    {
197
        $result = parent::validate();
198
199
        if (ProductCategory::get()->filter('Code', $this->Code)->exclude('ID', $this->ID)->first()) {
200
            $result->addError('Code must be unique for each category.');
201
        }
202
203
        return $result;
204
    }
205
206
    /**
207
     * @throws \SilverStripe\ORM\ValidationException
208
     */
209
    public function requireDefaultRecords()
210
    {
211
        parent::requireDefaultRecords();
212
        $allCats = self::get();
213
        if (!$allCats->count()) {
214
            $cat = new self();
215
            $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...
216
            $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...
217
            $cat->write();
218
        }
219
    }
220
221
    /**
222
     * @param bool $member
223
     *
224
     * @return bool
225
     */
226 10
    public function canView($member = false)
227
    {
228 10
        return true;
229
    }
230
231
    /**
232
     * @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...
233
     *
234
     * @return bool|int
235
     */
236 1
    public function canEdit($member = null)
237
    {
238 1
        return Permission::check('Product_CANCRUD', 'any', $member);
239
    }
240
241
    /**
242
     * @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...
243
     *
244
     * @return bool|int
245
     */
246 2
    public function canDelete($member = null)
247
    {
248
249
        //don't allow deletion of DEFAULT category
250 2
        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...
251
    }
252
253
    /**
254
     * @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...
255
     *
256
     * @param array $context
257
     *
258
     * @return bool|int
259
     */
260 1
    public function canCreate($member = null, $context = [])
261
    {
262 1
        return Permission::check('Product_CANCRUD', 'any', $member);
263
    }
264
265
    /**
266
     * @return array
267
     */
268 2
    public function getShippingOptions()
269
    {
270
        return [
271 2
            'shipped' => 'Shipped using live shipping rates',
272
            'downloaded' => 'Downloaded by the customer',
273
            'flat_rate' => 'Shipped using a flat rate fee',
274
            'pickup' => 'Picked up by the customer',
275
            'notshipped' => 'No Shipping',
276
        ];
277
    }
278
279
    /**
280
     * @return array
281
     */
282 2
    public function getShippingFlatRateTypes()
283
    {
284
        return [
285 2
            'per_order' => 'Charge per order',
286
            'per_item' => 'Charge per item',
287
        ];
288
    }
289
290
    /**
291
     * @return array
292
     */
293 2
    public function getHandlingFeeTypes()
294
    {
295
        return [
296 2
            'flat_per_order' => 'Flat fee per order with products in this category',
297
            'flat_per_item' => 'Flat fee per product in this category',
298
            'flat_percent' => 'Flat fee per shipment + % of price for products in this category',
299
            'flat_percent_with_minimum' => 'Flat fee per shipment OR % of order total with products in this category. 
300
                Whichever is greater.',
301
        ];
302
    }
303
304
    /**
305
     * @return array
306
     */
307 2
    public function getDiscountTypes()
308
    {
309
        return [
310 2
            'quantity_amount' => 'Discount by an amount based on the quantity',
311
            'quantity_percentage' => 'Discount by a percentage based on the quantity',
312
            'price_amount' => 'Discount by an amount based on the price in this category',
313
            'price_percentage' => 'Discount by a percentage based on the price in this category',
314
        ];
315
    }
316
317
    /**
318
     * @return array
319
     */
320 11
    public function getDataMap()
321
    {
322
        return [
323 11
            'name' => $this->Title,
324 11
            'code' => $this->Code,
325 11
            'item_delivery_type' => $this->DeliveryType,
326 11
            'max_downloads_per_customer' => $this->MaxDownloads,
327 11
            'max_downloads_time_period' => $this->MaxDownloadsTime,
328 11
            'customs_value' => $this->CustomsValue,
329 11
            'default_weight' => $this->DefaultWeight,
330 11
            'default_weight_unit' => $this->DefaultWeightUnit,
331 11
            '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...
332 11
            'shipping_flat_rate' => $this->ShippingFlatRate,
333 11
            'shipping_flat_rate_type' => $this->ShippingFlatRateType,
334 11
            'handling_fee_type' => $this->HandlingFeeType,
335 11
            'handling_fee' => $this->HandlingFee,
336 11
            'handling_fee_minimum' => $this->HandlingFeeMinimum,
337 11
            'handling_fee_percentage' => $this->HandlingFeePercentage,
338 11
            'discount_type' => $this->DiscountType,
339 11
            'discount_name' => $this->DiscountName,
340 11
            'discount_details' => $this->DiscountDetails,
341
        ];
342
    }
343
344
    /**
345
     * @throws \Psr\Container\NotFoundExceptionInterface
346
     */
347 9
    public function onAfterWrite()
348
    {
349 9
        parent::onAfterWrite();
350
351 9
        if ($this->isChanged()) {
352 9
            if ($fc = new FoxyStripeClient()) {
353 9
                $fc->putCategory($this->getDataMap());
354
            }
355
        }
356
    }
357
358
    /**
359
     * @throws \Psr\Container\NotFoundExceptionInterface
360
     */
361 1
    public function onAfterDelete()
362
    {
363 1
        parent::onAfterDelete();
364
365 1
        if ($fc = new FoxyStripeClient()) {
366 1
            $fc->deleteCategory($this->getDataMap());
367
        }
368
    }
369
}
370