From 19f2731dbceb444c5dd45f57fb0a785dcaf9aa65 Mon Sep 17 00:00:00 2001 From: levinse Date: Wed, 8 Dec 2010 21:37:45 +0000 Subject: [PATCH] -rename qual export sub to part_export, RT7111 -initial commit of part_pkg_vendor implementation, RT7111 --- FS/FS.pm | 2 + FS/FS/Mason.pm | 1 + FS/FS/Schema.pm | 12 +++ FS/FS/part_export/ikano.pm | 2 + FS/FS/part_pkg.pm | 85 +++++++++++++++++++++ FS/FS/part_pkg_vendor.pm | 140 +++++++++++++++++++++++++++++++++++ FS/FS/qual.pm | 2 +- FS/MANIFEST | 2 + FS/t/part_pkg_vendor.t | 5 ++ httemplate/edit/process/part_pkg.cgi | 10 +++ httemplate/elements/tr-pkg_svc.html | 39 ++++++++++ httemplate/search/qual.cgi | 2 +- httemplate/view/qual.cgi | 2 +- 13 files changed, 301 insertions(+), 3 deletions(-) create mode 100644 FS/FS/part_pkg_vendor.pm create mode 100644 FS/t/part_pkg_vendor.t diff --git a/FS/FS.pm b/FS/FS.pm index f9061f1d2..2b86b6150 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -211,6 +211,8 @@ L - Package definition option class L - Package reporting classification class +L - Package external mapping class + L - Class linking package definitions (see L) with service definitions (see L) diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index c13207474..3b46d77bc 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -262,6 +262,7 @@ if ( -e $addl_handler_use_file ) { use FS::qual; use FS::qual_option; use FS::dsl_note; + use FS::part_pkg_vendor; # Sammath Naur if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 7cccc7fdc..48363ce31 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2323,6 +2323,18 @@ sub tables_hashref { 'index' => [ [ 'pkgpart' ], [ 'optionname' ] ], }, + 'part_pkg_vendor' => { + 'columns' => [ + 'num', 'serial', '', '', '', '', + 'pkgpart', 'int', '', '', '', '', + 'exportnum', 'int', '', '', '', '', + 'vendor_pkg_id', 'varchar', '', $char_d, '', '', + ], + 'primary_key' => 'num', + 'unique' => [ [ 'pkgpart', 'exportnum' ] ], + 'index' => [ [ 'pkgpart' ] ], + }, + 'part_pkg_report_option' => { 'columns' => [ 'num', 'serial', '', '', '', '', diff --git a/FS/FS/part_export/ikano.pm b/FS/FS/part_export/ikano.pm index afed6f426..30e2bac7f 100644 --- a/FS/FS/part_export/ikano.pm +++ b/FS/FS/part_export/ikano.pm @@ -40,6 +40,8 @@ END sub rebless { shift; } +sub external_pkg_map { 1; } + sub dsl_pull { # we distinguish between invalid new data (return error) versus data that # has legitimately changed (may eventually execute hooks; now just update) diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 98bb74cab..46067d1ee 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -275,6 +275,23 @@ sub insert { } } + if ( $options{'part_pkg_vendor'} ) { + my($exportnum,$vendor_pkg_id); + my %options_part_pkg_vendor = $options{'part_pkg_vendor'}; + while(($exportnum,$vendor_pkg_id) = each %options_part_pkg_vendor){ + my $ppv = new FS::part_pkg_vendor( { + 'pkgpart' => $self->pkgpart, + 'exportnum' => $exportnum, + 'vendor_pkg_id' => $vendor_pkg_id, + } ); + my $error = $ppv->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error inserting part_pkg_vendor record: $error"; + } + } + } + warn " commiting transaction" if $DEBUG; $dbh->commit or die $dbh->errstr if $oldAutoCommit; @@ -432,6 +449,51 @@ sub replace { return $error; } } + + my @part_pkg_vendor = $old->part_pkg_vendor; + my @current_exportnum = (); + if ( $options->{'part_pkg_vendor'} ) { + my($exportnum,$vendor_pkg_id); + while ( ($exportnum,$vendor_pkg_id) + = each %{$options->{'part_pkg_vendor'}} ) { + my $replaced = 0; + foreach my $part_pkg_vendor ( @part_pkg_vendor ) { + if($exportnum == $part_pkg_vendor->exportnum + && $vendor_pkg_id ne $part_pkg_vendor->vendor_pkg_id) { + $part_pkg_vendor->vendor_pkg_id($vendor_pkg_id); + my $error = $part_pkg_vendor->replace; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error replacing part_pkg_vendor record: $error"; + } + $replaced = 1; + last; + } + } + unless ( $replaced ) { + my $ppv = new FS::part_pkg_vendor( { + 'pkgpart' => $new->pkgpart, + 'exportnum' => $exportnum, + 'vendor_pkg_id' => $vendor_pkg_id, + } ); + my $error = $ppv->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error inserting part_pkg_vendor record: $error"; + } + } + push @current_exportnum, $exportnum; + } + } + foreach my $part_pkg_vendor ( @part_pkg_vendor ) { + unless ( grep($_ eq $part_pkg_vendor->exportnum, @current_exportnum) ) { + my $error = $part_pkg_vendor->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error deleting part_pkg_vendor record: $error"; + } + } + } warn " commiting transaction" if $DEBUG; $dbh->commit or die $dbh->errstr if $oldAutoCommit; @@ -885,6 +947,29 @@ sub plandata { } } +=item part_pkg_vendor + +Returns all vendor/external package ids as FS::part_pkg_vendor objects (see +L). + +=cut + +sub part_pkg_vendor { + my $self = shift; + qsearch('part_pkg_vendor', { 'pkgpart' => $self->pkgpart } ); +} + +=item vendor_pkg_ids + +Returns a list of vendor/external package ids by exportnum + +=cut + +sub vendor_pkg_ids { + my $self = shift; + map { $_->exportnum => $_->vendor_pkg_id } $self->part_pkg_vendor; +} + =item part_pkg_option Returns all options as FS::part_pkg_option objects (see diff --git a/FS/FS/part_pkg_vendor.pm b/FS/FS/part_pkg_vendor.pm new file mode 100644 index 000000000..6b91f7535 --- /dev/null +++ b/FS/FS/part_pkg_vendor.pm @@ -0,0 +1,140 @@ +package FS::part_pkg_vendor; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs ); + +=head1 NAME + +FS::part_pkg_vendor - Object methods for part_pkg_vendor records + +=head1 SYNOPSIS + + use FS::part_pkg_vendor; + + $record = new FS::part_pkg_vendor \%hash; + $record = new FS::part_pkg_vendor { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::part_pkg_vendor object represents a mapping of pkgpart numbers to +external package numbers. FS::part_pkg_vendor inherits from FS::Record. +The following fields are currently supported: + +=over 4 + +=item num + +primary key + +=item pkgpart + +pkgpart + +=item exportnum + +exportnum + +=item vendor_pkg_id + +vendor_pkg_id + + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new example. To add the example 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 method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'part_pkg_vendor'; } + +=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 example. 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('num') + || $self->ut_foreign_key('pkgpart', 'part_pkg', 'pkgpart') + || $self->ut_foreign_key('exportnum', 'part_export', 'exportnum') + || $self->ut_textn('vendor_pkg_id') + ; + return $error if $error; + + $self->SUPER::check; +} + +=item part_export + +Returns the L associated with this vendor/external package id. + +=cut +sub part_export { + my $self = shift; + qsearchs( 'part_export', { 'exportnum' => $self->exportnum } ); +} + +=back + +=head1 SEE ALSO + +L, L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/FS/qual.pm b/FS/FS/qual.pm index 1bc339796..23a827224 100644 --- a/FS/FS/qual.pm +++ b/FS/FS/qual.pm @@ -127,7 +127,7 @@ sub check { $self->SUPER::check; } -sub export { +sub part_export { my $self = shift; if ( $self->exportnum ) { return qsearchs('part_export', { exportnum => $self->exportnum } ) diff --git a/FS/MANIFEST b/FS/MANIFEST index b58b58e20..edf8673c0 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -548,3 +548,5 @@ FS/qual_option.pm t/qual_option.t FS/dsl_note.pm t/dsl_note.t +FS/part_pkg_vendor.pm +t/part_pkg_vendor.t diff --git a/FS/t/part_pkg_vendor.t b/FS/t/part_pkg_vendor.t new file mode 100644 index 000000000..46a9c7949 --- /dev/null +++ b/FS/t/part_pkg_vendor.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_pkg_vendor; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/edit/process/part_pkg.cgi b/httemplate/edit/process/part_pkg.cgi index 724880190..27f07e617 100755 --- a/httemplate/edit/process/part_pkg.cgi +++ b/httemplate/edit/process/part_pkg.cgi @@ -131,6 +131,16 @@ my $args_callback = sub { 'custnum_ref' => \$custnum; } + my %part_pkg_vendor; + foreach my $param ( $cgi->param ) { + if ( $param =~ /^export(\d+)$/ && length($cgi->param($param)) > 0 ) { + $part_pkg_vendor{$1} = $cgi->param($param); + } + } + if ( keys %part_pkg_vendor > 0 ) { + push @args, 'part_pkg_vendor' => \%part_pkg_vendor; + } + #warn "args: ".join('/', @args). "\n"; @args; diff --git a/httemplate/elements/tr-pkg_svc.html b/httemplate/elements/tr-pkg_svc.html index 66bbddfda..6d17a376d 100644 --- a/httemplate/elements/tr-pkg_svc.html +++ b/httemplate/elements/tr-pkg_svc.html @@ -31,6 +31,11 @@ % } elsif ( $pkg_svc->quantity ) { % $quan = $pkg_svc->quantity; % } +% +% my @exports = $pkg_svc->part_svc->part_export; +% foreach my $export ( @exports ) { +% push @possible_exports, $export if $export->can('external_pkg_map'); +% } @@ -62,6 +67,32 @@ +% if ( scalar(@possible_exports) > 0 || scalar(@mapped_exports) > 0 ) { + + + + +% foreach my $export ( @mapped_exports ) { + + + + +% } +% foreach my $export ( @possible_exports ) { +% unless ( defined $vendor_pkg_ids{$export->exportnum} ) { + + + + +% } +% } +
ExportVendor Package Id (blank to delete)
<% $export->exportname %> +
<% $export->exportname %> + +
+% } + @@ -97,4 +128,12 @@ my @fixups = (); my $count = 0; my $columns = 3; +my @possible_exports = (); +my @mapped_exports = (); +my @part_pkg_vendor = $part_pkg->part_pkg_vendor; +foreach my $part_pkg_vendor ( @part_pkg_vendor ) { + push @mapped_exports, $part_pkg_vendor->part_export; +} +my %vendor_pkg_ids = $part_pkg->vendor_pkg_ids; + diff --git a/httemplate/search/qual.cgi b/httemplate/search/qual.cgi index 0bb455b3c..cf4f3d111 100755 --- a/httemplate/search/qual.cgi +++ b/httemplate/search/qual.cgi @@ -43,7 +43,7 @@ }, sub { my $self = shift; - my $export = $self->export; + my $export = $self->part_export; my $result = '(manual)'; $result = $export->exportname if $export; $result; diff --git a/httemplate/view/qual.cgi b/httemplate/view/qual.cgi index c440baeaf..8ab0032ad 100644 --- a/httemplate/view/qual.cgi +++ b/httemplate/view/qual.cgi @@ -60,6 +60,6 @@ $location_kind = "Residential" if $cust_location->get('location_kind') eq 'R'; $location_kind = "Business" if $cust_location->get('location_kind') eq 'B'; my $cust_or_prospect = $qual->cust_or_prospect; -my $export = $qual->export; +my $export = $qual->part_export; -- 2.11.0