respect part_svc labels in svc_hardware & svc_cable short service labels, RT#73405
[freeside.git] / FS / FS / svc_cable.pm
1 package FS::svc_cable;
2 use base qw( FS::MAC_Mixin
3              FS::svc_Common
4            ); #FS::device_Common
5
6 use strict;
7 use Tie::IxHash;
8
9 =head1 NAME
10
11 FS::svc_cable - Object methods for svc_cable records
12
13 =head1 SYNOPSIS
14
15   use FS::svc_cable;
16
17   $record = new FS::svc_cable \%hash;
18   $record = new FS::svc_cable { 'column' => 'value' };
19
20   $error = $record->insert;
21
22   $error = $new_record->replace($old_record);
23
24   $error = $record->delete;
25
26   $error = $record->check;
27
28 =head1 DESCRIPTION
29
30 An FS::svc_cable object represents a cable subscriber.  FS::svc_cable inherits
31 from FS::Record.  The following fields are currently supported:
32
33 =over 4
34
35 =item svcnum
36
37 primary key
38
39 =back
40
41 =head1 METHODS
42
43 =over 4
44
45 =item new HASHREF
46
47 Creates a new record.  To add the record to the database, see L<"insert">.
48
49 Note that this stores the hash reference, not a distinct copy of the hash it
50 points to.  You can ask the object for a copy with the I<hash> method.
51
52 =cut
53
54 sub table { 'svc_cable'; }
55
56 sub table_dupcheck_fields { ( 'serialnum', 'mac_addr' ); }
57
58 sub search_sql {
59   my( $class, $string ) = @_;
60   if ( $string =~ /^([A-F0-9]{12})$/i ) {
61     $class->search_sql_field('mac_addr', uc($string));
62   } elsif ( $string =~ /^(([A-F0-9]{2}:){5}([A-F0-9]{2}))$/i ) {
63     $string =~ s/://g;
64     $class->search_sql_field('mac_addr', uc($string) );
65   } elsif ( $string =~ /^(\w+)$/ ) {
66     $class->search_sql_field('serialnum', $1);
67   } else {
68     '1 = 0'; #false
69   }
70 }
71
72 sub table_info {
73
74   tie my %fields, 'Tie::IxHash',
75     'svcnum'      => 'Service',
76     'providernum' => { label             => 'Provider',
77                        type              => 'select-cable_provider',
78                        disable_inventory => 1,
79                        disable_select    => 1,
80                        value_callback    => sub {
81                                               my $svc = shift;
82                                               my $p = $svc->cable_provider;
83                                               $p ? $p->provider : '';
84                                             },
85                      },
86     'ordernum'    => 'Order number', #XXX "Circuit ID/Order number"
87     'modelnum'    => { label             => 'Model',
88                        type              => 'select-cable_model',
89                        disable_inventory => 1,
90                        disable_select    => 1,
91                        value_callback    => sub {
92                                               my $svc = shift;
93                                               $svc->cable_model->model_name;
94                                             },
95                      },
96     'serialnum'   => 'Serial number',
97     'mac_addr'    => { label          => 'MAC address',
98                        type           => 'input-mac_addr',
99                        value_callback => sub {
100                                            my $svc = shift;
101                                            $svc->mac_addr_formatted('U',':');
102                                          },
103                      },
104   ;
105
106   {
107     'name'            => 'Cable Subscriber',
108     #'name_plural'     => '', #optional,
109     #'longname_plural' => '', #optional
110     'fields'          => \%fields,
111     'sorts'           => [ 'svcnum', 'serialnum', 'mac_addr', ],
112     'display_weight'  => 54,
113     'cancel_weight'   => 70, #?  no deps, so
114   };
115 }
116
117 =item label
118
119 Returns the MAC address and serial number.
120
121 =cut
122
123 sub label {
124   my $self = shift;
125   my $part_svc = $self->cust_svc->part_svc;
126   my @label = ();
127   push @label, 'MAC:'. $self->mac_addr_pretty
128     if $self->mac_addr;
129   push @label, ($part_svc->part_svc_column('serialnum') || 'Serial#').
130                $self->serialnum
131     if $self->serialnum;
132   return join(', ', @label);
133 }
134
135 =item insert
136
137 Adds this record to the database.  If there is an error, returns the error,
138 otherwise returns false.
139
140 =item delete
141
142 Delete this record from the database.
143
144 =item replace OLD_RECORD
145
146 Replaces the OLD_RECORD with this one in the database.  If there is an error,
147 returns the error, otherwise returns false.
148
149 =item check
150
151 Checks all fields to make sure this is a valid record.  If there is
152 an error, returns the error, otherwise returns false.  Called by the insert
153 and replace methods.
154
155 =cut
156
157 sub check {
158   my $self = shift;
159
160   my $error = 
161        $self->ut_numbern('svcnum')
162     || $self->ut_foreign_keyn('providernum', 'cable_provider', 'providernum')
163     || $self->ut_alphan('ordernum')
164     || $self->ut_foreign_key('modelnum', 'cable_model', 'modelnum')
165     || $self->ut_alphan('serialnum')
166     || $self->ut_mac_addrn('mac_addr')
167   ;
168   return $error if $error;
169
170   $self->SUPER::check;
171 }
172
173 sub _check_duplicate {
174   my $self = shift;
175
176   # Not reliable checks because the table isn't locked, but that's why we have
177   # unique indices.  These are just to give friendlier error messages.
178
179   if ( $self->mac_addr ) {
180     my @dup_mac;
181     @dup_mac = $self->find_duplicates('global', 'mac_addr');
182     if ( @dup_mac ) {
183       return "MAC address in use (svcnum ".$dup_mac[0]->svcnum.")";
184     }
185   }
186
187   if ( $self->serialnum ) {
188     my @dup_serial;
189     @dup_serial = $self->find_duplicates('global', 'serialnum');
190     if ( @dup_serial ) {
191       return "Serial number in use (svcnum ".$dup_serial[0]->svcnum.")";
192     }
193   }
194
195   '';
196 }
197
198 =item cable_provider
199
200 Returns the cable_provider object for this record.
201
202 =item cable_model
203
204 Returns the cable_model object for this record.
205
206 =back
207
208 =head1 BUGS
209
210 =head1 SEE ALSO
211
212 L<FS::Record>, schema.html from the base documentation.
213
214 =cut
215
216 1;
217