return 0;
}
+# Problemfall: Verkaufsrechnungen, bei denen Steuern verbucht wurden, obwohl
+# kein Steuerschlüssel eingetragen ist.
+sub _check_missing_taxkeys_in_invoices {
+ $::lxdebug->enter_sub;
+
+ my $self = shift;
+ my %params = @_;
+ my $transaction = $params{transaction};
+ my $found_broken = 0;
+
+ $::lxdebug->leave_sub and return 0
+ if !$transaction->[0]->{invoice};
+
+ my @sub_transactions = $self->_group_sub_transactions($transaction);
+
+ for my $sub_transaction (@sub_transactions) {
+ $::lxdebug->leave_sub and return 0
+ if _is_split_transaction($sub_transaction)
+ || _is_simple_transaction($sub_transaction);
+
+ my $split_side_entries = _get_splitted_side($sub_transaction);
+ my $num_tax_rows;
+ my $num_taxed_rows;
+ for my $entry (@{ $split_side_entries }) {
+ my $is_tax = grep { m/(?:AP_tax|AR_tax)/ } keys %{ $entry->{chartlinks} };
+
+ $num_tax_rows++ if $is_tax;
+ $num_taxed_rows++ if !$is_tax && $entry->{tax_key} != 0;
+ }
+
+ # now if this has tax rows but NO taxed rows, something is wrong.
+ if ($num_tax_rows > 0 && $num_taxed_rows == 0) {
+ $params{problem}->{type} = 'missing_taxkeys_in_invoices';
+ push @{ $self->{missing_taxkeys_in_invoices} ||= [] }, $params{problem};
+ $found_broken = 1;
+ }
+ }
+
+ $::lxdebug->leave_sub;
+
+ return $found_broken;
+}
+
# Problemfall: Kreditorenbuchungen, bei denen mit Umsatzsteuerschlüsseln
# gebucht wurde und Debitorenbuchungen, bei denen mit Vorsteuerschlüsseln
# gebucht wurde.
unshift @problems, $problem;
}
+ if (0 != scalar @{ $self->{missing_taxkeys_in_invoices} }) {
+ my $problem = {
+ 'type' => 'missing_taxkeys_in_invoices',
+ 'ap_problems' => [ grep { $_->{data}->{module} eq 'ap' } @{ $self->{missing_taxkeys_in_invoices} } ],
+ 'ar_problems' => [ grep { $_->{data}->{module} eq 'ar' } @{ $self->{missing_taxkeys_in_invoices} } ],
+ };
+ unshift @problems, $problem;
+ }
+
$main::lxdebug->leave_sub();
+# $::lxdebug->dump(0, 'problems:', \@problems);
return @problems;
}
return $result;
}
+sub parse_excel_file {
+ $main::lxdebug->enter_sub();
+
+ my ($self, $myconfig, $form) = @_;
+ my $locale = $main::locale;
+
+ $form->{formname} = 'sales_quotation';
+ $form->{type} = 'sales_quotation';
+ $form->{format} = 'excel';
+ $form->{media} = 'screen';
+ $form->{quonumber} = 1;
+
+
+ # $form->{"notes"} will be overridden by the customer's/vendor's "notes" field. So save it here.
+ $form->{ $form->{"formname"} . "notes" } = $form->{"notes"};
+
+ my $inv = "quo";
+ my $due = "req";
+ $form->{"${inv}date"} = $form->{transdate};
+ $form->{label} = $locale->text('Quotation');
+ my $numberfld = "sqnumber";
+ my $order = 1;
+
+ # assign number
+ $form->{what_done} = $form->{formname};
+
+ map({ delete($form->{$_}); } grep(/^cp_/, keys(%{ $form })));
+
+ my $output_dateformat = $myconfig->{"dateformat"};
+ my $output_numberformat = $myconfig->{"numberformat"};
+ my $output_longdates = 1;
+
+ # map login user variables
+ map { $form->{"login_$_"} = $myconfig->{$_} } ("name", "email", "fax", "tel", "company");
+
+ # format item dates
+ for my $field (qw(transdate_oe deliverydate_oe)) {
+ map {
+ $form->{$field}[$_] = $locale->date($myconfig, $form->{$field}[$_], 1);
+ } 0 .. $#{ $form->{$field} };
+ }
+
+ if ($form->{shipto_id}) {
+ $form->get_shipto($myconfig);
+ }
+
+ $form->{notes} =~ s/^\s+//g;
+
+ $form->{templates} = $myconfig->{templates};
+
+ delete $form->{printer_command};
+
+ $form->get_employee_info($myconfig);
+
+ my ($cvar_date_fields, $cvar_number_fields) = CVar->get_field_format_list('module' => 'CT', 'prefix' => 'vc_');
+
+ if (scalar @{ $cvar_date_fields }) {
+ format_dates($output_dateformat, $output_longdates, @{ $cvar_date_fields });
+ }
+
+ while (my ($precision, $field_list) = each %{ $cvar_number_fields }) {
+ reformat_numbers($output_numberformat, $precision, @{ $field_list });
+ }
+
+ $form->{excel} = 1;
+ my $extension = 'xls';
+
+ my $form->{IN} = "$form->{formname}.${extension}";
+
+ delete $form->{OUT};
+
+ $form->parse_template($myconfig, $main::userspath);
+
+ $main::lxdebug->leave_sub();
+}
+
1;
} elsif ( $self->{"format"} =~ /elstertaxbird/i ) {
$template = XMLTemplate->new($self->{"IN"}, $self, $myconfig, $userspath);
+ } elsif ( $self->{"format"} =~ /excel/i ) {
+ $template = ExcelTemplate->new($self->{"IN"}, $self, $myconfig, $userspath);
+ $ext_for_format = 'xls';
+
} elsif ( defined $self->{'format'}) {
$self->error("Outputformat not defined. This may be a future feature: $self->{'format'}");
my $extension = $self->{format} =~ /pdf/i ? ".pdf"
: $self->{format} =~ /postscript/i ? ".ps"
: $self->{format} =~ /opendocument/i ? ".odt"
+ : $self->{format} =~ /excel/i ? ".xls"
: $self->{format} =~ /html/i ? ".html"
: "";
my $col_idx = 0;
foreach my $col_name (@visible_columns) {
my $col = $row->{$col_name};
- push @{ $data_row }, $self->_decode_text(join("\n", @{ $col->{data} }));
+ push @{ $data_row }, $self->_decode_text(join("\n", @{ $col->{data} || [] }));
$column_props[$col_idx]->{justify} = 'right' if ($col->{align} eq 'right');
return 1;
}
+
+##########################################################
+####
+#### ExcelTemplate
+####
+##########################################################
+
+package ExcelTemplate;
+
+use vars qw(@ISA);
+
+@ISA = qw(SimpleTemplate);
+
+sub new {
+ my $type = shift;
+
+ my $self = $type->SUPER::new(@_);
+
+ return $self;
+}
+sub _init {
+ my $self = shift;
+
+ $self->{source} = shift;
+ $self->{form} = shift;
+ $self->{myconfig} = shift;
+ $self->{userspath} = shift;
+
+ $self->{error} = undef;
+
+ $self->set_tag_style('<<', '>>');
+}
+
+sub get_mime_type() {
+ my ($self) = @_;
+
+ return "application/msexcel";
+}
+
+sub uses_temp_file {
+ return 1;
+}
+
+sub parse {
+ $main::lxdebug->enter_sub();
+
+ my $self = shift;
+ local *OUT = shift;
+ my $form = $self->{"form"};
+
+ open(IN, "$form->{templates}/$form->{IN}") or do { $self->{"error"} = "$!"; return 0; };
+ my @lines = <IN>;
+ close IN;
+
+ my $contents = join("", @lines);
+ my @indices;
+ $contents =~ s{
+ $self->{tag_start} [<]* (\s?) [<>\s]* ([\w\s]+) [<>\s]* $self->{tag_end}
+ }{
+ $self->format_vars(align_right => $1 ne '', varstring => $2, length => length($&), indices => \@indices)
+ }egx;
+
+ if (!defined($contents)) {
+ $main::lxdebug->leave_sub();
+ return 0;
+ }
+
+ print OUT $contents;
+
+ $main::lxdebug->leave_sub();
+ return 1;
+}
+
+sub format_vars {
+ my ($self, %params) = @_;
+ my $form = $self->{"form"};
+ my @indices = @{ $params{indices} };
+ my $align_right = $params{align_right};
+ my $varstring = $params{varstring};
+ my $length = $params{length};
+
+ $varstring =~ s/(\w+)/ $self->_get_loop_variable($1, 0, @indices) /eg;
+ my $old_string=$varstring;
+ my $new_string = sprintf "%*s", ($align_right ? 1 : -1 ) * $length, $varstring;
+ if (!defined($new_string) || $new_string eq ''){
+ $main::lxdebug->message(0, 'varstring' . $varstring . "old" . $old_string);
+ # return substr $varstring, ($align_right ? (0, $length) : -$length);
+ }
+ return substr $new_string, ($align_right ? (0, $length) : -$length);
+}
+
1;
my $sthTransferPartSQL = prepare_query($form, $dbh, $transferPartSQL);
# der return-string für die fehlermeldung inkl. welche waren zum fertigen noch fehlen
- my $kannNichtFertigen ="Für dieses Erzeugnis sind keine Einzelteile definiert.
- Dementsprechend kann auch nichts hergestellt werden";
+ my $kannNichtFertigen =""; # Falls leer dann erfolgreich
+ my $schleife_durchlaufen=0; # Falls die Schleife nicht ausgeführt wird -> Keine Einzelteile definiert. Bessere Idee? jan
while (my $hash_ref = $sth_part_qty_assembly->fetchrow_hashref()) { #Schleife für select parts_id,(...) from assembly
- $kannNichtFertigen =""; # Wieder auf erfolgreich setzen LEER == keine Fehlermeldung
+ $schleife_durchlaufen=1; # Erzeugnis definiert
my $partsQTY = $hash_ref->{qty} * $params{qty}; # benötigte teile * anzahl erzeugnisse
my $currentPart_ID = $hash_ref->{parts_id};
}
} # ende while SELECT SUM(qty), bin_id, chargenumber, bestbefore FROM inventory WHERE warehouse_id
} #ende while select parts_id,qty from assembly where id = ?
+
+ if ($schleife_durchlaufen==0){ # falls die schleife nicht durchlaufen wurde, wurden auch
+ # keine einzelteile definiert
+ $kannNichtFertigen ="Für dieses Erzeugnis sind keine Einzelteile definiert.
+ Dementsprechend kann auch nichts hergestellt werden";
+ }
+ # gibt die Fehlermeldung zurück. A.) Keine Teile definiert
+ # B.) Artikel und Anzahl der fehlenden Teile/Dienstleistungen
if ($kannNichtFertigen) {
return $kannNichtFertigen;
}
sub continue { call_sub($main::form->{"nextsub"}); }
+
+1;
+
+__END__
+
+=head1 NAME
+
+bin/mozilla/arap.pl - helper routines for invoiceing frontend.
+
+=head1 SYNOPSIS
+
+nothing yet
+
+=head1 DESCRIPTION
+
+nothing yet
+
+=head1 FUNCTIONS
+
+=head2 check_name customer|vendor
+
+check_name was originally meant to update the selected customer or vendor. The
+way it does that has generted more hate than almost any other part of this
+software.
+
+What it does is:
+
+=over 4
+
+=item
+
+It checks if a vendor or customer is given. No failsafe, vendor fallback if
+$_[0] is something fancy.
+
+=item
+
+It assumes, that there is a field named customer or vendor in $form.
+
+=item
+
+It assumes, that this field is filled with name--id, and tries to split that.
+sql ledger uses that combination to get ids into the select keys.
+
+=item
+
+It looks for a field selectcustomer or selectvendor in $form. sql ledger used
+to store a copy of the html select in there. (again, don't ask)
+
+=item
+
+If this field exists, it looks for a field called oldcustomer or oldvendor, in
+which the old name--id string was stored in sql ledger, and compares those.
+
+=item
+
+if they don't match, it will set customer_id or vendor_id in $form, load the
+entry (which will clobber everything in $form named like a column in customer
+oder vendor) and return.
+
+=item
+
+If there was no select* entry, it assumes that vclimit was lower than the
+number of entries, and that an input field was generated. In that case the
+splitting is omitted (since users don't generally include ids in entered names)
+
+=item
+
+It looks for a *_id field, and combines it with the given input into a name--id
+entry and compares it to the old* entry. (Missing any of these will instantly
+break check_namea.
+
+=item
+
+If those do not match, $form->get_name is called to get matching results.
+get_name only matches by *number and name, not by id, don't try to get it to do
+so.
+
+=item
+
+The results are stored in $form>{name_list} but a count is returned, and
+checked.
+
+=item
+
+If only one result was found, *_id, * and old* are copied into $form, the entry
+is loaded (like above, clobbering)
+
+=item
+
+If there is more than one, a selection dialog is rendered
+
+=item
+
+If none is found, an error is generated.
+
+=back
+
+=head3 I built a customer/vendor box somewhere and it doesn't work, what's wrong?
+
+Make sure a select* field is given if and only if you render a select box. The
+actual contents are ignored, but recognition fails if not present.
+
+Make sure old* and *_id fields are set correctly (name--id form for old*). They
+are necessary in all steps and branches.
+
+Since get_customer and get_vendor clobber a lot of fields, make sure what
+changes exactly.
+
+=cut
'description' => { 'text' => $locale->text('Description'), },
'debit' => { 'text' => $locale->text('Debit'), },
'credit' => { 'text' => $locale->text('Credit'), },
- 'gegenkonto' => { 'text' => $locale->text('Gegenkonto'), },
- 'ustkonto' => { 'text' => $locale->text('USt-Konto'), },
- 'balance' => { 'text' => $locale->text('Balance'), },
+ 'gegenkonto' => { 'text' => $locale->text('Gegenkonto'), },
+ 'ustkonto' => { 'text' => $locale->text('USt-Konto'), },
+ 'balance' => { 'text' => $locale->text('Balance'), },
'ustrate' => { 'text' => $locale->text('Satz %'), },
);
(!$options{no_html}) ?
opthash("html", $form->{DF}{html}, "HTML") : undef,
($main::opendocument_templates && !$options{no_opendocument}) ?
- opthash("opendocument", $form->{DF}{opendocument}, $locale->text("OpenDocument/OASIS")) : undef;
+ opthash("opendocument", $form->{DF}{opendocument}, $locale->text("OpenDocument/OASIS")) : undef,
+ ($main::excel_templates && !$options{no_excel}) ?
+ opthash("excel", $form->{DF}{excel}, $locale->text("Excel")) : undef;
push @LANGUAGE_ID,
map { opthash($_->{id}, ($_->{id} eq $form->{language_id} ? 'selected' : ''), $_->{description}) } +{}, @{ $form->{languages} }
} elsif ($form->{"format"} =~ /opendocument/) {
$form->{opendocument} = 1;
$extension = 'odt';
+ } elsif ($form->{"format"} =~ /excel/) {
+ $form->{excel} = 1;
+ $extension = 'xls';
}
my $email_extension = '_email' if (($form->{media} eq 'email') && (-f "$myconfig{templates}/$form->{formname}_email$form->{language}${printer_code}.${extension}"));
'invnumber' => { 'text' => $locale->text('Invoice'), },
'transdate' => { 'text' => $locale->text('Date'), },
'duedate' => { 'text' => $locale->text('Due'), },
- 'amount' => { 'text' => $locale->text('Amount'), },
- 'open' => { 'text' => $locale->text('Open'), },
+ 'amount' => { 'text' => $locale->text('Amount'), },
+ 'open' => { 'text' => $locale->text('Open'), },
);
my %column_alignment = ('statement' => 'center',
$webdav = 0;
$lizenzen = 1;
$vertreter = 0;
+$excel_templates = 0; # Minimalunterstützung für Excel-Druckvorlagen
# Zeige Felder für Mindesthaltbarkeitsdatum
$show_best_before = 0;
# Veränderungen von Lx-Office ERP #
###################################
+
+
+
+
+
+ Kleinere neue Features und Detailverbesserungen:
+
+ - Druckvorlage optional auf Excel erweitert, um Variablen die sich nicht in foreach-Schleifen
+ befinden anzuzeigen (s.a.: doc/excel_templates.txt).
+
+
+ Liste gefixter Bugs aus dem Bugtracker:
+
+ - Bug 1409 - Bei "Erzeugnis fertigen" wird nur der Bestand der letzten Komponente geprüft
+
+
+
2010-03-24 - Release 2.6.1
Größere neue Features:
--- /dev/null
+Table of Contents
+-----------------
+
+Inhalt der Anleitung
+1 Zusammenfassung
+2 Bedienung
+3 Exceltemplate Syntax
+4 Einschränkungen
+
+
+
+Zusammenfassung
+---------------
+
+Dieses Dokument beschreibt den Mechanismus, mit dem Exceltemplates abgearbeitet
+werden, und die Einschränkungen die damit einhergehen.
+
+
+
+Bedienung
+---------
+
+Der Excel Mechanismus muss in der Konfigurationsdatei aktiviert werden. Die
+Konfigurationsoption heißt:
+
+ $excel_templates = 1;
+
+Eine Excelvorlage kann dann unter dem Namen einer beliebigen anderen Vorlage mit
+der Endung .xls gespeichert werden. In den normalen Verkaufsmasken taucht nun
+"Excel" als auswählbares Format auf, und kann von da an bnutzt weren wie Latex
+oder OpenOffice Vorlagen.
+
+Der Sonderfall der Angebote aus der Kundenmaske ist ebenfalls eine
+Angebotsvorlage, und wird unter dem internen Namen der Angebote
+"sales_quotation.xls" gespeichert.
+
+
+
+Exceltemplate Syntax
+--------------------
+
+Einfache Syntax: <<varname>>
+
+Wobei "<<" und ">>" die Delimiter sind. Da Excel auf festen Breiten besteht,
+kann der Tag künstlich verlängert werden, indem weitere "<" oder ">" gegefügt
+werden. Der Tag muss nicht symmetrisch sein.
+
+Beispiel: <<<<<varname>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+Um die Limitierung der festen Breite zu reduzieren, können weitere Variablen in
+einem Block interpoliert werden. Whitespace wird dazwishen dann erhalten.
+
+Beispiel: <<<<<varname1 varname2 varname3>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+Die Variablen werden interpoliert, und linksbündig mit Leerzeichen auf die
+gewünschte Länge aufgefüllt. Ist der String zu lang, werden überzählige Zeichen
+abgeschnitten.
+
+Es ist ausserdem möglich Daten rechtsbündig darzustellen, wenn der Block mit
+einem Leerzeichen anfängt.
+
+Beispiel: <<<<<< varname>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+würde rechtsbündig triggern. Wenn bei rechtsbündiger Ausrichtung Text
+abgeschnitten werden muss, wird er vom linken Ende entfernt.
+
+
+
+Einschränkungen
+---------------
+
+Das Excelformat bis 2002 ist ein binäres Format, und kann nicht mit vertretbarem
+Aufwand editiert werden. Der Templatemechanismus beschränkt sich daher darauf,
+Textstellen _exakt_ durch einen anderen Text zu ersetzen.
+
+Aus dem gleichen Grund sind die Templatekonstrukte <% if %> und <% foreach %>
+nicht vorhanden. Der Delimiter <% %> kommt in den Headerinformationen evtl vor,
+deshalb wurde auf den sichereren "<<"/">>" gewechselt.
+
'<%netto_date%> -- Date the payment is due in full' => '<%netto_date%> -- Das Datum, bis die Rechnung in voller Höhe bezahlt werden muss',
'<%skonto_amount%> -- The deductible amount' => '<%skonto_amount%> -- Der abziehbare Skontobetrag',
'<%skonto_date%> -- Date the payment is due with discount' => '<%skonto_date%> -- Das Datum, bis die Rechnung unter Abzug von Skonto bezahlt werden kann',
+ '<%skonto_in_percent%> -- The discount in percent' => '<%skonto_in_percent%> -- Der prozentuale Rabatt',
'<%terms_netto%> -- The number of days for full payment' => '<%terms_netto%> -- Die Anzahl Tage, bis die Rechnung in voller Höhe bezahlt werden muss',
'<%total%> -- Amount payable' => '<%total%> -- Noch zu bezahlender Betrag',
'<%total_wo_skonto%> -- Amount payable less discount' => '<%total_wo_skonto%> -- Noch zu bezahlender Betrag abzüglich Skonto',
'Ertrag prozentual' => 'Ertrag prozentual',
'Escape character' => 'Escape-Zeichen',
'Exact' => 'Genau',
+ 'Excel' => 'Excel',
'Exch' => 'Wechselkurs.',
'Exchangerate' => 'Wechselkurs',
'Exchangerate Difference' => 'Wechselkursunterschied',
'Missing amount' => 'Fehlbetrag',
'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
'Missing parameter (at least one of #1) in call to sub #2.' => 'Fehlernder Parameter (mindestens einer aus \'#1\') in Funktionsaufruf \'#2\'.',
+ 'Missing taxkeys in invoices with taxes.' => 'Fehlende Steuerschlüssel in Rechnungen mit Steuern',
'Mitarbeiter' => 'Mitarbeiter',
'Mobile1' => 'Mobile 1',
'Mobile2' => 'Mobile 2',
'<%netto_date%> -- Date the payment is due in full' => '<%netto_date%> -- Das Datum, bis die Rechnung in voller Höhe bezahlt werden muss',
'<%skonto_amount%> -- The deductible amount' => '<%skonto_amount%> -- Der abziehbare Skontobetrag',
'<%skonto_date%> -- Date the payment is due with discount' => '<%skonto_date%> -- Das Datum, bis die Rechnung unter Abzug von Skonto bezahlt werden kann',
- '<%skonto_in_percent%> -- The discount in percent' => '<%skonto_in_percent%> -- Skonto in Prozent',
+ '<%skonto_in_percent%> -- The discount in percent' => '<%skonto_in_percent%> -- Der prozentuale Rabatt',
'<%terms_netto%> -- The number of days for full payment' => '<%terms_netto%> -- Die Anzahl Tage, bis die Rechnung in voller Höhe bezahlt werden muss',
'<%total%> -- Amount payable' => '<%total%> -- Noch zu bezahlender Betrag',
'<%total_wo_skonto%> -- Amount payable less discount' => '<%total_wo_skonto%> -- Noch zu bezahlender Betrag abzüglich Skonto',
'Enter longdescription' => 'Langtext eingeben',
'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
'Ertrag' => 'Ertrag',
+ 'Excel' => 'Excel',
'Extended' => 'Gesamt',
'Falsches Datumsformat!' => 'Falsches Datumsformat!',
'Fax' => 'Fax',
'Error in position #1: You must either assign no transfer at all or the full quantity of #2 #3.' => 'Fehler in Position #1: Sie müssen einer Position entweder gar keinen Lagerausgang oder die vollständige im Lieferschein vermerkte Menge von #2 #3 zuweisen.',
'Error in row #1: The quantity you entered is bigger than the stocked quantity.' => 'Fehler in Zeile #1: Die angegebene Menge ist größer als die vorhandene Menge.',
'Ertrag' => 'Ertrag',
+ 'Excel' => 'Excel',
'Extended' => 'Gesamt',
'Fax' => 'Fax',
'Feb' => 'Feb',
'Enter longdescription' => 'Langtext eingeben',
'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
'Ertrag' => 'Ertrag',
+ 'Excel' => 'Excel',
'Extended' => 'Gesamt',
'Fax' => 'Fax',
'Feb' => 'Feb',
'Enter longdescription' => 'Langtext eingeben',
'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
'Ertrag' => 'Ertrag',
+ 'Excel' => 'Excel',
'Extended' => 'Gesamt',
'Fax' => 'Fax',
'Feb' => 'Feb',
'Enter longdescription' => 'Langtext eingeben',
'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
'Ertrag' => 'Ertrag',
+ 'Excel' => 'Excel',
'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
'Exchangerate missing!' => 'Es fehlt der Wechselkurs!',
'Extended' => 'Gesamt',
'Enter longdescription' => 'Langtext eingeben',
'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
'Ertrag' => 'Ertrag',
+ 'Excel' => 'Excel',
'Exchangerate for payment missing!' => 'Es fehlt der Wechselkurs für die Bezahlung!',
'Exchangerate missing!' => 'Es fehlt der Wechselkurs!',
'Extended' => 'Gesamt',
[\-~#]* # Whitespace-Unterdrückung
\%\] # Template-Ende-Tag
/ix) {
-# print "Found filter >>>$1<<<\n";
+# print "Found filter '$1' in string '$line'\n";
$cached{$_[0]}{all}{$1} = 1;
$cached{$_[0]}{html}{$1} = 1;
$plugins{needed}->{T8} = 1;
- substr $line, $-[1], $+[0] - $-[0], '';
+ substr $line, $-[0], $+[0] - $-[0], '';
}
while ("" ne $line) {
'Error in row #1: The quantity you entered is bigger than the stocked quantity.' => 'Fehler in Zeile #1: Die angegebene Menge ist größer als die vorhandene Menge.',
'Ertrag' => 'Ertrag',
'Ertrag prozentual' => 'Ertrag prozentual',
+ 'Excel' => 'Excel',
'Exchangerate' => 'Wechselkurs',
'Exchangerate missing!' => 'Es fehlt der Wechselkurs!',
'Extended' => 'Gesamt',
'Error in row #1: The quantity you entered is bigger than the stocked quantity.' => 'Fehler in Zeile #1: Die angegebene Menge ist größer als die vorhandene Menge.',
'Ertrag' => 'Ertrag',
'Ertrag prozentual' => 'Ertrag prozentual',
+ 'Excel' => 'Excel',
'Exchangerate' => 'Wechselkurs',
'Exchangerate missing!' => 'Es fehlt der Wechselkurs!',
'Extended' => 'Gesamt',
'Error in row #1: The quantity you entered is bigger than the stocked quantity.' => 'Fehler in Zeile #1: Die angegebene Menge ist größer als die vorhandene Menge.',
'Ertrag' => 'Ertrag',
'Ertrag prozentual' => 'Ertrag prozentual',
+ 'Excel' => 'Excel',
'Exchangerate' => 'Wechselkurs',
'Exchangerate missing!' => 'Es fehlt der Wechselkurs!',
'Extended' => 'Gesamt',
[%- END %]
[%- END %]
+ [%- ELSIF problem.type == 'missing_taxkeys_in_invoices' %]
+ [%- IF problem.ar_problems.size %]
+ Verkaufsrechnungen
+ [%- FOREACH subproblem = problem.ar_problems %]
+ [%- UNLESS loop.first %], [%- END %]
+ <a href="[% subproblem.link %]">[% HTML.escape(subproblem.data.reference) %]</a>
+ [%- END %]
+ [%- END %]
+
+ [%- IF problem.ap_problems.size %]
+ [%- IF problem.ar_problems.size %]; [%- END %]
+ Einkaufsrechnungen
+ [%- FOREACH subproblem = problem.ap_problems %]
+ [%- UNLESS loop.first %], [%- END %]
+ <a href="[% subproblem.link %]">[% HTML.escape(subproblem.data.reference) %]</a>
+ [%- END %]
+ [%- END %]
+
[%- ELSE %]
<a href="[% problem.link %]">
[%- ELSIF problem.type == 'invoice_inventory_with_taxkeys' %]
Einkaufs- und Verkaufsrechnungen mit Warenbestandsbuchungen mit Steuerschlüsseln
+ [%- ELSIF problem.type == 'missing_taxkeys_in_invoices' %]
+ Fehlende Steuerschlüssel in Rechnungen mit Steuern
+
[%- END %]
</td>
[%- END %]
[%- END %]
+ [%- ELSIF problem.type == 'missing_taxkeys_in_invoices' %]
+ [%- IF problem.ar_problems.size %]
+ <translate>Sales invoices</translate>
+ [%- FOREACH subproblem = problem.ar_problems %]
+ [%- UNLESS loop.first %], [%- END %]
+ <a href="[% subproblem.link %]">[% HTML.escape(subproblem.data.reference) %]</a>
+ [%- END %]
+ [%- END %]
+
+ [%- IF problem.ap_problems.size %]
+ [%- IF problem.ar_problems.size %]; [%- END %]
+ <translate>Purchase invoices</translate>
+ [%- FOREACH subproblem = problem.ap_problems %]
+ [%- UNLESS loop.first %], [%- END %]
+ <a href="[% subproblem.link %]">[% HTML.escape(subproblem.data.reference) %]</a>
+ [%- END %]
+ [%- END %]
+
[%- ELSE %]
<a href="[% problem.link %]">
[%- ELSIF problem.type == 'invoice_inventory_with_taxkeys' %]
<translate>Sales and purchase invoices with inventory transactions with taxkeys</translate>
+ [%- ELSIF problem.type == 'missing_taxkeys_in_invoices' %]
+ <translate>Missing taxkeys in invoices with taxes.</translate>
+
[%- END %]
</td>
<!--
function enable_fix_button_maybe() {
var all_set = true;
- $("[@name='fixes[].taxkey']").each(function () {
+ $("[name='fixes[].taxkey']").each(function () {
var val = $(this).attr('value');
if (val == '')
all_set = false;
<!--
function enable_fix_button_maybe() {
var all_set = true;
- $("[@name='fixes[].taxkey']").each(function () {
+ $("[name='fixes[].taxkey']").each(function () {
var val = $(this).attr('value');
if (val == '')
all_set = false;