From 89626bbda094b09815a19ceb805338eb25515f89 Mon Sep 17 00:00:00 2001 From: PaulG <144158015+PaulGarewal@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:31:54 -0700 Subject: [PATCH] [FEAT][NMP-670] Calculations for Solid Fertigation (#696) * Fixed validation bug * WIP * Added conditional validation to calculate dry fertigation * WIP * To decimal * WIP * WIP * WIP * solubility auto populates * WIP Still need to properly implement conversions * feat: Added solid calculations and units - TODO: unit conversions of amount to dissolve and tank vol - TODO: general clean up and verification --------- Co-authored-by: Dallas Richmond --- app/Agri.Data/SeedData/FertigationData.json | 109 +++++++- .../Configuration/DryFertilizerSolubility.cs | 24 ++ app/Agri.Models/Configuration/Fertigation.cs | 6 + .../Configuration/SolubilityUnit.cs | 17 ++ app/Agri.Models/Farm/NutrientFertilizer.cs | 1 + .../Attributes/RequiredIfAttribute.cs | 32 +++ .../Controllers/NutrientsController.cs | 254 ++++++++++++++++-- .../ViewModels/FertigationDetailsViewModel.cs | 50 ++-- .../Views/Nutrients/Calculate.cshtml | 21 ++ .../Views/Nutrients/FertigationDetails.cshtml | 40 ++- 10 files changed, 501 insertions(+), 53 deletions(-) create mode 100644 app/Agri.Models/Configuration/DryFertilizerSolubility.cs create mode 100644 app/Agri.Models/Configuration/SolubilityUnit.cs create mode 100644 app/Server/src/SERVERAPI/Attributes/RequiredIfAttribute.cs diff --git a/app/Agri.Data/SeedData/FertigationData.json b/app/Agri.Data/SeedData/FertigationData.json index 9c150ad2..57b978fd 100644 --- a/app/Agri.Data/SeedData/FertigationData.json +++ b/app/Agri.Data/SeedData/FertigationData.json @@ -229,6 +229,92 @@ "StaticDataVersionId": 14 } ], + "DryFertilizerSolubilities":[ + { + "Id": 1, + "FertilizerId": 1, + "SolubilityUnitId": 1, + "Value": 1080, + "StaticDataVersionId": 14 + }, + { + "Id": 2, + "FertilizerId": 1, + "SolubilityUnitId": 2, + "Value": 1.08, + "StaticDataVersionId": 14 + }, + { + "Id": 3, + "FertilizerId": 1, + "SolubilityUnitId": 3, + "Value": 9.01, + "StaticDataVersionId": 14 + }, + { + "Id": 4, + "FertilizerId": 6, + "SolubilityUnitId": 1, + "Value": 1900, + "StaticDataVersionId": 14 + }, + { + "Id": 5, + "FertilizerId": 6, + "SolubilityUnitId": 2, + "Value": 1.9, + "StaticDataVersionId": 14 + }, + { + "Id": 6, + "FertilizerId": 6, + "SolubilityUnitId": 3, + "Value": 15.86, + "StaticDataVersionId": 14 + }, + { + "Id": 7, + "FertilizerId": 7, + "SolubilityUnitId": 1, + "Value": 764, + "StaticDataVersionId": 14 + }, + { + "Id": 8, + "FertilizerId": 7, + "SolubilityUnitId": 2, + "Value": 0.764, + "StaticDataVersionId": 14 + }, + { + "Id": 9, + "FertilizerId": 7, + "SolubilityUnitId": 3, + "Value": 6.38, + "StaticDataVersionId": 14 + }, + { + "Id": 10, + "FertilizerId": 29, + "SolubilityUnitId": 1, + "Value": 1444, + "StaticDataVersionId": 14 + }, + { + "Id": 11, + "FertilizerId": 29, + "SolubilityUnitId": 2, + "Value": 1.444, + "StaticDataVersionId": 14 + }, + { + "Id": 12, + "FertilizerId": 29, + "SolubilityUnitId": 3, + "Value": 12.03, + "StaticDataVersionId": 14 + } + ], "LiquidFertilizerDensities":[ { "Id": 1, @@ -747,8 +833,27 @@ "Name": "Imp. gallon/min", "StaticDataVersionId": 14 } - ] - , + ], + "SolubilityUnits": [ + { + "Id": 1, + "Name": "g/L", + "ConvFactor": 0.01002, + "StaticDataVersionId": 14 + }, + { + "Id": 2, + "Name": "kg/L", + "ConvFactor": 10.02, + "StaticDataVersionId": 14 + }, + { + "Id": 3, + "Name": "lb/imp. gallon", + "ConvFactor": 1, + "StaticDataVersionId": 14 + } + ], "FertilizerUnits": [ { "Id" : 1, diff --git a/app/Agri.Models/Configuration/DryFertilizerSolubility.cs b/app/Agri.Models/Configuration/DryFertilizerSolubility.cs new file mode 100644 index 00000000..7850d78c --- /dev/null +++ b/app/Agri.Models/Configuration/DryFertilizerSolubility.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; + +namespace Agri.Models.Configuration +{ + public class DryFertilizerSolubility : Versionable + { + [Key] + public int Id { get; set; } + + public int FertilizerId { get; set; } + public int SolubilityUnitId { get; set; } + public decimal Value { get; set; } + + [JsonIgnore] + [IgnoreDataMember] + public Fertilizer Fertilizer { get; set; } + + [JsonIgnore] + [IgnoreDataMember] + public SolubilityUnit SolubilityUnit { get; set; } + } +} \ No newline at end of file diff --git a/app/Agri.Models/Configuration/Fertigation.cs b/app/Agri.Models/Configuration/Fertigation.cs index 615fb201..386fd10d 100644 --- a/app/Agri.Models/Configuration/Fertigation.cs +++ b/app/Agri.Models/Configuration/Fertigation.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; @@ -13,11 +14,13 @@ public Fertigation() public List Fertilizers { get; set; } public List LiquidFertilizerDensities { get; set; } + public List DryFertilizerSolubilities { get; set; } public List LiquidMaterialApplicationUsGallonsPerAcreRateConversions { get; set; } public List LiquidMaterialsConversionFactors { get; set; } public List FertilizerTypes { get; set; } public List ProductRateUnits { get; set; } public List DensityUnits { get; set; } + public List SolubilityUnits { get; set; } public List InjectionRateUnits { get; set; } public List FertilizerUnit { get; set; } public List Schedules { get; set; } @@ -25,6 +28,9 @@ public Fertigation() public LiquidFertilizerDensity GetLiquidFertilizerDensity( int id, int densityUnitId){ return LiquidFertilizerDensities.Single(density => density.FertilizerId == id && density.DensityUnitId == densityUnitId); } + public DryFertilizerSolubility GetDryFertilizerSolubility(int id, int solubilityUnitId){ + return DryFertilizerSolubilities.Single(solubility => solubility.FertilizerId == id && solubility.SolubilityUnitId == solubilityUnitId); + } } } diff --git a/app/Agri.Models/Configuration/SolubilityUnit.cs b/app/Agri.Models/Configuration/SolubilityUnit.cs new file mode 100644 index 00000000..d36c7697 --- /dev/null +++ b/app/Agri.Models/Configuration/SolubilityUnit.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Agri.Models.Configuration +{ + public class SolubilityUnit : SelectOption + { + public SolubilityUnit() + { + DryFertilizerSolubilities = new List(); + } + + public decimal ConvFactor { get; set; } + + public List DryFertilizerSolubilities { get; set; } + } +} \ No newline at end of file diff --git a/app/Agri.Models/Farm/NutrientFertilizer.cs b/app/Agri.Models/Farm/NutrientFertilizer.cs index 9e419ea5..c3e253fe 100644 --- a/app/Agri.Models/Farm/NutrientFertilizer.cs +++ b/app/Agri.Models/Farm/NutrientFertilizer.cs @@ -22,6 +22,7 @@ public class NutrientFertilizer public decimal fertK2o { get; set; } public decimal liquidDensity { get; set; } public int liquidDensityUnitId { get; set; } + public int solInWaterUnitId { get; set; } public int eventsPerSeason { get; set; } public bool isFertigation { get; set; } public decimal injectionRate { get; set; } diff --git a/app/Server/src/SERVERAPI/Attributes/RequiredIfAttribute.cs b/app/Server/src/SERVERAPI/Attributes/RequiredIfAttribute.cs new file mode 100644 index 00000000..ecb90162 --- /dev/null +++ b/app/Server/src/SERVERAPI/Attributes/RequiredIfAttribute.cs @@ -0,0 +1,32 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Linq; + +namespace SERVERAPI.Attributes +{ + public class RequiredIfAttribute : RequiredAttribute + { + private string PropertyName { get; set; } + private object[] DesiredValues { get; set; } + + public RequiredIfAttribute(string propertyName, params object[] desiredValues) + { + PropertyName = propertyName; + DesiredValues = desiredValues; + } + + protected override ValidationResult IsValid(object value, ValidationContext context) + { + object instance = context.ObjectInstance; + Type type = instance.GetType(); + object propertyValue = type.GetProperty(PropertyName).GetValue(instance, null); + + if (DesiredValues.Contains(propertyValue)) + { + return base.IsValid(value, context); + } + + return ValidationResult.Success; + } + } +} \ No newline at end of file diff --git a/app/Server/src/SERVERAPI/Controllers/NutrientsController.cs b/app/Server/src/SERVERAPI/Controllers/NutrientsController.cs index fde3a2d0..70a5c2fb 100644 --- a/app/Server/src/SERVERAPI/Controllers/NutrientsController.cs +++ b/app/Server/src/SERVERAPI/Controllers/NutrientsController.cs @@ -291,6 +291,7 @@ public IActionResult FertigationDetails(string fldName, int? id, string? groupID } fgvm.density = nf.liquidDensity.ToString("#.##"); fgvm.selDensityUnitOption = nf.liquidDensityUnitId; + fgvm.selSolubilityUnitOption = nf.solInWaterUnitId; fgvm.eventsPerSeason = getNumberOfEvents(fgvm); fgvm.selFertSchedOption = nf.applMethodId.ToString(); fgvm.injectionRate = nf.injectionRate.ToString("#.##"); @@ -325,13 +326,29 @@ public IActionResult FertigationDetails(string fldName, int? id, string? groupID else { FertigationDetail_Reset(ref fgvm); - if (fgvm.selTypOption == "4") // This is custom liquid fertigation, could be put directly into details reset + if (fgvm.selTypOption == "4") // This is custom liquid fertigation { + fgvm.valN = ""; fgvm.valP2o5 = ""; fgvm.valK2o = ""; + fgvm.manualEntry = true; } + else if (fgvm.selTypOption == "2") // This is custom dry fertigation + { + fgvm.valN = ""; + fgvm.valP2o5 = ""; + fgvm.valK2o = ""; + + fgvm.tankVolume = ""; + fgvm.amountToDissolve = ""; + fgvm.solInWater = ""; + fgvm.dryAction = ""; + + fgvm.manualEntry = true; + } + } FertigationStillRequired(ref fgvm); FertigationDetailsSetup(ref fgvm); @@ -353,6 +370,10 @@ private void FertigationDetail_Reset(ref FertigationDetailsViewModel fgvm) fgvm.calcTotalK2o = "0"; fgvm.calcTotalP2o5 = "0"; + fgvm.nutrientConcentrationN = "0"; + fgvm.nutrientConcentrationP205 = "0"; + fgvm.nutrientConcentrationK2O = "0"; + fgvm.totN = "0"; fgvm.totP2o5 = "0"; fgvm.totK2o = "0"; @@ -365,13 +386,27 @@ private void FertigationDetail_Reset(ref FertigationDetailsViewModel fgvm) fgvm.totProductVolPerFert = 0.0M; fgvm.totProductVolPerSeason = 0.0M; + fgvm.tankVolume = ""; + fgvm.solInWater = ""; + fgvm.amountToDissolve = ""; + fgvm.eventsPerSeason = 1; // if custom liquid fertigation, we set these to empty for user to change - if (fgvm.selTypOption == "2" || fgvm.selTypOption == "4"){ + if (fgvm.selTypOption == "2"){ fgvm.valN = ""; fgvm.valP2o5 = ""; - fgvm.valK2o = ""; + fgvm.valK2o = ""; + + fgvm.tankVolume = ""; + fgvm.amountToDissolve = ""; + fgvm.solInWater = ""; + fgvm.dryAction = ""; + } + if (fgvm.selTypOption == "4"){ + fgvm.valN = ""; + fgvm.valP2o5 = ""; + fgvm.valK2o = ""; } } @@ -445,12 +480,20 @@ private List GetOptionsList(List selectOption) where T: Se private void FertigationDetailsSetup(ref FertigationDetailsViewModel fgvm) { + //here we will have to add the solid units dropdown fgvm.typOptions = GetOptionsList(_fg.FertilizerTypes); fgvm.fertOptions = GetFertigationFertilizers(fgvm.selTypOption); fgvm.productRateUnitOptions = GetOptionsList(_fg.ProductRateUnits); fgvm.injectionRateUnitOptions = GetOptionsList(_fg.InjectionRateUnits); fgvm.densityUnitOptions = GetOptionsList(_fg.DensityUnits); + fgvm.solubilityUnitOptions = GetOptionsList(_fg.SolubilityUnits); fgvm.applPeriod = GetOptionsList(_fg.Schedules); + fgvm.amountToDissolveUnitOptions = new List + { + new SelectListItem { Id = 1, Value = "lbs" }, + new SelectListItem { Id = 2, Value = "kgs" }, + new SelectListItem { Id = 3, Value = "grams" } + }; FertigationDetailSetup_Fertilizer(ref fgvm); } @@ -556,6 +599,10 @@ public IActionResult FertigationDetails(FertigationDetailsViewModel fgvm) FertigationDetailSetup_DefaultDensity(ref fgvm); } + if (fgvm.selTypOption == "1") + { + FertigationDetailSetup_DefaultSolubility(ref fgvm); + } return View(fgvm); } @@ -573,6 +620,57 @@ public IActionResult FertigationDetails(FertigationDetailsViewModel fgvm) } return View(fgvm); } + if (fgvm.buttonPressed == "TankVolumeChange") + { + ModelState.Clear(); + fgvm.buttonPressed = ""; + fgvm.btnText = "Calculate"; + + if (fgvm.selTypOption == "2") + { + FertigationDetailSetup_DefaultDensity(ref fgvm); + } + return View(fgvm); + } + if (fgvm.buttonPressed == "SolInWaterUnitChange") + { + ModelState.Clear(); + fgvm.buttonPressed = ""; + fgvm.btnText = "Calculate"; + + if (decimal.TryParse(fgvm.solInWater, out decimal currentValue)) + { + if (fgvm.solInWaterUnits == null) { + fgvm.solInWaterUnits = "1"; + } + var fromUnit = (SolubilityUnit)(int.TryParse(fgvm.solInWaterUnits, out int result) ? result : fgvm.selSolubilityUnitOption ?? 0); + var toUnit = (SolubilityUnit)fgvm.selSolubilityUnitOption; + + decimal convertedValue = ConvertSolubility(currentValue, fromUnit, toUnit); + fgvm.solInWater = convertedValue.ToString("#.##"); + } + + fgvm.solInWaterUnits = fgvm.selSolubilityUnitOption.ToString(); + return PartialView(fgvm); + } + if (fgvm.buttonPressed == "AmountToDissolveChange") + { + ModelState.Clear(); + fgvm.buttonPressed = ""; + fgvm.btnText = "Calculate"; + // WIP Convert amount to dissolve to grams per liter as a base unit + if (decimal.TryParse(fgvm.amountToDissolve, out decimal amountToDissolve)) { + if (fgvm.amountToDissolveUnits == null) { + fgvm.amountToDissolveUnits = "1"; + } + var fromUnit = (SolubilityUnit)(int.TryParse(fgvm.amountToDissolveUnits, out int result) ? result : fgvm.selSolubilityUnitOption ?? 0); + var toUnit = (SolubilityUnit)fgvm.selSolubilityUnitOption; + + decimal convertedValue = ConvertSolubility(amountToDissolve, fromUnit, toUnit); + fgvm.amountToDissolve = convertedValue.ToString("#.##"); + } + return View(fgvm); + } if (ModelState.IsValid) { @@ -660,22 +758,8 @@ public IActionResult FertigationDetails(FertigationDetailsViewModel fgvm) FertilizerType ft = _sd.GetFertilizerType(fgvm.selTypOption.ToString()); fgvm.applDate = fgvm.applDate?.Date; - // if (ft.DryLiquid == "liquid") - // { - // if (!ft.Custom) - // { - // if (fgvm.density != _sd.GetLiquidFertilizerDensity(fgvm.selFertOption ?? 0, fgvm.selDensityUnitOption ?? 0).Value.ToString("#.##")) - // { - // fgvm.stdDensity = false; - // } - // else - // { - // fgvm.stdDensity = true; - // } - // } - // } - // - + if (ft.DryLiquid == "liquid") { + var fertilizerNutrients = _calculateFertigationNutrients.GetFertilizerNutrients(fgvm.selFertOption ?? 0, fgvm.fertilizerType, Convert.ToDecimal(fgvm.productRate), @@ -734,6 +818,32 @@ public IActionResult FertigationDetails(FertigationDetailsViewModel fgvm) fgvm.calcTotalP2o5 = Convert.ToString(Convert.ToInt32(fertilizerNutrients.fertilizer_K2O) * Convert.ToInt32(fgvm.eventsPerSeason)); fgvm.btnText = fgvm.id == null ? "Add to Field" : "Update Field"; + } + + else { // fertigation is dry in this case + // calculate dry fertigation below (may need to move this else block above ^ to accont for still required and other funcs) + // FertilizerNutrients fertilizerNutrients = _calculateFertigationNutrients.GetFertilizerNutrients(fgvm.selFertOption ?? 0, + // fgvm.fertilizerType, + // Convert.ToDecimal(fgvm.productRate), + // Convert.ToInt32(fgvm.selProductRateUnitOption), + // fgvm.density != null ? Convert.ToDecimal(fgvm.density) : 0, + // Convert.ToInt16(fgvm.selDensityUnitOption), + // Convert.ToDecimal(fgvm.valN), + // Convert.ToDecimal(fgvm.valP2o5), + // Convert.ToDecimal(fgvm.valK2o), + // fgvm.manualEntry); + + Field field = _ud.GetFieldDetails(fgvm.fieldName); + fgvm.fieldArea = Convert.ToString(field.Area); + + SolidFertigationCalculation(fgvm); + //Total Applied Nutrients + fgvm.calcTotalN = Convert.ToString(Convert.ToDecimal(fgvm.calcN) * fgvm.eventsPerSeason); + fgvm.calcTotalK2o = Convert.ToString(Convert.ToDecimal(fgvm.calcK2o)* fgvm.eventsPerSeason); + fgvm.calcTotalP2o5 = Convert.ToString(Convert.ToDecimal(fgvm.calcP2o5) * fgvm.eventsPerSeason); + + fgvm.btnText = fgvm.id == null ? "Add to Field" : "Update Field"; + } // temporarily update the farm data so as to recalc the Still Required amounts if (fgvm.id == null) @@ -759,6 +869,7 @@ public IActionResult FertigationDetails(FertigationDetailsViewModel fgvm) { _ud.UpdateFieldNutrientsFertilizer(fgvm.fieldName, origFertilizer); } + } else if (fgvm.buttonPressed == "Add to Field" || fgvm.buttonPressed == "Update Field") { @@ -784,6 +895,111 @@ public IActionResult FertigationDetails(FertigationDetailsViewModel fgvm) return PartialView(fgvm); } + private enum SolubilityUnit { + GramsPerLiter = 1, + KilogramsPerLiter = 2, + PoundsPerImperialGallon = 3 + } + + private enum DissolveUnit { + Pounds = 1, + Kilograms = 2, + Grams = 3 + } + + private decimal ConvertSolubility(decimal value, SolubilityUnit fromUnit, SolubilityUnit toUnit) + { + if (fromUnit == toUnit) + return value; + + decimal baseValue = fromUnit switch + { + SolubilityUnit.GramsPerLiter => value, + SolubilityUnit.KilogramsPerLiter => value * 1000, + SolubilityUnit.PoundsPerImperialGallon => value * 99.776373M, + _ => throw new ArgumentException("Invalid fromUnit") + }; + + return toUnit switch + { + SolubilityUnit.GramsPerLiter => baseValue, + SolubilityUnit.KilogramsPerLiter => baseValue / 1000, + SolubilityUnit.PoundsPerImperialGallon => baseValue / 99.776373M, + _ => throw new ArgumentException("Invalid toUnit") + }; + } + + private void SolidFertigationCalculation(FertigationDetailsViewModel fgvm){ + decimal amountToDissolve = Convert.ToDecimal(fgvm.amountToDissolve); + decimal tankVolume = Convert.ToDecimal(fgvm.tankVolume); + decimal fertArea = Convert.ToDecimal(fgvm.fieldArea); + + fgvm.nutrientConcentrationN = Convert.ToString(amountToDissolve * Convert.ToDecimal(fgvm.valN) / 100 / tankVolume); + fgvm.nutrientConcentrationK2O = Convert.ToString(amountToDissolve * Convert.ToDecimal(fgvm.valK2o) / 100 / tankVolume); + fgvm.nutrientConcentrationP205 = Convert.ToString(amountToDissolve * Convert.ToDecimal(fgvm.valP2o5) / 100 / tankVolume); + + decimal injectionRate = Convert.ToDecimal(fgvm.injectionRate); + fgvm.fertigationTime = Math.Round(Convert.ToDecimal(fgvm.tankVolume) / injectionRate, 2); + + if (amountToDissolve <= tankVolume * Convert.ToDecimal(fgvm.solInWater)){ + fgvm.dryAction = "Good"; + } + else{ + fgvm.dryAction = "Reduce the amount to dissolve"; + } + + fgvm.calcN = Convert.ToString(Convert.ToDecimal(fgvm.nutrientConcentrationN) * tankVolume / fertArea); + fgvm.calcK2o = Convert.ToString(Convert.ToDecimal(fgvm.nutrientConcentrationK2O) * tankVolume / fertArea); + fgvm.calcP2o5 = Convert.ToString(Convert.ToDecimal(fgvm.nutrientConcentrationP205) * tankVolume / fertArea); + + fgvm.totN = Convert.ToString(Convert.ToDecimal(fgvm.calcN) * fgvm.eventsPerSeason); + fgvm.totK2o = Convert.ToString(Convert.ToDecimal(fgvm.calcK2o) * fgvm.eventsPerSeason); + fgvm.totP2o5 = Convert.ToString(Convert.ToDecimal(fgvm.calcP2o5) * fgvm.eventsPerSeason); + + } + + private void FertigationDetailSetup_DefaultSolubility(ref FertigationDetailsViewModel fgvm) + { + fgvm.fertOptions = new List(); + if (fgvm.selTypOption != null && + fgvm.selTypOption != "select") + { + FertilizerType ft = _sd.GetFertilizerType(fgvm.selTypOption); + if (!ft.Custom) + { + fgvm.fertOptions = GetFertigationFertilizers(ft.Id.ToString()).ToList(); + } + else + { + fgvm.fertOptions = new List() { new SelectListItem() { Id = 1, Value = "Custom" } }; + fgvm.selFertOption = 1; + // fgvm.stdDensity = true; + } + } + else + { + fgvm.fertOptions = new List(); + fgvm.selFertOption = 0; + } + + + if (fgvm.selSolubilityUnitOption == 0 || fgvm.selFertOption == 0) + { + fgvm.solInWater = ""; + // fgvm.stdDensity = true; + } + + if (!fgvm.manualEntry && + fgvm.fertilizerType == "dry" && + fgvm.selFertOption != 0 && + fgvm.selSolubilityUnitOption != 0) + { + fgvm.solInWater = _fg.GetDryFertilizerSolubility(Convert.ToInt32(fgvm.selFertOption), Convert.ToInt32(fgvm.selSolubilityUnitOption)).Value.ToString("#.##"); + + // fgvm.stdDensity = true; + } + + } private void FertigationDetailSetup_DefaultDensity(ref FertigationDetailsViewModel fgvm) { fgvm.fertOptions = new List(); diff --git a/app/Server/src/SERVERAPI/ViewModels/FertigationDetailsViewModel.cs b/app/Server/src/SERVERAPI/ViewModels/FertigationDetailsViewModel.cs index 4241f87b..99c0f82b 100644 --- a/app/Server/src/SERVERAPI/ViewModels/FertigationDetailsViewModel.cs +++ b/app/Server/src/SERVERAPI/ViewModels/FertigationDetailsViewModel.cs @@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations; using Agri.Models; using Agri.Models.Configuration; - +using SERVERAPI.Attributes; namespace SERVERAPI.ViewModels { public class FertigationDetailsViewModel @@ -32,22 +32,23 @@ public class FertigationDetailsViewModel public List fertOptions { get; set; } // Product rate - [Required(ErrorMessage = "Required")] - [Range(1, 9999, ErrorMessage = "Required")] + //[Required(ErrorMessage = "Required")] + //[Range(1, 9999, ErrorMessage = "Required")] public string selProductRateUnitOption { get; set; } public string selProductRateUnitOptionText { get; set; } public List productRateUnitOptions { get; set; } - [Required(ErrorMessage = "Required")] - [Range(1, 9999.99, ErrorMessage = "Required")] + [RequiredIf("selTypOption", "3", "4", ErrorMessage = "Required")] + //[Range(1, 9999.99, ErrorMessage = "Required")] public string productRate { get; set; } // Density - [Required(ErrorMessage = "Required")] - [Range(1, 9999, ErrorMessage = "Required")] + //[Required(ErrorMessage = "Required")] + //[Range(1, 9999, ErrorMessage = "Required")] public int? selDensityUnitOption { get; set; } public List densityUnitOptions { get; set; } - [Required(ErrorMessage = "Required")] - [Range(1, 9999.99, ErrorMessage = "Required")] + //[Required(ErrorMessage = "Required")] + //[Range(1, 9999.99, ErrorMessage = "Required")] + [RequiredIf("selTypOption", "3", "4", ErrorMessage = "Required")] public string density { get; set; } public bool stdDensity { get; set; } @@ -75,14 +76,14 @@ public class FertigationDetailsViewModel public bool manualEntry { get; set; } // Nutrient values - [Required(ErrorMessage = "Required")] - [Range(0, 9999, ErrorMessage = "Required")] + //[Required(ErrorMessage = "Required")] + //[Range(0, 9999, ErrorMessage = "Required")] public string valN { get; set; } - [Required(ErrorMessage = "Required")] - [Range(0, 9999, ErrorMessage = "Required")] + //[Required(ErrorMessage = "Required")] + //[Range(0, 9999, ErrorMessage = "Required")] public string valP2o5 { get; set; } - [Required(ErrorMessage = "Required")] - [Range(0, 9999, ErrorMessage = "Required")] + //[Required(ErrorMessage = "Required")] + //[Range(0, 9999, ErrorMessage = "Required")] public string valK2o { get; set; } // Calculated values @@ -110,18 +111,25 @@ public class FertigationDetailsViewModel public decimal totProductVolPerSeason { get; set; } // Dry fertigation additional fields - [Required(ErrorMessage = "Required")] - [Range(1, 9999, ErrorMessage = "Required")] + // [Required(ErrorMessage = "Required")] + // [Range(0, 9999, ErrorMessage = "Required")] + [RequiredIf("selTypOption", "1", "2", ErrorMessage = "Required")] public string tankVolume { get; set; } public string tankVolumeUnits { get; set; } - [Required(ErrorMessage = "Required")] - [Range(1, 9999, ErrorMessage = "Required")] + // [Required(ErrorMessage = "Required")] + // [Range(0, 9999, ErrorMessage = "Required")] + [RequiredIf("selTypOption", "1", "2", ErrorMessage = "Required")] public string solInWater { get; set; } public string solInWaterUnits { get; set; } - [Required(ErrorMessage = "Required")] - [Range(1, 9999, ErrorMessage = "Required")] + public List solubilityUnitOptions { get; set; } + public int? selSolubilityUnitOption { get; set; } + + // [Required(ErrorMessage = "Required")] + // [Range(0, 9999, ErrorMessage = "Required")] + [RequiredIf("selTypOption", "1", "2", ErrorMessage = "Required")] public string amountToDissolve { get; set; } public string amountToDissolveUnits { get; set; } + public List amountToDissolveUnitOptions { get; set; } public string dryAction { get; set; } public string nutrientConcentrationN { get; set; } public string nutrientConcentrationP205 { get; set; } diff --git a/app/Server/src/SERVERAPI/Views/Nutrients/Calculate.cshtml b/app/Server/src/SERVERAPI/Views/Nutrients/Calculate.cshtml index 2a7da854..cce0e635 100644 --- a/app/Server/src/SERVERAPI/Views/Nutrients/Calculate.cshtml +++ b/app/Server/src/SERVERAPI/Views/Nutrients/Calculate.cshtml @@ -388,6 +388,27 @@ }) }); + $(document).ready(function () { + $("body").on("change", "#ddlSolubilityUnits", function () { + $('#buttonPressed').val("SolInWaterUnitChange"); + $("#modForm").submit(); + }) + }); + + $(document).ready(function () { + $("body").on("change", "#ddlTankVolume", function () { + $('#buttonPressed').val("TankVolumeChange"); + $("#modForm").submit(); + }) + }); + + $(document).ready(function () { + $("body").on("change", "#ddlAmountToDissolve", function () { + $('#buttonPressed').val("AmountToDissolveChange"); + $("#modForm").submit(); + }) + }); + $(document).ready(function () { $("body").on("change", "#injectionRate", function () { $('#buttonPressed').val("InjectionChange"); diff --git a/app/Server/src/SERVERAPI/Views/Nutrients/FertigationDetails.cshtml b/app/Server/src/SERVERAPI/Views/Nutrients/FertigationDetails.cshtml index cd62d8c1..22c1dbd7 100644 --- a/app/Server/src/SERVERAPI/Views/Nutrients/FertigationDetails.cshtml +++ b/app/Server/src/SERVERAPI/Views/Nutrients/FertigationDetails.cshtml @@ -58,7 +58,7 @@
- +
@@ -74,31 +74,31 @@
- +
- - - + + +
- +
- +
- - + +
@@ -109,7 +109,17 @@ Action
- @Model.dryAction + @if (Model.dryAction == "Good") + { + @Model.dryAction + + + } + else if (Model.dryAction == "Reduce the amount to dissolve") + { + @Model.dryAction + + }
@@ -424,11 +434,19 @@ @Html.HiddenFor(x => x.tankVolume) @Html.HiddenFor(x => x.solInWater) - + @Html.HiddenFor(x => x.amountToDissolve) + @Html.HiddenFor(x => x.amountToDissolveUnitOptions) + @Html.HiddenFor(x => x.amountToDissolveUnits) + @Html.HiddenFor(x => x.selSolubilityUnitOption) + @Html.HiddenFor(m => m.solInWaterUnits) @Html.HiddenFor(x => x.fertigationTime) @Html.HiddenFor(x => x.totProductVolPerFert) @Html.HiddenFor(x => x.totProductVolPerSeason) + @Html.HiddenFor(x => x.nutrientConcentrationN) + @Html.HiddenFor(x => x.nutrientConcentrationK2O) + @Html.HiddenFor(x => x.nutrientConcentrationP205) +