summaryrefslogtreecommitdiff
path: root/httemplate/view
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2015-07-26 15:41:26 -0700
committerIvan Kohler <ivan@freeside.biz>2015-07-26 15:41:26 -0700
commit9aee669886202be7035e6c6049fc71bc99dd3013 (patch)
tree2fd5bf6de74f3d99270587ffb1833e4188a6373d /httemplate/view
parentac20214d38d9af00430423f147b5a0e50751b050 (diff)
parent1add633372bdca3cc7163c2ce48363fed3984437 (diff)
Merge branch 'master' of git.freeside.biz:/home/git/freeside
Diffstat (limited to 'httemplate/view')
-rwxr-xr-xhttemplate/view/cust_bill-tex.cgi51
-rwxr-xr-xhttemplate/view/cust_bill.cgi21
-rwxr-xr-xhttemplate/view/cust_main.cgi9
-rw-r--r--httemplate/view/cust_main/billing.html69
-rw-r--r--httemplate/view/cust_main/contacts.html2
-rw-r--r--httemplate/view/cust_main/menu.html526
-rw-r--r--httemplate/view/cust_main/notes/notes.html2
-rwxr-xr-xhttemplate/view/cust_main/packages.html26
-rw-r--r--httemplate/view/cust_main/packages/package.html26
-rwxr-xr-xhttemplate/view/cust_main/packages/section.html8
-rw-r--r--httemplate/view/cust_main/packages/status.html61
-rw-r--r--httemplate/view/cust_main/payment_history.html4
-rw-r--r--httemplate/view/cust_main/payment_history/invoice.html10
-rw-r--r--httemplate/view/cust_main/payment_history/payment.html103
-rw-r--r--httemplate/view/cust_main/payment_history/voided_invoice.html10
-rw-r--r--httemplate/view/prospect_main.html50
-rw-r--r--httemplate/view/svc_circuit.html9
17 files changed, 618 insertions, 369 deletions
diff --git a/httemplate/view/cust_bill-tex.cgi b/httemplate/view/cust_bill-tex.cgi
new file mode 100755
index 000000000..813376957
--- /dev/null
+++ b/httemplate/view/cust_bill-tex.cgi
@@ -0,0 +1,51 @@
+<% $tex %>
+<%init>
+
+use File::Slurp 'slurp';
+
+die "access denied"
+ unless $FS::CurrentUser::CurrentUser->access_right('View invoices');
+
+my( $invnum, $mode, $template, $notice_name );
+my($query) = $cgi->keywords;
+if ( $query =~ /^((.+)-)?(\d+)(.pdf)?$/ ) { #probably not necessary anymore?
+ $template = $2;
+ $invnum = $3;
+ $notice_name = 'Invoice';
+} else {
+ $invnum = $cgi->param('invnum');
+ $invnum =~ s/\.pdf//i; #probably not necessary anymore
+ $template = $cgi->param('template');
+ $notice_name = ( $cgi->param('notice_name') || 'Invoice' );
+ $mode = $cgi->param('mode');
+}
+
+my $conf = new FS::Conf;
+
+my %opt = (
+ 'unsquelch_cdr' => $conf->exists('voip-cdr_email'),
+ 'template' => $template,
+ 'notice_name' => $notice_name,
+ 'no_coupon' => ($cgi->param('no_coupon') || 0)
+);
+
+my $cust_bill = qsearchs({
+ 'select' => 'cust_bill.*',
+ 'table' => 'cust_bill',
+ 'addl_from' => 'LEFT JOIN cust_main USING ( custnum )',
+ 'hashref' => { 'invnum' => $invnum },
+ 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql,
+});
+die "Invoice #$invnum not found!" unless $cust_bill;
+
+$cust_bill->set(mode => $mode);
+
+my ($file) = $cust_bill->print_latex(\%opt);
+my $tex = slurp("$file.tex");
+
+http_header('Content-Type' => 'text/plain' );
+http_header('Content-Disposition' => "filename=$invnum.tex" );
+http_header('Content-Length' => length($tex) );
+http_header('Cache-control' => 'max-age=60' );
+
+</%init>
diff --git a/httemplate/view/cust_bill.cgi b/httemplate/view/cust_bill.cgi
index f1bcf4d52..2ff3ca883 100755
--- a/httemplate/view/cust_bill.cgi
+++ b/httemplate/view/cust_bill.cgi
@@ -9,30 +9,13 @@ function areyousure(href, message) {
}
</SCRIPT>
-% if ( !$cust_bill->closed ) { # otherwise allow no changes
-% my $can_delete = $conf->exists('deleteinvoices')
-% && $curuser->access_right('Delete invoices');
-% my $can_void = $curuser->access_right('Void invoices');
-% if ( $can_void ) {
+% if ( !$cust_bill->closed && $curuser->access_right('Void invoices') ) {
<& /elements/popup_link.html,
'label' => emt('Void this invoice'),
'actionlabel' => emt('Void this invoice'),
'action' => $p.'misc/void-cust_bill.html?invnum='.$invnum,
&>
-% }
-% if ( $can_void and $can_delete ) {
- &nbsp;|&nbsp;
-% }
-% if ( $can_delete ) {
- <A href="" onclick="areyousure(\
- '<%$p%>misc/delete-cust_bill.html?<% $invnum %>',\
- <% mt('Are you sure you want to delete this invoice?') |js_string %>)"\
- TITLE = "<% mt('Delete this invoice from the database completely') |h %>">\
- <% emt('Delete this invoice') |h %></A>
-% }
-% if ( $can_void or $can_delete ) {
- <BR><BR>
-% }
+ <BR><BR>
% }
% if ( $cust_bill->owed > 0
diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi
index 233c496ac..95cb5da7c 100755
--- a/httemplate/view/cust_main.cgi
+++ b/httemplate/view/cust_main.cgi
@@ -220,13 +220,10 @@ my $cust_main = qsearchs( {
});
die "Customer not found!" unless $cust_main;
-my $title = encode_entities($cust_main->name);
-$title = '#'. $cust_main->display_custnum. " $title";
-# if $conf->exists('cust_main-title-display_custnum');
-$title = mt("Customer")." ".$title;
+my $title = mt("Customer").' #'. $cust_main->display_custnum. ': '.
+ encode_entities($cust_main->name);
-my @agentnums = $curuser->agentnums;
-if (scalar(@agentnums) > 1 ) {
+if ( $curuser->num_agents ) {
$title = encode_entities($cust_main->agent->agent). " $title";
}
diff --git a/httemplate/view/cust_main/billing.html b/httemplate/view/cust_main/billing.html
index 0f794e334..c031ce929 100644
--- a/httemplate/view/cust_main/billing.html
+++ b/httemplate/view/cust_main/billing.html
@@ -19,6 +19,75 @@
<TD><B><% $balance %></B></TD>
</TR>
+% #54: just an arbitrary number i pulled out of my goober. ideally we'd like
+% # to consider e.g. a histogram of num_ncancelled_packages for the entire
+% # customer base, and compare it to a graph of the overhead for generating this
+% # information. (and optimize it better, we could get it more from SQL)
+% if ( $cust_main->num_ncancelled_pkgs < 54 ) {
+% my $sth = dbh->prepare("
+% SELECT DISTINCT freq FROM cust_pkg LEFT JOIN part_pkg USING (pkgpart)
+% WHERE freq IS NOT NULL AND freq != '0'
+% AND ( cancel IS NULL OR cancel = 0 )
+% AND custnum = ?
+% ") or die $DBI::errstr;
+%
+% $sth->execute($cust_main->custnum) or die $sth->errstr;
+
+% #not really a numeric sort because freqs can actually be all sorts of things
+% # but good enough for the 99% cases of ordering monthly quarterly annually
+% my @freqs = sort { $a <=> $b } map { $_->[0] } @{ $sth->fetchall_arrayref };
+%
+% foreach my $freq (@freqs) {
+% my @cust_pkg = qsearch({
+% 'table' => 'cust_pkg',
+% 'addl_from' => 'LEFT JOIN part_pkg USING (pkgpart)',
+% 'hashref' => { 'custnum' => $cust_main->custnum, },
+% 'extra_sql' => 'AND ( cancel IS NULL OR cancel = 0 )
+% AND freq = '. dbh->quote($freq),
+% }) or next;
+%
+% my $freq_pretty = $cust_pkg[0]->part_pkg->freq_pretty;
+%
+% my $amount = 0;
+% foreach my $cust_pkg (@cust_pkg) {
+% my $part_pkg = $cust_pkg->part_pkg;
+% next if $cust_pkg->susp
+% && ! $cust_pkg->option('suspend_bill')
+% && ( ! $part_pkg->option('suspend_bill')
+% || $cust_pkg->option('no_suspend_bill')
+% );
+%
+% my $pkg_amount = 0;
+%
+% #add recurring amounts for this package and its billing add-ons
+% foreach my $l_part_pkg ( $part_pkg->self_and_bill_linked ) {
+% $pkg_amount += $l_part_pkg->base_recur($cust_pkg);
+% }
+%
+% #subtract amounts for any active discounts
+% #(there should only be one at the moment, otherwise this makes no sense)
+% foreach my $cust_pkg_discount ( $cust_pkg->cust_pkg_discount_active ) {
+% my $discount = $cust_pkg_discount->discount;
+% #and only one of these for each
+% $pkg_amount -= $discount->amount;
+% $pkg_amount -= $amount * $discount->percent/100;
+% }
+%
+% $pkg_amount *= ( $cust_pkg->quantity || 1 );
+%
+% $amount += $pkg_amount;
+%
+% }
+
+ <TR>
+ <TH ALIGN="right"><% emt( ucfirst($freq_pretty). ' recurring' ) %></TH>
+ <TD><% $money_char. sprintf('%.2f', $amount) %></TD>
+ </TD>
+ </TR>
+% }
+
+% }
+
% if ( $conf->exists('cust_main-select-prorate_day') ) {
<TR>
<TH ALIGN="right"><% mt('Prorate day of month') |h %></TH>
diff --git a/httemplate/view/cust_main/contacts.html b/httemplate/view/cust_main/contacts.html
index 22a7b9584..e3d5d63cb 100644
--- a/httemplate/view/cust_main/contacts.html
+++ b/httemplate/view/cust_main/contacts.html
@@ -100,7 +100,7 @@
% if ( $location->county ) {
(<% $location->county |h %> county)\
% }
-,<% state_label( $location->state, $location->country ) |h %>
+<% ($location->city || $location->county) ? ', ' : ''%><% state_label( $location->state, $location->country ) |h %>
<% $location->zip %>
</TD>
</TR>
diff --git a/httemplate/view/cust_main/menu.html b/httemplate/view/cust_main/menu.html
index 326c2f954..f8ccc69a5 100644
--- a/httemplate/view/cust_main/menu.html
+++ b/httemplate/view/cust_main/menu.html
@@ -1,107 +1,170 @@
<style type="text/css">
-#menu_ul {
- padding: 0;
- margin: .5em 0 0 0;
+
+#customer_menu {
font-size: smaller;
+ border: none;
+ margin-top: .6em;
+ margin-bottom: 16px;
}
-#menu_ul li {
- margin: 0;
+#customer_menu li {
float: left;
- list-style: none;
- position: relative;
+ padding: .25em;
+}
+
+/* #customer_menu .ui-menu-item */
+#customer_menu > li {
+ background-color: #f8f8f8;
+ padding-left: 0px;
+}
+
+/* #customer_menu .ui-menu-item */
+#customer_menu > li.ui-state-focus {
+ background-color: #f8f8f8;
+ border: 1px solid transparent;
}
-#menu_ul a {
- display: block;
- margin: 0;
+#customer_menu > li.ui-state-active {
+ background-color: #f8f8f8;
+ border: 1px solid transparent;
+}
+
+#customer_menu > li > a {
+ border-top: 1px solid transparent;
+ border-left: 1px solid transparent;
+ border-right: 1px solid transparent;
+ border-bottom: none;
padding: .5em .75em;
- background: #f8f8f8;
- color: #525151;
- white-space: nowrap;
- text-decoration: none;
- border-bottom: thin solid #CFDFDF;
- border-top-left-radius: .5em;
- border-top-right-radius: .5em;
}
-#menu_ul a.current_show {
+#customer_menu > li.ui-state-active > a {
+
+/* if i could find something light enough that didn't look pink?
+ or is this too visually distracting and not the useful hint i think it is?
+ background: #ED55E7;
+*/
+}
+
+#customer_menu a.current_show {
font-weight: bold;
background: #FFFFFF;
- border-top: thin solid #CFDEFF;
- border-left: thin solid #CFDEFF;
- border-right: thin solid #CFDEFF;
- border-bottom: none;
+ border-top: 1px solid #7e0079;
+ border-left: 1px solid #7e0079;
+ border-right: 1px solid #7e0079;
+ border-bottom: 2px solid #ffffff;
+ margin-bottom: -2px;
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
}
-#menu_ul ul {
- margin:0;
- padding:0;
- display:none;
- position: absolute;
- top: 100%;
- left: 0;
+#customer_menu a {
+ margin-left: 0;
+ margin-right: 1em;
+ margin-top: 0;
+ border-top-left-radius: .5em;
+ border-top-right-radius: .5em;
+
+ font-weight: normal;
+ background: #e0e0e0;
+ color: #525151;
+ white-space: nowrap;
+ text-decoration: none;
+}
+
+#customer_menu ul {
background: #ffffff;
- border-top: none;
- border-left: thin solid #CFDEFF;
- border-right: thin solid #CFDEFF;
- border-bottom: thin solid #CFDEFF;
+ border: 1px solid #7e0079;
+ border-radius: 2px;
+ box-shadow: #333333 1px 1px 2px;
}
-#menu_ul ul li {
- margin: 0;
- padding: 0;
+#customer_menu ul li {
float: none;
+ margin-right: 2px;
+ margin-left: 2px;
}
-#menu_ul ul a {
+#customer_menu ul a {
color: #333333;
background: transparent;
- border-bottom: none;
- border-radius: 0;
}
-#menu_ul a:hover {
- background: #cfdeff;
+#customer_menu li.ui-menu-divider {
+ border-color: #7e0079;
+/* margin-right: 2px;
+ margin-left: 2px; */
+}
+
+#customer_menu a:hover {
text-decoration: underline;
color: #7e0079;
}
+#customer_menu ul li.ui-state-focus {
+ background: transparent;
+ border: 1px solid transparent;
+ margin-right: 1px;
+ margin-left: 1px;
+}
+
+#customer_menu ul li.ui-state-active {
+ background: #f8f0fc;
+ border: 1px solid #7e0079;
+ border-radius: 2px;
+ margin-right: 1px;
+ margin-left: 1px;
+}
+
+#customer_menu a .arrow {
+ float: right;
+ background-image: url("<% $p %>images/arrow.right.black.png");
+ width: 3px;
+ height: 6px;
+ margin-top:4px;
+}
+
+@-moz-document url-prefix() {
+ #customer_menu a .arrow {
+ margin-top:-.8em;
+ }
+}
+
</style>
-<script src="<% $p %>elements/jquery.js"></script>
-<script type="text/javascript">
-$(document).ready(function() {
- var openmenu;
- function closemenu () {
- if (openmenu !== undefined) {
- openmenu.hide();
- openmenu = undefined;
- }
- }
- $('#menu_ul > li').hover(function(){
- closemenu();
- openmenu = $('ul:first', this);
- openmenu.show();
- }, function(){
- closemenu();
- });
-});
-</script>
+<& /elements/one_time_charge_link.html, form_only=>1 &>
-<ul id="menu_ul">
+<ul id="customer_menu">
% foreach my $submenu (@processed_menu) {
<li>
<% shift @$submenu %>
- <ul>
-% foreach my $link ( @$submenu ) {
- <li><% $link %></li>
+% if ( @$submenu ) {
+ <ul class="customer_submenu">
+% foreach my $link ( @$submenu ) {
+ <li><% $link %></li>
+% }
+ </ul>
% }
- </ul>
</li>
% }
</ul>
+<script type="text/javascript">
+
+ $("#customer_menu").menu({
+ position: { my: "left top", at: "left+1 bottom+3" },
+ blur: function() {
+ $(this).menu("option", "position", { my:"left top", at:"left+1 bottom+3" } );
+ },
+ focus: function(e,ui) {
+ if ($("#customer_menu").get(0) !== $(ui).get(0).item.parent().get(0)) {
+ $(this).menu("option", "position", { my:"left top", at:"right+2 top"} );
+ }
+ },
+ });
+
+</script>
+
+
<%init>
my %opt = @_;
my $cust_main = $opt{'cust_main'};
@@ -111,6 +174,9 @@ my $conf = FS::Conf->new;
my %payby = map { $_ => 1 } $conf->config('payby');
+# cached for conditions, to avoid looking it up twice
+my $invoicing_list_emailonly = $cust_main->invoicing_list_emailonly;
+
# nice declarative menu; should be a parameter to some kind of menu generator
my @menu = (
[
@@ -126,7 +192,11 @@ my @menu = (
label => 'Edit contacts',
url => "edit/cust_main-contacts.html?$custnum",
},
-# separator
+
+ { label => '-',
+ content => '-',
+ },
+
{
label => 'Bill now',
acl => 'Bill customer now',
@@ -154,7 +224,7 @@ my @menu = (
},
{
label => 'Cancel',
- popup => "misc/suspend_cust.html?custnum=$custnum",
+ popup => "misc/cancel_cust.html?custnum=$custnum",
acl => 'Cancel customer',
condition => sub { shift->ncancelled_pkgs > 0 },
actionlabel => 'Confirm Cancellation',
@@ -173,7 +243,11 @@ my @menu = (
url => "edit/cust_main.cgi?referral_custnum=$custnum",
confexists => '!disable_customer_referrals',
},
-# should have a separator here
+
+ { label => '-',
+ content => '-',
+ },
+
{
label => 'View this customer\'s referrals',
url => "search/cust_main.cgi?referral_custnum=$custnum",
@@ -193,10 +267,12 @@ my @menu = (
url => sub {
my $cust_main = shift;
my $agentnum = $cust_main->agentnum;
- 'misc/email-customers.html?table=cust_main;search_hash='.
- 'agent_virt_agentnum='.$agentnum.";custnum=$custnum";
+ 'misc/email-customers.html?table=cust_main;'.
+ 'agent_virt_agentnum='.$agentnum.";custnum=$custnum;url=".
+ uri_escape($cgi->self_url);
},
- condition => sub { shift->invoicing_list_emailonly },
+ condition => sub { $invoicing_list_emailonly },
+ acl => 'Bulk send customer notices',
},
],
[
@@ -210,7 +286,7 @@ my @menu = (
actionlabel => 'Add note',
confexists => '!cust_main-disable_notes',
acl => 'Add customer note',
- width => 616,
+ width => 875,
height => 538,
},
{
@@ -251,7 +327,7 @@ my @menu = (
show => 'quotations',
},
{
- label => 'Add quotation',
+ label => 'Create new quotation',
url => "edit/quotation.html?custnum=$custnum",
acl => 'Generate quotation',
},
@@ -285,6 +361,7 @@ my @menu = (
content => sub {
include( '/elements/one_time_charge_link.html',
custnum => shift->custnum,
+ no_form => 1,
);
},
acl => 'One-time charge',
@@ -302,7 +379,11 @@ my @menu = (
url => "edit/cust_pkg.cgi?$custnum",
acl => 'Bulk change customer packages',
},
-# separator
+
+ { label => '-',
+ content => '-',
+ },
+
{
label => 'Package reports',
url => "search/report_cust_pkg?custnum=$custnum",
@@ -326,66 +407,80 @@ my @menu = (
label => 'Payment History',
show => 'payment_history',
},
+
# manual payment entry via edit/cust_pay
- {
- label => 'Enter check payment',
- popup => "edit/cust_pay.cgi?popup=1;payby=BILL;custnum=$custnum",
- actionlabel => 'Enter check payment',
- width => 763,
- height => 392,
- acl => [ 'Post payment', 'Post check payment' ],
- condition => sub { $payby{BILL} },
- },
- {
- label => 'Enter cash payment',
- popup => "edit/cust_pay.cgi?popup=1;payby=CASH;custnum=$custnum",
- actionlabel => 'Enter cash payment',
- width => 763,
- height => 392,
- acl => [ 'Post payment', 'Post cash payment' ],
- condition => sub { $payby{CASH} },
- },
- {
- label => 'Enter Western Union payment',
- popup => "edit/cust_pay.cgi?popup=1;payby=WEST;custnum=$custnum",
- actionlabel => 'Enter Western Union payment',
- width => 763,
- height => 392,
- acl => [ 'Post payment', ],
- condition => sub { $payby{WEST} },
- },
- {
- label => 'Post manual (offline/POS) credit card payment',
- popup => "edit/cust_pay.cgi?popup=1;payby=MCRD;custnum=$custnum",
- actionlabel => 'Enter credit card payment',
- width => 763,
- height => 392,
- acl => [ 'Post payment', ],
- condition => sub { $payby{MCRD} },
- },
- {
- label => 'Post manual (offline/POS) electronic check',
- popup => "edit/cust_pay.cgi?popup=1;payby=MCHK;custnum=$custnum",
- actionlabel => 'Enter credit card payment',
- width => 763,
- height => 392,
- acl => [ 'Post payment', ],
- condition => sub { $payby{MCHK} },
+ { label => 'Enter payment',
+ submenu => [
+ {
+ label => 'Enter check payment',
+ popup => "edit/cust_pay.cgi?popup=1;payby=BILL;custnum=$custnum",
+ actionlabel => 'Enter check payment',
+ width => 763,
+ height => 392,
+ acl => [ 'Post payment', 'Post check payment' ],
+ condition => sub { $payby{BILL} },
+ },
+ {
+ label => 'Enter cash payment',
+ popup => "edit/cust_pay.cgi?popup=1;payby=CASH;custnum=$custnum",
+ actionlabel => 'Enter cash payment',
+ width => 763,
+ height => 392,
+ acl => [ 'Post payment', 'Post cash payment' ],
+ condition => sub { $payby{CASH} },
+ },
+ {
+ label => 'Enter Western Union payment',
+ popup => "edit/cust_pay.cgi?popup=1;payby=WEST;custnum=$custnum",
+ actionlabel => 'Enter Western Union payment',
+ width => 763,
+ height => 392,
+ acl => [ 'Post payment', ],
+ condition => sub { $payby{WEST} },
+ },
+ {
+ label => 'Record manual (offline/POS) credit card payment',
+ popup => "edit/cust_pay.cgi?popup=1;payby=MCRD;custnum=$custnum",
+ actionlabel => 'Enter credit card payment',
+ width => 763,
+ height => 392,
+ acl => [ 'Post payment', ],
+ condition => sub { $payby{MCRD} },
+ },
+ {
+ label => 'Record manual (offline/POS) electronic check',
+ popup => "edit/cust_pay.cgi?popup=1;payby=MCHK;custnum=$custnum",
+ actionlabel => 'Enter credit card payment',
+ width => 763,
+ height => 392,
+ acl => [ 'Post payment', ],
+ condition => sub { $payby{MCHK} },
+ },
+ ],
},
+
# realtime payments via payment.cgi
- {
- label => 'Process credit card payment',
- url => "misc/payment.cgi?payby=CARD;custnum=$custnum",
- acl => [ 'Process payment', 'Process credit card payment', ],
- condition => sub { $payby{CARD} or $payby{DCRD} },
+ { label => 'Process payment',
+ submenu => [
+ {
+ label => 'Process credit card payment',
+ url => "misc/payment.cgi?payby=CARD;custnum=$custnum",
+ acl => [ 'Process payment', 'Process credit card payment', ],
+ condition => sub { $payby{CARD} or $payby{DCRD} },
+ },
+ {
+ label => 'Process electronic check payment',
+ url => "misc/payment.cgi?payby=CHEK;custnum=$custnum",
+ acl => [ 'Process payment', 'Process Echeck payment', ],
+ condition => sub { $payby{CHEK} or $payby{DCHK} },
+ },
+ ],
},
- {
- label => 'Process electronic check payment',
- url => "misc/payment.cgi?payby=CHEK;custnum=$custnum",
- acl => [ 'Process payment', 'Process Echeck payment', ],
- condition => sub { $payby{CHEK} or $payby{DCHK} },
+
+ { label => '-',
+ content => '-',
},
-#separator?
+
{
label => 'Enter credit',
popup => "edit/cust_credit.cgi?custnum=$custnum",
@@ -404,38 +499,55 @@ my @menu = (
FS::cust_bill->count('custnum = ?', shift->custnum) > 0
},
},
- {
- label => 'Enter check refund',
- popup => "edit/cust_refund.cgi?popup=1;payby=BILL;custnum=$custnum",
- actionlabel => 'Enter check refund',
- width => 440,
- acl => ['Post refund', 'Post check refund'],
- condition => sub { $payby{BILL} },
- },
- {
- label => 'Enter cash refund',
- popup => "edit/cust_refund.cgi?popup=1;payby=CASH;custnum=$custnum",
- actionlabel => 'Enter cash refund',
- width => 392,
- acl => ['Post refund', 'Post cash refund'],
- condition => sub { $payby{CASH} },
+
+ { label => '-',
+ content => '-',
},
- {
- label => 'Enter manual (offline/POS) credit card refund',
- popup => "edit/cust_refund.cgi?popup=1;payby=MCRD;custnum=$custnum",
- actionlabel => 'Enter credit card refund',
- width => 440,
- acl => ['Post refund' ],
- condition => sub { $payby{MCRD} },
+
+ { label => 'Enter refund',
+ submenu => [
+
+ {
+ label => 'Enter check refund',
+ popup => "edit/cust_refund.cgi?popup=1;payby=BILL;custnum=$custnum",
+ actionlabel => 'Enter check refund',
+ width => 440,
+ acl => ['Post refund', 'Post check refund'],
+ condition => sub { $payby{BILL} },
+ },
+ {
+ label => 'Enter cash refund',
+ popup => "edit/cust_refund.cgi?popup=1;payby=CASH;custnum=$custnum",
+ actionlabel => 'Enter cash refund',
+ width => 392,
+ acl => ['Post refund', 'Post cash refund'],
+ condition => sub { $payby{CASH} },
+ },
+ {
+ label => 'Record manual (offline/POS) credit card refund',
+ popup => "edit/cust_refund.cgi?popup=1;payby=MCRD;custnum=$custnum",
+ actionlabel => 'Enter credit card refund',
+ width => 440,
+ acl => ['Post refund' ],
+ condition => sub { $payby{MCRD} },
+ },
+ {
+ label => 'Record manual (offline/POS) electronic check refund',
+ popup => "edit/cust_refund.cgi?popup=1;payby=MCHK;custnum=$custnum",
+ actionlabel => 'Enter electronic check refund',
+ width => 440,
+ acl => ['Post refund' ],
+ condition => sub { $payby{MCHK} },
+ },
+
+ ],
+
},
- {
- label => 'Enter manual (offline/POS) electronic check refund',
- popup => "edit/cust_refund.cgi?popup=1;payby=MCHK;custnum=$custnum",
- actionlabel => 'Enter electronic check refund',
- width => 440,
- acl => ['Post refund' ],
- condition => sub { $payby{MCHK} },
+
+ { label => '-',
+ content => '-',
},
+
{
label => 'Add tax adjustment',
popup => "edit/cust_tax_adjustment.html?custnum=$custnum",
@@ -444,11 +556,29 @@ my @menu = (
confexists => 'enable_tax_adjustments',
acl => 'Add customer tax adjustment',
},
-# separator, definitely
+
+ { label => '-',
+ content => '-',
+ confexists => 'enable_tax_adjustments',
+ acl => 'Add customer tax adjustment',
+ },
+
+ {
+ label => 'Email statement to this customer',
+ url => sub {
+ my $cust_main = shift;
+ my $agentnum = $cust_main->agentnum;
+ 'misc/email-customer-statement.html?table=cust_main;'.
+ 'agent_virt_agentnum='.$agentnum.";custnum=$custnum;url=".
+ uri_escape($cgi->self_url);
+ },
+ condition => sub { $invoicing_list_emailonly },
+ acl => 'Resend invoices',
+ },
{
- label => 'Download statement',
+ label => 'Download PDF statement',
url => "view/cust_main_statement-pdf.cgi?$custnum",
- acl => 'List invoices',
+ acl => 'View legacy typeset statements',
condition => sub {
FS::cust_bill->count('custnum = ?', shift->custnum) > 0
},
@@ -477,6 +607,7 @@ my @menu = (
FS::cust_pay_pending->count('custnum = ?', shift->custnum) > 0
},
},
+
],
[
{
@@ -498,23 +629,52 @@ foreach my $submenu (@menu) {
last if (!$first and !@links);
$first = 0;
+ my $a = entry2link($entry, $cust_main, $opt{show});
+ push @links, $a if length($a);
+
+ } # foreach $entry
+
+ if (@links) {
+ push @processed_menu, \@links;
+ }
+
+}
+
+sub entry2link {
+ my( $entry, $cust_main, $show ) = @_;
+
# check conditions
if ( $entry->{acl} ) {
- next unless $curuser->access_right( $entry->{acl} );
+ return ''
+ unless $FS::CurrentUser::CurrentUser->access_right( $entry->{acl} );
}
if ( $entry->{confexists} ) {
if ( $entry->{confexists} =~ /^!(.*)/ ) {
# confexists => !foo, a negative condition
- next if $conf->exists( $1 );
+ return '' if FS::Conf->new->exists( $1 );
} else {
- next unless $conf->exists( $entry->{confexists} );
+ return '' unless FS::Conf->new->exists( $entry->{confexists} );
}
}
if ( $entry->{condition} ) {
- next unless &{ $entry->{condition} }($cust_main);
+ return '' unless &{ $entry->{condition} }($cust_main);
}
my $label = emt($entry->{label});
+
+ if ( $entry->{submenu} ) {
+
+ my $a = '<a href="javascript:void(0);">'. $label.
+ '<span class="arrow"></span>'.
+ '</a><ul class="customer_subsubmenu">';
+ foreach my $submenu (@{ $entry->{submenu} }) {
+ $a .= '<li>'. entry2link($submenu, $cust_main, $show), '</li>';
+ }
+
+ return $a. '</ul>';
+
+ }
+
my $target = $entry->{content}
|| $entry->{popup}
|| $entry->{url};
@@ -522,48 +682,44 @@ foreach my $submenu (@menu) {
if ( ref($target) eq 'CODE' ) {
$target = &$target($cust_main);
}
- my $a = '';
- if ( $entry->{content} ) { # then the coderef specified the whole thing
- $a = $target;
+ return $target if $entry->{content}; #the coderef specified the whole thing
- } elsif ( $entry->{show} ) {
+ if ( $entry->{show} ) {
# the menu head: always a link back to this page
$cgi->param('show', $entry->{show});
- $target = $cgi->self_url;
-
- $a = qq[ <A HREF="$target"];
- if ( $opt{'show'} eq $entry->{show} ) {
- $a .= ' class="current_show"';
- }
- $a .= qq[>$label</A> ];
+ $target = $cgi->self_url;
+ $cgi->param('show', $show);
+ my $a = qq[ <A HREF="$target"];
+ $a .= ' class="current_show"' if $show eq $entry->{show};
+ return $a. qq[>$label</A> ];
} elsif ( $entry->{popup} ) {
$target =~ s/\$custnum/$custnum/g;
$target = $p.$target;
- $a = include('/elements/popup_link.html',
+
+ return include('/elements/popup_link.html',
action => $target,
width => 616,
height => 410,
%$entry,
- label => emt($label),
+ label => $label,
);
} elsif ( $entry->{url} ) {
$target =~ s/\$custnum/$custnum/g;
$target = $p.$target;
- $a = qq[ <A HREF="$target">$label</A> ];
- }
- push @links, $a;
+ return qq[ <A HREF="$target">$label</A> ];
+
+ } else {
+ die "bad entry ". join(',',%$entry). " in menu: no url, popup or content";
+ }
- } # foreach $entry
- if (@links) {
- push @processed_menu, \@links;
- }
}
+
</%init>
diff --git a/httemplate/view/cust_main/notes/notes.html b/httemplate/view/cust_main/notes/notes.html
index b4ea87c19..eb421eb37 100644
--- a/httemplate/view/cust_main/notes/notes.html
+++ b/httemplate/view/cust_main/notes/notes.html
@@ -95,7 +95,7 @@
% if ( $conf->exists('cust_main_note-display_times') ) {
<TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Time') |h %></TH>
% }
- <TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Person') |h %></TH>
+ <TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Employee') |h %></TH>
% if ($conf->exists('note-classes') && $conf->config('note-classes') == 1) {
<TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Class') |h %></TH>
% }
diff --git a/httemplate/view/cust_main/packages.html b/httemplate/view/cust_main/packages.html
index 41315701f..4903e185b 100755
--- a/httemplate/view/cust_main/packages.html
+++ b/httemplate/view/cust_main/packages.html
@@ -180,8 +180,11 @@ my @packages = $cust_main->all_pkgs( {
},
} );
+my $is_anything_hidden = 0; # optimization
+
my %change_to_from; # target pkgnum => current cust_pkg, for future changes
my %changed_from; # old pkgnum => new cust_pkg, for past changes
+my %supplementals_of; # main pkgnum => arrayref of supplementals
foreach my $cust_pkg ( @packages ) {
my %hash = $cust_pkg->hash;
@@ -190,18 +193,33 @@ foreach my $cust_pkg ( @packages ) {
$cust_pkg->{'_pkgpart'} = new FS::part_pkg \%part_pkg;
if ( $cust_pkg->change_to_pkgnum ) {
$change_to_from{$cust_pkg->change_to_pkgnum} = $cust_pkg;
+ $is_anything_hidden = 1;
}
if ( $cust_pkg->change_pkgnum ) {
$changed_from{$cust_pkg->change_pkgnum} = $cust_pkg;
+ $is_anything_hidden = 1;
+ }
+ if ( $cust_pkg->main_pkgnum ) {
+ $supplementals_of{$cust_pkg->main_pkgnum} ||= [];
+ push @{ $supplementals_of{$cust_pkg->main_pkgnum} }, $cust_pkg;
+ $is_anything_hidden = 1;
}
}
# filter out hidden package changes
-if ( keys %change_to_from or keys %changed_from ) {
+if ( $is_anything_hidden ) {
my @displayable_packages;
foreach my $cust_pkg (@packages) {
- if ( exists( $change_to_from{$cust_pkg->pkgnum} ) ) {
+ # if this package has any supplemental packages, it should remember them
+ $cust_pkg->set('_supplemental', $supplementals_of{$cust_pkg->pkgnum});
+
+ if ( $cust_pkg->main_pkgnum ) {
+
+ # it's a supplemental package of something else, and shouldn't be on the
+ # root list
+
+ } elsif ( exists( $change_to_from{$cust_pkg->pkgnum} ) ) {
# $cust_pkg is an ordered, not-yet-active package change target
my $change_from = $change_to_from{ $cust_pkg->pkgnum };
@@ -217,7 +235,9 @@ if ( keys %change_to_from or keys %changed_from ) {
$changed_to->set('changed_from_pkg', $cust_pkg);
} else {
+
push @displayable_packages, $cust_pkg;
+
}
}
@@ -252,7 +272,7 @@ $num_old_packages -= scalar(@packages);
# don't include supplemental packages in this list; they'll be found from
# their main packages
# (as will change-target packages)
-@packages = grep !$_->main_pkgnum, @packages;
+####@packages = grep !$_->main_pkgnum, @packages;
foreach my $cust_pkg ( @packages ) {
$cust_pkg->{'_cust_pkg_discount_active'} =
diff --git a/httemplate/view/cust_main/packages/package.html b/httemplate/view/cust_main/packages/package.html
index 3036f2e84..8aa64039c 100644
--- a/httemplate/view/cust_main/packages/package.html
+++ b/httemplate/view/cust_main/packages/package.html
@@ -1,7 +1,6 @@
-<TD CLASS="inv package" BGCOLOR="<% $bgcolor %>" VALIGN="top" <%$style%>>
+<TD CLASS="inv package" BGCOLOR="<% $bgcolor %>" VALIGN="top">
+ <% join('', @marker ) %>
<TABLE CLASS="inv package">
-
-
<TR>
<TD COLSPAN=2>
<% $opt{before_pkg_callback}
@@ -107,7 +106,7 @@
% ) {
(&nbsp;<%pkg_event_link($cust_pkg)%>&nbsp;)
% }
-% } #!$supplemental
+% } # a canceled recurring package, or else no_links is in effect
</FONT>
</TD>
@@ -297,6 +296,7 @@
</TABLE>
% }
+ <% join('', map '</DIV>', @marker ) %>
</TD>
<%init>
@@ -317,16 +317,12 @@ my $statedefault = $opt{'statedefault'}
# if this package is somehow special
my $supplemental = $opt{'supplemental'} || 0;
my $change_from = $opt{'change_from'} || 0;
-my $style = '';
-if ( $supplemental or $change_from ) {
- $style = 'border-left-width: '.($supplemental + $change_from)*30 . 'px; '.
- 'border-color: ';
- if ( $supplemental ) {
- $style .= '#bbbbff';
- } elsif ( $change_from ) {
- $style .= '#bbffbb';
- }
- $style = qq!STYLE="$style"!;
+my @marker;
+if ( $supplemental ) {
+ push @marker, '<DIV CLASS="package-marker-supplemental">';
+}
+if ( $change_from ) {
+ push @marker, '<DIV CLASS="package-marker-change_from">';
}
$cust_pkg->pkgnum =~ /^(\d+)$/;
@@ -357,7 +353,7 @@ sub pkg_change_link {
'actionlabel' => emt('Change'),
'cust_pkg' => $cust_pkg,
'width' => 960,
- 'height' => 490,
+ 'height' => 538,
);
}
diff --git a/httemplate/view/cust_main/packages/section.html b/httemplate/view/cust_main/packages/section.html
index fe9f283c7..490f09c12 100755
--- a/httemplate/view/cust_main/packages/section.html
+++ b/httemplate/view/cust_main/packages/section.html
@@ -71,9 +71,11 @@
<& .packagerow, $cust_pkg->change_to_pkg, %iopt, 'change_from' => 1 &>
% }
% # include supplemental packages if any
-% $iopt{'supplemental'} = ($iopt{'supplemental'} || 0) + 1;
-% foreach my $supp_pkg ($cust_pkg->supplemental_pkgs) {
- <& .packagerow, $supp_pkg, %iopt &>
+% if ( $cust_pkg->_supplemental ) {
+% $iopt{'supplemental'} = ($iopt{'supplemental'} || 0) + 1;
+% foreach my $supp_pkg (@{ $cust_pkg->_supplemental }) {
+ <& .packagerow, $supp_pkg, %iopt &>
+% }
% }
</%def>
<%shared>
diff --git a/httemplate/view/cust_main/packages/status.html b/httemplate/view/cust_main/packages/status.html
index 8057d8c3a..7e125f72e 100644
--- a/httemplate/view/cust_main/packages/status.html
+++ b/httemplate/view/cust_main/packages/status.html
@@ -44,11 +44,11 @@
</TR>
% }
%
-% } else {
+% } else { # not canceled
%
% if ( $cust_pkg->get('susp') ) { #suspended or on hold
%
-% #if ( $cust_pkg->order_date eq $cust_pkg->get('susp') ) { # inconsistent with FS::cust_pkg::status
+% #if ( $cust_pkg->order_date eq $cust_pkg->get('susp') ) # inconsistent with FS::cust_pkg::status
% if ( ! $cust_pkg->setup ) { #status: on hold
<% pkg_status_row( $cust_pkg, emt('On Hold'), '', 'color'=>'7E0079', %opt ) %>
@@ -79,7 +79,7 @@
% } else {
<% pkg_status_row($cust_pkg, emt('Setup'), 'setup', %opt ) %>
% }
-% }
+% }
<% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
@@ -97,7 +97,10 @@
<% pkg_status_row_expire($cust_pkg, %opt, curuser=>$curuser) %>
<% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
-% if ( !$supplemental && ! $opt{no_links} && !$change_from ) {
+% # Status changes for suspended packages: can unsuspend, future-unsuspend,
+% # or future-change. If this package is a future change or is supplemental
+% # disable them all.
+% if ( !$supplemental && ! $opt{no_links} && !$change_from ) {
<TR>
<TD COLSPAN=<%$opt{colspan}%>>
<FONT SIZE=-1>
@@ -203,7 +206,7 @@
<% pkg_status_row_if($cust_pkg, emt('Un-cancelled'), 'uncancel', %opt ) %>
-% } else {
+% } else { # recurring package
%
% my $num_cust_svc = $cust_pkg->num_cust_svc;
% my $summarize = $opt{'cust_pkg-large_pkg_size'} > 0
@@ -259,7 +262,11 @@
<% pkg_status_row_expire($cust_pkg, %opt, curuser=>$curuser) %>
<% pkg_status_row_if( $cust_pkg, emt('Contract ends'), 'contract_end', %opt ) %>
-% if ( $part_pkg->freq and !$supplemental && ! $opt{no_links} ) {
+% # Status changes for active recurring packages. If it has a future
+% # package change scheduled, let that be modified. If it's supplemental,
+% # then that's the only allowed action. Otherwise allow suspend, future
+% # suspend, do-not-suspend, and immediate and future cancel.
+% if ( $part_pkg->freq and ! $opt{no_links} ) {
<TR>
<TD COLSPAN=<%$opt{colspan}%>>
@@ -277,27 +284,29 @@
% }
% }
+% if ( !$supplemental ) {
% # suspension actions--always available
-% if ( $curuser->access_right('Suspend customer package') ) {
- (&nbsp;<% pkg_suspend_link($cust_pkg) %>&nbsp;)
-% }
-% if ( $curuser->access_right('Suspend customer package later') ) {
- (&nbsp;<% pkg_adjourn_link($cust_pkg) %>&nbsp;)
-% }
-% if ( $curuser->access_right('Delay suspension events') ) {
- (&nbsp;<% pkg_delay_link($cust_pkg) %>&nbsp;)
-% }
+% if ( $curuser->access_right('Suspend customer package') ) {
+ (&nbsp;<% pkg_suspend_link($cust_pkg) %>&nbsp;)
+% }
+% if ( $curuser->access_right('Suspend customer package later') ) {
+ (&nbsp;<% pkg_adjourn_link($cust_pkg) %>&nbsp;)
+% }
+% if ( $curuser->access_right('Delay suspension events') ) {
+ (&nbsp;<% pkg_delay_link($cust_pkg) %>&nbsp;)
+% }
%
-% if ( $change_from or $cust_pkg->change_to_pkgnum ) {
-% # you can't cancel the package while in this state
-% } else { # the normal case: links to cancel the package
- <BR>
-% if ( $curuser->access_right('Cancel customer package immediately') ) {
- (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
+% if ( $change_from or $cust_pkg->change_to_pkgnum ) {
+% # you can't cancel the package while in this state
+% } else { # the normal case: links to cancel the package
+ <BR>
+% if ( $curuser->access_right('Cancel customer package immediately') ) {
+ (&nbsp;<% pkg_cancel_link($cust_pkg) %>&nbsp;)
+% }
+% if ( $curuser->access_right('Cancel customer package later') ) {
+ (&nbsp;<% pkg_expire_link($cust_pkg) %>&nbsp;)
+% }
% }
-% if ( $curuser->access_right('Cancel customer package later') ) {
- (&nbsp;<% pkg_expire_link($cust_pkg) %>&nbsp;)
-% }
% }
<FONT>
@@ -417,6 +426,10 @@ sub pkg_status_row_expire {
} elsif ( $cust_pkg->change_to_pkg->locationnum != $cust_pkg->locationnum )
{
$title = mt('Will <b>change location</b> on');
+ } elsif (( $cust_pkg->change_to_pkg->quantity != $cust_pkg->quantity ) ||
+ ( $cust_pkg->change_to_pkg->contract_end != $cust_pkg->contract_end ))
+ {
+ $title = mt('Will change on');
} else {
# FS::cust_pkg->change_later should have prevented this, but
# just so that we can display _something_
diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html
index 458469cb1..e3599bc06 100644
--- a/httemplate/view/cust_main/payment_history.html
+++ b/httemplate/view/cust_main/payment_history.html
@@ -217,7 +217,7 @@ my %opt = (
qw( card_refund-days date_format )
),
( map { $_ => $conf->exists($_) }
- qw( deleteinvoices deletepayments deleterefunds pkg-balances
+ qw( deletepayments deleterefunds pkg-balances
cust_credit_bill_pkg-manual cust_bill_pay_pkg-manual
)
),
@@ -226,7 +226,7 @@ my %opt = (
#rights
( map { $_ => $curuser->access_right($_) }
(
- 'View invoices', 'Void invoices', 'Unvoid invoices', 'Delete invoices',
+ 'View invoices', 'Void invoices', 'Unvoid invoices',
'Apply payment', 'Refund credit card payment', 'Refund Echeck payment',
'Credit card void', 'Echeck void', 'Void payments', 'Unvoid payments',
'Delete payment', 'Unapply payment',
diff --git a/httemplate/view/cust_main/payment_history/invoice.html b/httemplate/view/cust_main/payment_history/invoice.html
index acb1d6956..be4e93e31 100644
--- a/httemplate/view/cust_main/payment_history/invoice.html
+++ b/httemplate/view/cust_main/payment_history/invoice.html
@@ -1,4 +1,4 @@
-<% $link %><% $invoice %><% $link ? '</A>' : '' %><% "$void$delete$under" %>
+<% $link %><% $invoice %><% $link ? '</A>' : '' %><% "$void$under" %>
<%init>
my( $cust_bill, %opt ) = @_;
@@ -34,14 +34,6 @@ if ( $cust_bill->closed !~ /^Y/i && $opt{'Void invoices'} ) {
')';
}
-my $delete = '';
-$delete = areyousure_link("${p}misc/delete-cust_bill.html?$invnum",
- emt('Are you sure you want to delete this invoice?'),
- emt('Delete this invoice from the database completely'),
- emt('delete')
- )
- if ( $opt{'deleteinvoices'} && $opt{'Delete invoices'} );
-
my $events = '';
if ( $cust_bill->num_cust_event
&& ($opt{'Billing event reports'} || $opt{'View customer billing events'})
diff --git a/httemplate/view/cust_main/payment_history/payment.html b/httemplate/view/cust_main/payment_history/payment.html
index 4ec9271ef..bf88a6607 100644
--- a/httemplate/view/cust_main/payment_history/payment.html
+++ b/httemplate/view/cust_main/payment_history/payment.html
@@ -9,6 +9,7 @@ my $date_format = $opt{'date_format'} || '%m/%d/%Y';
my @cust_bill_pay = $cust_pay->cust_bill_pay;
my @cust_pay_refund = $cust_pay->cust_pay_refund;
+my $unapplied = $cust_pay->unapplied;
my ($payby,$payinfo) = translate_payinfo($cust_pay);
my $target = "$payby$payinfo";
@@ -50,39 +51,14 @@ if ( scalar(@cust_bill_pay) == 0
$payment = emt("Unapplied Payment by [_1]",$otaker);
$payment =~ s/$otaker/<i>$otaker<\/i>/ if $italicize_otaker;
$payment = '<B><FONT COLOR="#FF0000">'.$payment.'</FONT></B>';
- if ( $opt{'Apply payment'} ) {
- if ( $opt{total_owed} > 0 ) {
- $apply = ' ('.
- include( '/elements/popup_link.html',
- 'label' => emt('apply'),
- 'action' => "${p}edit/cust_bill_pay.cgi?".
- $cust_pay->paynum,
- 'actionlabel' => emt('Apply payment'),
- %cust_bill_pay_width,
- %cust_bill_pay_height,
- ).
- ')';
- }
- if ( $opt{total_unapplied_refunds} > 0 ) {
- $apply.= ' ('.
- include( '/elements/popup_link.html',
- 'label' => emt('apply to refund'),
- 'action' => "${p}edit/cust_pay_refund.cgi?".
- $cust_pay->paynum,
- 'actionlabel' => emt('Apply payment to refund'),
- 'width' => 392,
- ).
- ')';
- }
- }
} elsif ( scalar(@cust_bill_pay) == 1
&& scalar(@cust_pay_refund) == 0
- && $cust_pay->unapplied == 0 ) {
+ && $unapplied == 0 ) {
#applied to one invoice, the usual situation
$desc .= ' '. $cust_bill_pay[0]->applied_to_invoice;
} elsif ( scalar(@cust_bill_pay) == 0
&& scalar(@cust_pay_refund) == 1
- && $cust_pay->unapplied == 0 ) {
+ && $unapplied == 0 ) {
#applied to one refund
$desc .= emt(" refunded on [_1]", time2str($date_format, $cust_pay_refund[0]->_date) );
} else {
@@ -101,40 +77,59 @@ if ( scalar(@cust_bill_pay) == 0
die "$app is not a FS::cust_bill_pay or FS::cust_pay_refund";
}
}
- if ( $cust_pay->unapplied > 0 ) {
+ if ( $unapplied > 0 ) {
$desc .= '&nbsp;&nbsp;'.
'<B><FONT COLOR="#FF0000">'.
- emt("[_1][_2] unapplied", $opt{money_char}, $cust_pay->unapplied).
+ emt("[_1][_2] unapplied", $opt{money_char}, $unapplied).
'</FONT></B>';
- if ( $opt{'Apply payment'} ) {
- if ( $opt{total_owed} > 0 ) {
- $apply = ' ('.
- include( '/elements/popup_link.html',
- 'label' => emt('apply'),
- 'action' => "${p}edit/cust_bill_pay.cgi?".
- $cust_pay->paynum,
- 'actionlabel' => emt('Apply payment'),
- %cust_bill_pay_width,
- %cust_bill_pay_height,
- ).
- ')';
- }
- if ( $opt{total_unapplied_refunds} > 0 ) {
- $apply.= ' ('.
- include( '/elements/popup_link.html',
- 'label' => emt('apply to refund'),
- 'action' => "${p}edit/cust_pay_refund.cgi?".
- $cust_pay->paynum,
- 'actionlabel' => emt('Apply payment to refund'),
- 'width' => 392,
- ).
- ')';
- }
- }
$desc .= '<BR>';
}
}
+if ($unapplied > 0) {
+ if ( $opt{'Apply payment'} ) {
+ if ( $opt{total_owed} > 0 ) {
+ $apply = ' ('.
+ include( '/elements/popup_link.html',
+ 'label' => emt('apply'),
+ 'action' => "${p}edit/cust_bill_pay.cgi?".
+ $cust_pay->paynum,
+ 'actionlabel' => emt('Apply payment'),
+ %cust_bill_pay_width,
+ %cust_bill_pay_height,
+ ).
+ ')';
+ }
+ if ( $opt{total_unapplied_refunds} > 0 ) {
+ $apply.= ' ('.
+ include( '/elements/popup_link.html',
+ 'label' => emt('apply to refund'),
+ 'action' => "${p}edit/cust_pay_refund.cgi?".
+ $cust_pay->paynum,
+ 'actionlabel' => emt('Apply payment to refund'),
+ 'width' => 392,
+ ).
+ ')';
+ }
+ $apply .= ' (auto&#8209;apply:&nbsp;'
+ . ($cust_pay->no_auto_apply ? 'no' : 'yes')
+ . '&nbsp;|&nbsp;'
+ . include( '/elements/popup_link.html',
+ 'label' => emt($cust_pay->no_auto_apply ? 'yes' : 'no'),
+ 'action' => "${p}edit/process/cust_pay-no_auto_apply.cgi?paynum="
+ . $cust_pay->paynum
+ . '&no_auto_apply='
+ . ($cust_pay->no_auto_apply ? '' : 'Y'),
+ 'actionlabel' => emt('Toggle Auto-Apply'),
+ 'width' => 392,
+ 'height' => 200,
+ )
+ . ')';
+ } else { # end if $opt('Apply payment')
+ $apply .= ' (no auto-apply)' if $cust_pay->no_auto_apply;
+ }
+} # end if $unapplied > 0
+
my $view =
' ('. include('/elements/popup_link.html',
'label' => emt('view receipt'),
diff --git a/httemplate/view/cust_main/payment_history/voided_invoice.html b/httemplate/view/cust_main/payment_history/voided_invoice.html
index 3d81e662f..ea61f8446 100644
--- a/httemplate/view/cust_main/payment_history/voided_invoice.html
+++ b/httemplate/view/cust_main/payment_history/voided_invoice.html
@@ -10,7 +10,7 @@
% }
<% mt("on [_1]", time2str($date_format, $cust_bill_void->void_date) ) |h %>
</I>
-<% "$unvoid$delete$under" %>
+<% "$unvoid$under" %>
<%init>
my( $cust_bill_void, %opt ) = @_;
@@ -35,14 +35,6 @@ $unvoid = areyousure_link("${p}misc/unvoid-cust_bill_void.html?invnum=". $cust_b
)
if $cust_bill_void->closed !~ /^Y/ && $opt{'Unvoid invoices'};
-my $delete = '';
-$delete = areyousure_link("${p}misc/delete-cust_bill.html?$invnum",
- emt('Are you sure you want to delete this invoice?'),
- emt('Delete this invoice from the database completely'),
- emt('delete')
- )
- if $opt{'deleteinvoices'} && $opt{'Delete invoices'};
-
my $events = '';
if ( $cust_bill_void->num_cust_event
&& ($opt{'Billing event reports'} || $opt{'View customer billing events'})
diff --git a/httemplate/view/prospect_main.html b/httemplate/view/prospect_main.html
index b5ef64f48..8c93d6c02 100644
--- a/httemplate/view/prospect_main.html
+++ b/httemplate/view/prospect_main.html
@@ -1,40 +1,22 @@
-<& /elements/header.html, 'Prospect View: '. $prospect_main->company &>
+<& /elements/header.html, $title &>
% if ( $curuser->access_right('Edit prospect') ) {
<A HREF="<% $p %>edit/prospect_main.html?<% $prospectnum %>">Edit this prospect</A>
% }
-<% ntable("#cccccc",2) %>
-
-<TR>
- <TD ALIGN="right">Prospect #</TD>
- <TD BGCOLOR="#FFFFFF"><B><% $prospectnum %></B>
-% if ( $prospect_main->disabled ) {
- <B>(DISABLED)</B>
-% }
- </TD>
-</TR>
-
-%unless ( scalar(@agentnums) == 1
-% && !$curuser->access_right('View customers of all agents') ) {
-% my $agent = qsearchs('agent',{ 'agentnum' => $prospect_main->agentnum } );
- <TR>
- <TD ALIGN="right">Agent</TD>
- <TD BGCOLOR="#ffffff"><% $agent->agentnum %>: <% $agent->agent |h %></TD>
- </TR>
-%}
+<TABLE CLASS="fsinnerbox">
%unless ( ! $prospect_main->refnum ) { # || scalar(@part_referral) == 1 ) {
% my $part_referral = qsearchs('part_referral',{ 'refnum' => $prospect_main->refnum } );
<TR>
- <TD ALIGN="right">Advertising source</TD>
+ <TH ALIGN="right">Advertising source</TD>
<TD BGCOLOR="#ffffff"><% $part_referral->referral |h %></TD>
</TR>
%}
% if ( $prospect_main->company ) {
<TR>
- <TD ALIGN="right">Company</TD>
+ <TH ALIGN="right">Company</TD>
<TD BGCOLOR="#FFFFFF"><B><% $prospect_main->company |h %></B></TD>
</TR>
% }
@@ -42,7 +24,7 @@
% foreach my $prospect_contact ( $prospect_main->prospect_contact ) {
% my $contact = $prospect_contact->contact;
<TR>
- <TD ALIGN="right"><% $prospect_contact->contact_classname %> Contact</TD>
+ <TH ALIGN="right"><% $prospect_contact->contact_classname %> Contact</TD>
<TD BGCOLOR="#FFFFFF"><% $contact->line %></TD>
</TR>
%}
@@ -52,7 +34,7 @@
% #but only one, for now
% foreach my $cust_location (@cust_location) {
<TR>
- <TD ALIGN="right">Address</TD>
+ <TH ALIGN="right">Address</TD>
<TD BGCOLOR="#FFFFFF">
<% $cust_location->location_label(
'join_string' => '<BR>',
@@ -71,7 +53,7 @@
% }
% if ( my $tax_status = $prospect_main->tax_status ) {
<TR>
- <TD ALIGN="right">Tax status</TD>
+ <TH ALIGN="right">Tax status</TD>
<TD BGCOLOR="#FFFFFF">
<B><% $tax_status->taxstatus %>:</B> <% $tax_status->description %>
</TD>
@@ -100,15 +82,7 @@
<BR><BR>
% }
-<!--
-<% ntable("#cccccc") %>
-
-<TR>
- <TH CLASS="background" COLSPAN=2 ALIGN="left"><FONT SIZE="+1">Tickets</FONT></TH>
-</TR>
-
-</TABLE>
--->
+%# XXX display prospect tickets
<%init>
@@ -134,6 +108,14 @@ my $prospect_main = qsearchs( {
});
die "Prospect not found!" unless $prospect_main;
+my $title = encode_entities($prospect_main->name);
+$title = mt("Prospect"). ": $title";
+$title .= ' ('.mt('DISABLED').')'
+ if $prospect_main->disabled;
+
my @agentnums = $curuser->agentnums;
+if (scalar(@agentnums) > 1 ) {
+ $title = encode_entities($prospect_main->agent->agent). " $title";
+}
</%init>
diff --git a/httemplate/view/svc_circuit.html b/httemplate/view/svc_circuit.html
index 42bfc4b21..579ef5150 100644
--- a/httemplate/view/svc_circuit.html
+++ b/httemplate/view/svc_circuit.html
@@ -1,8 +1,9 @@
<& elements/svc_Common.html,
- 'table' => 'svc_circuit',
- 'labels' => \%labels,
- 'fields' => \@fields,
- 'html_foot' => sub { $self->call_method('.foot', @_) },
+ 'table' => 'svc_circuit',
+ 'labels' => \%labels,
+ 'fields' => \@fields,
+ 'html_foot' => sub { $self->call_method('.foot', @_) },
+ 'edit_url' => $fsurl.'edit/svc_circuit.html?',
&>
<%method .foot>
% my $svc_circuit = shift;