Passed
Pull Request — master (#27)
by Jason
02:14
created

ProductInventoryManager::updateGetIsAvailable()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 7
c 2
b 0
f 1
dl 0
loc 11
rs 9.6111
cc 5
nc 5
nop 1
1
<?php
2
3
namespace Dynamic\Foxy\Inventory\Extension;
4
5
use Dynamic\Foxy\Inventory\Model\CartReservation;
6
use Dynamic\Foxy\Orders\Model\OrderDetail;
7
use SilverStripe\Forms\CheckboxField;
8
use SilverStripe\Forms\FieldList;
9
use SilverStripe\Forms\NumericField;
10
use SilverStripe\Forms\ReadonlyField;
11
use SilverStripe\ORM\ArrayList;
12
use SilverStripe\ORM\DataExtension;
13
use SilverStripe\ORM\DataList;
14
use SilverStripe\ORM\ValidationResult;
15
use UncleCheese\DisplayLogic\Forms\Wrapper;
16
17
class ProductInventoryManager extends DataExtension
18
{
19
    /**
20
     * @var array
21
     */
22
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
23
        'ControlInventory' => 'Boolean',
24
        'PurchaseLimit' => 'Int',
25
    ];
26
27
    /**
28
     * @param FieldList $fields
29
     */
30
    public function updateCMSFields(FieldList $fields)
31
    {
32
        $fields->removeByName([
33
            'ControlInventory',
34
            'PurchaseLimit',
35
            'EmbargoLimit',
36
            'NumberPurchased',
37
        ]);
38
39
        $fields->addFieldsToTab('Root.Inventory', [
40
            Wrapper::create(
41
                CheckboxField::create('ControlInventory', 'Control Inventory?')
42
                    ->setDescription('limit the number of this product available for purchase'),
43
                Wrapper::create(
44
                    NumericField::create('PurchaseLimit')
45
                        ->setTitle('Number Available')
46
                        ->setDescription('add to cart form will be disabled once number available equals purchased'),
47
                    ReadonlyField::create('NumberAvailable', 'Remaining Available', $this->getNumberAvailable())
48
                        ->setDescription('This takes into account products added to the cart. Products removed from the cart may persist in the "Cart Reservations" until the expiration time.')//,
49
                )->displayIf('ControlInventory')->isChecked()->end()
50
            )->displayIf('Available')->isChecked()->end(),
51
        ]);
52
    }
53
54
    /**
55
     * @param ValidationResult $validationResult
56
     * @throws \SilverStripe\ORM\ValidationException
57
     */
58
    public function validate(ValidationResult $validationResult)
59
    {
60
        parent::validate($validationResult);
61
62
        if ($this->owner->ControlInventory && $this->owner->PurchaseLimit == 0) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $this->owner->PurchaseLimit of type mixed|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
63
            $validationResult->addFieldError('PurchaseLimit', 'You must specify a purchase limit more than 0');
64
        }
65
    }
66
67
    /**
68
     * @param $available
69
     */
70
    public function updateGetIsAvailable(&$available)
71
    {
72
        if ($this->owner->Variations()->count()) {
73
            foreach ($this->owner->Variations() as $variation) {
74
                $available = false;
75
                if ($variation->getIsAvailable()) {
76
                    $available = true;
77
                }
78
            }
79
        } elseif ($this->getHasInventory()) {
80
            $available = $this->getIsProductAvailable();
81
        }
82
    }
83
84
    /**
85
     * @return bool
86
     */
87
    public function getHasInventory()
88
    {
89
        return $this->owner->ControlInventory && $this->owner->PurchaseLimit != 0;
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $this->owner->PurchaseLimit of type mixed|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
90
    }
91
92
    /**
93
     * @return bool
94
     */
95
    public function getIsProductAvailable()
96
    {
97
        if ($this->owner->getHasInventory()) {
98
            return $this->getNumberAvailable() > 0;
99
        }
100
101
        return true;
102
    }
103
104
    /**
105
     * @return int|void
106
     */
107
    public function getNumberAvailable()
108
    {
109
        return (int)$this->owner->PurchaseLimit - (int)$this->getNumberPurchased() - (int)$this->getCartReservations()->count();
110
    }
111
112
    /**
113
     * @return int
114
     */
115
    public function getNumberPurchased()
116
    {
117
        $ct = 0;
118
        if ($this->getOrders()) {
119
            foreach ($this->getOrders() as $order) {
120
                $ct += $order->Quantity;
121
            }
122
        }
123
        return $ct;
124
    }
125
126
    /**
127
     * @return DataList|bool
128
     */
129
    public function getOrders()
130
    {
131
        if ($this->owner->ID) {
132
            $orderDetails = OrderDetail::get()->filter('ProductID', $this->owner->ID);
133
            $orders = ArrayList::create();
134
            foreach ($orderDetails as $orderDetail) {
135
                $hasVariation = false;
136
                foreach ($orderDetail->OrderVariations() as $variation) {
137
                    if ($variation->VariationID > 0) {
138
                        $hasVariation = true;
139
                    }
140
                }
141
                if (!$hasVariation) {
142
                    $orders->push($orderDetail);
143
                }
144
            }
145
146
            return $orders;
147
        }
148
149
        return false;
150
    }
151
152
    /**
153
     * @return DataList
154
     */
155
    public function getCartReservations()
156
    {
157
        return CartReservation::get()
158
            ->filter([
159
                'ProductID' => $this->owner->ID,
160
                'Expires:GreaterThan' => date('Y-m-d H:i:s', strtotime('now')),
161
            ]);
162
    }
163
}
164