PluginProbe
Packeta / 1.2.6
Packeta v1.2.6
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 / Checkout.php

Checkout.php in Packeta 1.2.6, at src/Packetery/Module/Checkout.php

755 lines 21.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Packeta plugin class for checkout.
4 *
5 * @package Packetery
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module;
11
12 use Packetery\Core;
13 use Packetery\Module\Options\Provider;
14 use PacketeryLatte\Engine;
15 use PacketeryNette\Http\Request;
16
17 /**
18 * Class Checkout
19 *
20 * @package Packetery
21 */
22 class Checkout {
23
24 public const CARRIER_PREFIX = 'packetery_carrier_';
25 private const NONCE_ACTION = 'packetery_checkout';
26
27 const ATTR_POINT_ID = 'packetery_point_id';
28 const ATTR_POINT_NAME = 'packetery_point_name';
29 const ATTR_POINT_CITY = 'packetery_point_city';
30 const ATTR_POINT_ZIP = 'packetery_point_zip';
31 const ATTR_POINT_STREET = 'packetery_point_street';
32 const ATTR_POINT_PLACE = 'packetery_point_place'; // Business name of pickup point.
33 const ATTR_CARRIER_ID = 'packetery_carrier_id';
34 const ATTR_POINT_URL = 'packetery_point_url';
35
36 /**
37 * Pickup point attributes configuration.
38 *
39 * @var array[]
40 */
41 public static $pickupPointAttrs = array(
42 'id' => array(
43 'name' => self::ATTR_POINT_ID,
44 'required' => true,
45 ),
46 'name' => array(
47 'name' => self::ATTR_POINT_NAME,
48 'required' => true,
49 ),
50 'city' => array(
51 'name' => self::ATTR_POINT_CITY,
52 'required' => true,
53 ),
54 'zip' => array(
55 'name' => self::ATTR_POINT_ZIP,
56 'required' => true,
57 ),
58 'street' => array(
59 'name' => self::ATTR_POINT_STREET,
60 'required' => true,
61 ),
62 'place' => array(
63 'name' => self::ATTR_POINT_PLACE,
64 'required' => false,
65 ),
66 'carrierId' => array(
67 'name' => self::ATTR_CARRIER_ID,
68 'required' => false,
69 ),
70 'url' => array(
71 'name' => self::ATTR_POINT_URL,
72 'required' => true,
73 ),
74 );
75
76 /**
77 * Home delivery attributes configuration.
78 *
79 * @var array[]
80 */
81 private static $homeDeliveryAttrs = [
82 'isValidated' => [
83 'name' => 'packetery_address_isValidated', // Name of checkout hidden form field. Must be unique in entire form.
84 'isWidgetResultField' => false, // Is attribute included in widget result address? By default, it is.
85 ],
86 'houseNumber' => [ // post type address field called 'houseNumber'.
87 'name' => 'packetery_address_houseNumber',
88 ],
89 'street' => [
90 'name' => 'packetery_address_street',
91 ],
92 'city' => [
93 'name' => 'packetery_address_city',
94 ],
95 'postCode' => [
96 'name' => 'packetery_address_postCode',
97 'widgetResultField' => 'postcode', // Widget returns address object containing specified field. By default, it is the array key 'postCode', but in this case it is 'postcode'.
98 ],
99 'county' => [
100 'name' => 'packetery_address_county',
101 ],
102 'country' => [
103 'name' => 'packetery_address_country',
104 ],
105 'latitude' => [
106 'name' => 'packetery_address_latitude',
107 ],
108 'longitude' => [
109 'name' => 'packetery_address_longitude',
110 ],
111 ];
112
113 /**
114 * PacketeryLatte engine
115 *
116 * @var Engine
117 */
118 private $latte_engine;
119
120 /**
121 * Options provider.
122 *
123 * @var Provider Options provider.
124 */
125 private $options_provider;
126
127 /**
128 * Carrier repository.
129 *
130 * @var Carrier\Repository Carrier repository.
131 */
132 private $carrierRepository;
133
134 /**
135 * Http request.
136 *
137 * @var Request Http request.
138 */
139 private $httpRequest;
140
141 /**
142 * Order repository.
143 *
144 * @var Order\Repository
145 */
146 private $orderRepository;
147
148 /**
149 * Checkout constructor.
150 *
151 * @param Engine $latte_engine PacketeryLatte engine.
152 * @param Provider $options_provider Options provider.
153 * @param Carrier\Repository $carrierRepository Carrier repository.
154 * @param Request $httpRequest Http request.
155 * @param Order\Repository $orderRepository Order repository.
156 */
157 public function __construct(
158 Engine $latte_engine,
159 Provider $options_provider,
160 Carrier\Repository $carrierRepository,
161 Request $httpRequest,
162 Order\Repository $orderRepository
163 ) {
164 $this->latte_engine = $latte_engine;
165 $this->options_provider = $options_provider;
166 $this->carrierRepository = $carrierRepository;
167 $this->httpRequest = $httpRequest;
168 $this->orderRepository = $orderRepository;
169 }
170
171 /**
172 * Check if chosen shipping rate is bound with Packeta pickup points
173 *
174 * @return bool
175 */
176 public function isPickupPointOrder(): bool {
177 $chosenMethod = $this->getChosenMethod();
178 $carrierId = $this->getCarrierId( $chosenMethod );
179
180 return $carrierId && $this->carrierRepository->isPickupPointCarrier( $carrierId );
181 }
182
183 /**
184 * Check if chosen shipping rate is bound with Packeta home delivery
185 *
186 * @return bool
187 */
188 public function isHomeDeliveryOrder(): bool {
189 $chosenMethod = $this->getChosenMethod();
190 $carrierId = $this->getCarrierId( $chosenMethod );
191
192 return $carrierId && $this->carrierRepository->isHomeDeliveryCarrier( $carrierId );
193 }
194
195 /**
196 * Renders widget button and information about chosen pickup point
197 */
198 public function renderWidgetButton(): void {
199 $this->latte_engine->render(
200 PACKETERY_PLUGIN_DIR . '/template/checkout/widget-button.latte',
201 [
202 'logo' => plugin_dir_url( PACKETERY_PLUGIN_DIR . '/packeta.php' ) . 'public/packeta-symbol.png',
203 ]
204 );
205 }
206
207 /**
208 * Gets widget carriers param.
209 *
210 * @param bool $isPickupPoints Is context pickup point related.
211 * @param string $carrierId Carrier id.
212 *
213 * @return string|null
214 */
215 public static function getWidgetCarriersParam( bool $isPickupPoints, string $carrierId ): ?string {
216 if ( $isPickupPoints ) {
217 return ( is_numeric( $carrierId ) ? $carrierId : Carrier\Repository::INTERNAL_PICKUP_POINTS_ID );
218 }
219
220 return null;
221 }
222
223 /**
224 * Renders main checkout script
225 */
226 public function render_after_checkout_form(): void {
227 $carrierConfig = [];
228 $carriers = $this->carrierRepository->getAllIncludingZpoints();
229
230 foreach ( $carriers as $carrier ) {
231 $optionId = self::CARRIER_PREFIX . $carrier['id'];
232 $carrierConfig[ $optionId ] = [
233 'id' => $carrier['id'],
234 'is_pickup_points' => $carrier['is_pickup_points'],
235 ];
236
237 if ( $carrier['is_pickup_points'] ) {
238 $carrierConfig[ $optionId ]['carriers'] = self::getWidgetCarriersParam( (bool) $carrier['is_pickup_points'], (string) $carrier['id'] );
239 }
240
241 if ( ! $carrier['is_pickup_points'] ) {
242 $carrierOption = get_option( $optionId );
243
244 $addressValidation = 'none';
245 if ( $carrierOption ) {
246 $addressValidation = ( $carrierOption['address_validation'] ?? $addressValidation );
247 }
248
249 $carrierConfig[ $optionId ]['address_validation'] = $addressValidation;
250 }
251 }
252
253 $this->latte_engine->render(
254 PACKETERY_PLUGIN_DIR . '/template/checkout/init.latte',
255 [
256 'settings' => [
257 'language' => substr( get_locale(), 0, 2 ),
258 'country' => $this->getCustomerCountry(),
259 'weight' => $this->getCartWeightKg(),
260 'carrierConfig' => $carrierConfig,
261 'pickupPointAttrs' => self::$pickupPointAttrs,
262 'homeDeliveryAttrs' => self::$homeDeliveryAttrs,
263 'appIdentity' => Plugin::getAppIdentity(),
264 'packeteryApiKey' => $this->options_provider->get_api_key(),
265 'translations' => [
266 'choosePickupPoint' => __( 'choosePickupPoint', 'packetery' ),
267 'chooseAddress' => __( 'checkShippingAddress', 'packetery' ),
268 'addressValidationIsOutOfOrder' => __( 'addressValidationIsOutOfOrder', 'packetery' ),
269 'invalidAddressCountrySelected' => __( 'invalidAddressCountrySelected', 'packetery' ),
270 'selectedShippingAddress' => __( 'selectedShippingAddress', 'packetery' ),
271 'addressIsValidated' => __( 'addressIsValidated', 'packetery' ),
272 'addressIsNotValidated' => __( 'addressIsNotValidated', 'packetery' ),
273 'addressIsNotValidatedAndRequiredByCarrier' => __( 'addressIsNotValidatedAndRequiredByCarrier', 'packetery' ),
274 ],
275 ],
276 ]
277 );
278 }
279
280 /**
281 * Adds fields to checkout page to save the values later
282 */
283 public function addPickupPointFields(): void {
284 $this->latte_engine->render(
285 PACKETERY_PLUGIN_DIR . '/template/checkout/input_fields.latte',
286 [ 'fields' => array_merge( array_column( self::$pickupPointAttrs, 'name' ), array_column( self::$homeDeliveryAttrs, 'name' ) ) ]
287 );
288
289 wp_nonce_field( self::NONCE_ACTION );
290 }
291
292 /**
293 * Checks if all pickup point attributes are set, sets an error otherwise.
294 */
295 public function validateCheckoutData(): void {
296 $post = $this->httpRequest->getPost();
297 if ( ! wp_verify_nonce( $post['_wpnonce'], self::NONCE_ACTION ) ) {
298 wp_nonce_ays( '' );
299 }
300
301 if ( $this->isPickupPointOrder() ) {
302 $error = false;
303 $required_attrs = array_filter(
304 array_combine(
305 array_column( self::$pickupPointAttrs, 'name' ),
306 array_column( self::$pickupPointAttrs, 'required' )
307 )
308 );
309 foreach ( $required_attrs as $attr => $required ) {
310 $attr_value = null;
311 if ( isset( $post[ $attr ] ) ) {
312 $attr_value = $post[ $attr ];
313 }
314 if ( ! $attr_value ) {
315 $error = true;
316 }
317 }
318 $carrierId = null;
319 if ( isset( $post['carrier_id'] ) ) {
320 $carrierId = $post['carrier_id'];
321 }
322 $pointCarrierId = null;
323 if ( isset( $post['point_carrier_id'] ) ) {
324 $pointCarrierId = $post['point_carrier_id'];
325 }
326 if ( $carrierId && ! $pointCarrierId ) {
327 $error = true;
328 }
329 if ( ! $carrierId && $pointCarrierId ) {
330 $error = true;
331 }
332 if ( $error ) {
333 wc_add_notice( __( 'Pick up point is not chosen.', 'packetery' ), 'error' );
334 }
335 }
336
337 if ( $this->isHomeDeliveryOrder() ) {
338 $chosenMethod = $this->getChosenMethod();
339 $carrierId = $this->getCarrierId( $chosenMethod );
340 $optionId = self::CARRIER_PREFIX . $carrierId;
341 $carrierOption = get_option( $optionId );
342
343 $addressValidation = 'none';
344 if ( $carrierOption ) {
345 $addressValidation = ( $carrierOption['address_validation'] ?? $addressValidation );
346 }
347
348 if (
349 'required' === $addressValidation &&
350 (
351 ! isset( $post[ self::$homeDeliveryAttrs['isValidated']['name'] ] ) ||
352 '1' !== $post[ self::$homeDeliveryAttrs['isValidated']['name'] ]
353 )
354 ) {
355 wc_add_notice( __( 'shippingAddressIsNotValidated', 'packetery' ), 'error' );
356 }
357 }
358 }
359
360 /**
361 * Saves pickup point and other Packeta information to order.
362 *
363 * @param int $orderId Order id.
364 *
365 * @throws \WC_Data_Exception When invalid data are passed during shipping address update.
366 */
367 public function updateOrderMeta( int $orderId ): void {
368 $chosenMethod = $this->getChosenMethod();
369 if ( false === $this->isPacketeryOrder( $chosenMethod ) ) {
370 return;
371 }
372
373 $post = $this->httpRequest->getPost();
374
375 $propsToSave = [];
376 // Save carrier id for home delivery (we got no id from widget).
377 $carrierId = $this->getCarrierId( $chosenMethod );
378 if ( empty( $post[ self::ATTR_CARRIER_ID ] ) && $carrierId ) {
379 $propsToSave[ self::ATTR_CARRIER_ID ] = $carrierId;
380 }
381
382 if ( $this->isPickupPointOrder() ) {
383 $wcOrder = wc_get_order( $orderId );
384 if ( ! $wcOrder instanceof \WC_Order ) {
385 return;
386 }
387
388 foreach ( self::$pickupPointAttrs as $attr ) {
389 $attrName = $attr['name'];
390 if ( ! isset( $post[ $attrName ] ) ) {
391 continue;
392 }
393 $attrValue = $post[ $attrName ];
394
395 $saveMeta = true;
396 if (
397 ( self::ATTR_CARRIER_ID === $attrName && ! $attrValue ) ||
398 ( self::ATTR_POINT_URL === $attrName && ! filter_var( $attrValue, FILTER_VALIDATE_URL ) )
399 ) {
400 $saveMeta = false;
401 }
402 if ( $saveMeta ) {
403 $propsToSave[ $attrName ] = $attrValue;
404 }
405
406 if ( $this->options_provider->replaceShippingAddressWithPickupPointAddress() ) {
407 self::updateShippingAddressProperty( $wcOrder, $attrName, (string) $attrValue );
408 }
409 }
410 $wcOrder->save();
411 }
412
413 $orderEntity = new Core\Entity\Order( (string) $orderId, $carrierId );
414 if (
415 isset( $post[ self::$homeDeliveryAttrs['isValidated']['name'] ] ) &&
416 '1' === $post[ self::$homeDeliveryAttrs['isValidated']['name'] ] &&
417 $this->isHomeDeliveryOrder()
418 ) {
419 $validatedAddress = new Core\Entity\Address(
420 $post[ self::$homeDeliveryAttrs['street']['name'] ],
421 $post[ self::$homeDeliveryAttrs['city']['name'] ],
422 $post[ self::$homeDeliveryAttrs['postCode']['name'] ]
423 );
424 $validatedAddress->setCounty( $post[ self::$homeDeliveryAttrs['county']['name'] ] );
425 $validatedAddress->setHouseNumber( $post[ self::$homeDeliveryAttrs['houseNumber']['name'] ] );
426 $validatedAddress->setLatitude( $post[ self::$homeDeliveryAttrs['latitude']['name'] ] );
427 $validatedAddress->setLongitude( $post[ self::$homeDeliveryAttrs['longitude']['name'] ] );
428
429 $orderEntity->setDeliveryAddress( $validatedAddress );
430 $orderEntity->setAddressValidated( true );
431 }
432
433 self::updateOrderEntityFromPropsToSave( $orderEntity, $propsToSave );
434 $this->orderRepository->save( $orderEntity );
435 }
436
437 /**
438 * Updates order entity from props to save-
439 *
440 * @param Core\Entity\Order $orderEntity Order entity.
441 * @param array $propsToSave Props to save.
442 *
443 * @return void
444 */
445 public static function updateOrderEntityFromPropsToSave( Core\Entity\Order $orderEntity, array $propsToSave ): void {
446 $orderEntityPickupPoint = $orderEntity->getPickupPoint();
447 if ( null === $orderEntityPickupPoint ) {
448 $orderEntityPickupPoint = new Core\Entity\PickupPoint();
449 }
450
451 foreach ( $propsToSave as $attrName => $attrValue ) {
452 switch ( $attrName ) {
453 case self::ATTR_CARRIER_ID:
454 $orderEntity->setCarrierId( $attrValue );
455 break;
456 case self::ATTR_POINT_ID:
457 $orderEntityPickupPoint->setId( $attrValue );
458 break;
459 case self::ATTR_POINT_NAME:
460 $orderEntityPickupPoint->setName( $attrValue );
461 break;
462 case self::ATTR_POINT_URL:
463 $orderEntityPickupPoint->setUrl( $attrValue );
464 break;
465 case self::ATTR_POINT_STREET:
466 $orderEntityPickupPoint->setStreet( $attrValue );
467 break;
468 case self::ATTR_POINT_ZIP:
469 $orderEntityPickupPoint->setZip( $attrValue );
470 break;
471 case self::ATTR_POINT_CITY:
472 $orderEntityPickupPoint->setCity( $attrValue );
473 break;
474 }
475 }
476
477 $orderEntity->setPickupPoint( $orderEntityPickupPoint );
478 }
479
480 /**
481 * Registers Packeta checkout hooks
482 */
483 public function register_hooks(): void {
484 add_action( 'woocommerce_review_order_before_payment', array( $this, 'renderWidgetButton' ) );
485 add_action( 'woocommerce_after_checkout_form', array( $this, 'render_after_checkout_form' ) );
486 add_action( 'woocommerce_after_order_notes', array( $this, 'addPickupPointFields' ) );
487 add_action( 'woocommerce_checkout_process', array( $this, 'validateCheckoutData' ) );
488 add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'updateOrderMeta' ) );
489 add_action( 'woocommerce_review_order_before_shipping', array( $this, 'updateShippingRates' ), 10, 2 );
490 add_action( 'woocommerce_cart_calculate_fees', [ $this, 'calculateFees' ] );
491 }
492
493 /**
494 * Updates shipping rates cost based on cart properties.
495 */
496 public function updateShippingRates(): void {
497 $customRates = $this->getShippingRates();
498
499 $packages = WC()->shipping()->get_packages();
500 foreach ( $packages as $i => $package ) {
501 if ( ! empty( $package['rates'] ) ) {
502 foreach ( $package['rates'] as $key => $rate ) {
503 if ( isset( $customRates[ $rate->get_id() ] ) ) {
504 $rate->set_cost( $customRates[ $rate->get_id() ]['cost'] );
505 WC()->shipping->packages[ $i ]['rates'][ $key ] = $rate;
506 }
507 }
508 }
509 }
510 }
511
512 /**
513 * Gets customer country from WC cart.
514 *
515 * @return string
516 */
517 public function getCustomerCountry(): string {
518 $country = strtolower( WC()->customer->get_shipping_country() );
519 if ( ! $country ) {
520 $country = strtolower( WC()->customer->get_billing_country() );
521 }
522
523 return $country;
524 }
525
526 /**
527 * Gets cart contents weight in kg.
528 *
529 * @return float|int
530 */
531 public function getCartWeightKg() {
532 $weight = WC()->cart->cart_contents_weight;
533 $weightKg = wc_get_weight( $weight, 'kg' );
534 if ( $weightKg ) {
535 $weightKg += $this->options_provider->getPackagingWeight();
536 }
537
538 return $weightKg;
539 }
540
541 /**
542 * Calculates fees.
543 *
544 * @return void
545 */
546 public function calculateFees(): void {
547 $chosenShippingMethod = $this->getChosenMethod();
548 if ( false === $this->isPacketeryOrder( $chosenShippingMethod ) ) {
549 return;
550 }
551
552 $carrierOptions = get_option( $chosenShippingMethod );
553 if ( ! $carrierOptions ) {
554 return;
555 }
556
557 $isCod = false;
558 $codPaymentMethod = $this->options_provider->getCodPaymentMethod();
559 $chosenPaymentMethod = WC()->session->get( 'chosen_payment_method' );
560 if ( null !== $codPaymentMethod && ! empty( $chosenPaymentMethod ) && $chosenPaymentMethod === $codPaymentMethod ) {
561 $isCod = true;
562 }
563
564 if ( false === $isCod ) {
565 return;
566 }
567
568 $applicableSurcharge = $this->getCODSurcharge( $carrierOptions, $this->getCartPrice() );
569 if ( 0 >= $applicableSurcharge ) {
570 return;
571 }
572
573 $fee = [
574 'id' => 'packetery-cod-surcharge',
575 'name' => __( 'codSurcharge', 'packetery' ),
576 'amount' => $applicableSurcharge,
577 ];
578
579 WC()->cart->fees_api()->add_fee( $fee );
580 }
581
582 /**
583 * Gets cart price. Value is cast to float because PHPDoc is not reliable.
584 *
585 * @return float
586 */
587 private function getCartPrice(): float {
588 return (float) WC()->cart->get_subtotal();
589 }
590
591 /**
592 * Prepare shipping rates based on cart properties.
593 *
594 * @return array
595 */
596 public function getShippingRates(): array {
597 $customerCountry = $this->getCustomerCountry();
598 $availableCarriers = $this->carrierRepository->getByCountryIncludingZpoints( $customerCountry );
599 $carrierOptions = [];
600 foreach ( $availableCarriers as $carrier ) {
601 $optionId = self::CARRIER_PREFIX . $carrier->getId();
602 $carrierOptions[ $optionId ] = get_option( $optionId );
603 }
604
605 $cartPrice = $this->getCartPrice();
606 $cartWeight = $this->getCartWeightKg();
607
608 $customRates = [];
609 foreach ( $carrierOptions as $optionId => $options ) {
610 if ( is_array( $options ) && true === $options['active'] ) {
611 $cost = $this->getRateCost( $options, $cartPrice, $cartWeight );
612 if ( null !== $cost ) {
613 $customRates[ $optionId ] = [
614 'label' => $options['name'],
615 'id' => $optionId,
616 'cost' => $cost,
617 'taxes' => '',
618 'calc_tax' => 'per_order',
619 ];
620 }
621 }
622 }
623
624 return $customRates;
625 }
626
627 /**
628 * Computes custom rate cost for carrier using cart contents.
629 *
630 * @param array $carrierOptions Carrier options.
631 * @param float $cartPrice Price.
632 * @param float|int $cartWeight Weight.
633 *
634 * @return int|float|null
635 */
636 private function getRateCost( array $carrierOptions, float $cartPrice, $cartWeight ) {
637 $cost = null;
638
639 foreach ( $carrierOptions['weight_limits'] as $weightLimit ) {
640 if ( $cartWeight <= $weightLimit['weight'] ) {
641 $cost = $weightLimit['price'];
642 break;
643 }
644 }
645
646 if ( null === $cost ) {
647 return null;
648 }
649
650 if ( $carrierOptions['free_shipping_limit'] && $cartPrice >= $carrierOptions['free_shipping_limit'] ) {
651 $cost = 0;
652 }
653
654 return $cost;
655 }
656
657 /**
658 * Gets applicable COD surcharge.
659 *
660 * @param array $carrierOptions Carrier options.
661 * @param float $cartPrice Cart price.
662 *
663 * @return float
664 */
665 private function getCODSurcharge( array $carrierOptions, float $cartPrice ): float {
666 if ( isset( $carrierOptions['surcharge_limits'] ) ) {
667 foreach ( $carrierOptions['surcharge_limits'] as $weightLimit ) {
668 if ( $cartPrice <= $weightLimit['order_price'] ) {
669 return (float) $weightLimit['surcharge'];
670 }
671 }
672 }
673
674 if ( isset( $carrierOptions['default_COD_surcharge'] ) && is_numeric( $carrierOptions['default_COD_surcharge'] ) ) {
675 return (float) $carrierOptions['default_COD_surcharge'];
676 }
677
678 return 0.0;
679 }
680
681 /**
682 * Get chosen shipping rate id.
683 *
684 * @return string
685 */
686 private function getChosenMethod(): string {
687 $chosenShippingRates = WC()->cart->calculate_shipping();
688 $chosenShippingRate = ( $chosenShippingRates[0] ?? null );
689
690 if ( $chosenShippingRate instanceof \WC_Shipping_Rate ) {
691 return $chosenShippingRate->get_id();
692 }
693
694 return '';
695 }
696
697 /**
698 * Gets carrier id from chosen shipping method.
699 *
700 * @param string $chosenMethod Chosen shipping method.
701 *
702 * @return string|null
703 */
704 public function getCarrierId( string $chosenMethod ): ?string {
705 if ( ! $this->isPacketeryOrder( $chosenMethod ) ) {
706 return null;
707 }
708
709 $carrierId = str_replace( self::CARRIER_PREFIX, '', $chosenMethod );
710 if ( strpos( $carrierId, 'zpoint' ) === 0 ) {
711 return Carrier\Repository::INTERNAL_PICKUP_POINTS_ID;
712 }
713
714 return $carrierId;
715 }
716
717
718 /**
719 * Checks if chosen shipping method is one of packetery.
720 *
721 * @param string $chosenMethod Chosen shipping method.
722 *
723 * @return bool
724 */
725 private function isPacketeryOrder( string $chosenMethod ): bool {
726 return ( strpos( $chosenMethod, self::CARRIER_PREFIX ) === 0 );
727 }
728
729 /**
730 * Update order shipping.
731 *
732 * @param \WC_Order $wcOrder WC Order.
733 * @param string $attributeName Attribute name.
734 * @param string $value Value.
735 *
736 * @return void
737 * @throws \WC_Data_Exception When shipping input is invalid.
738 */
739 public static function updateShippingAddressProperty( \WC_Order $wcOrder, string $attributeName, string $value ): void {
740 if ( self::ATTR_POINT_STREET === $attributeName ) {
741 $wcOrder->set_shipping_address_1( $value );
742 $wcOrder->set_shipping_address_2( '' );
743 }
744 if ( self::ATTR_POINT_PLACE === $attributeName ) {
745 $wcOrder->set_shipping_company( $value );
746 }
747 if ( self::ATTR_POINT_CITY === $attributeName ) {
748 $wcOrder->set_shipping_city( $value );
749 }
750 if ( self::ATTR_POINT_ZIP === $attributeName ) {
751 $wcOrder->set_shipping_postcode( $value );
752 }
753 }
754 }
755