UnleashedOrderTest::testSetBodySalesOrderLines()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 21
nc 1
nop 0
dl 0
loc 31
rs 9.584
c 1
b 0
f 0
1
<?php
2
3
namespace AntonyThorpe\SilverShopUnleashed\Tests;
4
5
use SilverShop\Shipping\ShippingFrameworkModifier;
0 ignored issues
show
Bug introduced by
The type SilverShop\Shipping\ShippingFrameworkModifier was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use AntonyThorpe\SilverShopUnleashed\BulkLoader\OrderBulkLoader;
7
use AntonyThorpe\SilverShopUnleashed\Defaults;
8
use SilverShop\Cart\ShoppingCart;
0 ignored issues
show
Bug introduced by
The type SilverShop\Cart\ShoppingCart was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use SilverShop\Checkout\OrderProcessor;
0 ignored issues
show
Bug introduced by
The type SilverShop\Checkout\OrderProcessor was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use SilverShop\Model\Modifiers\Shipping\Simple;
0 ignored issues
show
Bug introduced by
The type SilverShop\Model\Modifiers\Shipping\Simple was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use SilverShop\Model\Modifiers\Tax\FlatTax;
0 ignored issues
show
Bug introduced by
The type SilverShop\Model\Modifiers\Tax\FlatTax was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use SilverShop\Model\Order;
0 ignored issues
show
Bug introduced by
The type SilverShop\Model\Order was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use SilverShop\Page\Product;
0 ignored issues
show
Bug introduced by
The type SilverShop\Page\Product was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use SilverShop\Tests\ShopTest;
0 ignored issues
show
Bug introduced by
The type SilverShop\Tests\ShopTest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use SilverStripe\Core\Config\Config;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Core\Config\Config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use SilverStripe\Dev\SapphireTest;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Dev\SapphireTest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
18
class UnleashedOrderTest extends SapphireTest
19
{
20
    protected static $fixture_file = [
21
        'vendor/silvershop/core/tests/php/Fixtures/ShopMembers.yml',
22
        'vendor/silvershop/core/tests/php/Fixtures/shop.yml',
23
        'vendor/silvershop/shipping/tests/DistanceShippingMethod.yml',
24
        'vendor/silvershop/shipping/tests/Warehouses.yml',
25
        'fixtures/models.yml'
26
    ];
27
28
    protected function setUp(): void
29
    {
30
        Defaults::config()->set('send_sales_orders_to_unleashed', false);
31
        Defaults::config()->set('tax_modifier_class_name', FlatTax::class);
32
        Defaults::config()->set('shipping_modifier_class_name', Simple::class);
33
        parent::setUp();
34
        ShoppingCart::singleton()->clear();
35
        ShopTest::setConfiguration(); //reset config
36
        $this->logInWithPermission('ADMIN');
37
        Config::modify()
38
            ->set(Simple::class, 'default_charge', 8.95)
39
            ->set(Simple::class, 'product_code', 'Freight')
40
            ->set(FlatTax::class, 'rate', 0.15)
41
            ->set(FlatTax::class, 'exclusive', true)
42
            ->set(FlatTax::class, 'name', 'GST')
43
            ->set(FlatTax::class, 'tax_code', 'OUTPUT2')
44
            ->merge(Order::class, 'modifiers', [Simple::class, FlatTax::class]);
45
    }
46
47
    protected array $order_status_map = [
48
        'Open' => 'Unpaid',
49
        'Parked' => 'Paid',
50
        'Backordered' => 'Processing',
51
        'Placed' => 'Processing',
52
        'Picking' => 'Processing',
53
        'Picked' => 'Processing',
54
        'Packed' => 'Processing',
55
        'Dispatched' => 'Sent',
56
        'Complete' => 'Complete',
57
        'Deleted' => 'MemberCancelled'
58
    ];
59
60
    public function testChangeOrderStatus(): void
61
    {
62
        $apidata_array = (array) json_decode($this->jsondata, true);
63
        $apidata_array = reset($apidata_array);
64
65
        $items = $apidata_array['Items'];
66
67
        $orderBulkLoader = OrderBulkLoader::create(Order::class);
68
        $orderBulkLoader->transforms = [
69
            'Status' => [
70
                'callback' => fn($value, &$placeholder) =>
0 ignored issues
show
Unused Code introduced by
The parameter $placeholder is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

70
                'callback' => fn($value, /** @scrutinizer ignore-unused */ &$placeholder) =>

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
71
                    // convert from Unleashed Sales Order status to Silvershop
72
                    $this->order_status_map[$value]
73
            ]
74
        ];
75
        $bulkLoaderResult = $orderBulkLoader->updateRecords($items);
76
77
        // Check Results
78
        $this->assertEquals(0, $bulkLoaderResult->CreatedCount());
79
        $this->assertEquals(2, $bulkLoaderResult->UpdatedCount());
80
        $this->assertEquals(0, $bulkLoaderResult->DeletedCount());
81
        $this->assertEquals(0, $bulkLoaderResult->SkippedCount());
82
        $this->assertCount(2, $bulkLoaderResult);
83
84
        // Check Dataobjects
85
        $order1 = Order::get()->find('Reference', 'O1');
86
        $this->assertEquals(
87
            'Processing',
88
            $order1->Status,
89
            'OrderStatus of reference O1 is "Processing"'
90
        );
91
92
        $order2 = Order::get()->find('Reference', 'O2');
93
        $this->assertEquals(
94
            'Sent',
95
            $order2->Status,
96
            'OrderStatus of reference O1 is "Sent"'
97
        );
98
    }
99
100
    public function testSetBodyAddress(): void
101
    {
102
        $body = [
103
            'Addresses' => []
104
        ];
105
        $order = $this->objFromFixture(Order::class, "payablecart");
106
        OrderProcessor::create($order)->placeOrder();
107
        $body = $order->setBodyAddress($body, $order, 'Postal');
108
        $result = implode('|', array_values($body['Addresses'][0]));
109
        $this->assertSame(
110
            '12 Foo Street Bar Farmville|Postal|Farmville|United States||New Sandwich|12 Foo Street|Bar',
111
            $result,
112
            'Postal Address added to $body["Address"]'
113
        );
114
115
        $body = $order->setBodyAddress($body, $order, 'Physical');
116
        $result = implode('|', array_values($body['Addresses'][1]));
117
        $this->assertSame(
118
            '12 Foo Street Bar Farmville|Physical|Farmville|United States||New Sandwich|12 Foo Street|Bar',
119
            $result,
120
            'Physical Address added to $body["Address"]'
121
        );
122
        $result = implode('|', array_values($body['Addresses'][2]));
123
        $this->assertSame(
124
            '12 Foo Street Bar Farmville|Shipping|Farmville|United States||New Sandwich|12 Foo Street|Bar',
125
            $result,
126
            'Shipping Address added to $body["Address"]'
127
        );
128
129
        $result = $body['DeliveryCity'] . '|' . $body['DeliveryCountry'] . '|' . $body['DeliveryPostCode'] . '|' . $body['DeliveryRegion'] . '|' . $body['DeliveryStreetAddress'] . '|' . $body['DeliveryStreetAddress2'];
130
        $this->assertSame(
131
            'Farmville|United States||New Sandwich|12 Foo Street|Bar',
132
            $result,
133
            'Delivery Address added to $body'
134
        );
135
    }
136
137
    public function testSetBodyCurrencyCode(): void
138
    {
139
        $body = [
140
            'Currency' => []
141
        ];
142
        $order = $this->objFromFixture(Order::class, "payablecart");
143
        OrderProcessor::create($order)->placeOrder();
144
        $body = $order->setBodyCurrencyCode($body, $order);
145
146
        $this->assertSame(
147
            'NZD',
148
            $body['Currency']['CurrencyCode'],
149
            'Currency Code added to $body'
150
        );
151
    }
152
153
    public function testSetBodyCustomerCodeAndName(): void
154
    {
155
        $body = [];
156
        $order = $this->objFromFixture(Order::class, "payablecart");
157
        OrderProcessor::create($order)->placeOrder();
158
        $body = $order->setBodyCustomerCodeAndName($body, $order);
159
        $result = implode('|', array_values($body));
160
        $this->assertSame(
161
            'Payable Smith|Payable Smith',
162
            $result,
163
            'Set BodyCustomerCodeAndName'
164
        );
165
166
        $order->BillingAddress()->Company = 'Test Company';
167
        $body = $order->setBodyCustomerCodeAndName($body, $order);
168
        $result = implode('|', array_values($body));
169
        $this->assertSame(
170
            'Test Company|Test Company',
171
            $result,
172
            'Set BodyCustomerCodeAndName with Company name'
173
        );
174
    }
175
176
    public function testSetBodySalesOrderLines(): void
177
    {
178
        $order = $this->objFromFixture(Order::class, "paid1");
179
        OrderProcessor::create($order)->placeOrder();
180
        $this->assertEquals(408, $order->Total(), "check totals");
181
        $body = $order->setBodySalesOrderLines(
182
            [
183
                'Tax' => [
184
                    'TaxCode' => 'OUTPUT2'
185
                ]
186
            ],
187
            $order,
188
            FlatTax::class,
189
            2
190
        );
191
        $result = (string) json_encode($body, JSON_HEX_QUOT | JSON_HEX_TAG);
192
        $this->assertStringContainsString(
193
            'SalesOrderLines',
194
            $result,
195
            'Contains SalesOrderLines'
196
        );
197
        $this->assertStringContainsString(
198
            '"LineType":null,"LineTotal":8,"OrderQuantity":1,"Product":{"Guid":"G11"},"UnitPrice":8,"LineTax":1.2,"LineTaxCode":"OUTPUT2"}',
199
            $result,
200
            'Set SetBodySalesOrderLines line 1',
201
        );
202
203
        $this->assertStringContainsString(
204
            '"LineType":null,"LineTotal":400,"OrderQuantity":2,"Product":{"Guid":"G15"},"UnitPrice":200,"LineTax":60,"LineTaxCode":"OUTPUT2"}',
205
            $result,
206
            'Set SetBodySalesOrderLines line 2'
207
        );
208
    }
209
210
    public function testSetBodySalesOrderLinesWithModifiers(): void
211
    {
212
        $product = $this->objFromFixture(Product::class, 'urntap');
213
        $product->publishSingle();
214
215
        $shoppingCart = ShoppingCart::singleton();
216
        $shoppingCart->clear();
217
        $shoppingCart->add($product);
218
219
        $order = $shoppingCart->current();
220
        $order->calculate();
221
222
        $this->assertCount(
223
            2,
224
            $order->Modifiers(),
225
            'Shipping & Tax Modifiers in order'
226
        );
227
        $body = $order->setBodySalesOrderLines(
228
            [
229
                'Tax' => [
230
                    'TaxCode' => 'OUTPUT2'
231
                ]
232
            ],
233
            $order,
234
            FlatTax::class,
235
            2
236
        );
237
        $freight_modifier = $body['SalesOrderLines'][1];
238
        $result = $freight_modifier['DiscountRate'] . '|' . $freight_modifier['LineNumber'] . '|' . $freight_modifier['LineTotal'] . '|' . $freight_modifier['LineType'] . '|' . $freight_modifier['OrderQuantity'] . '|' . $freight_modifier['UnitPrice'] . '|' . $freight_modifier['LineTax'] . '|' . $freight_modifier['LineTaxCode'];
239
240
        $this->assertSame(
241
            '0|2|8.95||1|8.95|1.34|OUTPUT2',
242
            $result,
243
            'Modifiers in the SalesOrderLines added to $body'
244
        );
245
        $this->assertSame(
246
            'Freight',
247
            $freight_modifier['Product']['ProductCode'],
248
            'ProductCode of the Freight Modifier in $body is "Freight"'
249
        );
250
    }
251
252
    public function testSetBodySubTotalAndTax(): void
253
    {
254
        $product = $this->objFromFixture(Product::class, 'urntap');
255
        $product->publishSingle();
256
257
        $shoppingCart = ShoppingCart::singleton();
258
        $shoppingCart->clear();
259
        $shoppingCart->add($product);
260
261
        $order = $shoppingCart->current();
262
        $order->calculate();
263
264
        $body = $order->setBodyTaxCode(
265
            [],
266
            $order,
267
            FlatTax::class
268
        );
269
        $body = $order->setBodySalesOrderLines(
270
            $body,
271
            $order,
272
            FlatTax::class,
273
            2
274
        );
275
        $body = $order->setBodySubTotalAndTax(
276
            $body,
277
            $order,
278
            FlatTax::class,
279
            2
280
        );
281
282
        $this->assertTrue(
283
            $body['Taxable'],
284
            'Taxable is set to true'
285
        );
286
        $this->assertEqualsWithDelta(11.19, $body['TaxTotal'], PHP_FLOAT_EPSILON, 'TaxTotal is set to $11.19 ((65.65 + 8.95) * .15) in $body');
287
        $this->assertEqualsWithDelta(74.60, $body['SubTotal'], PHP_FLOAT_EPSILON, 'SubTotal is set to $74.60 (65.65 + 8.95) in $body');
288
    }
289
290
    public function testTaxRounding(): void
291
    {
292
        $product = $this->objFromFixture(Product::class, 'filter');
293
        $product->publishSingle();
294
295
        $tax_modifier_class_name = FlatTax::class;
296
        $shoppingCart = ShoppingCart::singleton();
297
        $shoppingCart->clear();
298
        $shoppingCart->add($product);
299
300
        $order = $shoppingCart->current();
301
        $total = $order->calculate();
302
303
        $body = $order->setBodyTaxCode(
304
            [],
305
            $order,
306
            $tax_modifier_class_name
307
        );
308
        $body = $order->setBodySalesOrderLines(
309
            $body,
310
            $order,
311
            $tax_modifier_class_name,
312
            2
313
        );
314
        $body = $order->setBodySubTotalAndTax(
315
            $body,
316
            $order,
317
            $tax_modifier_class_name,
318
            2
319
        );
320
        $this->assertEquals(
321
            '8.39',
322
            $body['TaxTotal'],
323
            'TaxTotal is set to $8.39 ((46.96 + 8.95) * .15) in $body'
324
        );
325
        $this->assertEquals(
326
            '55.91',
327
            $body['SubTotal'],
328
            'SubTotal is set to $55.91 (46.96 + 8.95) in $body'
329
        );
330
        $this->assertEqualsWithDelta(64.3, round($total, 2), PHP_FLOAT_EPSILON, 'Total equals $64.30');
331
        $this->assertEqualsWithDelta(64.3, round(floatval($body['TaxTotal'] + $body['SubTotal']), 2), PHP_FLOAT_EPSILON, 'TaxTotal plus SubTotal equals $64.30');
332
    }
333
334
    public function testTaxRounding2(): void
335
    {
336
        ShopTest::setConfiguration(); //reset config
337
        $this->logInWithPermission('ADMIN');
338
        Config::modify()
339
            ->set(Simple::class, 'default_charge', 15.50)
340
            ->set(Simple::class, 'product_code', 'Freight')
341
            ->set(FlatTax::class, 'rate', 0.15)
342
            ->set(FlatTax::class, 'exclusive', true)
343
            ->set(FlatTax::class, 'name', 'GST')
344
            ->set(FlatTax::class, 'tax_code', 'OUTPUT2')
345
            ->merge(Order::class, 'modifiers', [Simple::class, FlatTax::class]);
346
        $product = $this->objFromFixture(Product::class, 'boiler');
347
        $product->publishSingle();
348
349
        $tax_modifier_class_name = FlatTax::class;
350
        $shoppingCart = ShoppingCart::singleton();
351
        $shoppingCart->clear();
352
        $shoppingCart->add($product);
353
354
        $order = $shoppingCart->current();
355
        $total = $order->calculate();
356
357
        $body = $order->setBodyTaxCode(
358
            [],
359
            $order,
360
            $tax_modifier_class_name
361
        );
362
        $body = $order->setBodySalesOrderLines(
363
            $body,
364
            $order,
365
            $tax_modifier_class_name,
366
            2
367
        );
368
        $body = $order->setBodySubTotalAndTax(
369
            $body,
370
            $order,
371
            $tax_modifier_class_name,
372
            2
373
        );
374
375
        $this->assertEquals(
376
            '139.15',
377
            $body['TaxTotal'],
378
            'TaxTotal is set to $139.15 ((912.17 + 15.50) * .15) in $body'
379
        );
380
        $this->assertEquals(
381
            '927.67',
382
            $body['SubTotal'],
383
            'SubTotal is set to $927.67 (912.17 + 15.50) in $body'
384
        );
385
        $this->assertEqualsWithDelta(1066.82, round($total, 2), PHP_FLOAT_EPSILON, 'Total equals $1,066.82');
386
        $this->assertEqualsWithDelta(1066.82, round(floatval($body['TaxTotal'] + $body['SubTotal']), 2), PHP_FLOAT_EPSILON, 'TaxTotal plus SubTotal equals $1,066.82');
387
    }
388
389
390
    public function testSetBodyDeliveryMethodAndDeliveryName(): void
391
    {
392
        Defaults::config()->set('shipping_modifier_class_name', ShippingFrameworkModifier::class);
393
        Config::modify()->set(ShippingFrameworkModifier::class, 'product_code', 'Freight');
394
        $body = [];
395
        $configForClass = Defaults::config();
396
        $order = $this->objFromFixture(Order::class, "payablecart");
397
        $body = $order->setBodyDeliveryMethodAndDeliveryName($body, $order, $configForClass->get('shipping_modifier_class_name'));
398
        $result = implode('|', array_values($body));
399
        $this->assertSame(
400
            'Freight|Freight',
401
            $result,
402
            'Set BodyDeliveryMethodAndDeliveryName'
403
        );
404
    }
405
406
    /**
407
     * JSON data for test
408
     * Unleashed Software API Documentation @link https://apidocs.unleashedsoftware.com/Products
409
     * @var string
410
     */
411
    protected $jsondata = '[
412
        {
413
          "Pagination": {
414
            "NumberOfItems": 2,
415
            "PageSize": 200,
416
            "PageNumber": 1,
417
            "NumberOfPages": 1
418
          },
419
          "Items": [
420
            {
421
              "SalesOrderLines": [
422
                {
423
                  "LineNumber": 1,
424
                  "LineType": null,
425
                  "Product": {
426
                    "Guid": "G11",
427
                    "ProductCode": "IIID1",
428
                    "ProductDescription": "Socks"
429
                  },
430
                  "DueDate": "/Date(1473099415000)/",
431
                  "OrderQuantity": 1,
432
                  "UnitPrice": 8,
433
                  "DiscountRate": 0,
434
                  "LineTotal": 8,
435
                  "Volume": null,
436
                  "Weight": null,
437
                  "Comments": null,
438
                  "AverageLandedPriceAtTimeOfSale": 8,
439
                  "TaxRate": 0,
440
                  "LineTax": 0,
441
                  "XeroTaxCode": "G.S.T.",
442
                  "BCUnitPrice": 8,
443
                  "BCLineTotal": 8,
444
                  "BCLineTax": 0,
445
                  "LineTaxCode": "G.S.T.",
446
                  "XeroSalesAccount": null,
447
                  "SerialNumbers": null,
448
                  "BatchNumbers": null,
449
                  "Guid": "G401",
450
                  "LastModifiedOn": "/Date(1473149768263)/"
451
                },
452
                {
453
                  "LineNumber": 2,
454
                  "LineType": null,
455
                  "Product": {
456
                    "Guid": "G15",
457
                    "ProductCode": "IIID5",
458
                    "ProductDescription": "Mp3 Player"
459
                  },
460
                  "DueDate": "/Date(1473099415000)/",
461
                  "OrderQuantity": 2,
462
                  "UnitPrice": 200,
463
                  "DiscountRate": 0,
464
                  "LineTotal": 400,
465
                  "Volume": null,
466
                  "Weight": null,
467
                  "Comments": null,
468
                  "AverageLandedPriceAtTimeOfSale": 200,
469
                  "TaxRate": 0,
470
                  "LineTax": 0,
471
                  "XeroTaxCode": "G.S.T.",
472
                  "BCUnitPrice": 200,
473
                  "BCLineTotal": 400,
474
                  "BCLineTax": 0,
475
                  "LineTaxCode": "G.S.T.",
476
                  "XeroSalesAccount": null,
477
                  "SerialNumbers": null,
478
                  "BatchNumbers": null,
479
                  "Guid": "G402",
480
                  "LastModifiedOn": "/Date(1473149768279)/"
481
                }
482
              ],
483
              "OrderNumber": "O1",
484
              "OrderDate": "/Date(1473116400000)/",
485
              "RequiredDate": "/Date(1473548400000)/",
486
              "OrderStatus": "Placed",
487
              "Customer": {
488
                "CustomerCode": "Jeremy Peremy",
489
                "CustomerName": "Jeremy Peremy",
490
                "CurrencyId": 110,
491
                "Guid": "test",
492
                "LastModifiedOn": "/Date(1472624588017)/"
493
              },
494
              "CustomerRef": null,
495
              "Comments": "Test",
496
              "Warehouse": {
497
                "WarehouseCode": "test",
498
                "WarehouseName": "Queen St",
499
                "IsDefault": true,
500
                "StreetNo": "1",
501
                "AddressLine1": "Queen St",
502
                "AddressLine2": null,
503
                "City": "Invercargill",
504
                "Region": "Southland",
505
                "Country": "New Zealand",
506
                "PostCode": "9999",
507
                "PhoneNumber": "1234 567",
508
                "FaxNumber": null,
509
                "MobileNumber": null,
510
                "DDINumber": null,
511
                "ContactName": "Ed Hillary",
512
                "Obsolete": false,
513
                "Guid": "test",
514
                "LastModifiedOn": "/Date(1471582972964)/"
515
              },
516
              "ReceivedDate": "/Date(1473099415000)/",
517
              "DeliveryName": null,
518
              "DeliveryStreetAddress": "15 Ray St",
519
              "DeliverySuburb": "",
520
              "DeliveryCity": "Kaitaia",
521
              "DeliveryRegion": "Northland",
522
              "DeliveryCountry": "New Zealand",
523
              "DeliveryPostCode": "1111",
524
              "Currency": {
525
                "CurrencyCode": "NZD",
526
                "Description": "New Zealand, Dollars",
527
                "Guid": "test",
528
                "LastModifiedOn": "/Date(1415058050647)/"
529
              },
530
              "ExchangeRate": 1,
531
              "DiscountRate": 0,
532
              "Tax": {
533
                "TaxCode": "G.S.T.",
534
                "Description": null,
535
                "TaxRate": 0,
536
                "CanApplyToExpenses": false,
537
                "CanApplyToRevenue": false,
538
                "Obsolete": false,
539
                "Guid": "00000000-0000-0000-0000-000000000000",
540
                "LastModifiedOn": null
541
              },
542
              "TaxRate": 0,
543
              "XeroTaxCode": "G.S.T.",
544
              "SubTotal": 408,
545
              "TaxTotal": 0,
546
              "Total": 408,
547
              "TotalVolume": 0,
548
              "TotalWeight": 0,
549
              "BCSubTotal": 408,
550
              "BCTaxTotal": 0,
551
              "BCTotal": 408,
552
              "PaymentDueDate": "/Date(1473106568169)/",
553
              "SalesOrderGroup": null,
554
              "DeliveryMethod": null,
555
              "SalesPerson": null,
556
              "SendAccountingJournalOnly": false,
557
              "SourceId": "web",
558
              "CreatedBy": "[email protected]",
559
              "Guid": "G201",
560
              "LastModifiedOn": "/Date(1473149768310)/"
561
            },
562
            {
563
              "SalesOrderLines": [
564
                {
565
                  "LineNumber": 1,
566
                  "LineType": null,
567
                  "Product": {
568
                    "Guid": "G11",
569
                    "ProductCode": "IIID1",
570
                    "ProductDescription": "Socks"
571
                  },
572
                  "DueDate": "/Date(1473099415000)/",
573
                  "OrderQuantity": 1,
574
                  "UnitPrice": 8,
575
                  "DiscountRate": 0,
576
                  "LineTotal": 8,
577
                  "Volume": null,
578
                  "Weight": null,
579
                  "Comments": null,
580
                  "AverageLandedPriceAtTimeOfSale": 8,
581
                  "TaxRate": 0,
582
                  "LineTax": 0,
583
                  "XeroTaxCode": "G.S.T.",
584
                  "BCUnitPrice": 8,
585
                  "BCLineTotal": 8,
586
                  "BCLineTax": 0,
587
                  "LineTaxCode": "G.S.T.",
588
                  "XeroSalesAccount": null,
589
                  "SerialNumbers": null,
590
                  "BatchNumbers": null,
591
                  "Guid": "G403",
592
                  "LastModifiedOn": "/Date(1473149768263)/"
593
                },
594
                {
595
                  "LineNumber": 2,
596
                  "LineType": null,
597
                  "Product": {
598
                    "Guid": "G15",
599
                    "ProductCode": "IIID5",
600
                    "ProductDescription": "Mp3 Player"
601
                  },
602
                  "DueDate": "/Date(1473099415000)/",
603
                  "OrderQuantity": 2,
604
                  "UnitPrice": 200,
605
                  "DiscountRate": 0,
606
                  "LineTotal": 400,
607
                  "Volume": null,
608
                  "Weight": null,
609
                  "Comments": null,
610
                  "AverageLandedPriceAtTimeOfSale": 200,
611
                  "TaxRate": 0,
612
                  "LineTax": 0,
613
                  "XeroTaxCode": "G.S.T.",
614
                  "BCUnitPrice": 200,
615
                  "BCLineTotal": 400,
616
                  "BCLineTax": 0,
617
                  "LineTaxCode": "G.S.T.",
618
                  "XeroSalesAccount": null,
619
                  "SerialNumbers": null,
620
                  "BatchNumbers": null,
621
                  "Guid": "G404",
622
                  "LastModifiedOn": "/Date(1473149768279)/"
623
                }
624
              ],
625
              "OrderNumber": "O2",
626
              "OrderDate": "/Date(1473116400000)/",
627
              "RequiredDate": "/Date(1473548400000)/",
628
              "OrderStatus": "Dispatched",
629
              "Customer": {
630
                "CustomerCode": "Jeremy Peremy",
631
                "CustomerName": "Jeremy Peremy",
632
                "CurrencyId": 110,
633
                "Guid": "test",
634
                "LastModifiedOn": "/Date(1472624588017)/"
635
              },
636
              "CustomerRef": null,
637
              "Comments": "Test",
638
              "Warehouse": {
639
                "WarehouseCode": "test",
640
                "WarehouseName": "Queen St",
641
                "IsDefault": true,
642
                "StreetNo": "1",
643
                "AddressLine1": "Queen St",
644
                "AddressLine2": null,
645
                "City": "Invercargill",
646
                "Region": "Southland",
647
                "Country": "New Zealand",
648
                "PostCode": "9999",
649
                "PhoneNumber": "1234 567",
650
                "FaxNumber": null,
651
                "MobileNumber": null,
652
                "DDINumber": null,
653
                "ContactName": "Ed Hillary",
654
                "Obsolete": false,
655
                "Guid": "test",
656
                "LastModifiedOn": "/Date(1471582972964)/"
657
              },
658
              "ReceivedDate": "/Date(1473099415000)/",
659
              "DeliveryName": null,
660
              "DeliveryStreetAddress": "15 Ray St",
661
              "DeliverySuburb": "",
662
              "DeliveryCity": "Kaitaia",
663
              "DeliveryRegion": "Northland",
664
              "DeliveryCountry": "New Zealand",
665
              "DeliveryPostCode": "1111",
666
              "Currency": {
667
                "CurrencyCode": "NZD",
668
                "Description": "New Zealand, Dollars",
669
                "Guid": "test",
670
                "LastModifiedOn": "/Date(1415058050647)/"
671
              },
672
              "ExchangeRate": 1,
673
              "DiscountRate": 0,
674
              "Tax": {
675
                "TaxCode": "G.S.T.",
676
                "Description": null,
677
                "TaxRate": 0,
678
                "CanApplyToExpenses": false,
679
                "CanApplyToRevenue": false,
680
                "Obsolete": false,
681
                "Guid": "00000000-0000-0000-0000-000000000000",
682
                "LastModifiedOn": null
683
              },
684
              "TaxRate": 0,
685
              "XeroTaxCode": "G.S.T.",
686
              "SubTotal": 408,
687
              "TaxTotal": 0,
688
              "Total": 408,
689
              "TotalVolume": 0,
690
              "TotalWeight": 0,
691
              "BCSubTotal": 408,
692
              "BCTaxTotal": 0,
693
              "BCTotal": 408,
694
              "PaymentDueDate": "/Date(1473106568169)/",
695
              "SalesOrderGroup": null,
696
              "DeliveryMethod": null,
697
              "SalesPerson": null,
698
              "SendAccountingJournalOnly": false,
699
              "SourceId": "web",
700
              "CreatedBy": "[email protected]",
701
              "Guid": "G202",
702
              "LastModifiedOn": "/Date(1473149768310)/"
703
            }
704
          ]
705
        }
706
      ]';
707
}
708