Ejemplo n.º 1
0
    def linkage(self, members):
        """Link coaches and swimmers."""
        if self.is_active is False:
            return

        super().linkage(members)

        if self.data[A_COACHES]:
            for coach in self.data[A_COACHES]:
                guid = members.by_guid[coach[A_GUID]]
                if guid.is_active:
                    self.coaches.append(guid)
                    guid.add_coach_session(self)
                else:
                    if self.ignore_attendance is False:
                        issue(self, E_INACTIVE, "(Coach)")
                if A_LAST_ATTENDED in coach:
                    lastseen = coach[A_LAST_ATTENDED]
                    if lastseen:
                        guid.set_lastseen(lastseen)
        else:
            if self.is_active:
                issue(self, E_NO_COACH)

        # super() has already done member links, now search for last seen...
        if A_MEMBERS in self.data:
            for swimmer in self.data[A_MEMBERS]:
                guid = members.by_guid[swimmer[A_GUID]]
                guid.add_session(self)
                if A_LAST_ATTENDED in swimmer:
                    lastseen = swimmer[A_LAST_ATTENDED]
                    if lastseen:
                        guid.set_lastseen(lastseen)
Ejemplo n.º 2
0
    def check_name(self):
        """Check capitilisation of name."""
        firstname = self.data[A_FIRSTNAME]
        lastname = self.data[A_LASTNAME]
        knownas = self.data[A_KNOWNAS]
        ka_upper = True

        if knownas:
            ka_upper = knownas[0].isupper()

        fn_upper = firstname[0].isupper()
        ln_upper = lastname[0].isupper()

        if fn_upper and ln_upper and ka_upper:
            return

        if (fn_upper is False) or (ln_upper is False):
            issue(self, E_NAME_CAPITAL, "fixable", -1)

            fix = {}
            if fn_upper is False:
                fix[A_FIRSTNAME] = firstname.title()
            if ln_upper is False:
                fix[A_LASTNAME] = lastname.title()
            if ka_upper is False:
                fix[A_KNOWNAS] = knownas.title()

            self.fixit(fix, "Capitalisation of name")
            return

        issue(self, E_NAME_CAPITAL, f"Knownas = {knownas}", -1, "fixable")
        fix = {}
        fix[A_KNOWNAS] = knownas.title()
        self.fixit(fix, f"Capitalisation of {knownas}")
Ejemplo n.º 3
0
    def check_type(self, xtype):
        """Check the member type check box config."""
        cfg = get_config(self.scm, C_TYPES, xtype, C_GROUPS)
        name = get_config(self.scm, C_TYPES, xtype, C_NAME)
        if name is None:
            name = xtype
        jobtitle = get_config(self.scm, C_TYPES, xtype, C_JOBTITLE)
        if cfg:
            found = False
            for group in cfg:
                if self.find_group(group):
                    found = True
                    break
            if found is False:
                if self.in_ignore_group is False:
                    if self.in_ignore_swimmer is False:
                        issue(self, E_TYPE_GROUP, name)

        if jobtitle:
            if self.jobtitle:
                return
            issue(self, E_NO_JOB, f"{name}", 0, "fixable")
            fix = {}
            fix["JobTitle"] = xtype.title()
            self.fixit(fix, f"Add jobtitle: {name}")
Ejemplo n.º 4
0
 def check_age(self, xmin, xmax, group):
     """Check swimmer within age group."""
     if self.age and (self.age < xmin):
         issue(self, E_TOO_YOUNG, f"{group}: {self.age}")
     if self.age and (self.age > xmax):
         if not self.is_coach:
             issue(self, E_TOO_OLD, f"{group}: {self.age}")
Ejemplo n.º 5
0
    def linkage(self, members):
        """Link members."""
        if (A_MEMBERS in self.data) and (len(self.data[A_MEMBERS]) > 0):
            for swimmer in self.data[A_MEMBERS]:
                if swimmer[A_GUID] not in members.by_guid:
                    msg = (
                        f"GUID {swimmer[A_GUID]} missing in list - email address only?"
                    )
                    debug(msg, 7)
                    continue
                guid = members.by_guid[swimmer[A_GUID]]
                if guid.is_active:
                    self.members.append(guid)
                else:
                    name = guid.name
                    issue(self, E_INACTIVE, f"member {name}", 0, "Fixable")

                    if self.newdata and (A_MEMBERS in self.newdata):
                        fix = self.newdata
                    else:
                        fix = {}
                        fix[A_MEMBERS] = self.data[A_MEMBERS].copy()
                    remove = {A_GUID: guid.guid}
                    fix[A_MEMBERS].remove(remove)
                    self.fixit(fix, f"Delete {guid.name} (inactive)")
