Completed
Push — master ( bae698...330e3c )
by Antony
07:27
created

Order   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 344
Duplicated Lines 2.91 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 36
c 1
b 0
f 0
lcom 1
cbo 6
dl 10
loc 344
rs 8.8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A onBeforeWrite() 0 7 2
F onAfterWrite() 10 269 34

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php namespace SilvershopUnleashed\Model;
2
3
use DataExtension;
4
use ShopConfig;
5
use Member;
6
use HasGroupPricing;
7
use DateTime;
8
use UnleashedAPI;
9
use Utils;
10
use SS_Log;
11
12
class Order extends DataExtension
13
{
14
    /**
15
     * Enable sending of Sales Orders to Unleashed
16
     * @var boolean
17
     */
18
    private static $send_sales_orders_to_unleashed = false;
0 ignored issues
show
Unused Code introduced by
The property $send_sales_orders_to_unleashed is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
19
20
    /**
21
     * Declare the tax modifier used in Silvershop
22
     *
23
     * @example  'FlatTaxModifier'
24
     * @var string
25
     */
26
    private static $tax_modifier_class_name = '';
0 ignored issues
show
Unused Code introduced by
The property $tax_modifier_class_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
27
28
    /**
29
     * Days following payment that delivery is expected
30
     * @var int
31
     */
32
    private static $expected_days_to_deliver = 0;
0 ignored issues
show
Unused Code introduced by
The property $expected_days_to_deliver is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
33
34
    /**
35
     * Default CreatedBy
36
     * @var string
37
     */
38
    private static $default_created_by = '';
0 ignored issues
show
Unused Code introduced by
The property $default_created_by is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
39
40
    /**
41
     * Default payment term
42
     * @var string
43
     */
44
    private static $default_payment_term = 'Same Day';
0 ignored issues
show
Unused Code introduced by
The property $default_payment_term is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
45
46
    /**
47
     * Default Customer Type
48
     * @var string
49
     */
50
    private static $default_customer_type = '';
0 ignored issues
show
Unused Code introduced by
The property $default_customer_type is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
51
52
    /**
53
     * Default Sales Order Group
54
     * @var string
55
     */
56
    private static $default_sales_order_group = '';
0 ignored issues
show
Unused Code introduced by
The property $default_sales_order_group is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
57
58
    /**
59
     * Default Sales Person
60
     * @var string
61
     */
62
    private static $default_sales_person = '';
0 ignored issues
show
Unused Code introduced by
The property $default_sales_person is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
63
64
    /**
65
     * Default Source Id
66
     * @var string
67
     */
68
    private static $default_source_id = '';
0 ignored issues
show
Unused Code introduced by
The property $default_source_id is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
69
70
    /**
71
     * Apply Guid if absent
72
     */
73
    public function onBeforeWrite()
74
    {
75
        parent::onBeforeWrite();
76
        if (!$this->owner->getField("Guid")) {
77
            $this->owner->Guid = (string) Utils::createGuid();
78
        }
79
    }
80
81
    /**
82
     * Send a sales order to Unleashed upon paid status
83
     *
84
     * Note: create Customer first
85
     */
86
    public function onAfterWrite()
87
    {
88
        parent::onAfterWrite();
89
        $config = $this->owner->config();
90
91
        if ($config->send_sales_orders_to_unleashed && $this->owner->Status == "Paid") {
92
            // Definitions
93
            $order = $this->owner;
94
            $billing_address = $order->BillingAddress();
95
            $shipping_address = $order->ShippingAddress();
96
            $member = $order->Member();
97
            $countries = ShopConfig::config()->iso_3166_country_codes;
98
            $subtotal = $order->Total();
99
            $sell_price_tier = ShopConfig::current()->CustomerGroup()->Title;
100
            $taxable = false;
101
            $tax_code = '';
102
            $tax_total = 0;
103
            $tax_class_name = $config->tax_modifier_class_name;
104
            $modifiers = $order->Modifiers();
105
            $tax_modifier = $order->getModifier($config->tax_modifier_class_name);
106
            $shipping_method = '';
107
            $sales_order_lines = [];
108
            $line_number = 0;
109
110
111
            // Customer
112
            if (!$member->exists()) {  // Create Member for Guests
113
                $member = Member::create();
114
                $member->FirstName = $order->FirstName;
115
                $member->Surname = $order->Surname;
116
                $member->Email = $order->getLatestEmail();
117
            }
118
119
            // Selling Price Tier if Customer set with a different pricecard using the Extended Pricing Module
120
            if (class_exists('HasGroupPricing') && $member->Groups()->exists()) {
121
                $levels = HasGroupPricing::get_levels();
122
                foreach ($member->Groups() as $group) {
123
                    if (array_key_exists($group->Code, $levels)) {
124
                        // Assign member specific group
125
                        $sell_price_tier = $group->Title;
126
                    }
127
                }
128
            }
129
130
            // Taxation (e.g. Sales Tax/GST)
131
            if (!empty($tax_modifier)) {
132
                $subtotal -= $tax_modifier->Amount;
133
                $taxable = true;
134
                $tax_code = $tax_modifier::config()->name;
135
                $tax_total = floatval($tax_modifier->Amount);
136
            }
137
138
            // Define Customer (use Company field of BillingAddress to allow for B2B eCommerce sites)
139
            if ($company = $billing_address->Company) {
140
                $customer_name = $company;    // use Organisation name
141
            } else {
142
                $customer_name = $order->getName();  // use Contact full name instead
143
            }
144
145
            if (!$member->Guid) {  // See if New Customer/Guest has previously purchased
146
                $response = UnleashedAPI::sendCall(
147
                    'GET',
148
                    'https://api.unleashedsoftware.com/Customers?contactEmail=' .  $member->Email
149
                );
150
151
                if ($response->getStatusCode() == '200') {
152
                    $contents = json_decode($response->getBody()->getContents(), true);
153
                    if ($items = $contents['Items']) {
154
                        $member->Guid = $items[0]['Guid'];
155
                    } else {
156
                        // Create new Customer in Unleashed
157
                        $member->Guid = (string) Utils::createGuid();
158
                        $body = [
159
                            'Addresses' => [
160
                                [
161
                                    'AddressName' => _t("Address.BillingAddress"),
162
                                    'AddressType' => 'Postal',
163
                                    'City' => $billing_address->City,
164
                                    'Country' => $countries[$billing_address->Country],
165
                                    'PostalCode' => $billing_address->PostalCode,
166
                                    'Region' => $billing_address->State,
167
                                    'StreetAddress' => $billing_address->Address,
168
                                    'Suburb' => $billing_address->AddressLine2
169
                                ],
170
                                [
171
                                    'AddressName' => _t("Address.ShippingAddress"),
172
                                    'AddressType' => 'Physical',
173
                                    'City' => $shipping_address->City,
174
                                    'Country' => $countries[$shipping_address->Country],
175
                                    'PostalCode' => $shipping_address->PostalCode,
176
                                    'Region' => $shipping_address->State,
177
                                    'StreetAddress' => $shipping_address->Address,
178
                                    'Suburb' => $shipping_address->AddressLine2
179
                                ]
180
                            ],
181
                            'Currency' =>[
182
                                'CurrencyCode' => $order->Currency()
183
                            ],
184
                            'CustomerCode' => $customer_name,
185
                            'CustomerName' => $customer_name,
186
                            'ContactFirstName' => $member->FirstName,
187
                            'ContactLastName' => $member->Surname,
188
                            'Email' => $member->Email,
189
                            'Guid' => $member->Guid,
190
                            'PaymentTerm' => $config->default_payment_term,
191
                            'PrintPackingSlipInsteadOfInvoice' => true,
192
                            'SellPriceTier' => $sell_price_tier
193
                        ];
194
195
                        if ($taxable) {
196
                            $body['Taxable'] = $taxable;
197
                        }
198
199
                        if ($created_by = $config->default_created_by) {
200
                            $body['CreatedBy'] = $created_by;
201
                        }
202
203
                        if ($customer_type = $config->default_customer_type) {
204
                            $body['CustomerType'] = $customer_type;
205
                        }
206
207
                        if ($phone = $billing_address->Phone) {  // add phone number if available
208
                            $body['PhoneNumber'] = $phone;
209
                        }
210
211
                        $response = UnleashedAPI::sendCall(
212
                            'POST',
213
                            'https://api.unleashedsoftware.com/Customers/' . $member->Guid,
214
                            ['json' => $body ]
215
                        );
216
217
                        if ($response->getReasonPhrase() == 'Created' && $order->Member()->exists()) {
218
                            $member->write();
219
                        }
220
                    }
221
                }
222
            }
223
224
225
            // Prepare Sales Order data
226
            if ($member->Guid) {  // Skip if previous calls to Customer have failed and the Guid has not been set
227
228
                // Dates
229
                $date_placed = new DateTime($order->Placed);
230
                $date_paid = new DateTime($order->Paid);
231
                $date_required = new DateTime($order->Paid);
232
                if ($expected_days_to_deliver = $config->expected_days_to_deliver) {
233
                    $date_required->modify('+' . $expected_days_to_deliver . 'day');
234
                }
235
236
                // Sales Order Lines
237
                foreach ($order->Items()->getIterator() as $item) {
238
                    // Definitions
239
                    $product = $item->Product();
240
                    $line_number += 1;
241
242
                    $sales_order_line = [
243
                        'DiscountRate' => 0,
244
                        'Guid' => $item->Guid,
245
                        'LineNumber' => $line_number,
246
                        'LineType' => null,
247
                        'LineTotal' => round(floatval($item->Total()), $config->rounding_precision),
248
                        'OrderQuantity' => (int) $item->Quantity,
249
                        'Product' => [
250
                            'Guid' => $product->Guid
251
                        ],
252
                        'UnitPrice' => round(floatval($product->getPrice()), $config->rounding_precision)
253
                    ];
254 View Code Duplication
                    if ($tax_class_name) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
255
                        $tax_calculator = new $tax_class_name;
256
                        $sales_order_line['LineTax'] = round($tax_calculator->value($item->Total()), $config->rounding_precision);
257
                        $sales_order_line['LineTaxCode'] = $tax_code;
258
                    }
259
                    $sales_order_lines[] = $sales_order_line;
260
                }
261
262
                // Add Modifiers that have an associated product_code
263
                foreach ($modifiers->sort('Sort')->getIterator() as $modifier) {
264
                    if ($modifier::config()->product_code && $modifier->Type !== 'Ignored' && $modifier->value()) {
265
                        $line_number += 1;
266
                        $sales_order_line = [
267
                            'DiscountRate' => 0,
268
                            'Guid' => $modifier->Guid,
269
                            'LineNumber' => $line_number,
270
                            'LineTotal' => round(floatval($modifier->Amount), $config->rounding_precision),
271
                            'LineType' => null,
272
                            'OrderQuantity' => 1,
273
                            'Product' => [
274
                                'ProductCode' => $modifier::config()->product_code,
275
                            ],
276
                            'UnitPrice' => round(floatval($modifier->Amount), $config->rounding_precision)
277
                        ];
278 View Code Duplication
                        if ($tax_class_name) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
279
                            $tax_calculator = new $tax_class_name;
280
                            $sales_order_line['LineTax'] = round($tax_calculator->value($modifier->Amount), $config->rounding_precision);
281
                            $sales_order_line['LineTaxCode'] = $tax_code;
282
                        }
283
                        $sales_order_lines[] = $sales_order_line;
284
                    }
285
                }
286
287
                // Shipping Module
288
                if (class_exists('ShippingMethod')) {
289
                    if ($name = $order->ShippingMethod()->Name) {
290
                        $shipping_method = $name;
291
                    }
292
                }
293
294
                $body = [
295
                    'Comments' => $order->Notes,
296
                    'Currency' =>[
297
                        'CurrencyCode' => $order->Currency()
298
                    ],
299
                    'Customer' => [
300
                        'Guid' => $member->Guid
301
                    ],
302
                    'DeliveryCity' => $shipping_address->City,
303
                    'DeliveryCountry' => $countries[$shipping_address->Country],
304
                    'DeliveryPostCode' => $shipping_address->PostalCode,
305
                    'DeliveryRegion' => $shipping_address->State,
306
                    'DeliveryStreetAddress' => $shipping_address->Address,
307
                    'DeliverySuburb' => $shipping_address->AddressLine2,
308
                    'DiscountRate' => 0,
309
                    'Guid' => $order->Guid,
310
                    'OrderDate' => $date_placed->format('Y-m-d\TH:i:s'),
311
                    'OrderNumber' => $order->Reference,
312
                    'OrderStatus' => 'Parked',
313
                    'PaymentDueDate' => $date_paid->format('Y-m-d\TH:i:s'),
314
                    'ReceivedDate' => $date_placed->format('Y-m-d\TH:i:s'),
315
                    'RequiredDate' => $date_required->format('Y-m-d\TH:i:s'),
316
                    'SalesOrderLines' => $sales_order_lines,
317
                    'SubTotal' => $subtotal,
318
                    'Tax' => [
319
                        'TaxCode' => $tax_code
320
                    ],
321
                    'TaxTotal' => $tax_total,
322
                    'Total' => round(floatval($order->Total()), $config->rounding_precision)
323
                ];
324
325
                if ($shipping_method) {
326
                    $body['DeliveryMethod'] = $shipping_method;
327
                    $body['DeliveryName'] = $shipping_method;
328
                }
329
330
                if ($sales_order_group = $config->default_sales_order_group) {
331
                    $body['SalesOrderGroup'] = $sales_order_group;
332
                }
333
334
                if ($sales_person = $config->default_sales_person) {
335
                    $body['SalesPerson'] = $sales_person;
336
                }
337
338
                if ($source_id = $config->default_source_id) {
339
                    $body['SourceId'] = $source_id;
340
                }
341
342
                $this->owner->extend('updateUnleashedSalesOrder', $body);
343
344
                SS_Log::log(print_r($body, true), SS_Log::NOTICE);
345
346
                UnleashedAPI::sendCall(
347
                    'POST',
348
                    'https://api.unleashedsoftware.com/SalesOrders/' . $order->Guid,
349
                    ['json' => $body]
350
                );
351
            }
352
        }
353
354
    }
355
}
356