Passed
Push — master ( 97d330...e7fc5b )
by Jason
01:48
created

Order::canEdit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Dynamic\Foxy\Orders\Model;
4
5
use Dynamic\Foxy\Extension\Purchasable;
6
use Dynamic\Foxy\Orders\Foxy\Transaction;
7
use SilverStripe\CMS\Model\SiteTree;
8
use SilverStripe\Forms\DateField;
9
use SilverStripe\ORM\DataObject;
10
use SilverStripe\ORM\FieldType\DBHTMLVarchar;
11
use SilverStripe\ORM\ValidationException;
12
use SilverStripe\Security\Member;
13
use SilverStripe\Security\Permission;
14
use SilverStripe\Security\PermissionProvider;
15
16
/**
17
 * Class Order
18
 * @package Dynamic\Foxy\Model
19
 *
20
 * @property \SilverStripe\ORM\FieldType\DBInt StoreID
21
 * @property \SilverStripe\ORM\FieldType\DBInt OrderID
22
 * @property \SilverStripe\ORM\FieldType\DBVarchar Email
23
 * @property \SilverStripe\ORM\FieldType\DBDatetime TransactionDate
24
 * @property \SilverStripe\ORM\FieldType\DBCurrency ProductTotal
25
 * @property \SilverStripe\ORM\FieldType\DBCurrency TaxTotal
26
 * @property \SilverStripe\ORM\FieldType\DBCurrency ShippingTotal
27
 * @property \SilverStripe\ORM\FieldType\DBCurrency OrderTotal
28
 * @property \SilverStripe\ORM\FieldType\DBVarchar ReceiptURL
29
 * @property \SilverStripe\ORM\FieldType\DBVarchar OrderStatus
30
 * @property \SilverStripe\ORM\FieldType\DBText Response
31
 *
32
 * @property int MemberID
33
 * @method Member Member
34
 */
35
class Order extends DataObject implements PermissionProvider
36
{
37
    /**
38
     * @var array
39
     */
40
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
41
        'StoreID' => 'Int',
42
        'OrderID' => 'Int',
43
        'Email' => 'Varchar(255)',
44
        'TransactionDate' => 'DBDatetime',
45
        'ProductTotal' => 'Currency',
46
        'TaxTotal' => 'Currency',
47
        'ShippingTotal' => 'Currency',
48
        'OrderTotal' => 'Currency',
49
        'ReceiptURL' => 'Varchar(255)',
50
        'OrderStatus' => 'Varchar(255)',
51
        'Response' => 'Text',
52
    ];
53
54
    /**
55
     * @var array
56
     */
57
    private static $has_one = [
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
58
        'Member' => Member::class,
59
    ];
60
61
    /**
62
     * @var array
63
     */
64
    private static $has_many = array(
0 ignored issues
show
introduced by
The private property $has_many is not used, and could be removed.
Loading history...
65
        'Details' => OrderDetail::class,
66
    );
67
68
    /**
69
     * @var string
70
     */
71
    private static $singular_name = 'Order';
0 ignored issues
show
introduced by
The private property $singular_name is not used, and could be removed.
Loading history...
72
73
    /**
74
     * @var string
75
     */
76
    private static $plural_name = 'Orders';
0 ignored issues
show
introduced by
The private property $plural_name is not used, and could be removed.
Loading history...
77
78
    /**
79
     * @var string
80
     */
81
    private static $description = 'Orders from FoxyCart Datafeed';
0 ignored issues
show
introduced by
The private property $description is not used, and could be removed.
Loading history...
82
83
    /**
84
     * @var string
85
     */
86
    private static $default_sort = 'TransactionDate DESC, ID DESC';
0 ignored issues
show
introduced by
The private property $default_sort is not used, and could be removed.
Loading history...
87
88
    /**
89
     * @var array
90
     */
