示例#1
0
 def test_active_memberships(self):
     self.assertEqual(self.user.active_memberships(), [])
     m = self.add_membership(self.property_group)
     self.assertEqual(self.user.active_memberships(), [m])
     when = single(session.utcnow() - timedelta(hours=1))
     self.assertEqual(self.user.active_memberships(when), [])
     when = single(session.utcnow() + timedelta(hours=1))
     self.assertEqual(self.user.active_memberships(when), [m])
示例#2
0
 def test_active_memberships(self):
     self.assertEqual(self.user.active_memberships(), [])
     m = self.add_membership(self.property_group)
     self.assertEqual(self.user.active_memberships(), [m])
     when = single(session.utcnow() - timedelta(hours=1))
     self.assertEqual(self.user.active_memberships(when), [])
     when = single(session.utcnow() + timedelta(hours=1))
     self.assertEqual(self.user.active_memberships(when), [m])
示例#3
0
 def test_active_property_groups(self, session, utcnow, user,
                                 property_group, add_membership):
     assert user.active_property_groups() == []
     add_membership(property_group)
     assert user.active_property_groups() == [property_group]
     when = single(utcnow - timedelta(hours=1))
     assert user.active_property_groups(when) == []
     when = single(utcnow + timedelta(hours=1))
     assert user.active_property_groups(when) == [property_group]
示例#4
0
 def test_active_traffic_groups(self):
     self.assertEqual(self.user.active_traffic_groups(), [])
     self.add_membership(self.traffic_group)
     self.assertEqual(self.user.active_traffic_groups(),
                      [self.traffic_group])
     when = single(session.utcnow() - timedelta(hours=1))
     self.assertEqual(self.user.active_traffic_groups(when), [])
     when = single(session.utcnow() + timedelta(hours=1))
     self.assertEqual(self.user.active_traffic_groups(when),
                      [self.traffic_group])
示例#5
0
 def test_active_traffic_groups(self):
     self.assertEqual(self.user.active_traffic_groups(), [])
     self.add_membership(self.traffic_group)
     self.assertEqual(self.user.active_traffic_groups(),
                      [self.traffic_group])
     when = single(session.utcnow() - timedelta(hours=1))
     self.assertEqual(self.user.active_traffic_groups(when), [])
     when = single(session.utcnow() + timedelta(hours=1))
     self.assertEqual(self.user.active_traffic_groups(when),
                      [self.traffic_group])
示例#6
0
 def test_active_traffic_groups_expression(self):
     query = self.create_active_traffic_groups_query()
     self.assertEqual(query.all(), [])
     self.add_membership(self.traffic_group)
     query = self.create_active_traffic_groups_query()
     self.assertEqual(query.all(), [self.traffic_group])
     when = single(session.utcnow() - timedelta(hours=1))
     query = self.create_active_traffic_groups_query(when)
     self.assertEqual(query.all(), [])
     when = single(session.utcnow() + timedelta(hours=1))
     query = self.create_active_traffic_groups_query(when)
     self.assertEqual(query.all(), [self.traffic_group])
示例#7
0
 def test_active_property_groups_expression(self):
     query = self.create_active_property_groups_query()
     self.assertEqual(query.all(), [])
     self.add_membership(self.property_group)
     query = self.create_active_property_groups_query()
     self.assertEqual(query.all(), [self.property_group])
     when = single(session.utcnow() - timedelta(hours=1))
     query = self.create_active_property_groups_query(when)
     self.assertEqual(query.all(), [])
     when = single(session.utcnow() + timedelta(hours=1))
     query = self.create_active_property_groups_query(when)
     self.assertEqual(query.all(), [self.property_group])
示例#8
0
def estimate_balance(user, end_date):
    """
    :param user: The member
    :param end_date: Date of the end of the membership
    :return: Estimated balance at the end_date
    """

    now = session.utcnow().date()

    # Use tomorrow in case that it is the last of the month, the fee for the
    # current month will be added later
    tomorrow = now + timedelta(1)

    last_fee = MembershipFee.q.order_by(MembershipFee.ends_on.desc()).first()

    if last_fee is None:
        raise ValueError("no fee information available")

    # Bring end_date to previous month if the end_date is in grace period
    end_date_justified = end_date - timedelta(last_fee.booking_begin.days - 1)

    months_to_pay = diff_month(end_date_justified, tomorrow)

    # If the user has to pay a fee for the current month
    if user.has_property('membership_fee',
                         single(tomorrow.replace(day=last_fee.booking_end.days))):
        months_to_pay += 1

    # If there was no fee booked yet for the last month and the user has to pay
    # a fee for the last month, increment months_to_pay
    last_month_last = tomorrow.replace(day=1) - timedelta(1)
    last_month_fee_outstanding = (
        fee_from_valid_date(last_month_last, user.account) is None
    )

    if last_month_fee_outstanding:
        had_to_pay_last_month = user.has_property(
            'membership_fee',
            single(last_month_last.replace(day=last_fee.booking_end.days))
        )
        if had_to_pay_last_month:
            months_to_pay += 1

    # If there is already a fee booked for this month, decrement months_to_pay
    this_month_fee_outstanding = (
        fee_from_valid_date(last_day_of_month(tomorrow), user.account) is None
    )
    if not this_month_fee_outstanding:
        months_to_pay -= 1

    return (-user.account.balance) - (months_to_pay * last_fee.regular_fee)
