diff options
Diffstat (limited to 'httemplate/browse')
23 files changed, 2357 insertions, 0 deletions
diff --git a/httemplate/browse/access_group.html b/httemplate/browse/access_group.html new file mode 100644 index 000000000..ca162a094 --- /dev/null +++ b/httemplate/browse/access_group.html @@ -0,0 +1,82 @@ +<% include( 'elements/browse.html', + 'title' => 'Internal Access Groups', + 'menubar' => [ # 'Main menu' => $p, + 'Internal users' => $p.'browse/access_user.html', + ], + 'html_init' => $html_init, + 'name' => 'internal access groups', + 'query' => { 'table' => 'access_group', + 'hashref' => {}, + 'extra_sql' => 'ORDER BY groupname', #?? + }, + 'count_query' => $count_query, + 'header' => [ '#', + 'Group name', + 'Agents', + 'Rights', + ], + 'fields' => [ 'groupnum', + 'groupname', + $agents_sub, + $rights_sub, + ], + 'links' => [ $link, + $link, + '', + '', + ], + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $html_init = + "Internal access groups control access to the back-office interface.<BR><BR>". + qq!<A HREF="${p}edit/access_group.html"><I>Add an internal access group</I></A><BR><BR>!; + +#false laziness w/access_user.html & agent_type.cgi +my $agents_sub = sub { + my $access_group = shift; + + [ map { + my $access_groupagent = $_; + my $agent = $access_groupagent->agent; + [ + { + 'data' => $agent->agent, + 'align' => 'left', + 'link' => $p. 'edit/agent.cgi?'. $agent->agentnum, + }, + ]; + } + grep { $_->agent } #? + $access_group->access_groupagent, + + ]; + +}; + +my $rights_sub = sub { + my $access_group = shift; + + [ map { my $access_right = $_; + [ + { + 'data' => $access_right->rightname, + 'align' => 'left', + }, + ]; + } + $access_group->access_rights, + + ]; + +}; + +my $count_query = 'SELECT COUNT(*) FROM access_group'; + +my $link = [ $p.'edit/access_group.html?', 'groupnum' ]; + +</%init> diff --git a/httemplate/browse/access_user.html b/httemplate/browse/access_user.html new file mode 100644 index 000000000..8eb3e330a --- /dev/null +++ b/httemplate/browse/access_user.html @@ -0,0 +1,102 @@ +<% include( 'elements/browse.html', + 'title' => 'Internal Users', + 'menubar' => [ #'Main menu' => $p, + 'Internal access groups' => $p.'browse/access_group.html', + ], + 'html_init' => $html_init, + 'html_posttotal' => $posttotal, + 'name' => 'internal users', + 'query' => { 'table' => 'access_user', + 'hashref' => \%search, + 'extra_sql' => 'ORDER BY last, first', + }, + 'count_query' => $count_query, + 'header' => \@header, + 'fields' => \@fields, + 'links' => \@links, + 'style' => \@style, + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $html_init = + "Internal users have access to the back-office interface. Typically, this is your employees and contractors, but in a VISP setup, you can also add accounts for your reseller's employees. It is <B>highly recommended</B> to add a <B>separate account for each person</B> rather than using role accounts.<BR><BR>". + qq!<A HREF="${p}edit/access_user.html"><I>Add an internal user</I></A><BR><BR>!; + +#false laziness w/part_pkg.cgi +my %search = (); +my $search = ''; +unless ( $cgi->param('showdisabled') ) { + %search = ( 'disabled' => '' ); + $search = "( disabled = '' OR disabled IS NULL )"; +} + +#false laziness w/access_group.html & agent_type.cgi +my $groups_sub = sub { + my $access_user = shift; + + [ map { + my $access_usergroup = $_; + my $access_group = $access_usergroup->access_group; + [ + { + 'data' => $access_group->groupname, + 'align' => 'left', + 'link' => + $p. 'edit/access_group.html?'. $access_usergroup->groupnum, + }, + ]; + } + grep { $_->access_group # and ! $_->access_group->disabled + } + $access_user->access_usergroup, + + ]; + +}; + +my $posttotal; +if ( $cgi->param('showdisabled') ) { + $cgi->param('showdisabled', 0); + $posttotal = '( <a href="'. $cgi->self_url. '">hide disabled users</a> )'; + $cgi->param('showdisabled', 1); +} else { + $cgi->param('showdisabled', 1); + $posttotal = '( <a href="'. $cgi->self_url. '">show disabled users</a> )'; + $cgi->param('showdisabled', 0); +} + +my $count_query = 'SELECT COUNT(*) FROM access_user'; +$count_query .= " WHERE $search" + if $search; + +my $link = [ $p.'edit/access_user.html?', 'usernum' ]; + +my @header = ( '#', 'Username' ); +my @fields = ( 'usernum', 'username' ); +my $align = 'rl'; +my @links = ( $link, $link ); +my @style = ( '', '' ); + +#false laziness w/part_pkg.cgi +#unless ( $cgi->param('showdisabled') ) { #its been reversed already +if ( $cgi->param('showdisabled') ) { #its been reversed already + push @header, 'Status'; + push @fields, sub { shift->disabled + ? '<FONT COLOR="#FF0000">DISABLED</FONT>' + : '<FONT COLOR="#00CC00">Active</FONT>' + }; + push @links, ''; + $align .= 'c'; + push @style, 'b'; +} + +push @header, 'Full name', 'Groups'; +push @fields, 'name', $groups_sub; +push @links, $link, ''; +$align .= 'll'; + +</%init> diff --git a/httemplate/browse/addr_block.cgi b/httemplate/browse/addr_block.cgi new file mode 100644 index 000000000..408d57298 --- /dev/null +++ b/httemplate/browse/addr_block.cgi @@ -0,0 +1,86 @@ +<% include("/elements/header.html",'Address Blocks', menubar('Main Menu' => $p)) %> +% +% +%use NetAddr::IP; +% +%my @addr_block = qsearch('addr_block', {}); +%my @router = qsearch('router', {}); +%my $block; +%my $p2 = popurl(2); +%my $path = $p2 . "edit/process/addr_block"; +% +% +% if ($cgi->param('error')) { + + <FONT SIZE="+1" COLOR="#ff0000">Error: <%$cgi->param('error')%></FONT> + <BR><BR> +% } + + +<%table()%> +% foreach $block (sort {$a->NetAddr cmp $b->NetAddr} @addr_block) { + + <TR> + <TD><%$block->NetAddr%></TD> +% if (my $router = $block->router) { +% if (scalar($block->svc_broadband) == 0) { + + <TD> + <%$router->routername%> + </TD> + <TD> + <FORM ACTION="<%$path%>/deallocate.cgi" METHOD="POST"> + <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%$block->blocknum%>"> + <INPUT TYPE="submit" NAME="submit" VALUE="Deallocate"> + </FORM> + </TD> +% } else { + + <TD COLSPAN="2"> + <%$router->routername%> + </TD> +% } +% } else { + + <TD> + <FORM ACTION="<%$path%>/allocate.cgi" METHOD="POST"> + <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%$block->blocknum%>"> + <SELECT NAME="routernum" SIZE="1"> +% foreach (@router) { + + <OPTION VALUE="<%$_->routernum %>"><%$_->routername%></OPTION> +% } + + </SELECT> + <INPUT TYPE="submit" NAME="submit" VALUE="Allocate"> + </FORM> + </TD> + <TD> + <FORM ACTION="<%$path%>/split.cgi" METHOD="POST"> + <INPUT TYPE="hidden" NAME="blocknum" VALUE="<%$block->blocknum%>"> + <INPUT TYPE="submit" NAME="submit" VALUE="Split"> + </FORM> + </TD> + </TR> +% } +% } + + <TR><TD COLSPAN="3"><BR></TD></TR> + <TR> + <FORM ACTION="<%$path%>/add.cgi" METHOD="POST"> + <TD>Gateway/Netmask</TD> + <TD> + <INPUT TYPE="text" NAME="ip_gateway" SIZE="15">/<INPUT TYPE="text" NAME="ip_netmask" SIZE="2"> + </TD> + <TD> + <INPUT TYPE="submit" NAME="submit" VALUE="Add"> + </TD> + </FORM> + </TR> +</TABLE> +</BODY> +</HTML> +<%init> +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); +</%init> diff --git a/httemplate/browse/agent.cgi b/httemplate/browse/agent.cgi new file mode 100755 index 000000000..063f259de --- /dev/null +++ b/httemplate/browse/agent.cgi @@ -0,0 +1,374 @@ +<% include("/elements/header.html",'Agent Listing', menubar( + 'Main Menu' => $p, + 'Agent Types' => $p. 'browse/agent_type.cgi', +# 'Add new agent' => '../edit/agent.cgi' +)) %> +Agents are resellers of your service. Agents may be limited to a subset of your +full offerings (via their type).<BR><BR> +<A HREF="<% $p %>edit/agent.cgi"><I>Add a new agent</I></A><BR><BR> +% if ( dbdef->table('agent')->column('disabled') ) { + + <% $cgi->param('showdisabled') + ? do { $cgi->param('showdisabled', 0); + '( <a href="'. $cgi->self_url. '">hide disabled agents</a> )'; } + : do { $cgi->param('showdisabled', 1); + '( <a href="'. $cgi->self_url. '">show disabled agents</a> )'; } + %> +% } + + +<% include('/elements/table-grid.html') %> +% my $bgcolor1 = '#eeeeee'; +% my $bgcolor2 = '#ffffff'; +% my $bgcolor = ''; +% + + +<TR> + <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=<% ( $cgi->param('showdisabled') || !dbdef->table('agent')->column('disabled') ) ? 2 : 3 %>>Agent</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Type</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Customers</TH> + <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Customer<BR>packages</FONT></TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Reports</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Registration codes</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Prepaid cards</TH> +% if ( $conf->config('ticket_system') ) { + + <TH CLASS="grid" BGCOLOR="#cccccc">Ticketing</TH> +% } + + <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Payment Gateway Overrides</FONT></TH> + <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Freq.</FONT></TH> + <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1>Prog.</FONT></TH> +</TR> +% +%# <TH><FONT SIZE=-1>Agent #</FONT></TH> +%# <TH>Agent</TH> +% +%foreach my $agent ( sort { +% #$a->getfield('agentnum') <=> $b->getfield('agentnum') +% $a->getfield('agent') cmp $b->getfield('agent') +%} qsearch('agent', \%search ) ) { +% +% my $cust_main_link = $p. 'search/cust_main.cgi?agentnum_on=1&'. +% 'agentnum='. $agent->agentnum; +% +% my $cust_pkg_link = $p. 'search/cust_pkg.cgi?agentnum='. $agent->agentnum; +% +% if ( $bgcolor eq $bgcolor1 ) { +% $bgcolor = $bgcolor2; +% } else { +% $bgcolor = $bgcolor1; +% } +% +% + + + <TR> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><A HREF="<%$p%>edit/agent.cgi?<% $agent->agentnum %>"> + <% $agent->agentnum %></A></TD> +% if ( dbdef->table('agent')->column('disabled') +% && !$cgi->param('showdisabled') ) { + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><% $agent->disabled ? 'DISABLED' : '' %></TD> +% } + + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><A HREF="<%$p%>edit/agent.cgi?<% $agent->agentnum %>"> + <% $agent->agent %></A></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><A HREF="<%$p%>edit/agent_type.cgi?<% $agent->typenum %>"><% $agent->agent_type->atype %></A></TD> + + <TD CLASS="inv" BGCOLOR="<% $bgcolor %>"> + <TABLE CLASS="inv" CELLSPACING=0 CELLPADDING=0> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#7e0079"> + <% my $num_prospect = $agent->num_prospect_cust_main %> + </FONT> + </TH> + + <TD> +% if ( $num_prospect ) { + + <A HREF="<% $cust_main_link %>&prospect=1"> +% } +prospects +% if ($num_prospect ) { +</A> +% } + + <TD> + </TR> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#0000CC"> + <% my $num_inactive = $agent->num_inactive_cust_main %> + </FONT> + </TH> + + <TD> +% if ( $num_inactive ) { + + <A HREF="<% $cust_main_link %>&inactive=1"> +% } +inactive +% if ( $num_inactive ) { +</A> +% } + + </TD> + </TR> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#00CC00"> + <% my $num_active = $agent->num_active_cust_main %> + </FONT> + </TH> + + <TD> +% if ( $num_active ) { + + <A HREF="<% $cust_main_link %>&active=1"> +% } +active +% if ( $num_active ) { +</A> +% } + + </TD> + </TR> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#FF9900"> + <% my $num_susp = $agent->num_susp_cust_main %> + </FONT> + </TH> + + <TD> +% if ( $num_susp ) { + + <A HREF="<% $cust_main_link %>&suspended=1"> +% } +suspended +% if ( $num_susp ) { +</A> +% } + + </TD> + </TR> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#FF0000"> + <% my $num_cancel = $agent->num_cancel_cust_main %> + </FONT> + </TH> + + <TD> +% if ( $num_cancel ) { + + <A HREF="<% $cust_main_link %>&showcancelledcustomers=1&cancelled=1"> +% } +cancelled +% if ( $num_cancel ) { +</A> +% } + + </TD> + </TR> + + </TABLE> + </TD> + + <TD CLASS="inv" BGCOLOR="<% $bgcolor %>" VALIGN="bottom"> + <TABLE CLASS="inv" CELLSPACING=0 CELLPADDING=0> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#0000CC"> + <% my $num_inactive_pkg = $agent->num_inactive_cust_pkg %> + </FONT> + </TH> + + <TD> +% if ( $num_inactive_pkg ) { + + <A HREF="<% $cust_pkg_link %>&magic=inactive"> +% } +inactive +% if ( $num_inactive_pkg ) { +</A> +% } + + </TD> + </TR> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#00CC00"> + <% my $num_active_pkg = $agent->num_active_cust_pkg %> + </FONT> + </TH> + + <TD> +% if ( $num_active_pkg ) { + + <A HREF="<% $cust_pkg_link %>&magic=active"> +% } +active +% if ( $num_active_pkg ) { +</A> +% } + + </TD> + </TR> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#FF9900"> + <% my $num_susp_pkg = $agent->num_susp_cust_pkg %> + </FONT> + + </TH> + <TD> +% if ( $num_susp_pkg ) { + + <A HREF="<% $cust_pkg_link %>&magic=suspended"> +% } +suspended +% if ( $num_susp_pkg ) { +</A> +% } + + </TD> + </TR> + + <TR> + <TH ALIGN="right" WIDTH="40%"> + <FONT COLOR="#FF0000"> + <% my $num_cancel_pkg = $agent->num_cancel_cust_pkg %> + </FONT> + </TH> + + <TD> +% if ( $num_cancel_pkg ) { + + <A HREF="<% $cust_pkg_link %>&magic=cancelled"> +% } +cancelled +% if ( $num_cancel_pkg ) { +</A> +% } + + </TD> + </TR> + + </TABLE> + </TD> + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <A HREF="<% $p %>search/report_cust_pay.html?agentnum=<% $agent->agentnum %>">Payments</A> + <BR><A HREF="<% $p %>search/report_cust_credit.html?agentnum=<% $agent->agentnum %>">Credits</A> + <BR><A HREF="<% $p %>search/report_receivables.cgi?agentnum=<% $agent->agentnum %>">A/R Aging</A> + <!--<BR><A HREF="<% $p %>search/money_time.cgi?agentnum=<% $agent->agentnum %>">Sales/Credits/Receipts</A>--> + + </TD> + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% my $num_reg_code = $agent->num_reg_code %> +% if ( $num_reg_code ) { + + <A HREF="<%$p%>search/reg_code.html?agentnum=<% $agent->agentnum %>"> +% } +Unused +% if ( $num_reg_code ) { +</A> +% } + + <BR><A HREF="<%$p%>edit/reg_code.cgi?agentnum=<% $agent->agentnum %>">Generate codes</A> + </TD> + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% my $num_prepay_credit = $agent->num_prepay_credit %> +% if ( $num_prepay_credit ) { + + <A HREF="<%$p%>search/prepay_credit.html?agentnum=<% $agent->agentnum %>"> +% } +Unused +% if ( $num_prepay_credit ) { +</A> +% } + + <BR><A HREF="<%$p%>edit/prepay_credit.cgi?agentnum=<% $agent->agentnum %>">Generate cards</A> + </TD> +% if ( $conf->config('ticket_system') ) { + + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> +% if ( $agent->ticketing_queueid ) { + + Queue: <% $agent->ticketing_queueid %>: <% $agent->ticketing_queue %><BR> +% } + + </TD> +% } + + + <TD CLASS="inv" BGCOLOR="<% $bgcolor %>"> + <TABLE CLASS="inv" CELLSPACING=0 CELLPADDING=0> +% foreach my $override ( +% # sort { } want taxclass-full stuff first? and default cards (empty cardtype) +% qsearch('agent_payment_gateway', { 'agentnum' => $agent->agentnum } ) +% ) { +% + + <TR> + <TD> + <% $override->cardtype || 'Default' %> to <% $override->payment_gateway->gateway_module %> (<% $override->payment_gateway->gateway_username %>) + <% $override->taxclass + ? ' for '. $override->taxclass. ' only' + : '' + %> + <FONT SIZE=-1><A HREF="<%$p%>misc/delete-agent_payment_gateway.cgi?<% $override->agentgatewaynum %>">(delete)</A></FONT> + </TD> + </TR> +% } + + <TR> + <TD><FONT SIZE=-1><A HREF="<%$p%>edit/agent_payment_gateway.html?agentnum=<% $agent->agentnum %>">(add override)</A></FONT></TD> + </TR> + </TABLE> + </TD> + +<!-- + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><% $agent->freq %></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><% $agent->prog %></TD> +--> + + </TR> +% } + + + </TABLE> + </BODY> +</HTML> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my %search; +if ( $cgi->param('showdisabled') + || !dbdef->table('agent')->column('disabled') ) { + %search = (); +} else { + %search = ( 'disabled' => '' ); +} + +my $conf = new FS::Conf; + +</%init> diff --git a/httemplate/browse/agent_type.cgi b/httemplate/browse/agent_type.cgi new file mode 100755 index 000000000..b4e4fcf99 --- /dev/null +++ b/httemplate/browse/agent_type.cgi @@ -0,0 +1,63 @@ +<% include( 'elements/browse.html', + 'title' => 'Agent Types', + 'menubar' => [ #'Main menu' => $p, + 'Agents' =>"${p}browse/agent.cgi", + ], + 'html_init' => $html_init, + 'name' => 'agent types', + 'query' => { 'table' => 'agent_type', + 'hashref' => {}, + 'extra_sql' => 'ORDER BY typenum', # 'ORDER BY atype', + }, + 'count_query' => $count_query, + 'header' => [ '#', + 'Agent Type', + 'Packages', + ], + 'fields' => [ 'typenum', + 'atype', + $packages_sub, + ], + 'links' => [ $link, + $link, + '', + ], + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $html_init = +'Agent types define groups of packages that you can then assign to'. +' particular agents.<BR><BR>'. +qq!<A HREF="${p}edit/agent_type.cgi"><I>Add a new agent type</I></A><BR><BR>!; + +my $count_query = 'SELECT COUNT(*) FROM agent_type'; + +#false laziness w/access_user.html +my $packages_sub = sub { +my $agent_type = shift; + +[ map { + my $type_pkgs = $_; + #my $part_pkg = $type_pkgs->part_pkg; + [ + { + #'data' => $part_pkg->pkg. ' - '. $part_pkg->comment, + 'data' => $type_pkgs->pkg. ' - '. $type_pkgs->comment, + 'align' => 'left', + 'link' => $p. 'edit/part_pkg.cgi?'. $type_pkgs->pkgpart, + }, + ]; + } + + $agent_type->type_pkgs_enabled +]; + +}; + +my $link = [ $p.'edit/agent_type.cgi?', 'typenum' ]; + +</%init> diff --git a/httemplate/browse/cust_main_county.cgi b/httemplate/browse/cust_main_county.cgi new file mode 100755 index 000000000..3bbbb4b47 --- /dev/null +++ b/httemplate/browse/cust_main_county.cgi @@ -0,0 +1,170 @@ +<% include('/elements/header.html', "Tax Rate Listing", menubar( + 'Edit tax rates' => $p. "edit/cust_main_county.cgi", +)) %> + + Click on <u>expand country</u> to specify a country's tax rates by state. + <BR>Click on <u>expand state</u> to specify a state's tax rates by county. +% +%my $conf = new FS::Conf; +%my $enable_taxclasses = $conf->exists('enable_taxclasses'); +% +%if ( $enable_taxclasses ) { + + + <BR>Click on <u>expand taxclasses</u> to specify tax classes +% } + + +<BR><BR> +<% table() %> + + <TR> + <TH><FONT SIZE=-1>Country</FONT></TH> + <TH><FONT SIZE=-1>State</FONT></TH> + <TH>County</TH> + <TH>Taxclass<BR><FONT SIZE=-1>(per-package classification)</FONT></TH> + <TH>Tax name<BR><FONT SIZE=-1>(printed on invoices)</FONT></TH> + <TH><FONT SIZE=-1>Tax</FONT></TH> + <TH><FONT SIZE=-1>Exemption</TH> + </TR> +% +%my @regions = sort { $a->country cmp $b->country +% or $a->state cmp $b->state +% or $a->county cmp $b->county +% or $a->taxclass cmp $b->taxclass +% } qsearch('cust_main_county',{}); +% +%my $sup=0; +%#foreach $cust_main_county ( @regions ) { +%for ( my $i=0; $i<@regions; $i++ ) { +% my $cust_main_county = $regions[$i]; +% my $hashref = $cust_main_county->hashref; +% +% + + <TR> + <TD BGCOLOR="#ffffff"><% $hashref->{country} %></TD> +% +% +% my $j; +% if ( $sup ) { +% $sup--; +% } else { +% +% #lookahead +% for ( $j=1; $i+$j<@regions; $j++ ) { +% last if $hashref->{country} ne $regions[$i+$j]->country +% || $hashref->{state} ne $regions[$i+$j]->state +% || $hashref->{tax} != $regions[$i+$j]->tax +% || $hashref->{exempt_amount} != $regions[$i+$j]->exempt_amount +% || $hashref->{setuptax} ne $regions[$i+$j]->setuptax +% || $hashref->{recurtax} ne $regions[$i+$j]->recurtax; +% } +% +% my $newsup=0; +% if ( $j>1 && $i+$j+1 < @regions +% && ( $hashref->{state} ne $regions[$i+$j+1]->state +% || $hashref->{country} ne $regions[$i+$j+1]->country +% ) +% && ( ! $i +% || $hashref->{state} ne $regions[$i-1]->state +% || $hashref->{country} ne $regions[$i-1]->country +% ) +% ) { +% $sup = $j-1; +% } else { +% $j = 1; +% } +% +% + + + <TD ROWSPAN=<% $j %><% + $hashref->{state} + ? ' BGCOLOR="#ffffff">'. $hashref->{state} + : qq! BGCOLOR="#cccccc">(ALL) <FONT SIZE=-1>!. + qq!<A HREF="${p}edit/cust_main_county-expand.cgi?!. $hashref->{taxnum}. + qq!">expand country</A></FONT>! + %> +% if ( $j>1 ) { + + <FONT SIZE=-1><A HREF="<% $p %>edit/process/cust_main_county-collapse.cgi?<% $hashref->{taxnum} %>">collapse state</A></FONT> +% } + + + </TD> +% } +% # $sup=$newsup; + + + <TD +% if ( $hashref->{county} ) { +% + BGCOLOR="#ffffff"><% $hashref->{county} %> +% } else { +% + BGCOLOR="#cccccc">(ALL) +% if ( $hashref->{state} ) { + + <FONT SIZE=-1><A HREF="<% $p %>edit/cust_main_county-expand.cgi?<% $hashref->{taxnum} %>">expand state</A></FONT> +% } +% } + + </TD> + + <TD +% if ( $hashref->{taxclass} ) { +% + BGCOLOR="#ffffff"><% $hashref->{taxclass} %> +% } else { +% + BGCOLOR="#cccccc">(ALL) +% if ( $enable_taxclasses ) { + + <FONT SIZE=-1><A HREF="<% $p %>edit/cust_main_county-expand.cgi?taxclass<% $hashref->{taxnum} %>">expand taxclasses</A></FONT> +% } +% } + + </TD> + + <TD +% if ( $hashref->{taxname} ) { +% + BGCOLOR="#ffffff"><% $hashref->{taxname} %> +% } else { +% + BGCOLOR="#cccccc">Tax +% } + + </TD> + + <TD BGCOLOR="#ffffff"><% $hashref->{tax} %>%</TD> + + <TD BGCOLOR="#ffffff"> +% if ( $hashref->{exempt_amount} > 0 ) { + + $<% sprintf("%.2f", $hashref->{exempt_amount} ) %> per month<BR> +% } +% if ( $hashref->{setuptax} =~ /^Y$/i ) { + + Setup fee<BR> +% } +% if ( $hashref->{recurtax} =~ /^Y$/i ) { + + Recurring fee<BR> +% } + + + </TD> + + </TR> +% } + + +</TABLE> + +<% include('/elements/footer.html') %> +<%init> +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); +</%init> diff --git a/httemplate/browse/elements/browse.html b/httemplate/browse/elements/browse.html new file mode 100644 index 000000000..2cc5a9660 --- /dev/null +++ b/httemplate/browse/elements/browse.html @@ -0,0 +1,6 @@ +<% include( '/search/elements/search.html', + @_, + 'disable_download' => 1, + 'disable_nonefound' => 1, + ) +%> diff --git a/httemplate/browse/inventory_class.html b/httemplate/browse/inventory_class.html new file mode 100644 index 000000000..8ce131ac2 --- /dev/null +++ b/httemplate/browse/inventory_class.html @@ -0,0 +1,93 @@ +<% include( 'elements/browse.html', + 'title' => 'Inventory Classes', + 'name' => 'inventory classes', + 'menubar' => [ 'Add a new inventory class' => + $p.'edit/inventory_class.html', + ], + 'query' => { 'table' => 'inventory_class', }, + 'count_query' => 'SELECT COUNT(*) FROM inventory_class', + 'header' => [ '#', 'Inventory class', 'Inventory' ], + 'fields' => [ 'classnum', + 'classname', + sub { + #my $inventory_class = shift; + my $i_c = shift; + + my $link = + $p. 'search/inventory_item.html?'. + 'classnum='. $i_c->classnum; + + my %actioncol = (); + foreach ( keys %inv_action_link ) { + my($label, $baseurl, $method) = + @{ $inv_action_link{$_} }; + my $url = $baseurl. $i_c->$method(); + $actioncol{$_} = + '<FONT SIZE="-1">'. + '('. + '<A HREF="'.$url.'">'. + $label. + '</A>'. + ')'. + '</FONT>'; + } + + my %num = map { + $_ => $i_c->$_(); + } keys %labels; + + [ map { + [ + { + 'data' => '<B>'. $num{$_}. '</B>', + 'align' => 'right', + }, + { + 'data' => $labels{$_}, + 'align' => 'left', + 'link' => ( $num{$_} + ? $link.$link{$_} + : '' + ), + }, + { 'data' => $actioncol{$_}, + 'align' => 'left', + }, + ] + } keys %labels + ]; + }, + ], + 'links' => [ $link, + $link, + '', + ], + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +tie my %labels, 'Tie::IxHash', + 'num_avail' => 'Available', # <FONT SIZE="-1"><A HREF="eventually">(upload batch)</A></FONT>', + 'num_used' => 'In use', #'Used', #'Allocated', + 'num_total' => 'Total', +; + +my %link = ( + 'num_avail' => ';avail=1', + 'num_used' => ';used=1', + 'num_total' => '', +); + +my %inv_action_link = ( + 'num_avail' => [ 'upload batch', + $p.'misc/inventory_item-import.html?classnum=', + 'classnum' + ], +); + +my $link = [ "${p}edit/inventory_class.html?", 'classnum' ]; + +</%init> diff --git a/httemplate/browse/msgcat.cgi b/httemplate/browse/msgcat.cgi new file mode 100755 index 000000000..2c916dc9f --- /dev/null +++ b/httemplate/browse/msgcat.cgi @@ -0,0 +1,44 @@ +<% include('/elements/header.html', "View Message catalog", menubar( + 'Edit message catalog' => $p. "edit/msgcat.cgi", +)) %> +<% $widget->html %> +<% include('/elements/footer.html') %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $widget = new HTML::Widgets::SelectLayers( + 'selected_layer' => 'en_US', + 'options' => { 'en_US'=>'en_US' }, + 'layer_callback' => sub { + my $layer = shift; + my $html = "<BR>Messages for locale $layer<BR>". table(). + "<TR><TH COLSPAN=2>Code</TH>". + "<TH>Message</TH>"; + $html .= "<TH>en_US Message</TH>" unless $layer eq 'en_US'; + $html .= '</TR>'; + + #foreach my $msgcat ( sort { $a->msgcode cmp $b->msgcode } + # qsearch('msgcat', { 'locale' => $layer } ) ) { + foreach my $msgcat ( qsearch('msgcat', { 'locale' => $layer } ) ) { + $html .= '<TR><TD>'. $msgcat->msgnum. '</TD>'. + '<TD>'. $msgcat->msgcode. '</TD>'. + '<TD>'. $msgcat->msg. '</TD>'; + unless ( $layer eq 'en_US' ) { + my $en_msgcat = qsearchs('msgcat', { + 'locale' => 'en_US', + 'msgcode' => $msgcat->msgcode, + } ); + $html .= '<TD>'. $en_msgcat->msg. '</TD>'; + } + $html .= '</TR>'; + } + + $html .= '</TABLE>'; + $html; + }, + +); + +</%init> diff --git a/httemplate/browse/nas.cgi b/httemplate/browse/nas.cgi new file mode 100755 index 000000000..022c65ea7 --- /dev/null +++ b/httemplate/browse/nas.cgi @@ -0,0 +1,81 @@ +<!-- mason kludge --> +% +% +%print header('NAS ports', menubar( +% 'Main Menu' => $p, +%)); +% +%my $now = time; +% +%foreach my $nas ( sort { $a->nasnum <=> $b->nasnum } qsearch( 'nas', {} ) ) { +% print $nas->nasnum. ": ". $nas->nas. " ". +% $nas->nasfqdn. " (". $nas->nasip. ") ". +% "as of ". time2str("%c",$nas->last). +% " (". &pretty_interval($now - $nas->last). " ago)<br>". +% &table(). "<TR><TH>Nas<BR>Port #</TH><TH>Global<BR>Port #</BR></TH>". +% "<TH>IP address</TH><TH>User</TH><TH>Since</TH><TH>Duration</TH><TR>", +% ; +% foreach my $port ( sort { +% $a->nasport <=> $b->nasport || $a->portnum <=> $b->portnum +% } qsearch( 'port', { 'nasnum' => $nas->nasnum } ) ) { +% my $session = $port->session; +% my($user, $since, $pretty_since, $duration); +% if ( ! $session ) { +% $user = "(empty)"; +% $since = 0; +% $pretty_since = "(never)"; +% $duration = ''; +% } elsif ( $session->logout ) { +% $user = "(empty)"; +% $since = $session->logout; +% } else { +% my $svc_acct = $session->svc_acct; +% $user = "<A HREF=\"$p/view/svc_acct.cgi?". $svc_acct->svcnum. "\">". +% $svc_acct->username. "</A>"; +% $since = $session->login; +% } +% $pretty_since = time2str("%c", $since) if $since; +% $duration = pretty_interval( $now - $since ). " ago" +% unless defined($duration); +% print "<TR><TD>". $port->nasport. "</TD><TD>". $port->portnum. "</TD><TD>". +% $port->ip. "</TD><TD>$user</TD><TD>$pretty_since". +% "</TD><TD>$duration</TD></TR>" +% ; +% } +% print "</TABLE><BR>"; +%} +% +%#Time::Duration?? +%sub pretty_interval { +% my $interval = shift; +% my %howlong = ( +% '604800' => 'week', +% '86400' => 'day', +% '3600' => 'hour', +% '60' => 'minute', +% '1' => 'second', +% ); +% +% my $pretty = ""; +% foreach my $key ( sort { $b <=> $a } keys %howlong ) { +% my $value = int( $interval / $key ); +% if ( $value ) { +% if ( $value == 1 ) { +% $pretty .= +% ( $howlong{$key} eq 'hour' ? 'an ' : 'a ' ). $howlong{$key}. " " +% } else { +% $pretty .= $value. ' '. $howlong{$key}. 's '; +% } +% } +% $interval -= $value * $key; +% } +% $pretty =~ /^\s*(\S.*\S)\s*$/; +% $1; +%} +% +%#print &table(), <<END; +%#<TR> +%# <TH>#</TH> +%# <TH>NAS</ +% + diff --git a/httemplate/browse/part_bill_event.cgi b/httemplate/browse/part_bill_event.cgi new file mode 100755 index 000000000..682058b1d --- /dev/null +++ b/httemplate/browse/part_bill_event.cgi @@ -0,0 +1,123 @@ +<% include("/elements/header.html",'Invoice Event Listing', menubar( 'Main Menu' => $p) ) %> + + Invoice events are actions taken on open invoices.<BR><BR> + +<A HREF="<% $p %>edit/part_bill_event.cgi"><I>Add a new invoice event</I></A> +<BR><BR> + +<% $total %> events +<% $cgi->param('showdisabled') + ? do { $cgi->param('showdisabled', 0); + '( <a href="'. $cgi->self_url. '">hide disabled events</a> )'; } + : do { $cgi->param('showdisabled', 1); + '( <a href="'. $cgi->self_url. '">show disabled events</a> )'; } +%> +<BR><BR> +% tie my %payby, 'Tie::IxHash', FS::payby->cust_payby2longname; +% tie my %freq, 'Tie::IxHash', '1d' => 'daily', '1m' => 'monthly'; +% foreach my $payby ( keys %payby ) { +% my $oldfreq = ''; +% +% my @payby_part_bill_event = +% grep { $payby eq $_->payby } +% sort { ( $a->freq || '1d') cmp ( $b->freq || '1d' ) # for now +% || $a->seconds <=> $b->seconds +% || $a->weight <=> $b->weight +% || $a->eventpart <=> $b->eventpart +% } +% @part_bill_event; +% +% +% if ( @payby_part_bill_event ) { + + + <% include('/elements/table-grid.html') %> +% my $bgcolor1 = '#eeeeee'; +% my $bgcolor2 = '#ffffff'; +% my $bgcolor; +% +% +% foreach my $part_bill_event ( @payby_part_bill_event ) { +% my $url = "${p}edit/part_bill_event.cgi?". $part_bill_event->eventpart; +% my $delay = duration_exact($part_bill_event->seconds); +% ( my $plandata = $part_bill_event->plandata ) =~ s/\n/<BR>/go; +% my $freq = $part_bill_event->freq || '1d'; +% my $reason = $part_bill_event->reasontext ; +% +% if ( $oldfreq ne $freq ) { + + + <TR> + <TH CLASS="grid" BGCOLOR="#999999" COLSPAN=<% $cgi->param('showdisabled') ? 7 : 8 %>><% ucfirst($freq{$freq}) %> event tests for <FONT SIZE="+1"><I><% $payby{$payby} %> customers</I></FONT></TH> + </TR> + + <TR> + <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=<% $cgi->param('showdisabled') ? 2 : 3 %>>Event</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">After</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Action</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Reason</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Options</TH> + <TH CLASS="grid" BGCOLOR="#cccccc">Code</TH> + </TR> +% +% $oldfreq = $freq; +% $bgcolor = ''; +% +% } +% +% if ( $bgcolor eq $bgcolor1 ) { +% $bgcolor = $bgcolor2; +% } else { +% $bgcolor = $bgcolor1; +% } +% + + + <TR> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><A HREF="<% $url %>"> + <% $part_bill_event->eventpart %></A></TD> +% unless ( $cgi->param('showdisabled') ) { + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% $part_bill_event->disabled ? 'DISABLED' : '' %></TD> +% } + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><A HREF="<% $url %>"> + <% $part_bill_event->event %></A></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% $delay %></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% $part_bill_event->plan %></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% $reason %></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% $plandata %></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><FONT SIZE="-1"> + <% $part_bill_event->eventcode %></FONT></TD> + </TR> +% } + + </TABLE> + <BR><BR> +% } +% } + + +</BODY> +</HTML> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my %search; +if ( $cgi->param('showdisabled') ) { +%search = (); +} else { +%search = ( 'disabled' => '' ); +} + +my @part_bill_event = qsearch('part_bill_event', \%search ); +my $total = scalar(@part_bill_event); + +</%init> diff --git a/httemplate/browse/part_export.cgi b/httemplate/browse/part_export.cgi new file mode 100755 index 000000000..7b8ac8c20 --- /dev/null +++ b/httemplate/browse/part_export.cgi @@ -0,0 +1,44 @@ +<% include("/elements/header.html","Export Listing", menubar( 'Main Menu' => "$p#sysadmin" )) %> +Provisioning services to external machines, databases and APIs.<BR><BR> +<A HREF="<% $p %>edit/part_export.cgi"><I>Add a new export</I></A><BR><BR> +<SCRIPT> +function part_export_areyousure(href) { + if (confirm("Are you sure you want to delete this export?") == true) + window.location.href = href; +} +</SCRIPT> + +<% table() %> + <TR> + <TH COLSPAN=2>Export</TH> + <TH>Options</TH> + </TR> +% foreach my $part_export ( sort { +% $a->getfield('exportnum') <=> $b->getfield('exportnum') +% } qsearch('part_export',{}) ) { +% + + <TR> + <TD><A HREF="<% $p %>edit/part_export.cgi?<% $part_export->exportnum %>"><% $part_export->exportnum %></A></TD> + <TD><% $part_export->exporttype %> to <% $part_export->machine %> (<A HREF="<% $p %>edit/part_export.cgi?<% $part_export->exportnum %>">edit</A> | <A HREF="javascript:part_export_areyousure('<% $p %>misc/delete-part_export.cgi?<% $part_export->exportnum %>')">delete</A>)</TD> + <TD> + <% itable() %> +% my %opt = $part_export->options; +% foreach my $opt ( keys %opt ) { + + <TR><TD><% $opt %></TD><TD><% encode_entities($opt{$opt}) %></TD></TR> +% } + + </TABLE> + </TD> + </TR> +% } + + +</TABLE> +</BODY> +</HTML> +<%init> +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); +</%init> diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi new file mode 100755 index 000000000..6b62ec67b --- /dev/null +++ b/httemplate/browse/part_pkg.cgi @@ -0,0 +1,261 @@ +<% include( 'elements/browse.html', + 'title' => 'Package Definitions', + 'menubar' => [ 'Main Menu' => $p ], + 'html_init' => $html_init, + 'html_posttotal' => $posttotal, + 'name' => 'package definitions', + 'query' => { 'select' => $select, + 'table' => 'part_pkg', + 'hashref' => \%search, + 'extra_sql' => "ORDER BY $orderby", + }, + 'count_query' => $count_query, + 'header' => \@header, + 'fields' => \@fields, + 'links' => \@links, + 'align' => $align, + 'style' => \@style, + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +#false laziness w/access_user.html +my %search = (); +my $search = ''; +unless ( $cgi->param('showdisabled') ) { + %search = ( 'disabled' => '' ); + $search = "( disabled = '' OR disabled IS NULL )"; +} + +my $select = '*'; +my $orderby = 'pkgpart'; +if ( $cgi->param('active') ) { + + $orderby = 'num_active DESC'; +} + $select = " + + *, + + ( SELECT COUNT(*) FROM cust_pkg WHERE cust_pkg.pkgpart = part_pkg.pkgpart + AND ( cancel IS NULL OR cancel = 0 ) + AND ( susp IS NULL OR susp = 0 ) + ) AS num_active, + + ( SELECT COUNT(*) FROM cust_pkg WHERE cust_pkg.pkgpart = part_pkg.pkgpart + AND ( cancel IS NULL OR cancel = 0 ) + AND susp IS NOT NULL AND susp != 0 + ) AS num_suspended, + + ( SELECT COUNT(*) FROM cust_pkg WHERE cust_pkg.pkgpart = part_pkg.pkgpart + AND cancel IS NOT NULL AND cancel != 0 + ) AS num_cancelled + + "; + +#} + +my $conf = new FS::Conf; +my $taxclasses = $conf->exists('enable_taxclasses'); + +my $html_init; +#unless ( $cgi->param('active') ) { + $html_init = qq! + One or more service definitions are grouped together into a package + definition and given pricing information. Customers purchase packages + rather than purchase services directly.<BR><BR> + <A HREF="${p}edit/part_pkg.cgi"><I>Add a new package definition</I></A> + <BR><BR> + !; +#} + +my $posttotal; +if ( $cgi->param('showdisabled') ) { + $cgi->param('showdisabled', 0); + $posttotal = '( <a href="'. $cgi->self_url. '">hide disabled packages</a> )'; + $cgi->param('showdisabled', 1); +} else { + $cgi->param('showdisabled', 1); + $posttotal = '( <a href="'. $cgi->self_url. '">show disabled packages</a> )'; + $cgi->param('showdisabled', 0); +} + + +# ------ + +my $link = [ $p.'edit/part_pkg.cgi?', 'pkgpart' ]; + +my @header = ( '#', 'Package', 'Comment' ); +my @fields = ( 'pkgpart', 'pkg', 'comment' ); +my $align = 'rll'; +my @links = ( $link, $link, '' ); +my @style = ( '', '', '' ); + +#false laziness w/access_user.html +#unless ( $cgi->param('showdisabled') ) { #its been reversed already +if ( $cgi->param('showdisabled') ) { #its been reversed already + push @header, 'Status'; + push @fields, sub { shift->disabled + ? '<FONT COLOR="#FF0000">DISABLED</FONT>' + : '<FONT COLOR="#00CC00">Active</FONT>' + }; + push @links, ''; + $align .= 'c'; + push @style, 'b'; +} + +unless ( 0 ) { #already showing only one class or something? + push @header, 'Class'; + push @fields, sub { shift->classname || '(none)'; }; + $align .= 'l'; +} + +#if ( $cgi->param('active') ) { + push @header, 'Customer<BR>packages'; + my %col = ( + 'active' => '00CC00', + 'suspended' => 'FF9900', + 'cancelled' => 'FF0000', + #'one-time charge' => '000000', + 'charge' => '000000', + ); + my $cust_pkg_link = $p. 'search/cust_pkg.cgi?pkgpart='; + push @fields, sub { my $part_pkg = shift; + [ + map { + my $magic = $_; + my $label = $_; + if ( $magic eq 'active' && $part_pkg->freq == 0 ) { + $magic = 'inactive'; + #$label = 'one-time charge', + $label = 'charge', + } + + [ + { + 'data' => '<B><FONT COLOR="#'. $col{$label}. '">'. + $part_pkg->get("num_$_"). + '</FONT></B>', + 'align' => 'right', + }, + { + 'data' => $label. + ( $part_pkg->get("num_$_") != 1 + && $label =~ /charge$/ + ? 's' + : '' + ), + 'align' => 'left', + 'link' => ( $part_pkg->get("num_$_") + ? $cust_pkg_link. + $part_pkg->pkgpart. + ";magic=$magic" + : '' + ), + }, + ], + } (qw( active suspended cancelled )) + ]; }; + $align .= 'r'; +#} + +push @header, 'Frequency'; +push @fields, sub { shift->freq_pretty; }; +$align .= 'l'; + +if ( $taxclasses ) { + push @header, 'Taxclass'; + push @fields, sub { shift->taxclass() || ' '; }; + $align .= 'l'; +} + +push @header, 'Plan', + 'Data', + 'Services'; + #'Service', 'Quan', 'Primary'; + +push @fields, sub { shift->plan || '(legacy)' }, + + sub { + my $part_pkg = shift; + if ( $part_pkg->plan ) { + + [ map { + /^(\w+)=(.*)$/; #or something; + [ + { 'data' => $1, + 'align' => 'right', + }, + { 'data' => $2, + 'align' => 'left', + }, + ]; + } + split(/\n/, $part_pkg->plandata) + ]; + + } else { + + [ map { [ + { 'data' => uc($_), + 'align' => 'right', + }, + { + 'data' => $part_pkg->$_(), + 'align' => 'left', + }, + ]; + } + (qw(setup recur)) + ]; + + } + + }, + + sub { + my $part_pkg = shift; + + [ map { + my $pkg_svc = $_; + my $part_svc = $pkg_svc->part_svc; + my $svc = $part_svc->svc; + if ( $pkg_svc->primary_svc =~ /^Y/i ) { + $svc = "<B>$svc (PRIMARY)</B>"; + } + $svc =~ s/ +/ /g; + + [ + { + 'data' => '<B>'. $pkg_svc->quantity. '</B>', + 'align' => 'right' + }, + { + 'data' => $svc, + 'align' => 'left', + 'link' => $p. 'edit/part_svc.cgi?'. + $part_svc->svcpart, + }, + ]; + } + sort { $b->primary_svc =~ /^Y/i + <=> $a->primary_svc =~ /^Y/i + } + $part_pkg->pkg_svc + + ]; + + }; + +$align .= 'lrl'; #rr'; + +# -------- + +my $count_query = 'SELECT COUNT(*) FROM part_pkg'; +$count_query .= " WHERE $search" + if $search; + +</%init> diff --git a/httemplate/browse/part_referral.html b/httemplate/browse/part_referral.html new file mode 100755 index 000000000..065d8c1c1 --- /dev/null +++ b/httemplate/browse/part_referral.html @@ -0,0 +1,147 @@ +<% include("/elements/header.html","Advertising source Listing" ) %> + +Where a customer heard about your service. Tracked for informational purposes. +<BR><BR> + +<A HREF="<% $p %>edit/part_referral.html"><I>Add a new advertising source</I></A> +<BR><BR> +% +% my $today = timelocal(0, 0, 0, (localtime(time))[3..5] ); +% my %after; +% tie %after, 'Tie::IxHash', +% 'Today' => 0, +% 'Yesterday' => 86400, # 60sec * 60min * 24hrs +% 'Past week' => 518400, # 60sec * 60min * 24hrs * 6days +% 'Past 30 days' => 2505600, # 60sec * 60min * 24hrs * 29days +% 'Past 60 days' => 5097600, # 60sec * 60min * 24hrs * 59days +% 'Past 90 days' => 7689600, # 60sec * 60min * 24hrs * 89days +% 'Past 6 months' => 15724800, # 60sec * 60min * 24hrs * 182days +% 'Past year' => 31486000, # 60sec * 60min * 24hrs * 364days +% 'Total' => $today, +% ; +% my %before = ( +% 'Today' => 86400, # 60sec * 60min * 24hrs +% 'Yesterday' => 0, +% 'Past week' => 86400, # 60sec * 60min * 24hrs +% 'Past 30 days' => 86400, # 60sec * 60min * 24hrs +% 'Past 60 days' => 86400, # 60sec * 60min * 24hrs +% 'Past 90 days' => 86400, # 60sec * 60min * 24hrs +% 'Past 6 months' => 86400, # 60sec * 60min * 24hrs +% 'Past year' => 86400, # 60sec * 60min * 24hrs +% 'Total' => 86400, # 60sec * 60min * 24hrs +% ); +% +% my $curuser = $FS::CurrentUser::CurrentUser; +% +% my $statement = "SELECT COUNT(*) FROM h_cust_main +% WHERE history_action = 'insert' +% AND refnum = ? +% AND history_date >= ? +% AND history_date < ? +% AND ". $curuser->agentnums_sql; +% my $sth = dbh->prepare($statement) +% or die dbh->errstr; +% +% my $show_agentnums = scalar($curuser->agentnums); +% +% + + +<% include('/elements/table-grid.html') %> +% my $bgcolor1 = '#eeeeee'; +% my $bgcolor2 = '#ffffff'; +% my $bgcolor = ''; +% + + +<TR> + <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=2 ROWSPAN=2>Advertising source</TH> +% if ( $show_agentnums ) { + + <TH CLASS="grid" BGCOLOR="#cccccc" ROWSPAN=2>Agent</TH> +% } + + <TH CLASS="grid" BGCOLOR="#cccccc" COLSPAN=<% scalar(keys %after) %>>Customers</TH> +</TR> +% for my $period ( keys %after ) { + + <TH CLASS="grid" BGCOLOR="#cccccc"><FONT SIZE=-1><% $period %></FONT></TH> +% } + +</TR> +% +%foreach my $part_referral ( FS::part_referral->all_part_referral(1) ) { +% +% if ( $bgcolor eq $bgcolor1 ) { +% $bgcolor = $bgcolor2; +% } else { +% $bgcolor = $bgcolor1; +% } +% +% $a = 0; +% +% + + <TR> + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> +% if ( $part_referral->agentnum || $curuser->access_right('Edit global advertising sources') ) { +% $a++; +% + + <A HREF="<% $p %>edit/part_referral.html?<% $part_referral->refnum %>"> +% } + + <% $part_referral->refnum %><% $a ? '</A>' : '' %></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> +% if ( $a ) { + + <A HREF="<% $p %>edit/part_referral.html?<% $part_referral->refnum %>"> +% } + + <% $part_referral->referral %><% $a ? '</A>' : '' %></TD> +% if ( $show_agentnums ) { + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><% $part_referral->agentnum ? $part_referral->agent->agent : '(global)' %></TD> +% } +% for my $period ( keys %after ) { +% $sth->execute( $part_referral->refnum, +% $today-$after{$period}, +% $today+$before{$period}, +% ) or die $sth->errstr; +% my $number = $sth->fetchrow_arrayref->[0]; +% + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ALIGN="right"><% $number %></TD> +% } + + </TR> +% } +% +% $statement =~ s/AND refnum = \?//; +% $sth = dbh->prepare($statement) +% or die dbh->errstr; +% + + <TR> + <TD BGCOLOR="#dddddd" ALIGN="center" COLSPAN=3><B>Total</B></TD> +% for my $period ( keys %after ) { +% $sth->execute( $today-$after{$period}, +% $today+$before{$period}, +% ) or die $sth->errstr; +% my $number = $sth->fetchrow_arrayref->[0]; +% + + <TD BGCOLOR="#dddddd" ALIGN="right"><B><% $number %><B></TD> +% } + + </TR> + </TABLE> + </BODY> +</HTML> +<%init> +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration') + || $FS::CurrentUser::CurrentUser->access_right('Edit advertising sources') + || $FS::CurrentUser::CurrentUser->access_right('Edit global advertising sources'); +</%init> diff --git a/httemplate/browse/part_svc.cgi b/httemplate/browse/part_svc.cgi new file mode 100755 index 000000000..369495571 --- /dev/null +++ b/httemplate/browse/part_svc.cgi @@ -0,0 +1,212 @@ +<% include("/elements/header.html",'Service Definition Listing', menubar( 'Main Menu' => $p) ) %> + +<SCRIPT> +function part_export_areyousure(href) { + if (confirm("Are you sure you want to delete this export?") == true) + window.location.href = href; +} +</SCRIPT> + + Service definitions are the templates for items you offer to your customers.<BR><BR> + +<FORM METHOD="POST" ACTION="<% $p %>edit/part_svc.cgi"> +<A HREF="<% $p %>edit/part_svc.cgi"><I>Add a new service definition</I></A> +% if ( @part_svc ) { + or <SELECT NAME="clone"><OPTION></OPTION> +% foreach my $part_svc ( @part_svc ) { + + <OPTION VALUE="<% $part_svc->svcpart %>"><% $part_svc->svc %></OPTION> +% } + +</SELECT><INPUT TYPE="submit" VALUE="Clone existing service"> +% } + +</FORM><BR> + +<% $total %> service definitions +<% $cgi->param('showdisabled') + ? do { $cgi->param('showdisabled', 0); + '( <a href="'. $cgi->self_url. '">hide disabled services</a> )'; } + : do { $cgi->param('showdisabled', 1); + '( <a href="'. $cgi->self_url. '">show disabled services</a> )'; } +%> +% $cgi->param('showdisabled', ( 1 ^ $cgi->param('showdisabled') ) ); + +<% include('/elements/table-grid.html') %> +% my $bgcolor1 = '#eeeeee'; +% my $bgcolor2 = '#ffffff'; +% my $bgcolor = ''; + + <TR> + + <TH CLASS="grid" BGCOLOR="#cccccc"><A HREF="<% do { $cgi->param('orderby', 'svcpart'); $cgi->self_url } %>">#</A></TH> + +% if ( $cgi->param('showdisabled') ) { + <TH CLASS="grid" BGCOLOR="#cccccc">Status</TH> +% } + + <TH CLASS="grid" BGCOLOR="#cccccc"><A HREF="<% do { $cgi->param('orderby', 'svc'); $cgi->self_url; } %>">Service</A></TH> + + <TH CLASS="grid" BGCOLOR="#cccccc">Table</TH> + + <TH CLASS="grid" BGCOLOR="#cccccc"><A HREF="<% do { $cgi->param('orderby', 'active'); $cgi->self_url; } %>"><FONT SIZE=-1>Customer<BR>Services</FONT></A></TH> + + <TH CLASS="grid" BGCOLOR="#cccccc">Export</TH> + + <TH CLASS="grid" BGCOLOR="#cccccc">Field</TH> + + <TH COLSPAN=2 CLASS="grid" BGCOLOR="#cccccc">Modifier</TH> + + </TR> + +% foreach my $part_svc ( @part_svc ) { +% my $svcdb = $part_svc->svcdb; +% my $svc_x = "FS::$svcdb"->new( { svcpart => $part_svc->svcpart } ); +% my @dfields = $svc_x->fields; +% push @dfields, 'usergroup' if $svcdb eq 'svc_acct'; #kludge +% my @fields = +% grep { $svc_x->pvf($_) +% or $_ ne 'svcnum' && $part_svc->part_svc_column($_)->columnflag } +% @dfields ; +% my $rowspan = scalar(@fields) || 1; +% my $url = "${p}edit/part_svc.cgi?". $part_svc->svcpart; +% +% if ( $bgcolor eq $bgcolor1 ) { +% $bgcolor = $bgcolor2; +% } else { +% $bgcolor = $bgcolor1; +% } + + + <TR> + + <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <A HREF="<% $url %>"><% $part_svc->svcpart %></A> + </TD> + +% if ( $cgi->param('showdisabled') ) { + <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% $part_svc->disabled + ? '<FONT COLOR="#FF0000"><B>Disabled</B></FONT>' + : '<FONT COLOR="#00CC00"><B>Enabled</B></FONT>' + %> + </TD> +% } + + <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>"><A HREF="<% $url %>"> + <% $part_svc->svc %></A></TD> + + <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <% $svcdb %></TD> + + <TD ROWSPAN=<% $rowspan %> CLASS="grid" BGCOLOR="<% $bgcolor %>"> + <FONT COLOR="#00CC00"><B><% $num_active_cust_svc{$part_svc->svcpart} %></B></FONT> <% $num_active_cust_svc{$part_svc->svcpart} ? FS::UI::Web::svc_url( 'ahref' => 1, 'm' => $m, 'action' => 'search', 'part_svc' => $part_svc, 'query' => "svcpart=". $part_svc->svcpart ) : '<A NAME="zero">' %>active</A> + +% if ( $num_active_cust_svc{$part_svc->svcpart} ) { + <BR><FONT SIZE="-1">[ <A HREF="<%$p%>edit/bulk-cust_svc.html?svcpart=<% $part_svc->svcpart %>">change</A> ]</FONT> +% } + + </TD> + + <TD ROWSPAN=<% $rowspan %> CLASS="inv" BGCOLOR="<% $bgcolor %>"> + <TABLE CLASS="inv"> +% +%# my @part_export = +%map { qsearchs('part_export', { exportnum => $_->exportnum } ) } qsearch('export_svc', { svcpart => $part_svc->svcpart } ) ; +% foreach my $part_export ( +% map { qsearchs('part_export', { exportnum => $_->exportnum } ) } +% qsearch('export_svc', { svcpart => $part_svc->svcpart } ) +% ) { +% + + <TR> + <TD><A HREF="<% $p %>edit/part_export.cgi?<% $part_export->exportnum %>"><% $part_export->exportnum %>: <% $part_export->exporttype %> to <% $part_export->machine %></A></TD> + </TR> +% } + + </TABLE> + </TD> + +% unless ( @fields ) { +% for ( 1..3 ) { + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"</TD> +% } +% } +% +% my($n1)=''; +% foreach my $field ( @fields ) { +% my $flag = $part_svc->part_svc_column($field)->columnflag; +% + + <% $n1 %> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><% $field %></TD> + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"><% $flag{$flag} %></TD> + + <TD CLASS="grid" BGCOLOR="<% $bgcolor %>"> +% my $value = $part_svc->part_svc_column($field)->columnvalue; +% if ( $flag =~ /^[MA]$/ ) { +% $inventory_class{$value} +% ||= qsearchs('inventory_class', { 'classnum' => $value } ); +% + + <% $inventory_class{$value} + ? $inventory_class{$value}->classname + : "WARNING: inventory_class.classnum $value not found" %> +% } else { + + <% $value %> +% } + + </TD> +% $n1="</TR><TR>"; +% } +% + + </TR> +% } + +</TABLE> +</BODY> +</HTML> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +#code duplication w/ edit/part_svc.cgi, should move this hash to part_svc.pm +my %flag = ( + '' => '', + 'D' => 'Default', + 'F' => 'Fixed (unchangeable)', + 'S' => 'Selectable choice', + #'M' => 'Manual selection from inventory', + 'M' => 'Manual selected from inventory', + #'A' => 'Automatically fill in from inventory', + 'A' => 'Automatically filled in from inventory', + 'X' => 'Excluded', +); + +my %search; +if ( $cgi->param('showdisabled') ) { + %search = (); +} else { + %search = ( 'disabled' => '' ); +} + +my @part_svc = + sort { $a->getfield('svcpart') <=> $b->getfield('svcpart') } + qsearch('part_svc', \%search ); +my $total = scalar(@part_svc); + +my %num_active_cust_svc = map { $_->svcpart => $_->num_cust_svc } @part_svc; + +if ( $cgi->param('orderby') eq 'active' ) { + @part_svc = sort { $num_active_cust_svc{$b->svcpart} <=> + $num_active_cust_svc{$a->svcpart} } @part_svc; +} elsif ( $cgi->param('orderby') eq 'svc' ) { + @part_svc = sort { lc($a->svc) cmp lc($b->svc) } @part_svc; +} + +my %inventory_class = (); + +</%init> diff --git a/httemplate/browse/part_virtual_field.cgi b/httemplate/browse/part_virtual_field.cgi new file mode 100644 index 000000000..2e12603a0 --- /dev/null +++ b/httemplate/browse/part_virtual_field.cgi @@ -0,0 +1,46 @@ +<% include("/elements/header.html",'Virtual field definitions', menubar('Main Menu' => $p)) %> +% +% +%my %pvfs; +%my $block; +%my $p2 = popurl(2); +%my $dbtable; +% +%foreach (qsearch('part_virtual_field', {})) { +% push @{ $pvfs{$_->dbtable} }, $_; +%} +% +% if ($cgi->param('error')) { + + <FONT SIZE="+1" COLOR="#ff0000">Error: <%$cgi->param('error')%></FONT> + <BR><BR> +% } + + +<A HREF="<%$p2%>edit/part_virtual_field.cgi"><I>Add a new field</I></A><BR><BR> +% foreach $dbtable (sort { $a cmp $b } keys (%pvfs)) { + +<H3><%$dbtable%></H3> + +<%table()%> +<TH><TD>Field name</TD><TD>Description</TD></TH> +% foreach my $pvf (sort {$a->name cmp $b->name} @{ $pvfs{$dbtable} }) { + + <TR> + <TD></TD> + <TD> + <A HREF="<%$p2%>edit/part_virtual_field.cgi?<%$pvf->vfieldpart%>"> + <%$pvf->name%></A></TD> + <TD><%$pvf->label%></TD> + </TR> +% } + +</TABLE> +% } + +</BODY> +</HTML> +<%init> +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); +</%init> diff --git a/httemplate/browse/payment_gateway.html b/httemplate/browse/payment_gateway.html new file mode 100644 index 000000000..720858e9b --- /dev/null +++ b/httemplate/browse/payment_gateway.html @@ -0,0 +1,79 @@ +<% include("/elements/header.html",'Payment gateways', menubar( + 'Main Menu' => $p, + 'Agents' => $p. 'browse/agent.cgi', +)) %> + +<A HREF="<% $p %>edit/payment_gateway.html"><I>Add a new payment gateway</I></A><BR><BR> + +<% $cgi->param('showdisabled') + ? do { $cgi->param('showdisabled', 0); + '( <a href="'. $cgi->self_url. '">hide disabled gateways</a> )'; } + : do { $cgi->param('showdisabled', 1); + '( <a href="'. $cgi->self_url. '">show disabled gateways</a> )'; } +%> + +<% table() %> +<TR> + <TH COLSPAN=<% $cgi->param('showdisabled') ? 1 : 2 %>>#</TH> + <TH>Gateway</TH> + <TH>Username</TH> + <TH>Password</TH> + <TH>Action</TH> + <TH>Options</TH> +</TR> +% foreach my $payment_gateway ( qsearch( 'payment_gateway', \%search ) ) { + + + <TR> + <TD><% $payment_gateway->gatewaynum %></TD> +% if ( !$cgi->param('showdisabled') ) { + + <TD><% $payment_gateway->disabled ? 'DISABLED' : '' %></TD> +% } + + <TD><% $payment_gateway->gateway_module %> + <FONT SIZE="-1"> + <A HREF="<%$p%>edit/payment_gateway.html?<% $payment_gateway->gatewaynum %>">(edit)</A> + <% !$payment_gateway->disabled + ? '<A HREF="'. $p. 'misc/disable-payment_gateway.cgi?'. $payment_gateway->gatewaynum.'">(disable)</A>' + : '' + %> + </FONT> + </TD> + <TD><% $payment_gateway->gateway_username %></TD> + <TD> - </TD> + <TD><% $payment_gateway->gateway_action %></TD> + <TD> + <TABLE CELLSPACING=0 CELLPADDING=0> +% my %options = $payment_gateway->options; +% foreach my $option ( keys %options ) { +% + + <TR> + <TH><% $option %>:</TH> + <TD><% $options{$option} %></TD> + </TR> +% } + + </TABLE> + </TD> + </TR> +% } + + +</TABLE> +</BODY> +</HTML> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my %search; +if ( $cgi->param('showdisabled') ) { + %search = (); +} else { + %search = ( 'disabled' => '' ); +} + +</%init> diff --git a/httemplate/browse/pkg_class.html b/httemplate/browse/pkg_class.html new file mode 100644 index 000000000..886029df5 --- /dev/null +++ b/httemplate/browse/pkg_class.html @@ -0,0 +1,30 @@ +<% include( 'elements/browse.html', + 'title' => 'Package classes', + 'html_init' => $html_init, + 'name' => 'package classes', + 'disableable' => 1, + 'query' => { 'table' => 'pkg_class', + 'hashref' => {}, + 'extra_sql' => 'ORDER BY classnum', + }, + 'count_query' => $count_query, + 'header' => [ '#', 'Class', ], + 'fields' => [ 'classnum', 'classname' ], + 'links' => [ $link, $link ], + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $html_init = + 'Package classes define groups of packages, for reporting and '. + 'convenience purposes.<BR><BR>'. + qq!<A HREF="${p}edit/pkg_class.html"><I>Add a package class</I></A><BR><BR>!; + +my $count_query = 'SELECT COUNT(*) FROM pkg_class'; + +my $link = [ $p.'edit/pkg_class.html?', 'classnum' ]; + +</%init> diff --git a/httemplate/browse/rate.cgi b/httemplate/browse/rate.cgi new file mode 100644 index 000000000..584891aea --- /dev/null +++ b/httemplate/browse/rate.cgi @@ -0,0 +1,37 @@ +<% include( 'elements/browse.html', + 'title' => 'Rate plans', + 'menubar' => [ 'Main menu' => $p, ], + 'html_init' => $html_init, + 'name' => 'rate plans', + 'query' => { 'table' => 'rate', + 'hashref' => {}, + 'extra_sql' => 'ORDER BY ratenum', + }, + 'count_query' => $count_query, + 'header' => [ '#', 'Rate plan', ], + 'fields' => [ 'ratenum', 'ratename' ], + 'links' => [ $link, $link ], + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $html_init = +'Rate plans, regions and prefixes for VoIP and call billing.<BR><BR>'. +qq!<A HREF="${p}edit/rate.cgi"><I>Add a rate plan</I></A>!. +qq! | <A HREF="${p}edit/rate_region.cgi"><I>Add a region</I></A>!. +'<BR><BR> + <SCRIPT> + function rate_areyousure(href) { + if (confirm("Are you sure you want to delete this rate plan?") == true) + window.location.href = href; + } + </SCRIPT>'; + +my $count_query = 'SELECT COUNT(*) FROM rate'; + +my $link = [ $p.'edit/rate.cgi?', 'ratenum' ]; + +</%init> diff --git a/httemplate/browse/reason.html b/httemplate/browse/reason.html new file mode 100644 index 000000000..b017f8f58 --- /dev/null +++ b/httemplate/browse/reason.html @@ -0,0 +1,68 @@ +<% include( 'elements/browse.html', + 'title' => ucfirst($classname) . ' Reasons', + 'menubar' => [ # 'Main menu' => $p, + ucfirst($classname) . ' Reason Types' => + $p.'browse/reason_type.html?class='. + $class, + ], + 'html_init' => $html_init, + 'name' => $classname . ' reasons', + 'query' => { 'table' => 'reason', + 'hashref' => {}, + 'extra_sql' => $where_clause . + 'ORDER BY reason_type', + 'addl_from' => 'LEFT JOIN reason_type ON reason_type.typenum = reason.reason_type', + }, + 'count_query' => $count_query, + 'header' => [ '#', + ucfirst($classname) . ' Reason Type', + ucfirst($classname) . ' Reason', + ], + 'fields' => [ 'reasonnum', + sub { shift->reasontype->type }, + 'reason', + ], + 'links' => [ $link, + $link, + '', + ], + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('class') =~ /^(\w)$/ or die "illegal class"; +my $class = $1; + +my %classmap = ( 'C' => 'cancel', + 'S' => 'suspend', + ); + +my $classname = $classmap{$class}; + +my $html_init = ucfirst($classname) . +" reasons explain why we $classname a package.<BR><BR>". +qq!<A HREF="${p}edit/reason.html?class=$class">!. +"<I>Add a $classname reason</I></A><BR><BR>"; + +my $where_clause = "WHERE class='$class'"; +$where_clause .= " AND (disabled = '' OR disabled IS NULL)" +unless $cgi->param('showdisabled'); + +my $disabledurl = $cgi->param('showdisabled') + ? do { $cgi->param('showdisabled', 0); + '( <a href="'. $cgi->self_url. '">hide disabled reasons</a> )'; } + : do { $cgi->param('showdisabled', 1); + '( <a href="'. $cgi->self_url. '">show disabled reasons</a> )'; } + ; + +$html_init .= $disabledurl; + +my $count_query = 'SELECT COUNT(*) FROM reason LEFT JOIN reason_type on ' . + 'reason_type.typenum = reason.reason_type ' . $where_clause; + +my $link = [ $p."edit/reason.html?class=$class&reasonnum=", 'reasonnum' ]; + +</%init> diff --git a/httemplate/browse/reason_type.html b/httemplate/browse/reason_type.html new file mode 100644 index 000000000..09f451c9f --- /dev/null +++ b/httemplate/browse/reason_type.html @@ -0,0 +1,72 @@ +<% include( 'elements/browse.html', + 'title' => ucfirst($classname) . " Reason Types", + 'menubar' => [ ucfirst($classname) . " reasons" => + $p.'browse/reason.html?class=' . $class, + ], + 'html_init' => $html_init, + 'name' => $classname . " reason types", + 'query' => { 'table' => 'reason_type', + 'hashref' => {}, + 'extra_sql' => $where_clause . + 'ORDER BY typenum', + }, + 'count_query' => $count_query, + 'header' => [ '#', + ucfirst($classname) . ' Reason Type', + ucfirst($classname) . ' Reasons', + ], + 'fields' => [ 'typenum', + 'type', + $reasons_sub, + ], + 'links' => [ $link, + $link, + '', + ], + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +$cgi->param('class') =~ /^(\w)$/ or die "illegal class"; +my $class=$1; + +my %classmap = ( 'C' => 'cancel', + 'S' => 'suspend', + ); + +my $classname = $classmap{$class}; + +my $html_init = ucfirst($classname) . + " reason types allow groups of $classname reasons for reporting purposes." . + qq!<BR><BR><A HREF="${p}edit/reason_type.html?class=$class"><I>Add a ! . + $classname . " reason type</I></A><BR><BR>"; + +my $reasons_sub = sub { + my $reason_type = shift; + + [ map { + [ + { + 'data' => $_->reason, + 'align' => 'left', + 'link' => $p. "edit/reason.html?class=$class&reasonnum=". + $_->reasonnum, + }, + ]; + } + $reason_type->enabled_reasons, + + ]; + +}; + +my $where_clause = "WHERE class='$class'"; +my $count_query = 'SELECT COUNT(*) FROM reason_type '; +$count_query .= $where_clause; + +my $link = [ $p.'edit/reason_type.html?class='.$class.'&typenum=', 'typenum' ]; + +</%init> diff --git a/httemplate/browse/router.cgi b/httemplate/browse/router.cgi new file mode 100644 index 000000000..6dcd93a71 --- /dev/null +++ b/httemplate/browse/router.cgi @@ -0,0 +1,64 @@ +<% include("/elements/header.html",'Routers', menubar('Main Menu' => $p)) %> +% +% +%my @router = qsearch('router', {}); +%my $p2 = popurl(2); +% +% +% if ($cgi->param('error')) { + + <FONT SIZE="+1" COLOR="#ff0000">Error: <%$cgi->param('error')%></FONT> + <BR><BR> +% } +% +%my $hidecustomerrouters = 0; +%my $hideurl = ''; +%if ($cgi->param('hidecustomerrouters') eq '1') { +% $hidecustomerrouters = 1; +% $cgi->param('hidecustomerrouters', 0); +% $hideurl = '<A HREF="' . $cgi->self_url() . '">Show customer routers</A>'; +%} else { +% $hidecustomerrouters = 0; +% $cgi->param('hidecustomerrouters', 1); +% $hideurl = '<A HREF="' . $cgi->self_url() . '">Hide customer routers</A>'; +%} +% + + +<A HREF="<%$p2%>edit/router.cgi">Add a new router</A> | <%$hideurl%> + +<%table()%> + <TR> + <TD><B>Router name</B></TD> + <TD><B>Address block(s)</B></TD> + </TR> +% foreach my $router (sort {$a->routernum <=> $b->routernum} @router) { +% next if $hidecustomerrouters && $router->svcnum; +% my @addr_block = $router->addr_block; +% if (scalar(@addr_block) == 0) { +% push @addr_block, ' '; +% } +% + + <TR> + <TD ROWSPAN="<%scalar(@addr_block)+1%>"> + <A HREF="<%$p2%>edit/router.cgi?<%$router->routernum%>"><%$router->routername%></A> + </TD> + </TR> +% foreach my $block ( @addr_block ) { + + <TR> + <TD><%UNIVERSAL::isa($block, 'FS::addr_block') ? $block->NetAddr : ' '%></TD> + </TR> +% } + + </TR> +% } + +</TABLE> +</BODY> +</HTML> +<%init> +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); +</%init> diff --git a/httemplate/browse/svc_acct_pop.cgi b/httemplate/browse/svc_acct_pop.cgi new file mode 100755 index 000000000..306d02afb --- /dev/null +++ b/httemplate/browse/svc_acct_pop.cgi @@ -0,0 +1,73 @@ +<% include("/elements/header.html",'Access Number Listing', menubar( 'Main Menu' => $p )) %> +Points of Presence<BR><BR> +<A HREF="<% $p %>edit/svc_acct_pop.cgi"><I>Add new Access Number</I></A><BR><BR> +<% table() %> + <TR> + <TH></TH> + <TH>City</TH> + <TH>State</TH> + <TH>Area code</TH> + <TH>Exchange</TH> + <TH>Local</TH> + <TH>Accounts</TH> + </TR> +% +%foreach my $svc_acct_pop ( sort { +% #$a->getfield('popnum') <=> $b->getfield('popnum') +% $a->state cmp $b->state || $a->city cmp $b->city +% || $a->ac <=> $b->ac || $a->exch <=> $b->exch || $a->loc <=> $b->loc +%} qsearch('svc_acct_pop',{}) ) { +% +% my $svc_acct_pop_link = $p . 'edit/svc_acct_pop.cgi?'. $svc_acct_pop->popnum; +% +% $accounts_sth->execute($svc_acct_pop->popnum) or die $accounts_sth->errstr; +% my $num_accounts = $accounts_sth->fetchrow_arrayref->[0]; +% +% my $svc_acct_link = $p. 'search/svc_acct.cgi?popnum='. $svc_acct_pop->popnum; +% +% + + <TR> + <TD><A HREF="<% $svc_acct_pop_link %>"> + <% $svc_acct_pop->popnum %></A></TD> + <TD><A HREF="<% $svc_acct_pop_link %>"> + <% $svc_acct_pop->city %></A></TD> + <TD><A HREF="<% $svc_acct_pop_link %>"> + <% $svc_acct_pop->state %></A></TD> + <TD><A HREF="<% $svc_acct_pop_link %>"> + <% $svc_acct_pop->ac %></A></TD> + <TD><A HREF="<% $svc_acct_pop_link %>"> + <% $svc_acct_pop->exch %></A></TD> + <TD><A HREF="<% $svc_acct_pop_link %>"> + <% $svc_acct_pop->loc %></A></TD> + <TD> + <FONT COLOR="#00CC00"><B><% $num_accounts %></B></FONT> +% if ( $num_accounts ) { +<A HREF="<% $svc_acct_link %>"> +% } + + active +% if ( $num_accounts ) { +</A> +% } + + </TD> + </TR> +% } + + + <TR> + </TR> + </TABLE> + </BODY> +</HTML> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $accounts_sth = dbh->prepare("SELECT COUNT(*) FROM svc_acct + WHERE popnum = ? ") + or die dbh->errstr; + +</%init> |