Ejemplo n.º 6
0
def check_two_groups(swimmer):
    """Check if swimmer in two groups."""
    if get_config(swimmer.scm, C_GROUPS, C_GROUP) is None:
        return  # No config, so ignore error.

    g_count = 0
    errmsg = ""

    for group in swimmer.groups:

        nosession = get_config(swimmer.scm, C_GROUPS, C_GROUP, group.name,
                               C_NO_CLUB_SESSIONS)
        if nosession is True:
            continue

        unique = get_config(swimmer.scm, C_GROUPS, C_GROUP, group.name,
                            C_UNIQUE)
        if unique is None:
            unique = True

        if unique:
            g_count += 1
            if g_count > 1:
                errmsg += f", {group.name}"
            else:
                errmsg += group.name

    if g_count > 1:
        if swimmer.print_exception(EXCEPTION_TWOGROUPS):
            issue(swimmer, E_TWO_GROUPS, errmsg)
Ejemplo n.º 7
0
def check_login(swimmer):
    """Check if the login is OK."""
    if swimmer.username:
        min_age = get_config(swimmer.scm, C_SWIMMERS, C_USERNAME, C_MIN_AGE)
        if min_age:
            if swimmer.age and (swimmer.age < min_age):
                issue(swimmer, E_LOGIN_TOO_YOUNG, f"Age: {swimmer.age}")
Ejemplo n.º 8
0
    def check_category(self):
        """Check the member categoty."""
        cat = self.data[A_ASA_CATEGORY]
        if cat == "":
            return

        if cat not in CAT_VALID:
            issue(self, E_CATEGORY, cat)
Ejemplo n.º 9
0
    def linkage_parent(self, members):
        """Link parents."""
        for parent in self.data[A_PARENTS]:
            guid = members.by_guid[parent[A_GUID]]

            if guid == self.guid:
                issue(self, E_OWNPARENT)

            self._parents.append(guid)
Ejemplo n.º 10
0
 def check_email(self):
     """Check email."""
     email = self.email
     if email is None:
         if self.print_exception(EXCEPTION_NOEMAIL) is False:
             return
         issue(self, E_NO_EMAIL, f"{self.first_group}")
     else:
         space = re.search(" ", email)
         if space:
             issue(self, E_EMAIL_SPACE, f"{email}")
Ejemplo n.º 11
0
def analyse_coach(coach):
    """Analyse a coach..."""
    if coach.coach_role is False:
        if get_config(coach.scm, C_COACHES, C_ROLE, C_MANDATORY):
            issue(coach, E_NO_ROLE_COACH)

    if len(coach.coach_sessions) == 0:
        if coach.print_exception(EXCEPTION_NOSESSIONS):
            issue(coach, E_NO_SESSIONS)

    coach.check_dbs("Coach")
Ejemplo n.º 12
0
def check_conduct(member, my_codes):
    """Analyse a code of conduct."""
    # pylint: disable=too-many-branches

    if get_config(member.scm, C_CONDUCT) is None:
        return

    type_dict = {
        CTYPE_SWIMMER: member.is_swimmer,
        CTYPE_PARENT: member.is_parent,
        CTYPE_COACH: member.is_coach,
        CTYPE_COMMITTEE: member.is_committee_member,
        CTYPE_VOLUNTEER: member.is_volunteer,
        CTYPE_POLO: member.is_polo,
        CTYPE_SYNCHRO: member.is_synchro,
    }

    codes = member.scm.conduct.entities

    for code in codes:
        ignores = get_config(member.scm, C_CONDUCT, code.name, C_IGNORE_GROUP)

        found_ignore = False
        if ignores:
            for ignore in ignores:
                if member.find_group(ignore):
                    found_ignore = True
        if found_ignore:
            continue

        types = get_config(member.scm, C_CONDUCT, code.name, C_TYPES)
        if types is None:
            return

        for atype in types:
            found = False
            func = type_dict[atype]
            if func is True:
                for my_code in my_codes:
                    if my_code == code:
                        found = True
                        break
                if found is False:
                    issue(member, E_NO_CONDUCT, f"{code.name}")

                    if code.newdata and (A_MEMBERS in code.newdata):
                        fix = code.newdata
                    else:
                        fix = {}

                    fix[A_MEMBERS] = code.data[A_MEMBERS].copy()
                    add = {A_GUID: member.guid}
                    fix[A_MEMBERS].append(add)
                    code.fixit(fix, f"Add {member.name}")