示例#9
0
    def test_active_memberships(self, session, utcnow, user, property_group,
                                add_membership):
        assert user.active_memberships() == []
        assert user.current_memberships == []

        m = add_membership(property_group)
        session.refresh(user)

        assert user.active_memberships() == [m]
        assert user.current_memberships == [m]

        when = single(utcnow - timedelta(hours=1))
        assert user.active_memberships(when) == []
        when = single(utcnow + timedelta(hours=1))
        assert user.active_memberships(when) == [m]
示例#10
0
文件: user.py 项目: JuKu/pycroft
 def active_memberships(self, when=None):
     if when is None:
         now = session.utcnow()
         when = single(now)
     return [
         m for m in self.memberships
         if when.overlaps(closed(m.begins_at, m.ends_at))
     ]
示例#11
0
    def test_move_out_keeps_address(self):
        assert not self.user.has_custom_address
        old_address = self.user.address

        self.move_out(self.user)
        assert self.user.active_memberships(when=single(datetime.now(timezone.utc))) == []
        assert self.user.room is None
        assert self.user.address == old_address
示例#12
0
 def test_active_memberships_expression(
     self,
     session,
     utcnow,
     property_group,
     add_membership,
     create_active_memberships_query,
 ):
     query = create_active_memberships_query()
     assert query.all() == []
     m = add_membership(property_group)
     query = create_active_memberships_query()
     assert query.all() == [m]
     when = single(utcnow - timedelta(hours=1))
     query = create_active_memberships_query(when)
     assert query.all() == []
     when = single(utcnow + timedelta(hours=1))
     query = create_active_memberships_query(when)
     assert query.all() == [m]
示例#13
0
 def active_memberships(self,
                        when: Optional[Interval] = None
                        ) -> List[Membership]:
     if when is None:
         now = session.utcnow()
         when = single(now)
     return [
         m for m in self.memberships
         if when.overlaps(closed(m.begins_at, m.ends_at))
     ]
示例#14
0
文件: user.py 项目: agdsn/pycroft
 def active_property_groups(self, when: Interval | None = None) -> list[PropertyGroup]:
     sess = object_session(self)
     when = when or single(session.utcnow())
     return sess.query(
         PropertyGroup
     ).join(
         Membership
     ).filter(
         Membership.active_during & when,
         Membership.user_id == self.id
     ).all()
示例#15
0
    def test_move_out_keeps_address(self):
        self.assertFalse(self.user.has_custom_address)
        old_address = self.user.address

        self.move_out(self.user)
        self.assertEqual(
            self.user.active_memberships(when=single(datetime.now(timezone.utc))),
            []
        )
        self.assertIsNone(self.user.room)
        self.assertEqual(self.user.address, old_address)
示例#16
0
def status_query():
    now = single(session.utcnow())
    return session.session.query(
        User,
        User.member_of(config.member_group, now).label('member'),
        (Account.balance <= 0).label('account_balanced'),
        # a User.properties hybrid attribute would be preferrable
        (User.has_property('network_access', now)).label('network_access'),
        (User.has_property('violation', now)).label('violation'),
        (User.has_property('ldap', now)).label('ldap'),
        or_(*(User.has_property(prop, now) for prop in admin_properties)).label('admin')
    ).join(Account)
示例#17
0
文件: user.py 项目: agdsn/pycroft
    def active(self, when=None):
        """
        Tests if the membership overlaps with a given interval. If no interval
        is given, it tests if the membership is active right now.
        :param Interval when: interval in which the membership
        :rtype: bool
        """
        if when is None:
            now = object_session(self).query(func.current_timestamp()).scalar()
            when = single(now)

        return when.overlaps(closed(self.begins_at, self.ends_at))
示例#18
0
文件: user.py 项目: FriwiDev/pycroft
    def active(self, when=None):
        """
        Tests if the membership overlaps with a given interval. If no interval
        is given, it tests if the membership is active right now.
        :param Interval when: interval in which the membership
        :rtype: bool
        """
        if when is None:
            now = object_session(self).query(func.current_timestamp()).scalar()
            when = single(now)

        return when.overlaps(closed(self.begins_at, self.ends_at))
