From f12818cfddea4bf0e79744ce26e0a8508f05bc49 Mon Sep 17 00:00:00 2001 From: Jake Kasper Date: Sat, 23 Aug 2025 14:02:09 -0400 Subject: [PATCH] calcs again --- backend/src/utils/applicationCalculations.js | 74 ++++++++++++++------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/backend/src/utils/applicationCalculations.js b/backend/src/utils/applicationCalculations.js index d260e1e..6ba9149 100644 --- a/backend/src/utils/applicationCalculations.js +++ b/backend/src/utils/applicationCalculations.js @@ -27,57 +27,87 @@ function calculateLiquidApplication(areaSquareFeet, rateAmount, rateUnit, equipm Equipment: ${equipment?.categoryName} Nozzle GPM: ${nozzle?.flowRateGpm || 'N/A'}`); + // Calculate application speed first based on equipment and nozzle + if (equipment && nozzle && nozzle.flowRateGpm && equipment.sprayWidthFeet) { + const sprayWidthFeet = equipment.sprayWidthFeet; + const nozzleGpm = nozzle.flowRateGpm; + + // For liquid applications, we need to determine optimal speed based on target carrier rate + // Let's use a reasonable default carrier rate of 20 GPA (gallons per acre) + const targetGallonsPerAcre = 20; + const targetGallonsPerSqft = targetGallonsPerAcre / 43560; + + // Formula: Speed (MPH) = GPM / (width_ft × target_rate_gal_per_sqft × 88) + // Where 88 converts MPH to ft/min + applicationSpeedMph = nozzleGpm / (sprayWidthFeet * targetGallonsPerSqft * 88); + + // Limit speed to reasonable range (1-8 MPH for lawn applications) + applicationSpeedMph = Math.max(1, Math.min(8, applicationSpeedMph)); + } else { + applicationSpeedMph = 3; // Default speed + } + + // Now calculate actual carrier (water) rate using the calculated speed + // Formula: Rate (gal/sqft) = flow (GPM) / (width (ft) × speed (ft/min)) + // Where speed (ft/min) = speed (MPH) × 88 + let carrierRateGalPerSqft = 0; + + if (equipment && nozzle && nozzle.flowRateGpm && equipment.sprayWidthFeet) { + const flowGpm = nozzle.flowRateGpm; + const widthFt = equipment.sprayWidthFeet; + const speedFtPerMin = applicationSpeedMph * 88; // Convert MPH to ft/min + + carrierRateGalPerSqft = flowGpm / (widthFt * speedFtPerMin); + waterGallons = carrierRateGalPerSqft * areaSquareFeet; + + console.log('Carrier rate calculation:', { + flowGpm, + widthFt, + speedMph: applicationSpeedMph, + speedFtPerMin, + carrierRateGalPerSqft, + areaSquareFeet, + totalWaterGallons: waterGallons, + carrierRateGalPer1000Sqft: carrierRateGalPerSqft * 1000 + }); + } else { + // Fallback to area-based calculation if equipment data is missing + console.log('Using fallback water calculation - missing equipment/nozzle data'); + waterGallons = area1000sqft * 0.164; // Use your example: 0.164 gal/1000sqft + } + // Calculate product amount based on rate unit if (rateUnit.includes('oz/gal')) { // Rate is ounces per gallon of spray solution - // Need to determine gallons of water needed first - const gallonsPerAcre = 20; // Default 20 GPA for lawn applications - waterGallons = areaAcres * gallonsPerAcre; productOunces = waterGallons * rateAmount; } else if (rateUnit.includes('oz/1000sqft') || rateUnit.includes('oz per 1000sqft')) { // Rate is ounces per 1000 square feet productOunces = area1000sqft * rateAmount; - // Calculate water needed (typical lawn application is 0.5-1 gallon per 1000 sqft) - waterGallons = area1000sqft * 0.75; // 0.75 gal per 1000 sqft default } else if (rateUnit.includes('oz/acre')) { // Rate is ounces per acre productOunces = areaAcres * rateAmount; - waterGallons = areaAcres * 20; // 20 GPA default } else if (rateUnit.includes('fl oz/1000sqft') || rateUnit.includes('fl oz per 1000sqft')) { // Rate is fluid ounces per 1000 square feet productOunces = area1000sqft * rateAmount; - waterGallons = area1000sqft * 0.75; } else { // Fallback: assume rate is per 1000 sq ft productOunces = area1000sqft * rateAmount; - waterGallons = area1000sqft * 0.75; } - // Calculate application speed based on equipment and nozzle - if (equipment && nozzle) { - const sprayWidthFeet = equipment.sprayWidthFeet || 3; // Default 3 ft width - const nozzleGpm = nozzle.flowRateGpm || 0.25; // Default 0.25 GPM - const gallonsPerAcre = (waterGallons / areaAcres) || 20; - - // Speed calculation: MPH = (GPM × 5940) / (Width × GPA) - // Where 5940 is a conversion constant - applicationSpeedMph = (nozzleGpm * 5940) / (sprayWidthFeet * gallonsPerAcre); - - // Limit speed to reasonable range (1-8 MPH for lawn applications) - applicationSpeedMph = Math.max(1, Math.min(8, applicationSpeedMph)); - } const result = { productAmountOunces: Math.round(productOunces * 100) / 100, // Round to 2 decimals waterAmountGallons: Math.round(waterGallons * 100) / 100, applicationSpeedMph: Math.round(applicationSpeedMph * 100) / 100, gallonsPerAcre: Math.round((waterGallons / areaAcres) * 100) / 100, + carrierRateGalPer1000Sqft: Math.round(carrierRateGalPerSqft * 1000 * 1000) / 1000, // Rate per 1000 sqft calculationDetails: { areaSquareFeet, areaAcres: Math.round(areaAcres * 1000) / 1000, area1000sqft: Math.round(area1000sqft * 10) / 10, rateAmount, - rateUnit + rateUnit, + carrierRateGalPerSqft: carrierRateGalPerSqft } };