diff --git a/plugins/woocommerce/changelog/50842-43149-fix-bulk-product-price-in-de-crease b/plugins/woocommerce/changelog/50842-43149-fix-bulk-product-price-in-de-crease new file mode 100644 index 00000000000..affaea6bdf9 --- /dev/null +++ b/plugins/woocommerce/changelog/50842-43149-fix-bulk-product-price-in-de-crease @@ -0,0 +1,4 @@ +Significance: minor +Type: fix + +Product bulk edit: fix increasing & decreasing sale price when there was no previous sale. \ No newline at end of file diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php b/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php index 741fda165cd..095893653ba 100644 --- a/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php +++ b/plugins/woocommerce/includes/admin/class-wc-admin-post-types.php @@ -896,7 +896,8 @@ class WC_Admin_Post_Types { return false; } - $old_price = (float) $product->{"get_{$price_type}_price"}(); + $old_price = $product->{"get_{$price_type}_price"}(); + $old_price = '' === $old_price ? (float) $product->get_regular_price() : (float) $old_price; $price_changed = false; $change_price = absint( $request_data[ "change_{$price_type}_price" ] ); diff --git a/plugins/woocommerce/tests/e2e-pw/tests/merchant/product-edit.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/merchant/product-edit.spec.js index 89d18f069f5..e94595088b6 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/merchant/product-edit.spec.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/merchant/product-edit.spec.js @@ -282,3 +282,119 @@ test( } ); } ); + +test( + 'can decrease the sale price if the product was not previously in sale when bulk editing products', + { tag: [ '@gutenberg', '@services' ] }, + async ( { page, products } ) => { + await page.goto( `wp-admin/edit.php?post_type=product` ); + + const salePriceDecrease = 10; + + await test.step( 'Update products with the "Sale > Decrease existing sale price" option', async () => { + await page.goto( `wp-admin/edit.php?post_type=product` ); + + for ( const product of products ) { + await page.getByLabel( `Select ${ product.name }` ).click(); + } + + await page + .locator( '#bulk-action-selector-top' ) + .selectOption( 'Edit' ); + await page.locator( '#doaction' ).click(); + + await page + .locator( 'select[name="change_sale_price"]' ) + .selectOption( + 'Decrease existing sale price by (fixed amount or %):' + ); + await page + .getByPlaceholder( 'Enter sale price ($)' ) + .fill( `${ salePriceDecrease }%` ); + + await page.getByRole( 'button', { name: 'Update' } ).click(); + } ); + + await test.step( 'Verify products have a sale price', async () => { + for ( const product of products ) { + await page.goto( `product/${ product.slug }` ); + + const expectedSalePrice = ( + product.regular_price * + ( 1 - salePriceDecrease / 100 ) + ).toFixed( 2 ); + + await expect + .soft( + await page + .locator( 'ins' ) + .getByText( `$${ expectedSalePrice }` ) + .count() + ) + .toBeGreaterThan( 0 ); + } + } ); + } +); + +test( + 'increasing the sale price from 0 does not change the sale price when bulk editing products', + { tag: [ '@gutenberg', '@services' ] }, + async ( { page, api } ) => { + let product; + await api + .post( 'products', { + id: 0, + name: `Product _${ Date.now() }`, + type: 'simple', + regular_price: '100', + sale_price: '0', + manage_stock: true, + stock_quantity: 10, + stock_status: 'instock', + } ) + .then( ( response ) => { + product = response.data; + } ); + + const salePriceIncrease = 10; + + await test.step( 'Update products with the "Sale > Increase existing sale price" option', async () => { + await page.goto( `wp-admin/edit.php?post_type=product` ); + + await page.getByLabel( `Select ${ product.name }` ).click(); + + await page + .locator( '#bulk-action-selector-top' ) + .selectOption( 'Edit' ); + await page.locator( '#doaction' ).click(); + + await page + .locator( 'select[name="change_sale_price"]' ) + .selectOption( + 'Increase existing sale price by (fixed amount or %):' + ); + + await page + .getByPlaceholder( 'Enter sale price ($)' ) + .fill( `${ salePriceIncrease }%` ); + + await page.getByRole( 'button', { name: 'Update' } ).click(); + } ); + + await test.step( 'Verify products have a sale price', async () => { + await page.goto( `product/${ product.slug }` ); + + const expectedSalePrice = '$0.00'; + + await expect + .soft( + await page + .locator( 'ins' ) + .getByText( expectedSalePrice ) + .count() + ) + .toBeGreaterThan( 0 ); + } ); + } +);