Passed
Push — master ( fc01fb...26d801 )
by Aimeos
28:48 queued 11:51
created

StandardTest::tearDown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2023
7
 */
8
9
10
namespace Aimeos\MShop\Order\Manager;
11
12
13
class StandardTest extends \PHPUnit\Framework\TestCase
14
{
15
	private $context;
16
	private $object;
17
	private $editor = '';
18
19
20
	protected function setUp() : void
21
	{
22
		$this->editor = \TestHelper::context()->editor();
23
		$this->context = \TestHelper::context();
24
		$this->object = new \Aimeos\MShop\Order\Manager\Standard( $this->context );
25
	}
26
27
28
	protected function tearDown() : void
29
	{
30
		unset( $this->object );
31
	}
32
33
34
	public function testAggregate()
35
	{
36
		$search = $this->object->filter()->add( ['order.editor' => 'core'] );
37
		$result = $this->object->aggregate( $search, 'order.channel' );
38
39
		$this->assertEquals( 2, count( $result ) );
40
		$this->assertArrayHasKey( 'web', $result );
41
		$this->assertEquals( 3, $result->get( 'web' ) );
0 ignored issues
show
Bug introduced by
The method get() does not exist on ArrayAccess. It seems like you code against a sub-type of ArrayAccess such as Aimeos\MShop\Common\Item\Base or Yaf_Config_Simple or Aimeos\Map or Yaf\Session or Aimeos\MShop\Order\Item\Base or HttpQueryString or Yaf_Session or Cassandra\Map or Yaf\Config\Simple or Yaf\Config\Ini or http\QueryString or Yaf_Config_Ini. ( Ignorable by Annotation )

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

41
		$this->assertEquals( 3, $result->/** @scrutinizer ignore-call */ get( 'web' ) );
Loading history...
42
	}
43
44
45
	public function testAggregateMultiple()
46
	{
47
		$cols = ['order.channel', 'order.statuspayment'];
48
		$search = $this->object->filter()->add( ['order.editor' => 'core'] )->order( $cols );
49
		$result = $this->object->aggregate( $search, $cols );
50
51
		$this->assertEquals( ['phone' => [6 => 1], 'web' => [5 => 1, 6 => 2]], $result->toArray() );
52
	}
53
54
55
	public function testAggregateAvg()
56
	{
57
		$search = $this->object->filter()->add( ['order.editor' => 'core'] );
58
		$result = $this->object->aggregate( $search, 'order.cmonth', 'order.price', 'avg' );
59
60
		$this->assertEquals( 1, count( $result ) );
61
		$this->assertEquals( '784.75', round( $result->first(), 2 ) );
62
	}
63
64
65
	public function testAggregateAvgMultiple()
66
	{
67
		$cols = ['order.cmonth', 'order.statuspayment'];
68
		$search = $this->object->filter()->add( ['order.editor' => 'core'] )->order( $cols );
69
		$result = $this->object->aggregate( $search, $cols, 'order.price', 'avg' );
70
71
		$this->assertEquals( 1, count( $result ) );
72
		$this->assertArrayHasKey( 5, $result->first() );
73
		$this->assertArrayHasKey( 6, $result->first() );
74
		$this->assertEquals( '13.50', round( $result->first()[5], 2 ) );
75
		$this->assertEquals( '1041.83', round( $result->first()[6], 2 ) );
76
	}
77
78
79
	public function testAggregateSum()
80
	{
81
		$search = $this->object->filter()->add( ['order.editor' => 'core'] );
82
		$result = $this->object->aggregate( $search, 'order.cmonth', 'order.price', 'sum' );
83
84
		$this->assertEquals( 1, count( $result ) );
85
		$this->assertEquals( '3139.00', $result->first() );
86
	}
87
88
89
	public function testAggregateSumMultiple()
90
	{
91
		$cols = ['order.cmonth', 'order.statuspayment'];
92
		$search = $this->object->filter()->add( ['order.editor' => 'core'] )->order( $cols );
93
		$result = $this->object->aggregate( $search, $cols, 'order.price', 'sum' );
94
95
		$this->assertEquals( 1, count( $result ) );
96
		$this->assertArrayHasKey( 5, $result->first() );
97
		$this->assertArrayHasKey( 6, $result->first() );
98
		$this->assertEquals( '13.50', round( $result->first()[5], 2 ) );
99
		$this->assertEquals( '3125.5', round( $result->first()[6], 2 ) );
100
	}
101
102
103
	public function testAggregateTimes()
104
	{
105
		$search = $this->object->filter()->add( ['order.editor' => 'core'] );
106
		$search->setSortations( array( $search->sort( '-', 'order.cdate' ) ) );
107
		$result = $this->object->aggregate( $search, 'order.cmonth' )->toArray();
108
109
		$this->assertEquals( 1, count( $result ) );
110
		$this->assertEquals( 4, reset( $result ) );
111
	}
112
113
114
	public function testAggregateAddress()
115
	{
116
		$search = $this->object->filter()->add( ['order.editor' => 'core'] );
117
		$result = $this->object->aggregate( $search, 'order.address.countryid' )->toArray();
118
119
		$this->assertEquals( 1, count( $result ) );
120
		$this->assertArrayHasKey( 'DE', $result );
121
		$this->assertEquals( 4, reset( $result ) );
122
	}
123
124
125
	public function testAggregateAddressMultiple()
126
	{
127
		$cols = ['order.address.countryid', 'order.statuspayment'];
128
		$search = $this->object->filter()->add( ['order.editor' => 'core'] )->order( $cols );
129
		$result = $this->object->aggregate( $search, $cols )->toArray();
130
131
		$this->assertEquals( ['DE' => [5 => 1, 6 => 3]], $result );
132
	}
133
134
135
	public function testAggregateMonth()
136
	{
137
		$search = $this->object->filter()->add( ['order.editor' => 'core'] );
138
		$result = $this->object->aggregate( $search, 'order.channel' )->toArray();
139
140
		$this->assertEquals( 2, count( $result ) );
141
		$this->assertArrayHasKey( 'web', $result );
142
		$this->assertEquals( 3, $result['web'] );
143
	}
144
145
146
	public function testClear()
147
	{
148
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->clear( [-1] ) );
149
	}
