# Add to Cart Functionality in Diamond Search WooCommerce Plugin

## Introduction

This document provides a detailed explanation of how the "Add to Cart" functionality works in the Diamond Search WooCommerce plugin. The plugin integrates with WooCommerce to allow users to add diamonds (searched from an external database) to their shopping cart. Diamonds are treated as dynamic products: if a diamond doesn't exist as a WooCommerce product, the plugin creates one on-the-fly with attributes, images, pricing, and descriptions derived from the diamond's data.

The goal of this document is to serve as a guiding reference for implementing similar logic in a different plugin focused on jewelry (e.g., rings, necklaces) instead of diamonds. Key adaptations for jewelry are noted throughout.

**Key Components Involved:**
- **Frontend JS**: Handles user interactions (e.g., clicking "Add to Cart").
- **Backend PHP**: Manages AJAX requests, product creation, cart addition, and validation.
- **WooCommerce Integration**: Uses WooCommerce hooks and APIs for cart and product management.
- **Database**: Pulls diamond data from an SQLite database (adaptable to any data source for jewelry).

**Assumptions**:
- WooCommerce is active.
- The plugin has access to diamond/jewelry data (e.g., SKU, price, attributes like shape/color/carat for diamonds; adapt to metal/type/gemstone for jewelry).

## Overview of the Add to Cart Process

The process starts when a user clicks "Add to Cart" on a diamond in the search results or details page. An AJAX request is sent to the server, which:
1. Fetches diamond data by SKU.
2. Checks if the diamond is already in the cart (to prevent duplicates).
3. Creates or retrieves a WooCommerce product for the diamond.
4. Adds the product to the WooCommerce cart.
5. Validates inventory and availability during checkout.

For jewelry adaptation:
- Replace "diamond" with "jewelry item" (e.g., use item ID instead of SKU).
- Customize attributes (e.g., instead of carat/clarity, use weight/material).

## Workflow Diagram

Below is a Mermaid flowchart illustrating the high-level workflow.

```mermaid
graph TD
    A[User Clicks 'Add to Cart' on Frontend] --> B[JS: Send AJAX Request with SKU]
    B --> C[PHP: Handle AJAX (ajax_add_to_cart)]
    C --> D[Fetch Diamond Data by SKU]
    D --> E{Is Diamond Available?}
    E -->|No| F[Return Error Response]
    E -->|Yes| G[Check if Already in Cart]
    G -->|Yes| H[Return 'Already in Cart' Response]
    G -->|No| I[Get or Create WooCommerce Product]
    I --> J[Add Product to WooCommerce Cart]
    J --> K{Added Successfully?}
    K -->|Yes| L[Return Success Response with Cart URL]
    K -->|No| M[Return Error Response]
    L --> N[Frontend: Show Success Message / Redirect to Cart]
    J --> O[Hook: Validate Inventory on Checkout]
    O --> P[Mark as Sold on Order Completion]
```

### Explanation of Workflow Steps
1. **User Interaction**: Triggered by a button click in `diamond-search.js`.
2. **AJAX Handling**: Server-side validation and product creation in `class-cart-integration.php`.
3. **Product Creation**: Dynamic generation of WooCommerce products.
4. **Cart Addition**: Uses WooCommerce's `WC()->cart->add_to_cart()`.
5. **Validation Hooks**: Ensures availability during checkout and post-purchase.

## Detailed Steps

### 1. Frontend Trigger (JavaScript)
- In `assets/js/diamond-search.js`, the `addToCart(sku)` method is called when the user clicks the "Add to Cart" button.
- It sends an AJAX POST request to WooCommerce's AJAX endpoint with the diamond SKU.
- Handles responses: success (redirect to cart), error (show message), or already in cart.

**Code Example (from diamond-search.js)**:
```javascript
// assets/js/diamond-search.js (excerpt)
addToCart(sku) {
    this.showLoading(true);
    jQuery.ajax({
        type: 'POST',
        url: diamondSearch.ajax_url,
        data: {
            action: 'add_to_cart_diamondsearch',
            nonce: diamondSearch.nonce,
            sku: sku
        },
        success: (response) => {
            if (response.success) {
                // Show success message or redirect to cart
                window.location.href = response.data.cart_url;
            } else if (response.data.already_in_cart) {
                alert('This diamond is already in your cart.');
            } else {
                alert(response.data.message || 'Error adding to cart.');
            }
        },
        error: () => {
            alert('Network error. Please try again.');
        },
        complete: () => {
            this.showLoading(false);
        }
    });
}
```

**Jewelry Adaptation**: Change `sku` to `item_id`. Add custom data (e.g., size, color) to the AJAX payload.

### 2. AJAX Handler (PHP)
- In `includes/class-cart-integration.php`, `ajax_add_to_cart()` processes the request.
- Verifies nonce, fetches diamond data, and calls `add_diamond_to_cart()`.

**Code Example**:
```php
// includes/class-cart-integration.php (excerpt)
public function ajax_add_to_cart() {
    check_ajax_referer('diamond_search_nonce', 'nonce');
    $diamond_sku = sanitize_text_field($_POST['sku']);
    $result = $this->add_diamond_to_cart($diamond_sku);

    if (is_wp_error($result)) {
        wp_send_json_error(['message' => $result->get_error_message()]);
    } else {
        wp_send_json_success(['cart_url' => wc_get_cart_url()]);
    }
}
```

