Completed
Push — master ( 685540...ab50ec )
by
unknown
10:30
created

OrderStrategy::findExistingEntity()   D

Complexity

Conditions 9
Paths 6

Size

Total Lines 37
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 37
rs 4.9091
cc 9
eloc 20
nc 6
nop 2
1
<?php
2
3
namespace OroCRM\Bundle\MagentoBundle\ImportExport\Strategy;
4
5
use Symfony\Component\PropertyAccess\PropertyAccess;
6
7
use OroCRM\Bundle\MagentoBundle\Entity\CartStatus;
8
use OroCRM\Bundle\MagentoBundle\Entity\Customer;
9
use OroCRM\Bundle\MagentoBundle\Entity\Order;
10
use OroCRM\Bundle\MagentoBundle\Entity\OrderAddress;
11
use OroCRM\Bundle\MagentoBundle\Provider\MagentoConnectorInterface;
12
use OroCRM\Bundle\MagentoBundle\Entity\OrderItem;
13
14
class OrderStrategy extends AbstractImportStrategy
15
{
16
    const CONTEXT_ORDER_POST_PROCESS_IDS = 'postProcessOrderIds';
17
18
    /**
19
     * @var Order
20
     */
21
    protected $existingEntity;
22
23
    /**
24
     * @param Order $entity
25
     *
26
     * {@inheritdoc}
27
     */
28
    protected function beforeProcessEntity($entity)
29
    {
30
        $this->existingEntity = $this->databaseHelper->findOneByIdentity($entity);
31
        if (!$this->existingEntity) {
32
            $this->existingEntity = $entity;
33
        }
34
35
        return parent::beforeProcessEntity($entity);
36
    }
37
38
    /**
39
     * @param Order $entity
40
     *
41
     * {@inheritdoc}
42
     */
43
    protected function afterProcessEntity($entity)
44
    {
45
        if (!$entity->getUpdatedAt() && $entity->getCreatedAt()) {
46
            $entity->setUpdatedAt($entity->getCreatedAt());
47
        }
48
49
        /** @var Order $order */
50
        $this->processCart($entity);
51
        $this->processItems($entity);
52
        $this->processAddresses($entity);
53
        $this->processCustomer($entity, $entity->getCustomer());
0 ignored issues
show
Documentation introduced by
$entity->getCustomer() is of type object<Oro\Bundle\Busine...ndle\Entity\BasePerson>, but the function expects a null|object<OroCRM\Bundl...Bundle\Entity\Customer>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
54
55
        $this->existingEntity = null;
56
57
        $this->appendDataToContext(self::CONTEXT_ORDER_POST_PROCESS_IDS, $entity->getIncrementId());
58
59
        return parent::afterProcessEntity($entity);
60
    }
61
62
    /**
63
     * @param Order $order
64
     * @param Customer $customer
65
     */
66
    protected function processCustomer(Order $order, Customer $customer = null)
67
    {
68
        if (!$customer || !$customer->getId()) {
69
            $customer = $this->databaseHelper->findOneBy(
70
                'OroCRM\Bundle\MagentoBundle\Entity\Customer',
71
                [
72
                    'email' => $order->getCustomerEmail(),
73
                    'channel' => $order->getChannel()
74
                ]
75
            );
76
        }
77
78
        if ($customer instanceof Customer) {
79
            // now customer orders subtotal calculation support only one currency.
80
            // also we do not take into account order refunds due to magento does not bring subtotal data
81
            // customer currency needs on customer's grid to format lifetime value.
82
            $customer->setCurrency($order->getCurrency());
83
        }
84
        $order->setCustomer($customer);
0 ignored issues
show
Documentation introduced by
$customer is of type object|null, but the function expects a object<Oro\Bundle\Busine...ndle\Entity\BasePerson>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
85
86
        if ($order->getCart()) {
87
            $order->getCart()->setCustomer($customer);
0 ignored issues
show
Bug introduced by
It seems like $customer defined by $this->databaseHelper->f... $order->getChannel())) on line 69 can also be of type object; however, OroCRM\Bundle\MagentoBun...ity\Cart::setCustomer() does only seem to accept null|object<OroCRM\Bundl...Bundle\Entity\Customer>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
88
        }
89
    }
90
91
    /**
92
     * If cart exists then add relation to it,
93
     * do nothing otherwise
94
     *
95
     * @param Order $entity
96
     */
97
    protected function processCart(Order $entity)
98
    {
99
        $cart = $entity->getCart();
100
101
        if ($cart) {
102
            $statusClass = MagentoConnectorInterface::CART_STATUS_TYPE;
103
            /** @var CartStatus $purchasedStatus */
104
            $purchasedStatus = $this->databaseHelper
105
                ->findOneBy($statusClass, ['name' => CartStatus::STATUS_PURCHASED]);
106
            if ($purchasedStatus) {
107
                $cart->setStatus($purchasedStatus);
108
            }
109
        }
110
111
        $entity->setCart($cart);
112
    }
113
114
    /**
115
     * @param Order $order
116
     *
117
     * @return OrderStrategy
118
     */
119
    protected function processItems(Order $order)
120
    {
121
        foreach ($order->getItems() as $item) {
122
            $item->setOwner($order->getOrganization());
123
            $item->setOrder($order);
124
        }
125
126
        return $this;
127
    }
128
129
    /**
130
     * @param Order $order
131
     *
132
     * @return OrderStrategy
133
     */
134
    protected function processAddresses(Order $order)
135
    {
136
        /** @var OrderAddress $address */
137
        foreach ($order->getAddresses() as $address) {
138
            $address->setOwner($order);
139
        }
140
141
        return $this;
142
    }
143
144
    /**
145
     * BC layer to find existing collection items by old identity filed values
146
     *
147
     * {@inheritdoc}
148
     */
149
    protected function findExistingEntity($entity, array $searchContext = [])
150
    {
151
        $existingEntity = parent::findExistingEntity($entity, $searchContext);
152
153
        if (!$existingEntity && $entity instanceof OrderAddress) {
154
            $propertyAccessor = PropertyAccess::createPropertyAccessor();
155
156
            /** @var OrderAddress $existingEntity */
157
            $existingEntity = $this->existingEntity->getAddresses()
158
                ->filter(
159
                    function (OrderAddress $address) use ($entity, $propertyAccessor) {
160
                        $isMatched = true;
161
                        $fieldsToMatch = ['street', 'city', 'postalCode', 'country', 'region'];
162
163
                        foreach ($fieldsToMatch as $fieldToMatch) {
164
                            $addressValue = $propertyAccessor->getValue($address, $fieldToMatch);
165
                            $entityValue = $propertyAccessor->getValue($entity, $fieldToMatch);
166
                            $isMatched = $isMatched && ($addressValue === $entityValue);
167
                        }
168
169
                        return $isMatched;
170
                    }
171
                )
172
                ->first();
173
174
            if ($existingEntity && $entity->getOriginId()) {
175
                $existingEntity->setOriginId($entity->getOriginId());
176
            }
177
        }
178
179
        if ($entity instanceof OrderItem && is_null($entity->getName())) {
180
            //name can't be null, so to avoid import job failing empty string is used
181
            $entity->setName('');
182
        }
183
184
        return $existingEntity;
185
    }
186
}
187