From: Ivan Kohler Date: Sun, 18 Jan 2015 22:03:07 +0000 (-0800) Subject: disable quotations, RT#20688, RT#22232 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=85c78d955fbc2fd6c3991156b387d37c185b9f64 disable quotations, RT#20688, RT#22232 --- diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index 4a1f89aa0..121f83c40 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 25e61d079..4546741a9 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 e5a5781a9..d5e3b8b51 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 e72e6cf4d..5710b383e 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 000000000..a6c48299f --- /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) ); + + diff --git a/httemplate/misc/enable-quotation.html b/httemplate/misc/enable-quotation.html new file mode 100644 index 000000000..e5bb49990 --- /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) ); + + diff --git a/httemplate/search/elements/search.html b/httemplate/search/elements/search.html index 3fb1e3e74..62a0e4786 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 fbc35bea1..6badb13b7 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 833b6d08c..d18c7f70f 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') ) { - <% mt('Quotations') |h %>
+ <% mt('Quotations') |h %>
% } % if ( $view eq 'quotations' || $view eq 'jumbo' ) { diff --git a/httemplate/view/quotation.html b/httemplate/view/quotation.html index 4c913257e..b8dc1d1f9 100755 --- a/httemplate/view/quotation.html +++ b/httemplate/view/quotation.html @@ -7,47 +7,58 @@ function areyousure(href, message) { } -%#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 ) + &> +

+% } -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 ) { +%# <% mt('Email this quotation') |h %> +% #} - <% mt('Re-print this invoice') |h %> +%# <% mt('Re-print this invoice') |h %> -% if ( grep { $_ ne 'POST' } $cust_bill->cust_main->invoicing_list ) { - | <% mt('Re-email this invoice') |h %> -% } +%#% if ( $conf->exists('hylafax') && length($cust_bill->cust_main->fax) ) { +%# | <% mt('Re-fax this invoice') |h %> +%#% } -% if ( $conf->exists('hylafax') && length($cust_bill->cust_main->fax) ) { - | <% mt('Re-fax this invoice') |h %> -% } +% } -

+% if ( $conf->exists('quotation_latex') ) { + | <% mt('View typeset quotation PDF') |h %> +% } -% } +

- +% if ( $curuser->access_right('New customer') && $quotation->quotation_pkg ) { + Place order +

+% } -% 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') ) { - | <% mt('View typeset quotation PDF') |h %> +% if ( $curuser->access_right('Disable quotation') ) { +% if ( $quotation->disabled eq 'Y' ) { + <% emt('Enable this quotation') %> +% } 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 + ) %> +% } +

% } -% if ( $curuser->access_right('New customer') && $quotation->quotation_pkg ) { - | Place order -% } - -

% 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;