Passed
Push — 1.0 ( 07b100...83f8df )
by Morven
05:31
created

LineItem   D

Complexity

Total Complexity 60

Size/Duplication

Total Lines 534
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 534
rs 4.2857
c 0
b 0
f 0
wmc 60

22 Methods

Rating   Name   Duplication   Size   Complexity  
A getTaxTotal() 0 7 1
A FindStockItem() 0 3 1
A canView() 0 8 3
B Image() 0 10 8
A CustomisationAndPriceList() 0 18 4
A getSubTotal() 0 7 1
B Match() 0 12 5
A onBeforeDelete() 0 6 2
A canDelete() 0 8 3
A canEdit() 0 8 3
A onAfterWrite() 0 15 4
A onBeforeWrite() 0 6 1
A canCreate() 0 8 3
A CustomisationList() 0 18 4
A getUnitPrice() 0 11 2
A getTaxRate() 0 7 2
A getTotal() 0 7 1
A duplicate() 0 14 3
A checkStockLevel() 0 10 2
A getCMSFields() 0 55 2
A CustomisationHTML() 0 17 4
A getUnitTax() 0 7 1

How to fix   Complexity   

Complex Class

Complex classes like LineItem often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LineItem, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace SilverCommerce\OrdersAdmin\Model;
4
5
use SilverStripe\ORM\DataObject;
6
use SilverStripe\ORM\FieldType\DBHTMLText as HTMLText;
7
use SilverStripe\ORM\ArrayList;
8
use SilverStripe\Forms\FieldList;
9
use SilverStripe\Forms\ReadonlyField;
10
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
11
use SilverStripe\Forms\GridField\GridField;
12
use SilverStripe\Forms\GridField\GridFieldConfig;
13
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
14
use SilverStripe\Forms\GridField\GridFieldButtonRow;
15
use Symbiote\GridFieldExtensions\GridFieldEditableColumns;
16
use Symbiote\GridFieldExtensions\GridFieldAddNewInlineButton;
17
use SilverStripe\Forms\GridField\GridFieldEditButton;
18
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
19
use SilverStripe\Forms\GridField\GridFieldDataColumns;
20
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
21
use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter;
22
use SilverStripe\SiteConfig\SiteConfig;
23
use SilverCommerce\TaxAdmin\Model\TaxRate;
24
use SilverStripe\Forms\DropdownField;
25
26
/**
27
 * A LineItem is a single line item on an order, extimate or even in
28
 * the shopping cart.
29
 * 
30
 * An item has a number of fields that describes a product:
31
 * 
32
 * - Key: ID used to detect this item
33
 * - Title: Title of the item
34
 * - Content: Description of this object
35
 * - Quantity: Number or items in this order
36
 * - Weight: Weight of this item (unit of measurment is defined globally)
37
 * - TaxRate: Rate of tax for this item (e.g. 20.00 for 20%)
38
 * - ProductClass: ClassName of product that this item is matched against
39
 * - StockID: Unique identifier of this item (used with ProductClass
40
 *            match to a product)
41
 * - Locked: Is this a locked item? Locked items cannot be changed in the
42
 *           shopping cart
43
 * - Deliverable: Is this a product that can be delivered? This can effect
44
 *                delivery options
45
 *
46
 * @author Mo <[email protected]>
47
 */