150
151
152
	public function testDeleteItems()
153
	{
154
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->delete( [-1] ) );
155
	}
156
157
158
	public function testGetResourceType()
159
	{
160
		$result = $this->object->getResourceType();
161
162
		$this->assertContains( 'order', $result );
163
		$this->assertContains( 'order/status', $result );
164
		$this->assertContains( 'order/address', $result );
165
		$this->assertContains( 'order/coupon', $result );
166
		$this->assertContains( 'order/product', $result );
167
		$this->assertContains( 'order/product/attribute', $result );
168
		$this->assertContains( 'order/service', $result );
169
		$this->assertContains( 'order/service/attribute', $result );
170
	}
171
172
173
	public function testCreateItem()
174
	{
175
		$this->assertInstanceOf( \Aimeos\MShop\Order\Item\Iface::class, $this->object->create() );
176
	}
177
178
179
	public function testGetItem()
180
	{
181
		$search = $this->object->filter()->slice( 0, 1 )
182
			->add( ['order.price' => '672.00', 'order.editor' => $this->editor] );
183
184
		$item = $this->object->search( $search )->first( new \RuntimeException( 'No order item found' ) );
185
186
		$actual = $this->object->get( $item->getId() );
187
188
		$this->assertEquals( $item, $actual );
189
		$this->assertEquals( '32.00', $item->getPrice()->getCosts() );
190
		$this->assertEquals( '5.00', $item->getPrice()->getRebate() );
191
		$this->assertEquals( '112.4034', $item->getPrice()->getTaxValue() );
192
	}
193
194
195
	public function testSaveUpdateDeleteItem()
