Exemple #1
0
            public static FieldVisit Create(TreatmentBMP treatmentBMP)
            {
                var person     = TestPerson.Create();
                var fieldVisit = new FieldVisit(treatmentBMP, FieldVisitStatus.InProgress, person, DateTime.Now, false, FieldVisitType.DryWeather, false);

                return(fieldVisit);
            }
            public static TreatmentBMPAssessment Create(TreatmentBMP treatmentBMP)
            {
                var fieldVisit             = TestFieldVisit.Create(treatmentBMP);
                var treatmentBMPAssessment = new TreatmentBMPAssessment(treatmentBMP, treatmentBMP.TreatmentBMPType, fieldVisit, TreatmentBMPAssessmentType.Initial, false);

                return(treatmentBMPAssessment);
            }
Exemple #3
0
            public static TreatmentBMP Create(TreatmentBMPType treatmentBMPType)
            {
                var inventoryIsVerified = false;
                var treatmentBMP        = new TreatmentBMP(string.Empty, treatmentBMPType.TreatmentBMPTypeID, ModelObjectHelpers.NotYetAssignedID, ModelObjectHelpers.NotYetAssignedID, inventoryIsVerified, TrashCaptureStatusType.NotProvided.TrashCaptureStatusTypeID, SizingBasisType.NotProvided.SizingBasisTypeID);

                return(treatmentBMP);
            }
        private ViewResult ViewManageTreatmentBMPImages(ManageTreatmentBMPImagesViewModel viewModel,
                                                        TreatmentBMP treatmentBMP)
        {
            var managePhotosWithPreviewViewData = new ManagePhotosWithPreviewViewData(CurrentPerson, treatmentBMP);
            var viewData = new ManageTreatmentBMPImagesViewData(CurrentPerson, treatmentBMP, managePhotosWithPreviewViewData);

            return(RazorView <ManageTreatmentBMPImages, ManageTreatmentBMPImagesViewData, ManageTreatmentBMPImagesViewModel>(viewData, viewModel));
        }
Exemple #5
0
        public static void MarkTreatmentBMPDirty(TreatmentBMP treatmentBMP, DatabaseEntities dbContext)
        {
            var dirtyModelNode = new DirtyModelNode(DateTime.Now)
            {
                TreatmentBMPID = treatmentBMP.TreatmentBMPID
            };

            dbContext.DirtyModelNodes.Add(dirtyModelNode);

            dbContext.SaveChanges();
        }
Exemple #6
0
        private RedirectResult GetNextObservationTypeViewResult(TreatmentBMP treatmentBMP, TreatmentBMPAssessmentObservationType treatmentBMPAssessmentObservationType)
        {
            var orderedObservationTypes = treatmentBMP.TreatmentBMPType.GetObservationTypes()
                                          .Where(x => x.GetHasBenchmarkAndThreshold()).ToList();

            var nextObservationType = treatmentBMPAssessmentObservationType == null
                ? orderedObservationTypes.First()
                : orderedObservationTypes.ElementAtOrDefault(
                orderedObservationTypes.IndexOf(treatmentBMPAssessmentObservationType) + 1);

            var nextObservationTypeViewResult = nextObservationType == null
                ? RedirectToAction(new SitkaRoute <TreatmentBMPController>(x => x.Detail(treatmentBMP.TreatmentBMPID)))
                : Redirect(nextObservationType.BenchmarkAndThresholdUrl(treatmentBMP));

            return(nextObservationTypeViewResult);
        }