48
class LineItem extends DataObject
49
{
50
    private static $table_name = 'LineItem';
51
52
    /**
53
     * The name of the param used on a related product to
54
     * track Stock Levels.
55
     * 
56
     * Defaults to StockLevel
57
     *
58
     * @var string
59
     * @config
60
     */
61
    private static $stock_param = "StockLevel";
62
63
    /**
64
     * Standard database columns
65
     * 
66
     * @var array
67
     * @config
68
     */
69
    private static $db = [
70
        "Key"           => "Varchar(255)",
71
        "Title"         => "Varchar",
72
        "Content"       => "HTMLText",
73
        "Quantity"      => "Int",
74
        "Price"         => "Currency",
75
        "Weight"        => "Decimal",
76
        "StockID"       => "Varchar(100)",
77
        "ProductClass"  => "Varchar",
78
        "Locked"        => "Boolean",
79
        "Stocked"       => "Boolean",
80
        "Deliverable"   => "Boolean",
81
        "Customisation" => "Text",
82
    ];
83
84
    /**
85
     * Foreign key associations in DB
86
     * 
87
     * @var array
88
     * @config
89
     */
90
    private static $has_one = [
91
        "Parent"      => Estimate::class,
92
        "Tax"         => TaxRate::class,
93
    ];
94
    
95
    /**
96
     * One to many associations
97
     *
98
     * @var array
99
     * @config
100
     */
101
    private static $has_many = [
102
        "Customisations" => LineItemCustomisation::class
103
    ];
104
105
    /**
106
     * Specify default values of a field
107
     *
108
     * @var array
109
     * @config
110
     */
111
    private static $defaults = [
112
        "Quantity"      => 1,
113
        "ProductClass"  => "Product",
114
        "Locked"        => false,
115
        "Stocked"       => false,
116
        "Deliverable"   => true
117
    ];
118
119
    /**
120
     * Fields to display in list tables
121
     * 
122
     * @var array
123
     * @config
124
     */
125
    private static $summary_fields = [
126
        "Quantity"  => "Quantity",
127
        "Title"     => "Title",
128
        "StockID"   => "Stock ID",
129
        "Price"     => "Item Price",
130
        "TaxID"    => "Tax",
131
        "CustomisationAndPriceList" => "Customisations"
132
    ];
133
    
134
    /**
135
     * Function to DB Object conversions
136
     * 
137
     * @var array
138
     * @config
139
     */
140
    private static $casting = [
141
        "UnitPrice" => "Currency",
142
        "UnitTax"   => "Currency",
143
        "SubTotal"  => "Currency",
144
        "TaxRate"   => "Decimal",
145
        "TaxTotal"  => "Currency",
146
        "Total"     => "Currency"
147
    ];
148
149
    /**
150
     * Modify default field scaffolding in admin
151
     *
152
     * @return FieldList
153
     */
154
    public function getCMSFields()
155
    {
156
        
157
        $this->beforeUpdateCMSFields(function ($fields) {
158
            $config = SiteConfig::current_site_config();
159
160
            $fields->removeByName("Customisation");
161
162
            $fields->addFieldToTab(
163
                "Root.Main",
164
                ReadonlyField::create("Key"),
0 ignored issues
show
Bug introduced by
'Key' of type string is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

164
                ReadonlyField::create(/** @scrutinizer ignore-type */ "Key"),
Loading history...
165
                "Title"
166
            );
167
168
            $fields->addFieldToTab(
169
                "Root.Main",
170
                DropdownField::create(
171
                    "TaxID",
172
                    $this->fieldLabel("TaxID"),
173
                    $config->TaxRates()->map()
174
                ),
175
                "Weight"
176
            );
177
178
            $fields->addFieldsToTab(
179
                "Root.Description",
180
                array(
181
                    HTMLEditorField::create("Content")
182
                        ->addExtraClass("stacked")
183
                )
184
            );
185
186
            // Change unlink button to remove on customisation
187
            $custom_field = $fields->dataFieldByName("Customisations");
188
189
            if ($custom_field) {
190
                $config = $custom_field->getConfig();
191
                $config
192
                    ->removeComponentsByType(GridFieldDeleteAction::class)
193
                    ->removeComponentsByType(GridFieldDataColumns::class)
194
                    ->removeComponentsByType(GridFieldEditButton::class)
195
                    ->removeComponentsByType(GridFieldAddNewButton::class)
196
                    ->removeComponentsByType(GridFieldAddExistingAutocompleter::class)
197
                    ->addComponents(
198
                        new GridFieldEditableColumns(),
199
                        new GridFieldAddNewInlineButton(),
200
                        new GridFieldEditButton(),
201
                        new GridFieldDeleteAction()
202
                    );
203
                
204
                    $custom_field->setConfig($config);
205
            }
206
        });
207
208
        return parent::getCMSFields();
209
    }
210
211
    /**
212
     * Get the rate of tax for this item
213
     * 
214
     * @return float
215
     */
216
    public function getTaxRate()
217
    {
218
        $rate = ($this->Tax()->exists()) ? $this->Tax()->Rate : 0;
0 ignored issues
show
Bug introduced by
The method Tax() does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. 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

218
        $rate = ($this->/** @scrutinizer ignore-call */ Tax()->exists()) ? $this->Tax()->Rate : 0;
Loading history...
219
220
        $this->extend("updateTaxRate", $rate);
221
222
        return $rate;
223
    }
224
    
225
    /**
226
     * Get the price for a single line item (unit), minus any
227
     * tax
228
     * 
229
     * @return float
230
     */
231
    public function getUnitPrice()
232
    {
233
        $total = $this->Price;
0 ignored issues
show
Bug Best Practice introduced by
The property Price does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
234
235
        foreach ($this->Customisations() as $customisation) {
0 ignored issues
show
Bug introduced by
The method Customisations() does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. 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

235
        foreach ($this->/** @scrutinizer ignore-call */ Customisations() as $customisation) {
Loading history...
236
            $total += $customisation->Price;
237
        }
238
239
        $this->extend("updateUnitPrice", $total);
240
241
        return $total;
242
    }
243
244
    /**
245
     * Get the amount of tax for a single unit of this item
246
     * 
247
     * @return float
248
     */
249
    public function getUnitTax()
250
    {
251
        $total = ($this->UnitPrice / 100) * $this->TaxRate;
0 ignored issues
show
Bug Best Practice introduced by
The property UnitPrice does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property TaxRate does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
252
253
        $this->extend("updateUnitTax", $total);
254
255
        return $total;
256
    }
257
258
    /**
259
     * Get the value of this item, minus any tax
260
     * 
261
     * @return float
262
     */
263
    public function getSubTotal()
264
    {
265
        $total = $this->UnitPrice * $this->Quantity;
0 ignored issues
show
Bug Best Practice introduced by
The property Quantity does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property UnitPrice does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
266
267
        $this->extend("updateSubTotal", $total);
268
269
        return $total;
270
    }
271
272
    /**
273
     * Get the total amount of tax for a single unit of this item
274
     * 
275
     * @return float
276
     */
277
    public function getTaxTotal()
278
    {
279
        $total = $this->UnitTax * $this->Quantity;
0 ignored issues
show
Bug Best Practice introduced by
The property Quantity does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property UnitTax does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
280
281
        $this->extend("updateTaxTotal", $total);
282
283
        return $total;
284
    }
285
286
    /**
287
     * Get the value of this item, minus any tax
288
     * 
289
     * @return float
290
     */
291
    public function getTotal()
292
    {
293
        $total = $this->SubTotal + $this->TaxTotal;
0 ignored issues
show
Bug Best Practice introduced by
The property TaxTotal does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property SubTotal does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
294
295
        $this->extend("updateTotal", $total);
296
297
        return $total;
298
    }
299
300
    /**
301
     * Get an image object associated with this line item.
302
     * By default this is retrieved from the base product.
303
     * 
304
     * @return Image | null
0 ignored issues
show
Bug introduced by
The type SilverCommerce\OrdersAdmin\Model\Image was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
305
     */
306
    public function Image()
307
    {
308
        $product = $this->FindStockItem();
309
310
        if ($product && method_exists($product, "SortedImages")) {
0 ignored issues
show
introduced by
The condition $product && method_exist...roduct, 'SortedImages') can never be true.
Loading history...
311
            return  $product->SortedImages()->first();
312
        } elseif ($product && method_exists($product, "Images")) {
0 ignored issues
show
introduced by
The condition $product && method_exists($product, 'Images') can never be true.
Loading history...
313
            return $product->Images()->first();
314
        } elseif ($product && method_exists($product, "Image") && $product->Image()->exists()) {
0 ignored issues
show
introduced by
The condition $product && method_exist...duct->Image()->exists() can never be true.
Loading history...
315
            return $product->Image();
316
        }
317
    }
318
    
319
    /**
320
     * Provide a string of customisations seperated by a comma but not
321
     * including a price
322
     *
323
     * @return string
324
     */
325
    public function CustomisationList()
326
    {
327
        $return = "";
328
        $items = $this->Customisations();
329
        
330
        if ($items && $items->exists()) {
331
            $map = [];
332
333
            foreach ($items as $item) {
334
                $map[] = $item->Title . ': ' . $item->Value;
335
            }
336
337
            $return = implode(", ", $map);
338
        }
339
340
        $this->extend("updateCustomisationList", $return);
341
        
342
        return $return;
343
    }
344
345
    /**
346
     * Provide a string of customisations seperated by a comma and
347
     * including a price
348
     *
349
     * @return string
350
     */
351
    public function CustomisationAndPriceList()
352
    {
353
        $return = "";
354
        $items = $this->Customisations();
355
        
356
        if ($items && $items->exists()) {
357
            $map = [];
358
359
            foreach ($items as $item) {
360
                $map[] = $item->Title . ': ' . $item->Value . ' (' . $item->dbObject("Price")->Nice() . ')';
361
            }
362
363
            $return = implode(", ", $map);
364
        }
365
366
        $this->extend("updateCustomisationAndPriceList", $return);
367
        
368
        return $return;
369
    }
370
    
371
    /**
372
     * Unserialise the list of customisations and rendering into a basic
373
     * HTML string
374
     *
375
     * @return HTMLText
376
     */
377
    public function CustomisationHTML()
378
    {
379
        $return = HTMLText::create();
380
        $items = $this->Customisations();
381
        $html = "";
382
        
383
        if ($items && $items->exists()) {
384
            foreach ($items as $item) {
385
                $html .= $item->Title . ': ' . $item->Value . ";<br/>";
386
            }
387
        }
388
389
        $return->setValue($html);
390
391
        $this->extend("updateCustomisationHTML", $return);
392
393
        return $return;
394
    }
395
        
396
    /**
397
     * Match this item to another object in the Database, by the
398
     * provided details.
399
     * 
400
     * @param $relation_name = The class name of the related dataobject
401
     * @param $relation_col = The column name of the related object
402
     * @param $match_col = The column we use to match the two objects
403
     * @return DataObject
404
     */
0 ignored issues
show
Documentation Bug introduced by
The doc comment = at position 0 could not be parsed: Unknown type name '=' at position 0 in =.
Loading history...
405
    public function Match($relation_name = null, $relation_col = "StockID", $match_col = "StockID")
406
    {
407
        // Try to determine relation name
408
        if (!$relation_name && !$this->ProductClass) {
0 ignored issues
show
Bug Best Practice introduced by
The property ProductClass does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
409
            $relation_name = "Product";
410
        } elseif(!$relation_name && $this->ProductClass) {
411
            $relation_name = $this->ProductClass;
412
        }
413
        
414
        return $relation_name::get()
415
            ->filter($relation_col, $this->$match_col)
416
            ->first();
417
    }
418
419
    /**
420
     * Find our original stock item (useful for adding links back to the
421
     * original product).
422
     * 
423
     * This function is a synonym for @Link Match (as a result of) merging
424
     * LineItem
425
     * 
426
     * @return DataObject
427
     */
428
    public function FindStockItem()
429
    {
430
        return $this->Match();
431
    }
432
433
    /**
434
     * Check stock levels for this item, will return the actual number
435
     * of remaining stock after removing the current quantity
436
     * 
437
     * @param $qty The quantity we want to check against
0 ignored issues
show
Bug introduced by
The type SilverCommerce\OrdersAdmin\Model\The was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
438
     * @return Int
439
     */
440
    public function checkStockLevel($qty)
441
    {
442
        $stock_param = $this->config()->get("stock_param");
443
        $item = $this->Match();
444
        $stock = ($item->$stock_param) ? $item->$stock_param : 0;
445
        $return = $stock - $qty;
446
447
        $this->extend("updateCheckStockLevel", $return);
448
        
449
        return $return;
450
    }
451
452
    /**
453
     * Only order creators or users with VIEW admin rights can view
454
     *
455
     * @return Boolean
456
     */
457
    public function canView($member = null, $context = [])
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

457
    public function canView($member = null, /** @scrutinizer ignore-unused */ $context = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
458
    {
459
        $extended = $this->extend('canView', $member);
460
        if ($extended && $extended !== null) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $extended of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
461
            return $extended;
462
        }
463
464
        return $this->Parent()->canView($member);
0 ignored issues
show
Bug introduced by
The method Parent() does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. 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

464
        return $this->/** @scrutinizer ignore-call */ Parent()->canView($member);
Loading history...
465
    }
466
467
    /**
468
     * Anyone can create an order item
469
     *
470
     * @return Boolean
471
     */
472
    public function canCreate($member = null, $context = [])
473
    {
474
        $extended = $this->extend('canCreate', $member);
475
        if ($extended && $extended !== null) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $extended of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
476
            return $extended;
477
        }
478
479
        return true;
480
    }
