diff options
| -rw-r--r-- | FS/FS/Schema.pm | 1 | ||||
| -rw-r--r-- | FS/FS/did_order.pm | 91 | ||||
| -rw-r--r-- | FS/FS/did_order_item.pm | 5 | ||||
| -rw-r--r-- | FS/FS/phone_avail.pm | 16 | ||||
| -rw-r--r-- | bin/import-did-inventory | 8 | ||||
| -rw-r--r-- | httemplate/browse/did_order.html | 81 | ||||
| -rw-r--r-- | httemplate/edit/did_order.html | 8 | ||||
| -rw-r--r-- | httemplate/edit/process/did_order.html | 27 | ||||
| -rw-r--r-- | httemplate/elements/did_order_item.html | 12 | ||||
| -rw-r--r-- | httemplate/misc/did_order_confirmed.html | 81 | ||||
| -rw-r--r-- | httemplate/misc/did_order_provision.html | 82 | 
11 files changed, 308 insertions, 104 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 9d03ce39d..eebcfecd2 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3184,6 +3184,7 @@ sub tables_hashref {          'ratecenternum',      'int',     'NULL',      '', '', '',          'state',       'char',    'NULL',       2, '', '',           'quantity',      'int',     '',      '', '', '', +        'custnum',   'int', 'NULL', '', '', '',        ],        'primary_key' => 'orderitemnum',        'unique' => [], diff --git a/FS/FS/did_order.pm b/FS/FS/did_order.pm index c1b34c345..2404ad817 100644 --- a/FS/FS/did_order.pm +++ b/FS/FS/did_order.pm @@ -126,6 +126,59 @@ sub delete {    $dbh->commit or die $dbh->errstr if $oldAutoCommit;  } +=item merge SOURCE_ORDER + +Merges the DID order given by SOURCE_ORDER into THIS order.  + +The following fields from the source order are transferred, only if they aren't +set in this order: +-vendor order # +-submitted +-confirmed +-customer + +DID order items are transferred into this order. + +The source order is deleted. + +The operation fails if: +-either order has a received time; or +-the DID vendors do not match between the orders + +=cut + +sub merge { +    my $self = shift; +    my $src = shift; +    return "invalid source order" unless $src; + +    return "DIDs received for either order"  +        if $src->received || $self->received; + +    return "DID vendors do not match" +        if $src->vendornum != $self->vendornum; + +    my @move_if_unset = qw( vendor_order_id submitted confirmed custnum ); +    foreach my $f ( @move_if_unset ) { +        $self->$f($src->$f) if !$self->$f; +    } + +    my $error = ''; +    my @did_order_items = qsearch('did_order_item', { 'ordernum' => $src->ordernum }); +    foreach my $did_order_item ( @did_order_items ) { +        $did_order_item->ordernum($self->ordernum); +        $error = $did_order_item->replace; +        return $error if $error; +    } + +    $error = $src->delete; +    return $error if !$error; + +    $error = $self->replace; +    return $error if !$error; + +    ''; +}  =item replace OLD_RECORD @@ -176,16 +229,48 @@ sub did_order_item {  =item cust_main -Returns the cust_main (see L<FS::cust_main>), if any, associated with this bulk DID order. +Returns all cust_main (see L<FS::cust_main>), if any, associated with this +bulk DID order.  =cut  sub cust_main {    my $self = shift; -  return '' unless $self->custnum; -  qsearchs('cust_main', { 'custnum' => $self->custnum } ); +  my @did_order_item = $self->did_order_item; +  my @custnums; +  push @custnums, $self->custnum if $self->custnum; +  foreach my $did_order_item ( @did_order_item ) { +       push @custnums, $did_order_item->custnum if $did_order_item->custnum;  +  } +  my @cust_main; +  foreach my $custnum ( @custnums ) { +      push @cust_main, qsearchs('cust_main', { 'custnum' => $custnum } ); +  } +  @cust_main;  +} + + +=item has_stock  + +Returns true if and only if the order has any stock order items. + +=cut + +sub has_stock { +    my $self = shift; +    my $items_with_custnum = 0; +    my @did_order_item = $self->did_order_item; +    foreach my $did_order_item ( @did_order_item ) { +        $items_with_custnum++ if $did_order_item->custnum; +    } + +    return 0 if ($items_with_custnum == scalar(@did_order_item)  +                    && $items_with_custnum != 0 && !$self->custnum)  +                || $self->custnum; +    1;  } +  =item provisioned  Returns the provisioned DIDs, if any, as phone_avail (see L<FS::phone_avail>) objects. diff --git a/FS/FS/did_order_item.pm b/FS/FS/did_order_item.pm index c2d657ad8..235e00eb7 100644 --- a/FS/FS/did_order_item.pm +++ b/FS/FS/did_order_item.pm @@ -49,6 +49,8 @@ primary key  =item quantity +=item custnum - foreign key to cust_main table, optional +  =back  =head1 METHODS @@ -117,6 +119,7 @@ sub check {      || $self->ut_foreign_keyn('ratecenternum', 'rate_center', 'ratecenternum')      || $self->ut_textn('state')      || $self->ut_number('quantity') +    || $self->ut_foreign_keyn('custnum', 'cust_main', 'custnum')    ;    return $error if $error; @@ -127,7 +130,7 @@ sub check {  =head1 SEE ALSO -L<FS::Record>, schema.html from the base documentation. +L<FS::did_order>, <FS::Record>, schema.html from the base documentation.  =cut diff --git a/FS/FS/phone_avail.pm b/FS/FS/phone_avail.pm index b726d3497..44421ff57 100644 --- a/FS/FS/phone_avail.pm +++ b/FS/FS/phone_avail.pm @@ -226,14 +226,14 @@ sub process_batch_import {                 '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->confirmed(parse_datetime($record->confirmed)); -                        $did_order->vendor_order_id($record->vendor_order_id); -                        $did_order->replace; -                    } +                        my $did_order = qsearchs('did_order',  +                                            { '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/bin/import-did-inventory b/bin/import-did-inventory index 11d68a775..612217863 100644 --- a/bin/import-did-inventory +++ b/bin/import-did-inventory @@ -362,8 +362,12 @@ sub order {                      && $o->received == $received);          fatal("customer mismatch for vendor order #$vendor_order_id")              unless (    ($o->custnum && $cust{'custnum'}  -                            && $o->custnum == $cust{'custnum'}) -                        || (!$o->custnum && !exists($cust{'custnum'})) ); +                          && ($o->custnum == $cust{'custnum'}  +                            || $vendor_order_id eq '293745') +                        ) +                        || +                        (!$o->custnum && !exists($cust{'custnum'})) +                   );      } else {          $o = new FS::did_order{ vendornum       => $did_vendor_id,                                  vendor_order_id => $vendor_order_id, diff --git a/httemplate/browse/did_order.html b/httemplate/browse/did_order.html index 3da8cb1ba..61b37d8d9 100644 --- a/httemplate/browse/did_order.html +++ b/httemplate/browse/did_order.html @@ -4,10 +4,10 @@                   'name'        => 'bulk DID orders',                   'disableable' => 0,                   'query'       => $query, -                 'count_query' => 'SELECT COUNT(*) FROM did_order', # XXX: this is wrong!? +                 'count_query' => 'SELECT COUNT(*) FROM did_order', # XXX: this is wrong!                   'header'      => [ '#', 'Vendor',' Vendor Order #',                                       'Submitted', 'Confirmed', 'Customer', -                                    'Received', 'Provision', 'Cancel', +                                    'Received', 'Provision', 'Cancel', 'Merge Into',                                    ],                   'fields'      => [ sub {                                          my $did_order = shift; @@ -32,9 +32,19 @@                                      },                                       sub { # Customer                                          my $did_order = shift; -                                        my $cust_main = $did_order->cust_main; -                                        return "Stock" unless $cust_main; -                                        "<A HREF='${p}view/cust_main.cgi?".$cust_main->custnum."'>".$cust_main->name."</A>"; +                                        my @cust_main = $did_order->cust_main; +                                        my $has_stock = $did_order->has_stock; +                                        if (scalar(@cust_main) == 1 && !$has_stock) { +                                            my $cust_main = $cust_main[0]; +                                            return "<A HREF='${p}view/cust_main.cgi?".$cust_main->custnum."'>".$cust_main->name."</A>" +                                        } +                                        elsif(scalar(@cust_main) == 0 && $has_stock) { +                                            return 'Stock'; +                                        } +                                        elsif(scalar(@cust_main) > 0 && !$has_stock) { +                                            return 'Multiple'; +                                        } +                                        'Multiple/Stock';                                      },                                      sub { # Received                                          my $did_order = shift; @@ -50,11 +60,11 @@                                          my @provisioned = $did_order->provisioned;                                          return ''                                               unless $did_order->received  -                                                        && $did_order->custnum +                                                        && scalar($did_order->cust_main)                                                          && !scalar(@provisioned);                                          include( '/elements/popup_link.html',                                            { 'action'      => "${p}misc/did_order_provision.html?ordernum=".$did_order->ordernum, -                                            'label'       => 'Provision All DIDs', +                                            'label'       => 'Provision DIDs',                                              'actionlabel' => 'Bulk DID order - DID provisioning',                                              'width'       => 520,                                              'height'      => 300, @@ -68,6 +78,11 @@                                          . $did_order->ordernum . qq!', 'Cancel this order (#!                                          . $did_order->ordernum . qq!)?')">Cancel</A>!                                      }, +                                    sub { # Merge +                                        my $did_order = shift; +                                        return '' unless !$did_order->received; +                                        &$merge_select($did_order->ordernum); +                                    },                                    ],                   'links'       => [                                      [ $p.'edit/did_order.html?', 'ordernum' ], @@ -78,6 +93,12 @@                                      if (confirm(msg))                                          window.location.href = href;                                  } + +                                function mergeconfirm(select,source_ordernum) { +                                    var target_ordernum = select.options[select.selectedIndex].value; +                                    areyousure("'.$p.'misc/did_order_confirmed.html?action=merge;ordernum="+source_ordernum+";target_ordernum="+target_ordernum, +                                                "Merge order #" + source_ordernum + " into order #" + target_ordernum + "?"); +                                }                              </script>                                  ',               ) @@ -90,27 +111,26 @@ die "access denied"  my $conf = new FS::Conf;  my $date_format = $conf->config('date_format') || '%m/%d/%Y'; -my $display_date = sub { -    my $date = shift; -    return '' unless $date; -    time2str($date_format, $date); -}; -  my $html_init = qq!<A HREF="${p}edit/did_order.html">Add a bulk DID order</A>                      <BR><BR>!; -  my $query = {       'table'      => 'did_order',      'hashref'    => {},      'addl_from' => 'left join did_vendor using (vendornum) ',      'order_by' => 'ORDER BY ordernum',              }; -$query->{'hashref'}->{'custnum'} = $1 if $cgi->param('custnum') =~ /^(\d+)$/; +if ( $cgi->param('custnum') =~ /^(\d+)$/ ) { +    $query->{'extra_sql'} .= " where (custnum = $1 or $1 in (select distinct " +                            . " custnum from did_order_item where " +                            . " did_order_item.ordernum = did_order.ordernum ) )"; +}  if ( $cgi->param('custrcvdunprov') ) {      $query->{'hashref'}->{'received'} = { 'op' => '>', 'value' => '0', }; -    $query->{'hashref'}->{'custnum'} = { 'op' => '>', 'value' => '0', }; +    $query->{'hashref'}->{'svcnum'} = '';      $query->{'addl_from'} .= ' left join phone_avail using (ordernum) '; -    $query->{'extra_sql'} .= ' and svcnum is null '; +    $query->{'extra_sql'} .= " and (custnum > 0 or 0 < (select count(1) from " +                      . " did_order_item where did_order_item.custnum > 0 and " +                      . " did_order_item.ordernum = did_order.ordernum) )";      $html_init .= qq!<A HREF="${p}browse/did_order.html">Browse all DID orders</A>!;  }  else { @@ -118,7 +138,32 @@ else {                      Browse all non-stock orders with received unprovisioned DIDs                      </A>!;  } -  $html_init .= "<BR><BR>"; +my @merge_targets = qsearch({ +                                'table'     => 'did_order', +                                'hashref'   => { 'received' => '' }, +                                'order_by'  => 'ORDER BY ordernum', +                            }); + +my $merge_select = sub { +    my $source_ordernum = shift; +    my $merge_select = ''; +    if ( @merge_targets ) { +        $merge_select = "<SELECT onchange='mergeconfirm(this,$source_ordernum)'><OPTION></OPTION>"; +        foreach my $order ( @merge_targets ) { +            next if $order->ordernum == $source_ordernum; +            $merge_select .= "<OPTION>".$order->ordernum."</OPTION>"; +        } +        $merge_select .= "</SELECT>"; +    } +    $merge_select; +}; + +my $display_date = sub { +    my $date = shift; +    return '' unless $date; +    time2str($date_format, $date); +}; +  </%init> diff --git a/httemplate/edit/did_order.html b/httemplate/edit/did_order.html index 5837d438c..6912117de 100644 --- a/httemplate/edit/did_order.html +++ b/httemplate/edit/did_order.html @@ -12,6 +12,12 @@                              { field => 'confirmed',                                type => 'hidden',                              }, +                            { field => 'received', +                              type => 'hidden', +                            }, +                            { field => 'submitted', +                              type => 'hidden', +                            },                              { field => 'stock_or_customer',                                type => 'radio',                                options => [ 'Stock', 'Customer', ], @@ -104,12 +110,12 @@ my $javascript = <<END;              if ( f.stock_or_customer_Stock.checked ) {                  custnum_search.disabled = true;                  custnum_select.disabled = true; +                custnum.value = '';              }              else if ( f.stock_or_customer_Customer.checked ) {                  custnum_search.disabled = false;                  custnum_select.disabled = false;              } -            custnum.value = '';          }          /* o2m or something else is broken, can't put this in the actual diff --git a/httemplate/edit/process/did_order.html b/httemplate/edit/process/did_order.html index a7d30c36c..6a2884413 100644 --- a/httemplate/edit/process/did_order.html +++ b/httemplate/edit/process/did_order.html @@ -5,7 +5,7 @@                 'process_o2m' => {                      'table'  => 'did_order_item',                      'fields' => [ qw( msanum npa latanum ratecenternum state -                                  quantity ) ], +                                  quantity custnum ) ],                  },             )  %> @@ -25,14 +25,23 @@ my $value_callback = sub {  my @params = $cgi->param;  foreach my $param ( @params ) { -    next unless $param =~ /^(orderitemnum[0-9]+)_rc_new$/; -    my $prefix = $1; -    my $value = $cgi->param($param); -    next unless $value =~ /^[A-Za-z0-9\- ]+$/; -    my $rc = new FS::rate_center({ description => $value }); -    my $error = $rc->insert; -    die "error inserting new rate center: $error" if $error; -    $cgi->param("${prefix}_ratecenternum",$rc->ratecenternum); +    if ( $param =~ /^(orderitemnum[0-9]+)_rc_new$/ ) { +        my $prefix = $1; +        my $value = $cgi->param($param); +        if( $value =~ /^[A-Za-z0-9\- ]+$/ ) { +            my $rc = new FS::rate_center({ description => $value }); +            my $error = $rc->insert; +            die "error inserting new rate center: $error" if $error; +            $cgi->param("${prefix}_ratecenternum",$rc->ratecenternum); +        } +    } +    elsif ( $param =~ /^(orderitemnum[0-9]+)_custnum$/ ) { +        my $prefix = $1; +        my $value = $cgi->param($param); +        if ( $value =~ /^\d+$/ ) { +            $cgi->param("custnum",''); +        } +    }  }  </%init> diff --git a/httemplate/elements/did_order_item.html b/httemplate/elements/did_order_item.html index b582683b7..d1f90f338 100644 --- a/httemplate/elements/did_order_item.html +++ b/httemplate/elements/did_order_item.html @@ -98,6 +98,18 @@            <BR><FONT SIZE="-1">State</FONT>        </TD> +%     $value = $item->get('custnum'); +      <TD><INPUT TYPE  = "text" +                 NAME  = "<%$name%>_custnum" +                 ID    = "<%$id%>_custnum" +                 SIZE  = "7" +                 VALUE = "<% scalar($cgi->param($name."_custnum")) +                             || $value |h %>" +                 <% $onchange %> +          > +          <BR><FONT SIZE="-1">Customer #</FONT> +      </TD> +      </TR>    </TABLE> diff --git a/httemplate/misc/did_order_confirmed.html b/httemplate/misc/did_order_confirmed.html index c0c4795a6..3505a1e1d 100644 --- a/httemplate/misc/did_order_confirmed.html +++ b/httemplate/misc/did_order_confirmed.html @@ -1,17 +1,19 @@ -<% include('/elements/header-popup.html', $success_msg ) %> +<% include("/elements/header$popup.html", $header ) %> +<% include('/elements/error.html') %> +% unless ( $cgi->param('error') ) {    <SCRIPT TYPE="text/javascript">      <% $js %>    </SCRIPT> +% }    </BODY>  </HTML>  <%init>  die "access denied"    unless $FS::CurrentUser::CurrentUser->access_right('Import'); -$cgi->param('action') =~ /^(confirm|cancel|provision)$/ or die 'illegal action';  my $action = $1; -my $success_msg = ''; -my $error = ''; +my $header = ''; +my $popup = '';  my $js = 'window.top.location.reload();';  $cgi->param('ordernum') =~ /^(\d+)$/ or die 'illegal ordernum'; @@ -22,9 +24,10 @@ my $did_order = qsearchs( {  } );  die "No order $ordernum" unless $did_order; +my $action = $cgi->param('action');  if ( $action eq 'confirm' ) {      my $confirmed = ''; -    my $sucess_msg = 'DID order confirmed'; +    $header = 'DID order confirmed';      $confirmed = parse_datetime($cgi->param('confirmed'))          if $cgi->param('confirmed') && $cgi->param('confirmed') !~ /^\d+$/;      $confirmed = $1 @@ -34,34 +37,62 @@ if ( $action eq 'confirm' ) {      $did_order->confirmed($confirmed);      $did_order->vendor_order_id($cgi->param('vendor_order_id')); -    $error = $did_order->replace; -    if ( $error ) { -        $cgi->param('error', $error); -        print $cgi->redirect(popurl(1). "did_order_confirm.html?". $cgi->query_string ); -    } +    $cgi->param('error',$did_order->replace); +    print $cgi->redirect(popurl(1). "did_order_confirm.html?". $cgi->query_string ) +         if $cgi->param('error'); +    $popup = '-popup';  }  elsif ( $action eq 'cancel' ) { -    my $sucess_msg = 'DID order cancelled'; -    $error = $did_order->delete; +    $header = 'DID order cancelled'; +    $cgi->param('error',$did_order->delete);      $js = "window.location.href = '${p}browse/did_order.html'";  }  elsif ( $action eq 'provision' ) { -    my $sucess_msg = 'DID order provisioned'; -    $cgi->param('pkgnum_svcpart') =~ /^(\d+)_(\d+)$/ or die 'illegal pkgnum_svcpart'; -    my $pkgnum = $1; -    my $svcpart = $2; +    $header = 'DID order provisioned';      my @dids = qsearch( 'phone_avail', { ordernum => $ordernum } );      die "no DIDs on order" unless scalar(@dids); -    foreach my $did ( @dids ) { -        my $svc_phone = new FS::svc_phone({ -            pkgnum  => $pkgnum, -            svcpart => $svcpart, -            countrycode => 1, -            phonenum    => $did->npa.$did->nxx.$did->station, -        }); -        $error = $svc_phone->insert; -        last if $error; +    my @params = $cgi->param; +    foreach my $param ( @params ) { +        next unless $param =~ /^custnum(\d+)_pkgnum_svcpart$/; +        my $custnum = $1; +        my $value = $cgi->param($param); +        next unless $value =~ /^(\d+)_(\d+)$/; +        my $pkgnum = $1; +        my $svcpart = $2; +        if ( $did_order->custnum && $did_order->custnum == $custnum ) { +        # this is our old per-order custnum case + +            foreach my $did ( @dids ) { +                my $svc_phone = new FS::svc_phone({ +                    pkgnum  => $pkgnum, +                    svcpart => $svcpart, +                    countrycode => 1, +                    phonenum    => $did->npa.$did->nxx.$did->station, +                }); +                $cgi->param('error',$svc_phone->insert); +                last if $cgi->param('error'); +            } +        } +        # XXX: now what do we do for order items? Not clear how to match a DID in an order item      } +    $popup = '-popup'; +} +elsif ( $action eq 'merge' ) { +    $header = 'DID order merged'; +    $cgi->param('target_ordernum') =~ /^(\d+)$/ or die 'illegal target_ordernum'; +    my $target_ordernum = $1; +    my $target_did_order = qsearchs( { +      'table'     => 'did_order', +      'hashref'   => { 'ordernum' => $target_ordernum }, +    } ); +    die "No order $target_ordernum" unless $target_did_order; +    $cgi->param('error',$target_did_order->merge($did_order)); +    $js = "window.location.href = '${p}browse/did_order.html'"; +} +else {  +    die "illegal action";  } +$header = 'Error' if $cgi->param('error'); +  </%init> diff --git a/httemplate/misc/did_order_provision.html b/httemplate/misc/did_order_provision.html index 8241121a8..1df9444ab 100644 --- a/httemplate/misc/did_order_provision.html +++ b/httemplate/misc/did_order_provision.html @@ -5,27 +5,33 @@  <FORM NAME="did_order_confirm" ACTION="<% popurl(1) %>did_order_confirmed.html" METHOD=POST>  <INPUT TYPE="hidden" NAME="action" VALUE="provision">  <INPUT TYPE="hidden" NAME="ordernum" VALUE="<% $ordernum %>"> + +  <TABLE> -    <TR>     -        <TD>Order #</TD> -        <TD><% $ordernum %></TD> +    <TR> +        <TH COLSPAN="2" ALIGN="LEFT">Order # <% $ordernum %></TH> +    </TR> +    <TR> +        <TH>Customer</TH> +        <TH>Package/Service</TH>      </TR> +% my $anyavail = 0; +% foreach my $cust_main ( @cust_main ) { +%  my($cust_pkg_phone,$cust_pkg_label,$svc_label) = possible_pkgs($cust_main); +%  my $avail = keys(%$cust_pkg_phone); +%  $anyavail = 1 if $avail;      <TR>     -        <TD>Customer</TD>          <TD><% $cust_main->name %></TD> -    <TR> -        <TD>Package/Service</TD>          <TD>  %           if ( !$avail ) { -                No packages exist for this customer having at least <% scalar(@dids) %> -                    unprovisioned DIDs, as required for this order. +                No suitable packages exist for this customer.  %           } else { -           <SELECT NAME="pkgnum_svcpart"> -%           foreach my $pkgnum ( keys %cust_pkg_phone ) { -%               my @svcpart = @{$cust_pkg_phone{$pkgnum}}; +           <SELECT NAME="custnum<%$cust_main->custnum%>_pkgnum_svcpart"> +%           foreach my $pkgnum ( keys %$cust_pkg_phone ) { +%               my @svcpart = @{$cust_pkg_phone->{$pkgnum}};  %               foreach my $svcpart ( @svcpart ) {                      <OPTION value="<%"${pkgnum}_$svcpart"%>"> -                        <% $cust_pkg_label{$pkgnum} %> / <% $svc_label{$svcpart} %> +                        <% $cust_pkg_label->{$pkgnum} %> / <% $svc_label->{$svcpart} %>                      </OPTION>  %               }  %           } @@ -33,11 +39,10 @@  %           }         </TD>      </TR> -%   if ( $avail ) { -    <TR> -        <TD COLSPAN="2"><INPUT TYPE="SUBMIT" value="Provision"></TD> -    </TR> -%  } +% } +% if ( $anyavail ) { +    <TR><TD COLSPAN="2"><INPUT TYPE="SUBMIT" value="Provision"></TD></TR> +% }  </TABLE>  <%init> @@ -53,34 +58,37 @@ my $did_order = qsearchs( {  } );  die "No order $ordernum" unless $did_order; -die "Order is not in received status and/or DIDs not assigned to a customer" -    unless $did_order->received && $did_order->custnum;  +my @cust_main = $did_order->cust_main; -my $cust_main = qsearchs('cust_main', { custnum => $did_order->custnum } ); -die "invalid customer" unless $cust_main; - -my @pkgs = $cust_main->ncancelled_pkgs; -die "no packages" unless scalar(@pkgs); +die "Order is not in received status and/or DIDs not assigned to any customers" +    unless $did_order->received && scalar(@cust_main);  my @dids = qsearch( 'phone_avail', { ordernum => $ordernum } );  die "no DIDs on order" unless scalar(@dids); -my (%cust_pkg_phone, %cust_pkg_label, %svc_label ); +sub possible_pkgs { +    my $cust_main = shift; +     +    my (%cust_pkg_phone, %cust_pkg_label, %svc_label); + +    my @pkgs = $cust_main->ncancelled_pkgs; +    return (\%cust_pkg_phone,\%cust_pkg_label,\%svc_label) unless scalar(@pkgs); -foreach my $pkg ( @pkgs ) { -    my @avail_part_svc = $pkg->available_part_svc; -    my @svcpart; -    foreach my $avail_part_svc ( @avail_part_svc ) { -        if ($avail_part_svc->svcdb eq 'svc_phone' -                  && $avail_part_svc->num_avail >= scalar(@dids)) { -            push @svcpart, $avail_part_svc->svcpart; -            $svc_label{$avail_part_svc->svcpart} = $avail_part_svc->svc; +    foreach my $pkg ( @pkgs ) { +        my @avail_part_svc = $pkg->available_part_svc; +        my @svcpart; +        foreach my $avail_part_svc ( @avail_part_svc ) { +            if ($avail_part_svc->svcdb eq 'svc_phone' +                      && $avail_part_svc->num_avail >= scalar(@dids)) { +                push @svcpart, $avail_part_svc->svcpart; +                $svc_label{$avail_part_svc->svcpart} = $avail_part_svc->svc; +            }          } +        $cust_pkg_phone{$pkg->pkgnum} = \@svcpart if scalar(@svcpart); +        $cust_pkg_label{$pkg->pkgnum} = $pkg->part_pkg->pkg;      } -    $cust_pkg_phone{$pkg->pkgnum} = \@svcpart if scalar(@svcpart); -    $cust_pkg_label{$pkg->pkgnum} = $pkg->part_pkg->pkg; +     +    (\%cust_pkg_phone,\%cust_pkg_label,\%svc_label);  } -my $avail = keys(%cust_pkg_phone); -  </%init>  | 
