use FS::sales_pkg_class;
use FS::svc_alarm;
use FS::cable_model;
+ use FS::invoice_mode;
+ use FS::invoice_conf;
++ use FS::cable_provider;
# Sammath Naur
if ( $FS::Mason::addl_handler_use ) {
sub is_encrypted {
my ($self, $value) = @_;
-- # Possible Bug - Some work may be required here....
--
-- if ($value =~ /^M/ && length($value) > 80) {
-- return 1;
-- } else {
-- return 0;
-- }
++ # could be more precise about it, but this will do for now
++ $value =~ /^M/ && length($value) > 80;
}
=item decrypt($value)
'svc_cable' => {
'columns' => [
'svcnum', 'int', '', '', '', '',
++ 'providernum', 'int', 'NULL', '', '', '',
++ # XXX "Circuit ID/Order number"
'modelnum', 'int', 'NULL', '', '', '',
'serialnum', 'varchar', 'NULL', $char_d, '', '',
'mac_addr', 'varchar', 'NULL', 12, '', '',
'index' => [],
},
++ 'cable_provider' => {
++ 'columns' => [
++ 'providernum', 'serial', '', '', '', '',
++ 'provider', 'varchar', '', $char_d, '', '',
++ 'disabled', 'char', 'NULL', 1, '', '',
++ ],
++ 'primary_key' => 'providernum',
++ 'unique' => [ [ 'provider' ], ],
++ 'index' => [],
++ },
++
'vend_main' => {
'columns' => [
'vendnum', 'serial', '', '', '', '',
--- /dev/null
--- /dev/null
++package FS::cable_provider;
++
++use strict;
++use base qw( FS::Record );
++use FS::Record qw( qsearch qsearchs );
++
++=head1 NAME
++
++FS::cable_provider - Object methods for cable_provider records
++
++=head1 SYNOPSIS
++
++ use FS::cable_provider;
++
++ $record = new FS::cable_provider \%hash;
++ $record = new FS::cable_provider { 'column' => 'value' };
++
++ $error = $record->insert;
++
++ $error = $new_record->replace($old_record);
++
++ $error = $record->delete;
++
++ $error = $record->check;
++
++=head1 DESCRIPTION
++
++An FS::cable_provider object represents a cable service provider.
++FS::cable_provider inherits from FS::Record. The following fields are
++currently supported:
++
++=over 4
++
++=item providernum
++
++primary key
++
++=item provider
++
++provider
++
++=item disabled
++
++disabled
++
++
++=back
++
++=head1 METHODS
++
++=over 4
++
++=item new HASHREF
++
++Creates a new provider. To add the provider 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
++
++# the new method can be inherited from FS::Record, if a table method is defined
++
++sub table { 'cable_provider'; }
++
++=item insert
++
++Adds this record to the database. If there is an error, returns the error,
++otherwise returns false.
++
++=item delete
++
++Delete this record from the database.
++
++=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.
++
++=item check
++
++Checks all fields to make sure this is a valid provider. If there is
++an error, returns the error, otherwise returns false. Called by the insert
++and replace methods.
++
++=cut
++
++sub check {
++ my $self = shift;
++
++ my $error =
++ $self->ut_numbern('providernum')
++ || $self->ut_text('provider')
++ || $self->ut_enum('disabled', [ '', 'Y' ] )
++ ;
++ return $error if $error;
++
++ $self->SUPER::check;
++}
++
++=back
++
++=head1 BUGS
++
++=head1 SEE ALSO
++
++L<FS::Record>, schema.html from the base documentation.
++
++=cut
++
++1;
++
=item cust_svc [ OPTION => VALUE ... ] (current usage)
++=item cust_svc_unsorted [ OPTION => VALUE ... ]
++
Returns the services for this package, as FS::cust_svc objects (see
L<FS::cust_svc>). Available options are svcpart and svcdb. If either is
spcififed, returns only the matching services.
++As an optimization, use the cust_svc_unsorted version if you are not displaying
++the results.
++
=cut
sub cust_svc {
my $self = shift;
++ cluck "cust_pkg->cust_svc called" if $DEBUG > 2;
++ $self->_sort_cust_svc( $self->cust_svc_unsorted_arrayref );
++}
++
++sub cust_svc_unsorted {
++ my $self = shift;
++ @{ $self->cust_svc_unsorted_arrayref };
++}
++
++sub cust_svc_unsorted_arrayref {
++ my $self = shift;
return () unless $self->num_cust_svc(@_);
$search{extra_sql} = ' AND svcdb = '. dbh->quote( $opt{'svcdb'} );
}
-- cluck "cust_pkg->cust_svc called" if $DEBUG > 2;
--
-- #if ( $self->{'_svcnum'} ) {
-- # values %{ $self->{'_svcnum'}->cache };
-- #} else {
-- $self->_sort_cust_svc( [ qsearch(\%search) ] );
-- #}
++ [ qsearch(\%search) ];
}
}
sub pkg_age_age {
-- my( $self, $cust_pkg, %opt );
++ my( $self, $cust_pkg, %opt ) = @_;
$self->option_age_from('age', $opt{'time'} );
}
<LI><code>$uid</code> - of catchall account
<LI><code>$gid</code> - of catchall account
<LI><code>$dir</code> - home directory of catchall account
-- <LI>All other fields in
-- <a href="../docs/schema.html#svc_domain">svc_domain</a> are also available.
++ <LI>All other fields in <b>svc_domain</b> are also available.
</UL>
END
);
<LI><code>$shell</code>
<LI><code>$quota</code>
<LI><code>@radius_groups</code>
-- <LI>All other fields in <a href="../docs/schema.html#svc_acct">svc_acct</a> are also available.
++ <LI><code>$reasonnum (when suspending)</code>
++ <LI><code>$reasontext (when suspending)</code>
++ <LI><code>$reasontypenum (when suspending)</code>
++ <LI><code>$reasontypetext (when suspending)</code>
++ <LI><code>$pkgnum</code>
++ <LI><code>$custnum</code>
++ <LI>All other fields in <b>svc_acct</b> are also available.
++ <LI>The following fields from <b>cust_main</b> are also available (except during replace): company, address1, address2, city, state, zip, county, daytime, night, fax, otaker, agent_custid, locale. When used on the command line (rather than STDIN), they will be quoted for the shell already (do not add additional quotes).
++</UL>
++For the package changed command only, the following fields are also available:
++<UL>
++ <LI>$old_pkgnum and $new_pkgnum
++ <LI>$old_pkgpart and $new_pkgpart
++ <LI>$old_agent_pkgid and $new_agent_pkgid
++ <LI>$old_order_date and $new_order_date
++ <LI>$old_start_date and $new_start_date
++ <LI>$old_setup and $new_setup
++ <LI>$old_bill and $new_bill
++ <LI>$old_last_bill and $new_last_bill
++ <LI>$old_susp and $new_susp
++ <LI>$old_adjourn and $new_adjourn
++ <LI>$old_resume and $new_resume
++ <LI>$old_cancel and $new_cancel
++ <LI>$old_unancel and $new_unancel
++ <LI>$old_expire and $new_expire
++ <LI>$old_contract_end and $new_contract_end
</UL>
END
);
use strict;
use Tie::IxHash;
use FS::Record qw( qsearchs ); # qw( qsearch qsearchs );
++use FS::cable_provider;
use FS::cable_model;
=head1 NAME
sub table_info {
tie my %fields, 'Tie::IxHash',
-- 'svcnum' => 'Service',
-- 'modelnum' => { label => 'Model',
-- type => 'select-cable_model',
-- disable_inventory => 1,
-- disable_select => 1,
-- value_callback => sub {
-- my $svc = shift;
-- $svc->cable_model->model_name;
-- },
-- },
-- 'serialnum' => 'Serial number',
-- 'mac_addr' => { label => 'MAC address',
-- type => 'input-mac_addr',
-- value_callback => sub {
-- my $svc = shift;
-- join(':', $svc->mac_addr =~ /../g);
-- },
-- },
++ 'svcnum' => 'Service',
++ 'providernum' => { label => 'Provider',
++ type => 'select-cable_provider',
++ disable_inventory => 1,
++ disable_select => 1,
++ value_callback => sub {
++ my $svc = shift;
++ my $p = $svc->cable_provider;
++ $p ? $p->provider : '';
++ },
++ },
++ #XXX "Circuit ID/Order number"
++ 'modelnum' => { label => 'Model',
++ type => 'select-cable_model',
++ disable_inventory => 1,
++ disable_select => 1,
++ value_callback => sub {
++ my $svc = shift;
++ $svc->cable_model->model_name;
++ },
++ },
++ 'serialnum' => 'Serial number',
++ 'mac_addr' => { label => 'MAC address',
++ type => 'input-mac_addr',
++ value_callback => sub {
++ my $svc = shift;
++ join(':', $svc->mac_addr =~ /../g);
++ },
++ },
;
{
my $error =
$self->ut_numbern('svcnum')
++ || $self->ut_foreign_key('providernum', 'cable_provider', 'providernum')
|| $self->ut_foreign_key('modelnum', 'cable_model', 'modelnum')
|| $self->ut_alpha('serialnum')
|| $self->ut_mac_addr('mac_addr')
$self->SUPER::check;
}
++=item cable_provider
++
++Returns the cable_provider object for this record.
++
++=cut
++
++sub cable_provider {
++ my $self = shift;
++ qsearchs('cable_provider', { 'providernum'=>$self->providernum } );
++}
++
=item cable_model
Returns the cable_model object for this record.
t/svc_alarm.t
FS/cable_model.pm
t/cable_model.t
+ FS/invoice_mode.pm
+ t/invoice_mode.t
+ FS/invoice_conf.pm
+ t/invoice_conf.t
++FS/cable_provider.pm
++t/cable_provider.t
--- /dev/null
--- /dev/null
++BEGIN { $| = 1; print "1..1\n" }
++END {print "not ok 1\n" unless $loaded;}
++use FS::cable_provider;
++$loaded=1;
++print "ok 1\n";
my @conditions = $part_event->part_event_condition;
foreach my $condition ( @conditions ) {
-- my $sat = $condition->condition( $object, 'cust_event' => $cust_event );
++ my $sat = $condition->condition( $object,
++ 'cust_event' => $cust_event,
++ 'time' => time,
++ );
my $sql = $condition->condition_sql();
--- /dev/null
--- /dev/null
++<& elements/browse.html,
++ 'title' => 'Cable providers',
++ 'html_init' => $html_init,
++ 'name' => 'providers',
++ 'disableable' => 1,
++ 'disabled_statuspos' => 1,
++ 'query' => { 'table' => 'cable_provider',
++ 'hashref' => {},
++ 'order_by' => 'ORDER BY provider',
++ },
++ 'count_query' => $count_query,
++ 'header' => $header,
++ 'fields' => $fields,
++ 'links' => $links,
++&>
++<%init>
++
++die "access denied"
++ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
++
++my $html_init =
++ qq!<A HREF="${p}edit/cable_provider.html"><I>Add a provider</I></A><BR><BR>!;
++
++my $count_query = 'SELECT COUNT(*) FROM cable_provider';
++
++my $link = [ $p.'edit/cable_provider.html?', 'providernum' ];
++
++my $header = [ 'Provider' ];
++my $fields = [ 'provider' ];
++my $links = [ $link ];
++
++</%init>
% unless ( $agentnum ) {
<CENTER>
-- <FONT SIZE="-3">"I can't figure out ... if it's an end or the beginning" - R. Hunter</FONT>
++ <FONT SIZE="-3">"" - R. Hunter</FONT>
</CENTER>
% }
--- /dev/null
--- /dev/null
++<& elements/edit.html,
++ 'name_singular' => 'Provider',
++ 'table' => 'cable_provider',
++ 'fields' => [
++ 'provider',
++ { field=>'disabled', type=>'checkbox', value=>'Y', },
++ ],
++ 'labels' => {
++ 'providernum' => 'Provider',
++ 'provider' => 'Provider',
++ 'disabled' => 'Disabled',
++ },
++ 'viewall_dir' => 'browse',
++&>
++<%init>
++
++die "access denied"
++ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
++
++</%init>
--- /dev/null
--- /dev/null
++<& elements/process.html,
++ 'table' => 'cable_provider',
++ 'viewall_dir' => 'browse',
++&>
++<%init>
++
++die "access denied"
++ unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
++
++</%init>
;
tie my %config_cable, 'Tie::IxHash',
++ 'Cable providers' => [ $fsurl.'browse/cable_provider.html', '' ],
'Cable modem models' => [ $fsurl.'browse/cable_model.html', '' ],
;
--- /dev/null
--- /dev/null
++<% include( '/elements/select-table.html',
++ 'table' => 'cable_provider',
++ 'name_col' => 'provider',
++ 'empty_label' => 'Select provider',
++ @_,
++ )
++%>
--- /dev/null
--- /dev/null
++% #if ( scalar(@domains) < 2 ) {
++% #} else {
++ <TR>
++ <TD ALIGN="right"><% $opt{'label'} || 'Provider' %></TD>
++ <TD>
++ <% include( '/elements/select-cable_provider.html', %opt) %>
++ </TD>
++ </TR>
++% #}
++<%init>
++ my %opt = @_;
++</%init>
% if ( $br ) {
<BR><BR>
% }
--</%doc>
%my $signupurl = $conf->config('signupurl');
%if ( $signupurl ) {
if (grep $_ eq 'Requestor' || $_ eq 'Requestors', @{ $args{ARGSRef}->{'SkipNotification'} || [] }) {
push @txn_squelch, map $_->address, Email::Address->parse( $message_args->{Requestor} );
push @txn_squelch, $args{TicketObj}->Requestors->MemberEmailAddresses;
--
}
push @txn_squelch, @{$args{ARGSRef}{SquelchMailTo}} if $args{ARGSRef}{SquelchMailTo};
}
}
++sub ProcessAttachments {
++ my %args = (
++ ARGSRef => {},
++ @_
++ );
++
++ my $ARGSRef = $args{ARGSRef} || {};
++ # deal with deleting uploaded attachments
++ foreach my $key ( keys %$ARGSRef ) {
++ if ( $key =~ m/^DeleteAttach-(.+)$/ ) {
++ delete $session{'Attachments'}{$1};
++ }
++ $session{'Attachments'} = { %{ $session{'Attachments'} || {} } };
++ }
++
++ # store the uploaded attachment in session
++ if ( defined $ARGSRef->{'Attach'} && length $ARGSRef->{'Attach'} )
++ { # attachment?
++ my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' );
++
++ my $file_path = Encode::decode_utf8("$ARGSRef->{'Attach'}");
++ $session{'Attachments'} =
++ { %{ $session{'Attachments'} || {} }, $file_path => $attachment, };
++ }
++
++ # delete temporary storage entry to make WebUI clean
++ unless ( keys %{ $session{'Attachments'} } and $ARGSRef->{'UpdateAttach'} )
++ {
++ delete $session{'Attachments'};
++ }
++}
++
++
=head2 MakeMIMEEntity PARAMHASH
Takes a paramhash Subject, Body and AttachmentFieldName.
}
--sub ProcessAttachments {
-- my %args = (
-- ARGSRef => {},
-- @_
-- );
--
-- my $ARGSRef = $args{ARGSRef} || {};
-- # deal with deleting uploaded attachments
-- foreach my $key ( keys %$ARGSRef ) {
-- if ( $key =~ m/^DeleteAttach-(.+)$/ ) {
-- delete $session{'Attachments'}{$1};
-- }
-- $session{'Attachments'} = { %{ $session{'Attachments'} || {} } };
-- }
--
-- # store the uploaded attachment in session
-- if ( defined $ARGSRef->{'Attach'} && length $ARGSRef->{'Attach'} )
-- { # attachment?
-- my $attachment = MakeMIMEEntity( AttachmentFieldName => 'Attach' );
--
-- my $file_path = Encode::decode_utf8("$ARGSRef->{'Attach'}");
-- $session{'Attachments'} =
-- { %{ $session{'Attachments'} || {} }, $file_path => $attachment, };
-- }
--
-- # delete temporary storage entry to make WebUI clean
-- unless ( keys %{ $session{'Attachments'} } and $ARGSRef->{'UpdateAttach'} )
-- {
-- delete $session{'Attachments'};
-- }
--}
=head2 ParseDateToISO
my %squelched = ProcessTransactionSquelching( \%ARGS );
$ARGS{'SquelchMailTo'} = [keys %squelched] if keys %squelched;
++warn @{ $ARGS{'SquelchMailTo'} } if $ARGS{'SquelchMailTo'};
my $CFs = $TicketObj->TransactionCustomFields;
my $ValidCFs = $m->comp(
);
$checks_failure = 1 unless $status;
}
++warn @{ $ARGS{'SquelchMailTo'} } if $ARGS{'SquelchMailTo'};
# check email addresses for RT's
{