Untitled

Anonymous
plain_text
09/14/2026 8:41 AM
18.6 KB
3
Indexable
<?php
/**
 * Plugin Name: Softhrive B2B Roles & Registration
 * Description: F9 — creates the 4 B2B/B2C roles and extends /my-account/register/ with an optional business registration toggle.
 * Version: 1.0.0
 * Author: Softhrive
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/* ---------------------------------------------------------
 * STEP 1 — Roles (created on activation)
 * retail_customer / wholesale_customer / reseller / pending_b2b
 * These exact slugs must never change — Odoo connector (F10) is
 * built around them.
 * ------------------------------------------------------- */
function softhrive_b2b_roles_create() {
    add_role( 'retail_customer', 'Retail Customer', array(
        'read' => true,
        'level_0' => true,
    ) );
    add_role( 'wholesale_customer', 'Wholesale Customer', array(
        'read' => true,
        'level_0' => true,
        'view_wholesale_pricing' => true,
    ) );
    add_role( 'reseller', 'Reseller', array(
        'read' => true,
        'level_0' => true,
        'view_reseller_pricing' => true,
    ) );
    add_role( 'pending_b2b', 'Pending B2B Approval', array(
        'read' => true,
        'level_0' => true,
    ) );
}
register_activation_hook( __FILE__, 'softhrive_b2b_roles_create' );

// Dev-only convenience: recreate roles if this file gets refreshed
// but WordPress doesn't re-fire activation (e.g. after a manual file
// overwrite without deactivate/activate).
add_action( 'admin_init', function() {
    if ( ! get_role( 'retail_customer' ) ) {
        softhrive_b2b_roles_create();
    }
} );

function softhrive_b2b_roles_remove() {
    remove_role( 'retail_customer' );
    remove_role( 'wholesale_customer' );
    remove_role( 'reseller' );
    remove_role( 'pending_b2b' );
}
register_deactivation_hook( __FILE__, 'softhrive_b2b_roles_remove' );

/* ---------------------------------------------------------
 * STEP 2 — Extend the registration form
 * ------------------------------------------------------- */
function softhrive_b2b_register_fields() {
    ?>
    <div class="softhrive-b2b-toggle-row">
        <label class="softhrive-b2b-toggle">
            <input type="checkbox" name="softhrive_is_b2b" id="softhrive_is_b2b" value="1" <?php echo ( ! empty( $_POST['softhrive_is_b2b'] ) ) ? 'checked' : ''; ?>>
            <span class="softhrive-b2b-toggle-track"><span class="softhrive-b2b-toggle-thumb"></span></span>
            <span class="softhrive-b2b-toggle-label">I'm registering as a business (B2B)</span>
        </label>
    </div>

    <div class="softhrive-b2b-fields" id="softhrive-b2b-fields">
        <p class="form-row form-row-wide">
            <label for="softhrive_company_name">Company name <span class="required">*</span></label>
            <input type="text" class="input-text" name="softhrive_company_name" id="softhrive_company_name"
                value="<?php echo ( ! empty( $_POST['softhrive_company_name'] ) ) ? esc_attr( wp_unslash( $_POST['softhrive_company_name'] ) ) : ''; ?>">
        </p>
        <p class="form-row form-row-first">
            <label for="softhrive_vat_number">VAT number <span class="optional">(optional)</span></label>
            <input type="text" class="input-text" name="softhrive_vat_number" id="softhrive_vat_number"
                value="<?php echo ( ! empty( $_POST['softhrive_vat_number'] ) ) ? esc_attr( wp_unslash( $_POST['softhrive_vat_number'] ) ) : ''; ?>">
        </p>
        <p class="form-row form-row-last">
            <label for="softhrive_business_type">Business type <span class="required">*</span></label>
            <select class="input-text" name="softhrive_business_type" id="softhrive_business_type">
                <option value="">Select one</option>
                 <option value="Wholesale">Wholesale Customer</option>
                <option value="Retail">Retail Customer</option>
                <option value="Reseller">Reseller</option>
             </select>
        </p>
        <p class="form-row form-row-wide">
            <label for="softhrive_phone">Contact number <span class="required">*</span></label>
            <input type="tel" class="input-text" name="softhrive_phone" id="softhrive_phone"
                value="<?php echo ( ! empty( $_POST['softhrive_phone'] ) ) ? esc_attr( wp_unslash( $_POST['softhrive_phone'] ) ) : ''; ?>">
        </p>
        <p class="softhrive-b2b-note">Your account will be reviewed before you can see wholesale pricing. We'll email you once it's approved.</p>
    </div>
    <?php
}
add_action( 'woocommerce_register_form', 'softhrive_b2b_register_fields' );