**Jewelry Adaptation**: Fetch jewelry data from your database/API instead of diamond-specific queries.

### 3. Fetch Data and Check Cart
- `add_diamond_to_cart($diamond_sku)` fetches data using `Diamond_Search_DB_Manager::get_diamond_by_sku($sku)`.
- Checks if the item is already in the cart via `check_diamond_in_cart($diamond_sku)` (iterates through cart items).

**Code Example**:
```php
// includes/class-cart-integration.php (excerpt)
private function check_diamond_in_cart($diamond_sku) {
    foreach (WC()->cart->get_cart() as $cart_item) {
        if (isset($cart_item['diamond_sku']) && $cart_item['diamond_sku'] === $diamond_sku) {
            return true;
        }
    }
    return false;
}
```

**Jewelry Adaptation**: Use a custom meta key like `jewelry_id` instead of `diamond_sku`.

### 4. Create or Get WooCommerce Product
- `get_or_create_diamond_product($diamond_data)` checks for an existing product by SKU.
- If not found, calls `create_diamond_product($diamond_data)` to insert a new WooCommerce product.
- Sets attributes, images, price, etc., dynamically.

**Code Example**:
```php
// includes/class-cart-integration.php (excerpt)
private function create_diamond_product($diamond_data) {
    $product = new WC_Product_Simple();
    $product->set_name($this->generate_product_title($diamond_data));
    $product->set_description($this->generate_description($diamond_data));
    $product->set_short_description($this->generate_short_description($diamond_data));
    $product->set_regular_price($this->round_price($diamond_data['price']));
    $product->set_sku($diamond_data['sku']);
    $product->set_virtual(true); // Diamonds are virtual products
    $product->set_manage_stock(true);
    $product->set_stock_quantity(1); // Only one unique diamond
    $product->set_stock_status('instock');
    $product_id = $product->save();

    $this->add_diamond_attributes($product, $diamond_data);
    $this->attach_product_images($product, $diamond_data);

    return $product_id;
}
```

**Jewelry Adaptation**: For physical jewelry, set `set_virtual(false)` and manage real stock quantities. Customize title/description generators for jewelry attributes (e.g., "Gold Necklace with Ruby Gemstone").

### 5. Add to Cart and Validation
- Uses WooCommerce's `WC()->cart->add_to_cart($product_id, 1, 0, [], ['diamond_sku' => $diamond_sku])`.
- Hooks into `woocommerce_checkout_process` for inventory validation.
- On order completion (`woocommerce_order_status_completed`), marks the diamond as sold.

**Code Example (Validation Hook)**:
```php
// includes/class-cart-integration.php (excerpt)
public function validate_checkout_inventory() {
    foreach (WC()->cart->get_cart() as $cart_item) {
        if (isset($cart_item['diamond_sku'])) {
            $diamond_data = Diamond_Search_DB_Manager::get_instance()->get_diamond_by_sku($cart_item['diamond_sku']);
            if (!$this->validate_diamond_availability($diamond_data)) {
                wc_add_notice(__('Sorry, one of the diamonds in your cart is no longer available.', 'diamond-search'), 'error');
            }
        }
    }
}
```

**Jewelry Adaptation**: For jewelry, check stock from your inventory system. Handle variations (e.g., sizes) using WooCommerce variable products.

### 6. Post-Purchase Handling
- `on_order_completed($order_id)` marks the diamond as sold (e.g., update database status).

**Jewelry Adaptation**: Update jewelry inventory (e.g., decrement stock).

## Code Examples Summary

- **Frontend**: AJAX call in JS to trigger addition.
- **Backend**: Dynamic product creation with WooCommerce APIs.
- **Validation**: Custom hooks to ensure uniqueness and availability.

## Adaptation for Jewelry Plugin

1. **Data Source**: Replace diamond database queries with jewelry API/database calls.
2. **Attributes**: Map diamond specs (carat, clarity) to jewelry (metal, gem type, size).
3. **Product Type**: Use physical products if jewelry is shippable; add shipping classes.
4. **Uniqueness**: For unique jewelry items, limit quantity to 1 and mark as sold post-purchase.
5. **Images**: Adapt image attachment logic to handle multiple jewelry photos.
6. **Pricing**: Include dynamic pricing based on jewelry customizations.
7. **Cart Key**: Use `jewelry_id` instead of `diamond_sku` for cart item data.

This logic ensures seamless integration with WooCommerce while handling dynamic, unique items. For implementation, start by cloning the `class-cart-integration.php` structure and customizing data handlers. 

## Simple Flow Diagram

Here's a simplified text-based diagram of the add-to-cart process:

```
User --> Click Add to Cart --> JS AJAX Request
   |
   v
Server: Verify Nonce & Fetch Data
   |
   v
Check if in Cart? --> Yes --> Return 'Already in Cart'
   | No
   v
Create/Get Product --> Add to WooCommerce Cart
   |
   v
Success? --> Yes --> Return Cart URL
   | No --> Error
   |
   v
Frontend: Redirect or Show Message
   |
   v
Checkout: Validate Inventory
   |
   v
Order Complete: Mark as Sold
```

This ASCII diagram provides a quick overview of the flow. For more details, refer to the Mermaid diagram above. 