[freeside-commits] branch master updated. 961c99fbc92fbe296911a60980aef247f8adc049

Ivan ivan at 420.am
Sun Jan 18 14:03:41 PST 2015


The branch, master has been updated
       via  961c99fbc92fbe296911a60980aef247f8adc049 (commit)
       via  85c78d955fbc2fd6c3991156b387d37c185b9f64 (commit)
      from  89f9957267f05520fc676c378694383d16eedeb1 (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 961c99fbc92fbe296911a60980aef247f8adc049
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Sun Jan 18 14:03:25 2015 -0800

    disable quotations, RT#20688, RT#22232

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index f559564..8d33f92 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1681,6 +1681,7 @@ sub tables_hashref {
         'weight',          'int',     '',        '', '', '', 
         'payby',          'char',     '',         4, '', '', 
         'payinfo',     'varchar', 'NULL',       512, '', '', 
+        'cardtype',    'varchar', 'NULL',   $char_d, '', '',
         'paycvv',      'varchar', 'NULL',       512, '', '', 
         'paymask',     'varchar', 'NULL',   $char_d, '', '', 
         #'paydate',   @date_type, '', '', 
@@ -1848,7 +1849,7 @@ sub tables_hashref {
       ],
       'primary_key'  => 'quotationnum',
       'unique'       => [],
-      'index'        => [ [ 'prospectnum' ], ['custnum'], ],
+      'index'        => [ [ 'prospectnum' ], ['custnum'], ['disabled'], ],
       'foreign_keys' => [
                           { columns    => [ 'prospectnum' ],
                             table      => 'prospect_main',

commit 85c78d955fbc2fd6c3991156b387d37c185b9f64
Author: Ivan Kohler <ivan at freeside.biz>
Date:   Sun Jan 18 14:03:07 2015 -0800

    disable quotations, RT#20688, RT#22232

diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm
index 4a1f89a..121f83c 100644
--- a/FS/FS/AccessRight.pm
+++ b/FS/FS/AccessRight.pm
@@ -97,6 +97,7 @@ tie my %rights, 'Tie::IxHash',
     #'New contact',
     #'View customer contacts',
     'Generate quotation',
+    'Disable quotation',
   ],
   
   ###
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm
index 25e61d0..4546741 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -743,72 +743,74 @@ sub _from_hashref {
   return @return;
 }
 
-## makes this easier to read
-
 sub get_real_fields {
   my $table = shift;
   my $record = shift;
   my $real_fields = shift;
 
-   ## this huge map was previously inline, just broke it out to help read the qsearch method, should be optimized for readability
-      return ( 
-      map {
+  ## could be optimized more for readability
+  return ( 
+    map {
 
       my $op = '=';
       my $column = $_;
+      my $table_column = "$table.$column";
       my $type = dbdef->table($table)->column($column)->type;
       my $value = $record->{$column};
       $value = $value->{'value'} if ref($value);
-      if ( ref($record->{$_}) ) {
-        $op = $record->{$_}{'op'} if $record->{$_}{'op'};
+
+      if ( ref($record->{$column}) ) {
+        $op = $record->{$column}{'op'} if $record->{$column}{'op'};
         #$op = 'LIKE' if $op =~ /^ILIKE$/i && driver_name ne 'Pg';
         if ( uc($op) eq 'ILIKE' ) {
           $op = 'LIKE';
-          $record->{$_}{'value'} = lc($record->{$_}{'value'});
-          $column = "LOWER($_)";
+          $record->{$column}{'value'} = lc($record->{$column}{'value'});
+          $table_column = "LOWER($table_column)";
         }
-        $record->{$_} = $record->{$_}{'value'}
+        $record->{$column} = $record->{$column}{'value'}
       }
 
-      if ( ! defined( $record->{$_} ) || $record->{$_} eq '' ) {
+      if ( ! defined( $record->{$column} ) || $record->{$column} eq '' ) {
         if ( $op eq '=' ) {
           if ( driver_name eq 'Pg' ) {
             if ( $type =~ /(int|numeric|real|float4|(big)?serial)/i ) {
-              qq-( $column IS NULL )-;
+              qq-( $table_column IS NULL )-;
             } else {
-              qq-( $column IS NULL OR $column = '' )-;
+              qq-( $table_column IS NULL OR $table_column = '' )-;
             }
           } else {
-            qq-( $column IS NULL OR $column = "" )-;
+            qq-( $table_column IS NULL OR $table_column = "" )-;
           }
         } elsif ( $op eq '!=' ) {
           if ( driver_name eq 'Pg' ) {
             if ( $type =~ /(int|numeric|real|float4|(big)?serial)/i ) {
-              qq-( $column IS NOT NULL )-;
+              qq-( $table_column IS NOT NULL )-;
             } else {
-              qq-( $column IS NOT NULL AND $column != '' )-;
+              qq-( $table_column IS NOT NULL AND $table_column != '' )-;
             }
           } else {
-            qq-( $column IS NOT NULL AND $column != "" )-;
+            qq-( $table_column IS NOT NULL AND $table_column != "" )-;
           }
         } else {
           if ( driver_name eq 'Pg' ) {
-            qq-( $column $op '' )-;
+            qq-( $table_column $op '' )-;
           } else {
-            qq-( $column $op "" )-;
+            qq-( $table_column $op "" )-;
           }
         }
       } elsif ( $op eq '!=' ) {
-        qq-( $column IS NULL OR $column != ? )-;
+        qq-( $table_column IS NULL OR $table_column != ? )-;
       #if this needs to be re-enabled, it needs to use a custom op like
       #"APPROX=" or something (better name?, not '=', to avoid affecting other
       # searches
       #} elsif ( $op eq 'APPROX=' && _is_fs_float( $type, $value ) ) {
-      #  ( "$column <= ?", "$column >= ?" );
+      #  ( "$table_column <= ?", "$table_column >= ?" );
       } else {
-        "$column $op ?";
+        "$table_column $op ?";
       }
-    } @{ $real_fields } );  
+
+    } @{ $real_fields }
+  );  
 }
 
 =item by_key PRIMARY_KEY_VALUE
diff --git a/FS/FS/access_right.pm b/FS/FS/access_right.pm
index e5a5781..d5e3b8b 100644
--- a/FS/FS/access_right.pm
+++ b/FS/FS/access_right.pm
@@ -250,6 +250,7 @@ sub _upgrade_data { # class method
     'List prospects' => 'List contacts',
     'List customers' => 'List contacts',
     'Backdate payment' => 'Backdate credit',
+    'Generate quotation' => 'Disable quotation',
   );
 
 #  foreach my $old_acl ( keys %onetime ) {
diff --git a/FS/FS/quotation.pm b/FS/FS/quotation.pm
index e72e6cf..5710b38 100644
--- a/FS/FS/quotation.pm
+++ b/FS/FS/quotation.pm
@@ -6,6 +6,7 @@ use strict;
 use Tie::RefHash;
 use FS::CurrentUser;
 use FS::UID qw( dbh );
+use FS::Maketext qw( emt );
 use FS::cust_main;
 use FS::cust_pkg;
 
@@ -166,6 +167,38 @@ sub _total {
 
 }
 
+=item cust_or_prospect_label_link P
+
+HTML links to either the customer or prospect.
+
+Returns a list consisting of two elements.  The first is a text label for the
+link, and the second is the URL.
+
+=cut
+
+sub cust_or_prospect_label_link {
+  my( $self, $p ) = @_;
+
+  if ( my $custnum = $self->custnum ) {
+    my $display_custnum = $self->cust_main->display_custnum;
+    my $target = $FS::CurrentUser::CurrentUser->default_customer_view eq 'jumbo'
+                   ? '#quotations'
+                   : ';show=quotations';
+    (
+      emt("View this customer (#[_1])",$display_custnum) =>
+        "${p}view/cust_main.cgi?custnum=$custnum$target"
+    );
+  } elsif ( my $prospectnum = $self->prospectnum ) {
+    (
+      emt("View this prospect (#[_1])",$prospectnum) =>
+        "${p}view/prospect_main.html?$prospectnum"
+    );
+  } else { #die?
+    ( '', '' );
+  }
+
+}
+
 #prevent things from falsely showing up as taxes, at least until we support
 # quoting tax amounts..
 sub _items_tax {
@@ -271,6 +304,35 @@ sub order {
 
 }
 
+=item disable
+
+Disables this quotation (sets disabled to Y, which hides the quotation on
+prospects and customers).
+
+If there is an error, returns an error message, otherwise returns false.
+
+=cut
+
+sub disable {
+  my $self = shift;
+  $self->disabled('Y');
+  $self->replace();
+}
+
+=item enable
+
+Enables this quotation.
+
+If there is an error, returns an error message, otherwise returns false.
+
+=cut
+
+sub enable {
+  my $self = shift;
+  $self->disabled('');
+  $self->replace();
+}
+
 =back
 
 =head1 CLASS METHODS
diff --git a/httemplate/misc/disable-quotation.html b/httemplate/misc/disable-quotation.html
new file mode 100644
index 0000000..a6c4829
--- /dev/null
+++ b/httemplate/misc/disable-quotation.html
@@ -0,0 +1,21 @@
+%if ( $error ) {
+%  errorpage($error);
+%} else {
+<% $cgi->redirect($url) %>
+%}
+<%init>
+
+die "access deined"
+  unless $FS::CurrentUser::CurrentUser->access_right('Disable quotation');
+
+$cgi->param('quotationnum') =~ /^(\d+)$/ or die 'illegal quotationnum';
+my $quotationnum = $1;
+
+my $quotation =
+  qsearchs('quotation', { 'quotationnum' => $quotationnum } );
+
+my $error = $quotation->disable;
+
+my( $label, $url ) = $quotation->cust_or_prospect_label_link( popurl(2) );
+
+</%init>
diff --git a/httemplate/misc/enable-quotation.html b/httemplate/misc/enable-quotation.html
new file mode 100644
index 0000000..e5bb499
--- /dev/null
+++ b/httemplate/misc/enable-quotation.html
@@ -0,0 +1,21 @@
+%if ( $error ) {
+%  errorpage($error);
+%} else {
+<% $cgi->redirect(popurl(2)."view/quotation.html?quotationnum=$quotationnum") %>
+%}
+<%init>
+
+die "access deined"
+  unless $FS::CurrentUser::CurrentUser->access_right('Disable quotation');
+
+$cgi->param('quotationnum') =~ /^(\d+)$/ or die 'illegal quotationnum';
+my $quotationnum = $1;
+
+my $quotation =
+  qsearchs('quotation', { 'quotationnum' => $quotationnum } );
+
+my $error = $quotation->enable;
+
+#my( $label, $url ) = $quotation->cust_or_prospect_label_link( popurl(2) );
+
+</%init>
diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html
index 3fb1e3e..62a0e47 100644
--- a/httemplate/search/elements/search.html
+++ b/httemplate/search/elements/search.html
@@ -307,9 +307,11 @@ if ( $opt{'disableable'} ) {
     $opt{'query'}{'hashref'}{'disabled'} = '';
     $opt{'query'}{'extra_sql'} =~ s/^\s*WHERE/ AND/i;
 
+    my $table = $opt{'query'}{'table'};
+
     $opt{'count_query'} .=
       ( $opt{'count_query'} =~ /WHERE/i ? ' AND ' : ' WHERE ' ).
-      "( disabled = '' OR disabled IS NULL )";
+      "( $table.disabled = '' OR $table.disabled IS NULL )";
 
   } elsif (    $opt{'disabled_statuspos'}
             || $opt{'disabled_statuspos'} eq '0' ) { #add status column
@@ -360,12 +362,6 @@ unless ( $type =~ /^(csv|xml|\w*.xls)$/) {
       s/^\s*SELECT\s*(.*?)\s+FROM\s/SELECT COUNT(*) FROM /i; #silly vim:/
   }
 
-  if ( $opt{disableable} && ! $cgi->param('showdisabled') ) {
-    $opt{count_query} .=
-      ( ( $opt{count_query} =~ /WHERE/i ) ? ' AND ' : ' WHERE ' ).
-      "( disabled = '' OR disabled IS NULL )";
-  }
-
   unless ( $type eq 'html-print' ) {
 
     #setup some pagination things if we're in html mode
diff --git a/httemplate/search/quotation.html b/httemplate/search/quotation.html
index fbc35be..6badb13 100755
--- a/httemplate/search/quotation.html
+++ b/httemplate/search/quotation.html
@@ -1,20 +1,22 @@
 <& elements/search.html,
-                 'title'       => emt('Quotation Search Results'),
-                 'html_init'   => $html_init,
-                 'menubar'     => $menubar,
-                 'name'        => 'quotations',
-                 'query'       => $sql_query,
-                 'count_query' => $count_query,
-                 'count_addl'  => $count_addl,
-                 'redirect'    => $link,
-                 'header'      => [ emt('Quotation #'),
-                                    emt('Setup'),
-                                    emt('Recurring'),
-                                    emt('Date'),
-                                    emt('Prospect'),
-                                    emt('Customer'),
-                                  ],
-                 'fields'      => [
+                 'title'              => emt('Quotation Search Results'),
+                 'html_init'          => $html_init,
+                 'menubar'            => $menubar,
+                 'name'               => 'quotations',
+                 'query'              => $sql_query,
+                 'count_query'        => $count_query,
+                 'count_addl'         => $count_addl,
+                 'redirect'           => $link,
+                 'disableable'        => 1,
+                 'disabled_statuspos' => 1,
+                 'header'             => [ emt('Quotation #'),
+                                           emt('Setup'),
+                                           emt('Recurring'),
+                                           emt('Date'),
+                                           emt('Prospect'),
+                                           emt('Customer'),
+                                         ],
+                 'fields'             => [
                    'quotationnum',
                    sub { $money_char. shift->total_setup },
                    sub { $money_char. shift->total_recur },
@@ -27,7 +29,7 @@
                        },
                    #\&FS::UI::Web::cust_fields,
                  ],
-                 'sort_fields' => [
+                 'sort_fields'        => [
                    'quotationnum',
                    '', #FS::quotation->total_setup_sql,
                    '', #FS::quotation->total_recur_sql,
@@ -43,7 +45,7 @@
                    $link,
                    $prospect_link,
                    $cust_link,
-                   #( map { $_ ne 'Cust. Status' ? $clink : '' }
+                   #( map { $_ ne 'Cust. Status' ? $cust_link : '' }
                    #      FS::UI::Web::cust_header()
                    #),
                  ],
diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi
index 833b6d0..d18c7f7 100755
--- a/httemplate/view/cust_main.cgi
+++ b/httemplate/view/cust_main.cgi
@@ -239,7 +239,7 @@ function areyousure(href, message) {
 % ###
 
 % if ( $view eq 'jumbo' && $curuser->access_right('Generate quotation') ) { 
-  <A NAME="quotation"><FONT SIZE="+2"><% mt('Quotations') |h %></FONT></A><BR>
+  <A NAME="quotations"><FONT SIZE="+2"><% mt('Quotations') |h %></FONT></A><BR>
 % }
 
 % if ( $view eq 'quotations' || $view eq 'jumbo' ) {
diff --git a/httemplate/view/quotation.html b/httemplate/view/quotation.html
index 4c91325..b8dc1d1 100755
--- a/httemplate/view/quotation.html
+++ b/httemplate/view/quotation.html
@@ -7,47 +7,58 @@ function areyousure(href, message) {
 }
 </SCRIPT>
 
-%#XXX link to order...
+% unless ( $quotation->disabled eq 'Y' ) {
 
-<%doc>
+%   if ( $curuser->access_right('Order customer package') ) {
+      <& /elements/order_pkg_link.html,
+           'label'       => emt('Add package'),
+           'actionlabel' => emt('Add package'),
+           map { $_ => $quotation->$_ } qw( quotationnum custnum prospectnum )
+      &>
+      <BR><BR>
+%   }
 
-XXX resending quotations
+%   if ( 1 ) { #if ( $curuser->access_right('Send quotations') )
 
-% if ( $curuser->access_right('Resend invoices') ) {
+%     #if ( grep { $_ ne 'POST' } $cust_bill->cust_main->invoicing_list ) { 
+%#      <A HREF="<% $p %>misc/email-quotation.html?<% $link %>"><% mt('Email this quotation') |h %></A>
+%     #} 
 
-    <A HREF="<% $p %>misc/send-invoice.cgi?method=print;<% $link %>"><% mt('Re-print this invoice') |h %></A>
+%#      <A HREF="<% $p %>misc/send-invoice.cgi?method=print;<% $link %>"><% mt('Re-print this invoice') |h %></A>
 
-%   if ( grep { $_ ne 'POST' } $cust_bill->cust_main->invoicing_list ) { 
-        | <A HREF="<% $p %>misc/send-invoice.cgi?method=email;<% $link %>"><% mt('Re-email this invoice') |h %></A>
-%   } 
+%#%     if ( $conf->exists('hylafax') && length($cust_bill->cust_main->fax) ) { 
+%#           | <A HREF="<% $p %>misc/send-invoice.cgi?method=fax;<% $link %>"><% mt('Re-fax this invoice') |h %></A>
+%#%     } 
 
-%   if ( $conf->exists('hylafax') && length($cust_bill->cust_main->fax) ) { 
-        | <A HREF="<% $p %>misc/send-invoice.cgi?method=fax;<% $link %>"><% mt('Re-fax this invoice') |h %></A>
-%   } 
+%   }
 
-    <BR><BR>
+%   if ( $conf->exists('quotation_latex') ) { 
+      | <A HREF="<% $p %>view/quotation-pdf.cgi?<% $link %>"><% mt('View typeset quotation PDF') |h %></A>
+%   }
 
-% } 
+    <BR><BR>
 
-</%doc>
+%   if ( $curuser->access_right('New customer') && $quotation->quotation_pkg ) {
+      <A HREF="<%$p%>edit/process/quotation_convert.html?quotationnum=<% $quotation->quotationnum %>">Place order</A>
+      <BR><BR>
+%   }
 
-% if ( $curuser->access_right('Order customer package') ) {
-  <& /elements/order_pkg_link.html,
-       'label'       => emt('Add package'),
-       'actionlabel' => emt('Add package'),
-       map { $_ => $quotation->$_ } qw( quotationnum custnum prospectnum )
-  &>
 % }
 
-% if ( $conf->exists('quotation_latex') ) { 
-  | <A HREF="<% $p %>view/quotation-pdf.cgi?<% $link %>"><% mt('View typeset quotation PDF') |h %></A>
+% if ( $curuser->access_right('Disable quotation') ) {
+%   if ( $quotation->disabled eq 'Y' ) {
+      <A HREF="<%$p%>misc/enable-quotation.html?quotationnum=<% $quotation->quotationnum %>" TITLE="<% emt('Enable this quotation') %>"><% emt('Enable this quotation') %></A>
+%   } else {
+      <% areyousure_link(
+           "${p}misc/disable-quotation.html?quotationnum=". $quotation->quotationnum,
+           emt('Are you sure you want to disable this quotation?'),
+           emt('Disable this quotation'), #tooltip
+           emt('Disable this quotation'), #link
+      ) %>
+%   }
+  <BR><BR>
 % }
 
-% if ( $curuser->access_right('New customer') && $quotation->quotation_pkg ) {
-  | <A HREF="<%$p%>edit/process/quotation_convert.html?quotationnum=<% $quotation->quotationnum %>">Place order</A>
-% }
-
-<BR><BR>
 
 % if ( $conf->exists('quotation_html') ) { 
     <% join('', $quotation->print_html( preref_callback=>$preref_callback )) %>
@@ -83,17 +94,7 @@ my $quotation = qsearchs({
 });
 die "Quotation #$quotationnum not found!" unless $quotation;
 
-my $menubar;
-if ( my $custnum = $quotation->custnum ) {
-  my $display_custnum = $quotation->cust_main->display_custnum;
-  $menubar = menubar(
-    emt("View this customer (#[_1])",$display_custnum) => "${p}view/cust_main.cgi?$custnum",
-  );
-} elsif ( my $prospectnum = $quotation->prospectnum ) {
-  $menubar = menubar(
-    emt("View this prospect (#[_1])",$prospectnum) => "${p}view/prospect_main.html?$prospectnum",
-  );
-}
+my $menubar = menubar( $quotation->cust_or_prospect_label_link($p) );
 
 my $link = "quotationnum=$quotationnum";
 #$link .= ';template='. uri_escape($template) if $template;

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

Summary of changes:
 FS/FS/AccessRight.pm                   |    1 +
 FS/FS/Record.pm                        |   48 ++++++++++----------
 FS/FS/Schema.pm                        |    3 +-
 FS/FS/access_right.pm                  |    1 +
 FS/FS/quotation.pm                     |   62 +++++++++++++++++++++++++
 httemplate/misc/disable-quotation.html |   21 +++++++++
 httemplate/misc/enable-quotation.html  |   21 +++++++++
 httemplate/search/elements/search.html |   10 ++---
 httemplate/search/quotation.html       |   38 ++++++++--------
 httemplate/view/cust_main.cgi          |    2 +-
 httemplate/view/quotation.html         |   77 ++++++++++++++++----------------
 11 files changed, 196 insertions(+), 88 deletions(-)
 create mode 100644 httemplate/misc/disable-quotation.html
 create mode 100644 httemplate/misc/enable-quotation.html




More information about the freeside-commits mailing list