481
482
    /**
483
     * No one can edit items once they are created
484
     *
485
     * @return Boolean
486
     */
487
    public function canEdit($member = null, $context = [])
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

487
    public function canEdit($member = null, /** @scrutinizer ignore-unused */ $context = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
488
    {
489
        $extended = $this->extend('canEdit', $member);
490
        if ($extended && $extended !== null) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $extended of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
491
            return $extended;
492
        }
493
494
        return $this->Parent()->canEdit($member);
495
    }
496
497
    /**
498
     * No one can delete items once they are created
499
     *
500
     * @return Boolean
501
     */
502
    public function canDelete($member = null, $context = [])
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

502
    public function canDelete($member = null, /** @scrutinizer ignore-unused */ $context = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
503
    {
504
        $extended = $this->extend('canDelete', $member);
505
        if ($extended && $extended !== null) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $extended of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
506
            return $extended;
507
        }
508
509
        return $this->Parent()->canEdit($member);
510
    }
511
512
    /**
513
     * Overwrite default duplicate function
514
     *
515
     * @param boolean $doWrite (write the cloned object to DB)
516
     * @return DataObject $clone The duplicated object
517
     */
518
    public function duplicate($doWrite = true, $manyMany = "many_many")
519
    {
520
        $clone = parent::duplicate($doWrite);
521
522
        // Ensure we clone any customisations
523
        if ($doWrite) {
524
            foreach ($this->Customisations() as $customisation) {
525
                $new_item = $customisation->duplicate(false);
526
                $new_item->ParentID = $clone->ID;
527
                $new_item->write();
528
            }
529
        }
530
531
        return $clone;
532
    }
