summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlevinse <levinse>2011-02-13 07:22:32 +0000
committerlevinse <levinse>2011-02-13 07:22:32 +0000
commite356f2ebb6564fe8d5333fc89bb4583ee3cd1fb1 (patch)
treeac286e1979c4aeecf41ea411fbba20b3aec555e9
parent5226903b423e42e7e8ee135b2b445d362241102a (diff)
bulk DID orders and inventory, RT11291
-rw-r--r--FS/FS.pm6
-rw-r--r--FS/FS/Mason.pm3
-rw-r--r--FS/FS/Record.pm6
-rw-r--r--FS/FS/Schema.pm41
-rw-r--r--FS/FS/did_order.pm166
-rw-r--r--FS/FS/did_vendor.pm121
-rw-r--r--FS/FS/lata.pm121
-rw-r--r--FS/FS/phone_avail.pm20
-rw-r--r--FS/MANIFEST6
-rwxr-xr-xFS/bin/freeside-lata-import80
-rw-r--r--FS/t/did_order.t5
-rw-r--r--FS/t/did_vendor.t5
-rw-r--r--FS/t/lata.t5
-rw-r--r--httemplate/browse/did_order.html65
-rw-r--r--httemplate/browse/did_vendor.html32
-rw-r--r--httemplate/edit/did_order.html46
-rw-r--r--httemplate/edit/did_vendor.html19
-rw-r--r--httemplate/edit/elements/edit.html5
-rw-r--r--httemplate/edit/process/did_order.html21
-rw-r--r--httemplate/edit/process/did_vendor.html11
-rw-r--r--httemplate/elements/menu.html3
-rw-r--r--httemplate/elements/tr-select-state.html19
-rw-r--r--httemplate/misc/phone_avail-import.html32
23 files changed, 829 insertions, 9 deletions
diff --git a/FS/FS.pm b/FS/FS.pm
index 8e78639..9a4fbce 100644
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -166,6 +166,12 @@ L<FS::part_device> - Device definition class
L<FS::phone_avail> - Phone number availability cache
+L<FS::lata> - LATA number to name mapping class
+
+L<FS::did_vendor> - Bulk DID order vendor class
+
+L<FS::did_order> - Bulk DID order class
+
L<FS::cdr> - Call Detail Record class
L<FS::cdr_batch> - Call Detail Record batch class
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index f628313..2a04ae5 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -266,6 +266,9 @@ if ( -e $addl_handler_use_file ) {
use FS::part_pkg_vendor;
use FS::cust_note_class;
use FS::svc_port;
+ use FS::lata;
+ use FS::did_vendor;
+ use FS::did_order;
# Sammath Naur
if ( $FS::Mason::addl_handler_use ) {
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm
index e23699c..fb83faa 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -1593,6 +1593,7 @@ sub process_batch_import {
params => { map { $_ => $param->{$_} } @pass_params },
#?
default_csv => $opt->{default_csv},
+ postinsert_callback => $opt->{postinsert_callback},
);
if ( $opt->{'batch_namecol'} ) {
@@ -1666,6 +1667,8 @@ sub batch_import {
my( $type, $header, $sep_char, $fixedlength_format,
$xml_format, $row_callback, @fields );
my $postinsert_callback = '';
+ $postinsert_callback = $param->{'postinsert_callback'}
+ if $param->{'postinsert_callback'};
if ( $param->{'format'} ) {
my $format = $param->{'format'};
@@ -1711,9 +1714,6 @@ sub batch_import {
$row_callback = '';
@fields = @{ $param->{'fields'} };
- $postinsert_callback = $param->{'postinsert_callback'}
- if $param->{'postinsert_callback'}
-
} else {
die "neither format nor fields specified";
}
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 040f6df..327c96c 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -3030,6 +3030,8 @@ sub tables_hashref {
'nxx', 'char', 'NULL', 3, '', '',
'station', 'char', 'NULL', 4, '', '',
'name', 'varchar', 'NULL', $char_d, '', '',
+ 'rate_center_abbrev', 'varchar', 'NULL', $char_d, '', '',
+ 'ordernum', 'int', 'NULL', '', '', '',
'svcnum', 'int', 'NULL', '', '', '',
'availbatch', 'varchar', 'NULL', $char_d, '', '',
],
@@ -3043,6 +3045,45 @@ sub tables_hashref {
[ 'availbatch' ],
],
},
+
+ 'lata' => {
+ 'columns' => [
+ 'latanum', 'int', '', '', '', '',
+ 'description', 'varchar', '', $char_d, '', '',
+ ],
+ 'primary_key' => 'latanum',
+ 'unique' => [],
+ 'index' => [],
+ },
+
+ 'did_vendor' => {
+ 'columns' => [
+ 'vendornum', 'serial', '', '', '', '',
+ 'vendorname', 'varchar', '', $char_d, '', '',
+ ],
+ 'primary_key' => 'vendornum',
+ 'unique' => [],
+ 'index' => [],
+ },
+
+ 'did_order' => {
+ 'columns' => [
+ 'ordernum', 'serial', '', '', '', '',
+ 'vendornum', 'int', '', '', '', '',
+ 'vendor_order_id', 'varchar', '', $char_d, '', '',
+ 'msa', 'varchar', 'NULL', $char_d, '', '',
+ 'latanum', 'int', 'NULL', '', '', '',
+ 'rate_center', 'varchar', 'NULL', $char_d, '', '',
+ 'state', 'char', 'NULL', 2, '', '',
+ 'quantity', 'int', '', '', '', '',
+ 'submitted', 'int', '', '', '', '',
+ 'confirmed', 'int', 'NULL', '', '', '',
+ 'received', 'int', 'NULL', '', '', '',
+ ],
+ 'primary_key' => 'ordernum',
+ 'unique' => [ [ 'vendornum', 'vendor_order_id' ] ],
+ 'index' => [],
+ },
'reason_type' => {
'columns' => [
diff --git a/FS/FS/did_order.pm b/FS/FS/did_order.pm
new file mode 100644
index 0000000..6b199a9
--- /dev/null
+++ b/FS/FS/did_order.pm
@@ -0,0 +1,166 @@
+package FS::did_order;
+
+use strict;
+use base qw( FS::Record );
+use FS::Record qw( qsearch qsearchs );
+
+=head1 NAME
+
+FS::did_order - Object methods for did_order records
+
+=head1 SYNOPSIS
+
+ use FS::did_order;
+
+ $record = new FS::did_order \%hash;
+ $record = new FS::did_order { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::did_order object represents a bulk DID order. FS::did_order inherits from
+FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item ordernum
+
+primary key
+
+=item vendornum
+
+vendornum
+
+=item vendor_order_id
+
+vendor_order_id
+
+=item msa
+
+msa
+
+=item latanum
+
+latanum
+
+=item rate_center
+
+rate_center
+
+=item state
+
+state
+
+=item quantity
+
+quantity
+
+=item submitted
+
+submitted
+
+=item confirmed
+
+confirmed
+
+=item received
+
+received
+
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new bulk DID order. To add it to the database, see L<"insert">.
+
+Note that this stores the hash reference, not a distinct copy of the hash it
+points to. You can ask the object for a copy with the I<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'did_order'; }
+
+=item insert
+
+Adds this record to the database. If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+# the insert method can be inherited from FS::Record
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# the delete method can be inherited from FS::Record
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database. If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+# the replace method can be inherited from FS::Record
+
+=item check
+
+Checks all fields to make sure this is a valid bulk DID order. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+ my $self = shift;
+
+ my $error =
+ $self->ut_numbern('ordernum')
+ || $self->ut_foreign_key('vendornum', 'did_vendor', 'vendornum' )
+ || $self->ut_text('vendor_order_id')
+ || $self->ut_textn('msa')
+ || $self->ut_foreign_keyn('latanum', 'lata', 'latanum')
+ || $self->ut_textn('rate_center')
+ || $self->ut_textn('state')
+ || $self->ut_number('quantity')
+ || $self->ut_number('submitted')
+ || $self->ut_numbern('confirmed')
+ || $self->ut_numbern('received')
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
diff --git a/FS/FS/did_vendor.pm b/FS/FS/did_vendor.pm
new file mode 100644
index 0000000..a108435
--- /dev/null
+++ b/FS/FS/did_vendor.pm
@@ -0,0 +1,121 @@
+package FS::did_vendor;
+
+use strict;
+use base qw( FS::Record );
+use FS::Record qw( qsearch qsearchs );
+
+=head1 NAME
+
+FS::did_vendor - Object methods for did_vendor records
+
+=head1 SYNOPSIS
+
+ use FS::did_vendor;
+
+ $record = new FS::did_vendor \%hash;
+ $record = new FS::did_vendor { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::did_vendor object represents a bulk DID vendor. FS::did_vendor inherits from
+FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item vendornum
+
+primary key
+
+=item vendorname
+
+vendorname
+
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new bulk DID vendor. To add it to the database, see L<"insert">.
+
+Note that this stores the hash reference, not a distinct copy of the hash it
+points to. You can ask the object for a copy with the I<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'did_vendor'; }
+
+=item insert
+
+Adds this record to the database. If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+# the insert method can be inherited from FS::Record
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# the delete method can be inherited from FS::Record
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database. If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+# the replace method can be inherited from FS::Record
+
+=item check
+
+Checks all fields to make sure this is a valid bulk DID vendor. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+ my $self = shift;
+
+ my $error =
+ $self->ut_numbern('vendornum')
+ || $self->ut_text('vendorname')
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
diff --git a/FS/FS/lata.pm b/FS/FS/lata.pm
new file mode 100644
index 0000000..7b42555
--- /dev/null
+++ b/FS/FS/lata.pm
@@ -0,0 +1,121 @@
+package FS::lata;
+
+use strict;
+use base qw( FS::Record );
+use FS::Record qw( qsearch qsearchs );
+
+=head1 NAME
+
+FS::lata - Object methods for lata records
+
+=head1 SYNOPSIS
+
+ use FS::lata;
+
+ $record = new FS::lata \%hash;
+ $record = new FS::lata { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::lata object represents a LATA number/name. FS::lata inherits from
+FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item latanum
+
+primary key
+
+=item description
+
+description
+
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new LATA. To add the LATA to the database, see L<"insert">.
+
+Note that this stores the hash reference, not a distinct copy of the hash it
+points to. You can ask the object for a copy with the I<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'lata'; }
+
+=item insert
+
+Adds this record to the database. If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+# the insert method can be inherited from FS::Record
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# the delete method can be inherited from FS::Record
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database. If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+# the replace method can be inherited from FS::Record
+
+=item check
+
+Checks all fields to make sure this is a valid LATA. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+ my $self = shift;
+
+ my $error =
+ $self->ut_numbern('latanum')
+ || $self->ut_text('description')
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
diff --git a/FS/FS/phone_avail.pm b/FS/FS/phone_avail.pm
index 0d59113..8bb6a5c 100644
--- a/FS/FS/phone_avail.pm
+++ b/FS/FS/phone_avail.pm
@@ -145,7 +145,10 @@ sub check {
|| $self->ut_numbern('nxx')
|| $self->ut_numbern('station')
|| $self->ut_foreign_keyn('svcnum', 'cust_svc', 'svcnum' )
+ || $self->ut_foreign_keyn('ordernum', 'did_order', 'ordernum' )
|| $self->ut_textn('availbatch')
+ || $self->ut_textn('name')
+ || $self->ut_textn('rate_center_abbrev')
;
return $error if $error;
@@ -187,8 +190,21 @@ sub process_batch_import {
};
my $opt = { 'table' => 'phone_avail',
- 'params' => [ 'availbatch', 'exportnum', 'countrycode' ],
- 'formats' => { 'default' => [ 'state', $numsub, 'name' ], },
+ 'params' => [ 'availbatch', 'exportnum', 'countrycode', 'ordernum' ],
+ 'formats' => { 'default' => [ 'state', $numsub, 'name' ],
+ 'bulk' => [ 'state', $numsub, 'name', 'rate_center_abbrev' ],
+ },
+ 'postinsert_callback' => sub {
+ my $record = shift;
+ if($record->ordernum) {
+ my $did_order = qsearchs('did_order',
+ { 'ordernum' => $record->ordernum } );
+ if($did_order && !$did_order->received) {
+ $did_order->received(time);
+ $did_order->replace;
+ }
+ }
+ },
};
FS::Record::process_batch_import( $job, $opt, @_ );
diff --git a/FS/MANIFEST b/FS/MANIFEST
index 7698462..553c5ec 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -559,3 +559,9 @@ t/h_svc_port.t
FS/cust_main/Status.pm
FS/NetworkMonitoringSystem.pm
FS/NetworkMonitoringSystem/Torrus_Internal.pm
+FS/lata.pm
+t/lata.t
+FS/did_vendor.pm
+t/did_vendor.t
+FS/did_order.pm
+t/did_order.t
diff --git a/FS/bin/freeside-lata-import b/FS/bin/freeside-lata-import
new file mode 100755
index 0000000..295b40e
--- /dev/null
+++ b/FS/bin/freeside-lata-import
@@ -0,0 +1,80 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Getopt::Std;
+use FS::UID qw(adminsuidsetup);
+use FS::Conf;
+use FS::Record qw(qsearch qsearchs dbh);
+use LWP::Simple;
+use HTML::TableExtract;
+use Data::Dumper;
+
+&untaint_argv; #what it sounds like (eww)
+use vars qw(%opt);
+
+my $user = shift or die &usage;
+my $dbh = adminsuidsetup $user;
+
+my $content = get("http://www.localcallingguide.com/lca_listlata.php");
+my $te = new HTML::TableExtract();
+$te->parse($content);
+my $table = $te->first_table_found;
+my $sql = 'insert into lata (latanum, description) values ';
+my @sql;
+foreach my $row ( $table->rows ) {
+ my @row = @$row;
+ next unless $row[0] =~ /\d+/;
+ $row[1] =~ s/'//g;
+ push @sql, "( ${row[0]}, '${row[1]}')";
+}
+$sql .= join(',',@sql);
+
+my $sth = $dbh->prepare('delete from lata');
+$sth->execute or die $sth->errstr;
+
+$sth = $dbh->prepare($sql);
+$sth->execute or die $sth->errstr;
+
+$dbh->commit;
+
+###
+# subroutines
+###
+
+sub untaint_argv {
+ foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
+ #$ARGV[$_] =~ /^([\w\-\/]*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
+ # Date::Parse
+ $ARGV[$_] =~ /^(.*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
+ $ARGV[$_]=$1;
+ }
+}
+
+sub usage {
+ die "Usage:\n freeside-lata-import user \n";
+}
+
+###
+# documentation
+###
+
+=head1 NAME
+
+freeside-lata-import - Pull LATA data from and insert into LATA table
+
+=head1 SYNOPSIS
+
+ freeside-lata-import user
+
+=head1 DESCRIPTION
+
+user - name of an internal Freeside user
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::lata>
+
+=cut
+
diff --git a/FS/t/did_order.t b/FS/t/did_order.t
new file mode 100644
index 0000000..ae58719
--- /dev/null
+++ b/FS/t/did_order.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::did_order;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/did_vendor.t b/FS/t/did_vendor.t
new file mode 100644
index 0000000..b8df3ee
--- /dev/null
+++ b/FS/t/did_vendor.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::did_vendor;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/lata.t b/FS/t/lata.t
new file mode 100644
index 0000000..a70c3cb
--- /dev/null
+++ b/FS/t/lata.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::lata;
+$loaded=1;
+print "ok 1\n";
diff --git a/httemplate/browse/did_order.html b/httemplate/browse/did_order.html
new file mode 100644
index 0000000..54c2bd3
--- /dev/null
+++ b/httemplate/browse/did_order.html
@@ -0,0 +1,65 @@
+<% include( 'elements/browse.html',
+ 'title' => 'Bulk DID Orders',
+ 'html_init' => $html_init,
+ 'name' => 'bulk DID orders',
+ 'disableable' => 0,
+ 'query' => { 'table' => 'did_order',
+ 'addl_from' => 'left join did_vendor using (vendornum)
+ left join lata using (latanum)',
+ 'hashref' => {},
+ 'order_by' => 'ORDER BY ordernum',
+ },
+ 'count_query' => $count_query,
+ 'header' => $header,
+ 'fields' => $fields,
+ 'links' => $links,
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Import');
+
+my $conf = new FS::Conf;
+my $date_format = $conf->config('date_format') || '%m/%d/%Y';
+
+my $html_init =
+ qq!<A HREF="${p}edit/did_order.html"><I>Add a bulk DID order</I></A><BR><BR>!;
+
+my $count_query = 'SELECT COUNT(*) FROM did_order';
+
+my $link = [ $p.'edit/did_order.html?', 'ordernum' ];
+
+my $display_date = sub {
+ my $date = shift;
+ return '' unless $date;
+ time2str($date_format, $date);
+};
+
+my $header = [ '#', 'Vendor',' Vendor Order #', 'MSA', 'LATA #', 'LATA',
+ 'Rate Center', 'State', 'Quantity', 'Submitted', 'Confirmed',
+ 'Received',
+ ];
+my $links = [ ];
+my $fields = [ sub {
+ my $did_order = shift;
+ if($did_order->received) {
+ push @$links, $link;
+ }
+ else {
+ return $did_order->ordernum;
+ }
+ }, 'vendorname', 'vendor_order_id', 'msa', 'latanum',
+ 'description', 'rate_center', 'state', 'quantity',
+ sub { &$display_date(shift->submitted); },
+ sub { &$display_date(shift->confirmed); },
+ sub {
+ my $did_order = shift;
+ my $ordernum = $did_order->ordernum;
+ return &$display_date($did_order->received)
+ if $did_order->received;
+ "<A HREF='${p}misc/phone_avail-import.html?ordernum=$ordernum'>Upload Received</A>";
+ },
+ ];
+
+</%init>
diff --git a/httemplate/browse/did_vendor.html b/httemplate/browse/did_vendor.html
new file mode 100644
index 0000000..04904ec
--- /dev/null
+++ b/httemplate/browse/did_vendor.html
@@ -0,0 +1,32 @@
+<% include( 'elements/browse.html',
+ 'title' => 'Bulk DID Vendors',
+ 'html_init' => $html_init,
+ 'name' => 'bulk DID vendors',
+ 'disableable' => 0,
+ 'query' => { 'table' => 'did_vendor',
+ 'hashref' => {},
+ 'order_by' => 'ORDER BY vendornum',
+ },
+ 'count_query' => $count_query,
+ 'header' => $header,
+ 'fields' => $fields,
+ 'links' => $links,
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+my $html_init =
+ qq!<A HREF="${p}edit/did_vendor.html"><I>Add a bulk DID vendor</I></A><BR><BR>!;
+
+my $count_query = 'SELECT COUNT(*) FROM did_vendor';
+
+my $link = [ $p.'edit/did_vendor.html?', 'vendornum' ];
+
+my $header = [ '#', 'Vendor' ];
+my $fields = [ 'vendornum', 'vendorname' ];
+my $links = [ $link, $link ];
+
+</%init>
diff --git a/httemplate/edit/did_order.html b/httemplate/edit/did_order.html
new file mode 100644
index 0000000..ac8f336
--- /dev/null
+++ b/httemplate/edit/did_order.html
@@ -0,0 +1,46 @@
+<% include( 'elements/edit.html',
+ 'fields' => [
+ { field => 'vendornum',
+ type => 'select-table',
+ name_col => 'vendorname',
+ table => 'did_vendor',
+ disable_empty => 1,
+ },
+ 'vendor_order_id',
+ 'msa',
+ { field => 'latanum',
+ type => 'select-table',
+ name_col => 'description',
+ table => 'lata',
+ disable_empty => 1,
+ label_showkey => 1,
+ },
+ 'rate_center',
+ { field => 'state',
+ type => 'select-state',
+ country => 'US',
+ },
+ 'quantity',
+ { field => 'confirmed',
+ type => 'input-date-field',
+ },
+ ],
+ 'labels' => {
+ 'vendornum' => 'Vendor',
+ 'vendor_order_id' => 'Vendor Order #',
+ 'msa' => 'MSA',
+ 'latanum' => 'LATA',
+ 'rate_center' => 'Rate Center',
+ },
+ 'viewall_dir' => 'browse',
+ 'table' => 'did_order',
+ 'name' => 'Bulk DID Order',
+ )
+
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Import');
+
+</%init>
diff --git a/httemplate/edit/did_vendor.html b/httemplate/edit/did_vendor.html
new file mode 100644
index 0000000..b6d57b5
--- /dev/null
+++ b/httemplate/edit/did_vendor.html
@@ -0,0 +1,19 @@
+<% include( 'elements/edit.html',
+ 'fields' => [
+ 'vendorname',
+ ],
+ 'labels' => {
+ 'vendorname' => 'Vendor name',
+ },
+ 'viewall_dir' => 'browse',
+ 'table' => 'did_vendor',
+ 'name' => 'Bulk DID Vendor',
+ )
+
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html
index cab5167..b0c27e6 100644
--- a/httemplate/edit/elements/edit.html
+++ b/httemplate/edit/elements/edit.html
@@ -316,6 +316,11 @@ Example:
% foreach grep exists($f->{$_}),
% qw( formatted_value );
%
+% # select-country
+% $include_common{$_} = $f->{$_}
+% foreach grep exists($f->{$_}),
+% qw( country );
+%
% #htmlarea
% $include_common{$_} = $f->{$_}
% foreach grep exists($f->{$_}), qw( width height );
diff --git a/httemplate/edit/process/did_order.html b/httemplate/edit/process/did_order.html
new file mode 100644
index 0000000..0c9a3f0
--- /dev/null
+++ b/httemplate/edit/process/did_order.html
@@ -0,0 +1,21 @@
+<% include( 'elements/process.html',
+ 'table' => 'did_order',
+ 'viewall_dir' => 'browse',
+ 'value_callback' => $value_callback,
+ )
+%>
+<%init>
+
+unless($cgi->param('submitted')) {
+ $cgi->param('submitted',time);
+}
+
+my $value_callback = sub {
+ my ($field, $value) = @_;
+ ($field =~ /ed$/ && $value !~ /^\d+$/) ? parse_datetime($value) : $value;
+};
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Import');
+
+</%init>
diff --git a/httemplate/edit/process/did_vendor.html b/httemplate/edit/process/did_vendor.html
new file mode 100644
index 0000000..891a453
--- /dev/null
+++ b/httemplate/edit/process/did_vendor.html
@@ -0,0 +1,11 @@
+<% include( 'elements/process.html',
+ 'table' => 'did_vendor',
+ 'viewall_dir' => 'browse',
+ )
+%>
+<%init>
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+
+</%init>
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html
index 710850c..651b04d 100644
--- a/httemplate/elements/menu.html
+++ b/httemplate/elements/menu.html
@@ -380,6 +380,8 @@ $tools_menu{'Process payment batches'} = [ $fsurl.'search/pay_batch.cgi?magic=_d
&& $curuser->access_right('Process batches');
$tools_menu{'Download invoice batches'} = [ $fsurl.'search/bill_batch.cgi' ]
if $conf->exists('invoice_print_pdf');
+$tools_menu{'Bulk DID Orders'} = [ $fsurl.'browse/did_order.html', 'View/manage bulk DID orders' ]
+ if $curuser->access_right('Import');
$tools_menu{'Job Queue'} = [ $fsurl.'search/queue.html', 'View pending job queue' ]
if $curuser->access_right('Job queue');
$tools_menu{'Ticketing'} = [ \%tools_ticketing, 'Ticketing tools' ]
@@ -496,6 +498,7 @@ tie my %config_broadband, 'Tie::IxHash',
tie my %config_phone, 'Tie::IxHash',
'View/Edit phone device types' => [ $fsurl.'browse/part_device.html', 'Phone device types' ],
+ 'View/Edit bulk DID vendors' => [ $fsurl.'browse/did_vendor.html', 'Bulk DID vendors' ],
;
tie my %config_misc, 'Tie::IxHash';
diff --git a/httemplate/elements/tr-select-state.html b/httemplate/elements/tr-select-state.html
new file mode 100644
index 0000000..1a62ae5
--- /dev/null
+++ b/httemplate/elements/tr-select-state.html
@@ -0,0 +1,19 @@
+% unless ( $opt{'js_only'} ) {
+ <% include('tr-td-label.html', @_ ) %>
+
+ <TD <% $style %>>
+% }
+
+ <% include( '/elements/select-state.html', %opt ) %>
+
+% unless ( $opt{'js_only'} ) {
+ </TD>
+ </TR>
+% }
+<%init>
+
+my %opt = @_;
+
+my $style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : '';
+
+</%init>
diff --git a/httemplate/misc/phone_avail-import.html b/httemplate/misc/phone_avail-import.html
index c664c07..fcbfcc3 100644
--- a/httemplate/misc/phone_avail-import.html
+++ b/httemplate/misc/phone_avail-import.html
@@ -7,7 +7,7 @@ Import a file containing phone numbers (DIDs).
'name' => 'PhonenumImportForm',
'action' => 'process/phone_avail-import.html',
'num_files' => 1,
- 'fields' => [ 'format', 'availbatch', 'exportnum', 'countrycode' ],
+ 'fields' => [ 'format', 'availbatch', 'exportnum', 'countrycode', 'ordernum' ],
'message' => 'DID import successful',
'url' => $p."search/phone_avail.html?availbatch=$availbatch",
)
@@ -15,10 +15,22 @@ Import a file containing phone numbers (DIDs).
<% &ntable("#cccccc", 2) %>
- <INPUT TYPE="hidden" NAME="format" VALUE="default">
<INPUT TYPE="hidden" NAME="availbatch" VALUE="<% $availbatch %>">
+% if ( $ordernum ) {
+ <TR>
+ <TD ALIGN="RIGHT">Bulk DID Order #</TD>
+ <TD><% $ordernum %>
+ <INPUT TYPE="hidden" NAME="ordernum" VALUE="<% $ordernum %>">
+ </TD>
+ </TR>
+% }
+ <TR>
+ <TD ALIGN="RIGHT">Import Format</TD>
+ <TD><% $format %><INPUT TYPE="hidden" NAME="format" VALUE="<% $format %>"></TD>
+ </TR>
+
<% include( '/elements/tr-select-table.html',
'table' => 'part_export',
'name_col' => 'label',
@@ -65,15 +77,18 @@ Import a file containing phone numbers (DIDs).
Uploaded files can be CSV (comma-separated value) files or Excel spreadsheets. The file should have a .CSV or .XLS extension.
<BR><BR>
-<b>Default</b> format has the following field order: <i>state, number, name</i>
+<b>Default</b> format has the following field order: <i>state, number, name</i><br>
+<b>Bulk</b> format has the following field order: <i>state, number, rate center, rate_center_abbrev</i>
<BR><BR>
-
Field information:
<ul>
<li><i>state</i>: Two-letter state code, i.e. "CA"
<li><i>number</i>: Phone number
<li><i>name</i>: optional, rate center
+ <li><i>rate center</i>: rate center (required)
+ <li><i>rate_center_abbrev</i>: rate center abbreviation
</ul>
+<BR><BR>
<% include('/elements/footer.html') %>
@@ -84,6 +99,15 @@ die "access denied"
my $conf = new FS::Conf;
+my $ordernum = $cgi->param('ordernum');
+$ordernum = '' unless $ordernum =~ /^\d+$/;
+
+die 'invalid ordernum'
+ unless (!$ordernum || qsearchs('did_order', { 'ordernum' => $ordernum }));
+
+my $format = 'default';
+$format = 'bulk' if $ordernum;
+
my $availbatch =
time2str('webimport-%Y/%m/%d-%T'. "-$$-". rand() * 2**32, time);