Ejemplo n.º 13
0
    def check_role_permissions(self, member):
        """Check out a role permissions."""
        lookup = get_config(self.scm, C_ROLES, C_ROLE, self.name)
        if lookup is None:
            return

        if (C_CHECK_PERMISSIONS in lookup) and lookup[C_CHECK_PERMISSIONS]:
            check_coach_permissions(member, self)

        if (C_CHECK_RESTRICTIONS in lookup) and lookup[C_CHECK_RESTRICTIONS]:
            if len(member.restricted) == 0:
                issue(member, E_NO_RESTRICTIONS, f"Role: {self.name}")
Ejemplo n.º 14
0
    def analyse(self):
        """Analyse the role."""
        cfg = get_config(self.scm, C_ROLES, C_ROLE)
        unused = get_config(self.scm, C_ROLES, C_LOGIN, C_UNUSED)

        if len(self.members) == 0:
            issue(self, E_NO_SWIMMERS, "Role")
            return

        for member in self.members:
            self.check_role_member(member, unused)

            if cfg and (self.name in cfg):
                self.check_role_permissions(member)
Ejemplo n.º 15
0
def check_max_sessions(swimmer):
    """Check not exceeding max numbr of sessions allowed"""
    max_session = get_config(swimmer.scm, C_GROUPS, C_GROUP,
                             swimmer.first_group, C_MAX_SESSIONS)
    if max_session:
        num_sessions = len(swimmer.sessions)
        if num_sessions > max_session:
            for session in swimmer.sessions:
                if session.exclude_max:
                    num_sessions = num_sessions - 1
            if num_sessions > max_session:
                sessions = swimmer.print_swimmer_sessions(False)
                issue(swimmer, E_MAX_SESSIONS,
                      f"{len(swimmer.sessions)}: \n{sessions}")
Ejemplo n.º 16
0
def check_asa(swimmer):
    """Check ASA (Swim England) number is OK."""
    if swimmer.asa_number is None:
        cfg_synchro = get_config(swimmer.scm, C_TYPES, CTYPE_SYNCHRO,
                                 C_CHECK_SE_NUMBER)
        cfg_polo = get_config(swimmer.scm, C_TYPES, CTYPE_POLO,
                              C_CHECK_SE_NUMBER)

        err = True
        if swimmer.is_polo and (cfg_polo is False):
            err = False
        if swimmer.is_synchro and (cfg_synchro is False):
            err = False
        if err:
            issue(swimmer, E_ASA)
Ejemplo n.º 17
0
def analyse_parent(parent):
    """Analyse a parent..."""
    # pylint: disable=too-many-branches
    active = False
    inactive = None

    for swimmer in parent.swimmers:
        if swimmer.is_active:
            active = True
        else:
            inactive = swimmer.name

    if active is False:
        if inactive is None:
            issue(parent, E_NO_CHILD, "fixable")
            fix = {}
            fix[A_ISPARENT] = "0"
            parent.fixit(fix, "Remove 'is parent'")
        else:
            issue(parent, E_INACTIVE, f"child {inactive}")

    newmember = True
    for swimmer in parent.swimmers:
        if swimmer.newstarter is False:
            newmember = False
            break

    if (newmember is True) and parent.swimmers:
        parent.set_joined_today()

    age = get_config(parent.scm, C_PARENTS, C_AGE, C_MIN_AGE)
    if parent.age and (parent.age < age):
        issue(parent, E_PARENT_AGE)

    age = get_config(parent.scm, C_PARENTS, C_AGE, C_CHILD)
    for swimmer in parent.swimmers:
        if active and swimmer.age and (swimmer.age >= age):
            issue(swimmer, E_PARENT_AGE_TOO_OLD,
                  f"{swimmer.age}, {parent.name}")

    login = get_config(parent.scm, C_PARENTS, C_LOGIN, C_MANDATORY)
    if login and (parent.username is None) and parent.email:
        issue(parent, E_NO_LOGIN, "Parent (fixable)")
        fix = {}
        fix[A_USERNAME] = parent.email
        parent.fixit(fix, f"Create login, username: {parent.email}")
