class ProgramContact(db.Model): __tablename__ = 'program_contact' #table columns id = db.Column(db.Integer, nullable=False, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) program_id = db.Column(db.Integer, db.ForeignKey('program.id'), nullable=False) card_id = db.Column(db.String(25)) stage = db.Column(db.Integer) is_approved = db.Column(db.Boolean, default=False) is_active = db.Column(db.Boolean, default=True) #relationship fields program = db.relationship('Program', back_populates='contacts') contact = db.relationship('Contact', back_populates='programs') # for more info on why to use setattr() read this: # https://medium.com/@s.azad4/modifying-python-objects-within-the-sqlalchemy-framework-7b6c8dd71ab3 def update(self, **update_dict): for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value) db.session.commit() @hybrid_property def applications(self): return [app for app in self.contact.applications if app.program_id == self.program_id]
class Opportunity(db.Model): __tablename__ = 'opportunity' # table columns id = db.Column(db.String, primary_key=True) program_id = db.Column(db.Integer, db.ForeignKey('program.id'), nullable=False) title = db.Column(db.String(200), nullable=False) short_description = db.Column(db.String(2000), nullable=False) gdoc_id = db.Column(db.String(200)) gdoc_link = db.Column(db.String(200), nullable=False) card_id = db.Column(db.String) program_name = db.Column(db.String) stage = db.Column(db.Integer, default=1) org_name = db.Column(db.String(255), nullable=False) is_active = db.Column(db.Boolean, default=True, nullable=False) # relationships applications = db.relationship('OpportunityApp', back_populates='opportunity', cascade='all, delete, delete-orphan') program = db.relationship('Program', back_populates='opportunities') @hybrid_property def status(self): return OpportunityStage(self.stage)
class ProgramApp(db.Model): __tablename__ = 'program_app' #table columns id = db.Column(db.Integer, nullable=False, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) program_id = db.Column(db.Integer, db.ForeignKey('program.id'), nullable=False) is_approved = db.Column(db.Boolean, default=False) is_interested = db.Column(db.Boolean, default=False) decision_date = db.Column(db.Date) #relationship fields program = db.relationship('Program', back_populates='program_apps') contact = db.relationship('Contact', back_populates='program_apps') # for more info on why to use setattr() read this: # https://medium.com/@s.azad4/modifying-python-objects-within-the-sqlalchemy-framework-7b6c8dd71ab3 def update(self, **update_dict): for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value) @hybrid_property def status(self): if not self.is_interested: return 'Not interested' elif self.is_interested and self.is_approved: return 'Eligible' else: return 'Waiting for approval'
class Race(db.Model): __tablename__ = 'race' # table columns id = db.Column(db.Integer, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) american_indian = db.Column(db.Boolean, default=False) asian = db.Column(db.Boolean, default=False) black = db.Column(db.Boolean, default=False) hawaiian = db.Column(db.Boolean, default=False) hispanic = db.Column(db.Boolean, default=False) south_asian = db.Column(db.Boolean, default=False) white = db.Column(db.Boolean, default=False) not_listed = db.Column(db.Boolean, default=False) race_other = db.Column(db.String) #relationships contact = db.relationship('Contact', back_populates='race') profile = db.relationship('Profile', back_populates='race') #methods def update(self, **update_dict): UPDATE_FIELDS = [ 'american_indian', 'asian', 'black', 'hawaiian', 'hispanic', 'south_asian', 'white', 'not_listed', 'race_other' ] for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value)
class OpportunityApp(db.Model): __tablename__ = 'opportunity_app' #table columns id = db.Column(db.String, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) opportunity_id = db.Column(db.String, db.ForeignKey('opportunity.id'), nullable=False) resume_id = db.Column(db.Integer, db.ForeignKey('resume_snapshot.id'), nullable=True) interest_statement = db.Column(db.String(2000), nullable=True) stage = db.Column(db.Integer, nullable=False, default=0) is_active = db.Column(db.Boolean, nullable=False, default=True) interview_date = db.Column(db.Date) interview_time = db.Column(db.String) resume = db.relationship('ResumeSnapshot') contact = db.relationship('Contact', back_populates='applications') opportunity = db.relationship('Opportunity') __table_args__ = (db.Index('oppapp_contact_opportunity', 'contact_id', 'opportunity_id', unique=True), ) #calculated fields @hybrid_property def status(self): return ApplicationStage(self.stage) @hybrid_property def program_id(self): return self.opportunity.program_id @hybrid_property def interview_completed(self): if self.interview_date and self.interview_time: interview_scheduled = dt.datetime.strptime( f'{self.interview_date} {self.interview_time}', '%Y-%m-%d %H:%M:%S') return interview_scheduled < dt.datetime.now() else: return False # for more info on why to use setattr() read this: # https://medium.com/@s.azad4/modifying-python-objects-within-the-sqlalchemy-framework-7b6c8dd71ab3 def update(self, **update_dict): for field, value in update_dict.items(): print(field, value) if field in UPDATE_FIELDS: setattr(self, field, value)
class Race(db.Model): __tablename__ = 'race' # table columns id = db.Column(db.Integer, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) american_indian = db.Column(db.Boolean, default=False) asian = db.Column(db.Boolean, default=False) black = db.Column(db.Boolean, default=False) hawaiian = db.Column(db.Boolean, default=False) hispanic = db.Column(db.Boolean, default=False) south_asian = db.Column(db.Boolean, default=False) white = db.Column(db.Boolean, default=False) not_listed = db.Column(db.Boolean, default=False) race_other = db.Column(db.String) race_all = db.Column(db.String, default='No Response') #relationships contact = db.relationship('Contact', back_populates='race') profile = db.relationship('Profile', back_populates='race') #methods def update(self, **update_dict): UPDATE_FIELDS = { 'american_indian': 'American Indian or Alaskan Native', 'asian': 'Asian', 'black': 'Black or African Descent', 'hispanic': 'Hispanic or Latinx', 'hawaiian': 'Native Hawaiian or Other Pacific Islander', 'south_asian': 'South Asian', 'white': 'White', 'not_listed': 'Not Listed', 'race_other': '' } race_list = [] for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value) if value == True: race_list.append(UPDATE_FIELDS[field]) if not race_list: race_all = 'No Response' else: race_all = ";".join(sorted(race_list)) self.race_all = race_all
class Program(db.Model): #table columns id = db.Column(db.Integer, nullable=False, primary_key=True) name = db.Column(db.String(100), nullable=False) trello_board_id = db.Column(db.String) #relationship fields program_apps = db.relationship('ProgramApp', back_populates='program', cascade='all, delete, delete-orphan') opportunities = db.relationship('Opportunity', back_populates='program', cascade='all, delete, delete-orphan')
class ProgramsCompleted(db.Model): __tablename__ = 'programs_completed' # table columns id = db.Column(db.Integer, primary_key=True) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) fellowship = db.Column(db.Boolean, default=False) mayoral_fellowship = db.Column(db.Boolean, default=False) public_allies = db.Column(db.Boolean, default=False) kiva = db.Column(db.Boolean, default=False) civic_innovators = db.Column(db.Boolean, default=False) elevation_awards = db.Column(db.Boolean, default=False) #relationships profile = db.relationship('Profile', back_populates='programs_completed') #methods def update(self, **update_dict): UPDATE_FIELDS = [ 'fellowship', 'mayoral_fellowship', 'public_allies', 'kiva', 'civic_innovators', 'elevation_awards', ] for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value)
class RoleChoice(db.Model): __tablename__ = 'role_choice' # table columns id = db.Column(db.Integer, primary_key=True) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) advocacy_public_policy = db.Column(db.Boolean, default=False) community_engagement_outreach = db.Column(db.Boolean, default=False) data_analysis = db.Column(db.Boolean, default=False) fundraising_development = db.Column(db.Boolean, default=False) marketing_public_relations = db.Column(db.Boolean, default=False) program_management = db.Column(db.Boolean, default=False) #relationships profile = db.relationship('Profile', back_populates='roles') #methods def update(self, **update_dict): UPDATE_FIELDS = [ 'advocacy_public_policy', 'community_engagement_outreach', 'data_analysis', 'fundraising_development', 'marketing_public_relations', 'program_management', ] for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value)
class Achievement(db.Model): __tablename__ = 'achievement' #table columns id = db.Column(db.Integer, primary_key=True) exp_id = db.Column(db.Integer, db.ForeignKey('experience.id'), nullable=False) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) description = db.Column(db.String) #relationships experience = db.relationship('Experience', back_populates='achievements') contact = db.relationship('Contact', back_populates='achievements') skill_items = db.relationship('AchievementSkill', cascade='all, delete, delete-orphan') def add_skill(self, skill, capability=None): capability_id = capability.id if capability else None experience_skill = self.experience.add_skill(skill) achievement_skill = (AchievementSkill.query.filter_by( achievement_id=self.id, parent_id=experience_skill.id, capability_id=capability_id).first()) if not achievement_skill: achievement_skill = AchievementSkill(experience_skill, self, capability) self.skill_items.append(achievement_skill) return achievement_skill #calculated fields @hybrid_property def skills(self): skills = [] for skill_item in self.skill_items: if not skill_item.deleted: skills.append({ 'name': skill_item.skill.name, 'capability_id': skill_item.capability_id, }) return sorted(skills, key=lambda skill: skill['name'])
class Capability(db.Model): __tablename__ = 'capability' #table columns id = db.Column(db.String, nullable=False, primary_key=True) name = db.Column(db.String, nullable=False) #relationships related_skills = db.relationship('Skill', secondary=capability_skills, lazy='subquery', back_populates='capabilities') recommended_skills = db.relationship('SkillRecommendation', order_by='SkillRecommendation.order', cascade='all, delete') __table_args__ = ( db.UniqueConstraint('name', name='capability_name_uniq'), )
class CapabilitySkillSuggestion(db.Model): """These are suggestions the user makes about which skills should be associated with which capablities """ __tablename__ = 'capability_skill_suggestions' #table columns capability_id = db.Column(db.String, db.ForeignKey('capability.id'), nullable=False) skill_id = db.Column(db.String, db.ForeignKey('skill.id'), nullable=False) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) #relationships capability = db.relationship('Capability') skill = db.relationship('Skill') contact = db.relationship('Contact', back_populates='capability_skill_suggestions') __table_args__ = ( db.PrimaryKeyConstraint('contact_id', 'capability_id', 'skill_id', name='cap_skill_suggestion_pk'), )
class ContactSkill(db.Model): __tablename__ = 'contact_skill_item' #table columns id = db.Column(db.Integer, primary_key=True) skill_id = db.Column(db.String, db.ForeignKey('skill.id')) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) deleted = db.Column(db.Boolean, nullable=False, default=False) #relationships skill = db.relationship('Skill') experiences = db.relationship('ExperienceSkill', back_populates='parent', cascade='all, delete, delete-orphan') contact = db.relationship('Contact', back_populates='skill_items') def __init__(self, skill=None, contact=None): self.skill = skill self.contact = contact
class ExperienceSkill(db.Model): __tablename__ = 'experience_skill_item' #table columns id = db.Column(db.Integer, primary_key=True) parent_id = db.Column(db.Integer, db.ForeignKey('contact_skill_item.id')) experience_id = db.Column(db.Integer, db.ForeignKey('experience.id')) #relationships parent = db.relationship('ContactSkill', back_populates='experiences') achievements = db.relationship('AchievementSkill', back_populates='parent', cascade='all, delete, delete-orphan') skill = association_proxy('parent', 'skill') deleted = association_proxy('parent', 'deleted') experience = db.relationship('Experience', back_populates='skill_items') def __init__(self, parent=None, experience=None): self.parent = parent self.experience = experience
class ResumeItem(db.Model): __tablename__ = 'resume_item' #table columns resume_order = db.Column(db.Integer, nullable=False, primary_key=True) section_id = db.Column(db.Integer, db.ForeignKey('resume_section.id'), nullable=False, primary_key=True) exp_id = db.Column(db.Integer, db.ForeignKey('experience.id')) tag_id = db.Column(db.Integer, db.ForeignKey('tag_item.id')) achievement_id = db.Column(db.Integer, db.ForeignKey('achievement.id')) resume_id = db.Column(db.Integer, db.ForeignKey('resume.id')) indented = db.Column(db.Boolean, default=False) #relationships section = db.relationship('ResumeSection', back_populates='items') experience = db.relationship('Experience') tag = db.relationship('TagItem') achievement = db.relationship('Achievement') resume = db.relationship('Resume')
class ResumeSection(db.Model): __tablename__ = 'resume_section' #table columns id = db.Column(db.Integer, primary_key=True) resume_id = db.Column(db.Integer, db.ForeignKey('resume.id'), nullable=False) name = db.Column(db.String(100), nullable=False) min_count = db.Column(db.Integer) max_count = db.Column(db.Integer) #relationships #resume = db.relationship('Resume', back_populates='sections') items = db.relationship('ResumeItem', back_populates='section', cascade='all, delete, delete-orphan')
class Email(db.Model): __tablename__ = 'email' #table columns id = db.Column(db.Integer, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) is_primary = db.Column(db.Boolean, default=False) email = db.Column(db.String(100), nullable=False) type = db.Column(db.Enum(Type, name='EmailType')) #relationships contact = db.relationship('Contact', back_populates='email_primary')
class AchievementSkill(db.Model): __tablename__ = 'achievement_skill_item' #table columns id = db.Column(db.Integer, primary_key=True) parent_id = db.Column(db.Integer, db.ForeignKey('experience_skill_item.id')) achievement_id = db.Column(db.Integer, db.ForeignKey('achievement.id')) capability_id = db.Column(db.String, db.ForeignKey('capability.id'), nullable=True) #relationships parent = db.relationship('ExperienceSkill', back_populates='achievements') skill = association_proxy('parent', 'skill') deleted = association_proxy('parent', 'deleted') capability = db.relationship('Capability') achievement = db.relationship('Achievement', back_populates='skill_items') def __init__(self, parent=None, achievement=None, capability=None): self.parent = parent self.achievement = achievement if capability is not None: self.capability = capability
class ContactAddress(db.Model): __tablename__ = 'contact_address' #table columns id = db.Column(db.Integer, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id'), nullable=False) is_primary = db.Column(db.Boolean, default=True) street1 = db.Column(db.String) street2 = db.Column(db.String) city = db.Column(db.String) state = db.Column(db.String) country = db.Column(db.String) zip_code = db.Column(db.String) #relationships contact = db.relationship('Contact', back_populates='addresses') profile = db.relationship('Profile', back_populates='addresses') #methods def update(self, **update_dict): UPDATE_FIELDS = [ 'street1', 'street2', 'city', 'state', 'country', 'zip_code', ] for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value)
class Recipe(TimestampMixin, DB.Model): """ Encapsulates the business logic of a recipe in the yummy recipes system. A recipe belongs to a User """ __tablename__ = 'recipes' id = DB.Column(DB.Integer, primary_key=True) user_id = DB.Column(DB.Integer, DB.ForeignKey('users.id'), nullable=False) title = DB.Column(DB.String, unique=True) description = DB.Column(DB.String) fulfilled = DB.Column(DB.Boolean) instructions = DB.relationship('Instruction', backref='recipe', lazy=True) ingredients = DB.relationship('Ingredient', backref='recipe', lazy=True) def __repr__(self): return "<Recipe(user_id='{}', title='{}', description='{}')>".format( self.user_id, self.title, self.description) def save(self): """This method persists the recipe object in the database""" DB.session.add(self) DB.session.commit()
class Skill(db.Model): __tablename__ = 'skill' #table columns id = db.Column(db.String, nullable=False, primary_key=True) name = db.Column(db.String, nullable=False) #relationships capabilities = db.relationship('Capability', secondary=capability_skills, lazy='subquery', back_populates='related_skills' ) __table_args__ = ( db.UniqueConstraint('name', name='skill_name_uniq'), )
class TagItem(db.Model): __tablename__ = 'tag_item' #table columns id = db.Column(db.Integer, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) tag_id = db.Column(db.Integer, db.ForeignKey('tag.id'), nullable=False) score = db.Column(db.Integer) #relationships #contact = db.relationship('Contact', back_populates='tags') #tag = db.relationship('Tag', back_populates='contacts') resumes = db.relationship('ResumeItem', back_populates='tag', cascade='all, delete, delete-orphan')
class SkillRecommendation(db.Model): """These are recommendations the system makes to users about skills they should consider choosing in certain capabilities """ __tablename__ = 'capability_skill_recommendations' #table columns capability_id = db.Column(db.String, db.ForeignKey('capability.id'), nullable=False) skill_id = db.Column(db.String, db.ForeignKey('skill.id'), nullable=False) order = db.Column(db.Integer, nullable=False) #relationships skill = db.relationship('Skill') __table_args__ = ( db.PrimaryKeyConstraint('capability_id', 'skill_id', name='cap_skill_rec_pk'), db.UniqueConstraint('capability_id', 'order', name='cap_skill_rec_order_uniq'), )
class UserSession(UserMixin, db.Model): __tablename__ = 'user_session' #table columns # This is the session id, not the user's id # This means it changes every time the user starts a new session id = db.Column(db.String, primary_key=True) auth_id = db.Column(db.String, nullable=False) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) jwt = db.Column(db.String(1000), nullable=False) expiration = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) #relationships contact = db.relationship('Contact') @hybrid_property def is_authenticated(self): return self.expiration > datetime.utcnow()
class Profile(db.Model): __tablename__ = 'profile' # table columns id = db.Column(db.Integer, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) gender = db.Column(db.String) gender_other = db.Column(db.String) pronoun = db.Column(db.String) pronoun_other = db.Column(db.String) years_exp = db.Column(db.String) job_search_status = db.Column(db.String) current_job_status = db.Column(db.String) current_edu_status = db.Column(db.String) previous_bcorps_program = db.Column(db.String) needs_help_programs = db.Column(db.Boolean) hear_about_us = db.Column(db.String) hear_about_us_other = db.Column(db.String) value_question1 = db.Column(db.String) value_question2 = db.Column(db.String) #relationships race = db.relationship('Race', back_populates='profile', cascade='all, delete, delete-orphan', uselist=False) address_primary = db.relationship('ContactAddress', primaryjoin=db.and_( id == ContactAddress.profile_id, ContactAddress.is_primary == True), back_populates='profile', uselist=False) addresses = db.relationship('ContactAddress', back_populates='profile', cascade='all, delete, delete-orphan') roles = db.relationship('RoleChoice', back_populates='profile', cascade='all, delete, delete-orphan', uselist=False) programs_completed = db.relationship('ProgramsCompleted', back_populates='profile', cascade='all, delete, delete-orphan', uselist=False) contact = db.relationship('Contact', back_populates='profile') #methods def update(self, **update_dict): UPDATE_FIELDS = [ 'gender', 'gender_other', 'pronoun', 'pronoun_other', 'years_exp', 'job_search_status', 'current_job_status', 'current_edu_status', 'previous_bcorps_program', 'needs_help_programs', 'hear_about_us', 'hear_about_us_other', 'value_question1', 'value_question2', ] address_data = update_dict.pop('address_primary', None) race_data = update_dict.pop('race', None) role_data = update_dict.pop('roles', None) programs_data = update_dict.pop('programs_completed', None) for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value) if address_data: self.address_primary.update(**address_data) if race_data: self.race.update(**race_data) if role_data: self.roles.update(**role_data) if programs_data: self.programs_completed.update(**programs_data)
class Profile(db.Model): __tablename__ = 'profile' # table columns id = db.Column(db.Integer, primary_key=True) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) gender = db.Column(db.String) gender_other = db.Column(db.String) pronoun = db.Column(db.String) pronoun_other = db.Column(db.String) years_exp = db.Column(db.String) job_search_status = db.Column(db.String) current_job_status = db.Column(db.String) current_edu_status = db.Column(db.String) previous_bcorps_program = db.Column(db.String) needs_help_programs = db.Column(db.Boolean) hear_about_us = db.Column(db.String) hear_about_us_other = db.Column(db.String) value_question1 = db.Column(db.String) value_question2 = db.Column(db.String) #relationships race = db.relationship('Race', back_populates='profile', cascade='all, delete, delete-orphan', uselist=False) address_primary = db.relationship('ContactAddress', primaryjoin=db.and_( id == ContactAddress.profile_id, ContactAddress.is_primary == True), back_populates='profile', uselist=False) addresses = db.relationship('ContactAddress', back_populates='profile', cascade='all, delete, delete-orphan') roles = db.relationship('RoleChoice', back_populates='profile', cascade='all, delete, delete-orphan', uselist=False) programs_completed = db.relationship('ProgramsCompleted', back_populates='profile', cascade='all, delete, delete-orphan', uselist=False) contact = db.relationship('Contact', back_populates='profile') # calculated fields @hybrid_property def roles_list(self): role_dict = { 'advocacy_public_policy': 'Advocacy and Public Policy', 'community_engagement_outreach': 'Community Engagement and Outreach', 'data_analysis': 'Data Analysis', 'fundraising_development': 'Fundraising and Development', 'marketing_public_relations': 'Marketing and Public Relations', 'program_management': 'Program Management', } roles_selected = [ role_dict[k] for k, v in self.roles.__dict__.items() if k in role_dict.keys() and v == True ] return roles_selected @hybrid_property def candidate_info_complete(self): if self.address_primary: return (self.address_primary.street1 is not None and self.address_primary.city is not None and self.address_primary.state is not None and self.address_primary.country is not None and self.address_primary.zip_code is not None) else: return False @hybrid_property def value_alignment_complete(self): return (self.value_question1 is not None and self.value_question2 is not None) @hybrid_property def interests_and_goals_complete(self): return (self.years_exp is not None and self.job_search_status is not None and self.current_job_status is not None and self.current_edu_status is not None) @hybrid_property def programs_and_eligibility_complete(self): if self.contact.program_apps: programs = [ p for p in self.contact.program_apps if p.is_interested ] else: programs = [] return self.needs_help_programs or (len(programs) > 0) #methods def update(self, **update_dict): UPDATE_FIELDS = [ 'gender', 'gender_other', 'pronoun', 'pronoun_other', 'years_exp', 'job_search_status', 'current_job_status', 'current_edu_status', 'previous_bcorps_program', 'needs_help_programs', 'hear_about_us', 'hear_about_us_other', 'value_question1', 'value_question2', ] address_data = update_dict.pop('address_primary', None) race_data = update_dict.pop('race', None) role_data = update_dict.pop('roles', None) programs_data = update_dict.pop('programs_completed', None) for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value) if address_data: self.address_primary.update(**address_data) if race_data: self.race.update(**race_data) if role_data: self.roles.update(**role_data) if programs_data: self.programs_completed.update(**programs_data)
class Contact(db.Model): __tablename__ = 'contact' #table columns id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String(100), nullable=False) last_name = db.Column(db.String(100), nullable=False) email = db.Column(db.String) phone_primary = db.Column(db.String(25)) account_id = db.Column(db.String(255), nullable=True) terms_agreement = db.Column(db.Boolean, default=False) stage = db.Column(db.Integer, default=1) card_id = db.Column(db.String) #relationships emails = db.relationship('Email', back_populates='contact', cascade='all, delete, delete-orphan') email_primary = db.relationship("Email", primaryjoin=db.and_( id == Email.contact_id, Email.is_primary == True), uselist=False) addresses = db.relationship('ContactAddress', back_populates='contact') address_primary = db.relationship('ContactAddress', primaryjoin=db.and_( id == ContactAddress.contact_id, ContactAddress.is_primary == True), back_populates='contact', uselist=False) achievements = db.relationship('Achievement', back_populates='contact', cascade='all, delete, delete-orphan') skill_items = db.relationship('ContactSkill', cascade='all, delete, delete-orphan') capability_skill_suggestions = db.relationship( 'CapabilitySkillSuggestion', cascade='all, delete, delete-orphan') experiences = db.relationship('Experience', back_populates='contact', cascade='all, delete, delete-orphan') program_apps = db.relationship('ProgramApp', back_populates='contact', cascade='all, delete, delete-orphan') programs_interested = db.relationship('ProgramApp', primaryjoin=db.and_( id == ProgramApp.contact_id, ProgramApp.is_interested), back_populates='contact') applications = db.relationship('OpportunityApp', back_populates='contact', cascade='all, delete, delete-orphan') sessions = db.relationship('UserSession', cascade='all, delete, delete-orphan') profile = db.relationship('Profile', back_populates='contact', uselist=False, cascade='all, delete, delete-orphan') race = db.relationship('Race', back_populates='contact', cascade='all, delete, delete-orphan', uselist=False) def add_skill(self, skill): contact_skill = (ContactSkill.query.filter_by( contact_id=self.id, skill_id=skill.id).first()) if contact_skill: contact_skill.deleted = False else: contact_skill = ContactSkill(skill, self) self.skill_items.append(contact_skill) return contact_skill @hybrid_property def skills(self): skills = [] for skill_item in self.skill_items: if not skill_item.deleted: skills.append(skill_item.skill) return sorted(skills, key=lambda skill: skill.name) @hybrid_property def email_main(self): if not self.email: return self.email_primary.email else: return self.email @hybrid_property def tag_skills_complete(self): return (len(self.skills) >= 3) @hybrid_property def add_experience_complete(self): complete_experience = [ exp for exp in self.experiences if exp.type == Type('Work') and exp.tag_skills_complete and exp.add_achievements_complete ] status = (len(complete_experience) >= 1) exp_dict = { 'is_complete': status, 'components': { 'tag_skills': status, 'add_achievements': status } } return exp_dict @hybrid_property def add_education_complete(self): complete_education = [ exp for exp in self.experiences if exp.type == Type('Education') ] return (len(complete_education) >= 1) @hybrid_property def add_portfolio_complete(self): complete_portfolio = [ exp for exp in self.experiences if exp.type == Type('Accomplishment') ] return (len(complete_portfolio) >= 1) @hybrid_property def profile_complete(self): profile_status = (self.add_experience_complete['is_complete'] and self.add_education_complete) profile_dict = { 'is_complete': profile_status, 'components': { 'tag_skills': self.tag_skills_complete, 'add_experience': self.add_experience_complete, 'add_education': self.add_education_complete, 'add_portfolio': self.add_portfolio_complete, } } return profile_dict @hybrid_property def about_me_complete(self): if self.profile: about_me_status = (self.profile.candidate_info_complete and self.profile.value_alignment_complete and self.profile.interests_and_goals_complete and self.profile.programs_and_eligibility_complete) about_me_dict = { 'is_complete': about_me_status, 'components': { 'candidate_information': self.profile.candidate_info_complete, 'value_alignment': self.profile.value_alignment_complete, 'programs': self.profile.programs_and_eligibility_complete, 'interests': self.profile.interests_and_goals_complete, } } else: about_me_dict = { 'is_complete': False, 'components': { 'candidate_information': False, 'value_alignment': False, 'programs': False, 'interests': False, } } return about_me_dict @hybrid_property def submit_complete(self): return {'is_complete': self.stage >= 2} @hybrid_property def status(self): return ContactStage(self.stage) @hybrid_property def race_list(self): race_dict = { 'american_indian': 'American Indian or Alaskan Native', 'asian': 'Asian', 'black': 'Black or African Descent', 'hawaiian': 'Native Hawaiian or Other Pacific Islander', 'hispanic': 'Hispanic or Latinx', 'south_asian': 'South Asian', 'white': 'White', 'not_listed': 'Not Listed', } race_list = [ race_dict[r] for r in race_dict.keys() if self.race.getattr(r) ] return race_list @hybrid_property def instructions(self): instructions_dict = { 'profile': self.profile_complete, 'about_me': self.about_me_complete, 'submit': self.submit_complete } return instructions_dict def query_program_contact(self, program_id): return next((p for p in self.programs if p.program_id == program_id), None) def update(self, **update_dict): for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value)
class Contact(db.Model): __tablename__ = 'contact' #table columns id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String(100), nullable=False) last_name = db.Column(db.String(100), nullable=False) email = db.Column(db.String) phone_primary = db.Column(db.String(25)) account_id = db.Column(db.String(255), nullable=True) terms_agreement =db.Column(db.Boolean, default=False) stage = db.Column(db.Integer, default=1) #relationships emails = db.relationship('Email', back_populates='contact', cascade='all, delete, delete-orphan') email_primary = db.relationship("Email", primaryjoin=db.and_( id == Email.contact_id, Email.is_primary == True), uselist=False) addresses = db.relationship('ContactAddress', back_populates='contact') address_primary = db.relationship('ContactAddress', primaryjoin=db.and_( id == ContactAddress.contact_id, ContactAddress.is_primary == True), back_populates='contact', uselist=False) achievements = db.relationship('Achievement', back_populates='contact', cascade='all, delete, delete-orphan') skill_items = db.relationship('ContactSkill', cascade='all, delete, delete-orphan') capability_skill_suggestions = db.relationship( 'CapabilitySkillSuggestion', cascade='all, delete, delete-orphan' ) experiences = db.relationship('Experience', back_populates='contact', cascade='all, delete, delete-orphan') programs = db.relationship('ProgramContact', back_populates='contact', cascade='all, delete, delete-orphan') program_apps = db.relationship('ProgramApp', back_populates='contact', cascade='all, delete, delete-orphan') applications = db.relationship('OpportunityApp', back_populates='contact', cascade='all, delete, delete-orphan') sessions = db.relationship('UserSession', cascade='all, delete, delete-orphan') profile = db.relationship('Profile', back_populates='contact', uselist=False, cascade='all, delete, delete-orphan') race = db.relationship('Race', back_populates='contact', cascade='all, delete, delete-orphan', uselist=False) def add_skill(self, skill): contact_skill = (ContactSkill.query .filter_by(contact_id=self.id, skill_id=skill.id) .first()) if contact_skill: contact_skill.deleted = False else: contact_skill = ContactSkill(skill, self) self.skill_items.append(contact_skill) return contact_skill @hybrid_property def skills(self): skills = [] for skill_item in self.skill_items: if not skill_item.deleted: skills.append(skill_item.skill) return sorted(skills, key=lambda skill: skill.name) @hybrid_property def email_main(self): if not self.email: return self.email_primary.email else: return self.email def query_program_contact(self, program_id): return next((p for p in self.programs if p.program_id == program_id), None) def update(self, **update_dict): for field, value in update_dict.items(): if field in UPDATE_FIELDS: setattr(self, field, value)
class Experience(db.Model): __tablename__ = 'experience' # table columns id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String) host = db.Column(db.String, nullable=False) title = db.Column(db.String, nullable=False) degree_other = db.Column(db.String(100)) degree = db.Column(db.String(100)) link = db.Column(db.String) link_name = db.Column(db.String) start_month = db.Column(db.Enum(Month, name='MonthType'), nullable=False) start_year = db.Column(db.Integer, nullable=False) end_month = db.Column(db.Enum(Month, name='MonthType'), nullable=False) end_year = db.Column(db.Integer, nullable=False) type = db.Column(db.Enum(Type, name='ExperienceType')) contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'), nullable=False) location = db.Column(db.String(255)) # relationships contact = db.relationship('Contact') achievements = db.relationship('Achievement', back_populates='experience', cascade='all, delete, delete-orphan') skill_items = db.relationship('ExperienceSkill', cascade='all, delete, delete-orphan') def add_skill(self, skill): contact_skill = self.contact.add_skill(skill) exp_skill = (ExperienceSkill.query.filter_by( experience_id=self.id, parent_id=contact_skill.id).first()) if not exp_skill: exp_skill = ExperienceSkill(contact_skill, self) self.skill_items.append(exp_skill) return exp_skill # calculated fields @hybrid_property def skills(self): skills = [] for skill_item in self.skill_items: if not skill_item.deleted: skills.append(skill_item.skill) return sorted(skills, key=lambda skill: skill.name) @hybrid_property def date_end(self): if self.end_month == Month.none or self.end_year == 0: return dt.datetime.today() else: end_str = f'1 {self.end_month.value}, {self.end_year}' return dt.datetime.strptime(end_str, '%d %B, %Y') @hybrid_property def date_start(self): if self.start_month == Month.none or self.start_year == 0: return dt.datetime.today() else: start_str = f'1 {self.start_month.value}, {self.start_year}' return dt.datetime.strptime(start_str, '%d %B, %Y') @hybrid_property def date_length(self): end = self.date_end start = self.date_start return (end.year - start.year) * 12 + end.month - start.month @hybrid_property def length_year(self): return math.floor(self.date_length / 12) @hybrid_property def length_month(self): return self.date_length % 12 @hybrid_property def is_current(self): if self.end_month == Month.none or self.end_year == 0: return True else: return False