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); }