Ejemplo n.º 18
0
def check_coach_permissions(coach, role):
    """Check a coaches permissions."""
    # pylint: disable=too-many-branches

    debug(f"Permission check: {coach.name}, {role.name}", 7)
    if coach.is_coach is False:
        issue(coach, E_NOT_A_COACH, f"Role: {role.name} (fixable)")
        fix = {}
        fix[A_ISCOACH] = "1"
        coach.fixit(fix, "Add 'Is a coach'")

    coach.set_in_coach_role()

    if coach.is_swimmer is False:
        if len(coach.sessions) > 0:
            issue(coach, E_COACH_WITH_SESSIONS, f"Role: {role.name}")

    if coach.print_exception(EXCEPTION_PERMISSIONS) is False:
        return

    fix = {}
    fixed = False
    data = coach.data["SessionRestrictions"]
    if data:
        fix["SessionRestrictions"] = data.copy()
    else:
        fix["SessionRestrictions"] = []
    msg = "Fix permissions:\n"

    for session in coach.coach_sessions:
        match = False
        for permission in coach.restricted:
            if session == permission:
                match = True
                break
        if match is False:
            issue(coach, E_PERMISSION_MISSING, session.full_name)
            fix["SessionRestrictions"].append({A_GUID: session.guid})
            msg += f"  Add {session.name}\n"
            fixed = True

    for permission in coach.restricted:
        match = False
        for session in coach.coach_sessions:
            if session == permission:
                match = True
                break
        if match is False:
            issue(coach, E_PERMISSION_EXTRA, permission.full_name)
            fix["SessionRestrictions"].remove({A_GUID: permission.guid})
            fixed = True
            msg += f"  Remove {session.name}\n"

    if fixed:
        coach.fixit(fix, msg)
Ejemplo n.º 19
0
def check_parents(swimmer):
    """Check consistence between swimmer and parent email."""
    # pylint: disable=too-many-branches
    email = None
    match = False
    count = 0
    confirm_error = False

    confirm_verify = get_config(swimmer.scm, C_SWIMMERS, C_CONF_DIFF, C_VERIFY)
    max_age = get_config(swimmer.scm, C_SWIMMERS, C_PARENT, C_MAX_AGE)

    if swimmer.email:
        email = swimmer.email.split(";")

    for parent in swimmer.parents:
        count += 1
        if parent.is_active is False:
            issue(parent, E_INACTIVE, f"Swimmer {swimmer.name}")

        if match is False:
            match = check_parent_email_match(email, parent)

        if confirm_verify:
            confirm_error = check_confirmed_diff(swimmer, parent)
            if confirm_error:
                issue(swimmer, E_CONFIRM_DIFF, f"Parent {parent.name}")
    if (swimmer.parents and swimmer.age and (match is False)
            and (swimmer.age <= max_age)):
        if swimmer.print_exception(EXCEPTION_EMAILDIFF):
            err = f"{swimmer.email} - {swimmer.parents[0].email}"
            issue(swimmer, E_EMAIL_MATCH, err)

    if count == 0:
        mandatory = get_config(swimmer.scm, C_SWIMMERS, C_PARENT, C_MANDATORY)
        if mandatory and max_age:
            if swimmer.age and (swimmer.age <= max_age):
                msg = f"{swimmer.first_group}, Age: {swimmer.age}"
                issue(swimmer, E_NO_PARENT, msg)

    if count > 2:
        issue(swimmer, E_NUM_PARENTS)
