Ejemplo n.º 1
0
    def create_items(self, rental, data):
        errors = {}

        item_quantities = extract_item_quantities(data)

        if not item_quantities:
            raise ValidationError({
                'item_quantities':
                'The rental cannot be submitted without any items.'
            })

        item_list = Item.objects.filter(id__in=item_quantities.keys())

        availability = Availability(rental.start_date, rental.return_date,
                                    rental.depot_id)

        for item in item_list:
            intervals = availability.get_availability_intervals(item)

            try:
                available = min(intervals).value
                self.create_item_rental(rental, item, item_quantities[item.id],
                                        available)
            except ValidationError as e:
                for key, value in e:
                    errors['%s %s' % (item.name, key)] = value

        if errors:
            raise ValidationError(errors)
Ejemplo n.º 2
0
    def test_exactly_matching_rental_time_frame(self):
        self.create_conflicting_rental(self.start, self.end, 3)

        availability = Availability(self.start, self.end, self.depot.id)

        with self.assertNumQueries(2):
            intervals = availability.get_availability_intervals(self.item)
            expected = [Interval(self.start, self.end, 7)]
            self.assertEqual(intervals, expected)
Ejemplo n.º 3
0
    def test_not_relevant_state(self):
        start = self.start + timedelta(days=1)
        end = self.end + timedelta(days=-1)
        self.create_conflicting_rental(start, end, 3, Rental.STATE_PENDING)

        availability = Availability(self.start, self.end, self.depot.id)

        with self.assertNumQueries(1):
            intervals = availability.get_availability_intervals(self.item)
            expected = [Interval(self.start, self.end, 10)]
            self.assertEqual(intervals, expected)
Ejemplo n.º 4
0
    def test_no_overlap(self):
        start = self.end + timedelta(days=1)
        end = self.end + timedelta(days=2)
        self.create_conflicting_rental(start, end, 3)

        availability = Availability(self.start, self.end, self.depot.id)

        with self.assertNumQueries(1):
            intervals = availability.get_availability_intervals(self.item)
            expected = [Interval(self.start, self.end, 10)]
            self.assertEqual(intervals, expected)
Ejemplo n.º 5
0
    def test_completely_enclosing(self):
        start = self.start + timedelta(days=-1)
        end = self.end + timedelta(days=1)
        self.create_conflicting_rental(start, end, 3)

        availability = Availability(self.start, self.end, self.depot.id)

        with self.assertNumQueries(2):
            intervals = availability.get_availability_intervals(self.item)
            expected = [Interval(self.start, self.end, 7)]
            self.assertEqual(intervals, expected)
Ejemplo n.º 6
0
    def check_availability(self, rental):
        availability = Availability(rental.start_date, rental.return_date,
                                    rental.depot_id)

        for item_rental in rental.itemrental_set.all():
            intervals = availability.get_availability_intervals(
                item_rental.item)
            available = min(intervals).value

            if item_rental.quantity > available:
                raise ValidationError({
                    'quantity':
                    'The quantity must not exceed the availability '
                    'of the item in the requested time frame.'
                })
Ejemplo n.º 7
0
    def test_left_and_right_triple_overlap(self):
        left_start = self.start + timedelta(days=-1)
        left_end = self.end + timedelta(days=-1)
        self.create_conflicting_rental(left_start, left_end, 3)

        right_start = self.start + timedelta(days=1)
        right_end = self.end + timedelta(days=1)
        self.create_conflicting_rental(right_start, right_end, 3)

        availability = Availability(self.start, self.end, self.depot.id)

        with self.assertNumQueries(2):
            intervals = availability.get_availability_intervals(self.item)
            expected = [
                Interval(self.start, right_start, 7),
                Interval(right_start, left_end, 4),
                Interval(left_end, self.end, 7)
            ]
            self.assertEqual(intervals, expected)
    def get(self, request, depot_id):
        depot = get_depot_if_allowed(depot_id, request.user)

        # configure time frame
        start_date, return_date = self.get_start_return_date(request.GET)

        item_list = depot.visible_items(request.user)

        availability = Availability(
            datetime.combine(start_date.date() - timedelta(days=1),
                             datetime.min.time()),
            datetime.combine(return_date.date() + timedelta(days=1),
                             datetime.min.time()), depot_id)

        availability_data = []

        for item in item_list:
            intervals = availability.get_availability_intervals(item)

            availability_data.append(
                (item, self.get_chart_data(intervals), min(intervals).value))

        errors = request.session.pop('errors', None)
        data = request.session.pop('data', {})

        return render(
            request, 'depot/create-rental.html', {
                'depot': depot,
                'show_visibility': depot.show_internal_items(request.user),
                'availability_data': availability_data,
                'errors': errors,
                'data': data,
                'item_quantities': extract_item_quantities(data),
                'start_date': start_date,
                'return_date': return_date,
                'start_date_formatted': start_date.strftime('%Y-%m-%d %H:%M'),
                'return_date_formatted': return_date.strftime('%Y-%m-%d %H:%M')
            })