WooCommerce : Autoriser les utilisateurs à modifier les commandes de traitement
Publié: 2018-12-18Comment les clients WooCommerce peuvent-ils modifier une commande qu'ils viennent de passer et de payer ? Je jure que j'ai regardé les résultats des moteurs de recherche et d'autres endroits avant de conclure que je devais coder moi-même.
Par exemple, un utilisateur peut souhaiter modifier la date de livraison (si vous l'indiquez sur la page de paiement). Ou peut-être ont-ils besoin de changer de taille ou de se décider sur un produit donné dans la commande.
Quoi qu'il en soit, cela me choque que cette fonctionnalité ne soit pas dans un plugin - comme d'habitude, si vous souhaitez personnaliser cet extrait/plugin pour vos besoins spécifiques, n'hésitez pas à nous contacter.
Alors, voyons comment c'est fait !

Extrait (PHP) : Autoriser les clients à modifier les commandes sur la page Mon compte WooCommerce
La première chose dont nous avons besoin est d' afficher le bouton "Modifier la commande" pour le traitement des commandes uniquement . Ici, je profite et réutilise simplement la fonctionnalité "Commander à nouveau" offerte par WooCommerce - cette "Commander à nouveau" duplique essentiellement la commande donnée et remplit le panier avec les mêmes produits et méta.
Si vous comprenez ce que je veux dire, "Modifier la commande" revient à dupliquer la commande que vous souhaitez modifier, à passer une nouvelle commande et à supprimer la précédente . Au moins c'est comme ça que je le vois et c'est définitivement plus facile de cette façon.
Afin d'afficher le bouton "Modifier la commande" pour le traitement des commandes, nous devons déverrouiller le bouton "Commander à nouveau" (filtre "woocommerce_valid_order_statuses_for_order_again"). Par défaut, cela ne s'affiche que pour les commandes terminées - nous avons également besoin d'un traitement (partie 1).
Maintenant, je peux imprimer le bouton "Modifier la commande" avec le filtre "woocommerce_my_account_my_orders_actions". Comme vous pouvez le voir, le "add_query_arg" doit avoir "order_again" pour que cliquer sur le bouton déclenche à nouveau une fonction de commande, et aussi j'ajoute un deuxième "add_query_arg" égal à "edit_order" pour que je sache que le bouton Modifier la commande a été cliqué et pas l'ordre à nouveau. Le bouton "nom" se transforme en "Modifier la commande" (partie 2).
Génial - maintenant le bouton s'affichera sous Mon compte > Commandes pour le traitement des commandes, et en cliquant cela redirigera vers une URL de panier qui contiendra un paramètre (et le panier sera rempli avec les mêmes produits, grâce au paramètre "order_again" ). Je peux maintenant simplement "écouter" cela et voir si le bouton a été cliqué pendant "woocommerce_cart_loaded_from_session". Je peux utiliser "$_GET" pour voir si l'URL contient des paramètres - et si oui, j'ajoute l'ID de commande modifié à la session de panier (partie 3).
Maintenant, je passe aux parties 4 et 5 : je veux montrer un avis de panier indiquant que le panier a été rempli avec les mêmes produits de la commande précédente, et aussi qu'un « crédit » a été appliqué au panier actuel sous forme de remise (« add_fee ») – oui, c'est une remise égale à la même valeur que le total de la commande payée précédemment.
Mise à jour janvier 2019 : veuillez noter que add_fee() ne fonctionne pas bien lorsque vous utilisez des montants négatifs ET que les taxes sont activées. Dans ce cas, vous devrez trouver une alternative.
Et puis nous passons à la dernière section, partie 6 : si le client passe la commande, nous devons clairement annuler la commande "modifiée" et afficher un avis dans la page d'administration de la commande des deux commandes, y compris un lien vers la commande concernée ( annulé ou nouveau, respectivement). Pour cela, j'utilise la fonction "add_order_note".

Eh bien, une longue explication, mais j'espère que cela est utile
/**
* @snippet Edit Order Functionality @ WooCommerce My Account Page
* @how-to Get CustomizeWoo.com FREE
* @sourcecode https://businessbloomer.com/?p=91893
* @author Rodolfo Melogli
* @compatible WooCommerce 4.1
* @donate $9 https://businessbloomer.com/bloomer-armada/
*/
// ----------------
// 1. Allow Order Again for Processing Status
add_filter( 'woocommerce_valid_order_statuses_for_order_again', 'bbloomer_order_again_statuses' );
function bbloomer_order_again_statuses( $statuses ) {
$statuses[] = 'processing';
return $statuses;
}
// ----------------
// 2. Add Order Actions @ My Account
add_filter( 'woocommerce_my_account_my_orders_actions', 'bbloomer_add_edit_order_my_account_orders_actions', 50, 2 );
function bbloomer_add_edit_order_my_account_orders_actions( $actions, $order ) {
if ( $order->has_status( 'processing' ) ) {
$actions['edit-order'] = array(
'url' => wp_nonce_url( add_query_arg( array( 'order_again' => $order->get_id(), 'edit_order' => $order->get_id() ) ), 'woocommerce-order_again' ),
'name' => __( 'Edit Order', 'woocommerce' )
);
}
return $actions;
}
// ----------------
// 3. Detect Edit Order Action and Store in Session
add_action( 'woocommerce_cart_loaded_from_session', 'bbloomer_detect_edit_order' );
function bbloomer_detect_edit_order( $cart ) {
if ( isset( $_GET['edit_order'], $_GET['_wpnonce'] ) && is_user_logged_in() && wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'woocommerce-order_again' ) ) WC()->session->set( 'edit_order', absint( $_GET['edit_order'] ) );
}
// ----------------
// 4. Display Cart Notice re: Edited Order
add_action( 'woocommerce_before_cart', 'bbloomer_show_me_session' );
function bbloomer_show_me_session() {
if ( ! is_cart() ) return;
$edited = WC()->session->get('edit_order');
if ( ! empty( $edited ) ) {
$order = new WC_Order( $edited );
$credit = $order->get_total();
wc_print_notice( 'A credit of ' . wc_price($credit) . ' has been applied to this new order. Feel free to add products to it or change other details such as delivery date.', 'notice' );
}
}
// ----------------
// 5. Calculate New Total if Edited Order
add_action( 'woocommerce_cart_calculate_fees', 'bbloomer_use_edit_order_total', 20, 1 );
function bbloomer_use_edit_order_total( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$edited = WC()->session->get('edit_order');
if ( ! empty( $edited ) ) {
$order = new WC_Order( $edited );
$credit = -1 * $order->get_total();
$cart->add_fee( 'Credit', $credit );
}
}
// ----------------
// 6. Save Order Action if New Order is Placed
add_action( 'woocommerce_checkout_update_order_meta', 'bbloomer_save_edit_order' );
function bbloomer_save_edit_order( $order_id ) {
$edited = WC()->session->get( 'edit_order' );
if ( ! empty( $edited ) ) {
// update this new order
update_post_meta( $order_id, '_edit_order', $edited );
$neworder = new WC_Order( $order_id );
$oldorder_edit = get_edit_post_link( $edited );
$neworder->add_order_note( 'Order placed after editing. Old order number: <a href="' . $oldorder_edit . '">' . $edited . '</a>' );
// cancel previous order
$oldorder = new WC_Order( $edited );
$neworder_edit = get_edit_post_link( $order_id );
$oldorder->update_status( 'cancelled', 'Order cancelled after editing. New order number: <a href="' . $neworder_edit . '">' . $order_id . '</a> -' );
WC()->session->set( 'edit_order', null );
}
}