function softhrive_b2b_register_validation( $errors, $username, $email ) {
    if ( ! empty( $_POST['softhrive_is_b2b'] ) ) {
        if ( empty( $_POST['softhrive_company_name'] ) ) {
            $errors->add( 'softhrive_company_name_error', 'Please enter your company name.' );
        }
        if ( empty( $_POST['softhrive_business_type'] ) ) {
            $errors->add( 'softhrive_business_type_error', 'Please select your business type.' );
        }
        if ( empty( $_POST['softhrive_phone'] ) ) {
            $errors->add( 'softhrive_phone_error', 'Please enter a contact number.' );
        }
    }
    return $errors;
}
add_filter( 'woocommerce_registration_errors', 'softhrive_b2b_register_validation', 10, 3 );

function softhrive_b2b_save_registration( $customer_id ) {
    $user = new WP_User( $customer_id );

    if ( ! empty( $_POST['softhrive_is_b2b'] ) ) {
        update_user_meta( $customer_id, 'softhrive_company_name', sanitize_text_field( wp_unslash( $_POST['softhrive_company_name'] ?? '' ) ) );
        update_user_meta( $customer_id, 'softhrive_vat_number', sanitize_text_field( wp_unslash( $_POST['softhrive_vat_number'] ?? '' ) ) );
        update_user_meta( $customer_id, 'softhrive_business_type', sanitize_text_field( wp_unslash( $_POST['softhrive_business_type'] ?? '' ) ) );
        update_user_meta( $customer_id, 'softhrive_phone', sanitize_text_field( wp_unslash( $_POST['softhrive_phone'] ?? '' ) ) );
        $user->set_role( 'pending_b2b' );
        softhrive_b2b_notify_admin( $customer_id );
    } else {
        $user->set_role( 'retail_customer' );
    }
}
add_action( 'woocommerce_created_customer', 'softhrive_b2b_save_registration' );

/* ---------------------------------------------------------
 * STEP 3 — Approval workflow
 * ------------------------------------------------------- */

// 1. Admin gets emailed the moment a new B2B account registers
function softhrive_b2b_notify_admin( $customer_id ) {
    $user = get_userdata( $customer_id );
    if ( ! $user ) {
        return;
    }

    $company       = get_user_meta( $customer_id, 'softhrive_company_name', true );
    $business_type = get_user_meta( $customer_id, 'softhrive_business_type', true );
    $phone         = get_user_meta( $customer_id, 'softhrive_phone', true );
    $vat           = get_user_meta( $customer_id, 'softhrive_vat_number', true );
    $edit_link     = admin_url( 'user-edit.php?user_id=' . $customer_id );

    $subject = 'New B2B account awaiting approval — ' . $company;

    $message  = "A new business account has registered and needs review:\n\n";
    $message .= "Name: " . $user->display_name . "\n";
    $message .= "Email: " . $user->user_email . "\n";
    $message .= "Company: " . $company . "\n";
    $message .= "Business type: " . $business_type . "\n";
    $message .= "Phone: " . $phone . "\n";
    if ( $vat ) {
        $message .= "VAT number: " . $vat . "\n";
    }
    $message .= "\nTo approve: open the user, change their Role to \"Wholesale Customer\" or \"Reseller\", then Update.\n";
    $message .= "To reject: delete the user.\n\n";
    $message .= "Review here: " . $edit_link;

    wp_mail( get_option( 'admin_email' ), $subject, $message );
}

// 2. Customer gets emailed automatically the moment admin approves
// (i.e. changes their role from pending_b2b to wholesale_customer/reseller
// via the normal Users screen — set_user_role fires either way)
function softhrive_b2b_notify_customer_on_approval( $user_id, $role, $old_roles ) {
    $was_pending = in_array( 'pending_b2b', $old_roles, true );
    $now_approved = in_array( $role, array( 'wholesale_customer', 'reseller' ), true );

    if ( ! $was_pending || ! $now_approved ) {
        return;
    }

    $user = get_userdata( $user_id );
    if ( ! $user ) {
        return;
    }

    $subject = 'Your Twisted Hygiene business account has been approved';
    $message  = "Hi " . $user->display_name . ",\n\n";
    $message .= "Good news — your business account has been approved. You can now log in and see your wholesale pricing:\n\n";
    $message .= wc_get_page_permalink( 'myaccount' ) . "\n\n";
    $message .= "Thanks,\nTwisted Hygiene & Packaging";

    wp_mail( $user->user_email, $subject, $message );
}
add_action( 'set_user_role', 'softhrive_b2b_notify_customer_on_approval', 10, 3 );

