Example #1
0
def roombooking_occurrences_digest():
    if not Config.getInstance().getIsRoomBookingActive():
        logger.info('Digest not sent because room booking is disabled')
        return
    if not rb_settings.get('notifications_enabled'):
        logger.info('Digest not sent because notifications are globally disabled')
        return

    digest_start = round_up_month(date.today(), from_day=2)
    digest_end = get_month_end(digest_start)

    occurrences = ReservationOccurrence.find(
        Room.notifications_enabled,
        Reservation.is_accepted,
        Reservation.repeat_frequency == RepeatFrequency.WEEK,
        ReservationOccurrence.is_valid,
        ReservationOccurrence.start_dt >= digest_start,
        ReservationOccurrence.start_dt <= digest_end,
        ~ReservationOccurrence.notification_sent,
        _build_digest_window_filter(),
        _join=[Reservation, Room]
    )

    digests = defaultdict(list)
    for occurrence in occurrences:
        digests[occurrence.reservation].append(occurrence)

    try:
        for reservation, occurrences in digests.iteritems():
            notify_reservation_digest(reservation, occurrences)
            for occurrence in occurrences:
                occurrence.notification_sent = True
    finally:
        db.session.commit()
Example #2
0
    def run(self):
        if not rb_settings.get('notifications_enabled'):
            self._v_logger.info(
                'Digest not sent because notifications are globally disabled')
            return

        digest_start = round_up_month(date.today(), from_day=2)
        digest_end = get_month_end(digest_start)

        occurrences = ReservationOccurrence.find(
            Room.notifications_enabled,
            Reservation.is_accepted,
            Reservation.repeat_frequency == RepeatFrequency.WEEK,
            ReservationOccurrence.is_valid,
            ReservationOccurrence.start_dt >= digest_start,
            ReservationOccurrence.start_dt <= digest_end,
            ~ReservationOccurrence.notification_sent,
            _build_digest_window_filter(),
            _join=[Reservation, Room])

        digests = defaultdict(list)
        for occurrence in occurrences:
            digests[occurrence.reservation].append(occurrence)

        try:
            for reservation, occurrences in digests.iteritems():
                notify_reservation_digest(reservation, occurrences)
                for occurrence in occurrences:
                    occurrence.notification_sent = True
        finally:
            db.session.commit()
Example #3
0
    def create_occurrences(self, skip_conflicts, user=None):
        ReservationOccurrence.create_series_for_reservation(self)
        db.session.flush()

        if user is None:
            user = self.created_by_user

        # Check for conflicts with nonbookable periods
        if not rb_is_admin(user) and not self.room.is_owned_by(user):
            nonbookable_periods = self.room.nonbookable_periods.filter(NonBookablePeriod.end_dt > self.start_dt)
            for occurrence in self.occurrences:
                if not occurrence.is_valid:
                    continue
                for nbd in nonbookable_periods:
                    if nbd.overlaps(occurrence.start_dt, occurrence.end_dt):
                        if not skip_conflicts:
                            raise ConflictingOccurrences()
                        occurrence.cancel(user, u"Skipped due to nonbookable date", silent=True, propagate=False)
                        break

        # Check for conflicts with blockings
        blocked_rooms = self.room.get_blocked_rooms(*(occurrence.start_dt for occurrence in self.occurrences))
        for br in blocked_rooms:
            blocking = br.blocking
            if blocking.can_be_overridden(user, self.room):
                continue
            for occurrence in self.occurrences:
                if occurrence.is_valid and blocking.is_active_at(occurrence.start_dt.date()):
                    # Cancel OUR occurrence
                    msg = u"Skipped due to collision with a blocking ({})"
                    occurrence.cancel(user, msg.format(blocking.reason), silent=True, propagate=False)

        # Check for conflicts with other occurrences
        conflicting_occurrences = self.get_conflicting_occurrences()
        for occurrence, conflicts in conflicting_occurrences.iteritems():
            if not occurrence.is_valid:
                continue
            if conflicts["confirmed"]:
                if not skip_conflicts:
                    raise ConflictingOccurrences()
                # Cancel OUR occurrence
                msg = u"Skipped due to collision with {} reservation(s)"
                occurrence.cancel(user, msg.format(len(conflicts["confirmed"])), silent=True, propagate=False)
            elif conflicts["pending"] and self.is_accepted:
                # Reject OTHER occurrences
                for conflict in conflicts["pending"]:
                    conflict.reject(user, u"Rejected due to collision with a confirmed reservation")

        # Mark occurrences created within the notification window as notified
        for occurrence in self.occurrences:
            if occurrence.is_valid and occurrence.is_in_notification_window():
                occurrence.notification_sent = True

        # Mark occurrences created within the digest window as notified
        if self.repeat_frequency == RepeatFrequency.WEEK:
            if self.room.is_in_digest_window():
                digest_start = round_up_month(date.today())
            else:
                digest_start = date.today()
            digest_end = get_month_end(digest_start)
            self.occurrences.filter(ReservationOccurrence.start_dt <= digest_end).update({"notification_sent": True})
