Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ services:
- Packetery\Module\Checkout\Checkout
- Packetery\Module\Checkout\CheckoutService
- Packetery\Module\Checkout\CheckoutRenderer
- Packetery\Module\Checkout\ShippingTaxModifier
- Packetery\Module\Checkout\CheckoutStorage
- Packetery\Module\Checkout\CheckoutSettings
- Packetery\Module\Checkout\CheckoutValidator
Expand Down
9 changes: 9 additions & 0 deletions src/Packetery/Module/Checkout/Checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class Checkout {
*/
private $renderer;

/**
* @var ShippingTaxModifier
*/
private $shippingTaxModifier;

/**
* @var CartService
*/
Expand Down Expand Up @@ -105,6 +110,7 @@ public function __construct(
PaymentHelper $paymentHelper,
CheckoutService $checkoutService,
CheckoutRenderer $renderer,
ShippingTaxModifier $shippingTaxModifier,
CartService $cartService,
SessionService $sessionService,
CheckoutValidator $validator,
Expand All @@ -121,13 +127,16 @@ public function __construct(
$this->paymentHelper = $paymentHelper;
$this->checkoutService = $checkoutService;
$this->renderer = $renderer;
$this->shippingTaxModifier = $shippingTaxModifier;
$this->cartService = $cartService;
$this->sessionService = $sessionService;
$this->validator = $validator;
$this->orderUpdater = $orderUpdater;
}

public function registerHooks(): void {
$this->shippingTaxModifier->register();

// This action works for both classic and Divi templates.
$this->wpAdapter->addAction(
'woocommerce_review_order_before_submit',
Expand Down
12 changes: 7 additions & 5 deletions src/Packetery/Module/Checkout/RateCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,13 @@ public function getCODSurcharge( array $carrierOptions, float $cartPrice ): floa
*/
public function createShippingRate( string $name, string $optionId, float $taxExclusiveCost, ?array $taxes ): array {
return [
'label' => $name,
'id' => $optionId,
'cost' => $taxExclusiveCost,
'taxes' => $taxes ?? '',
'calc_tax' => 'per_order',
'label' => $name,
'id' => $optionId,
'cost' => $taxExclusiveCost,
'taxes' => $taxes ?? '',
'meta_data' => [
'packetaTaxes' => $taxes,
],
];
}

Expand Down
1 change: 1 addition & 0 deletions src/Packetery/Module/Checkout/ShippingRateFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ private function createShippingRateAndApplyTaxes( string $carrierName, float $co
if ( $this->isFreeShippingApplicable( $cost ) ) {
$carrierName = $this->formatCarrierNameWithFreeShipping( $carrierName );
}

$taxes = null;
if ( $cost > 0 && $this->optionsProvider->arePricesTaxInclusive() ) {
$rates = $this->wcAdapter->taxGetShippingTaxRates();
Expand Down
58 changes: 58 additions & 0 deletions src/Packetery/Module/Checkout/ShippingTaxModifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare( strict_types=1 );

namespace Packetery\Module\Checkout;

use Packetery\Module\Framework\WpAdapter;
use Packetery\Module\Options\OptionsProvider;
use Packetery\Module\Shipping\ShippingProvider;
use WC_Order_Item_Shipping;

class ShippingTaxModifier {

/**
* @var OptionsProvider
*/
private $optionsProvider;

/**
* @var WpAdapter
*/
private $wpAdapter;

public function __construct(
WpAdapter $wpAdapter,
OptionsProvider $optionsProvider
) {
$this->optionsProvider = $optionsProvider;
$this->wpAdapter = $wpAdapter;
}

public function register(): void {
$this->wpAdapter->addAction(
'woocommerce_order_item_shipping_after_calculate_taxes',
[
$this,
'afterCalculateTaxes',
]
);
}

public function afterCalculateTaxes( WC_Order_Item_Shipping $shippingItem ): void {
if ( ! $this->optionsProvider->arePricesTaxInclusive() ) {
return;
}

if ( ! ShippingProvider::isPacketaMethod( $shippingItem->get_method_id() ) ) {
return;
}

$taxes = $shippingItem->get_meta( 'packetaTaxes' );
if ( ! is_array( $taxes ) ) {
return;
}

$shippingItem->set_taxes( [ 'total' => $taxes ] );
}
}
11 changes: 11 additions & 0 deletions src/Packetery/Module/Shipping/BaseShippingMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ public function init(): void {
// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
$this->instance_form_fields = $this->get_instance_form_fields();
$this->title = $this->get_option( 'title' );
// phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
$this->tax_status = $this->get_option( 'tax_status', 'taxable' );
}

public function get_admin_options_html(): string {
Expand Down Expand Up @@ -173,6 +175,15 @@ public function get_instance_form_fields(): array {
'default' => $this->method_title,
'desc_tip' => true,
],
'tax_status' => [
'title' => __( 'Tax status', 'packeta' ),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'taxable',
'options' => [
'taxable' => __( 'Taxable', 'packeta' ),
],
],
'custom_html' => [
'title' => '',
'type' => 'title',
Expand Down
4 changes: 4 additions & 0 deletions tests/Module/Checkout/CheckoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Packetery\Module\Checkout\OrderUpdater;
use Packetery\Module\Checkout\RateCalculator;
use Packetery\Module\Checkout\SessionService;
use Packetery\Module\Checkout\ShippingTaxModifier;
use Packetery\Module\Framework\WcAdapter;
use Packetery\Module\Framework\WpAdapter;
use Packetery\Module\Options\OptionsProvider;
Expand All @@ -37,6 +38,7 @@ class CheckoutTest extends TestCase {
private Repository|MockObject $orderRepository;
private CurrencySwitcherService|MockObject $currencySwitcherService;
private CheckoutRenderer|MockObject $checkoutRenderer;
private ShippingTaxModifier|MockObject $shippingTaxModifier;
private SessionService|MockObject $sessionService;
private CheckoutValidator|MockObject $checkoutValidator;
private OrderUpdater|MockObject $orderUpdater;
Expand All @@ -55,6 +57,7 @@ protected function creatCheckout(): void {
$this->paymentHelper = $this->createMock( PaymentHelper::class );
$this->checkoutService = $this->createMock( CheckoutService::class );
$this->checkoutRenderer = $this->createMock( CheckoutRenderer::class );
$this->shippingTaxModifier = $this->createMock( ShippingTaxModifier::class );
$this->cartService = $this->createMock( CartService::class );
$this->sessionService = $this->createMock( SessionService::class );
$this->checkoutValidator = $this->createMock( CheckoutValidator::class );
Expand All @@ -73,6 +76,7 @@ protected function creatCheckout(): void {
$this->paymentHelper,
$this->checkoutService,
$this->checkoutRenderer,
$this->shippingTaxModifier,
$this->cartService,
$this->sessionService,
$this->checkoutValidator,
Expand Down
109 changes: 109 additions & 0 deletions tests/Module/Checkout/ShippingTaxModifierTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

declare(strict_types=1);

namespace Tests\Module\Checkout;

use Packetery\Module\Checkout\ShippingTaxModifier;
use Packetery\Module\Framework\WpAdapter;
use Packetery\Module\Options\OptionsProvider;
use PHPUnit\Framework\TestCase;
use WC_Order_Item_Shipping;

class ShippingTaxModifierTest extends TestCase {

private WpAdapter|MockObject $wpAdapterMock;
private OptionsProvider|MockObject $optionsProviderMock;
private ShippingTaxModifier $shippingTaxModifier;

protected function setup(): void {
$this->wpAdapterMock = $this->createMock( WpAdapter::class );
$this->optionsProviderMock = $this->createMock( OptionsProvider::class );

$this->shippingTaxModifier = new ShippingTaxModifier(
$this->wpAdapterMock,
$this->optionsProviderMock
);
}

public function testRegister(): void {
$this->wpAdapterMock
->expects( $this->once() )
->method( 'addAction' )
->with(
'woocommerce_order_item_shipping_after_calculate_taxes',
[ $this->shippingTaxModifier, 'afterCalculateTaxes' ]
);

$this->shippingTaxModifier->register();
}

public function testAfterCalculateTaxesSkipsWhenPricesAreNotTaxInclusive(): void {
$this->optionsProviderMock
->method( 'arePricesTaxInclusive' )
->willReturn( false );

$shippingItemMock = $this->createMock( WC_Order_Item_Shipping::class );
$shippingItemMock->expects( $this->never() )->method( 'get_method_id' );

$this->shippingTaxModifier->afterCalculateTaxes( $shippingItemMock );
}

public function testAfterCalculateTaxesSkipsWhenMethodIsNotPacketa(): void {
$this->optionsProviderMock
->method( 'arePricesTaxInclusive' )
->willReturn( true );

$shippingItemMock = $this->createMock( WC_Order_Item_Shipping::class );
$shippingItemMock
->method( 'get_method_id' )
->willReturn( 'non_packeta_method' );

$shippingItemMock->expects( $this->never() )->method( 'get_meta' );

$this->shippingTaxModifier->afterCalculateTaxes( $shippingItemMock );
}

public function testAfterCalculateTaxesSkipsWhenPacketaTaxesIsNotArray(): void {
$this->optionsProviderMock
->method( 'arePricesTaxInclusive' )
->willReturn( true );

$shippingItemMock = $this->createMock( WC_Order_Item_Shipping::class );
$shippingItemMock
->method( 'get_method_id' )
->willReturn( 'packeta_method_zpointcz' );

$shippingItemMock
->method( 'get_meta' )
->with( 'packetaTaxes' )
->willReturn( '' );

$shippingItemMock->expects( $this->never() )->method( 'set_taxes' );

$this->shippingTaxModifier->afterCalculateTaxes( $shippingItemMock );
}

public function testAfterCalculateTaxesSetsTaxes(): void {
$this->optionsProviderMock
->method( 'arePricesTaxInclusive' )
->willReturn( true );

$shippingItemMock = $this->createMock( WC_Order_Item_Shipping::class );
$shippingItemMock
->method( 'get_method_id' )
->willReturn( 'packeta_method_zpointcz' );

$shippingItemMock
->method( 'get_meta' )
->with( 'packetaTaxes' )
->willReturn( [ 10 ] );

$shippingItemMock
->expects( $this->once() )
->method( 'set_taxes' )
->with( [ 'total' => [ 10 ] ] );

$this->shippingTaxModifier->afterCalculateTaxes( $shippingItemMock );
}
}