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

ProductInventoryManager::getNumberPurchased()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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