Ejemplo n.º 1
0
def operator_vehicles(request, slug=None, parent=None):
    operators = Operator.objects.select_related('region')
    if slug:
        try:
            operator = get_object_or_404(operators, slug=slug.lower())
        except Http404:
            operator = get_object_or_404(operators,
                                         operatorcode__code=slug,
                                         operatorcode__source__name='slug')
        vehicles = operator.vehicle_set.filter(withdrawn=False)
    elif parent:
        operators = list(operators.filter(parent=parent))
        vehicles = Vehicle.objects.filter(
            operator__in=operators, withdrawn=False).select_related('operator')
        if not operators:
            raise Http404
        operator = operators[0]

    vehicles = vehicles.order_by('fleet_number', 'fleet_code', 'reg', 'code')
    if not parent:
        latest_journeys = Subquery(
            VehicleJourney.objects.filter(
                vehicle=OuterRef('pk')).order_by('-datetime').values('pk')[:1])
        latest_journeys = vehicles.filter(latest_location=None).annotate(
            latest_journey=latest_journeys)
        latest_journeys = VehicleJourney.objects.filter(
            id__in=latest_journeys.values('latest_journey'))
        prefetch = Prefetch('vehiclejourney_set',
                            queryset=latest_journeys.select_related('service'),
                            to_attr='latest_journeys')
        vehicles = vehicles.prefetch_related(prefetch, 'features')
        pending_edits = VehicleEdit.objects.filter(
            approved=None, vehicle=OuterRef('id')).only('id')
        vehicles = vehicles.annotate(pending_edits=Exists(pending_edits))
        vehicles = vehicles.select_related('latest_location__journey__service')

    vehicles = vehicles.select_related('livery', 'vehicle_type')

    submitted = False
    revisions = False
    breadcrumb = [operator.region, operator]

    form = request.path.endswith('/edit')

    if form:
        if not request.user.is_authenticated:
            return redirect(f'/accounts/login/?next={request.path}')

        breadcrumb.append(Vehicles(operator))
        initial = {
            'operator': operator,
            'other_colour': '#ffffff',
        }
        if request.method == 'POST':
            form = EditVehiclesForm(request.POST,
                                    initial=initial,
                                    operator=operator)
            if not form.has_really_changed():
                form.add_error(None, 'You haven\'t changed anything')
            elif form.is_valid():
                data = {
                    key: form.cleaned_data[key]
                    for key in form.changed_data
                }
                vehicle_ids = request.POST.getlist('vehicle')
                now = timezone.now()

                revisions, changed_fields = do_revisions(vehicle_ids, data)
                if revisions:
                    Vehicle.objects.bulk_update(
                        (revision.vehicle for revision in revisions),
                        changed_fields)
                    for revision in revisions:
                        revision.datetime = now
                        if request.user.is_authenticated:
                            revision.user = request.user
                    VehicleRevision.objects.bulk_create(revisions)
                    revisions = len(revisions)

                if data:
                    # this will fetch the vehicles list
                    # - slightly important that it occurs before any change of operator
                    ticked_vehicles = [
                        v for v in vehicles if str(v.id) in vehicle_ids
                    ]
                    edits = [
                        get_vehicle_edit(vehicle, data, now, request)
                        for vehicle in ticked_vehicles
                    ]
                    edits = VehicleEdit.objects.bulk_create(edit
                                                            for edit in edits
                                                            if edit)
                    submitted = len(edits)
                    if 'features' in data:
                        for edit in edits:
                            edit.features.set(data['features'])
                form = EditVehiclesForm(initial=initial, operator=operator)
        else:
            form = EditVehiclesForm(initial=initial, operator=operator)

    if operator.name == 'National Express':
        vehicles = sorted(vehicles, key=lambda v: v.notes)

    if not vehicles:
        raise Http404

    paginator = Paginator(vehicles, 1000)
    page = request.GET.get('page')
    vehicles = paginator.get_page(page)

    features_column = not parent and any(vehicle.features.all()
                                         for vehicle in vehicles)

    columns = set(key for vehicle in vehicles if vehicle.data
                  for key in vehicle.data)
    for vehicle in vehicles:
        vehicle.column_values = [
            vehicle.data and vehicle.data_get(key) or '' for key in columns
        ]

    response = render(
        request, 'operator_vehicles.html', {
            'breadcrumb':
            breadcrumb,
            'parent':
            parent,
            'operators':
            parent and operators,
            'object':
            operator,
            'today':
            timezone.localtime().date(),
            'vehicles':
            vehicles,
            'paginator':
            paginator,
            'code_column':
            any(v.fleet_number_mismatch() for v in vehicles),
            'branding_column':
            any(vehicle.branding for vehicle in vehicles),
            'name_column':
            any(vehicle.name for vehicle in vehicles),
            'notes_column':
            any(vehicle.notes and vehicle.notes != 'Spare ticket machine'
                for vehicle in vehicles),
            'features_column':
            features_column,
            'columns':
            columns,
            'edits':
            submitted,
            'revisions':
            revisions,
            'revision':
            revisions and revision,
            'form':
            form,
        })

    return response
