summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorlevinse <levinse>2010-12-01 05:56:10 +0000
committerlevinse <levinse>2010-12-01 05:56:10 +0000
commitad17d8651adb39fdef45f509490a6b2c6eac8301 (patch)
tree870832dd91871a0356b044f840d364df416150a6 /FS
parentb638e75f063e231edaf3f3859d27f3981c12c999 (diff)
-ikano, svc_dsl, dsl_note, and qual on-going implementation, RT7111
-add predelete_hook_first and predelete_hook into svc_Common (don't use yet, might change or be removed soon) -add new cust_location fields into geocode_Mixin location_hash
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/Schema.pm6
-rw-r--r--FS/FS/dsl_note.pm8
-rw-r--r--FS/FS/geocode_Mixin.pm3
-rw-r--r--FS/FS/part_export/ikano.pm78
-rw-r--r--FS/FS/qual.pm37
-rw-r--r--FS/FS/svc_Common.pm6
-rw-r--r--FS/FS/svc_dsl.pm21
7 files changed, 132 insertions, 27 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index e482bedfa..5f78b51f8 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1685,7 +1685,7 @@ sub tables_hashref {
'prospectnum', 'int', 'NULL', '', '', '',
'locationnum', 'int', 'NULL', '', '', '',
'phonenum', 'varchar', 'NULL', 24, '', '',
- 'exportnum', 'int', '', '', '', '',
+ 'exportnum', 'int', 'NULL', '', '', '',
'vendor_qual_id', 'varchar', 'NULL', $char_d, '', '',
'status', 'char', '', 1, '', '',
],
@@ -1871,9 +1871,9 @@ sub tables_hashref {
'columns' => [
'notenum', 'serial', '', '', '', '',
'svcnum', 'int', '', '', '', '',
- 'by', 'varchar', 'NULL', $char_d, '', '',
+ 'user', 'varchar', 'NULL', $char_d, '', '',
'priority', 'char', 'NULL', 1, '', '',
- 'date', 'int', 'NULL', '', '', '',
+ '_date', 'int', 'NULL', '', '', '',
'note', 'text', '', '', '', '',
],
'primary_key' => 'notenum',
diff --git a/FS/FS/dsl_note.pm b/FS/FS/dsl_note.pm
index 886365b68..0155cbd11 100644
--- a/FS/FS/dsl_note.pm
+++ b/FS/FS/dsl_note.pm
@@ -34,11 +34,11 @@ FS::Record. The following fields are currently supported:
=item svcnum - the DSL for this note, see L<FS::svc_dsl>
-=item by - export-specific, e.g. note's author or ISP vs. telco/vendor
+=item user - export-specific, e.g. note's author or ISP vs. telco/vendor
=item priority - export-specific, e.g. high priority or not; not used by most
-=item date - note date
+=item _date - note date
=item note - the note
@@ -105,9 +105,9 @@ sub check {
my $error =
$self->ut_numbern('notenum')
|| $self->ut_foreign_key('svcnum', 'svc_dsl', 'svcnum')
- || $self->ut_textn('by')
+ || $self->ut_textn('user')
|| $self->ut_alphasn('priority')
- || $self->ut_numbern('date')
+ || $self->ut_numbern('_date')
|| $self->ut_text('note')
;
return $error if $error;
diff --git a/FS/FS/geocode_Mixin.pm b/FS/FS/geocode_Mixin.pm
index c153914f0..d784b5709 100644
--- a/FS/FS/geocode_Mixin.pm
+++ b/FS/FS/geocode_Mixin.pm
@@ -51,7 +51,8 @@ sub location_hash {
map { my $method = ($_ eq 'geocode') ? $_ : $prefix.$_;
$_ => $self->get($method);
}
- qw( address1 address2 city county state zip country geocode );
+ qw( address1 address2 city county state zip country geocode
+ location_type location_number location_kind );
}
=item location_label [ OPTION => VALUE ... ]
diff --git a/FS/FS/part_export/ikano.pm b/FS/FS/part_export/ikano.pm
index 73f962c2c..6316b298d 100644
--- a/FS/FS/part_export/ikano.pm
+++ b/FS/FS/part_export/ikano.pm
@@ -49,10 +49,18 @@ sub dsl_pull {
# 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($self, $svc_dsl, $threshold) = (shift, shift, shift);
$self->loadmod;
my $result = $self->valid_order($svc_dsl,'pull');
return $result unless $result eq '';
+
+ my $now = time;
+ if($now - $svc_dsl->last_pull < $threshold) {
+ warn "$me skipping pull since threshold not reached (svcnum="
+ . $svc_dsl->svcnum . ",now=$now,threshold=$threshold,last_pull="
+ . $svc_dsl->last_pull .")" if $self->option('debug');
+ return '';
+ }
$result = $self->ikano_command('ORDERSTATUS',
{ OrderId => $svc_dsl->vendor_order_id } );
@@ -242,14 +250,68 @@ sub ikano2fsnote {
new FS::dsl_note( {
'svcnum' => $svcnum,
- 'by' => $by,
+ 'user' => $by,
'priority' => $n->{'HighPriority'} eq 'false' ? 'N' : 'H',
- 'date' => int(str2time($n->{'Date'})),
+ '_date' => int(str2time($n->{'Date'})),
'note' => $n->{'Text'},
} );
}
sub qual {
+ my($self,$qual) = (shift,shift);
+# address always required for Ikano qual, TN optional (assume dry if not given)
+
+ my %location_hash = $qual->location;
+ return 'No address provided' unless %location_hash;
+ my $svctn = $qual->phonenum;
+
+ my $result = $self->ikano_command('PREQUAL',
+ { AddressLine1 => $location_hash{address1},
+ AddressUnitType => $location_hash{location_type},
+ AddressUnitValue => $location_hash{location_number},
+ AddressCity => $location_hash{city},
+ AddressState => $location_hash{state},
+ ZipCode => $location_hash{zip},
+ Country => $location_hash{country},
+ LocationType => $location_hash{location_kind},
+ PhoneNumber => length($svctn) > 1 ? $svctn : "STANDALONE",
+ RequestClientIP => '127.0.0.1',
+ CheckNetworks => $self->option('check_networks'),
+ } );
+ return 'Invalid prequal response' unless defined $result->{'PrequalId'};
+
+ my $qoptions = {};
+ # lame data structure traversal...
+ # don't spend much time here, just get TermsId and ProductCustomId
+ my $networks = $result->{'Network'};
+ my @networks = defined $networks ? @$networks : ();
+ my $netcount = 0;
+ foreach my $network ( @networks ) {
+ my $productgroups = $network->{'ProductGroup'};
+ my @productgroups = defined $productgroups ? @$productgroups : ();
+ my $pgcount = 0;
+ foreach my $productgroup ( @productgroups ) {
+ my $prefix = "ikano_Network_$netcount"."_ProductGroup_$pgcount"."_";
+ $qoptions->{$prefix."TermsId"} = $productgroup->{'TermsId'};
+ my $products = $network->{'Product'};
+ my @products = defined $products ? @$products : ();
+ my $prodcount = 0;
+ foreach my $product ( @products ) {
+ $qoptions->{$prefix."Product_$prodcount"."_ProductCustomId"} = $product->{'ProductCustomId'};
+ $prodcount++;
+ }
+ $pgcount++;
+ }
+ $netcount++;
+ }
+
+ { 'vendor_qual_id' => $result->{'PrequalId'},
+ 'status' => scalar(@networks) ? 'Q' : 'D',
+ 'options' => $qoptions,
+ };
+}
+
+sub qual_html {
'';
}
@@ -469,8 +531,14 @@ sub _export_delete {
my $result = $self->ikano_command('CANCEL',
{ OrderId => $svc_dsl->vendor_order_id, } );
return $result unless ref($result); # scalar (string) is an error
-
- return $self->dsl_pull($svc_dsl);
+ return 'Unable to cancel order' unless $result->{'Order'};
+ $result = $result->{'Order'};
+ return 'Invalid cancellation response'
+ unless $result->{'Status'} eq 'CANCELLED'
+ && $result->{'OrderId'} eq $svc_dsl->vendor_order_id;
+
+ # we're supposed to do a pull, but it will break everything, so don't
+ # this is very wrong...
}
else {
return "Cannot cancel a NEW order unless it's in NEW or PENDING status";
diff --git a/FS/FS/qual.pm b/FS/FS/qual.pm
index de0633423..553de136a 100644
--- a/FS/FS/qual.pm
+++ b/FS/FS/qual.pm
@@ -38,10 +38,6 @@ FS::Record. The following fields are currently supported:
=item locationnum
-Either one of these cases must be true:
--locationnum is non-null and prospectnum is null and custnum is null
--locationnum is null and (prospectnum is non-null or custnum is non-null, but not both non-null)
-
=item phonenum - Service Telephone Number
=item exportnum - export instance providing service-qualification capabilities,
@@ -117,25 +113,40 @@ sub check {
|| $self->ut_foreign_keyn('prospectnum', 'prospect_main', 'prospectnum')
|| $self->ut_foreign_keyn('locationnum', 'cust_location', 'locationnum')
|| $self->ut_numbern('phonenum')
- || $self->ut_foreign_key('exportnum', 'part_export', 'exportnum')
+ || $self->ut_foreign_keyn('exportnum', 'part_export', 'exportnum')
|| $self->ut_textn('vendor_qual_id')
|| $self->ut_alpha('status')
;
return $error if $error;
-#Either one of these cases must be true:
-#1. locationnum is non-null and prospectnum is null and custnum is null
-#2. locationnum is null and (prospectnum is non-null or custnum is non-null, but not both non-null)
- return "Invalid prospect/customer/location combination" unless (
- ( $self->locationnum && !$self->prospectcnum && !$self->custnum ) #1
- ||
- ( !$self->locationnum && ( $self->prospectnum || $self->custnum )
- && !( $self->custnum && $self->prospectnum ) ) #2
+ return "Invalid prospect/customer/location combination" if (
+ ( $self->locationnum && $self->prospectnum && $self->custnum ) ||
+ ( !$self->locationnum && !$self->prospectnum && !$self->custnum )
);
$self->SUPER::check;
}
+sub location {
+ my $self = shift;
+ if ( $self->locationnum ) {
+ my $l = qsearchs( 'cust_location',
+ { 'locationnum' => $self->locationnum });
+ return $l->location_hash if $l;
+ }
+ if ( $self->custnum ) {
+ my $c = qsearchs( 'cust_main', { 'custnum' => $self->custnum });
+ return $c->location_hash if $c;
+ }
+ # prospectnum does not imply any particular address! must specify locationnum
+
+ '';
+}
+
+sub status_long {
+
+}
+
=back
=head1 SEE ALSO
diff --git a/FS/FS/svc_Common.pm b/FS/FS/svc_Common.pm
index e0f1e3338..b377642c7 100644
--- a/FS/FS/svc_Common.pm
+++ b/FS/FS/svc_Common.pm
@@ -330,6 +330,8 @@ sub preinsert_hook_first { ''; }
sub _check_duplcate { ''; }
sub preinsert_hook { ''; }
sub table_dupcheck_fields { (); }
+sub predelete_hook { ''; }
+sub predelete_hook_first { ''; }
=item delete [ , OPTION => VALUE ... ]
@@ -356,9 +358,11 @@ sub delete {
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
- my $error = $self->SUPER::delete
+ my $error = $self->predelete_hook_first
+ || $self->SUPER::delete
|| $self->export('delete', @$export_args)
|| $self->return_inventory
+ || $self->predelete_hook
|| $self->cust_svc->delete
;
if ( $error ) {
diff --git a/FS/FS/svc_dsl.pm b/FS/FS/svc_dsl.pm
index 93d357042..c5557ec6f 100644
--- a/FS/FS/svc_dsl.pm
+++ b/FS/FS/svc_dsl.pm
@@ -263,6 +263,27 @@ sub check {
$self->SUPER::check;
}
+sub predelete_hook_first {
+ my $self = shift;
+ my @exports = $self->part_svc->part_export_dsl_pull;
+ return 'More than one DSL-pulling export attached' if scalar(@exports) > 1;
+ if ( scalar(@exports) == 1 ) {
+ my $export = $exports[0];
+ return $export->dsl_pull($self);
+ }
+ '';
+}
+
+sub predelete_hook {
+ my $self = shift;
+ my @notes = $self->notes;
+ foreach my $note ( @notes ) {
+ my $error = $note->delete;
+ return $error if $error;
+ }
+ '';
+}
+
=back
=head1 SEE ALSO