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'
Beispiel #4
0
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)
Beispiel #5
0
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
Beispiel #7
0
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')
Beispiel #8
0
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)
Beispiel #9
0
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)
Beispiel #10
0
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'])
Beispiel #11
0
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'),
    )
Beispiel #12
0
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')
Beispiel #17
0
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
Beispiel #19
0
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)
Beispiel #20
0
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()
Beispiel #21
0
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'),
    )
Beispiel #22
0
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')
Beispiel #23
0
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()
Beispiel #25
0
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)
Beispiel #28
0
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