1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace OroCRM\Bundle\MagentoBundle\ImportExport\Strategy; |
4
|
|
|
|
5
|
|
|
use Doctrine\Common\Collections\ArrayCollection; |
6
|
|
|
|
7
|
|
|
use Oro\Bundle\AddressBundle\Entity\Region; |
8
|
|
|
|
9
|
|
|
use OroCRM\Bundle\MagentoBundle\Entity\Cart; |
10
|
|
|
use OroCRM\Bundle\MagentoBundle\Entity\CartAddress; |
11
|
|
|
use OroCRM\Bundle\MagentoBundle\Entity\CartStatus; |
12
|
|
|
use OroCRM\Bundle\MagentoBundle\Entity\MagentoSoapTransport; |
13
|
|
|
use OroCRM\Bundle\MagentoBundle\ImportExport\Converter\GuestCustomerDataConverter; |
14
|
|
|
use OroCRM\Bundle\MagentoBundle\Provider\Reader\ContextCustomerReader; |
15
|
|
|
|
16
|
|
|
class CartStrategy extends AbstractImportStrategy |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* @var Cart |
20
|
|
|
*/ |
21
|
|
|
protected $existingEntity; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @var array |
25
|
|
|
*/ |
26
|
|
|
protected $existingCartItems; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @param Cart $entity |
30
|
|
|
* |
31
|
|
|
* {@inheritdoc} |
32
|
|
|
*/ |
33
|
|
|
protected function beforeProcessEntity($entity) |
34
|
|
|
{ |
35
|
|
|
$this->existingEntity = $this->databaseHelper->findOneByIdentity($entity); |
36
|
|
|
if ($this->existingEntity) { |
37
|
|
|
$this->existingCartItems = $this->existingEntity->getCartItems()->toArray(); |
38
|
|
|
} else { |
39
|
|
|
$this->existingEntity = $entity; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
return parent::beforeProcessEntity($entity); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @param Cart $entity |
47
|
|
|
* |
48
|
|
|
* {@inheritdoc} |
49
|
|
|
*/ |
50
|
|
View Code Duplication |
public function process($entity) |
|
|
|
|
51
|
|
|
{ |
52
|
|
|
if (!$this->isProcessingAllowed($entity)) { |
53
|
|
|
$this->appendDataToContext( |
54
|
|
|
CartWithExistingCustomerStrategy::CONTEXT_CART_POST_PROCESS, |
55
|
|
|
$this->context->getValue('itemData') |
56
|
|
|
); |
57
|
|
|
|
58
|
|
|
return null; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
return parent::process($entity); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @param Cart $cart |
66
|
|
|
* @return bool |
67
|
|
|
*/ |
68
|
|
|
protected function isProcessingAllowed(Cart $cart) |
69
|
|
|
{ |
70
|
|
|
$isProcessingAllowed = true; |
71
|
|
|
|
72
|
|
|
if ($cart->getCustomer()) { |
73
|
|
|
$customer = $this->findExistingEntity($cart->getCustomer()); |
74
|
|
|
|
75
|
|
|
$customerOriginId = $cart->getCustomer()->getOriginId(); |
76
|
|
|
if (!$customer && $customerOriginId) { |
77
|
|
|
$this->appendDataToContext(ContextCustomerReader::CONTEXT_POST_PROCESS_CUSTOMERS, $customerOriginId); |
78
|
|
|
|
79
|
|
|
$isProcessingAllowed = false; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
if (!$customer && $cart->getIsGuest()) { |
83
|
|
|
/** @var MagentoSoapTransport $transport */ |
84
|
|
|
$channel = $this->databaseHelper->findOneByIdentity($cart->getChannel()); |
85
|
|
|
$transport = $channel->getTransport(); |
86
|
|
|
if ($transport->getGuestCustomerSync()) { |
87
|
|
|
$this->appendDataToContext( |
88
|
|
|
'postProcessGuestCustomers', |
89
|
|
|
GuestCustomerDataConverter::extractCustomersValues((array)$this->context->getValue('itemData')) |
90
|
|
|
); |
91
|
|
|
|
92
|
|
|
$isProcessingAllowed = false; |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
return $isProcessingAllowed; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @param Cart $entity |
102
|
|
|
* |
103
|
|
|
* {@inheritdoc} |
104
|
|
|
*/ |
105
|
|
|
protected function afterProcessEntity($entity) |
106
|
|
|
{ |
107
|
|
|
if ($this->existingEntity->getStatus()->getName() === CartStatus::STATUS_OPEN) { |
108
|
|
|
$this->updateRemovedCartItems($entity); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
if (!$this->hasContactInfo($entity)) { |
112
|
|
|
return null; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
$this |
116
|
|
|
->updateCustomer($entity) |
117
|
|
|
->updateAddresses($entity) |
118
|
|
|
->updateCartItems($entity) |
119
|
|
|
->updateCartStatus($entity); |
120
|
|
|
|
121
|
|
|
$now = new \DateTime('now', new \DateTimeZone('UTC')); |
122
|
|
|
if (!$entity->getImportedAt()) { |
123
|
|
|
$entity->setImportedAt($now); |
124
|
|
|
} |
125
|
|
|
$entity->setSyncedAt($now); |
126
|
|
|
|
127
|
|
|
$this->existingEntity = null; |
128
|
|
|
$this->existingCartItems = null; |
|
|
|
|
129
|
|
|
|
130
|
|
|
return parent::afterProcessEntity($entity); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Update removed cart items - set `removed` field to true if cart item was removed from a cart |
135
|
|
|
* |
136
|
|
|
* @param Cart $entity |
137
|
|
|
*/ |
138
|
|
|
protected function updateRemovedCartItems(Cart $entity) |
139
|
|
|
{ |
140
|
|
|
if ((int)$entity->getItemsQty() === 0) { |
141
|
|
View Code Duplication |
foreach ($entity->getCartItems() as $cartItem) { |
|
|
|
|
142
|
|
|
if (!$cartItem->isRemoved()) { |
143
|
|
|
$cartItem->setUpdatedAt(new \DateTime('now'), new \DateTimeZone('UTC')); |
144
|
|
|
$cartItem->setRemoved(true); |
145
|
|
|
} |
146
|
|
|
} |
147
|
|
|
} elseif ($this->existingCartItems) { |
|
|
|
|
148
|
|
|
$existingCartItems = new ArrayCollection($this->existingCartItems); |
149
|
|
|
$newCartItems = $entity->getCartItems(); |
150
|
|
|
|
151
|
|
View Code Duplication |
foreach ($existingCartItems as $existingCartItem) { |
|
|
|
|
152
|
|
|
if (!$newCartItems->contains($existingCartItem)) { |
153
|
|
|
if (!$existingCartItem->isRemoved()) { |
154
|
|
|
$existingCartItem->setUpdatedAt(new \DateTime('now'), new \DateTimeZone('UTC')); |
155
|
|
|
$existingCartItem->setRemoved(true); |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Update Customer email |
164
|
|
|
* |
165
|
|
|
* @param Cart $cart |
166
|
|
|
* |
167
|
|
|
* @return CartStrategy |
168
|
|
|
*/ |
169
|
|
|
protected function updateCustomer(Cart $cart) |
170
|
|
|
{ |
171
|
|
|
$customer = $cart->getCustomer(); |
172
|
|
|
if ($customer && !$customer->getEmail()) { |
173
|
|
|
$customer->setEmail($cart->getEmail()); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
return $this; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param Cart $cart |
181
|
|
|
* |
182
|
|
|
* @return CartStrategy |
183
|
|
|
*/ |
184
|
|
|
protected function updateCartItems(Cart $cart) |
185
|
|
|
{ |
186
|
|
|
foreach ($cart->getCartItems() as $cartItem) { |
187
|
|
|
$cartItem->setOwner($cart->getOrganization()); |
188
|
|
|
$cartItem->setCart($cart); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* @param Cart $entity |
196
|
|
|
* |
197
|
|
|
* @return CartStrategy |
198
|
|
|
*/ |
199
|
|
|
protected function updateAddresses(Cart $entity) |
200
|
|
|
{ |
201
|
|
|
$addresses = ['shippingAddress', 'billingAddress']; |
202
|
|
|
|
203
|
|
|
foreach ($addresses as $addressName) { |
204
|
|
|
/** @var CartAddress $address */ |
205
|
|
|
$address = $this->getPropertyAccessor()->getValue($entity, $addressName); |
206
|
|
|
|
207
|
|
|
if (!$address) { |
208
|
|
|
continue; |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
// at this point imported address region have code equal to region_id in magento db field |
212
|
|
|
$mageRegionId = $address->getRegion() ? $address->getRegion()->getCode() : null; |
213
|
|
|
$this->addressHelper->updateAddressCountryRegion($address, $mageRegionId); |
214
|
|
|
if ($address->getCountry()) { |
215
|
|
|
$this->getPropertyAccessor()->setValue($entity, $addressName, $address); |
216
|
|
|
} else { |
217
|
|
|
$this->getPropertyAccessor()->setValue($entity, $addressName, null); |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
return $this; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* @param Cart $entity |
226
|
|
|
* @return null |
227
|
|
|
*/ |
228
|
|
|
protected function hasContactInfo(Cart $entity) |
229
|
|
|
{ |
230
|
|
|
$hasContactInfo = ($entity->getBillingAddress() && $entity->getBillingAddress()->getPhone()) |
231
|
|
|
|| $entity->getEmail(); |
232
|
|
|
|
233
|
|
|
if (!$hasContactInfo) { |
234
|
|
|
$this->context->incrementErrorEntriesCount(); |
235
|
|
|
$this->logger->debug( |
236
|
|
|
sprintf('Cart ID: %d was skipped because lack of contact info', $entity->getOriginId()) |
237
|
|
|
); |
238
|
|
|
|
239
|
|
|
return false; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
return true; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* Update cart status |
247
|
|
|
* |
248
|
|
|
* @param Cart $cart |
249
|
|
|
* |
250
|
|
|
* @return CartStrategy |
251
|
|
|
*/ |
252
|
|
|
protected function updateCartStatus(Cart $cart) |
253
|
|
|
{ |
254
|
|
|
// allow to modify status only for "open" carts |
255
|
|
|
// because magento can only expire cart, so for different statuses this useless |
256
|
|
|
if ($this->existingEntity->getStatus()->getName() !== CartStatus::STATUS_OPEN) { |
257
|
|
|
$status = $this->existingEntity->getStatus(); |
258
|
|
|
} else { |
259
|
|
|
$status = $cart->getStatus(); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
$cart->setStatus($status); |
263
|
|
|
|
264
|
|
|
return $this; |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* {@inheritdoc} |
269
|
|
|
*/ |
270
|
|
|
protected function findExistingEntity($entity, array $searchContext = []) |
271
|
|
|
{ |
272
|
|
|
$existingEntity = null; |
273
|
|
|
|
274
|
|
|
if ($entity instanceof Region) { |
275
|
|
|
/** @var \OroCRM\Bundle\MagentoBundle\Entity\Region $magentoRegion */ |
276
|
|
|
$magentoRegion = $this->databaseHelper->findOneBy( |
277
|
|
|
'OroCRM\Bundle\MagentoBundle\Entity\Region', |
278
|
|
|
[ |
279
|
|
|
'regionId' => $entity->getCode() |
280
|
|
|
] |
281
|
|
|
); |
282
|
|
|
if ($magentoRegion) { |
283
|
|
|
$existingEntity = $this->databaseHelper->findOneBy( |
284
|
|
|
'Oro\Bundle\AddressBundle\Entity\Region', |
285
|
|
|
[ |
286
|
|
|
'combinedCode' => $magentoRegion->getCombinedCode() |
287
|
|
|
] |
288
|
|
|
); |
289
|
|
|
} |
290
|
|
|
} else { |
291
|
|
|
$existingEntity = parent::findExistingEntity($entity, $searchContext); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
return $existingEntity; |
295
|
|
|
} |
296
|
|
|
} |
297
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.