Passed
Push — master ( af9504...7332c2 )
by Aimeos
14:14
created

StandardTest::testSearchRef()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 0
dl 0
loc 15
rs 9.9
c 0
b 0
f 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-2024
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' ) );
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 testDelete()
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 testCreate()
174
	{
175
		$this->assertInstanceOf( \Aimeos\MShop\Order\Item\Iface::class, $this->object->create() );
176
	}
177
178
179
	public function testGet()
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 testSaveUpdateDelete()
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 testFilter()
376
	{
377
		$this->assertInstanceOf( \Aimeos\Base\Criteria\Iface::class, $this->object->filter() );
378
	}
379
380
381
	public function testFilterDefault()
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 testFilterSite()
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 testSearch()
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.telefax', '055544332212' );
461
		$expr[] = $search->compare( '==', 'order.address.mobile', '055544332213' );
462
		$expr[] = $search->compare( '==', 'order.address.email', '[email protected]' );
463
		$expr[] = $search->compare( '==', 'order.address.website', 'www.example.net' );
464
		$expr[] = $search->compare( '>=', 'order.address.mtime', '1970-01-01 00:00:00' );
465
		$expr[] = $search->compare( '>=', 'order.address.ctime', '1970-01-01 00:00:00' );
466
		$expr[] = $search->compare( '==', 'order.address.editor', $this->editor );
467
468
		$expr[] = $search->compare( '!=', 'order.coupon.id', null );
469
		$expr[] = $search->compare( '==', 'order.coupon.siteid', $siteid );
470
		$expr[] = $search->compare( '!=', 'order.coupon.parentid', null );
471
		$expr[] = $search->compare( '!=', 'order.coupon.productid', null );
472
		$expr[] = $search->compare( '==', 'order.coupon.code', 'OPQR' );
473
		$expr[] = $search->compare( '>=', 'order.coupon.mtime', '1970-01-01 00:00:00' );
474
		$expr[] = $search->compare( '>=', 'order.coupon.ctime', '1970-01-01 00:00:00' );
475
		$expr[] = $search->compare( '>=', 'order.coupon.editor', '' );
476
477
		$expr[] = $search->compare( '!=', 'order.product.id', null );
478
		$expr[] = $search->compare( '==', 'order.product.siteid', $siteid );
479
		$expr[] = $search->compare( '!=', 'order.product.parentid', null );
480
		$expr[] = $search->compare( '!=', 'order.product.productid', null );
481
		$expr[] = $search->compare( '==', 'order.product.prodcode', 'CNE' );
482
		$expr[] = $search->compare( '==', 'order.product.vendor', 'Test vendor' );
483
		$expr[] = $search->compare( '==', 'order.product.name', 'Cafe Noire Expresso' );
484
		$expr[] = $search->compare( '==', 'order.product.mediaurl', 'somewhere/thump1.jpg' );
485
		$expr[] = $search->compare( '==', 'order.product.quantity', 9 );
486
		$expr[] = $search->compare( '==', 'order.product.price', '4.50' );
487
		$expr[] = $search->compare( '==', 'order.product.costs', '0.00' );
488
		$expr[] = $search->compare( '==', 'order.product.rebate', '0.00' );
489
		$expr[] = $search->compare( '=~', 'order.product.taxrates', '{' );
490
		$expr[] = $search->compare( '==', 'order.product.flags', 0 );
491
		$expr[] = $search->compare( '==', 'order.product.position', 1 );
492
		$expr[] = $search->compare( '==', 'order.product.statuspayment', 5 );
493
		$expr[] = $search->compare( '==', 'order.product.statusdelivery', 1 );
494
		$expr[] = $search->compare( '>=', 'order.product.mtime', '1970-01-01 00:00:00' );
495
		$expr[] = $search->compare( '>=', 'order.product.ctime', '1970-01-01 00:00:00' );
496
		$expr[] = $search->compare( '==', 'order.product.editor', $this->editor );
497
498
		$expr[] = $search->compare( '!=', 'order.product.attribute.id', null );
499
		$expr[] = $search->compare( '==', 'order.product.attribute.siteid', $siteid );
500
		$expr[] = $search->compare( '!=', 'order.product.attribute.parentid', null );
501
		$expr[] = $search->compare( '==', 'order.product.attribute.code', 'width' );
502
		$expr[] = $search->compare( '==', 'order.product.attribute.value', '33' );
503
		$expr[] = $search->compare( '==', 'order.product.attribute.name', '33' );
504
		$expr[] = $search->compare( '==', 'order.product.attribute.quantity', 1 );
505
		$expr[] = $search->compare( '>=', 'order.product.attribute.mtime', '1970-01-01 00:00:00' );
506
		$expr[] = $search->compare( '>=', 'order.product.attribute.ctime', '1970-01-01 00:00:00' );
