Passed
Push — master ( 7b9381...037114 )
by Matthijs
04:14
created

Cart::addRow()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 2
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
//ugly class ever.......
4
5
namespace Hideyo\Ecommerce\Framework\Services\Cart;
6
7
use Hideyo\Ecommerce\Framework\Services\Cart\Helpers\Helpers;
8
use Hideyo\Ecommerce\Framework\Services\Sendingmethod\SendingmethodFacade as SendingmethodService;
9
use Hideyo\Ecommerce\Framework\Services\PaymentMethod\PaymentMethodFacade as PaymentMethodService;
10
use Hideyo\Ecommerce\Framework\Services\Shop\ShopFacade as ShopService;
11
use Hideyo\Ecommerce\Framework\Services\Product\ProductFacade as ProductService;
12
use Hideyo\Ecommerce\Framework\Services\Product\ProductCombinationFacade as ProductCombinationService;
13
use Hideyo\Ecommerce\Framework\Services\Coupon\CouponFacade as CouponService;
14
15
class Cart
16
{
17
    /**
18
     * the item storage
19
     *
20
     * @var
21
     */
22
    protected $session;
23
    /**
24
     * the event dispatcher
25
     *
26
     * @var
27
     */
28
    protected $events;
29
    /**
30
     * the cart session key
31
     *
32
     * @var
33
     */
34
    protected $instanceName;
35
36
    /**    
37
     *
38
     * @var
39
     */
40
    protected $sessionKeyCartItems;
41
42
    /**
43
     * the session key use to persist cart conditions
44
     *
45
     * @var
46
     */
47
    protected $sessionKeyCartConditions;
48
49
    /**
50
     * the session key use to persist voucher
51
     *
52
     * @var
53
     */
54
    protected $sessionKeyCartVoucher;
55
56
    /**
57
     * Configuration to pass to ItemCollection
58
     *
59
     * @var
60
     */
61
    protected $config;
62
63
    /**
64
     * our object constructor
65
     *
66
     * @param $session
67
     * @param $events
68
     * @param $instanceName
69
     */
70
    public function __construct($session, $events, $instanceName, $session_key, $config)
71
    {
72
        $this->events = $events;
73
        $this->session = $session;
74
        $this->instanceName = $instanceName;
75
        $this->sessionKeyCartItems = $session_key . '_cart_items';
76
        $this->sessionKeyCartConditions = $session_key . '_cart_conditions';
77
        $this->sessionKeyCartVoucher = $session_key . '_voucher';
78
        $this->fireEvent('created');
79
        $this->config = $config;
80
    }
81
82
    /**
83
     * get instance name of the cart
84
     *
85
     * @return string
86
     */
87
    public function getInstanceName()
88
    {
89
        return $this->instanceName;
90
    }
91
92
    /**
93
     * get an item on a cart by item ID
94
     *
95
     * @param $itemId
96
     * @return mixed
97
     */
98
    public function get($itemId)
99
    {
100
        return $this->getContent()->get($itemId);
101
    }
102
103
    /**
104
     * check if an item exists by item ID
105
     *
106
     * @param $itemId
107
     * @return bool
108
     */
109
    public function has($itemId)
110
    {
111
        return $this->getContent()->has($itemId);
112
    }
113
114
    /**
115
     * add item to the cart, it can be an array or multi dimensional array
116
     *
117
     * @param string|array $id
118
     * @param string $name
119
     * @param float $price
120
     * @param int $quantity
121
     * @param array $attributes
122
     * @param CartCondition|array $conditions
123
     * @return $this
124
     * @throws InvalidItemException
125
     */
126
    public function add($id, $attributes = array(), $quantity = null, $conditions = array(), $orderId = 0)
127
    {
128
        // validate data
129
        $item = array(
130
            'id' => $id,
131
            'orderId' => $orderId,
132
            'attributes' => $attributes,
133
            'quantity' => $quantity,
134
            'conditions' => $conditions
135
        );
136
137
        $cart = $this->getContent();
138
        // if the item is already in the cart we will just update it
139
        if ($cart->has($id)) {
140
            $this->update($id, $item);
141
        } else {
142
            $this->addRow($id, $item);
143
        }
144
        return $this;
145
    }
146
147
    /**
148
     * update a cart
149
     *
150
     * @param $id
151
     * @param $data
152
     *
153
     * the $data will be an associative array, you don't need to pass all the data, only the key value
154
     * of the item you want to update on it
155
     * @return bool
156
     */
157
    public function update($id, $data)
158
    {
159
        if($this->fireEvent('updating', $data) === false) {
160
            return false;
161
        }
162
        $cart = $this->getContent();
163
        $item = $cart->pull($id);
164
        foreach ($data as $key => $value) {
165
            // if the key is currently "quantity" we will need to check if an arithmetic
166
            // symbol is present so we can decide if the update of quantity is being added
167
            // or being reduced.
168
            if ($key == 'quantity') {
169
                // we will check if quantity value provided is array,
170
                // if it is, we will need to check if a key "relative" is set
171
                // and we will evaluate its value if true or false,
172
                // this tells us how to treat the quantity value if it should be updated
173
                // relatively to its current quantity value or just totally replace the value
174
                if (is_array($value)) {
175
                    if (isset($value['relative'])) {
176
                        if ((bool)$value['relative']) {
177
                            $item = $this->updateQuantityRelative($item, $key, $value['value']);
178
                        } else {
179
                            $item = $this->updateQuantityNotRelative($item, $key, $value['value']);
180
                        }
181
                    }
182
                } else {
183
                    $item = $this->updateQuantityRelative($item, $key, $value);
184
                }
185
            } elseif ($key == 'attributes') {
186
                $item[$key] = new ItemAttributeCollection($value);
187
            } else {
188
                $item[$key] = $value;
189
            }
190
        }
191
        $cart->put($id, $item);
192
        $this->save($cart);
193
        $this->fireEvent('updated', $item);
194
        return true;
195
    }
196
197
    /**
198
     * update a cart item quantity relative to its current quantity
199
     *
200
     * @param $item
201
     * @param $key
202
     * @param $value
203
     * @return mixed
204
     */
205
    protected function updateQuantityRelative($item, $key, $value)
206
    {
207
        if (preg_match('/\-/', $value) == 1) {
208
            $value = (int)str_replace('-', '', $value);
209
            // we will not allowed to reduced quantity to 0, so if the given value
210
            // would result to item quantity of 0, we will not do it.
211
            if (($item[$key] - $value) > 0) {
212
                $item[$key] -= $value;
213
            }
214
        } elseif (preg_match('/\+/', $value) == 1) {
215
            $item[$key] += (int)str_replace('+', '', $value);
216
        } else {
217
            $item[$key] += (int)$value;
218
        }
219
        return $item;
220
    }
221
222
    /**
223
     * update cart item quantity not relative to its current quantity value
224
     *
225
     * @param $item
226
     * @param $key
227
     * @param $value
228
     * @return mixed
229
     */
230
    protected function updateQuantityNotRelative($item, $key, $value)
231
    {
232
        $item[$key] = (int)$value;
233
        return $item;
234
    }
235
236
    /**
237
     * get the cart
238
     *
239
     * @return CartCollection
240
     */
241
    public function getContent()
242
    {
243
        return (new CartCollection($this->session->get($this->sessionKeyCartItems)));
244
    }
245
246
    /**
247
     * add row to cart collection
248
     *
249
     * @param $id
250
     * @param $item
251
     * @return bool
252
     */
253
    protected function addRow($id, $item)
254
    {
255
        if($this->fireEvent('adding', $item) === false) {
256
            return false;
257
        }
258
        $cart = $this->getContent();
259
        $cart->put($id, new ItemCollection($item, $this->config));
260
        $this->save($cart);
261
        $this->fireEvent('added', $item);
262
        return true;
263
    }
264
265
    /**
266
     * add a condition on the cart
267
     *
268
     * @param CartCondition|array $condition
269
     * @return $this
270
     * @throws InvalidConditionException
271
     */
272
    public function condition($condition)
273
    {
274
        if (is_array($condition)) {
275
            foreach ($condition as $c) {
276
                $this->condition($c);
277
            }
278
            return $this;
279
        }
280
        if (!$condition instanceof CartCondition) throw new InvalidConditionException('Argument 1 must be an instance of \'Darryldecode\Cart\CartCondition\'');
0 ignored issues
show
introduced by
$condition is always a sub-type of Hideyo\Ecommerce\Framewo...ices\Cart\CartCondition.
Loading history...
Bug introduced by
The type Hideyo\Ecommerce\Framewo...validConditionException 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...
281
        $conditions = $this->getConditions();
282
        // Check if order has been applied
283
        if ($condition->getOrder() == 0) {
284
            $last = $conditions->last();
285
            $condition->setOrder(!is_null($last) ? $last->getOrder() + 1 : 1);
286
        }
287
        $conditions->put($condition->getName(), $condition);
288
        $conditions = $conditions->sortBy(function ($condition, $key) {
289
            return $condition->getOrder();
290
        });
291
        $this->saveConditions($conditions);
292
        return $this;
293
    }
294
295
    /**
296
     * get conditions applied on the cart
297
     *
298
     * @return CartConditionCollection
299
     */
300
    public function getConditions()
301
    {
302
        return new CartConditionCollection($this->session->get($this->sessionKeyCartConditions));
303
    }
304
305
    /**
306
     * get condition applied on the cart by its name
307
     *
308
     * @param $conditionName
309
     * @return CartCondition
310
     */
311
    public function getCondition($conditionName)
312
    {
313
        return $this->getConditions()->get($conditionName);
314
    }
315
316
    /**
317
     * Get all the condition filtered by Type
318
     * Please Note that this will only return condition added on cart bases, not those conditions added
319
     * specifically on an per item bases
320
     *
321
     * @param $type
322
     * @return CartConditionCollection
323
     */
324
    public function getConditionsByType($type)
325
    {
326
        return $this->getConditions()->filter(function (CartCondition $condition) use ($type) {
327
            return $condition->getType() == $type;
328
        });
329
    }
330
331
    /**
332
     * Remove all the condition with the $type specified
333
     * Please Note that this will only remove condition added on cart bases, not those conditions added
334
     * specifically on an per item bases
335
     *
336
     * @param $type
337
     * @return $this
338
     */
339
    public function removeConditionsByType($type)
340
    {
341
        $this->getConditionsByType($type)->each(function ($condition) {
342
            $this->removeCartCondition($condition->getName());
343
        });
344
    }
345
346
    /**
347
     * removes a condition on a cart by condition name,
348
     * this can only remove conditions that are added on cart bases not conditions that are added on an item/product.
349
     * If you wish to remove a condition that has been added for a specific item/product, you may
350
     * use the removeItemCondition(itemId, conditionName) method instead.
351
     *
352
     * @param $conditionName
353
     * @return void
354
     */
355
    public function removeCartCondition($conditionName)
356
    {
357
        $conditions = $this->getConditions();
358
        $conditions->pull($conditionName);
359
        $this->saveConditions($conditions);
360
    }
361
362
    /**
363
     * remove a condition that has been applied on an item that is already on the cart
364
     *
365
     * @param $itemId
366
     * @param $conditionName
367
     * @return bool
368
     */
369
    public function removeItemCondition($itemId, $conditionName)
370
    {
371
        if (!$item = $this->getContent()->get($itemId)) {
372
            return false;
373
        }
374
        if ($this->itemHasConditions($item)) {
0 ignored issues
show
Bug introduced by
The method itemHasConditions() does not exist on Hideyo\Ecommerce\Framework\Services\Cart\Cart. ( Ignorable by Annotation )

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

374
        if ($this->/** @scrutinizer ignore-call */ itemHasConditions($item)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
375
            // NOTE:
376
            // we do it this way, we get first conditions and store
377
            // it in a temp variable $originalConditions, then we will modify the array there
378
            // and after modification we will store it again on $item['conditions']
379
            // This is because of ArrayAccess implementation
380
            // see link for more info: http://stackoverflow.com/questions/20053269/indirect-modification-of-overloaded-element-of-splfixedarray-has-no-effect
381
            $tempConditionsHolder = $item['conditions'];
382
            // if the item's conditions is in array format
383
            // we will iterate through all of it and check if the name matches
384
            // to the given name the user wants to remove, if so, remove it
385
            if (is_array($tempConditionsHolder)) {
386
                foreach ($tempConditionsHolder as $k => $condition) {
387
                    if ($condition->getName() == $conditionName) {
388
                        unset($tempConditionsHolder[$k]);
389
                    }
390
                }
391
                $item['conditions'] = $tempConditionsHolder;
392
            }
393
            // if the item condition is not an array, we will check if it is
394
            // an instance of a Condition, if so, we will check if the name matches
395
            // on the given condition name the user wants to remove, if so,
396
            // lets just make $item['conditions'] an empty array as there's just 1 condition on it anyway
397
            else {
398
                $conditionInstance = "Darryldecode\\Cart\\CartCondition";
399
                if ($item['conditions'] instanceof $conditionInstance) {
400
                    if ($tempConditionsHolder->getName() == $conditionName) {
401
                        $item['conditions'] = array();
402
                    }
403
                }
404
            }
405
        }
406
        $this->update($itemId, array(
407
            'conditions' => $item['conditions']
408
        ));
409
        return true;
410
    }
411
412
    /**
413
     * remove all conditions that has been applied on an item that is already on the cart
414
     *
415
     * @param $itemId
416
     * @return bool
417
     */
418
    public function clearItemConditions($itemId)
419
    {
420
        if (!$item = $this->getContent()->get($itemId)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $item is dead and can be removed.
Loading history...
421
            return false;
422
        }
423
        $this->update($itemId, array(
424
            'conditions' => array()
425
        ));
426
        return true;
427
    }
428
429
    /**
430
     * clears all conditions on a cart,
431
     * this does not remove conditions that has been added specifically to an item/product.
432
     * If you wish to remove a specific condition to a product, you may use the method: removeItemCondition($itemId, $conditionName)
433
     *
434
     * @return void
435
     */
436
    public function clearCartConditions()
437
    {
438
        $this->session->put(
439
            $this->sessionKeyCartConditions,
440
            array()
441
        );
442
    }
443
444
    /**
445
     * get cart sub total without conditions
446
     * @param bool $formatted
447
     * @return float
448
     */
449
    public function getSubTotalWithoutConditions($formatted = true)
450
    {
451
        $cart = $this->getContent();
452
        $sum = $cart->sum(function ($item) {
453
            return $item->getOriginalPriceWithTaxSum();
454
        });
455
456
        return Helpers::formatValue(floatval($sum), $formatted, $this->config);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Hideyo\Ecommerce\...rmatted, $this->config) also could return the type string which is incompatible with the documented return type double.
Loading history...
457
    }    
458
459
    /**
460
     * get cart sub total with tax
461
     * @param bool $formatted
462
     * @return float
463
     */
464
    public function getSubTotalWithTax($formatted = true)
465
    {
466
        $cart = $this->getContent();
467
        $sum = $cart->sum(function ($item) {
468
            return $item->getOriginalPriceWithTaxSum(false);
469
        });
470
471
472
        return Helpers::formatValue(floatval($sum), $formatted, $this->config);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Hideyo\Ecommerce\...rmatted, $this->config) also could return the type string which is incompatible with the documented return type double.
Loading history...
473
    }
