diff options
author | Christopher Burger <burgerc@freeside.biz> | 2018-11-29 14:50:50 -0500 |
---|---|---|
committer | Christopher Burger <burgerc@freeside.biz> | 2018-11-29 14:50:50 -0500 |
commit | 901c65cbf43e17a59a80d52ca01d1ac1628a856a (patch) | |
tree | db4e780ec770b34773658342b0d13a5f1cfa2ffa /FS/FS | |
parent | 289c2643882c611a068fffd06e42e258264844e8 (diff) | |
parent | aad287228dfbe5ef01be73ebaaa9a06dfbe11226 (diff) |
Merge branch 'master' of ssh://git.freeside.biz/home/git/freeside
Diffstat (limited to 'FS/FS')
-rw-r--r-- | FS/FS/Mason.pm | 1 | ||||
-rw-r--r-- | FS/FS/Record.pm | 31 | ||||
-rw-r--r-- | FS/FS/Schema.pm | 34 | ||||
-rw-r--r-- | FS/FS/cust_svc.pm | 6 | ||||
-rw-r--r-- | FS/FS/h_svc_group.pm | 29 | ||||
-rw-r--r-- | FS/FS/part_event/Action.pm | 2 | ||||
-rw-r--r-- | FS/FS/part_event/Action/notice_to.pm | 7 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/cust_birthdate.pm | 10 | ||||
-rw-r--r-- | FS/FS/part_event_option.pm | 38 | ||||
-rw-r--r-- | FS/FS/part_pkg/voip_cdr.pm | 4 | ||||
-rw-r--r-- | FS/FS/svc_group.pm | 203 |
11 files changed, 344 insertions, 21 deletions
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm index 7f883de..5b8242b 100644 --- a/FS/FS/Mason.pm +++ b/FS/FS/Mason.pm @@ -423,6 +423,7 @@ if ( -e $addl_handler_use_file ) { use FS::svc_realestate; use FS::saved_search; use FS::sector_coverage; + use FS::svc_group; # Sammath Naur if ( $FS::Mason::addl_handler_use ) { diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 9eb1c9a..b24b69e 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -25,6 +25,7 @@ use FS::Schema qw(dbdef); use FS::SearchCache; use FS::Msgcat qw(gettext); #use FS::Conf; #dependency loop bs, in install_callback below instead +use Email::Valid; use FS::part_virtual_field; @@ -3364,6 +3365,36 @@ sub ut_agentnum_acl { } + +=item ut_email COLUMN + +Check column contains a valid E-Mail address + +=cut + +sub ut_email { + my ( $self, $field ) = @_; + Email::Valid->address( $self->getfield( $field ) ) + ? '' + : "Illegal (email) field $field: ". $self->getfield( $field ); +} + +=item ut_emailn COLUMN + +Check column contains a valid E-Mail address + +May be null + +=cut + +sub ut_emailn { + my ( $self, $field ) = @_; + + $self->getfield( $field ) =~ /^$/ + ? $self->getfield( $field, '' ) + : $self->ut_email( $field ); +} + =item trim_whitespace FIELD[, FIELD ... ] Strip leading and trailing spaces from the value in the named FIELD(s). diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 169d22a..7cc84a9 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -7666,11 +7666,11 @@ sub tables_hashref { ], }, - realestate_location => { + 'realestate_location' => { 'columns' => [ 'realestatelocnum', 'serial', '', '', '', '', 'agentnum', 'int', 'NULL', '', '', '', - 'location_title', 'varchar', '', $char_d, '', '', + 'location_title', 'varchar', '', $char_d, '', '', 'address1', 'varchar', 'NULL', $char_d, '', '', 'address2', 'varchar', 'NULL', $char_d, '', '', 'city', 'varchar', 'NULL', $char_d, '', '', @@ -7678,23 +7678,39 @@ sub tables_hashref { 'zip', 'char', 'NULL', 5, '', '', 'disabled', 'char', 'NULL', 1, '', '', ], - primary_key => 'realestatelocnum', - 'unique' => [ ['location_title'] ], - 'index' => [ ['agentnum'], ['disabled'] ], + 'primary_key' => 'realestatelocnum', + 'unique' => [ ['location_title'] ], + 'index' => [ ['agentnum'], ['disabled'] ], 'foreign_keys' => [ {columns => ['agentnum'], table => 'agent'}, ], }, - svc_realestate => { - columns => [ + 'svc_realestate' => { + 'columns' => [ 'svcnum', 'serial', '', '', '', '', 'realestatenum', 'int', 'NULL', '', '', '', ], - primary_key => 'svcnum', - index => [], + 'primary_key' => 'svcnum', + 'index' => [], + }, + + 'svc_group' => { + 'columns' => [ + 'svcnum', 'int', '', '', '', '', + 'max_accounts', 'int', '', '', '', '', + ], + 'primary_key' => 'svcnum', + 'unique' => [], + 'index' => [], + 'foreign_keys' => [ + { columns => [ 'svcnum' ], + table => 'cust_svc', + }, + ], }, + # name type nullability length default local #'new_table' => { diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm index 4aa7504..9e16142 100644 --- a/FS/FS/cust_svc.pm +++ b/FS/FS/cust_svc.pm @@ -453,8 +453,10 @@ sub replace { #my $error = $new->SUPER::replace($old, @_); my $error = $new->SUPER::replace($old); - #trigger a relocate export on location changes - if ( $new->cust_pkg->locationnum != $old->cust_pkg->locationnum ) { + #trigger a relocate export on location changes (NENA2 and Northern 911 export) + my $old_pkg = $old->cust_pkg; + my $new_pkg = $new->cust_pkg; + if ( $old_pkg && $new_pkg && $new_pkg->locationnum != $old_pkg->locationnum ) { my $svc_x = $new->svc_x; if ( $svc_x->locationnum ) { if ( $svc_x->locationnum == $old->cust_pkg->locationnum ) { diff --git a/FS/FS/h_svc_group.pm b/FS/FS/h_svc_group.pm new file mode 100644 index 0000000..7da4a8a --- /dev/null +++ b/FS/FS/h_svc_group.pm @@ -0,0 +1,29 @@ +package FS::h_svc_group; + +use strict; +use base qw( FS::h_Common FS::svc_group ); + +sub table { 'h_svc_group' }; + +=head1 NAME + +FS::h_svc_group - Historical installed group service objects + +=head1 SYNOPSIS + +=head1 DESCRIPTION + +An FS::h_svc_group object represents a historical group service. +FS::h_svc_group inherits from FS::h_Common and FS::svc_group. + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::h_Common>, L<FS::svc_group>, L<FS::Record>, schema.html from the base +documentation. + +=cut + +1; + diff --git a/FS/FS/part_event/Action.pm b/FS/FS/part_event/Action.pm index c0c70b1..1916e40 100644 --- a/FS/FS/part_event/Action.pm +++ b/FS/FS/part_event/Action.pm @@ -85,6 +85,8 @@ hashref with the following values: =item size - Size for text fields +=item validation - (optional) Validate optionvalue using the given object method, such as ut_textn, ut_email + =item options - For checkbox-multiple and select, a list reference of available option values. =item option_labels - For select, a hash reference of availble option values and labels. diff --git a/FS/FS/part_event/Action/notice_to.pm b/FS/FS/part_event/Action/notice_to.pm index dee293b..565d169 100644 --- a/FS/FS/part_event/Action/notice_to.pm +++ b/FS/FS/part_event/Action/notice_to.pm @@ -21,9 +21,10 @@ sub eventtable_hashref { sub option_fields { ( - 'to' => { 'label' => 'Destination', - 'type' => 'text', - 'size' => 30, + 'to' => { 'label' => 'Destination', + 'type' => 'text', + 'size' => 30, + 'validation' => 'ut_email', }, 'msgnum' => { 'label' => 'Template', 'type' => 'select-table', diff --git a/FS/FS/part_event/Condition/cust_birthdate.pm b/FS/FS/part_event/Condition/cust_birthdate.pm index 874e3ac..e8ecb06 100644 --- a/FS/FS/part_event/Condition/cust_birthdate.pm +++ b/FS/FS/part_event/Condition/cust_birthdate.pm @@ -16,13 +16,13 @@ birthday (cust_main.birthdate) =cut sub description { - 'Customer birthdate occurs within the given timeframe'; + 'Customer birthday is within time window after billing date'; } sub option_fields { ( timeframe => { - label => 'Timeframe', + label => 'Time window after bill date', type => 'freq', value => '1m', } @@ -43,8 +43,10 @@ sub condition { die "Unparsable timeframe given: ".$self->option('timeframe'); } - my $ck_dt = DateTime->from_epoch( epoch => $opt{time} ); - my $bd_dt = DateTime->from_epoch( epoch => $birthdate ); + my $ck_dt = DateTime->from_epoch( epoch => $opt{time} ) + ->truncate( to => 'day' ); + my $bd_dt = DateTime->from_epoch( epoch => $birthdate ) + ->truncate( to => 'day' ); # Find the birthday for this calendar year. If customer birthday # has already passed this year, find the birthday for next year. diff --git a/FS/FS/part_event_option.pm b/FS/FS/part_event_option.pm index 6df9e84..1421f6f 100644 --- a/FS/FS/part_event_option.pm +++ b/FS/FS/part_event_option.pm @@ -183,11 +183,19 @@ sub check { $self->ut_numbern('optionnum') || $self->ut_foreign_key('eventpart', 'part_event', 'eventpart' ) || $self->ut_text('optionname') - #|| $self->ut_textn('optionvalue') || $self->ut_anything('optionvalue') #http.pm content has \n ; return $error if $error; + if ( my %option_fields = $self->option_fields ) { + if ( my $option_field = $option_fields{ $self->optionname } ) { + if ( my $validation_method = $option_field->{validation} ) { + $error = $self->$validation_method('optionvalue'); + } + } + } + return $error if $error; + $self->SUPER::check; } @@ -203,6 +211,34 @@ sub insert_reason { } +=item part_event + +Return the associated part_event row + +=cut + +sub part_event { + qsearchs( part_event => { eventpart => shift->eventpart }) +} + +=item option_fields + +Return the option_fields from the associated part_event::action::$action + +=cut + +sub option_fields { + my $part_event = shift->part_event + or return; + my $action = $part_event->action + or return; + + # For utility scripts, doesn't seem to be necessary + # eval "require FS::part_event::Action::$action;"; + + return "FS::part_event::Action::$action"->option_fields; +} + =back =head1 SEE ALSO diff --git a/FS/FS/part_pkg/voip_cdr.pm b/FS/FS/part_pkg/voip_cdr.pm index 522e4aa..49e43e9 100644 --- a/FS/FS/part_pkg/voip_cdr.pm +++ b/FS/FS/part_pkg/voip_cdr.pm @@ -674,9 +674,9 @@ sub check_chargable { and length($cdr->max_callers) and $cdr->max_callers <= $self->option_cacheable('skip_max_callers'); - return "calldate < ". str2time($self->option_cacheable('skip_old')) + return "calldate < ". $self->option_cacheable('skip_old') if $self->option_cacheable('skip_old') - && $self->calldate_unix < str2time($self->option_cacheable('skip_old')); + && $cdr->calldate_unix < str2time($self->option_cacheable('skip_old')); #all right then, rate it ''; diff --git a/FS/FS/svc_group.pm b/FS/FS/svc_group.pm new file mode 100644 index 0000000..8d77893 --- /dev/null +++ b/FS/FS/svc_group.pm @@ -0,0 +1,203 @@ +package FS::svc_group; +use base qw( FS::svc_Common ); + +use strict; +#use FS::Record qw( qsearch qsearchs ); +#use FS::cust_svc; + +=head1 NAME + +FS::svc_group - Object methods for svc_group records + +=head1 SYNOPSIS + + use FS::svc_group; + + $record = new FS::svc_group \%hash; + $record = new FS::svc_group { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + + $error = $record->suspend; + + $error = $record->unsuspend; + + $error = $record->cancel; + +=head1 DESCRIPTION + +An FS::svc_group object represents a group. FS::svc_group inherits from +FS::svc_Common. The following fields are currently supported: + +=over 4 + +=item max_accounts - Maximum number of group members + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new group. To add the group 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<hash> method. + +=cut + +sub table { 'svc_group'; } + +sub table_info { + { + 'name' => 'Group', + 'name_plural' => 'Groups', #optional, + 'longname_plural' => 'Groups', #optional + 'sorts' => 'svcnum', # optional sort field (or arrayref of sort fields, main first) + 'display_weight' => 100, + 'cancel_weight' => 100, + 'fields' => { + 'svcnum' => { label => 'Service' }, + 'max_accounts' => { + 'label' => 'Maximum number of accounts', + 'type' => 'text', + 'disable_inventory' => 1, + }, + + }, + }; +} + +=item search_sql STRING + +Class method which returns an SQL fragment to search for the given string. + +=cut + +#if we only have a quantity, then there's nothing to search on except svcnum +sub search_sql { + my($class, $string) = @_; + $class->search_sql_field('svcnum', $string); +} + + +=item label + +Returns a meaningful identifier for this group + +=cut + +sub label { + my $self = shift; + $self->svcnum; #i guess? +} + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be +defined. An FS::cust_svc record will be created and inserted. + +=cut + +#sub insert { +# my $self = shift; +# my $error; +# +# $error = $self->SUPER::insert; +# return $error if $error; +# +# ''; +#} + +=item delete + +Delete this record from the database. + +=cut + +#sub delete { +# my $self = shift; +# my $error; +# +# $error = $self->SUPER::delete; +# return $error if $error; +# +# ''; +#} + + +=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 + +#sub replace { +# my ( $new, $old ) = ( shift, shift ); +# my $error; +# +# $error = $new->SUPER::replace($old); +# return $error if $error; +# +# ''; +#} + +=item suspend + +Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>). + +=item unsuspend + +Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>). + +=item cancel + +Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>). + +=item check + +Checks all fields to make sure this is a valid group. If there is +an error, returns the error, otherwise returns false. Called by the insert +and repalce methods. + +=cut + +sub check { + my $self = shift; + + my $x = $self->setfixed; + return $x unless ref($x); + my $part_svc = $x; + + my $error = $self->ut_numbern('svcnum') + || $self->ut_number('max_accounts'); + return $error if $error; + + $self->SUPER::check; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::svc_Common>, L<FS::Record>, L<FS::cust_svc>, L<FS::part_svc>, +L<FS::cust_pkg>, schema.html from the base documentation. + +=cut + +1; + |