package FS::svc_hardware;
+use base qw( FS::svc_Common );
use strict;
-use base qw( FS::svc_Common );
-use FS::Record qw( qsearch qsearchs );
-use FS::hardware_type;
+use vars qw( $conf );
+use FS::Record qw( qsearchs ); #qsearch qsearchs );
use FS::hardware_status;
+use FS::Conf;
+
+FS::UID->install_callback(sub { $conf = FS::Conf->new; });
=head1 NAME
'name_plural' => 'Hardware',
'display_weight' => 59,
'cancel_weight' => 86,
+ 'manual_require' => 1,
'fields' => {
'svcnum' => { label => 'Service' },
'typenum' => { label => 'Device type',
disable_fixed => 1,
disable_default => 1,
disable_inventory => 1,
+ required => 1,
},
'serial' => { label => 'Serial number', %opts },
'hw_addr' => { label => 'Hardware address', %opts },
my ($class, $string) = @_;
my @where = ();
- my $ip = NetAddr::IP->new($string);
- if ( $ip ) {
- push @where, $class->search_sql_field('ip_addr', $ip->addr);
+ if ( $string =~ /^[\d\.:]+$/ ) {
+ # if the string isn't an IP address, this will waste several seconds
+ # attempting a DNS lookup. so try to filter those out.
+ my $ip = NetAddr::IP->new($string);
+ if ( $ip ) {
+ push @where, $class->search_sql_field('ip_addr', $ip->addr);
+ }
}
if ( $string =~ /^(\w+)$/ ) {
sub label {
my $self = shift;
- $self->serial || $self->hw_addr;
+ my $part_svc = $self->cust_svc->part_svc;
+ my @label = ();
+ if (my $type = $self->hardware_type) {
+ my $typenum_label = $part_svc->part_svc_column('typenum');
+ push @label, ( $typenum_label && $typenum_label->columnlabel || 'Type:' ).
+ $type->description;
+ }
+ if (my $ser = $self->serial) {
+ my $serial_label = $part_svc->part_svc_column('serial');
+ push @label, ( $serial_label && $serial_label->columnlabel || 'Serial#' ).
+ $ser;
+ }
+ if (my $mac = $self->display_hw_addr) {
+ my $hw_addr_label = $part_svc->part_svc_column('hw_addr');
+ push @label, ( $hw_addr_label && $hw_addr_label->columnlabel || 'MAC:').
+ $mac;
+ }
+ return join(', ', @label);
}
=item insert
return $x unless ref $x;
my $hw_addr = $self->getfield('hw_addr');
- $hw_addr = join('', split(/\W/, $hw_addr));
+ $hw_addr = join('', split(/[_\W]/, $hw_addr));
if ( $conf->exists('svc_hardware-check_mac_addr') ) {
$hw_addr = uc($hw_addr);
$hw_addr =~ /^[0-9A-F]{12}$/
$self->SUPER::check;
}
-=item hardware_type
+#false laziness w/svc_cable
+sub _check_duplicate {
+ my $self = shift;
-Returns the L<FS::hardware_type> object associated with this installation.
+ # Not reliable checks because the table isn't locked, but that's why we have
+ # unique indices. These are just to give friendlier error messages.
-=cut
+ if ( $self->hw_addr ) {
+ my @dup_mac;
+ @dup_mac = $self->find_duplicates('global', 'hw_addr');
+ if ( @dup_mac ) {
+ return "Hardware address in use (svcnum ".$dup_mac[0]->svcnum.")";
+ }
+ }
-sub hardware_type {
- my $self = shift;
- return qsearchs('hardware_type', { 'typenum' => $self->typenum });
+ if ( $self->ip_addr ) {
+ my @dup_ip;
+ @dup_ip = $self->find_duplicates('global', 'ip_addr');
+ if ( @dup_ip ) {
+ return "IP address in use (svcnum ".$dup_ip[0]->svcnum.")";
+ }
+ }
+
+ if ( $self->serial ) {
+ my @dup_serial;
+ @dup_serial = $self->find_duplicates('global', 'typenum', 'serial');
+ if ( @dup_serial ) {
+ return "Serial number in use (svcnum ".$dup_serial[0]->svcnum.")";
+ }
+ }
+
+ '';
}
+=item hardware_type
+
+Returns the L<FS::hardware_type> object associated with this installation.
+
=item status_label
Returns the 'label' field of the L<FS::hardware_status> object associated
$status->label;
}
+=item display_hw_addr
+
+Returns the 'hw_addr' field, formatted as a MAC address if the
+'svc_hardware-check_mac_addr' option is enabled.
+
+=cut
+
+sub display_hw_addr {
+ my $self = shift;
+ ($conf->exists('svc_hardware-check_mac_addr') ?
+ join(':', $self->hw_addr =~ /../g) : $self->hw_addr)
+}
+
+sub _upgrade_data {
+
+ require FS::Misc::FixIPFormat;
+ FS::Misc::FixIPFormat::fix_bad_addresses_in_table(
+ 'svc_hardware', 'svcnum', 'ip_addr',
+ );
+
+ '';
+
+}
=back
=cut
1;
-