474
475
    /**
476
     * get cart sub total with out tax
477
     * @param bool $formatted
478
     * @return float
479
     */
480
    public function getSubTotalWithoutTax($formatted = true)
481
    {
482
        $cart = $this->getContent();
483
        $sum = $cart->sum(function ($item) {
484
            return $item->getOriginalPriceWithoutTaxSum(false);
485
        });
486
487
        return Helpers::formatValue(floatval($sum), $formatted, $this->config);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Hideyo\Ecommerce\...rmatted, $this->config) also could return the type string which is incompatible with the documented return type double.
Loading history...
488
    }
489
490
    /**
491
     * the new total with tax in which conditions are already applied
492
     *
493
     * @return float
494
     */
495
    public function getTotalWithTax($formatted = true)
496
    {
497
498
        $subTotal = $this->getSubTotalWithTax(false);
499
        $newTotal = 0.00;
500
        $process = 0;
501
        $conditions = $this
502
            ->getConditions()
503
            ->filter(function ($cond) {
504
                return $cond->getTarget() === 'subtotal';
505
            });
506
        // if no conditions were added, just return the sub total
507
        if (!$conditions->count()) {
508
            return Helpers::formatValue(floatval($subTotal), $formatted, $this->config);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Hideyo\Ecommerce\...rmatted, $this->config) also could return the type string which is incompatible with the documented return type double.
Loading history...
509
        }