91
    private static $summary_fields = [
0 ignored issues
show
introduced by
The private property $summary_fields is not used, and could be removed.
Loading history...
92
        'OrderID',
93
        'TransactionDate.Nice',
94
        'Email',
95
        'ProductTotal.Nice',
96
        'ShippingTotal.Nice',
97
        'TaxTotal.Nice',
98
        'OrderTotal.Nice',
99
        'ReceiptLink',
100
    ];
101
102
    /**
103
     * @var array
104
     */
105
    private static $searchable_fields = [
0 ignored issues
show
introduced by
The private property $searchable_fields is not used, and could be removed.
Loading history...
106
        'OrderID',
107
        'TransactionDate' => [
108
            'field' => DateField::class,
109
            'filter' => 'PartialMatchFilter',
110
        ],
111
        'Email',
112
        'OrderTotal'
113
    ];
114
115
    /**
116
     * @var array
117
     */
118
    private static $casting = [
0 ignored issues
show
introduced by
The private property $casting is not used, and could be removed.
Loading history...
119
        'ReceiptLink' => 'HTMLVarchar',
120
    ];
121
122
    /**
123
     * @var array
124
     */
125
    private static $indexes = [
0 ignored issues
show
introduced by
The private property $indexes is not used, and could be removed.
Loading history...
126
        'OrderID' => true, // make unique
127
    ];
128
129
    /**
130
     * @var string
131
     */
132
    private static $table_name = 'FoxyOrder';
0 ignored issues
show
introduced by
The private property $table_name is not used, and could be removed.
Loading history...
133
134
    /**
135
     * @var
136
     */
137
    private $transaction;
138
139
    /**
140
     * @return mixed
141
     */
142
    protected function getTransaction()
143
    {
144
        if (!$this->transaction) {
145
            $this->setTransaction();
146
        }
147
        return $this->transaction;
148
    }
149
150
    /**
151
     * @return $this
152
     */
153
    protected function setTransaction()
154
    {
155
        if ($this->Response) {
156
            $this->transaction = Transaction::create($this->OrderID, urldecode($this->Response));
157
        } else {
158
            $this->transaction = false;
159
        }
160
        return $this;
161
    }
162
163
    /**
164
     * @param bool $includerelations
165
     *
166
     * @return array|string
167
     */
168
    public function fieldLabels($includerelations = true)
169
    {
170
        $labels = parent::fieldLabels();
171
        $labels['StoreID'] = _t(__CLASS__ . '.StoreID', 'Store ID#');
172
        $labels['OrderID'] = _t(__CLASS__ . '.OrderID', 'Order ID#');
173
        $labels['TransactionDate'] = _t(__CLASS__ . '.TransactionDate', 'Date');
174
        $labels['TransactionDate.NiceUS'] = _t(__CLASS__ . '.TransactionDate', 'Date');
175
        $labels['Email'] = _t(__CLASS__ . '.Email', 'Email');
176
        $labels['ProductTotal.Nice'] = _t(__CLASS__ . '.ProductTotal', 'Sub Total');
177
        $labels['TaxTotal.Nice'] = _t(__CLASS__ . '.TaxTotal', 'Tax');
178
        $labels['ShippingTotal.Nice'] = _t(__CLASS__ . '.ShippingTotal', 'Shipping');
179
        $labels['OrderTotal'] = _t(__CLASS__ . '.OrderTotal', 'Total');
180
        $labels['OrderTotal.Nice'] = _t(__CLASS__ . '.OrderTotal', 'Total');
181
        $labels['ReceiptLink'] = _t(__CLASS__ . '.ReceiptLink', 'Invoice');
182
        $labels['Details.ProductID'] = _t(__CLASS__ . '.Details.ProductID', 'Product');
183
        return $labels;
184
    }
185
186
    /**
187
     * @return mixed
188
     */
189
    public function ReceiptLink()
190
    {
191
        return $this->getReceiptLink();
192
    }
193
194
    /**
195
     * @return mixed
196
     */
197
    public function getReceiptLink()
198
    {
199
        $obj = DBHTMLVarchar::create();
200
        $obj->setValue(
201
            '<a href="' . $this->ReceiptURL . '" target="_blank" class="cms-panel-link action external-link">view</a>'
202
        );
203
        return $obj;
204
    }
