cust_attachment improvement, RT#4964 and #6225
authormark <mark>
Tue, 24 Nov 2009 01:11:22 +0000 (01:11 +0000)
committermark <mark>
Tue, 24 Nov 2009 01:11:22 +0000 (01:11 +0000)
FS/FS/Schema.pm
httemplate/browse/cust_attachment.html [new file with mode: 0755]
httemplate/edit/cust_main_attach.cgi
httemplate/edit/process/cust_main_attach.cgi
httemplate/elements/menu.html
httemplate/misc/cust_attachment.cgi [new file with mode: 0644]
httemplate/search/elements/search-html.html
httemplate/view/cust_main/attachments.html

index 3587a91..06baab6 100644 (file)
@@ -380,8 +380,9 @@ sub tables_hashref {
         'otaker',    'varchar', '', 32, '', '',
         'filename',  'varchar', '', 32, '', '',
         'mime_type', 'varchar', '', 32, '', '',
+        'title',     'varchar', 'NULL', 32, '', '',
         'body',      'blob', 'NULL', '', '', '',
-        'disabled',  @date_type, '', '',
+        'disabled',  'varchar', 'NULL', '10', '',
       ],
       'primary_key' => 'attachnum',
       'unique'      => [],
diff --git a/httemplate/browse/cust_attachment.html b/httemplate/browse/cust_attachment.html
new file mode 100755 (executable)
index 0000000..0fdc745
--- /dev/null
@@ -0,0 +1,183 @@
+<% include( 'elements/browse.html',
+                 'title'       => 'Attachments',
+                 'menubar'     => '',
+                 'name'        => ($disabled ? 'deleted' : '') .' attachments',
+                 'html_init'   => include('/elements/init_overlib.html') .
+                    ($curuser->access_right('View deleted attachments') ? (
+                    selflink('Show '.($disabled ? 'active' : 'deleted'),
+                             show_deleted => (1-$disabled))) : ''),
+                'html_form'   => 
+                    qq!<FORM NAME="attachForm" ACTION="$p/misc/cust_attachment.cgi" METHOD="POST">
+                    <INPUT TYPE="hidden" NAME="orderby" VALUE="$orderby">
+                    <INPUT TYPE="hidden" NAME="show_deleted" VALUE="$disabled">!
+                    , 
+                 'query'       => { 'table'     => 'cust_attachment',
+                                    'hashref'   => $hashref,
+                                    'extra_sql' => 'ORDER BY '.$orderby,
+                                  },
+                 'count_query' => $count_query,
+                 'header' => [ selflink('#',orderby => 'attachnum'),
+                               selflink('Customer',orderby => 'custnum'),
+                               selflink('Date',orderby => '_date'),
+                               selflink('Filename',orderby => 'filename'),
+                               selflink('Size',orderby => 'length(body)'),
+                               selflink('Uploaded by',orderby => 'otaker'),
+                               selflink('Description',orderby => 'title'),
+                               '', # checkbox column
+                             ],
+                 'fields' => [
+                               'attachnum',
+                               $sub_cust,
+                               $sub_date,
+                               'filename',
+                               $sub_size,
+                               'otaker',
+                               'title',
+                               $sub_checkbox,
+                             ],
+                 'links' => [ '',
+                              [ $p.'view/cust_main.cgi?', 'custnum' ],
+                            ],
+                 'link_onclicks' => [
+                              '',
+                              '',
+                              '',
+                              $sub_edit_link,
+                              ],
+
+                 #'links' =>  [
+                 #              '',
+                 #              '',
+                 #              '',
+                 #              '',
+                 #              '',
+                 #              '', #$acct_link,
+                 #              '',
+                'html_foot' => $sub_foot,
+             )
+
+%>
+
+
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+my $conf = new FS::Conf;
+
+my $noactions = 1;
+my $areboxes = 0;
+
+my $disabled = 0;
+
+if($cgi->param('show_deleted')) {
+  if ($curuser->access_right('View deleted attachments')) {
+    $disabled = 1;
+    if ($curuser->access_right('Purge attachment') or
+        $curuser->access_right('Undelete attachment')) {
+      $noactions = 0;
+    }
+  }
+  else {
+    die "access denied";
+  }
+}
+else {
+  if ($curuser->access_right('Delete attachment')) {
+    $noactions = 0;
+  }
+}
+
+my $hashref = $disabled ? 
+  { disabled => { op => '>', value => 0 } } :
+  { disabled => '' };
+
+my $count_query = 'SELECT COUNT(*) FROM cust_attachment WHERE '. ($disabled ?
+  'disabled > 0' : 'disabled IS NULL');
+
+my $orderby = $cgi->param('orderby') || 'custnum';
+
+my $sub_cust = sub {
+  my $c = qsearchs('cust_main', { custnum => shift->custnum } );
+  return $c ? $c->name : '<FONT COLOR="red"><B>(not found)</B></FONT>';
+};
+
+my $sub_date = sub {
+  time2str("%b %o, %Y", shift->_date);
+};
+
+my $sub_size = sub {
+  my $size = shift->size;
+  return $size if $size < 1024;
+  return int($size/1024).'K' if $size < 1048576;
+  return int($size/1048576).'M';
+};
+
+my $sub_checkbox = sub {
+  return '' if $noactions;
+  my $attach = shift;
+  my $attachnum = $attach->attachnum;
+  $areboxes = 1;
+  return qq!<INPUT NAME="attachnum$attachnum" TYPE="checkbox" VALUE="1">!;
+};
+
+my $sub_edit_link = sub {
+  my $attach = shift;
+  my $attachnum = $attach->attachnum;
+  my $custnum = $attach->custnum;
+  return include('/elements/popup_link_onclick.html',
+           action => popurl(2).'edit/cust_main_attach.cgi?'.
+                     "custnum=$custnum;attachnum=$attachnum",
+           actionlabel => 'Edit attachment properties',
+           width  => 510,
+           height => 315,
+           frame  => 'top',
+           );
+};
+
+sub selflink {
+  my $label = shift;
+  my %new_param = @_;
+  my $param = $cgi->Vars;
+  my %old_param = %$param;
+  @{$param}{keys(%new_param)} = values(%new_param);
+  my $link = '<a href="'.$cgi->self_url.'">'.$label.'</a>';
+  %$param = %old_param;
+  return $link;
+}
+
+sub confirm {
+  my $action = shift;
+  my $onclick = "return(confirm('$action all selected files?'))";
+  return qq!onclick="$onclick"!;
+}
+
+my $sub_foot = sub {
+  return '' if ($noactions or !$areboxes);
+  my $foot = 
+'<BR><INPUT TYPE="button" VALUE="Select all" onClick="setAll(true)">
+<INPUT TYPE="button" VALUE="Unselect all" onClick="setAll(false)">';
+  if ($disabled) {
+    if ($curuser->access_right('Undelete attachment')) {
+      $foot .= '<BR><INPUT TYPE="submit" NAME="action" VALUE="Undelete selected">';
+    }
+    if ($curuser->access_right('Purge attachment')) {
+      $foot .= '<BR><INPUT TYPE="submit" NAME="action" VALUE="Purge selected" '.confirm('Purge').'>';
+    }
+  }
+  else {
+    $foot .= '<BR><INPUT TYPE="submit" NAME="action" VALUE="Delete selected" '.confirm('Delete').'>';
+  }
+  $foot .= 
+'<SCRIPT TYPE="text/javascript">
+  function setAll(setTo) { 
+    theForm = document.attachForm;
+    for (i=0,n=theForm.elements.length;i<n;i++)
+      if (theForm.elements[i].name.indexOf("attachnum") != -1)
+        theForm.elements[i].checked = setTo;
+  }
+</SCRIPT>';
+  return $foot;
+};
+
+</%init>
index 43d2e29..5e9b16c 100755 (executable)
@@ -2,31 +2,39 @@
 
 <% include('/elements/error.html') %>
 
