fix(2meet-data-optimizer-woocommerce-addon): recompute commission amounts on every tracked status change and refund
- the commission upsert replaces subtotal, commission, vendor_payout and commission_rate on conflict (it kept the first amounts, so a partial refund before completion never reached the row) - woocommerce_order_refunded recomputes a tracked or already recorded order; a fully refunded order keeps its row at zero, untracked orders get none - Verify: WCOrdersInterceptorTest (5 new), integration 27, unit 11, phpcs; dev36 flow_wc partial refund -> completed - PR: PR-092
This commit is contained in:
@@ -25,9 +25,14 @@ if ( ! class_exists( 'TMDO_Test_WC_Order' ) ) {
|
||||
private float $total,
|
||||
private float $tax,
|
||||
private float $refunded,
|
||||
private int $product_id
|
||||
private int $product_id,
|
||||
private string $status = 'processing'
|
||||
) {}
|
||||
|
||||
public function get_status(): string {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function get_meta( string $key ) {
|
||||
return $this->meta[ $key ] ?? '';
|
||||
}
|
||||
@@ -106,6 +111,11 @@ class WCOrdersInterceptorTest extends TestCase {
|
||||
( new TMDO_WC_Orders_Interceptor() )->action_order_status_changed( self::ORDER_ID, 'pending', 'processing' );
|
||||
}
|
||||
|
||||
/** The same order after a refund (and, for a full refund, a new status). */
|
||||
private function refund( float $refunded, string $status ): void {
|
||||
$GLOBALS['_tmdo_test_orders'][ self::ORDER_ID ] = new TMDO_Test_WC_Order( $this->marketplace_meta(), 110.0, 10.0, $refunded, self::PRODUCT_ID, $status );
|
||||
}
|
||||
|
||||
private function commission_row(): ?array {
|
||||
global $wpdb;
|
||||
return $wpdb->get_row( 'SELECT * FROM `wp_itest_wpdo_wc_commissions` WHERE wc_order_id = ' . self::ORDER_ID, ARRAY_A );
|
||||
@@ -157,4 +167,55 @@ class WCOrdersInterceptorTest extends TestCase {
|
||||
$this->assertEqualsWithDelta( 0.0, (float) $row['vendor_payout'], 0.0001 );
|
||||
$this->assertEqualsWithDelta( 3.0, (float) $row['commission'], 0.0001 );
|
||||
}
|
||||
|
||||
public function test_partial_refund_then_completion_records_the_refunded_amounts(): void {
|
||||
$this->place_order( $this->marketplace_meta(), 110.0, 10.0 );
|
||||
$this->refund( 50.0, 'processing' );
|
||||
$interceptor = new TMDO_WC_Orders_Interceptor();
|
||||
$interceptor->action_order_status_changed( self::ORDER_ID, 'processing', 'completed' );
|
||||
$interceptor->action_order_status_changed( self::ORDER_ID, 'processing', 'completed' ); // Duplicate event.
|
||||
|
||||
global $wpdb;
|
||||
$this->assertSame( '1', (string) $wpdb->get_var( 'SELECT COUNT(*) FROM `wp_itest_wpdo_wc_commissions` WHERE wc_order_id = ' . self::ORDER_ID ) );
|
||||
$row = $this->commission_row();
|
||||
$this->assertSame( 'completed', $row['status'] );
|
||||
$this->assertEqualsWithDelta( 50.0, (float) $row['subtotal'], 0.0001, '110 - 50 refunded - 10 tax' );
|
||||
$this->assertEqualsWithDelta( 40.0, (float) $row['vendor_payout'], 0.0001 );
|
||||
$this->assertEqualsWithDelta( 10.0, (float) $row['commission'], 0.0001 );
|
||||
}
|
||||
|
||||
public function test_a_refund_recomputes_the_commission_without_a_status_change(): void {
|
||||
$this->place_order( $this->marketplace_meta(), 110.0, 10.0 );
|
||||
$this->refund( 50.0, 'processing' );
|
||||
|
||||
( new TMDO_WC_Orders_Interceptor() )->action_order_refunded( self::ORDER_ID, 1 );
|
||||
|
||||
$this->assertEqualsWithDelta( 50.0, (float) $this->commission_row()['subtotal'], 0.0001 );
|
||||
}
|
||||
|
||||
public function test_a_full_refund_zeroes_a_recorded_commission(): void {
|
||||
$this->place_order( $this->marketplace_meta(), 110.0, 10.0 );
|
||||
$this->refund( 110.0, 'refunded' );
|
||||
|
||||
( new TMDO_WC_Orders_Interceptor() )->action_order_refunded( self::ORDER_ID, 1 );
|
||||
|
||||
$row = $this->commission_row();
|
||||
$this->assertSame( 'refunded', $row['status'] );
|
||||
$this->assertEqualsWithDelta( 0.0, (float) $row['vendor_payout'], 0.0001 );
|
||||
}
|
||||
|
||||
public function test_a_refund_of_an_untracked_order_records_nothing(): void {
|
||||
$this->refund( 50.0, 'pending' );
|
||||
|
||||
( new TMDO_WC_Orders_Interceptor() )->action_order_refunded( self::ORDER_ID, 1 );
|
||||
|
||||
$this->assertNull( $this->commission_row() );
|
||||
}
|
||||
|
||||
public function test_refunds_are_hooked(): void {
|
||||
$interceptor = new TMDO_WC_Orders_Interceptor();
|
||||
$interceptor->register_hooks();
|
||||
|
||||
$this->assertContains( array( $interceptor, 'action_order_refunded' ), $GLOBALS['_wp_filter_callbacks']['woocommerce_order_refunded'] ?? array() );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user