'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' => [],
--- /dev/null
+<% 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>
<% 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>
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>
('_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);
}
if($filename) {
$new->filename($filename);
$new->mime_type($cgi->uploadInfo($filename)->{'Content-Type'});
+ $new->title($cgi->param('title'));
local $/;
my $fh = $cgi->upload('file');
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' ]
--- /dev/null
+<% '',$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>
% }
% $a = qq(<A HREF="$a"$onclick>);
% }
-%
+% elsif ( $onclick ) {
+% $a = qq(<A HREF="javascript:void(0);"$onclick>);
+% }
% }
%
% }
% }
<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>
% 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! <A HREF="javascript:void(0);" $clickjs>(purge)</A>!;
% }
% }
% }
% 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! <A HREF="javascript:void(0);" $clickjs>(delete)</A>!;
% }
% if ($curuser->access_right('Download attachment') ) {
<% $attach->filename %>
</TD>
<TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
+ <% $attach->title %>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
<% $attach->mime_type %>
</TD>
<TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
}
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"!;
}