web-dev-qa-db-fra.com

Créer une commande par programme avec des éléments de campagne dans Woocommerce

J'avais besoin de créer une commande Woocommerce par programme, mais l'utilisation de l '"ancien" Woocommerce en a fait une procédure très sale.

J'ai dû insérer manuellement toutes sortes d'enregistrements de base de données, en utilisant de nombreux appels update_post_meta.

Vous cherchez une meilleure solution.

24
Mattijs

Avec la dernière version de WooCommerce est possible, essayez ceci comme quelque chose comme

$address = array(
            'first_name' => 'Fresher',
            'last_name'  => 'StAcK OvErFloW',
            'company'    => 'stackoverflow',
            'email'      => '[email protected]',
            'phone'      => '777-777-777-777',
            'address_1'  => '31 Main Street',
            'address_2'  => '', 
            'city'       => 'Chennai',
            'state'      => 'TN',
            'postcode'   => '12345',
            'country'    => 'IN'
        );

        $order = wc_create_order();
        $order->add_product( get_product( '12' ), 2 ); //(get_product with id and next is for quantity)
        $order->set_address( $address, 'billing' );
        $order->set_address( $address, 'shipping' );
        $order->add_coupon('Fresher','10','2'); // accepted param $couponcode, $couponamount,$coupon_tax
        $order->calculate_totals();

Appelez ce code ci-dessus avec votre fonction, cela fonctionnera en conséquence.

Notez que cela ne fonctionne pas avec l'ancienne version de WooCommerce comme 2.1.12, cela ne fonctionne qu'à partir de 2.2 de WooCommerce.

J'espère que ça aide

43
Vignesh Pichamani

Avec la nouvelle version de WC 2, c'est beaucoup mieux.

Toutefois:

  • Je ne veux pas utiliser l'API REST, car je fais un appel directement depuis mon propre plugin WP. Je ne vois aucune utilité à faire une boucle pour mon localhost
  • Le ' WooCommerce REST API Client Library ' n'est pas utile pour moi car il est relayé sur le REST API et ce n'est pas le cas) prendre en charge un appel Créer une commande

Pour être honnête, les WooCom API Docs sont limités, peut-être sont-ils encore en train de le mettre à jour. Actuellement, ils ne me disent pas comment créer une nouvelle commande, quels paramètres sont nécessaires, etc.

Quoi qu'il en soit, j'ai compris comment créer une commande avec une commande en ligne (votre produit) en utilisant les classes et les fonctions utilisées par l'API REST et je veux la partager!

J'ai créé ma propre classe PHP:

class WP_MyPlugin_woocommerce
{

public static function init()
{
    // required classes to create an order
    require_once WOOCOMMERCE_API_DIR . 'class-wc-api-exception.php';
    require_once WOOCOMMERCE_API_DIR . 'class-wc-api-server.php';
    require_once WOOCOMMERCE_API_DIR . 'class-wc-api-resource.php';
    require_once WOOCOMMERCE_API_DIR . 'interface-wc-api-handler.php';
    require_once WOOCOMMERCE_API_DIR . 'class-wc-api-json-handler.php';
    require_once WOOCOMMERCE_API_DIR . 'class-wc-api-orders.php';
}

public static function create_order()
{
    global $wp;

    // create order
    $server = new WC_API_Server( $wp->query_vars['wc-api-route'] );
    $order = new WC_API_Orders( $server );

    $order_id = $order->create_order( array
    (
        'order'             => array
        (
           'status'            => 'processing'
        ,  'customer_id'       =>  get_current_user_id()
        // ,   'order_meta'        => array
        //     (
        //        'some order meta'         => 'a value
        //     ,   some more order meta'    => 1
        //     )
        ,   'shipping_address'        => array
            (
                'first_name'          => $firstname
            ,   'last_name'           => $lastname
            ,   'address_1'           => $address
            ,   'address_2'           => $address2
            ,   'city'                => $city
            ,   'postcode'            => $postcode
            ,   'state'               => $state
            ,   'country'             => $country
            )

        ,   'billing_address'        => array(..can be same as shipping )

        ,   'line_items'        => array
            (
                array
                (
                    'product_id'         => 258
                ,   'quantity'           => 1
                )
            )
        )
    ) );
    var_dump($order_id);
    die();
}
}

Important:

  • La constante 'WOOCOMMERCE_API_DIR' pointe vers '/ woocommerce/includes/api /' dans le répertoire de votre plugin.
  • La commande est attribuée à un client, dans mon cas, l'utilisateur actuellement connecté. Assurez-vous que votre utilisateur a un rôle qui a la capacité de lire, modifier, créer et supprimer des commandes. Mon rôle ressemble à ceci:

       $result = add_role(
        'customer'
    ,   __( 'Customer' )
    ,   array
        (
            'read'         => true
        // ,   'read_private_posts' => true
        // ,   'read_private_products' => true
        ,   'read_private_shop_orders' => true
        ,   'edit_private_shop_orders' => true
        ,   'delete_private_shop_orders' => true
        ,   'publish_shop_orders' => true
        // ,   'read_private_shop_coupons' => true
        ,   'edit_posts'   => false
        ,   'delete_posts' => false
        ,   'show_admin_bar_front' => false
        )
    );
    
  • Si vous souhaitez consulter les droits du directeur de magasin, cochez

    var_dump (get_option ('wp_user_roles'));

