PluginProbe
Packeta / 1.6.3
Packeta v1.6.3
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
packeta / src / Packetery / Module / Order / PacketSubmitter.php

PacketSubmitter.php in Packeta 1.6.3, at src/Packetery/Module/Order/PacketSubmitter.php

524 lines 16.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class PacketSubmitter
4 *
5 * @package Packetery\Module\Order
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module\Order;
11
12 use Packetery\Core\Api\InvalidRequestException;
13 use Packetery\Core\Api\Soap;
14 use Packetery\Core\Entity;
15 use Packetery\Core\Log;
16 use Packetery\Core\Rounder;
17 use Packetery\Core\Validator;
18 use Packetery\Core\Api\Soap\CreatePacketMapper;
19 use Packetery\Module\Carrier\Options;
20 use Packetery\Module\CustomsDeclaration;
21 use Packetery\Module\Exception\InvalidCarrierException;
22 use Packetery\Module\MessageManager;
23 use Packetery\Module\ShippingMethod;
24 use Packetery\Nette\Http\Request;
25 use WC_Order;
26 use Packetery\Module;
27
28 /**
29 * Class PacketSubmitter
30 *
31 * @package Packetery\Module\Order
32 */
33 class PacketSubmitter {
34
35 /**
36 * SOAP API Client.
37 *
38 * @var Soap\Client SOAP API Client.
39 */
40 private $soapApiClient;
41
42 /**
43 * Order validator.
44 *
45 * @var Validator\Order
46 */
47 private $orderValidator;
48
49 /**
50 * ILogger.
51 *
52 * @var Log\ILogger
53 */
54 private $logger;
55
56 /**
57 * Order repository.
58 *
59 * @var Repository
60 */
61 private $orderRepository;
62
63 /**
64 * CreatePacketMapper.
65 *
66 * @var CreatePacketMapper
67 */
68 private $createPacketMapper;
69
70 /**
71 * Request.
72 *
73 * @var Request
74 */
75 private $request;
76
77 /**
78 * Message manager.
79 *
80 * @var MessageManager
81 */
82 private $messageManager;
83
84 /**
85 * Log page.
86 *
87 * @var Module\Log\Page
88 */
89 private $logPage;
90
91 /**
92 * Common logic.
93 *
94 * @var PacketActionsCommonLogic
95 */
96 private $commonLogic;
97
98 /**
99 * Options provider.
100 *
101 * @var Module\Options\Provider
102 */
103 private $optionsProvider;
104
105 /**
106 * Customs declaration repository.
107 *
108 * @var CustomsDeclaration\Repository
109 */
110 private $customsDeclarationRepository;
111
112 /**
113 * OrderApi constructor.
114 *
115 * @param Soap\Client $soapApiClient SOAP API Client.
116 * @param Validator\Order $orderValidator Order validator.
117 * @param Log\ILogger $logger Logger.
118 * @param Repository $orderRepository Order repository.
119 * @param CreatePacketMapper $createPacketMapper CreatePacketMapper.
120 * @param Request $request Request.
121 * @param MessageManager $messageManager Message manager.
122 * @param Module\Log\Page $logPage Log page.
123 * @param PacketActionsCommonLogic $commonLogic Common logic.
124 * @param Module\Options\Provider $optionsProvider Options provider.
125 * @param CustomsDeclaration\Repository $customsDeclarationRepository Customs declaration repository.
126 */
127 public function __construct(
128 Soap\Client $soapApiClient,
129 Validator\Order $orderValidator,
130 Log\ILogger $logger,
131 Repository $orderRepository,
132 CreatePacketMapper $createPacketMapper,
133 Request $request,
134 MessageManager $messageManager,
135 Module\Log\Page $logPage,
136 PacketActionsCommonLogic $commonLogic,
137 Module\Options\Provider $optionsProvider,
138 CustomsDeclaration\Repository $customsDeclarationRepository
139 ) {
140 $this->soapApiClient = $soapApiClient;
141 $this->orderValidator = $orderValidator;
142 $this->logger = $logger;
143 $this->orderRepository = $orderRepository;
144 $this->createPacketMapper = $createPacketMapper;
145 $this->request = $request;
146 $this->messageManager = $messageManager;
147 $this->logPage = $logPage;
148 $this->commonLogic = $commonLogic;
149 $this->optionsProvider = $optionsProvider;
150 $this->customsDeclarationRepository = $customsDeclarationRepository;
151 }
152
153 /**
154 * Process action
155 *
156 * @return void
157 */
158 public function processAction(): void {
159 $order = $this->commonLogic->getOrder();
160 $redirectTo = $this->request->getQuery( PacketActionsCommonLogic::PARAM_REDIRECT_TO );
161
162 if ( null === $order ) {
163 $record = new Log\Record();
164 $record->action = Log\Record::ACTION_PACKET_SENDING;
165 $record->status = Log\Record::STATUS_ERROR;
166 $record->orderId = null;
167 $record->title = __( 'Packet submission error', 'packeta' );
168 $record->params = [
169 'referer' => (string) $this->request->getReferer(),
170 'errorMessage' => 'Order not found',
171 ];
172
173 $this->logger->add( $record );
174
175 $this->messageManager->flash_message( __( 'Order not found', 'packeta' ), MessageManager::TYPE_ERROR );
176 $this->commonLogic->redirectTo( $redirectTo, $order );
177
178 return;
179 }
180
181 $this->commonLogic->checkAction( PacketActionsCommonLogic::ACTION_SUBMIT_PACKET, $order );
182
183 $submissionResult = $this->submitPacket(
184 $this->orderRepository->getWcOrderById( (int) $order->getNumber() ),
185 $this->optionsProvider->isOrderStatusAutoChangeEnabled(),
186 $order
187 );
188 $resultsCounter = $submissionResult->getCounter();
189 $submissionResultMessages = $this->getTranslatedSubmissionMessages( $resultsCounter, (int) $order->getNumber() );
190
191 if ( $resultsCounter['success'] > 0 ) {
192 $this->messageManager->flashMessageObject(
193 Module\Message::create()
194 ->setText( $submissionResultMessages['success'] )
195 ->setEscape( false )
196 );
197 }
198
199 if ( $resultsCounter['ignored'] > 0 ) {
200 $this->messageManager->flashMessageObject(
201 Module\Message::create()
202 ->setText( $submissionResultMessages['ignored'] )
203 ->setEscape( false )
204 ->setType( MessageManager::TYPE_INFO )
205 );
206 }
207
208 if ( $resultsCounter['errors'] > 0 ) {
209 $this->messageManager->flashMessageObject(
210 Module\Message::create()
211 ->setText( $submissionResultMessages['errors'] )
212 ->setEscape( false )
213 ->setType( MessageManager::TYPE_ERROR )
214 );
215 }
216
217 $redirectTo = $this->request->getQuery( PacketActionsCommonLogic::PARAM_REDIRECT_TO );
218 $this->commonLogic->redirectTo( $redirectTo, $order );
219 }
220
221 /**
222 * Submits packet data to Packeta API.
223 *
224 * @param WC_Order $wcOrder WC order.
225 * @param bool $updateOrderStatus Updates WC order status if packet was successfully created. Value is based on plugin settings.
226 * @param Entity\Order|null $order Order.
227 *
228 * @return PacketSubmissionResult
229 */
230 public function submitPacket(
231 WC_Order $wcOrder,
232 bool $updateOrderStatus,
233 ?Entity\Order $order = null
234 ): PacketSubmissionResult {
235 $submissionResult = new PacketSubmissionResult();
236 if ( null === $order ) {
237 try {
238 $order = $this->orderRepository->getByWcOrder( $wcOrder );
239 } catch ( InvalidCarrierException $exception ) {
240 $order = null;
241 }
242 }
243 if ( null === $order ) {
244 $submissionResult->increaseIgnoredCount();
245
246 return $submissionResult;
247 }
248
249 $orderData = $wcOrder->get_data();
250 $shippingMethods = $wcOrder->get_shipping_methods();
251 $shippingMethod = reset( $shippingMethods );
252
253 $shippingMethodData = $shippingMethod->get_data();
254 $shippingMethodId = $shippingMethodData['method_id'];
255 if ( ShippingMethod::PACKETERY_METHOD_ID === $shippingMethodId && ! $order->isExported() ) {
256
257 $customsDeclaration = $order->getCustomsDeclaration();
258 if (
259 null !== $customsDeclaration &&
260 null === $customsDeclaration->getInvoiceFileId() &&
261 $customsDeclaration->hasInvoiceFileContent()
262 ) {
263 $invoiceFileResponse = $this->soapApiClient->createStorageFile(
264 new Soap\Request\CreateStorageFile(
265 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
266 base64_encode( $customsDeclaration->getInvoiceFile() ),
267 sprintf( 'invoice_%s.pdf', $customsDeclaration->getId() )
268 )
269 );
270
271 if ( $invoiceFileResponse->hasFault() ) {
272 $record = new Log\Record();
273 $record->action = Log\Record::ACTION_PACKET_SENDING;
274 $record->status = Log\Record::STATUS_ERROR;
275 $record->title = __( 'Packet invoice file could not be created.', 'packeta' );
276 $record->params = [
277 'errorMessage' => $invoiceFileResponse->getFaultString(),
278 ];
279 $record->orderId = $order->getNumber();
280 $this->logger->add( $record );
281 $submissionResult->increaseLogsCount();
282
283 $submissionResult->increaseErrorsCount();
284 $order->updateApiErrorMessage( $invoiceFileResponse->getFaultString() );
285 $this->orderRepository->save( $order );
286
287 return $submissionResult;
288 }
289
290 $customsDeclaration->setInvoiceFileId( $invoiceFileResponse->getId() );
291 $this->customsDeclarationRepository->save( $customsDeclaration );
292 }
293
294 if (
295 null !== $customsDeclaration &&
296 null === $customsDeclaration->getEadFileId() &&
297 $customsDeclaration->hasEadFileContent()
298 ) {
299 $eadFileResponse = $this->soapApiClient->createStorageFile(
300 new Soap\Request\CreateStorageFile(
301 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
302 base64_encode( $customsDeclaration->getEadFile() ),
303 sprintf( 'ead_%s.pdf', $customsDeclaration->getId() )
304 )
305 );
306
307 if ( $eadFileResponse->hasFault() ) {
308 $record = new Log\Record();
309 $record->action = Log\Record::ACTION_PACKET_SENDING;
310 $record->status = Log\Record::STATUS_ERROR;
311 $record->title = __( 'Packet ead file could not be created.', 'packeta' );
312 $record->params = [
313 'errorMessage' => $eadFileResponse->getFaultString(),
314 ];
315 $record->orderId = $order->getNumber();
316 $this->logger->add( $record );
317 $submissionResult->increaseLogsCount();
318
319 $submissionResult->increaseErrorsCount();
320 $order->updateApiErrorMessage( $eadFileResponse->getFaultString() );
321 $this->orderRepository->save( $order );
322
323 return $submissionResult;
324 }
325
326 $customsDeclaration->setEadFileId( $eadFileResponse->getId() );
327 $this->customsDeclarationRepository->save( $customsDeclaration );
328 }
329
330 try {
331 $createPacketData = $this->preparePacketData( $order );
332 } catch ( InvalidRequestException $e ) {
333 $record = new Log\Record();
334 $record->action = Log\Record::ACTION_PACKET_SENDING;
335 $record->status = Log\Record::STATUS_ERROR;
336 $record->title = __( 'Packet could not be created.', 'packeta' );
337 $record->params = [
338 'orderId' => $orderData['id'],
339 'errorMessages' => $e->getMessages(),
340 ];
341 $record->orderId = $order->getNumber();
342 $this->logger->add( $record );
343
344 $submissionResult->increaseLogsCount();
345 $submissionResult->increaseErrorsCount();
346
347 return $submissionResult;
348 }
349
350 $response = $this->soapApiClient->createPacket( $createPacketData );
351 if ( $response->hasFault() ) {
352 $record = new Log\Record();
353 $record->action = Log\Record::ACTION_PACKET_SENDING;
354 $record->status = Log\Record::STATUS_ERROR;
355 $record->title = __( 'Packet could not be created.', 'packeta' );
356 $record->params = [
357 'request' => $createPacketData,
358 'errorMessage' => $response->getErrorsAsString(),
359 ];
360 $record->orderId = $order->getNumber();
361 $errorMessage = $response->getErrorsAsString( false );
362
363 $submissionResult->increaseErrorsCount();
364 } else {
365 $order->setIsExported( true );
366 $order->setPacketId( $response->getId() );
367
368 $record = new Log\Record();
369 $record->action = Log\Record::ACTION_PACKET_SENDING;
370 $record->status = Log\Record::STATUS_SUCCESS;
371 $record->title = __( 'Packet was successfully created.', 'packeta' );
372 $record->params = [
373 'request' => $createPacketData,
374 'packetId' => $response->getId(),
375 ];
376 $record->orderId = $order->getNumber();
377 $errorMessage = null;
378
379 $submissionResult->increaseSuccessCount();
380 }
381
382 $submissionResult->increaseLogsCount();
383 $this->logger->add( $record );
384 $order->updateApiErrorMessage( $errorMessage );
385 $this->orderRepository->save( $order );
386
387 if ( $updateOrderStatus && false === $response->hasFault() ) {
388 $this->updateOrderStatusOrLogError( $wcOrder, $order->getNumber(), $submissionResult );
389 }
390 } else {
391 $submissionResult->increaseIgnoredCount();
392 }
393
394 return $submissionResult;
395 }
396
397 /**
398 * Prepares packet attributes.
399 *
400 * @param Entity\Order $order Order entity.
401 * @return array
402 * @throws InvalidRequestException For the case request is not eligible to be sent to API.
403 */
404 private function preparePacketData( Entity\Order $order ): array {
405 $validationErrors = $this->orderValidator->validate( $order );
406 if ( ! empty( $validationErrors ) ) {
407 throw new InvalidRequestException( 'All required order attributes are not set.', $validationErrors );
408 }
409
410 $createPacketData = $this->createPacketMapper->fromOrderToArray( $order );
411 if ( ! empty( $createPacketData['cod'] ) ) {
412 $roundingType = Options::createByCarrierId( $order->getCarrier()->getId() )->getCodRoundingType();
413 $roundedCod = Rounder::roundByCurrency( $createPacketData['cod'], $createPacketData['currency'], $roundingType );
414 $createPacketData['cod'] = $roundedCod;
415 }
416
417 /**
418 * Allows to update CreatePacket request data.
419 *
420 * @since 1.4
421 *
422 * @param array $createPacketData CreatePacket request data.
423 */
424 return (array) apply_filters( 'packeta_create_packet', $createPacketData );
425 }
426
427 /**
428 * Gets translated messages by submission result.
429 *
430 * @param array $submissionResult Submission result.
431 * @param int|null $orderId Order ID.
432 *
433 * @return array
434 */
435 public function getTranslatedSubmissionMessages( array $submissionResult, ?int $orderId ): array {
436 $success = null;
437 if ( is_numeric( $submissionResult['success'] ) && $submissionResult['success'] > 0 ) {
438 if ( $submissionResult['logs'] > 0 ) {
439 $success = sprintf( // translators: 1: link start 2: link end.
440 esc_html__( 'Shipments were submitted successfully. %1$sShow logs%2$s', 'packeta' ),
441 '<a href="' . $this->logPage->createLogListUrl( $orderId ) . '">',
442 '</a>'
443 );
444 } else {
445 $success = esc_html__( 'Shipments were submitted successfully.', 'packeta' );
446 }
447 }
448 $ignored = null;
449 if ( is_numeric( $submissionResult['ignored'] ) && $submissionResult['ignored'] > 0 ) {
450 if ( $submissionResult['logs'] > 0 ) {
451 $ignored = sprintf( // translators: 1: total number of shipments 2: link start 3: link end.
452 esc_html__( 'Some shipments (%1$s in total) were not submitted (these were submitted already or are not Packeta orders). %2$sShow logs%3$s', 'packeta' ),
453 $submissionResult['ignored'],
454 '<a href="' . $this->logPage->createLogListUrl( $orderId ) . '">',
455 '</a>'
456 );
457 } else {
458 $ignored = sprintf( // translators: %s is count.
459 esc_html__( 'Some shipments (%s in total) were not submitted (these were submitted already or are not Packeta orders).', 'packeta' ),
460 $submissionResult['ignored']
461 );
462 }
463 }
464 $errors = null;
465 if ( is_numeric( $submissionResult['errors'] ) && $submissionResult['errors'] > 0 ) {
466 if ( $submissionResult['logs'] > 0 ) {
467 $errors = sprintf( // translators: 1: total number of shipments 2: link start 3: link end.
468 esc_html__( 'Some shipments (%1$s in total) failed to be submitted to Packeta. %2$sShow logs%3$s', 'packeta' ),
469 $submissionResult['errors'],
470 '<a href="' . $this->logPage->createLogListUrl( $orderId ) . '">',
471 '</a>'
472 );
473 } else {
474 $errors = sprintf( // translators: %s is count.
475 esc_html__( 'Some shipments (%s in total) failed to be submitted to Packeta.', 'packeta' ),
476 $submissionResult['errors']
477 );
478 }
479 } elseif ( isset( $submissionResult['errors'] ) ) {
480 $errors = esc_html( $submissionResult['errors'] );
481 }
482
483 if ( is_numeric( $submissionResult['statusUnchanged'] ) && $submissionResult['statusUnchanged'] > 0 ) {
484 $errors = esc_html__( 'Some order statuses have not been automatically changed.', 'packeta' );
485 }
486
487 return [
488 'success' => $success,
489 'ignored' => $ignored,
490 'errors' => $errors,
491 ];
492 }
493
494 /**
495 * Updates order status or logs error.
496 *
497 * @param WC_Order $order WC Order.
498 * @param string $orderId Order ID.
499 * @param PacketSubmissionResult $submissionResult Packet submission result.
500 *
501 * @return void
502 */
503 private function updateOrderStatusOrLogError( WC_Order $order, string $orderId, PacketSubmissionResult $submissionResult ):void {
504 $autoOrderStatus = $this->optionsProvider->getValidAutoOrderStatus();
505 if ( '' === $autoOrderStatus ) {
506 $record = new Log\Record();
507 $record->action = Log\Record::ACTION_PACKET_SENDING;
508 $record->status = Log\Record::STATUS_ERROR;
509
510 $record->title = sprintf(
511 // translators: %s represents unknown order status.
512 __( 'Order status has not been changed, status "%s" doesn\'t exist.', 'packeta' ),
513 $this->optionsProvider->getAutoOrderStatus()
514 );
515 $record->orderId = $orderId;
516 $this->logger->add( $record );
517 $submissionResult->increaseStatusUnchangedCount();
518 } else {
519 $order->update_status( $autoOrderStatus );
520 }
521 }
522
523 }
524