apskel-pos-backend/PRODUCT_VARIANT_PRICE_MODIFIER.md

127 lines
3.6 KiB
Markdown
Raw Normal View History

2025-07-18 20:10:29 +07:00
# Product Variant Price Modifier Implementation
## Overview
This document describes the implementation of price modifier functionality for product variants in the order processing system.
## Feature Description
When a product variant is specified in an order item, the system now automatically applies the variant's price modifier to the base product price. This allows for flexible pricing based on product variations (e.g., size upgrades, add-ons, etc.).
## Implementation Details
### 1. Order Processor Changes
The `OrderProcessorImpl` has been updated to:
- Accept a `ProductVariantRepository` dependency
- Fetch product variant information when `ProductVariantID` is provided
- Apply the price modifier to the base product price
- Use variant-specific cost if available
### 2. Price Calculation Logic
```go
// Base price from product
unitPrice := product.Price
unitCost := product.Cost
// Apply variant price modifier if specified
if itemReq.ProductVariantID != nil {
variant, err := p.productVariantRepo.GetByID(ctx, *itemReq.ProductVariantID)
if err != nil {
return nil, fmt.Errorf("product variant not found: %w", err)
}
// Verify variant belongs to the product
if variant.ProductID != itemReq.ProductID {
return nil, fmt.Errorf("product variant does not belong to the specified product")
}
// Apply price modifier
unitPrice += variant.PriceModifier
// Use variant cost if available, otherwise use product cost
if variant.Cost > 0 {
unitCost = variant.Cost
}
}
```
### 3. Database Schema
The `product_variants` table includes:
- `price_modifier`: Decimal field for price adjustments (+/- values)
- `cost`: Optional variant-specific cost
- `product_id`: Foreign key to products table
### 4. API Usage
When creating orders or adding items to existing orders, you can specify a product variant:
```json
{
"order_items": [
{
"product_id": "uuid-of-product",
"product_variant_id": "uuid-of-variant",
"quantity": 2,
"notes": "Extra large size"
}
]
}
```
### 5. Example Scenarios
#### Scenario 1: Size Upgrade
- Base product: Coffee ($3.00)
- Variant: Large (+$1.00 modifier)
- Final price: $4.00
#### Scenario 2: Add-on
- Base product: Pizza ($12.00)
- Variant: Extra cheese (+$2.50 modifier)
- Final price: $14.50
#### Scenario 3: Discount
- Base product: Sandwich ($8.00)
- Variant: Student discount (-$1.00 modifier)
- Final price: $7.00
## Validation
The system includes several validation checks:
1. **Variant Existence**: Verifies the product variant exists
2. **Product Association**: Ensures the variant belongs to the specified product
3. **Price Integrity**: Maintains positive pricing (base price + modifier must be >= 0)
## Error Handling
Common error scenarios:
- `product variant not found`: When an invalid variant ID is provided
- `product variant does not belong to the specified product`: When variant-product mismatch occurs
## Testing
The implementation includes unit tests to verify:
- Correct price calculation with variants
- Proper error handling for invalid variants
- Cost calculation using variant-specific costs
## Migration
The feature uses existing database schema from migration `000013_add_cost_to_product_variants.up.sql` which adds the `cost` column to the `product_variants` table.
## Future Enhancements
Potential improvements:
1. **Percentage-based modifiers**: Support for percentage-based price adjustments
2. **Conditional modifiers**: Modifiers that apply based on order context
3. **Bulk variant pricing**: Tools for managing variant pricing across products
4. **Pricing history**: Track price modifier changes over time