Passed
Push — master ( 87d6cd...c6afeb )
by Jason
02:13
created

Order::parseOrderCustomer()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 6
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 13
rs 10
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->parseOrderCustomer();
225
            $this->parseOrderDetails();
226
        }
227
228
        $this->extend('updateParseOrder', $this);
229
    }
230
231
    /**
232
     * @param $response
233
     */
234
    public function parseOrderInfo()
235
    {
236
        $transaction = $this->getTransaction()->getTransaction();
237
238
        // Record transaction data from FoxyCart Datafeed:
239
        $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...
240
        $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...
241
        $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...
242
        $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...
243
        $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...
244
        $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...
245
        $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...
246
        $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...
247
        $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...
248
249
        $this->extend('handleOrderInfo', $order, $response);
250
    }
251
252
    /**
253
     * @param $response
254
     * @throws \SilverStripe\ORM\ValidationException
255
     */
256
    public function parseOrderCustomer()
257
    {
258
        $transaction = $this->getTransaction()->getTransaction();
259
        $customer = false;
260
261
        // if not a guest transaction in Foxy
262
        if (isset($transaction->customer_email) && $transaction->is_anonymous == 0) {
263
            if ($customer = Member::get()->filter('Email', $transaction->customer_email)->first()) {
264
                // set Order MemberID
265
                $this->MemberID = $customer->ID;
266
            }
267
        }
268
        $this->extend('updateParseOrderCustomer', $transaction, $customer);
269
    }
270
271
    /**
272
     * @param $response
273
     *
274
     * @throws \SilverStripe\ORM\ValidationException
275
     */
276
    public function parseOrderDetails()
277
    {
278
        // remove previous OrderDetails and OrderOptions so we don't end up with duplicates
279
        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

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