php - variacion - WooCommerce: crear un pedido mediante programación con un producto variable
variacion de precios woocommerce (3)
Estoy tratando de crear un orden programáticamente. Usar wc_create_order()
esto es bastante sencillo:
$myProduct = new WC_Product(100);
$order = wc_create_order();
$order->add_product($myProduct, 1);
$order->calculate_totals();
Esto funciona como se esperaba, y se crea una orden para un producto simple con ID 100 para la cantidad correcta.
Sin embargo, si trato de hacer esto con una variación, no parece comportarse correctamente. Después de mucho ensayo y error, lo hice para ordenarlo de esta manera:
$membershipProduct = new WC_Product_Variable(100);
$theMemberships = $membershipProduct->get_available_variations();
$trueProduct = new WC_Product(100);
$variationsArray = array();
foreach ($theMemberships as $membership) {
if ($membership[''sku''] == $chosenVariation) {
$variationID = $membership[''variation_id''];
$variationsArray = $membership[''attributes''];
}
}
if ($variationID) {
$trueProduct->variation_id = $variationID;
}
$order = wc_create_order();
$order->add_product($trueProduct, 1, $variationsArray);
$order->calculate_totals();
Sin embargo, aunque crea el pedido con el producto correcto y la ID de variación correcta, el total del pedido siempre es 0 (que, casualmente, es el precio de la primera variación).
Originalmente estaba intentando $order->add_product()
con el objeto creado a partir del new WC_Product_Variable()
, pero eso no dio como resultado la adición de ningún producto al pedido, lo que me lleva a pensar que es un problema crear órdenes programáticamente con productos variables . Sin embargo, siguiendo el código fuente de WooCommerce para estas llamadas, no puedo ver lo que estoy haciendo mal.
¿Hay algo que me falta, o una forma mejor de crear un pedido con un producto variable?
si ya tienes el variante_id, puedes hacer esto
$product_variation = new WC_Product_Variation($variation_id);
$order = wc_create_order();
$args=array();
foreach($product_variation->get_variation_attributes() as $attribute=>$attribute_value){
$args[''variation''][$attribute]=$attribute_value;
}
$order->add_product($product_variation, $product[''quantity''], $args);
Aquí está la solución que funcionó para mí:
function add_item_to_order( $order_id, $prod_id ) {
$order = wc_get_order( $order_id );
$_product = wc_get_product( $prod_id );
// Set values
$item = array();
$item[''product_id''] = $_product->id;
$item[''variation_id''] = isset( $_product->variation_id ) ? $_product->variation_id : '''';
$item[''variation_data''] = $item[''variation_id''] ? $_product->get_variation_attributes() : '''';
$item[''name''] = $_product->get_title();
$item[''tax_class''] = $_product->get_tax_class();
$item[''qty''] = 1;
$item[''line_subtotal''] = wc_format_decimal( $_product->get_price_excluding_tax() );
$item[''line_subtotal_tax''] = '''';
$item[''line_total''] = wc_format_decimal( $_product->get_price_excluding_tax() );
$item[''line_tax''] = '''';
$item[''type''] = ''line_item'';
// Add line item
$item_id = wc_add_order_item( $order_id, array(
''order_item_name'' => $item[''name''],
''order_item_type'' => ''line_item''
) );
// Add line item meta
if ( $item_id ) {
wc_add_order_item_meta( $item_id, ''_qty'', $item[''qty''] );
wc_add_order_item_meta( $item_id, ''_tax_class'', $item[''tax_class''] );
wc_add_order_item_meta( $item_id, ''_product_id'', $item[''product_id''] );
wc_add_order_item_meta( $item_id, ''_variation_id'', $item[''variation_id''] );
wc_add_order_item_meta( $item_id, ''_line_subtotal'', $item[''line_subtotal''] );
wc_add_order_item_meta( $item_id, ''_line_subtotal_tax'', $item[''line_subtotal_tax''] );
wc_add_order_item_meta( $item_id, ''_line_total'', $item[''line_total''] );
wc_add_order_item_meta( $item_id, ''_line_tax'', $item[''line_tax''] );
wc_add_order_item_meta( $item_id, ''_line_tax_data'', array(
''total'' => array(),
''subtotal'' => array() )
);
// Store variation data in meta
if ( $item[''variation_data''] && is_array( $item[''variation_data''] ) ) {
foreach ( $item[''variation_data''] as $key => $value ) {
wc_add_order_item_meta( $item_id, str_replace( ''attribute_'', '''', $key ), $value );
}
}
}
$item[''item_meta''] = $order->get_item_meta( $item_id );
$item[''item_meta_array''] = $order->get_item_meta_array( $item_id );
$item = $order->expand_item_meta( $item );
$order->calculate_totals();
}
Resuelto.
Aunque podría haber jurado que había intentado (y fallé) hacerlo de esta manera, la respuesta fue no agregar el producto padre ( $trueProduct
en el ejemplo), sino agregar el producto de variación por su ID .
Es posible que esto haya fallado anteriormente porque, como señaló @helgatheviking , my $variationsArray
se formateó incorrectamente de acuerdo con la fuente ; Necesitaba una matriz con una tecla [''variation'']
para enviar la matriz de variación de atributos correcta.
En total, mi código de trabajo ahora se ve así:
$membershipProduct = new WC_Product_Variable(100);
$theMemberships = $membershipProduct->get_available_variations();
$variationsArray = array();
foreach ($theMemberships as $membership) {
if ($membership[''sku''] == $chosenVariation) {
$variationID = $membership[''variation_id''];
$variationsArray[''variation''] = $membership[''attributes''];
}
}
if ($variationID) {
$varProduct = new WC_Product_Variation($variationID);
$order = wc_create_order();
$order->add_product($varProduct, 1, $variationsArray);
$order->calculate_totals();
}