533
534
    /**
535
     * Pre-write tasks
536
     *
537
     * @return void
538
     */
539
    public function onBeforeWrite()
540
    {
541
        parent::onBeforeWrite();
542
543
        // Generate a unique item key based on 
544
        $this->Key = $this->StockID . ':' . base64_encode(json_encode($this->Customisations()->toArray()));
0 ignored issues
show
Bug Best Practice introduced by
The property Key does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug Best Practice introduced by
The property StockID does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
545
    }
546
547
    /**
548
     * Perform post-DB write functions
549
     *
550
     * @return void
551
     */
552
    public function onAfterWrite()
553
    {
554
        parent::onAfterWrite();
555
556
        if ($this->Customisation) {
557
            $data = unserialize($this->Customisation);
558
559
            if ($data instanceof ArrayList) {
560
                foreach ($data as $data_item) {
561
                    $data_item->ParentID = $this->ID;
562
                    $data_item->write();
563
                }
564
565
                $this->Customisation = null;
0 ignored issues
show
Bug Best Practice introduced by
The property Customisation does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
566
                $this->write();
567
            }
568
        }
569
    }
570
571
    /**
572
     * Clean up DB on deletion
573
     *
574
     * @return void
575
     */
576
    public function onBeforeDelete()
577
    {
578
        parent::onBeforeDelete();
579
580
        foreach ($this->Customisations() as $customisation) {
581
            $customisation->delete();
582
        }
583
    }
584
}
585