work around missing id, RT#83146
[freeside.git] / FS / bin / freeside-svcbroadband_update_speeds
1 #!/usr/bin/perl
2
3 use strict;
4 use Getopt::Std;
5 use FS::UID qw(adminsuidsetup);
6 use FS::Record qw(qsearch qsearchs);
7 use FS::svc_broadband;
8 use Data::Dumper;
9
10 ###
11 # parse command line
12 ###
13
14 use vars qw( $opt_h $opt_v $opt_n $opt_e $opt_a $opt_s $opt_c $opt_r $opt_p $opt_t $opt_d );
15 getopts('hvneas:c:r:pt:d:');
16
17 my $user = shift or die &usage;
18 adminsuidsetup $user;
19
20 sub usage { "
21   Usage:
22       freeside-svcbroadband_update_speeds: [ -h help] [ -v verbose] [ -n only update services with a null up/down speed] [ -e export service ] [ -a update tower_sector_num ] [ -s service_part_num (required) ] [ -c sibling service_part_num ] [ -r (speed rate in KB 'up,down') ] [ -p (get speed from package fcc rate) ] [ -t tower_sector_num ] [ -d directory for exception file (required) ] user (required)\n
23       A directory for the exception file, freeside user name and a service to update is required.\n
24       Must set one or more of options p, c, or r. \n
25       Also must run this report as user freeside.\n
26       Option r up and down speed seperated by a comma in kbps.
27       Getting speed from option p (package fcc rates) first if set, if no rates found then checks for option c (rate of sibling service) if set, if still no rates found checks for rate in option r if set.  If no rates found service will be placed in exception file.
28       Option a will update tower/sector with that of sibling service if tower sector is null.
29       If option t is set, svc tower/sector will be set to sibling service set in -c, if no sibling service tower/sector found will set tower_sector to option t value.  This will only update services with a null tower/sector field.
30       By default serivce will not export if there is a export assigned to service.  Setting option e will perform the export.
31 " }
32
33 unless ($opt_d && $opt_s) { die &usage(); }
34 if ($opt_h) { die &usage(); }
35 unless ($opt_p || $opt_c || $opt_r) { die &usage(); }
36
37 my $exception_file = "$opt_d/svcbroadband_update_exceptions_".time().".txt";
38
39 ### get list of all provisioned services
40 my $only_null_speed_services = " AND (svc_broadband.speed_up IS NULL OR svc_broadband.speed_down IS NULL)" if $opt_n;
41 my $extra_sql = " WHERE cust_svc.svcpart = $opt_s $only_null_speed_services";
42 my @services = qsearch({
43     'select'    => 'svc_broadband.*, cust_svc.svcpart, cust_svc.pkgnum, cust_pkg.pkgpart',
44     'table'     => 'svc_broadband',
45     'addl_from' => 'LEFT JOIN cust_svc USING ( svcnum ) LEFT JOIN cust_pkg USING (pkgnum)',
46     'extra_sql' => $extra_sql,
47 });
48
49 ### get list of all unprovisioned services
50 #my $ups_extra_sql = "where cust_pkg.cancel is null and pkg_svc.quantity > 0 and  pkg_svc.quantity > (select count(1) from cust_svc where  cust_svc.pkgnum = cust_pkg.pkgnum and  cust_svc.svcpart = pkg_svc.svcpart)  and pkg_svc.svcpart = $opt_s";
51 #my @unprovisioned_services = qsearch({
52 #    'table'     => 'cust_pkg',
53 #    'addl_from' => 'JOIN pkg_svc using (pkgpart)',
54 #    'extra_sql' => $ups_extra_sql,
55 #});
56
57 my $speed;
58 $speed = 'package' if $opt_p;
59
60 foreach my $svc (@services) {
61   _update_service($svc, $exception_file);
62 }
63
64 sub _update_service {
65   my $service = shift;
66   my $exception_file = shift;
67   my $speed_up;
68   my $speed_down;
69
70   my $package = qsearchs({
71      'table'     => 'part_pkg',
72      'hashref'   => { 'pkgpart' => $service->pkgpart, },
73   });
74
75   ## get speed from package fcc option first if option p
76   if ($opt_p) {
77         warn ("Getting speed for service ".$service->description."(".$service->svcnum.") from package fcc info\n") if $opt_v;
78      $speed_up = $package->fcc_option('broadband_upstream') * 1000;
79      $speed_down = $package->fcc_option('broadband_downstream') * 1000;
80   }
81
82   ## if no fcc option get speed from sibling broadband service if option c
83   if ((!$speed_up || !$speed_down) && $opt_c) {
84         warn ("Getting speed for service ".$service->description."(".$service->svcnum.") from sibling service of package ".$service->pkgnum) if $opt_v;
85      my $sibling_service = qsearchs({
86        'select'    => 'svc_broadband.*, cust_svc.svcpart',
87        'table'     => 'svc_broadband',
88        'addl_from' => ' LEFT JOIN cust_svc USING ( svcnum )',
89        'extra_sql' => ' WHERE cust_svc.pkgnum = '.$service->pkgnum.' AND cust_svc.svcpart = '.$opt_c.' AND (svc_broadband.speed_up IS NOT NULL AND svc_broadband.speed_down IS NOT NULL)',
90      });
91      $speed_up = $sibling_service->speed_up if $sibling_service;
92      $speed_down = $sibling_service->speed_down if $sibling_service;
93   }
94      
95   ## if no fcc options and no speed from sibling service than get speed from option r if option r is set.
96   if ((!$speed_up || !$speed_down) && $opt_r) {
97         warn ("Getting speed for service ".$service->description."(".$service->svcnum.") from option r ($opt_r)\n") if $opt_v;
98      ($speed_up, $speed_down) = split /\,/, $opt_r;
99      warn ("Option r speeds not correct.  Must be in kbps up and down seperated by comma. [ -r xxxxxx,xxxxxx ]\n") if $opt_v && (!$speed_up || !$speed_down);
100   }
101
102   if ($speed_up && $speed_down) {
103     $service->set('speed_up', $speed_up);
104     $service->set('speed_down', $speed_down);
105   }
106
107   ## if option t, then update tower/sector for service.
108   if ($opt_a) {
109     warn ("Getting tower/sector for service ".$service->description."(".$service->svcnum.") from sibling service of package ".$service->pkgnum) if $opt_v;
110     my $tower_sector;
111     my $sibling_service = qsearchs({
112        'select'    => 'svc_broadband.*, cust_svc.svcpart',
113        'table'     => 'svc_broadband',
114        'addl_from' => ' LEFT JOIN cust_svc USING ( svcnum )',
115        'extra_sql' => ' WHERE cust_svc.pkgnum = '.$service->pkgnum.' AND cust_svc.svcpart = '.$opt_c.' AND svc_broadband.sectornum IS NOT NULL',
116     }) if $opt_c;
117     $tower_sector = $sibling_service->sectornum if $sibling_service;
118     $tower_sector = $opt_t if (!$tower_sector && $opt_t);
119     $service->set('sectornum', $tower_sector) if $tower_sector;
120   }
121
122   ## update service with new speed and tower/sector num.
123   if ($service->speed_up && $service->speed_down && $service->sectornum) {
124     warn("updating service ".$service->description."(".$service->svcnum.") with upload speed (".$service->speed_up.") and download speed (".$service->speed_down.") and sector num (".$service->sectornum.")\n") if $opt_v;
125     $service->set('no_export', $opt_e);
126     my $error = $service->replace();
127     warn($error) if $error;
128     ###todo: if no error provision service if not provisioned ie new svc_broadband.
129   }
130   else {
131     my $error;
132     $error .= " no download speed set," unless $service->speed_down;
133     $error .= " no upload speed set," unless $service->speed_up;
134     $error .= " no tower sector set" unless $service->sectornum;
135
136     open(FILE, ">>$exception_file")
137       or die "can't open $opt_d: $!";
138       print FILE "Service ".$service->description."(".$service->svcnum.") could not be updated.$error.\n";
139     close FILE or die "can't close $opt_d: $!";
140     warn("Service ".$service->description."(".$service->svcnum.") could not be updated.$error. added to exception file.\n") if $opt_v;
141   }
142   return;
143 }
144
145 exit;
146
147 =head2 freeside-svcbroadband_update_speeds
148
149 This script allows for the mas update of up and down speeds for a svc_broadband service.
150
151 the script will obtain the new speed from option p (package fcc rates) first if set, 
152 if no rates found then checks for option c (rate of sibling service) if set, 
153 if still no rates found checks for rate in option r if set.  
154 If no rates found service will be placed in exception file.
155
156 If option a is set, will also update tower/sector num with that of sibling service or option t
157
158 Script must be run as user freeside.
159 Options -s, -d and freeside user are required.
160
161 example:
162 sudo -u freeside ./freeside-svcbroadband_update_speeds -v -s 4 -c 2 -r 148000,248000 -p -d /home/freeside/ freesideuser
163
164 available options:
165 [ -h help]
166 [ -v verbose]
167 [ -n only update services with a null up/down speed]
168 [ -e export service ]
169 [ -a update tower_sector_num ]
170 [ -s service_part_num (required) ]
171 [ -c sibling service_part_num ]
172 [ -r (speed rate in KB 'up,down') ]
173 [ -p (get speed from package fcc rate) ]
174 [ -t tower_sector_num ]
175 [ -d directory for exception file (required) ]
176 freesideuser
177
178 =cut