aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm
blob: 80f62f495cdd682da9bf5e851c979497e8b97518 (plain)
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
package FixMyStreet::DB::ResultSet::Questionnaire;
use base 'DBIx::Class::ResultSet';

use strict;
use warnings;
use File::Slurp;
use Page;
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 => [ 'confirmed', 'fixed' ],
        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 = File::Slurp::read_file( FixMyStreet->path_to( "templates/email/emptyhomes/" . $row->lang . "/questionnaire-$template.txt" )->stringify );
        } else {
            $template = File::Slurp::read_file( FixMyStreet->path_to( "templates/email/" . $cobrand->moniker . "/questionnaire.txt" )->stringify );
        }

        my %h = map { $_ => $row->$_ } qw/name title detail category/;
        $h{created} = Page::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;
        }
    }
}

1;