Improve item total/price retrieval

Less calculations, also fee was not included in item price for subs with fee
This commit is contained in:
Alex P 2022-06-15 16:30:38 +03:00
parent 24586d0910
commit 02c84e43e0
4 changed files with 53 additions and 117 deletions

View file

@ -69,16 +69,8 @@ class AmountFactory {
public function from_wc_cart( \WC_Cart $cart ): Amount {
$total = new Money( (float) $cart->get_total( 'numeric' ), $this->currency );
$total_fees_amount = 0;
$fees = WC()->session->get( 'ppcp_fees' );
if ( $fees ) {
foreach ( WC()->session->get( 'ppcp_fees' ) as $fee ) {
$total_fees_amount += (float) $fee->amount;
}
}
$item_total = $cart->get_cart_contents_total() + $cart->get_discount_total() + $total_fees_amount;
$item_total = new Money( (float) $item_total, $this->currency );
$item_total = (float) $cart->get_subtotal() + (float) $cart->get_fee_total();
$item_total = new Money( $item_total, $this->currency );
$shipping = new Money(
(float) $cart->get_shipping_total(),
$this->currency
@ -138,13 +130,6 @@ class AmountFactory {
);
}
$items = array_filter(
$items,
function ( Item $item ): bool {
return $item->unit_amount()->value() > 0;
}
);
$total_value = (float) $order->get_total();
if ( (
CreditCardGateway::ID === $order->get_payment_method()
@ -157,13 +142,7 @@ class AmountFactory {
$total = new Money( $total_value, $currency );
$item_total = new Money(
(float) array_reduce(
$items,
static function ( float $total, Item $item ): float {
return $total + $item->quantity() * $item->unit_amount()->value();
},
0
),
(float) $order->get_subtotal(),
$currency
);
$shipping = new Money(

View file

@ -53,12 +53,10 @@ class ItemFactory {
*/
$quantity = (int) $item['quantity'];
$price = (float) wc_get_price_including_tax( $product );
$price_without_tax = (float) wc_get_price_excluding_tax( $product );
$price_without_tax_rounded = round( $price_without_tax, 2 );
$price = (float) $item['line_subtotal'] / (float) $item['quantity'];
return new Item(
mb_substr( $product->get_name(), 0, 127 ),
new Money( $price_without_tax_rounded, $this->currency ),
new Money( $price, $this->currency ),
$quantity,
substr( wp_strip_all_tags( $product->get_description() ), 0, 127 ) ?: '',
null,
@ -125,7 +123,6 @@ class ItemFactory {
$product = $item->get_product();
$currency = $order->get_currency();
$quantity = (int) $item->get_quantity();
$price = (float) $order->get_item_subtotal( $item, true );
$price_without_tax = (float) $order->get_item_subtotal( $item, false );
$price_without_tax_rounded = round( $price_without_tax, 2 );

View file

@ -35,28 +35,22 @@ class AmountFactoryTest extends TestCase
$cart
->shouldReceive('get_total')
->withAnyArgs()
->andReturn(1);
->andReturn(13);
$cart
->shouldReceive('get_cart_contents_total')
->andReturn(2);
$cart
->shouldReceive('get_discount_total')
->andReturn(3);
$cart
->shouldReceive('get_shipping_total')
->andReturn(4);
$cart
->shouldReceive('get_shipping_tax')
->shouldReceive('get_subtotal')
->andReturn(5);
$cart
->shouldReceive('get_cart_contents_tax')
->andReturn(6);
->shouldReceive('get_fee_total')
->andReturn(3);
$cart
->shouldReceive('get_discount_tax')
->andReturn(7);
->shouldReceive('get_discount_total')
->andReturn(1);
$cart
->shouldReceive('get_subtotal_tax')
->andReturn(8);
->shouldReceive('get_shipping_total')
->andReturn(2);
$cart
->shouldReceive('get_total_tax')
->andReturn(4);
$woocommerce = Mockery::mock(\WooCommerce::class);
$session = Mockery::mock(\WC_Session::class);
@ -66,46 +60,39 @@ class AmountFactoryTest extends TestCase
$result = $this->testee->from_wc_cart($cart);
$this->assertEquals($this->currency, $result->currency_code());
$this->assertEquals((float) 1, $result->value());
$this->assertEquals((float) 10, $result->breakdown()->discount()->value());
$this->assertEquals((float) 13, $result->value());
$this->assertEquals((float) 1, $result->breakdown()->discount()->value());
$this->assertEquals($this->currency, $result->breakdown()->discount()->currency_code());
$this->assertEquals((float) 9, $result->breakdown()->shipping()->value());
$this->assertEquals((float) 2, $result->breakdown()->shipping()->value());
$this->assertEquals($this->currency, $result->breakdown()->shipping()->currency_code());
$this->assertEquals((float) 5, $result->breakdown()->item_total()->value());
$this->assertEquals((float) 8, $result->breakdown()->item_total()->value());
$this->assertEquals($this->currency, $result->breakdown()->item_total()->currency_code());
$this->assertEquals((float) 8, $result->breakdown()->tax_total()->value());
$this->assertEquals((float) 4, $result->breakdown()->tax_total()->value());
$this->assertEquals($this->currency, $result->breakdown()->tax_total()->currency_code());
}
public function testFromWcCartNoDiscount()
{
$expectedTotal = 1;
$cart = Mockery::mock(\WC_Cart::class);
$cart
->shouldReceive('get_total')
->withAnyArgs()
->andReturn($expectedTotal);
$cart
->shouldReceive('get_cart_contents_total')
->andReturn(2);
->andReturn(11);
$cart
->shouldReceive('get_subtotal')
->andReturn(5);
$cart
->shouldReceive('get_fee_total')
->andReturn(0);
$cart
->shouldReceive('get_discount_total')
->andReturn(0);
$cart
->shouldReceive('get_shipping_total')
->andReturn(4);
$cart
->shouldReceive('get_shipping_tax')
->andReturn(5);
$cart
->shouldReceive('get_cart_contents_tax')
->andReturn(6);
$cart
->shouldReceive('get_discount_tax')
->andReturn(0);
->andReturn(2);
$cart
->shouldReceive('get_subtotal_tax')
->andReturn(11);
->shouldReceive('get_total_tax')
->andReturn(4);
$woocommerce = Mockery::mock(\WooCommerce::class);
$session = Mockery::mock(\WC_Session::class);
@ -114,6 +101,10 @@ class AmountFactoryTest extends TestCase
$session->shouldReceive('get')->andReturn([]);
$result = $this->testee->from_wc_cart($cart);
$this->assertNull($result->breakdown()->discount());
$this->assertEquals((float) 11, $result->value());
$this->assertEquals((float) 2, $result->breakdown()->shipping()->value());
$this->assertEquals((float) 5, $result->breakdown()->item_total()->value());
$this->assertEquals((float) 4, $result->breakdown()->tax_total()->value());
}
public function testFromWcOrderDefault()
@ -123,10 +114,7 @@ class AmountFactoryTest extends TestCase
$unitAmount
->shouldReceive('value')
->andReturn(3);
$tax = Mockery::mock(Money::class);
$tax
->shouldReceive('value')
->andReturn(1);
$item = Mockery::mock(Item::class);
$item
->shouldReceive('quantity')
@ -134,9 +122,6 @@ class AmountFactoryTest extends TestCase
$item
->shouldReceive('unit_amount')
->andReturn($unitAmount);
$item
->shouldReceive('tax')
->andReturn($tax);
$this->itemFactory
->expects('from_wc_order')
->with($order)
@ -149,6 +134,9 @@ class AmountFactoryTest extends TestCase
$order
->shouldReceive('get_total')
->andReturn(100);
$order
->shouldReceive('get_subtotal')
->andReturn(6);
$order
->shouldReceive('get_currency')
->andReturn($this->currency);
@ -156,11 +144,10 @@ class AmountFactoryTest extends TestCase
->shouldReceive('get_shipping_total')
->andReturn(1);
$order
->shouldReceive('get_shipping_tax')
->andReturn(.5);
->shouldReceive('get_total_tax')
->andReturn(2);
$order
->shouldReceive('get_total_discount')
->with(false)
->andReturn(3);
$order
->shouldReceive('get_meta')
@ -169,7 +156,7 @@ class AmountFactoryTest extends TestCase
$result = $this->testee->from_wc_order($order);
$this->assertEquals((float) 3, $result->breakdown()->discount()->value());
$this->assertEquals((float) 6, $result->breakdown()->item_total()->value());
$this->assertEquals((float) 1.5, $result->breakdown()->shipping()->value());
$this->assertEquals((float) 1, $result->breakdown()->shipping()->value());
$this->assertEquals((float) 100, $result->value());
$this->assertEquals((float) 2, $result->breakdown()->tax_total()->value());
$this->assertEquals($this->currency, $result->breakdown()->discount()->currency_code());
@ -186,10 +173,6 @@ class AmountFactoryTest extends TestCase
$unitAmount
->shouldReceive('value')
->andReturn(3);
$tax = Mockery::mock(Money::class);
$tax
->shouldReceive('value')
->andReturn(1);
$item = Mockery::mock(Item::class);
$item
->shouldReceive('quantity')
@ -197,9 +180,6 @@ class AmountFactoryTest extends TestCase
$item
->shouldReceive('unit_amount')
->andReturn($unitAmount);
$item
->shouldReceive('tax')
->andReturn($tax);
$this->itemFactory
->expects('from_wc_order')
->with($order)
@ -212,18 +192,20 @@ class AmountFactoryTest extends TestCase
$order
->shouldReceive('get_total')
->andReturn(100);
$order
->shouldReceive('get_subtotal')
->andReturn(6);
$order
->shouldReceive('get_currency')
->andReturn($this->currency);
$order
->shouldReceive('get_shipping_total')
->andReturn(1);
$order
->shouldReceive('get_shipping_tax')
->andReturn(.5);
$order
->shouldReceive('get_total_tax')
->andReturn(2);
$order
->shouldReceive('get_total_discount')
->with(false)
->andReturn(0);
$order
->shouldReceive('get_meta')

View file

@ -34,7 +34,8 @@ class ItemFactoryTest extends TestCase
$items = [
[
'data' => $product,
'quantity' => 1,
'quantity' => 2,
'line_subtotal' => 84,
],
];
$cart = Mockery::mock(\WC_Cart::class);
@ -42,12 +43,6 @@ class ItemFactoryTest extends TestCase
->expects('get_cart_contents')
->andReturn($items);
expect('wc_get_price_including_tax')
->with($product)
->andReturn(2.995);
expect('wc_get_price_excluding_tax')
->with($product)
->andReturn(1);
expect('wp_strip_all_tags')
->with('description')
->andReturn('description');
@ -68,10 +63,10 @@ class ItemFactoryTest extends TestCase
*/
$this->assertEquals(Item::PHYSICAL_GOODS, $item->category());
$this->assertEquals('description', $item->description());
$this->assertEquals(1, $item->quantity());
$this->assertEquals(2, $item->quantity());
$this->assertEquals('name', $item->name());
$this->assertEquals('sku', $item->sku());
$this->assertEquals(1, $item->unit_amount()->value());
$this->assertEquals(42, $item->unit_amount()->value());
}
public function testFromCartDigitalGood()
@ -95,6 +90,7 @@ class ItemFactoryTest extends TestCase
[
'data' => $product,
'quantity' => 1,
'line_subtotal' => 42,
],
];
$cart = Mockery::mock(\WC_Cart::class);
@ -102,12 +98,6 @@ class ItemFactoryTest extends TestCase
->expects('get_cart_contents')
->andReturn($items);
expect('wc_get_price_including_tax')
->with($product)
->andReturn(2.995);
expect('wc_get_price_excluding_tax')
->with($product)
->andReturn(1);
expect('wp_strip_all_tags')
->with('description')
->andReturn('description');
@ -160,10 +150,6 @@ class ItemFactoryTest extends TestCase
$order
->expects('get_items')
->andReturn([$item]);
$order
->expects('get_item_subtotal')
->with($item, true)
->andReturn(3);
$order
->expects('get_item_subtotal')
->with($item, false)
@ -222,10 +208,6 @@ class ItemFactoryTest extends TestCase
$order
->expects('get_items')
->andReturn([$item]);
$order
->expects('get_item_subtotal')
->with($item, true)
->andReturn(3);
$order
->expects('get_item_subtotal')
->with($item, false)
@ -280,10 +262,6 @@ class ItemFactoryTest extends TestCase
$order
->expects('get_items')
->andReturn([$item]);
$order
->expects('get_item_subtotal')
->with($item, true)
->andReturn(3);
$order
->expects('get_item_subtotal')
->with($item, false)