diff --git a/includes/Analytics/Reports/Orders/Stats/QueryFilter.php b/includes/Analytics/Reports/Orders/Stats/QueryFilter.php index f849b5f41e..34b47bd030 100644 --- a/includes/Analytics/Reports/Orders/Stats/QueryFilter.php +++ b/includes/Analytics/Reports/Orders/Stats/QueryFilter.php @@ -124,10 +124,18 @@ public function modify_admin_report_columns( array $column, string $context, str public function add_select_subquery_for_total( $clauses ) { $table_name = $this->get_dokan_table(); $types = $this->get_order_and_refund_types_to_include(); - - $clauses[] = ', sum(vendor_earning) as total_vendor_earning, sum(vendor_gateway_fee) as total_vendor_gateway_fee, sum(vendor_discount) as total_vendor_discount, sum(admin_commission) as total_admin_commission, sum(admin_gateway_fee) as total_admin_gateway_fee, sum(admin_discount) as total_admin_discount, sum(admin_subsidy) as total_admin_subsidy'; - $clauses[] = ", SUM( {$table_name}.admin_commission ) / SUM( CASE WHEN {$table_name}.order_type IN($types) THEN 1 ELSE 0 END ) AS avg_admin_commission"; - $clauses[] = ", SUM( {$table_name}.vendor_earning ) / SUM( CASE WHEN {$table_name}.order_type IN($types) THEN 1 ELSE 0 END ) AS avg_vendor_earning"; + $commission = ", SUM( CASE WHEN {$table_name}.order_type IN($types) THEN admin_commission ELSE 0 END)"; + $vendor_earning = ", SUM( CASE WHEN {$table_name}.order_type IN($types) THEN vendor_earning ELSE 0 END)"; + + $clauses[] = "$vendor_earning as total_vendor_earning"; + $clauses[] = ", SUM( CASE WHEN {$table_name}.order_type IN($types) THEN vendor_gateway_fee ELSE 0 END) as total_vendor_gateway_fee"; + $clauses[] = ", SUM( CASE WHEN {$table_name}.order_type IN($types) THEN vendor_discount ELSE 0 END) as total_vendor_discount"; + $clauses[] = "$commission as total_admin_commission"; + $clauses[] = ", SUM( CASE WHEN {$table_name}.order_type IN($types) THEN admin_gateway_fee ELSE 0 END) as total_admin_gateway_fee"; + $clauses[] = ", SUM( CASE WHEN {$table_name}.order_type IN($types) THEN admin_discount ELSE 0 END) as total_admin_discount"; + $clauses[] = ", SUM( CASE WHEN {$table_name}.order_type IN($types) THEN admin_subsidy ELSE 0 END) as total_admin_subsidy"; + $clauses[] = " $commission / SUM( CASE WHEN {$table_name}.order_type IN($types) THEN 1 ELSE 0 END ) AS avg_admin_commission"; + $clauses[] = "$vendor_earning / SUM( CASE WHEN {$table_name}.order_type IN($types) THEN 1 ELSE 0 END ) AS avg_vendor_earning"; return $clauses; } diff --git a/tests/php/src/Analytics/Reports/OrderQueryFilterTest.php b/tests/php/src/Analytics/Reports/OrderQueryFilterTest.php index 574b6520c9..3e0bf3b67d 100644 --- a/tests/php/src/Analytics/Reports/OrderQueryFilterTest.php +++ b/tests/php/src/Analytics/Reports/OrderQueryFilterTest.php @@ -3,6 +3,7 @@ use Mockery; use WeDevs\Dokan\Analytics\Reports\Orders\QueryFilter; +use WeDevs\Dokan\Commission; use WeDevs\Dokan\Test\Analytics\Reports\ReportTestCase; /** @@ -92,6 +93,21 @@ public function test_dokan_order_stats_fields_are_selected_for_seller( $expected $order_id = $this->create_multi_vendor_order(); $this->set_order_meta_for_dokan( $order_id, $expected_data ); + $mock_commission = Mockery::mock( Commission::class ); + + dokan()->get_container()->extend( 'commission' )->setConcrete( $mock_commission ); + + $mock_commission->shouldReceive( 'get_earning_by_order' )->andReturnUsing( + function ( $order, $context = 'seller' ) use ( $expected_data ) { + if ( $order->get_meta( 'has_sub_order' ) ) { + return 0; + } + if ( $context === 'admin' ) { + return $expected_data['admin_commission']; + } + return $expected_data['vendor_earning']; + } + ); $this->run_all_pending(); @@ -120,12 +136,21 @@ public function test_dokan_order_stats_fields_are_selected_for_seller( $expected foreach ( $sub_ids as $index => $s_id ) { $sub_order = wc_get_order( $s_id ); - $order_data = $report_data[ $index ]; + $order_data = array_reduce( + $report_data, function ( $carry, $item ) use ( $s_id ) { + if ( $item['order_id'] === $s_id ) { + $carry = $item; + } + + return $carry; + }, null + ); $this->assertEquals( $s_id, $order_data['order_id'] ); $this->assertEquals( floatval( $sub_order->get_total() ), $order_data['total_sales'] ); foreach ( $expected_data as $key => $val ) { + // var_dump() $this->assertEquals( $val, $order_data[ $key ] ); } } diff --git a/tests/php/src/Analytics/Reports/OrderStatsQueryFilterTest.php b/tests/php/src/Analytics/Reports/OrderStatsQueryFilterTest.php index f9a338b1de..56a13c3247 100644 --- a/tests/php/src/Analytics/Reports/OrderStatsQueryFilterTest.php +++ b/tests/php/src/Analytics/Reports/OrderStatsQueryFilterTest.php @@ -4,6 +4,7 @@ use Exception; use Mockery; use WeDevs\Dokan\Analytics\Reports\Orders\Stats\QueryFilter; +use WeDevs\Dokan\Commission; use WeDevs\Dokan\Test\Analytics\Reports\ReportTestCase; /** @@ -43,8 +44,8 @@ public function test_order_stats_hook_registered() { self::assertNotFalse( has_filter( 'woocommerce_analytics_clauses_join_orders_stats_total', [ $order_stats_query_filter, 'add_join_subquery' ] ) ); self::assertNotFalse( has_filter( 'woocommerce_analytics_clauses_join_orders_stats_interval', [ $order_stats_query_filter, 'add_join_subquery' ] ) ); // Assert the Where Clause filters are registered - self::assertNotFalse( has_filter( 'woocommerce_analytics_clauses_where_orders_stats_total', [ $order_stats_query_filter, 'add_where_subquery' ] ) ); - self::assertNotFalse( has_filter( 'woocommerce_analytics_clauses_where_orders_stats_interval', [ $order_stats_query_filter, 'add_where_subquery' ] ) ); + // self::assertNotFalse( has_filter( 'woocommerce_analytics_clauses_where_orders_stats_total', [ $order_stats_query_filter, 'add_where_subquery' ] ) ); + // self::assertNotFalse( has_filter( 'woocommerce_analytics_clauses_where_orders_stats_interval', [ $order_stats_query_filter, 'add_where_subquery' ] ) ); } @@ -65,7 +66,7 @@ public function test_dokan_order_states_query_filter_hooks_are_order_stats_updat $mocking_methods = [ 'add_join_subquery', - 'add_where_subquery', + // 'add_where_subquery', // For Coupon amount distribution. 'add_select_subquery_for_total', ]; @@ -88,79 +89,50 @@ function ( $clauses ) { $wc_stats_query->get_data(); } - /** - * @dataProvider get_dokan_stats_data - * - * @return void - */ - public function test_dokan_order_stats_added_to_wc_select_query_for_seller( array $data ) { - $parent_id = $this->create_multi_vendor_order(); - - $this->set_order_meta_for_dokan( $parent_id, $data ); - - $this->run_all_pending(); - - $filter = Mockery::mock( QueryFilter::class . '[should_filter_by_vendor_id]' ); - - dokan_get_container()->extend( QueryFilter::class )->setConcrete( $filter ); - - $filter->shouldReceive( 'should_filter_by_vendor_id' ) - ->atLeast() - ->once() - ->andReturnTrue(); - - $orders_query = new \Automattic\WooCommerce\Admin\API\Reports\Orders\Stats\Query( [] ); - - $report_data = $orders_query->get_data(); - - $sub_ids = dokan_get_suborder_ids_by( $parent_id ); - - $this->assertCount( $report_data->totals->orders_count, $sub_ids ); - - $sub_ord_count = count( $sub_ids ); - - // Assert dokan order stats totals. - foreach ( $data as $key => $val ) { - $this->assertEquals( floatval( $val * $sub_ord_count ), $report_data->totals->{"total_$key"} ); - } - } /** * @dataProvider get_dokan_stats_data * * @return void */ - public function test_dokan_order_stats_added_to_wc_select_query_for_admin( array $data ) { + public function test_dokan_order_stats_added_to_wc_select_query_for_total( array $data ) { $parent_id = $this->create_multi_vendor_order(); $this->set_order_meta_for_dokan( $parent_id, $data ); + $mock_commission = Mockery::mock( Commission::class ); + + dokan()->get_container()->extend( 'commission' )->setConcrete( $mock_commission ); + + $mock_commission->shouldReceive( 'get_earning_by_order' )->andReturnUsing( + function ( $order, $context = 'seller' ) use ( $data ) { + if ( $order->get_meta( 'has_sub_order' ) ) { + return 0; + } + if ( $context === 'admin' ) { + return $data['admin_commission']; + } + return $data['vendor_earning']; + } + ); $this->run_all_pending(); - $filter = Mockery::mock( QueryFilter::class . '[should_filter_by_vendor_id]' ); - remove_filter( 'woocommerce_analytics_clauses_where_orders_stats_total', [ $this->sut, 'add_where_subquery' ], 30 ); remove_filter( 'woocommerce_analytics_clauses_where_orders_stats_total', [ $this->sut, 'add_where_subquery' ], 30 ); - dokan_get_container()->extend( QueryFilter::class )->setConcrete( $filter ); - - $filter->shouldReceive( 'should_filter_by_vendor_id' ) - ->atLeast() - ->once() - ->andReturnFalse(); - $orders_query = new \Automattic\WooCommerce\Admin\API\Reports\Orders\Stats\Query( [], 'orders-stats' ); $report_data = $orders_query->get_data(); $sub_ids = dokan_get_suborder_ids_by( $parent_id ); - $this->assertEquals( 1, $report_data->totals->orders_count ); + $this->assertEquals( 2, $report_data->totals->orders_count ); $sub_ord_count = count( $sub_ids ); - // var_dump( $data ); // Assert dokan order stats totals. foreach ( $data as $key => $val ) { - $this->assertEquals( floatval( $val * $sub_ord_count ), $report_data->totals->{"total_$key"} ); + $expected = floatval( $val * $sub_ord_count ); + + $this->assertEquals( $expected, $report_data->totals->{"total_$key"}, $key . ' Mismatch: Expected: ' . $expected . ' Got: ' . $val ); } } } diff --git a/tests/php/src/Analytics/Reports/ReportTestCase.php b/tests/php/src/Analytics/Reports/ReportTestCase.php index b632014b98..606eb58912 100644 --- a/tests/php/src/Analytics/Reports/ReportTestCase.php +++ b/tests/php/src/Analytics/Reports/ReportTestCase.php @@ -2,6 +2,7 @@ namespace WeDevs\Dokan\Test\Analytics\Reports; +use WeDevs\Dokan\Commission; use WeDevs\Dokan\Test\DokanTestCase; /** @@ -100,14 +101,19 @@ public static function get_dokan_stats_data() { [ [ 'vendor_earning' => random_int( 5, 10 ), - 'vendor_gateway_fee' => random_int( 5, 10 ), - 'vendor_discount' => random_int( 5, 10 ), + // 'vendor_gateway_fee' => random_int( 5, 10 ), + // 'vendor_discount' => random_int( 5, 10 ), 'admin_commission' => random_int( 5, 10 ), - 'admin_gateway_fee' => random_int( 5, 10 ), - 'admin_discount' => random_int( 5, 10 ), - 'admin_subsidy' => random_int( 5, 10 ), + // 'admin_gateway_fee' => random_int( 5, 10 ), + // 'admin_discount' => random_int( 5, 10 ), + // 'admin_subsidy' => random_int( 5, 10 ), ], ], ]; } + + public function tear_down() { + dokan()->get_container()->extend( 'commission' )->setConcrete( new Commission() ); + parent::tear_down(); + } }