196
	{
197
		$search = $this->object->filter()->slice( 0, 1 )
198
			->add( ['order.channel' => 'phone', 'order.editor' => $this->editor] );
199
200
		$item = $this->object->search( $search )->first( new \RuntimeException( 'No order item found' ) );
201
202
		$item->setId( null );
203
		$resultSaved = $this->object->save( $item );
204
		$itemSaved = $this->object->get( $item->getId() );
205
206
		$itemExp = clone $itemSaved;
207
		$itemExp->setChannel( 'web' );
208
		$resultUpd = $this->object->save( $itemExp );
209
		$itemUpd = $this->object->get( $itemExp->getId() );
210
211
		$this->object->delete( $itemSaved->getId() );
212
213
214
		$itemPrice = $item->getPrice();
215
		$itemSavedPrice = $itemSaved->getPrice();
216
217
		$this->assertTrue( $item->getId() !== null );
218
		$this->assertEquals( $item->getId(), $itemSaved->getId() );
219
		$this->assertEquals( $item->getSiteId(), $itemSaved->getSiteId() );
220
		$this->assertEquals( $item->getChannel(), $itemSaved->getChannel() );
221
		$this->assertEquals( $item->getDatePayment(), $itemSaved->getDatePayment() );
222
		$this->assertEquals( $item->getDateDelivery(), $itemSaved->getDateDelivery() );
223
		$this->assertEquals( $item->getStatusPayment(), $itemSaved->getStatusPayment() );
224
		$this->assertEquals( $item->getStatusDelivery(), $itemSaved->getStatusDelivery() );
225
		$this->assertEquals( $item->getInvoiceNumber(), $itemSaved->getInvoiceNumber() );
226
		$this->assertEquals( $item->getRelatedId(), $itemSaved->getRelatedId() );
227
		$this->assertEquals( $item->getCustomerId(), $itemSaved->getCustomerId() );
228
		$this->assertEquals( $item->locale()->getLanguageId(), $itemSaved->locale()->getLanguageId() );
229
		$this->assertEquals( $item->getCustomerReference(), $itemSaved->getCustomerReference() );
230
		$this->assertEquals( $item->getComment(), $itemSaved->getComment() );
231
		$this->assertEquals( $item->getSiteCode(), $itemSaved->getSiteCode() );
232
		$this->assertEquals( $itemPrice->getValue(), $itemSavedPrice->getValue() );
233
		$this->assertEquals( $itemPrice->getCosts(), $itemSavedPrice->getCosts() );
234
		$this->assertEquals( $itemPrice->getRebate(), $itemSavedPrice->getRebate() );
235
		$this->assertEquals( $itemPrice->getTaxValue(), $itemSavedPrice->getTaxValue() );
236
		$this->assertEquals( $itemPrice->getCurrencyId(), $itemSavedPrice->getCurrencyId() );
237
238
		$this->assertEquals( $this->editor, $itemSaved->editor() );
239
		$this->assertMatchesRegularExpression( '/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $itemSaved->getTimeCreated() );
240
		$this->assertMatchesRegularExpression( '/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $itemSaved->getTimeModified() );
241
242
		$itemExpPrice = $itemExp->getPrice();
243
		$itemUpdPrice = $itemUpd->getPrice();
244
245
		$this->assertEquals( $itemExp->getId(), $itemUpd->getId() );
246
		$this->assertEquals( $itemExp->getSiteId(), $itemUpd->getSiteId() );
247
		$this->assertEquals( $itemExp->getChannel(), $itemUpd->getChannel() );
248
		$this->assertEquals( $itemExp->getDatePayment(), $itemUpd->getDatePayment() );
249
		$this->assertEquals( $itemExp->getDateDelivery(), $itemUpd->getDateDelivery() );
250
		$this->assertEquals( $itemExp->getStatusPayment(), $itemUpd->getStatusPayment() );
251
		$this->assertEquals( $itemExp->getStatusDelivery(), $itemUpd->getStatusDelivery() );
252
		$this->assertEquals( $itemExp->getInvoiceNumber(), $itemUpd->getInvoiceNumber() );
253
		$this->assertEquals( $itemExp->getRelatedId(), $itemUpd->getRelatedId() );
254
		$this->assertEquals( $itemExp->getCustomerId(), $itemUpd->getCustomerId() );
255
		$this->assertEquals( $itemExp->locale()->getLanguageId(), $itemUpd->locale()->getLanguageId() );
256
		$this->assertEquals( $itemExp->getCustomerReference(), $itemUpd->getCustomerReference() );
257
		$this->assertEquals( $itemExp->getComment(), $itemUpd->getComment() );
258
		$this->assertEquals( $itemExp->getSiteCode(), $itemUpd->getSiteCode() );
259
		$this->assertEquals( $itemExpPrice->getValue(), $itemUpdPrice->getValue() );
260
		$this->assertEquals( $itemExpPrice->getCosts(), $itemUpdPrice->getCosts() );
261
		$this->assertEquals( $itemExpPrice->getRebate(), $itemUpdPrice->getRebate() );
262
		$this->assertEquals( $itemExpPrice->getTaxValue(), $itemUpdPrice->getTaxValue() );
263
		$this->assertEquals( $itemExpPrice->getCurrencyId(), $itemUpdPrice->getCurrencyId() );
264
265
		$this->assertEquals( $this->editor, $itemUpd->editor() );
266
		$this->assertEquals( $itemExp->getTimeCreated(), $itemUpd->getTimeCreated() );
267
		$this->assertMatchesRegularExpression( '/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $itemUpd->getTimeModified() );
268
269
		$this->assertInstanceOf( \Aimeos\MShop\Common\Item\Iface::class, $resultSaved );
270
		$this->assertInstanceOf( \Aimeos\MShop\Common\Item\Iface::class, $resultUpd );
271
272
		$this->expectException( \Aimeos\MShop\Exception::class );
273
		$this->object->get( $itemSaved->getId() );
274
	}
275
276
277
	public function testSaveStatusUpdatePayment()
278
	{
279
		$statusManager = \Aimeos\MShop::create( $this->context, 'order/status' );
280
281
		$search = $this->object->filter();
282
		$conditions = array(
283
			$search->compare( '==', 'order.channel', 'phone' ),
284
			$search->compare( '==', 'order.editor', $this->editor )
285
		);
286
		$search->setConditions( $search->and( $conditions ) );
287
		$results = $this->object->search( $search )->toArray();
288
289
		if( ( $item = reset( $results ) ) === false ) {
290
			throw new \RuntimeException( 'No order item found.' );
291
		}
292
293
		$item->setId( null );
294
		$this->object->save( $item );
295
296
297
		$search = $statusManager->filter();
298
		$search->setConditions( $search->compare( '==', 'order.status.parentid', $item->getId() ) );
299
		$results = $statusManager->search( $search )->toArray();
300
301
		$this->object->delete( $item->getId() );
302
303
		$this->assertEquals( 0, count( $results ) );
304
305
306
		$item->setId( null );
307
		$item->setStatusPayment( \Aimeos\MShop\Order\Item\Base::PAY_CANCELED );
308
		$this->object->save( $item );
309
310
		$search = $statusManager->filter();
311
		$search->setConditions( $search->compare( '==', 'order.status.parentid', $item->getId() ) );
312
		$results = $statusManager->search( $search )->toArray();
313
314
		$this->object->delete( $item->getId() );
315
316
		if( ( $statusItem = reset( $results ) ) === false ) {
317
			throw new \RuntimeException( 'No status item found' );
318
		}
319
320
		$this->assertEquals( 1, count( $results ) );
321
		$this->assertEquals( \Aimeos\MShop\Order\Item\Status\Base::STATUS_PAYMENT, $statusItem->getType() );
322
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::PAY_CANCELED, $statusItem->getValue() );
323
	}
324
325
326
	public function testSaveStatusUpdateDelivery()
327
	{
328
		$statusManager = \Aimeos\MShop::create( $this->context, 'order/status' );
329
330
		$search = $this->object->filter();
331
		$conditions = array(
332
			$search->compare( '==', 'order.channel', 'phone' ),
333
			$search->compare( '==', 'order.editor', $this->editor )
334
		);
335
		$search->setConditions( $search->and( $conditions ) );
336
		$results = $this->object->search( $search )->toArray();
337
338
		if( ( $item = reset( $results ) ) === false ) {
339
			throw new \RuntimeException( 'No order item found.' );
340
		}
341
342
		$item->setId( null );
343
		$this->object->save( $item );
344
345
346
		$search = $statusManager->filter();
347
		$search->setConditions( $search->compare( '==', 'order.status.parentid', $item->getId() ) );
348
		$results = $statusManager->search( $search )->toArray();
349
350
		$this->object->delete( $item->getId() );
351
352
		$this->assertEquals( 0, count( $results ) );
353
354
355
		$item->setId( null );
356
		$item->setStatusDelivery( \Aimeos\MShop\Order\Item\Base::STAT_LOST );
357
		$this->object->save( $item );
358
359
		$search = $statusManager->filter();
360
		$search->setConditions( $search->compare( '==', 'order.status.parentid', $item->getId() ) );
361
		$results = $statusManager->search( $search )->toArray();
362
363
		$this->object->delete( $item->getId() );
364
365
		if( ( $statusItem = reset( $results ) ) === false ) {
366
			throw new \RuntimeException( 'No status item found' );
367
		}
368
369
		$this->assertEquals( 1, count( $results ) );
370
		$this->assertEquals( \Aimeos\MShop\Order\Item\Status\Base::STATUS_DELIVERY, $statusItem->getType() );
371
		$this->assertEquals( \Aimeos\MShop\Order\Item\Base::STAT_LOST, $statusItem->getValue() );
372
	}
373
374
375
	public function testCreateSearch()
376
	{
377
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $this->object->filter() );
378
	}
379
380
381
	public function testCreateSearchDefault()
382
	{
383
		$search = $this->object->filter( true );
384
385
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $search );
386
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\Iface::class, $search->getConditions() );
387
388
		$list = $search->getConditions()->getExpressions();