Exemple #7
0
        private static TreatmentBMPBenchmarkAndThreshold GetExistingTreatmentBMPObservationOrCreateNew(
            TreatmentBMP treatmentBMP, TreatmentBMPAssessmentObservationType treatmentBMPAssessmentObservationType)
        {
            var treatmentBMPObservation = treatmentBMP.TreatmentBMPBenchmarkAndThresholds.SingleOrDefault(x => x.TreatmentBMPAssessmentObservationTypeID == treatmentBMPAssessmentObservationType.TreatmentBMPAssessmentObservationTypeID);

            if (treatmentBMPObservation == null)
            {
                var treatmentBMPTypeAssessmentObservationType =
                    treatmentBMP.TreatmentBMPType.TreatmentBMPTypeAssessmentObservationTypes.SingleOrDefault(x =>
                                                                                                             x.TreatmentBMPAssessmentObservationTypeID == treatmentBMPAssessmentObservationType.TreatmentBMPAssessmentObservationTypeID);
                Check.RequireNotNull(treatmentBMPTypeAssessmentObservationType,
                                     $"Not a valid Observation Type ID {treatmentBMPAssessmentObservationType.TreatmentBMPAssessmentObservationTypeID} for Treatment BMP Type ID {treatmentBMP.TreatmentBMPTypeID}");
                treatmentBMPObservation = new TreatmentBMPBenchmarkAndThreshold(treatmentBMP, treatmentBMPTypeAssessmentObservationType,
                                                                                treatmentBMP.TreatmentBMPType, treatmentBMPAssessmentObservationType, 0, 0);
            }

            return(treatmentBMPObservation);
        }
        private ViewResult ViewNew(NewViewModel viewModel, TreatmentBMP treatmentBMP)
        {
            var geometry = treatmentBMP.GetCentralizedDelineationGeometry4326(HttpRequestStorage.DatabaseEntities);
            var feature  = DbGeometryToGeoJsonHelper.FromDbGeometryWithNoReproject(geometry);

            var layerGeoJson = new LayerGeoJson("centralizedDelineationLayer",
                                                new FeatureCollection(new List <Feature> {
                feature
            }), "#ffff00", .5m, LayerInitialVisibility.Show);

            var mapInitJson = new RegionalSubbasinRevisionRequestMapInitJson("revisionRequestMap",
                                                                             MapInitJson.DefaultZoomLevel, new List <LayerGeoJson>(),
                                                                             new BoundingBox(new List <DbGeometry> {
                geometry
            }), layerGeoJson);

            var viewData = new NewViewData(CurrentPerson, treatmentBMP, mapInitJson);

            return(RazorView <New, NewViewData, NewViewModel>(viewData, viewModel));
        }
Exemple #9
0
        public static void MarkDownstreamNodeDirty(TreatmentBMP treatmentBMP, DatabaseEntities dbContext)
        {
            // if this bmp is an upstream, then its downstream node is, obviously...
            if (treatmentBMP.TreatmentBMPsWhereYouAreTheUpstreamBMP.Any())
            {
                MarkTreatmentBMPDirty(treatmentBMP.TreatmentBMPsWhereYouAreTheUpstreamBMP.ToList(), dbContext);
                return;
            }

            // otherwise, we're looking for either the Regional Subbasin or the Centralized BMP of the Regional Subbasin
            var regionalSubbasinID = treatmentBMP.RegionalSubbasinID;

            var centralizedBMP = dbContext.vNereidRegionalSubbasinCentralizedBMPs.SingleOrDefault(x => x.RegionalSubbasinID == regionalSubbasinID && x.RowNumber == 1);

            if (centralizedBMP != null)
            {
                MarkTreatmentBMPDirty(centralizedBMP, dbContext);
                return;
            }

            // no centralized BMPs there, just go ahead and mark the regional subbasin
            MarkRegionalSubbasinDirty(regionalSubbasinID, dbContext);
        }
Exemple #10
0
        private PartialViewResult ViewNewFundingEventFundingSources(EditViewModel viewModel, TreatmentBMP treatmentBMP)
        {
            var allFundingSources = HttpRequestStorage.DatabaseEntities.FundingSources.ToList().Select(x => new FundingSourceSimple(x)).OrderBy(p => p.DisplayName).ToList();
            var viewData          = new EditViewData(allFundingSources, FundingEventType.All.OrderBy(x => x.SortOrder).ToList(), treatmentBMP);

            return(RazorPartialView <Edit, EditViewData, EditViewModel>(viewData, viewModel));
        }
 public vTreatmentBMPDetailedWithTreatmentBMPEntity(TreatmentBMP treatmentBMP, vTreatmentBMPDetailed vTreatmentBmpDetailed)
 {
     this.TreatmentBMP          = treatmentBMP;
     this.vTreatmentBmpDetailed = vTreatmentBmpDetailed;
 }