-<FORM ACTION="<% popurl(1) %>process/cust_main_attach.cgi" METHOD=POST ENCTYPE="multipart/form-data">
+<FORM NAME="attach_edit" ACTION="<% popurl(1) %>process/cust_main_attach.cgi" METHOD=POST ENCTYPE="multipart/form-data">
 <INPUT TYPE="hidden" NAME="custnum" VALUE="<% $custnum %>">
 <INPUT TYPE="hidden" NAME="attachnum" VALUE="<% $attachnum %>">
 
 <BR><BR>
 
+<% include('/elements/table.html') %>
 % if(defined $attach) {
-Filename <INPUT TYPE="text" NAME="filename" VALUE="<% $attach->filename %>"><BR>
-MIME type <INPUT TYPE="text" NAME="mime_type" VALUE="<% $attach->mime_type %>"<BR>
-Size: <% $attach->size %><BR>
-
+%   if($curuser->access_right("Download attachment")) {
+<A HREF="<% $p.'view/attachment.html?'.$attachnum %>">Download this file</A><BR>
+%   }
+<TR><TD> Filename </TD>
+<TD><INPUT TYPE="text" NAME="filename" SIZE=32 MAXLENGTH=32 VALUE="<% $attach->filename %>"<% $disabled %>></TD></TR>
+<TR><TD> Description </TD>
+<TD><INPUT TYPE="text" NAME="title" SIZE=32 MAXLENGTH=32 VALUE="<% $attach->title %>"<% $disabled %></TD></TR>
+<TR><TD> MIME type </TD>
+<TD><INPUT TYPE="text" NAME="mime_type" VALUE="<% $attach->mime_type %>"<% $disabled %></TD></TR>
+<TR><TD> Size </TD><TD><% $attach->size %></TD></TR>
 % }
 % else { # !defined $attach
-
-Filename <INPUT TYPE="file" NAME="file"><BR>
-
+<TR><TD> Filename </TD><TD><INPUT TYPE="file" SIZE=32 NAME="file"></TD></TR>
+<TR><TD> Description </TD><TD><INPUT TYPE="text" NAME="title" SIZE=32 MAXLENGTH=32></TD></TR>
 % }