389
		$this->assertArrayHasKey( 0, $list );
390
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\Iface::class, $list[0] );
391
	}
392
393
394
	public function testCreateSearchSite()
395
	{
396
		$result = $this->object->filter( false, true );
397
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Expression\Combine\Iface::class, $result->getConditions() );
398
	}
399
400
401
	public function testSearchItems()
402
	{
403
		$siteid = $this->context->locale()->getSiteId();
404
405
		$total = 0;
406
		$search = $this->object->filter();
407
		$funcStatus = $search->make( 'order:status', ['typestatus', 'shipped'] );
408
409
		$expr = [];
410
		$expr[] = $search->compare( '!=', 'order.id', null );
411
		$expr[] = $search->compare( '==', 'order.siteid', $siteid );
412
		$expr[] = $search->compare( '==', 'order.channel', 'web' );
413
		$expr[] = $search->compare( '==', 'order.invoiceno', 'UINV-001' );
414
		$expr[] = $search->compare( '==', 'order.datepayment', '2008-02-15 12:34:56' );
415
		$expr[] = $search->compare( '==', 'order.datedelivery', null );
416
		$expr[] = $search->compare( '==', 'order.statuspayment', \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED );
417
		$expr[] = $search->compare( '==', 'order.statusdelivery', 4 );
418
		$expr[] = $search->compare( '==', 'order.relatedid', '' );
419
		$expr[] = $search->compare( '==', 'order.sitecode', 'unittest' );
420
		$expr[] = $search->compare( '>=', 'order.customerid', '' );
421
		$expr[] = $search->compare( '==', 'order.languageid', 'de' );
422
		$expr[] = $search->compare( '==', 'order.currencyid', 'EUR' );
423
		$expr[] = $search->compare( '==', 'order.price', '53.50' );
424
		$expr[] = $search->compare( '==', 'order.costs', '1.50' );
425
		$expr[] = $search->compare( '==', 'order.rebate', '14.50' );
426
		$expr[] = $search->compare( '~=', 'order.comment', 'This is a comment' );
427
		$expr[] = $search->compare( '>=', 'order.mtime', '1970-01-01 00:00:00' );
428
		$expr[] = $search->compare( '>=', 'order.ctime', '1970-01-01 00:00:00' );
429
		$expr[] = $search->compare( '==', 'order.editor', $this->editor );
430
		$expr[] = $search->compare( '==', $funcStatus, 1 );
431
432
		$expr[] = $search->compare( '!=', 'order.status.id', null );
433
		$expr[] = $search->compare( '==', 'order.status.siteid', $siteid );
434
		$expr[] = $search->compare( '!=', 'order.status.parentid', null );
435
		$expr[] = $search->compare( '>=', 'order.status.type', 'typestatus' );
436
		$expr[] = $search->compare( '==', 'order.status.value', 'shipped' );
437
		$expr[] = $search->compare( '>=', 'order.status.mtime', '1970-01-01 00:00:00' );
438
		$expr[] = $search->compare( '>=', 'order.status.ctime', '1970-01-01 00:00:00' );
439
		$expr[] = $search->compare( '==', 'order.status.editor', $this->editor );
440
441
		$expr[] = $search->compare( '!=', 'order.address.id', null );
442
		$expr[] = $search->compare( '==', 'order.address.siteid', $siteid );
443
		$expr[] = $search->compare( '!=', 'order.address.parentid', null );
444
		$expr[] = $search->compare( '==', 'order.address.type', 'payment' );
445
		$expr[] = $search->compare( '==', 'order.address.company', 'Example company' );
446
		$expr[] = $search->compare( '==', 'order.address.vatid', 'DE999999999' );
447
		$expr[] = $search->compare( '==', 'order.address.salutation', 'mr' );
448
		$expr[] = $search->compare( '==', 'order.address.title', '' );
449
		$expr[] = $search->compare( '==', 'order.address.firstname', 'Our' );
450
		$expr[] = $search->compare( '==', 'order.address.lastname', 'Unittest' );
451
		$expr[] = $search->compare( '==', 'order.address.address1', 'Durchschnitt' );
452
		$expr[] = $search->compare( '==', 'order.address.address2', '1' );
453
		$expr[] = $search->compare( '==', 'order.address.address3', '' );
454
		$expr[] = $search->compare( '==', 'order.address.postal', '20146' );
455
		$expr[] = $search->compare( '==', 'order.address.city', 'Hamburg' );
456
		$expr[] = $search->compare( '==', 'order.address.state', 'Hamburg' );
457
		$expr[] = $search->compare( '==', 'order.address.countryid', 'DE' );
458
		$expr[] = $search->compare( '==', 'order.address.languageid', 'de' );
459
		$expr[] = $search->compare( '==', 'order.address.telephone', '055544332211' );
460
		$expr[] = $search->compare( '==', 'order.address.email', '[email protected]' );
461
		$expr[] = $search->compare( '==', 'order.address.telefax', '055544332213' );
462
		$expr[] = $search->compare( '==', 'order.address.website', 'www.example.net' );
463
		$expr[] = $search->compare( '>=', 'order.address.mtime', '1970-01-01 00:00:00' );
464
		$expr[] = $search->compare( '>=', 'order.address.ctime', '1970-01-01 00:00:00' );
465
		$expr[] = $search->compare( '==', 'order.address.editor', $this->editor );
466
467
		$expr[] = $search->compare( '!=', 'order.coupon.id', null );
468
		$expr[] = $search->compare( '==', 'order.coupon.siteid', $siteid );
469
		$expr[] = $search->compare( '!=', 'order.coupon.parentid', null );
470
		$expr[] = $search->compare( '!=', 'order.coupon.productid', null );
471
		$expr[] = $search->compare( '==', 'order.coupon.code', 'OPQR' );
472
		$expr[] = $search->compare( '>=', 'order.coupon.mtime', '1970-01-01 00:00:00' );
473
		$expr[] = $search->compare( '>=', 'order.coupon.ctime', '1970-01-01 00:00:00' );
474
		$expr[] = $search->compare( '>=', 'order.coupon.editor', '' );
475
476
		$expr[] = $search->compare( '!=', 'order.product.id', null );
477
		$expr[] = $search->compare( '==', 'order.product.siteid', $siteid );
478
		$expr[] = $search->compare( '!=', 'order.product.parentid', null );
479
		$expr[] = $search->compare( '!=', 'order.product.productid', null );
480
		$expr[] = $search->compare( '==', 'order.product.prodcode', 'CNE' );
481
		$expr[] = $search->compare( '==', 'order.product.vendor', 'Test vendor' );
482
		$expr[] = $search->compare( '==', 'order.product.name', 'Cafe Noire Expresso' );
483
		$expr[] = $search->compare( '==', 'order.product.mediaurl', 'somewhere/thump1.jpg' );
484
		$expr[] = $search->compare( '==', 'order.product.quantity', 9 );
485
		$expr[] = $search->compare( '==', 'order.product.price', '4.50' );
486
		$expr[] = $search->compare( '==', 'order.product.costs', '0.00' );
487
		$expr[] = $search->compare( '==', 'order.product.rebate', '0.00' );
488
		$expr[] = $search->compare( '=~', 'order.product.taxrates', '{' );
489
		$expr[] = $search->compare( '==', 'order.product.flags', 0 );
490
		$expr[] = $search->compare( '==', 'order.product.position', 1 );
491
		$expr[] = $search->compare( '==', 'order.product.statuspayment', 5 );
492
		$expr[] = $search->compare( '==', 'order.product.statusdelivery', 1 );
493
		$expr[] = $search->compare( '>=', 'order.product.mtime', '1970-01-01 00:00:00' );
494
		$expr[] = $search->compare( '>=', 'order.product.ctime', '1970-01-01 00:00:00' );
495
		$expr[] = $search->compare( '==', 'order.product.editor', $this->editor );
496
497
		$expr[] = $search->compare( '!=', 'order.product.attribute.id', null );
498
		$expr[] = $search->compare( '==', 'order.product.attribute.siteid', $siteid );
499
		$expr[] = $search->compare( '!=', 'order.product.attribute.parentid', null );
500
		$expr[] = $search->compare( '==', 'order.product.attribute.code', 'width' );
501
		$expr[] = $search->compare( '==', 'order.product.attribute.value', '33' );
502
		$expr[] = $search->compare( '==', 'order.product.attribute.name', '33' );
503
		$expr[] = $search->compare( '==', 'order.product.attribute.quantity', 1 );
504
		$expr[] = $search->compare( '>=', 'order.product.attribute.mtime', '1970-01-01 00:00:00' );
505
		$expr[] = $search->compare( '>=', 'order.product.attribute.ctime', '1970-01-01 00:00:00' );
506
		$expr[] = $search->compare( '==', 'order.product.attribute.editor', $this->editor );
507
508
		$expr[] = $search->compare( '!=', 'order.service.id', null );
509
		$expr[] = $search->compare( '==', 'order.service.siteid', $siteid );
510
		$expr[] = $search->compare( '!=', 'order.service.parentid', null );
511
		$expr[] = $search->compare( '==', 'order.service.type', 'payment' );
512
		$expr[] = $search->compare( '==', 'order.service.code', 'unitpaymentcode' );
513
		$expr[] = $search->compare( '==', 'order.service.name', 'unitpaymentcode' );
514
		$expr[] = $search->compare( '==', 'order.service.price', '0.00' );
515
		$expr[] = $search->compare( '==', 'order.service.costs', '0.00' );
516
		$expr[] = $search->compare( '==', 'order.service.rebate', '0.00' );
517
		$expr[] = $search->compare( '=~', 'order.service.taxrates', '{' );
518
		$expr[] = $search->compare( '>=', 'order.service.mtime', '1970-01-01 00:00:00' );
519
		$expr[] = $search->compare( '>=', 'order.service.ctime', '1970-01-01 00:00:00' );
520
		$expr[] = $search->compare( '==', 'order.service.editor', $this->editor );
521
522
		$expr[] = $search->compare( '!=', 'order.service.attribute.id', null );
523
		$expr[] = $search->compare( '==', 'order.service.attribute.siteid', $siteid );
524
		$expr[] = $search->compare( '!=', 'order.service.attribute.parentid', null );
525
		$expr[] = $search->compare( '==', 'order.service.attribute.code', 'NAME' );
526
		$expr[] = $search->compare( '==', 'order.service.attribute.value', '"CreditCard"' );
527
		$expr[] = $search->compare( '==', 'order.service.attribute.quantity', 1 );
528
		$expr[] = $search->compare( '>=', 'order.service.attribute.mtime', '1970-01-01 00:00:00' );
529
		$expr[] = $search->compare( '>=', 'order.service.attribute.ctime', '1970-01-01 00:00:00' );
530
		$expr[] = $search->compare( '==', 'order.service.attribute.editor', $this->editor );
531
532
533
534
		$search->setConditions( $search->and( $expr ) );
535
		$result = $this->object->search( $search, [], $total )->toArray();
536
537
		$this->assertEquals( 1, count( $result ) );
538
		$this->assertEquals( 1, $total );
539
	}
