Roasty
Roasty

Reputation: 57

Display selected BACS account from matching order item meta value using Woocommerce hooks

Based on "Select BACS account to show in thankyou page in WooCommerce" answer code to one of my questions, I have changed the Woocommerce core file "class-wc-gateway-bacs.php" In order to select the correct bank account displayed on thankyou page, that matches with the variation attribute of a purchased product.

I have added the next code to "class-wc-gateway-bacs.php" after line 255:

foreach ( $order->get_items() as $item ) {$sede = $item->get_meta("pa_sede");};
if ( $bacs_account->sort_code != $sede ) { continue; };

So the modified code section from bank_details() function, results as follows:

            foreach ( $bacs_accounts as $bacs_account ) {
                $bacs_account = (object) $bacs_account;

                foreach ( $order->get_items() as $item ) {$sede = $item->get_meta("pa_sede");};
                if ( $bacs_account->sort_code != $sede ) { continue; };

                if ( $bacs_account->account_name ) {
                    $account_html .= '<h3 class="wc-bacs-bank-details-account-name">' . wp_kses_post( wp_unslash( $bacs_account->account_name ) ) . ':</h3>' . PHP_EOL;
                }
                $account_html .= '<ul class="wc-bacs-bank-details order_details bacs_details">' . PHP_EOL;
                // BACS account fields shown on the thanks page and in emails.
                $account_fields = apply_filters(
                    'woocommerce_bacs_account_fields',
                    array(
                        'bank_name'      => array(
                            'label' => __( 'Bank', 'woocommerce' ),
                            'value' => $bacs_account->bank_name,
                        ),
                        'account_number' => array(
                            'label' => __( 'Account number', 'woocommerce' ),
                            'value' => $bacs_account->account_number,
                        ),
                        'sort_code'      => array(
                            'label' => $sortcode,
                            'value' => $bacs_account->sort_code,
                        ),
                        'iban'           => array(
                            'label' => __( 'IBAN', 'woocommerce' ),
                            'value' => $bacs_account->iban,
                        ),
                        'bic'            => array(
                            'label' => __( 'BIC', 'woocommerce' ),
                            'value' => $bacs_account->bic,
                        ),
                    ),
                    $order_id
                );
                foreach ( $account_fields as $field_key => $field ) {
                    if ( ! empty( $field['value'] ) ) {
                        $account_html .= '<li class="' . esc_attr( $field_key ) . '">' . wp_kses_post( $field['label'] ) . ': <strong>' . wp_kses_post( wptexturize( $field['value'] ) ) . '</strong></li>' . PHP_EOL;
                        $has_details   = true;
                    }
                }
                $account_html .= '</ul>';
            }

However, Is not a good practice and I would like to use a hooked function in the instead of messing with class-wc-gateway-bacs.php.

Any help will be appreciated.

Upvotes: 1

Views: 765

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254212

The following hooked function will avoid overwriting Woocommerce class-wc-gateway-bacs.php core file, using a specific variation attribute value from order items to display the matching bank account(s) in Woocommerce Order received page (thankyou):

add_filter( 'woocommerce_bacs_accounts', 'filter_woocommerce_bacs_accounts_callback', 10, 1 );
function filter_woocommerce_bacs_accounts_callback( $bacs_accounts ){
    if ( empty($bacs_accounts) ) {
        return $bacs_accounts; // Exit
    }

    if( is_wc_endpoint_url('order-received') ) {
        $endpoint = 'order-received';
    } elseif( is_wc_endpoint_url('view-order') ) {
        $endpoint = 'view-order';
    } else {
        return $bacs_accounts; // Exit
    }

    // Get the WC_Order Object
    $order = wc_get_order( get_query_var($endpoint) );

    $sort_codes = []; // Initializing variable array

    // Loop through order items
    foreach ( $order->get_items() as $item ) {
        $sort_codes[] = $item->get_meta("pa_sede");
    }

    if ( empty($sort_codes) ) {
        return $bacs_accounts; // Exit
    }

    // Loop through Bacs accounts
    foreach ( $bacs_accounts as $key => $bacs_account ) {
        $bacs_account = (object) $bacs_account;

        // Remove the non matching bank accounts
        if ( ! in_array($bacs_account->sort_code, $sort_codes ) ) {
            unset($bacs_accounts[$key]);
        }
    }
    return $bacs_accounts;
}

Code goes in function.php file of your active child theme (or active theme). Tested and work (it should work with your product attribute for variation pa_sede).

Upvotes: 2

Related Questions