@staticmethod
    def member_membership_paid(row):
        """
            Whether the member has paid within 12 months of start_date
            anniversary

            @ToDo: Formula should come from the deployment_template
        """

        T = current.T

        #try:
        #    exempted = row["member_membership.fee_exemption"]
        #except AttributeError:
        #    exempted = False
        #if excempted:
        #    return T("exempted")

        try:
            start_date = row["member_membership.start_date"]
        except __HOLE__:
            # not available
            start_date = None
        try:
            paid_date = row["member_membership.membership_paid"]
        except AttributeError:
            # not available
            paid_date = None

        if start_date:

            PAID = T("paid")
            OVERDUE = T("overdue")
            LAPSED = T("expired")
            lapsed = datetime.timedelta(days=183) # 6 months
            year = datetime.timedelta(days=365)
            now = current.request.utcnow.date()

            if not paid_date:
                # Never renewed since Membership started
                # => due within 1 year
                due = start_date + year
                if now < due:
                    return PAID
                elif now > (due + lapsed):
                    return LAPSED
                else:
                    return OVERDUE

            now_month = now.month
            start_month = start_date.month
            if now_month > start_month:
                due = datetime.date(now.year, start_month, start_date.day)
            elif now_month == start_month:
                now_day = now.day
                start_day = start_date.day
                if now_day >= start_day:
                    due = datetime.date(now.year, start_month, start_day)
                else:
                    due = datetime.date((now.year - 1), start_month, start_day)
            else:
                # now_month < start_month
                due = datetime.date((now.year - 1), start_month, start_date.day)

            if paid_date >= due:
                return PAID
            elif (due - paid_date) > lapsed:
                return LAPSED
            else:
                return OVERDUE

        return current.messages["NONE"]

    # ---------------------------------------------------------------------
dataset/ETHPy150Open sahana/eden/modules/s3db/member.py/S3MembersModel.member_membership_paid