540
541
542
	public function testSearchItemsTotal()
543
	{
544
		$total = 0;
545
		$search = $this->object->filter()->slice( 0, 1 );
546
		$conditions = array(
547
			$search->compare( '==', 'order.statuspayment', \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED ),
548
			$search->compare( '==', 'order.editor', $this->editor )
549
		);
550
		$search->setConditions( $search->and( $conditions ) );
551
		$items = $this->object->search( $search, [], $total )->toArray();
552
553
		$this->assertEquals( 1, count( $items ) );
554
		$this->assertEquals( 3, $total );
555
556
		foreach( $items as $itemId => $item ) {
557
			$this->assertEquals( $itemId, $item->getId() );
558
		}
559
	}
560
561
562
	public function testSearchItemsRef()
563
	{
564
		$total = 0;
565
		$search = $this->object->filter()->slice( 0, 1 );
566
		$conditions = array(
567
			$search->compare( '==', 'order.datepayment', '2008-02-15 12:34:56' ),
568
			$search->compare( '==', 'order.editor', $this->editor )
569
		);
570
		$search->setConditions( $search->and( $conditions ) );
571
		$item = $this->object->search( $search, ['order/address', 'order/coupon', 'order/product', 'order/service'], $total )->first();
572
573
		$this->assertEquals( 2, count( $item->getAddresses() ) );
574
		$this->assertEquals( 2, count( $item->getCoupons() ) );
575
		$this->assertEquals( 4, count( $item->getProducts() ) );
576
		$this->assertEquals( 2, count( $item->getServices() ) );
577
	}
