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
|