-
+</TABLE>
 <BR>
+% if(! $disabled) {
 <INPUT TYPE="submit" NAME="submit" 
     VALUE="<% $attachnum ? "Apply Changes" : "Upload File" %>">
-
+% }
 % if(defined $attach and $curuser->access_right('Delete attachment')) {
 <BR>
-<INPUT TYPE="submit" NAME="delete" value="Delete File">
+<INPUT TYPE="submit" NAME="delete" value="Delete File" 
+onclick="return(confirm('Delete this file?'));">
 % }
 
 </FORM>
@@ -47,13 +55,15 @@ if ( $cgi->param('error') ) {
   die "no such attachment: ". $attachnum unless $attach;
 }
 
-$cgi->param('custnum') =~ /^(\d+)$/ or die "illegal custnum";
-my $custnum = $1;
-
 my $action = $attachnum ? 'Edit' : 'Add';
 
-die "access denied"
-  unless $curuser->access_right("$action attachment");
+my $disabled='';
+if(! $curuser->access_right("$action attachment")) {
+  $disabled = ' disabled="disabled"';
+}
+
+$cgi->param('custnum') =~ /^(\d+)$/ or die "illegal custnum";
+my $custnum = $1;
 
 </%init>
 
index 98f4d09..0927141 100644 (file)
@@ -53,6 +53,7 @@ if($attachnum) {
       ('_date', 'otaker', 'body', 'disabled');
     $new->filename($cgi->param('filename') || $old->filename);
     $new->mime_type($cgi->param('mime_type') || $old->mime_type);
+    $new->title($cgi->param('title'));
     if($delete and not $old->disabled) {
       $new->disabled(time);
     }
@@ -67,6 +68,7 @@ else { # This is a new attachment, so require a file.
   if($filename) {
     $new->filename($filename);
     $new->mime_type($cgi->uploadInfo($filename)->{'Content-Type'});
+    $new->title($cgi->param('title'));
     
     local $/;
     my $fh = $cgi->upload('file');
index 17b8913..652f4f9 100644 (file)
@@ -322,6 +322,8 @@ $tools_menu{'Ticketing'} = [ \%tools_ticketing, 'Ticketing tools' ]
   if $conf->config('ticket_system');
 $tools_menu{'Time Queue'} =  [ $fsurl.'search/timeworked.html', 'View pending support time' ]
   if $curuser->access_right('Time queue');
+$tools_menu{'Attachments'} = [ $fsurl.'browse/cust_attachment.html', 'View customer attachments' ]
+  if !$conf->config('disable_cust_attachment');
 $tools_menu{'Importing'} =  [ \%tools_importing, 'Import tools' ]
   if $curuser->access_right('Import');
 $tools_menu{'Exporting'} =  [ \%tools_exporting, 'Export tools' ]
diff --git a/httemplate/misc/cust_attachment.cgi b/httemplate/misc/cust_attachment.cgi
new file mode 100644 (file)
index 0000000..d1ec777
--- /dev/null
@@ -0,0 +1,34 @@
+<% '',$cgi->redirect(popurl(2). "browse/cust_attachment.html?$browse_opts") %>
+<%init>
+
+$cgi->param('action') =~ /^(Delete|Undelete|Purge) selected$/
+  or die "Illegal action";
+my $action = $1;
+
+my $browse_opts = join(';', map { $_.'='.$cgi->param($_) } 
+    qw( orderby show_deleted )
+    );
+
+die "access denied"
+  unless $FS::CurrentUser::CurrentUser->access_right("$action attachment");
+
+foreach my $attachnum (
+    map { /^attachnum(\d+)$/; $1; } grep /^attachnum\d+$/, $cgi->param
+  ) {
+  my $attach = qsearchs('cust_attachment', { 'attachnum' => $attachnum });
+  my $error;
+  if ( $action eq 'Delete' and !$attach->disabled ) {
+    $attach->disabled(time);
+    $error = $attach->replace;
+  }
+  elsif ( $action eq 'Undelete' and $attach->disabled ) {
+    $attach->disabled('');
+    $error = $attach->replace;
+  }
+  elsif ( $action eq 'Purge' and $attach->disabled ) {
+    $error = $attach->delete;
+  }
+  die $error if $error;
+}
+
+</%init>
index 297774d..c0bb721 100644 (file)
 %                             }
 %                             $a = qq(<A HREF="$a"$onclick>);
 %                           }
-%
+%                           elsif ( $onclick ) {
+%                             $a = qq(<A HREF="javascript:void(0);"$onclick>);
+%                           }
 %                         }
 %
 %                       }