510
        $conditions
511
            ->each(function ($cond) use ($subTotal, &$newTotal, &$process) {
512
                $toBeCalculated = ($process > 0) ? $newTotal : $subTotal;
513
                $newTotal = $cond->applyCondition($toBeCalculated);
514
                $process++;
515
            });
516
517
518
        return Helpers::formatValue(floatval($newTotal), $formatted, $this->config);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Hideyo\Ecommerce\...rmatted, $this->config) also could return the type string which is incompatible with the documented return type double.
Loading history...
519
    }
520
521
522
    /**
523
     * the new total without tax in which conditions are already applied
524
     *
525
     * @return float
526
     */
527
    public function getTotalWithoutTax($formatted = true)
528
    {
529
        $subTotal = $this->getSubTotalWithoutTax(false);
530
        $newTotal = 0.00;
531
        $process = 0;
532
        $conditions = $this
533
            ->getConditions()
534
            ->filter(function ($cond) {
535
                return $cond->getTarget() === 'subtotal';
536
            });
537
        // if no conditions were added, just return the sub total
538
        if (!$conditions->count()) {
539
            return $subTotal;
540
        }
541
        $conditions
542
            ->each(function ($cond) use ($subTotal, &$newTotal, &$process) {
543
                $toBeCalculated = ($process > 0) ? $newTotal : $subTotal;
544
                $newTotal = $cond->applyConditionWithoutTax($toBeCalculated);
545
                $process++;
546
            });
547
548
        return Helpers::formatValue(floatval($newTotal), $formatted, $this->config);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Hideyo\Ecommerce\...rmatted, $this->config) also could return the type string which is incompatible with the documented return type double.