507
		$expr[] = $search->compare( '==', 'order.product.attribute.editor', $this->editor );
508
509
		$expr[] = $search->compare( '!=', 'order.service.id', null );
510
		$expr[] = $search->compare( '==', 'order.service.siteid', $siteid );
511
		$expr[] = $search->compare( '!=', 'order.service.parentid', null );
512
		$expr[] = $search->compare( '==', 'order.service.type', 'payment' );
513
		$expr[] = $search->compare( '==', 'order.service.code', 'unitpaymentcode' );
514
		$expr[] = $search->compare( '==', 'order.service.name', 'unitpaymentcode' );
515
		$expr[] = $search->compare( '==', 'order.service.price', '0.00' );
516
		$expr[] = $search->compare( '==', 'order.service.costs', '0.00' );
517
		$expr[] = $search->compare( '==', 'order.service.rebate', '0.00' );
518
		$expr[] = $search->compare( '=~', 'order.service.taxrates', '{' );
519
		$expr[] = $search->compare( '>=', 'order.service.mtime', '1970-01-01 00:00:00' );
520
		$expr[] = $search->compare( '>=', 'order.service.ctime', '1970-01-01 00:00:00' );
521
		$expr[] = $search->compare( '==', 'order.service.editor', $this->editor );
522
523
		$expr[] = $search->compare( '!=', 'order.service.attribute.id', null );
524
		$expr[] = $search->compare( '==', 'order.service.attribute.siteid', $siteid );
525
		$expr[] = $search->compare( '!=', 'order.service.attribute.parentid', null );
526
		$expr[] = $search->compare( '==', 'order.service.attribute.code', 'NAME' );
527
		$expr[] = $search->compare( '==', 'order.service.attribute.value', '"CreditCard"' );
528
		$expr[] = $search->compare( '==', 'order.service.attribute.quantity', 1 );
529
		$expr[] = $search->compare( '>=', 'order.service.attribute.mtime', '1970-01-01 00:00:00' );
530
		$expr[] = $search->compare( '>=', 'order.service.attribute.ctime', '1970-01-01 00:00:00' );
531
		$expr[] = $search->compare( '==', 'order.service.attribute.editor', $this->editor );
532
533
534
535
		$search->setConditions( $search->and( $expr ) );
536
		$result = $this->object->search( $search, [], $total )->toArray();
537
538
		$this->assertEquals( 1, count( $result ) );
539
		$this->assertEquals( 1, $total );
540
	}
541
542
543
	public function testSearchTotal()
544
	{
545
		$total = 0;
546
		$search = $this->object->filter()->slice( 0, 1 );
547
		$conditions = array(
548
			$search->compare( '==', 'order.statuspayment', \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED ),
549
			$search->compare( '==', 'order.editor', $this->editor )
550
		);
551
		$search->setConditions( $search->and( $conditions ) );
552
		$items = $this->object->search( $search, [], $total )->toArray();
553
554
		$this->assertEquals( 1, count( $items ) );
555
		$this->assertEquals( 3, $total );
556
557
		foreach( $items as $itemId => $item ) {
558
			$this->assertEquals( $itemId, $item->getId() );
559
		}
560
	}
561
562
563
	public function testSearchRef()
564
	{
565
		$total = 0;
566
		$search = $this->object->filter()->slice( 0, 1 );
567
		$conditions = array(
568
			$search->compare( '==', 'order.datepayment', '2008-02-15 12:34:56' ),
569
			$search->compare( '==', 'order.editor', $this->editor )
570
		);
571
		$search->setConditions( $search->and( $conditions ) );
572
		$item = $this->object->search( $search, ['order/address', 'order/coupon', 'order/product', 'order/service'], $total )->first();
573
574
		$this->assertEquals( 2, count( $item->getAddresses() ) );
575
		$this->assertEquals( 2, count( $item->getCoupons() ) );
576
		$this->assertEquals( 4, count( $item->getProducts() ) );
577
		$this->assertEquals( 2, count( $item->getServices() ) );
578
	}
579
580
581
	public function testGetSubManager()
582
	{
583
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'address' ) );
584
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'address', 'Standard' ) );
585
586
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'coupon' ) );
587
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'coupon', 'Standard' ) );
588
589
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'product' ) );
590
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'product', 'Standard' ) );
591
592
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'service' ) );
593
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'service', 'Standard' ) );
594
595
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'status' ) );
596
		$this->assertInstanceOf( \Aimeos\MShop\Common\Manager\Iface::class, $this->object->getSubManager( 'status', 'Standard' ) );
597
598
		$this->expectException( \LogicException::class );
599
		$this->object->getSubManager( 'unknown' );
600
	}
601
602
603
	public function testGetSubManagerInvalidName()
604
	{
605
		$this->expectException( \LogicException::class );
606
		$this->object->getSubManager( 'status', 'unknown' );
607
	}
