+sub provision_phone {
+ my $p = shift;
+ my @bulkdid;
+ @bulkdid = @{$p->{'bulkdid'}} if $p->{'bulkdid'};
+
+ if($p->{'svcnum'} && $p->{'svcnum'} =~ /^\d+$/){
+ my($context, $session, $custnum) = _custoragent_session_custnum($p);
+ return { 'error' => $session } if $context eq 'error';
+
+ my $svc_phone = qsearchs('svc_phone', { svcnum => $p->{'svcnum'} });
+ return { 'error' => 'service not found' } unless $svc_phone;
+ return { 'error' => 'invalid svcnum' }
+ if $svc_phone && $svc_phone->cust_svc->cust_pkg->custnum != $custnum;
+
+ $svc_phone->email($p->{'email'})
+ if $svc_phone->email ne $p->{'email'} && $p->{'email'} =~ /^([\w\.\d@]+|)$/;
+ $svc_phone->forwarddst($p->{'forwarddst'})
+ if $svc_phone->forwarddst ne $p->{'forwarddst'}
+ && $p->{'forwarddst'} =~ /^(\d+|)$/;
+ return { 'error' => $svc_phone->replace };
+ }
+
+# single DID LNP
+ unless($p->{'lnp'}) {
+ $p->{'lnp_desired_due_date'} = parse_datetime($p->{'lnp_desired_due_date'});
+ $p->{'lnp_status'} = "portingin";
+ return _provision( 'FS::svc_phone',
+ [qw(lnp_desired_due_date lnp_other_provider
+ lnp_other_provider_account phonenum countrycode lnp_status)],
+ [qw(phonenum countrycode)],
+ $p,
+ @_
+ );
+ }
+
+# single DID order
+ unless (scalar(@bulkdid)) {
+ return _provision( 'FS::svc_phone',
+ [qw(phonenum countrycode)],
+ [qw(phonenum countrycode)],
+ $p,
+ @_
+ );
+ }
+
+# bulk DID order case
+ my $error;
+ foreach my $did ( @bulkdid ) {
+ $did =~ s/[^0-9]//g;
+ $error = _provision( 'FS::svc_phone',
+ [qw(phonenum countrycode)],
+ [qw(phonenum countrycode)],
+ {
+ 'pkgnum' => $p->{'pkgnum'},
+ 'svcpart' => $p->{'svcpart'},
+ 'phonenum' => $did,
+ 'countrycode' => $p->{'countrycode'},
+ 'session_id' => $p->{'session_id'},
+ }
+ );
+ return $error if ($error->{'error'} && length($error->{'error'}) > 1);
+ }
+ { 'bulkdid' => [ @bulkdid ], 'svc' => $error->{'svc'} }
+}
+