summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/AccessRight.pm1
-rw-r--r--FS/FS/Record.pm48
-rw-r--r--FS/FS/access_right.pm1
-rw-r--r--FS/FS/quotation.pm62
-rw-r--r--httemplate/misc/disable-quotation.html21
-rw-r--r--httemplate/misc/enable-quotation.html21
-rw-r--r--httemplate/search/elements/search.html10
-rwxr-xr-xhttemplate/search/quotation.html38
-rwxr-xr-xhttemplate/view/cust_main.cgi2
-rwxr-xr-xhttemplate/view/quotation.html77
10 files changed, 194 insertions, 87 deletions
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;