Ma fonction create_order crée bien une commande, avec le lineitem dans les tables order_items.

J'espère que je vous ai aidé, il m'a fallu un certain temps pour bien faire les choses.

7
Mattijs

2017-2019 pour WooCommerce 3 et supérieur

Woocommerce 3 a introduit des objets CRUD et il y a beaucoup de changements sur les articles de la commande… De plus, certaines méthodes WC_Order Sont désormais obsolètes comme add_coupon().

Voici une fonction qui permet de créer par programmation une commande bien avec toutes les données requises:

function create_wc_order( $data ){
    $gateways = WC()->payment_gateways->get_available_payment_gateways();
    $order    = new WC_Order();

    // Set Billing and Shipping adresses
    foreach( array('billing_', 'shipping_') as $type ) {
        foreach ( $data['address'] as $key => $value ) {
            if( $type === 'shipping_' && in_array( $key, array( 'email', 'phone' ) ) )
                continue;

            $type_key = $type.$key;

            if ( is_callable( array( $order, "set_{$type_key}" ) ) ) {
                $order->{"set_{$type_key}"}( $value );
            }
        }
    }

    // Set other details
    $order->set_created_via( 'programatically' );
    $order->set_customer_id( $data['user_id'] );
    $order->set_currency( get_woocommerce_currency() );
    $order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
    $order->set_customer_note( isset( $data['order_comments'] ) ? $data['order_comments'] : '' );
    $order->set_payment_method( isset( $gateways[ $data['payment_method'] ] ) ? $gateways[ $data['payment_method'] ] : $data['payment_method'] );

    // Line items
    foreach( $data['line_items'] as $line_item ) {
        $args = $line_item['args'];
        $product = wc_get_product( isset($args['variation_id']) && $args['variation_id'] > 0 ? $$args['variation_id'] : $args['product_id'] );
        $order->add_product( $product, $line_item['quantity'], $line_item['args'] );
    }

    $calculate_taxes_for = array(
        'country'  => $data['address']['country'],
        'state'    => $data['address']['state'],
        'postcode' => $data['address']['postcode'],
        'city'     => $data['address']['city']
    );

    // Coupon items
    if( isset($data['coupon_items'])){
        foreach( $data['coupon_items'] as $coupon_item ) {
            $order->apply_coupon(sanitize_title($coupon_item['code']));
        }
    }

    // Fee items
    if( isset($data['fee_items'])){
        foreach( $data['fee_items'] as $fee_item ) {
            $item = new WC_Order_Item_Fee();

            $item->set_name( $fee_item['name'] );
            $item->set_total( $fee_item['total'] );
            $tax_class = isset($fee_item['tax_class']) && $fee_item['tax_class'] != 0 ? $fee_item['tax_class'] : 0;
            $item->set_tax_class( $tax_class ); // O if not taxable

            $item->calculate_taxes($calculate_taxes_for);

            $item->save();
            $order->add_item( $item );
        }
    }

    // Set calculated totals
    $order->calculate_totals();

    // Save order to database (returns the order ID)
    $order_id = $order->save();

    // Update order status from pending to …
    if( isset($data['order_status']) ) {
        $order->update_status($data['order_status']['satus'], $data['order_status']['note']);
    }

    // Returns the order ID
    return $order_id;
}

Le code va dans le fichier function.php de votre thème enfant actif (ou thème actif) ou dans un fichier plugin.


EXEMPLE D'UTILISATION à partir d'un tableau de données:

create_wc_order( array(
    'address' => array(
        'first_name' => 'Fresher',
        'last_name'  => 'StAcK OvErFloW',
        'company'    => 'stackoverflow',
        'email'      => '[email protected]',
        'phone'      => '777-777-777-777',
        'address_1'  => '31 Main Street',
        'address_2'  => '',
        'city'       => 'Chennai',
        'state'      => 'TN',
        'postcode'   => '12345',
        'country'    => 'IN',
    ),
    'user_id'        => '',
    'order_comments' => '',
    'payment_method' => 'bacs',
    'order_status'   => array(
        'status' => 'on-hold',
        'note'   => '',
    ),
    'line_items' => array(
        array(
            'quantity' => 1,
            'args'     => array(
                'product_id'    => 37,
                'variation_id'  => '',
                'variation'     => array(),
            )
        ),
    ),
    'coupon_items' => array(
        array(
            'code'         => 'summer',
        ),
    ),
    'fee_items' => array(
        array(
            'name'      => 'Delivery',
            'total'     => 5,
            'tax_class' => 0, // Not taxable
        ),
    ),
) );
4
LoicTheAztec