PluginProbe
Packeta / 2.3.2
Packeta v2.3.2
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
← All changes | src/Packetery/Module/Order/PacketSubmitter.php +182 -122 1.5.32.3.2 View file →
@@ -1,10 +1,5 @@
1 1 <?php
2 -/**
3 - * Class PacketSubmitter
4 - *
5 - * @package Packetery\Module\Order
6 - */
7 2
8 3 declare( strict_types=1 );
9 4
10 5 namespace Packetery\Module\Order;
@@ -10,114 +5,97 @@
10 5 namespace Packetery\Module\Order;
11 6
12 7 use Packetery\Core\Api\InvalidRequestException;
13 8 use Packetery\Core\Api\Soap;
9 +use Packetery\Core\Api\Soap\CreatePacketMapper;
10 +use Packetery\Core\CoreHelper;
14 11 use Packetery\Core\Entity;
15 12 use Packetery\Core\Log;
16 -use Packetery\Core\Rounder;
17 13 use Packetery\Core\Validator;
18 -use Packetery\Core\Api\Soap\CreatePacketMapper;
19 -use Packetery\Module\Carrier\Options;
14 +use Packetery\Module;
15 +use Packetery\Module\CustomsDeclaration;
20 16 use Packetery\Module\MessageManager;
21 -use Packetery\Module\ShippingMethod;
22 -use PacketeryNette\Http\Request;
17 +use Packetery\Module\ModuleHelper;
18 +use Packetery\Module\Shipping\ShippingProvider;
19 +use Packetery\Nette\Http\Request;
23 20 use WC_Order;
24 -use Packetery\Module;
25 21
26 -/**
27 - * Class PacketSubmitter
28 - *
29 - * @package Packetery\Module\Order
30 - */
31 22 class PacketSubmitter {
23 + const HOOK_PACKET_STATUS_SYNC = 'packetery_packet_status_sync_hook';
32 24
33 25 /**
34 - * SOAP API Client.
35 - *
36 - * @var Soap\Client SOAP API Client.
26 + * @var Soap\Client
37 27 */
38 28 private $soapApiClient;
39 29
40 30 /**
41 - * Order validator.
42 - *
43 31 * @var Validator\Order
44 32 */
45 33 private $orderValidator;
46 34
47 35 /**
48 - * ILogger.
49 - *
50 36 * @var Log\ILogger
51 37 */
52 38 private $logger;
53 39
54 40 /**
55 - * Order repository.
56 - *
57 41 * @var Repository
58 42 */
59 43 private $orderRepository;
60 44
61 45 /**
62 - * CreatePacketMapper.
63 - *
64 46 * @var CreatePacketMapper
65 47 */
66 48 private $createPacketMapper;
67 49
68 50 /**
69 - * Request.
70 - *
71 51 * @var Request
72 52 */
73 53 private $request;
74 54
75 55 /**
76 - * Message manager.
77 - *
78 56 * @var MessageManager
79 57 */
80 58 private $messageManager;
81 59
82 60 /**
83 - * Log page.
84 - *
85 61 * @var Module\Log\Page
86 62 */
87 63 private $logPage;
88 64
89 65 /**
90 - * Common logic.
91 - *
92 66 * @var PacketActionsCommonLogic
93 67 */
94 68 private $commonLogic;
95 69
96 70 /**
97 - * Options provider.
98 - *
99 - * @var Module\Options\Provider
71 + * @var CustomsDeclaration\Repository
100 72 */
101 - private $optionsProvider;
73 + private $customsDeclarationRepository;
102 74
103 75 /**
104 - * OrderApi constructor.
105 - *
106 - * @param Soap\Client $soapApiClient SOAP API Client.
107 - * @param Validator\Order $orderValidator Order validator.
108 - * @param Log\ILogger $logger Logger.
109 - * @param Repository $orderRepository Order repository.
110 - * @param CreatePacketMapper $createPacketMapper CreatePacketMapper.
111 - * @param Request $request Request.
112 - * @param MessageManager $messageManager Message manager.
113 - * @param Module\Log\Page $logPage Log page.
114 - * @param PacketActionsCommonLogic $commonLogic Common logic.
115 - * @param Module\Options\Provider $optionsProvider Options provider.
76 + * @var PacketSynchronizer
116 77 */
78 + private $packetSynchronizer;
79 +
80 + /**
81 + * @var ModuleHelper
82 + */
83 + private $moduleHelper;
84 +
85 + /**
86 + * @var CoreHelper
87 + */
88 + private $coreHelper;
89 +
90 + /**
91 + * @var ConsignPasswordSynchronizer
92 + */
93 + private $consignPasswordSynchronizer;
94 +
117 95 public function __construct(
118 96 Soap\Client $soapApiClient,
119 - Validator\Order $orderValidator,
97 + OrderValidatorFactory $orderValidatorFactory,
120 98 Log\ILogger $logger,
121 99 Repository $orderRepository,
122 100 CreatePacketMapper $createPacketMapper,
123 101 Request $request,
@@ -123,20 +101,28 @@
123 101 Request $request,
124 102 MessageManager $messageManager,
125 103 Module\Log\Page $logPage,
126 104 PacketActionsCommonLogic $commonLogic,
127 - Module\Options\Provider $optionsProvider
105 + CustomsDeclaration\Repository $customsDeclarationRepository,
106 + PacketSynchronizer $packetSynchronizer,
107 + ModuleHelper $moduleHelper,
108 + CoreHelper $coreHelper,
109 + ConsignPasswordSynchronizer $consignPasswordSynchronizer
128 110 ) {
129 - $this->soapApiClient = $soapApiClient;
130 - $this->orderValidator = $orderValidator;
131 - $this->logger = $logger;
132 - $this->orderRepository = $orderRepository;
133 - $this->createPacketMapper = $createPacketMapper;
134 - $this->request = $request;
135 - $this->messageManager = $messageManager;
136 - $this->logPage = $logPage;
137 - $this->commonLogic = $commonLogic;
138 - $this->optionsProvider = $optionsProvider;
111 + $this->soapApiClient = $soapApiClient;
112 + $this->orderValidator = $orderValidatorFactory->create();
113 + $this->logger = $logger;
114 + $this->orderRepository = $orderRepository;
115 + $this->createPacketMapper = $createPacketMapper;
116 + $this->request = $request;
117 + $this->messageManager = $messageManager;
118 + $this->logPage = $logPage;
119 + $this->commonLogic = $commonLogic;
120 + $this->customsDeclarationRepository = $customsDeclarationRepository;
121 + $this->packetSynchronizer = $packetSynchronizer;
122 + $this->moduleHelper = $moduleHelper;
123 + $this->coreHelper = $coreHelper;
124 + $this->consignPasswordSynchronizer = $consignPasswordSynchronizer;
139 125 }
140 126
141 127 /**
142 128 * Process action
@@ -146,9 +132,9 @@
146 132 public function processAction(): void {
147 133 $order = $this->commonLogic->getOrder();
148 134 $redirectTo = $this->request->getQuery( PacketActionsCommonLogic::PARAM_REDIRECT_TO );
149 135
150 - if ( null === $order ) {
136 + if ( $order === null ) {
151 137 $record = new Log\Record();
152 138 $record->action = Log\Record::ACTION_PACKET_SENDING;
153 139 $record->status = Log\Record::STATUS_ERROR;
154 140 $record->orderId = null;
@@ -169,10 +155,10 @@
169 155 $this->commonLogic->checkAction( PacketActionsCommonLogic::ACTION_SUBMIT_PACKET, $order );
170 156
171 157 $submissionResult = $this->submitPacket(
172 158 $this->orderRepository->getWcOrderById( (int) $order->getNumber() ),
173 - $this->optionsProvider->isOrderStatusAutoChangeEnabled(),
174 - $order
159 + $order,
160 + true
175 161 );
176 162 $resultsCounter = $submissionResult->getCounter();
177 163 $submissionResultMessages = $this->getTranslatedSubmissionMessages( $resultsCounter, (int) $order->getNumber() );
178 164
@@ -208,24 +194,24 @@
208 194
209 195 /**
210 196 * Submits packet data to Packeta API.
211 197 *
212 - * @param WC_Order $wcOrder WC order.
213 - * @param bool $updateOrderStatus Updates WC order status if packet was successfully created. Value is based on plugin settings.
214 - * @param Entity\Order|null $order Order.
198 + * @param WC_Order $wcOrder WC order.
199 + * @param Entity\Order|null $order Order.
200 + * @param bool $immediatePacketStatusCheck Whether to sync status immediately.
215 201 *
216 202 * @return PacketSubmissionResult
217 203 */
218 204 public function submitPacket(
219 205 WC_Order $wcOrder,
220 - bool $updateOrderStatus,
221 - ?Entity\Order $order = null
206 + ?Entity\Order $order = null,
207 + bool $immediatePacketStatusCheck = false
222 208 ): PacketSubmissionResult {
223 209 $submissionResult = new PacketSubmissionResult();
224 - if ( null === $order ) {
225 - $order = $this->orderRepository->getByWcOrder( $wcOrder );
210 + if ( $order === null ) {
211 + $order = $this->orderRepository->getByWcOrderWithValidCarrier( $wcOrder );
226 212 }
227 - if ( null === $order ) {
213 + if ( $order === null ) {
228 214 $submissionResult->increaseIgnoredCount();
229 215
230 216 return $submissionResult;
231 217 }
@@ -235,9 +221,82 @@
235 221 $shippingMethod = reset( $shippingMethods );
236 222
237 223 $shippingMethodData = $shippingMethod->get_data();
238 224 $shippingMethodId = $shippingMethodData['method_id'];
239 - if ( ShippingMethod::PACKETERY_METHOD_ID === $shippingMethodId && ! $order->isExported() ) {
225 + if ( ShippingProvider::isPacketaMethod( $shippingMethodId ) && ! $order->isExported() ) {
226 + $customsDeclaration = $order->getCustomsDeclaration();
227 + if (
228 + $customsDeclaration !== null &&
229 + $customsDeclaration->getInvoiceFileId() === null &&
230 + $customsDeclaration->hasInvoiceFileContent()
231 + ) {
232 + $invoiceFileResponse = $this->soapApiClient->createStorageFile(
233 + new Soap\Request\CreateStorageFile(
234 + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
235 + base64_encode( $customsDeclaration->getInvoiceFile() ),
236 + sprintf( 'invoice_%s.pdf', $customsDeclaration->getId() )
237 + )
238 + );
239 +
240 + if ( $invoiceFileResponse->hasFault() ) {
241 + $record = new Log\Record();
242 + $record->action = Log\Record::ACTION_PACKET_SENDING;
243 + $record->status = Log\Record::STATUS_ERROR;
244 + $record->title = __( 'Packet invoice file could not be created.', 'packeta' );
245 + $record->params = [
246 + 'errorMessage' => $invoiceFileResponse->getFaultString(),
247 + ];
248 + $record->orderId = $order->getNumber();
249 + $this->logger->add( $record );
250 + $submissionResult->increaseLogsCount();
251 +
252 + $submissionResult->increaseErrorsCount();
253 + $order->updateApiErrorMessage( $invoiceFileResponse->getFaultString() );
254 + $this->orderRepository->save( $order );
255 +
256 + return $submissionResult;
257 + }
258 +
259 + $customsDeclaration->setInvoiceFileId( $invoiceFileResponse->getId() );
260 + $this->customsDeclarationRepository->save( $customsDeclaration );
261 + }
262 +
263 + if (
264 + $customsDeclaration !== null &&
265 + $customsDeclaration->getEadFileId() === null &&
266 + $customsDeclaration->hasEadFileContent()
267 + ) {
268 + $eadFileResponse = $this->soapApiClient->createStorageFile(
269 + new Soap\Request\CreateStorageFile(
270 + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
271 + base64_encode( $customsDeclaration->getEadFile() ),
272 + sprintf( 'ead_%s.pdf', $customsDeclaration->getId() )
273 + )
274 + );
275 +
276 + if ( $eadFileResponse->hasFault() ) {
277 + $record = new Log\Record();
278 + $record->action = Log\Record::ACTION_PACKET_SENDING;
279 + $record->status = Log\Record::STATUS_ERROR;
280 + $record->title = __( 'Packet ead file could not be created.', 'packeta' );
281 + $record->params = [
282 + 'errorMessage' => $eadFileResponse->getFaultString(),
283 + ];
284 + $record->orderId = $order->getNumber();
285 + $this->logger->add( $record );
286 + $submissionResult->increaseLogsCount();
287 +
288 + $submissionResult->increaseErrorsCount();
289 + $order->updateApiErrorMessage( $eadFileResponse->getFaultString() );
290 + $this->orderRepository->save( $order );
291 +
292 + return $submissionResult;
293 + }
294 +
295 + $customsDeclaration->setEadFileId( $eadFileResponse->getId() );
296 + $this->customsDeclarationRepository->save( $customsDeclaration );
297 + }
298 +
240 299 try {
241 300 $createPacketData = $this->preparePacketData( $order );
242 301 } catch ( InvalidRequestException $e ) {
243 302 $record = new Log\Record();
@@ -244,10 +303,10 @@
244 303 $record->action = Log\Record::ACTION_PACKET_SENDING;
245 304 $record->status = Log\Record::STATUS_ERROR;
246 305 $record->title = __( 'Packet could not be created.', 'packeta' );
247 306 $record->params = [
248 - 'orderId' => $orderData['id'],
249 - 'errorMessage' => $e->getMessage(),
307 + 'orderId' => $orderData['id'],
308 + 'errorMessages' => $e->getMessages(),
250 309 ];
251 310 $record->orderId = $order->getNumber();
252 311 $this->logger->add( $record );
253 312
@@ -256,8 +315,11 @@
256 315
257 316 return $submissionResult;
258 317 }
259 318
319 + $shouldScheduleConsignPasswordFetch = false;
320 + $consignPasswordFetchImmediate = false;
321 +
260 322 $response = $this->soapApiClient->createPacket( $createPacketData );
261 323 if ( $response->hasFault() ) {
262 324 $record = new Log\Record();
263 325 $record->action = Log\Record::ACTION_PACKET_SENDING;
@@ -273,8 +335,9 @@
273 335 $submissionResult->increaseErrorsCount();
274 336 } else {
275 337 $order->setIsExported( true );
276 338 $order->setPacketId( $response->getId() );
339 + $order->setPacketTrackingUrl( $this->coreHelper->getTrackingUrl( $response->getId() ) );
277 340
278 341 $record = new Log\Record();
279 342 $record->action = Log\Record::ACTION_PACKET_SENDING;
280 343 $record->status = Log\Record::STATUS_SUCCESS;
@@ -286,8 +349,26 @@
286 349 $record->orderId = $order->getNumber();
287 350 $errorMessage = null;
288 351
289 352 $submissionResult->increaseSuccessCount();
353 +
354 + $wcOrder->add_order_note(
355 + sprintf(
356 + // translators: %s represents a packet tracking link.
357 + __( 'Packeta: Packet %s has been created', 'packeta' ),
358 + $this->moduleHelper->createHtmlLink( $order->getPacketTrackingUrl(), $order->getPacketBarcode() )
359 + )
360 + );
361 + $wcOrder->save();
362 +
363 + if ( $immediatePacketStatusCheck || ! function_exists( 'as_enqueue_async_action' ) ) {
364 + $this->packetSynchronizer->syncStatus( $order );
365 + } else {
366 + as_enqueue_async_action( self::HOOK_PACKET_STATUS_SYNC, [ $order->getNumber() ] );
367 + }
368 +
369 + $shouldScheduleConsignPasswordFetch = true;
370 + $consignPasswordFetchImmediate = $immediatePacketStatusCheck;
290 371 }
291 372
292 373 $submissionResult->increaseLogsCount();
293 374 $this->logger->add( $record );
@@ -293,10 +374,10 @@
293 374 $this->logger->add( $record );
294 375 $order->updateApiErrorMessage( $errorMessage );
295 376 $this->orderRepository->save( $order );
296 377
297 - if ( $updateOrderStatus && false === $response->hasFault() ) {
298 - $this->updateOrderStatusOrLogError( $wcOrder, $order->getNumber(), $submissionResult );
378 + if ( $shouldScheduleConsignPasswordFetch ) {
379 + $this->consignPasswordSynchronizer->schedule( $order, $consignPasswordFetchImmediate );
299 380 }
300 381 } else {
301 382 $submissionResult->increaseIgnoredCount();
302 383 }
@@ -307,30 +388,19 @@
307 388 /**
308 389 * Prepares packet attributes.
309 390 *
310 391 * @param Entity\Order $order Order entity.
311 - *
312 - * @return array
392 + * @return array<string, string|null|bool>
313 393 * @throws InvalidRequestException For the case request is not eligible to be sent to API.
314 394 */
315 395 private function preparePacketData( Entity\Order $order ): array {
316 - if ( ! $this->orderValidator->validate( $order ) ) {
317 - throw new InvalidRequestException( 'All required order attributes are not set.' );
396 + $validationErrors = $this->orderValidator->validate( $order );
397 + if ( count( $validationErrors ) > 0 ) {
398 + throw new InvalidRequestException( 'All required order attributes are not set.', $validationErrors );
318 399 }
319 400
320 401 $createPacketData = $this->createPacketMapper->fromOrderToArray( $order );
321 - if ( ! empty( $createPacketData['cod'] ) ) {
322 - if ( $order->getCarrierCode() === null ) {
323 - // This means that more accurate carrier id could not be determined. See Order\Builder.
324 - $roundingType = Rounder::DONT_ROUND;
325 - } else {
326 - $roundingType = Options::createByCarrierId( $order->getCarrierCode() )->getCodRoundingType();
327 - }
328 402
329 - $roundedCod = Rounder::roundByCurrency( $createPacketData['cod'], $createPacketData['currency'], $roundingType );
330 - $createPacketData['cod'] = $roundedCod;
331 - }
332 -
333 403 /**
334 404 * Allows to update CreatePacket request data.
335 405 *
336 406 * @since 1.4
@@ -342,12 +412,12 @@
342 412
343 413 /**
344 414 * Gets translated messages by submission result.
345 415 *
346 - * @param array $submissionResult Submission result.
347 - * @param int|null $orderId Order ID.
416 + * @param array<string, int> $submissionResult Submission result.
417 + * @param int|null $orderId Order ID.
348 418 *
349 - * @return array
419 + * @return array<string, null|string>
350 420 */
351 421 public function getTranslatedSubmissionMessages( array $submissionResult, ?int $orderId ): array {
352 422 $success = null;
353 423 if ( is_numeric( $submissionResult['success'] ) && $submissionResult['success'] > 0 ) {
@@ -392,9 +462,9 @@
392 462 $submissionResult['errors']
393 463 );
394 464 }
395 465 } elseif ( isset( $submissionResult['errors'] ) ) {
396 - $errors = esc_html( $submissionResult['errors'] );
466 + $errors = esc_html( (string) $submissionResult['errors'] );
397 467 }
398 468
399 469 if ( is_numeric( $submissionResult['statusUnchanged'] ) && $submissionResult['statusUnchanged'] > 0 ) {
400 470 $errors = esc_html__( 'Some order statuses have not been automatically changed.', 'packeta' );
@@ -407,33 +477,23 @@
407 477 ];
408 478 }
409 479
410 480 /**
411 - * Updates order status or logs error.
481 + * Registers action for cron.
412 482 *
413 - * @param WC_Order $order WC Order.
414 - * @param string $orderId Order ID.
415 - * @param PacketSubmissionResult $submissionResult Packet submission result.
416 - *
417 483 * @return void
418 484 */
419 - private function updateOrderStatusOrLogError( WC_Order $order, string $orderId, PacketSubmissionResult $submissionResult ):void {
420 - $autoOrderStatus = $this->optionsProvider->getValidAutoOrderStatus();
421 - if ( '' === $autoOrderStatus ) {
422 - $record = new Log\Record();
423 - $record->action = Log\Record::ACTION_PACKET_SENDING;
424 - $record->status = Log\Record::STATUS_ERROR;
425 -
426 - $record->title = sprintf(
427 - // translators: %s represents unknown order status.
428 - __( 'Order status has not been changed, status "%s" doesn\'t exist.', 'packeta' ),
429 - $this->optionsProvider->getAutoOrderStatus()
430 - );
431 - $record->orderId = $orderId;
432 - $this->logger->add( $record );
433 - $submissionResult->increaseStatusUnchangedCount();
434 - } else {
435 - $order->update_status( $autoOrderStatus );
436 - }
485 + public function registerCronAction(): void {
486 + add_action(
487 + self::HOOK_PACKET_STATUS_SYNC,
488 + function ( string $orderId ): void {
489 + $order = $this->orderRepository->getByIdWithValidCarrier( (int) $orderId );
490 + if ( $order === null ) {
491 + return;
492 + }
493 + $this->packetSynchronizer->syncStatus( $order );
494 + },
495 + 10,
496 + 1
497 + );
437 498 }
438 -
439 499 }