608
609
610
	public function testSave()
611
	{
612
		$item = $this->getOrderItem();
613
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
614
615
		$basket = $this->getBasket( $item->getId(), $ref, true );
616
		$this->object->save( $basket );
617
618
		$newBasketId = $basket->getId();
619
620
		$basket = $this->getBasket( $newBasketId, $ref );
621
		$this->object->delete( $newBasketId );
622
623
624
		$this->assertEquals( $item->getCustomerId(), $basket->getCustomerId() );
625
		$this->assertEquals( $basket->locale()->getSiteId(), $basket->getSiteId() );
626
627
		$this->assertEquals( 1.50, $basket->getPrice()->getCosts() );
628
629
		$pos = 1;
630
		$products = $basket->getProducts();
631
		$this->assertEquals( 4, count( $products ) );
632
633
		foreach( $products as $product )
634
		{
635
			if( $product->getProductCode() != 'U:MD' ) {
636
				$this->assertGreaterThanOrEqual( 2, count( $product->getAttributeItems() ) );
637
			}
638
			$this->assertEquals( $pos++, $product->getPosition() );
639
		}
640
641
		$this->assertEquals( 2, count( $basket->getAddresses() ) );
642
643
		$services = $basket->getServices();
644
		$this->assertEquals( 2, count( $services ) );
645
646
		$attributes = [];
647
		foreach( $services as $list )
648
		{
649
			foreach( $list as $service ) {
650
				$attributes[$service->getCode()] = $service->getAttributeItems();
651
			}
652
		}
653
654
		$this->assertEquals( 9, count( $attributes['unitpaymentcode'] ) );
655
		$this->assertEquals( 0, count( $attributes['unitdeliverycode'] ) );
656
657
		$this->expectException( \Aimeos\MShop\Exception::class );
658
		$this->object->get( $newBasketId );
659
	}
660
661
662
	public function testSaveExisting()
663
	{
664
		$item = $this->getOrderItem();
665
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
666
667
		$basket = $this->getBasket( $item->getId(), $ref, true );
668
		$this->object->save( $basket );
669
		$newBasketId = $basket->getId();
670
		$this->object->save( $basket );
671
		$newBasket = $this->getBasket( $newBasketId, $ref );
672
673
		$this->object->delete( $newBasketId );
674
675
		foreach( $basket->getAddresses() as $type => $list )
676
		{
677
			$this->assertTrue( map( $list )->getId()->equals( map( $newBasket->getAddress( $type ) )->getId() ) );
678
		}
679
680
		$this->assertTrue( $basket->getProducts()->getId()->equals( $newBasket->getProducts()->getId() ) );
681
682
		foreach( $basket->getServices() as $type => $list )
683
		{
684
			$this->assertTrue( map( $list )->getId()->equals( map( $newBasket->getService( $type ) )->getId() ) );
685
		}
686
	}
687
688
689
	public function testSaveBundles()
690
	{
691
		$search = $this->object->filter()->add( ['order.sitecode' => 'unittest', 'order.price' => 2400.00] );
692
		$item = $this->object->search( $search )->first( new \RuntimeException( 'No order found' ) );
693
694
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
695
		$basket = $this->getBasket( $item->getId(), $ref, true );
696
		$this->object->save( $basket );
697
698
		$newBasketId = $basket->getId();
699
700
		$basket = $this->getBasket( $newBasketId, $ref );
701
		$this->object->delete( $newBasketId );
702
703
		$this->assertEquals( $item->getCustomerId(), $basket->getCustomerId() );
704
		$this->assertEquals( $basket->locale()->getSiteId(), $basket->getSiteId() );
705
706
		$pos = 1;
707
		$products = $basket->getProducts();
708
709
		$this->assertEquals( 2, count( $products ) );
710
		foreach( $products as $product )
711
		{
712
			$this->assertEquals( 2, count( $product->getProducts() ) );
713
			$this->assertEquals( $pos, $product->getPosition() );
714
			$pos += 3; // two sub-products in between
715
		}
716
717
		$this->expectException( \Aimeos\MShop\Exception::class );
718
		$this->object->get( $newBasketId );
719
	}
720
721
722
	public function testSaveAddress()
723
	{
724
		$item = $this->getOrderItem();
725
726
		$basket = $this->getBasket( $item->getId(), ['order/address'], true );
727
		$this->object->save( $basket );
728
729
		$newBasketId = $basket->getId();
730
731
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
732
		$basket = $this->getBasket( $newBasketId, $ref );
733
		$this->object->delete( $newBasketId );
734
735
		$this->assertGreaterThan( 0, count( $basket->getAddresses() ) );
736
		$this->assertEquals( [], $basket->getProducts()->toArray() );
737
		$this->assertEquals( [], $basket->getCoupons()->toArray() );
738
		$this->assertEquals( [], $basket->getServices()->toArray() );
739
	}
