diff options
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Admin')
5 files changed, 177 insertions, 188 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm b/perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm index bcfeb3dd8..5dab1da2c 100644 --- a/perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm +++ b/perllib/FixMyStreet/App/Controller/Admin/DefectTypes.pm @@ -6,12 +6,6 @@ use mySociety::ArrayUtils; BEGIN { extends 'Catalyst::Controller'; } -sub begin : Private { - my ( $self, $c ) = @_; - - $c->forward('/admin/begin'); -} - sub index : Path : Args(0) { my ( $self, $c ) = @_; @@ -62,7 +56,7 @@ sub edit : Path : Args(2) { my %active_contacts = map { $_->id => 1 } @contacts; my @all_contacts = map { { id => $_->id, - category => $_->category, + category => $_->category_display, active => $active_contacts{$_->id}, } } @live_contacts; $c->stash->{contacts} = \@all_contacts; diff --git a/perllib/FixMyStreet/App/Controller/Admin/ExorDefects.pm b/perllib/FixMyStreet/App/Controller/Admin/ExorDefects.pm index 201742c81..bdeecc1a3 100644 --- a/perllib/FixMyStreet/App/Controller/Admin/ExorDefects.pm +++ b/perllib/FixMyStreet/App/Controller/Admin/ExorDefects.pm @@ -2,19 +2,13 @@ package FixMyStreet::App::Controller::Admin::ExorDefects; use Moose; use namespace::autoclean; -use Text::CSV; use DateTime; -use mySociety::Random qw(random_bytes); +use Try::Tiny; +use FixMyStreet::Integrations::ExorRDI; BEGIN { extends 'Catalyst::Controller'; } -sub begin : Private { - my ( $self, $c ) = @_; - - $c->forward('/admin/begin'); -} - sub index : Path : Args(0) { my ( $self, $c ) = @_; @@ -54,177 +48,32 @@ sub download : Path('download') : Args(0) { my $end_date = $parser-> parse_datetime ( $c->get_param('end_date') ) ; my $one_day = DateTime::Duration->new( days => 1 ); - my %params = ( - -and => [ - state => [ 'action scheduled' ], - external_id => { '!=' => undef }, - 'admin_log_entries.action' => 'inspected', - 'admin_log_entries.whenedited' => { '>=', $start_date }, - 'admin_log_entries.whenedited' => { '<=', $end_date + $one_day }, - ] - ); - - my $user; - if ( $c->get_param('user_id') ) { - my $uid = $c->get_param('user_id'); - $params{'admin_log_entries.user_id'} = $uid; - $user = $c->model('DB::User')->find( { id => $uid } ); - } - - my $problems = $c->cobrand->problems->search( - \%params, - { - join => 'admin_log_entries', - distinct => 1, - } - ); - - if ( !$problems->count ) { - if ( defined $user ) { + my $params = { + start_date => $start_date, + inspection_date => $start_date, + end_date => $end_date + $one_day, + user => $c->get_param('user_id'), + mark_as_processed => 0, + }; + my $rdi = FixMyStreet::Integrations::ExorRDI->new($params); + + try { + my $out = $rdi->construct; + $c->res->content_type('text/csv; charset=utf-8'); + $c->res->header('content-disposition' => "attachment; filename=" . $rdi->filename); + $c->res->body( $out ); + } catch { + die $_ unless $_ =~ /FixMyStreet::Integrations::ExorRDI::Error/; + if ($params->{user}) { $c->flash->{error_message} = _("No inspections by that inspector in the selected date range."); } else { $c->flash->{error_message} = _("No inspections in the selected date range."); } - $c->flash->{start_date} = $start_date; - $c->flash->{end_date} = $end_date; - $c->flash->{user_id} = $user->id if $user; + $c->flash->{start_date} = $params->{start_date}; + $c->flash->{end_date} = $params->{end_date}; + $c->flash->{user_id} = $params->{user}; $c->res->redirect( $c->uri_for( '' ) ); - } - - # A single RDI file might contain inspections from multiple inspectors, so - # we need to group inspections by inspector within G records. - my $inspectors = {}; - my $inspector_initials = {}; - while ( my $report = $problems->next ) { - my $user = $report->inspection_log_entry->user; - $inspectors->{$user->id} ||= []; - push @{ $inspectors->{$user->id} }, $report; - unless ( $inspector_initials->{$user->id} ) { - $inspector_initials->{$user->id} = $user->get_extra_metadata('initials'); - } - } - - my $csv = Text::CSV->new({ binary => 1, eol => "" }); - - my $p_count = 0; - my $link_id = $c->cobrand->exor_rdi_link_id; - - # RDI first line is always the same - $csv->combine("1", "1.8", "1.0.0.0", "ENHN", ""); - my @body = ($csv->string); - - my $i = 0; - foreach my $inspector_id (keys %$inspectors) { - my $inspections = $inspectors->{$inspector_id}; - my $initials = $inspector_initials->{$inspector_id}; - - $csv->combine( - "G", # start of an area/sequence - $link_id, # area/link id, fixed value for our purposes - "","", # must be empty - $initials || "XX", # inspector initials - $start_date->strftime("%y%m%d"), # date of inspection yymmdd - "0700", # time of inspection hhmm, set to static value for now - "D", # inspection variant, should always be D - "INS", # inspection type, always INS - "N", # Area of the county - north (N) or south (S) - "", "", "", "" # empty fields - ); - push @body, $csv->string; - - $csv->combine( - "H", # initial inspection type - "MC" # minor carriageway (changes depending on activity code) - ); - push @body, $csv->string; - - foreach my $report (@$inspections) { - my ($eastings, $northings) = $report->local_coords; - my $description = sprintf("%s %s", $report->external_id || "", $report->get_extra_metadata('detailed_information') || ""); - my $activity_code = $report->defect_type ? - $report->defect_type->get_extra_metadata('activity_code') - : 'MC'; - my $traffic_information = $report->get_extra_metadata('traffic_information') ? - 'TM ' . $report->get_extra_metadata('traffic_information') - : 'TM none'; - - $csv->combine( - "I", # beginning of defect record - $activity_code, # activity code - minor carriageway, also FC (footway) - "", # empty field, can also be A (seen on MC) or B (seen on FC) - sprintf("%03d", ++$i), # randomised sequence number - "${eastings}E ${northings}N", # defect location field, which we don't capture from inspectors - $report->inspection_log_entry->whenedited->strftime("%H%M"), # defect time raised - "","","","","","","", # empty fields - $traffic_information, - $description, # defect description - ); - push @body, $csv->string; - - my $defect_type = $report->defect_type ? - $report->defect_type->get_extra_metadata('defect_code') - : 'SFP2'; - $csv->combine( - "J", # georeferencing record - $defect_type, # defect type - SFP2: sweep and fill <1m2, POT2 also seen - $report->response_priority ? - $report->response_priority->external_id : - "2", # priority of defect - "","", # empty fields - $eastings, # eastings - $northings, # northings - "","","","","" # empty fields - ); - push @body, $csv->string; - - $csv->combine( - "M", # bill of quantities record - "resolve", # permanent repair - "","", # empty fields - "/CMC", # /C + activity code - "", "" # empty fields - ); - push @body, $csv->string; - } - - # end this group of defects with a P record - $csv->combine( - "P", # end of area/sequence - 0, # always 0 - 999999, # charging code, always 999999 in OCC - ); - push @body, $csv->string; - $p_count++; - } - - # end the RDI file with an X record - my $record_count = $i; - $csv->combine( - "X", # end of inspection record - $p_count, - $p_count, - $record_count, # number of I records - $record_count, # number of J records - 0, 0, 0, # always zero - $record_count, # number of M records - 0, # always zero - $p_count, - 0, 0, 0 # error counts, always zero - ); - push @body, $csv->string; - - my $start = $start_date->strftime("%Y%m%d"); - my $end = $end_date->strftime("%Y%m%d"); - my $filename = sprintf("exor_defects-%s-%s.rdi", $start, $end); - if ( $user ) { - my $initials = $user->get_extra_metadata("initials") || ""; - $filename = sprintf("exor_defects-%s-%s-%s.rdi", $start, $end, $initials); - } - $c->res->content_type('text/csv; charset=utf-8'); - $c->res->header('content-disposition' => "attachment; filename=$filename"); - # The RDI format is very weird CSV - each line must be wrapped in - # double quotes. - $c->res->body( join "", map { "\"$_\"\r\n" } @body ); + }; } -1;
\ No newline at end of file +1; diff --git a/perllib/FixMyStreet/App/Controller/Admin/ReportExtraFields.pm b/perllib/FixMyStreet/App/Controller/Admin/ReportExtraFields.pm new file mode 100644 index 000000000..337fb4bed --- /dev/null +++ b/perllib/FixMyStreet/App/Controller/Admin/ReportExtraFields.pm @@ -0,0 +1,55 @@ +package FixMyStreet::App::Controller::Admin::ReportExtraFields; +use Moose; +use namespace::autoclean; +use List::MoreUtils qw(uniq); + +BEGIN { extends 'Catalyst::Controller'; } + + +sub index : Path : Args(0) { + my ( $self, $c ) = @_; + + my @extras = $c->model('DB::ReportExtraFields')->search( + undef, + { + order_by => 'name' + } + ); + + $c->stash->{extra_fields} = \@extras; +} + +sub edit : Path : Args(1) { + my ( $self, $c, $extra_id ) = @_; + + my $extra; + if ( $extra_id eq 'new' ) { + $extra = $c->model('DB::ReportExtraFields')->new({}); + } else { + $extra = $c->model('DB::ReportExtraFields')->find( $extra_id ) + or $c->detach( '/page_error_404_not_found' ); + } + + if ($c->req->method eq 'POST') { + $c->forward('/auth/check_csrf_token'); + + foreach (qw/name cobrand language/) { + $extra->$_($c->get_param($_)); + } + $c->forward('/admin/update_extra_fields', [ $extra ]); + + $extra->update_or_insert; + } + + $c->forward('/auth/get_csrf_token'); + $c->forward('/admin/fetch_languages'); + + my @cobrands = uniq sort map { $_->{moniker} } FixMyStreet::Cobrand->available_cobrand_classes; + $c->stash->{cobrands} = \@cobrands; + + $c->stash->{extra} = $extra; +} + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm b/perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm index bae0f71a7..2613f6ae0 100644 --- a/perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm +++ b/perllib/FixMyStreet/App/Controller/Admin/ResponsePriorities.pm @@ -5,12 +5,6 @@ use namespace::autoclean; BEGIN { extends 'Catalyst::Controller'; } -sub begin : Private { - my ( $self, $c ) = @_; - - $c->forward('/admin/begin'); -} - sub index : Path : Args(0) { my ( $self, $c ) = @_; @@ -71,6 +65,7 @@ sub edit : Path : Args(2) { $priority->name( $c->get_param('name') ); $priority->description( $c->get_param('description') ); $priority->external_id( $c->get_param('external_id') ); + $priority->is_default( $c->get_param('is_default') ? 1 : 0 ); $priority->update_or_insert; my @live_contact_ids = map { $_->id } @live_contacts; diff --git a/perllib/FixMyStreet/App/Controller/Admin/States.pm b/perllib/FixMyStreet/App/Controller/Admin/States.pm new file mode 100644 index 000000000..938692af0 --- /dev/null +++ b/perllib/FixMyStreet/App/Controller/Admin/States.pm @@ -0,0 +1,96 @@ +package FixMyStreet::App::Controller::Admin::States; +use Moose; +use namespace::autoclean; + +BEGIN { extends 'Catalyst::Controller'; } + +sub index : Path : Args(0) { + my ( $self, $c ) = @_; + + $c->forward('/auth/get_csrf_token'); + $c->forward('/admin/fetch_languages'); + my $rs = $c->model('DB::State'); + + if ($c->req->method eq 'POST') { + $c->forward('/auth/check_csrf_token'); + + $c->forward('process_new') + && $c->forward('delete') + && $c->forward('update'); + + $rs->clear; + } + + $c->stash->{open_states} = $rs->open; + $c->stash->{closed_states} = $rs->closed; + $c->stash->{fixed_states} = $rs->fixed; +} + +sub process_new : Private { + my ($self, $c) = @_; + if ($c->get_param('new_fixed')) { + $c->model('DB::State')->create({ + label => 'fixed', + type => 'fixed', + name => _('Fixed'), + }); + return 0; + } + return 1 unless $c->get_param('new'); + my %params = map { $_ => $c->get_param($_) } qw/label type name/; + $c->model('DB::State')->create(\%params); + return 0; +} + +sub delete : Private { + my ($self, $c) = @_; + + my @params = keys %{ $c->req->params }; + my ($to_delete) = map { /^delete:(.*)/ } grep { /^delete:/ } @params; + if ($to_delete) { + $c->model('DB::State')->search({ label => $to_delete })->delete; + return 0; + } + return 1; +} + +sub update : Private { + my ($self, $c) = @_; + + my $rs = $c->model('DB::State'); + my %db_states = map { $_->label => $_ } @{$rs->states}; + my @params = keys %{ $c->req->params }; + my @states = map { /^type:(.*)/ } grep { /^type:/ } @params; + + foreach my $state (@states) { + # If there is only one language, we still store confirmed/closed + # as translations, as that seems a sensible place to store them. + if ($state eq 'confirmed' or $state eq 'closed') { + if (my $name = $c->get_param("name:$state")) { + my ($lang) = keys %{$c->stash->{languages}}; + $db_states{$state}->add_translation_for('name', $lang, $name); + } + } else { + $db_states{$state}->update({ + type => $c->get_param("type:$state"), + name => $c->get_param("name:$state"), + }); + } + + foreach my $lang (keys(%{$c->stash->{languages}})) { + my $id = $c->get_param("translation_id:$state:$lang"); + my $text = $c->get_param("translation:$state:$lang"); + if ($text) { + $db_states{$state}->add_translation_for('name', $lang, $text); + } elsif ($id) { + $c->model('DB::Translation')->find({ id => $id })->delete; + } + } + } + + return 1; +} + +__PACKAGE__->meta->make_immutable; + +1; |