default to a session cookie instead of setting an explicit timeout, weird timezone...
[freeside.git] / FS / bin / freeside-censustract-update
1 #!/usr/bin/perl
2
3 use strict;
4 use Getopt::Std;
5 use Date::Parse 'str2time';
6 use FS::UID qw(adminsuidsetup);
7 use FS::Record qw(qsearch dbh);
8 use FS::Conf;
9 use FS::cust_location;
10 use FS::h_cust_location;
11
12 my %opt;
13 getopts('d:', \%opt);
14
15 my $user = shift or die &usage;
16 adminsuidsetup($user);
17 $FS::UID::AutoCommit = 0;
18 my $dbh = dbh;
19
20 my $conf = FS::Conf->new;
21 my $current_year = $conf->config('census_legacy') || '2020';
22 my $date = str2time($opt{d}) if $opt{d};
23 $date ||= time;
24 # This now operates on cust_location, not cust_main.
25 # Find all locations that, as of $date, did not have 
26 # censusyear = the current year.  This includes those 
27 # that have no censusyear.
28 local($FS::Record::qsearch_qualify_columns) = 0;
29 my %h_cust_location = map { $_->locationnum => $_ }
30   qsearch(
31     'h_cust_location',
32     { censusyear => { op => '!=', value => $current_year } },
33     FS::h_cust_location->sql_h_search($date),
34   ) ;
35
36 # Find all locations that don't have censusyear = the current
37 # year as of now.
38 my @cust_location = qsearch({
39      'table'     => 'cust_location',
40      'hashref'   => { 'country' => 'US', },
41      'extra_sql' => " AND (    censusyear  != '$current_year'
42                             OR censustract IS NULL
43                           )
44                     ",
45 });
46
47 warn scalar(@cust_location)." records found.\n";
48 my $queued = 0; my $updated = 0;
49 foreach my $cust_location (@cust_location) {
50   my $error;
51   my $h = $h_cust_location{$cust_location->locationnum};
52   if ( defined($h) and $h->censustract eq $cust_location->censustract ) {
53     # Then the location's censustract hasn't been changed since $date
54     # (or it didn't exist on $date, or $date is now).  Queue a censustract 
55     # update for it.
56     my $job = FS::queue->new({
57         job => 'FS::cust_location::process_censustract_update'
58     });
59     $error = $job->insert($cust_location->locationnum);
60     $queued++;
61   }
62   elsif ($cust_location->censusyear eq '') {
63     # Then it's been updated since $date, but somehow has a null censusyear.
64     # (Is this still relevant?)
65     $cust_location->set('censusyear', $current_year);
66     $error = $cust_location->replace;
67     $updated++;
68   } # Else it's been updated since $date, so leave it alone.
69   if ( $error ) {
70     $dbh->rollback;
71     die "error updating ".$cust_location->locationnum.": $error\n";
72   }
73 }
74 warn "Queued $queued census code lookups, updated year in $updated records.\n";
75 $dbh->commit;
76
77 sub usage {
78     "Usage:\n\n  freeside-censustract-update [ -d date ] user\n\n"
79   }
80
81 =head1 NAME
82
83 freeside-censustract-update - Update census tract codes to the current year.
84
85 =head1 SYNOPSIS
86
87   freeside-censustract-update [ -d date ] user
88
89 =head1 DESCRIPTION
90
91 Finds all customers whose census tract codes don't appear to be current 
92 and updates them to the current year.  The "current year" is 2020, unless the
93 I<census_legacy> configuration variable is set.
94
95 The -d option tells the script to assume that tract codes last modified
96 after some date are already current.  Those customers will just have 
97 their 'censusyear' field set to the current year.  For all other 
98 customers with non-current censusyear values, the current tract code 
99 will be looked up externally and stored in the censustract field.
100
101 The actual tract code lookup runs from the job queue, because it's slow.
102 A separate job will be created for each customer.
103
104 =cut