740
741
742
	public function testSaveProduct()
743
	{
744
		$item = $this->getOrderItem();
745
746
		$basket = $this->getBasket( $item->getId(), ['order/product'], true );
747
		$this->object->save( $basket );
748
749
		$newBasketId = $basket->getId();
750
751
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
752
		$basket = $this->getBasket( $newBasketId, $ref );
753
		$this->object->delete( $newBasketId );
754
755
		$this->assertGreaterThan( 0, count( $basket->getProducts() ) );
756
		$this->assertEquals( [], $basket->getAddresses()->toArray() );
757
		$this->assertEquals( [], $basket->getCoupons()->toArray() );
758
		$this->assertEquals( [], $basket->getServices()->toArray() );
759
	}
760
761
762
	public function testSaveService()
763
	{
764
		$item = $this->getOrderItem();
765
766
		$basket = $this->getBasket( $item->getId(), ['order/service'], true );
767
		$this->object->save( $basket );
768
769
		$newBasketId = $basket->getId();
770
771
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
772
		$basket = $this->getBasket( $newBasketId, $ref );
773
		$this->object->delete( $newBasketId );
774
775
		$this->assertGreaterThan( 0, count( $basket->getServices() ) );
776
		$this->assertEquals( [], $basket->getProducts()->toArray() );
777
		$this->assertEquals( [], $basket->getAddresses()->toArray() );
778
		$this->assertEquals( [], $basket->getCoupons()->toArray() );
779
	}
780
781
782
	public function testLoadSaveCoupons()
783
	{
784
		$ref = ['order/address', 'order/product', 'order/service'];
785
786
		$search = $this->object->filter()->add( ['order.price' => '53.50'] );
787
		$item = $this->object->search( $search )->first( new \RuntimeException( 'No order found' ) );
788
789
		$basket = $this->getBasket( $item->getId(), $ref, true );
790
791
		$this->assertEquals( '53.50', $basket->getPrice()->getValue() );
792
		$this->assertEquals( '1.50', $basket->getPrice()->getCosts() );
793
		$this->assertEquals( 0, count( $basket->getCoupons() ) );
794
795
		$basket->addCoupon( 'CDEF' );
796
		$basket->addCoupon( '90AB' );
797
		$this->assertEquals( 2, count( $basket->getCoupons() ) );
798
799
		$this->object->save( $basket );
800
801
		$ref = ['order/address', 'order/coupon', 'order/product', 'order/service'];
802
803
		$newBasket = $this->object->get( $basket->getId(), $ref );
804
		$this->object->delete( $newBasket->getId() );
805
806
		$this->assertEquals( '53.50', $newBasket->getPrice()->getValue() );
807
		$this->assertEquals( '1.50', $newBasket->getPrice()->getCosts() );
808
		$this->assertEquals( '14.50', $newBasket->getPrice()->getRebate() );
809
		$this->assertEquals( 2, count( $newBasket->getCoupons() ) );
810
	}
811
812
813
	/**
814
	 * Returns the basket object
815
	 *
816
	 * @param string|null $id Unique order ID
817
	 * @param array $ref List of items that should be fetched too
818
	 * @param bool $fresh TRUE to return items without IDs
819
	 * @return \Aimeos\MShop\Order\Item\Iface Order base item
820
	 * @throws \Exception If no found
821
	 */
822
	protected function getBasket( ?string $id, array $ref = [], bool $fresh = false )
823
	{
824
		if( $id === null ) {
825
			throw new \Exception( 'ID can not be NULL' );
826
		}
827
828
		$basket = $this->object->get( $id, $ref );
829
830
		if( $fresh )
831
		{
832
			$basket->setId( null );
833
834
			$basket->getAddresses()->flat( 1 )->setParentId( null )->setId( null );
835
			$basket->getServices()->flat( 1 )->setParentId( null )->setId( null );
836
837
			$basket->getProducts()->merge( $basket->getProducts()->getProducts()->flat( 1 ) )
838
				->setParentId( null )->setPosition( null )->setId( null );
839
		}
840
841
		return $basket;
842
	}
843
844
845
	/**
846
	 * Returns an order base item
847
	 *
848
	 * @return \Aimeos\MShop\Order\Item\Iface Order base item
849
	 * @throws \Exception If no found
850
	 */
851
	protected function getOrderItem()
852
	{
853
		$search = $this->object->filter()->add( [
854
			'order.sitecode' => 'unittest',
855
			'order.price' => 53.50,
856
			'order.rebate' => 14.50,
857
			'order.editor' => $this->editor
858
		] );
859
860
		return $this->object->search( $search )->first( new \RuntimeException( 'No order found' ) );
861
	}
862
}
863