示例#19
0
文件: user.py 项目: agdsn/pycroft
 def has_property(self, property_name, when=None):
     """
     :param str property_name: name of a property
     :param Interval when:
     """
     if when is None:
         now = session.utcnow()
         when = single(now)
     prop_granted_flags = [
         group.property_grants[property_name]
         for group in self.active_property_groups(when)
         if property_name in group.property_grants
     ]
     return all(prop_granted_flags) and any(prop_granted_flags)
示例#20
0
文件: user.py 项目: JuKu/pycroft
 def has_property(self, property_name, when=None):
     """
     :param str property_name: name of a property
     :param Interval when:
     """
     if when is None:
         now = session.utcnow()
         when = single(now)
     prop_granted_flags = [
         group.property_grants[property_name]
         for group in self.active_property_groups(when)
         if property_name in group.property_grants
     ]
     return all(prop_granted_flags) and any(prop_granted_flags)
示例#21
0
 def test_empty(self):
     self.assertCallTrue(operator.attrgetter("empty"), [
         [empty(0)],
         [closedopen(0, 0)],
         [openclosed(0, 0)],
         [open(0, 0)],
     ])
     self.assertCallFalse(operator.attrgetter("empty"), [
         [single(0)],
         [closed(0, 0)],
         [closed(0, 1)],
         [closedopen(0, 1)],
         [openclosed(0, 1)],
         [open(0, 1)],
     ])
示例#22
0
    def has_property(self,
                     property_name: str,
                     when: Optional[Interval] = None) -> bool:
        if when is None:
            now = session.utcnow()
            when = single(now)

        prop_granted_flags = [
            group.property_grants[property_name]
            for group in self.active_property_groups(when)
            if property_name in group.property_grants
        ]

        # In case of prop_granted_flags = []: Return False
        # Else: Return True if all elements of prop_granted_flags are True
        return all(prop_granted_flags) and any(prop_granted_flags)
示例#23
0
文件: user.py 项目: agdsn/pycroft
    def active(cls, when=None):
        """
        Tests if memberships overlap with a given interval. If no interval is
        given, it tests if the memberships are active right now.
        :param Interval when:
        :return:
        """
        if when is None:
            now = session.utcnow()
            when = single(now)

        return and_(
            or_(cls.begins_at == null(), literal(when.end) == null(),
                cls.begins_at <= literal(when.end)),
            or_(literal(when.begin) == null(), cls.ends_at == null(),
                literal(when.begin) <= cls.ends_at)
        ).label("active")
示例#24
0
文件: user.py 项目: FriwiDev/pycroft
    def active(cls, when=None):
        """
        Tests if memberships overlap with a given interval. If no interval is
        given, it tests if the memberships are active right now.
        :param Interval when:
        :return:
        """
        if when is None:
            now = session.utcnow()
            when = single(now)

        return and_(
            or_(cls.begins_at == null(), literal(when.end) == null(),
                cls.begins_at <= literal(when.end)),
            or_(literal(when.begin) == null(), cls.ends_at == null(),
                literal(when.begin) <= cls.ends_at)
        ).label("active")
示例#25
0
文件: user.py 项目: agdsn/pycroft
    def has_property(self, property_name: str, when: datetime | None = None) -> bool:
        if when is None:
            return property_name in self.current_properties_set

        if isinstance(when, Interval):
            raise PycroftModelException("`has_property` does not accept intervals!")

        # usages in this branch: only wrt `membership_fee` in `estimate_balance` for finance stuff
        prop_granted_flags = [
            group.property_grants[property_name]
            for group in self.active_property_groups(single(when))
            if property_name in group.property_grants
        ]

        # In case of prop_granted_flags = []: Return False
        # Else: Return True if all elements of prop_granted_flags are True
        return all(prop_granted_flags) and any(prop_granted_flags)
示例#26
0
文件: user.py 项目: FriwiDev/pycroft
    def has_property(self, property_name, when=None):
        """
        :param str property_name: name of a property
        :param Interval when:
        """
        if when is None:
            now = session.utcnow()
            when = single(now)

        prop_granted_flags = [
            group.property_grants[property_name]
            for group in self.active_property_groups(when)
            if property_name in group.property_grants
        ]

        # In case of prop_granted_flags = []: Return False
        # Else: Return True if all elements of prop_granted_flags are True
        return all(prop_granted_flags) and any(prop_granted_flags)