205
206
    /**
207
     * @throws \SilverStripe\ORM\ValidationException
208
     */
209
    protected function onBeforeWrite()
210
    {
211
        parent::onBeforeWrite();
212
        $this->parseOrder();
213
    }
214
215
    /**
216
     * @return bool
217
     *
218
     * @throws ValidationException
219
     */
220
    public function parseOrder()
221
    {
222
        if ($this->getTransaction() && $this->getTransaction()->exists()) {
223
            $this->parseOrderInfo();
224
            $this->parseOrderDetails();
225
        }
226
227
        $this->extend('updateParseOrder', $this);
228
    }
229
230
    /**
231
     * @param $response
232
     */
233
    public function parseOrderInfo()
234
    {
235
        $transaction = $this->getTransaction()->getTransaction();
236
237
        // Record transaction data from FoxyCart Datafeed:
238
        $this->StoreID = (int)$transaction->store_id;
0 ignored issues
show
Documentation Bug introduced by
It seems like (int)$transaction->store_id of type integer is incompatible with the declared type SilverStripe\ORM\FieldType\DBInt of property $StoreID.

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...
239
        $this->Email = (string)$transaction->customer_email;
0 ignored issues
show
Documentation Bug introduced by
It seems like (string)$transaction->customer_email of type string is incompatible with the declared type SilverStripe\ORM\FieldType\DBVarchar of property $Email.

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...
240
        $this->TransactionDate = (string)$transaction->transaction_date;
0 ignored issues
show
Documentation Bug introduced by
It seems like (string)$transaction->transaction_date of type string is incompatible with the declared type SilverStripe\ORM\FieldType\DBDatetime of property $TransactionDate.

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...
241
        $this->ProductTotal = (float)$transaction->product_total;
0 ignored issues
show
Documentation Bug introduced by
It seems like (double)$transaction->product_total of type double is incompatible with the declared type SilverStripe\ORM\FieldType\DBCurrency of property $ProductTotal.

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...
242
        $this->TaxTotal = (float)$transaction->tax_total;
0 ignored issues
show
Documentation Bug introduced by
It seems like (double)$transaction->tax_total of type double is incompatible with the declared type SilverStripe\ORM\FieldType\DBCurrency of property $TaxTotal.

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...
243
        $this->ShippingTotal = (float)$transaction->shipping_total;
0 ignored issues
show
Documentation Bug introduced by
It seems like (double)$transaction->shipping_total of type double is incompatible with the declared type SilverStripe\ORM\FieldType\DBCurrency of property $ShippingTotal.

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...
244
        $this->OrderTotal = (float)$transaction->order_total;
0 ignored issues
show
Documentation Bug introduced by
It seems like (double)$transaction->order_total of type double is incompatible with the declared type SilverStripe\ORM\FieldType\DBCurrency of property $OrderTotal.

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...
245
        $this->ReceiptURL = (string)$transaction->receipt_url;
0 ignored issues
show
Documentation Bug introduced by
It seems like (string)$transaction->receipt_url of type string is incompatible with the declared type SilverStripe\ORM\FieldType\DBVarchar of property $ReceiptURL.

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...
246
        $this->OrderStatus = (string)$transaction->status;
0 ignored issues
show
Documentation Bug introduced by
It seems like (string)$transaction->status of type string is incompatible with the declared type SilverStripe\ORM\FieldType\DBVarchar of property $OrderStatus.

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...
247
248
        $this->extend('handleOrderInfo', $order, $response);
249
    }
250
251
    /**
252
     * @param $response
253
     *
254
     * @throws \SilverStripe\ORM\ValidationException
255
     */
256
    public function parseOrderDetails()
