diff options
| -rw-r--r-- | FS/FS.pm | 2 | ||||
| -rw-r--r-- | FS/FS/Mason.pm | 1 | ||||
| -rw-r--r-- | FS/FS/Schema.pm | 22 | ||||
| -rw-r--r-- | FS/FS/did_order.pm | 43 | ||||
| -rw-r--r-- | FS/FS/did_order_item.pm | 150 | ||||
| -rw-r--r-- | FS/FS/phone_avail.pm | 7 | ||||
| -rw-r--r-- | FS/MANIFEST | 2 | ||||
| -rw-r--r-- | FS/t/did_order_item.t | 5 | ||||
| -rw-r--r-- | httemplate/browse/did_order.html | 26 | ||||
| -rw-r--r-- | httemplate/edit/did_order.html | 95 | ||||
| -rw-r--r-- | httemplate/edit/elements/edit.html | 3 | ||||
| -rw-r--r-- | httemplate/edit/process/did_order.html | 6 | ||||
| -rw-r--r-- | httemplate/elements/did_order_item.html | 69 | ||||
| -rw-r--r-- | httemplate/elements/tr-did_order_item.html | 24 | ||||
| -rw-r--r-- | httemplate/misc/phone_avail-import.html | 38 | 
15 files changed, 414 insertions, 79 deletions
| @@ -172,6 +172,8 @@ L<FS::did_vendor> - Bulk DID order vendor class  L<FS::did_order> - Bulk DID order class +L<FS::did_order_item> - Bulk DID order item 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 dd1871739..db54ecbd4 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -278,6 +278,7 @@ if ( -e $addl_handler_use_file ) {    use FS::hardware_class;    use FS::hardware_type;    use FS::hardware_status; +  use FS::did_order_item;    # Sammath Naur    if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 66847b6c0..06406e636 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3092,6 +3092,8 @@ sub tables_hashref {          'station',     'char',    'NULL',       4, '', '',          'name',        'varchar', 'NULL', $char_d, '', '',          'rate_center_abbrev', 'varchar', 'NULL', $char_d, '', '', +        'latanum',      'int',     'NULL',      '', '', '', +        'msa',        'varchar', 'NULL', $char_d, '', '',          'ordernum',      'int',     'NULL',      '', '', '',          'svcnum',      'int',     'NULL',      '', '', '',          'availbatch', 'varchar',  'NULL', $char_d, '', '', @@ -3127,16 +3129,28 @@ sub tables_hashref {        'index'  => [],      }, -    'did_order' => { +    'did_order_item' => {        'columns' => [ -        'ordernum',    'serial',      '',      '', '', '',  -        'vendornum',   'int',       '',      '', '', '',  -        'vendor_order_id',   'varchar',  '',   $char_d, '', '',  +        'orderitemnum',    'serial',      '',      '', '', '',  +        'ordernum',    'int',      '',      '', '', '',           'msa',        'varchar', 'NULL', $char_d, '', '', +        'npa',      'int',     'NULL',      '', '', '',          'latanum',      'int',     'NULL',      '', '', '',          'rate_center',        'varchar', 'NULL', $char_d, '', '',          'state',       'char',    'NULL',       2, '', '',           'quantity',      'int',     '',      '', '', '', +      ], +      'primary_key' => 'orderitemnum', +      'unique' => [], +      'index'  => [], +    }, + +    'did_order' => { +      'columns' => [ +        'ordernum',    'serial',      '',      '', '', '',  +        'vendornum',   'int',       '',      '', '', '',  +        'vendor_order_id',   'varchar',  'NULL',   $char_d, '', '',  +        'custnum',   'int', 'NULL', '', '', '',          'submitted',      'int',     '',      '', '', '',          'confirmed',      'int',     'NULL',      '', '', '',          'received',      'int',     'NULL',      '', '', '', diff --git a/FS/FS/did_order.pm b/FS/FS/did_order.pm index 6b199a969..f46d72bf8 100644 --- a/FS/FS/did_order.pm +++ b/FS/FS/did_order.pm @@ -1,7 +1,7 @@  package FS::did_order;  use strict; -use base qw( FS::Record ); +use base qw( FS::o2m_Common FS::Record );  use FS::Record qw( qsearch qsearchs );  =head1 NAME @@ -42,26 +42,6 @@ vendornum  vendor_order_id -=item msa - -msa - -=item latanum - -latanum - -=item rate_center - -rate_center - -=item state - -state - -=item quantity - -quantity -  =item submitted  submitted @@ -137,12 +117,7 @@ sub check {    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_textn('vendor_order_id')      || $self->ut_number('submitted')      || $self->ut_numbern('confirmed')      || $self->ut_numbern('received') @@ -152,9 +127,19 @@ sub check {    $self->SUPER::check;  } -=back +=item did_order_item + +Returns the did_order_items (see L<FS::did_order_item>) associated with this bulk DID order. -=head1 BUGS +=cut + +sub did_order_item { +  my $self = shift; +  qsearch( 'did_order_item', { 'ordernum' => $self->ordernum } ); +} + + +=back  =head1 SEE ALSO diff --git a/FS/FS/did_order_item.pm b/FS/FS/did_order_item.pm new file mode 100644 index 000000000..4408c50f5 --- /dev/null +++ b/FS/FS/did_order_item.pm @@ -0,0 +1,150 @@ +package FS::did_order_item; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs ); + +=head1 NAME + +FS::did_order_item - Object methods for did_order_item records + +=head1 SYNOPSIS + +  use FS::did_order_item; + +  $record = new FS::did_order_item \%hash; +  $record = new FS::did_order_item { 'column' => 'value' }; + +  $error = $record->insert; + +  $error = $new_record->replace($old_record); + +  $error = $record->delete; + +  $error = $record->check; + +=head1 DESCRIPTION + +An FS::did_order_item object represents an item in a bulk DID order. +FS::did_order_item inherits from FS::Record.   +The following fields are currently supported: + +=over 4 + +=item orderitemnum + +primary key + +=item ordernum + +ordernum + +=item msa + +msa + +=item npa + +npa + +=item latanum + +latanum + +=item rate_center + +rate_center + +=item state + +state + +=item quantity + +quantity + + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new DID order item.  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'; } + +=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 DID order item.  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('orderitemnum') +    || $self->ut_number('ordernum') +    || $self->ut_textn('msa') +    || $self->ut_numbern('npa') +    || $self->ut_foreign_keyn('latanum', 'lata', 'latanum') +    || $self->ut_textn('rate_center') +    || $self->ut_textn('state') +    || $self->ut_number('quantity') +  ; +  return $error if $error; + +  $self->SUPER::check; +} + +=back + +=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 8bb6a5cc3..3066ac033 100644 --- a/FS/FS/phone_avail.pm +++ b/FS/FS/phone_avail.pm @@ -4,6 +4,7 @@ use strict;  use vars qw( @ISA $DEBUG $me );  use FS::Record qw( qsearch qsearchs dbh );  use FS::cust_svc; +use FS::Misc::DateTime qw( parse_datetime );  @ISA = qw(FS::cust_main_Mixin FS::Record); @@ -190,9 +191,9 @@ sub process_batch_import {    };    my $opt = { 'table'   => 'phone_avail', -              'params'  => [ 'availbatch', 'exportnum', 'countrycode', 'ordernum' ], +              'params'  => [ 'availbatch', 'exportnum', 'countrycode', 'ordernum', 'vendor_order_id', 'confirmed' ],                'formats' => { 'default' => [ 'state', $numsub, 'name' ], -			     'bulk' => [ 'state', $numsub, 'name', 'rate_center_abbrev' ], +			     'bulk' => [ 'state', $numsub, 'name', 'rate_center_abbrev', 'msa', 'latanum' ],  			   },  	      'postinsert_callback' => sub {    		    my $record = shift; @@ -201,6 +202,8 @@ sub process_batch_import {  						{ 'ordernum' => $record->ordernum } );  			if($did_order && !$did_order->received) {  			    $did_order->received(time); +			    $did_order->confirmed(parse_datetime($record->confirmed)); +			    $did_order->vendor_order_id($record->vendor_order_id);  			    $did_order->replace;  			}  		    } diff --git a/FS/MANIFEST b/FS/MANIFEST index a293451a1..c93f1ffc2 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -588,3 +588,5 @@ FS/hardware_type.pm  t/hardware_type.t  FS/hardware_status.pm  t/hardware_status.t +FS/did_order_item.pm +t/did_order_item.t diff --git a/FS/t/did_order_item.t b/FS/t/did_order_item.t new file mode 100644 index 000000000..cc33c1481 --- /dev/null +++ b/FS/t/did_order_item.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::did_order_item; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/browse/did_order.html b/httemplate/browse/did_order.html index 54c2bd3fc..e844169b3 100644 --- a/httemplate/browse/did_order.html +++ b/httemplate/browse/did_order.html @@ -4,15 +4,16 @@                   'name'        => 'bulk DID orders',                   'disableable' => 0,                   'query'       => { 'table'     => 'did_order', -				    'addl_from' => 'left join did_vendor using (vendornum)  -						    left join lata using (latanum)', +				    'addl_from' => 'left join did_vendor using (vendornum) ',                                      'hashref'   => {},                                      'order_by' => 'ORDER BY ordernum',                                    },                   'count_query' => $count_query,                   'header'      => $header,                   'fields'      => $fields, -                 'links'       => $links, +                 'links'       => [ +				    [ $p.'edit/did_order.html?', 'ordernum' ], +				  ],               )  %>  <%init> @@ -28,31 +29,22 @@ my $html_init =  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 $header = [ '#', 'Vendor',' Vendor Order #',   +		'Submitted', 'Confirmed', 'Customer', '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',  +		    $did_order->ordernum; +		}, 'vendorname', 'vendor_order_id',   		sub { &$display_date(shift->submitted); },   		sub { &$display_date(shift->confirmed);	},  +		'custnum',  		sub {   		    my $did_order = shift;  		    my $ordernum = $did_order->ordernum; diff --git a/httemplate/edit/did_order.html b/httemplate/edit/did_order.html index a9bece9b1..25e38c72e 100644 --- a/httemplate/edit/did_order.html +++ b/httemplate/edit/did_order.html @@ -6,39 +6,54 @@                                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 => 'vendor_order_id', +			      type => 'hidden', +			    },                              { field => 'confirmed', -                              type => 'input-date-field', +                              type => 'hidden',                              }, +			    'custnum', +			    { type => 'tablebreak-tr-title', +			      value => 'Order Items', +			    }, +			    { 'field' => 'orderitemnum', +			      'type' => 'did_order_item', +			      'o2m_table' => 'did_order_item', +			      'm2_label' => 'Item', +			      'm2_error_callback' => $m2_error_callback, +			    }, +                            #'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',                            ],                'labels' => {                               'ordernum'        => 'Order',                              'vendornum'       => 'Vendor',                              'vendor_order_id' => 'Vendor Order #', -                            'msa'             => 'MSA', -                            'latanum'         => 'LATA', -                            'rate_center'     => 'Rate Center', -                            'state'           => 'State', -                            'quantity'        => 'Quantity', +			    'custnum'	      => 'Customer', +                            #'msa'             => 'MSA', +                            #'latanum'         => 'LATA', +                            #'rate_center'     => 'Rate Center', +                            #'state'           => 'State', +                            #'quantity'        => 'Quantity',                              'confirmed'       => 'Confirmation Date', +			    'orderitemnum'     => 'Item',                            },                'viewall_dir' => 'browse',                'table' => 'did_order',                'name' => 'Bulk DID Order', +	      'field_callback' => $field_callback,             )  %> @@ -47,4 +62,42 @@  die "access denied"    unless $FS::CurrentUser::CurrentUser->access_right('Import'); + +my $field_callback = sub { +  my ($cgi, $object, $field_hashref ) = @_; +  if ($object->ordernum) { +    $field_hashref->{type} = 'text' +	if $field_hashref->{field} eq 'vendor_order_id'; +    $field_hashref->{type} = 'input-date-field' +	if $field_hashref->{field} eq 'confirmed'; +  } +}; + +my $m2_error_callback = sub { +  my($cgi, $object) = @_; + +  #process_o2m fields in process/did_order.html +  my @fields = qw( msa npa latanum rate_center state quantity ); +  my @gfields = ( '', map "_$_", @fields ); + +  map { +        if ( /^orderitemnum(\d+)$/ ) { +          my $num = $1; +          if ( grep $cgi->param("orderitemnum$num$_"), @gfields ) { +            my $x = new FS::did_order_item { +              'orderitemnum' => scalar($cgi->param("orderitemnum$num")), +              map { $_ => scalar($cgi->param("orderitemnum${num}_$_")) } @fields, +            }; +            $x; +          } else { +            (); +          } +        } else { +          (); +        } +      } +      $cgi->param; +}; + +  </%init> diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html index 295ad8567..f5698d98e 100644 --- a/httemplate/edit/elements/edit.html +++ b/httemplate/edit/elements/edit.html @@ -272,6 +272,7 @@ Example:  %     'options'       => $f->{'options'},  %     'labels'        => $f->{'labels'},  %     'multiple'      => $f->{'multiple'}, +%     'label_showkey' => $f->{'label_showkey'},  %     'disable_empty' => $f->{'disable_empty'},  %     #select-reason  %     'reason_class'  => $f->{'reason_class'}, @@ -439,7 +440,7 @@ Example:  %       }  %       warn "layer values: ". Dumper($layer_values)  %         if $opt{'debug'}; -% +%	  %       my @existing = &{ $include_sub }(  %         'label'        => $ex_label,  %         'fieldnum'     => $fieldnum, diff --git a/httemplate/edit/process/did_order.html b/httemplate/edit/process/did_order.html index 0c9a3f0e0..e5948ff0b 100644 --- a/httemplate/edit/process/did_order.html +++ b/httemplate/edit/process/did_order.html @@ -2,6 +2,10 @@                 'table'       => 'did_order',                 'viewall_dir' => 'browse',  	       'value_callback' => $value_callback, +		 'process_o2m' => { +		   'table'  => 'did_order_item', +		   'fields' => \@item_fields, +		 },             )  %>  <%init> @@ -15,6 +19,8 @@ my $value_callback = sub {       ($field =~ /ed$/ && $value !~ /^\d+$/) ? parse_datetime($value) : $value;  }; +my @item_fields = qw( msa npa latanum rate_center state quantity ); +  die "access denied"    unless $FS::CurrentUser::CurrentUser->access_right('Import'); diff --git a/httemplate/elements/did_order_item.html b/httemplate/elements/did_order_item.html new file mode 100644 index 000000000..263826ecc --- /dev/null +++ b/httemplate/elements/did_order_item.html @@ -0,0 +1,69 @@ +% unless ( $opt{'js_only'} ) { + +  <INPUT TYPE="hidden" NAME="<%$name%>" ID="<%$id%>" VALUE="<% $curr_value %>"> + +  <TABLE> +    <TR> +%     foreach my $field ( @fields ) { +% +%       my $value = ''; +%         $value = $item->get($field); + +        <TD> +          <INPUT TYPE  = "text" +                 NAME  = "<%$name%>_<%$field%>" +                 ID    = "<%$id%>_<%$field%>" +                 SIZE  = "<% $size{$field} || 15 %>" +                 VALUE = "<% scalar($cgi->param($name."_$field")) +                             || $value |h %>" +                 <% $onchange %> +          ><BR> +          <FONT SIZE="-1"><% $label{$field} %></FONT> +        </TD> +%     } +    </TR> +  </TABLE> + +% } +<%init> + +my( %opt ) = @_; + +my $name = $opt{'element_name'} || $opt{'field'} || 'orderitemnum'; +my $id = $opt{'id'} || 'orderitemnum'; + +my $curr_value = $opt{'curr_value'} || $opt{'value'}; + +my $onchange = ''; +if ( $opt{'onchange'} ) { +  $onchange = $opt{'onchange'}; +  $onchange .= '(this)' unless $onchange =~ /\(\w*\);?$/; +  $onchange =~ s/\(what\);/\(this\);/g; #ugh, terrible hack.  all onchange +                                        #callbacks should act the same +  $onchange = 'onChange="'. $onchange. '"'; +} + +my $item; +if ( $curr_value ) { +  $item = qsearchs('did_order_item', { 'orderitemnum' => $curr_value } ); +} else { +  $item = new FS::did_order_item {}; +} + +my %size = ( 'npa' => 3,  +	     'latanum' => 3, +	     'state' => 2, +	     'quantity' => 3,); + +tie my %label, 'Tie::IxHash', +  'msa'        => 'MSA', +  'npa'        => 'NPA', +  'latanum'         => 'LATA #', +  'rate_center'        => 'Rate Center', +  'state' => 'State', +  'quantity' => 'Quantity', +; + +my @fields = keys %label; + +</%init> diff --git a/httemplate/elements/tr-did_order_item.html b/httemplate/elements/tr-did_order_item.html new file mode 100644 index 000000000..7824aee03 --- /dev/null +++ b/httemplate/elements/tr-did_order_item.html @@ -0,0 +1,24 @@ +%   unless ( $opt{'js_only'} ) { + +      <% include('tr-td-label.html', %opt) %> +        <TD <% $cell_style %>> + +%   } +% +            <% include( '/elements/did_order_item.html', %opt ) %> +% +%   unless ( $opt{'js_only'} ) { + +        </TD> +      </TR> + +%   } +<%init> + +my( %opt ) = @_; + +my $cell_style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : ''; + +$opt{'label'} ||= 'Item'; + +</%init> diff --git a/httemplate/misc/phone_avail-import.html b/httemplate/misc/phone_avail-import.html index fcbfcc398..903c17bd9 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', 'ordernum' ], +              'fields'    => [ 'format', 'availbatch', 'exportnum', 'countrycode', 'ordernum', 'confirmed', 'vendor_order_id' ],                'message'   => 'DID import successful',                'url'       => $p."search/phone_avail.html?availbatch=$availbatch",            ) @@ -25,6 +25,20 @@ Import a file containing phone numbers (DIDs).  	    <INPUT TYPE="hidden" NAME="ordernum" VALUE="<% $ordernum %>">  	</TD>      </TR> +    <TR> +	<TD ALIGN="RIGHT">Vendor Order #</TD> +	<TD> +	    <INPUT TYPE="text" NAME="vendor_order_id" VALUE="<% $vendor_order_id %>"> +	</TD> +    </TR> +     +    <% include( '/elements/tr-input-date-field.html', { +		    'name' => 'confirmed', +		    'label' => 'Order Confirmed', +		    'value' => $confirmed, +           }) +    %> +  % }     <TR>      <TD ALIGN="RIGHT">Import Format</TD> @@ -78,7 +92,7 @@ Uploaded files can be CSV (comma-separated value) files or Excel spreadsheets.  <BR><BR>  <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> +<b>Bulk</b> format has the following field order: <i>state, number, rate center, rate_center_abbrev, msa, latanum</i>  <BR><BR>  Field information:  <ul> @@ -87,6 +101,8 @@ Field information:    <li><i>name</i>: optional, rate center    <li><i>rate center</i>: rate center (required)    <li><i>rate_center_abbrev</i>: rate center abbreviation +  <li><i>msa</i>: MSA +  <li><i>latanum</i>: LATA #  </ul>  <BR><BR> @@ -102,11 +118,23 @@ 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 $vendor_order_id = ''; +my $confirmed = ''; + +my $order = ''; +$order = qsearchs('did_order', { 'ordernum' => $ordernum } )  +    if $ordernum; + +die 'invalid ordernum' unless (!$ordernum || $order);  my $format = 'default'; -$format = 'bulk' if $ordernum; + +if ( $order ) { +    $format = 'bulk'; +    $confirmed = $order->confirmed; +    $vendor_order_id = $order->vendor_order_id; +} +  my $availbatch =    time2str('webimport-%Y/%m/%d-%T'. "-$$-". rand() * 2**32, time); | 
