From: C. Braun Date: Fri, 13 May 2011 12:49:10 +0000 (+0200) Subject: Merge branch 'master' of git@lx-office.linet-services.de:lx-office-erp X-Git-Tag: release-2.6.3~25^2~37 X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/commitdiff_plain/dd0ba7b9a6f931ce13ced906d9cc6cb3e7c3ea3a?hp=d018d87276e27a785ab119eb13fef83a5e15ba8c Merge branch 'master' of git@lx-office.linet-services.de:lx-office-erp --- diff --git a/SL/Auth.pm b/SL/Auth.pm index 3b14def5d..fca3b8b2c 100644 --- a/SL/Auth.pm +++ b/SL/Auth.pm @@ -598,52 +598,33 @@ sub _create_session_id { } sub create_or_refresh_session { - $main::lxdebug->enter_sub(); - - my $self = shift; - - $session_id ||= $self->_create_session_id(); - - my ($form, $dbh, $query, $sth, $id); - - $form = $main::form; - $dbh = $self->dbconnect(); - - $dbh->begin_work; - do_query($::form, $dbh, qq|LOCK auth.session_content|); - - $query = qq|SELECT id FROM auth.session WHERE id = ?|; - - ($id) = selectrow_query($form, $dbh, $query, $session_id); - - if ($id) { - do_query($form, $dbh, qq|UPDATE auth.session SET mtime = now() WHERE id = ?|, $session_id); - - } else { - do_query($form, $dbh, qq|INSERT INTO auth.session (id, ip_address, mtime) VALUES (?, ?, now())|, $session_id, $ENV{REMOTE_ADDR}); - - } - - $self->save_session($dbh); - - $dbh->commit(); - - $main::lxdebug->leave_sub(); + $session_id ||= shift->_create_session_id; } sub save_session { + $::lxdebug->enter_sub; my $self = shift; my $provided_dbh = shift; my $dbh = $provided_dbh || $self->dbconnect(1); - return unless $dbh; + $::lxdebug->leave_sub && return unless $dbh; $dbh->begin_work unless $provided_dbh; do_query($::form, $dbh, qq|LOCK auth.session_content|); do_query($::form, $dbh, qq|DELETE FROM auth.session_content WHERE session_id = ?|, $session_id); + my $query = qq|SELECT id FROM auth.session WHERE id = ?|; + + my ($id) = selectrow_query($::form, $dbh, $query, $session_id); + + if ($id) { + do_query($::form, $dbh, qq|UPDATE auth.session SET mtime = now() WHERE id = ?|, $session_id); + } else { + do_query($::form, $dbh, qq|INSERT INTO auth.session (id, ip_address, mtime) VALUES (?, ?, now())|, $session_id, $ENV{REMOTE_ADDR}); + } + if (%{ $self->{SESSION} }) { my $query = qq|INSERT INTO auth.session_content (session_id, sess_key, sess_value) VALUES (?, ?, ?)|; my $sth = prepare_query($::form, $dbh, $query); @@ -656,6 +637,7 @@ sub save_session { } $dbh->commit() unless $provided_dbh; + $::lxdebug->leave_sub; } sub set_session_value { @@ -1128,17 +1110,13 @@ sub assert { } sub load_rights_for_user { - $main::lxdebug->enter_sub(); - - my $self = shift; - my $login = shift; - - my $form = $main::form; - my $dbh = $self->dbconnect(); + $::lxdebug->enter_sub; + my ($self, $login) = @_; + my $dbh = $self->dbconnect; my ($query, $sth, $row, $rights); - $rights = {}; + $rights = { map { $rights->{$_} = 0 } all_rights() }; $query = qq|SELECT gr."right", gr.granted @@ -1149,16 +1127,14 @@ sub load_rights_for_user { LEFT JOIN auth."user" u ON (ug.user_id = u.id) WHERE u.login = ?)|; - $sth = prepare_execute_query($form, $dbh, $query, $login); + $sth = prepare_execute_query($::form, $dbh, $query, $login); while ($row = $sth->fetchrow_hashref()) { $rights->{$row->{right}} |= $row->{granted}; } $sth->finish(); - map({ $rights->{$_} = 0 unless (defined $rights->{$_}); } SL::Auth::all_rights()); - - $main::lxdebug->leave_sub(); + $::lxdebug->leave_sub; return $rights; } diff --git a/SL/Controller/DebugMenu.pm b/SL/Controller/DebugMenu.pm new file mode 100644 index 000000000..d612d3701 --- /dev/null +++ b/SL/Controller/DebugMenu.pm @@ -0,0 +1,24 @@ +package SL::Controller::DebugMenu; + +use strict; +use parent qw(SL::Controller::Base); + +# safety +__PACKAGE__->run_before(sub { die 'not allowed in config' unless $::lx_office_conf{debug}{show_debug_menu}; }); + +sub action_reload { + my ($self, %params) = @_; + + print $::cgi->redirect('kopf.pl'); + exit; +} + +sub action_toggle { + my ($self, %params) = @_; + + $::lxdebug->level_by_name($::form->{level}, !$::lxdebug->level_by_name($::form->{level})); + print $::cgi->redirect('kopf.pl'); + return; +} + +1; diff --git a/SL/DBConnect.pm b/SL/DBConnect.pm index fbcf1d5a1..4e084502a 100644 --- a/SL/DBConnect.pm +++ b/SL/DBConnect.pm @@ -12,7 +12,7 @@ sub connect { require Log::Log4perl; require DBIx::Log4perl; - my $filename = $LXDebug::file_name; + my $filename = $::lxdebug->file; my $config = $::lx_office_conf{debug}->{dbix_log4perl_config}; $config =~ s/LXDEBUGFILE/${filename}/g; diff --git a/SL/Dispatcher.pm b/SL/Dispatcher.pm index c1f31a4ef..e72897693 100644 --- a/SL/Dispatcher.pm +++ b/SL/Dispatcher.pm @@ -52,7 +52,6 @@ sub pre_request_checks { show_error('login/auth_db_unreachable'); } } - $::auth->expire_sessions; } sub show_error { @@ -237,6 +236,7 @@ sub handle_request { $::myconfig = (); Form::disconnect_standard_dbh; $::auth->expire_session_keys->save_session; + $::auth->expire_sessions; $::auth->reset; $::lxdebug->end_request; diff --git a/SL/IC.pm b/SL/IC.pm index b6007d9dc..cf7c99c36 100644 --- a/SL/IC.pm +++ b/SL/IC.pm @@ -502,7 +502,7 @@ sub save { if (($form->{"make_$i"}) || ($form->{"model_$i"})) { #hli $value = $form->parse_amount($myconfig, $form->{"lastcost_$i"}); - if ($value == $form->{"old_lastcost_$i"}) + if ($value == $form->parse_amount($myconfig, $form->{"old_lastcost_$i"})) { if ($form->{"lastupdate_$i"} eq "") { $lastupdate = 'now()'; @@ -1663,7 +1663,7 @@ sub prepare_parts_for_printing { } my $placeholders = join ', ', ('?') x scalar(@part_ids); - my $query = qq|SELECT mm.parts_id, mm.model, v.name AS make + my $query = qq|SELECT mm.parts_id, mm.model, mm.lastcost, v.name AS make FROM makemodel mm LEFT JOIN vendor v ON (mm.make = v.id) WHERE mm.parts_id IN ($placeholders)|; diff --git a/SL/LXDebug.pm b/SL/LXDebug.pm index b24372445..4e7790791 100644 --- a/SL/LXDebug.pm +++ b/SL/LXDebug.pm @@ -292,4 +292,24 @@ sub want_request_timer { $global_level & REQUEST_TIMER; } +sub file { + @_ == 2 ? $_[0]->{file} = $_[1] : $_[0]->{file}; +} + +sub _by_name { + my ($self, $level) = @_; + my $meth = $self->can(uc $level); + die 'unknown level' unless $meth; + $meth->(); +} + +sub level_by_name { + my ($self, $level, $val) = @_; + if (@_ == 3) { + $global_level |= $self->_by_name($level) if $val; + $global_level &= ~$self->_by_name($level) if !$val; + } + return $global_level & $self->_by_name($level); +} + 1; diff --git a/SL/SEPA.pm b/SL/SEPA.pm index 9a2978314..32e763cdb 100644 --- a/SL/SEPA.pm +++ b/SL/SEPA.pm @@ -21,7 +21,7 @@ sub retrieve_open_invoices { my $query = qq| - SELECT ${arap}.id, ${arap}.invnumber, ${arap}.${vc}_id, ${arap}.amount AS invoice_amount, ${arap}.invoice, + SELECT ${arap}.id, ${arap}.invnumber, ${arap}.${vc}_id as vc_id, ${arap}.amount AS invoice_amount, ${arap}.invoice, vc.name AS vcname, vc.language_id, ${arap}.duedate as duedate, COALESCE(vc.iban, '') <> '' AND COALESCE(vc.bic, '') <> '' AS vc_bank_info_ok, diff --git a/SL/Template/Plugin/HTMLFixes.pm b/SL/Template/Plugin/HTMLFixes.pm index 3f328a842..32d3c5683 100644 --- a/SL/Template/Plugin/HTMLFixes.pm +++ b/SL/Template/Plugin/HTMLFixes.pm @@ -17,7 +17,7 @@ use Encode; # creating invalid UTF-8 characters upon URL-unescaping. # The only addition is the "Encode::encode()" line. - +no warnings 'redefine'; sub url { my ($self, $text) = @_; return undef unless defined $text; diff --git a/bin/mozilla/do.pl b/bin/mozilla/do.pl index 10fdf2227..1b7a10960 100644 --- a/bin/mozilla/do.pl +++ b/bin/mozilla/do.pl @@ -337,7 +337,19 @@ sub update_delivery_order { $payment_id = $form->{payment_id} if $form->{payment_id}; check_name($form->{vc}); - + $form->{discount} = $form->{"$form->{vc}_discount"} if defined $form->{"$form->{vc}_discount"}; + # Problem: Wenn man ohne Erneuern einen Kunden/Lieferanten + # wechselt, wird der entsprechende Kunden/ Lieferantenrabatt + # nicht übernommen. Grundproblem: In Commit 82574e78 + # hab ich aus discount customer_discount und vendor_discount + # gemacht und entsprechend an den Oberflächen richtig hin- + # geschoben. Die damals bessere Lösung wäre gewesen: + # In den Templates nur die hidden für form-discount wieder ein- + # setzen dann wäre die Verrenkung jetzt nicht notwendig. + # TODO: Ggf. Bugfix 1284, 1575 und 817 wieder zusammenführen + # Testfälle: Kunden mit Rabatt 0 -> Rabatt 20 i.O. + # Kunde mit Rabatt 20 -> Rabatt 0 i.O. + # Kunde mit Rabatt 20 -> Rabatt 5,5 i.O. $form->{payment_id} = $payment_id if $form->{payment_id} eq ""; # for pricegroups diff --git a/bin/mozilla/ic.pl b/bin/mozilla/ic.pl index e56178206..13e0a5ac2 100644 --- a/bin/mozilla/ic.pl +++ b/bin/mozilla/ic.pl @@ -1703,6 +1703,9 @@ sub update { # parse pricegroups. and no, don't rely on check_form for this... map { $form->{"price_$_"} = $form->parse_amount(\%myconfig, $form->{"price_$_"}) } 1 .. $form->{price_rows}; + # same for lastcosts + map { $form->{"lastcost_$_"} = $form->parse_amount(\%myconfig, $form->{"lastcost_$_"}) } 1 .. $form->{"makemodel_rows"}; + if ($form->{item} eq "assembly") { my $i = $form->{assembly_rows}; diff --git a/bin/mozilla/kopf.pl b/bin/mozilla/kopf.pl index ed11e522b..0228566ae 100644 --- a/bin/mozilla/kopf.pl +++ b/bin/mozilla/kopf.pl @@ -1,136 +1,21 @@ #!/usr/bin/perl -# - -#$| = 1; - -#use CGI::Carp qw(fatalsToBrowser); use strict; +use DateTime; sub run { my $session_result = shift; - %::myconfig = $::auth->read_user($::form->{login}) if $::form->{login}; - $::locale = Locale->new($::myconfig{countrycode}) if $::myconfig{countrycode}; - -my $form = $main::form; -my $locale = $main::locale; - -$form->header; -my $paramstring = $ENV{"QUERY_STRING"}; -my @felder = split "&", $paramstring; -my ($name, $wert); -foreach (@felder) { - ($name, $wert) = split "=", $_; - $wert =~ tr/+/ /; - $name = $wert; -} -my $login = - "". $locale->text('User') . ": " . $form->{login} - . " [text('Logout now') . "\">" - . $locale->text('Logout') - . "] "; -my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat, - $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) - = localtime(time); -my $CTIME_String = localtime(time); -$Monat += 1; -$Jahrestag += 1; -$Monat = $Monat < 10 ? $Monat = "0" . $Monat : $Monat; -$Monatstag = $Monatstag < 10 ? $Monatstag = "0" . $Monatstag : $Monatstag; -$Jahr += 1900; -my @Wochentage = ("Sonntag", "Montag", "Dienstag", "Mittwoch", - "Donnerstag", "Freitag", "Samstag"); -my @Monatsnamen = ("", "Januar", "Februar", "März", - "April", "Mai", "Juni", "Juli", - "August", "September", "Oktober", "November", - "Dezember"); -my $datum = - $Wochentage[$Wochentag] . ", der " - . $Monatstag . "." - . $Monat . "." - . $Jahr . " - "; - -#$zeit="
".$Stunden.":".$Minuten.":".$Sekunden."
"; -my $zeit = "
" . $Stunden . ":" . $Minuten . "
"; -print qq| - -|; + %::myconfig = $::auth->read_user($::form->{login}) if $::form->{login}; + $::locale = Locale->new($::myconfig{countrycode}) if $::myconfig{countrycode}; -print qq| - - - - |; - if ( !($ENV{HTTP_USER_AGENT} =~ /links/i) ) { # do not show the the links in case of "links" in HTTP_USER_AGENT - print qq| - |; - } - print qq| - - -
- [| . $locale->text('Menu') . qq|] -  [| . $locale->text('New Win/Tab') . qq|] -  [| . $locale->text('Print') . qq|] -  [| . $locale->text('Back') . qq|] -  [| . $locale->text('Fwd') . qq|] - | - . $login . $datum . qq|   -
- - -|; + $::form->header; + print $::form->parse_html_template('menu/header', { + now => DateTime->now, + show_debug => $::lx_office_conf{debug}{show_debug_menu}, + lxdebug => $::lxdebug, + is_links => ($ENV{HTTP_USER_AGENT} =~ /links/i), + }); } 1; diff --git a/bin/mozilla/oe.pl b/bin/mozilla/oe.pl index 97fc1d237..2acf9fe8d 100644 --- a/bin/mozilla/oe.pl +++ b/bin/mozilla/oe.pl @@ -238,14 +238,14 @@ sub order_links { $form->{"$form->{vc}_id"} ||= $form->{"all_$form->{vc}"}->[0]->{id} if $form->{"all_$form->{vc}"}; - $form->backup_vars(qw(payment_id language_id taxzone_id salesman_id taxincluded cp_id intnotes)); + $form->backup_vars(qw(payment_id language_id taxzone_id salesman_id taxincluded cp_id intnotes shipto_id)); $form->{shipto} = 1 if $form->{id}; # get customer / vendor IR->get_vendor(\%myconfig, \%$form) if $form->{type} =~ /(purchase_order|request_quotation)/; IS->get_customer(\%myconfig, \%$form) if $form->{type} =~ /sales_(order|quotation)/; - $form->restore_vars(qw(payment_id language_id taxzone_id intnotes cp_id)); + $form->restore_vars(qw(payment_id language_id taxzone_id intnotes cp_id shipto_id)); $form->restore_vars(qw(taxincluded)) if $form->{id}; $form->restore_vars(qw(salesman_id)) if $editing; $form->{forex} = $form->{exchangerate}; diff --git a/config/lx_office.conf.default b/config/lx_office.conf.default index e78f2c357..5f7f272a4 100644 --- a/config/lx_office.conf.default +++ b/config/lx_office.conf.default @@ -171,6 +171,10 @@ login = # location of history file for permanent history history_file = users/console_history +# location of a separate log file for the console. everything normally written +# to the lx-office log will be put here if triggered from the console +log_file = /tmp/lxoffice_console_debug.log + [debug] # Use DBIx::Log4perl for logging DBI calls. The string LXDEBUGFILE # will be replaced by the file name configured for $::lxdebug. @@ -218,6 +222,9 @@ global_level = NONE # default. watch_form = 0 +# Include menu options for debugging in the HTML menu +show_debug_menu = 0 + # If you want to debug the creation of LaTeX files then set this to 1. # That way the temporary LaTeX files created during PDF creation are # not removed and remain in the "users" directory. diff --git a/doc/UPGRADE b/doc/UPGRADE index 03bb3b6cd..05683f01e 100644 --- a/doc/UPGRADE +++ b/doc/UPGRADE @@ -4,6 +4,25 @@ Wichtige Hinweise zum Upgrade von älteren Versionen ** BITTE FERTIGEN SIE VOR DEM UPGRADE EIN BACKUP IHRER DATENBANK(EN) AN! ** +Upgrade auf v2.6.3 +================== + +Mit Version 2.6.3. wurden die beiden Konfigurationsdateien authentication.pl +und lx-erp.conf, sowie deren Varianten, abgeschafft. Stattdessen gibt es nun +die Datei lx_office.conf, die aber erst neu angelegt werden muß. Als Vorlage +dient hierfür die Datei lx_office.conf.default. Die entsprechenden Werte muß +man selber neu konfigurieren, dies ist automatisiert zu fehleranfällig. + +Nach dem Upgrade kann man sich so lange nicht anmelden, bis lx_office.conf +angelegt und authentication.pl und lx-erp.conf gelöscht oder verschoben wurden. + +Es gibt keine local-Variante der lx_office.conf, arbeitet man mit git sollte +man lx_office.conf nicht einchecken. + +Eine etwas ausführlichere Beschreibung findet sich in der Datei: +doc/konfigurationsdatei.txt + + Upgrade auf v2.6.2 ================== diff --git a/doc/changelog b/doc/changelog index 526158b91..eefcecbda 100644 --- a/doc/changelog +++ b/doc/changelog @@ -1,4 +1,4 @@ -################################### +#################################### # Veränderungen von Lx-Office ERP # ################################### @@ -6,6 +6,19 @@ + Größere neue Features: + + - Es ist jetzt möglich wiederkehrende Rechnungen zu definieren und zu + konfigurieren, dies geschieht im Formular für den Verkaufsauftrag. + Mögliche Periodizitäten sind monatlich/quartalsweise/jährlich. Die + Hauptkonfiguration hierzu findet sich in der lx_office.conf im Abschnitt + [periodic_invoices] + + - Die Überprüfung, wann wiederkehrende Rechnungen erstellt werden sollen, + geschieht durch ein weiteres neues Feature, den Taskserver. Konfiguriert + wird der Taskserver in der lx_office.conf im Abschnitt [task_server]. Der + Taskserver läuft als eigener daemon im System, ähnlich cron. + Kleinere neue Features und Detailverbesserungen: - Beim Laden von Rechnungsentwürfen, das Fälligkeits- und Rechnungsdatum duch @@ -28,6 +41,9 @@ - Bugfix 1597: Report Lagerbestand wirft Fehler, wenn Artikelnummer ausgeblendet werden soll - Bugfix 1569: Zahlungseingang löschen bei Rechnung - Bugfix 1632: Nach Installation 2.6.2-0 aus .deb funktioniert CSV-Import nicht + - Bugfix 1633: Stammdatenaufruf aus SEPA-Modul + - Bugfix 1575: Kundenrabatt geht verloren + - Bugfix 1647: Lieferanten-Einkaufspreise verlieren Nachkommastellen 2011-02-02 - Release 2.6.2 diff --git a/doc/konfigurationsdatei.txt b/doc/konfigurationsdatei.txt new file mode 100644 index 000000000..18a9e3c27 --- /dev/null +++ b/doc/konfigurationsdatei.txt @@ -0,0 +1,70 @@ +== Lx-Office Konfigurationsdatei ab Version 2.6.3 == + +Seit Lx-Office 2.6.3. findet sich die Hauptconfigurationsdatei von Lx-Office in +der Datei config/lx_office.conf. + +Diese muß bei der Erstinstallation von Lx-Office (oder Migration von älteren +Versionen) angelegt werden, als Vorlage dient die Datei +config/lx_office.conf.default. Die Datei lx_office.conf ist eine +installationsspezifische Datei, enthält z.B. die wichtigsten Passwörter der +lokalen Installation, und findet sich auch nicht im Git Repository. Diese +Konfigurationsdatei ist unabhängig von den verschiedenen Mandanten, die auf der +Installation laufen. + +Die Konfigurationsdatei besteht aus mehreren Teilen, die entsprechend +kommentiert sind: + +* authentication +* authentication/database +* authentication/ldap +* system +* features +* paths +* applications +* environment +* print_templates +* task_server +* periodic_invoices +* console +* debug + +Die üblicherweise wichtigsten Parameter, die am Anfang einzustellen oder zu +kontrollieren sind, sind: + +[authentication] +admin_password = geheim + +[authentication/database] +host = localhost +port = 5432 +db = lxerp_auth +user = postgres +password = + +[system]: +* eur +* dbcharset + +Nutzt man wiederkehrende Rechnungen kann man unter [periodic_invoices] den +Login eines Benutzers angeben, der nach Erstellung der Rechnungen eine +entsprechende E-Mail mit Informationen über die erstellten Rechnungen bekommt. + +Nutzt man den Taskserver für wiederkehrende Rechnungen, muß unter [task_server] +ein Login eines Benutzers angegeben werden, mit dem sich der Taskserver an +Lx-Office bei der Datenbank anmeldet, die dem Benutzer zugewiesen ist. + +Für Entwickler finden sich unter [debug] wichtige Funktionen, um die +Fehlersuche zu erleichtern. + + +== Versionen vor 2.6.3 == + +In älteren Lx-Office Versionen gab es im Verzeichnis config die Dateien +authentication.pl und lx-erp.conf, die jeweils Perl-Dateien waren. Es gab auch +die Möglichkeit, eine lokale Version der Konfigurationsdatei zu erstellen +(lx-erp-local.conf), dies ist ab 2.6.3 auch nicht mehr möglich/nötig. + +Beim Update von einer älteren Lx-Office Version auf 2.6.3 müssen die +Einstellungen aus den alten Konfigurationsdateien manuell übertragen werden und +die alten Konfigurationsdateien gelöscht oder verschoben werden, sonst kommt es +zu einer Fehlermeldung. diff --git a/doc/programmierstilrichtlinien.txt b/doc/programmierstilrichtlinien.txt index 67e63ecdc..4b8b20122 100644 --- a/doc/programmierstilrichtlinien.txt +++ b/doc/programmierstilrichtlinien.txt @@ -188,6 +188,6 @@ Einige der Regeln lassen sich automatisch überprüfen, andere nicht. 14. Alle neuen Module müssen use strict verwenden. - $form, $auth, $locale, $lxdebug, %myconfig sowie der Inhalt der lx-erp.conf - werden derzeit aus dem main package importiert. Alle anderen Konstrukte - sollten lexikalisch lokal gehalten werden. + $form, $auth, $locale, $lxdebug und %myconfig werden derzeit aus dem main + package importiert. Alle anderen Konstrukte sollten lexikalisch lokal + gehalten werden. diff --git a/doc/wiederkehrende_rechnungen.txt b/doc/wiederkehrende_rechnungen.txt new file mode 100755 index 000000000..fe9a07c49 --- /dev/null +++ b/doc/wiederkehrende_rechnungen.txt @@ -0,0 +1,78 @@ +Wiederkehrende Rechnungen werden als normale Aufträge definiert und +konfiguriert, mit allen dazugehörigen Kunden- und Artikelangaben. Die +konfigurierten Aufträge werden später automatisch in Rechnungen +umgewandelt, so als ob man den Workflow benutzen würde, und auch die +Auftragsnummer wird übernommen, sodass alle wiederkehrenden +Rechnungen, die aus einem Auftrag erstellt wurden, später leicht +wiederzufinden sind. + +Um einen Auftrag für wiederkehrende Rechnung zu konfigurieren, findet sich beim +Bearbeiten des Auftrags ein neuer Knopf "Konfigurieren", der ein neues Fenster +öffnet, in dem man die nötigen Parameter einstellen kann. Hinter dem Knopf +wird außerdem noch angezeigt, ob der Auftrag als wiederkehrende Rechnung +konfiguriert ist oder nicht. + +Folgende Parameter kann man konfigurieren: + +* Status: + Bei aktiven Rechnungen wird automatisch eine Rechnung erstellt, wenn die + Periodizität erreicht ist (z.B. Anfang eines neuen Monats). + + Ist ein Auftrag nicht aktiv, so werden für ihn auch keine wiederkehrenden + Rechnungen erzeugt. Stellt man nach längerer nicht-aktiver Zeit einen Auftrag + wieder auf aktiv, wird beim nächsten Periodenwechsel für alle Perioden, seit + der letzten aktiven Periode, jeweils eine Rechnung erstellt. Möchte man dies + verhindern, muss man vorher das Startdatum neu setzen. + + Für gekündigte Aufträge werden nie mehr Rechnungen erstellt. Man kann sich + diese Aufträge aber gesondert in den Berichten anzeigen lassen. + +* Periodizität: + Ob monatlich, quartalsweise oder jährlich auf neue Rechnungen überprüft + werden soll. Für jede Periode seit dem Startdatum wird überprüft, ob für die + Periode (beginnend immer mit dem ersten Tag der Periode) schon eine Rechnung + erstellt wurde. Unter Umständen können bei einem Startdatum in der + Vergangenheit gleich mehrere Rechnungen erstellt werden. + +* Buchen auf: + Das Forderungskonto, in der Regel "Forderungen aus Lieferungen + und Leistungen". Das Gegenkonto ergibt sich aus den Buchungsgruppen der + betreffenden Waren. + +* Startdatum: ab welchem Datum auf Rechnungserstellung geprüft werden soll + +* Enddatum: ab wann keine Rechnungen mehr erstellt werden sollen. + +* Automatische Verlängerung um x Monate: + Sollen die wiederkehrenden Rechnungen bei Erreichen des + eingetragenen Enddatums weiterhin erstellt werden, so kann man hier + die Anzahl der Monate eingeben, um die das Enddatum automatisch nach + hinten geschoben wird. + +* Drucken: + Sind Drucker konfiguriert, so kann man sich die erstellten Rechnungen auch + gleich ausdrucken lassen. + +Unter Verkauf->Berichte->Aufträge finden sich zwei neue Checkboxen, +"Wiederkehrende Rechnungen aktiv" und "Wiederkehrende Rechnungen inaktiv", mit +denen man sich einen Überglick über die wiederkehrenden Rechnungen verschaffen +kann. + +Die zeitliche und periodische Überprüfung, ob eine wiederkehrende +Rechnung automatisch erstellt werden soll, geschieht durch den +Taskserver, einen externen Dienst, der automatisch beim Start des +Servers gestartet werden sollte. + +Nach Erstellung der Rechnungen kann eine E-Mail mit Informationen zu +den erstellten Rechnungen verschickt werden. Konfiguriert wird dies in +der Konfigurationsdatei config/lx_office.conf im Abschnitt +[periodic_invoices]. + +Will man im laufenden Monat eine monatlich wiederkehrende Rechnung inkl. des +laufenden Monats starten, stellt man das Startdatum auf den Monatsanfang und +wartet ein paar Minuten, bis der Taskserver den neu konfigurieren Auftrag +erkennt und daraus eine Rechnung generiert hat. Alternativ setzt man das +Startdatum auf den Monatsersten des Folgemonats und erstellt die erste Rechnung +direkt manuell über den Workflow. + + diff --git a/scripts/console b/scripts/console index 78b730559..8443321e1 100755 --- a/scripts/console +++ b/scripts/console @@ -18,6 +18,7 @@ SL::LxOfficeConf->read; my $login = shift || $::lx_office_conf{console}{login} || 'demo'; my $history_file = $::lx_office_conf{console}{history_file} || '/tmp/lxoffice_console_history.log'; # fallback if users is not writable +my $debug_file = $::lx_office_conf{console}{log_file} || '/tmp/lxoffice_console_debug.log'; my $autorun = $::lx_office_conf{console}{autorun}; # will be configed eventually @@ -58,7 +59,7 @@ sub lxinit { package main; - $::lxdebug = LXDebug->new; + $::lxdebug = LXDebug->new(file => $debug_file); $::locale = Locale->new($::lx_office_conf{system}->{language}); $::cgi = CGI->new qw(); $::form = Form->new; @@ -131,7 +132,7 @@ __END__ =head1 NAME -scripts/console - Lx Office Console +scripts/console - Lx-Office console =head1 SYNOPSIS diff --git a/scripts/installation_check.pl b/scripts/installation_check.pl index ce9501534..9a28c03ca 100755 --- a/scripts/installation_check.pl +++ b/scripts/installation_check.pl @@ -29,7 +29,7 @@ sub check { my @source_texts = source_texts($module); local $" = $/; - print <{fullname} could not be loaded. diff --git a/templates/webpages/menu/header.html b/templates/webpages/menu/header.html new file mode 100644 index 000000000..359c94094 --- /dev/null +++ b/templates/webpages/menu/header.html @@ -0,0 +1,41 @@ +[%- USE T8 %] + + + + + +[% UNLESS is_links %] + +[%- END %] +[% IF show_debug %] + +[%- END %] + + +
+ [[% 'Menu' | $T8 %]] + [[% 'New Win/Tab' | $T8 %]] + [[% 'Print' | $T8 %]] + [[% 'Back' | $T8 %]] + [[% 'Fwd' | $T8 %]] + + Debug: + [FCGI Reload] + [[% IF lxdebug.level_by_name('request_timer') %]Timing[% ELSE %]Timing[% END %]] + [[% IF lxdebug.level_by_name('trace') %]Trace[% ELSE %]Trace[% END %]] + [[% IF lxdebug.level_by_name('query') %]Query[% ELSE %]Query[% END %]] + + [% 'User' | $T8 %]: + [% login %] + [[% 'Logout' | $T8 %]] + [% now.to_lxoffice %] - + [% now.hms %] +
+ + diff --git a/templates/webpages/oe/form_header.html b/templates/webpages/oe/form_header.html index ce916e6a2..a04676141 100644 --- a/templates/webpages/oe/form_header.html +++ b/templates/webpages/oe/form_header.html @@ -63,13 +63,7 @@ [% 'Contact Person' | $T8 %] - [%- INCLUDE 'generic/multibox.html' - name = 'cp_id', - style = 'width: 250px', - DATA = ALL_CONTACTS, - id_key = 'cp_id', - label_sub = 'contact_labels', - show_empty = 1 -%] + [% L.select_tag('cp_id', L.options_for_select(ALL_CONTACTS, default=cp_id, value='cp_id', title_sub=\contact_labels, with_empty=1), style='width: 250px') %] [%- END %] @@ -77,14 +71,7 @@ [% 'Shipping Address' | $T8 %] - [%- INCLUDE 'generic/multibox.html' - name = 'shipto_id', - style = 'width: 250px', - DATA = ALL_SHIPTO, - id_key = 'shipto_id', - label_sub = 'shipto_labels', - show_empty = 1, - onChange = "document.getElementById('update_button').click();" -%] + [% L.select_tag('shipto_id', L.options_for_select(ALL_SHIPTO, default=shipto_id, value='shipto_id', title_sub=\shipto_labels, with_empty=1), style='width: 250px', onChange="document.getElementById('update_button').click();") %] [%- END %] @@ -112,25 +99,14 @@ [% 'Steuersatz' | $T8 %] - [%- INCLUDE 'generic/multibox.html' - name = 'taxzone_id', - style = 'width: 250px', - DATA = ALL_TAXZONES, - id_key = 'id', - label_key = 'description' -%] + [% L.select_tag('taxzone_id', L.options_for_select(ALL_TAXZONES, default=taxzone_id, title='description'), style='width: 250px') %] [%- IF ALL_DEPARTMENTS %] [% 'Department' | $T8 %] - [%- INCLUDE 'generic/multibox.html' - name = 'department_id', - style = 'width: 250px', - DATA = ALL_DEPARTMENTS, - id_key = 'id', - label_sub = 'department_labels', - show_empty = 1 -%] + [% L.select_tag('department_id', L.options_for_select(ALL_DEPARTMENTS, default=department_id, title_sub=\department_labels, with_empty=1), style='width:250px') %] [%- END %] @@ -195,23 +171,14 @@ [% 'Employee' | $T8 %] - [%- INCLUDE 'generic/multibox.html' - name = 'employee_id', - DATA = ALL_EMPLOYEES, - id_key = 'id', - label_sub = 'sales_employee_labels' -%] + [% L.select_tag('employee_id', L.options_for_select(ALL_EMPLOYEES, default=employee_id, title_sub=\sales_employee_labels)) %] [%- IF is_sales and ALL_SALESMEN.size %] [% 'Salesman' | $T8 %] - [%- INCLUDE 'generic/multibox.html' - name = 'salesman_id', - default = salesman_id ? salesman_id : employee_id, - DATA = ALL_SALESMEN, - id_key = 'id', - label_sub = 'sales_employee_labels' -%] + [% L.select_tag('salesman_id', L.options_for_select(ALL_SALESMEN, default=(salesman_id ? salesman_id : employee_id), title_sub=\sales_employee_labels)) %] [%- END %] @@ -262,13 +229,7 @@ [% 'Project Number' | $T8 %] - [%- INCLUDE 'generic/multibox.html' - name = 'globalproject_id', - DATA = ALL_PROJECTS, - id_key = 'id', - label_key = 'projectnumber', - show_empty = 1, - onChange = "document.getElementById('update_button').click();" -%] + [%- L.select_tag('globalproject_id', L.options_for_select(ALL_PROJECTS, title='projectnumber', default=globalproject_id, with_empty='1'), onChange="document.getElementById('update_button').click();") %]