Exemple #12
0
 public TreatmentBMPSimple(TreatmentBMP treatmentBMP)
 {
     TreatmentBMPID       = treatmentBMP.TreatmentBMPID;
     DisplayName          = treatmentBMP.TreatmentBMPName;
     TreatmentBMPTypeName = treatmentBMP.TreatmentBMPType.TreatmentBMPTypeName;
 }
        private static List <CustomAttribute> ParseCustomAttributes(TreatmentBMP treatmentBMP, TreatmentBMPType treatmentBMPType,
                                                                    string[] currentRow, Dictionary <string, int> fieldsDict,
                                                                    List <CustomAttributeType> customAttributeTypes, int rowNumber, out List <string> currentErrorList,
                                                                    out List <CustomAttributeValue> customAttributeValues)
        {
            currentErrorList      = new List <string>();
            customAttributeValues = new List <CustomAttributeValue>();
            var customAttributes = new List <CustomAttribute>();
            var isNew            = !ModelObjectHelpers.IsRealPrimaryKeyValue(treatmentBMP.TreatmentBMPID);

            foreach (var customAttributeType in customAttributeTypes)
            {
                var treatmentBMPTypeCustomAttributeType = customAttributeType.TreatmentBMPTypeCustomAttributeTypes.Single(x => x.TreatmentBMPTypeID == treatmentBMPType.TreatmentBMPTypeID);
                var customAttribute =
                    treatmentBMP.CustomAttributes.SingleOrDefault(x =>
                                                                  x.TreatmentBMPTypeCustomAttributeTypeID == treatmentBMPTypeCustomAttributeType
                                                                  .TreatmentBMPTypeCustomAttributeTypeID) ?? new CustomAttribute(treatmentBMP,
                                                                                                                                 treatmentBMPTypeCustomAttributeType, treatmentBMPTypeCustomAttributeType.TreatmentBMPType,
                                                                                                                                 treatmentBMPTypeCustomAttributeType.CustomAttributeType);
                if (fieldsDict.ContainsKey(customAttributeType.CustomAttributeTypeName))
                {
                    var value = currentRow[fieldsDict[customAttributeType.CustomAttributeTypeName]];

                    var customAttributeDataTypeEnum = customAttributeType.CustomAttributeDataType.ToEnum;

                    var customAttributeTypeAcceptableValues =
                        customAttributeType.CustomAttributeTypeOptionsSchema != null
                            ? JsonConvert.DeserializeObject <List <string> >(
                            customAttributeType.CustomAttributeTypeOptionsSchema)
                            : null;

                    if (String.IsNullOrEmpty(value))
                    {
                        //Don't do anything with an empty value if we're updating, but add it if we're new
                        if (isNew)
                        {
                            customAttributeValues.Add(new CustomAttributeValue(customAttribute.CustomAttributeID, value));
                        }
                    }
                    else if (!ValidateCustomAttributeValueEntry(
                                 value,
                                 customAttributeDataTypeEnum,
                                 customAttributeTypeAcceptableValues))
                    {
                        currentErrorList.Add(GetErrorForCustomAttributeType(
                                                 value,
                                                 customAttributeDataTypeEnum,
                                                 customAttributeType.CustomAttributeTypeName,
                                                 customAttributeType.CustomAttributeDataType.CustomAttributeDataTypeDisplayName,
                                                 customAttributeTypeAcceptableValues,
                                                 rowNumber));
                    }
                    else
                    {
                        HttpRequestStorage.DatabaseEntities.CustomAttributeValues.RemoveRange(customAttribute
                                                                                              .CustomAttributeValues);
                        customAttribute.CustomAttributeValues.Clear();

                        if (customAttributeType.CustomAttributeDataType == CustomAttributeDataType.MultiSelect)
                        {
                            var attributeValues = value.Split(new[] { ',' }).Select(x => x.Trim()).Select(x =>
                                                                                                          new CustomAttributeValue(customAttribute.CustomAttributeID, x));
                            customAttributeValues.AddRange(attributeValues);
                        }
                        else
                        {
                            customAttributeValues.Add(
                                new CustomAttributeValue(customAttribute.CustomAttributeID, value));
                        }
                    }
                }
                customAttributes.Add(customAttribute);
            }
            return(customAttributes);
        }
