diff --git a/frontend/src/pages/Applications/Applications.js b/frontend/src/pages/Applications/Applications.js index 4b4842e..0f045a2 100644 --- a/frontend/src/pages/Applications/Applications.js +++ b/frontend/src/pages/Applications/Applications.js @@ -24,6 +24,8 @@ const Applications = () => { const [selectedPropertyDetails, setSelectedPropertyDetails] = useState(null); const [editingPlan, setEditingPlan] = useState(null); const [propertyCache, setPropertyCache] = useState({}); + const [spreaderRecommendation, setSpreaderRecommendation] = useState(null); + const [loadingRecommendation, setLoadingRecommendation] = useState(false); useEffect(() => { fetchApplications(); @@ -432,6 +434,11 @@ const ApplicationPlanModal = ({ } }, [editingPlan, products]); + // Load spreader recommendation when relevant fields change + useEffect(() => { + loadSpreaderRecommendation(planData.selectedProduct, planData.equipmentId, planData.selectedAreas); + }, [planData.selectedProduct, planData.equipmentId, planData.selectedAreas, selectedPropertyDetails, equipment]); + const handlePropertyChange = async (propertyId) => { setPlanData({ ...planData, propertyId, selectedAreas: [] }); if (propertyId && propertyId !== selectedPropertyDetails?.id?.toString()) { @@ -440,6 +447,104 @@ const ApplicationPlanModal = ({ setLoadingProperty(false); } }; + + // Load spreader recommendations when granular product and spreader are selected + const loadSpreaderRecommendation = async (product, equipmentId, selectedAreas) => { + if (!product || !equipmentId || !selectedAreas.length || product.productType !== 'granular') { + setSpreaderRecommendation(null); + return; + } + + setLoadingRecommendation(true); + try { + // Find the selected equipment details + const selectedEquipment = equipment.find(eq => eq.id === parseInt(equipmentId)); + if (!selectedEquipment) { + setSpreaderRecommendation(null); + return; + } + + // Load spreader settings for this product + const productApiId = product.isShared ? product.id : product.id; // Use the actual product ID + const endpoint = product.isShared + ? `/api/product-spreader-settings/product/${productApiId}` + : `/api/product-spreader-settings/user-product/${productApiId}`; + + const response = await fetch(endpoint, { + headers: { + 'Authorization': `Bearer ${localStorage.getItem('authToken')}` + } + }); + + if (!response.ok) { + setSpreaderRecommendation(null); + return; + } + + const data = await response.json(); + const settings = data.data?.settings || []; + + // Find a matching setting for this equipment + let matchingSetting = null; + + // First try to find exact equipment match + matchingSetting = settings.find(setting => + setting.equipmentId === selectedEquipment.id + ); + + // If no exact match, try to find by equipment brand/manufacturer + if (!matchingSetting && selectedEquipment.manufacturer) { + matchingSetting = settings.find(setting => + setting.spreaderBrand && + setting.spreaderBrand.toLowerCase().includes(selectedEquipment.manufacturer.toLowerCase()) + ); + } + + // If still no match, use any available setting as fallback + if (!matchingSetting && settings.length > 0) { + matchingSetting = settings[0]; + } + + if (matchingSetting) { + // Calculate total area and product amount needed + const totalArea = selectedAreas.reduce((sum, areaId) => { + const area = selectedPropertyDetails?.sections?.find(s => s.id === areaId); + return sum + (area?.area || 0); + }, 0); + + // Calculate product amount based on rate + const rateAmount = product.customRateAmount || product.rateAmount || 1; + const rateUnit = product.customRateUnit || product.rateUnit || 'lbs/1000 sq ft'; + + let productAmountLbs = 0; + if (rateUnit.includes('1000')) { + // Rate per 1000 sq ft + productAmountLbs = (rateAmount * totalArea) / 1000; + } else if (rateUnit.includes('acre')) { + // Rate per acre (43,560 sq ft) + productAmountLbs = (rateAmount * totalArea) / 43560; + } else { + // Assume rate per sq ft + productAmountLbs = rateAmount * totalArea; + } + + setSpreaderRecommendation({ + setting: matchingSetting, + equipment: selectedEquipment, + totalArea, + productAmountLbs: Math.round(productAmountLbs * 100) / 100, // Round to 2 decimal places + isExactMatch: settings.some(s => s.equipmentId === selectedEquipment.id) + }); + } else { + setSpreaderRecommendation(null); + } + } catch (error) { + console.error('Failed to load spreader recommendation:', error); + setSpreaderRecommendation(null); + } finally { + setLoadingRecommendation(false); + } + }; // Filter equipment based on application type const availableEquipment = equipment.filter(eq => { @@ -665,6 +770,63 @@ const ApplicationPlanModal = ({ )} + {/* Spreader Recommendation for Granular Applications */} + {planData.applicationType === 'granular' && (spreaderRecommendation || loadingRecommendation) && ( +
+ Spreader Setting: {spreaderRecommendation.setting.settingValue} +
++ Product Amount: {spreaderRecommendation.productAmountLbs} lbs +
++ Total Area: {spreaderRecommendation.totalArea.toLocaleString()} sq ft +
++ {spreaderRecommendation.setting.rateDescription} +
+ )} + + {spreaderRecommendation.setting.notes && ( ++ Note: {spreaderRecommendation.setting.notes} +
+ )} + + {!spreaderRecommendation.isExactMatch && ( ++ ⚠️ This setting is based on a similar spreader. Please verify the setting is appropriate for your specific equipment. +
+ )} +