start adding package locations, RT#4499
[freeside.git] / FS / FS / part_pkg.pm
index 57145fd..f521d65 100644 (file)
@@ -144,6 +144,10 @@ record itself), the object will be updated to point to this package definition.
 In conjunction with I<cust_pkg>, if I<custnum_ref> is set to a scalar reference,
 the scalar will be updated with the custnum value from the cust_pkg record.
 
+If I<tax_overrides> is set to a hashref with usage classes as keys and comma
+separated tax class numbers as values, appropriate FS::part_pkg_taxoverride
+records will be inserted.
+
 If I<options> is set to a hashref of options, appropriate FS::part_pkg_option
 records will be inserted.
 
@@ -191,6 +195,22 @@ sub insert {
     }
   }
 
+  warn "  inserting part_pkg_taxoverride records" if $DEBUG;
+  my %overrides = %{ $options{'tax_overrides'} || {} };
+  foreach my $usage_class ( keys %overrides ) {
+    my @overrides = (grep "$_", split (',', $overrides{$usage_class}) );
+    my $error = $self->process_m2m (
+                  'link_table'   => 'part_pkg_taxoverride',
+                  'target_table' => 'tax_class',
+                  'hashref'      => { 'usage_class' => $usage_class },
+                  'params'       => \@overrides,
+                );
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
   warn "  inserting pkg_svc records" if $DEBUG;
   my $pkg_svc = $options{'pkg_svc'} || {};
   foreach my $part_svc ( qsearch('part_svc', {} ) ) {
@@ -579,15 +599,29 @@ sub svcpart {
   my $svcdb = scalar(@_) ? shift : '';
   my @svcdb_pkg_svc =
     grep { ( $svcdb eq $_->part_svc->svcdb || !$svcdb ) } $self->pkg_svc;
-  my @pkg_svc = ();
-  @pkg_svc = grep { $_->primary_svc =~ /^Y/i } @svcdb_pkg_svc
-    if dbdef->table('pkg_svc')->column('primary_svc');
+  my @pkg_svc = grep { $_->primary_svc =~ /^Y/i } @svcdb_pkg_svc;
   @pkg_svc = grep {$_->quantity == 1 } @svcdb_pkg_svc
     unless @pkg_svc;
   return '' if scalar(@pkg_svc) != 1;
   $pkg_svc[0]->svcpart;
 }
 
+=item svcpart_unique_svcdb SVCDB
+
+Returns the svcpart of the a service definition (see L<FS::part_svc>) matching
+SVCDB associated with this package definition (see L<FS::pkg_svc>).  Returns
+false if there not a primary service definition for SVCDB or there are multiple
+service definitions for SVCDB.
+
+=cut
+
+sub svcpart_unique_svcdb {
+  my( $self, $svcdb ) = @_;
+  my @svcdb_pkg_svc = grep { ( $svcdb eq $_->part_svc->svcdb ) } $self->pkg_svc;
+  return '' if scalar(@svcdb_pkg_svc) != 1;
+  $svcdb_pkg_svc[0]->svcpart;
+}
+
 =item payby
 
 Returns a list of the acceptable payment types for this package.  Eventually
@@ -838,7 +872,9 @@ sub has_taxproduct {
   my $self = shift;
 
   $self->taxproductnum ||
-  scalar(grep { $_ =~/^usage_taxproductnum_/ } keys %{ {$self->options} } )
+  scalar( grep { $_ =~/^usage_taxproductnum_/ && $self->option($_) } 
+          keys %{ {$self->options} }
+  )
 
 }
 
@@ -909,6 +945,7 @@ sub _expand_cch_taxproductnum {
                          ? ( split ':', $part_pkg_taxproduct->taxproduct )
                          : ()
                      );
+  $a = '' unless $a; $b = '' unless $b; $c = '' unless $c; $d = '' unless $d;
   my $extra_sql = "AND ( taxproduct = '$a:$b:$c:$d'
                       OR taxproduct = '$a:$b:$c:'
                       OR taxproduct = '$a:$b:".":$d'
@@ -935,11 +972,11 @@ sub part_pkg_taxrate {
         ).
     ')';
   # much more CCH oddness in m2m -- this is kludgy
+  my @tpnums = $self->_expand_cch_taxproductnum($class);
   $extra_sql .= ' AND ('.
-    join(' OR ', map{ "taxproductnum = $_" }
-                 $self->_expand_cch_taxproductnum($class)
-        ).
-    ')';
+                          join(' OR ', map{ "taxproductnum = $_" } @tpnums ).
+                     ')'
+     if @tpnums;
 
   my $addl_from = 'LEFT JOIN part_pkg_taxproduct USING ( taxproductnum )';
   my $order_by = 'ORDER BY taxclassnum, length(geocode) desc, length(taxproduct) desc';