/* ---------------------------------------------------------
 * Styling — matches the project's teal brand, scoped to the
 * WooCommerce register form only (login form untouched)
 * ------------------------------------------------------- */
function softhrive_b2b_register_assets() {
    if ( ! function_exists( 'is_account_page' ) || ! is_account_page() ) {
        return;
    }
    ?>
    <style>
        .woocommerce-form-register{
            background:#ffffff !important;
            border:1px solid #e5e7eb !important;
            border-radius:20px !important;
            padding:32px !important;
        }
        .softhrive-b2b-toggle-row{
            margin:22px 0 !important;
            padding:16px 18px !important;
            background:#f0fdfa !important;
            border:1px solid #d1fae5 !important;
            border-radius:12px !important;
        }
        .softhrive-b2b-toggle{
            display:flex !important;
            align-items:center !important;
            gap:12px !important;
            cursor:pointer !important;
            margin:0 !important;
            position:relative !important;
        }
        .softhrive-b2b-toggle input{
            position:absolute !important;
            opacity:0 !important;
            width:1px !important;
            height:1px !important;
        }
        .softhrive-b2b-toggle-track{
            width:42px !important;
            height:24px !important;
            border-radius:999px !important;
            background:#d1d5db !important;
            position:relative !important;
            flex-shrink:0 !important;
            transition:background .2s ease !important;
        }
        .softhrive-b2b-toggle-thumb{
            position:absolute !important;
            top:3px !important; left:3px !important;
            width:18px !important; height:18px !important;
            border-radius:50% !important;
            background:#ffffff !important;
            box-shadow:0 1px 3px rgba(0,0,0,.2) !important;
            transition:transform .2s ease !important;
        }
        .softhrive-b2b-toggle input:checked ~ .softhrive-b2b-toggle-track{
            background:#0d9488 !important;
        }
        .softhrive-b2b-toggle input:checked ~ .softhrive-b2b-toggle-track .softhrive-b2b-toggle-thumb{
            transform:translateX(18px) !important;
        }
        .softhrive-b2b-toggle-label{
            font-size:14.5px !important;
            font-weight:700 !important;
            color:#1f2937 !important;
        }
        .softhrive-b2b-fields{
            display:none;
            margin-top:18px;
        }
        .softhrive-b2b-fields.is-visible{
            display:block;
        }
        .woocommerce-form-register .form-row label{
            font-size:12.5px !important;
            font-weight:600 !important;
            color:#6b7280 !important;
            margin-bottom:6px !important;
            display:block !important;
        }
        .woocommerce-form-register .input-text,
        .woocommerce-form-register select{
            width:100% !important;
            border:1.5px solid #e5e7eb !important;
            border-radius:10px !important;
            padding:12px 14px !important;
            font-size:14px !important;
            font-family:inherit !important;
        }
        .woocommerce-form-register .input-text:focus,
        .woocommerce-form-register select:focus{
            outline:none !important;
            border-color:#0d9488 !important;
            box-shadow:0 0 0 3px rgba(13,148,136,.12) !important;
        }
        .softhrive-b2b-note{
            font-size:12.5px !important;
            color:#6b7280 !important;
            background:#f9fafb !important;
            border-radius:8px !important;
            padding:10px 14px !important;
            margin-top:6px !important;
        }
        .woocommerce-form-register button[type="submit"]{
            width:100% !important;
            height:52px !important;
            border:none !important;
            border-radius:14px !important;
            background:#0f8b8d !important;
            color:#fff !important;
            font-size:15px !important;
            font-weight:800 !important;
            box-shadow:0 15px 35px rgba(15,139,141,.2) !important;
            cursor:pointer !important;
        }
        .woocommerce-form-register button[type="submit"]:hover{
            background:#0b7c72 !important;
        }
    </style>
    <script>
    document.addEventListener('DOMContentLoaded', function () {
        var toggle = document.getElementById('softhrive_is_b2b');
        var fields = document.getElementById('softhrive-b2b-fields');
        if (!toggle || !fields) { return; }
        function sync() {
            fields.classList.toggle('is-visible', toggle.checked);
        }
        toggle.addEventListener('change', sync);
        sync();
    });
    </script>
    <?php
}
add_action( 'wp_footer', 'softhrive_b2b_register_assets' );
Editor is loading...
Leave a Comment