AvailabilityChecker   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 24
c 1
b 0
f 0
dl 0
loc 83
rs 10
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getCart() 0 8 2
A __construct() 0 10 1
A isStockAvailable() 0 8 2
A isStockSufficient() 0 16 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Setono\SyliusReserveStockPlugin\Checker;
6
7
use Setono\SyliusReserveStockPlugin\Repository\InCartQuantityForProductVariantOrderItemRepositoryAwareInterface;
8
use Sylius\Component\Core\Model\ProductVariantInterface;
9
use Sylius\Component\Inventory\Checker\AvailabilityCheckerInterface;
10
use Sylius\Component\Inventory\Model\StockableInterface;
11
use Sylius\Component\Order\Context\CartContextInterface;
12
use Sylius\Component\Order\Context\CartNotFoundException;
13
use Sylius\Component\Order\Model\OrderInterface;
14
15
final class AvailabilityChecker implements AvailabilityCheckerInterface
16
{
17
    /**
18
     * @var AvailabilityCheckerInterface
19
     */
20
    private $availabilityChecker;
21
22
    /**
23
     * @var InCartQuantityForProductVariantOrderItemRepositoryAwareInterface
24
     */
25
    private $repository;
26
27
    /**
28
     * @var int
29
     */
30
    private $cartTtl;
31
32
    /**
33
     * @var CartContextInterface
34
     */
35
    private $cartContext;
36
37
    public function __construct(
38
        AvailabilityCheckerInterface $availabilityChecker,
39
        InCartQuantityForProductVariantOrderItemRepositoryAwareInterface $repository,
40
        int $cartTtl,
41
        CartContextInterface $cartContext
42
    ) {
43
        $this->availabilityChecker = $availabilityChecker;
44
        $this->repository = $repository;
45
        $this->cartTtl = $cartTtl;
46
        $this->cartContext = $cartContext;
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function isStockAvailable(StockableInterface $stockable): bool
53
    {
54
        /** @var ProductVariantInterface $stockable */
55
        if (!$stockable instanceof ProductVariantInterface) {
0 ignored issues
show
introduced by
$stockable is always a sub-type of Sylius\Component\Core\Mo...ProductVariantInterface.
Loading history...
56
            return $this->availabilityChecker->isStockAvailable($stockable);
57
        }
58
59
        return $this->isStockSufficient($stockable, 1);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function isStockSufficient(StockableInterface $stockable, int $quantity): bool
66
    {
67
        /** @var ProductVariantInterface $stockable */
68
        if (!$stockable instanceof ProductVariantInterface) {
0 ignored issues
show
introduced by
$stockable is always a sub-type of Sylius\Component\Core\Mo...ProductVariantInterface.
Loading history...
69
            return $this->availabilityChecker->isStockSufficient($stockable, $quantity);
70
        }
71
72
        if (!$stockable->isTracked()) {
73
            return true;
74
        }
75
76
        $stockAvailable = $stockable->getOnHand() -
77
            $stockable->getOnHold() -
78
            $this->repository->inCartQuantityForProductVariantExcludingOrder($stockable, $this->cartTtl, $this->getCart());
79
80
        return $quantity <= $stockAvailable;
81
    }
82
83
    /**
84
     * Tries to fetch the current cart and return it in that case. If not, null will be returned.
85
     *
86
     * A try/catch block is used because the underlying cart context throws an exception in case there is
87
     * no cart found and a cart will not be generated. In all situations where no cart can be found, we should
88
     * be sure `null` is returned.
89
     */
90
    private function getCart(): ?OrderInterface
91
    {
92
        try {
93
            return $this->cartContext->getCart();
94
        } catch (CartNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
95
        }
96
97
        return null;
98
    }
99
}
100