summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/inventory_item.pm83
-rw-r--r--httemplate/misc/inventory_item-import.html20
-rw-r--r--httemplate/misc/process/inventory_item-import.html27
-rw-r--r--httemplate/search/inventory_class.html49
-rw-r--r--httemplate/search/inventory_item.html25
5 files changed, 188 insertions, 16 deletions
diff --git a/FS/FS/inventory_item.pm b/FS/FS/inventory_item.pm
index 5312d95f1..23bacf040 100644
--- a/FS/FS/inventory_item.pm
+++ b/FS/FS/inventory_item.pm
@@ -2,8 +2,9 @@ package FS::inventory_item;
use strict;
use vars qw( @ISA );
-use FS::Record qw( qsearch qsearchs );
+use FS::Record qw( dbh qsearch qsearchs );
use FS::inventory_class;
+use FS::cust_svc;
@ISA = qw(FS::Record);
@@ -105,20 +106,96 @@ sub check {
$self->ut_numbern('itemnum')
|| $self->ut_foreign_key('classnum', 'inventory_class', 'classnum' )
|| $self->ut_text('item')
- || $self->ut_numbern('svcnum')
+ || $self->ut_foreign_keyn('svcnum', 'cust_svc', 'svcnum' )
;
return $error if $error;
$self->SUPER::check;
}
+=item cust_svc
+
+Returns the customer service associated with this inventory item, if the
+item has been used (see L<FS::cust_svc>).
+
+=cut
+
+sub cust_svc {
+ my $self = shift;
+ return '' unless $self->svcnum;
+ qsearchs( 'cust_svc', { 'svcnum' => $self->svcnum } );
+}
+
+=back
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item batch_import
+
+=cut
+
+sub batch_import {
+ my $param = shift;
+
+ my $fh = $param->{filehandle};
+
+ my $imported = 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;
+
+ my $line;
+ while ( defined($line=<$fh>) ) {
+
+ chomp $line;
+
+ my $inventory_item = new FS::inventory_item {
+ 'classnum' => $param->{'classnum'},
+ 'item' => $line,
+ };
+
+ my $error = $inventory_item->insert;
+
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+
+ #or just skip?
+ #next;
+ }
+
+ $imported++;
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+ #might want to disable this if we skip records for any reason...
+ return "Empty file!" unless $imported;
+
+ '';
+
+}
+
=back
=head1 BUGS
+maybe batch_import should be a regular method in FS::inventory_class
+
=head1 SEE ALSO
-L<FS::Record>, schema.html from the base documentation.
+L<inventory_class>, L<cust_svc>, L<FS::Record>, schema.html from the base
+documentation.
=cut
diff --git a/httemplate/misc/inventory_item-import.html b/httemplate/misc/inventory_item-import.html
new file mode 100644
index 000000000..a702fbc49
--- /dev/null
+++ b/httemplate/misc/inventory_item-import.html
@@ -0,0 +1,20 @@
+<%
+
+my $classnum = $cgi->param('classnum');
+$classnum =~ /^(\d+)$/ or eidiot "illegal classnum $classnum";
+$classnum = $1;
+my $inventory_class = qsearchs('inventory_class', { 'classnum' => $classnum } );
+
+%><%= include("/elements/header.html", $inventory_class->classname. 's') %>
+
+<FORM ACTION="process/inventory_item-import.html" METHOD="POST" ENCTYPE="multipart/form-data">
+<INPUT TYPE="hidden" NAME="classnum" VALUE="<%= $classnum %>">
+Import a file containing <%= $inventory_class->classname %>s, one per line.<BR><BR>
+
+Filename: <INPUT TYPE="file" NAME="filename"><BR><BR>
+
+<INPUT TYPE="submit" VALUE="Upload">
+</FORM>
+
+<%= include('/elements/footer.html') %>
+
diff --git a/httemplate/misc/process/inventory_item-import.html b/httemplate/misc/process/inventory_item-import.html
new file mode 100644
index 000000000..8a58203c2
--- /dev/null
+++ b/httemplate/misc/process/inventory_item-import.html
@@ -0,0 +1,27 @@
+<%
+
+ my $fh = $cgi->upload('filename');
+
+ my $error = defined($fh)
+ ? FS::inventory_item::batch_import( {
+ 'filehandle' => $fh,
+ 'classnum' => $cgi->param('classnum'),
+ } )
+ : 'No file';
+
+ if ( $error ) {
+ %>
+ <!-- mason kludge -->
+ <%
+ eidiot($error);
+# $cgi->param('error', $error);
+# print $cgi->redirect( "${p}cust_main-import.cgi
+ } else {
+ %>
+ <!-- mason kludge -->
+ <%= include("/elements/header.html",'Import sucessful') %>
+ <!-- XXX redirect to batch search like the payment entry... -->
+ <%= include("/elements/footer.html",'Import sucessful') %> <%
+ }
+%>
+
diff --git a/httemplate/search/inventory_class.html b/httemplate/search/inventory_class.html
index 1bf1bcbce..37735f3c9 100644
--- a/httemplate/search/inventory_class.html
+++ b/httemplate/search/inventory_class.html
@@ -5,11 +5,18 @@ tie my %labels, 'Tie::IxHash',
'num_used' => 'In use', #'Used', #'Allocated',
'num_total' => 'Total',
;
-my %inv_action_link = (
- 'num_avail' => 'eventually'
+
+my %link = (
+ 'num_avail' => ';avail=1',
+ 'num_used' => ';avail=1',
+ 'num_total' => '',
);
-my %inv_action_label = (
- 'num_avail' => 'upload_batch'
+
+my %inv_action_link = (
+ 'num_avail' => [ 'upload batch',
+ $p.'misc/inventory_item-import.html?classnum=',
+ 'classnum'
+ ],
);
my $link = [ "${p}edit/inventory_class.html?", 'classnum' ];
@@ -29,20 +36,44 @@ my $link = [ "${p}edit/inventory_class.html?", 'classnum' ];
#my $inventory_class = shift;
my $i_c = shift;
+ my $link =
+ $p. 'search/inventory_item.html?'.
+ 'classnum='. $i_c->classnum;
+
+ my %actioncol = ();
+ foreach ( keys %inv_action_link ) {
+ my($label, $baseurl, $method) =
+ @{ $inv_action_link{$_} };
+ my $url = $baseurl. $i_c->$method();
+ $actioncol{$_} =
+ '<FONT SIZE="-1">'.
+ '('.
+ '<A HREF="'.$url.'">'.
+ $label.
+ '</A>'.
+ ')'.
+ '</FONT>';
+ }
+
+ my %num = map {
+ $_ => $i_c->$_();
+ } keys %labels;
+
[ map {
[
{
- 'data' => '<B>'. $i_c->$_(). '</B>',
+ 'data' => '<B>'. $num{$_}. '</B>',
'align' => 'right',
},
{
'data' => $labels{$_},
'align' => 'left',
- },
- { 'data' => ( exists($inv_action_link{$_})
- ? '<FONT SIZE="-1">(<A HREF="'. $inv_action_link{$_}. '">'. $inv_action_label{$_}. '</A>)</FONT>'
- : ''
+ 'link' => ( $num{$_}
+ ? $link.$link{$_}
+ : ''
),
+ },
+ { 'data' => $actioncol{$_},
'align' => 'left',
},
]
diff --git a/httemplate/search/inventory_item.html b/httemplate/search/inventory_item.html
index ff7f1fadf..bd74f5619 100644
--- a/httemplate/search/inventory_item.html
+++ b/httemplate/search/inventory_item.html
@@ -1,15 +1,31 @@
<%
my $classnum = $cgi->param('classnum');
-$classnum =~ /^(\d+)$/ or eidiot "illegal agentnum $agentnum";
+$classnum =~ /^(\d+)$/ or eidiot "illegal classnum $classnum";
$classnum = $1;
-my $inventory_class = qsearchs('inventory_class', { 'classnum' => $classnum } );
+
+my $inventory_class = qsearchs( {
+ 'table' => 'inventory_class',
+ 'hashref' => { 'classnum' => $classnum },
+} );
+
+my $title = $inventory_class->classname. ' Inventory';
+
+#little false laziness with SQL fragments in inventory_class.pm
+my $extra_sql = '';
+if ( $cgi->param('avail') ) {
+ $extra_sql = 'AND ( svcnum IS NULL OR svcnum = 0 )';
+ $title .= ' - Available';
+} elsif ( $cgi->param('used') ) {
+ $extra_sql = 'AND svcnum IS NOT NULL AND svcnum > 0';
+ $title .= ' - In use';
+}
my $count_query =
- "SELECT COUNT(*) FROM inventory_class WHERE classnum = $classnum";
+ "SELECT COUNT(*) FROM inventory_item WHERE classnum = $classnum $extra_sql";
%><%= include( 'elements/search.html',
- 'title' => $inventory_class->classname. ' Inventory',
+ 'title' => $title,
#less lame to use Lingua:: something to pluralize
'name' => $inventory_class->classname. 's',
@@ -17,6 +33,7 @@ my $count_query =
'query' => {
'table' => 'inventory_item',
'hashref' => { 'classnum' => $classnum },
+ 'extra_sql' => $extra_sql,
},
'count_query' => $count_query,