<commit_before>package FixMyStreet::App::Controller::Reports;
use Moose;
use namespace::autoclean;

use File::Slurp;
use List::MoreUtils qw(any);
use POSIX qw(strcoll);
use RABX;
use mySociety::MaPit;

BEGIN { extends 'Catalyst::Controller'; }

=head1 NAME

FixMyStreet::App::Controller::Reports - Catalyst Controller

=head1 DESCRIPTION

Catalyst Controller.

=head1 METHODS

=cut

=head2 index

Show the summary page of all reports.

=cut

sub index : Path : Args(0) {
    my ( $self, $c ) = @_;

    # Zurich goes straight to map page, with all reports
    if ( $c->cobrand->moniker eq 'zurich' ) {
        $c->forward( 'load_and_group_problems' );
        my $pins = $c->stash->{pins};
        $c->stash->{page} = 'reports';
        FixMyStreet::Map::display_map(
            $c,
            latitude  => @$pins ? $pins->[0]{latitude} : 0,
            longitude => @$pins ? $pins->[0]{longitude} : 0,
            area      => 274456,
            pins      => $pins,
            any_zoom  => 1,
        );
        return 1;
    }

    if ( my $body = $c->cobrand->all_reports_single_body ) {
        $c->stash->{body} = $body;
        $c->detach( 'redirect_body' );
    }

    # Fetch all bodies
    my @bodies = $c->model('DB::Body')->search({}, {
        '+select' => [ { count => 'area_id' } ],
        '+as' => [ 'area_count' ],
        join => 'body_areas',
        distinct => 1,
    })->all;
    @bodies = sort { strcoll($a->name, $b->name) } @bodies;
    $c->stash->{bodies} = \@bodies;
    $c->stash->{any_empty_bodies} = any { $_->get_column('area_count') == 0 } @bodies;

    eval {
        my $data = File::Slurp::read_file(
            FixMyStreet->path_to( '../data/all-reports.json' )->stringify
        );
        my $j = JSON->new->utf8->decode($data);
        $c->stash->{fixed} = $j->{fixed};
        $c->stash->{open} = $j->{open};
    };
    if ($@) {
        $c->stash->{message} = _("There was a problem showing the All Reports page. Please try again later.");
        if ($c->config->{STAGING_SITE}) {
            $c->stash->{message} .= '</p><p>Perhaps the bin/update-all-reports script needs running. Use: bin/update-all-reports</p><p>'
                . sprintf(_('The error was: %s'), $@);
        }
        $c->stash->{template} = 'errors/generic.html';
        return;
    }

    # Down here so that error pages aren't cached.
    $c->response->header('Cache-Control' => 'max-age=3600');
}

=head2 index

Show the summary page for a particular body.

=cut

sub body : Path : Args(1) {
    my ( $self, $c, $body ) = @_;
    $c->detach( 'ward', [ $body ] );
}

=head2 index

Show the summary page for a particular ward.

=cut

