soapApiClient = $soapApiClient; $this->orderValidator = $orderValidator; $this->logger = $logger; $this->orderRepository = $orderRepository; $this->createPacketMapper = $createPacketMapper; $this->request = $request; $this->messageManager = $messageManager; $this->logPage = $logPage; $this->commonLogic = $commonLogic; $this->optionsProvider = $optionsProvider; } /** * Process action * * @return void */ public function processAction(): void { $order = $this->commonLogic->getOrder(); $redirectTo = $this->request->getQuery( PacketActionsCommonLogic::PARAM_REDIRECT_TO ); if ( null === $order ) { $record = new Log\Record(); $record->action = Log\Record::ACTION_PACKET_SENDING; $record->status = Log\Record::STATUS_ERROR; $record->orderId = null; $record->title = __( 'Packet submission error', 'packeta' ); $record->params = [ 'referer' => (string) $this->request->getReferer(), 'errorMessage' => 'Order not found', ]; $this->logger->add( $record ); $this->messageManager->flash_message( __( 'Order not found', 'packeta' ), MessageManager::TYPE_ERROR ); $this->commonLogic->redirectTo( $redirectTo, $order ); return; } $this->commonLogic->checkAction( PacketActionsCommonLogic::ACTION_SUBMIT_PACKET, $order ); $submissionResult = $this->submitPacket( $this->orderRepository->getWcOrderById( (int) $order->getNumber() ), $this->optionsProvider->isOrderStatusAutoChangeEnabled(), $order ); $resultsCounter = $submissionResult->getCounter(); $submissionResultMessages = $this->getTranslatedSubmissionMessages( $resultsCounter, (int) $order->getNumber() ); if ( $resultsCounter['success'] > 0 ) { $this->messageManager->flashMessageObject( Module\Message::create() ->setText( $submissionResultMessages['success'] ) ->setEscape( false ) ); } if ( $resultsCounter['ignored'] > 0 ) { $this->messageManager->flashMessageObject( Module\Message::create() ->setText( $submissionResultMessages['ignored'] ) ->setEscape( false ) ->setType( MessageManager::TYPE_INFO ) ); } if ( $resultsCounter['errors'] > 0 ) { $this->messageManager->flashMessageObject( Module\Message::create() ->setText( $submissionResultMessages['errors'] ) ->setEscape( false ) ->setType( MessageManager::TYPE_ERROR ) ); } $redirectTo = $this->request->getQuery( PacketActionsCommonLogic::PARAM_REDIRECT_TO ); $this->commonLogic->redirectTo( $redirectTo, $order ); } /** * Submits packet data to Packeta API. * * @param WC_Order $wcOrder WC order. * @param bool $updateOrderStatus Updates WC order status if packet was successfully created. Value is based on plugin settings. * @param Entity\Order|null $order Order. * * @return PacketSubmissionResult */ public function submitPacket( WC_Order $wcOrder, bool $updateOrderStatus, ?Entity\Order $order = null ): PacketSubmissionResult { $submissionResult = new PacketSubmissionResult(); if ( null === $order ) { $order = $this->orderRepository->getByWcOrder( $wcOrder ); } if ( null === $order ) { $submissionResult->increaseIgnoredCount(); return $submissionResult; } $orderData = $wcOrder->get_data(); $shippingMethods = $wcOrder->get_shipping_methods(); $shippingMethod = reset( $shippingMethods ); $shippingMethodData = $shippingMethod->get_data(); $shippingMethodId = $shippingMethodData['method_id']; if ( ShippingMethod::PACKETERY_METHOD_ID === $shippingMethodId && ! $order->isExported() ) { try { $createPacketData = $this->preparePacketData( $order ); } catch ( InvalidRequestException $e ) { $record = new Log\Record(); $record->action = Log\Record::ACTION_PACKET_SENDING; $record->status = Log\Record::STATUS_ERROR; $record->title = __( 'Packet could not be created.', 'packeta' ); $record->params = [ 'orderId' => $orderData['id'], 'errorMessage' => $e->getMessage(), ]; $record->orderId = $order->getNumber(); $this->logger->add( $record ); $submissionResult->increaseLogsCount(); $submissionResult->increaseErrorsCount(); return $submissionResult; } $response = $this->soapApiClient->createPacket( $createPacketData ); if ( $response->hasFault() ) { $record = new Log\Record(); $record->action = Log\Record::ACTION_PACKET_SENDING; $record->status = Log\Record::STATUS_ERROR; $record->title = __( 'Packet could not be created.', 'packeta' ); $record->params = [ 'request' => $createPacketData, 'errorMessage' => $response->getErrorsAsString(), ]; $record->orderId = $order->getNumber(); $errorMessage = $response->getErrorsAsString( false ); $submissionResult->increaseErrorsCount(); } else { $order->setIsExported( true ); $order->setPacketId( (string) $response->getId() ); $record = new Log\Record(); $record->action = Log\Record::ACTION_PACKET_SENDING; $record->status = Log\Record::STATUS_SUCCESS; $record->title = __( 'Packet was successfully created.', 'packeta' ); $record->params = [ 'request' => $createPacketData, 'packetId' => $response->getId(), ]; $record->orderId = $order->getNumber(); $errorMessage = null; $submissionResult->increaseSuccessCount(); } $submissionResult->increaseLogsCount(); $this->logger->add( $record ); $order->updateApiErrorMessage( $errorMessage ); $this->orderRepository->save( $order ); if ( $updateOrderStatus && false === $response->hasFault() ) { $this->updateOrderStatusOrLogError( $wcOrder, $order->getNumber(), $submissionResult ); } } else { $submissionResult->increaseIgnoredCount(); } return $submissionResult; } /** * Prepares packet attributes. * * @param Entity\Order $order Order entity. * * @return array * @throws InvalidRequestException For the case request is not eligible to be sent to API. */ private function preparePacketData( Entity\Order $order ): array { if ( ! $this->orderValidator->validate( $order ) ) { throw new InvalidRequestException( 'All required order attributes are not set.' ); } $createPacketData = $this->createPacketMapper->fromOrderToArray( $order ); if ( ! empty( $createPacketData['cod'] ) ) { if ( $order->getCarrierCode() === null ) { // This means that more accurate carrier id could not be determined. See Order\Builder. $roundingType = Rounder::DONT_ROUND; } else { $roundingType = Options::createByCarrierId( $order->getCarrierCode() )->getCodRoundingType(); } $roundedCod = Rounder::roundByCurrency( $createPacketData['cod'], $createPacketData['currency'], $roundingType ); $createPacketData['cod'] = $roundedCod; } /** * Allows to update CreatePacket request data. * * @since 1.4 * * @param array $createPacketData CreatePacket request data. */ return (array) apply_filters( 'packeta_create_packet', $createPacketData ); } /** * Gets translated messages by submission result. * * @param array $submissionResult Submission result. * @param int|null $orderId Order ID. * * @return array */ public function getTranslatedSubmissionMessages( array $submissionResult, ?int $orderId ): array { $success = null; if ( is_numeric( $submissionResult['success'] ) && $submissionResult['success'] > 0 ) { if ( $submissionResult['logs'] > 0 ) { $success = sprintf( // translators: 1: link start 2: link end. esc_html__( 'Shipments were submitted successfully. %1$sShow logs%2$s', 'packeta' ), '', '' ); } else { $success = esc_html__( 'Shipments were submitted successfully.', 'packeta' ); } } $ignored = null; if ( is_numeric( $submissionResult['ignored'] ) && $submissionResult['ignored'] > 0 ) { if ( $submissionResult['logs'] > 0 ) { $ignored = sprintf( // translators: 1: total number of shipments 2: link start 3: link end. 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' ), $submissionResult['ignored'], '', '' ); } else { $ignored = sprintf( // translators: %s is count. esc_html__( 'Some shipments (%s in total) were not submitted (these were submitted already or are not Packeta orders).', 'packeta' ), $submissionResult['ignored'] ); } } $errors = null; if ( is_numeric( $submissionResult['errors'] ) && $submissionResult['errors'] > 0 ) { if ( $submissionResult['logs'] > 0 ) { $errors = sprintf( // translators: 1: total number of shipments 2: link start 3: link end. esc_html__( 'Some shipments (%1$s in total) failed to be submitted to Packeta. %2$sShow logs%3$s', 'packeta' ), $submissionResult['errors'], '', '' ); } else { $errors = sprintf( // translators: %s is count. esc_html__( 'Some shipments (%s in total) failed to be submitted to Packeta.', 'packeta' ), $submissionResult['errors'] ); } } elseif ( isset( $submissionResult['errors'] ) ) { $errors = esc_html( $submissionResult['errors'] ); } if ( is_numeric( $submissionResult['statusUnchanged'] ) && $submissionResult['statusUnchanged'] > 0 ) { $errors = esc_html__( 'Some order statuses have not been automatically changed.', 'packeta' ); } return [ 'success' => $success, 'ignored' => $ignored, 'errors' => $errors, ]; } /** * Updates order status or logs error. * * @param WC_Order $order WC Order. * @param string $orderId Order ID. * @param PacketSubmissionResult $submissionResult Packet submission result. * * @return void */ private function updateOrderStatusOrLogError( WC_Order $order, string $orderId, PacketSubmissionResult $submissionResult ):void { $autoOrderStatus = $this->optionsProvider->getValidAutoOrderStatus(); if ( '' === $autoOrderStatus ) { $record = new Log\Record(); $record->action = Log\Record::ACTION_PACKET_SENDING; $record->status = Log\Record::STATUS_ERROR; $record->title = sprintf( // translators: %s represents unknown order status. __( 'Order status has not been changed, status "%s" doesn\'t exist.', 'packeta' ), $this->optionsProvider->getAutoOrderStatus() ); $record->orderId = $orderId; $this->logger->add( $record ); $submissionResult->increaseStatusUnchangedCount(); } else { $order->update_status( $autoOrderStatus ); } } }