578
579
580
	public function testGetSubManager()
581
	{
582
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'address' ) );
583
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'address', 'Standard' ) );
584
585
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'coupon' ) );
586
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'coupon', 'Standard' ) );
587
588
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'product' ) );
589
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'product', 'Standard' ) );
590
591
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'service' ) );
592
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'service', 'Standard' ) );
593
594
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'status' ) );
595
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'status', 'Standard' ) );
596
597
		$this->expectException( \LogicException::class );
598
		$this->object->getSubManager( 'unknown' );
599
	}
600
601
602
	public function testGetSubManagerInvalidName()
603
	{
604
		$this->expectException( \LogicException::class );
605
		$this->object->getSubManager( 'status', 'unknown' );
606
	}
607
608
609
	public function testSave()
610
	{
611
		$item = $this->getOrderItem();
612
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
613
614
		$basket = $this->getBasket( $item->getId(), $ref, true );
0 ignored issues
show
Bug introduced by
It seems like $item->getId() can also be of type null; however, parameter $id of Aimeos\MShop\Order\Manag...andardTest::getBasket() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

614
		$basket = $this->getBasket( /** @scrutinizer ignore-type */ $item->getId(), $ref, true );
Loading history...
615
		$this->object->save( $basket );
616
617
		$newBasketId = $basket->getId();
618
619
		$basket = $this->getBasket( $newBasketId, $ref );
620
		$this->object->delete( $newBasketId );
621
622
623
		$this->assertEquals( $item->getCustomerId(), $basket->getCustomerId() );
624
		$this->assertEquals( $basket->locale()->getSiteId(), $basket->getSiteId() );
625
626
		$this->assertEquals( 1.50, $basket->getPrice()->getCosts() );
627
628
		$pos = 1;
629
		$products = $basket->getProducts();
630
		$this->assertEquals( 4, count( $products ) );
631
632
		foreach( $products as $product )
633
		{
634
			if( $product->getProductCode() != 'U:MD' ) {
635
				$this->assertGreaterThanOrEqual( 2, count( $product->getAttributeItems() ) );
636
			}
637
			$this->assertEquals( $pos++, $product->getPosition() );
638
		}
639
640
		$this->assertEquals( 2, count( $basket->getAddresses() ) );
641
642
		$services = $basket->getServices();
643
		$this->assertEquals( 2, count( $services ) );
644
645
		$attributes = [];
646
		foreach( $services as $list )
647
		{
648
			foreach( $list as $service ) {
649
				$attributes[$service->getCode()] = $service->getAttributeItems();
650
			}
651
		}
652
653
		$this->assertEquals( 9, count( $attributes['unitpaymentcode'] ) );
654
		$this->assertEquals( 0, count( $attributes['unitdeliverycode'] ) );
655
656
		$this->expectException( \Aimeos\MShop\Exception::class );
657
		$this->object->get( $newBasketId );
658
	}