Loading history...
549
    }
550
551
    /**
552
     * removes an item on cart by item ID
553
     *
554
     * @param $id
555
     * @return bool
556
     */
557
    public function remove($id)
558
    {
559
        $cart = $this->getContent();
560
        if($this->fireEvent('removing', $id) === false) {
561
            return false;
562
        }
563
        $cart->forget($id);
564
        $this->save($cart);
565
        $this->fireEvent('removed', $id);
566
        return true;
567
    }
568
569
    /**
570
     * save the cart
571
     *
572
     * @param $cart CartCollection
573
     */
574
    protected function save($cart)
575
    {
576
        $this->session->put($this->sessionKeyCartItems, $cart);
577
    }
578
579
    /**
580
     * save the cart conditions
581
     *
582
     * @param $conditions
583
     */
584
    protected function saveConditions($conditions)
585
    {
586
        $this->session->put($this->sessionKeyCartConditions, $conditions);
587
    }
588
589
    /**
590
     * save the cart voucher
591
     *
592
     * @param $voucher
593
     */
594
    public function saveVoucher($voucher)
595
    {
596
        $this->session->put($this->sessionKeyCartVoucher, $voucher);
597
    }
598
599
    /**
600
     * get the cart voucher
601
     *
602
     */
603
    public function getVoucher()
604
    {
605
        $voucher = $this->session->get($this->sessionKeyCartVoucher);
606
        if($voucher){
607
608
        $totalWithTax = self::getTotalWithTax();
0 ignored issues
show
Bug Best Practice introduced by
The method Hideyo\Ecommerce\Framewo...Cart::getTotalWithTax() is not static, but was called statically. ( Ignorable by Annotation )

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

608
        /** @scrutinizer ignore-call */ 
609
        $totalWithTax = self::getTotalWithTax();
Loading history...
609
        $totalWithoutTax = self::getTotalWithoutTax();
0 ignored issues
show
Bug Best Practice introduced by
The method Hideyo\Ecommerce\Framewo...t::getTotalWithoutTax() is not static, but was called statically. ( Ignorable by Annotation )

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

609
        /** @scrutinizer ignore-call */ 
610
        $totalWithoutTax = self::getTotalWithoutTax();
Loading history...
610
        $voucher['used_value_with_tax']  = $voucher['value'];
611
        $voucher['used_value_without_tax']  = $voucher['value'];
612
        if($totalWithTax <= $voucher['value']) {
613
            $voucher['used_value_with_tax']  = $voucher['value'] - ($voucher['value'] - $totalWithTax);
614
        }
615
616
        if($totalWithTax <= $voucher['value']) {
617
            $voucher['used_value_without_tax']  = $voucher['value'] - ($voucher['value'] - $totalWithoutTax);
618
        }
619
620
        $this->session->put($this->sessionKeyCartVoucher, $voucher);
621
622
        }
623
624
        return $this->session->get($this->sessionKeyCartVoucher);
625
    }
626
627
    public function getToPayWithTax($formatted = true) 
628
    {
629
        $voucher = self::getVoucher();
0 ignored issues
show
Bug Best Practice introduced by
The method Hideyo\Ecommerce\Framewo...Cart\Cart::getVoucher() is not static, but was called statically. ( Ignorable by Annotation )

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

629
        /** @scrutinizer ignore-call */ 
630
        $voucher = self::getVoucher();
Loading history...
630
        $toPay = self::getTotalWithTax(false) - $voucher['used_value_with_tax'];
0 ignored issues
show
Bug Best Practice introduced by
The method Hideyo\Ecommerce\Framewo...Cart::getTotalWithTax() is not static, but was called statically. ( Ignorable by Annotation )

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

630
        $toPay = self::/** @scrutinizer ignore-call */ getTotalWithTax(false) - $voucher['used_value_with_tax'];
Loading history...
631
632
        return Helpers::formatValue(floatval($toPay), $formatted, $this->config);      
633
    }
634
635
    public function getToPayWithoutTax($formatted = true) 
636
    {
637
        $voucher = self::getVoucher();
0 ignored issues
show
Bug Best Practice introduced by
The method Hideyo\Ecommerce\Framewo...Cart\Cart::getVoucher() is not static, but was called statically. ( Ignorable by Annotation )

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

637
        /** @scrutinizer ignore-call */ 
638
        $voucher = self::getVoucher();
Loading history...
638
        $toPay = self::getTotalWithoutTax(false) - $voucher['used_value_without_tax'];
0 ignored issues
show
Bug Best Practice introduced by
The method Hideyo\Ecommerce\Framewo...t::getTotalWithoutTax() is not static, but was called statically. ( Ignorable by Annotation )

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

638
        $toPay = self::/** @scrutinizer ignore-call */ getTotalWithoutTax(false) - $voucher['used_value_without_tax'];
Loading history...
639
640
        return Helpers::formatValue(floatval($toPay), $formatted, $this->config); 
641
    }
