Fix custom amount tons calculation and payment link failure
All checks were successful
Build and Push Docker Images / docker (push) Successful in 47s

Root Cause:
When users entered a custom monetary amount, the tons calculation was broken:
- actualOffsetTons was calculated as (tons * offsetPercentage) / 100
- When monetaryAmount was provided, tons was 0, so actualOffsetTons = 0
- This caused tons display to show 0 and payment link to fail (0 tons invalid)

Fix Applied:
1. Moved roundedPricePerTon calculation earlier in component lifecycle
2. Calculate baseTons from monetaryAmount when provided:
   baseTons = monetaryAmount / roundedPricePerTon
3. Then apply offset percentage: actualOffsetTons = (baseTons * offsetPercentage) / 100

Example:
- User enters $1,000 custom amount
- Portfolio price = $238/ton (rounded up)
- baseTons = 1000 / 238 = 4.20 tons
- With 100% offset: actualOffsetTons = 4.20 tons
- Payment link now passes 4.20 tons to Stripe ✓

Files Modified:
- src/components/OffsetOrder.tsx
- src/components/MobileOffsetOrder.tsx

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Matt 2025-10-30 15:40:49 +01:00
parent bda4a84bce
commit e21756d7f0
2 changed files with 12 additions and 4 deletions

View File

@ -73,8 +73,13 @@ export function MobileOffsetOrder({ tons, monetaryAmount, onBack }: Props) {
savedState?.offsetPercentage ?? 100 // Default to 100% or use saved value
);
// Calculate price per ton (rounded up)
const roundedPricePerTon = portfolio ? Math.ceil(portfolio.pricePerTon || 18) : 18;
// Calculate the actual tons to offset based on percentage
const actualOffsetTons = (tons * offsetPercentage) / 100;
// If monetaryAmount is provided (custom amount), calculate tons from the monetary amount
const baseTons = monetaryAmount ? (monetaryAmount / roundedPricePerTon) : tons;
const actualOffsetTons = (baseTons * offsetPercentage) / 100;
// Format tons for display
const formatTons = (tons: number): string => {
@ -214,7 +219,6 @@ export function MobileOffsetOrder({ tons, monetaryAmount, onBack }: Props) {
};
// Calculate offset cost using the portfolio price (rounded UP to match display)
const roundedPricePerTon = portfolio ? Math.ceil(portfolio.pricePerTon || 18) : 18;
const offsetCost = monetaryAmount || (portfolio ? actualOffsetTons * roundedPricePerTon : 0);
const handleInputChange = (field: keyof typeof formData, value: string) => {

View File

@ -77,8 +77,13 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
savedState?.offsetPercentage ?? 100 // Default to 100% or use saved value
);
// Calculate price per ton (rounded up)
const roundedPricePerTon = portfolio ? Math.ceil(portfolio.pricePerTon || 18) : 18;
// Calculate the actual tons to offset based on percentage
const actualOffsetTons = (tons * offsetPercentage) / 100;
// If monetaryAmount is provided (custom amount), calculate tons from the monetary amount
const baseTons = monetaryAmount ? (monetaryAmount / roundedPricePerTon) : tons;
const actualOffsetTons = (baseTons * offsetPercentage) / 100;
// Format tons for display
const formatTons = (tons: number): string => {
@ -193,7 +198,6 @@ export function OffsetOrder({ tons, monetaryAmount, onBack, calculatorType }: Pr
};
// Calculate offset cost using the portfolio price (rounded UP to match display)
const roundedPricePerTon = portfolio ? Math.ceil(portfolio.pricePerTon || 18) : 18;
const offsetCost = monetaryAmount || (portfolio ? actualOffsetTons * roundedPricePerTon : 0);
return (