-
Notifications
You must be signed in to change notification settings - Fork 4
BDMS 57: updated contact model, schema, tests, and transfer #119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3fcccb4
e3a834c
bde2d19
2426eaa
b422780
92f6268
ddbb9f6
8ca80e1
a08439e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,14 +34,18 @@ class ThingContactAssociation(Base, AutoBaseMixin): | |
|
|
||
|
|
||
| class Contact(Base, AutoBaseMixin, ReleaseMixin): | ||
| name = Column(String(100), nullable=False) | ||
| name = Column(String(100), nullable=True) | ||
| role = lexicon_term(nullable=False) | ||
| organization = Column(String(100), nullable=True) | ||
| nma_pk_owners = Column(String(100), nullable=True) | ||
|
|
||
| phones = relationship("Phone", back_populates="contact", passive_deletes=True) | ||
| emails = relationship("Email", back_populates="contact", passive_deletes=True) | ||
| addresses = relationship("Address", back_populates="contact", passive_deletes=True) | ||
|
|
||
| search_vector = Column(TSVectorType("name", "role")) | ||
| search_vector = Column( | ||
| TSVectorType("name", "role", "organization", "nma_pk_owners") | ||
| ) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should think about whether or not we should make nma_pk_owners searchable
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That data is encoded in either the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets leave role it in for now, but i get your point. Someone probably won't search by the "role" keyword |
||
|
|
||
| author_associations = relationship( | ||
| "AuthorContactAssociation", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| # =============================================================================== | ||
| # Copyright 2025 ross | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| # =============================================================================== | ||
| import numpy as np | ||
| import pandas as pd | ||
| from transfers.util import read_csv, filter_to_valid_point_ids | ||
| from db import Thing, Contact, ThingContactAssociation, Email, Phone, Address | ||
|
|
||
|
|
||
| def extract_owner_role(comment): | ||
| # if comment is None: | ||
| # return "Owner" | ||
| # if "Owner" in comment: | ||
| # return "Owner" | ||
| # if "Manager" in comment: | ||
| # return "Manager" | ||
| # if "Director" in comment: | ||
| # return "Director" | ||
|
|
||
| return "Primary" | ||
|
|
||
|
|
||
| def transfer_contacts(session): | ||
|
|
||
| odf = read_csv("ownersdata.csv") | ||
| odf = odf.replace(pd.NA, None) | ||
| odf = odf.replace({np.nan: None}) | ||
| odf = filter_to_valid_point_ids(session, odf) | ||
| for i, row in odf.iterrows(): | ||
| thing = session.query(Thing).where(Thing.name == row.PointID).first() | ||
| if thing is None: | ||
| print(f"Thing with PointID {row.PointID} not foaund. Skipping owner.") | ||
| continue | ||
|
|
||
| # TODO: extract role from OwnerComment | ||
| # role = extract_owner_role(row.OwnerComment) | ||
| role = "Primary" | ||
|
|
||
| # TODO: put in guards for null values | ||
| # name OR organization must be defined, otherwise skip | ||
| if not (row.FirstName or row.LastName) and not row.Company: | ||
| print( | ||
| f"Skipping first contact for PointID {row.PointID} due to missing name and organization." | ||
| ) | ||
| else: | ||
| print(f"Transferring first contact for PointID {row.PointID}") | ||
| contact1 = Contact( | ||
| name=f"{row.FirstName} {row.LastName}", | ||
| role=role, | ||
| organization=row.Company, # assumes organization applies to both contacts | ||
| nma_pk_owners=row.OwnerKey, | ||
| ) | ||
| assoc = ThingContactAssociation() | ||
| assoc.thing = thing | ||
| assoc.contact = contact1 | ||
| session.add(assoc) | ||
| session.add(contact1) | ||
|
|
||
| if row.Email: | ||
| contact1.emails.append(Email(email=row.Email, email_type="Primary")) | ||
| if row.Phone: | ||
| contact1.phones.append( | ||
| Phone(phone_number=row.Phone, phone_type="Primary") | ||
| ) | ||
| if row.CellPhone: | ||
| contact1.phones.append( | ||
| Phone(phone_number=row.CellPhone, phone_type="Mobile") | ||
| ) | ||
|
|
||
| if row.MailingAddress: | ||
| contact1.addresses.append( | ||
| Address( | ||
| address_line_1=row.MailingAddress, | ||
| city=row.MailCity, | ||
| state=row.MailState, | ||
| postal_code=row.MailZipCode, | ||
| address_type="Mailing", | ||
| ) | ||
| ) | ||
|
|
||
| contact1.addresses.append( | ||
| Address( | ||
| address_line_1=row.PhysicalAddress, | ||
| city=row.PhysicalCity, | ||
| state=row.PhysicalState, | ||
| postal_code=row.PhysicalZipCode, | ||
| address_type="Physical", | ||
| ) | ||
| ) | ||
|
|
||
| # TODO: put in guards for null values | ||
| if not (row.SecondFirstName or row.SecondLastName) and not row.Company: | ||
| print( | ||
| f"Skipping second contact for PointID {row.PointID} due to missing name and organization." | ||
| ) | ||
| else: | ||
| print(f"Transferring second contact for PointID {row.PointID}") | ||
| contact2 = Contact( | ||
| name=f"{row.SecondFirstName} {row.SecondLastName}", | ||
| role="Secondary", | ||
| organization=row.Company, # Assumes organization applies to both contacts | ||
| nma_pk_owners=row.OwnerKey, | ||
| ) | ||
| if row.SecondCtctEmail: | ||
| contact2.emails.append( | ||
| Email(email=row.SecondCtctEmail, email_type="Primary") | ||
| ) | ||
| if row.SecondCtctPhone: | ||
| contact2.phones.append( | ||
| Phone(phone_number=row.SecondCtctPhone, phone_type="Primary") | ||
| ) | ||
|
|
||
| assoc = ThingContactAssociation() | ||
| assoc.thing = thing | ||
| assoc.contact = contact2 | ||
| session.add(assoc) | ||
| session.add(contact2) | ||
|
|
||
| session.commit() | ||
|
|
||
|
|
||
| # ============= EOF ============================================= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| PointID,FirstName,LastName,OwnerKey,Email,CellPhone,Phone,MailingAddress,MailCity,MailState,MailZipCode,PhysicalAddress,PhysicalCity,PhysicalState,PhysicalZipCode,SecondLastName,SecondFirstName,SecondCtctEmail,SecondCtctPhone | ||
| EB-270,John,Doe,OWN001,john.doe@example.com,555-1234,555-5678,123 Main St,Albuquerque,NM,87101,456 Elm St,Albuquerque,NM,87102,Smith,Jane,jane.smith@example.com,555-8765 | ||
| EB-271,Alice,Johnson,OWN002,alice.j@example.com,555-2345,555-6789,789 Oak St,Socorro,NM,87801,101 Pine St,Socorro,NM,87802,Brown,Bob,bob.brown@example.com,555-4321 | ||
| EB-272,Maria,Gonzalez,OWN003,maria.g@example.com,555-3456,555-7890,234 Maple St,Las Cruces,NM,88001,567 Cedar St,Las Cruces,NM,88002,Lopez,Carlos,carlos.lopez@example.com,555-5432 | ||
| PointID,FirstName,LastName,OwnerKey,Company,Email,CellPhone,Phone,MailingAddress,MailCity,MailState,MailZipCode,PhysicalAddress,PhysicalCity,PhysicalState,PhysicalZipCode,SecondLastName,SecondFirstName,SecondCtctEmail,SecondCtctPhone | ||
| QU-047,John,Doe,OWN001,JD LLC,john.doe@example.com,555-1234,555-5678,123 Main St,Albuquerque,NM,87101,456 Elm St,Albuquerque,NM,87102,Smith,Jane,jane.smith@example.com,555-8765 | ||
| NM-11224,Alice,Johnson,OWN002,AJ LLC,alice.j@example.com,555-2345,555-6789,789 Oak St,Socorro,NM,87801,101 Pine St,Socorro,NM,87802,Brown,Bob,bob.brown@example.com,555-4321 | ||
| NM-21466,Maria,Gonzalez,OWN003,MG LLC,maria.g@example.com,555-3456,555-7890,234 Maple St,Las Cruces,NM,88001,567 Cedar St,Las Cruces,NM,88002,Lopez,Carlos,carlos.lopez@example.com,555-5432 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be