示例#27
0
 def test_0030_transferred_value(self):
     amount = Decimal(90)
     today = session.utcnow().date()
     simple_transaction("transaction", self.fee_account, self.user_account,
                        amount, self.author, today - timedelta(1))
     simple_transaction("transaction", self.fee_account, self.user_account,
                        amount, self.author, today)
     simple_transaction("transaction", self.fee_account, self.user_account,
                        amount, self.author, today + timedelta(1))
     assert (transferred_amount(self.fee_account, self.user_account,
                                single(today)) == amount)
     assert (transferred_amount(self.fee_account, self.user_account,
                                closedopen(today, None)) == 2 * amount)
     assert (transferred_amount(self.fee_account, self.user_account,
                                openclosed(None, today)) == 2 * amount)
     assert (transferred_amount(self.fee_account,
                                self.user_account) == 3 * amount)
     Transaction.q.delete()
     session.session.commit()
示例#28
0
 def test_0030_transferred_value(self):
     amount = Decimal(90)
     today = session.utcnow().date()
     simple_transaction(
         u"transaction", self.fee_account, self.user_account,
         amount, self.author, today - timedelta(1)
     )
     simple_transaction(
         u"transaction", self.fee_account, self.user_account,
         amount, self.author, today
     )
     simple_transaction(
         u"transaction", self.fee_account, self.user_account,
         amount, self.author, today + timedelta(1)
     )
     self.assertEqual(
         transferred_amount(
             self.fee_account, self.user_account, single(today)
         ),
         amount
     )
     self.assertEqual(
         transferred_amount(
             self.fee_account, self.user_account, closedopen(today, None)
         ),
         2*amount
     )
     self.assertEqual(
         transferred_amount(
             self.fee_account, self.user_account, openclosed(None, today)
         ),
         2*amount
     )
     self.assertEqual(
         transferred_amount(
             self.fee_account, self.user_account
         ),
         3*amount
     )
     Transaction.q.delete()
     session.session.commit()
示例#29
0
文件: user.py 项目: agdsn/pycroft
 def active_memberships(self, when=None):
     if when is None:
         now = session.utcnow()
         when = single(now)
     return [m for m in self.memberships
             if when.overlaps(closed(m.begins_at, m.ends_at))]
示例#30
0
    (open(0, 1), 1),
    (closed(0, 1), 1),
    (closed(0, None), None),
    (closed(None, 0), None),
    (closed(None, None), None),
])
def test_length(interval: Interval, expected):
    assert interval.length == expected


@pytest.mark.parametrize('interval, should_be_empty', [
    (empty(0), True),
    (closedopen(0, 0), True),
    (openclosed(0, 0), True),
    (open(0, 0), True),
    (single(0), False),
    (closed(0, 0), False),
    (closed(0, 1), False),
    (closedopen(0, 1), False),
    (openclosed(0, 1), False),
    (open(0, 1), False),
])
def test_empty(interval, should_be_empty):
    assert interval.empty == should_be_empty


@pytest.mark.parametrize('one, other, expected', [
    (closed(0, 0), closed(0, 0), closed(0, 0)),
    (closed(0, 0), open(0, 0), None),
    (closed(1, 1), closed(0, 2), closed(1, 1)),
    (closed(0, 2), closed(1, 3), closed(1, 2)),
示例#31
0
    open(NOW, NOW + timedelta(days=1)),
])
def test_literal_select(session, interval):
    stmt = select(cast(literal(interval, TsTzRange), TsTzRange))
    assert session.scalar(stmt) == interval


@pytest.fixture
def table_with_interval(session):
    interval = closedopen(NOW, NOW + timedelta(days=1))
    with session.begin_nested():
        session.add(TableWithInterval(value=interval))


@pytest.mark.parametrize('value, expected', [
    (literal(NOW, DateTimeTz), True),
    (NOW, True),
    (func.current_timestamp(), True),
    (NOW + timedelta(hours=6), True),
    (single(NOW), True),
    (closedopen(NOW, NOW + timedelta(days=1)), True),
    (open(NOW, NOW + timedelta(days=1)), True),
    (NOW - timedelta(days=1), False),
    (NOW - timedelta(seconds=1), False),
    (literal(NOW - timedelta(seconds=1), DateTimeTz), False),
    (closed(NOW, NOW + timedelta(days=1)), False),
])
def test_containmment(session, table_with_interval, value, expected):
    stmt = select(TableWithInterval.value.contains(value))
    assert session.execute(stmt).scalar() is expected
示例#32
0
文件: user.py 项目: agdsn/pycroft
 def active_memberships(self, when: Interval | None = None) -> list[Membership]:
     if when is None:
         now = session.utcnow()
         when = single(now)
     return [m for m in self.memberships
             if when.overlaps(m.active_during.closure)]