PluginProbe
seQura / 4.1.0
seQura v4.1.0
4.3.4 4.3.3 4.3.2 4.3.1 trunk 2.0.0 2.0.10 2.0.11 2.0.12 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0.0 3.0.2 3.0.5 3.0.6 3.0.7 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 4.0.0 All 30 releases
← All changes | src/Services/Order/class-order-service.php +151 -578 3.1.14.1.0 View file →
@@ -7,34 +7,26 @@
7 7 */
8 8
9 9 namespace SeQura\WC\Services\Order;
10 10
11 -use Exception;
12 -use SeQura\Core\BusinessLogic\Domain\Multistore\StoreContext;
13 -use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Address;
11 +use SeQura\Core\BusinessLogic\Domain\Connection\Services\ConnectionService;
14 12 use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Cart;
15 -use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Customer;
16 -use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\DeliveryMethod;
17 -use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\PreviousOrder;
18 13 use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderUpdateData;
19 -use SeQura\Core\BusinessLogic\Domain\Order\OrderStates;
20 14 use SeQura\Core\BusinessLogic\Domain\Order\RepositoryContracts\SeQuraOrderRepositoryInterface;
21 15 use SeQura\Core\BusinessLogic\Domain\Order\Service\OrderService;
22 -use SeQura\Core\Infrastructure\Logger\LogContextData;
16 +use SeQura\Core\BusinessLogic\SeQuraAPI\BaseProxy;
23 17 use SeQura\WC\Core\Extension\BusinessLogic\Domain\OrderStatusSettings\Services\Order_Status_Settings_Service;
24 -use SeQura\WC\Core\Extension\Infrastructure\Configuration\Configuration;
25 18 use SeQura\WC\Dto\Cart_Info;
26 19 use SeQura\WC\Dto\Payment_Method_Data;
27 20 use SeQura\WC\Repositories\Interface_Deletable_Repository;
21 +use SeQura\WC\Repositories\Interface_Table_Migration_Repository;
28 22 use SeQura\WC\Services\Cart\Interface_Cart_Service;
29 -use SeQura\WC\Services\Interface_Logger_Service;
30 -use SeQura\WC\Services\Payment\Interface_Payment_Service;
23 +use SeQura\WC\Services\Log\Interface_Logger_Service;
31 24 use SeQura\WC\Services\Pricing\Interface_Pricing_Service;
25 +use SeQura\WC\Services\Time\Interface_Time_Checker_Service;
32 26 use Throwable;
33 -use WC_Customer;
34 27 use WC_DateTime;
35 28 use WC_Order;
36 -use WP_User;
37 29
38 30 /**
39 31 * Handle use cases related to Order
40 32 */
@@ -47,15 +39,8 @@
47 39 private const META_KEY_CART_CREATED_AT = '_sq_cart_created_at';
48 40 private const META_KEY_SENT_TO_SEQURA = '_sq_sent_to_sequra';
49 41
50 42 /**
51 - * Payment service
52 - *
53 - * @var Interface_Payment_Service
54 - */
55 - private $payment_service;
56 -
57 - /**
58 43 * Pricing service
59 44 *
60 45 * @var Interface_Pricing_Service
61 46 */
@@ -68,15 +53,8 @@
68 53 */
69 54 private $order_status_service;
70 55
71 56 /**
72 - * Configuration
73 - *
74 - * @var Configuration
75 - */
76 - private $configuration;
77 -
78 - /**
79 57 * Cart service
80 58 *
81 59 * @var Interface_Cart_Service
82 60 */
@@ -82,15 +60,8 @@
82 60 */
83 61 private $cart_service;
84 62
85 63 /**
86 - * Store context
87 - *
88 - * @var StoreContext
89 - */
90 - private $store_context;
91 -
92 - /**
93 64 * Logger
94 65 *
95 66 * @var Interface_Logger_Service
96 67 */
@@ -103,436 +74,84 @@
103 74 */
104 75 private $sequra_order_repository;
105 76
106 77 /**
107 - * Deletable repository
108 - *
109 - * @var Interface_Deletable_Repository
110 - */
111 - private $sequra_order_deletable_repository;
112 -
113 - /**
114 - * Constructor
78 + * Time checker service
115 79 *
116 - * @param Interface_Deletable_Repository $sequra_order_deletable_repository
80 + * @var Interface_Time_Checker_Service
117 81 */
118 - public function __construct(
119 - $sequra_order_deletable_repository,
120 - SeQuraOrderRepositoryInterface $sequra_order_repository,
121 - Interface_Payment_Service $payment_service,
122 - Interface_Pricing_Service $pricing_service,
123 - Order_Status_Settings_Service $order_status_service,
124 - Configuration $configuration,
125 - Interface_Cart_Service $cart_service,
126 - StoreContext $store_context,
127 - Interface_Logger_Service $logger
128 - ) {
129 - $this->payment_service = $payment_service;
130 - $this->pricing_service = $pricing_service;
131 - $this->order_status_service = $order_status_service;
132 - $this->configuration = $configuration;
133 - $this->cart_service = $cart_service;
134 - $this->store_context = $store_context;
135 - $this->logger = $logger;
136 - $this->sequra_order_repository = $sequra_order_repository;
137 - $this->sequra_order_deletable_repository = $sequra_order_deletable_repository;
138 - }
139 -
140 - /**
141 - * Get delivery method
142 - */
143 - public function get_delivery_method( ?WC_Order $order ): DeliveryMethod {
82 + private $time_checker_service;
144 83
145 - if ( ! $order ) {
146 - $session = WC()->session;
147 - $shipping_methods = $session ? WC()->session->chosen_shipping_methods : array();
148 -
149 - if ( ! $shipping_methods || empty( WC()->shipping->get_packages() ) ) {
150 - return new DeliveryMethod( 'default', null, 'default' );
151 - }
152 - $package = current( WC()->shipping->get_packages() );
153 - $shipping_method = current( $shipping_methods );
154 -
155 - if ( ! isset( $package['rates'][ $shipping_method ] ) ) {
156 - return new DeliveryMethod( 'default', null, 'default' );
157 - }
158 -
159 - $rate = $package['rates'][ $shipping_method ];
160 - return new DeliveryMethod( $rate->label, null, $rate->id );
161 - }
162 -
163 - $shipping_method = current( $order->get_shipping_methods() );
164 -
165 - return new DeliveryMethod(
166 - $shipping_method['name'] ?? 'default',
167 - null,
168 - $shipping_method['method_id'] ?? 'default'
169 - );
170 - }
171 -
172 84 /**
173 - * Get client first name. If the order is null, attempt to retrieve data from the session.
85 + * Deletable repository
86 + *
87 + * @var Interface_Deletable_Repository
174 88 */
175 - public function get_first_name( ?WC_Order $order, $is_delivery = true ): string {
176 - $prefix = $is_delivery ? 'shipping' : 'billing';
177 - return $this->get_customer_field( $order, "get_{$prefix}_first_name", 'get_billing_first_name', "{$prefix}_first_name", 'first_name' );
178 - }
89 + private $deletable_repository;
179 90
180 91 /**
181 - * Get client last name. If the order is null, attempt to retrieve data from the session.
92 + * Table migration repository
93 + *
94 + * @var Interface_Table_Migration_Repository
182 95 */
183 - public function get_last_name( ?WC_Order $order, $is_delivery = true ): string {
184 - $prefix = $is_delivery ? 'shipping' : 'billing';
185 - return $this->get_customer_field( $order, "get_{$prefix}_last_name", 'get_billing_last_name', "{$prefix}_last_name", 'last_name' );
186 - }
96 + private $table_migration_repository;
187 97
188 98 /**
189 - * Get client company. If the order is null, attempt to retrieve data from the session.
99 + * Payment gateway ID
100 + *
101 + * @var string
190 102 */
191 - public function get_company( ?WC_Order $order, $is_delivery = true ): string {
192 - $prefix = $is_delivery ? 'shipping' : 'billing';
193 - return $this->get_customer_field( $order, "get_{$prefix}_company", 'get_billing_company', "{$prefix}_company", 'company' );
194 - }
103 + private $payment_gateway_id;
195 104
196 105 /**
197 - * Get client address's first line. If the order is null, attempt to retrieve data from the session.
106 + * Connection service
107 + *
108 + * @var ConnectionService
198 109 */
199 - public function get_address_1( ?WC_Order $order, $is_delivery = true ): string {
200 - $prefix = $is_delivery ? 'shipping' : 'billing';
201 - return $this->get_customer_field( $order, "get_{$prefix}_address_1", 'get_billing_address_1', "{$prefix}_address_1", 'address_1' );
202 - }
110 + private $connection_service;
203 111
204 112 /**
205 - * Get client address's second line. If the order is null, attempt to retrieve data from the session.
113 + * Order service
114 + *
115 + * @var OrderService
206 116 */
207 - public function get_address_2( ?WC_Order $order, $is_delivery = true ): string {
208 - $prefix = $is_delivery ? 'shipping' : 'billing';
209 - return $this->get_customer_field( $order, "get_{$prefix}_address_2", 'get_billing_address_2', "{$prefix}_address_2", 'address_2' );
210 - }
117 + private $order_service;
211 118
212 119 /**
213 - * Get client postcode. If the order is null, attempt to retrieve data from the session.
120 + * Constructor
214 121 */
215 - public function get_postcode( ?WC_Order $order, $is_delivery = true ): string {
216 - $prefix = $is_delivery ? 'shipping' : 'billing';
217 - return $this->get_customer_field( $order, "get_{$prefix}_postcode", 'get_billing_postcode', "{$prefix}_postcode", 'postcode' );
122 + public function __construct(
123 + SeQuraOrderRepositoryInterface $sequra_order_repository,
124 + Interface_Pricing_Service $pricing_service,
125 + Order_Status_Settings_Service $order_status_service,
126 + Interface_Cart_Service $cart_service,
127 + Interface_Logger_Service $logger,
128 + Interface_Time_Checker_Service $time_checker_service,
129 + Interface_Deletable_Repository $deletable_repository,
130 + Interface_Table_Migration_Repository $table_migration_repository,
131 + string $payment_gateway_id,
132 + ConnectionService $connection_service,
133 + OrderService $order_service
134 + ) {
135 + $this->pricing_service = $pricing_service;
136 + $this->order_status_service = $order_status_service;
137 + $this->cart_service = $cart_service;
138 + $this->logger = $logger;
139 + $this->sequra_order_repository = $sequra_order_repository;
140 + $this->time_checker_service = $time_checker_service;
141 + $this->deletable_repository = $deletable_repository;
142 + $this->table_migration_repository = $table_migration_repository;
143 + $this->payment_gateway_id = $payment_gateway_id;
144 + $this->connection_service = $connection_service;
145 + $this->order_service = $order_service;
218 146 }
219 147
220 148 /**
221 - * Get client city. If the order is null, attempt to retrieve data from the session.
222 - */
223 - public function get_city( ?WC_Order $order, $is_delivery = true ): string {
224 - $prefix = $is_delivery ? 'shipping' : 'billing';
225 - $city = $this->get_customer_field( $order, "get_{$prefix}_city", 'get_billing_city', "{$prefix}_city", 'city' );
226 - if ( ! $city ) {
227 - $city = $this->get_customer_field( $order, 'get_city', 'get_city', 'city', 'city' );
228 - }
229 - return $city;
230 - }
231 -
232 - /**
233 - * Get client country code. If the order is null, attempt to retrieve data from the session.
234 - */
235 - public function get_country( ?WC_Order $order, $is_delivery = true ): string {
236 - $prefix = $is_delivery ? 'shipping' : 'billing';
237 - return $this->get_customer_field( $order, "get_{$prefix}_country", 'get_billing_country', "{$prefix}_country", 'country' );
238 - }
239 -
240 - /**
241 - * Get client state. If the order is null, attempt to retrieve data from the session.
242 - */
243 - public function get_state( ?WC_Order $order, $is_delivery = true ): string {
244 - $prefix = $is_delivery ? 'shipping' : 'billing';
245 - $state_code = $this->get_customer_field( $order, "get_{$prefix}_state", 'get_billing_state', "{$prefix}_state", 'state' );
246 - if ( ! $state_code ) {
247 - return '';
248 - }
249 - $states = WC()->countries->get_states( $this->get_country( $order ) );
250 - if ( ! $states || ! isset( $states[ $state_code ] ) ) {
251 - return '';
252 - }
253 - return $states[ $state_code ];
254 - }
255 -
256 - /**
257 - * Get client phone. If the order is null, attempt to retrieve data from the session.
258 - */
259 - public function get_phone( ?WC_Order $order, $is_delivery = true ): string {
260 - $prefix = $is_delivery ? 'shipping' : 'billing';
261 - return $this->get_customer_field( $order, "get_{$prefix}_phone", 'get_billing_phone', "{$prefix}_phone", 'phone' );
262 - }
263 -
264 - /**
265 - * Get client email. If the order is null, attempt to retrieve data from the session.
266 - */
267 - public function get_email( ?WC_Order $order ): string {
268 - return $this->get_customer_field( $order, 'get_billing_email', 'get_billing_email', 'email', 'email' );
269 - }
270 -
271 - /**
272 - * TODO: Review this with Mikel. I need to know what is the origin of the VAT number field because it is not a default field in WooCommerce.
273 - * Get shopper vat number. If the order is null, attempt to retrieve data from the session.
274 - */
275 - public function get_vat( ?WC_Order $order, $is_delivery = true ): string {
276 - $prefix = $is_delivery ? 'shipping' : 'billing';
277 - $vat = $this->get_customer_field( $order, "get_{$prefix}_nif", 'get_billing_nif', "{$prefix}_nif", 'nif' );
278 - if ( ! $vat ) {
279 - $vat = $this->get_customer_field( $order, 'get_nif', 'get_nif', 'nif', 'nif' );
280 - }
281 - if ( ! $vat ) {
282 - $vat = $this->get_customer_field( $order, "get_{$prefix}_vat", 'get_billing_vat', "{$prefix}_vat", 'vat' );
283 - }
284 -
285 - return $vat;
286 - }
287 -
288 - /**
289 - * Get shopper NIN number. If the order is null, attempt to retrieve data from the session.
290 - */
291 - public function get_nin( ?WC_Order $order ): ?string {
292 - /**
293 - * TODO: Document this filter
294 - * Get NIN number
295 - *
296 - * @since 3.0.0
297 - */
298 - $nin = \apply_filters( 'sequra_get_nin', null, $order );
299 - return is_string( $nin ) || null === $nin ? $nin : null;
300 - }
301 -
302 - /**
303 - * Get date of birth. If the order is null, attempt to retrieve data from the session.
304 - */
305 - public function get_dob( ?WC_Order $order ): ?string {
306 - /**
307 - * TODO: Document this filter
308 - * Get Date of Birth number
309 - *
310 - * @since 3.0.0
311 - */
312 - $dob = \apply_filters( 'sequra_get_dob', null, $order );
313 - return is_string( $dob ) || null === $dob ? $dob : null;
314 - }
315 -
316 - /**
317 - * Get shopper title. If the order is null, attempt to retrieve data from the session.
318 - */
319 - public function get_shopper_title( ?WC_Order $order ): ?string {
320 - /**
321 - * TODO: Document this filter
322 - * Get Shopper title
323 - *
324 - * @since 3.0.0
325 - */
326 - $title = \apply_filters( 'sequra_get_shopper_title', null, $order );
327 - return is_string( $title ) || null === $title ? $title : null;
328 - }
329 -
330 - /**
331 - * Get shopper created at date. If the order is null, attempt to retrieve data from the session.
332 - */
333 - public function get_shopper_created_at( ?WC_Order $order ): ?string {
334 - /**
335 - * TODO: Document this filter
336 - * Get Shopper created at date
337 - *
338 - * @since 3.0.0
339 - */
340 - $date = \apply_filters( 'sequra_get_shopper_created_at', $this->get_shopper_registration_date( $order ), $order );
341 - return is_string( $date ) || null === $date ? $date : null;
342 - }
343 -
344 - /**
345 - * Get shopper registration date
346 - */
347 - private function get_shopper_registration_date( ?WC_Order $order ): ?string {
348 - if ( ! $order ) {
349 - return null;
350 - }
351 - /**
352 - * Order user
353 - *
354 - * @var WP_User $shopper
355 - */
356 - $shopper = \get_user_by( 'id', $order->get_customer_id() );
357 - if ( ! $shopper instanceof WP_User ) {
358 - return null;
359 - }
360 - $timestamp = strtotime( $shopper->user_registered );
361 - return $timestamp ? gmdate( 'c', $timestamp ) : null;
362 - }
363 -
364 - /**
365 - * Get shopper updated at date. If the order is null, attempt to retrieve data from the session.
366 - */
367 - public function get_shopper_updated_at( ?WC_Order $order ): ?string {
368 - /**
369 - * TODO: Document this filter
370 - * Get Shopper updated at date
371 - *
372 - * @since 3.0.0
373 - */
374 - $date = \apply_filters( 'sequra_get_shopper_updated_at', $this->get_shopper_registration_date( $order ), $order );
375 - return is_string( $date ) || null === $date ? $date : null;
376 - }
377 -
378 - /**
379 - * Get shopper rating. If the order is null, attempt to retrieve data from the session.
380 - */
381 - public function get_shopper_rating( ?WC_Order $order ): ?int {
382 - /**
383 - * TODO: Document this filter
384 - * Get Shopper rating. Must return an integer between 0 and 100 or null.
385 - *
386 - * @since 3.0.0
387 - */
388 - $rating = \apply_filters( 'sequra_get_shopper_rating', null, $order );
389 - return ( is_int( $rating ) && 0 <= $rating && 100 >= $rating ) || null === $rating ? $rating : null;
390 - }
391 -
392 - /**
393 - * Get previous orders
394 - *
395 - * @return PreviousOrder[]
396 - */
397 - public function get_previous_orders( int $customer_id ): array {
398 - $previous_orders = array();
399 -
400 - $order_statuses = $this->order_status_service->getOrderStatusSettings();
401 -
402 - if ( ! $order_statuses ) {
403 - return $previous_orders;
404 - }
405 -
406 - $statuses = $this->order_status_service->get_shop_status_completed();
407 - foreach ( $order_statuses as $order_status ) {
408 - if ( $order_status->getSequraStatus() === OrderStates::STATE_APPROVED ) {
409 - // Use the default status if the shop status is not set.
410 - $statuses[] = empty( $order_status->getShopStatus() ) ? 'wc-processing' : $order_status->getShopStatus();
411 - }
412 - }
413 -
414 - $orders = array();
415 - if ( $customer_id ) {
416 - /**
417 - * Get previous orders
418 - *
419 - * @var WC_Order[] $previous_orders
420 - */
421 - $orders = \wc_get_orders(
422 - array(
423 - 'limit' => -1,
424 - 'customer' => $customer_id,
425 - 'status' => $statuses,
426 - )
427 - );
428 - }
429 -
430 - if ( is_array( $orders ) ) {
431 - foreach ( $orders as $order ) {
432 - /**
433 - * Order date
434 - *
435 - * @var WC_DateTime $date
436 - */
437 - $date = $order->get_date_created( 'edit' );
438 - $postcode = $this->get_postcode( $order );
439 - $country = $this->get_country( $order );
440 -
441 - $previous_orders[] = new PreviousOrder(
442 - $date ? $date->date( 'c' ) : '',
443 - $this->pricing_service->to_cents( (float) $order->get_total( 'edit' ) ),
444 - $order->get_currency(),
445 - $order->get_status( 'edit' ),
446 - \wc_get_order_status_name( $order->get_status( 'edit' ) ),
447 - $order->get_payment_method( 'edit' ),
448 - $order->get_payment_method_title( 'edit' ),
449 - $postcode ? $postcode : null,
450 - $country ? $country : null
451 - );
452 - }
453 - }
454 -
455 - return $previous_orders;
456 - }
457 -
458 - /**
459 - * Get customer data from order, session or POST. If not found, return an empty string.
460 - */
461 - private function get_customer_field(
462 - ?WC_Order $order,
463 - string $order_func,
464 - string $order_alt_func,
465 - string $session_key,
466 - string $session_alt_key
467 - ): string {
468 - if ( ! $order ) {
469 - $customer = $this->get_customer_from_session();
470 - return ! empty( $customer[ $session_key ] ) ? $customer[ $session_key ] : (
471 - $session_alt_key !== $session_key && ! empty( $customer[ $session_alt_key ] ) ? $customer[ $session_alt_key ] : ''
472 - );
473 - }
474 - $value = '';
475 - if ( method_exists( $order, $order_func ) ) {
476 - $value = call_user_func( array( $order, $order_func ) );
477 - }
478 -
479 - if ( ! $value && $order_alt_func !== $order_func && method_exists( $order, $order_alt_func ) ) {
480 - $value = call_user_func( array( $order, $order_alt_func ) );
481 - }
482 -
483 - return $value;
484 - }
485 -
486 - /**
487 - * Get customer data from session. If not found, return an empty array.
488 - */
489 - private function get_customer_from_session(): array {
490 - $data = array();
491 - if ( function_exists( 'WC' ) && WC()->customer ) {
492 - /**
493 - * Customer instance.
494 - *
495 - * @var WC_Customer $customer
496 - */
497 - $customer = WC()->customer;
498 - $data = array(
499 - 'email' => $customer->get_email(),
500 - 'billing_first_name' => $customer->get_billing_first_name(),
501 - 'billing_last_name' => $customer->get_billing_last_name(),
502 - 'billing_company' => $customer->get_billing_company(),
503 - 'billing_address_1' => $customer->get_billing_address_1(),
504 - 'billing_address_2' => $customer->get_billing_address_2(),
505 - 'billing_postcode' => $customer->get_billing_postcode(),
506 - 'billing_city' => $customer->get_billing_city(),
507 - 'billing_country' => $customer->get_billing_country(),
508 - 'billing_state' => $customer->get_billing_state(),
509 - 'billing_phone' => $customer->get_billing_phone(),
510 - 'billing_nif' => method_exists( $customer, 'get_billing_nif' ) ? $customer->get_billing_nif() : '',
511 - 'billing_vat' => method_exists( $customer, 'get_billing_vat' ) ? $customer->get_billing_vat() : '',
512 - 'shipping_first_name' => $customer->get_shipping_first_name(),
513 - 'shipping_last_name' => $customer->get_shipping_last_name(),
514 - 'shipping_company' => $customer->get_shipping_company(),
515 - 'shipping_address_1' => $customer->get_shipping_address_1(),
516 - 'shipping_address_2' => $customer->get_shipping_address_2(),
517 - 'shipping_postcode' => $customer->get_shipping_postcode(),
518 - 'shipping_city' => $customer->get_shipping_city(),
519 - 'shipping_country' => $customer->get_shipping_country(),
520 - 'shipping_state' => $customer->get_shipping_state(),
521 - 'shipping_phone' => $customer->get_shipping_phone(),
522 - 'shipping_nif' => method_exists( $customer, 'get_shipping_nif' ) ? $customer->get_shipping_nif() : '',
523 - 'shipping_vat' => method_exists( $customer, 'get_shipping_vat' ) ? $customer->get_shipping_vat() : '',
524 - );
525 - }
526 - return $data;
527 - }
528 -
529 - /**
530 149 * Get order meta value by key from a seQura order.
531 150 * If the order is not a seQura order an empty string is returned.
532 151 */
533 152 private function get_order_meta( WC_Order $order, $meta_key ): string {
534 - if ( $order->get_payment_method() !== $this->payment_service->get_payment_gateway_id() ) {
153 + if ( $order->get_payment_method() !== $this->payment_gateway_id ) {
535 154 return '';
536 155 }
537 156 return strval( $order->get_meta( $meta_key, true ) );
538 157 }
@@ -574,50 +193,8 @@
574 193 );
575 194 }
576 195
577 196 /**
578 - * Get IPN webhook identifier
579 - */
580 - public function get_ipn_url( WC_Order $order, string $store_id ): string {
581 - return \add_query_arg(
582 - array(
583 - 'order' => strval( $order->get_id() ),
584 - 'wc-api' => $this->payment_service->get_ipn_webhook(),
585 - 'store_id' => $store_id,
586 - ),
587 - \home_url( '/' )
588 - );
589 - }
590 -
591 - /**
592 - * Get payment gateway webhook identifier
593 - */
594 - public function get_event_url( WC_Order $order, string $store_id ): string {
595 - return \add_query_arg(
596 - array(
597 - 'order' => strval( $order->get_id() ),
598 - 'wc-api' => $this->payment_service->get_event_webhook(),
599 - 'store_id' => $store_id,
600 - ),
601 - \home_url( '/' )
602 - );
603 - }
604 -
605 - /**
606 - * Get payment gateway webhook identifier
607 - */
608 - public function get_return_url( WC_Order $order ): string {
609 - return \add_query_arg(
610 - array(
611 - 'order' => strval( $order->get_id() ),
612 - 'sq_product' => 'SQ_PRODUCT_CODE',
613 - 'wc-api' => $this->payment_service->get_return_webhook(),
614 - ),
615 - \home_url( '/' )
616 - );
617 - }
618 -
619 - /**
620 197 * Save required metadata for the order.
621 198 * Returns true if the metadata was saved, false otherwise.
622 199 */
623 200 public function set_order_metadata( WC_Order $order, ?Payment_Method_Data $dto, ?Cart_Info $cart_info ): bool {
@@ -685,69 +262,14 @@
685 262 $order->save();
686 263 }
687 264
688 265 /**
689 - * Get customer for the order
690 - */
691 - public function get_customer( ?WC_Order $order, string $lang, int $fallback_user_id = 0, string $fallback_ip = '', string $fallback_user_agent = '' ): Customer {
692 - $current_user_id = $order ? $order->get_customer_id() : $fallback_user_id;
693 - $logged_in = $current_user_id > 0;
694 - $ref = $logged_in ? $current_user_id : null;
695 - $ip = $order ? $order->get_customer_ip_address( 'edit' ) : $fallback_ip;
696 - $user_agent = $order ? $order->get_customer_user_agent( 'edit' ) : $fallback_user_agent;
697 -
698 - return new Customer(
699 - $this->get_email( $order ),
700 - $lang,
701 - $ip,
702 - $user_agent,
703 - $this->get_first_name( $order, true ),
704 - $this->get_last_name( $order, true ),
705 - $this->get_shopper_title( $order ), // title.
706 - $ref,
707 - $this->get_dob( $order ), // dateOfBirth.
708 - $this->get_nin( $order ), // nin.
709 - $this->get_company( $order, true ),
710 - $this->get_vat( $order, true ), // vatNumber.
711 - $this->get_shopper_created_at( $order, true ), // createdAt.
712 - $this->get_shopper_updated_at( $order, true ), // updatedAt.
713 - $this->get_shopper_rating( $order ), // rating.
714 - null, // ninControl.
715 - $this->get_previous_orders( $current_user_id ),
716 - null, // vehicle.
717 - $logged_in
718 - );
719 - }
720 -
721 - /**
722 - * Get delivery or invoice address
723 - */
724 - public function get_address( ?WC_Order $order, bool $is_delivery ): Address {
725 - $country = $this->get_country( $order, $is_delivery );
726 - return new Address(
727 - $this->get_company( $order, $is_delivery ),
728 - $this->get_address_1( $order, $is_delivery ),
729 - $this->get_address_2( $order, $is_delivery ),
730 - $this->get_postcode( $order, $is_delivery ),
731 - $this->get_city( $order, $is_delivery ),
732 - $country ? $country : 'ES',
733 - $this->get_first_name( $order, $is_delivery ),
734 - $this->get_last_name( $order, $is_delivery ),
735 - null, // phone.
736 - $this->get_phone( $order, $is_delivery ), // mobile phone.
737 - $this->get_state( $order, $is_delivery ),
738 - $order ? $order->get_customer_note( 'edit' ) : null, // extra.
739 - $this->get_vat( $order, $is_delivery )
740 - );
741 - }
742 -
743 - /**
744 266 * Call the Order Update API to sync the order status with SeQura
745 267 *
746 268 * @throws Throwable
747 269 */
748 270 public function update_sequra_order_status( WC_Order $order, string $old_store_status, string $new_store_status ): void {
749 - if ( $order->get_payment_method( 'edit' ) !== $this->payment_service->get_payment_gateway_id()
271 + if ( $order->get_payment_method( 'edit' ) !== $this->payment_gateway_id
750 272 || ! in_array( $new_store_status, $this->order_status_service->get_shop_status_completed( true ), true )
751 273 || ! $order->needs_processing() ) {
752 274 // Prevent updating orders that:
753 275 // 1. Were not paid with SeQura.
@@ -768,9 +290,9 @@
768 290 $cart_info = $this->get_cart_info( $order );
769 291 $currency = $order->get_currency( 'edit' );
770 292 $cart_ref = $cart_info ? $cart_info->ref : null;
771 293 $created_at = $cart_info ? $cart_info->created_at : null;
772 - $updated_at = $order->get_date_completed()->format( 'Y-m-d H:i:s' );
294 + $updated_at = $this->get_order_completion_date( $order );
773 295 $shipped_items = array_merge(
774 296 $this->cart_service->get_items( $order ),
775 297 $this->cart_service->get_handling_items( $order ),
776 298 $this->cart_service->get_discount_items( $order ),
@@ -783,10 +305,9 @@
783 305 *
784 306 * @since 2.0.0
785 307 */
786 308 $ref_1 = \apply_filters( 'woocommerce_sequra_get_order_ref_1', $order->get_id(), $order );
787 -
788 - $this->call_update_order(
309 + $this->order_service->updateOrder(
789 310 new OrderUpdateData(
790 311 $ref_1, // Order reference.
791 312 new Cart( $currency, false, $shipped_items, $cart_ref, $created_at, $updated_at ), // Shipped cart.
792 313 new Cart( $currency ), // Unshipped cart.
@@ -799,26 +320,8 @@
799 320 }
800 321 }
801 322
802 323 /**
803 - * Get a fresh instance of the core order service
804 - *
805 - * @param OrderUpdateData $order_data Order data
806 - *
807 - * @throws Exception
808 - */
809 - private function call_update_order( $order_data ) {
810 - $store_id = $this->configuration->get_store_id();
811 - /**
812 - * Order service
813 - *
814 - * @var OrderService $order_service
815 - */
816 - $order_service = $this->store_context::doWithStore( $store_id, 'SeQura\Core\Infrastructure\ServiceRegister::getService', array( OrderService::class ) );
817 - $this->store_context::doWithStore( $store_id, array( $order_service, 'updateOrder' ), array( $order_data ) );
818 - }
819 -
820 - /**
821 324 * Update the order amount in SeQura after a refund
822 325 *
823 326 * @throws Throwable
824 327 */
@@ -826,9 +329,9 @@
826 329 $cart_info = $this->get_cart_info( $order );
827 330 $currency = $order->get_currency( 'edit' );
828 331 $cart_ref = $cart_info ? $cart_info->ref : null;
829 332 $created_at = $cart_info ? $cart_info->created_at : null;
830 - $updated_at = $order->get_date_completed()->format( 'Y-m-d H:i:s' );
333 + $updated_at = $this->get_order_completion_date( $order );
831 334 $shipped_items = array();
832 335 if ( $order->get_total( 'edit' ) > $amount ) {
833 336 $shipped_items = array_merge(
834 337 $this->cart_service->get_items( $order ),
@@ -844,9 +347,9 @@
844 347 *
845 348 * @since 2.0.0
846 349 */
847 350 $ref_1 = \apply_filters( 'woocommerce_sequra_get_order_ref_1', $order->get_id(), $order );
848 - $this->call_update_order(
351 + $this->order_service->updateOrder(
849 352 new OrderUpdateData(
850 353 $ref_1, // Order reference.
851 354 new Cart( $currency, false, $shipped_items, $cart_ref, $created_at, $updated_at ), // Shipped cart.
852 355 new Cart( $currency ), // Unshipped cart.
@@ -862,20 +365,34 @@
862 365 /**
863 366 * Get the link to the SeQura back office for the order
864 367 */
865 368 public function get_link_to_sequra_back_office( WC_Order $order ): ?string {
866 - if ( $order->get_payment_method() !== $this->payment_service->get_payment_gateway_id() ) {
369 + if ( $order->get_payment_method() !== $this->payment_gateway_id ) {
867 370 return null;
868 371 }
869 -
870 - switch ( $this->configuration->get_env() ) {
871 - case 'sandbox':
872 - return 'https://simbox.sequrapi.com/orders/' . $order->get_transaction_id();
873 - case 'live':
874 - return 'https://simba.sequra.es/orders/' . $order->get_transaction_id();
875 - default:
876 - return null;
372 +
373 + $merchant_id = $this->get_merchant_id( $order );
374 + if ( ! $merchant_id ) {
375 + return null;
877 376 }
377 +
378 + try {
379 + $conn_data = $this->connection_service->getConnectionDataByMerchantId( $merchant_id );
380 + $base_url = array(
381 + 'sequra' => array(
382 + BaseProxy::TEST_MODE => 'https://portal-sandbox.sequra.com',
383 + BaseProxy::LIVE_MODE => 'https://portal.sequra.com',
384 + ),
385 + 'svea' => array(
386 + BaseProxy::TEST_MODE => 'https://portal-sandbox.sequra.com',
387 + BaseProxy::LIVE_MODE => 'https://portal.sequra.com',
388 + ),
389 + );
390 + return ! isset( $base_url[ $conn_data->getDeployment() ][ $conn_data->getEnvironment() ] ) ? null : $base_url[ $conn_data->getDeployment() ][ $conn_data->getEnvironment() ] . '/orders/' . $order->get_transaction_id();
391 + } catch ( Throwable $e ) {
392 + $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
393 + return null;
394 + }
878 395 }
879 396
880 397 /**
881 398 * Get the total amount of the order
@@ -896,21 +413,9 @@
896 413 *
897 414 * @return void
898 415 */
899 416 public function cleanup_orders() {
900 - if ( ! $this->sequra_order_deletable_repository instanceof Interface_Deletable_Repository ) {
901 - $this->logger->log_error(
902 - 'seQura Orders cleanup CRON JOB skipped: The order deletable repository is not set.',
903 - __FUNCTION__,
904 - __CLASS__,
905 - array(
906 - new LogContextData( 'actualType', is_object( $this->sequra_order_deletable_repository ) ? get_class( $this->sequra_order_deletable_repository ) : 'NULL' ),
907 - new LogContextData( 'expectedType', Interface_Deletable_Repository::class ),
908 - )
909 - );
910 - return;
911 - }
912 - $this->sequra_order_deletable_repository->delete_old_and_invalid();
417 + $this->deletable_repository->delete_old_and_invalid();
913 418 }
914 419
915 420 /**
916 421 * Get the Merchant ID
@@ -924,6 +429,74 @@
924 429 }
925 430
926 431 $sq_order = $this->sequra_order_repository->getByShopReference( $order->get_id() );
927 432 return $sq_order ? (string) $sq_order->getMerchant()->getId() : null;
433 + }
434 +
435 +
436 + /**
437 + * Check if the migration process is complete
438 + *
439 + * @return bool True if they are missing indexes, false otherwise
440 + */
441 + public function is_migration_complete() {
442 + return $this->table_migration_repository->is_migration_complete();
443 + }
444 +
445 + /**
446 + * Execute the migration process
447 + */
448 + public function migrate_data() {
449 + try {
450 + $this->table_migration_repository->prepare_tables_for_migration();
451 + } catch ( Throwable $e ) {
452 + $this->logger->log_throwable( $e, __FUNCTION__, __CLASS__ );
453 + return;
454 + }
455 +
456 + /**
457 + * Filters the start hour for the migration process.
458 + *
459 + * @since 3.1.2
460 + * @return int The hour to start the migration process, default is 2 (2AM).
461 + */
462 + $from = (int) apply_filters( 'sequra_migration_from', 2 );
463 +
464 + /**
465 + * Filters the end hour for the migration process.
466 + *
467 + * @since 3.1.2
468 + * @return int The hour to end the migration process, default is 6 (6AM).
469 + */
470 + $to = (int) apply_filters( 'sequra_migration_to', 6 );
471 +
472 + if ( ! $this->time_checker_service->is_current_hour_in_range( $from, $to ) ) {
473 + return;
474 + }
475 +
476 + /**
477 + * Filters the batch size for the migration process.
478 + *
479 + * @since 3.1.2
480 + * @return int The number of rows to process in each batch, default is 100.
481 + */
482 + $batch_size = (int) apply_filters( 'sequra_migration_batch_size', 100 );
483 + for ( $i = 0; $i < $batch_size; $i++ ) {
484 + $this->table_migration_repository->migrate_next_row();
485 + if ( $this->table_migration_repository->maybe_remove_legacy_table() ) {
486 + // Migration is complete.
487 + break;
488 + }
489 + }
490 + }
491 +
492 + /**
493 + * Get the order completion date or current date if not completed.
494 + *
495 + * @param WC_Order $order
496 + * @return string
497 + */
498 + public function get_order_completion_date( $order ) {
499 + $datetime = $order instanceof WC_Order ? $order->get_date_completed() : null;
500 + return ( $datetime ?? new WC_DateTime() )->format( 'Y-m-d H:i:s' );
928 501 }
929 502 }