Skip to content

Commit 9b08049

Browse files
committed
Merge remote-tracking branch 'origin/kas-well-BDMS-626-inventory-ingestion-updates_v2' into kas-well-BDMS-626-inventory-ingestion-updates_v2
2 parents 467c87e + eb6792c commit 9b08049

2 files changed

Lines changed: 151 additions & 5 deletions

File tree

services/well_inventory_csv.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,22 @@ def _add_csv_row(session: Session, group: Group, model: WellInventoryRow, user)
765765
}
766766
)
767767

768+
if (
769+
model.mp_height is not None
770+
and model.measuring_point_height_ft is not None
771+
and model.mp_height != model.measuring_point_height_ft
772+
):
773+
raise ValueError(
774+
"Conflicting values for measuring point height: mp_height and measuring_point_height_ft"
775+
)
776+
777+
if model.measuring_point_height_ft is not None:
778+
universal_mp_height = model.measuring_point_height_ft
779+
elif model.mp_height is not None:
780+
universal_mp_height = model.mp_height
781+
else:
782+
universal_mp_height = None
783+
768784
data = CreateWell(
769785
location_id=loc.id,
770786
group_id=group.id,
@@ -773,7 +789,7 @@ def _add_csv_row(session: Session, group: Group, model: WellInventoryRow, user)
773789
well_depth=model.total_well_depth_ft,
774790
well_depth_source=model.depth_source,
775791
well_casing_diameter=model.casing_diameter_ft,
776-
measuring_point_height=model.measuring_point_height_ft,
792+
measuring_point_height=universal_mp_height,
777793
measuring_point_description=model.measuring_point_description,
778794
well_completion_date=model.date_drilled,
779795
well_completion_date_source=model.completion_source,
@@ -917,7 +933,7 @@ def _add_csv_row(session: Session, group: Group, model: WellInventoryRow, user)
917933
value=model.depth_to_water_ft,
918934
unit="ft",
919935
observation_datetime=model.measurement_date_time,
920-
measuring_point_height=model.mp_height,
936+
measuring_point_height=universal_mp_height,
921937
groundwater_level_reason=(
922938
model.level_status.value
923939
if hasattr(model.level_status, "value")

tests/test_well_inventory.py

Lines changed: 133 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ def test_well_inventory_db_contents_with_waterlevels(tmp_path):
482482
"sample_method": "Steel-tape measurement",
483483
"data_quality": "Water level accurate to within two hundreths of a foot",
484484
"water_level_notes": "Attempted measurement",
485-
"mp_height_ft": 2.5,
485+
"mp_height_ft": 3.5,
486486
"level_status": "Water level not affected",
487487
}
488488
)
@@ -530,6 +530,136 @@ def test_well_inventory_db_contents_with_waterlevels(tmp_path):
530530
assert observation.sample == sample
531531

532532