642
643
    /**
644
     * clear the cart voucher
645
     *
646
     */
647
    public function clearVoucher()
648
    {
649
        $this->session->put($this->sessionKeyCartVoucher, array());
650
    }
651
652
    /**
653
     * clear cart
654
     * @return bool
655
     */
656
    public function clear()
657
    {
658
        if($this->fireEvent('clearing') === false) {
659
            return false;
660
        }
661
        $this->session->put(
662
            $this->sessionKeyCartItems,
663
            array()
664
        );
665
        $this->fireEvent('cleared');
666
        return true;
667
    }
668
669
    /**
670
     * @param $name
671
     * @param $value
672
     * @return mixed
673
     */
674
    protected function fireEvent($name, $value = [])
675
    {
676
        return $this->events->fire($this->getInstanceName() . '.' . $name, array_values([$value, $this]));
677
    }  
678
679
    public function updateAmountProduct($productId, $amount, $leadingAttributeId, $productAttributeId)
680
    {
681
        $explode = explode('-', $productId);
682
        $product = ProductService::selectOneById($explode[0]);
683
684
        $productCombination = false;
685
        if (isset($explode[1])) {
686
            $productAttributeId = $explode[1];
687
            $productCombination = ProductCombinationService::getModel()->where('id', '=', $productAttributeId)->first();
688
        }
689
690
        if ($product->id) {
691
                $productArray = $product->toArray();
692
                $productArray['product_amount_series'] = false;
693
                $productArray['product_category_slug'] = $product->productCategory->slug;
694
                $productArray['price_details'] = $product->getPriceDetails();
695
            if ($productCombination) {
696
                $productArray['id'] = $productArray['id'].'-'.$productCombination->id;
697
                $productArray['product_id'] = $product->id;
698
                $productArray['price_details'] = $productCombination->getPriceDetails();
699
700
                $productArray['product_combination_title'] = array();
701
                $productArray['attributeIds'] = $productCombination->combinations->pluck('attribute_id')->toArray();
702
                foreach ($productCombination->combinations as $combination) {
703
                    $productArray['product_combination_title'][$combination->attribute->attributeGroup->title] = $combination->attribute->value;
704
                }
705
    
706
                $productArray['product_combination_id'] = $productCombination->id;
707
                if ($productCombination->price) {
708
                    $productArray['price_details'] = $productCombination->getPriceDetails();
709
                }
710
711
                if ($productCombination->reference_code) {
712
                    $productArray['reference_code'] = $productCombination->reference_code;
713
                }
714
715
                $productArray['product_images'] =     ProductService::ajaxProductImages($product, array($leadingAttributeId), $productAttributeId);
716
            }
717
718
            if ($product->amountSeries()->where('active', '=', '1')->count()) {
719
                $productArray['product_amount_series'] = true;
720
                $productArray['product_amount_series_range'] = $product->amountSeries()->where('active', '=', '1')->first()->range();
721
            }
722
723
            if($productArray['price_details']['amount'] > 0) {
724
725
                if($amount >= $productArray['price_details']['amount']) {
726
                    $amount = $productArray['price_details']['amount'];
727
                }
728
729
                $this->update($productId, array(
730
                  'quantity' => array(
731
                      'relative' => false,
732
                      'value' => $amount
733
                  ),
734
                ));
735
            } else {
736
                $this->remove($productId);
737
            }
738
739
            if($this->getConditionsByType('sending_method_country_price')->count()) {
740
                $this->updateSendingMethodCountryPrice($this->getConditionsByType('sending_method_country_price')->first()->getAttributes()['data']['sending_method_country_price_id']);  
741
            }
742
        }
743
    }
744
   
745
    public function postProduct($productId, $productCombinationId = false, $leadingAttributeId, $productAttributeId, $amount)
746
    {
747
        $product = ProductService::selectOneByShopIdAndId(config()->get('app.shop_id'), $productId);
748
        $productCombination = false;
749
750
        if ($productCombinationId) {
751
            $productCombination = ProductCombinationService::getModel()->where('id', '=', $productCombinationId)->first();
752
        } elseif ($product->attributes()->count()) {
753
            return false;
754
        }
755
 
756
        if ($product->id) {
757
            $productArray = $product->toArray();
758
            $productArray['product_amount_series'] = false;
759
            $productArray['product_category_slug'] = $product->productCategory->slug;
760
            $productArray['tax_rate'] = $product->taxRate->rate;
761
762
            $productArray['price_details'] = $product->getPriceDetails();
763
            if ($productCombination) {
764
                $productArray['product_combination_title'] = array();
765
                $productArray['attributeIds'] = $productCombination->combinations->pluck('attribute_id')->toArray();
766
                foreach ($productCombination->combinations as $combination) {
767
                    $productArray['product_combination_title'][$combination->attribute->attributeGroup->title] = $combination->attribute->value;
768
                }
769
    
770
                $productArray['product_combination_id'] = $productCombination->id;
771
                if ($productCombination->price) {
772
                    $productArray['price_details'] = $productCombination->getPriceDetails();
773
                }
774
775
                if ($productCombination->reference_code) {
776
                    $productArray['reference_code'] = $productCombination->reference_code;
777
                }
778
779
                $productArray['product_images'] =     ProductService::ajaxProductImages($product, array($leadingAttributeId, $productAttributeId));
780
            }
781
782
            $productId = $productArray['id'];
783
   
784
            if (isset($productArray['product_combination_id'])) {
785
                $productId = $productArray['id'].'-'.$productArray['product_combination_id'];
786
            }
787
788
            $discountValue = false;
789
790
            if(session()->get('preSaleDiscount')) {
791
                $preSaleDiscount = session()->get('preSaleDiscount');             
792
793
794
795
                if ($preSaleDiscount['value'] AND $preSaleDiscount['collection_id'] == $product->collection_id) {
796
797
                    if ($preSaleDiscount['discount_way'] == 'amount') {
798
                        $discountValue = "-".$preSaleDiscount->value;
799
                      } elseif ($preSaleDiscount['discount_way'] == 'percent') {          
800
                        $discountValue = "-".$preSaleDiscount['value']."%";                    
801
                    }                     
802
                }
803
804
                if($preSaleDiscount['products']) {
805
806
                    $productIds = array_column($preSaleDiscount['products'], 'id');
807
808
                    if (in_array($product->id, $productIds) OR (isset($product->product_id) AND in_array($product->product_id, $productIds))) {
809
810
                        if ($preSaleDiscount['discount_way'] == 'amount') {
811
                            $discountValue = "-".$preSaleDiscount->value;
812
                        } elseif ($preSaleDiscount['discount_way'] == 'percent') {
813
                            $discountValue = "-".$preSaleDiscount['value']."%";                     
814
                        }
815
                    }
816
817
                }             
818
819
            }
820
821
            if ($product->discount_value) {
822
                if ($product->discount_type == 'amount') {
823
                    $discountValue = "-".$product->discount_value;
824
                } elseif ($product->discount_type == 'percent') {
825
                    $discountValue = "-".$product->discount_value."%"; 
826
                }
827
            }
828
829
            $discountCondition = array();
830
            if($discountValue) {
831
832
                $discountCondition = new \Hideyo\Ecommerce\Framework\Services\Cart\CartCondition(array(
833
                    'name' => 'Discount',
834
                    'type' => 'tax',
835
                    'target' => 'item',
836
                    'value' => $discountValue,
837
                ));
838
            }
839
840
            return $this->add($productId, $productArray,  $amount, $discountCondition);
841
        }
842
843
        return false;
844
    }