Ejemplo n.º 20
0
    def get_notes(self):
        """Extract Facebook name from Notes."""
        notes = self.notes
        if notes is None:
            return

        note = FACEBOOK_RE.findall(notes)
        if note:
            for facebook in note:
                facebook = facebook.strip()
                self.facebook.append(facebook)
                debug(f"Found Facebook name in notes '{facebook}'", 8)

        note = API_RE.findall(notes)
        if note is None:
            return
        for api in note:
            exclusion = API_TEXT_RE.search(api)
            expiry = DATE_RE.search(api)
            when = self.scm.today
            gotdate = False
            if expiry:
                date = expiry.group(0)
                when = get_date(date, "%d-%m-%Y")
                gotdate = True
            else:
                expiry = DATE2_RE.search(api)
                if expiry:
                    date = expiry.group(0)
                    when = get_date(date, "%d/%m/%Y")
                    gotdate = True
            if when:
                excl = exclusion.group(0).strip()
                if (self.scm.today - when).days <= 0:
                    self.ignore_errors.append(excl)
                    debug(f"Found API token in notes {api}", 8)
                else:
                    debug(f"Token expired {api}", 8)
            elif gotdate:
                issue(self, E_DATE, f"Notes: {api}")
Ejemplo n.º 21
0
    def analyse(self):
        """Analyse the conduct entry."""
        # A better way of doing this would be to add
        # the attribute to the swimmer in linkage.
        # This approach breaks the model. Oh well.

        ignores = get_config(self.scm, C_CONDUCT, self.name, C_IGNORE_GROUP)
        c_date_str = get_config(self.scm, C_CONDUCT, self.name, C_DATE)

        if c_date_str is None:
            c_date_str = "1900-01-01"
        c_date = datetime.datetime.strptime(c_date_str, SCM_DATE_FORMAT)

        for member in self.data[A_MEMBERS]:

            if member[A_DATEAGREED]:
                m_date = datetime.datetime.strptime(member[A_DATEAGREED],
                                                    SCM_DATE_FORMAT)
                if m_date >= c_date:
                    continue

            person = self.scm.members.by_guid[member[A_GUID]]
            if person.confirmed_date:  # Will get a not confirmed error later in not set

                found_ignore = False
                if ignores:
                    for ignore in ignores:
                        if person.find_group(ignore):
                            found_ignore = True
                if found_ignore:
                    continue

                issue(person, E_NO_CONDUCT_DATE, self.name, 0,
                      person.first_group)
                codes = get_config(self.scm, C_LISTS, C_CONDUCT)
                if codes:
                    for code in codes:
                        if self.name == code:
                            msg = f"{self.name} missing"
                            self.scm.lists.add(msg, person)
Ejemplo n.º 22
0
    def check_confirmation(self):
        """Check confimation status."""
        expiry = get_config(self.scm, C_MEMBERS, C_CONFIRMATION, C_EXPIRY)
        align = get_config(self.scm, C_MEMBERS, C_CONFIRMATION, C_ALIGN_QUARTER)
        xlist = get_config(self.scm, C_LISTS, C_CONFIRMATION)
        q_offset = 0

        if align:
            q_offset = self.scm.q_offset

        if self.confirmed_date:
            gap = (self.scm.today - self.confirmed_date).days
            if gap > (expiry + q_offset):
                issue(self, E_CONFIRMATION_EXPIRED, f"{self.first_group}")
                self.scm.members.count_not_confirmed += 1
                if xlist:
                    self._list_add(E_CONFIRMATION_EXPIRED)
        else:
            issue(self, E_NOT_CONFIRMED, f"{self.first_group}")
            self.scm.members.count_not_confirmed += 1
            if xlist:
                self._list_add(E_NOT_CONFIRMED)
