use Tie::IxHash;
use FS::Conf;
use FS::Record qw( qsearch qsearchs dbh dbdef );
+use FS::Cursor; # for upgrade
use FS::pkg_svc;
use FS::part_svc;
use FS::cust_pkg;
use FS::agent_type;
use FS::type_pkgs;
use FS::part_pkg_option;
+use FS::part_pkg_fcc_option;
+use FS::pkg_class;
+use FS::agent;
use FS::part_pkg_msgcat;
use FS::part_pkg_taxrate;
use FS::part_pkg_taxoverride;
}
}
+ if ( $options{fcc_options} ) {
+ warn " updating fcc options " if $DEBUG;
+ $self->process_fcc_options( $options{fcc_options} );
+ }
+
warn " committing transaction" if $DEBUG and $oldAutoCommit;
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
}
}
+ if ( $options->{fcc_options} ) {
+ warn " updating fcc options " if $DEBUG;
+ $new->process_fcc_options( $options->{fcc_options} );
+ }
+
warn " committing transaction" if $DEBUG and $oldAutoCommit;
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
'';
join("\n", @error);
}
+=item process_fcc_options HASHREF
+
+Sets the FCC options on this package definition to the values specified
+in HASHREF. Names are as in L<FS::part_pkg_fcc_option/info>.
+
+=cut
+
+sub process_fcc_options {
+ my $self = shift;
+ my $pkgpart = $self->pkgpart;
+ my $options;
+ if (ref $_[0]) {
+ $options = shift;
+ } else {
+ $options = { @_ };
+ }
+
+ my %existing_num = map { $_->fccoptionname => $_->num }
+ qsearch('part_pkg_fcc_option', { pkgpart => $pkgpart });
+
+ # set up params for process_o2m
+ my $i = 0;
+ my $params = {};
+ foreach my $name (keys %$options ) {
+ $params->{ "num$i" } = $existing_num{$name} || '';
+ $params->{ "num$i".'_fccoptionname' } = $name;
+ $params->{ "num$i".'_optionvalue' } = $options->{$name};
+ $i++;
+ }
+
+ $self->process_o2m(
+ table => 'part_pkg_fcc_option',
+ fields => [qw( fccoptionname optionvalue )],
+ params => $params,
+ );
+}
+
=item pkg_locale LOCALE
Returns a customer-viewable string representing this package for the given
$part_pkg_currency->optionvalue;
}
+=item fcc_option OPTIONNAME
+
+Returns the FCC 477 report option value for the given name, or the empty
+string.
+
+=cut
+
+sub fcc_option {
+ my ($self, $name) = @_;
+ my $part_pkg_fcc_option =
+ qsearchs('part_pkg_fcc_option', {
+ pkgpart => $self->pkgpart,
+ fccoptionname => $name,
+ });
+ $part_pkg_fcc_option ? $part_pkg_fcc_option->optionvalue : '';
+}
+
+=item fcc_options
+
+Returns all FCC 477 report options for this package, as a hash-like list.
+
+=cut
+
+sub fcc_options {
+ my $self = shift;
+ map { $_->fccoptionname => $_->optionvalue }
+ qsearch('part_pkg_fcc_option', { pkgpart => $self->pkgpart });
+}
+
=item bill_part_pkg_link
Returns the associated part_pkg_link records (see L<FS::part_pkg_link>).
$self->part_pkg_taxoverride($class);
if (!@taxclassnums) {
my $part_pkg_taxproduct = $self->taxproduct($class);
+ # If this isn't defined, then the class has no taxproduct designation,
+ # so return no tax rates.
+ return () if !$part_pkg_taxproduct;
+
+ # convert the taxproduct to the tax classes that might apply to it in
+ # $geocode
@taxclassnums = map { $_->taxclassnum }
grep { $_->taxable eq 'Y' } # why do we need this?
$part_pkg_taxproduct->part_pkg_taxrate($geocode);
}
return unless @taxclassnums;
+ # then look up the actual tax_rate entries
warn "Found taxclassnum values of ". join(',', @taxclassnums) ."\n"
if $DEBUG;
my $extra_sql = "AND taxclassnum IN (". join(',', @taxclassnums) . ")";
$part_pkg->replace;
}
+ # the rest can be done asynchronously
+}
+sub queueable_upgrade {
# now upgrade to the explicit custom flag
- @part_pkg = qsearch({
+ my $search = FS::Cursor->new({
'table' => 'part_pkg',
'hashref' => { disabled => 'Y', custom => '' },
'extra_sql' => "AND comment LIKE '(CUSTOM) %'",
});
+ my $dbh = dbh;
- foreach my $part_pkg (@part_pkg) {
+ while (my $part_pkg = $search->fetch) {
my $new = new FS::part_pkg { $part_pkg->hash };
$new->custom('Y');
my $comment = $part_pkg->comment;
'primary_svc' => $primary,
'options' => $options,
);
- die $error if $error;
+ if ($error) {
+ warn "pkgpart#".$part_pkg->pkgpart.": $error\n";
+ $dbh->rollback;
+ } else {
+ $dbh->commit;
+ }
}
# set family_pkgpart on any packages that don't have it
- @part_pkg = qsearch('part_pkg', { 'family_pkgpart' => '' });
- foreach my $part_pkg (@part_pkg) {
+ $search = FS::Cursor->new('part_pkg', { 'family_pkgpart' => '' });
+ while (my $part_pkg = $search->fetch) {
$part_pkg->set('family_pkgpart' => $part_pkg->pkgpart);
my $error = $part_pkg->SUPER::replace;
- die $error if $error;
+ if ($error) {
+ warn "pkgpart#".$part_pkg->pkgpart.": $error\n";
+ $dbh->rollback;
+ } else {
+ $dbh->commit;
+ }
}
my @part_pkg_option = qsearch('part_pkg_option',
}
} # $bad_upgrade exists
else { # do the original upgrade, but correctly this time
- @part_pkg = qsearch('part_pkg', {
+ my @part_pkg = qsearch('part_pkg', {
fcc_ds0s => { op => '>', value => 0 },
fcc_voip_class => ''
});