This commit introduces a new user-friendly interface for managing product attributes:
1. **Form Changes** (products/forms.py):
- Removed 'option' field from ConfigurableKitOptionForm (values now inline)
- Updated ConfigurableKitProductAttributeFormSetCreate to only include name, position, visible
- Updated BaseConfigurableKitProductAttributeFormSet validation for new structure
2. **Template Updates** (products/templates/products/configurablekit_form.html):
- Replaced row-based attribute interface with card-based design
- Each card contains:
- Parameter name field
- Position field
- Visibility toggle
- Inline value inputs with add/remove buttons
- "Add parameter" button creates new cards
- "Add value" button adds inline value inputs
3. **JavaScript Enhancements**:
- addValueField(): Creates new value input with delete button
- initAddValueBtn(): Initializes add value button for each card
- addParameterBtn: Dynamically generates new parameter cards
- serializeAttributeValues(): Converts inline values to JSON for POST submission
- Form submission intercept to serialize data before sending
4. **View Updates** (products/views/configurablekit_views.py):
- Both Create and Update views now have _save_attributes_from_cards() method
- Reads attributes-X-values JSON from POST data
- Creates ConfigurableKitProductAttribute for each parameter+value combination
- Handles parameter deletion and visibility toggling
**Key Features**:
✓ One-time parameter name entry with multiple inline values
✓ Add/remove values without reloading page
✓ Add/remove entire parameters with one click
✓ No database changes required
✓ Better UX: card layout more intuitive than rows
✓ Proper JSON serialization for value transmission
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
211 lines
6.3 KiB
Markdown
211 lines
6.3 KiB
Markdown
# ConfigurableKitProduct Testing Guide
|
||
|
||
## Overview
|
||
The M2M architecture for variable products is now fully implemented. This guide walks through testing the complete workflow.
|
||
|
||
## Prerequisites
|
||
- Django project is running on `http://grach.localhost:8000/`
|
||
- You have at least 2-3 ProductKit objects in the database
|
||
- Admin panel is accessible
|
||
|
||
## Automated Tests
|
||
|
||
Run the test scripts to verify implementation:
|
||
|
||
```bash
|
||
cd myproject
|
||
|
||
# Test 1: Basic model and form verification
|
||
python test_configurable_simple.py
|
||
|
||
# Test 2: Complete workflow test
|
||
python test_workflow.py
|
||
```
|
||
|
||
Expected output: "OK: ALL TESTS PASSED!"
|
||
|
||
## Manual Testing - Full Workflow
|
||
|
||
### Step 1: Create a Variable Product
|
||
|
||
1. Open http://grach.localhost:8000/products/configurable-kits/create/
|
||
2. Fill in the form:
|
||
- **Name**: "Test Bouquet"
|
||
- **SKU**: "TEST-BQ-001"
|
||
- **Description**: "A test variable product"
|
||
|
||
### Step 2: Define Attributes
|
||
|
||
In the "Attributes" section, add attribute values:
|
||
|
||
1. **First Attribute Group** - "Length" (Длина)
|
||
- Click "Add Attribute"
|
||
- Name: Длина
|
||
- Value: 50
|
||
- Position: 0
|
||
- Click "Add Attribute" again
|
||
- Name: Длина
|
||
- Value: 60
|
||
- Position: 1
|
||
- Click "Add Attribute" again
|
||
- Name: Длина
|
||
- Value: 70
|
||
- Position: 2
|
||
|
||
2. **Second Attribute Group** - "Packaging" (Упаковка)
|
||
- Click "Add Attribute"
|
||
- Name: Упаковка
|
||
- Value: БЕЗ
|
||
- Position: 0
|
||
- Click "Add Attribute" again
|
||
- Name: Упаковка
|
||
- Value: В УПАКОВКЕ
|
||
- Position: 1
|
||
|
||
### Step 3: Create Variants
|
||
|
||
In the "Variants" section, create variants by:
|
||
|
||
1. **Variant 1** - Default variant
|
||
- Select a ProductKit (e.g., "Kit 1")
|
||
- Select attributes:
|
||
- Длина: 50
|
||
- Упаковка: БЕЗ
|
||
- Check "По умолчанию" (Default)
|
||
|
||
2. **Variant 2** - Alternative
|
||
- Click "Add Variant"
|
||
- Select a different ProductKit (e.g., "Kit 2")
|
||
- Select attributes:
|
||
- Длина: 60
|
||
- Упаковка: В УПАКОВКЕ
|
||
- Don't check default
|
||
|
||
3. **Variant 3** - Another alternative
|
||
- Click "Add Variant"
|
||
- Select yet another ProductKit (e.g., "Kit 3")
|
||
- Select attributes:
|
||
- Длина: 70
|
||
- Упаковка: БЕЗ
|
||
- Don't check default
|
||
|
||
### Step 4: Save and Verify
|
||
|
||
1. Click "Save"
|
||
2. If successful, you should see the product in the list
|
||
3. Click on it to edit and verify:
|
||
- All attributes are saved correctly
|
||
- All variants have their correct attribute values
|
||
- The default variant is marked correctly
|
||
|
||
## Testing Validation
|
||
|
||
### Test 1: Missing Attribute Validation
|
||
|
||
1. Edit the product you just created
|
||
2. Add a new variant
|
||
3. Select a ProductKit but leave one of the attribute dropdowns empty
|
||
4. Click Save
|
||
5. **Expected**: Form should show error: "Вариант X: необходимо заполнить атрибут(ы) 'Длина'."
|
||
|
||
### Test 2: Duplicate Kit Validation
|
||
|
||
1. Edit the product
|
||
2. Add a new variant with the same ProductKit as Variant 1
|
||
3. Click Save
|
||
4. **Expected**: Form should show error: "Комплект 'X' добавлен более одного раза."
|
||
|
||
### Test 3: Multiple Default Validation
|
||
|
||
1. Edit the product
|
||
2. Check the "Default" checkbox on Variant 2
|
||
3. Don't uncheck Variant 1's default
|
||
4. Click Save
|
||
5. **Expected**: Form should show error: "Можно установить только один вариант как 'по умолчанию'."
|
||
|
||
### Test 4: Dynamic Variant Addition
|
||
|
||
1. Click "Add Variant" button
|
||
2. A new form row should appear with:
|
||
- Kit dropdown
|
||
- All attribute dropdowns matching the first variant
|
||
- Default checkbox
|
||
- Delete button
|
||
3. **Expected**: All fields should be properly named with correct formset indices
|
||
|
||
## Database Verification
|
||
|
||
### Check M2M Relationships
|
||
|
||
```python
|
||
from django_tenants.utils import tenant_context
|
||
from tenants.models import Client
|
||
from products.models.kits import ConfigurableKitProduct, ConfigurableKitOptionAttribute
|
||
|
||
client = Client.objects.get(schema_name='grach')
|
||
|
||
with tenant_context(client):
|
||
# Get your test product
|
||
product = ConfigurableKitProduct.objects.get(name='Test Bouquet')
|
||
|
||
# Check attributes
|
||
attrs = product.parent_attributes.all()
|
||
print(f"Attributes: {attrs.count()}")
|
||
for attr in attrs:
|
||
print(f" - {attr.name} = {attr.option}")
|
||
|
||
# Check variants and their attributes
|
||
for option in product.options.all():
|
||
print(f"\nVariant for kit {option.kit.name}:")
|
||
for opt_attr in option.attributes_set.all():
|
||
print(f" - {opt_attr.attribute.name} = {opt_attr.attribute.option}")
|
||
```
|
||
|
||
## What to Check
|
||
|
||
- [ ] Product created successfully
|
||
- [ ] Attributes display in correct order
|
||
- [ ] Variants can be created with all required attributes
|
||
- [ ] Form validates missing attributes
|
||
- [ ] Form prevents duplicate kits
|
||
- [ ] Form prevents multiple default variants
|
||
- [ ] Dynamic variant addition works with all attribute fields
|
||
- [ ] Delete button removes variants correctly
|
||
- [ ] Data persists correctly after save
|
||
- [ ] Editing existing product pre-fills attribute selections
|
||
|
||
## Troubleshooting
|
||
|
||
### Template Error: "Unused 'attribute_' at end of if expression"
|
||
- **Fixed**: Changed `field.name.startswith 'attribute_'` to `"attribute_" in field.name`
|
||
- Already applied in the template
|
||
|
||
### Form Fields Not Showing for Attributes
|
||
- Check that parent product has attributes defined
|
||
- Verify `parent_attributes` are accessible in form __init__
|
||
- Check browser console for JavaScript errors
|
||
|
||
### M2M Relationships Not Saving
|
||
- Verify ConfigurableKitOptionAttribute model exists
|
||
- Check migration 0006 has been applied: `python manage.py migrate products`
|
||
- Verify view code properly creates ConfigurableKitOptionAttribute records
|
||
|
||
### Dynamic Variant Form Doesn't Show Attributes
|
||
- Check first form has attribute selects with `data-attribute-name` attribute
|
||
- Verify JavaScript addOptionBtn listener is working
|
||
- Check browser console for errors
|
||
|
||
## Performance Notes
|
||
|
||
- Attributes are indexed on option and attribute fields for fast queries
|
||
- Formset validation iterates through all forms and attributes
|
||
- For products with many attributes (>10), consider pagination
|
||
|
||
## Next Steps
|
||
|
||
After successful testing, you can:
|
||
1. Delete test products and attributes
|
||
2. Create real variable products in admin
|
||
3. Test WooCommerce integration (if applicable)
|
||
4. Monitor performance with actual product data
|