533+
def test_measuring_point_height_ft_used_for_thing_and_observation(tmp_path):
534+
"""When measuring_point_height_ft is provided it is used for the thing's (MeasuringPointHistory) and observation's measuring_point_height values."""
535+
row = _minimal_valid_well_inventory_row()
536+
row.update(
537+
{
538+
"measuring_point_height_ft": 3.5,
539+
"water_level_date_time": "2025-02-15T10:30:00",
540+
"depth_to_water_ft": "8",
541+
"sample_method": "Steel-tape measurement",
542+
"data_quality": "Water level accurate to within two hundreths of a foot",
543+
"water_level_notes": "Attempted measurement",
544+
}
545+
)
546+
547+
file_path = tmp_path / "well-inventory-blank-depth.csv"
548+
with file_path.open("w", encoding="utf-8", newline="") as f:
549+
writer = csv.DictWriter(f, fieldnames=list(row.keys()))
550+
writer.writeheader()
551+
writer.writerow(row)
552+
553+
result = well_inventory_csv(file_path)
554+
assert result.exit_code == 0, result.stderr
555+
556+
with session_ctx() as session:
557+
things = session.query(Thing).all()
558+
observations = session.query(Observation).all()
559+
560+
assert len(things) == 1
561+
assert things[0].measuring_point_height == 3.5
562+
assert len(observations) == 1
563+
assert observations[0].measuring_point_height == 3.5
564+
565+
566+
def test_mp_height_used_for_thing_and_observation_when_measuring_point_height_ft_blank(
567+
tmp_path,
568+
):
569+
"""When depth to water is provided and measuring_point_height_ft is blank the mp_height value should be used for the thing's (MeasuringPointHistory) and observation's measuring_point_height."""
570+
row = _minimal_valid_well_inventory_row()
571+
row.update(
572+
{
573+
"measuring_point_height_ft": "",
574+
"water_level_date_time": "2025-02-15T10:30:00",
575+
"depth_to_water_ft": "8",
576+
"sample_method": "Steel-tape measurement",
577+
"data_quality": "Water level accurate to within two hundreths of a foot",
578+
"water_level_notes": "Attempted measurement",
579+
"mp_height": 4.0,
580+
}
581+
)
582+
583+
file_path = tmp_path / "well-inventory-blank-depth.csv"
584+
with file_path.open("w", encoding="utf-8", newline="") as f:
585+
writer = csv.DictWriter(f, fieldnames=list(row.keys()))
586+
writer.writeheader()
587+
writer.writerow(row)
588+
589+
result = well_inventory_csv(file_path)
590+
assert result.exit_code == 0, result.stderr
591+
592+
with session_ctx() as session:
593+
things = session.query(Thing).all()
594+
observations = session.query(Observation).all()
595+
596+
assert len(things) == 1
597+
assert things[0].measuring_point_height == 4.0
598+
assert len(observations) == 1
599+
assert observations[0].measuring_point_height == 4.0
600+
601+
602+
def test_null_mp_height_allowed(tmp_path):
603+
"""A null measuring_point_height_ft and mp_height are allowed when depth to water is provided, and results in null measuring_point_height for the thing and observation."""
604+
row = _minimal_valid_well_inventory_row()
605+
row.update(
606+
{
607+
"measuring_point_height_ft": "",
608+
"water_level_date_time": "2025-02-15T10:30:00",
609+
"depth_to_water_ft": 8,
610+
"sample_method": "Steel-tape measurement",
611+
"data_quality": "Water level accurate to within two hundreths of a foot",
612+
"water_level_notes": "Attempted measurement",
613+
}
614+
)
615+
616+
file_path = tmp_path / "well-inventory-blank-depth.csv"
617+
with file_path.open("w", encoding="utf-8", newline="") as f:
618+
writer = csv.DictWriter(f, fieldnames=list(row.keys()))
619+
writer.writeheader()
620+
writer.writerow(row)
621+
622+
result = well_inventory_csv(file_path)
623+
assert result.exit_code == 0, result.stderr
624+
625+
with session_ctx() as session:
626+
things = session.query(Thing).all()
627+
observations = session.query(Observation).all()
628+
629+
assert len(things) == 1
630+
assert things[0].measuring_point_height is None
631+
assert len(observations) == 1
632+
assert observations[0].value == 8
633+
assert observations[0].measuring_point_height is None
634+
635+
636+
def test_conflicting_mp_heights_raises_error(tmp_path):
637+
"""
638+
When both measuring_point_height_ft and mp_height are provided, an inequality (conflict) should raise an error.
639+
"""
640+
row = _minimal_valid_well_inventory_row()
641+
642+
row.update(
643+
{
644+
"measuring_point_height_ft": 3.5,
645+
"mp_height": 4.0,
646+
}
647+
)
648+
649+
file_path = tmp_path / "well-inventory-blank-depth.csv"
650+
with file_path.open("w", encoding="utf-8", newline="") as f:
651+
writer = csv.DictWriter(f, fieldnames=list(row.keys()))
652+
writer.writeheader()
653+
writer.writerow(row)
654+
655+
result = well_inventory_csv(file_path)
656+
assert result.exit_code == 1, result.stderr
657+
assert (
658+
result.payload["validation_errors"][0]["error"]
659+
== "Conflicting values for measuring point height: mp_height and measuring_point_height_ft"
660+
)
661+
662+
533663
def test_blank_depth_to_water_still_creates_water_level_records(tmp_path):
534664
"""Blank depth-to-water is treated as missing while preserving the attempted measurement."""
535665
row = _minimal_valid_well_inventory_row()
@@ -540,7 +670,7 @@ def test_blank_depth_to_water_still_creates_water_level_records(tmp_path):
540670
"sample_method": "Steel-tape measurement",
541671
"data_quality": "Water level accurate to within two hundreths of a foot",
542672
"water_level_notes": "Attempted measurement",
543-
"mp_height_ft": 2.5,
673+
"mp_height_ft": 3.5,
544674
}
545675
)
546676

@@ -564,7 +694,7 @@ def test_blank_depth_to_water_still_creates_water_level_records(tmp_path):
564694
"2025-02-15T10:30:00Z"
565695
)
566696
assert observations[0].value is None
567-
assert observations[0].measuring_point_height == 2.5
697+
assert observations[0].measuring_point_height == 3.5
568698

569699

570700
def test_rerunning_same_well_inventory_csv_is_idempotent():

0 commit comments

Comments
 (0)