Revision a40f0c2f
Von Martin Helmling martin.helmling@octosoft.eu vor fast 8 Jahren hinzugefügt
SL/Controller/EmailJournal.pm | ||
---|---|---|
60 | 60 |
if (!$self->can_view_all && ($attachment->email_journal->sender_id != SL::DB::Manager::Employee->current->id)) { |
61 | 61 |
$::form->error(t8('You do not have permission to access this entry.')); |
62 | 62 |
} |
63 |
|
|
64 |
$self->send_file(\$attachment->content, name => $attachment->name, type => $attachment->mime_type); |
|
63 |
my $ref = \$attachment->content; |
|
64 |
if ( $attachment->file_id > 0 ) { |
|
65 |
my $file = SL::File->get(id => $attachment->file_id ); |
|
66 |
$ref = SL::File->get_content(dbfile => $file) if $file; |
|
67 |
} |
|
68 |
$self->send_file($ref, name => $attachment->name, type => $attachment->mime_type); |
|
65 | 69 |
} |
66 | 70 |
|
67 | 71 |
# |
SL/DB/MetaSetup/EmailJournalAttachment.pm | ||
---|---|---|
11 | 11 |
__PACKAGE__->meta->columns( |
12 | 12 |
content => { type => 'bytea', not_null => 1 }, |
13 | 13 |
email_journal_id => { type => 'integer', not_null => 1 }, |
14 |
file_id => { type => 'integer', default => '0', not_null => 1 }, |
|
14 | 15 |
id => { type => 'serial', not_null => 1 }, |
15 | 16 |
itime => { type => 'timestamp', default => 'now()', not_null => 1 }, |
16 | 17 |
mime_type => { type => 'text', not_null => 1 }, |
SL/Form.pm | ||
---|---|---|
1102 | 1102 |
|
1103 | 1103 |
if ( !$self->{preview} && $ext_for_format eq 'pdf' && $::instance_conf->get_doc_storage) { |
1104 | 1104 |
$self->{attachment_filename} ||= $self->generate_attachment_filename; |
1105 |
$self->store_pdf($self); |
|
1105 |
$self->{print_file_id} = $self->store_pdf($self);
|
|
1106 | 1106 |
} |
1107 | 1107 |
if ($self->{media} eq 'email') { |
1108 |
if ( getcwd() eq $self->{"tmpdir"} ) { |
|
1109 |
# in the case of generating pdf we are in the tmpdir, but WHY ??? |
|
1110 |
$self->{tmpfile} = $userspath."/".$self->{tmpfile}; |
|
1111 |
chdir("$self->{cwd}"); |
|
1112 |
} |
|
1113 |
$self->send_email(\%::myconfig,$ext_for_format); |
|
1114 |
} |
|
1115 |
else { |
|
1116 |
$self->{OUT} = $out; |
|
1117 |
$self->{OUT_MODE} = $out_mode; |
|
1118 |
$self->output_file($template->get_mime_type,$command_formatter); |
|
1119 |
} |
|
1120 |
delete $self->{print_file_id}; |
|
1108 | 1121 |
|
1109 |
my $mail = Mailer->new; |
|
1110 |
|
|
1111 |
map { $mail->{$_} = $self->{$_} } |
|
1112 |
qw(cc bcc subject message version format); |
|
1113 |
$mail->{to} = $self->{EMAIL_RECIPIENT} ? $self->{EMAIL_RECIPIENT} : $self->{email}; |
|
1114 |
$mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|; |
|
1115 |
$mail->{fileid} = time() . '.' . $$ . '.'; |
|
1116 |
my $full_signature = $self->create_email_signature(); |
|
1117 |
$full_signature =~ s/\r//g; |
|
1118 |
|
|
1119 |
# if we send html or plain text inline |
|
1120 |
if (($self->{format} eq 'html') && ($self->{sendmode} eq 'inline')) { |
|
1121 |
$mail->{contenttype} = "text/html"; |
|
1122 |
$mail->{message} =~ s/\r//g; |
|
1123 |
$mail->{message} =~ s/\n/<br>\n/g; |
|
1124 |
$full_signature =~ s/\n/<br>\n/g; |
|
1125 |
$mail->{message} .= $full_signature; |
|
1126 |
|
|
1127 |
open(IN, "<:encoding(UTF-8)", $self->{tmpfile}) |
|
1128 |
or $self->error($self->cleanup . "$self->{tmpfile} : $!"); |
|
1129 |
$mail->{message} .= $_ while <IN>; |
|
1130 |
close(IN); |
|
1122 |
$self->cleanup; |
|
1131 | 1123 |
|
1132 |
} else { |
|
1124 |
chdir("$self->{cwd}"); |
|
1125 |
$main::lxdebug->leave_sub(); |
|
1126 |
} |
|
1133 | 1127 |
|
1134 |
if (!$self->{"do_not_attach"}) { |
|
1135 |
my $attachment_name = $self->{attachment_filename} || $self->{tmpfile}; |
|
1136 |
$attachment_name =~ s/\.(.+?)$/.${ext_for_format}/ if ($ext_for_format); |
|
1137 |
$mail->{attachments} = [{ "filename" => $self->{tmpfile}, |
|
1138 |
"name" => $attachment_name }]; |
|
1139 |
} |
|
1128 |
sub get_bcc_defaults { |
|
1129 |
my ($self, $myconfig, $mybcc) = @_; |
|
1130 |
# if (SL::DB::Default->get->bcc_to_login) { |
|
1131 |
# $mybcc .= ", " if $mybcc; |
|
1132 |
# $mybcc .= $myconfig->{email}; |
|
1133 |
# } |
|
1134 |
my $otherbcc = SL::DB::Default->get->global_bcc; |
|
1135 |
if ($otherbcc) { |
|
1136 |
$mybcc .= ", " if $mybcc; |
|
1137 |
$mybcc .= $otherbcc; |
|
1138 |
} |
|
1139 |
return $mybcc; |
|
1140 |
} |
|
1140 | 1141 |
|
1141 |
$mail->{message} .= $full_signature; |
|
1142 |
} |
|
1142 |
sub send_email { |
|
1143 |
$main::lxdebug->enter_sub(); |
|
1144 |
my ($self, $myconfig, $ext_for_format) = @_; |
|
1145 |
my $mail = Mailer->new; |
|
1143 | 1146 |
|
1144 |
my $err = $mail->send();
|
|
1145 |
$self->error($self->cleanup . "$err") if ($err);
|
|
1147 |
map { $mail->{$_} = $self->{$_} }
|
|
1148 |
qw(cc subject message version format);
|
|
1146 | 1149 |
|
1147 |
} else { |
|
1150 |
$mail->{bcc} = $self->get_bcc_defaults($myconfig, $self->{bcc}); |
|
1151 |
$mail->{to} = $self->{EMAIL_RECIPIENT} ? $self->{EMAIL_RECIPIENT} : $self->{email}; |
|
1152 |
$mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|; |
|
1153 |
$mail->{fileid} = time() . '.' . $$ . '.'; |
|
1154 |
my $full_signature = $self->create_email_signature(); |
|
1155 |
$full_signature =~ s/\r//g; |
|
1148 | 1156 |
|
1149 |
$self->{OUT} = $out; |
|
1150 |
$self->{OUT_MODE} = $out_mode; |
|
1157 |
$mail->{attachments} = []; |
|
1158 |
my @attfiles; |
|
1159 |
# if we send html or plain text inline |
|
1160 |
if (($self->{format} eq 'html') && ($self->{sendmode} eq 'inline')) { |
|
1161 |
$mail->{contenttype} = "text/html"; |
|
1162 |
$mail->{message} =~ s/\r//g; |
|
1163 |
$mail->{message} =~ s/\n/<br>\n/g; |
|
1164 |
$full_signature =~ s/\n/<br>\n/g; |
|
1165 |
$mail->{message} .= $full_signature; |
|
1151 | 1166 |
|
1152 |
my $numbytes = (-s $self->{tmpfile}); |
|
1153 | 1167 |
open(IN, "<", $self->{tmpfile}) |
1154 | 1168 |
or $self->error($self->cleanup . "$self->{tmpfile} : $!"); |
1155 |
binmode IN; |
|
1169 |
$mail->{message} .= $_ while <IN>; |
|
1170 |
close(IN); |
|
1156 | 1171 |
|
1157 |
$self->{copies} = 1 unless $self->{media} eq 'printer'; |
|
1172 |
} else { |
|
1173 |
$main::lxdebug->message(LXDebug->DEBUG2(),"action_oldfile=" . $self->{action_oldfile}." action_nofile=".$self->{action_nofile}); |
|
1174 |
if (!$self->{"do_not_attach"} && !$self->{action_nofile}) { |
|
1175 |
my $attachment_name = $self->{attachment_filename} || $self->{tmpfile}; |
|
1176 |
$attachment_name =~ s/\.(.+?)$/.${ext_for_format}/ if ($ext_for_format); |
|
1177 |
if ( $self->{action_oldfile} ) { |
|
1178 |
$main::lxdebug->message(LXDebug->DEBUG2(),"object_id =>". $self->{id}." object_type =>". $self->{formname}); |
|
1179 |
my ( $attfile ) = SL::File->get_all(object_id => $self->{id}, |
|
1180 |
object_type => $self->{formname}, |
|
1181 |
file_type => 'document'); |
|
1182 |
$main::lxdebug->message(LXDebug->DEBUG2(), "old file obj=".$attfile); |
|
1183 |
push @attfiles, $attfile if $attfile; |
|
1184 |
} else { |
|
1185 |
push @{ $mail->{attachments} }, { path => $self->{tmpfile}, |
|
1186 |
id => $self->{print_file_id}, |
|
1187 |
type => "application/pdf", |
|
1188 |
name => $attachment_name }; |
|
1189 |
} |
|
1190 |
} |
|
1191 |
} |
|
1192 |
if (!$self->{"do_not_attach"}) { |
|
1193 |
for my $i (1 .. $self->{attfile_count}) { |
|
1194 |
if ( $self->{"attsel_$i"} ) { |
|
1195 |
my $attfile = SL::File->get(id => $self->{"attfile_$i"}); |
|
1196 |
$main::lxdebug->message(LXDebug->DEBUG2(), "att file=".$self->{"attfile_$i"}." obj=".$attfile); |
|
1197 |
push @attfiles, $attfile if $attfile; |
|
1198 |
} |
|
1199 |
} |
|
1200 |
for my $i (1 .. $self->{attfile_cv_count}) { |
|
1201 |
if ( $self->{"attsel_cv_$i"} ) { |
|
1202 |
my $attfile = SL::File->get(id => $self->{"attfile_cv_$i"}); |
|
1203 |
$main::lxdebug->message(LXDebug->DEBUG2(), "att file=".$self->{"attfile_$i"}." obj=".$attfile); |
|
1204 |
push @attfiles, $attfile if $attfile; |
|
1205 |
} |
|
1206 |
} |
|
1207 |
for my $i (1 .. $self->{attfile_part_count}) { |
|
1208 |
if ( $self->{"attsel_part_$i"} ) { |
|
1209 |
my $attfile = SL::File->get(id => $self->{"attfile_part_$i"}); |
|
1210 |
$main::lxdebug->message(LXDebug->DEBUG2(), "att file=".$self->{"attfile_$i"}." obj=".$attfile); |
|
1211 |
push @attfiles, $attfile if $attfile; |
|
1212 |
} |
|
1213 |
} |
|
1214 |
foreach my $attfile ( @attfiles ) { |
|
1215 |
push @{ $mail->{attachments} }, { path => SL::File->get_file_path(dbfile => $attfile), |
|
1216 |
id => $attfile->id, |
|
1217 |
type => $attfile->file_mime_type, |
|
1218 |
name => $attfile->file_name }; |
|
1219 |
} |
|
1220 |
} |
|
1221 |
$mail->{message} =~ s/\r//g; |
|
1222 |
$mail->{message} .= $full_signature; |
|
1223 |
$self->{emailerr} = $mail->send(); |
|
1224 |
# $self->error($self->cleanup . "$err") if $self->{emailerr}; |
|
1225 |
$self->{email_journal_id} = $mail->{journalentry}; |
|
1158 | 1226 |
|
1159 |
chdir("$self->{cwd}"); |
|
1160 |
#print(STDERR "Kopien $self->{copies}\n"); |
|
1161 |
#print(STDERR "OUT $self->{OUT}\n"); |
|
1162 |
for my $i (1 .. $self->{copies}) { |
|
1163 |
if ($self->{OUT}) { |
|
1164 |
$self->{OUT} = $command_formatter->($self->{OUT_MODE}, $self->{OUT}); |
|
1227 |
#write back for message info and mail journal |
|
1228 |
$self->{cc} = $mail->{cc}; |
|
1229 |
$self->{bcc} = $mail->{bcc}; |
|
1230 |
$self->{email} = $mail->{to}; |
|
1165 | 1231 |
|
1166 |
open OUT, $self->{OUT_MODE}, $self->{OUT} or $self->error($self->cleanup . "$self->{OUT} : $!"); |
|
1167 |
print OUT $_ while <IN>; |
|
1168 |
close OUT; |
|
1169 |
seek IN, 0, 0; |
|
1232 |
$main::lxdebug->leave_sub(); |
|
1233 |
} |
|
1170 | 1234 |
|
1171 |
} else { |
|
1172 |
my %headers = ('-type' => $template->get_mime_type, |
|
1173 |
'-connection' => 'close', |
|
1174 |
'-charset' => 'UTF-8'); |
|
1175 |
|
|
1176 |
$self->{attachment_filename} ||= $self->generate_attachment_filename; |
|
1177 |
|
|
1178 |
if ($self->{attachment_filename}) { |
|
1179 |
%headers = ( |
|
1180 |
%headers, |
|
1181 |
'-attachment' => $self->{attachment_filename}, |
|
1182 |
'-content-length' => $numbytes, |
|
1183 |
'-charset' => '', |
|
1184 |
); |
|
1185 |
} |
|
1235 |
sub output_file { |
|
1236 |
$main::lxdebug->enter_sub(); |
|
1186 | 1237 |
|
1187 |
print $::request->cgi->header(%headers); |
|
1238 |
my ($self,$mimeType,$command_formatter) = @_; |
|
1239 |
my $numbytes = (-s $self->{tmpfile}); |
|
1240 |
open(IN, "<", $self->{tmpfile}) |
|
1241 |
or $self->error($self->cleanup . "$self->{tmpfile} : $!"); |
|
1242 |
binmode IN; |
|
1188 | 1243 |
|
1189 |
$::locale->with_raw_io(\*STDOUT, sub { print while <IN> }); |
|
1190 |
} |
|
1191 |
} |
|
1244 |
$self->{copies} = 1 unless $self->{media} eq 'printer'; |
|
1192 | 1245 |
|
1193 |
close(IN); |
|
1194 |
} |
|
1246 |
chdir("$self->{cwd}"); |
|
1247 |
for my $i (1 .. $self->{copies}) { |
|
1248 |
if ($self->{OUT}) { |
|
1249 |
$self->{OUT} = $command_formatter->($self->{OUT_MODE}, $self->{OUT}); |
|
1195 | 1250 |
|
1196 |
$self->cleanup; |
|
1251 |
open OUT, $self->{OUT_MODE}, $self->{OUT} or $self->error($self->cleanup . "$self->{OUT} : $!"); |
|
1252 |
print OUT $_ while <IN>; |
|
1253 |
close OUT; |
|
1254 |
seek IN, 0, 0; |
|
1197 | 1255 |
|
1198 |
chdir("$self->{cwd}"); |
|
1256 |
} else { |
|
1257 |
my %headers = ('-type' => $mimeType, |
|
1258 |
'-connection' => 'close', |
|
1259 |
'-charset' => 'UTF-8'); |
|
1260 |
|
|
1261 |
$self->{attachment_filename} ||= $self->generate_attachment_filename; |
|
1262 |
|
|
1263 |
if ($self->{attachment_filename}) { |
|
1264 |
%headers = ( |
|
1265 |
%headers, |
|
1266 |
'-attachment' => $self->{attachment_filename}, |
|
1267 |
'-content-length' => $numbytes, |
|
1268 |
'-charset' => '', |
|
1269 |
); |
|
1270 |
} |
|
1271 |
|
|
1272 |
print $::request->cgi->header(%headers); |
|
1273 |
|
|
1274 |
$::locale->with_raw_io(\*STDOUT, sub { print while <IN> }); |
|
1275 |
} |
|
1276 |
} |
|
1277 |
close(IN); |
|
1199 | 1278 |
$main::lxdebug->leave_sub(); |
1200 | 1279 |
} |
1201 | 1280 |
|
SL/InstallationCheck.pm | ||
---|---|---|
29 | 29 |
{ name => "Digest::SHA", url => "http://search.cpan.org/~mshelor/", debian => 'libdigest-sha-perl' }, |
30 | 30 |
{ name => "Email::Address", url => "http://search.cpan.org/~rjbs/", debian => 'libemail-address-perl' }, |
31 | 31 |
{ name => "Email::MIME", url => "http://search.cpan.org/~rjbs/", debian => 'libemail-mime-perl' }, |
32 |
{ name => "MIME::Entity", url => "http://search.cpan.org/~dskoll/", debian => '' }, |
|
33 |
{ name => "MIME::Parser", url => "http://search.cpan.org/~dskoll/", debian => '' }, |
|
32 | 34 |
{ name => "FCGI", version => '0.72', url => "http://search.cpan.org/~mstrout/", debian => 'libfcgi-perl' }, |
33 | 35 |
{ name => "File::Copy::Recursive", url => "http://search.cpan.org/~dmuey/", debian => 'libfile-copy-recursive-perl' }, |
34 | 36 |
{ name => "GD", url => "http://search.cpan.org/~lds/", debian => 'libgd-gd2-perl', }, |
SL/Mailer.pm | ||
---|---|---|
24 | 24 |
package Mailer; |
25 | 25 |
|
26 | 26 |
use Email::Address; |
27 |
use Email::MIME::Creator; |
|
27 |
use MIME::Entity; |
|
28 |
use MIME::Parser; |
|
29 |
use File::MimeInfo::Magic; |
|
28 | 30 |
use File::Slurp; |
29 | 31 |
use List::UtilsBy qw(bundle_by); |
30 | 32 |
|
... | ... | |
32 | 34 |
use SL::DB::EmailJournal; |
33 | 35 |
use SL::DB::EmailJournalAttachment; |
34 | 36 |
use SL::DB::Employee; |
35 |
use SL::MIME; |
|
36 | 37 |
use SL::Template; |
37 | 38 |
|
38 | 39 |
use strict; |
40 |
use Encode; |
|
39 | 41 |
|
40 | 42 |
my $num_sent = 0; |
43 |
my $parser; |
|
41 | 44 |
|
42 | 45 |
my %mail_delivery_modules = ( |
43 | 46 |
sendmail => 'SL::Mailer::Sendmail', |
... | ... | |
47 | 50 |
sub new { |
48 | 51 |
my ($type, %params) = @_; |
49 | 52 |
my $self = { %params }; |
53 |
$parser = new MIME::Parser; |
|
54 |
$parser->output_under("users"); |
|
50 | 55 |
|
51 | 56 |
bless $self, $type; |
52 | 57 |
} |
... | ... | |
117 | 122 |
$addr_obj->phrase($phrase); |
118 | 123 |
} |
119 | 124 |
|
120 |
push @header_addresses, $addr_obj->format;
|
|
125 |
push @header_addresses, encode('MIME-Header',$addr_obj->format);
|
|
121 | 126 |
} |
122 | 127 |
|
123 | 128 |
push @{ $self->{headers} }, ( ucfirst($item) => join(', ', @header_addresses) ) if @header_addresses; |
... | ... | |
128 | 133 |
my ($self, $attachment) = @_; |
129 | 134 |
|
130 | 135 |
my %attributes = ( |
131 |
disposition => 'attachment',
|
|
132 |
encoding => 'base64',
|
|
136 |
Disposition => 'attachment',
|
|
137 |
Encoding => 'base64',
|
|
133 | 138 |
); |
134 | 139 |
|
140 |
my $file_id = 0; |
|
135 | 141 |
my $attachment_content; |
142 |
my $email_journal = $::instance_conf->get_email_journal; |
|
136 | 143 |
|
144 |
$main::lxdebug->message(LXDebug->DEBUG2(), "mail5 att=".$attachment." email_journal=". $email_journal." id=".$attachment->{id}); |
|
137 | 145 |
if (ref($attachment) eq "HASH") { |
138 |
$attributes{filename} = $attachment->{name}; |
|
139 |
$attachment_content = $attachment->{content} // eval { read_file($attachment->{filename}) }; |
|
146 |
$attributes{Path} = $attachment->{path} || $attachment->{filename}; |
|
147 |
$attributes{Filename} = $attachment->{name}; |
|
148 |
$file_id = $attachment->{id} || '0'; |
|
149 |
$attributes{Type} = $attachment->{type} || 'application/pdf'; |
|
150 |
$attachment_content = eval { read_file($attachment->{path}) } if $email_journal > 1; |
|
140 | 151 |
|
141 | 152 |
} else { |
142 | 153 |
# strip path |
143 |
$attributes{filename} = $attachment; |
|
144 |
$attributes{filename} =~ s:.*\Q$self->{fileid}\E:: if $self->{fileid}; |
|
145 |
$attributes{filename} =~ s:.*/::g; |
|
146 |
$attachment_content = eval { read_file($attachment) }; |
|
154 |
$attributes{Path} = $attachment; |
|
155 |
$attributes{Filename} = $attachment; |
|
156 |
$attributes{Filename} =~ s:.*\Q$self->{fileid}\E:: if $self->{fileid}; |
|
157 |
$attributes{Filename} =~ s:.*/::g; |
|
158 |
|
|
159 |
my $application = ($attachment =~ /(^\w+$)|\.(html|text|txt|sql)$/) ? 'text' : 'application'; |
|
160 |
$attributes{Type} = File::MimeInfo::Magic::magic($attachment); |
|
161 |
$attributes{Type} ||= "${application}/$self->{format}" if $self->{format}; |
|
162 |
$attributes{Type} ||= 'application/octet-stream'; |
|
163 |
$attachment_content = eval { read_file($attachment) } if $email_journal > 1; |
|
147 | 164 |
} |
148 | 165 |
|
149 |
return undef if !defined $attachment_content; |
|
166 |
return undef if $email_journal > 1 && !defined $attachment_content; |
|
167 |
$attachment_content ||= ' '; |
|
168 |
$main::lxdebug->message(LXDebug->DEBUG2(), "mail6 mtype=".$attributes{Type}." path=". |
|
169 |
$attributes{Path}." filename=".$attributes{Filename}); |
|
150 | 170 |
|
151 |
my $application = ($attachment =~ /(^\w+$)|\.(html|text|txt|sql)$/) ? 'text' : 'application'; |
|
152 |
$attributes{content_type} = SL::MIME->mime_type_from_ext($attributes{filename}); |
|
153 |
$attributes{content_type} ||= "${application}/$self->{format}" if $self->{format}; |
|
154 |
$attributes{content_type} ||= 'application/octet-stream'; |
|
155 |
$attributes{charset} = $self->{charset} if lc $application eq 'text' && $self->{charset}; |
|
171 |
# $attributes{Charset} = $self->{charset} if lc $application eq 'text' && $self->{charset}; |
|
172 |
$attributes{Charset} = $self->{charset} if $self->{charset}; |
|
156 | 173 |
|
157 |
return Email::MIME->create( |
|
158 |
attributes => \%attributes, |
|
159 |
body => $attachment_content, |
|
174 |
my $ent; |
|
175 |
if ( $attributes{Type} eq 'message/rfc822' ) { |
|
176 |
my $fh = IO::File->new($attributes{Path}, "r"); |
|
177 |
if (! defined $fh) { |
|
178 |
return undef; |
|
179 |
} |
|
180 |
$ent = $parser->parse($fh); |
|
181 |
undef $fh; |
|
182 |
my $head = $ent->head; |
|
183 |
$head->replace('Content-disposition','attachment; filename='.$attributes{Filename}); |
|
184 |
} else { |
|
185 |
$ent = MIME::Entity->build(%attributes); |
|
186 |
} |
|
187 |
push @{ $self->{mail_attachments}} , SL::DB::EmailJournalAttachment->new( |
|
188 |
name => $attributes{Filename}, |
|
189 |
mime_type => $attributes{Type}, |
|
190 |
content => ( $email_journal > 1 ? $attachment_content : ' '), |
|
191 |
file_id => $file_id, |
|
160 | 192 |
); |
193 |
return $ent; |
|
161 | 194 |
} |
162 | 195 |
|
163 | 196 |
sub _create_message { |
164 | 197 |
my ($self) = @_; |
165 | 198 |
|
166 |
my @parts;
|
|
167 |
|
|
199 |
push @{ $self->{headers} }, ('Type' =>"multipart/mixed" );
|
|
200 |
my $top = MIME::Entity->build(@{$self->{headers}}); |
|
168 | 201 |
if ($self->{message}) { |
169 |
push @parts, Email::MIME->create( |
|
170 |
attributes => { |
|
171 |
content_type => $self->{contenttype}, |
|
172 |
charset => $self->{charset}, |
|
173 |
encoding => 'quoted-printable', |
|
174 |
}, |
|
175 |
body_str => $self->{message}, |
|
176 |
); |
|
177 |
|
|
178 |
push @{ $self->{headers} }, ( |
|
179 |
'Content-Type' => qq|$self->{contenttype}; charset="$self->{charset}"|, |
|
180 |
); |
|
202 |
$top->attach(Data => encode($self->{charset},$self->{message}), |
|
203 |
Charset => $self->{charset}, |
|
204 |
Type => $self->{contenttype}, |
|
205 |
Encoding => 'quoted-printable'); |
|
181 | 206 |
} |
182 | 207 |
|
183 |
push @parts, grep { $_ } map { $self->_create_attachment_part($_) } @{ $self->{attachments} || [] }; |
|
184 |
|
|
185 |
return Email::MIME->create( |
|
186 |
header_str => $self->{headers}, |
|
187 |
parts => \@parts, |
|
188 |
); |
|
208 |
map { $top->add_part($self->_create_attachment_part($_)) } @{ $self->{attachments} || [] }; |
|
209 |
return $top; |
|
189 | 210 |
} |
190 | 211 |
|
191 | 212 |
sub send { |
... | ... | |
202 | 223 |
$self->{charset} = 'UTF-8'; |
203 | 224 |
$self->{contenttype} ||= "text/plain"; |
204 | 225 |
$self->{headers} = [ |
205 |
Subject => $self->{subject},
|
|
226 |
Subject => encode('MIME-Header',$self->{subject}),
|
|
206 | 227 |
'Message-ID' => '<' . $self->_create_message_id . '>', |
207 | 228 |
'X-Mailer' => "kivitendo $self->{version}", |
208 | 229 |
]; |
230 |
$self->{mail_attachments} = []; |
|
231 |
$self->{content_by_name} = $::instance_conf->get_email_journal == 1 && $::instance_conf->get_doc_files; |
|
209 | 232 |
|
210 | 233 |
my $error; |
211 | 234 |
my $ok = eval { |
... | ... | |
215 | 238 |
|
216 | 239 |
my $email = $self->_create_message; |
217 | 240 |
|
218 |
# $::lxdebug->message(0, "message: " . $email->as_string);
|
|
241 |
#$::lxdebug->message(0, "message: " . $email->as_string); |
|
219 | 242 |
# return "boom"; |
220 | 243 |
|
221 |
$self->{driver}->start_mail(from => $self->{from}, to => [ $self->_all_recipients ]);
|
|
244 |
$self->{driver}->start_mail(from => encode('MIME-Header',$self->{from}), to => [ $self->_all_recipients ]);
|
|
222 | 245 |
$self->{driver}->print($email->as_string); |
223 | 246 |
$self->{driver}->send; |
224 | 247 |
|
... | ... | |
227 | 250 |
|
228 | 251 |
$error = $@ if !$ok; |
229 | 252 |
|
230 |
$self->_store_in_journal; |
|
253 |
$self->{journalentry} = $self->_store_in_journal; |
|
254 |
$parser->filer->purge; |
|
231 | 255 |
|
232 | 256 |
return $ok ? '' : "send email: $error"; |
233 | 257 |
} |
234 | 258 |
|
235 | 259 |
sub _all_recipients { |
236 | 260 |
my ($self) = @_; |
237 |
|
|
238 | 261 |
$self->{addresses} ||= {}; |
239 | 262 |
return map { @{ $self->{addresses}->{$_} || [] } } qw(to cc bcc); |
240 | 263 |
} |
... | ... | |
251 | 274 |
$extended_status //= $self->{driver}->extended_status if $self->{driver}; |
252 | 275 |
$extended_status //= 'unknown error'; |
253 | 276 |
|
254 |
my @attachments; |
|
255 |
|
|
256 |
@attachments = grep { $_ } map { |
|
257 |
my $part = $self->_create_attachment_part($_); |
|
258 |
if ($part) { |
|
259 |
SL::DB::EmailJournalAttachment->new( |
|
260 |
name => $part->filename, |
|
261 |
mime_type => $part->content_type, |
|
262 |
content => $part->body, |
|
263 |
) |
|
264 |
} |
|
265 |
} @{ $self->{attachments} || [] } if $journal_enable > 1; |
|
266 |
|
|
267 | 277 |
my $headers = join "\r\n", (bundle_by { join(': ', @_) } 2, @{ $self->{headers} || [] }); |
268 | 278 |
|
269 |
SL::DB::EmailJournal->new( |
|
279 |
my $jentry = SL::DB::EmailJournal->new(
|
|
270 | 280 |
sender => SL::DB::Manager::Employee->current, |
271 | 281 |
from => $self->{from} // '', |
272 | 282 |
recipients => join(', ', $self->_all_recipients), |
... | ... | |
274 | 284 |
headers => $headers, |
275 | 285 |
body => $self->{message} // '', |
276 | 286 |
sent_on => DateTime->now_local, |
277 |
attachments => \@attachments,
|
|
287 |
attachments => \@{ $self->{mail_attachments} },
|
|
278 | 288 |
status => $status, |
279 | 289 |
extended_status => $extended_status, |
280 | 290 |
)->save; |
291 |
return $jentry->id; |
|
281 | 292 |
} |
282 | 293 |
|
283 | 294 |
1; |
bin/mozilla/io.pl | ||
---|---|---|
50 | 50 |
use SL::Locale::String qw(t8); |
51 | 51 |
use SL::IC; |
52 | 52 |
use SL::IO; |
53 |
use SL::File; |
|
53 | 54 |
use SL::PriceSource; |
54 | 55 |
|
55 | 56 |
use SL::DB::Customer; |
... | ... | |
58 | 59 |
use SL::DB::Printer; |
59 | 60 |
use SL::DB::Vendor; |
60 | 61 |
use SL::Helper::CreatePDF; |
61 |
use SL::Helper::Flash qw(flash);
|
|
62 |
use SL::Helper::Flash; |
|
62 | 63 |
|
63 | 64 |
require "bin/mozilla/common.pl"; |
64 | 65 |
|
... | ... | |
1066 | 1067 |
@dont_hide_key{@dont_hide_key_list} = (1) x @dont_hide_key_list; |
1067 | 1068 |
@hidden_keys = sort grep { !$dont_hide_key{$_} } grep { !ref $form->{$_} } keys %$form; |
1068 | 1069 |
|
1070 |
my (@files, @vc_files, @part_files, $has_document); |
|
1071 |
|
|
1072 |
if ($::instance_conf->get_doc_storage) { |
|
1073 |
@files = SL::File->get_all_versions(object_id => $form->{id}, object_type => $form->{type}, file_type => 'document'); |
|
1074 |
$has_document = 1 if scalar(@files) > 0; |
|
1075 |
@files = SL::File->get_all(object_id => $form->{id}, object_type => $form->{type}, file_type => 'attachment'); |
|
1076 |
@vc_files = SL::File->get_all(object_id => $form->{"$form->{vc}_id"}, object_type => $form->{vc}) |
|
1077 |
if $form->{vc} && $form->{"$form->{vc}_id"}; |
|
1078 |
|
|
1079 |
my %part_id_map = map { $_->{id} => $_ } grep { $_->{id} } map { |
|
1080 |
{ |
|
1081 |
'id' => $form->{"id_$_"}, |
|
1082 |
'partname' => $form->{"partnumber_$_"} |
|
1083 |
} |
|
1084 |
} (1 .. $form->{rowcount}); |
|
1085 |
|
|
1086 |
foreach my $partid (keys %part_id_map) { |
|
1087 |
my @pfiles = SL::File->get_all(object_id => $partid, object_type => 'part'); |
|
1088 |
push @part_files, map { $_->{partname} = $part_id_map{$partid}->{partname}; $_ } @pfiles; |
|
1089 |
} |
|
1090 |
} |
|
1091 |
|
|
1069 | 1092 |
print $form->parse_html_template('generic/edit_email', |
1070 | 1093 |
{ title => $title, |
1071 | 1094 |
a_filename => $attachment_filename, |
1072 | 1095 |
subject => $subject, |
1096 |
has_document => $has_document, |
|
1073 | 1097 |
print_options => print_options('inline' => 1), |
1074 | 1098 |
action => 'send_email', |
1099 |
FILES => \@files, |
|
1100 |
VC_FILES => \@vc_files, |
|
1101 |
PART_FILES => \@part_files, |
|
1075 | 1102 |
HIDDEN => [ map +{ name => $_, value => $form->{$_} }, @hidden_keys ], |
1076 | 1103 |
SHOW_BCC => $::auth->assert('email_bcc', 'may fail') }); |
1077 | 1104 |
|
... | ... | |
1088 | 1115 |
|
1089 | 1116 |
my $callback = $form->{script} . "?action=edit"; |
1090 | 1117 |
map({ $callback .= "\&${_}=" . E($form->{$_}); } qw(type id)); |
1118 |
if ( $form->{action_oldfile} || $form->{action_nofile} ) { |
|
1119 |
if (!$form->{email} || $form->{email} =~ /^\s*$/) { |
|
1120 |
flash('error', $::locale->text('E-mail address missing!')); |
|
1121 |
} |
|
1122 |
else { |
|
1123 |
$form->send_email(\%myconfig,'pdf'); |
|
1124 |
} |
|
1125 |
} |
|
1126 |
else { |
|
1127 |
print_form("return"); |
|
1128 |
$form->{addition} = "SCREENED"; |
|
1129 |
$form->save_history; |
|
1130 |
$form->{addition} = "MAILED"; |
|
1131 |
} |
|
1132 |
|
|
1133 |
flash_later('info' , $::locale->text('E-Mail is sent to #1', $form->{email})) if !$form->{emailerr}; |
|
1134 |
flash_later('error', $::locale->text($form->{emailerr})) if $form->{emailerr}; |
|
1091 | 1135 |
|
1092 |
print_form("return");
|
|
1136 |
delete $form->{emailerr};
|
|
1093 | 1137 |
|
1094 | 1138 |
Common->save_email_status(\%myconfig, $form); |
1139 |
##TODO andere SAVE HISTORY |
|
1095 | 1140 |
|
1096 | 1141 |
$form->{callback} = $callback; |
1097 | 1142 |
$form->redirect(); |
js/locale/de.js | ||
---|---|---|
57 | 57 |
"If you switch to a different tab without saving you will lose the data you've entered in the current tab.":"Wenn Sie auf einen anderen Tab wechseln, ohne vorher zu speichern, so gehen die im aktuellen Tab eingegebenen Daten verloren.", |
58 | 58 |
"Map":"Karte", |
59 | 59 |
"No":"Nein", |
60 |
"No articles have been added yet.":"Es wurden noch keine Artikel hinzugefügt.", |
|
61 | 60 |
"No delievery orders selected, please set one checkbox!":"Kein Lieferschein selektiert, bitte eine Box anklicken!", |
62 | 61 |
"No delivery orders have been selected.":"Es wurden keine Lieferscheine ausgewählt.", |
63 | 62 |
"No entries have been selected.":"Es wurden keine Einträge ausgewählt.", |
locale/de/all | ||
---|---|---|
767 | 767 |
'Customer' => 'Kunde', |
768 | 768 |
'Customer (database ID)' => 'Kunde (Datenbank-ID)', |
769 | 769 |
'Customer (name)' => 'Kunde (Name)', |
770 |
'Customer Attachments' => 'Anhänge des Kunden', |
|
770 | 771 |
'Customer Discount' => 'Kundenrabatt', |
771 | 772 |
'Customer Master Data' => 'Kundenstammdaten', |
772 | 773 |
'Customer Name' => 'Kundenname', |
... | ... | |
1042 | 1043 |
'Duplicate in CSV file' => 'Duplikat in CSV-Datei', |
1043 | 1044 |
'Duplicate in database' => 'Duplikat in Datenbank', |
1044 | 1045 |
'During the next update a taxkey 0 with tax rate of 0 will automatically created.' => 'Beim nächsten Ausführen des Updates wird ein Steuerschlüssel 0 mit einem Steuersatz von 0% automatisch erzeugt.', |
1046 |
'E-Mail is sent to #1' => 'E-Mail wurde an #1 gesendet', |
|
1045 | 1047 |
'E-mail' => 'E-Mail', |
1046 | 1048 |
'E-mail Statement to' => 'Fälligkeitsabrechnung als E-Mail an', |
1047 | 1049 |
'E-mail address missing!' => 'E-Mail-Adresse fehlt!', |
... | ... | |
1480 | 1482 |
'Illegal characters have been removed from the following fields: #1' => 'Ungültige Zeichen wurden aus den folgenden Feldern entfernt: #1', |
1481 | 1483 |
'Illegal date' => 'Ungültiges Datum', |
1482 | 1484 |
'Image' => 'Grafik', |
1485 |
'ImagePreview' => 'Bildvorschau', |
|
1486 |
'Images' => 'Bilder', |
|
1483 | 1487 |
'Import' => 'Import', |
1484 | 1488 |
'Import AP from Scanner or Email' => 'Einkaufsbelege importieren vom Scanner oder von Email', |
1485 | 1489 |
'Import AR from Scanner or Email' => 'Verkaufsbelege importieren vom Scanner oder von Email', |
... | ... | |
1707 | 1711 |
'Make (vendor\'s database ID, number or name; with X being a number)' => 'Lieferant (Datenbank-ID, Nummer oder Name des Lieferanten; X ist eine fortlaufende Zahl)', |
1708 | 1712 |
'Make compatible for import' => 'Für den Import kompatibel machen', |
1709 | 1713 |
'Make default profile' => 'Zu Standardprofil machen', |
1714 |
'Make new document' => 'Erzeuge ein neue Datei', |
|
1710 | 1715 |
'Makemodel Price' => 'Lieferantenpreis', |
1711 | 1716 |
'Manage Custom Variables' => 'Benutzerdefinierte Variablen', |
1712 | 1717 |
'Mandantennummer' => 'Mandantennummer', |
... | ... | |
1840 | 1845 |
'No delivery orders have been selected.' => 'Es wurden keine Lieferscheine ausgewählt.', |
1841 | 1846 |
'No delivery term has been created yet.' => 'Es wurden noch keine Lieferbedingungen angelegt', |
1842 | 1847 |
'No department has been created yet.' => 'Es wurde noch keine Abteilung erfasst.', |
1848 |
'No document' => 'Kein Datei mitschicken (ggf. Anhänge)', |
|
1843 | 1849 |
'No draft was found.' => 'Kein Entwurf gefunden.', |
1844 | 1850 |
'No dunnings have been selected for printing.' => 'Es wurden keine Mahnungen zum Drucken ausgewählt.', |
1845 | 1851 |
'No end date given, setting to today' => 'Kein Enddatum gegeben, setze Enddatum auf heute', |
... | ... | |
2037 | 2043 |
'Part "#1" has chargenumber or best before date set. So it cannot be transfered automatically.' => 'Bei Artikel "#1" ist eine Chargenummer oder ein Mindesthaltbarkeitsdatum vergeben. Deshalb kann dieser Artikel nicht automatisch ausgelagert werden.', |
2038 | 2044 |
'Part (database ID)' => 'Artikel (Datenbank-ID)', |
2039 | 2045 |
'Part (typeabbreviation)' => 'W', |
2046 |
'Part Attachments' => 'Anhänge der Artikel', |
|
2040 | 2047 |
'Part Classification' => 'Artikel-Klassifizierung', |
2041 | 2048 |
'Part Description' => 'Artikelbeschreibung', |
2042 | 2049 |
'Part Description missing!' => 'Artikelbezeichnung fehlt!', |
... | ... | |
3596 | 3603 |
'Zip, City' => 'PLZ, Ort', |
3597 | 3604 |
'Zipcode' => 'PLZ', |
3598 | 3605 |
'[email]' => '[email]', |
3606 |
'a_credit_note' => '', |
|
3607 |
'a_purchase_delivery_order' => '', |
|
3608 |
'a_purchase_invoice' => '', |
|
3609 |
'a_purchase_order' => '', |
|
3610 |
'a_request_quotation' => '', |
|
3611 |
'a_sales_delivery_order' => '', |
|
3612 |
'a_sales_order' => '', |
|
3613 |
'a_sales_quotation' => '', |
|
3599 | 3614 |
'absolute' => 'absolut', |
3600 | 3615 |
'account_description' => 'Beschreibung', |
3601 | 3616 |
'accrual' => 'Soll-Versteuerung', |
... | ... | |
3603 | 3618 |
'active' => 'aktiv', |
3604 | 3619 |
'all' => 'Alle', |
3605 | 3620 |
'all entries' => 'alle Einträge', |
3621 |
'an_invoice' => '', |
|
3606 | 3622 |
'and' => 'und', |
3607 | 3623 |
'ap_aging_list' => 'liste_offene_verbindlichkeiten', |
3608 | 3624 |
'ar_aging_list' => 'liste_offene_forderungen', |
... | ... | |
3718 | 3734 |
'list_of_payments' => 'zahlungsausgaenge', |
3719 | 3735 |
'list_of_receipts' => 'zahlungseingaenge', |
3720 | 3736 |
'list_of_transactions' => 'buchungsliste', |
3737 |
'mail_greeting #1' => '', |
|
3721 | 3738 |
'male' => 'männlich', |
3722 | 3739 |
'mark as paid' => 'als bezahlt markieren', |
3723 | 3740 |
'max filesize' => 'maximale Dateigröße', |
... | ... | |
3752 | 3769 |
'only OB Transactions' => 'nur EB-Buchungen', |
3753 | 3770 |
'open' => 'Offen', |
3754 | 3771 |
'order' => 'Reihenfolge', |
3772 |
'other Document Attachments' => 'Weitere Dateianhänge', |
|
3755 | 3773 |
'our vendor number at customer' => 'Unsere Lieferanten-Nr. beim Kunden', |
3756 | 3774 |
'parsing csv' => 'Parse CSV Daten', |
3757 | 3775 |
'part' => 'Ware', |
... | ... | |
3838 | 3856 |
'unconfigured' => 'unkonfiguriert', |
3839 | 3857 |
'unnamed record template' => 'unbenannte Belegvorlage', |
3840 | 3858 |
'until' => 'bis', |
3859 |
'uploaded' => 'Hochgeladen', |
|
3860 |
'use actual document' => 'Verwende aktuelle Datei', |
|
3841 | 3861 |
'use program settings' => 'benutze Programmeinstellungen', |
3842 | 3862 |
'use user config' => 'Verwende Benutzereinstellung', |
3843 | 3863 |
'used' => 'Verbraucht', |
sql/Pg-upgrade2/email_journal_attachments_add_fileid.sql | ||
---|---|---|
1 |
-- @tag: email_journal_attachments_add_fileid |
|
2 |
-- @description: attachments mit file_id |
|
3 |
-- @depends: email_journal filemanagement_feature files |
|
4 |
ALTER TABLE email_journal_attachments ADD COLUMN file_id integer default 0 NOT NULL; |
templates/webpages/generic/edit_email.html | ||
---|---|---|
6 | 6 |
|
7 | 7 |
<table width="100%"> |
8 | 8 |
<tr> |
9 |
<td> |
|
9 |
<td style="width: 500px">
|
|
10 | 10 |
<table> |
11 | 11 |
<tr> |
12 | 12 |
<th align="right" nowrap>[% 'To' | $T8 %]</th> |
... | ... | |
33 | 33 |
</tr> |
34 | 34 |
</table> |
35 | 35 |
</td> |
36 |
[%- IF INSTANCE_CONF.get_doc_storage %] |
|
37 |
<td align="left" rowspan="2"> |
|
38 |
<table> |
|
39 |
[%- USE ATT_it = Iterator(FILES) %] |
|
40 |
[% FOREACH file = ATT_it %] |
|
41 |
[% END %] |
|
42 |
[%- IF ATT_it.size > 0 %] |
|
43 |
<tr class="listheading"> |
|
44 |
<th colspan="3" align="left" nowrap>[% LxERP.t8('other Document Attachments') %]</th> |
|
45 |
<input type="hidden" name="attfile_count" id="m_attfile_count" value="[% ATT_it.size %]"> |
|
46 |
</tr> |
|
47 |
<tr class=""> |
|
48 |
<th align="left" nowrap></th> |
|
49 |
<th align="left" nowrap>[% LxERP.t8('Filename') %]</th> |
|
50 |
<th align="left" nowrap></th> |
|
51 |
</tr> |
|
52 |
<tr><td colspan="3"><hr size="1" style="height:1px;background-color:#000;" noshade></td></tr> |
|
53 |
[% FOREACH file = ATT_it %] |
|
54 |
<tr class="listrow"> |
|
55 |
<td></td><td>[% file.file_name %] |
|
56 |
<input type="hidden" name="attfile_[% ATT_it.count %]" value="[% file.id %]"> |
|
57 |
<td><input name="attsel_[% ATT_it.count %]" type="checkbox" class="checkbox" ></td> |
|
58 |
</tr> |
|
59 |
[% END %] |
|
60 |
[%- END %] |
|
61 |
[%- USE ATT_it = Iterator(VC_FILES) %] |
|
62 |
[% FOREACH file = ATT_it %] |
|
63 |
[% END %] |
|
64 |
[%- IF ATT_it.size > 0 %] |
|
65 |
<tr><td colspan="3"><hr size="1" noshade></td></tr> |
|
66 |
<tr class="listheading"> |
|
67 |
<th colspan="3" align="left" nowrap> |
|
68 |
<input type="hidden" name="attfile_cv_count" id="m_attfile_cv_count" value="[% ATT_it.size %]"> |
|
69 |
[% LxERP.t8('Customer Attachments') %] |
|
70 |
</th> |
|
71 |
</tr> |
|
72 |
<tr class=""> |
|
73 |
<th align="left" nowrap></th> |
|
74 |
<th align="left" nowrap>[% LxERP.t8('Filename') %]</th> |
|
75 |
<th align="left" nowrap></th> |
|
76 |
</tr> |
|
77 |
<tr><td colspan="3"><hr size="1" style="height:1px;background-color:#000;" noshade></td></tr> |
|
78 |
[% FOREACH file = ATT_it %] |
|
79 |
<tr class="listrow"> |
|
80 |
<td></td><td>[% file.file_name %] |
|
81 |
<input type="hidden" name="attfile_cv_[% ATT_it.count %]" value="[% file.id %]"> |
|
82 |
<td><input name="attsel_cv_[% ATT_it.count %]" type="checkbox" class="checkbox" ></td> |
|
83 |
</tr> |
|
84 |
[% END %] |
|
85 |
[%- END %] |
|
86 |
[%- USE ATT_it = Iterator(PART_FILES) %] |
|
87 |
[%- SET lastpartid = '' %] |
|
88 |
[%- FOREACH file = ATT_it %] |
|
89 |
[%- END %] |
|
90 |
[%- IF ATT_it.size > 0 %] |
|
91 |
<tr><td colspan="3"><hr size="1" noshade></td></tr> |
|
92 |
<tr class="listheading"> |
|
93 |
<th colspan="3" align="left" nowrap> |
|
94 |
<input type="hidden" name="attfile_part_count" id="m_attfile_part_count" value="[% ATT_it.size %]"> |
|
95 |
[% LxERP.t8('Part Attachments') %] |
|
96 |
</th> |
|
97 |
</tr> |
|
98 |
<tr class=""> |
|
99 |
<th align="left" nowrap>[% LxERP.t8('Part Number') %]</th> |
|
100 |
<th align="left" nowrap>[% LxERP.t8('Filename') %]</th> |
|
101 |
<th align="left" nowrap></th> |
|
102 |
</tr> |
|
103 |
[% FOREACH file = ATT_it %] |
|
104 |
[%- IF lastpartid != file.trans_id %] |
|
105 |
[%- SET lastpartid = file.trans_id %][%- SET partname = file.partname %] |
|
106 |
<tr><td colspan="3"><hr size="1" style="height:1px;background-color:#000;" noshade></td></tr> |
|
107 |
[%- ELSE %][%- SET partname = '' %][% END %] |
|
108 |
<tr class="listrow"> |
|
109 |
<td>[% partname %]</td> |
|
110 |
<td>[% file.file_name %] |
|
111 |
<input type="hidden" name="attfile_part_[% ATT_it.count %]" value="[% file.id %]"> |
|
112 |
<td><input name="attsel_part_[% ATT_it.count %]" type="checkbox" class="checkbox" ></td> |
|
113 |
</tr> |
|
114 |
[% END %] |
|
115 |
[%- END %] |
|
116 |
</table> |
|
117 |
</td> |
|
118 |
[%- ELSE %] |
|
119 |
<td rowspan="2"> |
|
120 |
</td> |
|
121 |
[%- END %] |
|
36 | 122 |
</tr> |
37 | 123 |
|
38 | 124 |
<tr> |
... | ... | |
49 | 135 |
</td> |
50 | 136 |
</tr> |
51 | 137 |
<tr> |
52 |
<td> |
|
138 |
<td colspan="2">
|
|
53 | 139 |
|
54 | 140 |
[% print_options %] |
55 | 141 |
[% FOREACH row = HIDDEN %]<input type="hidden" name="[% row.name %]" value="[% HTML.escape(row.value) %]"> |
... | ... | |
59 | 145 |
</tr> |
60 | 146 |
|
61 | 147 |
<tr> |
62 |
<td><hr size="3" noshade></td> |
|
148 |
<td colspan="2"><hr size="3" noshade></td>
|
|
63 | 149 |
</tr> |
64 | 150 |
</table> |
65 | 151 |
|
66 | 152 |
[% L.hidden_tag('action', action) %] |
67 | 153 |
|
68 | 154 |
<br> |
69 |
[% L.submit_tag('dummy_action', LxERP.t8('Continue'), onclick="return check_prerequisites();") %] |
|
155 |
[% L.submit_tag('action_newfile', LxERP.t8('Make new document'), onclick="return check_prerequisites();") %] |
|
156 |
[%- IF has_document %] |
|
157 |
[% L.submit_tag('action_oldfile', LxERP.t8('use actual document'), onclick="return check_prerequisites();") %] |
|
158 |
[%- END %] |
|
159 |
[% L.submit_tag('action_nofile', LxERP.t8('No document'), onclick="return check_prerequisites();") %] |
|
70 | 160 |
</form> |
71 | 161 |
|
72 | 162 |
<script type="text/javascript"> |
Auch abrufbar als: Unified diff
Dateimanagement: Alle Anhänge per E-Mail versendbar machen
Es können an eine E-Mail alle Anhänge eines Dokumentes,
sowie die Anhänge am Kunden/Liefranten sowie die Anhänge an Artikeln
mitgesendet werden.
Falls ein Dokument bereits existiert muss es nicht noch neu erzeugt werden.
Als MIME Types werden die bereits in der Datenbank abgespeicherten Typen verwendet.
Es werden in Perl nun MIME::Entity und MIME::Parser verwendet,
deshalb ist der installationcheck erweitet.