PluginProbe
Packeta / 1.5.4
Packeta v1.5.4
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.5.4, at src/Packetery/Module/Order/PacketSubmitter.php

440 lines 13.2 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\MessageManager;
21 use Packetery\Module\ShippingMethod;
22 use PacketeryNette\Http\Request;
23 use WC_Order;
24 use Packetery\Module;
25
26 /**
27 * Class PacketSubmitter
28 *
29 * @package Packetery\Module\Order
30 */
31 class PacketSubmitter {
32
33 /**
34 * SOAP API Client.
35 *
36 * @var Soap\Client SOAP API Client.
37 */
38 private $soapApiClient;
39
40 /**
41 * Order validator.
42 *
43 * @var Validator\Order
44 */
45 private $orderValidator;
46
47 /**
48 * ILogger.
49 *
50 * @var Log\ILogger
51 */
52 private $logger;
53
54 /**
55 * Order repository.
56 *
57 * @var Repository
58 */
59 private $orderRepository;
60
61 /**
62 * CreatePacketMapper.
63 *
64 * @var CreatePacketMapper
65 */
66 private $createPacketMapper;
67
68 /**
69 * Request.
70 *
71 * @var Request
72 */
73 private $request;
74
75 /**
76 * Message manager.
77 *
78 * @var MessageManager
79 */
80 private $messageManager;
81
82 /**
83 * Log page.
84 *
85 * @var Module\Log\Page
86 */
87 private $logPage;
88
89 /**
90 * Common logic.
91 *
92 * @var PacketActionsCommonLogic
93 */
94 private $commonLogic;
95
96 /**
97 * Options provider.
98 *
99 * @var Module\Options\Provider
100 */
101 private $optionsProvider;
102
103 /**
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.
116 */
117 public function __construct(
118 Soap\Client $soapApiClient,
119 Validator\Order $orderValidator,
120 Log\ILogger $logger,
121 Repository $orderRepository,
122 CreatePacketMapper $createPacketMapper,
123 Request $request,
124 MessageManager $messageManager,
125 Module\Log\Page $logPage,
126 PacketActionsCommonLogic $commonLogic,
127 Module\Options\Provider $optionsProvider
128 ) {
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;
139 }
140
141 /**
142 * Process action
143 *
144 * @return void
145 */
146 public function processAction(): void {
147 $order = $this->commonLogic->getOrder();
148 $redirectTo = $this->request->getQuery( PacketActionsCommonLogic::PARAM_REDIRECT_TO );
149
150 if ( null === $order ) {
151 $record = new Log\Record();
152 $record->action = Log\Record::ACTION_PACKET_SENDING;
153 $record->status = Log\Record::STATUS_ERROR;
154 $record->orderId = null;
155 $record->title = __( 'Packet submission error', 'packeta' );
156 $record->params = [
157 'referer' => (string) $this->request->getReferer(),
158 'errorMessage' => 'Order not found',
159 ];
160
161 $this->logger->add( $record );
162
163 $this->messageManager->flash_message( __( 'Order not found', 'packeta' ), MessageManager::TYPE_ERROR );
164 $this->commonLogic->redirectTo( $redirectTo, $order );
165
166 return;
167 }
168
169 $this->commonLogic->checkAction( PacketActionsCommonLogic::ACTION_SUBMIT_PACKET, $order );
170
171 $submissionResult = $this->submitPacket(
172 $this->orderRepository->getWcOrderById( (int) $order->getNumber() ),
173 $this->optionsProvider->isOrderStatusAutoChangeEnabled(),
174 $order
175 );
176 $resultsCounter = $submissionResult->getCounter();
177 $submissionResultMessages = $this->getTranslatedSubmissionMessages( $resultsCounter, (int) $order->getNumber() );
178
179 if ( $resultsCounter['success'] > 0 ) {
180 $this->messageManager->flashMessageObject(
181 Module\Message::create()
182 ->setText( $submissionResultMessages['success'] )
183 ->setEscape( false )
184 );
185 }
186
187 if ( $resultsCounter['ignored'] > 0 ) {
188 $this->messageManager->flashMessageObject(
189 Module\Message::create()
190 ->setText( $submissionResultMessages['ignored'] )
191 ->setEscape( false )
192 ->setType( MessageManager::TYPE_INFO )
193 );
194 }
195
196 if ( $resultsCounter['errors'] > 0 ) {
197 $this->messageManager->flashMessageObject(
198 Module\Message::create()
199 ->setText( $submissionResultMessages['errors'] )
200 ->setEscape( false )
201 ->setType( MessageManager::TYPE_ERROR )
202 );
203 }
204
205 $redirectTo = $this->request->getQuery( PacketActionsCommonLogic::PARAM_REDIRECT_TO );
206 $this->commonLogic->redirectTo( $redirectTo, $order );
207 }
208
209 /**
210 * Submits packet data to Packeta API.
211 *
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.
215 *
216 * @return PacketSubmissionResult
217 */
218 public function submitPacket(
219 WC_Order $wcOrder,
220 bool $updateOrderStatus,
221 ?Entity\Order $order = null
222 ): PacketSubmissionResult {
223 $submissionResult = new PacketSubmissionResult();
224 if ( null === $order ) {
225 $order = $this->orderRepository->getByWcOrder( $wcOrder );
226 }
227 if ( null === $order ) {
228 $submissionResult->increaseIgnoredCount();
229
230 return $submissionResult;
231 }
232
233 $orderData = $wcOrder->get_data();
234 $shippingMethods = $wcOrder->get_shipping_methods();
235 $shippingMethod = reset( $shippingMethods );
236
237 $shippingMethodData = $shippingMethod->get_data();
238 $shippingMethodId = $shippingMethodData['method_id'];
239 if ( ShippingMethod::PACKETERY_METHOD_ID === $shippingMethodId && ! $order->isExported() ) {
240 try {
241 $createPacketData = $this->preparePacketData( $order );
242 } catch ( InvalidRequestException $e ) {
243 $record = new Log\Record();
244 $record->action = Log\Record::ACTION_PACKET_SENDING;
245 $record->status = Log\Record::STATUS_ERROR;
246 $record->title = __( 'Packet could not be created.', 'packeta' );
247 $record->params = [
248 'orderId' => $orderData['id'],
249 'errorMessage' => $e->getMessage(),
250 ];
251 $record->orderId = $order->getNumber();
252 $this->logger->add( $record );
253
254 $submissionResult->increaseLogsCount();
255 $submissionResult->increaseErrorsCount();
256
257 return $submissionResult;
258 }
259
260 $response = $this->soapApiClient->createPacket( $createPacketData );
261 if ( $response->hasFault() ) {
262 $record = new Log\Record();
263 $record->action = Log\Record::ACTION_PACKET_SENDING;
264 $record->status = Log\Record::STATUS_ERROR;
265 $record->title = __( 'Packet could not be created.', 'packeta' );
266 $record->params = [
267 'request' => $createPacketData,
268 'errorMessage' => $response->getErrorsAsString(),
269 ];
270 $record->orderId = $order->getNumber();
271 $errorMessage = $response->getErrorsAsString( false );
272
273 $submissionResult->increaseErrorsCount();
274 } else {
275 $order->setIsExported( true );
276 $order->setPacketId( $response->getId() );
277
278 $record = new Log\Record();
279 $record->action = Log\Record::ACTION_PACKET_SENDING;
280 $record->status = Log\Record::STATUS_SUCCESS;
281 $record->title = __( 'Packet was successfully created.', 'packeta' );
282 $record->params = [
283 'request' => $createPacketData,
284 'packetId' => $response->getId(),
285 ];
286 $record->orderId = $order->getNumber();
287 $errorMessage = null;
288
289 $submissionResult->increaseSuccessCount();
290 }
291
292 $submissionResult->increaseLogsCount();
293 $this->logger->add( $record );
294 $order->updateApiErrorMessage( $errorMessage );
295 $this->orderRepository->save( $order );
296
297 if ( $updateOrderStatus && false === $response->hasFault() ) {
298 $this->updateOrderStatusOrLogError( $wcOrder, $order->getNumber(), $submissionResult );
299 }
300 } else {
301 $submissionResult->increaseIgnoredCount();
302 }
303
304 return $submissionResult;
305 }
306
307 /**
308 * Prepares packet attributes.
309 *
310 * @param Entity\Order $order Order entity.
311 *
312 * @return array
313 * @throws InvalidRequestException For the case request is not eligible to be sent to API.
314 */
315 private function preparePacketData( Entity\Order $order ): array {
316 if ( ! $this->orderValidator->validate( $order ) ) {
317 throw new InvalidRequestException( 'All required order attributes are not set.' );
318 }
319
320 $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
329 $roundedCod = Rounder::roundByCurrency( $createPacketData['cod'], $createPacketData['currency'], $roundingType );
330 $createPacketData['cod'] = $roundedCod;
331 }
332
333 /**
334 * Allows to update CreatePacket request data.
335 *
336 * @since 1.4
337 *
338 * @param array $createPacketData CreatePacket request data.
339 */
340 return (array) apply_filters( 'packeta_create_packet', $createPacketData );
341 }
342
343 /**
344 * Gets translated messages by submission result.
345 *
346 * @param array $submissionResult Submission result.
347 * @param int|null $orderId Order ID.
348 *
349 * @return array
350 */
351 public function getTranslatedSubmissionMessages( array $submissionResult, ?int $orderId ): array {
352 $success = null;
353 if ( is_numeric( $submissionResult['success'] ) && $submissionResult['success'] > 0 ) {
354 if ( $submissionResult['logs'] > 0 ) {
355 $success = sprintf( // translators: 1: link start 2: link end.
356 esc_html__( 'Shipments were submitted successfully. %1$sShow logs%2$s', 'packeta' ),
357 '<a href="' . $this->logPage->createLogListUrl( $orderId ) . '">',
358 '</a>'
359 );
360 } else {
361 $success = esc_html__( 'Shipments were submitted successfully.', 'packeta' );
362 }
363 }
364 $ignored = null;
365 if ( is_numeric( $submissionResult['ignored'] ) && $submissionResult['ignored'] > 0 ) {
366 if ( $submissionResult['logs'] > 0 ) {
367 $ignored = sprintf( // translators: 1: total number of shipments 2: link start 3: link end.
368 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' ),
369 $submissionResult['ignored'],
370 '<a href="' . $this->logPage->createLogListUrl( $orderId ) . '">',
371 '</a>'
372 );
373 } else {
374 $ignored = sprintf( // translators: %s is count.
375 esc_html__( 'Some shipments (%s in total) were not submitted (these were submitted already or are not Packeta orders).', 'packeta' ),
376 $submissionResult['ignored']
377 );
378 }
379 }
380 $errors = null;
381 if ( is_numeric( $submissionResult['errors'] ) && $submissionResult['errors'] > 0 ) {
382 if ( $submissionResult['logs'] > 0 ) {
383 $errors = sprintf( // translators: 1: total number of shipments 2: link start 3: link end.
384 esc_html__( 'Some shipments (%1$s in total) failed to be submitted to Packeta. %2$sShow logs%3$s', 'packeta' ),
385 $submissionResult['errors'],
386 '<a href="' . $this->logPage->createLogListUrl( $orderId ) . '">',
387 '</a>'
388 );
389 } else {
390 $errors = sprintf( // translators: %s is count.
391 esc_html__( 'Some shipments (%s in total) failed to be submitted to Packeta.', 'packeta' ),
392 $submissionResult['errors']
393 );
394 }
395 } elseif ( isset( $submissionResult['errors'] ) ) {
396 $errors = esc_html( $submissionResult['errors'] );
397 }
398
399 if ( is_numeric( $submissionResult['statusUnchanged'] ) && $submissionResult['statusUnchanged'] > 0 ) {
400 $errors = esc_html__( 'Some order statuses have not been automatically changed.', 'packeta' );
401 }
402
403 return [
404 'success' => $success,
405 'ignored' => $ignored,
406 'errors' => $errors,
407 ];
408 }
409
410 /**
411 * Updates order status or logs error.
412 *
413 * @param WC_Order $order WC Order.
414 * @param string $orderId Order ID.
415 * @param PacketSubmissionResult $submissionResult Packet submission result.
416 *
417 * @return void
418 */
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 }
437 }
438
439 }
440