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

getNumberPurchasedUpdate()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 9
rs 10
cc 3
nc 2
nop 0
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
        'NumberPurchased' => 'Int',
26
        'InventorySync' => 'Datetime',
27
    ];
28
29
    /**
30
     * @param FieldList $fields
31
     */
32
    public function updateCMSFields(FieldList $fields)
33
    {
34
        $fields->removeByName([
35
            'ControlInventory',
36
            'PurchaseLimit',
37
            'EmbargoLimit',
38
            'NumberPurchased',
39
        ]);
40
41
        $fields->addFieldsToTab('Root.Inventory', [
42
            Wrapper::create(
43
                CheckboxField::create('ControlInventory', 'Control Inventory?')
44
                    ->setDescription('limit the number of this product available for purchase'),
45
                Wrapper::create(
46
                    NumericField::create('PurchaseLimit')
47
                        ->setTitle('Number Available')
48
                        ->setDescription('add to cart form will be disabled once number available equals purchased'),
49
                    ReadonlyField::create('NumberPurchased', 'Number Purchased', $this->owner->NumberPurchased)
50
                        ->setDescription('Number of products purchased all time'),
51
                    ReadonlyField::create('NumberAvailable', 'Remaining Available', $this->getNumberAvailable())
52
                        ->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.')//,
53
                )->displayIf('ControlInventory')->isChecked()->end()
54
            )->displayIf('Available')->isChecked()->end(),
55
        ]);
56
    }
57
58
    /**
59
     * @param ValidationResult $validationResult
60
     * @throws \SilverStripe\ORM\ValidationException
61
     */
62
    public function validate(ValidationResult $validationResult)
63
    {
64
        parent::validate($validationResult);
65
66
        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...
67
            $validationResult->addFieldError('PurchaseLimit', 'You must specify a purchase limit more than 0');
68
        }
69
    }
70
71
    /**
72
     * @param $available
73
     */
74
    public function updateGetIsAvailable(&$available)
75
    {
76
        if ($this->owner->Variations()->count()) {
77
            $available = false;
78
            foreach ($this->owner->Variations() as $variation) {
79
                if ($variation->getIsAvailable()) {
80
                    $available = true;
81
                }
82
            }
83
        } elseif ($this->getHasInventory()) {
84
            $available = $this->getIsProductAvailable();
85
        }
86
    }
87
88
    /**
89
     * @return bool
90
     */
91
    public function getHasInventory()
92
    {
93
        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...
94
    }
95
96
    /**
97
     * @return bool
98
     */
99
    public function getIsProductAvailable()
100
    {
101
        if ($this->owner->getHasInventory()) {
102
            return $this->getNumberAvailable() > 0;
103
        }
104
105
        return true;
106
    }
107
108
    /**
109
     * @return int|void
110
     */
111
    public function getNumberAvailable()
112
    {
113
        return (int)$this->owner->PurchaseLimit - (int)$this->owner->NumberPurchased - (int)$this->getCartReservations()->count();
114
    }
115
116
    /**
117
     * @return int
118
     */
119
    public function getNumberPurchasedUpdate()
120
    {
121
        $ct = 0;
122
        if ($this->getOrders()) {
123
            foreach ($this->getOrders() as $order) {
124
                $ct += $order->Quantity;
125
            }
126
        }
127
        return $ct;
128
    }
129
130
    /**
131
     * @return DataList|bool
132
     */
133
    public function getOrders()
134
    {
135
        if ($this->owner->ID) {
136
            $orderDetails = OrderDetail::get()->filter('ProductID', $this->owner->ID);
137
            $orders = ArrayList::create();
138
            foreach ($orderDetails as $orderDetail) {
139
                $hasVariation = false;
140
                foreach ($orderDetail->OrderVariations() as $variation) {
141
                    if ($variation->VariationID > 0) {
142
                        $hasVariation = true;
143
                    }
144
                }
145
                if (!$hasVariation) {
146
                    $orders->push($orderDetail);
147
                }
148
            }
149
150
            return $orders;
151
        }
152
153
        return false;
154
    }
155
156
    /**
157
     * @return DataList
158
     */
159
    public function getCartReservations()
160
    {
161
        return CartReservation::get()
162
            ->filter([
163
                'ProductID' => $this->owner->ID,
164
                'Expires:GreaterThan' => date('Y-m-d H:i:s', strtotime('now')),
165
            ]);
166
    }
167
}
168