Exemple #14
0
 public static string TreatmentBMPNodeID(TreatmentBMP treatmentBMP)
 {
     return("BMP_" + treatmentBMP.TreatmentBMPID);
 }
        private static TreatmentBMPModelingAttribute ParseModelingAttributes(TreatmentBMP treatmentBMP,
                                                                             TreatmentBMPType treatmentBMPType, string[] currentRow, Dictionary <string, int> fieldsDict,
                                                                             List <string> availableModelingAttributesForType, int rowCount, out List <string> currentErrorList)
        {
            currentErrorList = new List <string>();
            var treatmentBMPModelingAttribute = treatmentBMP.TreatmentBMPModelingAttribute ??
                                                new TreatmentBMPModelingAttribute(treatmentBMP)
            {
                RoutingConfigurationID = RoutingConfiguration.Online.RoutingConfigurationID
            };

            foreach (var attribute in availableModelingAttributesForType)
            {
                if (fieldsDict.ContainsKey(attribute) && !string.IsNullOrWhiteSpace(currentRow[fieldsDict[attribute]]))
                {
                    var modelingProperty = GetAppropriateModelingAttributeColumnName(attribute);
                    var value            = currentRow[fieldsDict[attribute]];

                    var propertyToChange = treatmentBMPModelingAttribute.GetType().GetProperty(modelingProperty);
                    var propType         = propertyToChange?.Name == "UnderlyingHydrologicSoilGroupID"
                        ?
                                           typeof(UnderlyingHydrologicSoilGroup)
                        :
                                           propertyToChange?.Name == "TimeOfConcentrationID"
                            ? typeof(TimeOfConcentration)
                            :
                                           propertyToChange?.Name == "RoutingConfigurationID"
                                ? typeof(RoutingConfiguration)
                                :
                                           propertyToChange?.Name == "MonthsOfOperationID"
                                    ? typeof(MonthsOfOperation)
                                    :
                                           propertyToChange?.PropertyType;

                    if (propType != null && (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable <>)))
                    {
                        propType = propType.GetGenericArguments()[0];
                    }

                    if (propType == typeof(int))
                    {
                        if (int.TryParse(value, out var valueInt))
                        {
                            propertyToChange.SetValue(treatmentBMPModelingAttribute,
                                                      valueInt);
                        }
                        else
                        {
                            currentErrorList.Add(
                                $"{attribute} field can not be converted to Integer at row: {rowCount}");
                        }
                    }
                    else if (propType == typeof(double))
                    {
                        if (double.TryParse(value, out var valueDouble))
                        {
                            propertyToChange.SetValue(treatmentBMPModelingAttribute,
                                                      valueDouble);
                        }
                        else
                        {
                            currentErrorList.Add(
                                $"{attribute} field can not be converted to Double at row: {rowCount}");
                        }
                    }
                    else if (propType == typeof(UnderlyingHydrologicSoilGroup))
                    {
                        var treatmentBMPModelingTypeEnum   = treatmentBMPType.TreatmentBMPModelingType.ToEnum;
                        var underlyingHydrologicSoilGroups = UnderlyingHydrologicSoilGroup.All;
                        var underlyingHydrologicSoilGroup  =
                            underlyingHydrologicSoilGroups.SingleOrDefault(x =>
                                                                           x.UnderlyingHydrologicSoilGroupDisplayName == value);
                        if (underlyingHydrologicSoilGroup == null ||
                            (treatmentBMPModelingTypeEnum == TreatmentBMPModelingTypeEnum
                             .BioinfiltrationBioretentionWithRaisedUnderdrain &&
                             underlyingHydrologicSoilGroup.ToEnum == UnderlyingHydrologicSoilGroupEnum.Liner))
                        {
                            currentErrorList.Add(
                                $"{value} is not a valid {attribute} entry for Treatment BMPs of {treatmentBMPType.TreatmentBMPTypeName} type at row: {rowCount}.Acceptable values are :{string.Join(", ", underlyingHydrologicSoilGroups.Where(x => treatmentBMPModelingTypeEnum != TreatmentBMPModelingTypeEnum.BioinfiltrationBioretentionWithRaisedUnderdrain || x.UnderlyingHydrologicSoilGroupDisplayName != "Liner").Select(x => x.UnderlyingHydrologicSoilGroupDisplayName))}");
                        }
                        else
                        {
                            propertyToChange.SetValue(treatmentBMPModelingAttribute,
                                                      underlyingHydrologicSoilGroup.UnderlyingHydrologicSoilGroupID);
                        }
                    }
                    else if (propType == typeof(TimeOfConcentration))
                    {
                        SetModelingAttributeLookupValue(rowCount, currentErrorList, value, propertyToChange,
                                                        treatmentBMPModelingAttribute, attribute, TimeOfConcentration.All,
                                                        x => x.TimeOfConcentrationDisplayName);
                    }
                    else if (propType == typeof(RoutingConfiguration))
                    {
                        SetModelingAttributeLookupValue(rowCount, currentErrorList, value, propertyToChange,
                                                        treatmentBMPModelingAttribute, attribute, RoutingConfiguration.All,
                                                        x => x.RoutingConfigurationDisplayName);
                    }
                    else if (propType == typeof(MonthsOfOperation))
                    {
                        SetModelingAttributeLookupValue(rowCount, currentErrorList, value, propertyToChange,
                                                        treatmentBMPModelingAttribute, attribute, MonthsOfOperation.All,
                                                        x => x.MonthsOfOperationDisplayName);
                    }
                    else
                    {
                        currentErrorList.Add($"{attribute} is not a valid modeling parameter entry at row: {rowCount}");
                    }
                }
            }

            if (treatmentBMPModelingAttribute.RoutingConfigurationID == RoutingConfiguration.Offline.RoutingConfigurationID &&
                treatmentBMPModelingAttribute.DiversionRate == null)
            {
                currentErrorList.Add($"The modeling attribute 'Diversion Rate' is required when the Routing Configuration is set to 'Offline'. Please adjust entry at row: {rowCount}");
            }
            return(treatmentBMPModelingAttribute);
        }
