Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,5 @@
GeographicScale: type[Enum] = build_enum_from_lexicon_category("geographic_scale")
Lithology: type[Enum] = build_enum_from_lexicon_category("lithology")
FormationCode: type[Enum] = build_enum_from_lexicon_category("formation_code")
NoteType: type[Enum] = build_enum_from_lexicon_category("note_type")
# ============= EOF =============================================
1 change: 1 addition & 0 deletions core/lexicon.json
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,7 @@
{"categories": ["note_type"], "term": "Water", "definition": "Water bearing zone information and other info from ose reports"},
{"categories": ["note_type"], "term": "Measuring", "definition": "Notes about measuring/visiting the well, on Access form"},
{"categories": ["note_type"], "term": "Coordinate", "definition": "Notes about a location's coordinates"},
{"categories": ["note_type"], "term": "Communication", "definition": "Notes about communication preferences/requests for a contact"},
{"categories": ["well_pump_type"], "term": "Submersible", "definition": "Submersible"},
{"categories": ["well_pump_type"], "term": "Jet", "definition": "Jet Pump"},
{"categories": ["well_pump_type"], "term": "Line Shaft", "definition": "Line Shaft"},
Expand Down
11 changes: 10 additions & 1 deletion db/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from sqlalchemy_utils import TSVectorType

from db.base import Base, AutoBaseMixin, ReleaseMixin, lexicon_term
from db.notes import NotesMixin

if TYPE_CHECKING:
from db.field import FieldEventParticipant, FieldEvent
Expand All @@ -45,7 +46,7 @@ class ThingContactAssociation(Base, AutoBaseMixin):
)


class Contact(Base, AutoBaseMixin, ReleaseMixin):
class Contact(Base, AutoBaseMixin, ReleaseMixin, NotesMixin):
name: Mapped[str] = mapped_column(String(100), nullable=True)
organization: Mapped[str] = lexicon_term(nullable=True)
role: Mapped[str] = lexicon_term(nullable=False)
Expand Down Expand Up @@ -124,6 +125,14 @@ class Contact(Base, AutoBaseMixin, ReleaseMixin):
UniqueConstraint("name", "organization", name="uq_contact_name_organization"),
)

@property
def communication_notes(self):
return self._get_notes("Communication")

@property
def general_notes(self):
return self._get_notes("General")


class IncompleteNMAPhone(Base, AutoBaseMixin):
"""
Expand Down
4 changes: 4 additions & 0 deletions schemas/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from core.enums import Role, ContactType, PhoneType, EmailType, AddressType
from schemas import BaseResponseModel, BaseCreateModel, BaseUpdateModel
from schemas.notes import CreateNote, NoteResponse


# -------- VALIDATORS ----------
Expand Down Expand Up @@ -157,6 +158,7 @@ class CreateContact(BaseCreateModel, ValidateContact):
emails: list[CreateEmail] | None = None
phones: list[CreatePhone] | None = None
addresses: list[CreateAddress] | None = None
notes: list[CreateNote] | None = None


# -------- RESPONSE ----------
Expand Down Expand Up @@ -221,6 +223,8 @@ class ContactResponse(BaseResponseModel):
phones: List[PhoneResponse] = []
addresses: List[AddressResponse] = []
things: List[ThingResponseForContact] = []
communication_notes: List[NoteResponse] = []
general_notes: List[NoteResponse] = []

@field_validator("incomplete_nma_phones", mode="before")
def make_incomplete_nma_phone_str(cls, v: list) -> list:
Expand Down
7 changes: 5 additions & 2 deletions schemas/notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Pydantic models for the Notes table.
"""

from core.enums import NoteType

from pydantic import BaseModel
from schemas import BaseCreateModel, BaseUpdateModel, BaseResponseModel