Ejemplo n.º 23
0
 def check_duplicate(self, member):
     """See if member already exists before adding."""
     firtname = member[A_FIRSTNAME]
     lastname = member[A_LASTNAME]
     name = f"{firtname} {lastname}"
     if name in self.by_name:
         if member[A_ACTIVE] == "1" and self.by_name[name].is_active:
             act1 = member[A_ACTIVE]
             act2 = self.by_name[name].is_active
             debug(f"{name}: {act1}-{act2}", 6)
             issue(self.by_name[name], E_DUPLICATE, name)
         else:
             active = self.by_name[name].is_active
             if member[A_ACTIVE] == "0" and active is False:
                 issue(self.by_name[name], E_DUPLICATE, "BOTH inactive", 9)
             else:
                 issue(self.by_name[name], E_DUPLICATE, "One is inactive", -1)
         return
     if name in self.knownas:
         if member[A_ACTIVE] == "1" and self.knownas[name].is_active:
             issue(self.knownas[name], E_DUPLICATE, name, 0, "(Known as)")
         else:
             issue(self.knownas[name], E_DUPLICATE, "One is inactive (Known as)", -1)
Ejemplo n.º 24
0
def check_lastseen(swimmer):
    """Check when swimemr was last seen."""
    if swimmer.lastseen is None:
        if len(swimmer.sessions) > 0:
            # if no session, don't have data about when they have been seen
            check = True
            for session in swimmer.sessions:
                if get_config(
                        swimmer.scm,
                        C_SESSIONS,
                        C_SESSION,
                        session.name,
                        C_IGNORE_ATTENDANCE,
                ):
                    check = False
                    continue
            if check:
                issue(swimmer, E_NEVERSEEN)
    else:
        gap = (swimmer.scm.today - swimmer.lastseen).days
        absence = get_config(swimmer.scm, C_SWIMMERS, C_ABSENCE, C_TIME)
        if gap > absence:
            when = swimmer.lastseen.strftime(PRINT_DATE_FORMAT)
            issue(swimmer, E_ABSENT, f"Last seen: {when}")
Ejemplo n.º 25
0
def analyse_swimmer(swimmer):
    """Analyse a swimmer..."""
    # pylint: disable=too-many-branches
    if swimmer.in_ignore_group:
        return

    if swimmer.in_ignore_swimmer:
        return

    if len(swimmer.groups) == 0:
        if swimmer.print_exception(EXCEPTION_NOGROUPS):
            issue(swimmer, E_NO_GROUP)

    if swimmer.dob is None:
        issue(swimmer, E_DOB)

    if swimmer.gender is None:
        issue(swimmer, E_GENDER)

    if swimmer.date_joined is None:
        issue(swimmer, E_DATE_JOINED)

    check_asa(swimmer)
    check_lastseen(swimmer)
    check_two_groups(swimmer)
    check_login(swimmer)

    if swimmer.is_swimmer:
        check_parents(swimmer)
        check_max_sessions(swimmer)
        return

    if swimmer.is_synchro:
        if get_config(swimmer.scm, C_TYPES, CTYPE_SYNCHRO, C_PARENTS) is False:
            pass
        else:
            check_parents(swimmer)
            return

    if swimmer.is_polo:
        if get_config(swimmer.scm, C_TYPES, CTYPE_POLO, C_PARENTS) is False:
            pass
        else:
            check_parents(swimmer)
Ejemplo n.º 26
0
    def analyse(self):
        """Analyse existing lists."""
        if len(self.members) == 0:
            issue(self, E_NO_SWIMMERS, "List")
            return

        for member in self.members:
            if member.is_active is False:
                # Never get here as entity linkage prevents it.
                msg = f"Inactive but on email list {self.name} (fixable)"
                issue(member, E_LIST_ERROR, msg)
                if self.newdata and (A_MEMBERS in self.newdata):
                    fix = self.newdata
                else:
                    fix = {}
                    fix[A_MEMBERS] = self.data[A_MEMBERS].copy()
                fix[A_MEMBERS].remove({A_GUID: member.guid})
                self.fixit(fix, f"Delete {member.name}")

            if member.email is None:
                issue(member, E_LIST_ERROR, f"No email, but on email list {self.name}")
Ejemplo n.º 27
0
    def check_inactive(self):
        """Check an inactive member."""
        lastmod = self.last_modified_date
        if lastmod:
            gap = (self.scm.today - lastmod).days
            inactive = get_config(self.scm, C_MEMBERS, C_INACTIVE, C_TIME)
            if inactive and (gap > inactive):
                when = lastmod.strftime(PRINT_DATE_FORMAT)
                issue(self, E_INACTIVE_TOOLONG, f"Last Modified: {when}")

        if self.check_attribute(A_DATELEFT):
            return

        if lastmod:
            issue(self, E_NO_LEAVE_DATE, "fixable", -1)
            fix = {}
            fix[A_DATELEFT] = lastmod.strftime(SCM_DATE_FORMAT)
            self.fixit(fix, f"Add dataleft = {fix[A_DATELEFT]}")
            return

        issue(self, E_NO_LEAVE_DATE, "", -1)
