0
votes

I added an override function of the extended class of WC_Gateway_BACS. The function will update the status of the order from on-hold to processing. The problem is the email is missing the bank details now. Before I have the bank account number included on the email but after the customization, the email does not include it and I think it is because the order status is now processing.

Has anyone here did the same thing and come up with a solution? I included some images here of on-hold and processing emails. I like to add the account number to processing-email

class WC_Gateway_BACS_custom extends WC_Gateway_BACS {
    /**
     * Process the payment and return the result
     *
     * @access public
     * @param int $order_id
     * @return array
     */
    function process_payment( $order_id ) {
        global $woocommerce;
        $order = new WC_Order( $order_id );
        // Mark as processing (or anything you want)
        $order->update_status('processing', __( 'Awaiting BACS payment', 'woocommerce' ));

        // Reduce stock levels
        $order->reduce_order_stock();

        // Remove cart
        $woocommerce->cart->empty_cart();

        // Return thankyou redirect
        return array(
            'result'  => 'success',
            'redirect'  => $this->get_return_url( $order )
        );
    }

    /**
     * Add content to the WC emails.
     *
     * @param WC_Order $order
     * @param bool $sent_to_admin
     * @param bool $plain_text
     */
    // public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {

    //  if ( ! $sent_to_admin && 'bacs' === $order->payment_method && ($order->has_status( 'on-hold' ) || $order->has_status( 'processing' )) ) {
    //      if ( $this->instructions ) {
    //          echo wpautop( wptexturize( $this->instructions ) ) . PHP_EOL;
    //      }
    //      $this->bank_details( $order->id );
    //  }

    // }
}

on-hold email processing email

1

1 Answers

0
votes

I actually ran into the same issue today. I came up with two possible solutions:

Extending the class, as you did above:

/* override gateway for BACS */
function my_core_gateways($methods)
{
  foreach ($methods as &$method){
    if($method == 'WC_Gateway_BACS')
    {
      $method = 'WC_Gateway_BACS_custom';
    }
  }
  return $methods;
}

/* custom gateway processor for BACS */
class WC_Gateway_BACS_custom extends WC_Gateway_BACS
{

    /**
     * Add content to the WC emails.
     *
     * @param WC_Order $order
     * @param bool $sent_to_admin
     * @param bool $plain_text
     */
    public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {

        if ( ! $sent_to_admin && 'bacs' === $order->payment_method && $order->has_status( 'processing' ) ) {
            if ( $this->instructions ) {
                echo wpautop( wptexturize( $this->instructions ) ) . PHP_EOL;
            }

      /* dirty hack to get access to bank_details */
      $reflector = new ReflectionObject($this);
      $method = $reflector->getMethod('bank_details');
      $method->setAccessible(true);

      $result = $method->invoke($this, $order->id);
        }
    }

    /**
     * Process the payment and return the result.
     *
     * @param int $order_id
     * @return array
     */
    public function process_payment( $order_id ) {

        $order = wc_get_order( $order_id );

        // Mark as on-hold (we're awaiting the payment)
        $order->update_status( 'processing', __( 'Awaiting BACS payment', 'woocommerce' ) );

        // Reduce stock levels
        $order->reduce_order_stock();

        // Remove cart
        WC()->cart->empty_cart();

        // Return thankyou redirect
        return array(
            'result'    => 'success',
            'redirect'  => $this->get_return_url( $order )
        );
    }
}

Or, cleaner in my opinion, by adding two actions

add_action( 'woocommerce_email_before_order_table', 'add_order_email_instructions', 10, 2 );
add_action( 'woocommerce_thankyou', 'bacs_order_payment_processing_order_status', 10, 1 );

function bacs_order_payment_processing_order_status( $order_id ) 
{
  if ( ! $order_id ) {
    return;
  }

  $order = new WC_Order( $order_id );

  if ('bacs' === $order->payment_method && ('on-hold' == $order->status || 'pending' == $order->status)) {
    $order->update_status('processing');
  } else {
    return;
  }
}

function add_order_email_instructions( $order, $sent_to_admin ) {

  if ( ! $sent_to_admin && 'bacs' === $order->payment_method && $order->has_status( 'processing' ) ) {
    $gw = new WC_Gateway_BACS();

    $reflector = new ReflectionObject($gw);
    $method = $reflector->getMethod('bank_details');
    $method->setAccessible(true);

    $result = $method->invoke($gw, $order->id);
  }
}

The second solution has the least maintenance requirements in the long run.