# -------- BASE SCHEMA: ----------
Expand All @@ -10,8 +13,8 @@
"""


class BaseNote:
note_type: str
class BaseNote(BaseModel):
note_type: NoteType
content: str


Expand Down
18 changes: 14 additions & 4 deletions services/contact_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def add_contact(session: Session, data: CreateContact | dict, user: dict) -> Con
phone_data = data.pop("phones", [])
address_data = data.pop("addresses", [])
thing_id = data.pop("thing_id", None)
notes_data = data.pop("notes", None)
contact_data = data

"""
Expand Down Expand Up @@ -104,12 +105,21 @@ def add_contact(session: Session, data: CreateContact | dict, user: dict) -> Con
audit_add(user, location_contact_association)

session.add(location_contact_association)
# owner_contact_association = OwnerContactAssociation()
# owner_contact_association.owner_id = owner.id
# owner_contact_association.contact_id = contact.id
# session.add(owner_contact_association)

session.flush()
session.commit()

if notes_data is not None:
for n in notes_data:
note = contact.add_note(n["content"], n["note_type"])
session.add(note)

session.commit()
session.refresh(contact)

for note in contact.notes:
session.refresh(note)

except Exception as e:
session.rollback()
raise e
Expand Down
10 changes: 9 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def location():
session.commit()
session.refresh(loc)

note = loc.add_note("these are some test notes", "Other")
note = loc.add_note("these are some test notes", "General")
session.add(note)
session.commit()
session.refresh(loc)
Expand Down Expand Up @@ -356,6 +356,14 @@ def contact(water_well_thing):
session.commit()
session.refresh(association)

for content, note_type in [
("Communication note", "Communication"),
("General note", "General"),
]:
note = contact.add_note(content, note_type)
session.add(note)
session.commit()

yield contact
session.delete(contact)
session.delete(association)
Expand Down
22 changes: 22 additions & 0 deletions tests/test_contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ def test_add_contact(spring_thing):
"address_type": "Primary",
}
],
"notes": [
{
"note_type": "General",
"content": "This is a general note for the contact.",
}
],
}
response = client.post("/contact", json=payload)
data = response.json()
Expand Down Expand Up @@ -158,6 +164,12 @@ def test_add_contact(spring_thing):
)
assert data["release_status"] == payload["release_status"]

assert data["general_notes"][0]["note_type"] == "General"
assert (
data["general_notes"][0]["content"] == "This is a general note for the contact."
)
assert len(data["communication_notes"]) == 0

cleanup_post_test(Contact, data["id"])


Expand Down Expand Up @@ -429,6 +441,11 @@ def test_get_contacts(
assert data["items"][0]["addresses"][0]["address_type"] == address.address_type
assert data["items"][0]["addresses"][0]["release_status"] == address.release_status

assert data["items"][0]["general_notes"][0]["note_type"] == "General"
assert data["items"][0]["general_notes"][0]["content"] == "General note"
assert data["items"][0]["communication_notes"][0]["note_type"] == "Communication"
assert data["items"][0]["communication_notes"][0]["content"] == "Communication note"


def test_get_contacts_by_thing_id(contact, second_contact, water_well_thing):
response = client.get(f"/contact?thing_id={water_well_thing.id}")
Expand Down Expand Up @@ -495,6 +512,11 @@ def test_get_contact_by_id(
assert data["addresses"][0]["address_type"] == address.address_type
assert data["addresses"][0]["release_status"] == address.release_status

assert data["general_notes"][0]["note_type"] == "General"
assert data["general_notes"][0]["content"] == "General note"
assert data["communication_notes"][0]["note_type"] == "Communication"
assert data["communication_notes"][0]["content"] == "Communication note"


def test_get_contact_by_id_404_not_found(contact):
bad_contact_id = 99999
Expand Down
3 changes: 1 addition & 2 deletions transfers/contact_transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,7 @@ def _make_contact_and_assoc(session, data, thing, added):
from schemas.contact import CreateContact

contact = CreateContact(**data)
contact_data = contact.model_dump()
contact_data.pop("thing_id")
contact_data = contact.model_dump(exclude=["thing_id", "notes"])
contact = Contact(**contact_data)
session.add(contact)

Expand Down
Loading