agent-virtualize advertising sources
authorivan <ivan>
Thu, 10 Aug 2006 11:55:50 +0000 (11:55 +0000)
committerivan <ivan>
Thu, 10 Aug 2006 11:55:50 +0000 (11:55 +0000)
12 files changed:
FS/FS/AccessRight.pm
FS/FS/Record.pm
FS/FS/Schema.pm
FS/FS/access_user.pm
FS/FS/part_referral.pm
httemplate/browse/part_referral.cgi [deleted file]
httemplate/browse/part_referral.html [new file with mode: 0755]
httemplate/edit/part_referral.cgi [deleted file]
httemplate/edit/part_referral.html [new file with mode: 0755]
httemplate/edit/process/part_referral.cgi [deleted file]
httemplate/edit/process/part_referral.html [new file with mode: 0755]
httemplate/elements/menu.html

index 797a12a..888a686 100644 (file)
@@ -136,8 +136,11 @@ assigned to users and/or groups.
   'Import',    #
   'Export',    #
 
-  'Configuration', #none of the configuraiton is agent-virtualized either
+  'Edit advertising sources',
+  'Edit global advertising sources',
 
+  'Configuration', #most of the rest of the configuraiton is not
+                   # agent-virtualized
 );
 
 sub rights {
index 41e0eba..a551bb8 100644 (file)
@@ -10,6 +10,7 @@ use Locale::Country;
 use DBI qw(:sql_types);
 use DBIx::DBSchema 0.25;
 use FS::UID qw(dbh getotaker datasrc driver_name);
+use FS::CurrentUser;
 use FS::Schema qw(dbdef);
 use FS::SearchCache;
 use FS::Msgcat qw(gettext);
@@ -1620,6 +1621,36 @@ sub ut_foreign_keyn {
     : '';
 }
 
+=item ut_agentnum_acl
+
+Checks this column as an agentnum, taking into account the current users's
+ACLs.
+
+=cut
+
+sub ut_agentnum_acl {
+  my( $self, $field, $null_acl ) = @_;
+
+  my $error = $self->ut_foreign_keyn($field, 'agent', 'agentnum');
+  return "Illegal agentnum: $error" if $error;
+
+  my $curuser = $FS::CurrentUser::CurrentUser;
+
+  if ( $self->$field() ) {
+
+    return "Access deined"
+      unless $curuser->agentnum($self->$field());
+
+  } else {
+
+    return "Access denied"
+      unless $curuser->access_right($null_acl);
+
+  }
+
+  '';
+
+}
 
 =item virtual_fields [ TABLE ]
 
index e750546..e23ae73 100644 (file)
@@ -692,9 +692,10 @@ sub tables_hashref {
 
     'part_referral' => {
       'columns' => [
-        'refnum',   'serial',    '',   '', '', '', 
-        'referral', 'varchar',   '',   $char_d, '', '', 
-        'disabled',     'char', 'NULL', 1, '', '', 
+        'refnum',   'serial',     '',        '', '', '', 
+        'referral', 'varchar',    '',   $char_d, '', '', 
+        'disabled', 'char',   'NULL',         1, '', '', 
+        'agentnum', 'int',    'NULL',        '', '', '', 
       ],
       'primary_key' => 'refnum',
       'unique' => [],
index 5d1e183..f32fa3a 100644 (file)
@@ -106,6 +106,10 @@ sub insert {
 
 sub htpasswd_kludge {
   my $self = shift;
+  
+  #awful kludge to skip setting htpasswd for fs_* users
+  return '' if $self->username =~ /^fs_/;
+
   unshift @_, '-c' unless -e $htpasswd_file;
   if ( 
        system('htpasswd', '-b', @_,
@@ -297,6 +301,24 @@ sub agentnums_sql {
   ' )';
 }
 
+=item agentnum
+
+Returns true if the user can view the specified agent.
+
+=cut
+
+sub agentnum {
+  my( $self, $agentnum ) = @_;
+  my $sth = dbh->prepare(
+    "SELECT COUNT(*) FROM access_usergroup
+                     JOIN access_groupagent USING ( groupnum )
+       WHERE usernum = ? AND agentnum = ?"
+  ) or die dbh->errstr;
+  $sth->execute($self->usernum, $agentnum) or die $sth->errstr;
+  $sth->fetchrow_arrayref->[0];
+}
+
+
 =item access_right
 
 Given a right name, returns true if this user has this right (currently via
index c0858c0..b12cd62 100644 (file)
@@ -2,7 +2,8 @@ package FS::part_referral;
 
 use strict;
 use vars qw( @ISA );
-use FS::Record;
+use FS::Record qw(qsearchs);
+use FS::agent;
 
 @ISA = qw( FS::Record );
 
@@ -40,6 +41,8 @@ The following fields are currently supported:
 
 =item disabled - Disabled flag, empty or 'Y'
 
+=item agentnum - Optional agentnum (see L<FS::agent>)
+
 =back
 
 =head1 NOTE
@@ -95,17 +98,26 @@ sub check {
 
   my $error = $self->ut_numbern('refnum')
     || $self->ut_text('referral')
+    || $self->ut_enum('disabled', [ '', 'Y' ] )
+    #|| $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum')
+    || $self->ut_agentnum_acl('agentnum', 'Edit global advertising sources')
   ;
   return $error if $error;
 
-  if ( $self->dbdef_table->column('disabled') ) {
-    $error = $self->ut_enum('disabled', [ '', 'Y' ] );
-    return $error if $error;
-  }
-
   $self->SUPER::check;
 }
 
+=item agent 
+
+Returns the associated agent for this referral, if any, as an FS::agent object.
+
+=cut
+
+sub agent {
+  my $self = shift;
+  qsearchs('agent', { 'agentnum' => $self->agentnum } );
+}
+
 =back
 
 =head1 BUGS
diff --git a/httemplate/browse/part_referral.cgi b/httemplate/browse/part_referral.cgi
deleted file mode 100755 (executable)
index 238ddac..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<!-- mason kludge -->
-<%= include("/elements/header.html","Advertising source Listing", menubar(
-  'Main Menu' => $p,
-#  'Add new referral' => "../edit/part_referral.cgi",
-)) %>
-Where a customer heard about your service. Tracked for informational purposes.
-<BR><BR>
-<A HREF="<%= $p %>edit/part_referral.cgi"><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 $statement = "SELECT COUNT(*) FROM h_cust_main
-                    WHERE history_action = 'insert'
-                      AND refnum = ?
-                      AND history_date >= ?
-                     AND history_date < ?
-                 ";
-  my $sth = dbh->prepare($statement)
-    or die dbh->errstr;
-%>
-
-<%= table() %>
-<TR>
-  <TH COLSPAN=2 ROWSPAN=2>Advertising source</TH>
-  <TH COLSPAN=<%= scalar(keys %after) %>>Customers</TH>
-</TR>
-<% for my $period ( keys %after ) { %>
-  <TH><FONT SIZE=-1><%= $period %></FONT></TH>
-<% } %>
-</TR>
-
-<%
-foreach my $part_referral ( sort { 
-  $a->getfield('refnum') <=> $b->getfield('refnum')
-} qsearch('part_referral',{}) ) {
-%>
-      <TR>
-        <TD><A HREF="<%= $p %>edit/part_referral.cgi?<%= $part_referral->refnum %>">
-          <%= $part_referral->refnum %></A></TD>
-        <TD><A HREF="<%= $p %>edit/part_referral.cgi?<%= $part_referral->refnum %>">
-          <%= $part_referral->referral %></A></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 ALIGN="right"><%= $number %></TD>
-        <% } %>
-      </TR>
-<% } %>
-
-<%
-  $statement =~ s/AND refnum = \?//;
-  $sth = dbh->prepare($statement)
-    or die dbh->errstr;
-%>
-      <TR>
-        <TH COLSPAN=2>Total</TH>
-        <% for my $period ( keys %after ) {
-          $sth->execute( $today-$after{$period},
-                         $today+$before{$period},
-          ) or die $sth->errstr;
-          my $number = $sth->fetchrow_arrayref->[0];
-        %>
-          <TD ALIGN="right"><%= $number %></TD>
-        <% } %>
-      </TR>
-    </TABLE>
-  </BODY>
-</HTML>
diff --git a/httemplate/browse/part_referral.html b/httemplate/browse/part_referral.html
new file mode 100755 (executable)
index 0000000..fff433a
--- /dev/null
@@ -0,0 +1,132 @@
+<%= 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 $extra_sql = $curuser->agentnums_sql;
+  $extra_sql .= ' OR agentnum IS NULL '
+    if $curuser->access_right('Edit global advertising sources');
+
+  $extra_sql = " WHERE $extra_sql";
+
+  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 (
+
+  qsearch({
+    'table'     => 'part_referral',
+    'extra_sql' => "$extra_sql ORDER BY refnum",
+  })
+
+) {
+
+  if ( $bgcolor eq $bgcolor1 ) {
+    $bgcolor = $bgcolor2;
+  } else {
+    $bgcolor = $bgcolor1;
+  }
+
+%>
+      <TR>
+
+        <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><A HREF="<%= $p %>edit/part_referral.html?<%= $part_referral->refnum %>">
+          <%= $part_referral->refnum %></A></TD>
+        <TD CLASS="grid" BGCOLOR="<%= $bgcolor %>"><A HREF="<%= $p %>edit/part_referral.html?<%= $part_referral->refnum %>">
+          <%= $part_referral->referral %></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" 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"><%= $number %></TD>
+        <% } %>
+      </TR>
+    </TABLE>
+  </BODY>
+</HTML>
diff --git a/httemplate/edit/part_referral.cgi b/httemplate/edit/part_referral.cgi
deleted file mode 100755 (executable)
index dce1e63..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<%
-
-my $part_referral;
-if ( $cgi->param('error') ) {
-  $part_referral = new FS::part_referral ( {
-    map { $_, scalar($cgi->param($_)) } fields('part_referral')
-  } );
-} elsif ( $cgi->keywords ) {
-  my($query) = $cgi->keywords;
-  $query =~ /^(\d+)$/;
-  $part_referral = qsearchs( 'part_referral', { 'refnum' => $1 } );
-} else { #adding
-  $part_referral = new FS::part_referral {};
-}
-my $action = $part_referral->refnum ? 'Edit' : 'Add';
-my $hashref = $part_referral->hashref;
-
-my $p1 = popurl(1);
-
-%><%= include('/elements/header.html', "$action Advertising source", menubar(
-  'Main Menu' => popurl(2),
-  'View all advertising sources' => popurl(2). "browse/part_referral.cgi",
-)) %>
-
-<% if ( $cgi->param('error') ) { %>
-  <FONT SIZE="+1" COLOR="#ff0000">Error: <%= $cgi->param('error') %></FONT>
-<% } %>
-
-<FORM ACTION="<%= $p1 %>process/part_referral.cgi" METHOD=POST>
-
-<INPUT TYPE="hidden" NAME="refnum" VALUE="<%= $hashref->{refnum} %>">
-
-<%
-#print "Referral #", $hashref->{refnum} ? $hashref->{refnum} : "(NEW)";
-%>
-
-Advertising source <INPUT TYPE="text" NAME="referral" SIZE=32 VALUE="<%= $hashref->{referral} %>">
-
-<BR>
-<INPUT TYPE="submit" VALUE="<%= $hashref->{refnum} ? "Apply changes" : "Add advertising source" %>">
-
-</FORM>
-
-<%= include('/elements/footer.html') %>
diff --git a/httemplate/edit/part_referral.html b/httemplate/edit/part_referral.html
new file mode 100755 (executable)
index 0000000..ec0f32f
--- /dev/null
@@ -0,0 +1,9 @@
+<%= include( 'elements/edit.html',
+                'name'        => 'Advertising source',
+                'table'       => 'part_referral',
+                'fields'      => [ 'referral' ],
+                'labels'      => { 'referral' => 'Advertising source' },
+                'viewall_dir' => 'browse',
+                'html_table_bottom' => include('/elements/tr-select-agent.html'),
+           )
+%>
diff --git a/httemplate/edit/process/part_referral.cgi b/httemplate/edit/process/part_referral.cgi
deleted file mode 100755 (executable)
index fd2c015..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<%
-
-my $refnum = $cgi->param('refnum');
-
-my $new = new FS::part_referral ( {
-  map {
-    $_, scalar($cgi->param($_));
-  } fields('part_referral')
-} );
-
-my $error;
-if ( $refnum ) {
-  my $old = qsearchs( 'part_referral', { 'refnum' =>$ refnum } );
-  die "(Old) Record not found!" unless $old;
-  $error = $new->replace($old);
-} else {
-  $error = $new->insert;
-}
-$refnum=$new->refnum;
-
-if ( $error ) {
-  $cgi->param('error', $error);
-  print $cgi->redirect(popurl(2). "part_referral.cgi?". $cgi->query_string );
-} else {
-  print $cgi->redirect(popurl(3). "browse/part_referral.cgi");
-}
-
-%>
diff --git a/httemplate/edit/process/part_referral.html b/httemplate/edit/process/part_referral.html
new file mode 100755 (executable)
index 0000000..0b5d959
--- /dev/null
@@ -0,0 +1,5 @@
+<%= include( 'elements/process.html',
+                 'table'       => 'part_referral',
+                 'viewall_dir' => 'browse',
+           )
+%>
index 8c62d97..a5b41ae 100644 (file)
     'View/Edit address blocks' => [ $fsurl.'browse/addr_block.cgi', 'Manage address blocks and block assignments to broadband routers' ],
   ;
 
-  tie my %config_misc, 'Tie::IxHash',
-    'View/Edit advertising sources' => [ $fsurl.'browse/part_referral.cgi', 'Where a customer heard about your service.  Tracked for informational purposes' ],
-    'View/Edit virtual fields' => [ $fsurl.'browse/part_virtual_field.cgi', 'Locally defined fields', ],
-    'View/Edit message catalog' => [ $fsurl.'browse/msgcat.cgi', 'Change error messages and other customizable labels' ],
-    'View/Edit inventory classes and inventory' => [ $fsurl.'browse/inventory_class.html', 'Setup inventory classes and stock inventory' ],
-  ;
+  tie my %config_misc, 'Tie::IxHash';
+  $config_misc{'View/Edit advertising sources'} = [ $fsurl.'browse/part_referral.html', 'Where a customer heard about your service.  Tracked for informational purposes' ]
+    if $curuser->access_right('Configuration')
+    || $curuser->access_right('Edit advertising sources')
+    || $curuser->access_right('Edit global advertising sources');
+  if ( $curuser->access_right('Configuration') ) {
+    $config_misc{'View/Edit virtual fields'} = [ $fsurl.'browse/part_virtual_field.cgi', 'Locally defined fields', ];
+    $config_misc{'View/Edit message catalog'} = [ $fsurl.'browse/msgcat.cgi', 'Change error messages and other customizable labels' ];
+    $config_misc{'View/Edit inventory classes and inventory'} = [ $fsurl.'browse/inventory_class.html', 'Setup inventory classes and stock inventory' ];
+  }
 
-  tie my %config_menu, 'Tie::IxHash',
-    'Settings'      => [ $fsurl.'config/config-view.cgi', '' ],
-    'separator'     => '', #its a separator!
-    'Employees'     => [ \%config_employees, '' ],
-    'Provisioning, services and packages'
-                    => [ \%config_export_svc_pkg, ''    ],
-    'Resellers'     => [ \%config_agent, ''    ],
-    'Billing'       => [ \%config_billing, ''    ],
-    'Dialup'        => [ \%config_dialup, ''    ],
-    'Fixed (username-less) broadband'
-                    => [ \%config_broadband, ''    ],
-    'Miscellaneous' => [ \%config_misc, ''    ],
-  ;
+  tie my %config_menu, 'Tie::IxHash';
+  if ( $curuser->access_right('Configuration' ) ) {
+    %config_menu = (
+      'Settings'      => [ $fsurl.'config/config-view.cgi', '' ],
+      'separator'     => '', #its a separator!
+      'Employees'     => [ \%config_employees, '' ],
+      'Provisioning, services and packages'
+                      => [ \%config_export_svc_pkg, ''    ],
+      'Resellers'     => [ \%config_agent, ''    ],
+      'Billing'       => [ \%config_billing, ''    ],
+      'Dialup'        => [ \%config_dialup, ''    ],
+      'Fixed (username-less) broadband'
+                      => [ \%config_broadband, ''    ],
+    );
+  }
+  $config_menu{'Miscellaneous'} = [ \%config_misc, ''    ]
+    if $curuser->access_right('Configuration')
+    || $curuser->access_right('Edit advertising sources')
+    || $curuser->access_right('Edit global advertising sources');
 
   tie my %menu, 'Tie::IxHash',
     'Billing Main'   => [ $fsurl, 'Billing start page', ],
   $menu{'Tools'} = [ \%tools_menu, 'Tools' ]
     if keys %tools_menu;
   $menu{'Configuration'} = [ \%config_menu, 'Configuraiton and setup' ]
-    if $curuser->access_right('Configuration');
+    if $curuser->access_right('Configuration')
+    || $curuser->access_right('Edit advertising sources')
+    || $curuser->access_right('Edit global advertising sources');
 
   use vars qw($gmenunum);
   $gmenunum = 0;