845
846
    public function updateSendingMethod($sendingMethodId)
847
    {
848
        $sendingMethod = SendingmethodService::selectOneByShopIdAndId(config()->get('app.shop_id'), $sendingMethodId);
849
        $sendingMethodArray = array();
850
        if (isset($sendingMethod->id)) {
851
            $sendingMethodArray = $sendingMethod->toArray();          
852
            $sendingMethodArray['price_details'] = $sendingMethod->getPriceDetails();
853
            if($sendingMethod->relatedPaymentMethodsActive) {
854
                $sendingMethodArray['related_payment_methods_list'] = $sendingMethod->relatedPaymentMethodsActive->pluck('title', 'id');                
855
            }
856
857
        }
858
859
        $this->removeConditionsByType('sending_method');
860
        $condition = new \Hideyo\Ecommerce\Framework\Services\Cart\CartCondition(array(
861
            'name' => 'Sending method',
862
            'type' => 'sending_method',
863
            'target' => 'subtotal',
864
            'value' => 0,
865
            'attributes' => array(
866
                'data' => $sendingMethodArray
867
            )
868
        ));
869
870
        $this->condition($condition);
871
872
        if (!$this->getConditionsByType('payment_method')->count() and $sendingMethod->relatedPaymentMethodsActive) {
873
            $this->updatePaymentMethod($sendingMethod->relatedPaymentMethodsActive->first()->id);
874
        }
875
876
        return true;
877
    }
878
879
    public function updatePaymentMethod($paymentMethodId)
880
    {
881
        $paymentMethod = PaymentMethodService::selectOneByShopIdAndId(config()->get('app.shop_id'), $paymentMethodId);
882
883
        $paymentMethodArray = array();
884
        if (isset($paymentMethod->id)) {
885
            $paymentMethodArray = $paymentMethod->toArray();
886
            $paymentMethodArray['price_details'] = $paymentMethod->getPriceDetails();
887
        }
888
889
        $valueExTax = $paymentMethodArray['price_details']['original_price_ex_tax'];
890
        $valueIncTax = $paymentMethodArray['price_details']['original_price_inc_tax'];
891
        $shop = ShopService::find(config()->get('app.shop_id'));
0 ignored issues
show
Unused Code introduced by
The assignment to $shop is dead and can be removed.
Loading history...
892
        $value = $valueIncTax;
893
        $freeSending = ( $paymentMethodArray['no_price_from'] - $this->getSubTotalWithTax());
894
895
896
        if ($freeSending < 0) {
897
            $value = 0;
898
            $valueIncTax = 0;
899
            $valueExTax = 0;
900
        }
901
902
        $paymentMethodArray['value_inc_tax'] = $valueIncTax;
903
        $paymentMethodArray['value_ex_tax'] = $valueExTax;
904
905
        $this->removeConditionsByType('payment_method');
906
        $condition = new \Hideyo\Ecommerce\Framework\Services\Cart\CartCondition(array(
907
            'name' => 'Payment method',
908
            'type' => 'payment_method',
909
            'target' => 'subtotal',
910
            'value' => $value,
911
            'attributes' => array(
912
                'data' => $paymentMethodArray
913
            )
914
        ));
915
916
        return $this->condition($condition);
917
    }
918
919
    public function updateSendingMethodCountryPrice($sendingMethodCountryPriceId)
