From 54e4131e091831e00a861fe2c4f53e344b87ddca Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Mon, 13 Nov 2006 16:49:57 +0000 Subject: [PATCH] Uebernahme der kompletten Version, so wie sie Philip als "Demo-Version" gezeigt hat, in das unstable-Repo. Dabei werden auch einige Patches, die seit der 2.2.0 hier eingepflegt wurden, wieder ueberschrieben. Diese werden in den naechsten Tagen wieder eingespielt, sofern noetig. Zu den neuen Features gehoeren (ohne Anspruch auf Vollstaendigkeit) Mahnwesen, Einheiten, Template-Neucodierung, AJAX-basierende Dialoge an einigen Stellen, Buchungsgruppen etc etc. --- SL/AM.pm | 1062 +++++++++-- SL/AP.pm | 29 +- SL/AR.pm | 31 +- SL/BP.pm | 6 +- SL/CP.pm | 9 +- SL/CT.pm | 331 +++- SL/Common.pm | 179 ++ SL/DATEV.pm | 2 +- SL/DN.pm | 497 +++++ SL/Form.pm | 798 ++++---- SL/GL.pm | 139 +- SL/IC.pm | 336 +++- SL/IR.pm | 343 +++- SL/IS.pm | 877 +++++++-- SL/LICENSES.pm | 2 +- SL/LXDebug.pm | 38 +- SL/Menu.pm | 9 +- SL/OE.pm | 280 ++- SL/RC.pm | 2 +- SL/Template.pm | 838 ++++++++ SL/USTVA.pm | 212 +- VERSION | 2 +- bin/mozilla/admin.pl | 12 +- bin/mozilla/am.pl | 1697 +++++++++++++++-- bin/mozilla/ap.pl | 4 +- bin/mozilla/arap.pl | 5 +- bin/mozilla/bp.pl | 7 - bin/mozilla/cn.pl | 1223 ++++++++++++ bin/mozilla/common.pl | 453 ++++- bin/mozilla/cp.pl | 16 +- bin/mozilla/ct.pl | 965 ++++++++-- bin/mozilla/dn.pl | 983 ++++++++++ bin/mozilla/gl.pl | 4 +- bin/mozilla/ic.pl | 453 ++++- bin/mozilla/io.pl | 336 +++- bin/mozilla/ir.pl | 149 +- bin/mozilla/is.pl | 511 ++++- bin/mozilla/menu.pl | 40 +- bin/mozilla/oe.pl | 332 +++- bin/mozilla/rc.pl | 8 +- bin/mozilla/rp.pl | 87 +- bin/mozilla/ustva.pl | 56 +- css/shade.gif | Bin 0 -> 946 bytes css/shadeactive.gif | Bin 0 -> 838 bytes css/tabcontent.css | 63 + doc/INSTALL | 63 +- doc/changelog | 12 + ... => dokumentenvorlagen-und-variablen.html} | 169 +- image/Dunning Process.png | Bin 0 -> 761 bytes js/calculate_qty.js | 22 + js/common.js | 24 + js/delivery_customer_selection.js | 14 + js/dunning.js | 15 + js/highlight_input.js | 40 + js/parts_language_selection.js | 14 + js/tabcontent.js | 82 + js/vendor_selection.js | 14 + js/wz_tooltip.js | 478 +++++ locale/de/all | 255 ++- locale/de/am | 117 +- locale/de/cn | 253 +++ locale/de/common | 35 +- locale/de/ct | 39 +- locale/de/dn | 230 +++ locale/de/gl | 6 +- locale/de/ic | 41 +- locale/de/io | 13 + locale/de/ir | 28 +- locale/de/is | 42 +- locale/de/menu | 30 +- locale/de/menunew | 30 +- locale/de/oe | 22 + locale/de/rc | 2 +- locale/de/rp | 2 +- locale/de/ustva | 1 + lx-erp.conf | 23 +- makesymlinks | 4 +- menu.ini | 137 ++ sql/Germany-DATEV-SKR03EU-chart.sql | 4 +- .../Pg-upgrade-2.2.0.10-2.2.0.11.sql | 8 + .../Pg-upgrade-2.2.0.11-2.2.0.12.sql | 3 + .../Pg-upgrade-2.2.0.12-2.2.0.13.sql | 37 + .../Pg-upgrade-2.2.0.13-2.2.0.14.sql | 3 + .../Pg-upgrade-2.2.0.14-2.2.0.15.sql | 2 + .../Pg-upgrade-2.2.0.15-2.2.0.16.sql | 14 + .../Pg-upgrade-2.2.0.16-2.2.0.17.sql | 4 + .../Pg-upgrade-2.2.0.17-2.2.0.18.sql | 40 + .../Pg-upgrade-2.2.0.18-2.2.0.19.sql | 1 + .../Pg-upgrade-2.2.0.19-2.2.0.20.sql | 9 + sql/Pg-upgrade/Pg-upgrade-2.2.0.2-2.2.0.3.sql | 43 + .../Pg-upgrade-2.2.0.20-2.2.0.21.sql | 3 + .../Pg-upgrade-2.2.0.21-2.2.0.22.sql | 3 + sql/Pg-upgrade/Pg-upgrade-2.2.0.3-2.2.0.4.sql | 52 + sql/Pg-upgrade/Pg-upgrade-2.2.0.4-2.2.0.5.sql | 2 + sql/Pg-upgrade/Pg-upgrade-2.2.0.5-2.2.0.6.sql | 2 + sql/Pg-upgrade/Pg-upgrade-2.2.0.6-2.2.0.7.sql | 53 + sql/Pg-upgrade/Pg-upgrade-2.2.0.7-2.2.0.8.sql | 6 + sql/Pg-upgrade/Pg-upgrade-2.2.0.8-2.2.0.9.sql | 2 + .../Pg-upgrade-2.2.0.9-2.2.0.10.sql | 4 + sql/lx-office.sql | 47 +- templates/German-invoice.tex | 217 +-- templates/German-packing_list.tex | 157 +- templates/German-sales_order.tex | 180 +- templates/webpages/am/edit_units_de.html | 129 ++ templates/webpages/am/edit_units_master.html | 129 ++ templates/webpages/dunning/set_email_de.html | 44 + .../webpages/dunning/set_email_master.html | 44 + .../webpages/generic/calculate_alu_de.html | 162 ++ .../generic/calculate_alu_master.html | 162 ++ .../webpages/generic/calculate_qty_de.html | 83 + .../generic/calculate_qty_master.html | 83 + templates/webpages/generic/error.html | 14 + templates/webpages/generic/error_de.html | 2 +- .../webpages/generic/information_de.html | 14 + .../webpages/generic/information_master.html | 14 + .../generic/parts_language_selection_de.html | 62 + .../generic/select_delivery_customer_de.html | 62 + .../select_delivery_customer_master.html | 62 + .../webpages/generic/select_vendor_de.html | 62 + .../generic/select_vendor_master.html | 62 + .../generic/set_longdescription_de.html | 37 + .../generic/set_longdescription_master.html | 37 + .../ic/parts_language_selection_de.html | 63 + .../ic/parts_language_selection_master.html | 63 + .../user/autotext/mytexts.bau | Bin 0 -> 567 bytes .../user/basic/Standard/Module1.xba | 7 + .../user/basic/Standard/dialog.xlb | 3 + .../user/basic/Standard/script.xlb | 5 + users/.openoffice.org2/user/basic/dialog.xlc | 15 + users/.openoffice.org2/user/basic/script.xlc | 15 + .../user/config/arrowhd_de.soe | 28 + .../user/config/arrowhd_en-US.soe | 28 + .../.openoffice.org2/user/config/autotbl.fmt | Bin 0 -> 48408 bytes .../user/config/classic_de.sog | 141 ++ .../user/config/classic_en-US.sog | 141 ++ users/.openoffice.org2/user/config/cmyk.soc | 220 +++ .../.openoffice.org2/user/config/gallery.soc | 65 + .../user/config/hatching_de.soh | 39 + .../user/config/hatching_en-US.soh | 39 + users/.openoffice.org2/user/config/html.soc | 135 ++ .../user/config/javasettings_Linux_x86.xml | 16 + .../user/config/modern_de.sog | 31 + .../user/config/modern_en-US.sog | 31 + .../user/config/palette_de.soc | 81 + .../user/config/palette_en-US.soc | 81 + .../global/accelerator/en-US/current.xml | 28 + .../swriter/accelerator/en-US/current.xml | 110 ++ .../user/config/styles_de.sod | 10 + .../user/config/styles_en-US.sod | 10 + .../user/config/sun-color.soc | 55 + users/.openoffice.org2/user/config/web.soc | 236 +++ users/.openoffice.org2/user/gallery/sg100.sdv | Bin 0 -> 2048 bytes users/.openoffice.org2/user/gallery/sg100.thm | Bin 0 -> 538 bytes users/.openoffice.org2/user/gallery/sg30.sdv | Bin 0 -> 2048 bytes users/.openoffice.org2/user/gallery/sg30.thm | Bin 0 -> 565 bytes .../data/org/openoffice/Office/Common.xcu | 20 + .../data/org/openoffice/Office/Linguistic.xcu | 8 + .../data/org/openoffice/Office/Recovery.xcu | 6 + .../Office/UI/WriterWindowState.xcu | 57 + .../data/org/openoffice/Office/Views.xcu | 64 + .../registry/data/org/openoffice/Setup.xcu | 20 + xvfb-run | 102 + 162 files changed, 17696 insertions(+), 2120 deletions(-) create mode 100644 SL/Common.pm create mode 100644 SL/DN.pm create mode 100644 SL/Template.pm create mode 100644 bin/mozilla/cn.pl create mode 100644 bin/mozilla/dn.pl create mode 100644 css/shade.gif create mode 100644 css/shadeactive.gif create mode 100644 css/tabcontent.css rename doc/{latex-template-variablen.html => dokumentenvorlagen-und-variablen.html} (76%) create mode 100644 image/Dunning Process.png create mode 100644 js/calculate_qty.js create mode 100644 js/common.js create mode 100644 js/delivery_customer_selection.js create mode 100644 js/dunning.js create mode 100644 js/highlight_input.js create mode 100644 js/parts_language_selection.js create mode 100644 js/tabcontent.js create mode 100644 js/vendor_selection.js create mode 100644 js/wz_tooltip.js create mode 100644 locale/de/cn create mode 100644 locale/de/dn create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.10-2.2.0.11.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.11-2.2.0.12.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.12-2.2.0.13.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.13-2.2.0.14.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.14-2.2.0.15.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.15-2.2.0.16.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.16-2.2.0.17.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.17-2.2.0.18.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.18-2.2.0.19.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.19-2.2.0.20.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.2-2.2.0.3.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.20-2.2.0.21.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.21-2.2.0.22.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.3-2.2.0.4.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.4-2.2.0.5.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.5-2.2.0.6.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.6-2.2.0.7.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.7-2.2.0.8.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.8-2.2.0.9.sql create mode 100644 sql/Pg-upgrade/Pg-upgrade-2.2.0.9-2.2.0.10.sql create mode 100644 templates/webpages/am/edit_units_de.html create mode 100644 templates/webpages/am/edit_units_master.html create mode 100644 templates/webpages/dunning/set_email_de.html create mode 100644 templates/webpages/dunning/set_email_master.html create mode 100644 templates/webpages/generic/calculate_alu_de.html create mode 100644 templates/webpages/generic/calculate_alu_master.html create mode 100644 templates/webpages/generic/calculate_qty_de.html create mode 100644 templates/webpages/generic/calculate_qty_master.html create mode 100644 templates/webpages/generic/error.html create mode 100644 templates/webpages/generic/information_de.html create mode 100644 templates/webpages/generic/information_master.html create mode 100644 templates/webpages/generic/parts_language_selection_de.html create mode 100644 templates/webpages/generic/select_delivery_customer_de.html create mode 100644 templates/webpages/generic/select_delivery_customer_master.html create mode 100644 templates/webpages/generic/select_vendor_de.html create mode 100644 templates/webpages/generic/select_vendor_master.html create mode 100644 templates/webpages/generic/set_longdescription_de.html create mode 100644 templates/webpages/generic/set_longdescription_master.html create mode 100644 templates/webpages/ic/parts_language_selection_de.html create mode 100644 templates/webpages/ic/parts_language_selection_master.html create mode 100644 users/.openoffice.org2/user/autotext/mytexts.bau create mode 100644 users/.openoffice.org2/user/basic/Standard/Module1.xba create mode 100644 users/.openoffice.org2/user/basic/Standard/dialog.xlb create mode 100644 users/.openoffice.org2/user/basic/Standard/script.xlb create mode 100644 users/.openoffice.org2/user/basic/dialog.xlc create mode 100644 users/.openoffice.org2/user/basic/script.xlc create mode 100644 users/.openoffice.org2/user/config/arrowhd_de.soe create mode 100644 users/.openoffice.org2/user/config/arrowhd_en-US.soe create mode 100644 users/.openoffice.org2/user/config/autotbl.fmt create mode 100644 users/.openoffice.org2/user/config/classic_de.sog create mode 100644 users/.openoffice.org2/user/config/classic_en-US.sog create mode 100644 users/.openoffice.org2/user/config/cmyk.soc create mode 100644 users/.openoffice.org2/user/config/gallery.soc create mode 100644 users/.openoffice.org2/user/config/hatching_de.soh create mode 100644 users/.openoffice.org2/user/config/hatching_en-US.soh create mode 100644 users/.openoffice.org2/user/config/html.soc create mode 100644 users/.openoffice.org2/user/config/javasettings_Linux_x86.xml create mode 100644 users/.openoffice.org2/user/config/modern_de.sog create mode 100644 users/.openoffice.org2/user/config/modern_en-US.sog create mode 100644 users/.openoffice.org2/user/config/palette_de.soc create mode 100644 users/.openoffice.org2/user/config/palette_en-US.soc create mode 100644 users/.openoffice.org2/user/config/soffice.cfg/global/accelerator/en-US/current.xml create mode 100644 users/.openoffice.org2/user/config/soffice.cfg/modules/swriter/accelerator/en-US/current.xml create mode 100644 users/.openoffice.org2/user/config/styles_de.sod create mode 100644 users/.openoffice.org2/user/config/styles_en-US.sod create mode 100644 users/.openoffice.org2/user/config/sun-color.soc create mode 100644 users/.openoffice.org2/user/config/web.soc create mode 100644 users/.openoffice.org2/user/gallery/sg100.sdv create mode 100644 users/.openoffice.org2/user/gallery/sg100.thm create mode 100644 users/.openoffice.org2/user/gallery/sg30.sdv create mode 100644 users/.openoffice.org2/user/gallery/sg30.thm create mode 100644 users/.openoffice.org2/user/registry/data/org/openoffice/Office/Common.xcu create mode 100644 users/.openoffice.org2/user/registry/data/org/openoffice/Office/Linguistic.xcu create mode 100644 users/.openoffice.org2/user/registry/data/org/openoffice/Office/Recovery.xcu create mode 100644 users/.openoffice.org2/user/registry/data/org/openoffice/Office/UI/WriterWindowState.xcu create mode 100644 users/.openoffice.org2/user/registry/data/org/openoffice/Office/Views.xcu create mode 100644 users/.openoffice.org2/user/registry/data/org/openoffice/Setup.xcu create mode 100755 xvfb-run diff --git a/SL/AM.pm b/SL/AM.pm index a06761c04..a4b0c950c 100644 --- a/SL/AM.pm +++ b/SL/AM.pm @@ -37,6 +37,8 @@ package AM; +use Data::Dumper; + sub get_account { $main::lxdebug->enter_sub(); @@ -48,7 +50,7 @@ sub get_account { my $dbh = $form->dbconnect($myconfig); my $query = qq|SELECT c.accno, c.description, c.charttype, c.gifi_accno, - c.category, c.link, c.taxkey_id, c.pos_ustva, c.pos_bwa, c.pos_bilanz,c.pos_eur + c.category, c.link, c.taxkey_id, c.pos_ustva, c.pos_bwa, c.pos_bilanz,c.pos_eur, c.new_chart_id, c.valid_from FROM chart c WHERE c.id = $form->{id}|; @@ -88,7 +90,23 @@ sub get_account { } $sth->finish; + if ($form->{id}) { + $where = " WHERE link='$form->{link}'"; + + + # get new accounts + $query = qq|SELECT id, accno,description + FROM chart $where|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{NEWACCOUNT} }, $ref; + } + + $sth->finish; + } # check if we have any transactions $query = qq|SELECT a.trans_id FROM acc_trans a WHERE a.chart_id = $form->{id}|; @@ -99,6 +117,21 @@ sub get_account { $form->{orphaned} = !$form->{orphaned}; $sth->finish; + # check if new account is active + $form->{new_chart_valid} = 0; + if ($form->{new_chart_id}) { + $query = qq|SELECT current_date-valid_from FROM chart + WHERE id = $form->{id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my ($count) = $sth->fetchrow_array; + if ($count >=0) { + $form->{new_chart_valid} = 1; + } + $sth->finish; + } + $dbh->disconnect; $main::lxdebug->leave_sub(); @@ -145,9 +178,11 @@ sub save_account { } map({ $form->{$_} = "NULL" unless ($form->{$_}); } - qw(pos_ustva pos_bwa pos_bilanz pos_eur)); + qw(pos_ustva pos_bwa pos_bilanz pos_eur new_chart_id)); - if ($form->{id}) { + $form->{valid_from} = ($form->{valid_from}) ? "'$form->{valid_from}'" : "NULL"; + + if ($form->{id} && $form->{orphaned}) { $query = qq|UPDATE chart SET accno = '$form->{accno}', description = '$form->{description}', @@ -159,15 +194,22 @@ sub save_account { pos_ustva = $form->{pos_ustva}, pos_bwa = $form->{pos_bwa}, pos_bilanz = $form->{pos_bilanz}, - pos_eur = $form->{pos_eur} + pos_eur = $form->{pos_eur}, + new_chart_id = $form->{new_chart_id}, + valid_from = $form->{valid_from} + WHERE id = $form->{id}|; + } elsif ($form->{id} && !$form->{new_chart_valid}) { + $query = qq|UPDATE chart SET + new_chart_id = $form->{new_chart_id}, + valid_from = $form->{valid_from} WHERE id = $form->{id}|; } else { $query = qq|INSERT INTO chart - (accno, description, charttype, gifi_accno, category, link, taxkey_id, pos_ustva, pos_bwa, pos_bilanz,pos_eur) + (accno, description, charttype, gifi_accno, category, link, taxkey_id, pos_ustva, pos_bwa, pos_bilanz,pos_eur, new_chart_id, valid_from) VALUES ('$form->{accno}', '$form->{description}', '$form->{charttype}', '$form->{gifi_accno}', - '$form->{category}', '$form->{link}', $form->{taxkey_id}, $form->{pos_ustva}, $form->{pos_bwa}, $form->{pos_bilanz}, $form->{pos_eur})|; + '$form->{category}', '$form->{link}', $form->{taxkey_id}, $form->{pos_ustva}, $form->{pos_bwa}, $form->{pos_bilanz}, $form->{pos_eur}, $form->{new_chart_id}, $form->{valid_from})|; } $dbh->do($query) || $form->dberror($query); @@ -262,28 +304,545 @@ sub delete_account { WHERE income_accno_id = $form->{id}|; $dbh->do($query) || $form->dberror($query); - $query = qq|UPDATE parts - SET expense_accno_id = - (SELECT expense_accno_id FROM defaults) - WHERE expense_accno_id = $form->{id}|; + $query = qq|UPDATE parts + SET expense_accno_id = + (SELECT expense_accno_id FROM defaults) + WHERE expense_accno_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + foreach my $table (qw(partstax customertax vendortax tax)) { + $query = qq|DELETE FROM $table + WHERE chart_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + } + + # commit and redirect + my $rc = $dbh->commit; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); + + return $rc; +} + +sub gifi_accounts { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT accno, description + FROM gifi + ORDER BY accno|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub get_gifi { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT g.accno, g.description + FROM gifi g + WHERE g.accno = '$form->{accno}'|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + + $sth->finish; + + # check for transactions + $query = qq|SELECT count(*) FROM acc_trans a, chart c, gifi g + WHERE c.gifi_accno = g.accno + AND a.chart_id = c.id + AND g.accno = '$form->{accno}'|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + ($form->{orphaned}) = $sth->fetchrow_array; + $sth->finish; + $form->{orphaned} = !$form->{orphaned}; + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub save_gifi { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{description} =~ s/\'/\'\'/g; + + # id is the old account number! + if ($form->{id}) { + $query = qq|UPDATE gifi SET + accno = '$form->{accno}', + description = '$form->{description}' + WHERE accno = '$form->{id}'|; + } else { + $query = qq|INSERT INTO gifi + (accno, description) + VALUES ('$form->{accno}', '$form->{description}')|; + } + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub delete_gifi { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + # id is the old account number! + $query = qq|DELETE FROM gifi + WHERE accno = '$form->{id}'|; + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub warehouses { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT id, description + FROM warehouse + ORDER BY 2|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub get_warehouse { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT w.description + FROM warehouse w + WHERE w.id = $form->{id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + + $sth->finish; + + # see if it is in use + $query = qq|SELECT count(*) FROM inventory i + WHERE i.warehouse_id = $form->{id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + ($form->{orphaned}) = $sth->fetchrow_array; + $form->{orphaned} = !$form->{orphaned}; + $sth->finish; + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub save_warehouse { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{description} =~ s/\'/\'\'/g; + + if ($form->{id}) { + $query = qq|UPDATE warehouse SET + description = '$form->{description}' + WHERE id = $form->{id}|; + } else { + $query = qq|INSERT INTO warehouse + (description) + VALUES ('$form->{description}')|; + } + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub delete_warehouse { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $query = qq|DELETE FROM warehouse + WHERE id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub departments { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT d.id, d.description, d.role + FROM department d + ORDER BY 2|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub get_department { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT d.description, d.role + FROM department d + WHERE d.id = $form->{id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + + $sth->finish; + + # see if it is in use + $query = qq|SELECT count(*) FROM dpt_trans d + WHERE d.department_id = $form->{id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + ($form->{orphaned}) = $sth->fetchrow_array; + $form->{orphaned} = !$form->{orphaned}; + $sth->finish; + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub save_department { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{description} =~ s/\'/\'\'/g; + + if ($form->{id}) { + $query = qq|UPDATE department SET + description = '$form->{description}', + role = '$form->{role}' + WHERE id = $form->{id}|; + } else { + $query = qq|INSERT INTO department + (description, role) + VALUES ('$form->{description}', '$form->{role}')|; + } + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub delete_department { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $query = qq|DELETE FROM department + WHERE id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub business { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT id, description, discount, customernumberinit, salesman + FROM business + ORDER BY 2|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub get_business { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = + qq|SELECT b.description, b.discount, b.customernumberinit, b.salesman + FROM business b + WHERE b.id = $form->{id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + + $sth->finish; + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub save_business { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{description} =~ s/\'/\'\'/g; + $form->{discount} /= 100; + $form->{salesman} *= 1; + + # id is the old record + if ($form->{id}) { + $query = qq|UPDATE business SET + description = '$form->{description}', + discount = $form->{discount}, + customernumberinit = '$form->{customernumberinit}', + salesman = '$form->{salesman}' + WHERE id = $form->{id}|; + } else { + $query = qq|INSERT INTO business + (description, discount, customernumberinit, salesman) + VALUES ('$form->{description}', $form->{discount}, '$form->{customernumberinit}', '$form->{salesman}')|; + } + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub delete_business { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $query = qq|DELETE FROM business + WHERE id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + + +sub language { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT id, description, template_code, article_code + FROM language + ORDER BY 2|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub get_language { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = + qq|SELECT l.description, l.template_code, l.article_code + FROM language l + WHERE l.id = $form->{id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + + $sth->finish; + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub save_language { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{description} =~ s/\'/\'\'/g; + $form->{article_code} =~ s/\'/\'\'/g; + $form->{template_code} =~ s/\'/\'\'/g; + + + # id is the old record + if ($form->{id}) { + $query = qq|UPDATE language SET + description = '$form->{description}', + template_code = '$form->{template_code}', + article_code = '$form->{article_code}' + WHERE id = $form->{id}|; + } else { + $query = qq|INSERT INTO language + (description, template_code, article_code) + VALUES ('$form->{description}', '$form->{template_code}', '$form->{article_code}')|; + } + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub delete_language { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $query = qq|DELETE FROM language + WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); - foreach my $table (qw(partstax customertax vendortax tax)) { - $query = qq|DELETE FROM $table - WHERE chart_id = $form->{id}|; - $dbh->do($query) || $form->dberror($query); - } - - # commit and redirect - my $rc = $dbh->commit; $dbh->disconnect; $main::lxdebug->leave_sub(); - - return $rc; } -sub gifi_accounts { + +sub buchungsgruppe { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -291,9 +850,9 @@ sub gifi_accounts { # connect to database my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT accno, description - FROM gifi - ORDER BY accno|; + my $query = qq|SELECT id, description, inventory_accno_id, (select accno from chart where id=inventory_accno_id) as inventory_accno, income_accno_id_0, (select accno from chart where id=income_accno_id_0) as income_accno_0, expense_accno_id_0, (select accno from chart where id=expense_accno_id_0) as expense_accno_0, income_accno_id_1, (select accno from chart where id=income_accno_id_1) as income_accno_1, expense_accno_id_1, (select accno from chart where id=expense_accno_id_1) as expense_accno_1, income_accno_id_2, (select accno from chart where id=income_accno_id_2) as income_accno_2, expense_accno_id_2, (select accno from chart where id=expense_accno_id_2) as expense_accno_2, income_accno_id_3, (select accno from chart where id=income_accno_id_3) as income_accno_3, expense_accno_id_3, (select accno from chart where id=expense_accno_id_3) as expense_accno_3 + FROM buchungsgruppen + ORDER BY id|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); @@ -308,7 +867,7 @@ sub gifi_accounts { $main::lxdebug->leave_sub(); } -sub get_gifi { +sub get_buchungsgruppe { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -316,36 +875,74 @@ sub get_gifi { # connect to database my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT g.accno, g.description - FROM gifi g - WHERE g.accno = '$form->{accno}'|; - my $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); - - my $ref = $sth->fetchrow_hashref(NAME_lc); + if ($form->{id}) { + my $query = + qq|SELECT description, inventory_accno_id, (select accno from chart where id=inventory_accno_id) as inventory_accno, income_accno_id_0, (select accno from chart where id=income_accno_id_0) as income_accno_0, expense_accno_id_0, (select accno from chart where id=expense_accno_id_0) as expense_accno_0, income_accno_id_1, (select accno from chart where id=income_accno_id_1) as income_accno_1, expense_accno_id_1, (select accno from chart where id=expense_accno_id_1) as expense_accno_1, income_accno_id_2, (select accno from chart where id=income_accno_id_2) as income_accno_2, expense_accno_id_2, (select accno from chart where id=expense_accno_id_2) as expense_accno_2, income_accno_id_3, (select accno from chart where id=income_accno_id_3) as income_accno_3, expense_accno_id_3, (select accno from chart where id=expense_accno_id_3) as expense_accno_3 + FROM buchungsgruppen + WHERE id = $form->{id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + + $sth->finish; + + my $query = + qq|SELECT count(id) as anzahl + FROM parts + WHERE buchungsgruppen_id = $form->{id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + if (!$ref->{anzahl}) { + $form->{orphaned} = 1; + } + $sth->finish; - map { $form->{$_} = $ref->{$_} } keys %$ref; + } + my $module = "IC"; + $query = qq|SELECT c.accno, c.description, c.link, c.id, + d.inventory_accno_id, d.income_accno_id, d.expense_accno_id + FROM chart c, defaults d + WHERE c.link LIKE '%$module%' + ORDER BY c.accno|; - $sth->finish; - # check for transactions - $query = qq|SELECT count(*) FROM acc_trans a, chart c, gifi g - WHERE c.gifi_accno = g.accno - AND a.chart_id = c.id - AND g.accno = '$form->{accno}'|; - $sth = $dbh->prepare($query); + my $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); - - ($form->{orphaned}) = $sth->fetchrow_array; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + foreach my $key (split /:/, $ref->{link}) { + if ($key =~ /$module/) { + if ( ($ref->{id} eq $ref->{inventory_accno_id}) + || ($ref->{id} eq $ref->{income_accno_id}) + || ($ref->{id} eq $ref->{expense_accno_id})) { + push @{ $form->{"${module}_links"}{$key} }, + { accno => $ref->{accno}, + description => $ref->{description}, + selected => "selected", + id => $ref->{id} }; + } else { + push @{ $form->{"${module}_links"}{$key} }, + { accno => $ref->{accno}, + description => $ref->{description}, + selected => "", + id => $ref->{id} }; + } + } + } + } $sth->finish; - $form->{orphaned} = !$form->{orphaned}; + $dbh->disconnect; $main::lxdebug->leave_sub(); } -sub save_gifi { +sub save_buchungsgruppe { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -355,16 +952,25 @@ sub save_gifi { $form->{description} =~ s/\'/\'\'/g; - # id is the old account number! + + # id is the old record if ($form->{id}) { - $query = qq|UPDATE gifi SET - accno = '$form->{accno}', - description = '$form->{description}' - WHERE accno = '$form->{id}'|; + $query = qq|UPDATE buchungsgruppen SET + description = '$form->{description}', + inventory_accno_id = '$form->{inventory_accno_id}', + income_accno_id_0 = '$form->{income_accno_id_0}', + expense_accno_id_0 = '$form->{expense_accno_id_0}', + income_accno_id_1 = '$form->{income_accno_id_1}', + expense_accno_id_1 = '$form->{expense_accno_id_1}', + income_accno_id_2 = '$form->{income_accno_id_2}', + expense_accno_id_2 = '$form->{expense_accno_id_2}', + income_accno_id_3 = '$form->{income_accno_id_3}', + expense_accno_id_3 = '$form->{expense_accno_id_3}' + WHERE id = $form->{id}|; } else { - $query = qq|INSERT INTO gifi - (accno, description) - VALUES ('$form->{accno}', '$form->{description}')|; + $query = qq|INSERT INTO buchungsgruppen + (description, inventory_accno_id, income_accno_id_0, expense_accno_id_0, income_accno_id_1, expense_accno_id_1, income_accno_id_2, expense_accno_id_2, income_accno_id_3, expense_accno_id_3) + VALUES ('$form->{description}', '$form->{inventory_accno_id}', '$form->{income_accno_id_0}', '$form->{expense_accno_id_0}', '$form->{income_accno_id_1}', '$form->{expense_accno_id_1}', '$form->{income_accno_id_2}', '$form->{expense_accno_id_2}', '$form->{income_accno_id_3}', '$form->{expense_accno_id_3}')|; } $dbh->do($query) || $form->dberror($query); @@ -373,7 +979,7 @@ sub save_gifi { $main::lxdebug->leave_sub(); } -sub delete_gifi { +sub delete_buchungsgruppe { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -381,9 +987,8 @@ sub delete_gifi { # connect to database my $dbh = $form->dbconnect($myconfig); - # id is the old account number! - $query = qq|DELETE FROM gifi - WHERE accno = '$form->{id}'|; + $query = qq|DELETE FROM buchungsgruppe + WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); $dbh->disconnect; @@ -391,7 +996,7 @@ sub delete_gifi { $main::lxdebug->leave_sub(); } -sub warehouses { +sub printer { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -399,8 +1004,8 @@ sub warehouses { # connect to database my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT id, description - FROM warehouse + my $query = qq|SELECT id, printer_description, template_code, printer_command + FROM printers ORDER BY 2|; $sth = $dbh->prepare($query); @@ -416,7 +1021,7 @@ sub warehouses { $main::lxdebug->leave_sub(); } -sub get_warehouse { +sub get_printer { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -424,9 +1029,10 @@ sub get_warehouse { # connect to database my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT w.description - FROM warehouse w - WHERE w.id = $form->{id}|; + my $query = + qq|SELECT p.printer_description, p.template_code, p.printer_command + FROM printers p + WHERE p.id = $form->{id}|; my $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); @@ -436,22 +1042,12 @@ sub get_warehouse { $sth->finish; - # see if it is in use - $query = qq|SELECT count(*) FROM inventory i - WHERE i.warehouse_id = $form->{id}|; - $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); - - ($form->{orphaned}) = $sth->fetchrow_array; - $form->{orphaned} = !$form->{orphaned}; - $sth->finish; - $dbh->disconnect; $main::lxdebug->leave_sub(); } -sub save_warehouse { +sub save_printer { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -459,16 +1055,22 @@ sub save_warehouse { # connect to database my $dbh = $form->dbconnect($myconfig); - $form->{description} =~ s/\'/\'\'/g; + $form->{printer_description} =~ s/\'/\'\'/g; + $form->{printer_command} =~ s/\'/\'\'/g; + $form->{template_code} =~ s/\'/\'\'/g; + + # id is the old record if ($form->{id}) { - $query = qq|UPDATE warehouse SET - description = '$form->{description}' + $query = qq|UPDATE printers SET + printer_description = '$form->{printer_description}', + template_code = '$form->{template_code}', + printer_command = '$form->{printer_command}' WHERE id = $form->{id}|; } else { - $query = qq|INSERT INTO warehouse - (description) - VALUES ('$form->{description}')|; + $query = qq|INSERT INTO printers + (printer_description, template_code, printer_command) + VALUES ('$form->{printer_description}', '$form->{template_code}', '$form->{printer_command}')|; } $dbh->do($query) || $form->dberror($query); @@ -477,7 +1079,7 @@ sub save_warehouse { $main::lxdebug->leave_sub(); } -sub delete_warehouse { +sub delete_printer { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -485,7 +1087,7 @@ sub delete_warehouse { # connect to database my $dbh = $form->dbconnect($myconfig); - $query = qq|DELETE FROM warehouse + $query = qq|DELETE FROM printers WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); @@ -494,7 +1096,7 @@ sub delete_warehouse { $main::lxdebug->leave_sub(); } -sub departments { +sub adr { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -502,9 +1104,9 @@ sub departments { # connect to database my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT d.id, d.description, d.role - FROM department d - ORDER BY 2|; + my $query = qq|SELECT id, adr_description, adr_code + FROM adr + ORDER BY adr_code|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); @@ -519,7 +1121,7 @@ sub departments { $main::lxdebug->leave_sub(); } -sub get_department { +sub get_adr { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -527,9 +1129,10 @@ sub get_department { # connect to database my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT d.description, d.role - FROM department d - WHERE d.id = $form->{id}|; + my $query = + qq|SELECT a.adr_description, a.adr_code + FROM adr a + WHERE a.id = $form->{id}|; my $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); @@ -539,22 +1142,12 @@ sub get_department { $sth->finish; - # see if it is in use - $query = qq|SELECT count(*) FROM dpt_trans d - WHERE d.department_id = $form->{id}|; - $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); - - ($form->{orphaned}) = $sth->fetchrow_array; - $form->{orphaned} = !$form->{orphaned}; - $sth->finish; - $dbh->disconnect; $main::lxdebug->leave_sub(); } -sub save_department { +sub save_adr { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -562,17 +1155,20 @@ sub save_department { # connect to database my $dbh = $form->dbconnect($myconfig); - $form->{description} =~ s/\'/\'\'/g; + $form->{adr_description} =~ s/\'/\'\'/g; + $form->{adr_code} =~ s/\'/\'\'/g; + + # id is the old record if ($form->{id}) { - $query = qq|UPDATE department SET - description = '$form->{description}', - role = '$form->{role}' + $query = qq|UPDATE adr SET + adr_description = '$form->{adr_description}', + adr_code = '$form->{adr_code}' WHERE id = $form->{id}|; } else { - $query = qq|INSERT INTO department - (description, role) - VALUES ('$form->{description}', '$form->{role}')|; + $query = qq|INSERT INTO adr + (adr_description, adr_code) + VALUES ('$form->{adr_description}', '$form->{adr_code}')|; } $dbh->do($query) || $form->dberror($query); @@ -581,7 +1177,7 @@ sub save_department { $main::lxdebug->leave_sub(); } -sub delete_department { +sub delete_adr { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -589,7 +1185,7 @@ sub delete_department { # connect to database my $dbh = $form->dbconnect($myconfig); - $query = qq|DELETE FROM department + $query = qq|DELETE FROM adr WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); @@ -598,7 +1194,7 @@ sub delete_department { $main::lxdebug->leave_sub(); } -sub business { +sub payment { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -606,14 +1202,15 @@ sub business { # connect to database my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT id, description, discount, customernumberinit, salesman - FROM business - ORDER BY 2|; + my $query = qq|SELECT * + FROM payment_terms + ORDER BY id|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); - while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + $ref->{percent_skonto} = $form->format_amount($myconfig,($ref->{percent_skonto} * 100)); push @{ $form->{ALL} }, $ref; } @@ -623,7 +1220,7 @@ sub business { $main::lxdebug->leave_sub(); } -sub get_business { +sub get_payment { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -632,13 +1229,14 @@ sub get_business { my $dbh = $form->dbconnect($myconfig); my $query = - qq|SELECT b.description, b.discount, b.customernumberinit, b.salesman - FROM business b - WHERE b.id = $form->{id}|; + qq|SELECT * + FROM payment_terms + WHERE id = $form->{id}|; my $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); my $ref = $sth->fetchrow_hashref(NAME_lc); + $ref->{percent_skonto} = $form->format_amount($myconfig,($ref->{percent_skonto} * 100)); map { $form->{$_} = $ref->{$_} } keys %$ref; @@ -649,7 +1247,7 @@ sub get_business { $main::lxdebug->leave_sub(); } -sub save_business { +sub save_payment { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -658,21 +1256,29 @@ sub save_business { my $dbh = $form->dbconnect($myconfig); $form->{description} =~ s/\'/\'\'/g; - $form->{discount} /= 100; - $form->{salesman} *= 1; + $form->{description_long} =~ s/\'/\'\'/g; + $percentskonto = $form->parse_amount($myconfig, $form->{percent_skonto}) /100; + $form->{ranking} *= 1; + $form->{terms_netto} *= 1; + $form->{terms_skonto} *= 1; + $form->{percent_skonto} *= 1; + + # id is the old record if ($form->{id}) { - $query = qq|UPDATE business SET + $query = qq|UPDATE payment_terms SET description = '$form->{description}', - discount = $form->{discount}, - customernumberinit = '$form->{customernumberinit}', - salesman = '$form->{salesman}' + ranking = $form->{ranking}, + description_long = '$form->{description_long}', + terms_netto = $form->{terms_netto}, + terms_skonto = $form->{terms_skonto}, + percent_skonto = $percentskonto WHERE id = $form->{id}|; } else { - $query = qq|INSERT INTO business - (description, discount, customernumberinit, salesman) - VALUES ('$form->{description}', $form->{discount}, '$form->{customernumberinit}', '$form->{salesman}')|; + $query = qq|INSERT INTO payment_terms + (description, ranking, description_long, terms_netto, terms_skonto, percent_skonto) + VALUES ('$form->{description}', $form->{ranking}, '$form->{description_long}', $form->{terms_netto}, $form->{terms_skonto}, $percentskonto)|; } $dbh->do($query) || $form->dberror($query); @@ -681,7 +1287,7 @@ sub save_business { $main::lxdebug->leave_sub(); } -sub delete_business { +sub delete_payment { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; @@ -689,7 +1295,7 @@ sub delete_business { # connect to database my $dbh = $form->dbconnect($myconfig); - $query = qq|DELETE FROM business + $query = qq|DELETE FROM payment_terms WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); @@ -863,6 +1469,7 @@ sub save_preferences { (SELECT c.id FROM chart c WHERE c.accno = '$form->{fxloss_accno}'), invnumber = '$form->{invnumber}', + cnnumber = '$form->{cnnumber}', sonumber = '$form->{sonumber}', ponumber = '$form->{ponumber}', sqnumber = '$form->{sqnumber}', @@ -1355,4 +1962,197 @@ sub closebooks { $main::lxdebug->leave_sub(); } +sub get_base_unit { + my ($self, $units, $unit_name, $factor) = @_; + + $factor = 1 unless ($factor); + + my $unit = $units->{$unit_name}; + + if (!defined($unit) || !$unit->{"base_unit"} || + ($unit_name eq $unit->{"base_unit"})) { + return ($unit_name, $factor); + } + + return AM->get_base_unit($units, $unit->{"base_unit"}, $factor * $unit->{"factor"}); +} + +sub retrieve_units { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $type, $prefix) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my $query = "SELECT *, base_unit AS original_base_unit FROM units"; + my @values; + if ($type) { + $query .= " WHERE (type = ?)"; + @values = ($type); + } + + my $sth = $dbh->prepare($query); + $sth->execute(@values) || $form->dberror($query . " (" . join(", ", @values) . ")"); + + my $units = {}; + while (my $ref = $sth->fetchrow_hashref()) { + $units->{$ref->{"name"}} = $ref; + } + $sth->finish(); + + foreach my $unit (keys(%{$units})) { + ($units->{$unit}->{"${prefix}base_unit"}, $units->{$unit}->{"${prefix}factor"}) = AM->get_base_unit($units, $unit); + } + + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); + + return $units; +} + +sub units_in_use { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $units) = @_; + + my $dbh = $form->dbconnect($myconfig); + + foreach my $unit (values(%{$units})) { + my $base_unit = $unit->{"original_base_unit"}; + while ($base_unit) { + $units->{$base_unit}->{"DEPENDING_UNITS"} = [] unless ($units->{$base_unit}->{"DEPENDING_UNITS"}); + push(@{$units->{$base_unit}->{"DEPENDING_UNITS"}}, $unit->{"name"}); + $base_unit = $units->{$base_unit}->{"original_base_unit"}; + } + } + + foreach my $unit (values(%{$units})) { + $unit->{"in_use"} = 0; + map({ $_ = $dbh->quote($_); } @{$unit->{"DEPENDING_UNITS"}}); + + foreach my $table (qw(parts invoice orderitems)) { + my $query = "SELECT COUNT(*) FROM $table WHERE unit "; + + if (0 == scalar(@{$unit->{"DEPENDING_UNITS"}})) { + $query .= "= " . $dbh->quote($unit->{"name"}); + } else { + $query .= "IN (" . $dbh->quote($unit->{"name"}) . "," . join(",", @{$unit->{"DEPENDING_UNITS"}}) . ")"; + } + + my ($count) = $dbh->selectrow_array($query); + $form->dberror($query) if ($dbh->err); + + if ($count) { + $unit->{"in_use"} = 1; + last; + } + } + } + + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); +} + +sub unit_select_data { + $main::lxdebug->enter_sub(); + + my ($self, $units, $selected, $empty_entry) = @_; + + my $select = []; + + if ($empty_entry) { + push(@{$select}, { "name" => "", "base_unit" => "", "factor" => "", "selected" => "" }); + } + + foreach my $unit (sort({ lc($a) cmp lc($b) } keys(%{$units}))) { + push(@{$select}, { "name" => $unit, + "base_unit" => $units->{$unit}->{"base_unit"}, + "factor" => $units->{$unit}->{"factor"}, + "selected" => ($unit eq $selected) ? "selected" : "" }); + } + + $main::lxdebug->leave_sub(); + + return $select; +} + +sub unit_select_html { + $main::lxdebug->enter_sub(); + + my ($self, $units, $name, $selected, $convertible_into) = @_; + + my $select = ""; + + $main::lxdebug->leave_sub(); + + return $select; +} + +sub add_unit { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $name, $base_unit, $factor, $type) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my $query = "INSERT INTO units (name, base_unit, factor, type) VALUES (?, ?, ?, ?)"; + $dbh->do($query, undef, $name, $base_unit, $factor, $type) || $form->dberror($query . " ($name, $base_unit, $factor, $type)"); + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); +} + +sub save_units { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $type, $units, $delete_units) = @_; + + my $dbh = $form->dbconnect_noauto($myconfig); + + my ($base_unit, $unit, $sth, $query); + + if ($delete_units && (0 != scalar(@{$delete_units}))) { + $query = "DELETE FROM units WHERE name = ?"; + $sth = $dbh->prepare($query); + map({ $sth->execute($_) || $form->dberror($query . " ($_)"); } @{$delete_units}); + $sth->finish(); + } + + $query = "UPDATE units SET name = ?, base_unit = ?, factor = ? WHERE name = ?"; + $sth = $dbh->prepare($query); + + foreach $unit (values(%{$units})) { + $unit->{"depth"} = 0; + my $base_unit = $unit; + while ($base_unit->{"base_unit"}) { + $unit->{"depth"}++; + $base_unit = $units->{$base_unit->{"base_unit"}}; + } + } + + foreach $unit (sort({ $a->{"depth"} <=> $b->{"depth"} } values(%{$units}))) { + next if ($unit->{"unchanged_unit"}); + + my @values = ($unit->{"name"}, $unit->{"base_unit"}, $unit->{"factor"}, $unit->{"old_name"}); + $sth->execute(@values) || $form->dberror($query . " (" . join(", ", @values) . ")"); + } + + $sth->finish(); + $dbh->commit(); + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); +} + 1; diff --git a/SL/AP.pm b/SL/AP.pm index 0d132293f..e909890f8 100644 --- a/SL/AP.pm +++ b/SL/AP.pm @@ -76,9 +76,6 @@ sub post_transaction { $form->{exchangerate} * -1, 2); $amount += ($form->{"amount_$i"} * -1); - - # parse tax_$i for later - $form->{"tax_$i"} = $form->parse_amount($myconfig, $form->{"tax_$i"}) * -1; } # this is for ap @@ -100,28 +97,22 @@ sub post_transaction { $form->{AP_amounts}{"amount_$i"}{taxkey} = $form->{"taxkey_$i"}; $sth->finish; - if ($form->{taxincluded} *= 1) { - if (!$form->{"korrektur_$i"}) { + if (!$form->{"korrektur_$i"}) { + if ($form->{taxincluded} *= 1) { $tax = $form->{"amount_$i"} - ($form->{"amount_$i"} / ($form->{"taxrate_$i"} + 1)); + $amount = $form->{"amount_$i"} - $tax; + $form->{"amount_$i"} = $form->round_amount($amount, 2); + $diff += $amount - $form->{"amount_$i"}; + $form->{"tax_$i"} = $form->round_amount($tax, 2); + $form->{netamount} += $form->{"amount_$i"}; } else { - $tax = $form->{"tax_$i"}; - } - $amount = $form->{"amount_$i"} - $tax; - $form->{"amount_$i"} = $form->round_amount($amount, 2); - $diff += $amount - $form->{"amount_$i"}; - $form->{"tax_$i"} = $form->round_amount($tax, 2); - $form->{netamount} += $form->{"amount_$i"}; - } else { - if (!$form->{"korrektur_$i"}) { $form->{"tax_$i"} = $form->{"amount_$i"} * $form->{"taxrate_$i"}; - } else { - $tax = $form->{"tax_$i"}; + $form->{"tax_$i"} = + $form->round_amount($form->{"tax_$i"} * $form->{exchangerate}, 2); + $form->{netamount} += $form->{"amount_$i"}; } - $form->{"tax_$i"} = - $form->round_amount($form->{"tax_$i"} * $form->{exchangerate}, 2); - $form->{netamount} += $form->{"amount_$i"}; } $form->{total_tax} += $form->{"tax_$i"} * -1; } diff --git a/SL/AR.pm b/SL/AR.pm index fe687ee86..42f8c1cc7 100644 --- a/SL/AR.pm +++ b/SL/AR.pm @@ -103,28 +103,23 @@ sub post_transaction { $form->{AR_amounts}{"amount_$i"}{taxkey} = $form->{"taxkey_$i"}; $sth->finish; - if ($form->{taxincluded} *= 1) { - if (!$form->{"korrektur_$i"}) { - $tax = - $form->{"amount_$i"} - - ($form->{"amount_$i"} / ($form->{"taxrate_$i"} + 1)); + if (!$form->{"korrektur_$i"}) { + if ($form->{taxincluded} *= 1) { + $tax = + $form->{"amount_$i"} - + ($form->{"amount_$i"} / ($form->{"taxrate_$i"} + 1)); + $amount = $form->{"amount_$i"} - $tax; + $form->{"amount_$i"} = $form->round_amount($amount, 2); + $diff += $amount - $form->{"amount_$i"}; + $form->{"tax_$i"} = $form->round_amount($tax, 2); + $form->{netamount} += $form->{"amount_$i"}; } else { - $tax = $form->{"tax_$i"}; - } - $amount = $form->{"amount_$i"} - $tax; - $form->{"amount_$i"} = $form->round_amount($amount, 2); - $diff += $amount - $form->{"amount_$i"}; - $form->{"tax_$i"} = $form->round_amount($tax, 2); - $form->{netamount} += $form->{"amount_$i"}; - } else { - if (!$form->{"korrektur_$i"}) { $form->{"tax_$i"} = $form->{"amount_$i"} * $form->{"taxrate_$i"}; + $form->{"tax_$i"} = + $form->round_amount($form->{"tax_$i"} * $form->{exchangerate}, 2); + $form->{netamount} += $form->{"amount_$i"}; } - $form->{"tax_$i"} = - $form->round_amount($form->{"tax_$i"} * $form->{exchangerate}, 2); - $form->{netamount} += $form->{"amount_$i"}; } - $form->{total_tax} += $form->{"tax_$i"}; } diff --git a/SL/BP.pm b/SL/BP.pm index 683edd44d..e77695426 100644 --- a/SL/BP.pm +++ b/SL/BP.pm @@ -180,10 +180,8 @@ sub get_spoolfiles { $query .= " AND lower(a.quonumber) LIKE '$quonumber'"; } - if ($form->{type} =~ /(invoice|sales_order|sales_quotation|packing_list|puchase_order|request_quotation)$/) { - $query .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom}; - $query .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto}; - } + # $query .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom}; + # $query .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto}; my @a = (transdate, $invnumber, name); my $sortorder = join ', ', $form->sort_columns(@a); diff --git a/SL/CP.pm b/SL/CP.pm index b411b0608..341510c55 100644 --- a/SL/CP.pm +++ b/SL/CP.pm @@ -370,17 +370,10 @@ sub process_payment { $pth->finish; $amount += $form->{"paid_$i"}; - - # BUG 324 - if ($form->{arap} eq 'ap') { - $paid = "paid = paid + $amount"; - } else { - $paid = "paid = $amount"; - } # update AR/AP transaction $query = qq|UPDATE $form->{arap} set - $paid, + paid = $amount, datepaid = '$form->{datepaid}' WHERE id = $form->{"id_$i"}|; $dbh->do($query) || $form->dberror($query); diff --git a/SL/CT.pm b/SL/CT.pm index 3616a4eee..c61f5a450 100644 --- a/SL/CT.pm +++ b/SL/CT.pm @@ -36,6 +36,8 @@ #====================================================================== package CT; +use Data::Dumper; + sub get_tuple { $main::lxdebug->enter_sub(); @@ -43,10 +45,9 @@ sub get_tuple { my ($self, $myconfig, $form) = @_; my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT ct.*, b.id AS business, s.*, cp.* + my $query = qq|SELECT ct.*, b.id AS business, cp.* FROM $form->{db} ct LEFT JOIN business b on ct.business_id = b.id - LEFT JOIN shipto s on ct.id = s.trans_id LEFT JOIN contacts cp on ct.id = cp.cp_cv_id WHERE ct.id = $form->{id} order by cp.cp_id limit 1|; my $sth = $dbh->prepare($query); @@ -131,6 +132,68 @@ sub get_tuple { } $sth->finish; + # get tax zones + $query = qq|SELECT id, description + FROM tax_zones|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{TAXZONE} }, $ref; + } + $sth->finish; + + + # get shipto address + $query = qq|SELECT id, shiptoname + FROM shipto WHERE trans_id=$form->{id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{SHIPTO} }, $ref; + } + $sth->finish; + + + # get contacts + $query = qq|SELECT cp_id, cp_name + FROM contacts WHERE cp_cv_id=$form->{id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{CONTACTS} }, $ref; + } + $sth->finish; + + # get languages + $query = qq|SELECT id, description + FROM language + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{languages} }, $ref; + } + $sth->finish; + + # get languages + $query = qq|SELECT id, description + FROM payment_terms + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{payment_terms} }, $ref; + } + $sth->finish; + $dbh->disconnect; $main::lxdebug->leave_sub(); @@ -159,6 +222,20 @@ sub query_titles_and_greetings { %tmp = (); + $query = + "SELECT greeting FROM customer UNION select greeting FROM vendor"; + $sth = $dbh->prepare($query); + $sth->execute() || $form->dberror($query); + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + next unless ($ref->{greeting} =~ /[a-zA-Z]/); + $tmp{ $ref->{greeting} } = 1; + } + $sth->finish(); + + @{ $form->{COMPANY_GREETINGS} } = sort(keys(%tmp)); + + %tmp = (); + $query = "SELECT DISTINCT(c.cp_title) FROM contacts c WHERE c.cp_title LIKE '%'"; $sth = $dbh->prepare($query); @@ -171,6 +248,19 @@ sub query_titles_and_greetings { @{ $form->{TITLES} } = sort(keys(%tmp)); + %tmp = (); + + $query = + "SELECT DISTINCT(c.cp_abteilung) FROM contacts c WHERE c.cp_abteilung LIKE '%'"; + $sth = $dbh->prepare($query); + $sth->execute() || $form->dberror($query); + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + $tmp{ $ref->{cp_abteilung} } = 1; + } + $sth->finish(); + + @{ $form->{DEPARTMENT} } = sort(keys(%tmp)); + $dbh->disconnect(); $main::lxdebug->leave_sub(); } @@ -210,6 +300,42 @@ sub taxaccounts { push @{ $form->{all_business} }, $ref; } $sth->finish; + # get languages + $query = qq|SELECT id, description + FROM language + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{languages} }, $ref; + } + $sth->finish; + + # get payment terms + $query = qq|SELECT id, description + FROM payment_terms + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{payment_terms} }, $ref; + } + $sth->finish; + + # get taxkeys and description + $query = qq|SELECT id, description + FROM tax_zones|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{TAXZONE} }, $ref; + } + $sth->finish; + $dbh->disconnect; @@ -231,8 +357,9 @@ sub save_customer { map({ $form->{"cp_${_}"} = $form->{"selected_cp_${_}"} if ($form->{"selected_cp_${_}"}); - } qw(title greeting)); - + } qw(title greeting abteilung)); + $form->{"greeting"} = $form->{"selected_company_greeting"} + if ($form->{"selected_company_greeting"}); # # escape ' map { $form->{$_} =~ s/\'/\'\'/g } @@ -246,56 +373,27 @@ sub save_customer { $form->{obsolete} *= 1; $form->{business} *= 1; $form->{salesman_id} *= 1; + $form->{language_id} *= 1; + $form->{payment_id} *= 1; + $form->{taxzone_id} *= 1; $form->{creditlimit} = $form->parse_amount($myconfig, $form->{creditlimit}); - my ($query, $sth, $f_id); + my ($query, $sth); if ($form->{id}) { - - $query = qq|SELECT id FROM customer - WHERE customernumber = '$form->{customernumber}'|; - $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); - (${f_id}) = $sth->fetchrow_array; - $sth->finish; - if ((${f_id} ne $form->{id}) and (${f_id} ne "")) { - - $main::lxdebug->leave_sub(); - return 3; - } $query = qq|DELETE FROM customertax WHERE customer_id = $form->{id}|; $dbh->do($query) || $form->dberror($query); - $query = qq|DELETE FROM shipto - WHERE trans_id = $form->{id}|; - $dbh->do($query) || $form->dberror($query); +# $query = qq|DELETE FROM shipto +# WHERE trans_id = $form->{id} AND module = 'CT'|; +# $dbh->do($query) || $form->dberror($query); } else { - my $uid = rand() . time; $uid .= $form->{login}; $uid = substr($uid, 2, 75); - if (!$form->{customernumber} && $form->{business}) { - $form->{customernumber} = - $form->update_business($myconfig, $form->{business}); - } - if (!$form->{customernumber}) { - $form->{customernumber} = - $form->update_defaults($myconfig, "customernumber"); - } - - $query = qq|SELECT c.id FROM customer c - WHERE c.customernumber = '$form->{customernumber}'|; - $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); - (${f_id}) = $sth->fetchrow_array; - $sth->finish; - if (${f_id} ne "") { - $main::lxdebug->leave_sub(); - return 3; - } $query = qq|INSERT INTO customer (name) VALUES ('$uid')|; @@ -308,10 +406,21 @@ sub save_customer { ($form->{id}) = $sth->fetchrow_array; $sth->finish; + if (!$form->{customernumber} && $form->{business}) { + $form->{customernumber} = + $form->update_business($myconfig, $form->{business}); + } + if (!$form->{customernumber}) { + $form->{customernumber} = + $form->update_defaults($myconfig, "customernumber"); + } + } + $query = qq|UPDATE customer SET customernumber = '$form->{customernumber}', name = '$form->{name}', + greeting = '$form->{greeting}', department_1 = '$form->{department_1}', department_2 = '$form->{department_2}', street = '$form->{street}', @@ -341,6 +450,9 @@ sub save_customer { ustid = '$form->{ustid}', username = '$form->{username}', salesman_id = '$form->{salesman_id}', + language_id = '$form->{language_id}', + payment_id = '$form->{payment_id}', + taxzone_id = '$form->{taxzone_id}', user_password = | . $dbh->quote($form->{user_password}) . qq|, c_vendor_id = '$form->{c_vendor_id}', klass = '$form->{klass}' @@ -355,12 +467,22 @@ sub save_customer { cp_name = '$form->{cp_name}', cp_email = '$form->{cp_email}', cp_phone1 = '$form->{cp_phone1}', - cp_phone2 = '$form->{cp_phone2}' - WHERE cp_id = $form->{cp_id}|; + cp_phone2 = '$form->{cp_phone2}', + cp_abteilung = | . $dbh->quote($form->{cp_abteilung}) . qq|, + cp_fax = | . $dbh->quote($form->{cp_fax}) . qq|, + cp_mobile1 = | . $dbh->quote($form->{cp_mobile1}) . qq|, + cp_mobile2 = | . $dbh->quote($form->{cp_mobile2}) . qq|, + cp_satphone = | . $dbh->quote($form->{cp_satphone}) . qq|, + cp_satfax = | . $dbh->quote($form->{cp_satfax}) . qq|, + cp_project = | . $dbh->quote($form->{cp_project}) . qq|, + cp_privatphone = | . $dbh->quote($form->{cp_privatphone}) . qq|, + cp_privatemail = | . $dbh->quote($form->{cp_privatemail}) . qq|, + cp_birthday = | . $dbh->quote($form->{cp_birthday}) . qq| + WHERE cp_id = $form->{cp_id}|; } elsif ($form->{cp_name} || $form->{cp_givenname}) { $query = - qq|INSERT INTO contacts ( cp_cv_id, cp_greeting, cp_title, cp_givenname, cp_name, cp_email, cp_phone1, cp_phone2) - VALUES ($form->{id}, '$form->{cp_greeting}','$form->{cp_title}','$form->{cp_givenname}','$form->{cp_name}','$form->{cp_email}','$form->{cp_phone1}','$form->{cp_phone2}')|; + qq|INSERT INTO contacts ( cp_cv_id, cp_greeting, cp_title, cp_givenname, cp_name, cp_email, cp_phone1, cp_phone2, cp_abteilung, cp_fax, cp_mobile1, cp_mobile2, cp_satphone, cp_satfax, cp_project, cp_privatphone, cp_privatemail, cp_birthday) + VALUES ($form->{id}, '$form->{cp_greeting}','$form->{cp_title}','$form->{cp_givenname}','$form->{cp_name}','$form->{cp_email}','$form->{cp_phone1}','$form->{cp_phone2}', '$form->{cp_abteilung}', | . $dbh->quote($form->{cp_fax}) . qq|,| . $dbh->quote($form->{cp_mobile1}) . qq|,| . $dbh->quote($form->{cp_mobile2}) . qq|,| . $dbh->quote($form->{cp_satphone}) . qq|,| . $dbh->quote($form->{cp_satfax}) . qq|,| . $dbh->quote($form->{cp_project}) . qq|,| . $dbh->quote($form->{cp_privatphone}) . qq|,| . $dbh->quote($form->{cp_privatemail}) . qq|,| . $dbh->quote($form->{cp_birthday}) . qq|)|; } $dbh->do($query) || $form->dberror($query); @@ -374,9 +496,9 @@ sub save_customer { $dbh->do($query) || $form->dberror($query); } } - + print(STDERR "SHIPTO_ID $form->{shipto_id}\n"); # add shipto - $form->add_shipto($dbh, $form->{id}); + $form->add_shipto($dbh, $form->{id}, "CT"); $rc = $dbh->disconnect; @@ -395,8 +517,9 @@ sub save_vendor { map({ $form->{"cp_${_}"} = $form->{"selected_cp_${_}"} if ($form->{"selected_cp_${_}"}); - } qw(title greeting)); - + } qw(title greeting abteilung)); + $form->{"greeting"} = $form->{"selected_company_greeting"} + if ($form->{"selected_company_greeting"}); # escape ' map { $form->{$_} =~ s/\'/\'\'/g } qw(vendornumber name street zipcode city country homepage contact notes cp_title cp_greeting language); @@ -407,6 +530,9 @@ sub save_vendor { $form->{taxincluded} *= 1; $form->{obsolete} *= 1; $form->{business} *= 1; + $form->{payment_id} *= 1; + $form->{language_id} *= 1; + $form->{taxzone_id} *= 1; $form->{creditlimit} = $form->parse_amount($myconfig, $form->{creditlimit}); my $query; @@ -417,7 +543,7 @@ sub save_vendor { $dbh->do($query) || $form->dberror($query); $query = qq|DELETE FROM shipto - WHERE trans_id = $form->{id}|; + WHERE trans_id = $form->{id} AND module = 'CT'|; $dbh->do($query) || $form->dberror($query); } else { my $uid = time; @@ -447,6 +573,7 @@ sub save_vendor { $query = qq|UPDATE vendor SET vendornumber = '$form->{vendornumber}', name = '$form->{name}', + greeting = '$form->{greeting}', department_1 = '$form->{department_1}', department_2 = '$form->{department_2}', street = '$form->{street}', @@ -475,6 +602,9 @@ sub save_vendor { bank = '$form->{bank}', obsolete = '$form->{obsolete}', ustid = '$form->{ustid}', + payment_id = '$form->{payment_id}', + taxzone_id = '$form->{taxzone_id}', + language_id = '$form->{language_id}', username = '$form->{username}', user_password = '$form->{user_password}', v_customer_id = '$form->{v_customer_id}' @@ -660,5 +790,108 @@ sub search { $main::lxdebug->leave_sub(); } +sub get_contact { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + my $dbh = $form->dbconnect($myconfig); + my $query = qq|SELECT c.* + FROM contacts c + WHERE c.cp_id = $form->{cp_id} order by c.cp_id limit 1|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + + +sub get_shipto { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + my $dbh = $form->dbconnect($myconfig); + my $query = qq|SELECT s.* + FROM shipto s + WHERE s.id = $form->{shipto_id} order by s.id limit 1|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub get_delivery { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + my $dbh = $form->dbconnect($myconfig); + $where = " WHERE 1=1 "; + if ($form->{shipto_id}) { + $where .= "AND ar.shipto_id=$form->{shipto_id} "; + } + if ($form->{from}) { + $where .= "AND ar.transdate >= '$form->{from}' "; + } + if ($form->{to}) { + $where .= "AND ar.transdate <= '$form->{to}' "; + } + + my $query = qq|select shiptoname, adr_code, ar.transdate, ar.invnumber, ar.ordnumber, invoice.description, qty, invoice.unit FROM ar LEFT join shipto ON (ar.shipto_id=shipto.id) LEFT join invoice on (ar.id=invoice.trans_id) LEFT join parts ON (parts.id=invoice.parts_id) LEFT join adr ON (parts.adr_id=adr.id) $where ORDER BY ar.transdate DESC LIMIT 15|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{DELIVERY} }, $ref; + } + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub adr { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + my $dbh = $form->dbconnect($myconfig); + $where = " WHERE 1=1 "; + if ($form->{from}) { + $where .= "AND ar.transdate >= '$form->{from}' "; + } + if ($form->{to}) { + $where .= "AND ar.transdate <= '$form->{to}' "; + } + if ($form->{year}) { + $where = " WHERE ar.transdate >= '$form->{year}-01-01' AND ar.transdate <= '$form->{year}-12-31' "; + } + + my $query = qq|select adr_code, adr_description, sum(base_qty), parts.unit from ar LEFT join invoice on (ar.id=invoice.trans_id) LEFT join parts ON (invoice.parts_id=parts.id) LEFT join adr ON (adr.id=parts.adr_id) $where GROUP BY adr_code,adr_description,parts.unit|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ADR} }, $ref; + } + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + 1; diff --git a/SL/Common.pm b/SL/Common.pm new file mode 100644 index 000000000..de1735ffe --- /dev/null +++ b/SL/Common.pm @@ -0,0 +1,179 @@ +#==================================================================== +# LX-Office ERP +# Copyright (C) 2004 +# Based on SQL-Ledger Version 2.1.9 +# Web http://www.lx-office.org +# +#==================================================================== + +package Common; + +sub retrieve_parts { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $order_by, $order_dir) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my (@filter_values, $filter); + if ($form->{"partnumber"}) { + $filter .= " AND (partnumber ILIKE ?)"; + push(@filter_values, '%' . $form->{"partnumber"} . '%'); + } + if ($form->{"description"}) { + $filter .= " AND (description ILIKE ?)"; + push(@filter_values, '%' . $form->{"description"} . '%'); + } + substr($filter, 1, 3) = "WHERE" if ($filter); + + $order_by =~ s/[^a-zA-Z_]//g; + $order_dir = $order_dir ? "ASC" : "DESC"; + + my $query = "SELECT id, partnumber, description FROM parts $filter ORDER BY $order_by $order_dir"; + my $sth = $dbh->prepare($query); + $sth->execute(@filter_values) || $form->dberror($query . " (" . join(", ", @filter_values) . ")"); + my $parts = []; + while (my $ref = $sth->fetchrow_hashref()) { + push(@{$parts}, $ref); + } + $sth->finish(); + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); + + return $parts; +} + +sub retrieve_projects { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $order_by, $order_dir) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my (@filter_values, $filter); + if ($form->{"projectnumber"}) { + $filter .= " AND (projectnumber ILIKE ?)"; + push(@filter_values, '%' . $form->{"projectnumber"} . '%'); + } + if ($form->{"description"}) { + $filter .= " AND (description ILIKE ?)"; + push(@filter_values, '%' . $form->{"description"} . '%'); + } + substr($filter, 1, 3) = "WHERE" if ($filter); + + $order_by =~ s/[^a-zA-Z_]//g; + $order_dir = $order_dir ? "ASC" : "DESC"; + + my $query = "SELECT id, projectnumber, description FROM project $filter ORDER BY $order_by $order_dir"; + my $sth = $dbh->prepare($query); + $sth->execute(@filter_values) || $form->dberror($query . " (" . join(", ", @filter_values) . ")"); + my $projects = []; + while (my $ref = $sth->fetchrow_hashref()) { + push(@{$projects}, $ref); + } + $sth->finish(); + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); + + return $projects; +} + +sub retrieve_employees { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $order_by, $order_dir) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my (@filter_values, $filter); + if ($form->{"name"}) { + $filter .= " AND (name ILIKE ?)"; + push(@filter_values, '%' . $form->{"name"} . '%'); + } + substr($filter, 1, 3) = "WHERE" if ($filter); + + $order_by =~ s/[^a-zA-Z_]//g; + $order_dir = $order_dir ? "ASC" : "DESC"; + + my $query = "SELECT id, name FROM employee $filter ORDER BY $order_by $order_dir"; + my $sth = $dbh->prepare($query); + $sth->execute(@filter_values) || $form->dberror($query . " (" . join(", ", @filter_values) . ")"); + my $employees = []; + while (my $ref = $sth->fetchrow_hashref()) { + push(@{$employees}, $ref); + } + $sth->finish(); + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); + + return $employees; +} + +sub retrieve_delivery_customer { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $order_by, $order_dir) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my (@filter_values, $filter); + if ($form->{"name"}) { + $filter .= " (name ILIKE '%$form->{name}%') AND"; + push(@filter_values, '%' . $form->{"name"} . '%'); + } + #substr($filter, 1, 3) = "WHERE" if ($filter); + + $order_by =~ s/[^a-zA-Z_]//g; + $order_dir = $order_dir ? "ASC" : "DESC"; + + my $query = "SELECT id, name, customernumber, (street || ', ' || zipcode || city) as address FROM customer WHERE $filter business_id=(SELECT id from business WHERE description='Endkunde') ORDER BY $order_by $order_dir"; + my $sth = $dbh->prepare($query); + $sth->execute() || $form->dberror($query . " (" . join(", ", @filter_values) . ")"); + my $delivery_customers = []; + while (my $ref = $sth->fetchrow_hashref()) { + push(@{$delivery_customers}, $ref); + } + $sth->finish(); + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); + + return $delivery_customers; +} + +sub retrieve_vendor { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $order_by, $order_dir) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my (@filter_values, $filter); + if ($form->{"name"}) { + $filter .= " (name ILIKE '%$form->{name}%') AND"; + push(@filter_values, '%' . $form->{"name"} . '%'); + } + #substr($filter, 1, 3) = "WHERE" if ($filter); + + $order_by =~ s/[^a-zA-Z_]//g; + $order_dir = $order_dir ? "ASC" : "DESC"; + + my $query = "SELECT id, name, customernumber, (street || ', ' || zipcode || city) as address FROM customer WHERE $filter business_id=(SELECT id from business WHERE description='Händler') ORDER BY $order_by $order_dir"; + my $sth = $dbh->prepare($query); + $sth->execute() || $form->dberror($query . " (" . join(", ", @filter_values) . ")"); + my $vendors = []; + while (my $ref = $sth->fetchrow_hashref()) { + push(@{$vendors}, $ref); + } + $sth->finish(); + $dbh->disconnect(); + + $main::lxdebug->leave_sub(); + + return $vendors; +} + +1; diff --git a/SL/DATEV.pm b/SL/DATEV.pm index 9c617dbb8..e0a0435eb 100644 --- a/SL/DATEV.pm +++ b/SL/DATEV.pm @@ -329,7 +329,7 @@ sub get_transactions { } } if (abs($absumsatz) > 0.01) { - $form->error("Datev-Export fehlgeschlagen!"); + $form->error("Datev-Export fehlgeschlagen! Bei Transaktion $i->[0]->{trans_id}\n"); } } else { push @{ $form->{DATEV} }, \@{$i}; diff --git a/SL/DN.pm b/SL/DN.pm new file mode 100644 index 000000000..5de9a552b --- /dev/null +++ b/SL/DN.pm @@ -0,0 +1,497 @@ +#====================================================================== +# LX-Office ERP +# Copyright (C) 2006 +# Based on SQL-Ledger Version 2.1.9 +# Web http://www.lx-office.org +# +#===================================================================== +# SQL-Ledger Accounting +# Copyright (C) 1998-2002 +# +# Author: Dieter Simader +# Email: dsimader@sql-ledger.org +# Web: http://www.sql-ledger.org +# +# Contributors: +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#====================================================================== +# +# Dunning process module +# +#====================================================================== + +package DN; + +use SL::Template; +use SL::IS; +use Data::Dumper; + +sub get_config { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT dn.* + FROM dunning_config dn + ORDER BY dn.dunning_level|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + $ref->{fee} = $form->format_amount($myconfig, $ref->{fee}, 2); + $ref->{interest} = $form->format_amount($myconfig, ($ref->{interest} * 100)); + push @{ $form->{DUNNING} }, $ref; + } + + $sth->finish; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + + +sub save_config { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + for my $i (1 .. $form->{rowcount}) { + $form->{"active_$i"} *= 1; + $form->{"auto_$i"} *= 1; + $form->{"email_$i"} *= 1; + $form->{"terms_$i"} *= 1; + $form->{"payment_terms_$i"} *= 1; + $form->{"email_attachment_$i"} *= 1; + $form->{"fee_$i"} = $form->parse_amount($myconfig, $form->{"fee_$i"}) * 1; + $form->{"interest_$i"} = $form->parse_amount($myconfig, $form->{"interest_$i"})/100; + + if (($form->{"dunning_level_$i"} ne "") && ($form->{"dunning_description_$i"} ne "")) { + if ($form->{"id_$i"}) { + my $query = qq|UPDATE dunning_config SET + dunning_level = | . $dbh->quote($form->{"dunning_level_$i"}) . qq|, + dunning_description = | . $dbh->quote($form->{"dunning_description_$i"}) . qq|, + email_subject = | . $dbh->quote($form->{"email_subject_$i"}) . qq|, + email_body = | . $dbh->quote($form->{"email_body_$i"}) . qq|, + template = | . $dbh->quote($form->{"template_$i"}) . qq|, + fee = '$form->{"fee_$i"}', + interest = '$form->{"interest_$i"}', + active = '$form->{"active_$i"}', + auto = '$form->{"auto_$i"}', + email = '$form->{"email_$i"}', + email_attachment = '$form->{"email_attachment_$i"}', + payment_terms = $form->{"payment_terms_$i"}, + terms = $form->{"terms_$i"} + WHERE id=$form->{"id_$i"}|; + $dbh->do($query) || $form->dberror($query); + } else { + my $query = qq|INSERT INTO dunning_config (dunning_level, dunning_description, email_subject, email_body, template, fee, interest, active, auto, email, email_attachment, terms, payment_terms) VALUES (| . $dbh->quote($form->{"dunning_level_$i"}) . qq|,| . $dbh->quote($form->{"dunning_description_$i"}) . qq|,| . $dbh->quote($form->{"email_subject_$i"}) . qq|,| . $dbh->quote($form->{"email_body_$i"}) . qq|,| . $dbh->quote($form->{"template_$i"}) . qq|,'$form->{"fee_$i"}','$form->{"interest_$i"}','$form->{"active_$i"}','$form->{"auto_$i"}','$form->{"email_$i"}','$form->{"email_attachment_$i"}',$form->{"terms_$i"},$form->{"payment_terms_$i"})|; + $dbh->do($query) || $form->dberror($query); + } + } + if (($form->{"dunning_description_$i"} eq "") && ($form->{"id_$i"})) { + my $query = qq|DELETE FROM dunning_config WHERE id=$form->{"id_$i"}|; + $dbh->do($query) || $form->dberror($query); + } + } + + $dbh->commit; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub save_dunning { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $rows, $userspath,$spool, $sendmail) = @_; + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + foreach my $row (@{ $rows }) { + + $form->{"interest_$row"} = $form->parse_amount($myconfig,$form->{"interest_$row"}); + $form->{"fee_$row"} = $form->parse_amount($myconfig,$form->{"fee_$row"}); + $form->{send_email} = $form->{"email_$row"}; + + my $query = qq| UPDATE ar set dunning_id = '$form->{"next_dunning_id_$row"}' WHERE id='$form->{"inv_id_$row"}'|; + $dbh->do($query) || $form->dberror($query); + my $query = qq| INSERT into dunning (dunning_id,dunning_level,trans_id,fee,interest,transdate,duedate) VALUES ($form->{"next_dunning_id_$row"},(select dunning_level from dunning_config WHERE id=$form->{"next_dunning_id_$row"}),$form->{"inv_id_$row"},'$form->{"fee_$row"}', '$form->{"interest_$row"}',current_date, |.$dbh->quote($form->{"next_duedate_$row"}) . qq|)|; + $dbh->do($query) || $form->dberror($query); + } + + my $query = qq| SELECT invnumber, ordnumber, customer_id, amount, netamount, ar.transdate, ar.duedate, paid, amount-paid AS open_amount, template AS formname, email_subject, email_body, email_attachment, da.fee, da.interest, da.transdate AS dunning_date, da.duedate AS dunning_duedate FROM ar LEFT JOIN dunning_config ON (dunning_config.id=ar.dunning_id) LEFT JOIN dunning da ON (ar.id=da.trans_id) where ar.id IN $form->{inv_ids}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + my $first = 1; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + if ($first) { + map({ $form->{"dn_$_"} = []; } keys(%{$ref})); + $first = 0; + } + map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2) } qw(amount netamount paid open_amount fee interest); + map { $form->{$_} = $ref->{$_} } keys %$ref; + #print(STDERR Dumper($ref)); + map { push @{ $form->{"dn_$_"} }, $ref->{$_}} keys %$ref; + } + $sth->finish; + + IS->customer_details($myconfig,$form); + #print(STDERR Dumper($form->{dn_invnumber})); + $form->{templates} = "$myconfig->{templates}"; + + + + $form->{language} = $form->get_template_language(\%myconfig); + $form->{printer_code} = $form->get_printer_code(\%myconfig); + + if ($form->{language} ne "") { + $form->{language} = "_" . $form->{language}; + } + + if ($form->{printer_code} ne "") { + $form->{printer_code} = "_" . $form->{printer_code}; + } + + $form->{IN} = "$form->{formname}$form->{language}$form->{printer_code}.html"; + if ($form->{format} eq 'postscript') { + $form->{postscript} = 1; + $form->{IN} =~ s/html$/tex/; + } elsif ($form->{"format"} =~ /pdf/) { + $form->{pdf} = 1; + if ($form->{"format"} =~ /opendocument/) { + $form->{IN} =~ s/html$/odt/; + } else { + $form->{IN} =~ s/html$/tex/; + } + } elsif ($form->{"format"} =~ /opendocument/) { + $form->{"opendocument"} = 1; + $form->{"IN"} =~ s/html$/odt/; + } + + if ($form->{"send_email"} && $form->{email}) { + $form->{media} = 'email'; + } + + $form->{keep_tmpfile} = 0; + if ($form->{media} eq 'email') { + $form->{subject} = qq|$form->{label} $form->{"${inv}number"}| + unless $form->{subject}; + if (!$form->{email_attachment}) { + $form->{do_not_attach} = 1; + } else { + $form->{do_not_attach} = 0; + } + $form->{subject} = parse_strings($myconfig, $form, $userspath, $form->{email_subject}); + $form->{message} = parse_strings($myconfig, $form, $userspath, $form->{email_body}); + + $form->{OUT} = "$sendmail"; + + } else { + + my $uid = rand() . time; + + $uid .= $form->{login}; + + $uid = substr($uid, 2, 75); + $filename = $uid; + + $filename .= '.pdf'; + $form->{OUT} = ">$spool/$filename"; + push(@{ $form->{DUNNING_PDFS} }, $filename); + $form->{keep_tmpfile} = 1; + } + + $form->parse_template($myconfig, $userspath); + + $dbh->commit; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); +} + +sub get_invoices { + + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $where = qq| WHERE 1=1 AND a.paid < a.amount AND a.duedate < current_date AND dnn.id = (select id from dunning_config WHERE dunning_level>(select case when a.dunning_id is null then 0 else (select dunning_level from dunning_config where id=a.dunning_id order by dunning_level limit 1 ) end from dunning_config limit 1) limit 1) |; + + if ($form->{"$form->{vc}_id"}) { + $where .= qq| AND a.$form->{vc}_id = $form->{"$form->{vc}_id"}|; + } else { + if ($form->{ $form->{vc} }) { + $where .= " AND lower(ct.name) LIKE '$name'"; + } + } + + my $sortorder = join ', ', + ("a.id", $form->sort_columns(transdate, duedate, name)); + $sortorder = $form->{sort} if $form->{sort}; + + $where .= " AND lower(ordnumber) LIKE '$form->{ordnumber}'" if $form->{ordnumber}; + $where .= " AND lower(invnumber) LIKE '$form->{invnumber}'" if $form->{invnumber}; + + + $form->{minamount} = $form->parse_amount($myconfig,$form->{minamount}); + $where .= " AND a.dunning_id='$form->{dunning_level}'" + if $form->{dunning_level}; + $where .= " AND a.ordnumber ilike '%$form->{ordnumber}%'" + if $form->{ordnumber}; + $where .= " AND a.invnumber ilike '%$form->{invnumber}%'" + if $form->{invnumber}; + $where .= " AND a.notes ilike '%$form->{notes}%'" + if $form->{notes}; + $where .= " AND ct.name ilike '%$form->{customer}%'" + if $form->{customer}; + + $where .= " AND a.amount-a.paid>'$form->{minamount}'" + if $form->{minamount}; + + $where .= " ORDER by $sortorder"; + + $paymentdate = ($form->{paymentuntil}) ? "'$form->{paymentuntil}'" : current_date; + + $query = qq|SELECT a.id, a.ordnumber, a.transdate, a.invnumber,a.amount, ct.name AS customername, a.customer_id, a.duedate,da.fee AS old_fee, dnn.fee as fee, dn.dunning_description, da.transdate AS dunning_date, da.duedate AS dunning_duedate, a.duedate + dnn.terms - current_date AS nextlevel, $paymentdate - a.duedate AS pastdue, dn.dunning_level, current_date + dnn.payment_terms AS next_duedate, dnn.dunning_description AS next_dunning_description, dnn.id AS next_dunning_id, dnn.interest AS interest_rate, dnn.terms + FROM dunning_config dnn, ar a + JOIN customer ct ON (a.customer_id = ct.id) + LEFT JOIN dunning_config dn ON (dn.id = a.dunning_id) + LEFT JOIN dunning da ON (da.trans_id=a.id) + $where|; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + $ref->{fee} += $ref->{old_fee}; + $ref->{interest} = ($ref->{amount} * $ref->{pastdue} * $ref->{interest_rate}) /360; + $ref->{interest} = $form->round_amount($ref->{interest},2); + map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2)} qw(amount fee interest); + if ($ref->{pastdue} >= $ref->{terms}) { + push @{ $form->{DUNNINGS} }, $ref; + } + } + + $sth->finish; + + $query = qq|select id, dunning_description FROM dunning_config order by dunning_level|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{DUNNING_CONFIG} }, $ref; + } + + $sth->finish; + + $dbh->disconnect; + $main::lxdebug->leave_sub(); +} + +sub get_dunning { + + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $where = qq| WHERE 1=1 AND da.trans_id=a.id|; + + if ($form->{"$form->{vc}_id"}) { + $where .= qq| AND a.$form->{vc}_id = $form->{"$form->{vc}_id"}|; + } else { + if ($form->{ $form->{vc} }) { + $where .= " AND lower(ct.name) LIKE '$name'"; + } + } + + my $sortorder = join ', ', + ("a.id", $form->sort_columns(transdate, duedate, name)); + $sortorder = $form->{sort} if $form->{sort}; + + $where .= " AND lower(ordnumber) LIKE '$form->{ordnumber}'" if $form->{ordnumber}; + $where .= " AND lower(invnumber) LIKE '$form->{invnumber}'" if $form->{invnumber}; + + + $form->{minamount} = $form->parse_amount($myconfig,$form->{minamount}); + $where .= " AND a.dunning_id='$form->{dunning_level}'" + if $form->{dunning_level}; + $where .= " AND a.ordnumber ilike '%$form->{ordnumber}%'" + if $form->{ordnumber}; + $where .= " AND a.invnumber ilike '%$form->{invnumber}%'" + if $form->{invnumber}; + $where .= " AND a.notes ilike '%$form->{notes}%'" + if $form->{notes}; + $where .= " AND ct.name ilike '%$form->{customer}%'" + if $form->{customer}; + $where .= " AND a.amount > a.paid AND da.dunning_id=a.dunning_id " unless ($form->{showold}); + + $where .= " AND a.transdate >='$form->{transdatefrom}' " if ($form->{transdatefrom}); + $where .= " AND a.transdate <='$form->{transdateto}' " if ($form->{transdateto}); + $where .= " AND da.transdate >='$form->{dunningfrom}' " if ($form->{dunningfrom}); + $where .= " AND da.transdate <='$form->{dunningto}' " if ($form->{dunningto}); + + $where .= " ORDER by $sortorder"; + + + $query = qq|SELECT a.id, a.ordnumber, a.transdate, a.invnumber,a.amount, ct.name AS customername, a.duedate,da.fee ,da.interest, dn.dunning_description, da.transdate AS dunning_date, da.duedate AS dunning_duedate + FROM ar a + JOIN customer ct ON (a.customer_id = ct.id), + dunning da LEFT JOIN dunning_config dn ON (da.dunning_id=dn.id) + $where|; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + + map { $ref->{$_} = $form->format_amount($myconfig, $ref->{$_}, 2)} qw(amount fee interest); + push @{ $form->{DUNNINGS} }, $ref; + } + + $sth->finish; + + + + $dbh->disconnect; + $main::lxdebug->leave_sub(); +} + + +sub parse_strings { + + $main::lxdebug->enter_sub(); + + my ($myconfig, $form, $userspath, $string) = @_; + + my $format = $form->{format}; + $form->{format} = "html"; + + $tmpstring = "parse_string.html"; + $tmpfile = "$myconfig->{templates}/$tmpstring"; + open(OUT, ">$tmpfile") or $form->error("$tmpfile : $!"); + print(OUT $string); + close(OUT); + + my $in = $form->{IN}; + $form->{IN} = $tmpstring; + $template = HTMLTemplate->new($tmpstring, $form, $myconfig, $userspath); + + my $fileid = time; + $form->{tmpfile} = "$userspath/${fileid}.$tmpstring"; + $out = $form->{OUT}; + $form->{OUT} = ">$form->{tmpfile}"; + + if ($form->{OUT}) { + open(OUT, "$form->{OUT}") or $form->error("$form->{OUT} : $!"); + } + if (!$template->parse(*OUT)) { + $form->cleanup(); + $form->error("$form->{IN} : " . $template->get_error()); + } + + close(OUT); + my $result = ""; + open(IN, $form->{tmpfile}) or $form->error($form->cleanup . "$form->{tmpfile} : $!"); + + while () { + $result .= $_; + } + + close(IN); +# unlink($tmpfile); +# unlink($form->{tmpfile}); + $form->{IN} = $in; + $form->{format} = $format; + + $main::lxdebug->leave_sub(); + return $result; +} + +sub melt_pdfs { + + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $userspath) = @_; + + foreach my $file (@{ $form->{DUNNING_PDFS} }) { + $inputfiles .= " $userspath/$file "; + } + + my $outputfile = "$userspath/dunning.pdf"; + system("gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=$outputfile $inputfiles"); + foreach my $file (@{ $form->{DUNNING_PDFS} }) { + unlink("$userspath/$file"); + } + $out=""; + + + $form->{OUT} = $out; + + my $numbytes = (-s $outputfile); + open(IN, $outputfile) + or $form->error($self->cleanup . "$outputfile : $!"); + + $form->{copies} = 1 unless $form->{media} eq 'printer'; + + chdir("$self->{cwd}"); + + for my $i (1 .. $form->{copies}) { + if ($form->{OUT}) { + open(OUT, $form->{OUT}) + or $form->error($form->cleanup . "$form->{OUT} : $!"); + } else { + + # launch application + print qq|Content-Type: Application/PDF +Content-Disposition: attachment; filename="$outputfile" +Content-Length: $numbytes + +|; + + open(OUT, ">-") or $form->error($form->cleanup . "$!: STDOUT"); + + } + + while () { + print OUT $_; + } + + close(OUT); + + seek IN, 0, 0; + } + + close(IN); + unlink("$userspath/$outputfile"); + + $main::lxdebug->leave_sub(); +} + +1; diff --git a/SL/Form.pm b/SL/Form.pm index 9e55af355..1faec58a1 100644 --- a/SL/Form.pm +++ b/SL/Form.pm @@ -36,9 +36,14 @@ #====================================================================== package Form; +use Data::Dumper; +use Cwd; use HTML::Template; +use SL::Template; +use CGI::Ajax; use SL::Menu; +use CGI; sub _input_to_hash { $main::lxdebug->enter_sub(2); @@ -141,9 +146,9 @@ sub new { $self->{menubar} = 1 if $self->{path} =~ /lynx/i; $self->{action} = lc $self->{action}; - $self->{action} =~ s/( |-|,|#)/_/g; + $self->{action} =~ s/( |-|,|\#)/_/g; - $self->{version} = "2.3.0"; + $self->{version} = "2.4.0"; $main::lxdebug->leave_sub(); @@ -240,7 +245,6 @@ sub error { $main::lxdebug->enter_sub(); my ($self, $msg) = @_; - if ($ENV{HTTP_USER_AGENT}) { $msg =~ s/\n/
/g; $self->show_generic_error($msg); @@ -386,7 +390,10 @@ function fokus(){document.$self->{fokus}.focus();} ($self->{title}) ? "$self->{title} - $self->{titlebar}" : $self->{titlebar}; - + $ajax = ""; + foreach $item (@ { $self->{AJAX} }) { + $ajax .= $item->show_javascript(); + } print qq|Content-Type: text/html @@ -397,7 +404,21 @@ function fokus(){document.$self->{fokus}.focus();} $favicon $charset $jsscript + $ajax $fokus + + + + + |; @@ -480,7 +501,6 @@ sub parse_html_template { $menu->generate_acl("", $additional_params); my @additional_param_names = keys(%{$additional_params}); - foreach my $key ($template->param()) { if (grep(/^${key}$/, @additional_param_names)) { $template->param($key => $additional_params->{$key}); @@ -488,7 +508,6 @@ sub parse_html_template { $template->param($key => $self->{$key}); } } - my $output = $template->output(); $main::lxdebug->leave_sub(); @@ -610,33 +629,78 @@ sub sort_columns { return @columns; } -# + sub format_amount { $main::lxdebug->enter_sub(2); my ($self, $myconfig, $amount, $places, $dash) = @_; - my $neg = ($amount =~ s/-//); - $amount = $self->round_amount($amount, $places) if ($places =~ /\d/); + #Workaround for $format_amount calls without $places + if (!defined $places) { + (my $dec) = ($amount =~ /\.(\d+)/); + $places = length $dec; + } - my @d = map { s/\d//g; reverse split // } my $tmp = $myconfig->{numberformat}; # get delim chars - my @p = split /\./, $amount ; # split amount at decimal point + if ($places =~ /\d/) { + $amount = $self->round_amount($amount, $places); + } - $p[0] =~ s/\B(?=(...)*$)/$d[1]/g if $d[1]; # add 1,000 delimiters + # is the amount negative + my $negative = ($amount < 0); + my $fillup = ""; + + if ($amount != 0) { + if ($myconfig->{numberformat} && ($myconfig->{numberformat} ne '1000.00')) + { + my ($whole, $dec) = split /\./, "$amount"; + $whole =~ s/-//; + $amount = join '', reverse split //, $whole; + $fillup = "0" x ($places - length($dec)); + + if ($myconfig->{numberformat} eq '1,000.00') { + $amount =~ s/\d{3,}?/$&,/g; + $amount =~ s/,$//; + $amount = join '', reverse split //, $amount; + $amount .= "\.$dec" . $fillup if ($places ne '' && $places * 1 != 0); + } + + if ($myconfig->{numberformat} eq '1.000,00') { + $amount =~ s/\d{3,}?/$&./g; + $amount =~ s/\.$//; + $amount = join '', reverse split //, $amount; + $amount .= ",$dec" . $fillup if ($places ne '' && $places * 1 != 0); + } + + if ($myconfig->{numberformat} eq '1000,00') { + $amount = "$whole"; + $amount .= ",$dec" . $fillup if ($places ne '' && $places * 1 != 0); + } + + if ($dash =~ /-/) { + $amount = ($negative) ? "($amount)" : "$amount"; + } elsif ($dash =~ /DRCR/) { + $amount = ($negative) ? "$amount DR" : "$amount CR"; + } else { + $amount = ($negative) ? "-$amount" : "$amount"; + } + } + } else { + if ($dash eq "0" && $places) { + if ($myconfig->{numberformat} eq '1.000,00') { + $amount = "0" . "," . "0" x $places; + } else { + $amount = "0" . "." . "0" x $places; + } + } else { + $amount = ($dash ne "") ? "$dash" : "0"; + } + } - $amount = $p[0]; - $amount .= $d[0].$p[1].(0 x ($places - length $p[1])) if ($places || $p[1] ne ''); - - $amount = do { - ($dash =~ /-/) ? ($neg ? "($amount)" : "$amount" ) : - ($dash =~ /DRCR/) ? ($neg ? "$amount DR" : "$amount CR" ) : - ($neg ? "-$amount" : "$amount" ) ; - }; - $main::lxdebug->leave_sub(2); + return $amount; } -# + sub parse_amount { $main::lxdebug->enter_sub(2); @@ -696,23 +760,20 @@ sub parse_template { $main::lxdebug->enter_sub(); my ($self, $myconfig, $userspath) = @_; + my $template; - # { Moritz Bunkus - # Some variables used for page breaks - my ($chars_per_line, $lines_on_first_page, $lines_on_second_page) = - (0, 0, 0); - my ($current_page, $current_line, $current_row) = (1, 1, 0); - my $pagebreak = ""; - my $sum = 0; - # } Moritz Bunkus - - # The old fixed notation of <%variable%> is changed to a new dynamic one. - my ${pre} = '<%'; # Variable Prefix, must be regex save! - my ${suf} = '%>'; # Variable Suffix, must be regex save! + $self->{"cwd"} = getcwd(); + $self->{"tmpdir"} = $self->{cwd} . "/${userspath}"; - - # Make sure that all *notes* (intnotes, partnotes_*, notes etc) are converted to markup correctly. - $self->format_string(grep(/notes/, keys(%{$self}))); + if ($self->{"format"} =~ /(opendocument|oasis)/i) { + $template = OpenDocumentTemplate->new($self->{"IN"}, $self, $myconfig, $userspath); + } elsif ($self->{"format"} =~ /(postscript|pdf)/i) { + $ENV{"TEXINPUTS"} = ".:" . getcwd() . "/" . $myconfig->{"templates"} . ":" . $ENV{"TEXINPUTS"}; + $template = LaTeXTemplate->new($self->{"IN"}, $self, $myconfig, $userspath); + } elsif (($self->{"format"} =~ /html/i) || + (!$self->{"format"} && ($self->{"IN"} =~ /html$/i))) { + $template = HTMLTemplate->new($self->{"IN"}, $self, $myconfig, $userspath); + } # Copy the notes from the invoice/sales order etc. back to the variable "notes" because that is where most templates expect it to be. $self->{"notes"} = $self->{ $self->{"formname"} . "notes" }; @@ -720,19 +781,13 @@ sub parse_template { map({ $self->{"employee_${_}"} = $myconfig->{$_}; } qw(email tel fax name signature company address businessnumber)); - open(IN, "$self->{templates}/$self->{IN}") - or $self->error("$self->{IN} : $!"); - - @_ = ; - close(IN); - $self->{copies} = 1 if (($self->{copies} *= 1) <= 0); # OUT is used for the media, screen, printer, email # for postscript we store a copy in a temporary file my $fileid = time; $self->{tmpfile} = "$userspath/${fileid}.$self->{IN}"; - if ($self->{format} =~ /(postscript|pdf)/ || $self->{media} eq 'email') { + if ($template->uses_temp_file() || $self->{media} eq 'email') { $out = $self->{OUT}; $self->{OUT} = ">$self->{tmpfile}"; } @@ -744,246 +799,17 @@ sub parse_template { $self->header; } - # Do we have to run LaTeX two times? This is needed if - # the template contains page references. - $two_passes = 0; - - # first we generate a tmpfile - # read file and replace ${pre}variable${suf} - while ($_ = shift) { - - $par = ""; - $var = $_; - - # Switch ${pre}analyse${suf} for template checking - # If ${pre}analyse${suf} is set in the template, you'll find the - # parsed output in the user Directory for analysing - # Latex errors - # ${pre}analyse${suf} is a switch (allways off, on if set), not a Variable - # Set $form->{analysing}="" for system state: never analyse. - # Set $form->{analysing}="1" for system state: ever analyse. - $self->{analysing} = "1" if (/${pre}analyse${suf}/ && !defined $self->{analysing}); - - $two_passes = 1 if (/\\pageref/); - - # { Moritz Bunkus - # detect pagebreak block and its parameters - if (/\s*${pre}pagebreak ([0-9]+) ([0-9]+) ([0-9]+)${suf}/) { - $chars_per_line = $1; - $lines_on_first_page = $2; - $lines_on_second_page = $3; - - while ($_ = shift) { - last if (/\s*${pre}end pagebreak${suf}/); - $pagebreak .= $_; - } - } - - # } Moritz Bunkus - - if (/\s*${pre}foreach /) { - - # this one we need for the count - chomp $var; - $var =~ s/\s*${pre}foreach (.+?)${suf}/$1/; - while ($_ = shift) { - last if (/\s*${pre}end /); - - # store line in $par - $par .= $_; - } - - # display contents of $self->{number}[] array - for $i (0 .. $#{ $self->{$var} }) { - - # { Moritz Bunkus - # Try to detect whether a manual page break is necessary - # but only if there was a ${pre}pagebreak ...${suf} block before - - if ($chars_per_line) { - my $lines = - int(length($self->{"description"}[$i]) / $chars_per_line + 0.95); - my $lpp; - - my $_description = $self->{"description"}[$i]; - while ($_description =~ /\\newline/) { - $lines++; - $_description =~ s/\\newline//; - } - $self->{"description"}[$i] =~ s/(\\newline\s?)*$//; - - if ($current_page == 1) { - $lpp = $lines_on_first_page; - } else { - $lpp = $lines_on_second_page; - } - - # Yes we need a manual page break -- or the user has forced one - if ( - (($current_line + $lines) > $lpp) - || ($self->{"_forced_pagebreaks"} - && grep(/^${current_row}$/, @{ $self->{"_forced_pagebreaks"} })) - ) { - my $pb = $pagebreak; - - # replace the special variables ${pre}sumcarriedforward${suf} - # and ${pre}lastpage${suf} - - my $psum = $self->format_amount($myconfig, $sum, 2); - $pb =~ s/${pre}sumcarriedforward${suf}/$psum/g; - $pb =~ s/${pre}lastpage${suf}/$current_page/g; - - # only "normal" variables are supported here - # (no ${pre}if, no ${pre}foreach, no ${pre}include) - - $pb =~ s/${pre}(.+?)${suf}/$self->{$1}/g; - - # page break block is ready to rock - print(OUT $pb); - $current_page++; - $current_line = 1; - } - $current_line += $lines; - $current_row++; - } - $sum += $self->parse_amount($myconfig, $self->{"linetotal"}[$i]); - - # } Moritz Bunkus - - # don't parse par, we need it for each line - $_ = $par; - s/${pre}(.+?)${suf}/$self->{$1}[$i]/mg; - print OUT; - } - next; - } - - # if not comes before if! - if (/\s*${pre}if not /) { - - # check if it is not set and display - chop; - s/\s*${pre}if not (.+?)${suf}/$1/; - - unless ($self->{$_}) { - while ($_ = shift) { - last if (/\s*${pre}end /); - - # store line in $par - $par .= $_; - } - - $_ = $par; - - } else { - while ($_ = shift) { - last if (/\s*${pre}end /); - } - next; - } - } - - if (/\s*${pre}if /) { - - # check if it is set and display - chop; - s/\s*${pre}if (.+?)${suf}/$1/; - - if ($self->{$_}) { - while ($_ = shift) { - last if (/\s*${pre}end /); - - # store line in $par - $par .= $_; - } - - $_ = $par; - - } else { - while ($_ = shift) { - last if (/\s*${pre}end /); - } - next; - } - } - - # check for ${pre}include filename${suf} - if (/\s*${pre}include /) { - - # get the directory/filename - chomp $var; - $var =~ s/\s*${pre}include (.+?)${suf}/$1/; - - # mangle filename on basedir - $var =~ s/^(\/|\.\.)//g; - - # prevent the infinite loop! - next if ($self->{"$var"}); - - open(INC, "$self->{templates}/$var") - or $self->error($self->cleanup . "$self->{templates}/$var : $!"); - unshift(@_, ); - close(INC); - - $self->{"$var"} = 1; - - next; - } - - s/${pre}(.+?)${suf}/$self->{$1}/g; - s/<\/nobr>/ /g; - print OUT; + if (!$template->parse(*OUT)) { + $self->cleanup(); + $self->error("$self->{IN} : " . $template->get_error()); } close(OUT); + + use Data::Dumper; + #print(STDERR Dumper($self)); - # { Moritz Bunkus - # Convert the tex file to postscript - if ($self->{format} =~ /(postscript|pdf)/) { - - use Cwd; - $self->{cwd} = cwd(); - $self->{tmpdir} = "$self->{cwd}/$userspath"; - - chdir("$userspath") or $self->error($self->cleanup . "chdir : $!"); - - $self->{tmpfile} =~ s/$userspath\///g; - - if ($self->{format} eq 'postscript') { - system( - "latex --interaction=nonstopmode $self->{tmpfile} > $self->{tmpfile}.err" - ); - $self->error($self->cleanup) if ($?); - if ($two_passes) { - system( - "latex --interaction=nonstopmode $self->{tmpfile} > $self->{tmpfile}.err" - ); - $self->error($self->cleanup) if ($?); - } - - $self->{tmpfile} =~ s/tex$/dvi/; - - system("dvips $self->{tmpfile} -o -q > /dev/null"); - $self->error($self->cleanup . "dvips : $!") if ($?); - $self->{tmpfile} =~ s/dvi$/ps/; - } - if ($self->{format} eq 'pdf') { - system( - "pdflatex --interaction=nonstopmode $self->{tmpfile} > $self->{tmpfile}.err" - ); - $self->error($self->cleanup) if ($?); - if ($two_passes) { - system( - "pdflatex --interaction=nonstopmode $self->{tmpfile} > $self->{tmpfile}.err" - ); - $self->error($self->cleanup) if ($?); - } - $self->{tmpfile} =~ s/tex$/pdf/; - } - - } - - if ($self->{format} =~ /(postscript|pdf)/ || $self->{media} eq 'email') { + if ($template->uses_temp_file() || $self->{media} eq 'email') { if ($self->{media} eq 'email') { @@ -1015,7 +841,7 @@ sub parse_template { } else { - @{ $mail->{attachments} } = ($self->{tmpfile}); + @{ $mail->{attachments} } = ($self->{tmpfile}) unless ($form->{do_not_attach}); $myconfig->{signature} =~ s/\\n/\r\n/g; $mail->{message} .= "\r\n--\r\n$myconfig->{signature}"; @@ -1036,7 +862,8 @@ sub parse_template { $self->{copies} = 1 unless $self->{media} eq 'printer'; chdir("$self->{cwd}"); - + #print(STDERR "Kopien $self->{copies}\n"); + #print(STDERR "OUT $self->{OUT}\n"); for my $i (1 .. $self->{copies}) { if ($self->{OUT}) { open(OUT, $self->{OUT}) @@ -1044,7 +871,7 @@ sub parse_template { } else { # launch application - print qq|Content-Type: application/$self->{format} + print qq|Content-Type: | . $template->get_mime_type() . qq| Content-Disposition: attachment; filename="$self->{tmpfile}" Content-Length: $numbytes @@ -1088,14 +915,12 @@ sub cleanup { close(FH); } - if ($self->{analysing} eq "") { - if ($self->{tmpfile}) { - - # strip extension - $self->{tmpfile} =~ s/\.\w+$//g; - my $tmpfile = $self->{tmpfile}; - unlink(<$tmpfile.*>); - } + if ($self->{tmpfile}) { + $self->{tmpfile} =~ s|.*/||g; + # strip extension + $self->{tmpfile} =~ s/\.\w+$//g; + my $tmpfile = $self->{tmpfile}; + unlink(<$tmpfile.*>); } chdir("$self->{cwd}"); @@ -1105,101 +930,6 @@ sub cleanup { return "@err"; } -sub format_string { - $main::lxdebug->enter_sub(); - - my ($self, @fields) = @_; - my %unique_fields; - - %unique_fields = map({ $_ => 1 } @fields); - @fields = keys(%unique_fields); - - foreach my $field (@fields) { - next unless ($self->{$field} =~ /\/); - $self->{$field} =~ s/\//g; - if ($field =~ /.*_(\d+)$/) { - if (!$self->{"_forced_pagebreaks"}) { - $self->{"_forced_pagebreaks"} = []; - } - push(@{ $self->{"_forced_pagebreaks"} }, "$1"); - } - } - - my $format = $self->{format}; - if ($self->{format} =~ /(postscript|pdf)/) { - $format = 'tex'; - } - - my %replace = ( - 'order' => { - 'html' => [ - '<', '>', quotemeta('\n'), ' -' - ], - 'tex' => [ - '&', quotemeta('\n'), ' -', - '"', '\$', '%', '_', '#', quotemeta('^'), - '{', '}', '<', '>', '£', "\r", '²' - ] - }, - 'html' => { - '<' => '<', - '>' => '>', - quotemeta('\n') => '
', - ' -' => '
' - }, - 'tex' => { - '"' => "''", - '&' => '\&', - '\$' => '\$', - '%' => '\%', - '_' => '\_', - '#' => '\#', - quotemeta('^') => '\^\\', - '{' => '\{', - '}' => '\}', - '<' => '$<$', - '>' => '$>$', - quotemeta('\n') => '\newline ', - ' -' => '\newline ', - '£' => '\pounds ', - '²' => '$^2$', - "\r" => "" - }); - - foreach my $key (@{ $replace{order}{$format} }) { - map { $self->{$_} =~ s/$key/$replace{$format}{$key}/g; } @fields; - } - - # Allow some HTML markup to be converted into the output format's - # corresponding markup code, e.g. bold or italic. - if ('html' eq $format) { - my @markup_replace = ('b', 'i', 's', 'u'); - - foreach my $key (@markup_replace) { - map({ $self->{$_} =~ s/\<(\/?)${key}\>/<$1${key}>/g } @fields); - } - - } elsif ('tex' eq $format) { - my %markup_replace = ('b' => 'textbf', - 'i' => 'textit', - 'u' => 'underline'); - - foreach my $field (@fields) { - foreach my $key (keys(%markup_replace)) { - my $new = $markup_replace{$key}; - $self->{$field} =~ - s/\$\<\$${key}\$\>\$(.*?)\$<\$\/${key}\$>\$/\\${new}\{$1\}/gi; - } - } - } - - $main::lxdebug->leave_sub(); -} - sub datetonum { $main::lxdebug->enter_sub(); @@ -1381,11 +1111,53 @@ sub get_exchangerate { my ($exchangerate) = $sth->fetchrow_array; $sth->finish; + if ($exchangerate == 0) { + $exchangerate = 1; + } + $main::lxdebug->leave_sub(); return $exchangerate; } +sub set_payment_options { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $transdate) = @_; + + if ($self->{payment_id}) { + + my $dbh = $self->dbconnect($myconfig); + + + my $query = qq|SELECT p.terms_netto, p.terms_skonto, p.percent_skonto, p.description_long FROM payment_terms p + WHERE p.id = $self->{payment_id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $self->dberror($query); + + ($self->{terms_netto}, $self->{terms_skonto}, $self->{percent_skonto}, $self->{payment_terms}) = $sth->fetchrow_array; + + $sth->finish; + my $query = qq|SELECT date '$transdate' + $self->{terms_netto} AS netto_date,date '$transdate' + $self->{terms_skonto} AS skonto_date FROM payment_terms + LIMIT 1|; + my $sth = $dbh->prepare($query); + $sth->execute || $self->dberror($query); + ($self->{netto_date}, $self->{skonto_date}) = $sth->fetchrow_array; + $sth->finish; + + $self->{skonto_amount} = $self->format_amount($myconfig, ($self->parse_amount($myconfig, $self->{subtotal}) * $self->{percent_skonto}), 2); + + $self->{payment_terms} =~ s/<%netto_date%>/$self->{netto_date}/g; + $self->{payment_terms} =~ s/<%skonto_date%>/$self->{skonto_date}/g; + $self->{payment_terms} =~ s/<%skonto_amount%>/$self->{skonto_amount}/g; + + $dbh->disconnect; + } + + $main::lxdebug->leave_sub(); + +} + sub check_exchangerate { $main::lxdebug->enter_sub(); @@ -1413,10 +1185,90 @@ sub check_exchangerate { return $exchangerate; } +sub get_template_language { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig) = @_; + + my $template_code = ""; + + if ($self->{language_id}) { + + my $dbh = $self->dbconnect($myconfig); + + + my $query = qq|SELECT l.template_code FROM language l + WHERE l.id = $self->{language_id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $self->dberror($query); + + ($template_code) = $sth->fetchrow_array; + $sth->finish; + $dbh->disconnect; + } + + $main::lxdebug->leave_sub(); + + return $template_code; +} + +sub get_printer_code { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig) = @_; + + my $template_code = ""; + + if ($self->{printer_id}) { + + my $dbh = $self->dbconnect($myconfig); + + + my $query = qq|SELECT p.template_code,p.printer_command FROM printers p + WHERE p.id = $self->{printer_id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $self->dberror($query); + + ($template_code, $self->{printer_command}) = $sth->fetchrow_array; + $sth->finish; + $dbh->disconnect; + } + + $main::lxdebug->leave_sub(); + + return $template_code; +} + +sub get_shipto { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig) = @_; + + my $template_code = ""; + + if ($self->{shipto_id}) { + + my $dbh = $self->dbconnect($myconfig); + + + my $query = qq|SELECT s.* FROM shipto s + WHERE s.id = $self->{shipto_id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $self->dberror($query); + $ref = $sth->fetchrow_hashref(NAME_lc); + map { $form->{$_} = $ref->{$_} } keys %$ref; + $sth->finish; + $dbh->disconnect; + } + + $main::lxdebug->leave_sub(); + +} + sub add_shipto { $main::lxdebug->enter_sub(); - my ($self, $dbh, $id) = @_; + my ($self, $dbh, $id, $module) = @_; ##LINET my $shipto; foreach my $item ( @@ -1429,16 +1281,33 @@ sub add_shipto { } if ($shipto) { - my $query = + if ($self->{shipto_id}) { + my $query = qq| UPDATE shipto set + shiptoname = '$self->{shiptoname}', + shiptodepartment_1 = '$self->{shiptodepartment_1}', + shiptodepartment_2 = '$self->{shiptodepartment_2}', + shiptostreet = '$self->{shiptostreet}', + shiptozipcode = '$self->{shiptozipcode}', + shiptocity = '$self->{shiptocity}', + shiptocountry = '$self->{shiptocountry}', + shiptocontact = '$self->{shiptocontact}', + shiptophone = '$self->{shiptophone}', + shiptofax = '$self->{shiptofax}', + shiptoemail = '$self->{shiptoemail}' + WHERE id = $self->{shipto_id}|; + $dbh->do($query) || $self->dberror($query); + } else { + my $query = qq|INSERT INTO shipto (trans_id, shiptoname, shiptodepartment_1, shiptodepartment_2, shiptostreet, shiptozipcode, shiptocity, shiptocountry, shiptocontact, - shiptophone, shiptofax, shiptoemail) VALUES ($id, + shiptophone, shiptofax, shiptoemail, module) VALUES ($id, '$self->{shiptoname}', '$self->{shiptodepartment_1}', '$self->{shiptodepartment_2}', '$self->{shiptostreet}', '$self->{shiptozipcode}', '$self->{shiptocity}', '$self->{shiptocountry}', '$self->{shiptocontact}', '$self->{shiptophone}', '$self->{shiptofax}', - '$self->{shiptoemail}')|; - $dbh->do($query) || $self->dberror($query); + '$self->{shiptoemail}', '$module')|; + $dbh->do($query) || $self->dberror($query); + } } ##/LINET $main::lxdebug->leave_sub(); @@ -1488,7 +1357,7 @@ sub get_contacts { my ($self, $dbh, $id) = @_; - my $query = qq|SELECT c.cp_id, c.cp_cv_id, c.cp_name, c.cp_givenname + my $query = qq|SELECT c.cp_id, c.cp_cv_id, c.cp_name, c.cp_givenname, c.cp_abteilung FROM contacts c WHERE cp_cv_id=$id|; my $sth = $dbh->prepare($query); @@ -1501,7 +1370,7 @@ sub get_contacts { } if ($i == 0) { - push @{ $self->{all_contacts} }, { { "", "", "", "", "" } }; + push @{ $self->{all_contacts} }, { { "", "", "", "", "", "" } }; } $sth->finish; $main::lxdebug->leave_sub(); @@ -1638,6 +1507,117 @@ sub all_vc { } $sth->finish; + # get languages + $query = qq|SELECT id, description + FROM language + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{languages} }, $ref; + } + $sth->finish; + + # get printer + $query = qq|SELECT printer_description, id + FROM printers + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{printers} }, $ref; + } + $sth->finish; + + + # get payment terms + $query = qq|SELECT id, description + FROM payment_terms + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{payment_terms} }, $ref; + } + $sth->finish; + $dbh->disconnect; + $main::lxdebug->leave_sub(); +} + + +sub language_payment { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig) = @_; + undef $self->{languages}; + undef $self->{payment_terms}; + undef $self->{printers}; + + my $ref; + my $dbh = $self->dbconnect($myconfig); + # get languages + my $query = qq|SELECT id, description + FROM language + ORDER BY 1|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{languages} }, $ref; + } + $sth->finish; + + # get printer + $query = qq|SELECT printer_description, id + FROM printers + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{printers} }, $ref; + } + $sth->finish; + + # get payment terms + $query = qq|SELECT id, description + FROM payment_terms + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{payment_terms} }, $ref; + } + $sth->finish; + + # get buchungsgruppen + $query = qq|SELECT id, description + FROM buchungsgruppen|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $self->{BUCHUNGSGRUPPEN} = []; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{BUCHUNGSGRUPPEN} }, $ref; + } + $sth->finish; + + # get adr + $query = qq|SELECT id, adr_description, adr_code + FROM adr|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + $self->{ADR} = []; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{ADR} }, $ref; + } + $sth->finish; $dbh->disconnect; $main::lxdebug->leave_sub(); } @@ -1717,6 +1697,33 @@ sub create_links { } $sth->finish; + # get taxkeys and description + $query = qq|SELECT taxkey, taxdescription + FROM tax|; + $sth = $dbh->prepare($query); + $sth->execute || $self->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{TAXKEY} }, $ref; + } + + $sth->finish; + + + # get tax zones + $query = qq|SELECT id, description + FROM tax_zones|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{TAXZONE} }, $ref; + } + $sth->finish; + if (($module eq "AP") || ($module eq "AR")) { # get tax rates and description @@ -1738,7 +1745,7 @@ sub create_links { a.taxincluded, a.curr AS currency, a.notes, a.intnotes, c.name AS $table, a.department_id, d.description AS department, a.amount AS oldinvtotal, a.paid AS oldtotalpaid, - a.employee_id, e.name AS employee, a.gldate + a.employee_id, e.name AS employee, a.gldate, a.type FROM $arap a JOIN $table c ON (a.${table}_id = c.id) LEFT JOIN employee e ON (e.id = a.employee_id) @@ -1782,6 +1789,9 @@ sub create_links { if (!($xkeyref{ $ref->{accno} } =~ /tax/)) { $index++; } + if (($xkeyref{ $ref->{accno} } =~ /paid/) && ($self->{type} eq "credit_note")) { + $ref->{amount} *= -1; + } $ref->{index} = $index; push @{ $self->{acc_trans}{ $xkeyref{ $ref->{accno} } } }, $ref; diff --git a/SL/GL.pm b/SL/GL.pm index c56de7beb..d6723d3c5 100644 --- a/SL/GL.pm +++ b/SL/GL.pm @@ -362,7 +362,7 @@ sub all_transactions { } my $query = - qq|SELECT g.id, 'gl' AS type, $false AS invoice, g.reference, ac.taxkey, c.link, + qq|SELECT g.id, 'gl' AS type, $false AS invoice, g.reference, ac.taxkey, t.taxkey AS sorttax, g.description, ac.transdate, ac.source, ac.trans_id, ac.amount, c.accno, c.gifi_accno, g.notes, t.chart_id, ac.oid FROM gl g, acc_trans ac, chart c LEFT JOIN tax t ON @@ -371,7 +371,7 @@ sub all_transactions { AND ac.chart_id = c.id AND g.id = ac.trans_id UNION - SELECT a.id, 'ar' AS type, a.invoice, a.invnumber, ac.taxkey, c.link, + SELECT a.id, 'ar' AS type, a.invoice, a.invnumber, ac.taxkey, t.taxkey AS sorttax, ct.name, ac.transdate, ac.source, ac.trans_id, ac.amount, c.accno, c.gifi_accno, a.notes, t.chart_id, ac.oid FROM ar a, acc_trans ac, customer ct, chart c LEFT JOIN tax t ON @@ -381,7 +381,7 @@ sub all_transactions { AND a.customer_id = ct.id AND a.id = ac.trans_id UNION - SELECT a.id, 'ap' AS type, a.invoice, a.invnumber, ac.taxkey, c.link, + SELECT a.id, 'ap' AS type, a.invoice, a.invnumber, ac.taxkey, t.taxkey AS sorttax, ct.name, ac.transdate, ac.source, ac.trans_id, ac.amount, c.accno, c.gifi_accno, a.notes, t.chart_id, ac.oid FROM ap a, acc_trans ac, vendor ct, chart c LEFT JOIN tax t ON @@ -390,28 +390,18 @@ sub all_transactions { AND ac.chart_id = c.id AND a.vendor_id = ct.id AND a.id = ac.trans_id - ORDER BY $sortorder transdate, trans_id, taxkey DESC, oid|; - - # Show all $query in Debuglevel LXDebug::QUERY - $callingdetails = (caller (0))[3]; - $main::lxdebug->message(LXDebug::QUERY, "$callingdetails \$query=\n $query"); - + ORDER BY $sortorder transdate, trans_id, taxkey DESC, sorttax DESC,oid|; my $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); my $trans_id = ""; my $trans_id2 = ""; - while (my $ref0 = $sth->fetchrow_hashref(NAME_lc)) { - $trans_id = $ref0->{id}; - - if ($trans_id != $trans_id2) { # first line of a booking - + if ($trans_id != $trans_id2) { if ($trans_id2) { push @{ $form->{GL} }, $ref; $balance = 0; } - $ref = $ref0; $trans_id2 = $ref->{id}; @@ -437,101 +427,64 @@ sub all_transactions { $ref->{module} = "ar"; } } - $balance = $ref->{amount}; - - # Linenumbers of General Ledger - $k = 0; # Debit # AP # Soll - $l = 0; # Credit # AR # Haben - $i = 0; # Debit Tax # AP_tax # VSt - $j = 0; # Credit Tax # AR_tax # USt - - - if ($ref->{chart_id} > 0) { # all tax accounts first line, no line increasing - if ($ref->{amount} < 0) { - if ($ref->{link} =~ /AR_tax/) { - $ref->{credit_tax}{$j} = $ref->{amount}; - $ref->{credit_tax_accno}{$j} = $ref->{accno}; - } - if ($ref->{link} =~ /AP_tax/) { - $ref->{debit_tax}{$i} = $ref->{amount} * -1; - $ref->{debit_tax_accno}{$i} = $ref->{accno}; - } + $i = 0; + $j = 0; + $k = 0; + $l = 0; + if ($ref->{amount} < 0) { + if ($ref->{chart_id} > 0) { + $ref->{debit_tax}{$i} = $ref->{amount} * -1; + $ref->{debit_tax_accno}{$i} = $ref->{accno}; } else { - if ($ref->{link} =~ /AR_tax/) { - $ref->{credit_tax}{$j} = $ref->{amount}; - $ref->{credit_tax_accno}{$j} = $ref->{accno}; - } - if ($ref->{link} =~ /AP_tax/) { - $ref->{debit_tax}{$i} = $ref->{amount} * -1; - $ref->{debit_tax_accno}{$i} = $ref->{accno}; - } - } - } else { #all other accounts first line - if ($ref->{amount} < 0) { $ref->{debit}{$k} = $ref->{amount} * -1; $ref->{debit_accno}{$k} = $ref->{accno}; $ref->{debit_taxkey}{$k} = $ref->{taxkey}; - + } + } else { + if ($ref->{chart_id} > 0) { + $ref->{credit_tax}{$j} = $ref->{amount}; + $ref->{credit_tax_accno}{$j} = $ref->{accno}; } else { - $ref->{credit}{$l} = $ref->{amount} * 1; + $ref->{credit}{$l} = $ref->{amount}; $ref->{credit_accno}{$l} = $ref->{accno}; $ref->{credit_taxkey}{$l} = $ref->{taxkey}; - - } } - - } else { # following lines of a booking, line increasing - + } else { $ref2 = $ref0; - $trans_old =$trans_id2; $trans_id2 = $ref2->{id}; - + + # if ($form->{accno} eq ''){ # flo & udo: if general report, + # then check balance + # while (abs($balance) >= 0.015) { + # my $ref2 = $sth->fetchrow_hashref(NAME_lc) + # || $form->error("Unbalanced ledger!"); + # $balance = (int($balance * 100000) + int(100000 * $ref2->{amount})) / 100000; - - - if ($ref2->{chart_id} > 0) { # all tax accounts, following lines - if ($ref2->{amount} < 0) { - if ($ref2->{link} =~ /AR_tax/) { - if ($ref->{credit_tax_accno}{$j} ne "") { - $j++; - } - $ref->{credit_tax}{$j} = $ref2->{amount}; - $ref->{credit_tax_accno}{$j} = $ref2->{accno}; - } - if ($ref2->{link} =~ /AP_tax/) { - if ($ref->{debit_tax_accno}{$i} ne "") { - $i++; - } - $ref->{debit_tax}{$i} = $ref2->{amount} * -1; - $ref->{debit_tax_accno}{$i} = $ref2->{accno}; + if ($ref2->{amount} < 0) { + if ($ref2->{chart_id} > 0) { + if ($ref->{debit_tax_accno}{$i} ne "") { + $i++; } + $ref->{debit_tax}{$i} = $ref2->{amount} * -1; + $ref->{debit_tax_accno}{$i} = $ref2->{accno}; } else { - if ($ref2->{link} =~ /AR_tax/) { - if ($ref->{credit_tax_accno}{$j} ne "") { - $j++; - } - $ref->{credit_tax}{$j} = $ref2->{amount}; - $ref->{credit_tax_accno}{$j} = $ref2->{accno}; - } - if ($ref2->{link} =~ /AP_tax/) { - if ($ref->{debit_tax_accno}{$i} ne "") { - $i++; - } - $ref->{debit_tax}{$i} = $ref2->{amount} * -1; - $ref->{debit_tax_accno}{$i} = $ref2->{accno}; - } - } - } else { # all other accounts, following lines - if ($ref2->{amount} < 0) { if ($ref->{debit_accno}{$k} ne "") { $k++; } - $ref->{debit}{$k} = $ref2->{amount} * - 1; + $ref->{debit}{$k} = $ref2->{amount} * -1; $ref->{debit_accno}{$k} = $ref2->{accno}; $ref->{debit_taxkey}{$k} = $ref2->{taxkey}; + } + } else { + if ($ref2->{chart_id} > 0) { + if ($ref->{credit_tax_accno}{$j} ne "") { + $j++; + } + $ref->{credit_tax}{$j} = $ref2->{amount}; + $ref->{credit_tax_accno}{$j} = $ref2->{accno}; } else { if ($ref->{credit_accno}{$l} ne "") { $l++; @@ -541,7 +494,15 @@ sub all_transactions { $ref->{credit_taxkey}{$l} = $ref2->{taxkey}; } } + + # } + # } else { + # # if account-report, then calculate the Balance?! + # # ToDo: Calculate the Balance + # 1; + # } } + } push @{ $form->{GL} }, $ref; $sth->finish; diff --git a/SL/IC.pm b/SL/IC.pm index 8f2cfb35b..fb2944b85 100644 --- a/SL/IC.pm +++ b/SL/IC.pm @@ -193,6 +193,16 @@ sub get_part { } } + # get translations + $form->{language_values} = ""; + $query = qq|SELECT language_id, translation FROM translation WHERE parts_id = $form->{id}|; + $trq = $dbh->prepare($query); + $trq->execute || $form->dberror($query); + while ($tr = $trq->fetchrow_hashref(NAME_lc)) { + $form->{language_values} .= "---+++---".$tr->{language_id}."--++--".$tr->{translation}; + } + $trq->finish; + # now get accno for taxes $query = qq|SELECT c.accno FROM chart c, partstax pt @@ -227,6 +237,18 @@ sub get_part { $form->{orphaned} = !$form->{orphaned}; $sth->finish; + $form->{"unit_changeable"} = 1; + foreach my $table (qw(invoice assembly orderitems inventory license)) { + $query = "SELECT COUNT(*) FROM $table WHERE parts_id = ?"; + my ($count) = $dbh->selectrow_array($query, undef, $form->{"id"}); + $form->dberror($query . " (" . $form->{"id"} . ")") if ($dbh->err); + + if ($count) { + $form->{"unit_changeable"} = 0; + last; + } + } + $dbh->disconnect; $main::lxdebug->leave_sub(); @@ -277,12 +299,38 @@ sub get_pricegroups { $main::lxdebug->leave_sub(); } +sub retrieve_buchungsgruppen { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + my ($query, $sth); + + my $dbh = $form->dbconnect($myconfig); + + # get buchungsgruppen + $query = qq|SELECT id, description + FROM buchungsgruppen|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $form->{BUCHUNGSGRUPPEN} = []; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push(@{ $form->{BUCHUNGSGRUPPEN} }, $ref); + } + $sth->finish; + + $main::lxdebug->leave_sub(); +} + sub save { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; + $form->{IC_expense} = "1000"; + $form->{IC_income} = "2000"; - if ($form->{eur} && ($form->{item} ne 'service')) { + if ($form->{item} ne 'service') { $form->{IC} = $form->{IC_expense}; } @@ -322,6 +370,11 @@ sub save { $form->{onhand} *= 1; $form->{ve} *= 1; $form->{ge} *= 1; + $form->{alu} *= 1; + $form->{buchungsgruppen_id} *= 1; + $form->{adr_id} *= 1; + $form->{not_discountable} *= 1; + $form->{payment_id} *= 1; my ($query, $sth); @@ -373,6 +426,11 @@ sub save { WHERE parts_id = $form->{id}|; $dbh->do($query) || $form->dberror($query); + # delete translations + $query = qq|DELETE FROM translation + WHERE parts_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + } else { my $uid = rand() . time; $uid .= $form->{login}; @@ -429,8 +487,12 @@ sub save { priceupdate = $form->{priceupdate}, unit = '$form->{unit}', notes = '$form->{notes}', + formel = '$form->{formel}', rop = $form->{rop}, bin = '$form->{bin}', + buchungsgruppen_id = '$form->{buchungsgruppen_id}', + adr_id = '$form->{adr_id}', + payment_id = '$form->{payment_id}', inventory_accno_id = (SELECT c.id FROM chart c WHERE c.accno = '$form->{inventory_accno}'), income_accno_id = (SELECT c.id FROM chart c @@ -443,16 +505,33 @@ sub save { shop = '$form->{shop}', ve = '$form->{ve}', gv = '$form->{gv}', + alu = '$form->{alu}', + not_discountable = '$form->{not_discountable}', microfiche = '$form->{microfiche}', partsgroup_id = $partsgroup_id WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); + # delete translation records + $query = qq|DELETE FROM translation + WHERE parts_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + if ($form->{language_values} ne "") { + split /---\+\+\+---/,$form->{language_values}; + foreach $item (@_) { + my ($language_id, $translation, $longdescription) = split /--\+\+--/, $item; + if ($translation ne "") { + $query = qq|INSERT into translation (parts_id, language_id, translation, longdescription) VALUES + ($form->{id}, $language_id, | . $dbh->quote($translation) . qq|, | . $dbh->quote($longdescription) . qq| )|; + $dbh->do($query) || $form->dberror($query); + } + } + } # delete price records $query = qq|DELETE FROM prices WHERE parts_id = $form->{id}|; $dbh->do($query) || $form->dberror($query); - # insert price records only if different to sellprice for my $i (1 .. $form->{price_rows}) { if ($form->{"price_$i"} eq "0") { @@ -718,11 +797,6 @@ sub delete { # connect to database, turn off AutoCommit my $dbh = $form->dbconnect_noauto($myconfig); - # first delete prices of pricegroup - my $query = qq|DELETE FROM prices - WHERE parts_id = $form->{id}|; - $dbh->do($query) || $form->dberror($query); - my $query = qq|DELETE FROM parts WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); @@ -830,10 +904,14 @@ sub all_parts { my $group; my $limit; - foreach my $item (qw(partnumber drawing microfiche)) { + foreach my $item (qw(partnumber drawing microfiche make model)) { if ($form->{$item}) { $var = $form->like(lc $form->{$item}); - $where .= " AND lower(p.$item) LIKE '$var'"; + + # make will build later Bugfix 145 + if ($item ne 'make') { + $where .= " AND lower(p.$item) LIKE '$var'"; + } } } @@ -1001,7 +1079,7 @@ sub all_parts { p.priceupdate, p.image, p.drawing, p.microfiche, pg.partsgroup, a.invnumber, a.ordnumber, a.quonumber, i.trans_id, - ct.name, i.deliverydate|; + ct.name|; if ($form->{bought}) { $query = qq| @@ -1208,6 +1286,171 @@ sub all_parts { $main::lxdebug->leave_sub(); } +sub update_prices { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + my $where = '1 = 1'; + my $var; + + my $group; + my $limit; + + foreach my $item (qw(partnumber drawing microfiche make model)) { + if ($form->{$item}) { + $var = $form->like(lc $form->{$item}); + + # make will build later Bugfix 145 + if ($item ne 'make') { + $where .= " AND lower(p.$item) LIKE '$var'"; + } + } + } + + # special case for description + if ($form->{description}) { + unless ( $form->{bought} + || $form->{sold} + || $form->{onorder} + || $form->{ordered} + || $form->{rfq} + || $form->{quoted}) { + $var = $form->like(lc $form->{description}); + $where .= " AND lower(p.description) LIKE '$var'"; + } + } + + # special case for serialnumber + if ($form->{l_serialnumber}) { + if ($form->{serialnumber}) { + $var = $form->like(lc $form->{serialnumber}); + $where .= " AND lower(serialnumber) LIKE '$var'"; + } + } + + + # items which were never bought, sold or on an order + if ($form->{itemstatus} eq 'orphaned') { + $form->{onhand} = $form->{short} = 0; + $form->{bought} = $form->{sold} = 0; + $form->{onorder} = $form->{ordered} = 0; + $form->{rfq} = $form->{quoted} = 0; + + $form->{transdatefrom} = $form->{transdateto} = ""; + + $where .= " AND p.onhand = 0 + AND p.id NOT IN (SELECT p.id FROM parts p, invoice i + WHERE p.id = i.parts_id) + AND p.id NOT IN (SELECT p.id FROM parts p, assembly a + WHERE p.id = a.parts_id) + AND p.id NOT IN (SELECT p.id FROM parts p, orderitems o + WHERE p.id = o.parts_id)"; + } + + if ($form->{itemstatus} eq 'active') { + $where .= " AND p.obsolete = '0'"; + } + if ($form->{itemstatus} eq 'obsolete') { + $where .= " AND p.obsolete = '1'"; + $form->{onhand} = $form->{short} = 0; + } + if ($form->{itemstatus} eq 'onhand') { + $where .= " AND p.onhand > 0"; + } + if ($form->{itemstatus} eq 'short') { + $where .= " AND p.onhand < p.rop"; + } + if ($form->{make}) { + $var = $form->like(lc $form->{make}); + $where .= " AND p.id IN (SELECT DISTINCT ON (m.parts_id) m.parts_id + FROM makemodel m WHERE lower(m.make) LIKE '$var')"; + } + if ($form->{model}) { + $var = $form->like(lc $form->{model}); + $where .= " AND p.id IN (SELECT DISTINCT ON (m.parts_id) m.parts_id + FROM makemodel m WHERE lower(m.model) LIKE '$var')"; + } + if ($form->{partsgroup}) { + $var = $form->like(lc $form->{partsgroup}); + $where .= " AND lower(pg.partsgroup) LIKE '$var'"; + } + + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + if ($form->{"sellprice"} ne "") { + my $update = ""; + my $faktor = $form->parse_amount($myconfig,$form->{"sellprice"}); + if ($form->{"sellprice_type"} eq "percent") { + my $faktor = $form->parse_amount($myconfig,$form->{"sellprice"})/100 +1; + $update = "sellprice* $faktor"; + } else { + $update = "sellprice+$faktor"; + } + + $query = qq|UPDATE parts set sellprice=$update WHERE id IN (SELECT p.id + FROM parts p + LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) + WHERE $where)|; + $dbh->do($query); + } + + if ($form->{"listprice"} ne "") { + my $update = ""; + my $faktor = $form->parse_amount($myconfig,$form->{"listprice"}); + if ($form->{"listprice_type"} eq "percent") { + my $faktor = $form->parse_amount($myconfig,$form->{"sellprice"})/100 +1; + $update = "listprice* $faktor"; + } else { + $update = "listprice+$faktor"; + } + + $query = qq|UPDATE parts set listprice=$update WHERE id IN (SELECT p.id + FROM parts p + LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) + WHERE $where)|; + + $dbh->do($query); + } + + + + + for my $i (1 .. $form->{price_rows}) { + + my $query = ""; + + + if ($form->{"price_$i"} ne "") { + my $update = ""; + my $faktor = $form->parse_amount($myconfig,$form->{"price_$i"}); + if ($form->{"pricegroup_type_$i"} eq "percent") { + my $faktor = $form->parse_amount($myconfig,$form->{"sellprice"})/100 +1; + $update = "price* $faktor"; + } else { + $update = "price+$faktor"; + } + + $query = qq|UPDATE prices set price=$update WHERE parts_id IN (SELECT p.id + FROM parts p + LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) + WHERE $where) AND pricegroup_id=$form->{"pricegroup_id_$i"}|; + + $dbh->do($query); + } + } + + + + my $rc= $dbh->commit; + $dbh->disconnect; + $main::lxdebug->leave_sub(); + + return $rc; +} + sub create_links { $main::lxdebug->enter_sub(); @@ -1243,6 +1486,7 @@ sub create_links { { accno => $ref->{accno}, description => $ref->{description}, selected => "selected" }; + $form->{"${key}_default"} = "$ref->{accno}--$ref->{description}"; } else { push @{ $form->{"${module}_links"}{$key} }, { accno => $ref->{accno}, @@ -1254,6 +1498,43 @@ sub create_links { } $sth->finish; + # get buchungsgruppen + $query = qq|SELECT id, description + FROM buchungsgruppen|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $form->{BUCHUNGSGRUPPEN} = []; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{BUCHUNGSGRUPPEN} }, $ref; + } + $sth->finish; + + # get adr + $query = qq|SELECT id, adr_description, adr_code + FROM adr|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + $form->{ADR} = []; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ADR} }, $ref; + } + $sth->finish; + + # get payment terms + $query = qq|SELECT id, description + FROM payment_terms + ORDER BY 1|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{payment_terms} }, $ref; + } + $sth->finish; + if ($form->{id}) { $query = qq|SELECT weightunit FROM defaults|; @@ -1433,4 +1714,39 @@ sub retrieve_item { $main::lxdebug->leave_sub(); } +sub retrieve_languages { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + if ($form->{id}) { + $where .= "tr.parts_id=$form->{id}"; + } + + + if ($form->{language_values} ne "") { + $query = qq|SELECT l.id, l.description, tr.translation, tr.longdescription + FROM language l LEFT OUTER JOIN translation tr ON (tr.language_id=l.id AND $where)|; + } else { + $query = qq|SELECT l.id, l.description + FROM language l|; + } + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push(@{$languages}, $ref); + } + $sth->finish; + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); + return $languages; + +} + 1; diff --git a/SL/IR.pm b/SL/IR.pm index 5c243a468..69463ba49 100644 --- a/SL/IR.pm +++ b/SL/IR.pm @@ -34,6 +34,8 @@ package IR; +use SL::AM; + sub post_invoice { $main::lxdebug->enter_sub(); @@ -50,6 +52,9 @@ sub post_invoice { my $taxdiff; my $item; + my $service_units = AM->retrieve_units($myconfig,$form,"service"); + my $part_units = AM->retrieve_units($myconfig,$form,"dimension"); + if ($form->{id}) { &reverse_invoice($dbh, $form); @@ -98,9 +103,39 @@ sub post_invoice { for my $i (1 .. $form->{rowcount}) { $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"}); - + + if ($form->{storno}) { + $form->{"qty_$i"} *= -1; + } + if ($form->{"qty_$i"} != 0) { + # get item baseunit + $query = qq|SELECT p.unit + FROM parts p + WHERE p.id = $form->{"id_$i"}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my ($item_unit) = $sth->fetchrow_array(); + $sth->finish; + + if ($form->{"inventory_accno_$i"}) { + if (defined($part_units->{$item_unit}->{factor}) && $part_units->{$item_unit}->{factor} ne '' && $part_units->{$item_unit}->{factor} ne '0') { + $basefactor = $part_units->{$form->{"unit_$i"}}->{factor} / $part_units->{$item_unit}->{factor}; + } else { + $basefactor = 1; + } + $baseqty = $form->{"qty_$i"} * $basefactor; + } else { + if (defined($service_units->{$item_unit}->{factor}) && $service_units->{$item_unit}->{factor} ne '' && $service_units->{$item_unit}->{factor} ne '0') { + $basefactor = $service_units->{$form->{"unit_$i"}}->{factor} / $service_units->{$item_unit}->{factor}; + } else { + $basefactor = 1; + } + $baseqty = $form->{"qty_$i"} * $basefactor; + } + map { $form->{"${_}_$i"} =~ s/\'/\'\'/g } qw(partnumber description unit); @@ -186,7 +221,7 @@ sub post_invoice { $form->update_balance($dbh, "parts", "onhand", qq|id = $form->{"id_$i"}|, - $form->{"qty_$i"}) + $baseqty) unless $form->{shipped}; # check if we sold the item already and @@ -196,23 +231,23 @@ sub post_invoice { FROM invoice i, ar a, parts p WHERE i.parts_id = p.id AND i.parts_id = $form->{"id_$i"} - AND (i.qty + i.allocated) > 0 + AND (i.base_qty + i.allocated) > 0 AND i.trans_id = a.id ORDER BY transdate|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); - my $totalqty = $form->{"qty_$i"}; + my $totalqty = $base_qty; while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { - my $qty = $ref->{qty} + $ref->{allocated}; + my $qty = $ref->{base_qty} + $ref->{allocated}; if (($qty - $totalqty) > 0) { $qty = $totalqty; } - $linetotal = $form->round_amount($form->{"sellprice_$i"} * $qty, 2); + $linetotal = $form->round_amount(($form->{"sellprice_$i"} * $qty) / $basefactor, 2); if ($ref->{allocated} < 0) { @@ -343,11 +378,11 @@ sub post_invoice { : "NULL"; # save detail record in invoice table - $query = qq|INSERT INTO invoice (trans_id, parts_id, description, qty, + $query = qq|INSERT INTO invoice (trans_id, parts_id, description, qty, base_qty, sellprice, fxsellprice, allocated, unit, deliverydate, project_id, serialnumber) VALUES ($form->{id}, $form->{"id_$i"}, - '$form->{"description_$i"}', | . ($form->{"qty_$i"} * -1) . qq|, + '$form->{"description_$i"}', | . ($form->{"qty_$i"} * -1) . qq|, | . ($baseqty * -1) . qq|, $form->{"sellprice_$i"}, $fxsellprice, $allocated, '$form->{"unit_$i"}', $deliverydate, (SELECT id FROM project WHERE projectnumber = '$project_id'), '$form->{"serialnumber_$i"}')|; @@ -571,6 +606,11 @@ sub post_invoice { ($null, $form->{department_id}) = split(/--/, $form->{department}); $form->{department_id} *= 1; + $form->{payment_id} *= 1; + $form->{language_id} *= 1; + $form->{taxzone_id} *= 1; + $form->{storno} *= 1; + $form->{invnumber} = $form->{id} unless $form->{invnumber}; @@ -587,19 +627,34 @@ sub post_invoice { datepaid = $datepaid, duedate = $duedate, invoice = '1', + taxzone_id = '$form->{taxzone_id}', taxincluded = '$form->{taxincluded}', notes = '$form->{notes}', intnotes = '$form->{intnotes}', curr = '$form->{currency}', department_id = $form->{department_id}, + storno = '$form->{storno}', cp_id = $form->{contact_id} WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); + if ($form->{storno}) { + $query = qq| update ap set paid=paid+amount where id=$form->{storno_id}|; + $dbh->do($query) || $form->dberror($query); + $query = qq| update ap set storno='$form->{storno}' where id=$form->{storno_id}|; + $dbh->do($query) || $form->dberror($query); + $query = qq§ update ap set intnotes='Rechnung storniert am $form->{invdate} ' || intnotes where id=$form->{storno_id}§; + $dbh->do($query) || $form->dberror($query); + + $query = qq| update ap set paid=amount where id=$form->{id}|; + $dbh->do($query) || $form->dberror($query); + } + + # add shipto $form->{name} = $form->{vendor}; $form->{name} =~ s/--$form->{vendor_id}//; - $form->add_shipto($dbh, $form->{id}); + $form->add_shipto($dbh, $form->{id}, "AP"); # delete zero entries $query = qq|DELETE FROM acc_trans @@ -701,7 +756,7 @@ sub reverse_invoice { $dbh->do($query) || $form->dberror($query); $query = qq|DELETE FROM shipto - WHERE trans_id = $form->{id}|; + WHERE trans_id = $form->{id} AND module = 'AP'|; $dbh->do($query) || $form->dberror($query); $main::lxdebug->leave_sub(); @@ -786,7 +841,7 @@ sub retrieve_invoice { # retrieve invoice $query = qq|SELECT a.cp_id, a.invnumber, a.transdate AS invdate, a.duedate, - a.ordnumber, a.quonumber, a.paid, a.taxincluded, a.notes, + a.ordnumber, a.quonumber, a.paid, a.taxincluded, a.notes, a.taxzone_id, a.storno, a.intnotes, a.curr AS currency FROM ap a WHERE a.id = $form->{id}|; @@ -803,28 +858,36 @@ sub retrieve_invoice { # get shipto $query = qq|SELECT s.* FROM shipto s - WHERE s.trans_id = $form->{id}|; + WHERE s.trans_id = $form->{id} AND s.module = 'AP'|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); $ref = $sth->fetchrow_hashref(NAME_lc); + delete($ref->{id}); map { $form->{$_} = $ref->{$_} } keys %$ref; $sth->finish; + my $transdate = "current_date"; + if($form->{invdate}) { + $transdate = "'$form->{invdate}'"; + } + if(!$form->{taxzone_id}) { + $form->{taxzone_id} = 0; + } # retrieve individual items - $query = qq|SELECT c1.accno AS inventory_accno, - c2.accno AS income_accno, - c3.accno AS expense_accno, - p.partnumber, i.description, i.qty, i.fxsellprice AS sellprice, + $query = qq|SELECT c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid, + c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid, + c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid, + p.partnumber, i.description, i.qty, i.fxsellprice AS sellprice, p.inventory_accno_id AS part_inventory_accno_id, i.parts_id AS id, i.unit, p.bin, i.deliverydate, pr.projectnumber, i.project_id, i.serialnumber, pg.partsgroup FROM invoice i JOIN parts p ON (i.parts_id = p.id) - LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id) - LEFT JOIN chart c2 ON (p.income_accno_id = c2.id) - LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id) + LEFT JOIN chart c1 ON ((select inventory_accno_id from buchungsgruppen where id=p.buchungsgruppen_id) = c1.id) + LEFT JOIN chart c2 ON ((select income_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c2.id) + LEFT JOIN chart c3 ON ((select expense_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c3.id) LEFT JOIN project pr ON (i.project_id = pr.id) LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id) WHERE i.trans_id = $form->{id} @@ -833,6 +896,36 @@ sub retrieve_invoice { $sth->execute || $form->dberror($query); while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + if (!$ref->{"part_inventory_accno_id"}) { + map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid)); + } + delete($ref->{"part_inventory_accno_id"}); + + while ($ref->{inventory_new_chart} && ($ref->{inventory_valid} >=0)) { + my $query = qq| SELECT accno AS inventory_accno, new_chart_id AS inventory_new_chart, date($transdate) - valid_from AS inventory_valid FROM chart WHERE id = $ref->{inventory_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{inventory_accno}, $ref->{inventory_new_chart}, $ref->{inventory_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + while ($ref->{income_new_chart} && ($ref->{income_valid} >=0)) { + my $query = qq| SELECT accno AS income_accno, new_chart_id AS income_new_chart, date($transdate) - valid_from AS income_valid FROM chart WHERE id = $ref->{income_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{income_accno}, $ref->{income_new_chart}, $ref->{income_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + while ($ref->{expense_new_chart} && ($ref->{expense_valid} >=0)) { + my $query = qq| SELECT accno AS expense_accno, new_chart_id AS expense_new_chart, date($transdate) - valid_from AS expense_valid FROM chart WHERE id = $ref->{expense_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{expense_accno}, $ref->{expense_new_chart}, $ref->{expense_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + #set expense_accno=inventory_accno if they are different => bilanz $vendor_accno = @@ -847,20 +940,25 @@ sub retrieve_invoice { # get tax rates and description $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $vendor_accno; - $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber - FROM chart c, tax t - WHERE c.id=t.chart_id AND t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id') + $query = qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber + FROM tax t LEFT join chart c ON (c.id=t.chart_id) + WHERE t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id') ORDER BY accno|; $stw = $dbh->prepare($query); $stw->execute || $form->dberror($query); $ref->{taxaccounts} = ""; + my $i = 0; while ($ptr = $stw->fetchrow_hashref(NAME_lc)) { # if ($customertax{$ref->{accno}}) { + if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) { + $i++; + $ptr->{accno} = $i; + } $ref->{taxaccounts} .= "$ptr->{accno} "; if (!($form->{taxaccounts} =~ /$ptr->{accno}/)) { $form->{"$ptr->{accno}_rate"} = $ptr->{rate}; - $form->{"$ptr->{accno}_description"} = $ptr->{description}; + $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription}; $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; $form->{taxaccounts} .= "$ptr->{accno} "; } @@ -907,9 +1005,9 @@ sub get_vendor { # get vendor my $query = qq|SELECT v.name AS vendor, v.creditlimit, v.terms, - v.email, v.cc, v.bcc, v.language, - v.street, v.zipcode, v.city, v.country, - $duedate + v.terms AS duedate, v.notes AS intnotes + v.email, v.cc, v.bcc, v.language_id, v.payment_id, + v.street, v.zipcode, v.city, v.country, v.taxzone_id, + $duedate + v.terms AS duedate FROM vendor v WHERE v.id = $form->{vendor_id}|; my $sth = $dbh->prepare($query); @@ -962,7 +1060,7 @@ sub get_vendor { qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry shiptocontact shiptophone shiptofax shiptoemail); $query = qq|SELECT s.* FROM shipto s - WHERE s.trans_id = $form->{vendor_id}|; + WHERE s.trans_id = $form->{vendor_id} AND s.module= 'CT'|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); @@ -1050,19 +1148,33 @@ sub retrieve_item { $where .= " ORDER BY p.partnumber"; } + my $transdate = ""; + if ($form->{type} eq "invoice") { + $transdate = "'$form->{invdate}'"; + } elsif ($form->{type} eq "purchase_order") { + $transdate = "'$form->{transdate}'"; + } elsif ($form->{type} eq "request_quotation") { + $transdate = "'$form->{transdate}'"; + } + + if ($transdate eq "") { + $transdate = "current_date"; + } + # connect to database my $dbh = $form->dbconnect($myconfig); - my $query = qq|SELECT p.id, p.partnumber, p.description, - c1.accno AS inventory_accno, - c2.accno AS income_accno, - c3.accno AS expense_accno, - pg.partsgroup, - p.lastcost AS sellprice, p.unit, p.bin, p.onhand, p.notes AS partnotes + my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice, + p.listprice, p.inventory_accno_id, + c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid, + c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid, + c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid, + p.unit, p.assembly, p.bin, p.onhand, p.notes AS partnotes, p.notes AS longdescription, p.not_discountable, + pg.partsgroup, p.formel, p.alu FROM parts p - LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id) - LEFT JOIN chart c2 ON (p.income_accno_id = c2.id) - LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id) + LEFT JOIN chart c1 ON ((select inventory_accno_id from buchungsgruppen where id=p.buchungsgruppen_id) = c1.id) + LEFT JOIN chart c2 ON ((select income_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c2.id) + LEFT JOIN chart c3 ON ((select expense_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c3.id) LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id) WHERE $where|; my $sth = $dbh->prepare($query); @@ -1070,6 +1182,14 @@ sub retrieve_item { while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + # In der Buchungsgruppe ist immer ein Bestandskonto verknuepft, auch wenn + # es sich um eine Dienstleistung handelt. Bei Dienstleistungen muss das + # Buchungskonto also aus dem Ergebnis rausgenommen werden. + if (!$ref->{inventory_accno_id}) { + map({ delete($ref->{"inventory_${_}"}); } qw(accno new_chart valid)); + } + delete($ref->{inventory_accno_id}); + #set expense_accno=inventory_accno if they are different => bilanz $vendor_accno = ($ref->{expense_accno} != $ref->{inventory_accno}) @@ -1083,21 +1203,26 @@ sub retrieve_item { # get tax rates and description $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $vendor_accno; - $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber - FROM chart c, tax t - WHERE c.id=t.chart_id AND t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id') + $query = qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber + FROM tax t LEFT JOIN chart c ON (c.id=t.chart_id) + WHERE t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id') ORDER BY c.accno|; $stw = $dbh->prepare($query); $stw->execute || $form->dberror($query); $ref->{taxaccounts} = ""; + my $i = 0; while ($ptr = $stw->fetchrow_hashref(NAME_lc)) { # if ($customertax{$ref->{accno}}) { + if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) { + $i++; + $ptr->{accno} = $i; + } $ref->{taxaccounts} .= "$ptr->{accno} "; if (!($form->{taxaccounts} =~ /$ptr->{accno}/)) { $form->{"$ptr->{accno}_rate"} = $ptr->{rate}; - $form->{"$ptr->{accno}_description"} = $ptr->{description}; + $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription}; $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; $form->{taxaccounts} .= "$ptr->{accno} "; } @@ -1216,4 +1341,142 @@ SWITCH: { $main::lxdebug->leave_sub(); } +sub post_payment { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $locale) = @_; + + # connect to database, turn off autocommit + my $dbh = $form->dbconnect_noauto($myconfig); + + $form->{datepaid} = $form->{invdate}; + + # total payments, don't move we need it here + for my $i (1 .. $form->{paidaccounts}) { + $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"}); + $form->{paid} += $form->{"paid_$i"}; + $form->{datepaid} = $form->{"datepaid_$i"} if ($form->{"datepaid_$i"}); + } + + $form->{exchangerate} = + $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, + "buy"); + + # record payments and offsetting AP + for my $i (1 .. $form->{paidaccounts}) { + + if ($form->{"paid_$i"} != 0) { + my ($accno) = split /--/, $form->{"AP_paid_$i"}; + $form->{"datepaid_$i"} = $form->{invdate} + unless ($form->{"datepaid_$i"}); + $form->{datepaid} = $form->{"datepaid_$i"}; + + $exchangerate = 0; + if (($form->{currency} eq $form->{defaultcurrency}) || ($form->{defaultcurrency} eq "")) { + $form->{"exchangerate_$i"} = 1; + } else { + $exchangerate = + $form->check_exchangerate($myconfig, $form->{currency}, + $form->{"datepaid_$i"}, 'buy'); + + $form->{"exchangerate_$i"} = + ($exchangerate) + ? $exchangerate + : $form->parse_amount($myconfig, $form->{"exchangerate_$i"}); + } + + # record AP + $amount = + $form->round_amount($form->{"paid_$i"} * $form->{"exchangerate"}, + 2) * -1; + + + $query = qq|DELETE FROM acc_trans WHERE trans_id=$form->{id} AND chart_id=(SELECT c.id FROM chart c + WHERE c.accno = '$form->{AP}') AND amount=$amount AND transdate='$form->{"datepaid_$i"}'|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate) + VALUES ($form->{id}, (SELECT c.id FROM chart c + WHERE c.accno = '$form->{AP}'), + $amount, '$form->{"datepaid_$i"}')|; + $dbh->do($query) || $form->dberror($query); + + + + $query = qq|DELETE FROM acc_trans WHERE trans_id=$form->{id} AND chart_id=(SELECT c.id FROM chart c + WHERE c.accno = '$accno') AND amount=$form->{"paid_$i"} AND transdate='$form->{"datepaid_$i"}' AND source='$form->{"source_$i"}' AND memo='$form->{"memo_$i"}'|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, + source, memo) + VALUES ($form->{id}, (SELECT c.id FROM chart c + WHERE c.accno = '$accno'), + $form->{"paid_$i"}, '$form->{"datepaid_$i"}', + '$form->{"source_$i"}', '$form->{"memo_$i"}')|; + $dbh->do($query) || $form->dberror($query); + + + # gain/loss + $amount = + $form->{"paid_$i"} * $form->{exchangerate} - $form->{"paid_$i"} * + $form->{"exchangerate_$i"}; + if ($amount > 0) { + $form->{fx}{ $form->{fxgain_accno} }{ $form->{"datepaid_$i"} } += + $amount; + } else { + $form->{fx}{ $form->{fxloss_accno} }{ $form->{"datepaid_$i"} } += + $amount; + } + + $diff = 0; + + # update exchange rate + if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) { + $form->update_exchangerate($dbh, $form->{currency}, + $form->{"datepaid_$i"}, + $form->{"exchangerate_$i"}, 0); + } + } + } + + # record exchange rate differences and gains/losses + foreach my $accno (keys %{ $form->{fx} }) { + foreach my $transdate (keys %{ $form->{fx}{$accno} }) { + if ( + ($form->{fx}{$accno}{$transdate} = + $form->round_amount($form->{fx}{$accno}{$transdate}, 2) + ) != 0 + ) { + $query = qq|DELETE FROM acc_trans WHERE trans_id=$form->{id} AND chart_id=(SELECT c.id FROM chart c + WHERE c.accno = '$accno') AND amount=$form->{fx}{$accno}{$transdate} AND transdate='$transdate' AND cleared='0' AND fx_transaction='1'|; + $dbh->do($query) || $form->dberror($query); + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate, cleared, fx_transaction) + VALUES ($form->{id}, + (SELECT c.id FROM chart c + WHERE c.accno = '$accno'), + $form->{fx}{$accno}{$transdate}, '$transdate', '0', '1')|; + $dbh->do($query) || $form->dberror($query); + } + } + } + my $datepaid = ($form->{paid}) ? qq|'$form->{datepaid}'| : "NULL"; + + # save AP record + my $query = qq|UPDATE ap set + paid = $form->{paid}, + datepaid = $datepaid + WHERE id=$form->{id}|; + + $dbh->do($query) || $form->dberror($query); + + my $rc = $dbh->commit; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); + + return $rc; +} + 1; diff --git a/SL/IS.pm b/SL/IS.pm index e29f67fe2..686f8644c 100644 --- a/SL/IS.pm +++ b/SL/IS.pm @@ -35,6 +35,7 @@ package IS; use Data::Dumper; +use SL::AM; sub invoice_details { $main::lxdebug->enter_sub(); @@ -67,7 +68,6 @@ sub invoice_details { for $i (1 .. $form->{rowcount}) { $partsgroup = ""; if ($form->{"partsgroup_$i"} && $form->{groupitems}) { - $form->format_string("partsgroup_$i"); $partsgroup = $form->{"partsgroup_$i"}; } push @partsgroup, [$i, $partsgroup]; @@ -81,6 +81,14 @@ sub invoice_details { my $taxamount; my $taxbase; my $taxdiff; + my $nodiscount; + my $yesdiscount; + my $nodiscount_subtotal = 0; + my $discount_subtotal = 0; + my $position = 0; + my $subtotal_header = 0; + my $subposition = 0; + foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) { $i = $item->[0]; @@ -97,13 +105,27 @@ sub invoice_details { if ($form->{"qty_$i"} != 0) { - # add number, description and qty to $form->{number}, .... - push(@{ $form->{runningnumber} }, $i); + # add number, description and qty to $form->{number}, + if ($form->{"subtotal_$i"} && !$subtotal_header) { + $subtotal_header = $i; + $position = int($position); + $subposition = 0; + $position++; + } elsif ($subtotal_header) { + $subposition += 1; + $position = int($position); + $position = $position.".".$subposition; + } else { + $position = int($position); + $position++; + } + push(@{ $form->{runningnumber} }, $position); push(@{ $form->{number} }, qq|$form->{"partnumber_$i"}|); push(@{ $form->{serialnumber} }, qq|$form->{"serialnumber_$i"}|); push(@{ $form->{bin} }, qq|$form->{"bin_$i"}|); push(@{ $form->{"partnotes"} }, qq|$form->{"partnotes_$i"}|); push(@{ $form->{description} }, qq|$form->{"description_$i"}|); + push(@{ $form->{longdescription} }, qq|$form->{"longdescription_$i"}|); push(@{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"})); push(@{ $form->{unit} }, qq|$form->{"unit_$i"}|); @@ -112,6 +134,8 @@ sub invoice_details { push(@{ $form->{sellprice} }, $form->{"sellprice_$i"}); push(@{ $form->{ordnumber_oe} }, qq|$form->{"ordnumber_$i"}|); push(@{ $form->{transdate_oe} }, qq|$form->{"transdate_$i"}|); + push(@{ $form->{invnumber} }, qq|$form->{"invnumber"}|); + push(@{ $form->{invdate} }, qq|$form->{"invdate"}|); if ($form->{lizenzen}) { if ($form->{"licensenumber_$i"}) { @@ -162,6 +186,9 @@ sub invoice_details { my $linetotal = $form->round_amount($form->{"qty_$i"} * $form->{"netprice_$i"}, 2); + my $nodiscount_linetotal = + $form->round_amount($form->{"qty_$i"} * $sellprice, 2); + $discount = ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, $decimalplaces) @@ -170,12 +197,39 @@ sub invoice_details { push(@{ $form->{discount} }, $discount); push(@{ $form->{p_discount} }, $form->{"discount_$i"}); - + if (($form->{"discount_$i"} ne "") && ($form->{"discount_$i"} != 0)) { + $form->{discount_p} = $form->{"discount_$i"}; + } $form->{total} += $linetotal; + $discount_subtotal += $linetotal; + $form->{nodiscount_total} += $nodiscount_linetotal; + $nodiscount_subtotal += $nodiscount_linetotal; + $form->{discount_total} += $form->parse_amount($myconfig, $discount); + + if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) { + $discount_subtotal = $form->format_amount($myconfig, $discount_subtotal, 2); + push(@{ $form->{discount_sub} }, $discount_subtotal); + $nodiscount_subtotal = $form->format_amount($myconfig, $nodiscount_subtotal, 2); + push(@{ $form->{nodiscount_sub} }, $nodiscount_subtotal); + $discount_subtotal = 0; + $nodiscount_subtotal = 0; + $subtotal_header = 0; + } else { + push(@{ $form->{discount_sub} }, ""); + push(@{ $form->{nodiscount_sub} }, ""); + } + + if ($linetotal == $netto_linetotal) { + $nodiscount += $linetotal; + } push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2)); + push(@{ $form->{nodiscount_linetotal} }, + $form->format_amount($myconfig, $nodiscount_linetotal, 2)); + + @taxaccounts = split / /, $form->{"taxaccounts_$i"}; $taxrate = 0; $taxdiff = 0; @@ -247,20 +301,19 @@ sub invoice_details { while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) { map { push(@{ $form->{$_} }, "") } - qw(runningnumber number serialnumber unit qty bin sellprice listprice netprice discount linetotal); + qw(runningnumber number serialnumber unit qty bin sellprice listprice netprice discount linetotal nodiscount_linetotal); $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--"; push(@{ $form->{description} }, $sameitem); } map { $form->{"a_$_"} = $ref->{$_} } qw(partnumber description); - $form->format_string("a_partnumber", "a_description"); push(@{ $form->{description} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"} ) . qq| -- $form->{"a_partnumber"}, $form->{"a_description"}|); map { push(@{ $form->{$_} }, "") } - qw(number unit qty runningnumber serialnumber bin sellprice listprice netprice discount linetotal); + qw(number unit qty runningnumber serialnumber bin sellprice listprice netprice discount linetotal nodiscount_linetotal); } $sth->finish; @@ -269,18 +322,16 @@ sub invoice_details { } foreach my $item (sort keys %taxaccounts) { - if ($form->round_amount($taxaccounts{$item}, 2) != 0) { - push(@{ $form->{taxbase} }, - $form->format_amount($myconfig, $taxbase{$item}, 2)); + push(@{ $form->{taxbase} }, + $form->format_amount($myconfig, $taxbase{$item}, 2)); - $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2); + $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2); - push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2)); - push(@{ $form->{taxdescription} }, $form->{"${item}_description"}); - push(@{ $form->{taxrate} }, - $form->format_amount($myconfig, $form->{"${item}_rate"} * 100)); - push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"}); - } + push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2)); + push(@{ $form->{taxdescription} }, $form->{"${item}_description"}); + push(@{ $form->{taxrate} }, + $form->format_amount($myconfig, $form->{"${item}_rate"} * 100)); + push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"}); } for my $i (1 .. $form->{paidaccounts}) { @@ -296,12 +347,18 @@ sub invoice_details { } $form->{subtotal} = $form->format_amount($myconfig, $form->{total}, 2); + $yesdiscount = $form->{nodiscount_total} - $nodiscount; + $form->{nodiscount_subtotal} = $form->format_amount($myconfig, $form->{nodiscount_total}, 2); + $form->{discount_total} = $form->format_amount($myconfig, $form->{discount_total}, 2); + $form->{nodiscount} = $form->format_amount($myconfig, $nodiscount, 2); + $form->{yesdiscount} = $form->format_amount($myconfig, $yesdiscount, 2); + $form->{invtotal} = ($form->{taxincluded}) ? $form->{total} : $form->{total} + $tax; $form->{total} = $form->format_amount($myconfig, $form->{invtotal} - $form->{paid}, 2); $form->{invtotal} = $form->format_amount($myconfig, $form->{invtotal}, 2); - + $form->set_payment_options($myconfig, $form->{invdate}); $form->{paid} = $form->format_amount($myconfig, $form->{paid}, 2); $form->{username} = $myconfig->{name}; @@ -340,7 +397,7 @@ sub customer_details { my $dbh = $form->dbconnect($myconfig); # get contact id, set it if nessessary - ($null, $form->{cp_id}) = split /--/, $form->{contact}; + $form->{cp_id} *= 1; $contact = ""; if ($form->{cp_id}) { @@ -357,11 +414,36 @@ sub customer_details { $ref = $sth->fetchrow_hashref(NAME_lc); - # remove notes, id and taxincluded before copy back - delete @$ref{qw(id taxincluded notes)}; + # remove id and taxincluded before copy back + delete @$ref{qw(id taxincluded)}; map { $form->{$_} = $ref->{$_} } keys %$ref; - $sth->finish; + + if ($form->{delivery_customer_id}) { + my $query = qq|SELECT ct.*, ct.notes as customernotes + FROM customer ct + WHERE ct.id = $form->{delivery_customer_id} limit 1|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + + $sth->finish; + map { $form->{"dc_$_"} = $ref->{$_} } keys %$ref; + } + + if ($form->{delivery_vendor_id}) { + my $query = qq|SELECT ct.*, ct.notes as customernotes + FROM customer ct + WHERE ct.id = $form->{delivery_vendor_id} limit 1|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + + $sth->finish; + map { $form->{"dv_$_"} = $ref->{$_} } keys %$ref; + } $dbh->disconnect; $main::lxdebug->leave_sub(); @@ -383,12 +465,25 @@ sub post_invoice { $form->get_employee($dbh); } - ($null, $form->{contact_id}) = split /--/, $form->{contact}; + $form->{contact_id} = $form->{cp_id}; $form->{contact_id} *= 1; + $form->{payment_id} *= 1; + $form->{language_id} *= 1; + $form->{taxzone_id} *= 1; + $form->{delivery_customer_id} *= 1; + $form->{delivery_vendor_id} *= 1; + $form->{storno} *= 1; + $form->{shipto_id} *= 1; + ($null, $form->{department_id}) = split(/--/, $form->{department}); $form->{department_id} *= 1; + my $service_units = AM->retrieve_units($myconfig,$form,"service"); + my $part_units = AM->retrieve_units($myconfig,$form,"dimension"); + + + if ($form->{id}) { &reverse_invoice($dbh, $form); @@ -435,10 +530,47 @@ sub post_invoice { $form->{expense_inventory} = ""; foreach my $i (1 .. $form->{rowcount}) { - $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"}); + if ($form->{type} eq "credit_note") { + $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"}) * -1; + $form->{shipped} = 1; + } else { + $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"}); + } + my $basefactor; + my $basqty; + + if ($form->{storno}) { + $form->{"qty_$i"} *= -1; + } if ($form->{"qty_$i"} != 0) { + # get item baseunit + $query = qq|SELECT p.unit + FROM parts p + WHERE p.id = $form->{"id_$i"}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my ($item_unit) = $sth->fetchrow_array(); + $sth->finish; + + if ($form->{"inventory_accno_$i"}) { + if (defined($part_units->{$item_unit}->{factor}) && $part_units->{$item_unit}->{factor} ne '' && $part_units->{$item_unit}->{factor} ne '0') { + $basefactor = $part_units->{$form->{"unit_$i"}}->{factor} / $part_units->{$item_unit}->{factor}; + } else { + $basefactor = 1; + } + $baseqty = $form->{"qty_$i"} * $basefactor; + } else { + if (defined($service_units->{$item_unit}->{factor}) && $service_units->{$item_unit}->{factor} ne '' && $service_units->{$item_unit}->{factor} ne '0') { + $basefactor = $service_units->{$form->{"unit_$i"}}->{factor} / $service_units->{$item_unit}->{factor}; + } else { + $basefactor = 1; + } + $baseqty = $form->{"qty_$i"} * $basefactor; + } + map { $form->{"${_}_$i"} =~ s/\'/\'\'/g } (qw(partnumber description unit)); @@ -527,20 +659,20 @@ sub post_invoice { if ($sth->fetchrow_array) { $form->update_balance($dbh, "parts", "onhand", qq|id = $form->{"id_$i"}|, - $form->{"qty_$i"} * -1) + $baseqty * -1) unless $form->{shipped}; } $sth->finish; # record assembly item as allocated - &process_assembly($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"}); + &process_assembly($dbh, $form, $form->{"id_$i"}, $baseqty); } else { $form->update_balance($dbh, "parts", "onhand", qq|id = $form->{"id_$i"}|, - $form->{"qty_$i"} * -1) + $baseqty * -1) unless $form->{shipped}; - $allocated = &cogs($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"}); + $allocated = &cogs($dbh, $form, $form->{"id_$i"}, $baseqty, $basefactor); } } @@ -556,19 +688,20 @@ sub post_invoice { # get pricegroup_id and save ist ($null, my $pricegroup_id) = split /--/, $form->{"sellprice_drag_$i"}; $pricegroup_id *= 1; + my $subtotal = $form->{"subtotal_$i"} * 1; # save detail record in invoice table - $query = qq|INSERT INTO invoice (trans_id, parts_id, description, qty, + $query = qq|INSERT INTO invoice (trans_id, parts_id, description,longdescription, qty, sellprice, fxsellprice, discount, allocated, assemblyitem, unit, deliverydate, project_id, serialnumber, pricegroup_id, - ordnumber, transdate, cusordnumber) + ordnumber, transdate, cusordnumber, base_qty, subtotal) VALUES ($form->{id}, $form->{"id_$i"}, - '$form->{"description_$i"}', $form->{"qty_$i"}, + '$form->{"description_$i"}', '$form->{"longdescription_$i"}', $form->{"qty_$i"}, $form->{"sellprice_$i"}, $fxsellprice, $form->{"discount_$i"}, $allocated, 'f', '$form->{"unit_$i"}', $deliverydate, (SELECT id from project where projectnumber = '$project_id'), '$form->{"serialnumber_$i"}', '$pricegroup_id', - '$form->{"ordnumber_$i"}', '$form->{"transdate_$i"}', '$form->{"cusordnumber_$i"}')|; + '$form->{"ordnumber_$i"}', '$form->{"transdate_$i"}', '$form->{"cusordnumber_$i"}', $baseqty, '$subtotal')|; $dbh->do($query) || $form->dberror($query); if ($form->{lizenzen}) { @@ -594,7 +727,11 @@ sub post_invoice { # total payments, don't move we need it here for my $i (1 .. $form->{paidaccounts}) { - $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"}); + if ($form->{type} eq "credit_note") { + $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"}) * -1; + } else { + $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"}); + } $form->{paid} += $form->{"paid_$i"}; $form->{datepaid} = $form->{"datepaid_$i"} if ($form->{"datepaid_$i"}); } @@ -704,77 +841,79 @@ sub post_invoice { # $form->{amount}{$form->{id}}{$form->{AR}} = 1 if ($form->{amount}{$form->{id}}{$form->{AR}} == 0); # record payments and offsetting AR - for my $i (1 .. $form->{paidaccounts}) { - - if ($form->{"paid_$i"} != 0) { - my ($accno) = split /--/, $form->{"AR_paid_$i"}; - $form->{"datepaid_$i"} = $form->{invdate} - unless ($form->{"datepaid_$i"}); - $form->{datepaid} = $form->{"datepaid_$i"}; - - $exchangerate = 0; - - if ($form->{currency} eq $form->{defaultcurrency}) { - $form->{"exchangerate_$i"} = 1; - } else { - $exchangerate = - $form->check_exchangerate($myconfig, $form->{currency}, - $form->{"datepaid_$i"}, 'buy'); - - $form->{"exchangerate_$i"} = - ($exchangerate) - ? $exchangerate - : $form->parse_amount($myconfig, $form->{"exchangerate_$i"}); - } - - # record AR - $amount = - $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} + $diff, - 2); - - if ($form->{amount}{ $form->{id} }{ $form->{AR} } != 0) { - $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, - transdate) - VALUES ($form->{id}, (SELECT c.id FROM chart c - WHERE c.accno = '$form->{AR}'), - $amount, '$form->{"datepaid_$i"}')|; + if (!$form->{storno}) { + for my $i (1 .. $form->{paidaccounts}) { + + if ($form->{"paid_$i"} != 0) { + my ($accno) = split /--/, $form->{"AR_paid_$i"}; + $form->{"datepaid_$i"} = $form->{invdate} + unless ($form->{"datepaid_$i"}); + $form->{datepaid} = $form->{"datepaid_$i"}; + + $exchangerate = 0; + + if ($form->{currency} eq $form->{defaultcurrency}) { + $form->{"exchangerate_$i"} = 1; + } else { + $exchangerate = + $form->check_exchangerate($myconfig, $form->{currency}, + $form->{"datepaid_$i"}, 'buy'); + + $form->{"exchangerate_$i"} = + ($exchangerate) + ? $exchangerate + : $form->parse_amount($myconfig, $form->{"exchangerate_$i"}); + } + + # record AR + $amount = + $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} + $diff, + 2); + + if ($form->{amount}{ $form->{id} }{ $form->{AR} } != 0) { + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate) + VALUES ($form->{id}, (SELECT c.id FROM chart c + WHERE c.accno = '$form->{AR}'), + $amount, '$form->{"datepaid_$i"}')|; + $dbh->do($query) || $form->dberror($query); + } + + # record payment + $form->{"paid_$i"} *= -1; + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, + source, memo) + VALUES ($form->{id}, (SELECT c.id FROM chart c + WHERE c.accno = '$accno'), + $form->{"paid_$i"}, '$form->{"datepaid_$i"}', + '$form->{"source_$i"}', '$form->{"memo_$i"}')|; $dbh->do($query) || $form->dberror($query); - } - - # record payment - $form->{"paid_$i"} *= -1; - - $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, - source, memo) - VALUES ($form->{id}, (SELECT c.id FROM chart c - WHERE c.accno = '$accno'), - $form->{"paid_$i"}, '$form->{"datepaid_$i"}', - '$form->{"source_$i"}', '$form->{"memo_$i"}')|; - $dbh->do($query) || $form->dberror($query); - - # exchangerate difference - $form->{fx}{$accno}{ $form->{"datepaid_$i"} } += - $form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) + $diff; - - # gain/loss - $amount = - $form->{"paid_$i"} * $form->{exchangerate} - $form->{"paid_$i"} * - $form->{"exchangerate_$i"}; - if ($amount > 0) { - $form->{fx}{ $form->{fxgain_accno} }{ $form->{"datepaid_$i"} } += - $amount; - } else { - $form->{fx}{ $form->{fxloss_accno} }{ $form->{"datepaid_$i"} } += - $amount; - } - - $diff = 0; - - # update exchange rate - if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) { - $form->update_exchangerate($dbh, $form->{currency}, - $form->{"datepaid_$i"}, - $form->{"exchangerate_$i"}, 0); + + # exchangerate difference + $form->{fx}{$accno}{ $form->{"datepaid_$i"} } += + $form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) + $diff; + + # gain/loss + $amount = + $form->{"paid_$i"} * $form->{exchangerate} - $form->{"paid_$i"} * + $form->{"exchangerate_$i"}; + if ($amount > 0) { + $form->{fx}{ $form->{fxgain_accno} }{ $form->{"datepaid_$i"} } += + $amount; + } else { + $form->{fx}{ $form->{fxloss_accno} }{ $form->{"datepaid_$i"} } += + $amount; + } + + $diff = 0; + + # update exchange rate + if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) { + $form->update_exchangerate($dbh, $form->{currency}, + $form->{"datepaid_$i"}, + $form->{"exchangerate_$i"}, 0); + } } } } @@ -850,18 +989,41 @@ Message: $form->{message}\r| if $form->{message}; taxincluded = '$form->{taxincluded}', curr = '$form->{currency}', department_id = $form->{department_id}, + payment_id = $form->{payment_id}, + type = '$form->{type}', + language_id = $form->{language_id}, + taxzone_id = $form->{taxzone_id}, + shipto_id = $form->{shipto_id}, + delivery_customer_id = $form->{delivery_customer_id}, + delivery_vendor_id = $form->{delivery_vendor_id}, employee_id = $form->{employee_id}, + storno = '$form->{storno}', cp_id = $form->{contact_id} WHERE id = $form->{id} |; $dbh->do($query) || $form->dberror($query); + if ($form->{storno}) { + $query = qq| update ar set paid=paid+amount where id=$form->{storno_id}|; + $dbh->do($query) || $form->dberror($query); + $query = qq| update ar set storno='$form->{storno}' where id=$form->{storno_id}|; + $dbh->do($query) || $form->dberror($query); + $query = qq§ update ar set intnotes='Rechnung storniert am $form->{invdate} ' || intnotes where id=$form->{storno_id}§; + $dbh->do($query) || $form->dberror($query); + + $query = qq| update ar set paid=amount where id=$form->{id}|; + $dbh->do($query) || $form->dberror($query); + } + $form->{pago_total} = $amount; # add shipto $form->{name} = $form->{customer}; $form->{name} =~ s/--$form->{customer_id}//; - $form->add_shipto($dbh, $form->{id}); + + if (!$form->{shipto_id}) { + $form->add_shipto($dbh, $form->{id}, "AR"); + } # save printed, emailed and queued $form->save_status($dbh); @@ -878,6 +1040,150 @@ Message: $form->{message}\r| if $form->{message}; return $rc; } +sub post_payment { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form, $locale) = @_; + + # connect to database, turn off autocommit + my $dbh = $form->dbconnect_noauto($myconfig); + + $form->{datepaid} = $form->{invdate}; + + # total payments, don't move we need it here + for my $i (1 .. $form->{paidaccounts}) { + if ($form->{type} eq "credit_note") { + $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"}) * -1; + } else { + $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"}); + } + $form->{paid} += $form->{"paid_$i"}; + $form->{datepaid} = $form->{"datepaid_$i"} if ($form->{"datepaid_$i"}); + } + + $form->{exchangerate} = + $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, + "buy"); + + # record payments and offsetting AR + for my $i (1 .. $form->{paidaccounts}) { + + if ($form->{"paid_$i"} != 0) { + my ($accno) = split /--/, $form->{"AR_paid_$i"}; + $form->{"datepaid_$i"} = $form->{invdate} + unless ($form->{"datepaid_$i"}); + $form->{datepaid} = $form->{"datepaid_$i"}; + + $exchangerate = 0; + if (($form->{currency} eq $form->{defaultcurrency}) || ($form->{defaultcurrency} eq "")) { + $form->{"exchangerate_$i"} = 1; + } else { + $exchangerate = + $form->check_exchangerate($myconfig, $form->{currency}, + $form->{"datepaid_$i"}, 'buy'); + + $form->{"exchangerate_$i"} = + ($exchangerate) + ? $exchangerate + : $form->parse_amount($myconfig, $form->{"exchangerate_$i"}); + } + + # record AR + $amount = + $form->round_amount($form->{"paid_$i"} * $form->{"exchangerate"}, + 2); + + + $query = qq|DELETE FROM acc_trans WHERE trans_id=$form->{id} AND chart_id=(SELECT c.id FROM chart c + WHERE c.accno = '$form->{AR}') AND amount=$amount AND transdate='$form->{"datepaid_$i"}'|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate) + VALUES ($form->{id}, (SELECT c.id FROM chart c + WHERE c.accno = '$form->{AR}'), + $amount, '$form->{"datepaid_$i"}')|; + $dbh->do($query) || $form->dberror($query); + + + # record payment + $form->{"paid_$i"} *= -1; + + $query = qq|DELETE FROM acc_trans WHERE trans_id=$form->{id} AND chart_id=(SELECT c.id FROM chart c + WHERE c.accno = '$accno') AND amount=$form->{"paid_$i"} AND transdate='$form->{"datepaid_$i"}' AND source='$form->{"source_$i"}' AND memo='$form->{"memo_$i"}'|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, + source, memo) + VALUES ($form->{id}, (SELECT c.id FROM chart c + WHERE c.accno = '$accno'), + $form->{"paid_$i"}, '$form->{"datepaid_$i"}', + '$form->{"source_$i"}', '$form->{"memo_$i"}')|; + $dbh->do($query) || $form->dberror($query); + + + # gain/loss + $amount = + $form->{"paid_$i"} * $form->{exchangerate} - $form->{"paid_$i"} * + $form->{"exchangerate_$i"}; + if ($amount > 0) { + $form->{fx}{ $form->{fxgain_accno} }{ $form->{"datepaid_$i"} } += + $amount; + } else { + $form->{fx}{ $form->{fxloss_accno} }{ $form->{"datepaid_$i"} } += + $amount; + } + + $diff = 0; + + # update exchange rate + if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) { + $form->update_exchangerate($dbh, $form->{currency}, + $form->{"datepaid_$i"}, + $form->{"exchangerate_$i"}, 0); + } + } + } + + # record exchange rate differences and gains/losses + foreach my $accno (keys %{ $form->{fx} }) { + foreach my $transdate (keys %{ $form->{fx}{$accno} }) { + if ( + ($form->{fx}{$accno}{$transdate} = + $form->round_amount($form->{fx}{$accno}{$transdate}, 2) + ) != 0 + ) { + $query = qq|DELETE FROM acc_trans WHERE trans_id=$form->{id} AND chart_id=(SELECT c.id FROM chart c + WHERE c.accno = '$accno') AND amount=$form->{fx}{$accno}{$transdate} AND transdate='$transdate' AND cleared='0' AND fx_transaction='1'|; + $dbh->do($query) || $form->dberror($query); + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate, cleared, fx_transaction) + VALUES ($form->{id}, + (SELECT c.id FROM chart c + WHERE c.accno = '$accno'), + $form->{fx}{$accno}{$transdate}, '$transdate', '0', '1')|; + $dbh->do($query) || $form->dberror($query); + } + } + } + my $datepaid = ($form->{paid}) ? qq|'$form->{datepaid}'| : "NULL"; + + # save AR record + my $query = qq|UPDATE ar set + paid = $form->{paid}, + datepaid = $datepaid + WHERE id=$form->{id}|; + + $dbh->do($query) || $form->dberror($query); + + my $rc = $dbh->commit; + $dbh->disconnect; + + $main::lxdebug->leave_sub(); + + return $rc; +} + sub process_assembly { $main::lxdebug->enter_sub(); @@ -933,9 +1239,9 @@ sub process_assembly { sub cogs { $main::lxdebug->enter_sub(); - my ($dbh, $form, $id, $totalqty) = @_; + my ($dbh, $form, $id, $totalqty, $basefactor) = @_; - my $query = qq|SELECT i.id, i.trans_id, i.qty, i.allocated, i.sellprice, + my $query = qq|SELECT i.id, i.trans_id, i.base_qty, i.allocated, i.sellprice, (SELECT c.accno FROM chart c WHERE p.inventory_accno_id = c.id) AS inventory_accno, (SELECT c.accno FROM chart c @@ -943,7 +1249,7 @@ sub cogs { FROM invoice i, parts p WHERE i.parts_id = p.id AND i.parts_id = $id - AND (i.qty + i.allocated) < 0 + AND (i.base_qty + i.allocated) < 0 ORDER BY trans_id|; my $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); @@ -952,7 +1258,7 @@ sub cogs { my $qty; while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { - if (($qty = (($ref->{qty} * -1) - $ref->{allocated})) > $totalqty) { + if (($qty = (($ref->{base_qty} * -1) - $ref->{allocated})) > $totalqty) { $qty = $totalqty; } @@ -961,7 +1267,7 @@ sub cogs { # total expenses and inventory # sellprice is the cost of the item - $linetotal = $form->round_amount($ref->{sellprice} * $qty, 2); + $linetotal = $form->round_amount(($ref->{sellprice} * $qty) / $basefactor, 2); if (!$eur) { @@ -1062,7 +1368,7 @@ sub reverse_invoice { } $query = qq|DELETE FROM shipto - WHERE trans_id = $form->{id}|; + WHERE trans_id = $form->{id} AND module = 'AR'|; $dbh->do($query) || $form->dberror($query); $main::lxdebug->leave_sub(); @@ -1166,10 +1472,10 @@ sub retrieve_invoice { # retrieve invoice $query = qq|SELECT a.invnumber, a.ordnumber, a.quonumber, a.cusordnumber, - a.transdate AS invdate, a.deliverydate, a.paid, - a.shippingpoint, a.shipvia, a.terms, a.notes, a.intnotes, - a.duedate, a.taxincluded, a.curr AS currency, - a.employee_id, e.name AS employee + a.transdate AS invdate, a.deliverydate, a.paid, a.storno, + a.shippingpoint, a.shipvia, a.terms, a.notes, a.intnotes, a.taxzone_id, + a.duedate, a.taxincluded, a.curr AS currency, a.shipto_id, a.cp_id, + a.employee_id, e.name AS employee, a.payment_id, a.language_id, a.delivery_customer_id, a.delivery_vendor_id, a.type FROM ar a LEFT JOIN employee e ON (e.id = a.employee_id) WHERE a.id = $form->{id}|; @@ -1183,17 +1489,33 @@ sub retrieve_invoice { $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, "buy"); - # get shipto $query = qq|SELECT s.* FROM shipto s - WHERE s.trans_id = $form->{id}|; + WHERE s.trans_id = $form->{id} AND s.module = 'AR'|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); $ref = $sth->fetchrow_hashref(NAME_lc); + delete($ref->{id}); map { $form->{$_} = $ref->{$_} } keys %$ref; $sth->finish; + if ($form->{delivery_customer_id}) { + $query = qq|SELECT name FROM customer WHERE id=$form->{delivery_customer_id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + ($form->{delivery_customer_string}) = $sth->fetchrow_array(); + $sth->finish; + } + + if ($form->{delivery_vendor_id}) { + $query = qq|SELECT name FROM customer WHERE id=$form->{delivery_vendor_id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + ($form->{delivery_vendor_string}) = $sth->fetchrow_array(); + $sth->finish; + } + # get printed, emailed $query = qq|SELECT s.printed, s.emailed, s.spoolfile, s.formname FROM status s @@ -1210,34 +1532,71 @@ sub retrieve_invoice { $sth->finish; map { $form->{$_} =~ s/ +$//g } qw(printed emailed queued); + my $transdate = "current_date"; + if($form->{invdate}) { + $transdate = "'$form->{invdate}'"; + } + + if(!$form->{taxzone_id}) { + $form->{taxzone_id} = 0; + } # retrieve individual items - $query = qq|SELECT (SELECT c.accno FROM chart c - WHERE p.inventory_accno_id = c.id) - AS inventory_accno, - (SELECT c.accno FROM chart c - WHERE p.income_accno_id = c.id) - AS income_accno, - (SELECT c.accno FROM chart c - WHERE p.expense_accno_id = c.id) - AS expense_accno, - i.description, i.qty, i.fxsellprice AS sellprice, + $query = qq|SELECT + c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid, + c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid, + c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid, + i.description, i.longdescription, i.qty, i.fxsellprice AS sellprice, i.discount, i.parts_id AS id, i.unit, i.deliverydate, i.project_id, pr.projectnumber, i.serialnumber, - p.partnumber, p.assembly, p.bin, p.notes AS partnotes, i.id AS invoice_pos, + p.partnumber, p.assembly, p.bin, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, i.id AS invoice_pos, pg.partsgroup, i.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=i.pricegroup_id) as pricegroup, - i.ordnumber, i.transdate, i.cusordnumber + i.ordnumber, i.transdate, i.cusordnumber, p.alu, p.formel, i.subtotal FROM invoice i JOIN parts p ON (i.parts_id = p.id) LEFT JOIN project pr ON (i.project_id = pr.id) LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) - WHERE i.trans_id = $form->{id} + LEFT JOIN chart c1 ON ((select inventory_accno_id from buchungsgruppen where id=p.buchungsgruppen_id) = c1.id) + LEFT JOIN chart c2 ON ((select income_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c2.id) + LEFT JOIN chart c3 ON ((select expense_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c3.id) + WHERE i.trans_id = $form->{id} AND NOT i.assemblyitem = '1' ORDER BY i.id|; $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + if (!$ref->{"part_inventory_accno_id"}) { + map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid)); + } + delete($ref->{"part_inventory_accno_id"}); #set expense_accno=inventory_accno if they are different => bilanz + + + while ($ref->{inventory_new_chart} && ($ref->{inventory_valid} >=0)) { + my $query = qq| SELECT accno AS inventory_accno, new_chart_id AS inventory_new_chart, date($transdate) - valid_from AS inventory_valid FROM chart WHERE id = $ref->{inventory_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{inventory_accno}, $ref->{inventory_new_chart}, $ref->{inventory_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + while ($ref->{income_new_chart} && ($ref->{income_valid} >=0)) { + my $query = qq| SELECT accno AS income_accno, new_chart_id AS income_new_chart, date($transdate) - valid_from AS income_valid FROM chart WHERE id = $ref->{income_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{income_accno}, $ref->{income_new_chart}, $ref->{income_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + while ($ref->{expense_new_chart} && ($ref->{expense_valid} >=0)) { + my $query = qq| SELECT accno AS expense_accno, new_chart_id AS expense_new_chart, date($transdate) - valid_from AS expense_valid FROM chart WHERE id = $ref->{expense_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{expense_accno}, $ref->{expense_new_chart}, $ref->{expense_valid}) = $stw->fetchrow_array; + $stw->finish; + } + $vendor_accno = ($ref->{expense_accno} != $ref->{inventory_accno}) ? $ref->{inventory_accno} @@ -1246,20 +1605,26 @@ sub retrieve_invoice { # get tax rates and description $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $vendor_accno; - $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber - FROM chart c, tax t - WHERE c.id=t.chart_id AND t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id') + $query = qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber + FROM tax t LEFT join chart c ON (c.id=t.chart_id) + WHERE t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id') ORDER BY accno|; $stw = $dbh->prepare($query); $stw->execute || $form->dberror($query); $ref->{taxaccounts} = ""; + my $i=0; while ($ptr = $stw->fetchrow_hashref(NAME_lc)) { # if ($customertax{$ref->{accno}}) { + if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) { + $i++; + $ptr->{accno} = $i; + } $ref->{taxaccounts} .= "$ptr->{accno} "; + if (!($form->{taxaccounts} =~ /$ptr->{accno}/)) { $form->{"$ptr->{accno}_rate"} = $ptr->{rate}; - $form->{"$ptr->{accno}_description"} = $ptr->{description}; + $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription}; $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; $form->{taxaccounts} .= "$ptr->{accno} "; } @@ -1277,6 +1642,9 @@ sub retrieve_invoice { ""; $stg->finish(); } + if ($form->{type} eq "credit_note") { + $ref->{qty} *= -1; + } chop $ref->{taxaccounts}; push @{ $form->{invoice_details} }, $ref; @@ -1317,10 +1685,10 @@ sub get_customer { # get customer my $query = qq|SELECT c.name AS customer, c.discount, c.creditlimit, c.terms, - c.email, c.cc, c.bcc, c.language, + c.email, c.cc, c.bcc, c.language_id, c.payment_id AS customer_payment_id, c.street, c.zipcode, c.city, c.country, $duedate + c.terms AS duedate, c.notes AS intnotes, - b.discount AS tradediscount, b.description AS business, c.klass as customer_klass + b.discount AS tradediscount, b.description AS business, c.klass as customer_klass, c.taxzone_id FROM customer c LEFT JOIN business b ON (b.id = c.business_id) WHERE c.id = $form->{customer_id}|; @@ -1332,6 +1700,45 @@ sub get_customer { map { $form->{$_} = $ref->{$_} } keys %$ref; $sth->finish; + my $query = qq|SELECT sum(a.amount-a.paid) AS dunning_amount FROM ar a WHERE a.paid < a.amount AND a.customer_id=$form->{customer_id} AND a.dunning_id IS NOT NULL|; + my $sth = $dbh->prepare($query); + + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + $sth->finish; + + #print(STDERR "DUNNING AMOUTN $form->{dunning_amount}\n"); + + my $query = qq|SELECT dnn.dunning_description AS max_dunning_level FROM dunning_config dnn WHERE id in (select dunning_id from ar WHERE paid < amount AND customer_id=$form->{customer_id} AND dunning_id IS NOT NULL) ORDER BY dunning_level DESC LIMIT 1|; + my $sth = $dbh->prepare($query); + + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + + map { $form->{$_} = $ref->{$_} } keys %$ref; + $sth->finish; + #print(STDERR "LEVEL $form->{max_dunning_level}\n"); + + + #check whether payment_terms are better than old payment_terms + if (($form->{payment_id} ne "") && ($form->{customer_payment_id} ne "")) { + my $query = qq|select (select ranking from payment_terms WHERE id = $form->{payment_id}), (select ranking from payment_terms WHERE id = $form->{customer_payment_id})|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($old_ranking, $new_ranking) = $stw->fetchrow_array; + $stw->finish; + if ($new_ranking > $old_ranking) { + $form->{payment_id} =$form->{customer_payment_id}; + } + } + if ($form->{payment_id} eq "") { + $form->{payment_id} =$form->{customer_payment_id}; + } + $form->{creditremaining} = $form->{creditlimit}; $query = qq|SELECT SUM(a.amount - a.paid) FROM ar a @@ -1361,10 +1768,10 @@ sub get_customer { $sth->finish; $form->get_contacts($dbh, $form->{customer_id}); - ($null, $form->{cp_id}) = split /--/, $form->{contact}; + $form->{cp_id} *= 1; # get contact if selected - if ($form->{contact} ne "--" && $form->{contact} ne "") { + if ($form->{cp_id}) { $form->get_contact($dbh, $form->{cp_id}); } @@ -1374,11 +1781,12 @@ sub get_customer { qw(shiptoname shiptodepartment_1 shiptodepartment_2 shiptostreet shiptozipcode shiptocity shiptocountry shiptocontact shiptophone shiptofax shiptoemail); $query = qq|SELECT s.* FROM shipto s - WHERE s.trans_id = $form->{customer_id}|; + WHERE s.trans_id = $form->{customer_id} AND s.module = 'CT'|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); $ref = $sth->fetchrow_hashref(NAME_lc); + undef($ref->{id}); map { $form->{$_} = $ref->{$_} } keys %$ref; $sth->finish; } @@ -1397,6 +1805,19 @@ sub get_customer { } $sth->finish; + # get shipping addresses + $query = qq|SELECT s.id,s.shiptoname + FROM shipto s + WHERE s.trans_id = $form->{customer_id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $customertax = (); + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push(@{ $form->{SHIPTO} }, $ref); + } + $sth->finish; + # setup last accounts used for this customer if (!$form->{id} && $form->{type} !~ /_(order|quotation)/) { $query = qq|SELECT c.accno, c.description, c.link, c.category @@ -1459,28 +1880,89 @@ sub retrieve_item { $where .= " ORDER BY p.partnumber"; } + my $transdate = ""; + if ($form->{type} eq "invoice") { + $transdate = "'$form->{invdate}'"; + } elsif ($form->{type} eq "sales_order") { + $transdate = "'$form->{transdate}'"; + } elsif ($form->{type} eq "sales_quotation") { + $transdate = "'$form->{transdate}'"; + } + + if ($transdate eq "") { + $transdate = "current_date"; + } + # connect to database my $dbh = $form->dbconnect($myconfig); my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice, - p.listprice, - c1.accno AS inventory_accno, - c2.accno AS income_accno, - c3.accno AS expense_accno, - p.unit, p.assembly, p.bin, p.onhand, p.notes AS partnotes, - pg.partsgroup + p.listprice, p.inventory_accno_id, + c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid, + c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid, + c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid, + p.unit, p.assembly, p.bin, p.onhand, p.notes AS partnotes, p.notes AS longdescription, p.not_discountable, + pg.partsgroup, p.formel, p.alu, p.payment_id AS part_payment_id, adr.adr_description FROM parts p - LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id) - LEFT JOIN chart c2 ON (p.income_accno_id = c2.id) - LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id) + LEFT JOIN chart c1 ON ((select inventory_accno_id from buchungsgruppen where id=p.buchungsgruppen_id) = c1.id) + LEFT JOIN chart c2 ON ((select income_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c2.id) + LEFT JOIN chart c3 ON ((select expense_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c3.id) LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id) + LEFT JOIN adr adr ON (adr.id = p.adr_id) WHERE $where|; my $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + # In der Buchungsgruppe ist immer ein Bestandskonto verknuepft, auch wenn + # es sich um eine Dienstleistung handelt. Bei Dienstleistungen muss das + # Buchungskonto also aus dem Ergebnis rausgenommen werden. + if (!$ref->{inventory_accno_id}) { + map({ delete($ref->{"inventory_${_}"}); } qw(accno new_chart valid)); + } + delete($ref->{inventory_accno_id}); + #set expense_accno=inventory_accno if they are different => bilanz + + + while ($ref->{inventory_new_chart} && ($ref->{inventory_valid} >=0)) { + my $query = qq| SELECT accno AS inventory_accno, new_chart_id AS inventory_new_chart, date($transdate) - valid_from AS inventory_valid FROM chart WHERE id = $ref->{inventory_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{inventory_accno}, $ref->{inventory_new_chart}, $ref->{inventory_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + while ($ref->{income_new_chart} && ($ref->{income_valid} >=0)) { + my $query = qq| SELECT accno AS income_accno, new_chart_id AS income_new_chart, date($transdate) - valid_from AS income_valid FROM chart WHERE id = $ref->{income_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{income_accno}, $ref->{income_new_chart}, $ref->{income_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + while ($ref->{expense_new_chart} && ($ref->{expense_valid} >=0)) { + my $query = qq| SELECT accno AS expense_accno, new_chart_id AS expense_new_chart, date($transdate) - valid_from AS expense_valid FROM chart WHERE id = $ref->{expense_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{expense_accno}, $ref->{expense_new_chart}, $ref->{expense_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + #check whether payment_terms are better than old payment_terms + if (($form->{payment_id} ne "") && ($ref->{part_payment_id} ne "")) { + my $query = qq|select (select ranking from payment_terms WHERE id = $form->{payment_id}), (select ranking from payment_terms WHERE id = $ref->{part_payment_id})|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($old_ranking, $new_ranking) = $stw->fetchrow_array; + $stw->finish; + if ($new_ranking <= $old_ranking) { + $ref->{part_payment_id} = ""; + } + } + + $vendor_accno = ($ref->{expense_accno} != $ref->{inventory_accno}) ? $ref->{inventory_accno} @@ -1489,21 +1971,27 @@ sub retrieve_item { # get tax rates and description $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $vendor_accno; - $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber - FROM chart c, tax t - WHERE c.id=t.chart_id AND t.taxkey in (SELECT c2.taxkey_id from chart c2 where c2.accno = '$accno_id') + $query = qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber + FROM tax t LEFT JOIN chart c on (c.id=t.chart_id) + WHERE t.taxkey in (SELECT c2.taxkey_id from chart c2 where c2.accno = '$accno_id') ORDER BY c.accno|; $stw = $dbh->prepare($query); $stw->execute || $form->dberror($query); $ref->{taxaccounts} = ""; + my $i = 0; while ($ptr = $stw->fetchrow_hashref(NAME_lc)) { # if ($customertax{$ref->{accno}}) { + if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) { + $i++; + $ptr->{accno} = $i; + } $ref->{taxaccounts} .= "$ptr->{accno} "; + if (!($form->{taxaccounts} =~ /$ptr->{accno}/)) { $form->{"$ptr->{accno}_rate"} = $ptr->{rate}; - $form->{"$ptr->{accno}_description"} = $ptr->{description}; + $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription}; $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; $form->{taxaccounts} .= "$ptr->{accno} "; } @@ -1512,6 +2000,32 @@ sub retrieve_item { $stw->finish; chop $ref->{taxaccounts}; + if ($form->{language_id}) { + $query = qq|SELECT tr.translation, tr.longdescription + FROM translation tr + WHERE tr.language_id=$form->{language_id} AND tr.parts_id=$ref->{id}|; + $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + my ($translation, $longdescription) = $stw->fetchrow_array(); + if ($translation ne "") { + $ref->{description} = $translation; + $ref->{longdescription} = $longdescription; + + } else { + $query = qq|SELECT tr.translation, tr.longdescription + FROM translation tr + WHERE tr.language_id in (select id from language where article_code=(select article_code from language where id = $form->{language_id})) AND tr.parts_id=$ref->{id} LIMIT 1|; + $stg = $dbh->prepare($query); + $stg->execute || $form->dberror($query); + my ($translation) = $stg->fetchrow_array(); + if ($translation ne "") { + $ref->{description} = $translation; + $ref->{longdescription} = $longdescription; + } + $stg->finish; + } + $stw->finish; + } push @{ $form->{item_list} }, $ref; @@ -1550,7 +2064,9 @@ sub get_pricegroups_for_parts { my $i = 1; my $id = 0; - + my $dimension_units = AM->retrieve_units($myconfig, $form, "dimension"); + my $service_units = AM->retrieve_units($myconfig, $form, "service"); + my $all_units = AM->retrieve_units($myconfig, $form); while (($form->{"id_$i"}) or ($form->{"new_id_$i"})) { $id = $form->{"id_$i"}; @@ -1564,20 +2080,52 @@ sub get_pricegroups_for_parts { $form->{"sellprice_drag_$i"}; $pricegroup_old = $form->{"pricegroup_old_$i"}; - + $form->{"new_pricegroup_$i"} = $selectedpricegroup_id; + $form->{"old_pricegroup_$i"} = $pricegroup_old; $price_new = $form->{"price_new_$i"}; $price_old = $form->{"price_old_$i"}; - $query = qq|SELECT pricegroup_id, (SELECT p.sellprice from parts p where p.id = $id) as default_sellprice,(SELECT pg.pricegroup FROM pricegroup pg WHERE id=pricegroup_id) AS pricegroup, price, '' AS selected FROM prices WHERE parts_id = $id UNION SELECT 0 as pricegroup_id,(SELECT sellprice FROM parts WHERE id=$id) as default_sellprice,'' as pricegroup, (SELECT DISTINCT sellprice from parts where id=$id) as price, 'selected' AS selected from prices ORDER BY pricegroup|; $pkq = $dbh->prepare($query); $pkq->execute || $form->dberror($query); + if (!$form->{"unit_old_$i"}) { + # Neue Ware aus der Datenbank. In diesem Fall ist unit_$i die + # Einheit, wie sie in den Stammdaten hinterlegt wurde. + # Es sollte also angenommen werden, dass diese ausgewaehlt war. + $form->{"unit_old_$i"} = $form->{"unit_$i"}; + } + + # Die zuletzt ausgewaehlte mit der aktuell ausgewaehlten Einheit + # vergleichen und bei Unterschied den Preis entsprechend umrechnen. + $form->{"selected_unit_$i"} = $form->{"unit_$i"} unless ($form->{"selected_unit_$i"}); + + my $check_units = $form->{"inventory_accno_$i"} ? $dimension_units : $service_units; + if (!$check_units->{$form->{"selected_unit_$i"}} || + ($check_units->{$form->{"selected_unit_$i"}}->{"base_unit"} ne + $all_units->{$form->{"unit_old_$i"}}->{"base_unit"})) { + # Die ausgewaehlte Einheit ist fuer diesen Artikel nicht gueltig + # (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber + # um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen. + $form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"}; + } + my $basefactor = 1; + + if ($form->{"unit_old_$i"} ne $form->{"selected_unit_$i"}) { + if (defined($all_units->{$form->{"unit_old_$i"}}->{"factor"}) && + $all_units->{$form->{"unit_old_$i"}}->{"factor"}) { + $basefactor = $all_units->{$form->{"selected_unit_$i"}}->{"factor"} / + $all_units->{$form->{"unit_old_$i"}}->{"factor"}; + } + } + if (!$form->{"basefactor_$i"}) { + $form->{"basefactor_$i"} = 1; + } while ($pkr = $pkq->fetchrow_hashref(NAME_lc)) { # push @{ $form->{PRICES}{$id} }, $pkr; - push @{ $form->{PRICES}{$i} }, $pkr; + #push @{ $form->{PRICES}{$i} }, $pkr; $pkr->{id} = $id; $pkr->{selected} = ''; @@ -1586,13 +2134,17 @@ sub get_pricegroups_for_parts { $pkr->{price} /= $form->{exchangerate}; } + + $pkr->{price} *= $form->{"basefactor_$i"}; + + $pkr->{price} *= $basefactor; + $pkr->{price} = $form->format_amount($myconfig, $pkr->{price}, 5); if ($selectedpricegroup_id eq undef) { if ($pkr->{pricegroup_id} eq $form->{customer_klass}) { $pkr->{selected} = ' selected'; - $last->{selected} = ''; # no customer pricesgroup set if ($pkr->{price} == $pkr->{default_sellprice}) { @@ -1612,26 +2164,21 @@ sub get_pricegroups_for_parts { } } } + if ($selectedpricegroup_id or $selectedpricegroup_id == 0) { if ($selectedpricegroup_id ne $pricegroup_old) { if ($pkr->{pricegroup_id} eq $selectedpricegroup_id) { - if ($price_new != $form->{"sellprice_$i"}) { - } else { - $pkr->{selected} = ' selected'; - $last->{selected} = ''; - } + $pkr->{selected} = ' selected'; } } else { if (($price_new != $form->{"sellprice_$i"}) and ($price_new ne 0)) { if ($pkr->{pricegroup_id} == 0) { $pkr->{price} = $form->{"sellprice_$i"}; $pkr->{selected} = ' selected'; - $last->{selected} = ''; } } else { if ($pkr->{pricegroup_id} eq $selectedpricegroup_id) { $pkr->{selected} = ' selected'; - $last->{selected} = ''; if ( ($pkr->{pricegroup_id} == 0) and ($pkr->{price} == $form->{"sellprice_$i"})) { @@ -1643,7 +2190,11 @@ sub get_pricegroups_for_parts { } } } + push @{ $form->{PRICES}{$i} }, $pkr; + } + $form->{"basefactor_$i"} *= $basefactor; + $i++; $pkq->finish; diff --git a/SL/LICENSES.pm b/SL/LICENSES.pm index ce1e799d6..25b4d66ee 100644 --- a/SL/LICENSES.pm +++ b/SL/LICENSES.pm @@ -127,7 +127,7 @@ sub search { if ($form->{"customer_name"}) { $f .= " AND " if ($f); $f .= - "(l.customer_id IN (SELECT id FROM customer WHERE name ILIKE " + "(customer_id IN (SELECT id FROM customer WHERE name ILIKE " . $dbh->quote('%' . $form->{"customer_name"} . '%') . "))"; } diff --git a/SL/LXDebug.pm b/SL/LXDebug.pm index 3a56e62a9..72e097113 100644 --- a/SL/LXDebug.pm +++ b/SL/LXDebug.pm @@ -4,7 +4,6 @@ use constant NONE => 0; use constant INFO => 1; use constant DEBUG1 => 2; use constant DEBUG2 => 3; -use constant QUERY => 4; use constant FILE_TARGET => 0; use constant STDERR_TARGET => 1; @@ -55,50 +54,50 @@ sub set_target { sub enter_sub { my ($self, $level) = @_; - return if $global_trace_subs < $level; + return 1 if $global_trace_subs < $level; if (!$self->{"trace_subs"} && !$global_trace_subs) { - return; + return 1; } my ($package, $filename, $line, $subroutine) = caller(1); my ($dummy1, $self_filename, $self_line) = caller(0); - my $indent = " " x $self->{"calldepth"}; + my $indent = " " x $self->{"calldepth"}; $self->{"calldepth"} += 1; if (!defined($package)) { - $self->_write("enter_sub", $indent . "top-level?\n"); + $self->_write('sub', $indent . "\\ top-level?\n"); } else { - $self->_write("enter_sub", - $indent - . "${subroutine} in " + $self->_write('sub', $indent + . "\\ ${subroutine} in " . "${self_filename}:${self_line} called from " . "${filename}:${line}\n"); } + return 1; } sub leave_sub { my ($self, $level) = @_; - return if $global_trace_subs < $level; + return 1 if $global_trace_subs < $level; if (!$self->{"trace_subs"} && !$global_trace_subs) { - return; + return 1; } my ($package, $filename, $line, $subroutine) = caller(1); my ($dummy1, $self_filename, $self_line) = caller(0); $self->{"calldepth"} -= 1; - my $indent = " " x $self->{"calldepth"}; + my $indent = " " x $self->{"calldepth"}; if (!defined($package)) { - $self->_write("leave_sub", $indent . "top-level?\n"); + $self->_write('sub', $indent . "/ top-level?\n"); } else { - $self->_write("leave_sub", - $indent . "${subroutine} in " . "${self_filename}:${self_line}\n"); + $self->_write('sub', $indent . "/ ${subroutine} in " . "${self_filename}:${self_line}\n"); } + return 1; } sub message { @@ -110,11 +109,10 @@ sub message { } if ($log_level >= $level) { - $self->_write(INFO == $level ? "info" - : DEBUG1 == $level ? "debug1" - : DEBUG2 == $level ? "debug2" - : QUERY == $level ? "query":"", - $message ); + $self->_write(INFO == $level + ? "info" + : DEBUG1 == $level ? "debug1" : "debug2", + $message); } } @@ -137,7 +135,7 @@ sub enable_sub_tracing { sub disable_sub_tracing { my ($self) = @_; - $self->{"trace_subs"} = 0; + $self->{"trace_subs"} = 1; } sub _write { diff --git a/SL/Menu.pm b/SL/Menu.pm index bef524266..5da42e64a 100644 --- a/SL/Menu.pm +++ b/SL/Menu.pm @@ -69,7 +69,7 @@ sub menuitem { my $level = $form->escape($item); my $str = - qq|{path}&action=$action&level=$level&login=$form->{login}&password=$form->{password}|; + qq|{path}&action=$action&level=$level&login=$form->{login}&password=$form->{password}|; my @vars = qw(module action target href); @@ -150,8 +150,11 @@ sub access_control { @menu = grep { /^${menulevel}--/ } @{ $self->{ORDER} }; } - my @a = split /;/, $myconfig->{acs}; - my %excl; + my @a = split /;/, $myconfig->{acs}; + my $excl = (); + + # remove --AR, --AP from array + grep { ($a, $b) = split /--/; s/--$a$//; } @a; map { $excl{$_} = 1 } @a; diff --git a/SL/OE.pm b/SL/OE.pm index fab550712..0349977a7 100644 --- a/SL/OE.pm +++ b/SL/OE.pm @@ -34,6 +34,8 @@ package OE; +use SL::AM; + sub transactions { $main::lxdebug->enter_sub(); @@ -161,13 +163,23 @@ sub save { my ($query, $sth, $null); my $exchangerate = 0; + my $service_units = AM->retrieve_units($myconfig,$form,"service"); + my $part_units = AM->retrieve_units($myconfig,$form,"dimension"); + $form->{service_units} =$service_units; + $form->{part_units} =$part_units; + ($null, $form->{employee_id}) = split /--/, $form->{employee}; unless ($form->{employee_id}) { $form->get_employee($dbh); } - ($null, $form->{contact_id}) = split /--/, $form->{contact}; + $form->{contact_id} = $form->{cp_id}; $form->{contact_id} *= 1; + $form->{payment_id} *= 1; + $form->{language_id} *= 1; + $form->{shipto_id} *= 1; + $form->{delivery_customer_id} *= 1; + $form->{delivery_vendor_id} *= 1; my $ml = ($form->{type} eq 'sales_order') ? 1 : -1; @@ -180,7 +192,7 @@ sub save { $dbh->do($query) || $form->dberror($query); $query = qq|DELETE FROM shipto - WHERE trans_id = $form->{id}|; + WHERE trans_id = $form->{id} AND module = 'OE'|; $dbh->do($query) || $form->dberror($query); } else { @@ -229,6 +241,32 @@ sub save { if ($form->{"qty_$i"}) { + # get item baseunit + $query = qq|SELECT p.unit + FROM parts p + WHERE p.id = $form->{"id_$i"}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my ($item_unit) = $sth->fetchrow_array(); + $sth->finish; + + if ($form->{"inventory_accno_$i"}) { + if (defined($part_units->{$item_unit}->{factor}) && $part_units->{$item_unit}->{factor} ne '' && $part_units->{$item_unit}->{factor} ne '0') { + $basefactor = $part_units->{$form->{"unit_$i"}}->{factor} / $part_units->{$item_unit}->{factor}; + } else { + $basefactor = 1; + } + $baseqty = $form->{"qty_$i"} * $basefactor; + } else { + if (defined($service_units->{$item_unit}->{factor}) && $service_units->{$item_unit}->{factor} ne '' && $service_units->{$item_unit}->{factor} ne '0') { + $basefactor = $service_units->{$form->{"unit_$i"}}->{factor} / $service_units->{$item_unit}->{factor}; + } else { + $basefactor = 1; + } + $baseqty = $form->{"qty_$i"} * $basefactor; + } + map { $form->{"${_}_$i"} =~ s/\'/\'\'/g } qw(partnumber description unit); @@ -315,22 +353,23 @@ sub save { # get pricegroup_id and save ist ($null, my $pricegroup_id) = split /--/, $form->{"sellprice_drag_$i"}; $pricegroup_id *= 1; + $subtotal = $form->{"subtotal_$i"} * 1; # save detail record in orderitems table $query = qq|INSERT INTO orderitems (|; $query .= "id, " if $form->{"orderitems_id_$i"}; - $query .= qq|trans_id, parts_id, description, qty, sellprice, discount, + $query .= qq|trans_id, parts_id, description, longdescription, qty, base_qty, sellprice, discount, unit, reqdate, project_id, serialnumber, ship, pricegroup_id, - ordnumber, transdate, cusordnumber) + ordnumber, transdate, cusordnumber, subtotal) VALUES (|; $query .= qq|$form->{"orderitems_id_$i"},| if $form->{"orderitems_id_$i"}; $query .= qq|$form->{id}, $form->{"id_$i"}, - '$form->{"description_$i"}', $form->{"qty_$i"}, + '$form->{"description_$i"}', '$form->{"longdescription_$i"}', $form->{"qty_$i"}, $baseqty, $fxsellprice, $form->{"discount_$i"}, '$form->{"unit_$i"}', $reqdate, (SELECT id from project where projectnumber = '$project_id'), '$form->{"serialnumber_$i"}', $form->{"ship_$i"}, '$pricegroup_id', - '$form->{"ordnumber_$i"}', '$form->{"transdate_$i"}', '$form->{"cusordnumber_$i"}')|; + '$form->{"ordnumber_$i"}', '$form->{"transdate_$i"}', '$form->{"cusordnumber_$i"}', '$subtotal')|; $dbh->do($query) || $form->dberror($query); $form->{"sellprice_$i"} = $fxsellprice; @@ -395,6 +434,12 @@ Message: $form->{message}\r| if $form->{message}; ($null, $form->{department_id}) = split(/--/, $form->{department}); $form->{department_id} *= 1; + $form->{payment_id} *= 1; + $form->{language_id} *= 1; + $form->{taxzone_id} *= 1; + $form->{proforma} *= 1; + + # save OE record $query = qq|UPDATE oe set @@ -414,8 +459,15 @@ Message: $form->{message}\r| if $form->{message}; intnotes = '$form->{intnotes}', curr = '$form->{currency}', closed = '$form->{closed}', + proforma = '$form->{proforma}', quotation = '$quotation', department_id = $form->{department_id}, + language_id = $form->{language_id}, + taxzone_id = $form->{taxzone_id}, + shipto_id = $form->{shipto_id}, + payment_id = $form->{payment_id}, + delivery_vendor_id = $form->{delivery_vendor_id}, + delivery_customer_id = $form->{delivery_customer_id}, employee_id = $form->{employee_id}, cp_id = $form->{contact_id} WHERE id = $form->{id}|; @@ -430,7 +482,10 @@ Message: $form->{message}\r| if $form->{message}; # add shipto $form->{name} = $form->{ $form->{vc} }; $form->{name} =~ s/--$form->{"$form->{vc}_id"}//; - $form->add_shipto($dbh, $form->{id}); + + if (!$form->{shipto_id}) { + $form->add_shipto($dbh, $form->{id}, "OE"); + } # save printed, emailed, queued $form->save_status($dbh); @@ -558,7 +613,7 @@ sub delete { $dbh->do($query) || $form->dberror($query); $query = qq|DELETE FROM shipto - WHERE trans_id = $form->{id}|; + WHERE trans_id = $form->{id} AND module = 'OE'|; $dbh->do($query) || $form->dberror($query); my $rc = $dbh->commit; @@ -653,7 +708,7 @@ sub retrieve { o.curr AS currency, e.name AS employee, o.employee_id, o.$form->{vc}_id, cv.name AS $form->{vc}, o.amount AS invtotal, o.closed, o.reqdate, o.quonumber, o.department_id, o.cusordnumber, - d.description AS department + d.description AS department, o.payment_id, o.language_id, o.taxzone_id, o.delivery_customer_id, o.delivery_vendor_id, o.proforma, o.shipto_id FROM oe o JOIN $form->{vc} cv ON (o.$form->{vc}_id = cv.id) LEFT JOIN employee e ON (o.employee_id = e.id) @@ -671,6 +726,8 @@ sub retrieve { $ref = $sth->fetchrow_hashref(NAME_lc); map { $form->{$_} = $ref->{$_} } keys %$ref; + + # set all entries for multiple ids blank that yield different information while ($ref = $sth->fetchrow_hashref(NAME_lc)) { map { $form->{$_} = '' if ($ref->{$_} ne $form->{$_}) } keys %$ref; @@ -682,14 +739,31 @@ sub retrieve { $sth->finish; + if ($form->{delivery_customer_id}) { + $query = qq|SELECT name FROM customer WHERE id=$form->{delivery_customer_id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + ($form->{delivery_customer_string}) = $sth->fetchrow_array(); + $sth->finish; + } + + if ($form->{delivery_vendor_id}) { + $query = qq|SELECT name FROM customer WHERE id=$form->{delivery_vendor_id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + ($form->{delivery_vendor_string}) = $sth->fetchrow_array(); + $sth->finish; + } + # shipto and pinted/mailed/queued status makes only sense for single id retrieve if (!@ids) { $query = qq|SELECT s.* FROM shipto s - WHERE s.trans_id = $form->{id}|; + WHERE s.trans_id = $form->{id} AND s.module = 'OE'|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); $ref = $sth->fetchrow_hashref(NAME_lc); + delete($ref->{id}); map { $form->{$_} = $ref->{$_} } keys %$ref; $sth->finish; @@ -713,26 +787,33 @@ sub retrieve { my %oid = ('Pg' => 'oid', 'Oracle' => 'rowid'); + my $transdate = "'$form->{transdate}'"; + if (!$transdate) { + $transdate = "current_date"; + } + if(!$form->{taxzone_id}) { + $form->{taxzone_id} = 0; + } # retrieve individual items # this query looks up all information about the items # stuff different from the whole will not be overwritten, but saved with a suffix. $query = qq|SELECT o.id AS orderitems_id, - c1.accno AS inventory_accno, - c2.accno AS income_accno, - c3.accno AS expense_accno, + c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid, + c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid, + c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid, oe.ordnumber AS ordnumber_oe, oe.transdate AS transdate_oe, oe.cusordnumber AS cusordnumber_oe, p.partnumber, p.assembly, o.description, o.qty, - o.sellprice, o.parts_id AS id, o.unit, o.discount, p.bin, p.notes AS partnotes, + o.sellprice, o.parts_id AS id, o.unit, o.discount, p.bin, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, o.reqdate, o.project_id, o.serialnumber, o.ship, - o.ordnumber, o.transdate, o.cusordnumber, - pr.projectnumber, + o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription, + pr.projectnumber, p.alu, p.formel, pg.partsgroup, o.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=o.pricegroup_id) as pricegroup FROM orderitems o JOIN parts p ON (o.parts_id = p.id) JOIN oe ON (o.trans_id = oe.id) - LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id) - LEFT JOIN chart c2 ON (p.income_accno_id = c2.id) - LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id) + LEFT JOIN chart c1 ON ((select inventory_accno_id from buchungsgruppen where id=p.buchungsgruppen_id) = c1.id) + LEFT JOIN chart c2 ON ((select income_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c2.id) + LEFT JOIN chart c3 ON ((select expense_accno_id_$form->{taxzone_id} from buchungsgruppen where id=p.buchungsgruppen_id) = c3.id) LEFT JOIN project pr ON (o.project_id = pr.id) LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | @@ -746,6 +827,10 @@ sub retrieve { $sth->execute || $form->dberror($query); while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + if (!$ref->{"part_inventory_accno_id"}) { + map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid)); + } + delete($ref->{"part_inventory_accno_id"}); # in collective order, copy global ordnumber, transdate, cusordnumber into item scope # unless already present there @@ -755,8 +840,31 @@ sub retrieve { if (@ids); map { delete $ref->{$_} } qw|ordnumber_oe transdate_oe cusordnumber_oe|; - # delete orderitems_id in collective orders, so that they get cloned no matter what - delete $ref->{orderitems_id} if (@ids); + + + while ($ref->{inventory_new_chart} && ($ref->{inventory_valid} >=0)) { + my $query = qq| SELECT accno AS inventory_accno, new_chart_id AS inventory_new_chart, date($transdate) - valid_from AS inventory_valid FROM chart WHERE id = $ref->{inventory_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{inventory_accno}, $ref->{inventory_new_chart}, $ref->{inventory_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + while ($ref->{income_new_chart} && ($ref->{income_valid} >=0)) { + my $query = qq| SELECT accno AS income_accno, new_chart_id AS income_new_chart, date($transdate) - valid_from AS income_valid FROM chart WHERE id = $ref->{income_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{income_accno}, $ref->{income_new_chart}, $ref->{income_valid}) = $stw->fetchrow_array; + $stw->finish; + } + + while ($ref->{expense_new_chart} && ($ref->{expense_valid} >=0)) { + my $query = qq| SELECT accno AS expense_accno, new_chart_id AS expense_new_chart, date($transdate) - valid_from AS expense_valid FROM chart WHERE id = $ref->{expense_new_chart}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + ($ref->{expense_accno}, $ref->{expense_new_chart}, $ref->{expense_valid}) = $stw->fetchrow_array; + $stw->finish; + } #set expense_accno=inventory_accno if they are different => bilanz $vendor_accno = @@ -767,20 +875,25 @@ sub retrieve { # get tax rates and description $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $vendor_accno; - $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber - FROM chart c, tax t - WHERE c.id=t.chart_id AND t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id') + $query = qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber + FROM tax t LEFT JOIN chart c ON (c.id=t.chart_id) + WHERE t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id') ORDER BY accno|; $stw = $dbh->prepare($query); $stw->execute || $form->dberror($query); $ref->{taxaccounts} = ""; + my $i = 0; while ($ptr = $stw->fetchrow_hashref(NAME_lc)) { # if ($customertax{$ref->{accno}}) { + if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) { + $i++; + $ptr->{accno} = $i; + } $ref->{taxaccounts} .= "$ptr->{accno} "; if (!($form->{taxaccounts} =~ /$ptr->{accno}/)) { $form->{"$ptr->{accno}_rate"} = $ptr->{rate}; - $form->{"$ptr->{accno}_description"} = $ptr->{description}; + $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription}; $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; $form->{taxaccounts} .= "$ptr->{accno} "; } @@ -809,6 +922,19 @@ sub retrieve { &webdav_folder($myconfig, $form); } + # get tax zones + $query = qq|SELECT id, description + FROM tax_zones|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{TAXZONE} }, $ref; + } + $sth->finish; + + my $rc = $dbh->commit; $dbh->disconnect; @@ -826,11 +952,18 @@ sub order_details { my $dbh = $form->dbconnect($myconfig); my $query; my $sth; - + my $nodiscount; + my $yesdiscount; + my $nodiscount_subtotal = 0; + my $discount_subtotal = 0; my $item; my $i; my @partsgroup = (); my $partsgroup; + my $position = 0; + my $subtotal_header = 0; + my $subposition = 0; + my %oid = ('Pg' => 'oid', 'Oracle' => 'rowid'); @@ -838,7 +971,6 @@ sub order_details { for $i (1 .. $form->{rowcount}) { $partsgroup = ""; if ($form->{"partsgroup_$i"} && $form->{groupitems}) { - $form->format_string("partsgroup_$i"); $partsgroup = $form->{"partsgroup_$i"}; } push @partsgroup, [$i, $partsgroup]; @@ -885,9 +1017,25 @@ sub order_details { if ($form->{"qty_$i"} != 0) { # add number, description and qty to $form->{number}, .... + + if ($form->{"subtotal_$i"} && !$subtotal_header) { + $subtotal_header = $i; + $position = int($position); + $subposition = 0; + $position++; + } elsif ($subtotal_header) { + $subposition += 1; + $position = int($position); + $position = $position.".".$subposition; + } else { + $position = int($position); + $position++; + } + push(@{ $form->{runningnumber} }, $i); push(@{ $form->{number} }, qq|$form->{"partnumber_$i"}|); push(@{ $form->{description} }, qq|$form->{"description_$i"}|); + push(@{ $form->{longdescription} }, qq|$form->{"longdescription_$i"}|); push(@{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"})); push(@{ $form->{ship} }, @@ -919,7 +1067,8 @@ sub order_details { # keep a netprice as well, (sellprice - discount) #$form->{"netprice_$i"} = $sellprice - $discount; $form->{"netprice_$i"} = $sellprice - $i_discount; - + my $nodiscount_linetotal = + $form->round_amount($form->{"qty_$i"} * $sellprice, 2); my $linetotal = $form->round_amount($form->{"qty_$i"} * $form->{"netprice_$i"}, 2); @@ -941,9 +1090,31 @@ sub order_details { push(@{ $form->{p_discount} }, $form->{"discount_$i"}); $form->{ordtotal} += $linetotal; + $discount_subtotal += $linetotal; + $form->{nodiscount_total} += $nodiscount_linetotal; + $nodiscount_subtotal += $nodiscount_linetotal; + $form->{discount_total} += $form->parse_amount($myconfig, $discount); + + if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) { + $discount_subtotal = $form->format_amount($myconfig, $discount_subtotal, 2); + push(@{ $form->{discount_sub} }, $discount_subtotal); + $nodiscount_subtotal = $form->format_amount($myconfig, $nodiscount_subtotal, 2); + push(@{ $form->{nodiscount_sub} }, $nodiscount_subtotal); + $discount_subtotal = 0; + $nodiscount_subtotal = 0; + $subtotal_header = 0; + } else { + push(@{ $form->{discount_sub} }, ""); + push(@{ $form->{nodiscount_sub} }, ""); + } + if ($linetotal == $netto_linetotal) { + $nodiscount += $linetotal; + } push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2)); + push(@{ $form->{nodiscount_linetotal} }, + $form->format_amount($myconfig, $nodiscount_linetotal, 2)); my ($taxamount, $taxbase); my $taxrate = 0; @@ -998,7 +1169,7 @@ sub order_details { while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) { map { push(@{ $form->{$_} }, "") } - qw(runningnumber ship bin serialnumber number unit bin qty reqdate sellprice listprice netprice discount linetotal); + qw(runningnumber ship bin serialnumber number unit bin qty reqdate sellprice listprice netprice discount linetotal nodiscount_linetotal); $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--"; push(@{ $form->{description} }, $sameitem); } @@ -1009,7 +1180,7 @@ sub order_details { . qq|, $ref->{partnumber}, $ref->{description}|); map { push(@{ $form->{$_} }, "") } - qw(number unit qty runningnumber ship bin serialnumber reqdate sellprice listprice netprice discount linetotal); + qw(number unit qty runningnumber ship bin serialnumber reqdate sellprice listprice netprice discount linetotal nodiscount_linetotal); } $sth->finish; @@ -1020,7 +1191,6 @@ sub order_details { my $tax = 0; foreach $item (sort keys %taxaccounts) { - if ($form->round_amount($taxaccounts{$item}, 2) != 0) { push(@{ $form->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2)); @@ -1031,8 +1201,13 @@ sub order_details { push(@{ $form->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100)); push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"}); - } } + $form->{subtotal} = $form->format_amount($myconfig, $form->{total}, 2); + $yesdiscount = $form->{nodiscount_total} - $nodiscount; + $form->{nodiscount_subtotal} = $form->format_amount($myconfig, $form->{nodiscount_total}, 2); + $form->{discount_total} = $form->format_amount($myconfig, $form->{discount_total}, 2); + $form->{nodiscount} = $form->format_amount($myconfig, $nodiscount, 2); + $form->{yesdiscount} = $form->format_amount($myconfig, $yesdiscount, 2); $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2); $form->{ordtotal} = @@ -1042,6 +1217,12 @@ sub order_details { $form->{quototal} = $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2); + if ($form->{type} =~ /_quotation/) { + $form->set_payment_options($myconfig, $form->{quodate}); + } else { + $form->set_payment_options($myconfig, $form->{orddate}); + } + # myconfig variables map { $form->{$_} = $myconfig->{$_} } (qw(company address tel fax signature businessnumber)); @@ -1203,7 +1384,10 @@ sub adj_onhand { my ($dbh, $form, $ml) = @_; - my $query = qq|SELECT oi.parts_id, oi.ship, p.inventory_accno_id, p.assembly + my $service_units = $form->{service_units}; + my $part_units = $form->{part_units}; + + my $query = qq|SELECT oi.parts_id, oi.ship, oi.unit, p.inventory_accno_id, p.assembly FROM orderitems oi JOIN parts p ON (p.id = oi.parts_id) WHERE oi.trans_id = $form->{id}|; @@ -1219,6 +1403,7 @@ sub adj_onhand { my $ispa; while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + #print(STDERR "Bin in Schleife $ref->{inventory_accno_id}\n"); if ($ref->{inventory_accno_id} || $ref->{assembly}) { @@ -1233,10 +1418,37 @@ sub adj_onhand { } + # get item baseunit + $query = qq|SELECT p.unit + FROM parts p + WHERE p.id = $ref->{parts_id}|; + my $stw = $dbh->prepare($query); + $stw->execute || $form->dberror($query); + + my ($item_unit) = $stw->fetchrow_array(); + $stw->finish; + + if ($ref->{inventory_accno_id}) { + if (defined($part_units->{$item_unit}->{factor}) && $part_units->{$item_unit}->{factor} ne '' && $part_units->{$item_unit}->{factor} ne '0') { + $basefactor = $part_units->{$ref->{unit}}->{factor} / $part_units->{$item_unit}->{factor}; + } else { + $basefactor = 1; + } + $baseqty = $ref->{ship} * $basefactor; + } else { + if (defined($service_units->{$item_unit}->{factor}) && $service_units->{$item_unit}->{factor} ne '' && $service_units->{$item_unit}->{factor} ne '0') { + $basefactor = $service_units->{$ref->{unit}}->{factor} / $part_units->{$item_unit}->{factor}; + } else { + $basefactor = 1; + } + $baseqty = $ref->{ship} * $basefactor; + } + #print(STDERR "$baseqty Basismenge\n"); + # adjust onhand in parts table $form->update_balance($dbh, "parts", "onhand", qq|id = $ref->{parts_id}|, - $ref->{ship} * $ml); + $baseqty * $ml); } } diff --git a/SL/RC.pm b/SL/RC.pm index 6de28ab65..63a41f434 100644 --- a/SL/RC.pm +++ b/SL/RC.pm @@ -73,7 +73,7 @@ sub payment_transactions { if ($form->{fromdate}) { $query = qq|SELECT sum(a.amount), (SELECT DISTINCT c2.category FROM chart c2 - WHERE c2.accno = '$form->{accno}') AS category + WHERE c2accno = '$form->{accno}') AS category FROM acc_trans a JOIN chart c ON (c.id = a.chart_id) WHERE a.transdate < date '$form->{fromdate}' diff --git a/SL/Template.pm b/SL/Template.pm new file mode 100644 index 000000000..5763eee46 --- /dev/null +++ b/SL/Template.pm @@ -0,0 +1,838 @@ +#==================================================================== +# LX-Office ERP +# Copyright (C) 2004 +# Based on SQL-Ledger Version 2.1.9 +# Web http://www.lx-office.org +# +#==================================================================== + +package SimpleTemplate; + +# Parameters: +# 1. The template's file name +# 2. A reference to the Form object +# 3. A reference to the myconfig hash +# +# Returns: +# A new template object +sub new { + my $type = shift; + my $self = {}; + + bless($self, $type); + $self->_init(@_); + + return $self; +} + +sub _init { + my $self = shift; + + $self->{"source"} = shift; + $self->{"form"} = shift; + $self->{"myconfig"} = shift; + $self->{"userspath"} = shift; + + $self->{"error"} = undef; +} + +sub cleanup { + my ($self) = @_; +} + +# Parameters: +# 1. A typeglob for the file handle. The output will be written +# to this file handle. +# +# Returns: +# 1 on success and undef or 0 if there was an error. In the latter case +# the calling function can retrieve the error message via $obj->get_error() +sub parse { + my $self = $_[0]; + local *OUT = $_[1]; + + print(OUT "Hallo!\n"); +} + +sub get_error { + my $self = shift; + + return $self->{"error"}; +} + +sub uses_temp_file { + return 0; +} + +1; + +#### +#### LaTeXTemplate +#### + +package LaTeXTemplate; + +use vars qw(@ISA); + +@ISA = qw(SimpleTemplate); + +sub new { + my $type = shift; + + return $type->SUPER::new(@_); +} + +sub format_string { + my ($self, $variable) = @_; + my $form = $self->{"form"}; + + my %replace = + ('order' => [ + '&', quotemeta("\n"), + '"', '\$', '%', '_', '#', quotemeta('^'), + '{', '}', '<', '>', '£', "\r" + ], + '"' => "''", + '&' => '\&', + '\$' => '\$', + '%' => '\%', + '_' => '\_', + '#' => '\#', + '{' => '\{', + '}' => '\}', + '<' => '$<$', + '>' => '$>$', + '£' => '\pounds ', + "\r" => "", + quotemeta('^') => '\^\\', + quotemeta("\n") => '\newline ' + ); + + map({ $variable =~ s/$_/$replace{$_}/g; } @{ $replace{"order"} }); + + # Allow some HTML markup to be converted into the output format's + # corresponding markup code, e.g. bold or italic. + my %markup_replace = ('b' => 'textbf', + 'i' => 'textit', + 'u' => 'underline'); + + foreach my $key (keys(%markup_replace)) { + my $new = $markup_replace{$key}; + $variable =~ s/\$\<\$${key}\$\>\$(.*?)\$<\$\/${key}\$>\$/\\${new}\{$1\}/gi; + } + + return $variable; +} + +sub parse { + my $self = $_[0]; + local *OUT = $_[1]; + my ($form, $myconfig) = ($self->{"form"}, $self->{"myconfig"}); + + # Some variables used for page breaks + my ($chars_per_line, $lines_on_first_page, $lines_on_second_page) = + (0, 0, 0); + my ($current_page, $current_line, $current_row) = (1, 1, 0); + my ($pagebreak, $sum, $two_passes, $nodiscount_sum) = ("", 0, 0, 0); + my ($par, $var); + + # Do we have to run LaTeX two times? This is needed if + # the template contains page references. + $two_passes = 0; + + if (!open(IN, "$form->{templates}/$form->{IN}")) { + $self->{"error"} = "$!"; + return 0; + } + @_ = ; + close(IN); + + # first we generate a tmpfile + # read file and replace <%variable%> + while ($_ = shift) { + $par = ""; + $var = $_; + + $two_passes = 1 if (/\\pageref/); + + # detect pagebreak block and its parameters + if (/\s*<%pagebreak ([0-9]+) ([0-9]+) ([0-9]+)%>/) { + $chars_per_line = $1; + $lines_on_first_page = $2; + $lines_on_second_page = $3; + + while ($_ = shift) { + last if (/\s*<%end pagebreak%>/); + $pagebreak .= $_; + } + } + + if (/\s*<%foreach /) { + + # this one we need for the count + chomp $var; + $var =~ s/\s*<%foreach (.+?)%>/$1/; + while ($_ = shift) { + last if (/\s*<%end /); + + # store line in $par + $par .= $_; + } + + # Count the number of "lines" for our variable. Also find the forced pagebreak entries. + my $num_entries = scalar(@{$form->{$var}}); + my @forced_pagebreaks = (); + for (my $i = 0; $i < scalar(@{$form->{$var}}); $i++) { + if ($form->{$var}->[$i] =~ //) { + push(@forced_pagebreaks, $i); + } + } + + $current_line = 1; + # display contents of $form->{number}[] array + for ($i = 0; $i < $num_entries; $i++) { + # Try to detect whether a manual page break is necessary + # but only if there was a <%pagebreak ...%> block before + + if ($chars_per_line) { + my $lines = + int(length($form->{"description"}->[$i]) / $chars_per_line + 0.95); + my $lpp; + + $form->{"description"}->[$i] =~ s/(\\newline\s?)*$//; + my $_description = $form->{"description"}->[$i]; + while ($_description =~ /\\newline/) { + $lines++; + $_description =~ s/\\newline//; + } + $lines++; + + if ($current_page == 1) { + $lpp = $lines_on_first_page; + } else { + $lpp = $lines_on_second_page; + } + + # Yes we need a manual page break -- or the user has forced one + if ((($current_line + $lines) > $lpp) || + grep(/^${current_row}$/, @forced_pagebreaks)) { + my $pb = $pagebreak; + + # replace the special variables <%sumcarriedforward%> + # and <%lastpage%> + + my $psum = $form->format_amount($myconfig, $sum, 2); + my $nodiscount_psum = $form->format_amount($myconfig, $nodiscount_sum, 2); + $pb =~ s/<%nodiscount_sumcarriedforward%>/$nodiscount_psum/g; + $pb =~ s/<%sumcarriedforward%>/$psum/g; + $pb =~ s/<%lastpage%>/$current_page/g; + + # only "normal" variables are supported here + # (no <%if, no <%foreach, no <%include) + + while ($pb =~ /<%(.*?)%>/) { + substr($pb, $-[0], $+[0] - $-[0]) = + $self->format_string($form->{"$1"}->[$i]); + } + + # page break block is ready to rock + print(OUT $pb); + $current_page++; + $current_line = 1; + } + $current_line += $lines; + $current_row++; + } + $sum += $form->parse_amount($myconfig, $form->{"linetotal"}->[$i]); + $nodiscount_sum += $form->parse_amount($myconfig, $form->{"nodiscount_linetotal"}->[$i]); + + # don't parse par, we need it for each line + $_ = $par; + while (/<%(.*?)%>/) { + substr($_, $-[0], $+[0] - $-[0]) = + $self->format_string($form->{"$1"}->[$i]); + } + print OUT; + } + next; + } + + # if not comes before if! + if (/\s*<%if not /) { + + # check if it is not set and display + chop; + s/\s*<%if not (.+?)%>/$1/; + + unless ($form->{$_}) { + while ($_ = shift) { + last if (/\s*<%end /); + + # store line in $par + $par .= $_; + } + + $_ = $par; + + } else { + while ($_ = shift) { + last if (/\s*<%end /); + } + next; + } + } + + if (/\s*<%if /) { + + # check if it is set and display + chop; + s/\s*<%if (.+?)%>/$1/; + + if ($form->{$_}) { + while ($_ = shift) { + last if (/\s*<%end /); + + # store line in $par + $par .= $_; + } + + $_ = $par; + + } else { + while ($_ = shift) { + last if (/\s*<%end /); + } + next; + } + } + + # check for <%include filename%> + if (/\s*<%include /) { + + # get the filename + chomp $var; + $var =~ s/\s*<%include (.+?)%>/$1/; + + # mangle filename + $var =~ s/(\/|\.\.)//g; + + # prevent the infinite loop! + next if ($form->{"$var"}); + + open(INC, $form->{templates} . "/$var") + or $form->error($self->cleanup . $form->{templates} . "/$var : $!"); + unshift(@_, ); + close(INC); + + $form->{"$var"} = 1; + + next; + } + + while (/<%(.*?)%>/) { + substr($_, $-[0], $+[0] - $-[0]) = $self->format_string($form->{$1}); + } + print OUT; + } + + if ($form->{"format"} =~ /postscript/i) { + return $self->convert_to_postscript($two_passes); + } elsif ($form->{"format"} =~ /pdf/i) { + return $self->convert_to_pdf($two_passes); + } else { + return 1; + } +} + +sub convert_to_postscript { + my ($self, $two_passes) = @_; + my ($form, $userspath) = ($self->{"form"}, $self->{"userspath"}); + + # Convert the tex file to postscript + + if (!chdir("$userspath")) { + $self->{"error"} = "chdir : $!"; + $self->cleanup(); + return 0; + } + + $form->{tmpfile} =~ s/$userspath\///g; + + system("latex --interaction=nonstopmode $form->{tmpfile} " . + "> $form->{tmpfile}.err"); + if ($?) { + $self->{"error"} = $form->cleanup(); + $self->cleanup(); + return 0; + } + if ($two_passes) { + system("latex --interaction=nonstopmode $form->{tmpfile} " . + "> $form->{tmpfile}.err"); + if ($?) { + $self->{"error"} = $form->cleanup(); + $self->cleanup(); + return 0; + } + } + + $form->{tmpfile} =~ s/tex$/dvi/; + + system("dvips $form->{tmpfile} -o -q > /dev/null"); + if ($?) { + $self->{"error"} = "dvips : $!"; + $self->cleanup(); + return 0; + } + $form->{tmpfile} =~ s/dvi$/ps/; + + $self->cleanup(); + + return 1; +} + +sub convert_to_pdf { + my ($self, $two_passes) = @_; + my ($form, $userspath) = ($self->{"form"}, $self->{"userspath"}); + + # Convert the tex file to PDF + + if (!chdir("$userspath")) { + $self->{"error"} = "chdir : $!"; + $self->cleanup(); + return 0; + } + + $form->{tmpfile} =~ s/$userspath\///g; + + system("pdflatex --interaction=nonstopmode $form->{tmpfile} " . + "> $form->{tmpfile}.err"); + if ($?) { + $self->{"error"} = $form->cleanup(); + $self->cleanup(); + return 0; + } + + if ($two_passes) { + system("pdflatex --interaction=nonstopmode $form->{tmpfile} " . + "> $form->{tmpfile}.err"); + if ($?) { + $self->{"error"} = $form->cleanup(); + $self->cleanup(); + return 0; + } + } + + $form->{tmpfile} =~ s/tex$/pdf/; + + $self->cleanup(); +} + +sub get_mime_type() { + my ($self) = @_; + + if ($self->{"form"}->{"format"} =~ /postscript/i) { + return "application/postscript"; + } else { + return "application/pdf"; + } +} + +sub uses_temp_file { + return 1; +} + + +#### +#### HTMLTemplate +#### + +package HTMLTemplate; + +use vars qw(@ISA); + +@ISA = qw(LaTeXTemplate); + +sub new { + my $type = shift; + + return $type->SUPER::new(@_); +} + +sub format_string { + my ($self, $variable) = @_; + my $form = $self->{"form"}; + + my %replace = + ('order' => ['<', '>', quotemeta("\n")], + '<' => '<', + '>' => '>', + quotemeta("\n") => '
', + ); + + map({ $variable =~ s/$_/$replace{$_}/g; } @{ $replace{"order"} }); + + # Allow some HTML markup to be converted into the output format's + # corresponding markup code, e.g. bold or italic. + my @markup_replace = ('b', 'i', 's', 'u'); + + foreach my $key (@markup_replace) { + $variable =~ s/\<(\/?)${key}\>/<$1${key}>/g; + } + + return $variable; +} + +sub get_mime_type() { + return "text/html"; +} + +sub uses_temp_file { + return 0; +} + + + +#### +#### HTMLTemplate +#### + +package OpenDocumentTemplate; + +use vars qw(@ISA); + +use Cwd; +# use File::Copy; +# use File::Spec; +# use File::Temp qw(:mktemp); +use IO::File; + +@ISA = qw(SimpleTemplate); + +sub new { + my $type = shift; + + $self = $type->SUPER::new(@_); + + foreach my $module (qw(Archive::Zip Text::Iconv)) { + eval("use ${module};"); + if ($@) { + $self->{"form"}->error("The Perl module '${module}' could not be " . + "loaded. Support for OpenDocument templates " . + "does not work without it. Please install your " . + "distribution's package or get the module from " . + "CPAN ( http://www.cpan.org )."); + } + } + + $self->{"rnd"} = int(rand(1000000)); + $self->{"iconv"} = Text::Iconv->new($main::dbcharset, "UTF-8"); + + return $self; +} + +sub substitute_vars { + my ($self, $text, @indices) = @_; + + my $form = $self->{"form"}; + + while ($text =~ /\<\%(.*?)\%\>/) { + my $value = $form->{$1}; + + for (my $i = 0; $i < scalar(@indices); $i++) { + last unless (ref($value) eq "ARRAY"); + $value = $value->[$indices[$i]]; + } + substr($text, $-[0], $+[0] - $-[0]) = $self->format_string($value); + } + + return $text; +} + +sub parse_foreach { + my ($self, $var, $text, $start_tag, $end_tag, @indices) = @_; + + my ($form, $new_contents) = ($self->{"form"}, ""); + + my $ary = $form->{$var}; + for (my $i = 0; $i < scalar(@indices); $i++) { + last unless (ref($ary) eq "ARRAY"); + $ary = $ary->[$indices[$i]]; + } + + for (my $i = 0; $i < scalar(@{$ary}); $i++) { + my $new_text = $self->parse_block($text, (@indices, $i)); + return undef unless (defined($new_text)); + $new_contents .= $start_tag . $new_text . $end_tag; + } + + return $new_contents; +} + +sub parse_block { + $main::lxdebug->enter_sub(); + + my ($self, $contents, @indices) = @_; + + my $new_contents = ""; + + while ($contents ne "") { + if (substr($contents, 0, 1) eq "<") { + $contents =~ m|^<[^>]+>|; + my $tag = $&; + substr($contents, 0, length($&)) = ""; + + if ($tag =~ m|]*>)|; + my $table_row = $1; + my $end_tag = $2; + substr($contents, 0, length($1) + length($end_tag)) = ""; + + if ($table_row =~ m|\<\%foreachrow\s+(.*?)\%\>|) { + my $var = $1; + + $table_row =~ s|\<\%foreachrow .*?\%\>||g; + $table_row =~ s!\<\%end(for|foreach)?row\s+${var}\%\>!!g; + + my $new_text = $self->parse_foreach($var, $table_row, $tag, $end_tag, @indices); + return undef unless (defined($new_text)); + $new_contents .= $new_text; + + } else { + my $new_text = $self->parse_block($table_row, @indices); + return undef unless (defined($new_text)); + $new_contents .= $tag . $new_text . $end_tag; + } + + } else { + $new_contents .= $tag; + } + + } else { + $contents =~ /^[^<]+/; + my $text = $&; + + my $pos_if = index($text, '<%if'); + my $pos_foreach = index($text, '<%foreach'); + + if ((-1 == $pos_if) && (-1 == $pos_foreach)) { + substr($contents, 0, length($text)) = ""; + $new_contents .= $self->substitute_vars($text, @indices); + next; + } + + if ((-1 == $pos_if) || ((-1 != $pos_foreach) && ($pos_if > $pos_foreach))) { + $new_contents .= $self->substitute_vars(substr($contents, 0, $pos_foreach), @indices); + substr($contents, 0, $pos_foreach) = ""; + + if ($contents !~ m|^\<\%foreach (.*?)\%\>|) { + $self->{"error"} = "Malformed <\%foreach\%>."; + $main::lxdebug->leave_sub(); + return undef; + } + + my $var = $1; + + substr($contents, 0, length($&)) = ""; + + if ($contents !~ m!\<\%end\s*?(for)?\s+${var}\%\>!) { + $self->{"error"} = "Unclosed <\%foreach\%>."; + $main::lxdebug->leave_sub(); + return undef; + } + + substr($contents, 0, length($`) + length($&)) = ""; + my $new_text = $self->parse_foreach($var, $`, "", "", @indices); + return undef unless (defined($new_text)); + $new_contents .= $new_text; + + } else { + $new_contents .= $self->substitute_vars(substr($contents, 0, $pos_if), @indices); + substr($contents, 0, $pos_if) = ""; + + if ($contents !~ m|^\<\%if(not)?\s+(.*?)\%\>|) { + $self->{"error"} = "Malformed <\%if\%>."; + $main::lxdebug->leave_sub(); + return undef; + } + + my ($not, $var) = ($1, $2); + + substr($contents, 0, length($&)) = ""; + + if ($contents !~ m!\<\%endif${not}\s+${var}\%\>!) { + $self->{"error"} = "Unclosed <\%if${not}\%>."; + $main::lxdebug->leave_sub(); + return undef; + } + + substr($contents, 0, length($`) + length($&)) = ""; + + my $value = $self->{"form"}->{$var}; + for (my $i = 0; $i < scalar(@indices); $i++) { + last unless (ref($value) eq "ARRAY"); + $value = $value->[$indices[$i]]; + } + + if (($not && !$value) || (!$not && $value)) { + my $new_text = $self->parse_block($`, @indices); + return undef unless (defined($new_text)); + $new_contents .= $new_text; + } + } + } + } + + return $new_contents; +} + +sub parse { + $main::lxdebug->enter_sub(); + + my $self = $_[0]; + local *OUT = $_[1]; + my $form = $self->{"form"}; + + close(OUT); + + my $zip = Archive::Zip->new(); + if (Archive::Zip::AZ_OK != $zip->read("$form->{templates}/$form->{IN}")) { + $self->{"error"} = "File not found/is not a OpenDocument file."; + $main::lxdebug->leave_sub(); + return 0; + } + + my $contents = $zip->contents("content.xml"); + if (!$contents) { + $self->{"error"} = "File is not a OpenDocument file."; + $main::lxdebug->leave_sub(); + return 0; + } + + my $rnd = $self->{"rnd"}; + my $new_styles = qq| + + + + + + + + + + +|; + + $contents =~ s||${new_styles}|; + $contents =~ s|[\n\r]||gm; + + my $new_contents = $self->parse_block($contents); + return 0 unless (defined($new_contents)); + +# $new_contents =~ s|>|>\n|g; + + $zip->contents("content.xml", $new_contents); + $zip->writeToFileNamed($form->{"tmpfile"}, 1); + + my $res = 1; + if ($form->{"format"} =~ /pdf/) { + $res = $self->convert_to_pdf(); + } + + $main::lxdebug->leave_sub(); + return $res; +} + +sub convert_to_pdf { + my ($self) = @_; + + my $form = $self->{"form"}; + + my $filename = $form->{"tmpfile"}; + $filename =~ s/.odt$//; + if (substr($filename, 0, 1) ne "/") { + $filename = getcwd() . "/${filename}"; + } + + if (substr($self->{"userspath"}, 0, 1) eq "/") { + $ENV{'HOME'} = $self->{"userspath"}; + } else { + $ENV{'HOME'} = getcwd() . "/" . $self->{"userspath"}; + } + + my @cmdline = ($main::xvfb_run_bin, $main::openofficeorg_writer_bin, + "-minimized", "-norestore", "-nologo", "-nolockcheck", + "-headless", + "file:${filename}.odt", + "macro://" . (split('/', $filename))[-1] . + "/Standard.Conversion.ConvertSelfToPDF()"); + + system(@cmdline); + + my $res = $?; + if (0 == $?) { + $form->{"tmpfile"} =~ s/odt$/pdf/; + + unlink($filename . ".odt"); + + $main::lxdebug->leave_sub(); + return 1; + + } + + unlink($filename . ".odt", $filename . ".pdf"); + $self->{"error"} = "Conversion from OpenDocument to PDF failed. " . + "Exit code: $res"; + + $main::lxdebug->leave_sub(); + return 0; +} + +sub format_string { + my ($self, $variable) = @_; + my $form = $self->{"form"}; + my $iconv = $self->{"iconv"}; + + my %replace = + ('order' => ['<', '>', '"', "'", + '\x80', # Euro + quotemeta("\n"), quotemeta("\r"), '&'], + '<' => '<', + '>' => '>', + '"' => '"', + "'" => ''', + '&' => '"', + '\x80' => chr(0xa4), # Euro + quotemeta("\n") => '', + quotemeta("\r") => '', + ); + + map({ $variable =~ s/$_/$replace{$_}/g; } @{ $replace{"order"} }); + + # Allow some HTML markup to be converted into the output format's + # corresponding markup code, e.g. bold or italic. + my $rnd = $self->{"rnd"}; + my %markup_replace = ("b" => "BOLD", "i" => "ITALIC", "s" => "STRIKETHROUGH", + "u" => "UNDERLINE"); + + foreach my $key (keys(%markup_replace)) { + my $value = $markup_replace{$key}; + $variable =~ s|\<${key}\>||g; + $variable =~ s|\</${key}\>||g; + } + + return $iconv->convert($variable); +} + +sub get_mime_type() { + if ($self->{"form"}->{"format"} =~ /pdf/) { + return "application/pdf"; + } else { + return "application/vnd.oasis.opendocument.text"; + } +} + +sub uses_temp_file { + return 1; +} + +1; diff --git a/SL/USTVA.pm b/SL/USTVA.pm index 3551efab4..84dc4f312 100644 --- a/SL/USTVA.pm +++ b/SL/USTVA.pm @@ -669,18 +669,13 @@ sub get_accounts_ustva { AND ac.project_id = $form->{project_id} |; } -######################################### -# Method eq 'cash' = IST Versteuerung -######################################### - if ($form->{method} eq 'cash') { + if ($form->{method} eq 'cash') { $query = qq| + SELECT - -- Alle tatsaechlichen Zahlungseingaenge - -- im Voranmeldezeitraum erfassen - -- (Teilzahlungen werden prozentual auf verschiedene Steuern aufgeteilt) - SUM( ac.amount * + SUM( ac.amount * -- Bezahlt / Rechnungssumme ( SELECT SUM(acc.amount) @@ -705,43 +700,101 @@ sub get_accounts_ustva { -- Here no where, please. All Transactions ever should be -- testet if they are paied in the USTVA report period. GROUP BY c.pos_ustva + UNION + + SELECT sum(ac.amount) AS amount, + c.$category + FROM acc_trans ac + JOIN chart c ON (c.id = ac.chart_id) + JOIN ap a ON (a.id = ac.trans_id) + $dpt_join + WHERE $where + $dpt_where + AND ac.trans_id IN + ( + SELECT trans_id + FROM acc_trans + JOIN chart ON (chart_id = id) + WHERE link LIKE '%AP_amount%' + $subwhere + ) + + $project + GROUP BY c.$category + + UNION + + SELECT sum(ac.amount) AS amount, + c.$category + FROM acc_trans ac + JOIN chart c ON (c.id = ac.chart_id) + JOIN gl a ON (a.id = ac.trans_id) + $dpt_join + WHERE $where + $glwhere + $dpt_from + AND NOT (c.link = 'AR' OR c.link = 'AP') + $project + GROUP BY c.$category - UNION -- alle Ausgaben AP erfassen + |; - SELECT sum(ac.amount) AS amount, c.$category - FROM acc_trans ac - JOIN chart c ON (c.id = ac.chart_id) - $dpt_join - WHERE - $where - AND c.link LIKE '%AP_amount%' - $dpt_where - $project - GROUP BY c.$category - - UNION -- alle Ausgaben und Einnahmen direkter gl Buchungen erfassen - - SELECT sum - ( - CASE WHEN c.link LIKE '%AR%' THEN ac.amount * -1 - WHEN c.link LIKE '%AP%' THEN ac.amount * 1 - END - ) AS amount, c.$category - FROM acc_trans ac - JOIN chart c ON (c.id = ac.chart_id) - JOIN gl a ON (a.id = ac.trans_id) - $dpt_join - WHERE $where - $dpt_from - AND NOT (c.link = 'AR' OR c.link = 'AP') - $project - GROUP BY c.$category - |; - - } else { -######################################### -# Method eq 'accrual' = Soll Versteuerung -######################################### + if ($form->{project_id}) { + + $query .= qq| + + UNION + + SELECT SUM(ac.sellprice * ac.qty) AS amount, + c.$category + FROM invoice ac + JOIN ar a ON (a.id = ac.trans_id) + JOIN parts p ON (ac.parts_id = p.id) + JOIN chart c on (p.income_accno_id = c.id) + $dpt_join + -- use transdate from subwhere + WHERE 1 = 1 $subwhere + AND c.category = 'I' + $dpt_where + AND ac.trans_id IN + ( + SELECT trans_id + FROM acc_trans + JOIN chart ON (chart_id = id) + WHERE link LIKE '%AR_paid%' + $subwhere + ) + + $project + GROUP BY c.$category + + UNION + + SELECT SUM(ac.sellprice) AS amount, + c.$category + FROM invoice ac + JOIN ap a ON (a.id = ac.trans_id) + JOIN parts p ON (ac.parts_id = p.id) + JOIN chart c on (p.expense_accno_id = c.id) + $dpt_join + WHERE 1 = 1 $subwhere + AND c.category = 'E' + $dpt_where + AND ac.trans_id IN + ( + SELECT trans_id + FROM acc_trans + JOIN chart ON (chart_id = id) + WHERE link LIKE '%AP_paid%' + $subwhere + ) + + $project + GROUP BY c.$category + |; + } + + } else { if ($department_id) { $dpt_join = qq| @@ -753,38 +806,69 @@ sub get_accounts_ustva { } $query = qq| - SELECT sum - ( - CASE WHEN c.link LIKE '%AR%' THEN ac.amount * -1 - WHEN c.link LIKE '%AP%' THEN ac.amount * 1 - END - ) AS amount, c.$category - FROM acc_trans ac - JOIN chart c ON (c.id = ac.chart_id) - $dpt_join - WHERE $where - $dpt_where - $project - GROUP BY c.$category - |; + + SELECT sum(ac.amount) AS amount, + c.$category + FROM acc_trans ac + JOIN chart c ON (c.id = ac.chart_id) + $dpt_join + WHERE $where + $dpt_where + $project + GROUP BY c.$category + |; + + if ($form->{project_id}) { + + $query .= qq| + + UNION + + SELECT SUM(ac.sellprice * ac.qty) AS amount, + c.$category + FROM invoice ac + JOIN ar a ON (a.id = ac.trans_id) + JOIN parts p ON (ac.parts_id = p.id) + JOIN chart c on (p.income_accno_id = c.id) + $dpt_join + -- use transdate from subwhere + WHERE 1 = 1 $subwhere + AND c.category = 'I' + $dpt_where + $project + GROUP BY c.$category + + UNION + + SELECT SUM(ac.sellprice * ac.qty) * -1 AS amount, + c.$category + FROM invoice ac + JOIN ap a ON (a.id = ac.trans_id) + JOIN parts p ON (ac.parts_id = p.id) + JOIN chart c on (p.expense_accno_id = c.id) + $dpt_join + WHERE 1 = 1 $subwhere + AND c.category = 'E' + $dpt_where + $project + GROUP BY c.$category + |; + + } } my @accno; my $accno; my $ref; - # Show all $query in Debuglevel LXDebug::QUERY - $callingdetails = (caller (0))[3]; - $main::lxdebug->message(LXDebug::QUERY, "$callingdetails \$query=\n $query"); - + #print $query; my $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); while ($ref = $sth->fetchrow_hashref(NAME_lc)) { -# Bug 365 solved?! -# if ($ref->{amount} < 0) { + if ($ref->{amount} < 0) { $ref->{amount} *= -1; -# } + } if ($category eq "pos_bwa") { if ($last_period) { $form->{ $ref->{$category} }{kumm} += $ref->{amount}; diff --git a/VERSION b/VERSION index 276cbf9e2..197c4d5c2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.3.0 +2.4.0 diff --git a/bin/mozilla/admin.pl b/bin/mozilla/admin.pl index f10026729..118712531 100644 --- a/bin/mozilla/admin.pl +++ b/bin/mozilla/admin.pl @@ -164,6 +164,10 @@ sub add_user { } $myconfig->{vclimit} = 200; + $myconfig->{"countrycode"} = "de"; + $myconfig->{"numberformat"} = "1000,00"; + $myconfig->{"dateformat"} = "dd.mm.yy"; + &form_header; &form_footer; @@ -440,7 +444,7 @@ sub form_header { closedir TEMPLATEDIR; @allhtml = sort grep /\.html/, @all; - @alldir = grep !/\.(html|tex)$/, @all; + @alldir = grep !/\.(html|tex|sty|odt)$/, @all; @alldir = grep !/^(webpages|\.svn)$/, @alldir; @allhtml = reverse grep !/Default/, @allhtml; @@ -462,7 +466,8 @@ sub form_header { $item =~ s/-.*//g; if ($item ne $lastitem) { - $mastertemplates .= qq|
{script}?action=edit_sic&code=$ref->{code}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{code}|; - $column_data{description} = qq|$ref->{description}|; - - } else { - print qq| + print qq| |; - $column_data{code} = - qq|{script}?action=edit_sic&code=$ref->{code}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{code}|; - $column_data{description} = qq|$ref->{description}|; - } + $column_data{description} = + qq|{script}?action=edit_language&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{description}|; + $column_data{template_code} = qq|$ref->{template_code}|; + $column_data{article_code} = + qq|$ref->{article_code}|; map { print "$column_data{$_}\n" } @column_index; @@ -1382,7 +1420,7 @@ sub list_sic { - + {path}> {login}> @@ -1397,6 +1435,7 @@ sub list_sic { } print qq| + @@ -1406,18 +1445,18 @@ sub list_sic { $lxdebug->leave_sub(); } -sub sic_header { +sub language_header { $lxdebug->enter_sub(); - $form->{title} = $locale->text("$form->{title} SIC"); + $form->{title} = $locale->text("$form->{title} Language"); - # $locale->text('Add SIC') - # $locale->text('Edit SIC') + # $locale->text('Add Language') + # $locale->text('Edit Language') - $form->{code} =~ s/\"/"/g; $form->{description} =~ s/\"/"/g; + $form->{template_code} =~ s/\"/"/g; + $form->{article_code} =~ s/\"/"/g; - $checked = ($form->{sictype} eq 'H') ? "checked" : ""; $form->header; @@ -1426,8 +1465,8 @@ sub sic_header {
{script}> - -{code}> +{id}> + @@ -1435,19 +1474,18 @@ sub sic_header { - - - + + - - + + + - - + + - +
| . $locale->text('Code') . qq|{code}>
| . $locale->text('Language') . qq|
| - . $locale->text('Heading') . qq|
| . $locale->text('Template Code') . qq|{template_code}>
| . $locale->text('Description') . qq|| . $locale->text('Article Code') . qq|{article_code}>


|; @@ -1455,164 +1493,1374 @@ sub sic_header { $lxdebug->leave_sub(); } -sub save_sic { +sub save_language { $lxdebug->enter_sub(); - $form->isblank("code", $locale->text('Code missing!')); - $form->isblank("description", $locale->text('Description missing!')); - AM->save_sic(\%myconfig, \%$form); - $form->redirect($locale->text('SIC saved!')); + $form->isblank("description", $locale->text('Language missing!')); + $form->isblank("template_code", $locale->text('Template Code missing!')); + $form->isblank("article_code", $locale->text('Article Code missing!')); + AM->save_language(\%myconfig, \%$form); + $form->redirect($locale->text('Language saved!')); $lxdebug->leave_sub(); } -sub delete_sic { +sub delete_language { $lxdebug->enter_sub(); - AM->delete_sic(\%myconfig, \%$form); - $form->redirect($locale->text('SIC deleted!')); + AM->delete_language(\%myconfig, \%$form); + $form->redirect($locale->text('Language deleted!')); $lxdebug->leave_sub(); } -sub display_stylesheet { + +sub add_buchungsgruppe { $lxdebug->enter_sub(); - $form->{file} = "css/$myconfig{stylesheet}"; - &display_form; + # $locale->text("Add Buchungsgruppe") + # $locale->text("Edit Buchungsgruppe") + $form->{title} = "Add"; + + $form->{callback} = + "$form->{script}?action=add_buchungsgruppe&path=$form->{path}&login=$form->{login}&password=$form->{password}" + unless $form->{callback}; + AM->get_buchungsgruppe(\%myconfig, \%$form); + + &buchungsgruppe_header; + &form_footer; $lxdebug->leave_sub(); } -sub display_form { +sub edit_buchungsgruppe { $lxdebug->enter_sub(); - $form->{file} =~ s/^(.:)*?\/|\.\.\///g; - $form->{file} =~ s/^\/*//g; - $form->{file} =~ s/$userspath//; - - $form->error("$!: $form->{file}") unless -f $form->{file}; + $form->{title} = "Edit"; - AM->load_template(\%$form); + AM->get_buchungsgruppe(\%myconfig, \%$form); - $form->{title} = $form->{file}; + &buchungsgruppe_header; - # if it is anything but html - if ($form->{file} !~ /\.html$/) { - $form->{body} = "
\n$form->{body}\n
"; - } + &form_footer; - $form->header; + $lxdebug->leave_sub(); +} - print qq| - +sub list_buchungsgruppe { + $lxdebug->enter_sub(); -$form->{body} + AM->buchungsgruppe(\%myconfig, \%$form); -{script}> + $form->{callback} = + "$form->{script}?action=list_buchungsgruppe&path=$form->{path}&login=$form->{login}&password=$form->{password}"; -{file}> - + $callback = $form->escape($form->{callback}); -{path}> -{login}> -{password}> + $form->{title} = $locale->text('Buchungsgruppen'); -|; + @column_index = qw(description inventory_accno income_accno_0 expense_accno_0 income_accno_1 expense_accno_1 income_accno_2 expense_accno_2 income_accno_3 expense_accno_3 ); - if ($form->{menubar}) { - require "$form->{path}/menu.pl"; - &menubar; - } + $column_header{description} = + qq|| + . $locale->text('Description') + . qq||; + $column_header{inventory_accno} = + qq|| + . $locale->text('Bestandskonto') + . qq||; + $column_header{income_accno_0} = + qq|| + . $locale->text('Erlöse Inland') + . qq||; + $column_header{expense_accno_0} = + qq|| + . $locale->text('Aufwand Inland') + . qq||; + $column_header{income_accno_1} = + qq|| + . $locale->text('Erlöse EU o. UStId') + . qq||; + $column_header{expense_accno_1} = + qq|| + . $locale->text('Aufwand EU o. UStId') + . qq||; + $column_header{income_accno_2} = + qq|| + . $locale->text('Erlöse EU m. UStId') + . qq||; + $column_header{expense_accno_2} = + qq|| + . $locale->text('Aufwand EU m. UStId') + . qq||; + $column_header{income_accno_3} = + qq|| + . $locale->text('Erlöse Ausland') + . qq||; + $column_header{expense_accno_3} = + qq|| + . $locale->text('Aufwand Ausland') + . qq||; + $form->header; print qq| -
+ - - + + + + + + + + + + + +
$form->{title}
+ + |; - $lxdebug->leave_sub(); -} + map { print "$column_header{$_}\n" } @column_index; -sub edit_template { - $lxdebug->enter_sub(); + print qq| + +|; - AM->load_template(\%$form); + foreach $ref (@{ $form->{ALL} }) { - $form->{title} = $locale->text('Edit Template'); + $i++; + $i %= 2; - # convert   to &nbsp; - $form->{body} =~ s/ /&nbsp;/gi; + print qq| + +|; - $form->header; + + $column_data{description} = + qq||; + $column_data{inventory_accno} = qq||; + $column_data{income_accno_0} = + qq||; + $column_data{expense_accno_0} = qq||; + $column_data{income_accno_1} = + qq||; + $column_data{expense_accno_1} = qq||; + $column_data{income_accno_2} = + qq||; + $column_data{expense_accno_2} = qq||; + $column_data{income_accno_3} = + qq||; + $column_data{expense_accno_3} = qq||; + + map { print "$column_data{$_}\n" } @column_index; + + print qq| + +|; + } print qq| - +
{script}?action=edit_buchungsgruppe&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{description}$ref->{inventory_accno}$ref->{income_accno_0}$ref->{expense_accno_0}$ref->{income_accno_1}$ref->{expense_accno_1}$ref->{income_accno_2}$ref->{expense_accno_2}$ref->{income_accno_3}$ref->{expense_accno_3}
+

+
{script}> -{file}> - + + + {path}> {login}> {password}> - - - - -
-|; +|; if ($form->{menubar}) { require "$form->{path}/menu.pl"; &menubar; } - print q| -
+ print qq| + - - + + |; $lxdebug->leave_sub(); } -sub save_template { +sub buchungsgruppe_header { $lxdebug->enter_sub(); - AM->save_template(\%$form); - $form->redirect($locale->text('Template saved!')); + $form->{title} = $locale->text("$form->{title} Buchungsgruppe"); - $lxdebug->leave_sub(); -} + # $locale->text('Buchungsgruppe hinzufügen') + # $locale->text('Buchungsgruppe bearbeiten') -sub config { - $lxdebug->enter_sub(); + $form->{description} =~ s/\"/"/g; - # get defaults for account numbers and last numbers - AM->defaultaccounts(\%myconfig, \%$form); + # build the popup menus + $form->{taxaccounts} = ""; + foreach $key (keys %{ $form->{IC_links} }) { + foreach $ref (@{ $form->{IC_links}{$key} }) { + + # if this is a tax field + if ($key =~ /IC_tax/) { + if ($key =~ /$item/) { + $form->{taxaccounts} .= "$ref->{accno} "; + $form->{"IC_tax_$ref->{accno}_description"} = + "$ref->{accno}--$ref->{description}"; + + if ($form->{id}) { + if ($form->{amount}{ $ref->{accno} }) { + $form->{"IC_tax_$ref->{accno}"} = "checked"; + } + } else { + $form->{"IC_tax_$ref->{accno}"} = "checked"; + } + } + } else { - foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd)) { - $dateformat .= - ($item eq $myconfig{dateformat}) - ? "|; + foreach $item (@{ $form->{payment_terms} }) { + if ($form->{payment_id} eq $item->{id}) { + $payment .= qq||; + } else { + $payment .= qq||; + } + } + + # set option selected + foreach $item (qw(AR customer currency department employee contact)) { + $form->{"select$item"} =~ s/ selected//; + $form->{"select$item"} =~ + s/option>\Q$form->{$item}\E/option selected>$form->{$item}/; + } + + #build contacts + if ($form->{all_contacts}) { + + $form->{selectcontact} = ""; + foreach $item (@{ $form->{all_contacts} }) { + if ($form->{cp_id} == $item->{cp_id}) { + $form->{selectcontact} .= + "|; + foreach $item (@{ $form->{LIZENZEN}{ $form->{"id_$i"} } }) { + $form->{"lizenzen_$i"} .= + qq||; + } + $form->{"lizenzen_$i"} .= + qq||; + } + } + + # get pricegroups for parts + IS->get_pricegroups_for_parts(\%myconfig, \%$form); + + # build up html code for prices_$i + &set_pricegroup($i); + } + + &display_form; + + } else { + + # ok, so this is a new part + # ask if it is a part or service item + + if ( $form->{"partsgroup_$i"} + && ($form->{"partsnumber_$i"} eq "") + && ($form->{"description_$i"} eq "")) { + $form->{rowcount}--; + $form->{"discount_$i"} = ""; + &display_form; + } else { + + $form->{"id_$i"} = 0; + $form->{"unit_$i"} = $locale->text('ea'); + + &new_item; + + } + } + } + $lxdebug->leave_sub(); +} + +sub post { + $lxdebug->enter_sub(); + $form->isblank("invdate", $locale->text('Invoice Date missing!')); + $form->isblank("customer", $locale->text('Customer missing!')); + + # if oldcustomer ne customer redo form + if (&check_name(customer)) { + &update; + exit; + } + if ($form->{second_run}) { + $form->{print_and_post} = 0; + } + + &validate_items; + + $closedto = $form->datetonum($form->{closedto}, \%myconfig); + $invdate = $form->datetonum($form->{invdate}, \%myconfig); + + $form->error($locale->text('Cannot post invoice for a closed period!')) + if ($invdate <= $closedto); + + $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) + if ($form->{currency} ne $form->{defaultcurrency}); + + for $i (1 .. $form->{paidaccounts}) { + if ($form->{"paid_$i"}) { + $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig); + + $form->isblank("datepaid_$i", $locale->text('Payment date missing!')); + + $form->error($locale->text('Cannot post payment for a closed period!')) + if ($datepaid <= $closedto); + + if ($form->{currency} ne $form->{defaultcurrency}) { + $form->{"exchangerate_$i"} = $form->{exchangerate} + if ($invdate == $datepaid); + $form->isblank("exchangerate_$i", + $locale->text('Exchangerate for payment missing!')); + } + } + } + + ($form->{AR}) = split /--/, $form->{AR}; + ($form->{AR_paid}) = split /--/, $form->{AR_paid}; + + $form->{label} = $locale->text('Invoice'); + + $form->{id} = 0 if $form->{postasnew}; + + # get new invnumber in sequence if no invnumber is given or if posasnew was requested + if (!$form->{invnumber} || $form->{postasnew}) { + $form->{invnumber} = $form->update_defaults(\%myconfig, "invnumber"); + } + if ($print_post) { + if (!(IS->post_invoice(\%myconfig, \%$form))) { + $form->error($locale->text('Cannot post invoice!')); + } + } else { + $form->redirect( + $form->{label} . " $form->{invnumber} " . $locale->text('posted!')) + if (IS->post_invoice(\%myconfig, \%$form)); + $form->error($locale->text('Cannot post invoice!')); + } + + $lxdebug->leave_sub(); +} + +sub print_and_post { + $lxdebug->enter_sub(); + + $old_form = new Form; + $print_post = 1; + $form->{print_and_post} = 1; + &post(); + + &edit(); + $lxdebug->leave_sub(); + +} + +sub preview { + $lxdebug->enter_sub(); + + $form->{preview} = 1; + $old_form = new Form; + for (keys %$form) { $old_form->{$_} = $form->{$_} } + $old_form->{rowcount}++; + + &print_form($old_form); + $lxdebug->leave_sub(); + +} + +sub delete { + $lxdebug->enter_sub(); + if ($form->{second_run}) { + $form->{print_and_post} = 0; + } + $form->header; + + print qq| + + +
{script}> +|; + + # delete action variable + map { delete $form->{$_} } qw(action header); + + foreach $key (keys %$form) { + $form->{$key} =~ s/\"/"/g; + print qq|\n|; + } + + print qq| +

| . $locale->text('Confirm!') . qq|

+ +

| + . $locale->text('Are you sure you want to delete Invoice Number') + . qq| $form->{invnumber} +

+ +

+ +

+|; + + $lxdebug->leave_sub(); +} + +sub yes { + $lxdebug->enter_sub(); + + $form->redirect($locale->text('Invoice deleted!')) + if (IS->delete_invoice(\%myconfig, \%$form, $spool)); + $form->error($locale->text('Cannot delete invoice!')); + + $lxdebug->leave_sub(); +} diff --git a/bin/mozilla/common.pl b/bin/mozilla/common.pl index 429a1ec6b..ed2612911 100644 --- a/bin/mozilla/common.pl +++ b/bin/mozilla/common.pl @@ -11,17 +11,14 @@ use Data::Dumper; +use SL::Common; + sub save_form { $lxdebug->enter_sub(); - my (@names, @values); - foreach my $key (keys(%{$form})) { - push(@names, "\$form->{\"$key\"}"); - push(@values, $form->{$key}); - } - my $dumper = Data::Dumper->new(\@values, \@names); - $dumper->Indent(0); - my $old_form = $dumper->Dump(); + my $old_form = ""; + map({ $old_form .= "$_=" . $form->escape($form->{$_}) . '&'; } keys(%{$form})); + chop($old_form); $lxdebug->leave_sub(); @@ -31,16 +28,446 @@ sub save_form { sub restore_form { $lxdebug->enter_sub(); - my ($old_form, $no_delete) = @_; + my ($old_form) = @_; + + map({ delete($form->{$_}); } keys(%{$form})); + + foreach my $pair (split('&', $old_form)) { + my ($key, $value) = split('=', $form->unescape($pair), 2); + $form->{$key} = $value; + } + + $lxdebug->leave_sub(); +} + +sub select_employee { + $lxdebug->enter_sub(); + + my ($callback_sub, @employees) = @_; + + if (0 == scalar(@employees)) { + @employees = SystemBrace->get_all_employees(\%myconfig, $form); + } + + my $old_form = save_form(); + + $form->header(); + print($form->parse_html_template("generic/select_employee", + { "EMPLOYEES" => \@employees, + "old_form" => $old_form, + "title" => $locale->text("Select an employee"), + "nextsub" => "select_employee_internal", + "callback_sub" => $callback_sub })); + + $lxdebug->leave_sub(); +} + +sub select_employee_internal { + $lxdebug->enter_sub(); + + my ($new_id, $new_name, $callback_sub); + + my $new_id = $form->{"new_id_" . $form->{"selection"}}; + my $new_name = $form->{"new_name_" . $form->{"selection"}}; + my $callback_sub = $form->{"callback_sub"}; - map({ delete($form->{$_}); } keys(%{$form})) unless ($no_delete); - eval($old_form); + restore_form($form->{"old_form"}); + + &{ $callback_sub }($new_id, $new_name); $lxdebug->leave_sub(); } -sub H { - return $form->quote_html($_[0]); +sub select_part { + $lxdebug->enter_sub(); + + my ($callback_sub, @parts) = @_; + + my $remap_parts_id = 0; + if (defined($parts[0]->{"parts_id"}) && !defined($parts[0]->{"id"})) { + $remap_parts_id = 1; + map({ $_->{"id"} = $_->{"parts_id"}; } @parts); + } + + my $remap_partnumber = 0; + if (defined($parts[0]->{"partnumber"}) && !defined($parts[0]->{"number"})) { + $remap_partnumber = 1; + map({ $_->{"number"} = $_->{"partnumber"}; } @parts); + } + + my $has_charge = 0; + if (defined($parts[0]->{"chargenumber"})) { + $has_charge = 1; + map({ $_->{"has_charge"} = 1; } @parts); + } + + my $old_form = save_form(); + + $form->header(); + print($form->parse_html_template("generic/select_part", + { "PARTS" => \@parts, + "old_form" => $old_form, + "title" => $locale->text("Select a part"), + "nextsub" => "select_part_internal", + "callback_sub" => $callback_sub, + "has_charge" => $has_charge, + "remap_parts_id" => $remap_parts_id, + "remap_partnumber" => $remap_partnumber })); + + $lxdebug->leave_sub(); +} + +sub select_part_internal { + $lxdebug->enter_sub(); + + my ($new_item, $callback_sub); + + my $re = "^new_.*_" . $form->{"selection"}; + map({ + my $key = $_; + $key =~ s/^new_//; + $key =~ s/_\d+$//; + $new_item->{$key} = $form->{$_}; + } grep(/$re/, keys(%{$form}))); + + if ($form->{"remap_parts_id"}) { + $new_item->{"parts_id"} = $new_item->{"id"}; + delete($new_item->{"id"}); + } + if ($form->{"remap_partnumber"}) { + $new_item->{"partnumber"} = $new_item->{"number"}; + delete($new_item->{"number"}); + } + + my $callback_sub = $form->{"callback_sub"}; + + restore_form($form->{"old_form"}); + + &{ $callback_sub }($new_item); + + $lxdebug->leave_sub(); +} + +sub part_selection_internal { + $lxdebug->enter_sub(); + + $order_by = "description"; + $order_by = $form->{"order_by"} if (defined($form->{"order_by"})); + $order_dir = 1; + $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"})); + + $parts = Common->retrieve_parts(\%myconfig, $form, $order_by, $order_dir); + map({ $parts->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$parts})); + if (0 == scalar(@{$parts})) { + $form->show_generic_information($locale->text("No part was found matching the search parameters.")); + } elsif (1 == scalar(@{$parts})) { + $onload = "part_selected('1')"; + } + + my $callback = "$form->{script}?action=part_selection_internal&"; + map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } + (qw(login path password partnumber description input_partnumber input_description input_partsid), grep({ /^[fl]_/ } keys %$form))); + + my @header_sort = qw(partnumber description); + my %header_title = ( "partnumber" => $locale->text("Part Number"), + "description" => $locale->text("Part description"), + ); + + my @header = + map(+{ "column_title" => $header_title{$_}, + "column" => $_, + "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir), + }, + @header_sort); + + $form->{"title"} = $locale->text("Select a part"); + $form->header(); + print($form->parse_html_template("generic/part_selection", { "HEADER" => \@header, + "PARTS" => $parts, + "onload" => $onload })); + + $lxdebug->leave_sub(); +} + +sub project_selection_internal { + $lxdebug->enter_sub(); + + $order_by = "description"; + $order_by = $form->{"order_by"} if (defined($form->{"order_by"})); + $order_dir = 1; + $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"})); + + $projects = Common->retrieve_projects(\%myconfig, $form, $order_by, $order_dir); + map({ $projects->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$projects})); + if (0 == scalar(@{$projects})) { + $form->show_generic_information($locale->text("No project was found matching the search parameters.")); + } elsif (1 == scalar(@{$projects})) { + $onload = "project_selected('1')"; + } + + my $callback = "$form->{script}?action=project_selection_internal&"; + map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } + (qw(login path password projectnumber description input_projectnumber input_description input_project_id), grep({ /^[fl]_/ } keys %$form))); + + my @header_sort = qw(projectnumber description); + my %header_title = ( "projectnumber" => $locale->text("Project Number"), + "description" => $locale->text("Project description"), + ); + + my @header = + map(+{ "column_title" => $header_title{$_}, + "column" => $_, + "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir), + }, + @header_sort); + + $form->{"title"} = $locale->text("Select a project"); + $form->header(); + print($form->parse_html_template("generic/project_selection", { "HEADER" => \@header, + "PROJECTS" => $projects, + "onload" => $onload })); + + $lxdebug->leave_sub(); +} + +sub employee_selection_internal { + $lxdebug->enter_sub(); + + $order_by = "name"; + $order_by = $form->{"order_by"} if (defined($form->{"order_by"})); + $order_dir = 1; + $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"})); + + $employees = Common->retrieve_employees(\%myconfig, $form, $order_by, $order_dir); + map({ $employees->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$employees})); + if (0 == scalar(@{$employees})) { + $form->show_generic_information($locale->text("No employee was found matching the search parameters.")); + } elsif (1 == scalar(@{$employees})) { + $onload = "employee_selected('1')"; + } + + my $callback = "$form->{script}?action=employee_selection_internal&"; + map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } + (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form))); + + my @header_sort = qw(name); + my %header_title = ( "name" => $locale->text("Name"), + ); + + my @header = + map(+{ "column_title" => $header_title{$_}, + "column" => $_, + "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir), + }, + @header_sort); + + $form->{"title"} = $locale->text("Select an employee"); + $form->header(); + print($form->parse_html_template("generic/employee_selection", { "HEADER" => \@header, + "EMPLOYEES" => $employees, + "onload" => $onload })); + + $lxdebug->leave_sub(); +} + +sub delivery_customer_selection { + $lxdebug->enter_sub(); + + $order_by = "name"; + $order_by = $form->{"order_by"} if (defined($form->{"order_by"})); + $order_dir = 1; + $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"})); + + $delivery = Common->retrieve_delivery_customer(\%myconfig, $form, $order_by, $order_dir); + map({ $delivery->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$delivery})); + if (0 == scalar(@{$delivery})) { + $form->show_generic_information($locale->text("No Customer was found matching the search parameters.")); + } elsif (1 == scalar(@{$delivery})) { + $onload = "customer_selected('1')"; + } + + my $callback = "$form->{script}?action=delivery_customer_selection&"; + map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } + (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form))); + + my @header_sort = qw(name customernumber address); + my %header_title = ( "name" => $locale->text("Name"), + "customernumber" => $locale->text("Customer Number"), + "address" => $locale->text("Address"), + ); + + my @header = + map(+{ "column_title" => $header_title{$_}, + "column" => $_, + "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir), + }, + @header_sort); + + $form->{"title"} = $locale->text("Select a Customer"); + $form->header(); + print($form->parse_html_template("generic/select_delivery_customer", { "HEADER" => \@header, + "DELIVERY" => $delivery, + "onload" => $onload })); + + $lxdebug->leave_sub(); +} + +sub vendor_selection { + $lxdebug->enter_sub(); + + $order_by = "name"; + $order_by = $form->{"order_by"} if (defined($form->{"order_by"})); + $order_dir = 1; + $order_dir = $form->{"order_dir"} if (defined($form->{"order_dir"})); + + $vendor = Common->retrieve_vendor(\%myconfig, $form, $order_by, $order_dir); + map({ $vendor->[$_]->{"selected"} = $_ ? 0 : 1; } (0..$#{$vendor})); + if (0 == scalar(@{$vendor})) { + $form->show_generic_information($locale->text("No Vendor was found matching the search parameters.")); + } elsif (1 == scalar(@{$vendor})) { + $onload = "vendor_selected('1')"; + } + + my $callback = "$form->{script}?action=vendor_selection&"; + map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } + (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form))); + + my @header_sort = qw(name customernumber address); + my %header_title = ( "name" => $locale->text("Name"), + "customernumber" => $locale->text("Customer Number"), + "address" => $locale->text("Address"), + ); + + my @header = + map(+{ "column_title" => $header_title{$_}, + "column" => $_, + "callback" => $callback . "order_by=${_}&order_dir=" . ($order_by eq $_ ? 1 - $order_dir : $order_dir), + }, + @header_sort); + + $form->{"title"} = $locale->text("Select a Customer"); + $form->header(); + print($form->parse_html_template("generic/select_vendor", { "HEADER" => \@header, + "VENDOR" => $vendor, + "onload" => $onload })); + + $lxdebug->leave_sub(); +} + +sub calculate_qty { + $lxdebug->enter_sub(); + + my @variable_sort = (); + my %variable_list = (); + my $unit_list = (); + $form->{formel} =~ s/\r\n//g; + + my ($variable_string, $formel) = split /###/,$form->{formel}; + + + split /;/, $variable_string; + foreach $item (@_) { + my($name, $valueunit) = split /=/,$item; + my($value, $unit) = split / /, $valueunit; + + push(@variable_sort, $value); + $variable_list{$value} = $name; + $unit_list{$value} = $unit; + } + + my @header_sort = qw(variable value unit); + my %header_title = ( "variable" => $locale->text("Variable"), + "value" => $locale->text("Value"), + "unit" => $locale->text("Unit"), + ); + + my @variable = map(+{ "description" => $variable_list{$_}, + "name" => $_, + "unit" => $unit_list{$_} }, @variable_sort); + + my @header = + map(+{ "column_title" => $header_title{$_}, + "column" => $_, + }, + @header_sort); + $form->{formel} = $formel; + $form->{"title"} = $locale->text("Please enter values"); + $form->header(); + print($form->parse_html_template("generic/calculate_qty", { "HEADER" => \@header, + "VARIABLES" => \@variable, + "onload" => $onload })); + + $lxdebug->leave_sub(); +} + +sub calculate_alu { + $lxdebug->enter_sub(); + + + + my ($length, $weight) = split /\r\n/,$form->{formel}; + + #print(STDERR "$form->{formel} Formel\n"); + #print(STDERR "$form->{description} Description\n"); + + map({ $form->{$_} = "" } (qw(qty_alu price_alu total_alu qty_eloxal price_eloxal total_eloxal total))); + + if ($form->{description} =~ /.*Alupreisberechnung.*/) { + $form->{description} =~ /.*Alupreisberechnung:\n(.*)kg Aluminiumprofil Einzelpreis: (.*) Gesamt: (.*)\n(.*)m Eloxal Einzelpreis: (.*) Gesamt: (.*)/; + $form->{qty_alu} = $1; + $form->{price_alu} = $2; + $form->{total_alu} = $3; + $form->{qty_eloxal} = $4; + $form->{price_eloxal} = $5; + $form->{total_eloxal} = $6; + $form->{total} = $form->format_amount(\%myconfig, ($form->parse_amount(\%myconfig, $form->{total_alu}) + $form->parse_amount(\%myconfig, $form->{total_eloxal}))); + } + ($form->{description}, $null) = split /\nAlupreisberechnung/, $form->{description}; + #map({ print(STDERR "$_ = $form->{$_}\n") } (qw(qty_alu price_alu total_alu qty_eloxal price_eloxal total_eloxal total))); + + my $callback = "$form->{script}?action=vendor_selection&"; + map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } + (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form))); + + my @header_sort = qw(name customernumber address); + my %header_title = ( "name" => $locale->text("Name"), + "customernumber" => $locale->text("Customer Number"), + "address" => $locale->text("Address"), + ); + ($null, $form->{weight}) = split / /, $weight; + ($null, $form->{length}) = split / /, $length; + + $form->{calc_weight} = $form->parse_amount(\%myconfig, $form->{weight}); + $form->{calc_length} = $form->parse_amount(\%myconfig, $form->{length}); + + + my @header = + map(+{ "column_title" => $header_title{$_}, + "column" => $_, + }, + @header_sort); + + $form->{"title"} = $locale->text("Enter values for aluminium calculation"); + $form->header(); + print($form->parse_html_template("generic/calculate_alu")); + + $lxdebug->leave_sub(); +} + + +sub set_longdescription { + $lxdebug->enter_sub(); + + + my $callback = "$form->{script}?action=set_longdescription&"; + map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } + (qw(login path password name input_name input_id), grep({ /^[fl]_/ } keys %$form))); + + $form->{"title"} = $locale->text("Enter longdescription"); + $form->header(); + print($form->parse_html_template("generic/set_longdescription")); + + $lxdebug->leave_sub(); } 1; diff --git a/bin/mozilla/cp.pl b/bin/mozilla/cp.pl index 8d7f65943..a80e8e176 100644 --- a/bin/mozilla/cp.pl +++ b/bin/mozilla/cp.pl @@ -603,10 +603,7 @@ sub update { } # recalculate - - # Modified from $amount = $form->{amount} by J.Zach to update amount to total - # payment amount in Zahlungsausgang - $amount = 0; + $amount = $form->{amount}; for $i (1 .. $form->{rowcount}) { map { @@ -621,9 +618,7 @@ sub update { $form->{"paid_$i"} = $form->{"due_$i"}; } - # Modified by J.Zach, see abovev - $amount += $form->{"paid_$i"}; - + $amount -= $form->{"paid_$i"}; } else { $form->{"paid_$i"} = ""; } @@ -635,9 +630,6 @@ sub update { } - # Line added by J.Zach, see above - $form->{amount}=$amount; - &form_header; &list_invoices; &form_footer; @@ -724,10 +716,6 @@ sub print { $form->{company} = $myconfig{company}; $form->{address} = $myconfig{address}; - @a = - qw(name invnumber company address text_amount street zipcode city country memo); - $form->format_string(@a); - $form->parse_template(\%myconfig, $userspath); if ($form->{media} ne 'screen') { diff --git a/bin/mozilla/ct.pl b/bin/mozilla/ct.pl index c9e991139..beefcc1fb 100644 --- a/bin/mozilla/ct.pl +++ b/bin/mozilla/ct.pl @@ -38,6 +38,9 @@ # $locale->text('Add Vendor') use SL::CT; +use CGI::Ajax; +use CGI; +use Data::Dumper; 1; @@ -182,6 +185,346 @@ sub search { $lxdebug->leave_sub(); } +sub search_delivery { + $lxdebug->enter_sub(); + + $label = ucfirst $form->{db}; + $form->{title} = $locale->text($label . "s"); + + if ($form->{db} eq 'vendor') { + $gifi = qq| + | + . $locale->text('GIFI') . qq| +|; + } + + $form->header; + + print qq| + + +
{script}> + +{db}> + + + + + + + + + + + + +
$form->{title}
+ + + + + + + + + + + + + + + + + + + + + + + + + +
| . $locale->text($label . ' Number') . qq|{db}number size=35>
| . $locale->text('Company Name') . qq|
| . $locale->text('Contact') . qq|
| . $locale->text('E-mail') . qq|
 | + . $locale->text('All') . qq| +  | + . $locale->text('Orphaned') . qq|
| . $locale->text('Include in Report') . qq| + + + + + + + + + + + + + + + + $gifi + + + + + + + + +
| + . $locale->text('ID') . qq| | + . $locale->text($label . ' Number') . qq| | + . $locale->text('Company Name') . qq| | + . $locale->text('Address') . qq|
| + . $locale->text('Contact') . qq| | + . $locale->text('Phone') . qq| | + . $locale->text('Fax') . qq| | + . $locale->text('E-mail') . qq|
| + . $locale->text('Tax Number') . qq| | + . $locale->text('SIC') . qq| | + . $locale->text('Type of Business') . qq|
| + . $locale->text('Invoices') . qq| | + . $locale->text('Orders') . qq| | + . $locale->text('Quotations') . qq|
+
+

+ + + +{path}> +{login}> +{password}> + +
+ +
+ + + +|; + $lxdebug->leave_sub(); +} + +sub search_adr { + $lxdebug->enter_sub(); + + $form->{title} = $locale->text('ADR Report'); + + # use JavaScript Calendar or not + $form->{jsscript} = $jscalendar; + $jsscript = ""; + + if ($form->{jsscript}) { + + # with JavaScript Calendar + $button1 = qq| + {from}> + text('button') . qq|> + |; + $button2 = qq| + {to}> + text('button') . qq|> + |; + + + #write Trigger + $jsscript = + Form->write_trigger(\%myconfig, "2", + "from", "BL", + "trigger1", "to", + "BL", "trigger2"); + } else { + + # without JavaScript Calendar + $button1 = + qq|{from}>|; + $button2 = + qq|{to}>|; + } + + $form->header; + + print qq| + + +
{script}> + + + + + + + + + + + + + +
$form->{title}
+ + + + + + + $button1 + + + + $button2 + + + + + +
| . $locale->text('Year') . qq|{year}>
| . $locale->text('From') . qq|
| . $locale->text('Bis') . qq|
 | + . $locale->text('HTML') . qq| +  | + . $locale->text('CSV') . qq|
+

+$jsscript + + +{path}> +{login}> +{password}> + +
+ +
+ + + +|; + $lxdebug->leave_sub(); +} +sub adr_report { + $lxdebug->enter_sub(); + + CT->adr(\%myconfig, \%$form); + + $form->{title} = $locale->text('ADR Report'); + if ($form->{from} || $form->{to}) { + $option = "Für den Zeitraum $form->{from} bis $form->{to}"; + } elsif ($form->{year}) { + $option = "Für das Jahr $form->{year}"; + } + + if ($form->{format} eq "html") { + $form->header(); + print qq| + + + + + + + + + + +
$form->{title}
$option
|; + + + @column_index = + $form->sort_columns(adr_code, + adr_description, + sum, + unit); + + + + $column_header{adr_code} = + qq|| . $locale->text('ADR Code') . qq||; + $column_header{adr_description} = + qq||. $locale->text('ADR Description'). qq||; + $column_header{sum} = + qq||. $locale->text('Quantity'). qq||; + $column_header{unit} = + qq|| . $locale->text('Unit') . qq||; + + print qq| + + + + + + + + |; + + $get_contact_url = + "$form->{script}?login=$form->{login}&path=$form->{path}&password=$form->{password}&action=get_contact"; + + my $pjx = new CGI::Ajax( 'get_contact' => $get_contact_url ); + $form->{selectcontact} = ""; + if (@{ $form->{CONTACTS} }) { + foreach $item (@{ $form->{CONTACTS} }) { + if ($item->{cp_id} == $form->{cp_id}) { + $form->{selectcontact} .= + qq|\n|; + } else { + $form->{selectcontact} .= + qq|\n|; + } + + } + } + push(@ { $form->{AJAX} }, $pjx); + $ansprechpartner = qq| + + + + + |; + $get_shipto_url = + "$form->{script}?login=$form->{login}&path=$form->{path}&password=$form->{password}&action=get_shipto"; + + my $pjy = new CGI::Ajax( 'get_shipto' => $get_shipto_url ); + $form->{selectshipto} = ""; + if (@{ $form->{SHIPTO} }) { + foreach $item (@{ $form->{SHIPTO} }) { + if ($item->{id} == $form->{shipto_id}) { + $form->{selectshipto} .= + " + + + + |; + + + $get_delivery_url = + "$form->{script}?login=$form->{login}&path=$form->{path}&password=$form->{password}&action=get_delivery"; + + my $pjz = new CGI::Ajax( 'get_delivery' => $get_delivery_url ); + + push(@ { $form->{AJAX} }, $pjz); + + $delivery = qq| + + + + |; + foreach $item (split / /, $form->{taxaccounts}) { if (($form->{tax}{$item}{taxable}) || !($form->{id})) { $taxable .= @@ -525,7 +968,11 @@ sub form_header { s/|; } @{ $form->{GREETINGS} }); $select_greeting .= qq||; + + $select_company_greeting = + qq| |; + + $select_department = + qq| |; ## /LINET if ($form->{db} eq 'customer') { @@ -612,177 +1071,130 @@ sub form_header { $form->{selectpricegroup} =~ s/(
+ + +|; + + map { print "$column_header{$_}\n" } @column_index; + + print qq| + +|; + + + foreach $ref (@{ $form->{ADR} }) { + + map { $column_data{$_} = "" } @column_index; + + + $i++; + $i %= 2; + print " + +"; + + map { print "$column_data{$_}\n" } @column_index; + + print qq| + +|; + + + } + + print qq| +
$ref->{$_} 
+ + +|; + } else { + my $filename = "adr-report-$form->{from}-$form->{to}.csv"; + if ($form->{year}) { + $filename = "adr-report-$form->{year}.csv"; + } + @column_index = + $form->sort_columns(adr_code, + adr_description, + sum, + unit); + + $tmpfile = qq|ADR Code;ADR Beschreibung;Menge;Einheit\n|; + foreach $ref (@{ $form->{ADR} }) { + + map { $column_data{$_} = qq|"$ref->{$_}"| } @column_index; + + $line = ""; + map { $line .= "$column_data{$_};" } @column_index; + chomp($line); + $tmpfile .= qq|$line\n|;; + } + + my $size = length($tmpfile); + # launch application + print qq|Content-Type: application/csv +Content-Disposition: attachment; filename="$filename" +Content-Length: $size + +$tmpfile +|; + } + + $lxdebug->leave_sub(); +} + sub list_names { $lxdebug->enter_sub(); @@ -463,7 +806,6 @@ sub form_header { $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : ""; $form->{creditlimit} = $form->format_amount(\%myconfig, $form->{creditlimit}, 0); - $form->{discount} = $form->format_amount(\%myconfig, $form->{discount}); if ($myconfig{role} eq 'admin') { $bcc = qq| @@ -474,16 +816,117 @@ sub form_header { |; } $form->{obsolete} = "checked" if $form->{obsolete}; - %langs = (de => "deutsch", en => "englisch", fr => "französisch"); + $lang = qq||; - foreach $item (keys %langs) { - if ($form->{language} eq $item) { - $lang .= qq||; + foreach $item (@{ $form->{languages} }) { + if ($form->{language_id} eq $item->{id}) { + $lang .= qq||; } else { - $lang .= qq||; + $lang .= qq||; + } + } + + $payment = qq||; + foreach $item (@{ $form->{payment_terms} }) { + if ($form->{payment_id} eq $item->{id}) { + $payment .= qq||; + } else { + $payment .= qq||; + } + } + + if (!$form->{id}) { + if ($form->{db} eq "customer") { + $form->{taxzone_id} = 0; + } else { + $form->{taxzone_id} = 0; + } + } + + if (@{ $form->{TAXZONE} }) { + foreach $item (@{ $form->{TAXZONE} }) { + if ($item->{id} == $form->{taxzone_id}) { + $form->{selecttaxzone} .= + "
| . $locale->text('Steuersatz') . qq|
| . $locale->text('Ansprechpartner') . qq|
| . $locale->text('Shipping Address') . qq|
| . $locale->text('Shipping Address') . qq|
- -
$form->{title}
+
+ + +{script} onKeyUp="highlight(event)" onClick="highlight(event)"> + + + +
+ +
+ +
+ - - - - $business_salesman + + + + - - + - - + - - + - - + - - + - - + - - + - - + - - + - + - - |; -##LINET - added fields for contact person - print qq| - - - |; -##/LINET - print qq| $bcc - $tax -
| - . $locale->text('Billing Address') . qq|| - . $locale->text('Shipping Address') . qq|
| . $locale->text($label . ' Number') . qq| {db}number"}">
| . $locale->text('Greeting') . qq|  + $select_company_greeting
| . $locale->text('Company Name') . qq|
| . $locale->text('Abteilung') . qq| - - +
| . $locale->text('Street') . qq|
| . $locale->text('Zipcode') . "/" . $locale->text('City') . qq| - - +
| . $locale->text('Country') . qq|
| . $locale->text('Contact') . qq|
| . $locale->text('Phone') . qq|
| . $locale->text('Fax') . qq|
| . $locale->text('E-mail') . qq|
| . $locale->text('Homepage') . qq|
- {cp_id}> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| - . $locale->text('Contact Person') . qq|
| . $locale->text('Greeting') . qq|  - $select_greeting| . $locale->text('Title') . qq|  - $select_title
| - . $locale->text('Given Name') . qq|| . $locale->text('Name') . qq|
| . $locale->text('Phone1') . qq|| . $locale->text('Phone2') . qq|
| . $locale->text('E-mail') . qq|
-
- - - - - +
+ - + - - - + - + $customer - + - + - + $business - |; if ($form->{db} eq 'customer') { @@ -795,20 +1207,197 @@ sub form_header { + + + $taxzone
| . $locale->text('Credit Limit') . qq| | . $locale->text('Terms: Net') . qq|| + | . $locale->text('days') . qq| | . $locale->text('Discount') . qq| + %
| . $locale->text('Tax Number / SSN') . qq| | . $locale->text('USt-IdNr.') . qq|
| . $locale->text('Account Number') . qq| | . $locale->text('Bank Code Number') . qq| | . $locale->text('Bank') . qq|
| . $locale->text('Language') . qq|
| . $locale->text('Obsolete') . qq| {obsolete}>| . $locale->text('Payment Terms') . qq|
- - + - - - + +
| . $locale->text('Notes') . qq|

+ + +
|; + +print qq| +
+ + +$shipto + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
| . $locale->text('Company Name') . qq|
| . $locale->text('Abteilung') . qq| +
| . $locale->text('Street') . qq|
| + . $locale->text('Zipcode') . "/" . $locale->text('City') . qq| +
| . $locale->text('Country') . qq|
| . $locale->text('Contact') . qq|
| . $locale->text('Phone') . qq|
| . $locale->text('Fax') . qq|
| . $locale->text('E-mail') . qq|
 
 
+
|; + + +##LINET - added fields for contact person + print qq| +
+ + + + + |; +##/LINET + print qq| $bcc + $tax +
+ {cp_id}> + + $ansprechpartner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
| . $locale->text('Greeting') . qq|  + $select_greeting
| . $locale->text('Title') . qq|  + $select_title
| . $locale->text('Department') . qq|  + $select_department
| + . $locale->text('Given Name') . qq|
| . $locale->text('Name') . qq|
| . $locale->text('Phone1') . qq|
| . $locale->text('Phone2') . qq|
| . $locale->text('Fax') . qq|
| . $locale->text('Mobile1') . qq|
| . $locale->text('Mobile2') . qq|
| . $locale->text('Sat. Phone') . qq|
| . $locale->text('Sat. Fax') . qq|
| . $locale->text('Project') . qq|
| . $locale->text('E-mail') . qq|
| . $locale->text('Private Phone') . qq|
| . $locale->text('Private E-mail') . qq|
| . $locale->text('Birthday') . qq|
+
+ + + + + +
+
+ + $delivery + + + + + + + + + +
| . $locale->text('From') . qq|| . $locale->text('Bis') . qq|
+
+
+
+
+ +
+ |; $lxdebug->leave_sub(); @@ -858,6 +1447,8 @@ sub form_footer { $update_button + @@ -880,7 +1471,10 @@ $update_button print qq| - + |; @@ -892,9 +1486,6 @@ sub add_transaction { $lxdebug->enter_sub(); $form->isblank("name", $locale->text("Name missing!")); - if ($vertreter && $form->{db} eq "customer") { - $form->isblank("salesman_id", $locale->text("Salesman missing!")); - } &{"CT::save_$form->{db}"}("", \%myconfig, \%$form); $form->{callback} = $form->escape($form->{callback}, 1); @@ -967,7 +1558,7 @@ sub save_and_order { $lxdebug->leave_sub(); } -sub save { +sub save_and_close { $lxdebug->enter_sub(); # $locale->text('Customer saved!') @@ -980,15 +1571,34 @@ sub save { if ($vertreter && $form->{db} eq "customer") { $form->isblank("salesman_id", $locale->text("Salesman missing!")); } - $rc = &{"CT::save_$form->{db}"}("", \%myconfig, \%$form); - if ($rc == 3) { - $form->error($locale->text('customernumber not unique!')); - } + &{"CT::save_$form->{db}"}("", \%myconfig, \%$form); + $form->redirect($locale->text($msg)); $lxdebug->leave_sub(); } +sub save { + $lxdebug->enter_sub(); + + # $locale->text('Customer saved!') + # $locale->text('Vendor saved!') + + $msg = ucfirst $form->{db}; + $imsg .= " saved!"; + + $form->isblank("name", $locale->text("Name missing!")); + if ($vertreter && $form->{db} eq "customer") { + $form->isblank("salesman_id", $locale->text("Salesman missing!")); + } + print(STDERR "SHIPTO in sub save $form->{shipto_id}\n"); + &{"CT::save_$form->{db}"}("", \%myconfig, \%$form); + + &edit; + exit; + $lxdebug->leave_sub(); +} + sub delete { $lxdebug->enter_sub(); @@ -1194,4 +1804,119 @@ sub salesman_selected { $lxdebug->leave_sub(); } +sub get_contact { + $lxdebug->enter_sub(); + + CT->get_contact(\%myconfig, \%$form); + + my $q = new CGI; + $result = "$form->{cp_name}"; + map { $result .= "__pjx__" . $form->{$_} } qw(cp_greeting cp_title cp_givenname cp_phone1 cp_phone2 cp_email cp_abteilung cp_fax cp_mobile1 cp_mobile2 cp_satphone cp_satfax cp_project cp_privatphone cp_privatemail cp_birthday); + print $q->header(); + print $result; + $lxdebug->leave_sub(); + +} + + +sub get_shipto { + $lxdebug->enter_sub(); + + CT->get_shipto(\%myconfig, \%$form); + + my $q = new CGI; + $result = "$form->{shiptoname}"; + map { $result .= "__pjx__" . $form->{$_} } qw(shiptodepartment_1 shiptodepartment_2 shiptostreet shiptozipcode shiptocity shiptocountry shiptocontact shiptophone shiptofax shiptoemail); + print $q->header(); + print $result; + $lxdebug->leave_sub(); + +} + +sub get_delivery { + $lxdebug->enter_sub(); + + CT->get_delivery(\%myconfig, \%$form); + + @column_index = + $form->sort_columns(shiptoname, + invnumber, + ordnumber, + transdate, + description, + adr_code, + qty, + unit); + + + + $column_header{shiptoname} = + qq|| . $locale->text('Shipping Address') . qq||; + $column_header{invnumber} = + qq||. $locale->text('Invoice'). qq||; + $column_header{ordnumber} = + qq||. $locale->text('Order'). qq||; + $column_header{transdate} = + qq|| . $locale->text('Invdate') . qq||; + $column_header{description} = + qq|| . $locale->text('Description') . qq||; + $column_header{adr_code} = + qq|| . $locale->text('ADR') . qq||; + $column_header{qty} = + qq|| . $locale->text('Qty') . qq||; + $column_header{unit} = + qq|| . $locale->text('Unit') . qq||; + $result .= qq| + + + + |; + $column_header{dunning_description} = + qq||; + $column_header{active} = + qq||; + $column_header{auto} = + qq||; + $column_header{email} = + qq||; + $column_header{payment_terms} = + qq||; + $column_header{terms} = + qq||; + $column_header{fee} = + qq||; + $column_header{interest} = + qq||; + $column_header{template} = + qq||; + print qq| + + + +{script}> + + +
+ + +|; + + map { $result .= "$column_header{$_}\n" } @column_index; + + $result .= qq| + +|; + + + foreach $ref (@{ $form->{DELIVERY} }) { + + if ($ref->{shiptoname} eq $sameshiptoname) { + map { $column_data{$_} = "" } @column_index; + $column_data{shiptoname} = ""; + } else { + map { $column_data{$_} = "" } @column_index; + } + + $i++; + $i %= 2; + $result .= " + +"; + + map { $result .= "$column_data{$_}\n" } @column_index; + + $result .= qq| + +|; + + $sameshiptoname = $ref->{shiptoname}; + + } + + $result .= qq| +
$ref->{$_}  $ref->{$_} 
+|; + + + my $q = new CGI; + print $q->header(); + print $result; + $lxdebug->leave_sub(); + +} + sub continue { &{ $form->{nextsub} } } diff --git a/bin/mozilla/dn.pl b/bin/mozilla/dn.pl new file mode 100644 index 000000000..e79283a6d --- /dev/null +++ b/bin/mozilla/dn.pl @@ -0,0 +1,983 @@ +#===================================================================== +# LX-Office ERP +# Copyright (C) 2006 +# Based on SQL-Ledger Version 2.1.9 +# Web http://www.lx-office.org +# +#===================================================================== +# SQL-Ledger Accounting +# Copyright (c) 1998-2002 +# +# Author: Dieter Simader +# Email: dsimader@sql-ledger.org +# Web: http://www.sql-ledger.org +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#====================================================================== +# +# Dunning process module +# +#====================================================================== + +use SL::IS; +use SL::PE; +use SL::DN; +use Data::Dumper; + +require "$form->{path}/io.pl"; +require "$form->{path}/arap.pl"; + +1; + +sub edit_config { + $lxdebug->enter_sub(); + + # edit all dunning config data + + $form->header; + DN->get_config(\%myconfig, \%$form); + $form->{title} = $locale->text('Edit Dunning Process Config'); + + $form->{callback} = + "$form->{script}?action=edit_config&path=$form->{path}&login=$form->{login}&password=$form->{password}" + unless $form->{callback}; + + @column_index = qw(dunning_level dunning_description active auto email payment_terms terms fee interest template); + + $column_header{dunning_level} = + qq|
| + . $locale->text('Dunning Level') + . qq|| + . $locale->text('Dunning Description') + . qq|| + . $locale->text('Active?') + . qq|| + . $locale->text('Auto Send?') + . qq|| + . $locale->text('eMail Send?') + . qq|| + . $locale->text('Fristsetzung') + . qq|| + . $locale->text('Duedate +Days') + . qq|| + . $locale->text('Fee') + . qq|| + . $locale->text('Interest Rate') + . qq|| + . $locale->text('Template') + . qq|
+ + + + + |; + map { print "$column_header{$_}\n" } @column_index; + + print qq| + +|; + my $i = 0; + foreach $ref (@{ $form->{DUNNING} }) { + + $i++; + my $j = $i % 2; + + print qq| + +|; + + + $column_data{dunning_level} = + qq||; + $column_data{dunning_description} = qq||; + my $active = ($ref->{active}) ? "checked" : ""; + $column_data{active} = + qq||; + my $email = ($ref->{email}) ? "checked" : ""; + $column_data{email} = + qq||; + + my $auto = ($ref->{auto}) ? "checked" : ""; + $column_data{auto} = + qq||; + $column_data{payment_terms} = qq||; + $column_data{terms} = qq||; + $column_data{fee} = qq||; + $column_data{interest} = qq||; + $column_data{template} = qq||; + + + + map { print "$column_data{$_}\n" } @column_index; + + print qq| + +|; + } + $i++; + my $j = $i % 2; + + print qq| + +|; + + + $column_data{dunning_level} = + qq||; + $column_data{dunning_description} = qq||; + my $active = ""; + $column_data{active} = + qq||; + my $email = ""; + $column_data{email} = + qq||; + my $auto = ""; + $column_data{auto} = + qq||; + $column_data{payment_terms} = qq||; + $column_data{terms} = qq||; + $column_data{fee} = qq||; + $column_data{interest} = qq||; + $column_data{template} = qq||; + + + $form->{rowcount} = $i; + map { print "$column_data{$_}\n" } @column_index; + + print qq| + +|; + + + print qq| +
$form->{title}
$i%
$i%
+ + + +
+ + + +
+{script}> + + + + +{path}> +{login}> +{password}> + +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + + + + + +|; + + $lxdebug->leave_sub(); +} + +sub add { + $lxdebug->enter_sub(); + # setup customer selection + $form->all_vc(\%myconfig, "customer", "AR"); + + DN->get_config(\%myconfig, \%$form); + + if (@{ $form->{all_customer} }) { + map { $customer .= "\n" + } (@{ $form->{DUNNING} }); + } + $dunning_level = qq| + + | . $locale->text('Next Dunning Level') . qq| + + + | if $form->{selectdunning_level}; + + # departments + if (@{ $form->{all_departments} }) { + $form->{selectdepartment} = ""; + } + } + + + $form->{nextsub} = "save_dunning"; + + $form->{callback} = + "$form->{script}?action=show_invoices&path=$form->{path}&login=$form->{login}&password=$form->{password}&customer=$form->{customer}&invnumber=$form->{invnumber}&ordnumber=$form->{ordnumber}&paymentuntil=$form->{paymentuntil}&groupinvoices=$form->{groupinvoices}&minamount=$form->{minamount}&dunning_level=$form->{dunning_level}¬es=$form->{notes}" + unless $form->{callback}; + + @column_index = qw(dunning_description active email customername invnumber invdate inv_duedate invamount next_duedate fee interest ); + + $column_header{dunning_description} = + qq|| + . $locale->text('Current / Next Level') + . qq||; + $column_header{active} = + qq|| + . $locale->text('Active?') + . qq||; + $column_header{email} = + qq|| + . $locale->text('eMail?') + . qq||; + $column_header{customername} = + qq|| + . $locale->text('Customername') + . qq||; + $column_header{invnumber} = + qq|| + . $locale->text('Invno.') + . qq||; + $column_header{inv_duedate} = + qq|| + . $locale->text('Inv. Duedate') + . qq||; + $column_header{next_duedate} = + qq|| + . $locale->text('Dunning Duedate') + . qq||; + $column_header{invdate} = + qq|| + . $locale->text('Invdate') + . qq||; + $column_header{invamount} = + qq|| + . $locale->text('Amount') + . qq||; + $column_header{fee} = + qq|| + . $locale->text('Total Fees') + . qq||; + $column_header{interest} = + qq|| + . $locale->text('Total Interest') + . qq||; + + $form->header; + + + print qq| + + + +
{script}> + + + + + + + + |; + map { print "$column_header{$_}\n" } @column_index; + + print qq| + +|; + my $i = 0; + foreach $ref (@{ $form->{DUNNINGS} }) { + + $i++; + my $j = $i % 2; + + print qq| + +|; + + $form->{selectdunning} =~ s/ selected//g; + if ($ref->{next_dunning_id} ne "") { + $form->{selectdunning} =~ s/value=$ref->{next_dunning_id}/value=$ref->{next_dunning_id} selected/; + } + + + $dunning = qq||; + + + $column_data{dunning_description} = qq||; + my $active = "checked"; + $column_data{active} = + qq||; + my $email = "checked"; + $column_data{email} = + qq||; + $column_data{next_duedate} = qq||; + + $column_data{inv_duedate} = qq||; + $column_data{invdate} = qq||; + $column_data{invnumber} = qq||; + $column_data{customername} = qq||; + $column_data{invamount} = qq||; + $column_data{fee} = qq||; + $column_data{interest} = qq||; + + + + map { print "$column_data{$_}\n" } @column_index; + + print qq| + +|; + } + + $form->{rowcount} = $i; + + print qq| +
$form->{title}
$ref->{dunning_level}: $dunning$ref->{next_duedate}$ref->{duedate}$ref->{transdate}$ref->{invnumber}$ref->{customername}$ref->{amount}$ref->{fee}$ref->{interest}
+ + + +
+ +|; +&print_options; +print qq| +
+{script}> + + + + + + + +{path}> +{login}> +{password}> + +|; + + if ($form->{menubar}) { + require "$form->{path}/menu.pl"; + &menubar; + } + + print qq| + +
+ + + +|; + + + $lxdebug->leave_sub(); + +} + +sub save { + $lxdebug->enter_sub(); + + for my $i (1 .. $form->{rowcount}) { + if ($form->{"dunning_description_$i"} ne "") { + $form->isblank("dunning_level_$i", $locale->text('Dunning Level missing in row '). $i); + $form->isblank("dunning_description_$i", $locale->text('Dunning Description missing in row '). $i); + $form->isblank("terms_$i", $locale->text('Terms missing in row '). $i); + $form->isblank("payment_terms_$i", $locale->text('Payment Terms missing in row '). $i); + } + } + + DN->save_config(\%myconfig, \%$form); + $form->redirect($locale->text('Dunning Process Config saved!')); + + $lxdebug->leave_sub(); +} + +sub save_dunning { + $lxdebug->enter_sub(); + + my $active=1; + my @rows = (); + undef($form->{DUNNING_PDFS}); + if ($form->{groupinvoices}) { + while ($active) { + $lastcustomer = 0; + $form->{inv_ids} = ""; + $active = 0; + @rows = (); + for my $i (1 .. $form->{rowcount}) { + $form->{"active_$i"} *= 1; + $lastcustomer = $form->{"customer_id_$i"} unless ($lastcustomer); + #print(STDERR qq|LASTCUSTOMER $lastcustomer AKTUELL $form->{"customer_id_$i"} ACTIVE? $form->{"active_$i"} active $active\n Zeile $i|); + if ($form->{"active_$i"} && ($form->{"customer_id_$i"} == $lastcustomer)) { + if ($form->{inv_ids}) { + $form->{inv_ids} .= qq|,$form->{"inv_id_$i"}|; + } else { + $form->{inv_ids} = qq|($form->{"inv_id_$i"}|; + } + $form->{"active_$i"} = 0; + $form->{"customer_id_$i"} = 0; + push(@rows, $i); + } elsif ($form->{"active_$i"}) { + $active = 1; + } else { + $form->{"customer_id_$i"} = 0; + } + } + if ($form->{inv_ids} ne "") { + $form->{inv_ids} .= ")"; + #print(STDERR "Rufe save_dunning_auf für Zeile $form->{inv_ids} von Kunde $lastcustomer\n"); + DN->save_dunning(\%myconfig, \%$form, \@rows, $userspath,$spool, $sendmail); + } + } + } else { + for my $i (1 .. $form->{rowcount}) { + if ($form->{"active_$i"}) { + @rows = (); + $form->{inv_ids} = qq|($form->{"inv_id_$i"})|; + push(@rows, $i); + #print(STDERR "Rufe save_dunning_auf für Zeile $i\n"); + DN->save_dunning(\%myconfig, \%$form, \@rows, $userspath,$spool, $sendmail); + } + } + } + #print(STDERR Dumper($form->{DUNNING_PDFS})); + if($form->{DUNNING_PDFS}) { + DN->melt_pdfs(\%myconfig, \%$form,$spool); + } + + $form->redirect($locale->text('Dunning Process started for selected invoices!')); + + $lxdebug->leave_sub(); +} + +sub set_email { + $lxdebug->enter_sub(); + + + my $callback = "$form->{script}?action=set_email&"; + map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } + (qw(login path password name input_subject input_body input_attachment email_subject email_body email_attachment), grep({ /^[fl]_/ } keys %$form))); + + if ($form->{email_attachment}) { + $form->{email_attachment} = "checked"; + } + $form->{"title"} = $locale->text("Set eMail text"); + $form->header(); + print($form->parse_html_template("dunning/set_email")); + + $lxdebug->leave_sub(); +} + +sub search { + $lxdebug->enter_sub(); + # setup customer selection + $form->all_vc(\%myconfig, "customer", "AR"); + + DN->get_config(\%myconfig, \%$form); + + if (@{ $form->{all_customer} }) { + map { $customer .= "\n" + } (@{ $form->{DUNNING} }); + } + $dunning_level = qq| + + | . $locale->text('Next Dunning Level') . qq| + + + | if $form->{selectdunning_level}; + + # departments + if (@{ $form->{all_departments} }) { + $form->{selectdepartment} = "