[freeside-commits] branch master updated. 9e0abf502762db98b6aab1aaec0508d339bddb92

Ivan ivan at 420.am
Thu Sep 5 21:05:16 PDT 2013


The branch, master has been updated
       via  9e0abf502762db98b6aab1aaec0508d339bddb92 (commit)
       via  cf14219879b437bd63e15b77b96f55103a645531 (commit)
       via  0191f49853fc8f1ff7c8a608600474bc23ffa69d (commit)
      from  3f77bb21dfb560a6a91d828f7af9844f80d0d914 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9e0abf502762db98b6aab1aaec0508d339bddb92
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Thu Sep 5 21:05:14 2013 -0700

    add no_fuzzy_on_exact global, RT#24804

diff --git a/httemplate/pref/pref.html b/httemplate/pref/pref.html
index dc44db0..d2b8835 100644
--- a/httemplate/pref/pref.html
+++ b/httemplate/pref/pref.html
@@ -108,6 +108,12 @@ Interface
     </TD>
   </TR>
 
+% if ( FS::Conf->new->exists('enable_fuzzy_on_exact') ) {
+
+  <INPUT TYPE="hidden" NAME="enable_fuzzy_on_exact" VALUE="<% $curuser->option('enable_fuzzy_on_exact') ? 1 : 0 %>">
+
+% } else {
+
  <TR>
     <TH ALIGN="right" COLSPAN=1>Enable approximate customer searching <BR>even when an exact match is found: </TH>
     <TD ALIGN="left" COLSPAN=2>
@@ -115,6 +121,8 @@ Interface
     </TD>
   </TR>
 
+% }
+
   <TR>
     <TH ALIGN="right" COLSPAN=1>Disable HTML editor for customer notes: </TH>
     <TD ALIGN="left" COLSPAN=2>
diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi
index 2c09c69..69f04f5 100755
--- a/httemplate/search/cust_main.cgi
+++ b/httemplate/search/cust_main.cgi
@@ -470,7 +470,9 @@ if ( $cgi->param('browse')
     $orderby = "ORDER BY LOWER(company || ' ' || last || ' ' || first )";
     push @cust_main, smart_search(
       'search'            => scalar($cgi->param('search_cust')),
-      'no_fuzzy_on_exact' => ! $curuser->option('enable_fuzzy_on_exact'),
+      'no_fuzzy_on_exact' => ! ( $curuser->option('enable_fuzzy_on_exact')
+                                 || $conf->exists('enable_fuzzy_on_exact')
+                               ),
     );
   }
 

commit cf14219879b437bd63e15b77b96f55103a645531
Merge: 0191f49 3f77bb2
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Thu Sep 5 21:05:11 2013 -0700

    Merge branch 'master' of git.freeside.biz:/home/git/freeside


commit 0191f49853fc8f1ff7c8a608600474bc23ffa69d
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Thu Sep 5 01:40:39 2013 -0700

    credit utilities for fibernetics, RT#24243

