Commit f3c1ec37ef6 for woocommerce

commit f3c1ec37ef65763ba309ab1818f253950de9b363
Author: Poli Gilad <83961704+poligilad-auto@users.noreply.github.com>
Date:   Fri May 22 10:31:26 2026 +0200

    Fix variation quick edit crashes and save errors in experimental products app (#65159)

    * Fix variations quick edit crashes and save errors

    * improve logic

    ---------

    Co-authored-by: Luigi Teschio <gigitux@gmail.com>

diff --git a/packages/js/experimental-products-app/src/product-edit/save.test.ts b/packages/js/experimental-products-app/src/product-edit/save.test.ts
index 8216736bb54..7ea31556909 100644
--- a/packages/js/experimental-products-app/src/product-edit/save.test.ts
+++ b/packages/js/experimental-products-app/src/product-edit/save.test.ts
@@ -189,6 +189,59 @@ describe( 'saveSelectedProducts', () => {
 		expect( request.data.images ).toBeUndefined();
 	} );

+	it( 'omits variation cost of goods when the defined value is null', async () => {
+		const editedVariation = buildVariation( {
+			id: 101,
+			cost_of_goods_sold: {
+				values: [
+					{
+						defined_value: null,
+						effective_value: '5.00',
+					},
+				],
+			},
+		} );
+		const editedParent = buildProduct( {
+			id: 10,
+			type: 'variable',
+			_embedded: {
+				variations: [ editedVariation ],
+			},
+		} );
+		const editEntityRecord = jest.fn(
+			(
+				_kind,
+				_name,
+				_recordId,
+				edits: Partial< ProductEntityRecord >
+			) => {
+				Object.assign( editedParent, edits );
+			}
+		);
+		const saveEditedEntityRecord = jest.fn( async () => editedParent );
+
+		mockGetEditedEntityRecord.mockImplementation( ( _kind, _name, id ) =>
+			id === editedParent.id ? editedParent : undefined
+		);
+		( apiFetch as unknown as jest.Mock ).mockResolvedValueOnce( {
+			id: 101,
+			parent_id: 10,
+			name: 'Blue saved',
+			manage_stock: false,
+		} );
+
+		await saveSelectedProducts( {
+			selectedProducts: [ editedVariation ],
+			editEntityRecord,
+			saveEditedEntityRecord,
+		} );
+
+		const request = ( apiFetch as unknown as jest.Mock ).mock
+			.calls[ 0 ][ 0 ];
+
+		expect( request.data.cost_of_goods_sold ).toBeUndefined();
+	} );
+
 	it( 'keeps edits for selected variations that failed after another variation saved', async () => {
 		const originalSavedVariation = buildVariation( {
 			id: 101,
diff --git a/packages/js/experimental-products-app/src/product-edit/save.ts b/packages/js/experimental-products-app/src/product-edit/save.ts
index 3daa8f09f93..4083eaa98e1 100644
--- a/packages/js/experimental-products-app/src/product-edit/save.ts
+++ b/packages/js/experimental-products-app/src/product-edit/save.ts
@@ -74,10 +74,16 @@ function getVariationImageSaveData(
 function getVariationSaveData(
 	variation: ProductEntityRecord
 ): ProductVariationSaveData {
-	const { images, ...data } = variation;
+	const { images, cost_of_goods_sold: costOfGoodsSold, ...data } = variation;
+	const hasNullCostOfGoodsSoldValue = costOfGoodsSold?.values?.some(
+		( value ) => value.defined_value === null
+	);

 	return {
 		...data,
+		...( ! hasNullCostOfGoodsSoldValue && costOfGoodsSold !== undefined
+			? { cost_of_goods_sold: costOfGoodsSold }
+			: {} ),
 		image: getVariationImageSaveData( images?.[ 0 ] ),
 	};
 }