The SalesPriceProvider manages the state and business logic for calculating sales prices based on cost and profit margins. It supports both markup (profit on cost) and margin (profit on sales) calculations.
Overview
This provider handles two types of profit calculations:
- Markup: Calculate profit as a percentage of cost (e.g., 50% markup on 100cost=150 selling price)
- Margin: Calculate profit as a percentage of selling price (e.g., 50% margin means cost is 50% of selling price)
All inputs are persisted across app sessions using SharedPreferences.
Enums
MarginType
Defines the method of profit calculation.
enum MarginType {
markup,
margin,
}
Calculate profit as a percentage of cost (Profit / Cost × 100)
Calculate profit as a percentage of sales price (Profit / Sales Price × 100)
Constructor
SalesPriceProvider(SharedPreferences prefs)
prefs
SharedPreferences
required
The SharedPreferences instance used for persisting calculator state
Getters
Calculation Results
The selling price before tax (cost + profit)
The final selling price including tax
The dollar amount of profit on this sale
The calculated tax amount based on the base sale price
Error message if validation fails, null otherwise
Configuration
The current profit calculation method (markup or margin)
The persisted cost input string
The persisted profit percentage input string
The persisted tax percentage input string
Methods
calculatePrice
Calculates the sales price based on cost and profit percentage.
void calculatePrice({
required String costStr,
required String profitPercentStr,
String taxStr = '0',
})
The base cost of the product
The desired profit percentage (interpreted based on marginType)
Optional tax percentage to apply to the base sale price
For Markup (Profit on Cost):
profitAmount = cost × (profitPercent / 100)
baseSalePrice = cost + profitAmount
Example: $100 cost with 50% markup:
- Profit = 100×0.50=50
- Sale Price = 100+50 = $150
For Margin (Profit on Sales):
baseSalePrice = cost / (1 - (profitPercent / 100))
profitAmount = baseSalePrice - cost
Example: $100 cost with 50% margin:
- Sale Price = 100/(1−0.50)=200
- Profit = 200−100 = $100
Tax Calculation:
taxAmount = baseSalePrice × (taxPercent / 100)
finalPrice = baseSalePrice + taxAmount
Validation
The method validates:
- All numeric inputs are valid numbers
- No negative values
- For margin calculation: profit percentage must be less than 100%
If validation fails, errorMessage is set and results are cleared.
setMarginType
Changes the margin calculation type and persists the selection.
void setMarginType(MarginType type)
The new margin type to use for calculations
This method automatically persists the selection to SharedPreferences and notifies listeners.
clear
Resets all inputs and calculation results.
This method:
- Clears all input strings
- Removes persisted values from SharedPreferences
- Clears all calculation results
- Clears any error messages
- Notifies listeners of the state change
Usage Example
import 'package:provider/provider.dart';
import 'package:numix/features/sales_price_calculator/providers/sales_price_provider.dart';
// In your widget
final provider = context.read<SalesPriceProvider>();
// Calculate with markup
provider.setMarginType(MarginType.markup);
provider.calculatePrice(
costStr: '100.00',
profitPercentStr: '50', // 50% markup
taxStr: '8.5', // 8.5% tax
);
// Access results
if (provider.errorMessage != null) {
print('Error: ${provider.errorMessage}');
} else {
print('Base Sale Price: \$${provider.baseSalePrice}');
print('Profit Amount: \$${provider.profitAmount}');
print('Tax: \$${provider.taxAmount}');
print('Final Price: \$${provider.finalPrice}');
}
// Switch to margin calculation
provider.setMarginType(MarginType.margin);
provider.calculatePrice(
costStr: '100.00',
profitPercentStr: '50', // 50% margin on sales
taxStr: '8.5',
);
// Clear all
provider.clear();
Markup vs Margin Comparison
Understanding the difference between markup and margin is critical for pricing:Markup: Profit as a percentage of cost
- Formula:
(Profit / Cost) × 100
- Example: 100cost,50 profit = 50% markup
- Common in retail and wholesale
Margin: Profit as a percentage of selling price
- Formula:
(Profit / Sales Price) × 100
- Example: 150sale,50 profit = 33.3% margin
- Common in financial analysis
Note: A 50% markup equals a 33.3% margin, while a 50% margin equals a 100% markup.
UI Integration
Use with Consumer widgets for reactive updates:
Consumer<SalesPriceProvider>(
builder: (context, provider, child) {
if (provider.finalPrice != null) {
return Column(
children: [
Text('Sale Price: \$${provider.baseSalePrice!.toStringAsFixed(2)}'),
Text('Profit: \$${provider.profitAmount!.toStringAsFixed(2)}'),
Text('Final (with tax): \$${provider.finalPrice!.toStringAsFixed(2)}'),
],
);
}
return const SizedBox.shrink();
},
)
Persistence
All user inputs are automatically persisted using the following SharedPreferences keys:
sales_cost - Product cost
sales_profit - Profit percentage
sales_tax - Tax percentage
sales_margin_type - Margin type (0 = markup, 1 = margin)
The provider automatically restores these values when initialized.