index 53635fd..dbb29a7 100755 (executable)
@@ -11,6 +11,7 @@
 %   }
     <TH CLASS="grid" BGCOLOR="#cccccc">Person</TH>
     <TH CLASS="grid" BGCOLOR="#cccccc">Filename</TH>
+    <TH CLASS="grid" BGCOLOR="#cccccc">Description</TH>
     <TH CLASS="grid" BGCOLOR="#cccccc">Type</TH>
     <TH CLASS="grid" BGCOLOR="#cccccc">Size</TH>
     <TH CLASS="grid" BGCOLOR="#cccccc"></TH>
@@ -54,7 +55,8 @@
 %       my $clickjs = popup('edit/process/cust_main_attach.cgi?'.
 %                           "custnum=$custnum;attachnum=$attachnum;".
 %                           "purge=1",
-%                           'Purge attachment');
+%                           'Purge attachment',
+%                           'Permanently remove this file?');
 %       $edit .= qq!&nbsp; <A HREF="javascript:void(0);" $clickjs>(purge)</A>!;
 %     }
 %   }
@@ -67,9 +69,9 @@
 %     }
 %     if($curuser->access_right('Delete attachment') ) {
 %       my $clickjs = popup('edit/process/cust_main_attach.cgi?'.
-%                           "custnum=$custnum;attachnum=$attachnum;".
-%                           "delete=1",
-%                           'Delete attachment');
+%                           "custnum=$custnum;attachnum=$attachnum;delete=1",
+%                           'Delete attachment',
+%                           'Delete this file?');
 %       $edit .= qq!&nbsp; <A HREF="javascript:void(0);" $clickjs>(delete)</A>!;
 %     }
 %     if ($curuser->access_right('Download attachment') ) {
@@ -86,6 +88,8 @@
        &nbsp;<% $attach->filename %>
       </TD>
       <TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
+       &nbsp;<% $attach->title %>
+      <TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
        &nbsp;<% $attach->mime_type %>
       </TD>
       <TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
@@ -135,15 +139,16 @@ sub size_units {
 }
 
 sub popup {
-  my ($url, $label) = @_;
+  my ($url, $label, $confirm) = @_;
   my $onclick = 
     include('/elements/popup_link_onclick.html',
       'action'     => popurl(2).$url,
       'actionlabel' => $label,
-      'width'       => 616,
-      'height'      => 408,
+      'width'       => 510,
+      'height'      => 315,
       'frame'       => 'top',
     );
+  $onclick = qq!if(confirm('$confirm')) { $onclick }! if $confirm;
   return qq!onclick="$onclick"!;
 }