fix: customer search & linking fully implemented
- Add ajax_search_wc_customers() – searches user_login, user_email, display_name AND first_name/last_name meta so any query returns hits - Add ajax_unlink_customer() to remove an existing Odoo link - Replace placeholder Customers tab with two-panel UI: Step 1 search WC customers → Step 2 search Odoo partners independently (WC email and Odoo email do not need to match) - Results table shows current link status; inline Link/Unlink actions update the row in-place without page reload - Admin JS fully wired: both search inputs respond to Enter key and button - Add two-panel layout CSS and results table styles Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,9 @@ class WooDoo_Admin {
|
||||
// AJAX handlers (admin only)
|
||||
add_action( 'wp_ajax_woodoo_test_connection', [ __CLASS__, 'ajax_test_connection' ] );
|
||||
add_action( 'wp_ajax_woodoo_search_partners', [ __CLASS__, 'ajax_search_partners' ] );
|
||||
add_action( 'wp_ajax_woodoo_search_wc_customers',[ __CLASS__, 'ajax_search_wc_customers' ] );
|
||||
add_action( 'wp_ajax_woodoo_link_customer', [ __CLASS__, 'ajax_link_customer' ] );
|
||||
add_action( 'wp_ajax_woodoo_unlink_customer', [ __CLASS__, 'ajax_unlink_customer' ] );
|
||||
|
||||
// WC customer list column
|
||||
add_filter( 'manage_users_columns', [ __CLASS__, 'add_users_column' ] );
|
||||
@@ -91,10 +93,17 @@ class WooDoo_Admin {
|
||||
'nonce' => wp_create_nonce( 'woodoo_admin' ),
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'i18n' => [
|
||||
'testing' => __( 'Testing…', 'woodoo' ),
|
||||
'searching' => __( 'Searching…', 'woodoo' ),
|
||||
'link_done' => __( 'Linked!', 'woodoo' ),
|
||||
'error' => __( 'Error. Check console.', 'woodoo' ),
|
||||
'testing' => __( 'Testing…', 'woodoo' ),
|
||||
'searching' => __( 'Searching…', 'woodoo' ),
|
||||
'no_wc_customers' => __( 'No customers found.', 'woodoo' ),
|
||||
'no_odoo_partners' => __( 'No Odoo partners found.', 'woodoo' ),
|
||||
'link_done' => __( 'Linked!', 'woodoo' ),
|
||||
'unlink_confirm' => __( 'Remove the Odoo link for this customer?', 'woodoo' ),
|
||||
'unlinked' => __( 'Unlinked', 'woodoo' ),
|
||||
'error' => __( 'Error. Check console.', 'woodoo' ),
|
||||
'search_odoo' => __( 'Search Odoo partners…', 'woodoo' ),
|
||||
'linked_to' => __( 'Linked to', 'woodoo' ),
|
||||
'not_linked' => __( 'Not linked', 'woodoo' ),
|
||||
],
|
||||
] );
|
||||
}
|
||||
@@ -230,12 +239,35 @@ class WooDoo_Admin {
|
||||
<!-- Customer Linking Tab -->
|
||||
<div id="tab-customers" class="woodoo-tab" style="display:none;">
|
||||
<h2><?php esc_html_e( 'Customer Linking', 'woodoo' ); ?></h2>
|
||||
<p><?php esc_html_e( 'Link WooCommerce customers to their Odoo partner record. You can also edit this from each user\'s profile page.', 'woodoo' ); ?></p>
|
||||
<p><?php esc_html_e( 'Search a WooCommerce customer, then search and pick their matching Odoo partner. Emails do not need to match.', 'woodoo' ); ?></p>
|
||||
|
||||
<div class="woodoo-customer-linker">
|
||||
<label><?php esc_html_e( 'Search WooCommerce Customer:', 'woodoo' ); ?></label>
|
||||
<input type="text" id="woo-customer-search" class="regular-text" placeholder="<?php esc_attr_e( 'Customer name or email…', 'woodoo' ); ?>">
|
||||
<div id="woo-customer-results"></div>
|
||||
<div class="woodoo-linker-panel">
|
||||
<div class="woodoo-linker-col">
|
||||
<h3><?php esc_html_e( '1. Find WooCommerce Customer', 'woodoo' ); ?></h3>
|
||||
<div class="woodoo-search-row">
|
||||
<input type="text" id="woo-customer-search"
|
||||
class="regular-text"
|
||||
placeholder="<?php esc_attr_e( 'Name or email…', 'woodoo' ); ?>">
|
||||
<button type="button" id="woo-customer-search-btn" class="button button-secondary">
|
||||
<?php esc_html_e( 'Search', 'woodoo' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="woo-customer-results" class="woodoo-results-list"></div>
|
||||
</div>
|
||||
|
||||
<div class="woodoo-linker-col" id="woodoo-odoo-col" style="display:none;">
|
||||
<h3><?php esc_html_e( '2. Find Odoo Partner', 'woodoo' ); ?></h3>
|
||||
<p id="woodoo-linking-for" class="woodoo-linking-for"></p>
|
||||
<div class="woodoo-search-row">
|
||||
<input type="text" id="woodoo-odoo-partner-search"
|
||||
class="regular-text"
|
||||
placeholder="<?php esc_attr_e( 'Name or email…', 'woodoo' ); ?>">
|
||||
<button type="button" id="woodoo-odoo-partner-search-btn" class="button button-secondary">
|
||||
<?php esc_html_e( 'Search', 'woodoo' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="woodoo-odoo-partner-results" class="woodoo-results-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -399,4 +431,81 @@ class WooDoo_Admin {
|
||||
'partner_name' => $partners[0]['name'],
|
||||
] );
|
||||
}
|
||||
|
||||
public static function ajax_unlink_customer(): void {
|
||||
check_ajax_referer( 'woodoo_admin', 'nonce' );
|
||||
if ( ! current_user_can( 'edit_users' ) ) wp_send_json_error( 'Forbidden', 403 );
|
||||
|
||||
$user_id = absint( $_POST['user_id'] ?? 0 );
|
||||
if ( ! $user_id ) wp_send_json_error( 'Invalid user ID' );
|
||||
|
||||
delete_user_meta( $user_id, 'woodoo_odoo_partner_id' );
|
||||
delete_user_meta( $user_id, 'woodoo_odoo_partner_name' );
|
||||
|
||||
wp_send_json_success( [ 'user_id' => $user_id ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Search WooCommerce customers by name or email.
|
||||
* Searches user_login, user_email, display_name in the users table,
|
||||
* AND first_name / last_name in user meta — so the email in WC doesn't
|
||||
* need to match Odoo at all.
|
||||
*/
|
||||
public static function ajax_search_wc_customers(): void {
|
||||
check_ajax_referer( 'woodoo_admin', 'nonce' );
|
||||
if ( ! current_user_can( 'edit_users' ) ) wp_send_json_error( 'Forbidden', 403 );
|
||||
|
||||
$q = sanitize_text_field( wp_unslash( $_POST['query'] ?? '' ) );
|
||||
if ( strlen( $q ) < 2 ) wp_send_json_error( 'Query too short' );
|
||||
|
||||
// Search main user table columns
|
||||
$query1 = new WP_User_Query( [
|
||||
'search' => '*' . $q . '*',
|
||||
'search_columns' => [ 'user_login', 'user_email', 'display_name' ],
|
||||
'number' => 20,
|
||||
'fields' => 'all',
|
||||
] );
|
||||
|
||||
// Search first_name / last_name meta fields
|
||||
$query2 = new WP_User_Query( [
|
||||
'number' => 20,
|
||||
'fields' => 'all',
|
||||
'meta_query' => [
|
||||
'relation' => 'OR',
|
||||
[ 'key' => 'first_name', 'value' => $q, 'compare' => 'LIKE' ],
|
||||
[ 'key' => 'last_name', 'value' => $q, 'compare' => 'LIKE' ],
|
||||
],
|
||||
] );
|
||||
|
||||
// Merge and deduplicate
|
||||
$all = array_merge( $query1->get_results(), $query2->get_results() );
|
||||
$seen = [];
|
||||
$users = [];
|
||||
foreach ( $all as $user ) {
|
||||
if ( isset( $seen[ $user->ID ] ) ) continue;
|
||||
$seen[ $user->ID ] = true;
|
||||
$users[] = $user;
|
||||
}
|
||||
|
||||
if ( empty( $users ) ) {
|
||||
wp_send_json_success( [] );
|
||||
}
|
||||
|
||||
$results = [];
|
||||
foreach ( $users as $user ) {
|
||||
$partner_id = (int) get_user_meta( $user->ID, 'woodoo_odoo_partner_id', true );
|
||||
$partner_name = get_user_meta( $user->ID, 'woodoo_odoo_partner_name', true );
|
||||
|
||||
$results[] = [
|
||||
'id' => $user->ID,
|
||||
'display_name' => $user->display_name,
|
||||
'email' => $user->user_email,
|
||||
'partner_id' => $partner_id ?: null,
|
||||
'partner_name' => $partner_name ?: null,
|
||||
'edit_url' => esc_url( get_edit_user_link( $user->ID ) ),
|
||||
];
|
||||
}
|
||||
|
||||
wp_send_json_success( $results );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user