if (!$self->can_view_all && ($attachment->email_journal->sender_id != SL::DB::Manager::Employee->current->id)) {
$::form->error(t8('You do not have permission to access this entry.'));
}
-
- $self->send_file(\$attachment->content, name => $attachment->name, type => $attachment->mime_type);
+ my $ref = \$attachment->content;
+ if ( $attachment->file_id > 0 ) {
+ my $file = SL::File->get(id => $attachment->file_id );
+ $ref = SL::File->get_content(dbfile => $file) if $file;
+ }
+ $self->send_file($ref, name => $attachment->name, type => $attachment->mime_type);
}
#
__PACKAGE__->meta->columns(
content => { type => 'bytea', not_null => 1 },
email_journal_id => { type => 'integer', not_null => 1 },
+ file_id => { type => 'integer', default => '0', not_null => 1 },
id => { type => 'serial', not_null => 1 },
itime => { type => 'timestamp', default => 'now()', not_null => 1 },
mime_type => { type => 'text', not_null => 1 },
if ( !$self->{preview} && $ext_for_format eq 'pdf' && $::instance_conf->get_doc_storage) {
$self->{attachment_filename} ||= $self->generate_attachment_filename;
- $self->store_pdf($self);
+ $self->{print_file_id} = $self->store_pdf($self);
}
if ($self->{media} eq 'email') {
+ if ( getcwd() eq $self->{"tmpdir"} ) {
+ # in the case of generating pdf we are in the tmpdir, but WHY ???
+ $self->{tmpfile} = $userspath."/".$self->{tmpfile};
+ chdir("$self->{cwd}");
+ }
+ $self->send_email(\%::myconfig,$ext_for_format);
+ }
+ else {
+ $self->{OUT} = $out;
+ $self->{OUT_MODE} = $out_mode;
+ $self->output_file($template->get_mime_type,$command_formatter);
+ }
+ delete $self->{print_file_id};
- my $mail = Mailer->new;
-
- map { $mail->{$_} = $self->{$_} }
- qw(cc bcc subject message version format);
- $mail->{to} = $self->{EMAIL_RECIPIENT} ? $self->{EMAIL_RECIPIENT} : $self->{email};
- $mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
- $mail->{fileid} = time() . '.' . $$ . '.';
- my $full_signature = $self->create_email_signature();
- $full_signature =~ s/\r//g;
-
- # if we send html or plain text inline
- if (($self->{format} eq 'html') && ($self->{sendmode} eq 'inline')) {
- $mail->{contenttype} = "text/html";
- $mail->{message} =~ s/\r//g;
- $mail->{message} =~ s/\n/<br>\n/g;
- $full_signature =~ s/\n/<br>\n/g;
- $mail->{message} .= $full_signature;
-
- open(IN, "<:encoding(UTF-8)", $self->{tmpfile})
- or $self->error($self->cleanup . "$self->{tmpfile} : $!");
- $mail->{message} .= $_ while <IN>;
- close(IN);
+ $self->cleanup;
- } else {
+ chdir("$self->{cwd}");
+ $main::lxdebug->leave_sub();
+}
- if (!$self->{"do_not_attach"}) {
- my $attachment_name = $self->{attachment_filename} || $self->{tmpfile};
- $attachment_name =~ s/\.(.+?)$/.${ext_for_format}/ if ($ext_for_format);
- $mail->{attachments} = [{ "filename" => $self->{tmpfile},
- "name" => $attachment_name }];
- }
+sub get_bcc_defaults {
+ my ($self, $myconfig, $mybcc) = @_;
+# if (SL::DB::Default->get->bcc_to_login) {
+# $mybcc .= ", " if $mybcc;
+# $mybcc .= $myconfig->{email};
+# }
+ my $otherbcc = SL::DB::Default->get->global_bcc;
+ if ($otherbcc) {
+ $mybcc .= ", " if $mybcc;
+ $mybcc .= $otherbcc;
+ }
+ return $mybcc;
+}
- $mail->{message} .= $full_signature;
- }
+sub send_email {
+ $main::lxdebug->enter_sub();
+ my ($self, $myconfig, $ext_for_format) = @_;
+ my $mail = Mailer->new;
- my $err = $mail->send();
- $self->error($self->cleanup . "$err") if ($err);
+ map { $mail->{$_} = $self->{$_} }
+ qw(cc subject message version format);
- } else {
+ $mail->{bcc} = $self->get_bcc_defaults($myconfig, $self->{bcc});
+ $mail->{to} = $self->{EMAIL_RECIPIENT} ? $self->{EMAIL_RECIPIENT} : $self->{email};
+ $mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
+ $mail->{fileid} = time() . '.' . $$ . '.';
+ my $full_signature = $self->create_email_signature();
+ $full_signature =~ s/\r//g;
- $self->{OUT} = $out;
- $self->{OUT_MODE} = $out_mode;
+ $mail->{attachments} = [];
+ my @attfiles;
+ # if we send html or plain text inline
+ if (($self->{format} eq 'html') && ($self->{sendmode} eq 'inline')) {
+ $mail->{contenttype} = "text/html";
+ $mail->{message} =~ s/\r//g;
+ $mail->{message} =~ s/\n/<br>\n/g;
+ $full_signature =~ s/\n/<br>\n/g;
+ $mail->{message} .= $full_signature;
- my $numbytes = (-s $self->{tmpfile});
open(IN, "<", $self->{tmpfile})
or $self->error($self->cleanup . "$self->{tmpfile} : $!");
- binmode IN;
+ $mail->{message} .= $_ while <IN>;
+ close(IN);
- $self->{copies} = 1 unless $self->{media} eq 'printer';
+ } else {
+ $main::lxdebug->message(LXDebug->DEBUG2(),"action_oldfile=" . $self->{action_oldfile}." action_nofile=".$self->{action_nofile});
+ if (!$self->{"do_not_attach"} && !$self->{action_nofile}) {
+ my $attachment_name = $self->{attachment_filename} || $self->{tmpfile};
+ $attachment_name =~ s/\.(.+?)$/.${ext_for_format}/ if ($ext_for_format);
+ if ( $self->{action_oldfile} ) {
+ $main::lxdebug->message(LXDebug->DEBUG2(),"object_id =>". $self->{id}." object_type =>". $self->{formname});
+ my ( $attfile ) = SL::File->get_all(object_id => $self->{id},
+ object_type => $self->{formname},
+ file_type => 'document');
+ $main::lxdebug->message(LXDebug->DEBUG2(), "old file obj=".$attfile);
+ push @attfiles, $attfile if $attfile;
+ } else {
+ push @{ $mail->{attachments} }, { path => $self->{tmpfile},
+ id => $self->{print_file_id},
+ type => "application/pdf",
+ name => $attachment_name };
+ }
+ }
+ }
+ if (!$self->{"do_not_attach"}) {
+ for my $i (1 .. $self->{attfile_count}) {
+ if ( $self->{"attsel_$i"} ) {
+ my $attfile = SL::File->get(id => $self->{"attfile_$i"});
+ $main::lxdebug->message(LXDebug->DEBUG2(), "att file=".$self->{"attfile_$i"}." obj=".$attfile);
+ push @attfiles, $attfile if $attfile;
+ }
+ }
+ for my $i (1 .. $self->{attfile_cv_count}) {
+ if ( $self->{"attsel_cv_$i"} ) {
+ my $attfile = SL::File->get(id => $self->{"attfile_cv_$i"});
+ $main::lxdebug->message(LXDebug->DEBUG2(), "att file=".$self->{"attfile_$i"}." obj=".$attfile);
+ push @attfiles, $attfile if $attfile;
+ }
+ }
+ for my $i (1 .. $self->{attfile_part_count}) {
+ if ( $self->{"attsel_part_$i"} ) {
+ my $attfile = SL::File->get(id => $self->{"attfile_part_$i"});
+ $main::lxdebug->message(LXDebug->DEBUG2(), "att file=".$self->{"attfile_$i"}." obj=".$attfile);
+ push @attfiles, $attfile if $attfile;
+ }
+ }
+ foreach my $attfile ( @attfiles ) {
+ push @{ $mail->{attachments} }, { path => SL::File->get_file_path(dbfile => $attfile),
+ id => $attfile->id,
+ type => $attfile->file_mime_type,
+ name => $attfile->file_name };
+ }
+ }
+ $mail->{message} =~ s/\r//g;
+ $mail->{message} .= $full_signature;
+ $self->{emailerr} = $mail->send();
+ # $self->error($self->cleanup . "$err") if $self->{emailerr};
+ $self->{email_journal_id} = $mail->{journalentry};
- chdir("$self->{cwd}");
- #print(STDERR "Kopien $self->{copies}\n");
- #print(STDERR "OUT $self->{OUT}\n");
- for my $i (1 .. $self->{copies}) {
- if ($self->{OUT}) {
- $self->{OUT} = $command_formatter->($self->{OUT_MODE}, $self->{OUT});
+ #write back for message info and mail journal
+ $self->{cc} = $mail->{cc};
+ $self->{bcc} = $mail->{bcc};
+ $self->{email} = $mail->{to};
- open OUT, $self->{OUT_MODE}, $self->{OUT} or $self->error($self->cleanup . "$self->{OUT} : $!");
- print OUT $_ while <IN>;
- close OUT;
- seek IN, 0, 0;
+ $main::lxdebug->leave_sub();
+}
- } else {
- my %headers = ('-type' => $template->get_mime_type,
- '-connection' => 'close',
- '-charset' => 'UTF-8');
-
- $self->{attachment_filename} ||= $self->generate_attachment_filename;
-
- if ($self->{attachment_filename}) {
- %headers = (
- %headers,
- '-attachment' => $self->{attachment_filename},
- '-content-length' => $numbytes,
- '-charset' => '',
- );
- }
+sub output_file {
+ $main::lxdebug->enter_sub();
- print $::request->cgi->header(%headers);
+ my ($self,$mimeType,$command_formatter) = @_;
+ my $numbytes = (-s $self->{tmpfile});
+ open(IN, "<", $self->{tmpfile})
+ or $self->error($self->cleanup . "$self->{tmpfile} : $!");
+ binmode IN;
- $::locale->with_raw_io(\*STDOUT, sub { print while <IN> });
- }
- }
+ $self->{copies} = 1 unless $self->{media} eq 'printer';
- close(IN);
- }
+ chdir("$self->{cwd}");
+ for my $i (1 .. $self->{copies}) {
+ if ($self->{OUT}) {
+ $self->{OUT} = $command_formatter->($self->{OUT_MODE}, $self->{OUT});
- $self->cleanup;
+ open OUT, $self->{OUT_MODE}, $self->{OUT} or $self->error($self->cleanup . "$self->{OUT} : $!");
+ print OUT $_ while <IN>;
+ close OUT;
+ seek IN, 0, 0;
- chdir("$self->{cwd}");
+ } else {
+ my %headers = ('-type' => $mimeType,
+ '-connection' => 'close',
+ '-charset' => 'UTF-8');
+
+ $self->{attachment_filename} ||= $self->generate_attachment_filename;
+
+ if ($self->{attachment_filename}) {
+ %headers = (
+ %headers,
+ '-attachment' => $self->{attachment_filename},
+ '-content-length' => $numbytes,
+ '-charset' => '',
+ );
+ }
+
+ print $::request->cgi->header(%headers);
+
+ $::locale->with_raw_io(\*STDOUT, sub { print while <IN> });
+ }
+ }
+ close(IN);
$main::lxdebug->leave_sub();
}
{ name => "Digest::SHA", url => "http://search.cpan.org/~mshelor/", debian => 'libdigest-sha-perl' },
{ name => "Email::Address", url => "http://search.cpan.org/~rjbs/", debian => 'libemail-address-perl' },
{ name => "Email::MIME", url => "http://search.cpan.org/~rjbs/", debian => 'libemail-mime-perl' },
+ { name => "MIME::Entity", url => "http://search.cpan.org/~dskoll/", debian => '' },
+ { name => "MIME::Parser", url => "http://search.cpan.org/~dskoll/", debian => '' },
{ name => "FCGI", version => '0.72', url => "http://search.cpan.org/~mstrout/", debian => 'libfcgi-perl' },
{ name => "File::Copy::Recursive", url => "http://search.cpan.org/~dmuey/", debian => 'libfile-copy-recursive-perl' },
{ name => "GD", url => "http://search.cpan.org/~lds/", debian => 'libgd-gd2-perl', },
package Mailer;
use Email::Address;
-use Email::MIME::Creator;
+use MIME::Entity;
+use MIME::Parser;
+use File::MimeInfo::Magic;
use File::Slurp;
use List::UtilsBy qw(bundle_by);
use SL::DB::EmailJournal;
use SL::DB::EmailJournalAttachment;
use SL::DB::Employee;
-use SL::MIME;
use SL::Template;
use strict;
+use Encode;
my $num_sent = 0;
+my $parser;
my %mail_delivery_modules = (
sendmail => 'SL::Mailer::Sendmail',
sub new {
my ($type, %params) = @_;
my $self = { %params };
+ $parser = new MIME::Parser;
+ $parser->output_under("users");
bless $self, $type;
}
$addr_obj->phrase($phrase);
}
- push @header_addresses, $addr_obj->format;
+ push @header_addresses, encode('MIME-Header',$addr_obj->format);
}
push @{ $self->{headers} }, ( ucfirst($item) => join(', ', @header_addresses) ) if @header_addresses;
my ($self, $attachment) = @_;
my %attributes = (
- disposition => 'attachment',
- encoding => 'base64',
+ Disposition => 'attachment',
+ Encoding => 'base64',
);
+ my $file_id = 0;
my $attachment_content;
+ my $email_journal = $::instance_conf->get_email_journal;
+ $main::lxdebug->message(LXDebug->DEBUG2(), "mail5 att=".$attachment." email_journal=". $email_journal." id=".$attachment->{id});
if (ref($attachment) eq "HASH") {
- $attributes{filename} = $attachment->{name};
- $attachment_content = $attachment->{content} // eval { read_file($attachment->{filename}) };
+ $attributes{Path} = $attachment->{path} || $attachment->{filename};
+ $attributes{Filename} = $attachment->{name};
+ $file_id = $attachment->{id} || '0';
+ $attributes{Type} = $attachment->{type} || 'application/pdf';
+ $attachment_content = eval { read_file($attachment->{path}) } if $email_journal > 1;
} else {
# strip path
- $attributes{filename} = $attachment;
- $attributes{filename} =~ s:.*\Q$self->{fileid}\E:: if $self->{fileid};
- $attributes{filename} =~ s:.*/::g;
- $attachment_content = eval { read_file($attachment) };
+ $attributes{Path} = $attachment;
+ $attributes{Filename} = $attachment;
+ $attributes{Filename} =~ s:.*\Q$self->{fileid}\E:: if $self->{fileid};
+ $attributes{Filename} =~ s:.*/::g;
+
+ my $application = ($attachment =~ /(^\w+$)|\.(html|text|txt|sql)$/) ? 'text' : 'application';
+ $attributes{Type} = File::MimeInfo::Magic::magic($attachment);
+ $attributes{Type} ||= "${application}/$self->{format}" if $self->{format};
+ $attributes{Type} ||= 'application/octet-stream';
+ $attachment_content = eval { read_file($attachment) } if $email_journal > 1;
}
- return undef if !defined $attachment_content;
+ return undef if $email_journal > 1 && !defined $attachment_content;
+ $attachment_content ||= ' ';
+ $main::lxdebug->message(LXDebug->DEBUG2(), "mail6 mtype=".$attributes{Type}." path=".
+ $attributes{Path}." filename=".$attributes{Filename});
- my $application = ($attachment =~ /(^\w+$)|\.(html|text|txt|sql)$/) ? 'text' : 'application';
- $attributes{content_type} = SL::MIME->mime_type_from_ext($attributes{filename});
- $attributes{content_type} ||= "${application}/$self->{format}" if $self->{format};
- $attributes{content_type} ||= 'application/octet-stream';
- $attributes{charset} = $self->{charset} if lc $application eq 'text' && $self->{charset};
+# $attributes{Charset} = $self->{charset} if lc $application eq 'text' && $self->{charset};
+ $attributes{Charset} = $self->{charset} if $self->{charset};
- return Email::MIME->create(
- attributes => \%attributes,
- body => $attachment_content,
+ my $ent;
+ if ( $attributes{Type} eq 'message/rfc822' ) {
+ my $fh = IO::File->new($attributes{Path}, "r");
+ if (! defined $fh) {
+ return undef;
+ }
+ $ent = $parser->parse($fh);
+ undef $fh;
+ my $head = $ent->head;
+ $head->replace('Content-disposition','attachment; filename='.$attributes{Filename});
+ } else {
+ $ent = MIME::Entity->build(%attributes);
+ }
+ push @{ $self->{mail_attachments}} , SL::DB::EmailJournalAttachment->new(
+ name => $attributes{Filename},
+ mime_type => $attributes{Type},
+ content => ( $email_journal > 1 ? $attachment_content : ' '),
+ file_id => $file_id,
);
+ return $ent;
}
sub _create_message {
my ($self) = @_;
- my @parts;
-
+ push @{ $self->{headers} }, ('Type' =>"multipart/mixed" );
+ my $top = MIME::Entity->build(@{$self->{headers}});
if ($self->{message}) {
- push @parts, Email::MIME->create(
- attributes => {
- content_type => $self->{contenttype},
- charset => $self->{charset},
- encoding => 'quoted-printable',
- },
- body_str => $self->{message},
- );
-
- push @{ $self->{headers} }, (
- 'Content-Type' => qq|$self->{contenttype}; charset="$self->{charset}"|,
- );
+ $top->attach(Data => encode($self->{charset},$self->{message}),
+ Charset => $self->{charset},
+ Type => $self->{contenttype},
+ Encoding => 'quoted-printable');
}
- push @parts, grep { $_ } map { $self->_create_attachment_part($_) } @{ $self->{attachments} || [] };
-
- return Email::MIME->create(
- header_str => $self->{headers},
- parts => \@parts,
- );
+ map { $top->add_part($self->_create_attachment_part($_)) } @{ $self->{attachments} || [] };
+ return $top;
}
sub send {
$self->{charset} = 'UTF-8';
$self->{contenttype} ||= "text/plain";
$self->{headers} = [
- Subject => $self->{subject},
+ Subject => encode('MIME-Header',$self->{subject}),
'Message-ID' => '<' . $self->_create_message_id . '>',
'X-Mailer' => "kivitendo $self->{version}",
];
+ $self->{mail_attachments} = [];
+ $self->{content_by_name} = $::instance_conf->get_email_journal == 1 && $::instance_conf->get_doc_files;
my $error;
my $ok = eval {
my $email = $self->_create_message;
- # $::lxdebug->message(0, "message: " . $email->as_string);
+ #$::lxdebug->message(0, "message: " . $email->as_string);
# return "boom";
- $self->{driver}->start_mail(from => $self->{from}, to => [ $self->_all_recipients ]);
+ $self->{driver}->start_mail(from => encode('MIME-Header',$self->{from}), to => [ $self->_all_recipients ]);
$self->{driver}->print($email->as_string);
$self->{driver}->send;
$error = $@ if !$ok;
- $self->_store_in_journal;
+ $self->{journalentry} = $self->_store_in_journal;
+ $parser->filer->purge;
return $ok ? '' : "send email: $error";
}
sub _all_recipients {
my ($self) = @_;
-
$self->{addresses} ||= {};
return map { @{ $self->{addresses}->{$_} || [] } } qw(to cc bcc);
}
$extended_status //= $self->{driver}->extended_status if $self->{driver};
$extended_status //= 'unknown error';
- my @attachments;
-
- @attachments = grep { $_ } map {
- my $part = $self->_create_attachment_part($_);
- if ($part) {
- SL::DB::EmailJournalAttachment->new(
- name => $part->filename,
- mime_type => $part->content_type,
- content => $part->body,
- )
- }
- } @{ $self->{attachments} || [] } if $journal_enable > 1;
-
my $headers = join "\r\n", (bundle_by { join(': ', @_) } 2, @{ $self->{headers} || [] });
- SL::DB::EmailJournal->new(
+ my $jentry = SL::DB::EmailJournal->new(
sender => SL::DB::Manager::Employee->current,
from => $self->{from} // '',
recipients => join(', ', $self->_all_recipients),
headers => $headers,
body => $self->{message} // '',
sent_on => DateTime->now_local,
- attachments => \@attachments,
+ attachments => \@{ $self->{mail_attachments} },
status => $status,
extended_status => $extended_status,
)->save;
+ return $jentry->id;
}
1;
use SL::Locale::String qw(t8);
use SL::IC;
use SL::IO;
+use SL::File;
use SL::PriceSource;
use SL::DB::Customer;
use SL::DB::Printer;
use SL::DB::Vendor;
use SL::Helper::CreatePDF;
-use SL::Helper::Flash qw(flash);
+use SL::Helper::Flash;
require "bin/mozilla/common.pl";
@dont_hide_key{@dont_hide_key_list} = (1) x @dont_hide_key_list;
@hidden_keys = sort grep { !$dont_hide_key{$_} } grep { !ref $form->{$_} } keys %$form;
+ my (@files, @vc_files, @part_files, $has_document);
+
+ if ($::instance_conf->get_doc_storage) {
+ @files = SL::File->get_all_versions(object_id => $form->{id}, object_type => $form->{type}, file_type => 'document');
+ $has_document = 1 if scalar(@files) > 0;
+ @files = SL::File->get_all(object_id => $form->{id}, object_type => $form->{type}, file_type => 'attachment');
+ @vc_files = SL::File->get_all(object_id => $form->{"$form->{vc}_id"}, object_type => $form->{vc})
+ if $form->{vc} && $form->{"$form->{vc}_id"};
+
+ my %part_id_map = map { $_->{id} => $_ } grep { $_->{id} } map {
+ {
+ 'id' => $form->{"id_$_"},
+ 'partname' => $form->{"partnumber_$_"}
+ }
+ } (1 .. $form->{rowcount});
+
+ foreach my $partid (keys %part_id_map) {
+ my @pfiles = SL::File->get_all(object_id => $partid, object_type => 'part');
+ push @part_files, map { $_->{partname} = $part_id_map{$partid}->{partname}; $_ } @pfiles;
+ }
+ }
+
print $form->parse_html_template('generic/edit_email',
{ title => $title,
a_filename => $attachment_filename,
subject => $subject,
+ has_document => $has_document,
print_options => print_options('inline' => 1),
action => 'send_email',
+ FILES => \@files,
+ VC_FILES => \@vc_files,
+ PART_FILES => \@part_files,
HIDDEN => [ map +{ name => $_, value => $form->{$_} }, @hidden_keys ],
SHOW_BCC => $::auth->assert('email_bcc', 'may fail') });
my $callback = $form->{script} . "?action=edit";
map({ $callback .= "\&${_}=" . E($form->{$_}); } qw(type id));
+ if ( $form->{action_oldfile} || $form->{action_nofile} ) {
+ if (!$form->{email} || $form->{email} =~ /^\s*$/) {
+ flash('error', $::locale->text('E-mail address missing!'));
+ }
+ else {
+ $form->send_email(\%myconfig,'pdf');
+ }
+ }
+ else {
+ print_form("return");
+ $form->{addition} = "SCREENED";
+ $form->save_history;
+ $form->{addition} = "MAILED";
+ }
+
+ flash_later('info' , $::locale->text('E-Mail is sent to #1', $form->{email})) if !$form->{emailerr};
+ flash_later('error', $::locale->text($form->{emailerr})) if $form->{emailerr};
- print_form("return");
+ delete $form->{emailerr};
Common->save_email_status(\%myconfig, $form);
+ ##TODO andere SAVE HISTORY
$form->{callback} = $callback;
$form->redirect();
"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.",
"Map":"Karte",
"No":"Nein",
-"No articles have been added yet.":"Es wurden noch keine Artikel hinzugefügt.",
"No delievery orders selected, please set one checkbox!":"Kein Lieferschein selektiert, bitte eine Box anklicken!",
"No delivery orders have been selected.":"Es wurden keine Lieferscheine ausgewählt.",
"No entries have been selected.":"Es wurden keine Einträge ausgewählt.",
'Customer' => 'Kunde',
'Customer (database ID)' => 'Kunde (Datenbank-ID)',
'Customer (name)' => 'Kunde (Name)',
+ 'Customer Attachments' => 'Anhänge des Kunden',
'Customer Discount' => 'Kundenrabatt',
'Customer Master Data' => 'Kundenstammdaten',
'Customer Name' => 'Kundenname',
'Duplicate in CSV file' => 'Duplikat in CSV-Datei',
'Duplicate in database' => 'Duplikat in Datenbank',
'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.',
+ 'E-Mail is sent to #1' => 'E-Mail wurde an #1 gesendet',
'E-mail' => 'E-Mail',
'E-mail Statement to' => 'Fälligkeitsabrechnung als E-Mail an',
'E-mail address missing!' => 'E-Mail-Adresse fehlt!',
'Illegal characters have been removed from the following fields: #1' => 'Ungültige Zeichen wurden aus den folgenden Feldern entfernt: #1',
'Illegal date' => 'Ungültiges Datum',
'Image' => 'Grafik',
+ 'ImagePreview' => 'Bildvorschau',
+ 'Images' => 'Bilder',
'Import' => 'Import',
'Import AP from Scanner or Email' => 'Einkaufsbelege importieren vom Scanner oder von Email',
'Import AR from Scanner or Email' => 'Verkaufsbelege importieren vom Scanner oder von Email',
'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)',
'Make compatible for import' => 'Für den Import kompatibel machen',
'Make default profile' => 'Zu Standardprofil machen',
+ 'Make new document' => 'Erzeuge ein neue Datei',
'Makemodel Price' => 'Lieferantenpreis',
'Manage Custom Variables' => 'Benutzerdefinierte Variablen',
'Mandantennummer' => 'Mandantennummer',
'No delivery orders have been selected.' => 'Es wurden keine Lieferscheine ausgewählt.',
'No delivery term has been created yet.' => 'Es wurden noch keine Lieferbedingungen angelegt',
'No department has been created yet.' => 'Es wurde noch keine Abteilung erfasst.',
+ 'No document' => 'Kein Datei mitschicken (ggf. Anhänge)',
'No draft was found.' => 'Kein Entwurf gefunden.',
'No dunnings have been selected for printing.' => 'Es wurden keine Mahnungen zum Drucken ausgewählt.',
'No end date given, setting to today' => 'Kein Enddatum gegeben, setze Enddatum auf heute',
'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.',
'Part (database ID)' => 'Artikel (Datenbank-ID)',
'Part (typeabbreviation)' => 'W',
+ 'Part Attachments' => 'Anhänge der Artikel',
'Part Classification' => 'Artikel-Klassifizierung',
'Part Description' => 'Artikelbeschreibung',
'Part Description missing!' => 'Artikelbezeichnung fehlt!',
'Zip, City' => 'PLZ, Ort',
'Zipcode' => 'PLZ',
'[email]' => '[email]',
+ 'a_credit_note' => '',
+ 'a_purchase_delivery_order' => '',
+ 'a_purchase_invoice' => '',
+ 'a_purchase_order' => '',
+ 'a_request_quotation' => '',
+ 'a_sales_delivery_order' => '',
+ 'a_sales_order' => '',
+ 'a_sales_quotation' => '',
'absolute' => 'absolut',
'account_description' => 'Beschreibung',
'accrual' => 'Soll-Versteuerung',
'active' => 'aktiv',
'all' => 'Alle',
'all entries' => 'alle Einträge',
+ 'an_invoice' => '',
'and' => 'und',
'ap_aging_list' => 'liste_offene_verbindlichkeiten',
'ar_aging_list' => 'liste_offene_forderungen',
'list_of_payments' => 'zahlungsausgaenge',
'list_of_receipts' => 'zahlungseingaenge',
'list_of_transactions' => 'buchungsliste',
+ 'mail_greeting #1' => '',
'male' => 'männlich',
'mark as paid' => 'als bezahlt markieren',
'max filesize' => 'maximale Dateigröße',
'only OB Transactions' => 'nur EB-Buchungen',
'open' => 'Offen',
'order' => 'Reihenfolge',
+ 'other Document Attachments' => 'Weitere Dateianhänge',
'our vendor number at customer' => 'Unsere Lieferanten-Nr. beim Kunden',
'parsing csv' => 'Parse CSV Daten',
'part' => 'Ware',
'unconfigured' => 'unkonfiguriert',
'unnamed record template' => 'unbenannte Belegvorlage',
'until' => 'bis',
+ 'uploaded' => 'Hochgeladen',
+ 'use actual document' => 'Verwende aktuelle Datei',
'use program settings' => 'benutze Programmeinstellungen',
'use user config' => 'Verwende Benutzereinstellung',
'used' => 'Verbraucht',
--- /dev/null
+-- @tag: email_journal_attachments_add_fileid
+-- @description: attachments mit file_id
+-- @depends: email_journal filemanagement_feature files
+ALTER TABLE email_journal_attachments ADD COLUMN file_id integer default 0 NOT NULL;
<table width="100%">
<tr>
- <td>
+ <td style="width: 500px">
<table>
<tr>
<th align="right" nowrap>[% 'To' | $T8 %]</th>
</tr>
</table>
</td>
+[%- IF INSTANCE_CONF.get_doc_storage %]
+ <td align="left" rowspan="2">
+ <table>
+[%- USE ATT_it = Iterator(FILES) %]
+[% FOREACH file = ATT_it %]
+[% END %]
+[%- IF ATT_it.size > 0 %]
+ <tr class="listheading">
+ <th colspan="3" align="left" nowrap>[% LxERP.t8('other Document Attachments') %]</th>
+ <input type="hidden" name="attfile_count" id="m_attfile_count" value="[% ATT_it.size %]">
+ </tr>
+ <tr class="">
+ <th align="left" nowrap></th>
+ <th align="left" nowrap>[% LxERP.t8('Filename') %]</th>
+ <th align="left" nowrap></th>
+ </tr>
+ <tr><td colspan="3"><hr size="1" style="height:1px;background-color:#000;" noshade></td></tr>
+ [% FOREACH file = ATT_it %]
+ <tr class="listrow">
+ <td></td><td>[% file.file_name %]
+ <input type="hidden" name="attfile_[% ATT_it.count %]" value="[% file.id %]">
+ <td><input name="attsel_[% ATT_it.count %]" type="checkbox" class="checkbox" ></td>
+ </tr>
+ [% END %]
+[%- END %]
+[%- USE ATT_it = Iterator(VC_FILES) %]
+[% FOREACH file = ATT_it %]
+[% END %]
+[%- IF ATT_it.size > 0 %]
+ <tr><td colspan="3"><hr size="1" noshade></td></tr>
+ <tr class="listheading">
+ <th colspan="3" align="left" nowrap>
+ <input type="hidden" name="attfile_cv_count" id="m_attfile_cv_count" value="[% ATT_it.size %]">
+ [% LxERP.t8('Customer Attachments') %]
+ </th>
+ </tr>
+ <tr class="">
+ <th align="left" nowrap></th>
+ <th align="left" nowrap>[% LxERP.t8('Filename') %]</th>
+ <th align="left" nowrap></th>
+ </tr>
+ <tr><td colspan="3"><hr size="1" style="height:1px;background-color:#000;" noshade></td></tr>
+ [% FOREACH file = ATT_it %]
+ <tr class="listrow">
+ <td></td><td>[% file.file_name %]
+ <input type="hidden" name="attfile_cv_[% ATT_it.count %]" value="[% file.id %]">
+ <td><input name="attsel_cv_[% ATT_it.count %]" type="checkbox" class="checkbox" ></td>
+ </tr>
+ [% END %]
+[%- END %]
+[%- USE ATT_it = Iterator(PART_FILES) %]
+[%- SET lastpartid = '' %]
+[%- FOREACH file = ATT_it %]
+[%- END %]
+[%- IF ATT_it.size > 0 %]
+ <tr><td colspan="3"><hr size="1" noshade></td></tr>
+ <tr class="listheading">
+ <th colspan="3" align="left" nowrap>
+ <input type="hidden" name="attfile_part_count" id="m_attfile_part_count" value="[% ATT_it.size %]">
+ [% LxERP.t8('Part Attachments') %]
+ </th>
+ </tr>
+ <tr class="">
+ <th align="left" nowrap>[% LxERP.t8('Part Number') %]</th>
+ <th align="left" nowrap>[% LxERP.t8('Filename') %]</th>
+ <th align="left" nowrap></th>
+ </tr>
+ [% FOREACH file = ATT_it %]
+ [%- IF lastpartid != file.trans_id %]
+ [%- SET lastpartid = file.trans_id %][%- SET partname = file.partname %]
+ <tr><td colspan="3"><hr size="1" style="height:1px;background-color:#000;" noshade></td></tr>
+ [%- ELSE %][%- SET partname = '' %][% END %]
+ <tr class="listrow">
+ <td>[% partname %]</td>
+ <td>[% file.file_name %]
+ <input type="hidden" name="attfile_part_[% ATT_it.count %]" value="[% file.id %]">
+ <td><input name="attsel_part_[% ATT_it.count %]" type="checkbox" class="checkbox" ></td>
+ </tr>
+ [% END %]
+[%- END %]
+ </table>
+ </td>
+[%- ELSE %]
+ <td rowspan="2">
+ </td>
+[%- END %]
</tr>
<tr>
</td>
</tr>
<tr>
- <td>
+ <td colspan="2">
[% print_options %]
[% FOREACH row = HIDDEN %]<input type="hidden" name="[% row.name %]" value="[% HTML.escape(row.value) %]">
</tr>
<tr>
- <td><hr size="3" noshade></td>
+ <td colspan="2"><hr size="3" noshade></td>
</tr>
</table>
[% L.hidden_tag('action', action) %]
<br>
-[% L.submit_tag('dummy_action', LxERP.t8('Continue'), onclick="return check_prerequisites();") %]
+[% L.submit_tag('action_newfile', LxERP.t8('Make new document'), onclick="return check_prerequisites();") %]
+[%- IF has_document %]
+[% L.submit_tag('action_oldfile', LxERP.t8('use actual document'), onclick="return check_prerequisites();") %]
+[%- END %]
+[% L.submit_tag('action_nofile', LxERP.t8('No document'), onclick="return check_prerequisites();") %]
</form>
<script type="text/javascript">