155 lines
4.5 KiB
Markdown
155 lines
4.5 KiB
Markdown
# Outlet-Based Tax Calculation Implementation
|
||
|
||
## Overview
|
||
|
||
This document describes the implementation of outlet-based tax calculation in the order processing system. The system now uses the tax rate configured for each outlet instead of a hardcoded tax rate.
|
||
|
||
## Feature Description
|
||
|
||
Previously, the system used a hardcoded 10% tax rate for all orders. Now, the tax calculation is based on the `tax_rate` field configured for each outlet, allowing for different tax rates across different locations.
|
||
|
||
## Implementation Details
|
||
|
||
### 1. Order Processor Changes
|
||
|
||
The `OrderProcessorImpl` has been updated to:
|
||
|
||
- Accept an `OutletRepository` dependency
|
||
- Fetch outlet information to get the tax rate
|
||
- Calculate tax using the outlet's specific tax rate
|
||
- Recalculate tax when adding items to existing orders
|
||
|
||
### 2. Tax Calculation Logic
|
||
|
||
```go
|
||
// Get outlet information for tax rate
|
||
outlet, err := p.outletRepo.GetByID(ctx, req.OutletID)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("outlet not found: %w", err)
|
||
}
|
||
|
||
// Calculate tax using outlet's tax rate
|
||
taxAmount := subtotal * outlet.TaxRate
|
||
totalAmount := subtotal + taxAmount
|
||
```
|
||
|
||
### 3. Database Schema
|
||
|
||
The `outlets` table includes:
|
||
|
||
- `tax_rate`: Decimal field (DECIMAL(5,4)) for tax rate as a decimal (e.g., 0.085 for 8.5%)
|
||
- Constraint: `CHECK (tax_rate >= 0 AND tax_rate <= 1)` to ensure valid percentage
|
||
|
||
### 4. Tax Rate Examples
|
||
|
||
| Tax Rate (Decimal) | Percentage | Example Calculation |
|
||
|-------------------|------------|-------------------|
|
||
| 0.0000 | 0% | No tax |
|
||
| 0.0500 | 5% | $100 × 0.05 = $5.00 tax |
|
||
| 0.0850 | 8.5% | $100 × 0.085 = $8.50 tax |
|
||
| 0.1000 | 10% | $100 × 0.10 = $10.00 tax |
|
||
| 0.1500 | 15% | $100 × 0.15 = $15.00 tax |
|
||
|
||
### 5. API Usage
|
||
|
||
The tax calculation is automatic and transparent to the API consumer. When creating orders or adding items, the system:
|
||
|
||
1. Fetches the outlet's tax rate
|
||
2. Calculates tax based on the current subtotal
|
||
3. Updates the order with the correct tax amount
|
||
|
||
```json
|
||
{
|
||
"outlet_id": "uuid-of-outlet",
|
||
"order_items": [
|
||
{
|
||
"product_id": "uuid-of-product",
|
||
"quantity": 2
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
The response will include the calculated tax amount:
|
||
|
||
```json
|
||
{
|
||
"id": "order-uuid",
|
||
"outlet_id": "outlet-uuid",
|
||
"subtotal": 20.00,
|
||
"tax_amount": 1.70, // Based on outlet's tax rate
|
||
"total_amount": 21.70
|
||
}
|
||
```
|
||
|
||
### 6. Business Scenarios
|
||
|
||
#### Scenario 1: Different Tax Rates by Location
|
||
- **Downtown Location**: 8.5% tax rate
|
||
- **Suburban Location**: 6.5% tax rate
|
||
- **Airport Location**: 10.0% tax rate
|
||
|
||
#### Scenario 2: Tax-Exempt Locations
|
||
- **Wholesale Outlet**: 0% tax rate
|
||
- **Export Zone**: 0% tax rate
|
||
|
||
#### Scenario 3: Seasonal Tax Changes
|
||
- **Holiday Period**: Temporary tax rate adjustments
|
||
- **Promotional Period**: Reduced tax rates
|
||
|
||
### 7. Validation
|
||
|
||
The system includes several validation checks:
|
||
|
||
1. **Outlet Existence**: Verifies the outlet exists
|
||
2. **Tax Rate Range**: Database constraint ensures 0% ≤ tax rate ≤ 100%
|
||
3. **Tax Calculation**: Ensures positive tax amounts
|
||
|
||
### 8. Error Handling
|
||
|
||
Common error scenarios:
|
||
|
||
- `outlet not found`: When an invalid outlet ID is provided
|
||
- Database constraint violations for invalid tax rates
|
||
|
||
### 9. Testing
|
||
|
||
The implementation includes unit tests to verify:
|
||
|
||
- Correct tax calculation with different outlet tax rates
|
||
- Proper error handling for invalid outlets
|
||
- Tax recalculation when adding items to existing orders
|
||
|
||
### 10. Migration
|
||
|
||
The feature uses existing database schema from migration `000002_create_outlets_table.up.sql` which includes the `tax_rate` column.
|
||
|
||
### 11. Configuration
|
||
|
||
Outlet tax rates can be configured through:
|
||
|
||
1. **Outlet Creation API**: Set initial tax rate
|
||
2. **Outlet Update API**: Modify tax rate for existing outlets
|
||
3. **Database Direct Update**: For bulk changes
|
||
|
||
### 12. Future Enhancements
|
||
|
||
Potential improvements:
|
||
|
||
1. **Tax Rate History**: Track tax rate changes over time
|
||
2. **Conditional Tax Rates**: Different rates based on order type or customer type
|
||
3. **Tax Exemptions**: Support for tax-exempt customers or items
|
||
4. **Multi-Tax Support**: Support for multiple tax types (state, local, etc.)
|
||
5. **Tax Rate Validation**: Integration with tax authority APIs for rate validation
|
||
|
||
### 13. Performance Considerations
|
||
|
||
- Outlet information is fetched once per order creation/modification
|
||
- Tax calculation is performed in memory for efficiency
|
||
- Consider caching outlet information for high-volume scenarios
|
||
|
||
### 14. Compliance
|
||
|
||
- Tax rates should comply with local tax regulations
|
||
- Consider implementing tax rate validation against official sources
|
||
- Maintain audit trails for tax rate changes |