From 705719c34352808839deb2f7fb9c420fd1baf3c8 Mon Sep 17 00:00:00 2001 From: levinse Date: Sun, 13 Feb 2011 07:23:42 +0000 Subject: [PATCH] bulk DID orders and inventory, RT11291 --- FS/FS.pm | 6 ++ FS/FS/Mason.pm | 3 + FS/FS/Record.pm | 6 +- FS/FS/Schema.pm | 41 ++++++++ FS/FS/did_order.pm | 166 +++++++++++++++++++++++++++++++ FS/FS/did_vendor.pm | 121 ++++++++++++++++++++++ FS/FS/lata.pm | 121 ++++++++++++++++++++++ FS/FS/phone_avail.pm | 20 +++- FS/MANIFEST | 6 ++ FS/bin/freeside-lata-import | 80 +++++++++++++++ FS/t/did_order.t | 5 + FS/t/did_vendor.t | 5 + FS/t/lata.t | 5 + httemplate/browse/did_order.html | 65 ++++++++++++ httemplate/browse/did_vendor.html | 32 ++++++ httemplate/edit/did_order.html | 46 +++++++++ httemplate/edit/did_vendor.html | 19 ++++ httemplate/edit/elements/edit.html | 5 + httemplate/edit/process/did_order.html | 21 ++++ httemplate/edit/process/did_vendor.html | 11 ++ httemplate/elements/menu.html | 3 + httemplate/elements/tr-select-state.html | 19 ++++ httemplate/misc/phone_avail-import.html | 32 +++++- 23 files changed, 829 insertions(+), 9 deletions(-) create mode 100644 FS/FS/did_order.pm create mode 100644 FS/FS/did_vendor.pm create mode 100644 FS/FS/lata.pm create mode 100755 FS/bin/freeside-lata-import create mode 100644 FS/t/did_order.t create mode 100644 FS/t/did_vendor.t create mode 100644 FS/t/lata.t create mode 100644 httemplate/browse/did_order.html create mode 100644 httemplate/browse/did_vendor.html create mode 100644 httemplate/edit/did_order.html create mode 100644 httemplate/edit/did_vendor.html create mode 100644 httemplate/edit/process/did_order.html create mode 100644 httemplate/edit/process/did_vendor.html create mode 100644 httemplate/elements/tr-select-state.html diff --git a/FS/FS.pm b/FS/FS.pm index af35d9602..db26204d0 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -162,6 +162,12 @@ L - Device definition class L - Phone number availability cache +L - LATA number to name mapping class + +L - Bulk DID order vendor class + +L - Bulk DID order class + L - Call Detail Record class L - Call Detail Record batch class diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index b66dc8cee..53b98610f 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -259,6 +259,9 @@ if ( -e $addl_handler_use_file ) { use FS::part_pkg_discount; use FS::svc_cert; use FS::cust_note_class; + 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 2e2612e35..33a3609d9 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -1591,6 +1591,7 @@ sub process_batch_import { params => { map { $_ => $param->{$_} } @pass_params }, #? default_csv => $opt->{default_csv}, + postinsert_callback => $opt->{postinsert_callback}, ); if ( $opt->{'batch_namecol'} ) { @@ -1664,6 +1665,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'}; @@ -1709,9 +1712,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 a7f0bfacc..42153bff6 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2839,6 +2839,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, '', '', ], @@ -2852,6 +2854,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 000000000..6b199a969 --- /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 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, 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 000000000..a10843515 --- /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 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, 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 000000000..7b425550c --- /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 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, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/phone_avail.pm b/FS/FS/phone_avail.pm index 0d591138c..8bb6a5cc3 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 58728e4b0..16c717b27 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -543,3 +543,9 @@ t/svc_cert.t FS/cust_main/Status.pm FS/cust_note_class.pm t/cust_note_class.t +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 000000000..295b40e0b --- /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 + +=cut + diff --git a/FS/t/did_order.t b/FS/t/did_order.t new file mode 100644 index 000000000..ae58719bd --- /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 000000000..b8df3ee66 --- /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 000000000..a70c3cbe4 --- /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 000000000..54c2bd3fc --- /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!Add a bulk DID order

!; + +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; + "Upload Received"; + }, + ]; + + diff --git a/httemplate/browse/did_vendor.html b/httemplate/browse/did_vendor.html new file mode 100644 index 000000000..04904ec63 --- /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!Add a bulk DID vendor

!; + +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 ]; + + diff --git a/httemplate/edit/did_order.html b/httemplate/edit/did_order.html new file mode 100644 index 000000000..ac8f336d4 --- /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'); + + diff --git a/httemplate/edit/did_vendor.html b/httemplate/edit/did_vendor.html new file mode 100644 index 000000000..b6d57b548 --- /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'); + + diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html index 89f0fcc4c..6d88e5d58 100644 --- a/httemplate/edit/elements/edit.html +++ b/httemplate/edit/elements/edit.html @@ -311,6 +311,11 @@ Example: % foreach grep exists($f->{$_}), % qw( hashref agent_virt agent_null agent_null_right ); % +% # 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 000000000..0c9a3f0e0 --- /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'); + + diff --git a/httemplate/edit/process/did_vendor.html b/httemplate/edit/process/did_vendor.html new file mode 100644 index 000000000..891a45392 --- /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'); + + diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index a981abd87..ae58cdaaa 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 000000000..1a62ae561 --- /dev/null +++ b/httemplate/elements/tr-select-state.html @@ -0,0 +1,19 @@ +% unless ( $opt{'js_only'} ) { + <% include('tr-td-label.html', @_ ) %> + + > +% } + + <% include( '/elements/select-state.html', %opt ) %> + +% unless ( $opt{'js_only'} ) { + + +% } +<%init> + +my %opt = @_; + +my $style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : ''; + + diff --git a/httemplate/misc/phone_avail-import.html b/httemplate/misc/phone_avail-import.html index c664c0726..fcbfcc398 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) %> - +% if ( $ordernum ) { + + Bulk DID Order # + <% $ordernum %> + + + +% } + + Import Format + <% $format %> + + <% 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.

-Default format has the following field order: state, number, name +Default format has the following field order: state, number, name
+Bulk format has the following field order: state, number, rate center, rate_center_abbrev

- Field information:
  • state: Two-letter state code, i.e. "CA"
  • number: Phone number
  • name: optional, rate center +
  • rate center: rate center (required) +
  • rate_center_abbrev: rate center abbreviation
+

<% 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); -- 2.11.0