PluginProbe
Packeta / 2.0.9
Packeta v2.0.9
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 / Checkout.php

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

347 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare( strict_types=1 );
4
5 namespace Packetery\Module\Checkout;
6
7 use Packetery\Core\Entity;
8 use Packetery\Module\Carrier;
9 use Packetery\Module\Carrier\CarrierOptionsFactory;
10 use Packetery\Module\Exception\ProductNotFoundException;
11 use Packetery\Module\Framework\WcAdapter;
12 use Packetery\Module\Framework\WpAdapter;
13 use Packetery\Module\Options\OptionsProvider;
14 use Packetery\Module\Order;
15 use Packetery\Module\Payment\PaymentHelper;
16 use WC_Cart;
17 use WC_Payment_Gateway;
18
19 class Checkout {
20
21 /**
22 * @var WpAdapter
23 */
24 private $wpAdapter;
25
26 /**
27 * @var WcAdapter
28 */
29 private $wcAdapter;
30
31 /**
32 * @var CarrierOptionsFactory
33 */
34 private $carrierOptionsFactory;
35
36 /**
37 * @var OptionsProvider
38 */
39 private $optionsProvider;
40
41 /**
42 * @var Order\Repository
43 */
44 private $orderRepository;
45
46 /**
47 * @var CurrencySwitcherService
48 */
49 private $currencySwitcherService;
50
51 /**
52 * @var RateCalculator
53 */
54 private $rateCalculator;
55
56 /**
57 * @var Carrier\EntityRepository
58 */
59 private $carrierEntityRepository;
60
61 /**
62 * @var PaymentHelper
63 */
64 private $paymentHelper;
65
66 /**
67 * @var CheckoutService
68 */
69 private $checkoutService;
70
71 /**
72 * @var CheckoutRenderer
73 */
74 private $renderer;
75
76 /**
77 * @var CartService
78 */
79 private $cartService;
80
81 /**
82 * @var SessionService
83 */
84 private $sessionService;
85
86 /**
87 * @var CheckoutValidator
88 */
89 private $validator;
90
91 /**
92 * @var OrderUpdater
93 */
94 private $orderUpdater;
95
96 public function __construct(
97 WpAdapter $wpAdapter,
98 WcAdapter $wcAdapter,
99 CarrierOptionsFactory $carrierOptionsFactory,
100 OptionsProvider $optionsProvider,
101 Order\Repository $orderRepository,
102 CurrencySwitcherService $currencySwitcherService,
103 RateCalculator $rateCalculator,
104 Carrier\EntityRepository $carrierEntityRepository,
105 PaymentHelper $paymentHelper,
106 CheckoutService $checkoutService,
107 CheckoutRenderer $renderer,
108 CartService $cartService,
109 SessionService $sessionService,
110 CheckoutValidator $validator,
111 OrderUpdater $orderUpdater
112 ) {
113 $this->wpAdapter = $wpAdapter;
114 $this->wcAdapter = $wcAdapter;
115 $this->carrierOptionsFactory = $carrierOptionsFactory;
116 $this->optionsProvider = $optionsProvider;
117 $this->orderRepository = $orderRepository;
118 $this->currencySwitcherService = $currencySwitcherService;
119 $this->rateCalculator = $rateCalculator;
120 $this->carrierEntityRepository = $carrierEntityRepository;
121 $this->paymentHelper = $paymentHelper;
122 $this->checkoutService = $checkoutService;
123 $this->renderer = $renderer;
124 $this->cartService = $cartService;
125 $this->sessionService = $sessionService;
126 $this->validator = $validator;
127 $this->orderUpdater = $orderUpdater;
128 }
129
130 public function registerHooks(): void {
131 // This action works for both classic and Divi templates.
132 $this->wpAdapter->addAction(
133 'woocommerce_review_order_before_submit',
134 [
135 $this->renderer,
136 'actionRenderHiddenInputFields',
137 ]
138 );
139
140 $this->wpAdapter->addAction( 'woocommerce_checkout_process', [ $this->validator, 'actionValidateCheckoutData' ] );
141 $this->wpAdapter->addAction( 'woocommerce_checkout_update_order_meta', [ $this->orderUpdater, 'actionUpdateOrderById' ] );
142 $this->wpAdapter->addAction(
143 'woocommerce_store_api_checkout_order_processed',
144 [
145 $this->orderUpdater,
146 'actionUpdateOrder',
147 ]
148 );
149
150 // Must not be registered at backend.
151 $this->wpAdapter->addFilter( 'woocommerce_available_payment_gateways', [ $this, 'filterPaymentGateways' ] );
152
153 $this->wpAdapter->addAction(
154 'woocommerce_review_order_before_shipping',
155 [
156 $this->sessionService,
157 'actionUpdateShippingRates',
158 ]
159 );
160 $this->wpAdapter->addFilter(
161 'woocommerce_cart_shipping_packages',
162 [
163 $this->sessionService,
164 'filterUpdateShippingPackages',
165 ]
166 );
167 $this->wpAdapter->addAction(
168 'init',
169 function () {
170 /**
171 * Tells if widget button table row should be used.
172 *
173 * @since 1.3.0
174 */
175 if ( $this->optionsProvider->getCheckoutWidgetButtonLocation() === 'after_transport_methods' ) {
176 $this->wpAdapter->addAction(
177 'woocommerce_review_order_after_shipping',
178 [
179 $this->renderer,
180 'actionRenderWidgetButtonTableRow',
181 ]
182 );
183 } else {
184 $this->wpAdapter->addAction(
185 'woocommerce_after_shipping_rate',
186 [
187 $this->renderer,
188 'actionRenderWidgetButtonAfterShippingRate',
189 ]
190 );
191 }
192 }
193 );
194
195 $this->wpAdapter->addAction(
196 'woocommerce_review_order_after_shipping',
197 [
198 $this->renderer,
199 'actionRenderEstimatedDeliveryDateSection',
200 ]
201 );
202 }
203
204 /**
205 * Calculates fees.
206 *
207 * @return void
208 * @throws ProductNotFoundException Product not found.
209 */
210 public function actionCalculateFees( WC_Cart $cart ): void {
211 $chosenShippingMethodOptionId = $this->checkoutService->calculateShippingAndGetOptionId();
212
213 if (
214 $chosenShippingMethodOptionId === null ||
215 $this->checkoutService->isPacketeryShippingMethod( $chosenShippingMethodOptionId ) === false
216 ) {
217 return;
218 }
219
220 $carrierOptions = $this->carrierOptionsFactory->createByOptionId( $chosenShippingMethodOptionId );
221 $chosenCarrier = $this->carrierEntityRepository->getAnyById(
222 $this->checkoutService->getCarrierIdFromPacketeryShippingMethod( $chosenShippingMethodOptionId )
223 );
224 $maxTaxClass = $this->cartService->getTaxClassWithMaxRate();
225 $isTaxable = $maxTaxClass !== null;
226
227 if (
228 $carrierOptions->hasCouponFreeShippingForFeesAllowed() &&
229 $this->rateCalculator->isFreeShippingCouponApplied( $this->wcAdapter->cart() )
230 ) {
231 return;
232 }
233
234 $this->addAgeVerificationFee( $cart, $chosenCarrier, $carrierOptions, $isTaxable, $maxTaxClass );
235 $this->addCodSurchargeFee( $cart, $carrierOptions, $isTaxable, $maxTaxClass );
236 }
237
238 private function addAgeVerificationFee( WC_Cart $cart, ?Entity\Carrier $chosenCarrier, Carrier\Options $carrierOptions, bool $isTaxable, ?string $maxTaxClass ): void {
239 if (
240 $chosenCarrier === null ||
241 ! $chosenCarrier->supportsAgeVerification() ||
242 $carrierOptions->getAgeVerificationFee() === null ||
243 ! $this->cartService->isAgeVerificationRequired()
244 ) {
245 return;
246 }
247 $feeAmount = $this->currencySwitcherService->getConvertedPrice( $carrierOptions->getAgeVerificationFee() );
248
249 if ( $isTaxable && $feeAmount > 0 && $this->optionsProvider->arePricesTaxInclusive() ) {
250 $feeAmount = $this->calcTaxExclusiveFeeAmount( $feeAmount, $maxTaxClass );
251 }
252 $cart->add_fee( $this->wpAdapter->__( 'Age verification fee', 'packeta' ), $feeAmount, $isTaxable, $maxTaxClass );
253 }
254
255 private function addCodSurchargeFee( WC_Cart $cart, Carrier\Options $carrierOptions, bool $isTaxable, ?string $maxTaxClass ): void {
256 if ( $this->checkoutService->areBlocksUsedInCheckout() ) {
257 $paymentMethod = $this->wcAdapter->sessionGetString( 'packetery_checkout_payment_method' );
258 } else {
259 $paymentMethod = $this->sessionService->getChosenPaymentMethod();
260 }
261
262 if ( $paymentMethod === null || $this->paymentHelper->isCodPaymentMethod( $paymentMethod ) === false ) {
263 return;
264 }
265
266 $applicableSurcharge = $this->rateCalculator->getCODSurcharge(
267 $carrierOptions->toArray(),
268 $this->wcAdapter->cartGetSubtotal()
269 );
270 $applicableSurcharge = $this->currencySwitcherService->getConvertedPrice( $applicableSurcharge );
271 if ( $applicableSurcharge <= 0 ) {
272 return;
273 }
274
275 if ( $isTaxable && $this->optionsProvider->arePricesTaxInclusive() ) {
276 $applicableSurcharge = $this->calcTaxExclusiveFeeAmount( $applicableSurcharge, $maxTaxClass );
277 }
278
279 $cart->add_fee( $this->wpAdapter->__( 'COD surcharge', 'packeta' ), $applicableSurcharge, $isTaxable, $maxTaxClass );
280 }
281
282 /**
283 * Calculates tax exclusive fee amount.
284 *
285 * @param float $taxInclusiveFeeAmount Tax inclusive fee amount.
286 * @param string $taxClass Related tax class.
287 *
288 * @return float
289 */
290 private function calcTaxExclusiveFeeAmount( float $taxInclusiveFeeAmount, string $taxClass ): float {
291 return $taxInclusiveFeeAmount - array_sum(
292 $this->wcAdapter->calcTax(
293 $taxInclusiveFeeAmount,
294 $this->wcAdapter->taxGetRates( $taxClass ),
295 true
296 )
297 );
298 }
299
300 /**
301 * Filters out payment methods, that can not be used.
302 *
303 * @param WC_Payment_Gateway[] $availableGateways Available gateways.
304 *
305 * @return WC_Payment_Gateway[]
306 */
307 public function filterPaymentGateways( array $availableGateways ): array {
308 $order = null;
309 $wpOrderPay = $this->checkoutService->getOrderPayParameter();
310 if ( is_numeric( $wpOrderPay ) ) {
311 $order = $this->orderRepository->getByIdWithValidCarrier( (int) $wpOrderPay );
312 }
313
314 if ( $order instanceof Entity\Order ) {
315 $chosenMethod = Carrier\OptionPrefixer::getOptionId( $order->getCarrier()->getId() );
316 } else {
317 $chosenMethod = $this->sessionService->getChosenMethodFromSession();
318 }
319
320 if ( ! $this->checkoutService->isPacketeryShippingMethod( $chosenMethod ) ) {
321 return $availableGateways;
322 }
323
324 $carrierId = $this->checkoutService->getCarrierIdFromPacketeryShippingMethod( $chosenMethod );
325 $carrier = $this->carrierEntityRepository->getAnyById( $carrierId );
326 if ( $carrier === null ) {
327 return $availableGateways;
328 }
329
330 $carrierOptions = $this->carrierOptionsFactory->createByCarrierId( $carrierId );
331 foreach ( $availableGateways as $key => $availableGateway ) {
332 if (
333 $this->paymentHelper->isCodPaymentMethod( $availableGateway->id ) &&
334 ! $carrier->supportsCod()
335 ) {
336 unset( $availableGateways[ $key ] );
337 }
338
339 if ( $carrierOptions->hasCheckoutPaymentMethodDisallowed( $availableGateway->id ) ) {
340 unset( $availableGateways[ $key ] );
341 }
342 }
343
344 return $availableGateways;
345 }
346 }
347