aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/zurich-overdue-alert83
-rw-r--r--conf/crontab.ugly4
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm15
-rw-r--r--perllib/FixMyStreet/Cobrand/Zurich.pm63
-rw-r--r--templates/email/zurich/alert-moderation-overdue.txt1
-rw-r--r--templates/web/zurich/admin/header.html47
-rw-r--r--templates/web/zurich/admin/problem_row.html5
-rw-r--r--templates/web/zurich/admin/report_edit.html27
-rw-r--r--templates/web/zurich/header.html35
-rw-r--r--web/cobrands/fixmystreet/position_map.js4
-rw-r--r--web/cobrands/zurich/layout.scss18
11 files changed, 241 insertions, 61 deletions
diff --git a/bin/zurich-overdue-alert b/bin/zurich-overdue-alert
new file mode 100755
index 000000000..aa9f6fe60
--- /dev/null
+++ b/bin/zurich-overdue-alert
@@ -0,0 +1,83 @@
+#!/usr/bin/env perl
+
+# zurich-overdue-alert:
+# Send email alerts to administrators for overdue admin activities.
+#
+# Copyright (c) 2012 UK Citizens Online Democracy. All rights reserved.
+# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
+
+use strict;
+use warnings;
+require 5.8.0;
+
+use DateTime;
+use CronFns;
+use FixMyStreet::App;
+
+my ($verbose, $nomail) = CronFns::options();
+
+# Only run on working days
+my $now = DateTime->now();
+exit if FixMyStreet::Cobrand::Zurich::is_public_holiday($now) or FixMyStreet::Cobrand::Zurich::is_weekend($now);
+
+my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('zurich')->new();
+my %bodies = map { $_->id => $_ } FixMyStreet::App->model("DB::Body")->all;
+
+loop_through( 'alert-moderation-overdue.txt', 0, 1, [ 'unconfirmed', 'confirmed' ] );
+loop_through( 'alert-overdue.txt', 1, 5, 'in progress' );
+
+sub loop_through {
+ my ( $template, $include_parent, $days, $states ) = @_;
+
+ my $reports = FixMyStreet::App->model("DB::Problem")->search( {
+ state => $states,
+ whensent => { '<', FixMyStreet::Cobrand::Zurich::sub_days( $now, $days ) },
+ bodies_str => { '!=', undef },
+ } );
+
+ my %to_send = ();
+ while (my $row = $reports->next) {
+ $to_send{$row->bodies_str} .= '* ' . $row->id . ": '" . $row->title . "'\n\n";
+ }
+
+ my $template_path = FixMyStreet->path_to( "templates", "email", "zurich", $template )->stringify;
+ $template = Utils::read_file( $template_path );
+
+ foreach my $body_id (keys %to_send) {
+ send_alert( $template, $body_id, $to_send{$body_id}, $include_parent );
+ }
+}
+
+sub send_alert {
+ my ( $template, $body_id, $data, $include_parent ) = @_;
+
+ my $body = $bodies{$body_id};
+ my $body_email = $body->endpoint;
+
+ my $h = {
+ data => $data,
+ admin_url => $cobrand->admin_base_url,
+ };
+
+ my $env_to = [ $body_email ];
+ my $to = [ [ $body_email, $body->name ] ];
+ if ( $include_parent ) {
+ my $parent = $body->parent;
+ my $parent_email = $parent->endpoint;
+ push @$env_to, $parent_email;
+ push @$to, [ $parent_email, $parent->name ];
+ }
+
+ my $result = FixMyStreet::App->send_email_cron(
+ {
+ _template_ => $template,
+ _parameters_ => $h,
+ To => $to,
+ From => [ FixMyStreet->config('CONTACT_EMAIL'), FixMyStreet->config('CONTACT_NAME') ],
+ },
+ FixMyStreet->config('CONTACT_EMAIL'),
+ $env_to,
+ $nomail
+ );
+}
+
diff --git a/conf/crontab.ugly b/conf/crontab.ugly
index 7a2ab1891..c1de3d66f 100644
--- a/conf/crontab.ugly
+++ b/conf/crontab.ugly
@@ -64,3 +64,7 @@ my %no_alerts = map { $_ => 1 } @no_alerts;
39 2 * * * !!(*= $user *)!! /data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/problems-filed-graph
43 2 * * * !!(*= $user *)!! /data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/problem-creation-graph
00 8 * * * !!(*= $user *)!! /data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/check-for-zombies !!(*= $user *)!!
+
+!!(* if ($vhost =~ /zurich/) { *)!!
+30 0 * * * !!(*= $user *)!! /data/vhost/!!(*= $vhost *)!!/fixmystreet/bin/zurich-overdue-alert
+!!(* } *)!!
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index de69880c1..7869b21b7 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -606,6 +606,21 @@ sub report_edit : Path('report_edit') : Args(1) {
}
if ( $c->cobrand->moniker eq 'zurich' ) {
+
+ FixMyStreet::Map::display_map(
+ $c,
+ latitude => $problem->latitude,
+ longitude => $problem->longitude,
+ pins => $problem->used_map
+ ? [ {
+ latitude => $problem->latitude,
+ longitude => $problem->longitude,
+ colour => 'yellow',
+ type => 'big',
+ } ]
+ : [],
+ );
+
my $done = $c->cobrand->admin_report_edit();
return if $done;
}
diff --git a/perllib/FixMyStreet/Cobrand/Zurich.pm b/perllib/FixMyStreet/Cobrand/Zurich.pm
index 81ace5a05..6ac04ce1e 100644
--- a/perllib/FixMyStreet/Cobrand/Zurich.pm
+++ b/perllib/FixMyStreet/Cobrand/Zurich.pm
@@ -1,6 +1,7 @@
package FixMyStreet::Cobrand::Zurich;
use base 'FixMyStreet::Cobrand::Default';
+use DateTime;
use POSIX qw(strcoll);
use strict;
@@ -43,6 +44,68 @@ sub get_body_sender {
return { method => 'Zurich' };
}
+# Report overdue functions
+
+my %public_holidays = map { $_ => 1 } (
+ '2013-01-01', '2013-01-02', '2013-03-29', '2013-04-01',
+ '2013-04-15', '2013-05-01', '2013-05-09', '2013-05-20',
+ '2013-08-01', '2013-09-09', '2013-12-25', '2013-12-26',
+ '2014-01-01', '2014-01-02', '2014-04-18', '2014-04-21',
+ '2014-04-28', '2014-05-01', '2014-05-29', '2014-06-09',
+ '2014-08-01', '2014-09-15', '2014-12-25', '2014-12-26',
+);
+
+sub is_public_holiday {
+ my $dt = shift;
+ return $public_holidays{$dt->ymd};
+}
+
+sub is_weekend {
+ my $dt = shift;
+ return $dt->dow > 5;
+}
+
+sub add_days {
+ my ( $dt, $days ) = @_;
+ $dt = $dt->clone;
+ while ( $days > 0 ) {
+ $dt->add ( days => 1 );
+ next if is_public_holiday($dt) or is_weekend($dt);
+ $days--;
+ }
+ return $dt;
+}
+
+sub sub_days {
+ my ( $dt, $days ) = @_;
+ $dt = $dt->clone;
+ while ( $days > 0 ) {
+ $dt->subtract ( days => 1 );
+ next if is_public_holiday($dt) or is_weekend($dt);
+ $days--;
+ }
+ return $dt;
+}
+
+sub overdue {
+ my ( $self, $problem ) = @_;
+
+ my $w = $problem->whensent;
+ return 0 unless $w;
+
+ if ( $problem->state eq 'unconfirmed' || $problem->state eq 'confirmed' ) {
+ # One working day
+ $w = add_days( $w, 1 );
+ return $w < DateTime->now();
+ } elsif ( $problem->state eq 'in progress' ) {
+ # Five working days
+ $w = add_days( $w, 5 );
+ return $w < DateTime->now();
+ } else {
+ return 0;
+ }
+}
+
# Specific administrative displays
sub admin_pages {
diff --git a/templates/email/zurich/alert-moderation-overdue.txt b/templates/email/zurich/alert-moderation-overdue.txt
index cf3569bc5..c3aab66d2 100644
--- a/templates/email/zurich/alert-moderation-overdue.txt
+++ b/templates/email/zurich/alert-moderation-overdue.txt
@@ -1,6 +1,7 @@
Subject: eskalierte Meldungen auf Fix my Zurich
Die folgenden Meldungen auf Fix my Zurich sind älter als einen Tag und müssen dringend bearbeitet werden:
+
<?=$values['data']?>
Um diese Meldungen zu moderieren, klicken Sie auf folgende URL:
diff --git a/templates/web/zurich/admin/header.html b/templates/web/zurich/admin/header.html
index d0c399a83..72472492a 100644
--- a/templates/web/zurich/admin/header.html
+++ b/templates/web/zurich/admin/header.html
@@ -1,5 +1,7 @@
-[% INCLUDE 'header.html' admin = 1, bodyclass = 'fullwidthpage admin' %]
[%
+ SET bodyclass = bodyclass || 'fullwidthpage';
+ INCLUDE 'header.html' admin = 1, bodyclass = bodyclass _ ' admin';
+
states = {
'unconfirmed' = loc('Submitted'),
'confirmed' = loc('Open'),
@@ -11,45 +13,10 @@
}
%]
<style type="text/css">
-dt { clear: left; float: left; font-weight: bold; }
-dd { margin-left: 8em; }
-.adminhidden { color: #666666; }
-.error { color: red; }
-select { width: auto; }
+ .adminhidden { color: #666666; }
+ .error { color: red; }
+ .overdue { color: #660000; }
+ select { width: auto; }
</style>
- <!--<strong>[% loc('FixMyStreet admin:') %]</strong>-->
- <div class="admin-nav">
- <ul>
- [% pagename = c.req.uri.path %]
- [% pagename = pagename.replace('/admin/?(\w*).*', '$1') %]
-
- <li [% IF pagename == 'summary' OR pagename == '' %]class="current"[% END %]>
- <a href="/admin/summary">[% loc('Summary') %]</a>
- </li>
- <li [% IF pagename == 'reports' OR pagename == 'report_edit' %]class="current"[% END %]>
- <a href="/admin/reports">[% loc('Reports') %]</a>
- </li>
- [% IF admin_type == 'dm' OR admin_type == 'super' %]
- <li [% IF pagename == 'bodies' OR pagename == 'body' %]class="current"[% END %]>
- <a href="/admin/bodies">[% loc('Bodies') %]</a>
- </li>
- [% END %]
- [% IF admin_type == 'super' %]
- <li [% IF pagename == 'users' OR pagename == 'user_edit' %]class="current"[% END %]>
- <a href="/admin/users">[% loc('Users') %]</a>
- </li>
- [% END %]
- <li class="search-box">
- <form method="get" action="[% c.uri_for('reports') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
- <input type="text" name="search" size="20" id="search" placeholder="[% loc('Search reports') %]">
- </form>
- </li>
- </ul>
- </div>
- <!-- | <a href="timeline">Timeline</a> -->
- <!-- | <a href="questionnaire">Survey</a> -->
- <!-- | <a href="flagged">Flagged</a> -->
- <!-- | <a href="stats">Stats</a> -->
-
<h1 style="clear:both;">[% title %]</h1>
diff --git a/templates/web/zurich/admin/problem_row.html b/templates/web/zurich/admin/problem_row.html
index 176f1a1a6..617490232 100644
--- a/templates/web/zurich/admin/problem_row.html
+++ b/templates/web/zurich/admin/problem_row.html
@@ -4,7 +4,10 @@
[% NEXT IF admin_type == 'sdm' AND p_body.id != body.id %]
[% NEXT IF admin_type == 'dm' AND p_body.id != body.id AND p_body.parent.id != body.id %]
[% END %]
- <tr[% ' class="adminhidden"' IF problem.state == 'hidden' %]>
+ <tr[%
+ ' class="adminhidden"' IF problem.state == 'hidden';
+ ' class="overdue"' IF c.cobrand.overdue( problem );
+ %]>
<td class="record-id">[%- IF problem.is_visible -%]
<a href="[% c.uri_for_email( '/report', problem.id ) %]">[% problem.id %]</a>
[%- ELSE %]
diff --git a/templates/web/zurich/admin/report_edit.html b/templates/web/zurich/admin/report_edit.html
index eb543a777..122045550 100644
--- a/templates/web/zurich/admin/report_edit.html
+++ b/templates/web/zurich/admin/report_edit.html
@@ -1,18 +1,20 @@
-[% INCLUDE 'admin/header.html' title=tprintf(loc('Editing problem %d'), problem.id ) -%]
-[% PROCESS 'admin/report_blocks.html' %]
+[%
+ PROCESS "maps/zurich.html";
+ INCLUDE 'admin/header.html'
+ title = tprintf(loc('Editing problem %d'), problem.id ),
+ bodyclass = 'mappage';
+ PROCESS 'admin/report_blocks.html'
+-%]
+
+[% map_html %]
+</div>
[% status_message %]
-[% IF problem.state == 'planned' %]
-[% INCLUDE 'admin/list_updates.html' %]
-[% END %]
-
<form method="post" action="[% c.uri_for( 'report_edit', problem.id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
<input type="hidden" name="token" value="[% token %]" >
<input type="hidden" name="submit" value="1" >
-<div style="float:left; margin-top: 1em; width:48%; margin-right:2%">
-
<ul>
<li><a href="[% c.uri_for_email( '/report', problem.id ) %]">[% loc('View report on site' )%]</a></li>
@@ -53,9 +55,6 @@
<label class="inline" for="publish_photo">[% loc("Publish photo") %]</label></li>
[% END %]
</ul>
-</div>
-
-<div style="float:right;width:48%">
<p><label for="internal_notes">[% loc('Internal notes:') %]</label>
<textarea name='internal_notes' id='internal_notes' cols=60 rows=5>[% problem.extra.internal_notes | html %]</textarea></p>
@@ -154,9 +153,6 @@ $(function(){
[% END %]
-</div>
-
-<div style="clear:both"></div>
<p align="right">
[% IF problem.state == 'planned' %]
<input type="submit" name="publish_response" value="[% loc('Publish the response') %]">
@@ -166,9 +162,6 @@ $(function(){
</form>
-[% IF problem.state != 'planned' %]
[% INCLUDE 'admin/list_updates.html' %]
-[% END %]
-
[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/zurich/header.html b/templates/web/zurich/header.html
index 47d7d39d2..77dd3cd63 100644
--- a/templates/web/zurich/header.html
+++ b/templates/web/zurich/header.html
@@ -44,6 +44,41 @@
</header>
<div class="container">
+
+[% IF admin %]
+ <div class="admin-nav-wrapper">
+ <div class="admin-nav">
+ <ul>
+ [% pagename = c.req.uri.path %]
+ [% pagename = pagename.replace('/admin/?(\w*).*', '$1') %]
+
+ <li [% IF pagename == 'summary' OR pagename == '' %]class="current"[% END %]>
+ <a href="/admin/summary">[% loc('Summary') %]</a>
+ </li>
+ <li [% IF pagename == 'reports' OR pagename == 'report_edit' %]class="current"[% END %]>
+ <a href="/admin/reports">[% loc('Reports') %]</a>
+ </li>
+ [% IF admin_type == 'dm' OR admin_type == 'super' %]
+ <li [% IF pagename == 'bodies' OR pagename == 'body' %]class="current"[% END %]>
+ <a href="/admin/bodies">[% loc('Bodies') %]</a>
+ </li>
+ [% END %]
+ [% IF admin_type == 'super' %]
+ <li [% IF pagename == 'users' OR pagename == 'user_edit' %]class="current"[% END %]>
+ <a href="/admin/users">[% loc('Users') %]</a>
+ </li>
+ [% END %]
+ <li class="search-box">
+ <form method="get" action="[% c.uri_for('reports') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <input type="text" name="search" size="20" id="search" placeholder="[% loc('Search reports') %]">
+ </form>
+
+ </li>
+ </ul>
+ </div>
+ </div>
+[% END %]
+
<div class="content[% " $mainclass" | html IF mainclass %]" role="main">
[% INCLUDE 'nav_over_content.html' %]
diff --git a/web/cobrands/fixmystreet/position_map.js b/web/cobrands/fixmystreet/position_map.js
index 4a18d9f9a..71794e8d6 100644
--- a/web/cobrands/fixmystreet/position_map.js
+++ b/web/cobrands/fixmystreet/position_map.js
@@ -1,14 +1,14 @@
function position_map_box() {
var $html = $('html');
if ($html.hasClass('ie6')) {
- $('#map_box').prependTo('.wrapper').css({
+ $('#map_box').prependTo('body').css({
zIndex: 0, position: 'absolute',
top: 0, left: 0, right: 0, bottom: 0,
width: '100%', height: $(window).height(),
margin: 0
});
} else {
- $('#map_box').prependTo('.wrapper').css({
+ $('#map_box').prependTo('body').css({
zIndex: 0, position: 'fixed',
top: 0, left: 0, right: 0, bottom: 0,
width: '100%', height: '100%',
diff --git a/web/cobrands/zurich/layout.scss b/web/cobrands/zurich/layout.scss
index 9ebab6da1..189957f5d 100644
--- a/web/cobrands/zurich/layout.scss
+++ b/web/cobrands/zurich/layout.scss
@@ -190,6 +190,11 @@ body.fullwidthpage.admin .content {
width: 100%;
}
+body.mappage.admin .content {
+ margin-top: 6em;
+ margin-left: 0.5em;
+
+}
.admin {
.content {
margin: 2em 0 1em;
@@ -239,11 +244,22 @@ body.fullwidthpage.admin .content {
}
}
+.admin-nav-wrapper {
+ background-color: white;
+ padding: 1.5em 0 1em;
+}
+body.mappage .admin-nav-wrapper {
+ box-sizing: border-box;
+ padding-left: 10px;
+ padding-right: 10px;
+ position: fixed;
+ width: 100%;
+}
+
.admin-nav {
background: #f4f4f4;
@include background(linear-gradient(#fbfbfb, #efefef));
border-bottom: 2px solid $table_border_color;
- margin: 0 0 1em 0;
ul {
overflow:auto;
margin:0 0 -2px 0;