659
660
661
	public function testSaveExisting()
662
	{
663
		$item = $this->getOrderItem();
664
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
665
666
		$basket = $this->getBasket( $item->getId(), $ref, true );
0 ignored issues
show
Bug introduced by
It seems like $item->getId() can also be of type null; however, parameter $id of Aimeos\MShop\Order\Manag...andardTest::getBasket() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

666
		$basket = $this->getBasket( /** @scrutinizer ignore-type */ $item->getId(), $ref, true );
Loading history...
667
		$this->object->save( $basket );
668
		$newBasketId = $basket->getId();
669
		$this->object->save( $basket );
670
		$newBasket = $this->getBasket( $newBasketId, $ref );
671
672
		$this->object->delete( $newBasketId );
673
674
		foreach( $basket->getAddresses() as $type => $list )
675
		{
676
			$this->assertTrue( map( $list )->getId()->equals( map( $newBasket->getAddress( $type ) )->getId() ) );
677
		}
678
679
		$this->assertTrue( $basket->getProducts()->getId()->equals( $newBasket->getProducts()->getId() ) );
680
681
		foreach( $basket->getServices() as $type => $list )
682
		{
683
			$this->assertTrue( map( $list )->getId()->equals( map( $newBasket->getService( $type ) )->getId() ) );
684
		}
685
	}
686
687
688
	public function testSaveBundles()
689
	{
690
		$search = $this->object->filter()->add( ['order.sitecode' => 'unittest', 'order.price' => 2400.00] );
691
		$item = $this->object->search( $search )->first( new \RuntimeException( 'No order found' ) );
692
693
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
694
		$basket = $this->getBasket( $item->getId(), $ref, true );
695
		$this->object->save( $basket );
696
697
		$newBasketId = $basket->getId();
698
699
		$basket = $this->getBasket( $newBasketId, $ref );
0 ignored issues
show
Bug introduced by
It seems like $newBasketId can also be of type null; however, parameter $id of Aimeos\MShop\Order\Manag...andardTest::getBasket() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

699
		$basket = $this->getBasket( /** @scrutinizer ignore-type */ $newBasketId, $ref );
Loading history...
700
		$this->object->delete( $newBasketId );
701
702
		$this->assertEquals( $item->getCustomerId(), $basket->getCustomerId() );
703
		$this->assertEquals( $basket->locale()->getSiteId(), $basket->getSiteId() );
704
705
		$pos = 1;
706
		$products = $basket->getProducts();
707
708
		$this->assertEquals( 2, count( $products ) );
709
		foreach( $products as $product )
710
		{
711
			$this->assertEquals( 2, count( $product->getProducts() ) );
712
			$this->assertEquals( $pos, $product->getPosition() );
713
			$pos += 3; // two sub-products in between
714
		}
715
716
		$this->expectException( \Aimeos\MShop\Exception::class );
717
		$this->object->get( $newBasketId );
718
	}
719
720
721
	public function testSaveAddress()
722
	{
723
		$item = $this->getOrderItem();
724
725
		$basket = $this->getBasket( $item->getId(), ['order/address'], true );
0 ignored issues
show
Bug introduced by
It seems like $item->getId() can also be of type null; however, parameter $id of Aimeos\MShop\Order\Manag...andardTest::getBasket() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

725
		$basket = $this->getBasket( /** @scrutinizer ignore-type */ $item->getId(), ['order/address'], true );
Loading history...
726
		$this->object->save( $basket );
727
728
		$newBasketId = $basket->getId();
729
730
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
731
		$basket = $this->getBasket( $newBasketId, $ref );
732
		$this->object->delete( $newBasketId );
733
734
		$this->assertGreaterThan( 0, count( $basket->getAddresses() ) );
735
		$this->assertEquals( [], $basket->getProducts()->toArray() );
736
		$this->assertEquals( [], $basket->getCoupons()->toArray() );
737
		$this->assertEquals( [], $basket->getServices()->toArray() );
738
	}
