private void MergeWithExistingVisit(FieldVisitInfo existingVisit, StageDischargeReadingRecord visitRecord) { existingVisit.FieldVisitDetails.FieldVisitPeriod = ExpandInterval( existingVisit.FieldVisitDetails.FieldVisitPeriod, visitRecord.MeasurementStartDateTime, visitRecord.MeasurementEndDateTime); existingVisit.FieldVisitDetails.Comments = MergeUniqueComments(existingVisit.FieldVisitDetails.Comments, visitRecord.Comments); existingVisit.FieldVisitDetails.Party = MergeUniqueParties(existingVisit.FieldVisitDetails.Party, visitRecord.Party); var visitDuration = existingVisit.FieldVisitDetails.FieldVisitPeriod.End - existingVisit.FieldVisitDetails.FieldVisitPeriod.Start; if (visitDuration.TotalHours > 36) { // Log a warning, but keep going _log.Error($"{existingVisit.LocationInfo.LocationIdentifier} visit Start={existingVisit.FieldVisitDetails.FieldVisitPeriod.Start} End={existingVisit.FieldVisitDetails.FieldVisitPeriod.End} exceeds 36 hours TotalHours={visitDuration.TotalHours:F1}"); } if (!IsValidMeasurementId(visitRecord.MeasurementId)) { return; } AddVisitByMeasurementId(existingVisit, visitRecord); }
private void CreateReadingsForVisit(FieldVisitInfo fieldVisit, StageDischargeReadingRecord record) { foreach (var reading in record.Readings) { _fieldDataResultsAppender.AddReading(fieldVisit, reading); } }
private FieldVisitInfo MergeOrCreateVisit(LocationInfo location, StageDischargeReadingRecord visitRecord) { var existingVisit = FindExistingVisit(visitRecord); if (existingVisit != null) { MergeWithExistingVisit(existingVisit, visitRecord); return(existingVisit); } var visitStart = visitRecord.MeasurementStartDateTime; var visitEnd = visitRecord.MeasurementEndDateTime; var fieldVisitDetails = new FieldVisitDetails(new DateTimeInterval(visitStart, visitEnd)) { Comments = visitRecord.Comments, Party = visitRecord.Party }; var fieldVisitInfo = _fieldDataResultsAppender.AddFieldVisit(location, fieldVisitDetails); CreatedVisits.Add(fieldVisitInfo); if (IsValidMeasurementId(visitRecord.MeasurementId)) { AddVisitByMeasurementId(fieldVisitInfo, visitRecord); } return(fieldVisitInfo); }
private void CheckNoExceptionWhenSpecifiedFieldIsNull(StageDischargeReadingRecord stageDischargeReadingRecord, string propertyName) { SetValueToNull(ref stageDischargeReadingRecord, propertyName); Action validationAction = () => stageDischargeReadingRecord.Validate(); validationAction.ShouldNotThrow(); }
private Stream CreateMemoryStream(StageDischargeReadingRecord originalRecord) { var csvFile = new InMemoryCsvFile <StageDischargeReadingRecord>(); csvFile.AddRecord(originalRecord); return(csvFile.GetInMemoryCsvFileStream()); }
private void CheckExpectedExceptionForProperty <E>(StageDischargeReadingRecord stageDischargeReadingRecord, string propertyName) where E : Exception { Action validationAction = () => stageDischargeReadingRecord.Validate(); validationAction .ShouldThrow <E>() .And.Message.Should().Contain(propertyName); }
private void SetValueToNull(ref StageDischargeReadingRecord stageDischargeReadingRecord, string propertyName) { var field = stageDischargeReadingRecord.GetType().GetField(propertyName); if (field != null) { field.SetValue(stageDischargeReadingRecord, null); } }
private void CreateDischargeActivityForVisit(FieldVisitInfo fieldVisit, StageDischargeReadingRecord record) { if (!record.Discharge.HasValue) { return; } _fieldDataResultsAppender.AddDischargeActivity(fieldVisit, CreateDischargeActivityFromRecord(record)); }
private Stream CreateMinimalValidFileStream() { StageDischargeReadingRecord stageDischargeReadingRecord = StageDischargeCsvFileBuilder.CreateFullRecord(_fixture); stageDischargeReadingRecord.ChannelWidth = null; stageDischargeReadingRecord.ChannelArea = null; stageDischargeReadingRecord.Party = null; stageDischargeReadingRecord.Comments = null; return(CreateMemoryStream(stageDischargeReadingRecord)); }
private static UnitSystem CreateUnitSystem(StageDischargeReadingRecord record) { return(new UnitSystem { DistanceUnitId = record.WidthUnits, AreaUnitId = record.AreaUnits, DischargeUnitId = record.DischargeUnits, VelocityUnitId = record.VelocityUnits }); }
private void PutNRecordsInCsvFile(int recordCount, ref InMemoryCsvFile <StageDischargeReadingRecord> csvFile) { for (var i = 0; i < recordCount; i++) { StageDischargeReadingRecord rRecord = _fixture.Build <StageDischargeReadingRecord>() .With(x => x.MeasurementStartDateTime, DateTime.Now.AddHours(i)) .With(x => x.MeasurementEndDateTime, DateTime.Now.AddHours(i * 2)) .Without(x => x.Readings) .Create(); csvFile.AddRecord(rRecord); } }
private void AddGageHeightMeasurements(DischargeActivity activity, StageDischargeReadingRecord record) { if (record.StageAtStart.HasValue) { activity.GageHeightMeasurements.Add(new GageHeightMeasurement(new Measurement(record.StageAtStart.GetValueOrDefault(), record.StageUnits), record.MeasurementStartDateTime)); } if (record.StageAtEnd.HasValue) { activity.GageHeightMeasurements.Add(new GageHeightMeasurement(new Measurement(record.StageAtEnd.GetValueOrDefault(), record.StageUnits), record.MeasurementEndDateTime)); } }
private FieldVisitInfo FindExistingVisit(StageDischargeReadingRecord visitRecord) { if (VisitsByMeasurementId.TryGetValue(visitRecord.MeasurementId.Trim(), out var otherVisit)) { if (otherVisit.StartDate.Date == visitRecord.MeasurementStartDateTime.Date || otherVisit.EndDate.Date == visitRecord.MeasurementEndDateTime.Date) { // We can match up visits by measurement ID _log.Info($"Found associated measurementId={visitRecord.MeasurementId} at Start={otherVisit.StartDate} and End={otherVisit.EndDate}"); return(otherVisit); } } var containingVisits = CreatedVisits .Where(fv => fv.StartDate <= visitRecord.MeasurementStartDateTime && fv.EndDate >= visitRecord.MeasurementEndDateTime) .ToList(); if (containingVisits.Count == 1) { // The record fits completely within exactly one existing visit var visit = containingVisits.Single(); _log.Info($"Merging existing {visit.LocationInfo.LocationIdentifier} visit.Start={visit.StartDate} visit.End={visit.EndDate} with completely contained record.Start={visitRecord.MeasurementStartDateTime} record.End={visitRecord.MeasurementEndDateTime}"); return(visit); } var possibleVisits = CreatedVisits .Where(fv => fv.StartDate.Date == visitRecord.MeasurementStartDateTime.Date || fv.EndDate.Date == visitRecord.MeasurementEndDateTime.Date) .ToList(); if (possibleVisits.Count == 1) { // An exact match with on existing visit on the same day as the record var visit = possibleVisits.Single(); _log.Info($"Merging existing {visit.LocationInfo.LocationIdentifier} visit.Start={visit.StartDate} visit.End={visit.EndDate} with same day record.Start={visitRecord.MeasurementStartDateTime} record.End={visitRecord.MeasurementEndDateTime}"); return(visit); } if (possibleVisits.Count == 0) { return(null); } var error = $"Confused merge of record.Start={visitRecord.MeasurementStartDateTime} record.End={visitRecord.MeasurementEndDateTime} with {possibleVisits.Count} possible visits: {string.Join(", ", possibleVisits.Select(fv => $"Start={fv.StartDate} End={fv.EndDate}"))}"; _log.Error(error); throw new Exception(error); }
public void StageDischargeRecord_SelfValidate_Timestamps() { StageDischargeReadingRecord stageDischargeReadingRecord = StageDischargeCsvFileBuilder.CreateFullRecord(_fixture); Action validationAction = () => stageDischargeReadingRecord.Validate(); stageDischargeReadingRecord.MeasurementStartDateTime = DateTimeOffset.Now; stageDischargeReadingRecord.MeasurementEndDateTime = stageDischargeReadingRecord.MeasurementStartDateTime; validationAction.ShouldNotThrow(); stageDischargeReadingRecord.MeasurementEndDateTime = DateTimeOffset.Now.AddDays(1); validationAction.ShouldNotThrow(); stageDischargeReadingRecord.MeasurementStartDateTime = DateTimeOffset.Now.AddDays(200); validationAction.ShouldThrow <ArgumentException>().And.Message.Should().Contain("MeasurementStartDateTime"); }
private void AddVisitByMeasurementId(FieldVisitInfo fieldVisitInfo, StageDischargeReadingRecord visitRecord) { var measurementId = visitRecord.MeasurementId.Trim(); if (VisitsByMeasurementId.ContainsKey(measurementId)) { var associatedVisit = VisitsByMeasurementId[measurementId]; if (associatedVisit != fieldVisitInfo) { _log.Error($"MeasurementId={measurementId} is already associated with a different {associatedVisit.LocationInfo.LocationIdentifier} visit Start={associatedVisit.StartDate} End={associatedVisit.EndDate}. Can't switch to a different {fieldVisitInfo.LocationInfo.LocationIdentifier} visit Start={fieldVisitInfo.StartDate} End={fieldVisitInfo.EndDate}"); // Re-associate it, but the import is likely going to fail anyway. VisitsByMeasurementId[measurementId] = fieldVisitInfo; } return; } VisitsByMeasurementId.Add(measurementId, fieldVisitInfo); }
public DischargeActivity FromStageDischargeRecord(StageDischargeReadingRecord record) { var discharge = new Measurement(record.Discharge.GetValueOrDefault(), record.DischargeUnits); var dischargeInterval = new DateTimeInterval(record.MeasurementStartDateTime, record.MeasurementEndDateTime); var activity = new DischargeActivity(dischargeInterval, discharge) { MeasurementId = record.MeasurementId, Comments = record.Comments, Party = record.Party }; AddGageHeightMeasurements(activity, record); var manualGaugingDischarge = CreateChannelMeasurementFromRecord(record, dischargeInterval, discharge); if (manualGaugingDischarge != null) { activity.ChannelMeasurements.Add(manualGaugingDischarge); } return(activity); }
private static ChannelMeasurementBase CreateChannelMeasurementFromRecord(StageDischargeReadingRecord record, DateTimeInterval dischargeInterval, Measurement discharge) { var section = new ManualGaugingDischargeSectionFactory(CreateUnitSystem(record)) { DefaultChannelName = record.ChannelName } .CreateManualGaugingDischargeSection(dischargeInterval, discharge.Value); section.AreaValue = record.ChannelArea; section.AreaUnitId = record.AreaUnits; section.WidthValue = record.ChannelWidth; section.DistanceUnitId = record.WidthUnits; section.VelocityAverageValue = record.ChannelVelocity; section.VelocityUnitId = record.VelocityUnits; section.ChannelName = record.ChannelName; section.Party = record.Party; section.DischargeMethod = DischargeMethodType.MidSection; section.VelocityObservationMethod = PointVelocityObservationType.Unknown; section.DeploymentMethod = DeploymentMethodType.Unspecified; section.MeterSuspension = MeterSuspensionType.Unspecified; return(section); }
private StageDischargeRecordBuilder() { _stageDischargeReadingRecord = new StageDischargeReadingRecord(); }
private void CheckExpectedExceptionAndMessageWhenSpecifiedFieldIsNull <E>(StageDischargeReadingRecord stageDischargeReadingRecord, string propertyName) where E : Exception { SetValueToNull(ref stageDischargeReadingRecord, propertyName); CheckExpectedExceptionForProperty <E>(stageDischargeReadingRecord, propertyName); }
private DischargeActivity CreateDischargeActivityFromRecord(StageDischargeReadingRecord record) { return(_dischargeActivityMapper.FromStageDischargeRecord(record)); }
private Stream CreateValidCsvFileStream() { StageDischargeReadingRecord originalRecord = StageDischargeCsvFileBuilder.CreateFullRecord(_fixture); return(CreateMemoryStream(originalRecord)); }