Completed
Push — master ( 9e5ca0...55dfa7 )
by Antony
01:19
created

Order::getAddressName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 2
eloc 6
nc 2
nop 1
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_Datetime;
11
use SS_Log;
12
13
class Order extends DataExtension
14
{   
0 ignored issues
show
Coding Style introduced by
The opening class brace should be on a newline by itself.
Loading history...
15
    /**
16
     * Record when an order is sent to Unleashed
17
     */
18
    private static $db = [
0 ignored issues
show
Unused Code introduced by
The property $db 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
        'OrderSentToUnleashed' => 'SS_Datetime'
20
    ];
21
22
    /**
23
     * Enable sending of Sales Orders to Unleashed
24
     * @var boolean
25
     */
26
    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...
27
28
    /**
29
     * Declare the tax modifier used in Silvershop
30
     *
31
     * @example  'FlatTaxModifier'
32
     * @var string
33
     */
34
    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...
35
36
    /**
37
     * Days following payment that delivery is expected
38
     * @var int
39
     */
40
    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...
41
42
    /**
43
     * Default CreatedBy
44
     * @var string
45
     */
46
    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...
47
48
    /**
49
     * Default payment term
50
     * @var string
51
     */
52
    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...
53
54
    /**
55
     * Default Customer Type
56
     * @var string
57
     */
58
    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...
59
60
    /**
61
     * Default Sales Order Group
62
     * @var string
63
     */
64
    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...
65
66
    /**
67
     * Default Sales Person
68
     * @var string
69
     */
70
    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...
71
72
    /**
73
     * Default Source Id
74
     * @var string
75
     */
76
    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...
77
78
    /**
79
     * Apply Guid if absent
80
     */
81
    public function onBeforeWrite()
82
    {
83
        parent::onBeforeWrite();
84
        if (!$this->owner->getField("Guid")) {
85
            $this->owner->Guid = (string) Utils::createGuid();
86
        }
87
    }
88
89
    /**
90
     * Return the Address Name
91
     */
92
    private function getAddressName($address)
93
    {
94
        $address_name = $address->Address;
95
        if ($address->AddressLine2) {
96
            $address_name .= ' ' . $address->AddressLine2;
97
        }
98
        $address_name .= ' ' . $address->City;
99
        return $address_name;
100
    }
101
102
    /**
103
     * Send a sales order to Unleashed upon paid status
104
     *
105
     * Note: create Customer first
106
     */
107
    public function onAfterWrite()
108
    {
109
        parent::onAfterWrite();
110
        $config = $this->owner->config();
111
112
        if (
113
            $config->send_sales_orders_to_unleashed
114
            && $this->owner->Status == "Paid"
115
            && !$this->owner->OrderSentToUnleashed
116
        ) {
117
            // Definitions
118
            $order = $this->owner;
119
            $billing_address = $order->BillingAddress();
120
            $shipping_address = $order->ShippingAddress();
121
            $member = $order->Member();
122
            $countries = ShopConfig::config()->iso_3166_country_codes;
123
            $subtotal = $order->Total();
124
            $sell_price_tier = ShopConfig::current()->CustomerGroup()->Title;
125
            $taxable = false;
126
            $tax_code = '';
127
            $tax_total = 0;
128
            $tax_class_name = $config->tax_modifier_class_name;
129
            $modifiers = $order->Modifiers();
130
            $tax_modifier = $order->getModifier($config->tax_modifier_class_name);
131
            $shipping_method = '';
132
            $sales_order_lines = [];
133
            $line_number = 0;
134
135
136
            // Customer
137
            if (!$member->exists()) {  // Create Member for Guests
138
                $member = Member::create();
139
                $member->FirstName = $order->FirstName;
140
                $member->Surname = $order->Surname;
141
                $member->Email = $order->getLatestEmail();
142
            }
143
144
            // Selling Price Tier if Customer set with a different pricecard using the Extended Pricing Module
145
            if (class_exists('HasGroupPricing') && $member->Groups()->exists()) {
146
                $levels = HasGroupPricing::get_levels();
147
                foreach ($member->Groups() as $group) {
148
                    if (array_key_exists($group->Code, $levels)) {
149
                        // Assign member specific group
150
                        $sell_price_tier = $group->Title;
151
                    }
152
                }
153
            }
154
155
            // Taxation (e.g. Sales Tax/GST)
156
            if (!empty($tax_modifier)) {
157
                $subtotal -= $tax_modifier->Amount;
158
                $taxable = true;
159
                $tax_code = $tax_modifier::config()->name;
160
                $tax_total = floatval($tax_modifier->Amount);
161
            }
162
163
            // Define Customer (use Company field of BillingAddress to allow for B2B eCommerce sites)
164
            if ($billing_address->Company) {
165
                $customer_name = $billing_address->Company;    // use Organisation name
166
            } else {
167
                $customer_name = $order->getName();  // use Contact full name instead
168
            }
169
170
            if (!$member->Guid) {  // See if New Customer/Guest has previously purchased
171
                $response = UnleashedAPI::sendCall(
172
                    'GET',
173
                    'https://api.unleashedsoftware.com/Customers?contactEmail=' .  $member->Email
174
                );
175
176
                if ($response->getStatusCode() == '200') {
177
                    $contents = json_decode($response->getBody()->getContents(), true);
178
                    if ($items = $contents['Items']) {
179
                        $member->Guid = $items[0]['Guid'];
180
                    } else {
181
                        
182
                        // Create new Customer in Unleashed
183
                        $member->Guid = (string) Utils::createGuid();
184
                        $address_name_postal_new_customer = $this->getAddressName($billing_address);
185
                        $address_name_physical_new_customer = $this->getAddressName($shipping_address);
186
187
                        $body = [
188
                            'Addresses' => [
189
                                [
190
                                    'AddressName' => $address_name_postal_new_customer,
191
                                    'AddressType' => 'Postal',
192
                                    'City' => $billing_address->City,
193
                                    'Country' => $countries[$billing_address->Country],
194
                                    'PostalCode' => $billing_address->PostalCode,
195
                                    'Region' => $billing_address->State,
196
                                    'StreetAddress' => $billing_address->Address,
197
                                    'StreetAddress2' => $billing_address->AddressLine2
198
                                ],
199
                                [
200
                                    'AddressName' => $address_name_physical_new_customer,
201
                                    'AddressType' => 'Physical',
202
                                    'City' => $shipping_address->City,
203
                                    'Country' => $countries[$shipping_address->Country],
204
                                    'PostalCode' => $shipping_address->PostalCode,
205
                                    'Region' => $shipping_address->State,
206
                                    'StreetAddress' => $shipping_address->Address,
207
                                    'StreetAddress2' => $shipping_address->AddressLine2
208
                                ]
209
                            ],
210
                            'Currency' =>[
211
                                'CurrencyCode' => $order->Currency()
212
                            ],
213
                            'CustomerCode' => $customer_name,
214
                            'CustomerName' => $customer_name,
215
                            'ContactFirstName' => $member->FirstName,
216
                            'ContactLastName' => $member->Surname,
217
                            'Email' => $member->Email,
218
                            'Guid' => $member->Guid,
219
                            'PaymentTerm' => $config->default_payment_term,
220
                            'PrintPackingSlipInsteadOfInvoice' => true,
221
                            'SellPriceTier' => $sell_price_tier
222
                        ];
223
224
                        if ($taxable) {
225
                            $body['Taxable'] = $taxable;
226
                        }
227
228
                        if ($created_by = $config->default_created_by) {
229
                            $body['CreatedBy'] = $created_by;
230
                        }
231
232
                        if ($customer_type = $config->default_customer_type) {
233
                            $body['CustomerType'] = $customer_type;
234
                        }
235
236
                        if ($phone = $billing_address->Phone) {  // add phone number if available
237
                            $body['PhoneNumber'] = $phone;
238
                        }
239
240
                        $response = UnleashedAPI::sendCall(
241
                            'POST',
242
                            'https://api.unleashedsoftware.com/Customers/' . $member->Guid,
243
                            ['json' => $body ]
244
                        );
245
246
                        if ($response->getReasonPhrase() == 'Created' && $order->Member()->exists()) {
247
                            $member->write();
248
                        }
249
                    }
250
                }
251
            }
252
253
254
            // Prepare Sales Order data
255
            if ($member->Guid) {  // Skip if previous calls to Customer have failed and the Guid has not been set
256
257
                // Dates
258
                $date_placed = new DateTime($order->Placed);
259
                $date_paid = new DateTime($order->Paid);
260
                $date_required = new DateTime($order->Paid);
261
                if ($expected_days_to_deliver = $config->expected_days_to_deliver) {
262
                    $date_required->modify('+' . $expected_days_to_deliver . 'day');
263
                }
264
265
                // Sales Order Lines
266
                foreach ($order->Items()->getIterator() as $item) {
267
                    // Definitions
268
                    $product = $item->Product();
269
                    $line_number += 1;
270
271
                    $sales_order_line = [
272
                        'DiscountRate' => 0,
273
                        'Guid' => $item->Guid,
274
                        'LineNumber' => $line_number,
275
                        'LineType' => null,
276
                        'LineTotal' => round(floatval($item->Total()), $config->rounding_precision),
277
                        'OrderQuantity' => (int) $item->Quantity,
278
                        'Product' => [
279
                            'Guid' => $product->Guid
280
                        ],
281
                        'UnitPrice' => round(floatval($product->getPrice()), $config->rounding_precision)
282
                    ];
283 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...
284
                        $tax_calculator = new $tax_class_name;
285
                        $sales_order_line['LineTax'] = round($tax_calculator->value($item->Total()), $config->rounding_precision);
286
                        $sales_order_line['LineTaxCode'] = $tax_code;
287
                    }
288
                    $sales_order_lines[] = $sales_order_line;
289
                }
290
291
                // Add Modifiers that have an associated product_code
292
                foreach ($modifiers->sort('Sort')->getIterator() as $modifier) {
293
                    if ($modifier::config()->product_code && $modifier->Type !== 'Ignored' && $modifier->value()) {
294
                        $line_number += 1;
295
                        $sales_order_line = [
296
                            'DiscountRate' => 0,
297
                            'Guid' => $modifier->Guid,
298
                            'LineNumber' => $line_number,
299
                            'LineTotal' => round(floatval($modifier->Amount), $config->rounding_precision),
300
                            'LineType' => null,
301
                            'OrderQuantity' => 1,
302
                            'Product' => [
303
                                'ProductCode' => $modifier::config()->product_code,
304
                            ],
305
                            'UnitPrice' => round(floatval($modifier->Amount), $config->rounding_precision)
306
                        ];
307 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...
308
                            $tax_calculator = new $tax_class_name;
309
                            $sales_order_line['LineTax'] = round($tax_calculator->value($modifier->Amount), $config->rounding_precision);
310
                            $sales_order_line['LineTaxCode'] = $tax_code;
311
                        }
312
                        $sales_order_lines[] = $sales_order_line;
313
                    }
314
                }
315
316
                // Shipping Module
317
                if (class_exists('ShippingMethod')) {
318
                    if ($name = $order->ShippingMethod()->Name) {
319
                        $shipping_method = $name;
320
                    }
321
                }
322
323
                $body = [
324
                    'Comments' => $order->Notes,
325
                    'Currency' =>[
326
                        'CurrencyCode' => $order->Currency()
327
                    ],
328
                    'Customer' => [
329
                        'Guid' => $member->Guid
330
                    ],
331
                    'DeliveryCity' => $shipping_address->City,
332
                    'DeliveryCountry' => $countries[$shipping_address->Country],
333
                    'DeliveryPostCode' => $shipping_address->PostalCode,
334
                    'DeliveryRegion' => $shipping_address->State,
335
                    'DeliveryStreetAddress' => $shipping_address->Address,
336
                    'DeliveryStreetAddress2' => $shipping_address->AddressLine2,
337
                    'DiscountRate' => 0,
338
                    'Guid' => $order->Guid,
339
                    'OrderDate' => $date_placed->format('Y-m-d\TH:i:s'),
340
                    'OrderNumber' => $order->Reference,
341
                    'OrderStatus' => 'Parked',
342
                    'PaymentDueDate' => $date_paid->format('Y-m-d\TH:i:s'),
343
                    'ReceivedDate' => $date_placed->format('Y-m-d\TH:i:s'),
344
                    'RequiredDate' => $date_required->format('Y-m-d\TH:i:s'),
345
                    'SalesOrderLines' => $sales_order_lines,
346
                    'SubTotal' => $subtotal,
347
                    'Tax' => [
348
                        'TaxCode' => $tax_code
349
                    ],
350
                    'TaxTotal' => $tax_total,
351
                    'Total' => round(floatval($order->Total()), $config->rounding_precision)
352
                ];
353
354
                if ($shipping_method) {
355
                    $body['DeliveryMethod'] = $shipping_method;
356
                    $body['DeliveryName'] = $shipping_method;
357
                }
358
359
                if ($sales_order_group = $config->default_sales_order_group) {
360
                    $body['SalesOrderGroup'] = $sales_order_group;
361
                }
362
363
                if ($sales_person = $config->default_sales_person) {
364
                    $body['SalesPerson'] = $sales_person;
365
                }
366
367
                if ($source_id = $config->default_source_id) {
368
                    $body['SourceId'] = $source_id;
369
                }
370
371
                $this->owner->extend('updateUnleashedSalesOrder', $body);
372
373
                $response = UnleashedAPI::sendCall(
374
                    'POST',
375
                    'https://api.unleashedsoftware.com/SalesOrders/' . $order->Guid,
376
                    ['json' => $body]
377
                );
378
                if ($response->getReasonPhrase() == 'Created') {
379
                    $this->owner->OrderSentToUnleashed = SS_Datetime::now()->Rfc2822();
380
                    $this->owner->write();
381
                }
382
            }
383
        }
384
385
    }
386
}
387
388