1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
package FixMyStreet::DB::ResultSet::Questionnaire;
use base 'DBIx::Class::ResultSet';
use strict;
use warnings;
use Encode;
use Utils;
use mySociety::EmailUtil;
sub send_questionnaires {
my ( $rs, $params ) = @_;
$rs->send_questionnaires_period( '4 weeks', $params );
$rs->send_questionnaires_period( '26 weeks', $params )
if $params->{site} eq 'emptyhomes';
}
sub send_questionnaires_period {
my ( $rs, $period, $params ) = @_;
# Select all problems that need a questionnaire email sending
my $q_params = {
state => [ FixMyStreet::DB::Result::Problem::visible_states() ],
whensent => [
'-and',
{ '!=', undef },
{ '<', \"ms_current_timestamp() - '$period'::interval" },
],
send_questionnaire => 1,
};
# FIXME Do these a bit better...
if ($params->{site} eq 'emptyhomes' && $period eq '4 weeks') {
$q_params->{'(select max(whensent) from questionnaire where me.id=problem_id)'} = undef;
} elsif ($params->{site} eq 'emptyhomes' && $period eq '26 weeks') {
$q_params->{'(select max(whensent) from questionnaire where me.id=problem_id)'} = { '!=', undef };
} else {
$q_params->{'-or'} = [
'(select max(whensent) from questionnaire where me.id=problem_id)' => undef,
'(select max(whenanswered) from questionnaire where me.id=problem_id)' => { '<', \"ms_current_timestamp() - '$period'::interval" }
];
}
my $unsent = FixMyStreet::App->model('DB::Problem')->search( $q_params, {
order_by => { -desc => 'confirmed' }
} );
while (my $row = $unsent->next) {
my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new();
$cobrand->set_lang_and_domain($row->lang, 1);
# Cobranded and non-cobranded messages can share a database. In this case, the conf file
# should specify a vhost to send the reports for each cobrand, so that they don't get sent
# more than once if there are multiple vhosts running off the same database. The email_host
# call checks if this is the host that sends mail for this cobrand.
next unless $cobrand->email_host;
my $template;
if ($params->{site} eq 'emptyhomes') {
($template = $period) =~ s/ //;
$template = Utils::read_file( FixMyStreet->path_to( "templates/email/emptyhomes/" . $row->lang . "/questionnaire-$template.txt" )->stringify );
} else {
$template = FixMyStreet->path_to( "templates", "email", $cobrand->moniker, "questionnaire.txt" )->stringify;
$template = FixMyStreet->path_to( "templates", "email", "default", "questionnaire.txt" )->stringify
unless -e $template;
$template = Utils::read_file( $template );
}
my %h = map { $_ => $row->$_ } qw/name title detail category/;
$h{created} = Utils::prettify_duration( time() - $row->confirmed->epoch, 'week' );
my $questionnaire = FixMyStreet::App->model('DB::Questionnaire')->create( {
problem_id => $row->id,
whensent => \'ms_current_timestamp()',
} );
# We won't send another questionnaire unless they ask for it (or it was
# the first EHA questionnaire.
$row->send_questionnaire( 0 )
if $params->{site} ne 'emptyhomes' || $period eq '26 weeks';
my $token = FixMyStreet::App->model("DB::Token")->new_result( {
scope => 'questionnaire',
data => $questionnaire->id,
} );
$h{url} = $cobrand->base_url_for_emails($row->cobrand_data) . '/Q/' . $token->token;
my $sender = $cobrand->contact_email;
my $sender_name = _($cobrand->contact_name);
$sender =~ s/team/fms-DO-NOT-REPLY/;
print "Sending questionnaire " . $questionnaire->id . ", problem "
. $row->id . ", token " . $token->token . " to "
. $row->user->email . "\n"
if $params->{verbose};
my $result = FixMyStreet::App->send_email_cron(
{
_template_ => $template,
_parameters_ => \%h,
To => [ [ $row->user->email, $row->name ] ],
From => [ $sender, $sender_name ],
},
$sender,
[ $row->user->email ],
$params->{nomail}
);
if ($result == mySociety::EmailUtil::EMAIL_SUCCESS) {
print " ...success\n" if $params->{verbose};
$row->update();
$token->insert();
} else {
print " ...failed\n" if $params->{verbose};
$questionnaire->delete;
}
}
}
sub timeline {
my ( $rs, $restriction ) = @_;
return $rs->search(
{
-or => {
whenanswered => { '>=', \"ms_current_timestamp()-'7 days'::interval" },
'me.whensent' => { '>=', \"ms_current_timestamp()-'7 days'::interval" },
},
%{ $restriction },
},
{
-select => [qw/me.*/],
prefetch => [qw/problem/],
}
);
}
sub summary_count {
my ( $rs, $restriction ) = @_;
return $rs->search(
$restriction,
{
group_by => [ \'whenanswered is not null' ],
select => [ \'(whenanswered is not null)', { count => 'me.id' } ],
as => [qw/answered questionnaire_count/],
join => 'problem'
}
);
}
1;
|