diff options
| author | levinse <levinse> | 2010-11-29 05:27:02 +0000 | 
|---|---|---|
| committer | levinse <levinse> | 2010-11-29 05:27:02 +0000 | 
| commit | 136200fb9ff797ea0ca44c00b5070129f35f47ce (patch) | |
| tree | 1f3739760f9dcf409ee21ae73c02b634880ab439 | |
| parent | 1594e450be1c4f0c9f9a2d98ab72c714a4695bdc (diff) | |
ikano.pm near-finished pull, finished order notes, RT7111
| -rw-r--r-- | FS/FS/part_export/ikano.pm | 158 | ||||
| -rw-r--r-- | httemplate/view/svc_dsl.cgi | 2 | 
2 files changed, 106 insertions, 54 deletions
diff --git a/FS/FS/part_export/ikano.pm b/FS/FS/part_export/ikano.pm index f162f2523..91953e320 100644 --- a/FS/FS/part_export/ikano.pm +++ b/FS/FS/part_export/ikano.pm @@ -4,9 +4,10 @@ use vars qw(@ISA %info %orderType %orderStatus %loopType $DEBUG $me);  use Tie::IxHash;  use Date::Format qw( time2str );  use Date::Parse qw( str2time ); -use FS::Record qw(qsearch qsearchs); +use FS::Record qw(qsearch qsearchs dbh);  use FS::part_export;  use FS::svc_dsl; +use FS::dsl_note;  use Data::Dumper;  @ISA = qw(FS::part_export); @@ -47,6 +48,12 @@ sub rebless { shift; }  sub dsl_pull {  # we distinguish between invalid new data (return error) versus data that  # has legitimately changed (may eventually execute hooks; now just update) +# if we do add hooks later, we should work on a copy of svc_dsl and pass +# the old and new svc_dsl to the hooks so they know what changed +# +# current assumptions of what won't change (from their side): +# vendor_order_id, vendor_qual_id, vendor_order_type, pushed, monitored, +# last_pull, address (from qual), contact info, ProductCustomId      my($self, $svc_dsl) = (shift, shift);      my $result = $self->valid_order($svc_dsl,'pull'); @@ -64,31 +71,25 @@ sub dsl_pull {      return 'No order id or status returned'   	unless defined $result->{'Status'} && defined $result->{'OrderId'}; - -    # update this always (except in the above cases), even if error later -    $svc_dsl->last_pull((time)); -    local $FS::svc_Common::noexport_hack = 1; -    local $FS::UID::AutoCommit = 1; -    my $error = $svc_dsl->replace;  -    return 'Error updating last pull time' if $error; - -    # let's compare what we have to what we got back... -  -    # current assumptions of what won't change (from their side): -    # vendor_order_id, vendor_qual_id, vendor_order_type, pushed, monitored, -    # last_pull, address (from qual), contact info, ProductCustomId - -    my $wechanged = 0; +	 +    local $SIG{HUP} = 'IGNORE'; +    local $SIG{INT} = 'IGNORE'; +    local $SIG{QUIT} = 'IGNORE'; +    local $SIG{TERM} = 'IGNORE'; +    local $SIG{TSTP} = 'IGNORE'; +    local $SIG{PIPE} = 'IGNORE'; + +    my $oldAutoCommit = $FS::UID::AutoCommit; +    local $FS::UID::AutoCommit = 0; +    my $dbh = dbh;      # 1. status       my $new_order_status = $self->orderstatus_long2short($result->{'Status'});      return 'Invalid new status' if $new_order_status eq '';      if($svc_dsl->vendor_order_status ne $new_order_status) { -	if($new_order_status eq 'X' || $new_order_status eq 'C') { -	    $svc_dsl->monitored(''); -	} +	$svc_dsl->monitored('')  +	    if ($new_order_status eq 'X' || $new_order_status eq 'C');  	$svc_dsl->vendor_order_status($new_order_status); -	$wechanged = 1;      }      # 2. fields we don't care much about @@ -99,10 +100,8 @@ sub dsl_pull {  		    'password' => 'Password' );      while (($fsf, $ikanof) = each %justUpdate) { -       if ( $result->{$ikanof} ne $svc_dsl->$fsf ) { -	    $svc_dsl->$fsf($result->{$ikanof}); -	    $wechanged = 1; -	} +       $svc_dsl->$fsf($result->{$ikanof})  +	    if $result->{$ikanof} ne $svc_dsl->$fsf;      }      # let's look inside the <Product> response element @@ -112,20 +111,19 @@ sub dsl_pull {      # 3. phonenum       if($svc_dsl->loop_type eq '') { # line-share -	# TN may change only if sub changes it and  -	# New or Change order in Completed status +# TN may change only if sub changes it and New or Change order in Completed status  	my $tn = $product->{'PhoneNumber'};  	if($tn ne $svc_dsl->phonenum) {  	    if( ($svc_dsl->vendor_order_type eq 'N'   		|| $svc_dsl->vendor_order_type eq 'C')  	       && $svc_dsl->vendor_order_status eq 'C' ) {  		$svc_dsl->phonenum($tn); -		$wechanged = 1;  	    }  	    else { return 'TN has changed in an invalid state'; }  	}      }      elsif($svc_dsl->loop_type eq '0') { # dry loop +# TN may change only if it's assigned while a New or Change order is in progress  	return 'Invalid PhoneNumber value for a dry loop'   	    if $product->{'PhoneNumber'} ne 'STANDALONE';  	my $tn = $product->{'VirtualPhoneNumber'}; @@ -135,8 +133,8 @@ sub dsl_pull {  	      && $svc_dsl->vendor_order_status ne 'C'  	      && $svc_dsl->vendor_order_status ne 'X') {  		$svc_dsl->phonenum($tn); -		$wechanged = 1;  	    } +	    else { return 'TN has changed in an invalid state'; }  	}      } @@ -145,32 +143,23 @@ sub dsl_pull {  	    || $svc_dsl->vendor_order_type eq 'C'){  	my $f = str2time($product->{'DateToOrder'});  	return 'Invalid DateToOrder' unless $f; -	if ( $svc_dsl->desired_due_date != $f ) { -	    $svc_dsl->desired_due_date($f); -	    $wechanged = 1; -	} +	$svc_dsl->desired_due_date($f) if $svc_dsl->desired_due_date != $f;  	# XXX: optionally sync back to start_date or whatever...       }      elsif($svc_dsl->vendor_order_type eq 'X'){  	my $f = str2time($product->{'DateToDisconnect'});  	return 'Invalid DateToDisconnect' unless $f; -	if ( $svc_dsl->desired_due_date != $f ) { -	    $svc_dsl->desired_due_date($f); -	    $wechanged = 1; -	} +	$svc_dsl->desired_due_date($f) if $svc_dsl->desired_due_date != $f;  	# XXX: optionally sync back to expire or whatever...       } -    # 4. due_date +    # 5. due_date      if($svc_dsl->vendor_order_type eq 'N'    	  || $svc_dsl->vendor_order_type eq 'C') {  	my $f = str2time($product->{'ActivationDate'});  	if($svc_dsl->vendor_order_status ne 'N') {  	    return 'Invalid ActivationDate' unless $f; -	    if( $svc_dsl->due_date != $f ) { -		$svc_dsl->due_date($f); -		$wechanged = 1; -	    } +	    $svc_dsl->due_date($f) if $svc_dsl->due_date != $f;  	}      }      # Ikano API does not implement the proper disconnect date, @@ -180,27 +169,90 @@ sub dsl_pull {      my @statics = $result->{'StaticIps'};  # XXX -    # 7. notes - put them into the common format: -    # "by" = 0 for Ikano; 1 for ISP -    # "priority" = 1 for high priority; 0 otherwise -    my @notes = $result->{'OrderNotes'};  -# XXX - -    if($wechanged) { # you can't check ->modified, the replace above screws it -	# noexport_hack and AutoCommit are set correctly above -	$result = $svc_dsl->replace;  -	return 'Error updating DSL data' if $result; +    # 7. notes - put them into the common format and compare +    my $tnotes = $result->{'OrderNotes'};  +    my @tnotes = @$tnotes; +    my @inotes = (); # all Ikano OrderNotes as FS::dsl_note objects +    my $notesChanged = 0;  +    foreach $tnote ( @tnotes ) { +	my $inote = $self->ikano2fsnote($tnote,$svc_dsl->svcnum); +	return 'Cannot parse note' unless ref($inote); +	push @inotes, $inote; +    } +    my @onotes = $svc_dsl->notes; +    # assume notes we already have don't change & no notes added from our side +    # so using the horrible code below just find what we're missing and add it +    my $error; +    foreach $inote ( @inotes ) { +	my $found = 0; +	foreach $onote ( @onotes ) { +	    if($onote->date == $inote->date && $onote->note eq $inote->note) { +		$found = 1; +		last; +	    } +	} +	$error = $inote->insert unless ( $found ); +	if ( $error ) { +	  $dbh->rollback if $oldAutoCommit; +	  return "Cannot add note: $error"; +	} +    } +     +    $svc_dsl->last_pull((time)); +    local $FS::svc_Common::noexport_hack = 1; +    $error = $svc_dsl->replace;  +    if ( $error ) { +      $dbh->rollback if $oldAutoCommit; +      return "Cannot update DSL data: $error";      } +    $dbh->commit or die $dbh->errstr if $oldAutoCommit; +      '';  } +sub ikano2fsnote { +    my($self,$n,$svcnum) = (shift,shift,shift); +    my @ikanoRequired = qw( HighPriority StaffId Date Text CompanyStaffId ); +    return '' unless defined $n->{'HighPriority'} +		&& defined $n->{'StaffId'} +		&& defined $n->{'CompanyStaffId'} +		&& defined $n->{'Date'} +		&& defined $n->{'Text'} +		; +    my $by = 'Unknown'; +    $by = "Ikano" if $n->{'CompanyStaffId'} == -1 && $n->{'StaffId'} != -1; +    $by = "Us" if $n->{'StaffId'} == -1 && $n->{'CompanyStaffId'} != -1; + +    $fsnote = new FS::dsl_note( { +	'svcnum' => $svcnum, +	'by' => $by, +	'priority' => $n->{'HighPriority'} eq 'false' ? 'N' : 'H', +	'date' => int(str2time($n->{'Date'})), +	'note' => $n->{'Text'}, +     } ); +} +  sub qual {      '';  } -sub notes_html { -    ''; +sub notes_html {  +    my($self,$svc_dsl) = (shift,shift); +    my $conf = new FS::Conf; +    my $date_format = $conf->config('date_format') || '%m/%d/%Y'; +    my @notes = $svc_dsl->notes; +    my $html = '<TABLE border="1" cellspacing="2" cellpadding="2" id="dsl_notes"> +	<TR><TH>Date</TH><TH>By</TH><TH>Priority</TH><TH>Note</TH></TR>'; +    foreach $note ( @notes ) { +	$html .= "<TR> +	    <TD>".time2str("$date_format %H:%M",$note->date)."</TD> +	    <TD>".$note->by."</TD> +	    <TD>". ($note->priority eq 'N' ? 'Normal' : 'High') ."</TD> +	    <TD>".$note->note."</TD></TR>"; +    } +    $html .= '</TABLE>'; +    $html;  }  sub loop_type_long { # sub, not a method diff --git a/httemplate/view/svc_dsl.cgi b/httemplate/view/svc_dsl.cgi index 1107d46c8..14c1eb26d 100644 --- a/httemplate/view/svc_dsl.cgi +++ b/httemplate/view/svc_dsl.cgi @@ -57,6 +57,6 @@ my $svc_cb = sub {      # else add any other export-specific stuff here      $footer = "<B>".$export->status_line($svc_x)."</B>"; -    $footer .= "<BR><BR><BR>Order Notes:<BR>".$export->notes_html($svc_x); +    $footer .= "<BR><BR><BR><B>Order Notes:</B><BR>".$export->notes_html($svc_x);  };  </%init>  | 