Ejemplo n.º 2
0
def operator_vehicles(request, slug):
    operators = Operator.objects.select_related('region')
    try:
        operator = get_object_or_404(operators, slug=slug)
    except Http404:
        operator = get_object_or_404(operators, operatorcode__code=slug, operatorcode__source__name='slug')
    vehicles = operator.vehicle_set
    latest_journeys = Subquery(VehicleJourney.objects.filter(
        vehicle=OuterRef('pk')
    ).order_by('-datetime').values('pk')[:1])
    latest_journeys = vehicles.filter(latest_location=None).annotate(latest_journey=latest_journeys)
    latest_journeys = VehicleJourney.objects.filter(id__in=latest_journeys.values('latest_journey'))
    prefetch = Prefetch('vehiclejourney_set',
                        queryset=latest_journeys.select_related('service'), to_attr='latest_journeys')
    vehicles = vehicles.prefetch_related(prefetch)
    vehicles = vehicles.order_by('fleet_number', 'reg', 'code')
    vehicles = vehicles.select_related('vehicle_type', 'livery', 'latest_location__journey__service')

    edit = request.path.endswith('/edit')
    submitted = False
    if edit:
        form = EditVehiclesForm(request.POST, operator=operator, initial={
            'operator': operator
        })
        if request.POST and form.is_valid():
            ticked_vehicles = (vehicle for vehicle in vehicles if str(vehicle.id) in request.POST.getlist('vehicle'))
            data = {key: form.cleaned_data[key] for key in form.changed_data}
            submitted = len(VehicleEdit.objects.bulk_create(
                get_vehicle_edit(vehicle, data) for vehicle in ticked_vehicles
            ))
            if form.cleaned_data.get('operator') and form.cleaned_data['operator'] != operator:
                Vehicle.objects.filter(id__in=request.POST.getlist('vehicle')).update(operator=operator)
    else:
        form = None
        pending_edits = VehicleEdit.objects.filter(approved=False, vehicle=OuterRef('id'))
        vehicles = vehicles.annotate(pending_edits=Exists(pending_edits))

    if not vehicles:
        raise Http404()

    if operator.name == 'National Express':
        for v in vehicles:
            parts = v.notes.split()
            if parts and parts[-1][-1].isdigit():
                v.fleet_number = parts[-1]
                if v.fleet_number.isdigit():
                    v.fleet_number = int(v.fleet_number)
                v.notes = ' '.join(parts[:-1])
        vehicles = sorted(vehicles, key=lambda v: v.fleet_number if type(v.fleet_number) is int else 0)
        vehicles = sorted(vehicles, key=lambda v: v.notes or 'z')

    return render(request, 'operator_vehicles.html', {
        'breadcrumb': [operator.region, operator],
        'object': operator,
        'today': timezone.localtime().date(),
        'vehicles': vehicles,
        'code_column': any(v.fleet_number_mismatch() for v in vehicles),
        'branding_column': any(vehicle.branding for vehicle in vehicles),
        'name_column': any(vehicle.name for vehicle in vehicles),
        'notes_column': any(vehicle.notes for vehicle in vehicles),
        'edit_url': reverse('admin:vehicles_vehicle_changelist'),
        'edit': edit,
        'submitted': submitted,
        'form': form,
    })