Exemple #16
0
        private ViewResult ViewEditBenchmarkAndThreshold(TreatmentBMP treatmentBMP, TreatmentBMPAssessmentObservationType treatmentBMPAssessmentObservationType, EditBenchmarkAndThresholdViewModel viewModel)
        {
            var viewData = new EditBenchmarkAndThresholdViewData(CurrentPerson, treatmentBMP, treatmentBMPAssessmentObservationType);

            return(RazorView <EditBenchmarkAndThreshold, EditBenchmarkAndThresholdViewData, EditBenchmarkAndThresholdViewModel>(viewData, viewModel));
        }
        public static TreatmentFacility ToTreatmentFacility(this TreatmentBMP treatmentBMP, bool isBaselineCondition)
        {
            var    treatmentBMPNodeID   = NereidUtilities.TreatmentBMPNodeID(treatmentBMP);
            var    lspcBasinKey         = treatmentBMP.LSPCBasin?.LSPCBasinKey.ToString();
            var    isFullyParameterized = treatmentBMP.IsFullyParameterized();
            double?treatmentRate        = null;
            var    modelingAttribute    = treatmentBMP.TreatmentBMPModelingAttribute;

            // in the baseline condition, anything built after 2003 is treated as if it doesn't exist.
            if (!isFullyParameterized ||
                (isBaselineCondition && treatmentBMP.YearBuilt.HasValue && treatmentBMP.YearBuilt.Value > NereidUtilities.BASELINE_CUTOFF_YEAR))
            {
                return(new TreatmentFacility
                {
                    NodeID = treatmentBMPNodeID,
                    FacilityType = "NoTreatment",
                    ReferenceDataKey = lspcBasinKey,
                    DesignStormwaterDepth = treatmentBMP.PrecipitationZone?.DesignStormwaterDepthInInches ?? .8,
                    EliminateAllDryWeatherFlowOverride = modelingAttribute?.DryWeatherFlowOverrideID == DryWeatherFlowOverride.Yes.DryWeatherFlowOverrideID
                });
            }

            // treatment rate is an alias for four different fields, so we need to pick the one that's not null
            if (modelingAttribute.InfiltrationDischargeRate != null)
            {
                treatmentRate = modelingAttribute.InfiltrationDischargeRate;
            }
            else if (modelingAttribute.TreatmentRate != null)
            {
                treatmentRate = modelingAttribute.TreatmentRate;
            }
            else if (modelingAttribute.AverageDivertedFlowrate != null)
            {
                // AverageDivertedFlowrate is collected in gallons per day instead of CFS, but we need to send CFS to Nereid.
                treatmentRate = modelingAttribute.AverageDivertedFlowrate * NereidUtilities.GPD_TO_CFS;
            }
            else if (modelingAttribute.AverageTreatmentFlowrate != null)
            {
                treatmentRate = modelingAttribute.AverageTreatmentFlowrate;
            }

            double?area = null;

            // area_sqft is an alias for four different fields, so we need to take the one that's not null
            if (modelingAttribute.EffectiveFootprint != null)
            {
                area = modelingAttribute.EffectiveFootprint;
            }
            else if (modelingAttribute.InfiltrationSurfaceArea != null)
            {
                area = modelingAttribute.InfiltrationSurfaceArea;
            }
            else if (modelingAttribute.MediaBedFootprint != null)
            {
                area = modelingAttribute.MediaBedFootprint;
            }
            else if (modelingAttribute.WettedFootprint != null)
            {
                area = modelingAttribute.WettedFootprint;
            }

            double?designCapacity = null;

            if (modelingAttribute.DesignDryWeatherTreatmentCapacity != null)
            {
                designCapacity = modelingAttribute.DesignDryWeatherTreatmentCapacity;
            }
            else if (modelingAttribute.DesignLowFlowDiversionCapacity != null)
            {
                // DesignLowFlowDiversionCapacity is collected in GPD, so convert to CFS
                designCapacity = modelingAttribute.DesignLowFlowDiversionCapacity * NereidUtilities.GPD_TO_CFS;
            }

            if (designCapacity == null)
            {
                designCapacity = treatmentRate;
            }
            else if (treatmentRate == null)
            {
                treatmentRate = designCapacity;
            }

            // null-coalescence here represents default values.
            // It's generally an anti-pattern for an API to require its clients to insert default values,
            // since the API should be written to replace nulls/absent values with defaults,
            // but it's so few that it's not worth a revision to the modeling engine at this time (4/16/2020)
            var treatmentFacility = new TreatmentFacility
            {
                NodeID                    = treatmentBMPNodeID,
                FacilityType              = treatmentBMP.TreatmentBMPType.TreatmentBMPModelingType.TreatmentBMPModelingTypeName,
                ReferenceDataKey          = lspcBasinKey,
                DesignStormwaterDepth     = treatmentBMP.PrecipitationZone.DesignStormwaterDepthInInches,
                DesignCapacity            = designCapacity,
                DesignMediaFiltrationRate = modelingAttribute.DesignMediaFiltrationRate,
                //convert Days to Hours for this field.
                DesignResidenceTimeforPermanentPool = modelingAttribute.DesignResidenceTimeforPermanentPool * 24 ?? double.PositiveInfinity,
                DiversionRate = modelingAttribute.DiversionRate,
                DrawdownTimeforWQDetentionVolume = modelingAttribute.DrawdownTimeforWQDetentionVolume,
                Area = area,
                EffectiveRetentionDepth                 = modelingAttribute.EffectiveRetentionDepth,
                MonthsOfOperation                       = modelingAttribute.MonthsOfOperation?.MonthsOfOperationNereidAlias ?? MonthsOfOperation.Both.MonthsOfOperationNereidAlias,
                PermanentPoolorWetlandVolume            = modelingAttribute.PermanentPoolorWetlandVolume,
                RoutingConfiguration                    = modelingAttribute.RoutingConfigurationID == RoutingConfiguration.Online.RoutingConfigurationID,
                StorageVolumeBelowLowestOutletElevation = modelingAttribute.StorageVolumeBelowLowestOutletElevation,
                // SummerHarvestedWaterDemand is collected in GPD, so convert to CFS
                SummerHarvestedWaterDemand = modelingAttribute.SummerHarvestedWaterDemand * NereidUtilities.GPD_TO_CFS,
                TimeOfConcentration        = modelingAttribute.TimeOfConcentration?.TimeOfConcentrationDisplayName ?? TimeOfConcentration.FiveMinutes.TimeOfConcentrationDisplayName,
                TotalDrawdownTime          = modelingAttribute.DrawdownTimeforWQDetentionVolume,
                TotalEffectiveBMPVolume    = modelingAttribute.TotalEffectiveBMPVolume,
                TreatmentRate = treatmentRate,
                UnderlyingHydrologicSoilGroup = modelingAttribute.UnderlyingHydrologicSoilGroup?.UnderlyingHydrologicSoilGroupDisplayName.ToLower() ?? UnderlyingHydrologicSoilGroup.D.UnderlyingHydrologicSoilGroupDisplayName.ToLower(),
                UnderlyingInfiltrationRate    = modelingAttribute.UnderlyingInfiltrationRate,
                UpstreamBMP = modelingAttribute.UpstreamTreatmentBMPID.HasValue ? NereidUtilities.TreatmentBMPNodeID(modelingAttribute.UpstreamTreatmentBMPID.Value) : null,
                WaterQualityDetentionVolume = modelingAttribute.WaterQualityDetentionVolume,
                // WinterHarvestedWaterDemand is collected in GPD, so convert to CFS
                WinterHarvestedWaterDemand         = modelingAttribute.WinterHarvestedWaterDemand * NereidUtilities.GPD_TO_CFS,
                EliminateAllDryWeatherFlowOverride = modelingAttribute.DryWeatherFlowOverrideID == DryWeatherFlowOverride.Yes.DryWeatherFlowOverrideID
            };

            return(treatmentFacility);
        }
        private static TreatmentBMP ParseRequiredAndOptionalFieldAndCreateBMP(string[] row,
                                                                              Dictionary <string, int> fieldsDict, int rowNumber, out List <string> errorList,
                                                                              TreatmentBMPType treatmentBMPType, List <Organization> organizations,
                                                                              List <StormwaterJurisdiction> stormwaterJurisdictions, List <string> treatmentBMPNamesInCsv)
        {
            errorList = new List <string>();

            var treatmentBMPName         = SetStringValue(row, fieldsDict, rowNumber, errorList, "BMP Name", TreatmentBMP.FieldLengths.TreatmentBMPName, true);
            var stormwaterJurisdictionID = FindLookupValue(row, fieldsDict, "Jurisdiction", rowNumber, errorList, stormwaterJurisdictions, x => x.Organization.OrganizationName, x => x.StormwaterJurisdictionID, false, true);

            if (!stormwaterJurisdictionID.HasValue || string.IsNullOrWhiteSpace(treatmentBMPName))
            {
                // no point in going further if we don't have a name and jurisdiction
                return(null);
            }

            if (!string.IsNullOrWhiteSpace(treatmentBMPName))
            {
                if (treatmentBMPNamesInCsv.Contains(treatmentBMPName))
                {
                    errorList.Add(
                        $"The BMP with Name '{treatmentBMPName}' was already added in this upload, duplicate name is found at row: {rowNumber}");
                }
                treatmentBMPNamesInCsv.Add(treatmentBMPName);
            }

            var treatmentBMP = HttpRequestStorage.DatabaseEntities.TreatmentBMPs.SingleOrDefault(x =>
                                                                                                 x.TreatmentBMPName == treatmentBMPName &&
                                                                                                 x.StormwaterJurisdictionID == stormwaterJurisdictionID.Value);

            if (treatmentBMP != null)
            {
                // one last check; make sure the treatment bmp type of the existing treatment bmp matches the passed type
                if (treatmentBMPType.TreatmentBMPTypeID != treatmentBMP.TreatmentBMPTypeID)
                {
                    errorList.Add(
                        $"BMP with name '{treatmentBMPName}' has a Type '{treatmentBMP.TreatmentBMPType.TreatmentBMPTypeName}', which does not match the uploaded Type '{treatmentBMPType.TreatmentBMPTypeName}' for row: {rowNumber}");
                }
            }
            else
            {
                treatmentBMP = new TreatmentBMP(treatmentBMPName, treatmentBMPType.TreatmentBMPTypeID,
                                                stormwaterJurisdictionID.Value, default(int), false,
                                                default(int), default(int));
            }

            var isNew = !ModelObjectHelpers.IsRealPrimaryKeyValue(treatmentBMP.TreatmentBMPID);
            var treatmentBMPLatitude  = row[fieldsDict["Latitude"]];
            var treatmentBMPLongitude = row[fieldsDict["Longitude"]];
            var locationPoint4326     = ParseLocation(treatmentBMPLatitude, treatmentBMPLongitude, rowNumber, errorList,
                                                      isNew);

            if (locationPoint4326 != null)
            {
                treatmentBMP.LocationPoint4326 = locationPoint4326;
                var locationPoint = CoordinateSystemHelper.ProjectWebMercatorToCaliforniaStatePlaneVI(locationPoint4326);
                treatmentBMP.LocationPoint = locationPoint;

                treatmentBMP.SetTreatmentBMPPointInPolygonDataByLocationPoint(locationPoint);
            }

            var ownerOrganizationID = FindLookupValue(row, fieldsDict, "Owner", rowNumber, errorList, organizations,
                                                      x => x.OrganizationName, x => x.OrganizationID, false, isNew);

            if (ownerOrganizationID.HasValue)
            {
                treatmentBMP.OwnerOrganizationID = ownerOrganizationID.Value;
            }

            //start of Optional Fields
            var yearBuilt =
                GetOptionalIntFieldValue(row, fieldsDict, rowNumber, errorList, "Year Built or Installed");

            if (yearBuilt.HasValue)
            {
                treatmentBMP.YearBuilt = yearBuilt;
            }

            var assetIDInSystemOfRecord = SetStringValue(row, fieldsDict, rowNumber, errorList,
                                                         "Asset ID in System of Record", TreatmentBMP.FieldLengths.SystemOfRecordID, false);

            if (!string.IsNullOrWhiteSpace(assetIDInSystemOfRecord))
            {
                treatmentBMP.SystemOfRecordID = assetIDInSystemOfRecord;
            }

            var notes = SetStringValue(row, fieldsDict, rowNumber, errorList, "Notes",
                                       TreatmentBMP.FieldLengths.Notes, false);

            if (!string.IsNullOrWhiteSpace(notes))
            {
                treatmentBMP.Notes = notes;
            }

            var fieldNameRequiredLifespanOfInstallation = "Required Lifespan of Installation";

            if (fieldsDict.ContainsKey(fieldNameRequiredLifespanOfInstallation))
            {
                var treatmentBMPLifespanTypeID = FindLookupValue(row, fieldsDict,
                                                                 fieldNameRequiredLifespanOfInstallation, rowNumber, errorList, TreatmentBMPLifespanType.All,
                                                                 x => x.TreatmentBMPLifespanTypeDisplayName, x => x.TreatmentBMPLifespanTypeID, true, false);
                if (treatmentBMPLifespanTypeID.HasValue)
                {
                    treatmentBMP.TreatmentBMPLifespanTypeID = treatmentBMPLifespanTypeID;
                }

                var fieldNameAllowableEndDateOfInstallationIfApplicable =
                    "Allowable End Date of Installation (if applicable)";
                if (fieldsDict.ContainsKey(fieldNameAllowableEndDateOfInstallationIfApplicable))
                {
                    var requiredLifespanOfInstallation = row[fieldsDict[fieldNameRequiredLifespanOfInstallation]];
                    var allowableEndDateOfInstallation =
                        row[fieldsDict[fieldNameAllowableEndDateOfInstallationIfApplicable]];
                    var isAllowableEndDateOfInstallationEmpty =
                        string.IsNullOrWhiteSpace(allowableEndDateOfInstallation);
                    if (isAllowableEndDateOfInstallationEmpty && treatmentBMPLifespanTypeID ==
                        TreatmentBMPLifespanType.FixedEndDate.TreatmentBMPLifespanTypeID)
                    {
                        errorList.Add(
                            $"An end date must be provided if the '{fieldNameRequiredLifespanOfInstallation}' field is set to fixed end date for row: {rowNumber}");
                    }

                    if (!isAllowableEndDateOfInstallationEmpty && treatmentBMPLifespanTypeID !=
                        TreatmentBMPLifespanType.FixedEndDate.TreatmentBMPLifespanTypeID)
                    {
                        errorList.Add(
                            $"An end date was provided when '{fieldNameRequiredLifespanOfInstallation}' field was set to {requiredLifespanOfInstallation} for row: {rowNumber}");
                    }

                    if (!treatmentBMPLifespanTypeID.HasValue && !isAllowableEndDateOfInstallationEmpty)
                    {
                        errorList.Add(
                            $"An end date was provided when '{fieldNameRequiredLifespanOfInstallation}' field was set to null for row: {rowNumber}");
                    }

                    if (!isAllowableEndDateOfInstallationEmpty)
                    {
                        if (!DateTime.TryParse(allowableEndDateOfInstallation,
                                               out var allowableEndDateOfInstallationDateTime))
                        {
                            errorList.Add(
                                $"{fieldNameAllowableEndDateOfInstallationIfApplicable} can not be converted to Date Time format at row: {rowNumber}");
                        }
                        else
                        {
                            treatmentBMP.TreatmentBMPLifespanEndDate = allowableEndDateOfInstallationDateTime;
                        }
                    }
                }
            }

            var requiredFieldVisitsPerYear = GetOptionalIntFieldValue(row, fieldsDict, rowNumber, errorList,
                                                                      "Required Field Visits Per Year");

            if (requiredFieldVisitsPerYear.HasValue)
            {
                treatmentBMP.RequiredFieldVisitsPerYear = requiredFieldVisitsPerYear;
            }

            var requiredPostStormFieldVisitsPerYear = GetOptionalIntFieldValue(row, fieldsDict, rowNumber,
                                                                               errorList, "Required Post-Storm Field Visits Per Year");

            if (requiredPostStormFieldVisitsPerYear.HasValue)
            {
                treatmentBMP.RequiredPostStormFieldVisitsPerYear = requiredPostStormFieldVisitsPerYear;
            }

            //End of Optional Fields
            var trashCaptureStatusTypeID = FindLookupValue(row, fieldsDict, "Trash Capture Status", rowNumber,
                                                           errorList, TrashCaptureStatusType.All, x => x.TrashCaptureStatusTypeDisplayName,
                                                           x => x.TrashCaptureStatusTypeID, true, isNew);

            if (trashCaptureStatusTypeID.HasValue)
            {
                treatmentBMP.TrashCaptureStatusTypeID = trashCaptureStatusTypeID.Value;
            }

            var treatmentBMPSizingBasisTypeID = FindLookupValue(row, fieldsDict, "Sizing Basis", rowNumber,
                                                                errorList, SizingBasisType.All, x => x.SizingBasisTypeDisplayName, x => x.SizingBasisTypeID, true,
                                                                isNew);

            if (treatmentBMPSizingBasisTypeID.HasValue)
            {
                treatmentBMP.SizingBasisTypeID = treatmentBMPSizingBasisTypeID.Value;
            }

            return(treatmentBMP);
        }