920
    {
921
        $sendingMethodCountryPrice = SendingmethodService::selectOneCountryPriceByShopIdAndId(config()->get('app.shop_id'), $sendingMethodCountryPriceId);
0 ignored issues
show
Bug introduced by
The method selectOneCountryPriceByShopIdAndId() does not exist on Hideyo\Ecommerce\Framewo...hod\SendingMethodFacade. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

921
        /** @scrutinizer ignore-call */ 
922
        $sendingMethodCountryPrice = SendingmethodService::selectOneCountryPriceByShopIdAndId(config()->get('app.shop_id'), $sendingMethodCountryPriceId);
Loading history...
922
     
923
        if ($sendingMethodCountryPrice) {
924
            $sendingMethod = $sendingMethodCountryPrice->sendingMethod;
925
            $sendingMethodArray = array();
926
            if (isset($sendingMethod->id)) {
927
                $sendingMethodArray = $sendingMethodCountryPrice->toArray();
928
                if ($sendingMethod->countryPrices()->count()) {
929
                    $sendingMethodArray['countries'] = $sendingMethod->countryPrices->toArray();
930
                    $sendingMethodArray['country_list'] = $sendingMethod->countryPrices->pluck('name', 'id');
931
                }
932
                $sendingMethodArray['sending_method_country_price'] = $sendingMethodCountryPrice;
933
                $sendingMethodArray['sending_method_country_price_id'] = $sendingMethodCountryPrice->id;
934
                $sendingMethodArray['sending_method_country_price_country_code'] = $sendingMethodCountryPrice->country_code;
935
                $sendingMethodArray['no_price_from'] = $sendingMethodCountryPrice->no_price_from;
936
                
937
                $sendingMethodArray['price_details'] = $sendingMethodCountryPrice->getPriceDetails();
938
                $sendingMethodArray['sending_method_country_price'] = $sendingMethodCountryPrice->toArray();
939
            }
940
941
            $shop = ShopService::find(config()->get('app.shop_id'));
0 ignored issues
show
Unused Code introduced by
The assignment to $shop is dead and can be removed.
Loading history...
942
943
            $valueExTax = $sendingMethodArray['price_details']['original_price_ex_tax'];
944
            $valueIncTax = $sendingMethodArray['price_details']['original_price_inc_tax'];
945
            $value = $valueIncTax;
946
            $freeSending = ( $sendingMethodArray['no_price_from'] - $this->getSubTotalWithTax());
947
      
948
            if ($freeSending < 0) {
949
                $value = 0;
950
                $valueIncTax = 0;
951
                $valueExTax = 0;
952
            }
953
954
            $sendingMethodArray['value_inc_tax'] = $valueIncTax;
955
            $sendingMethodArray['value_ex_tax'] = $valueExTax;
956
957
            $this->removeConditionsByType('sending_method_country_price');
958
            $condition1 = new \Hideyo\Ecommerce\Framework\Services\Cart\CartCondition(array(
959
                'name' => 'Sending method country price',
960
                'type' => 'sending_method_country_price',
961
                'target' => 'subtotal',
962
                'value' => 0,
963
                'attributes' => array(
964
                    'data' => $sendingMethodArray
965
                )
966
            ));
967
968
            $this->removeConditionsByType('sending_cost');
969
            $condition2 = new \Hideyo\Ecommerce\Framework\Services\Cart\CartCondition(array(
970
                'name' => 'Sending Cost',
971
                'type' => 'sending_cost',
972
                'target' => 'subtotal',
973
                'value' => $value,
974
                'attributes' => array(
975
                    'data' => $sendingMethodArray
976
                )
977
            ));
978
979
            $this->condition([$condition1, $condition2]);
980
981
            if (!$this->getConditionsByType('payment_method')->count() and $sendingMethod->relatedPaymentMethodsActive->first()->id) {
982
                $this->updatePaymentMethod($sendingMethod->relatedPaymentMethodsActive->first()->id);
983
            }
984
985
            return true;
986
        }     
987
    }
988
989
    public function updateOrderStatus($orderStatusId) 
990
    {
991
        session()->put('orderStatusId', $orderStatusId);
992
    }
993
994
    public function addClient($clientId) 
995
    {
996
        session()->put('orderClientId', $clientId);
997
        session()->forget('orderClientBillAddressId');
998
        session()->forget('orderClientDeliveryAddressId');
999
    }
1000
1001
    public function addClientBillAddress($clientBillAddressId) 
1002
    {
1003
        session()->put('orderClientBillAddressId', $clientBillAddressId);
1004
    }
1005
1006
    public function addClientDeliveryAddress($clientDeliveryAddressId) 
1007
    {
1008
        session()->put('orderClientDeliveryAddressId', $clientDeliveryAddressId);
1009
    }
1010
1011
    public function updateCouponCode($couponCode) 