sub ward : Path : Args(2) {
    my ( $self, $c, $body, $ward ) = @_;

    $c->forward( 'body_check', [ $body ] );
    $c->forward( 'ward_check', [ $ward ] )
        if $ward;
    $c->forward( 'check_canonical_url', [ $body ] );
    $c->forward( 'load_and_group_problems' );

    my $body_short = $c->cobrand->short_name( $c->stash->{body} );
    $c->stash->{rss_url} = '/rss/reports/' . $body_short;
    $c->stash->{rss_url} .= '/' . $c->cobrand->short_name( $c->stash->{ward} )
        if $c->stash->{ward};

    $c->stash->{body_url} = '/reports/' . $body_short;

    $c->stash->{stats} = $c->cobrand->get_report_stats();

    my $pins = $c->stash->{pins};

    $c->stash->{page} = 'reports'; # So the map knows to make clickable pins
    my %map_params = (
        latitude  => @$pins ? $pins->[0]{latitude} : 0,
        longitude => @$pins ? $pins->[0]{longitude} : 0,
        area      => $c->stash->{ward} ? $c->stash->{ward}->{id} : [ keys %{$c->stash->{body}->areas} ],
        any_zoom  => 1,
    );
    if ( $c->cobrand->moniker eq 'emptyhomes' ) {
        FixMyStreet::Map::display_map(<commit_msg>Preserve the 'status' value on /reports<commit_after>package FixMyStreet::App::Controller::Reports;
use Moose;
use namespace::autoclean;

use File::Slurp;
use List::MoreUtils qw(any);
use POSIX qw(strcoll);
use RABX;
use mySociety::MaPit;

BEGIN { extends 'Catalyst::Controller'; }

=head1 NAME

FixMyStreet::App::Controller::Reports - Catalyst Controller

=head1 DESCRIPTION

Catalyst Controller.

=head1 METHODS

=cut

=head2 index

Show the summary page of all reports.

=cut

sub index : Path : Args(0) {
    my ( $self, $c ) = @_;

    # Zurich goes straight to map page, with all reports
    if ( $c->cobrand->moniker eq 'zurich' ) {
        $c->forward( 'load_and_group_problems' );
        my $pins = $c->stash->{pins};
        $c->stash->{page} = 'reports';
        FixMyStreet::Map::display_map(
            $c,
            latitude  => @$pins ? $pins->[0]{latitude} : 0,
            longitude => @$pins ? $pins->[0]{longitude} : 0,
            area      => 274456,
            pins      => $pins,
            any_zoom  => 1,
        );
        return 1;
    }

    if ( my $body = $c->cobrand->all_reports_single_body ) {
        $c->stash->{body} = $body;
        $c->detach( 'redirect_body' );
    }

    # Fetch all bodies
    my @bodies = $c->model('DB::Body')->search({}, {
        '+select' => [ { count => 'area_id' } ],
        '+as' => [ 'area_count' ],
        join => 'body_areas',
        distinct => 1,
    })->all;
    @bodies = sort { strcoll($a->name, $b->name) } @bodies;
    $c->stash->{bodies} = \@bodies;
    $c->stash->{any_empty_bodies} = any { $_->get_column('area_count') == 0 } @bodies;

    eval {
        my $data = File::Slurp::read_file(
            FixMyStreet->path_to( '../data/all-reports.json' )->stringify
        );
        my $j = JSON->new->utf8->decode($data);
        $c->stash->{fixed} = $j->{fixed};
        $c->stash->{open} = $j->{open};
    };
    if ($@) {
        $c->stash->{message} = _("There was a problem showing the All Reports page. Please try again later.");
        if ($c->config->{STAGING_SITE}) {
            $c->stash->{message} .= '</p><p>Perhaps the bin/update-all-reports script needs running. Use: bin/update-all-reports</p><p>'
                . sprintf(_('The error was: %s'), $@);
        }
        $c->stash->{template} = 'errors/generic.html';
        return;
    }

    # Down here so that error pages aren't cached.
    $c->response->header('Cache-Control' => 'max-age=3600');
}

=head2 index

Show the summary page for a particular body.

=cut

sub body : Path : Args(1) {
    my ( $self, $c, $body ) = @_;
    $c->detach( 'ward', [ $body ] );
}

=head2 index

Show the summary page for a particular ward.

=cut

sub ward : Path : Args(2) {
    my ( $self, $c, $body, $ward ) = @_;

    $c->forward( 'body_check', [ $body ] );
    $c->forward( 'ward_check', [ $ward ] )
        if $ward;
    $c->forward( 'check_canonical_url', [ $body ] );
    $c->forward( 'load_and_group_problems' );

    my $body_short = $c->cobrand->short_name( $c->stash->{body} );
    $c->stash->{rss_url} = '/rss/reports/' . $body_short;
    $c->stash->{rss_url} .= '/' . $c->cobrand->short_name( $c->stash->{ward} )
        if $c->stash->{ward};

    $c->stash->{body_url} = '/reports/' . $body_short;

    $c->stash->{stats} = $c->cobrand->get_report_stats();

    $c->stash->{filter_status} = $c->cobrand->on_map_default_status;
    my $status = $c->req->param('status') || '';
    if ( !defined $c->cobrand->on_map_default_states || $status eq 'all' ) {
        $c->stash->{filter_status} = 'all';
    } elsif ( $status eq 'open' ) {
        $c->stash->{filter_status} = 'open';
    } elsif ( $status eq 'fixed' ) {
        $c->stash->{filter_status} = 'fixed';
    }

    my $pins = $c->stash->{pins};

    $c->stash->{page} = 'reports'; # So the map knows to make clickable pins
    my %map_params = (
        latitude  => @$pins ? $pins->[0]{latitude} : 0,
        longitude => @$pins ? $pins->[0]{longitude} : 0,
        area      => $c->stash->{ward} ? $c->stash->{ward}->{id} : [ keys %{$c->stash->{body}->areas} ],
        any_zoom  => 1,
    );
    if ( $c->cobrand->moniker eq 'emptyhomes' ) {
        FixMyStreet::Map::display_map(
{'fraction_non_alphanumeric': 0.2041405269761606, 'fraction_numerical': 0.008281053952321205, 'mean_word_length': 2.4914586070959266, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 227, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4033582', 'n_tokens_mistral': 3113, 'n_tokens_neox': 2947, 'n_words': 605}