Ejemplo n.º 28
0
    def populate(self):
        """Search for entries and fill the list."""
        # pylint: disable=too-many-branches, too-many-statements
        cfg = get_config(self.scm, C_LISTS, C_LIST, self.name)

        # set defaults
        min_age = 0
        if C_MIN_AGE in cfg:
            min_age = cfg[C_MIN_AGE]

        max_age = 999
        if C_MAX_AGE in cfg:
            max_age = cfg[C_MAX_AGE]

        min_age_eoy = 0
        if C_MIN_AGE_EOY in cfg:
            min_age_eoy = cfg[C_MIN_AGE_EOY]

        max_age_eoy = 999
        if C_MAX_AGE_EOY in cfg:
            max_age_eoy = cfg[C_MAX_AGE_EOY]

        min_year = 1900
        if C_MIN_YEAR in cfg:
            min_year = cfg[C_MIN_YEAR]

        max_year = 2200
        if C_MAX_YEAR in cfg:
            max_year = cfg[C_MAX_YEAR]

        for member in self.scm.members.entities:

            if member.is_active is False:
                continue

            if member.in_ignore_group:
                continue

            if member.age and (member.age < min_age):
                continue

            if member.age and (member.age > max_age):
                continue

            if member.age_eoy and (member.age_eoy < min_age_eoy):
                continue

            if member.age_eoy and (member.age_eoy > max_age_eoy):
                continue

            if member.dob and (member.dob.year > max_year):
                continue

            if member.dob and (member.dob.year < min_year):
                continue

            if C_GROUP in cfg:
                if member.find_group(cfg[C_GROUP]) is False:
                    continue
                if C_UNIQUE in cfg:
                    if len(member.groups) > 1:
                        if C_ALLOW_GROUP not in cfg:
                            continue
                        if member.find_group(cfg[C_ALLOW_GROUP]) is False:
                            continue

            if C_GENDER in cfg:
                gender = cfg[C_GENDER]
                xgender = "F"
                if gender == "male":
                    xgender = "M"
                if member.gender != xgender:
                    continue

            if C_TYPE in cfg:
                xtype = cfg[C_TYPE]
                if check_type(member, xtype) is False:
                    continue

            if member.email is None:
                if member.print_exception(EXCEPTION_NOEMAIL):
                    msg = f"No email, but required for email list {self.name}"
                    issue(member, E_LIST_ERROR, msg)
                continue

            self.add_member(member)
