PluginProbe
seQura / 3.0.2
seQura v3.0.2
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
sequra / src / Services / Order / class-order-service.php

class-order-service.php in seQura 3.0.2, at src/Services/Order/class-order-service.php

816 lines 26.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Order service
4 *
5 * @package SeQura/WC
6 * @subpackage SeQura/WC/Services
7 */
8
9 namespace SeQura\WC\Services\Order;
10
11 use Exception;
12 use SeQura\Core\BusinessLogic\Domain\Multistore\StoreContext;
13 use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderRequest\Address;
14 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 use SeQura\Core\BusinessLogic\Domain\Order\Models\OrderUpdateData;
19 use SeQura\Core\BusinessLogic\Domain\Order\OrderStates;
20 use SeQura\Core\BusinessLogic\Domain\Order\Service\OrderService;
21 use SeQura\WC\Core\Extension\BusinessLogic\Domain\OrderStatusSettings\Services\Order_Status_Settings_Service;
22 use SeQura\WC\Core\Extension\Infrastructure\Configuration\Configuration;
23 use SeQura\WC\Dto\Cart_Info;
24 use SeQura\WC\Dto\Payment_Method_Data;
25 use SeQura\WC\Services\Cart\Interface_Cart_Service;
26 use SeQura\WC\Services\Payment\Interface_Payment_Service;
27 use SeQura\WC\Services\Pricing\Interface_Pricing_Service;
28 use Throwable;
29 use WC_Customer;
30 use WC_DateTime;
31 use WC_Order;
32 use WP_User;
33
34 /**
35 * Handle use cases related to Order
36 */
37 class Order_Service implements Interface_Order_Service {
38
39 private const META_KEY_METHOD_TITLE = '_sq_method_title';
40 private const META_KEY_PRODUCT = '_sq_product';
41 private const META_KEY_CAMPAIGN = '_sq_campaign';
42 private const META_KEY_CART_REF = '_sq_cart_ref';
43 private const META_KEY_CART_CREATED_AT = '_sq_cart_created_at';
44 private const META_KEY_SENT_TO_SEQURA = '_sq_sent_to_sequra';
45
46 /**
47 * Payment service
48 *
49 * @var Interface_Payment_Service
50 */
51 private $payment_service;
52
53 /**
54 * Pricing service
55 *
56 * @var Interface_Pricing_Service
57 */
58 private $pricing_service;
59
60 /**
61 * Order status service
62 *
63 * @var Order_Status_Settings_Service
64 */
65 private $order_status_service;
66
67 /**
68 * Configuration
69 *
70 * @var Configuration
71 */
72 private $configuration;
73
74 /**
75 * Cart service
76 *
77 * @var Interface_Cart_Service
78 */
79 private $cart_service;
80
81 /**
82 * Store context
83 *
84 * @var StoreContext
85 */
86 private $store_context;
87
88 /**
89 * Constructor
90 */
91 public function __construct(
92 Interface_Payment_Service $payment_service,
93 Interface_Pricing_Service $pricing_service,
94 Order_Status_Settings_Service $order_status_service,
95 Configuration $configuration,
96 Interface_Cart_Service $cart_service,
97 StoreContext $store_context
98 ) {
99 $this->payment_service = $payment_service;
100 $this->pricing_service = $pricing_service;
101 $this->order_status_service = $order_status_service;
102 $this->configuration = $configuration;
103 $this->cart_service = $cart_service;
104 $this->store_context = $store_context;
105 }
106
107 /**
108 * Get delivery method
109 */
110 public function get_delivery_method( ?WC_Order $order ): DeliveryMethod {
111
112 if ( ! $order ) {
113 $session = WC()->session;
114 $shipping_methods = $session ? WC()->session->chosen_shipping_methods : array();
115
116 if ( ! $shipping_methods || empty( WC()->shipping->get_packages() ) ) {
117 return new DeliveryMethod( 'default', null, 'default' );
118 }
119 $package = current( WC()->shipping->get_packages() );
120 $shipping_method = current( $shipping_methods );
121
122 if ( ! isset( $package['rates'][ $shipping_method ] ) ) {
123 return new DeliveryMethod( 'default', null, 'default' );
124 }
125
126 $rate = $package['rates'][ $shipping_method ];
127 return new DeliveryMethod( $rate->label, null, $rate->id );
128 }
129
130 $shipping_method = current( $order->get_shipping_methods() );
131
132 return new DeliveryMethod(
133 $shipping_method['name'] ?? 'default',
134 null,
135 $shipping_method['method_id'] ?? 'default'
136 );
137 }
138
139 /**
140 * Get client first name. If the order is null, attempt to retrieve data from the session.
141 */
142 public function get_first_name( ?WC_Order $order, $is_delivery = true ): string {
143 $prefix = $is_delivery ? 'shipping' : 'billing';
144 return $this->get_customer_field( $order, "get_{$prefix}_first_name", 'get_billing_first_name', "{$prefix}_first_name", 'first_name' );
145 }
146
147 /**
148 * Get client last name. If the order is null, attempt to retrieve data from the session.
149 */
150 public function get_last_name( ?WC_Order $order, $is_delivery = true ): string {
151 $prefix = $is_delivery ? 'shipping' : 'billing';
152 return $this->get_customer_field( $order, "get_{$prefix}_last_name", 'get_billing_last_name', "{$prefix}_last_name", 'last_name' );
153 }
154
155 /**
156 * Get client company. If the order is null, attempt to retrieve data from the session.
157 */
158 public function get_company( ?WC_Order $order, $is_delivery = true ): string {
159 $prefix = $is_delivery ? 'shipping' : 'billing';
160 return $this->get_customer_field( $order, "get_{$prefix}_company", 'get_billing_company', "{$prefix}_company", 'company' );
161 }
162
163 /**
164 * Get client address's first line. If the order is null, attempt to retrieve data from the session.
165 */
166 public function get_address_1( ?WC_Order $order, $is_delivery = true ): string {
167 $prefix = $is_delivery ? 'shipping' : 'billing';
168 return $this->get_customer_field( $order, "get_{$prefix}_address_1", 'get_billing_address_1', "{$prefix}_address_1", 'address_1' );
169 }
170
171 /**
172 * Get client address's second line. If the order is null, attempt to retrieve data from the session.
173 */
174 public function get_address_2( ?WC_Order $order, $is_delivery = true ): string {
175 $prefix = $is_delivery ? 'shipping' : 'billing';
176 return $this->get_customer_field( $order, "get_{$prefix}_address_2", 'get_billing_address_2', "{$prefix}_address_2", 'address_2' );
177 }
178
179 /**
180 * Get client postcode. If the order is null, attempt to retrieve data from the session.
181 */
182 public function get_postcode( ?WC_Order $order, $is_delivery = true ): string {
183 $prefix = $is_delivery ? 'shipping' : 'billing';
184 return $this->get_customer_field( $order, "get_{$prefix}_postcode", 'get_billing_postcode', "{$prefix}_postcode", 'postcode' );
185 }
186
187 /**
188 * Get client city. If the order is null, attempt to retrieve data from the session.
189 */
190 public function get_city( ?WC_Order $order, $is_delivery = true ): string {
191 $prefix = $is_delivery ? 'shipping' : 'billing';
192 $city = $this->get_customer_field( $order, "get_{$prefix}_city", 'get_billing_city', "{$prefix}_city", 'city' );
193 if ( ! $city ) {
194 $city = $this->get_customer_field( $order, 'get_city', 'get_city', 'city', 'city' );
195 }
196 return $city;
197 }
198
199 /**
200 * Get client country code. If the order is null, attempt to retrieve data from the session.
201 */
202 public function get_country( ?WC_Order $order, $is_delivery = true ): string {
203 $prefix = $is_delivery ? 'shipping' : 'billing';
204 return $this->get_customer_field( $order, "get_{$prefix}_country", 'get_billing_country', "{$prefix}_country", 'country' );
205 }
206
207 /**
208 * Get client state. If the order is null, attempt to retrieve data from the session.
209 */
210 public function get_state( ?WC_Order $order, $is_delivery = true ): string {
211 $prefix = $is_delivery ? 'shipping' : 'billing';
212 $state_code = $this->get_customer_field( $order, "get_{$prefix}_state", 'get_billing_state', "{$prefix}_state", 'state' );
213 if ( ! $state_code ) {
214 return '';
215 }
216 $states = WC()->countries->get_states( $this->get_country( $order ) );
217 if ( ! $states || ! isset( $states[ $state_code ] ) ) {
218 return '';
219 }
220 return $states[ $state_code ];
221 }
222
223 /**
224 * Get client phone. If the order is null, attempt to retrieve data from the session.
225 */
226 public function get_phone( ?WC_Order $order, $is_delivery = true ): string {
227 $prefix = $is_delivery ? 'shipping' : 'billing';
228 return $this->get_customer_field( $order, "get_{$prefix}_phone", 'get_billing_phone', "{$prefix}_phone", 'phone' );
229 }
230
231 /**
232 * Get client email. If the order is null, attempt to retrieve data from the session.
233 */
234 public function get_email( ?WC_Order $order ): string {
235 return $this->get_customer_field( $order, 'get_billing_email', 'get_billing_email', 'email', 'email' );
236 }
237
238 /**
239 * 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.
240 * Get shopper vat number. If the order is null, attempt to retrieve data from the session.
241 */
242 public function get_vat( ?WC_Order $order, $is_delivery = true ): string {
243 $prefix = $is_delivery ? 'shipping' : 'billing';
244 $vat = $this->get_customer_field( $order, "get_{$prefix}_nif", 'get_billing_nif', "{$prefix}_nif", 'nif' );
245 if ( ! $vat ) {
246 $vat = $this->get_customer_field( $order, 'get_nif', 'get_nif', 'nif', 'nif' );
247 }
248 if ( ! $vat ) {
249 $vat = $this->get_customer_field( $order, "get_{$prefix}_vat", 'get_billing_vat', "{$prefix}_vat", 'vat' );
250 }
251
252 return $vat;
253 }
254
255 /**
256 * Get shopper NIN number. If the order is null, attempt to retrieve data from the session.
257 */
258 public function get_nin( ?WC_Order $order ): ?string {
259 /**
260 * TODO: Document this filter
261 * Get NIN number
262 *
263 * @since 3.0.0
264 */
265 $nin = apply_filters( 'sequra_get_nin', null, $order );
266 return is_string( $nin ) || null === $nin ? $nin : null;
267 }
268
269 /**
270 * Get date of birth. If the order is null, attempt to retrieve data from the session.
271 */
272 public function get_dob( ?WC_Order $order ): ?string {
273 /**
274 * TODO: Document this filter
275 * Get Date of Birth number
276 *
277 * @since 3.0.0
278 */
279 $dob = apply_filters( 'sequra_get_dob', null, $order );
280 return is_string( $dob ) || null === $dob ? $dob : null;
281 }
282
283 /**
284 * Get shopper title. If the order is null, attempt to retrieve data from the session.
285 */
286 public function get_shopper_title( ?WC_Order $order ): ?string {
287 /**
288 * TODO: Document this filter
289 * Get Shopper title
290 *
291 * @since 3.0.0
292 */
293 $title = apply_filters( 'sequra_get_shopper_title', null, $order );
294 return is_string( $title ) || null === $title ? $title : null;
295 }
296
297 /**
298 * Get shopper created at date. If the order is null, attempt to retrieve data from the session.
299 */
300 public function get_shopper_created_at( ?WC_Order $order ): ?string {
301 /**
302 * TODO: Document this filter
303 * Get Shopper created at date
304 *
305 * @since 3.0.0
306 */
307 $date = apply_filters( 'sequra_get_shopper_created_at', $this->get_shopper_registration_date( $order ), $order );
308 return is_string( $date ) || null === $date ? $date : null;
309 }
310
311 /**
312 * Get shopper registration date
313 */
314 private function get_shopper_registration_date( ?WC_Order $order ): ?string {
315 if ( ! $order ) {
316 return null;
317 }
318 /**
319 * Order user
320 *
321 * @var WP_User $shopper
322 */
323 $shopper = get_user_by( 'id', $order->get_customer_id() );
324 if ( ! $shopper instanceof WP_User ) {
325 return null;
326 }
327 $timestamp = strtotime( $shopper->user_registered );
328 return $timestamp ? gmdate( 'c', $timestamp ) : null;
329 }
330
331 /**
332 * Get shopper updated at date. If the order is null, attempt to retrieve data from the session.
333 */
334 public function get_shopper_updated_at( ?WC_Order $order ): ?string {
335 /**
336 * TODO: Document this filter
337 * Get Shopper updated at date
338 *
339 * @since 3.0.0
340 */
341 $date = apply_filters( 'sequra_get_shopper_updated_at', $this->get_shopper_registration_date( $order ), $order );
342 return is_string( $date ) || null === $date ? $date : null;
343 }
344
345 /**
346 * Get shopper rating. If the order is null, attempt to retrieve data from the session.
347 */
348 public function get_shopper_rating( ?WC_Order $order ): ?int {
349 /**
350 * TODO: Document this filter
351 * Get Shopper rating. Must return an integer between 0 and 100 or null.
352 *
353 * @since 3.0.0
354 */
355 $rating = apply_filters( 'sequra_get_shopper_rating', null, $order );
356 return ( is_int( $rating ) && 0 <= $rating && 100 >= $rating ) || null === $rating ? $rating : null;
357 }
358
359 /**
360 * Get previous orders
361 *
362 * @return PreviousOrder[]
363 */
364 public function get_previous_orders( int $customer_id ): array {
365 $previous_orders = array();
366
367 $order_statuses = $this->order_status_service->getOrderStatusSettings();
368
369 if ( ! $order_statuses ) {
370 return $previous_orders;
371 }
372
373 $statuses = $this->order_status_service->get_shop_status_completed();
374 foreach ( $order_statuses as $order_status ) {
375 if ( $order_status->getSequraStatus() === OrderStates::STATE_APPROVED ) {
376 // Use the default status if the shop status is not set.
377 $statuses[] = empty( $order_status->getShopStatus() ) ? 'wc-processing' : $order_status->getShopStatus();
378 }
379 }
380
381 /**
382 * Get previous orders
383 *
384 * @var WC_Order[] $previous_orders
385 */
386 $orders = wc_get_orders(
387 array(
388 'limit' => -1,
389 'customer' => $customer_id,
390 'status' => $statuses,
391 )
392 );
393
394 if ( is_array( $orders ) ) {
395 foreach ( $orders as $order ) {
396 /**
397 * Order date
398 *
399 * @var WC_DateTime $date
400 */
401 $date = $order->get_date_created( 'edit' );
402 $postcode = $this->get_postcode( $order );
403 $country = $this->get_country( $order );
404
405 $previous_orders[] = new PreviousOrder(
406 $date ? $date->date( 'c' ) : '',
407 $this->pricing_service->to_cents( (float) $order->get_total( 'edit' ) ),
408 $order->get_currency(),
409 $order->get_status( 'edit' ),
410 wc_get_order_status_name( $order->get_status( 'edit' ) ),
411 $order->get_payment_method( 'edit' ),
412 $order->get_payment_method_title( 'edit' ),
413 $postcode ? $postcode : null,
414 $country ? $country : null
415 );
416 }
417 }
418
419 return $previous_orders;
420 }
421
422 /**
423 * Get customer data from order, session or POST. If not found, return an empty string.
424 */
425 private function get_customer_field(
426 ?WC_Order $order,
427 string $order_func,
428 string $order_alt_func,
429 string $session_key,
430 string $session_alt_key
431 ): string {
432 if ( ! $order ) {
433 $customer = $this->get_customer_from_session();
434 return ! empty( $customer[ $session_key ] ) ? $customer[ $session_key ] : (
435 $session_alt_key !== $session_key && ! empty( $customer[ $session_alt_key ] ) ? $customer[ $session_alt_key ] : ''
436 );
437 }
438 $value = '';
439 if ( method_exists( $order, $order_func ) ) {
440 $value = call_user_func( array( $order, $order_func ) );
441 }
442
443 if ( ! $value && $order_alt_func !== $order_func && method_exists( $order, $order_alt_func ) ) {
444 $value = call_user_func( array( $order, $order_alt_func ) );
445 }
446
447 return $value;
448 }
449
450 /**
451 * Get customer data from session. If not found, return an empty array.
452 */
453 private function get_customer_from_session(): array {
454 $data = array();
455 if ( function_exists( 'WC' ) && WC()->customer ) {
456 /**
457 * Customer instance.
458 *
459 * @var WC_Customer $customer
460 */
461 $customer = WC()->customer;
462 $data = array(
463 'email' => $customer->get_email(),
464 'billing_first_name' => $customer->get_billing_first_name(),
465 'billing_last_name' => $customer->get_billing_last_name(),
466 'billing_company' => $customer->get_billing_company(),
467 'billing_address_1' => $customer->get_billing_address_1(),
468 'billing_address_2' => $customer->get_billing_address_2(),
469 'billing_postcode' => $customer->get_billing_postcode(),
470 'billing_city' => $customer->get_billing_city(),
471 'billing_country' => $customer->get_billing_country(),
472 'billing_state' => $customer->get_billing_state(),
473 'billing_phone' => $customer->get_billing_phone(),
474 'billing_nif' => method_exists( $customer, 'get_billing_nif' ) ? $customer->get_billing_nif() : '',
475 'billing_vat' => method_exists( $customer, 'get_billing_vat' ) ? $customer->get_billing_vat() : '',
476 'shipping_first_name' => $customer->get_shipping_first_name(),
477 'shipping_last_name' => $customer->get_shipping_last_name(),
478 'shipping_company' => $customer->get_shipping_company(),
479 'shipping_address_1' => $customer->get_shipping_address_1(),
480 'shipping_address_2' => $customer->get_shipping_address_2(),
481 'shipping_postcode' => $customer->get_shipping_postcode(),
482 'shipping_city' => $customer->get_shipping_city(),
483 'shipping_country' => $customer->get_shipping_country(),
484 'shipping_state' => $customer->get_shipping_state(),
485 'shipping_phone' => $customer->get_shipping_phone(),
486 'shipping_nif' => method_exists( $customer, 'get_shipping_nif' ) ? $customer->get_shipping_nif() : '',
487 'shipping_vat' => method_exists( $customer, 'get_shipping_vat' ) ? $customer->get_shipping_vat() : '',
488 );
489 }
490 return $data;
491 }
492
493 /**
494 * Get order meta value by key from a seQura order.
495 * If the order is not a seQura order an empty string is returned.
496 */
497 private function get_order_meta( WC_Order $order, $meta_key ): string {
498 if ( $order->get_payment_method() !== $this->payment_service->get_payment_gateway_id() ) {
499 return '';
500 }
501 return strval( $order->get_meta( $meta_key, true ) );
502 }
503
504 /**
505 * Get the seQura payment method title for the order.
506 * If the order is not a seQura order an empty string is returned.
507 */
508 public function get_payment_method_title( WC_Order $order ): string {
509 return $this->get_order_meta( $order, self::META_KEY_METHOD_TITLE );
510 }
511
512 /**
513 * Get the seQura product for the order.
514 * If the value is not found an empty string is returned.
515 */
516 public function get_product( WC_Order $order ): string {
517 return $this->get_order_meta( $order, self::META_KEY_PRODUCT );
518 }
519
520 /**
521 * Get the seQura campaign for the order.
522 * If the value is not found an empty string is returned.
523 */
524 public function get_campaign( WC_Order $order ): string {
525 return $this->get_order_meta( $order, self::META_KEY_CAMPAIGN );
526 }
527
528 /**
529 * Get the seQura cart info for the order.
530 * If the value is not found null is returned.
531 */
532 public function get_cart_info( WC_Order $order ): ?Cart_Info {
533 return Cart_Info::from_array(
534 array(
535 'ref' => $this->get_order_meta( $order, self::META_KEY_CART_REF ),
536 'created_at' => $this->get_order_meta( $order, self::META_KEY_CART_CREATED_AT ),
537 )
538 );
539 }
540
541 /**
542 * Get IPN webhook identifier
543 */
544 public function get_ipn_url( WC_Order $order, string $store_id ): string {
545 return add_query_arg(
546 array(
547 'order' => strval( $order->get_id() ),
548 'wc-api' => $this->payment_service->get_ipn_webhook(),
549 'store_id' => $store_id,
550 ),
551 home_url( '/' )
552 );
553 }
554
555 /**
556 * Get payment gateway webhook identifier
557 */
558 public function get_event_url( WC_Order $order, string $store_id ): string {
559 return add_query_arg(
560 array(
561 'order' => strval( $order->get_id() ),
562 'wc-api' => $this->payment_service->get_event_webhook(),
563 'store_id' => $store_id,
564 ),
565 home_url( '/' )
566 );
567 }
568
569 /**
570 * Get payment gateway webhook identifier
571 */
572 public function get_return_url( WC_Order $order ): string {
573 return add_query_arg(
574 array(
575 'order' => strval( $order->get_id() ),
576 'sq_product' => 'SQ_PRODUCT_CODE',
577 'wc-api' => $this->payment_service->get_return_webhook(),
578 ),
579 home_url( '/' )
580 );
581 }
582
583 /**
584 * Save required metadata for the order.
585 * Returns true if the metadata was saved, false otherwise.
586 */
587 public function set_order_metadata( WC_Order $order, ?Payment_Method_Data $dto, ?Cart_Info $cart_info ): bool {
588 if ( ! $dto ) {
589 return false;
590 }
591
592 if ( ! $cart_info ) {
593 return false;
594 }
595
596 $order->update_meta_data( self::META_KEY_PRODUCT, $dto->product );
597 if ( ! empty( $dto->campaign ) ) {
598 $order->update_meta_data( self::META_KEY_CAMPAIGN, $dto->campaign );
599 } else {
600 $order->delete_meta_data( self::META_KEY_CAMPAIGN );
601 }
602 $order->update_meta_data( self::META_KEY_METHOD_TITLE, $dto->title );
603
604 $order->update_meta_data( self::META_KEY_CART_REF, $cart_info->ref );
605 $order->update_meta_data( self::META_KEY_CART_CREATED_AT, $cart_info->created_at );
606
607 $order->save();
608 return true;
609 }
610
611 /**
612 * Set cart info if it is not already set
613 */
614 public function create_cart_info( WC_Order $order ): ?Cart_Info {
615 $cart_info = $this->get_cart_info( $order );
616 if ( $cart_info && $cart_info->ref ) {
617 // Skip if the cart info is already set.
618 return null;
619 }
620
621 $date = $order->get_date_created();
622 $cart_info = new Cart_Info( null, $date ? $date->date( 'c' ) : null );
623 $order->update_meta_data( self::META_KEY_CART_REF, $cart_info->ref );
624 $order->update_meta_data( self::META_KEY_CART_CREATED_AT, $cart_info->created_at );
625 $order->save();
626
627 return $cart_info;
628 }
629
630 /**
631 * Get the meta key used to store the sent to seQura value.
632 */
633 public function get_sent_to_sequra_meta_key(): string {
634 return self::META_KEY_SENT_TO_SEQURA;
635 }
636
637 /**
638 * Set the order as sent to seQura
639 */
640 public function set_as_sent_to_sequra( WC_Order $order ): void {
641 $order->update_meta_data( self::META_KEY_SENT_TO_SEQURA, 1 );
642 $order->save();
643 }
644
645 /**
646 * Get customer for the order
647 */
648 public function get_customer( ?WC_Order $order, string $lang, int $fallback_user_id = 0, string $fallback_ip = '', string $fallback_user_agent = '' ): Customer {
649 $current_user_id = $order ? $order->get_customer_id() : $fallback_user_id;
650 $logged_in = $current_user_id > 0;
651 $ref = $logged_in ? $current_user_id : null;
652 $ip = $order ? $order->get_customer_ip_address( 'edit' ) : $fallback_ip;
653 $user_agent = $order ? $order->get_customer_user_agent( 'edit' ) : $fallback_user_agent;
654
655 return new Customer(
656 $this->get_email( $order ),
657 $lang,
658 $ip,
659 $user_agent,
660 $this->get_first_name( $order, true ),
661 $this->get_last_name( $order, true ),
662 $this->get_shopper_title( $order ), // title.
663 $ref,
664 $this->get_dob( $order ), // dateOfBirth.
665 $this->get_nin( $order ), // nin.
666 $this->get_company( $order, true ),
667 $this->get_vat( $order, true ), // vatNumber.
668 $this->get_shopper_created_at( $order, true ), // createdAt.
669 $this->get_shopper_updated_at( $order, true ), // updatedAt.
670 $this->get_shopper_rating( $order ), // rating.
671 null, // ninControl.
672 $this->get_previous_orders( $current_user_id ),
673 null, // vehicle.
674 $logged_in
675 );
676 }
677
678 /**
679 * Get delivery or invoice address
680 */
681 public function get_address( ?WC_Order $order, bool $is_delivery ): Address {
682 $country = $this->get_country( $order, $is_delivery );
683 return new Address(
684 $this->get_company( $order, $is_delivery ),
685 $this->get_address_1( $order, $is_delivery ),
686 $this->get_address_2( $order, $is_delivery ),
687 $this->get_postcode( $order, $is_delivery ),
688 $this->get_city( $order, $is_delivery ),
689 $country ? $country : 'ES',
690 $this->get_first_name( $order, $is_delivery ),
691 $this->get_last_name( $order, $is_delivery ),
692 null, // phone.
693 $this->get_phone( $order, $is_delivery ), // mobile phone.
694 $this->get_state( $order, $is_delivery ),
695 $order ? $order->get_customer_note( 'edit' ) : null, // extra.
696 $this->get_vat( $order, $is_delivery )
697 );
698 }
699
700 /**
701 * Call the Order Update API to sync the order status with SeQura
702 *
703 * @throws Throwable
704 */
705 public function update_sequra_order_status( WC_Order $order, string $old_store_status, string $new_store_status ): void {
706 if ( in_array( $new_store_status, $this->order_status_service->get_shop_status_completed( true ), true ) ) {
707 $this->set_sequra_order_status_to_shipped( $order );
708 }
709 }
710
711 /**
712 * Set the order status to shipped in SeQura
713 *
714 * @throws Throwable
715 */
716 private function set_sequra_order_status_to_shipped( WC_Order $order ): void {
717 $cart_info = $this->get_cart_info( $order );
718 $currency = $order->get_currency( 'edit' );
719 $cart_ref = $cart_info ? $cart_info->ref : null;
720 $created_at = $cart_info ? $cart_info->created_at : null;
721 $updated_at = $order->get_date_completed()->format( 'Y-m-d H:i:s' );
722 $shipped_items = array_merge(
723 $this->cart_service->get_items( $order ),
724 $this->cart_service->get_handling_items( $order ),
725 $this->cart_service->get_discount_items( $order ),
726 $this->cart_service->get_refund_items( $order )
727 );
728
729 try {
730 $this->call_update_order(
731 new OrderUpdateData(
732 (string) $order->get_id(), // Order reference.
733 new Cart( $currency, false, $shipped_items, $cart_ref, $created_at, $updated_at ), // Shipped cart.
734 new Cart( $currency ), // Unshipped cart.
735 null, // Delivery address.
736 null // Invoice address.
737 )
738 );
739 } catch ( Throwable $e ) {
740 throw $e;
741 }
742 }
743
744 /**
745 * Get a fresh instance of the core order service
746 *
747 * @param OrderUpdateData $order_data Order data
748 *
749 * @throws Exception
750 */
751 private function call_update_order( $order_data ) {
752 $store_id = $this->configuration->get_store_id();
753 /**
754 * Order service
755 *
756 * @var OrderService $order_service
757 */
758 $order_service = $this->store_context::doWithStore( $store_id, 'SeQura\Core\Infrastructure\ServiceRegister::getService', array( OrderService::class ) );
759 $this->store_context::doWithStore( $store_id, array( $order_service, 'updateOrder' ), array( $order_data ) );
760 }
761
762 /**
763 * Update the order amount in SeQura after a refund
764 *
765 * @throws Throwable
766 */
767 public function handle_refund( WC_Order $order, float $amount ): void {
768 $cart_info = $this->get_cart_info( $order );
769 $currency = $order->get_currency( 'edit' );
770 $cart_ref = $cart_info ? $cart_info->ref : null;
771 $created_at = $cart_info ? $cart_info->created_at : null;
772 $updated_at = $order->get_date_completed()->format( 'Y-m-d H:i:s' );
773 $shipped_items = array();
774 if ( $order->get_total( 'edit' ) > $amount ) {
775 $shipped_items = array_merge(
776 $this->cart_service->get_items( $order ),
777 $this->cart_service->get_handling_items( $order ),
778 $this->cart_service->get_discount_items( $order ),
779 $this->cart_service->get_refund_items( $order )
780 );
781 }
782
783 try {
784 $this->call_update_order(
785 new OrderUpdateData(
786 (string) $order->get_id(), // Order reference.
787 new Cart( $currency, false, $shipped_items, $cart_ref, $created_at, $updated_at ), // Shipped cart.
788 new Cart( $currency ), // Unshipped cart.
789 null, // Delivery address.
790 null // Invoice address.
791 )
792 );
793 } catch ( Throwable $e ) {
794 throw $e;
795 }
796 }
797
798 /**
799 * Get the link to the SeQura back office for the order
800 */
801 public function get_link_to_sequra_back_office( WC_Order $order ): ?string {
802 if ( $order->get_payment_method() !== $this->payment_service->get_payment_gateway_id() ) {
803 return null;
804 }
805
806 switch ( $this->configuration->get_env() ) {
807 case 'sandbox':
808 return 'https://simbox.sequrapi.com/orders/' . $order->get_transaction_id();
809 case 'live':
810 return 'https://simba.sequra.es/orders/' . $order->get_transaction_id();
811 default:
812 return null;
813 }
814 }
815 }
816