diff --git a/bin/cust_bill-credit b/bin/cust_bill-credit
new file mode 100755
index 0000000..2d322f5
--- /dev/null
+++ b/bin/cust_bill-credit
@@ -0,0 +1,255 @@
+#!/usr/bin/perl -w
+
+use strict;
+use vars qw( $opt_d $opt_s $opt_p $opt_m $opt_c $opt_e $opt_r );
+use Getopt::Std;
+use Date::Parse qw(str2time);
+use FS::UID qw( dbh adminsuidsetup );
+use FS::Record qw( qsearch qsearchs );
+use FS::cust_main_county;
+use FS::cust_bill;
+use FS::msg_template;
+use FS::cust_credit;
+use FS::cust_credit_bill;
+
+getopts('d:s:pm:c:er');
+
+my $user = shift or &usage;
+adminsuidsetup $user;
+
+#i should be an option
+my $taxname = 'HST, ON';
+my $rate = '13';
+                                                                                
+my $oldAutoCommit = $FS::UID::AutoCommit;
+local $FS::UID::AutoCommit = 0;
+my $dbh = dbh;
+
+###
+# find tax classes with double taxes
+##
+
+#my $sql = "select distinct taxclass from cust_main_county where taxname = '$taxname';";
+#my $sth = dbh->prepare($sql) or die dbh->errstr;
+#$sth->execute or die $sth->errstr;
+#my @taxclasses = map $_->[0], @{ $sth->fetchall_arrayref() };
+#
+#my %taxclass = map {
+#                my $taxclass = $_;
+#                my @cust_main_county = qsearch('cust_main_county', {
+#                                         'taxclass' => $taxclass,
+#                                         'taxname'  => $taxname,
+#                                         'tax'      => { op=>'>', value=>'0' },
+#                                       });
+#
+#                $taxclass => ( scalar(@cust_main_county) > 1 );
+#
+#              } @taxclasses;
+
+my %taxclass = map { $_ => 1 } (
+  'InternetService',
+  'ComputerSetup-Remote',
+  'Config File- Static IPs',
+  'GST',
+  'GST + PST',
+  'GST ONLY',
+  'HST ONLY',
+  'HardwareRental',
+  'HardwareSale',
+  'HardwareSale_WEx',
+  'InternetService_WEx',
+  'LondDistanceFixedRate',
+  'LondDistanceVariableRate',
+  'PST',
+  'SARA-ONLY-GSTPayable',
+  'SetupInternet',
+  'SetupVoice',
+  'Shipping',
+  'SoftwareLicenseToUse',
+  'TDMPRI',
+  'TDMPRI_WEx',
+  'WarrantyCoverageHardware',
+  'WarrantyCoverageSoftware',
+  'WebHosting',
+  'federal and qst',
+  'telephoneNumber',
+  'LongDistanceFixedRate_WEx',
+  'LongDistanceVariableRate_WEx',
+);
+
+###
+# find invoices
+###
+
+#my $extra_sql = $opt_s ? " AND cust_main.state = '$opt_s' " : '';
+
+my $start_date = $opt_d ? str2time($opt_d) : 0;
+my $end_date = 1375471643;
+
+my @cust_bill = qsearch({
+  'select'    => 'cust_bill.*',
+  'table'     => 'cust_bill',
+  'addl_from' => 'LEFT JOIN cust_main USING ( custnum )',
+  'hashref'   => { '_date' => { op=>'>', value=>$start_date } },
+  'extra_sql' => " AND _date < $end_date ",
+#  'extra_sql' => $extra_sql,
+});
+
+my( @billpkgnums, @setuprecurs, @amounts );
+
+foreach my $cust_bill ( @cust_bill ) {
+
+  my $tax = $cust_bill->tax;
+
+  my $cust_main = $cust_bill->cust_main;
+
+  next if $cust_bill->charged == 0
+       or $tax == 0
+       or $cust_main->tax eq 'Y';
+
+  my $credit = 0;
+
+  @billpkgnums = ();
+  @setuprecurs = ();
+  @amounts = ();
+
+  foreach my $cust_bill_pkg ( $cust_bill->cust_bill_pkg ) {
+    my $cust_pkg = $cust_bill_pkg->cust_pkg or next;
+
+    my $loc = $cust_pkg->cust_location_or_main;
+    next if $opt_s && $loc->state ne $opt_s;
+
+    my $part_pkg = $cust_pkg->part_pkg;
+    next unless $taxclass{ $part_pkg->taxclass };
+
+    #my $amount = $cust_bill_pkg->setup + $cust_bill_pkg->recur;
+    #$credit += $rate * $amount / 100;
+
+    if ( $cust_bill_pkg->setup ) {
+      my $scredit = sprintf('%.2f', ($rate * $cust_bill_pkg->setup / 100) + 0.00000001);
+      $credit += $scredit;
+      push @setuprecurs, 'setup';
+      push @billpkgnums, $cust_bill_pkg->billpkgnum;
+      push @amounts, $scredit;
+    } 
+
+    if ( $cust_bill_pkg->recur ) {
+      my $rcredit = sprintf('%.2f', ($rate * $cust_bill_pkg->recur / 100) + 0.00000001);
+      $credit += $rcredit;
+      push @setuprecurs, 'recur';
+      push @billpkgnums, $cust_bill_pkg->billpkgnum;
+      push @amounts, $rcredit;
+    }
+
+  }
+
+  $credit = sprintf('%.2f', $credit + 0.00000001);
+
+  next if $credit == 0;
+
+  #$credit = sprintf('%.2f', $credit + 0.00000001);
+
+  warn "invoice ". $cust_bill->invnum. ": credit of $credit is more than orignally taxed ($tax)\n" if $credit > $tax;
+
+  warn "invoice ". $cust_bill->invnum. ": credit of $credit is more than 50% of originally taxed ($tax)\n" if $credit-0.01 > $tax/2;
+
+  #my $cr_percent = sprintf('%.1f', 100 * $credit / $tax);
+
+  if ( $opt_p ) {
+    #print $cust_bill->invnum. ','. $cust_bill->custnum. ",$tax,$credit,$cr_percent%\n";
+    print $cust_bill->invnum. ','. $cust_bill->custnum. ',"'.
+          $cust_bill->cust_main->name. '",'. "$tax,$credit\n";
+  }
+
+  if ( $opt_m && ! $opt_r ) {
+
+    my $msg_template = qsearchs('msg_template', { 'msgnum' => $opt_m } )
+        or die "Template $opt_m not found";
+    my $error = $msg_template->send(
+      'cust_main' => $cust_main,
+      'object'    => $cust_main,
+    );
+    if ( $error ) {
+      warn "error sending email for invnum ". $cust_bill->invnum. ','.
+           " custnum ". $cust_bill->custnum. ": $error\n";
+    }
+  }
+
+  if ( $opt_c ) {
+    my $cust_credit = new FS::cust_credit {
+      'custnum'   => $cust_main->custnum,
+      'amount'    => $credit,
+      'reasonnum' => $opt_c,
+    };
+    my $error = $cust_credit->insert;
+    if ( $error ) {
+      warn "error inserting credit: $error\n";
+    }
+    my $cust_credit_bill = new FS::cust_credit_bill {
+      'crednum' => $cust_credit->crednum,
+      'invnum'  => $cust_bill->invnum,
+      'amount'  => $credit,
+    };
+    my $aerror = $cust_credit_bill->insert;
+    if ( $aerror ) {
+      warn "error applying credit to invnum ". $cust_bill->invnum. ": $aerror\n";
+    }
+  }
+
+  if ( $opt_e && ! $opt_r ) {
+    eval { $cust_bill->email };
+    if ( $@ ) {
+      warn "error sending invnum ". $cust_bill->invnum. ','.
+         " custnum ". $cust_bill->custnum. ": $@\n";
+    }
+  }
+
+}
+
+if ( $opt_r ) {
+  $dbh->rollback or die $dbh->errstr; #if $oldAutoCommit;
+} else {
+  $dbh->commit or die $dbh->errstr; #if $oldAutoCommit;
+}
+
+sub usage {                                                                     
+  die "usage:  cust_bill-credit [ -d date ] [ -s state ] [ -p ] [ -m templatenum ] [ -c reasonnum ] [ -e ] [ -r ] employee_username\n";
+}                                                                               
+                                                                                
+=head1 NAME                                                                     
+                                                                                
+cust_bill-credit
+                                                                                
+=head1 SYNOPSIS                                                                 
+                                                                                
+  cust_bill-credit [ -d date ] [ -s state ] [ -p ] [ -m templatenum ] [ -c reasonnum ] [ -e ] employee_username   
+                                                                                
+=head1 DESCRIPTION
+
+Command-line tool to search for and credit invoices.
+
+-d: Search for invoices starting from this date
+
+-s: Search for invoices for packages within this state
+
+-p: Print an informational line for each invoice with invnum, custnum, original tax amount, calculate credit, and credit percentage of original.
+
+-m: Send an email to the customer with this message template.
+
+-c: Credit the invoice for one-half of the taxation amount, using this reason.
+
+-e: re-Email invoice
+
+-r: dRy run
+
+employee_username
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::part_pkg>
+
+=cut
+
+1;
diff --git a/bin/cust_bill-credit34 b/bin/cust_bill-credit34
new file mode 100755
index 0000000..f3e579b
--- /dev/null
+++ b/bin/cust_bill-credit34
@@ -0,0 +1,205 @@
+#!/usr/bin/perl -w
+
+use strict;
+use vars qw( $opt_d $opt_s $opt_p $opt_m $opt_c $opt_e $opt_r );
+use Getopt::Std;
+use Date::Parse qw(str2time);
+use FS::UID qw( dbh adminsuidsetup );
+use FS::Record qw( qsearch qsearchs );
+use FS::cust_main_county;
+use FS::cust_bill;
+use FS::msg_template;
+use FS::cust_credit;
+use FS::cust_credit_bill;
+
+getopts('d:s:pm:c:er');
+
+my $user = shift or &usage;
+adminsuidsetup $user;
+
+#i should be an option
+my $taxname = 'HST, ON';
+my $rate = '13';
+                                                                                
+my $oldAutoCommit = $FS::UID::AutoCommit;
+local $FS::UID::AutoCommit = 0;
+my $dbh = dbh;
+
+# only pkgpart 34
+
+###
+# find invoices
+###
+
+#my $extra_sql = $opt_s ? " AND cust_main.state = '$opt_s' " : '';
+
+my $start_date = $opt_d ? str2time($opt_d) : 0;
+my $end_date = 1375471643;
+
+my @cust_bill = qsearch({
+  'select'    => 'cust_bill.*',
+  'table'     => 'cust_bill',
+  'addl_from' => 'LEFT JOIN cust_main USING ( custnum )',
+  'hashref'   => { '_date' => { op=>'>', value=>$start_date } },
+  'extra_sql' => " AND _date < $end_date ",
+#  'extra_sql' => $extra_sql,
+});
+
+my( @billpkgnums, @setuprecurs, @amounts );
+
+foreach my $cust_bill ( @cust_bill ) {
+
+  my $tax = $cust_bill->tax;
+
+  my $cust_main = $cust_bill->cust_main;
+
+  next if $cust_bill->charged == 0
+       or $tax == 0
+       or $cust_main->tax eq 'Y';
+
+  my $credit = 0;
+
+  @billpkgnums = ();
+  @setuprecurs = ();
+  @amounts = ();
+
+  foreach my $cust_bill_pkg ( $cust_bill->cust_bill_pkg ) {
+    my $cust_pkg = $cust_bill_pkg->cust_pkg or next;
+
+    my $loc = $cust_pkg->cust_location_or_main;
+    next if $opt_s && $loc->state ne $opt_s;
+
+    my $part_pkg = $cust_pkg->part_pkg;
+    next unless $cust_pkg->pkgpart == 34; #only pkgpart 34
+
+    #my $amount = $cust_bill_pkg->setup + $cust_bill_pkg->recur;
+    #$credit += $rate * $amount / 100;
+
+    if ( $cust_bill_pkg->setup ) {
+      my $scredit = sprintf('%.2f', ($rate * $cust_bill_pkg->setup / 100) + 0.00000001);
+      $credit += $scredit;
+      push @setuprecurs, 'setup';
+      push @billpkgnums, $cust_bill_pkg->billpkgnum;
+      push @amounts, $scredit;
+    } 
+
+    if ( $cust_bill_pkg->recur ) {
+      my $rcredit = sprintf('%.2f', ($rate * $cust_bill_pkg->recur / 100) + 0.00000001);
+      $credit += $rcredit;
+      push @setuprecurs, 'recur';
+      push @billpkgnums, $cust_bill_pkg->billpkgnum;
+      push @amounts, $rcredit;
+    }
+
+  }
+
+  $credit = sprintf('%.2f', $credit + 0.00000001);
+
+  next if $credit == 0;
+
+  #$credit = sprintf('%.2f', $credit + 0.00000001);
+
+  warn "invoice ". $cust_bill->invnum. ": credit of $credit is more than orignally taxed ($tax)\n" if $credit > $tax;
+
+  warn "invoice ". $cust_bill->invnum. ": credit of $credit is more than 50% of originally taxed ($tax)\n" if $credit-0.01 > $tax/2;
+
+  #my $cr_percent = sprintf('%.1f', 100 * $credit / $tax);
+
+  if ( $opt_p ) {
+    #print $cust_bill->invnum. ','. $cust_bill->custnum. ",$tax,$credit,$cr_percent%\n";
+    print $cust_bill->invnum. ','. $cust_bill->custnum. ',"'.
+          $cust_bill->cust_main->name. '",'. "$tax,$credit\n";
+  }
+
+  if ( $opt_m && ! $opt_r ) {
+
+    my $msg_template = qsearchs('msg_template', { 'msgnum' => $opt_m } )
+        or die "Template $opt_m not found";
+    my $error = $msg_template->send(
+      'cust_main' => $cust_main,
+      'object'    => $cust_main,
+    );
+    if ( $error ) {
+      warn "error sending email for invnum ". $cust_bill->invnum. ','.
+           " custnum ". $cust_bill->custnum. ": $error\n";
+    }
+  }
+
+  if ( $opt_c ) {
+    my $cust_credit = new FS::cust_credit {
+      'custnum'   => $cust_main->custnum,
+      'amount'    => $credit,
+      'reasonnum' => $opt_c,
+    };
+    my $error = $cust_credit->insert;
+    if ( $error ) {
+      warn "error inserting credit: $error\n";
+    }
+    my $cust_credit_bill = new FS::cust_credit_bill {
+      'crednum' => $cust_credit->crednum,
+      'invnum'  => $cust_bill->invnum,
+      'amount'  => $credit,
+    };
+    my $aerror = $cust_credit_bill->insert;
+    if ( $aerror ) {
+      warn "error applying credit to invnum ". $cust_bill->invnum. ": $aerror\n";
+    }
+  }
+
+  if ( $opt_e && ! $opt_r ) {
+    eval { $cust_bill->email };
+    if ( $@ ) {
+      warn "error sending invnum ". $cust_bill->invnum. ','.
+         " custnum ". $cust_bill->custnum. ": $@\n";
+    }
+  }
+
+}
+
+if ( $opt_r ) {
+  $dbh->rollback or die $dbh->errstr; #if $oldAutoCommit;
+} else {
+  $dbh->commit or die $dbh->errstr; #if $oldAutoCommit;
+}
+
+sub usage {                                                                     
+  die "usage:  cust_bill-credit [ -d date ] [ -s state ] [ -p ] [ -m templatenum ] [ -c reasonnum ] [ -e ] [ -r ] employee_username\n";
+}                                                                               
+                                                                                
+=head1 NAME                                                                     
+                                                                                
+cust_bill-credit
+                                                                                
+=head1 SYNOPSIS                                                                 
+                                                                                
+  cust_bill-credit [ -d date ] [ -s state ] [ -p ] [ -m templatenum ] [ -c reasonnum ] [ -e ] employee_username   
+                                                                                
+=head1 DESCRIPTION
+
+Command-line tool to search for and credit invoices.
+
+-d: Search for invoices starting from this date
+
+-s: Search for invoices for packages within this state
+
+-p: Print an informational line for each invoice with invnum, custnum, original tax amount, calculate credit, and credit percentage of original.
+
+-m: Send an email to the customer with this message template.
+
+-c: Credit the invoice for one-half of the taxation amount, using this reason.
+
+-e: re-Email invoice
+
+-r: dRy run
+
+employee_username
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::part_pkg>
+
+=cut
+
+1;
diff --git a/bin/cust_bill-credit_ship b/bin/cust_bill-credit_ship
new file mode 100755
index 0000000..0ea8091
--- /dev/null
+++ b/bin/cust_bill-credit_ship
@@ -0,0 +1,276 @@
+#!/usr/bin/perl -w
+
+use strict;
+use vars qw( $opt_d $opt_f $opt_s $opt_p $opt_m $opt_c $opt_e $opt_r );
+use Getopt::Std;
+use Date::Parse qw(str2time);
+use FS::UID qw( dbh adminsuidsetup );
+use FS::Record qw( qsearch qsearchs );
+use FS::cust_main_county;
+use FS::cust_bill;
+use FS::msg_template;
+use FS::cust_credit;
+use FS::cust_credit_bill;
+
+getopts('d:f:s:pm:c:er');
+
+my $user = shift or &usage;
+adminsuidsetup $user;
+
+#i should be an option
+my $taxname = 'HST, ON';
+my $rate = '13';
+                                                                                
+my $oldAutoCommit = $FS::UID::AutoCommit;
+local $FS::UID::AutoCommit = 0;
+my $dbh = dbh;
+
+###
+# find tax classes with double taxes
+##
+
+#my $sql = "select distinct taxclass from cust_main_county where taxname = '$taxname';";
+#my $sth = dbh->prepare($sql) or die dbh->errstr;
+#$sth->execute or die $sth->errstr;
+#my @taxclasses = map $_->[0], @{ $sth->fetchall_arrayref() };
+#
+#my %taxclass = map {
+#                my $taxclass = $_;
+#                my @cust_main_county = qsearch('cust_main_county', {
+#                                         'taxclass' => $taxclass,
+#                                         'taxname'  => $taxname,
+#                                         'tax'      => { op=>'>', value=>'0' },
+#                                       });
+#
+#                $taxclass => ( scalar(@cust_main_county) > 1 );
+#
+#              } @taxclasses;
+
+my %taxclass = map { $_ => 1 } (
+  'InternetService',
+  'ComputerSetup-Remote',
+  'Config File- Static IPs',
+  'GST',
+  'GST + PST',
+  'GST ONLY',
+  'HST ONLY',
+  'HardwareRental',
+  'HardwareSale',
+  'HardwareSale_WEx',
+  'InternetService_WEx',
+  'LondDistanceFixedRate',
+  'LondDistanceVariableRate',
+  'PST',
+  'SARA-ONLY-GSTPayable',
+  'SetupInternet',
+  'SetupVoice',
+  'Shipping',
+  'SoftwareLicenseToUse',
+  'TDMPRI',
+  'TDMPRI_WEx',
+  'WarrantyCoverageHardware',
+  'WarrantyCoverageSoftware',
+  'WebHosting',
+  'federal and qst',
+  'telephoneNumber',
+  'LongDistanceFixedRate_WEx',
+  'LongDistanceVariableRate_WEx',
+);
+
+my %h;
+$FS::Record::nowarn_classload = 1;
+$FS::Record::nowarn_classload = 1;
+
+###
+# find invoices
+###
+
+#my $extra_sql = $opt_s ? " AND cust_main.state = '$opt_s' " : '';
+
+my $start_date = $opt_d ? str2time($opt_d) : 0;
+my $end_date = $opt_f ? str2time($opt_f) : 1375471643;
+
+my @cust_bill = qsearch({
+  'select'    => 'cust_bill.*',
+  'table'     => 'cust_bill',
+  'addl_from' => 'LEFT JOIN cust_main USING ( custnum )',
+  'hashref'   => { '_date' => { op=>'>', value=>$start_date } },
+  'extra_sql' => " AND _date < $end_date ",
+#  'extra_sql' => $extra_sql,
+});
+
+my( @billpkgnums, @setuprecurs, @amounts );
+
+foreach my $cust_bill ( @cust_bill ) {
+
+  my $tax = $cust_bill->tax;
+
+  my $cust_main = $cust_bill->cust_main;
+
+  next if $cust_bill->charged == 0
+       or $tax == 0
+       or $cust_main->tax eq 'Y';
+
+  my $credit = 0;
+
+  @billpkgnums = ();
+  @setuprecurs = ();
+  @amounts = ();
+
+  foreach my $cust_bill_pkg ( $cust_bill->cust_bill_pkg ) {
+    my $cust_pkg = $cust_bill_pkg->cust_pkg or next;
+
+    #my $loc = $cust_pkg->cust_location_or_main;
+    #next if $opt_s && $loc->state ne $opt_s;
+    next if $cust_pkg->cust_location; #we did these already
+    next if $opt_s && $cust_main->ship_state ne $opt_s;
+    next if $opt_s && $cust_main->state eq $opt_s; #we did these already too
+
+    my $part_pkg = $cust_pkg->part_pkg;
+
+    #these were changed already
+    # next unless $taxclass{ $part_pkg->taxclass };
+
+    my $h = $h{$part_pkg->pkgpart} ||= qsearchs({
+      'table'     => 'h_part_pkg', 
+      'hashref'   => { 'pkgpart' => $part_pkg->pkgpart },
+      'extra_sql' => "AND history_action IN ( 'insert', 'replace_new' )",
+      'order_by'  => 'ORDER BY HISTORYNUM DESC LIMIT 1',
+    });
+    next unless $taxclass{ $h->taxclass };
+
+    #my $amount = $cust_bill_pkg->setup + $cust_bill_pkg->recur;
+    #$credit += $rate * $amount / 100;
+
+    if ( $cust_bill_pkg->setup ) {
+      my $scredit = sprintf('%.2f', ($rate * $cust_bill_pkg->setup / 100) + 0.00000001);
+      $credit += $scredit;
+      push @setuprecurs, 'setup';
+      push @billpkgnums, $cust_bill_pkg->billpkgnum;
+      push @amounts, $scredit;
+    } 
+
+    if ( $cust_bill_pkg->recur ) {
+      my $rcredit = sprintf('%.2f', ($rate * $cust_bill_pkg->recur / 100) + 0.00000001);
+      $credit += $rcredit;
+      push @setuprecurs, 'recur';
+      push @billpkgnums, $cust_bill_pkg->billpkgnum;
+      push @amounts, $rcredit;
+    }
+
+  }
+
+  $credit = sprintf('%.2f', $credit + 0.00000001);
+
+  next if $credit == 0;
+
+  #$credit = sprintf('%.2f', $credit + 0.00000001);
+
+  warn "invoice ". $cust_bill->invnum. ": credit of $credit is more than orignally taxed ($tax)\n" if $credit > $tax;
+
+  warn "invoice ". $cust_bill->invnum. ": credit of $credit is more than 50% of originally taxed ($tax)\n" if $credit-0.01 > $tax/2;
+
+  #my $cr_percent = sprintf('%.1f', 100 * $credit / $tax);
+
+  if ( $opt_p ) {
+    #print $cust_bill->invnum. ','. $cust_bill->custnum. ",$tax,$credit,$cr_percent%\n";
+    print $cust_bill->invnum. ','. $cust_bill->custnum. ',"'.
+          $cust_bill->cust_main->name. '",'. "$tax,$credit\n";
+  }
+
+#COMMENTING OUT ALL DANGEROUT STUFF
+#
+#  if ( $opt_m && ! $opt_r ) {
+#
+#    my $msg_template = qsearchs('msg_template', { 'msgnum' => $opt_m } )
+#        or die "Template $opt_m not found";
+#    my $error = $msg_template->send(
+#      'cust_main' => $cust_main,
+#      'object'    => $cust_main,
+#    );
+#    if ( $error ) {
+#      warn "error sending email for invnum ". $cust_bill->invnum. ','.
+#           " custnum ". $cust_bill->custnum. ": $error\n";
+#    }
+#  }
+#
+#  if ( $opt_c ) {
+#    my $cust_credit = new FS::cust_credit {
+#      'custnum'   => $cust_main->custnum,
+#      'amount'    => $credit,
+#      'reasonnum' => $opt_c,
+#    };
+#    my $error = $cust_credit->insert;
+#    if ( $error ) {
+#      warn "error inserting credit: $error\n";
+#    }
+#    my $cust_credit_bill = new FS::cust_credit_bill {
+#      'crednum' => $cust_credit->crednum,
+#      'invnum'  => $cust_bill->invnum,
+#      'amount'  => $credit,
+#    };
+#    my $aerror = $cust_credit_bill->insert;
+#    if ( $aerror ) {
+#      warn "error applying credit to invnum ". $cust_bill->invnum. ": $aerror\n";
+#    }
+#  }
+#
+#  if ( $opt_e && ! $opt_r ) {
+#    eval { $cust_bill->email };
+#    if ( $@ ) {
+#      warn "error sending invnum ". $cust_bill->invnum. ','.
+#         " custnum ". $cust_bill->custnum. ": $@\n";
+#    }
+#  }
+
+}
+
+if ( $opt_r ) {
+  $dbh->rollback or die $dbh->errstr; #if $oldAutoCommit;
+} else {
+  $dbh->commit or die $dbh->errstr; #if $oldAutoCommit;
+}
+
+sub usage {                                                                     
+  die "usage:  cust_bill-credit [ -d date ] [ -s state ] [ -p ] [ -m templatenum ] [ -c reasonnum ] [ -e ] [ -r ] employee_username\n";
+}                                                                               
+                                                                                
+=head1 NAME                                                                     
+                                                                                
+cust_bill-credit
+                                                                                
+=head1 SYNOPSIS                                                                 
+                                                                                
+  cust_bill-credit [ -d date ] [ -s state ] [ -p ] [ -m templatenum ] [ -c reasonnum ] [ -e ] employee_username   
+                                                                                
+=head1 DESCRIPTION
+
+Command-line tool to search for and credit invoices.
+
+-d: Search for invoices starting from this date
+
+-f: Search for invoice finishing on this date
+
+-s: Search for invoices for packages within this state
+
+-p: Print an informational line for each invoice with invnum, custnum, original tax amount, calculate credit, and credit percentage of original.
+
+-m: Send an email to the customer with this message template.
+
+-c: Credit the invoice for one-half of the taxation amount, using this reason.
+
+-e: re-Email invoice
+
+-r: dRy run
+
+employee_username
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::part_pkg>
+
+=cut
+
+1;

-----------------------------------------------------------------------

Summary of changes:
 bin/cust_bill-credit            |  255 ++++++++++++++++++++++++++++++++++++
 bin/cust_bill-credit34          |  205 +++++++++++++++++++++++++++++
 bin/cust_bill-credit_ship       |  276 +++++++++++++++++++++++++++++++++++++++
 httemplate/pref/pref.html       |    8 +
 httemplate/search/cust_main.cgi |    4 +-
 5 files changed, 747 insertions(+), 1 deletions(-)
 create mode 100755 bin/cust_bill-credit
 create mode 100755 bin/cust_bill-credit34
 create mode 100755 bin/cust_bill-credit_ship




More information about the freeside-commits mailing list