Ok, so I was being dumb.
We just have to pass a second argument to woocommerce_bacs_accounts
which is the order_id. And as the filter runs inside the order_email it will apply the same rules.
add_filter( 'woocommerce_bacs_accounts', 'filter_woocommerce_bacs_accounts_callback', 10, 2 );
function filter_woocommerce_bacs_accounts_callback( $bacs_accounts, $order_id ){
if ( empty($bacs_accounts) ) {
return $bacs_accounts; // Exit
}
if( is_wc_endpoint_url('order-received') ) {
$endpoint = 'order-received';
// Get the WC_Order Object
$order = wc_get_order( get_query_var($endpoint) );
} elseif( is_wc_endpoint_url('view-order') ) {
$endpoint = 'view-order';
// Get the WC_Order Object
$order = wc_get_order( get_query_var($endpoint) );
} else if ($order_id){
// Get the WC_Order Object
$order = wc_get_order($order_id );
}
$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;
}