Implement card-based interface for ConfigurableKitProduct attributes
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>
This commit is contained in:
210
TESTING_GUIDE.md
Normal file
210
TESTING_GUIDE.md
Normal file
@@ -0,0 +1,210 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user