From 96b69dd1aa5c8045b5a4297ecea510d60f575251 Mon Sep 17 00:00:00 2001 From: Jonathan Prykop Date: Mon, 9 Nov 2015 17:05:36 -0600 Subject: RT#34960: Quotations [changed billpkgnum to quotationpkgnum] --- FS/FS/Schema.pm | 4 ++-- FS/FS/TemplateItem_Mixin.pm | 7 ++++--- FS/FS/quotation_pkg.pm | 23 +++++++---------------- FS/FS/quotation_pkg_detail.pm | 7 +++---- httemplate/edit/quotation_pkg_detail.html | 10 +++++----- 5 files changed, 21 insertions(+), 30 deletions(-) diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 6b5d6586c..7880cc10c 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1973,7 +1973,7 @@ sub tables_hashref { 'quotation_pkg_detail' => { 'columns' => [ 'detailnum', 'serial', '', '', '', '', - 'billpkgnum', 'int', '', '', '', '', # actually links to quotationpkgnum + 'quotationpkgnum', 'int', '', '', '', '', 'format', 'char', 'NULL', 1, '', '', # not used for anything 'detail', 'varchar', '', 255, '', '', ], @@ -1981,7 +1981,7 @@ sub tables_hashref { 'unique' => [], 'index' => [ [ 'billpkgnum' ] ], 'foreign_keys' => [ - { columns => [ 'billpkgnum' ], + { columns => [ 'quotationpkgnum' ], table => 'quotation_pkg', references => [ 'quotationpkgnum' ], }, diff --git a/FS/FS/TemplateItem_Mixin.pm b/FS/FS/TemplateItem_Mixin.pm index dcd7ab3fb..248da3cae 100644 --- a/FS/FS/TemplateItem_Mixin.pm +++ b/FS/FS/TemplateItem_Mixin.pm @@ -175,6 +175,7 @@ sub details { my $escape_function = $opt{escape_function} || sub { shift }; my $csv = new Text::CSV_XS; + my $key = $self->primary_key; if ( $opt{format_function} ) { @@ -189,14 +190,14 @@ sub details { ) } qsearch ({ 'table' => $self->detail_table, - 'hashref' => { 'billpkgnum' => $self->billpkgnum }, + 'hashref' => { $key => $self->get($key) }, 'order_by' => 'ORDER BY detailnum', }); } elsif ( $opt{'no_usage'} ) { my $sql = "SELECT detail FROM ". $self->detail_table. - " WHERE billpkgnum = ". $self->billpkgnum. + " WHERE " . $key . " = ". $self->get($key). " AND ( format IS NULL OR format != 'C' ) ". " ORDER BY detailnum"; my $sth = dbh->prepare($sql) or die dbh->errstr; @@ -251,7 +252,7 @@ sub details { } my $sql = "SELECT format, detail FROM ". $self->detail_table. - " WHERE billpkgnum = ". $self->billpkgnum. + " WHERE " . $key . " = ". $self->get($key). " ORDER BY detailnum"; my $sth = dbh->prepare($sql) or die dbh->errstr; $sth->execute or die $sth->errstr; diff --git a/FS/FS/quotation_pkg.pm b/FS/FS/quotation_pkg.pm index 49d0d9a5c..e264209ef 100644 --- a/FS/FS/quotation_pkg.pm +++ b/FS/FS/quotation_pkg.pm @@ -101,21 +101,8 @@ sub display_table { 'quotation_pkg'; } # # (for invoice display order) sub discount_table { 'quotation_pkg_discount'; } - -# detail table uses non-quotation fieldnames, see billpkgnum below sub detail_table { 'quotation_pkg_detail'; } -=item billpkgnum - -Sets/returns quotationpkgnum, for ease of integration with TemplateItem_Mixin::details - -=cut - -sub billpkgnum { - my $self = shift; - $self->quotationpkgnum(@_); -} - =item insert Adds this record to the database. If there is an error, returns the error, @@ -380,7 +367,7 @@ sub delete_details { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - foreach my $detail ( qsearch('quotation_pkg_detail',{ 'billpkgnum' => $self->quotationpkgnum }) ) { + foreach my $detail ( qsearch('quotation_pkg_detail',{ 'quotationpkgnum' => $self->quotationpkgnum }) ) { my $error = $detail->delete; if ( $error ) { $dbh->rollback if $oldAutoCommit; @@ -416,8 +403,8 @@ sub set_details { foreach my $detail ( @details ) { my $quotation_pkg_detail = new FS::quotation_pkg_detail { - 'billpkgnum' => $self->quotationpkgnum, - 'detail' => $detail, + 'quotationpkgnum' => $self->quotationpkgnum, + 'detail' => $detail, }; $error = $quotation_pkg_detail->insert; if ( $error ) { @@ -431,6 +418,10 @@ sub set_details { } +sub details_header { + return (); +} + =item cust_bill_pkg_display [ type => TYPE ] =cut diff --git a/FS/FS/quotation_pkg_detail.pm b/FS/FS/quotation_pkg_detail.pm index be3d81529..ce13589f0 100644 --- a/FS/FS/quotation_pkg_detail.pm +++ b/FS/FS/quotation_pkg_detail.pm @@ -34,10 +34,9 @@ currently supported: primary key -=item billpkgnum +=item quotationpkgnum -named thusly for quick compatability with L, -actually the quotationpkgnum for the relevant L +for the relevant L =item detail @@ -108,7 +107,7 @@ sub check { my $error = $self->ut_numbern('detailnum') - || $self->ut_foreign_key('billpkgnum', 'quotation_pkg', 'quotationpkgnum') + || $self->ut_foreign_key('quotationpkgnum', 'quotation_pkg', 'quotationpkgnum') || $self->ut_text('detail') ; return $error if $error; diff --git a/httemplate/edit/quotation_pkg_detail.html b/httemplate/edit/quotation_pkg_detail.html index b8f589a9a..80a904420 100644 --- a/httemplate/edit/quotation_pkg_detail.html +++ b/httemplate/edit/quotation_pkg_detail.html @@ -21,15 +21,11 @@ <% $part_pkg->comment |h %> - - Detail: - - % my $row = 0; % for ( @details ) { - + <% $row ? '' : 'Detail' %> @@ -63,6 +59,10 @@ var row = document.createElement('TR'); var empty_cell = document.createElement('TD'); + if (!rownum) { + empty_cell.innerHTML = 'Detail:' + empty_cell.style.textAlign = 'right'; + } row.appendChild(empty_cell); var detail_cell = document.createElement('TD'); -- cgit v1.2.1 From adde23e02a271005a708519efd82c43f388cfdee Mon Sep 17 00:00:00 2001 From: Jonathan Prykop Date: Mon, 9 Nov 2015 18:53:42 -0600 Subject: RT#18439: Sorting routers alphabetically, routers disappear --- httemplate/browse/router.cgi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/httemplate/browse/router.cgi b/httemplate/browse/router.cgi index ef8ad3160..85512f8df 100644 --- a/httemplate/browse/router.cgi +++ b/httemplate/browse/router.cgi @@ -43,11 +43,13 @@ my @menubar = ( 'Add a new router', "${p2}edit/router.cgi" ); if ($cgi->param('hidecustomerrouters') eq '1') { $extra_sql = 'WHERE svcnum > 0'; - $cgi->param('hidecustomerrouters', 0); + $cgi->delete('hidecustomerrouters'); push @menubar, 'Show customer routers', $cgi->self_url(); + $cgi->param('hidecustomerrouters', 1); } else { $cgi->param('hidecustomerrouters', 1); push @menubar, 'Hide customer routers', $cgi->self_url(); + $cgi->delete('hidecustomerrouters'); } my $count_sql = $extra_sql. ( $extra_sql =~ /WHERE/ ? ' AND' : 'WHERE' ). -- cgit v1.2.1 From d719b00e871830c3b8d48d4f713ae455b4c1b5b5 Mon Sep 17 00:00:00 2001 From: Jonathan Prykop Date: Mon, 9 Nov 2015 19:58:47 -0600 Subject: RT#36806: Add message template substitution to show last four digits of credit card number --- FS/FS/msg_template.pm | 32 +++++++++++++++++--------------- httemplate/edit/msg_template/email.html | 2 ++ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/FS/FS/msg_template.pm b/FS/FS/msg_template.pm index 01a656366..7d9750cc2 100644 --- a/FS/FS/msg_template.pm +++ b/FS/FS/msg_template.pm @@ -462,6 +462,17 @@ my $usage_warning = sub { # If you add anything, be sure to add a description in # httemplate/edit/msg_template.html. sub substitutions { + my $payinfo_sub = sub { + my $obj = shift; + ($obj->payby eq 'CARD' || $obj->payby eq 'CHEK') + ? $obj->paymask + : $obj->decrypt($obj->payinfo) + }; + my $payinfo_end = sub { + my $obj = shift; + my $payinfo = &$payinfo_sub($obj); + substr($payinfo, -4); + }; { 'cust_main' => [qw( display_custnum agentnum agent_name @@ -608,11 +619,8 @@ sub substitutions { # overrides the one in cust_main in cases where a cust_pay is passed [ payby => sub { FS::payby->shortname(shift->payby) } ], [ date => sub { time2str("%a %B %o, %Y", shift->_date) } ], - [ payinfo => sub { - my $cust_pay = shift; - ($cust_pay->payby eq 'CARD' || $cust_pay->payby eq 'CHEK') ? - $cust_pay->paymask : $cust_pay->decrypt($cust_pay->payinfo) - } ], + [ 'payinfo' => $payinfo_sub ], + [ 'payinfo_end' => $payinfo_end ], ], # for refund receipts 'cust_refund' => [ @@ -620,11 +628,8 @@ sub substitutions { [ refund => sub { sprintf("%.2f", shift->refund) } ], [ payby => sub { FS::payby->shortname(shift->payby) } ], [ date => sub { time2str("%a %B %o, %Y", shift->_date) } ], - [ payinfo => sub { - my $cust_refund = shift; - ($cust_refund->payby eq 'CARD' || $cust_refund->payby eq 'CHEK') ? - $cust_refund->paymask : $cust_refund->decrypt($cust_refund->payinfo) - } ], + [ 'payinfo' => $payinfo_sub ], + [ 'payinfo_end' => $payinfo_end ], ], # for payment decline messages # try to support all cust_pay fields @@ -636,11 +641,8 @@ sub substitutions { [ paid => sub { sprintf("%.2f", shift->paid) } ], [ payby => sub { FS::payby->shortname(shift->payby) } ], [ date => sub { time2str("%a %B %o, %Y", shift->_date) } ], - [ payinfo => sub { - my $pending = shift; - ($pending->payby eq 'CARD' || $pending->payby eq 'CHEK') ? - $pending->paymask : $pending->decrypt($pending->payinfo) - } ], + [ 'payinfo' => $payinfo_sub ], + [ 'payinfo_end' => $payinfo_end ], ], }; } diff --git a/httemplate/edit/msg_template/email.html b/httemplate/edit/msg_template/email.html index 12a4a6f56..53f538b11 100644 --- a/httemplate/edit/msg_template/email.html +++ b/httemplate/edit/msg_template/email.html @@ -300,6 +300,7 @@ my %substitutions = ( '$payby' => 'Payment method', '$date' => 'Payment date', '$payinfo' => 'Card/account# (masked)', + '$payinfo_end' => 'Card/account last 4 digits', '$error' => 'Decline reason', ], 'cust_refund' => [ @@ -308,6 +309,7 @@ my %substitutions = ( '$payby' => 'Refund method', '$date' => 'Refund date', '$payinfo' => 'Card/account# (masked)', + '$payinfo_end' => 'Card/account last 4 digits', ], 'system_log' => [ '$logmessage' => 'Log entry message', -- cgit v1.2.1 From 33f34ee0cbcaa0ef2cce678f843dfc0a0b6d17bd Mon Sep 17 00:00:00 2001 From: Jonathan Prykop Date: Mon, 9 Nov 2015 23:36:07 -0600 Subject: RT#24739: Announcment page for customers logged into portal --- FS/FS/ClientAPI/MyAccount.pm | 5 +++++ FS/FS/Conf.pm | 7 +++++++ fs_selfservice/FS-SelfService/cgi/myaccount.html | 3 ++- ng_selfservice/main.php | 8 +++++--- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index f272cd490..6e76e1d1b 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -669,6 +669,11 @@ sub customer_info_short { } + # this is here because this routine is called by both fs_ and ng_ main pages, where it appears + # it is not customer-specific, though it is only shown to authenticated customers + # it is not currently agent-specific, though at some point it might be + $return{'announcement'} = join(' ',$conf->config('selfservice-announcement')) || ''; + return { 'error' => '', 'custnum' => $custnum, %return, diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 990f2a3be..ffe53027d 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -5678,6 +5678,13 @@ and customer address. Include units.', 'type' => 'checkbox', }, + { + 'key' => 'selfservice-announcement', + 'section' => 'self-service', + 'description' => 'HTML announcement to display to all authenticated users on account overview page', + 'type' => 'textarea', + }, + { 'key' => 'logout-timeout', 'section' => 'UI', diff --git a/fs_selfservice/FS-SelfService/cgi/myaccount.html b/fs_selfservice/FS-SelfService/cgi/myaccount.html index 309021a87..524be1f6a 100644 --- a/fs_selfservice/FS-SelfService/cgi/myaccount.html +++ b/fs_selfservice/FS-SelfService/cgi/myaccount.html @@ -55,9 +55,10 @@ Hello <%= $name %>!

} else { $OUT .= '

You have no outstanding invoices.

'; } - %> +<%= $announcement || '' %> + <%= if ( @support_services ) { $OUT .= ''. diff --git a/ng_selfservice/main.php b/ng_selfservice/main.php index 792c961af..6c12d5260 100644 --- a/ng_selfservice/main.php +++ b/ng_selfservice/main.php @@ -17,13 +17,15 @@ extract($customer_info); ?> -Hello

+

Hello

- Thank you for being a customer since

+

Thank you for being a customer since

-Your current balance is: $

+

Your current balance is: $

+ + + +% } else { +<% include('/elements/header-popup.html', 'Merge Reasons') %> +% if ($error) { +

<% emt($error) %>

+% } +% if (@reasons > 1) { +

+The following reasons will be merged into one. +Please select one reason to merge the others into. +

+"> +

+% foreach my $reason (@reasons) { + + +<% $reason->reason %>
+% } +

+

Caution: merging reasons cannot be undone!

+

+ +% } else { + +% } +% } + +<%init> +my @reasonnums = $cgi->param('reasonnum'); +my $destreasonnum = $cgi->param('destreasonnum'); + +my $error; +my $class; +my @reasons; +my $destreason; +foreach my $reasonnum (@reasonnums) { + unless ($reasonnum =~ /^\d+$/) { + $error = "Invalid reasonnum $reasonnum."; + last; + } + my $reason = qsearchs('reason',{ 'reasonnum' => $reasonnum }); + unless ($reason) { + $error = "Reason $reasonnum could not be loaded."; + last; + } + my $reasontype = $reason->reasontype; + $class ||= $reasontype->class; + if ($class ne $reasontype->class) { + $error = "Selected reasons must have the same reason type class."; + last; + } + push(@reasons, $reason); + $destreason = $reason if $reasonnum eq $destreasonnum; +} + +unless ($error) { + $error = "No reasons selected." unless @reasons; + $error = "Select two or more reasons to merge." unless @reasons > 1; +} + +@reasons = () if $error; + +my $success = 0; +if ($cgi->param('process_merge') && !$error) { + if ($destreason) { + $error = $destreason->merge(\@reasons); + $success = 1 unless $error; + } else { + $error = "No desitation reason selected."; + } +} + + -- cgit v1.2.1 From 06ba67f2db8e73955cd98e25927c4c6751539426 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Fri, 13 Nov 2015 16:42:40 -0800 Subject: remove ugly workaround for Params::Classify bug, #32456 --- FS/FS/Password_Mixin.pm | 4 ++-- debian/control | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FS/FS/Password_Mixin.pm b/FS/FS/Password_Mixin.pm index af4c5e2b7..c4549c727 100644 --- a/FS/FS/Password_Mixin.pm +++ b/FS/FS/Password_Mixin.pm @@ -4,7 +4,7 @@ use FS::Record qw(qsearch); use FS::Conf; use FS::password_history; use Authen::Passphrase; -# use Authen::Passphrase::BlowfishCrypt; # ha ha, no. +use Authen::Passphrase::BlowfishCrypt; # https://rt.cpan.org/Ticket/Display.html?id=72743 our $DEBUG = 1; @@ -12,7 +12,7 @@ our $conf; FS::UID->install_callback( sub { $conf = FS::Conf->new; # this is safe - eval "use Authen::Passphrase::BlowfishCrypt;"; + #eval "use Authen::Passphrase::BlowfishCrypt;"; }); our $me = '[' . __PACKAGE__ . ']'; diff --git a/debian/control b/debian/control index 11c71ea8c..2764f706d 100644 --- a/debian/control +++ b/debian/control @@ -87,7 +87,7 @@ Depends: gnupg,ghostscript,gsfonts,gzip,latex-xcolor, libemail-address-list-perl, libsymbol-global-name-perl, libdate-extract-perl, librole-basic-perl, libhtml-formattext-withlinks-andtables-perl, libcrypt-x509-perl, - libdata-guid-perl + libdata-guid-perl, libparams-classify-perl (>= 0.013-5.1) Suggests: libbusiness-onlinepayment-perl Description: Libraries for Freeside billing and trouble ticketing Freeside is a web-based billing and trouble ticketing application. -- cgit v1.2.1 From c0886229d19cfa798580fbeb342826fd11ceeeb0 Mon Sep 17 00:00:00 2001 From: Jonathan Prykop Date: Mon, 16 Nov 2015 19:32:09 -0600 Subject: RT#17480: Freeside Cancel Reason [small fixes] --- httemplate/misc/reason-merge.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/httemplate/misc/reason-merge.html b/httemplate/misc/reason-merge.html index a531e582c..14f5ebb84 100644 --- a/httemplate/misc/reason-merge.html +++ b/httemplate/misc/reason-merge.html @@ -1,9 +1,7 @@ % if ($success) { <% include('/elements/header-popup.html', 'Reason Merge Success') %> % } else { <% include('/elements/header-popup.html', 'Merge Reasons') %> @@ -72,7 +70,7 @@ if ($cgi->param('process_merge') && !$error) { $error = $destreason->merge(\@reasons); $success = 1 unless $error; } else { - $error = "No desitation reason selected."; + $error = "No destination reason selected."; } } -- cgit v1.2.1