Example #4
0
    def create_occurrences(self, skip_conflicts, user=None):
        ReservationOccurrence.create_series_for_reservation(self)
        db.session.flush()

        if user is None:
            user = self.created_by_user

        # Check for conflicts with nonbookable periods
        if not user.isRBAdmin() and not self.room.is_owned_by(user):
            nonbookable_periods = self.room.nonbookable_periods.filter(
                NonBookablePeriod.end_dt > self.start_dt)
            for occurrence in self.occurrences:
                if not occurrence.is_valid:
                    continue
                for nbd in nonbookable_periods:
                    if nbd.overlaps(occurrence.start_dt, occurrence.end_dt):
                        if not skip_conflicts:
                            raise ConflictingOccurrences()
                        occurrence.cancel(user,
                                          u'Skipped due to nonbookable date',
                                          silent=True,
                                          propagate=False)
                        break

        # Check for conflicts with blockings
        blocked_rooms = self.room.get_blocked_rooms(
            *(occurrence.start_dt for occurrence in self.occurrences))
        for br in blocked_rooms:
            blocking = br.blocking
            if blocking.can_be_overridden(user, self.room):
                continue
            for occurrence in self.occurrences:
                if occurrence.is_valid and blocking.is_active_at(
                        occurrence.start_dt.date()):
                    # Cancel OUR occurrence
                    msg = u'Skipped due to collision with a blocking ({})'
                    occurrence.cancel(user,
                                      msg.format(blocking.reason),
                                      silent=True,
                                      propagate=False)

        # Check for conflicts with other occurrences
        conflicting_occurrences = self.get_conflicting_occurrences()
        for occurrence, conflicts in conflicting_occurrences.iteritems():
            if not occurrence.is_valid:
                continue
            if conflicts['confirmed']:
                if not skip_conflicts:
                    raise ConflictingOccurrences()
                # Cancel OUR occurrence
                msg = u'Skipped due to collision with {} reservation(s)'
                occurrence.cancel(user,
                                  msg.format(len(conflicts['confirmed'])),
                                  silent=True,
                                  propagate=False)
            elif conflicts['pending'] and self.is_accepted:
                # Reject OTHER occurrences
                for conflict in conflicts['pending']:
                    conflict.reject(
                        user,
                        u'Rejected due to collision with a confirmed reservation'
                    )

        # Mark occurrences created within the notification window as notified
        for occurrence in self.occurrences:
            if occurrence.is_valid and occurrence.is_in_notification_window():
                occurrence.notification_sent = True

        # Mark occurrences created within the digest window as notified
        if self.repeat_frequency == RepeatFrequency.WEEK:
            if self.room.is_in_digest_window():
                digest_start = round_up_month(date.today())
            else:
                digest_start = date.today()
            digest_end = get_month_end(digest_start)
            self.occurrences.filter(
                ReservationOccurrence.start_dt <= digest_end).update(
                    {'notification_sent': True})