Skip to content

Commit

Permalink
Merge branch 'WP-55' into 'main'
Browse files Browse the repository at this point in the history
feat: check is order created before

See merge request ecommerce_modules/cms/wordpress/wordpress!25
  • Loading branch information
DEMAxx committed Oct 4, 2024
2 parents e20223d + 50a4d0a commit b14f6f9
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 93 deletions.
166 changes: 122 additions & 44 deletions src/Actions/CreateOrderAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@
namespace Cdek\Actions {

use Cdek\CdekApi;
use Cdek\CoreApi;
use Cdek\Config;
use Cdek\Exceptions\AuthException;
use Cdek\Exceptions\CdekApiException;
use Cdek\Exceptions\CdekClientException;
use Cdek\Exceptions\CdekServerException;
use Cdek\Exceptions\PhoneNotValidException;
use Cdek\Exceptions\RestApiInvalidRequestException;
use Cdek\Exceptions\ShippingMethodNotFoundException;
use Cdek\Helper;
use Cdek\Helpers\CheckoutHelper;
use Cdek\Helpers\ScheduleLocker;
use Cdek\Helpers\StringHelper;
use Cdek\Helpers\WeightCalc;
use Cdek\MetaKeys;
Expand All @@ -20,33 +28,29 @@
use Cdek\Note;
use Exception;
use Throwable;
use JsonException;
use WC_Order;

class CreateOrderAction
{
private const ALLOWED_PRODUCT_TYPES = ['variation', 'simple'];

private CdekApi $api;
private CoreApi $coreApi;

/**
* @throws \Cdek\Exceptions\RestApiInvalidRequestException|\Throwable|\JsonException
* @throws RestApiInvalidRequestException|Throwable|JsonException
*/
public function __invoke(int $orderId, int $attempt = 0, array $packages = null): array
{
$this->api = new CdekApi;
$this->coreApi = new CoreApi('common');
$order = wc_get_order($orderId);
$postOrderData = OrderMetaData::getMetaByOrderId($orderId);

if (!empty($postOrderData['order_number']) || !empty($postOrderData['order_uuid'])) {
return [
'state' => false,
'message' => esc_html__('Order already exists', 'cdekdelivery'),
];
}

$shippingMethod = CheckoutHelper::getOrderShippingMethod($order);
$tariffCode = $shippingMethod->get_meta(MetaKeys::TARIFF_CODE) ?:
$shippingMethod->get_meta('tariff_code') ?: $postOrderData['tariff_id'];
$shippingMethod->get_meta('tariff_code') ?: $postOrderData['tariff_id'];
$postOrderData = [
'currency' => $order->get_currency() ?: 'RUB',
'tariff_code' => $tariffCode,
Expand All @@ -55,45 +59,16 @@ public function __invoke(int $orderId, int $attempt = 0, array $packages = null)
];

try {
$param = $this->buildRequestData($order, $postOrderData);
$param['packages'] = $this->buildPackagesData($order, $postOrderData, $packages);

$orderData = $this->api->createOrder($param);

sleep(5);

$cdekNumber = $this->getCdekOrderNumber($orderData['entity']['uuid']);

try {
$cdekStatuses = Helper::getCdekOrderStatuses($orderData['entity']['uuid']);
$actionOrderAvailable = Helper::getCdekActionOrderAvailable($cdekStatuses);
} catch (Exception $e) {
$cdekStatuses = [];
$actionOrderAvailable = true;
}

$postOrderData['order_number'] = $cdekNumber ?? $orderData['entity']['uuid'];
$postOrderData['order_uuid'] = $orderData['entity']['uuid'];
OrderMetaData::updateMetaByOrderId($orderId, $postOrderData);

ob_start();
include(WP_PLUGIN_DIR.'/cdek/templates/admin/status_list.php');
$cdekStatusesRender = ob_get_clean();
return $this->sendOrderInfo($postOrderData, $this->coreApi->getOrderById($orderId));
} catch (CdekClientException $e) {
if($e->getCode() === 404) {
return $this->createOrder($order, $postOrderData, $packages);
}

if (!empty($cdekNumber)) {
Note::send($orderId, sprintf(esc_html__(/* translators: 1: tracking number */ 'Tracking number: %1$s',
'cdekdelivery'),
$cdekNumber), true);
throw $e;
}

return [
'state' => true,
'code' => $cdekNumber,
'statuses' => $cdekStatusesRender,
'available' => $actionOrderAvailable,
'door' => Tariff::isTariffFromDoor($postOrderData['tariff_code']),
];

} catch (PhoneNotValidException $e) {
Note::send($order->get_id(),
sprintf(esc_html__(/* translators: 1: error message */ 'Cdek shipping error: %1$s', 'cdekdelivery'),
Expand All @@ -117,6 +92,14 @@ public function __invoke(int $orderId, int $attempt = 0, array $packages = null)
}
}

/**
* @param WC_Order $order
* @param $postOrderData
*
* @return array
* @throws PhoneNotValidException
* @throws ShippingMethodNotFoundException
*/
private function buildRequestData(WC_Order $order, $postOrderData): array
{
$countryCode = trim(($order->get_shipping_country() ?: $order->get_billing_country()) ?? 'RU');
Expand Down Expand Up @@ -381,5 +364,100 @@ private function getCdekOrderNumber(string $orderUuid, int $iteration = 1): ?str

return $orderInfo['entity']['cdek_number'] ?? $this->getCdekOrderNumber($orderUuid, $iteration + 1);
}

private function getStatusList(bool $actionAvailable, array $statuses = []): string
{
$cdekStatuses = $statuses;
$actionOrderAvailable = $actionAvailable;
ob_start();
include(WP_PLUGIN_DIR.'/cdek/templates/admin/status_list.php');
return ob_get_clean();
}

/**
* @param $order
* @param $postOrderData
* @param $packages
*
* @return array
* @throws AuthException
* @throws CdekApiException
* @throws CdekClientException
* @throws CdekServerException
* @throws PhoneNotValidException
* @throws RestApiInvalidRequestException
* @throws ShippingMethodNotFoundException
* @throws JsonException
*/
private function createOrder($order, $postOrderData, $packages): array
{
$param = $this->buildRequestData($order, $postOrderData);
$param['packages'] = $this->buildPackagesData($order, $postOrderData, $packages);

$orderData = $this->api->createOrder($param);

sleep(5);

$cdekNumber = $this->getCdekOrderNumber($orderData['entity']['uuid']);

try {
$cdekStatuses = Helper::getCdekOrderStatuses($orderData['entity']['uuid']);
$actionOrderAvailable = Helper::getCdekActionOrderAvailable($cdekStatuses);
} catch (Exception $e) {
$cdekStatuses = [];
$actionOrderAvailable = true;
}

$postOrderData['order_number'] = $cdekNumber ?? $orderData['entity']['uuid'];
$postOrderData['order_uuid'] = $orderData['entity']['uuid'];
OrderMetaData::updateMetaByOrderId($order->get_id(), $postOrderData);

if (!empty($cdekNumber)) {
Note::send($order->get_id(), sprintf(esc_html__(/* translators: 1: tracking number */ 'Tracking number: %1$s',
'cdekdelivery'),
$cdekNumber), true);
}

return [
'state' => true,
'code' => $cdekNumber,
'statuses' => $this->getStatusList($actionOrderAvailable, $cdekStatuses),
'available' => $actionOrderAvailable,
'door' => Tariff::isTariffFromDoor($postOrderData['tariff_code']),
];
}

/**
* @param $postOrderData
* @param $existOrder
*
* @return array
* @throws AuthException
* @throws JsonException
*/
private function sendOrderInfo($postOrderData, $existOrder): array
{
$cdekStatuses[] = $existOrder['status'];

try {
$historyCdekStatuses = $this->coreApi->getHistory($existOrder['uuid']);
}catch (CdekApiException $e){
$historyCdekStatuses = [];
}

return [
'state' => true,
'code' => $existOrder['track'],
'statuses' => $this->getStatusList(
!empty($historyCdekStatuses),
array_merge(
$cdekStatuses,
$historyCdekStatuses,
),
),
'available' => !empty($historyCdekStatuses),
'door' => Tariff::isTariffFromDoor($postOrderData['tariff_code']),
];
}
}
}
57 changes: 47 additions & 10 deletions src/Actions/DispatchOrderAutomationAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,30 @@

namespace Cdek\Actions;

use ActionScheduler_Lock;
use Cdek\CoreApi;
use Cdek\Config;
use Cdek\Exceptions\AuthException;
use Cdek\Exceptions\CdekApiException;
use Cdek\Exceptions\CdekClientException;
use Cdek\Exceptions\CdekServerException;
use Cdek\Exceptions\ShippingMethodNotFoundException;
use Cdek\Helper;
use Cdek\Helpers\CheckoutHelper;
use Cdek\Helpers\ScheduleLocker;
use Cdek\Note;
use JsonException;
use WC_Order;

class DispatchOrderAutomationAction
{
const LOCK_TYPE = 'cdek_dispatch_order_automation_lock';

/**
* @param int|WC_Order $orderId
* @param int|WC_Order $orderId
*
* @throws CdekApiException
* @throws JsonException
*/
public function __invoke($orderId, $postedData = null, ?WC_Order $originalOrder = null): void
{
Expand All @@ -31,25 +43,50 @@ public function __invoke($orderId, $postedData = null, ?WC_Order $originalOrder
return;
}

$actualShippingMethod = Helper::getActualShippingMethod($shipping->get_instance_id());
$actualShippingMethod = Helper::getActualShippingMethod((int)$shipping->get_instance_id());

if ($actualShippingMethod->get_option('automate_orders') !== 'yes') {
return;
}

$awaitingGateways = $actualShippingMethod->get_option('automate_wait_gateways', []);

if (!empty($awaitingGateways) &&
in_array($order->get_payment_method(), $awaitingGateways, true) &&
!$order->is_paid()) {
if (
!empty($awaitingGateways)
&&
in_array($order->get_payment_method(), $awaitingGateways, true)
&&
!$order->is_paid()
) {
return;
}

if (as_schedule_single_action(time() + 60 * 5, Config::ORDER_AUTOMATION_HOOK_NAME, [
$order->get_id(),
1,
], 'cdekdelivery')) {
Note::send($order->get_id(), esc_html__('Created order automation task', 'cdekdelivery'));
$lock = ScheduleLocker::instance();
$lockType = ScheduleLocker::LOCK_TYPE_AUTOMATION_ORDER . '_' . $order->get_id();

if ($lock->is_locked($lockType)) {
return;
}

if (!$lock->set($lockType)) {
return;
}

try {
(new CoreApi('common'))->getOrderById($orderId);
} catch (AuthException|CdekServerException $e) {
Note::send($orderId, $e->getCode() . ': ' . $e->getMessage(), true);
} catch (CdekClientException $e) {
if($e->getCode() === 404){
if (as_schedule_single_action(time() + 60 * 5, Config::ORDER_AUTOMATION_HOOK_NAME, [
$order->get_id(),
1,
], 'cdekdelivery')) {
Note::send($order->get_id(), esc_html__('Created order automation task', 'cdekdelivery'));
}
}else{
Note::send($orderId, $e->getMessage(), true);
}
}
}
}
5 changes: 5 additions & 0 deletions src/Actions/Schedule/ReindexOrders.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@

class ReindexOrders extends TaskContract
{
/**
* @throws CdekScheduledTaskException
* @throws CdekApiException
* @throws \JsonException
*/
public function __construct(string $taskId)
{
parent::__construct($taskId);
Expand Down
Loading

0 comments on commit b14f6f9

Please sign in to comment.