Ejemplo n.º 29
0
    def analyse(self):
        """Analyse the group."""
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements
        # pylint: disable=too-many-locals
        no_session = False
        check_dbs = False
        wanted_session = None
        allowed = None
        xtype = None
        ignore = None
        confirm = None

        if self.config:
            ignore = self.config_item(C_IGNORE_GROUP)
            no_session = self.config_item(C_NO_SESSIONS)
            check_dbs = self.config_item(C_CHECK_DBS)
            wanted_sessions = self.config_item(C_SESSIONS)
            allowed = self.config_item(C_NO_SESSION_ALLOWED)
            xtype = self.config_item(C_TYPE)
            confirm = self.config_item(C_CONFIRMATION)

        if ignore:
            debug(f"Ignoring group {self.name}", 7)
            return

        if len(self.members) == 0:
            issue(self, E_NO_SWIMMERS, "Group")
            return

        if no_session:
            for member in self.members:
                if len(member.sessions) > 0:
                    name = member.sessions[0].name
                    issue(member, E_SESSIONS,
                          f"Group: {self.name}, Session: {name}")

        if confirm:
            try:
                date = datetime.datetime.strptime(confirm, SCM_CSV_DATE_FORMAT)
                confirm = date
            except ValueError:
                notify(
                    f"*** Error in date format in config file for groups config: {confirm} ***\n"
                )
                confirm = None

        for member in self.members:
            self.check_age(member)
            if check_dbs:
                member.check_dbs(self.name)

            if confirm:
                err = False
                if member.confirmed_date:
                    gap = (confirm - member.confirmed_date).days
                    if gap >= 0:
                        err = True
                else:
                    err = True

                if err:
                    issue(member, E_CONFIRMATION_EXPIRED,
                          f"Group: {self.name}")
                    msg = f"Confirmation Expired for Group: {member.name}"
                    member.scm.lists.add(msg, member)

            if member.newstarter:
                continue

            if wanted_session:
                for session in wanted_sessions:
                    if check_in_session(member, session, allowed) is False:
                        res1 = self.print_exception(
                            EXCEPTION_NONSWIMMINGMASTER)
                        res2 = self.print_exception(EXCEPTION_GROUPNOSESSION)
                        if res1 or res2:
                            issue(member, E_NOT_IN_SESSION,
                                  f"Group: {self.name}")
                    break

            if xtype:
                if check_type(member, xtype):
                    continue
                if xtype == CTYPE_SWIMMER:  # if swimmers wanted, allow it to be a coach
                    if check_type(member, CTYPE_COACH) is True:
                        continue
                msg = f"Group: {self.name}, Type required: {xtype} (fixable)"
                issue(member, E_TYPE, msg)
                fix = {}
                attr = None

                if xtype == CTYPE_MASTER:
                    attr = "Masters"

                if xtype == CTYPE_SWIMMER:
                    attr = "IsASwimmer"

                if xtype == CTYPE_SYNCHRO:
                    attr = "SynchronisedSwimming"

                if xtype == CTYPE_COACH:
                    attr = "IsACoach"

                if xtype == CTYPE_POLO:
                    attr = "WaterPolo"

                if attr:
                    fix[attr] = "1"
                    member.fixit(fix, f"Add type: {attr}")
Ejemplo n.º 30
0
    def analyse(self):
        """Analyse the member."""
        # pylint: disable=too-many-branches
        # pylint: disable=too-many-statements

        if self.is_active is False:
            self.check_inactive()
            return

        self.check_name()

        found = False

        if self.is_coach:
            self.check_type(CTYPE_COACH)
            analyse_coach(self)
            found = True

        if self.newstarter:
            return

        if self.is_swimmer:
            self.check_type(CTYPE_SWIMMER)
            found = True

        if self.is_master:
            self.check_type(CTYPE_MASTER)
            found = True

        if self.is_synchro:
            self.check_type(CTYPE_SYNCHRO)
            found = True

        if self.is_polo:
            self.check_type(CTYPE_POLO)
            found = True

        if self.is_swimmer or self.is_polo or self.is_synchro or self.is_openwater:
            analyse_swimmer(self)

        if self.is_parent:
            self.check_type(CTYPE_PARENT)
            analyse_parent(self)
            found = True

        if self.is_volunteer:
            vol = get_config(self.scm, C_TYPES, CTYPE_VOLUNTEER, C_IGNORE_COACH)
            ctte = get_config(self.scm, C_TYPES, CTYPE_VOLUNTEER, C_IGNORE_COMMITTEE)

            if vol or ctte or self.is_coach:
                pass
            else:
                self.check_type(CTYPE_VOLUNTEER)
            found = True

        if self.is_committee_member:
            found = True
            self.check_type(CTYPE_COMMITTEE)

        if A_ASA_CATEGORY in self.data:
            self.check_category()

        if self.jobtitle:
            if (
                (self.is_volunteer is not True)
                and (self.is_committee_member is not True)
                and (self.is_coach is not True)
            ):
                cfg = get_config(self.scm, C_JOBTITLE, C_IGNORE)
                if self.jobtitle not in cfg:
                    issue(self, E_JOB, self.jobtitle)

        if found:
            if self.in_ignore_swimmer:
                return
            self.check_email()
            self.check_confirmation()  # Must come after analyse_swimmer
            check_conduct(self, self._conduct)
            return

        for group in self.groups:
            if get_config(self.scm, C_GROUPS, C_GROUP, group.name, C_IGNORE_UNKNOWN):
                continue
            issue(self, E_UNKNOWN)