1012
    {
1013
        $this->removeConditionsByType('coupon');
1014
        $coupon = CouponService::selectOneByShopIdAndCode(config()->get('app.shop_id'), $couponCode);
0 ignored issues
show
Bug introduced by
The method selectOneByShopIdAndCode() does not exist on Hideyo\Ecommerce\Framewo...ces\Coupon\CouponFacade. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

1014
        /** @scrutinizer ignore-call */ 
1015
        $coupon = CouponService::selectOneByShopIdAndCode(config()->get('app.shop_id'), $couponCode);
Loading history...
1015
        
1016
        $couponData = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $couponData is dead and can be removed.
Loading history...
1017
        $discountValue = 0;
1018
1019
        if($coupon) {
1020
1021
            $couponData = $coupon->toArray();
1022
            if($coupon->type == 'total_price') {
1023
1024
                if($coupon->discount_way == 'total') {
1025
                    $discountValue = $coupon->value;
1026
                } elseif ($coupon->discount_way == 'percent') {
1027
                    $discountValue = $coupon->value.'%';
1028
                } 
1029
1030
                $this->setCouponCode($discountValue, $couponData, $couponCode);
1031
            }
1032
1033
            if($coupon->type == 'product') {
1034
1035
                if($coupon->products()->count()) {
1036
                    
1037
                    foreach ($this->getContent() as $row) {
1038
1039
                        $id = $row->id;
1040
                        $explode = explode('-', $id);
1041
                        $contains = $coupon->products->contains($explode[0]);
1042
1043
                        if($contains) {
1044
1045
                            if($coupon->discount_way == 'total') {
1046
                                $discountValue += $coupon->value;
1047
                            } elseif ($coupon->discount_way == 'percent') {
1048
                                $value = $coupon->value / 100;                      
1049
                                $discountValue += $row->getOriginalPriceWithTaxSum() * $value;
1050
                            }                             
1051
                        }
1052
                    }
1053
1054
                    $this->setCouponCode($discountValue, $couponData, $couponCode);
1055
                }
1056
            }
1057
1058
            if($coupon->type == 'product_category') {
1059
1060
                if($coupon->productCategories()->count()) {
1061
1062
                    foreach ($this->getContent()->sortBy('id')  as $row) {
1063
1064
                        $contains = $coupon->productCategories->contains($row['attributes']['product_category_id']);
1065
1066
                        if($contains) {
1067
1068
                            if($coupon->discount_way == 'total') {
1069
                                $discountValue += $coupon->value;
1070
                            } elseif ($coupon->discount_way == 'percent') {
1071
                                $value = $coupon->value / 100;                      
1072
                                $discountValue += $row->getOriginalPriceWithTaxSum() * $value;
1073
                            }                             
1074
                        }
1075
1076
                    }
1077
1078
                    $this->setCouponCode($discountValue, $couponData, $couponCode);
1079
                }
1080
            }
1081
1082
            if($coupon->type == 'sending_method') {
1083
1084
                if($coupon->sendingMethodCountries()->count()) {
1085
1086
                    foreach ($coupon->sendingMethodCountries as $country) {
1087
1088
                        if($this->getConditionsByType('sending_method_country_price')){
1089
                            if($country->name == $this->getConditionsByType('sending_method_country_price')->first()->getAttributes()['data']['sending_method_country_price']['name']) {
1090
1091
                                if($coupon->discount_way == 'total') {
1092
                                    $discountValue += $coupon->value;
1093
                                } elseif ($coupon->discount_way == 'percent') {
1094
                                    $value = $coupon->value / 100; 
1095
                                    $discountValue += $this->getConditionsByType('sending_cost')->first()->getValue() * $value;
1096
                                } 
1097
                            }
1098
                        }
1099
                    }
1100
1101
                    $this->setCouponCode($discountValue, $couponData, $couponCode);
1102
1103
                } elseif($coupon->sendingMethods()->count()) {
1104
1105
                    foreach ($coupon->sendingMethods as $sendingMethod) {
1106
1107
                        if($this->getConditionsByType('sending_cost')){
1108
1109
                            if($sendingMethod->id == $this->getConditionsByType('sending_cost')->first()->getAttributes()['data']['sending_method']['id']) {
1110
1111
                                if($coupon->discount_way == 'total') {
1112
                                    $discountValue += $coupon->value;
1113
                                } elseif ($coupon->discount_way == 'percent') {
1114
                                    $value = $coupon->value / 100; 
1115
                                    $discountValue += $this->getConditionsByType('sending_cost')->first()->getValue() * $value;
1116
                                }                 
1117
                            }
1118
                        }            
1119
                    }
1120
1121
                    $this->setCouponCode($discountValue, $couponData, $couponCode);
1122
                }
1123
            }
1124
1125
            if($coupon->type == 'payment_method') {
1126
1127
                if($coupon->paymentMethods()->count()) {
1128
1129
                    foreach ($coupon->paymentMethods as $paymentMethod) {
1130
1131
                        if($this->getConditionsByType('payment_method')){
1132
1133
                            if($paymentMethod->id == $this->getConditionsByType('payment_method')->first()->getAttributes()['data']['id']) {
1134
1135
                                if($coupon->discount_way == 'total') {
1136
                                    $discountValue += $coupon->value;
1137
                                } elseif ($coupon->discount_way == 'percent') {
1138
                                    $value = $coupon->value / 100; 
1139
                                    $discountValue += $this->getConditionsByType('payment_method')->first()->getValue() * $value;
1140
                                }                 
1141
                            }
1142
                        }            
1143
                    }
1144
1145
                    $this->setCouponCode($discountValue, $couponData, $couponCode);
1146
                }
1147
            }
1148
        }
1149
    }
1150
1151
    public function setCouponCode($discountValue, $couponData, $couponCode)
1152
    {
1153
        $condition = new \Hideyo\Ecommerce\Framework\Services\Cart\CartCondition(array(
1154
            'name' => 'Coupon code',
1155
            'type' => 'coupon',
1156
            'target' => 'subtotal',
1157
            'value' => '-'.$discountValue,
1158
            'attributes' => array(
1159
                'couponData' => $couponData,
1160
                'inputCouponValue' => $couponCode
1161
            )
1162
        ));
1163
1164
        $this->condition($condition);
1165
    }
1166
1167
    public function replaceTags($content, $order)
1168
    {
1169
        $replace = array(
1170
            'orderId' => $order->id,
1171
            'orderCreated' => $order->created_at,
1172
            'orderTotalPriceWithTax' => $order->price_with_tax,
1173
            'orderTotalPriceWithoutTax' => $order->price_without_tax,
1174
            'clientEmail' => $order->client->email,
1175
            'clientFirstname' => $order->orderBillAddress->firstname,
1176
            'clientLastname' => $order->orderBillAddress->lastname,
1177
            'clientDeliveryStreet' => $order->orderDeliveryAddress->street,
1178
            'clientDeliveryHousenumber' => $order->orderDeliveryAddress->housenumber,
1179
            'clientDeliveryHousenumberSuffix' => $order->orderDeliveryAddress->housenumber_suffix,
1180
            'clientDeliveryZipcode' => $order->orderDeliveryAddress->zipcode,
1181
            'clientDeliveryCity' => $order->orderDeliveryAddress->city,
1182
            'clientDeliveryCounty' => $order->orderDeliveryAddress->country,
1183
        );
1184
1185
        foreach ($replace as $key => $val) {
1186
            $content = str_replace("[" . $key . "]", $val, $content);
1187
        }
1188
        $content = nl2br($content);
1189
        return $content;
1190
    } 
1191
}