739
740
741
	public function testSaveProduct()
742
	{
743
		$item = $this->getOrderItem();
744
745
		$basket = $this->getBasket( $item->getId(), ['order/product'], true );
0 ignored issues
show
Bug introduced by
It seems like $item->getId() can also be of type null; however, parameter $id of Aimeos\MShop\Order\Manag...andardTest::getBasket() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

745
		$basket = $this->getBasket( /** @scrutinizer ignore-type */ $item->getId(), ['order/product'], true );
Loading history...
746
		$this->object->save( $basket );
747
748
		$newBasketId = $basket->getId();
749
750
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
751
		$basket = $this->getBasket( $newBasketId, $ref );
752
		$this->object->delete( $newBasketId );
753
754
		$this->assertGreaterThan( 0, count( $basket->getProducts() ) );
755
		$this->assertEquals( [], $basket->getAddresses()->toArray() );
756
		$this->assertEquals( [], $basket->getCoupons()->toArray() );
757
		$this->assertEquals( [], $basket->getServices()->toArray() );
758
	}
759
760
761
	public function testSaveService()
762
	{
763
		$item = $this->getOrderItem();
764
765
		$basket = $this->getBasket( $item->getId(), ['order/service'], true );
0 ignored issues
show
Bug introduced by
It seems like $item->getId() can also be of type null; however, parameter $id of Aimeos\MShop\Order\Manag...andardTest::getBasket() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

765
		$basket = $this->getBasket( /** @scrutinizer ignore-type */ $item->getId(), ['order/service'], true );
Loading history...
766
		$this->object->save( $basket );
767
768
		$newBasketId = $basket->getId();
769
770
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
771
		$basket = $this->getBasket( $newBasketId, $ref );
772
		$this->object->delete( $newBasketId );
773
774
		$this->assertGreaterThan( 0, count( $basket->getServices() ) );
775
		$this->assertEquals( [], $basket->getProducts()->toArray() );
776
		$this->assertEquals( [], $basket->getAddresses()->toArray() );
777
		$this->assertEquals( [], $basket->getCoupons()->toArray() );
778
	}
779
780
781
	public function testLoadSaveCoupons()
782
	{
783
		$ref = ['order/address', 'order/product', 'order/service'];
784
785
		$search = $this->object->filter()->add( ['order.price' => '53.50'] );
786
		$item = $this->object->search( $search )->first( new \RuntimeException( 'No order found' ) );
787
788
		$basket = $this->getBasket( $item->getId(), $ref, true );
789
790
		$this->assertEquals( '53.50', $basket->getPrice()->getValue() );
791
		$this->assertEquals( '1.50', $basket->getPrice()->getCosts() );
792
		$this->assertEquals( 0, count( $basket->getCoupons() ) );
793
794
		$basket->addCoupon( 'CDEF' );
795
		$basket->addCoupon( '90AB' );
796
		$this->assertEquals( 2, count( $basket->getCoupons() ) );
797
798
		$this->object->save( $basket );
799
800
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
801
802
		$newBasket = $this->object->get( $basket->getId(), $ref );
803
		$this->object->delete( $newBasket->getId() );
804
805
		$this->assertEquals( '53.50', $newBasket->getPrice()->getValue() );
806
		$this->assertEquals( '1.50', $newBasket->getPrice()->getCosts() );
807
		$this->assertEquals( '14.50', $newBasket->getPrice()->getRebate() );
808
		$this->assertEquals( 2, count( $newBasket->getCoupons() ) );
809
	}
810
811
812
	/**
813
	 * Returns the basket object
814
	 *
815
	 * @return \Aimeos\MShop\Order\Item\Iface Order base item
816
	 * @throws \Exception If no found
817
	 */
818
	protected function getBasket( string $id, array $ref = [], $fresh = false )
819
	{
820
		$basket = $this->object->get( $id, $ref );
821
822
		if( $fresh )
823
		{
824
			$basket->setId( null );
825
826
			$basket->getAddresses()->flat( 1 )->setParentId( null )->setId( null );
827
			$basket->getServices()->flat( 1 )->setParentId( null )->setId( null );
828
829
			$basket->getProducts()->merge( $basket->getProducts()->getProducts()->flat( 1 ) )
830
				->setParentId( null )->setPosition( null )->setId( null );
831
		}
832
833
		return $basket;
834
	}
835
836
837
	/**
838
	 * Returns an order base item
839
	 *
840
	 * @return \Aimeos\MShop\Order\Item\Iface Order base item
841
	 * @throws \Exception If no found
842
	 */
843
	protected function getOrderItem()
844
	{
845
		$search = $this->object->filter()->add( [
846
			'order.sitecode' => 'unittest',
847
			'order.price' => 53.50,
848
			'order.rebate' => 14.50,
849
			'order.editor' => $this->editor
850
		] );
851
852
		return $this->object->search( $search )->first( new \RuntimeException( 'No order found' ) );
853
	}
854
}
855