257
    {
258
        // remove previous OrderDetails and OrderOptions so we don't end up with duplicates
259
        foreach ($this->Details() as $detail) {
0 ignored issues
show
Bug introduced by
The method Details() does not exist on Dynamic\Foxy\Orders\Model\Order. 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

259
        foreach ($this->/** @scrutinizer ignore-call */ Details() as $detail) {
Loading history...
260
            /** @var OrderOption $orderOption */
261
            foreach ($detail->OrderOptions() as $orderOption) {
262
                $orderOption->delete();
263
            }
264
            $detail->delete();
265
        }
266
267
        $transaction = $this->getTransaction()->getTransaction();
268
269
        // Associate ProductPages, Options, Quantity with Order
270
        foreach ($transaction->transaction_details->transaction_detail as $detail) {
271
            $OrderDetail = OrderDetail::create();
272
            $OrderDetail->Quantity = (int)$detail->product_quantity;
273
            $OrderDetail->ProductName = (string)$detail->product_name;
274
            $OrderDetail->ProductCode = (string)$detail->product_code;
275
            $OrderDetail->ProductImage = (string)$detail->image;
276
            $OrderDetail->ProductCategory = (string)$detail->category_code;
277
            $priceModifier = 0;
278
279
            // parse OrderOptions
280
            foreach ($detail->transaction_detail_options->transaction_detail_option as $option) {
281
                // Find product via product_id custom variable
282
                if ($option->product_option_name == 'product_id') {
283
                    // if product is found, set relation to OrderDetail
284
                    $OrderProduct = SiteTree::get()->byID((int)$option->product_option_value);
285
                    if ($OrderProduct && $OrderProduct->isProduct()) {
286
                        $OrderDetail->ProductID = $OrderProduct->ID;
287
                    }
288
                } else {
289
                    // record non product_id options as OrderOption
290
                    $OrderOption = OrderOption::create();
291
                    $OrderOption->Name = (string)$option->product_option_name;
292
                    $OrderOption->Value = (string)$option->product_option_value;
293
                    $OrderOption->write();
294
                    $OrderDetail->OrderOptions()->add($OrderOption);
295
                    $priceModifier += $option->price_mod;
296
                }
297
            }
298
299
            $OrderDetail->Price = (float)$detail->product_price + (float)$priceModifier;
300
301
            // extend OrderDetail parsing, allowing for recording custom fields from FoxyCart
302
            $this->extend('handleOrderItem', $this, $transaction, $OrderDetail);
303
304
            // write
305
            $OrderDetail->write();
306
307
            // associate with this order
308
            $this->Details()->add($OrderDetail);
309
        }
310
    }
311
312
    /**
313
     * @return array
314
     */
315
    public function providePermissions()
316
    {
317
        return [
318
            'MANAGE_FOXY_ORDERS' => [
319
                'name' => _t(
320
                    __CLASS__ . '.PERMISSION_MANAGE_ORDERS_DESCRIPTION',
321
                    'Manage orders'
322
                ),
323
                'category' => _t(
324
                    Purchasable::class . '.PERMISSIONS_CATEGORY',
325
                    'Foxy'
326
                ),
327
                'help' => _t(
328
                    __CLASS__ . '.PERMISSION_MANAGE_ORDERS_HELP',
329
                    'Manage orders and view recipts'
330
                ),
331
                'sort' => 400,
332
            ],
333
        ];
334
    }
335
336
    /**
337
     * @param bool $member
338
     *
339
     * @return bool|int
340
     */
341
    public function canView($member = null)
342
    {
343
        return Permission::checkMember($member, 'MANAGE_FOXY_ORDERS');
344
    }
345
346
    /**
347
     * @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...
348
     *
349
     * @return bool
350
     */
351
    public function canEdit($member = null)
352
    {
353
        return false;
354
    }
355
356
    /**
357
     * @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...
358
     *
359
     * @return bool
360
     */
361
    public function canDelete($member = null)
362
    {
363
        return false;
364
    }
365
366
    /**
367
     * @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...
368
     * @param array $context
369
     *
370
     * @return bool
371
     */
372
    public function canCreate($member = null, $context = [])
373
    {
374
        return false;
375
    }
376
}
377