+ # Remove dangling customer links, if any
+ my %target_pkey = ('cust_main' => 'custnum', 'cust_svc' => 'svcnum');
+ for my $table (keys %target_pkey) {
+ my $pkey = $target_pkey{$table};
+ my $rows = $dbh->do(
+ "DELETE FROM Links WHERE id IN(
+ SELECT id FROM (
+ SELECT Links.id FROM Links LEFT JOIN $table ON (Links.Target =
+ 'freeside://freeside/$table/' || $table.$pkey)
+ WHERE Links.Target like 'freeside://freeside/$table/%'
+ AND $table.$pkey IS NULL
+ ) AS x
+ )"
+ ) or die $dbh->errstr;
+ warn "Removed $rows dangling ticket-$table links\n" if $rows > 0;
+ }
+
+ # Fix ticket transactions on the Time* fields where the NewValue (or
+ # OldValue, though this is not known to happen) is an empty string
+ foreach (qw(newvalue oldvalue)) {
+ my $rows = $dbh->do(
+ "UPDATE Transactions SET $_ = '0' WHERE ObjectType='RT::Ticket' AND ".
+ "Field IN ('TimeWorked', 'TimeEstimated', 'TimeLeft') AND $_ = ''"
+ ) or die $dbh->errstr;
+ warn "Fixed $rows transactions with empty time values\n" if $rows > 0;
+ }
+
+ # One-time fix: We've created a "BulkUpdateTickets" access right; grant
+ # it to all auth'd users initially.
+ eval "use FS::upgrade_journal;";
+ my $upgrade = 'RT_add_BulkUpdateTickets_ACL';
+ if (!FS::upgrade_journal->is_done($upgrade)) {
+ my $groups = RT::Groups->new(RT->SystemUser);
+ $groups->LimitToEnabled;
+ $groups->LimitToSystemInternalGroups;
+ $groups->Limit(
+ FIELD => 'Name',
+ VALUE => 'Privileged',
+ OPERATOR => '=',
+ CASESENSITIVE => 0,
+ );
+ my $group = $groups->First
+ or die "No RT internal group found for Privileged users";
+ my ($val, $msg) = $group->PrincipalObj->GrantRight(
+ Right => 'BulkUpdateTickets', Object => RT->System
+ );
+ die "Couldn't grant BulkUpdateTickets right to all users: $msg\n"
+ if !$val;
+ FS::upgrade_journal->set_done($upgrade);
+ }