X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FForm.pm;h=d85fe54daf8329ec606f67241e5f566e26d59563;hb=91ee6cb28c37fe07d001da04808f9c49e1959502;hp=525d7329ee95c8fb2a5aa09b5e2bbdbe05e92129;hpb=3879426c4db6c8a2ff8afa9a98992eeaede38a49;p=kivitendo-erp.git
diff --git a/SL/Form.pm b/SL/Form.pm
index 525d7329e..d85fe54da 100644
--- a/SL/Form.pm
+++ b/SL/Form.pm
@@ -37,8 +37,6 @@
package Form;
-#use strict;
-
use Data::Dumper;
use CGI;
@@ -56,7 +54,11 @@ use SL::Menu;
use SL::Template;
use SL::User;
use Template;
+use URI;
use List::Util qw(first max min sum);
+use List::MoreUtils qw(any);
+
+use strict;
my $standard_dbh;
@@ -70,45 +72,46 @@ END {
sub _store_value {
$main::lxdebug->enter_sub(2);
- my $curr = shift;
+ my $self = shift;
my $key = shift;
my $value = shift;
- while ($key =~ /\[\+?\]\.|\./) {
- substr($key, 0, $+[0]) = '';
+ my @tokens = split /((?:\[\+?\])?(?:\.|$))/, $key;
- if ($& eq '.') {
- $curr->{$`} ||= { };
- $curr = $curr->{$`};
+ my $curr;
- } else {
- $curr->{$`} ||= [ ];
- if (!scalar @{ $curr->{$`} } || $& eq '[+].') {
- push @{ $curr->{$`} }, { };
- }
+ if (scalar @tokens) {
+ $curr = \ $self->{ shift @tokens };
+ }
- $curr = $curr->{$`}->[-1];
- }
+ while (@tokens) {
+ my $sep = shift @tokens;
+ my $key = shift @tokens;
+
+ $curr = \ $$curr->[++$#$$curr], next if $sep eq '[]';
+ $curr = \ $$curr->[max 0, $#$$curr] if $sep eq '[].';
+ $curr = \ $$curr->[++$#$$curr] if $sep eq '[+].';
+ $curr = \ $$curr->{$key}
}
- $curr->{$key} = $value;
+ $$curr = $value;
$main::lxdebug->leave_sub(2);
- return \$curr->{$key};
+ return $curr;
}
sub _input_to_hash {
$main::lxdebug->enter_sub(2);
- my $params = shift;
- my $input = shift;
+ my $self = shift;
+ my $input = shift;
- my @pairs = split(/&/, $input);
+ my @pairs = split(/&/, $input);
foreach (@pairs) {
my ($key, $value) = split(/=/, $_, 2);
- _store_value($params, unescape(undef, $key), unescape(undef, $value));
+ $self->_store_value($self->unescape($key), $self->unescape($value)) if ($key);
}
$main::lxdebug->leave_sub(2);
@@ -117,13 +120,13 @@ sub _input_to_hash {
sub _request_to_hash {
$main::lxdebug->enter_sub(2);
- my $params = shift;
- my $input = shift;
+ my $self = shift;
+ my $input = shift;
if (!$ENV{'CONTENT_TYPE'}
|| ($ENV{'CONTENT_TYPE'} !~ /multipart\/form-data\s*;\s*boundary\s*=\s*(.+)$/)) {
- _input_to_hash($params, $input);
+ $self->_input_to_hash($input);
$main::lxdebug->leave_sub(2);
return;
@@ -171,8 +174,8 @@ sub _request_to_hash {
substr $line, $-[0], $+[0] - $-[0], "";
}
- $previous = _store_value($params, $name, '');
- $params->{FILENAME} = $filename if ($filename);
+ $previous = $self->_store_value($name, '') if ($name);
+ $self->{FILENAME} = $filename if ($filename);
next;
}
@@ -195,12 +198,16 @@ sub _request_to_hash {
}
sub _recode_recursively {
+ $main::lxdebug->enter_sub();
my ($iconv, $param) = @_;
- if (ref $param eq 'HASH') {
+ if (any { ref $param eq $_ } qw(Form HASH)) {
foreach my $key (keys %{ $param }) {
if (!ref $param->{$key}) {
- $param->{$key} = $iconv->convert($param->{$key});
+ # Workaround for a bug: converting $param->{$key} directly
+ # leads to 'undef'. I don't know why. Converting a copy works,
+ # though.
+ $param->{$key} = $iconv->convert("" . $param->{$key});
} else {
_recode_recursively($iconv, $param->{$key});
}
@@ -209,12 +216,16 @@ sub _recode_recursively {
} elsif (ref $param eq 'ARRAY') {
foreach my $idx (0 .. scalar(@{ $param }) - 1) {
if (!ref $param->[$idx]) {
- $param->[$idx] = $iconv->convert($param->[$idx]);
+ # Workaround for a bug: converting $param->[$idx] directly
+ # leads to 'undef'. I don't know why. Converting a copy works,
+ # though.
+ $param->[$idx] = $iconv->convert("" . $param->[$idx]);
} else {
_recode_recursively($iconv, $param->[$idx]);
}
}
}
+ $main::lxdebug->leave_sub();
}
sub new {
@@ -241,27 +252,26 @@ sub new {
bless $self, $type;
- my $parameters = { };
- _request_to_hash($parameters, $_);
+ $self->_request_to_hash($_);
my $db_charset = $main::dbcharset;
$db_charset ||= Common::DEFAULT_CHARSET;
- if ($parameters->{INPUT_ENCODING} && (lc $parameters->{INPUT_ENCODING} ne $db_charset)) {
- require Text::Iconv;
- my $iconv = Text::Iconv->new($parameters->{INPUT_ENCODING}, $db_charset);
+ if ($self->{INPUT_ENCODING}) {
+ if (lc $self->{INPUT_ENCODING} ne lc $db_charset) {
+ require Text::Iconv;
+ my $iconv = Text::Iconv->new($self->{INPUT_ENCODING}, $db_charset);
- _recode_recursively($iconv, $parameters);
+ _recode_recursively($iconv, $self);
+ }
- delete $parameters{INPUT_ENCODING};
+ delete $self->{INPUT_ENCODING};
}
- map { $self->{$_} = $parameters->{$_}; } keys %{ $parameters };
-
$self->{action} = lc $self->{action};
$self->{action} =~ s/( |-|,|\#)/_/g;
- $self->{version} = "2.6.0 beta 1";
+ $self->{version} = "2.6.1";
$main::lxdebug->leave_sub();
@@ -394,28 +404,33 @@ sub unescape {
}
sub quote {
+ $main::lxdebug->enter_sub();
my ($self, $str) = @_;
if ($str && !ref($str)) {
$str =~ s/\"/"/g;
}
- $str;
+ $main::lxdebug->leave_sub();
+ return $str;
}
sub unquote {
+ $main::lxdebug->enter_sub();
my ($self, $str) = @_;
if ($str && !ref($str)) {
$str =~ s/"/\"/g;
}
- $str;
+ $main::lxdebug->leave_sub();
+ return $str;
}
sub hide_form {
+ $main::lxdebug->enter_sub();
my $self = shift;
if (@_) {
@@ -426,7 +441,7 @@ sub hide_form {
print($main::cgi->hidden("-name" => $_, "-default" => $self->{$_}) . "\n");
}
}
-
+ $main::lxdebug->leave_sub();
}
sub error {
@@ -520,6 +535,26 @@ sub isblank {
$main::lxdebug->leave_sub();
}
+sub _get_request_uri {
+ my $self = shift;
+
+ return URI->new($ENV{HTTP_REFERER})->canonical() if $ENV{HTTP_X_FORWARDED_FOR};
+
+ my $scheme = $ENV{HTTPS} && (lc $ENV{HTTPS} eq 'on') ? 'https' : 'http';
+ my $port = $ENV{SERVER_PORT} || '';
+ $port = undef if (($scheme eq 'http' ) && ($port == 80))
+ || (($scheme eq 'https') && ($port == 443));
+
+ my $uri = URI->new("${scheme}://");
+ $uri->scheme($scheme);
+ $uri->port($port);
+ $uri->host($ENV{HTTP_HOST} || $ENV{SERVER_ADDR});
+ $uri->path_query($ENV{REQUEST_URI});
+ $uri->query('');
+
+ return $uri;
+}
+
sub create_http_response {
$main::lxdebug->enter_sub();
@@ -529,25 +564,20 @@ sub create_http_response {
my $cgi = $main::cgi;
$cgi ||= CGI->new('');
- my $base_path;
-
- if ($ENV{HTTP_X_FORWARDED_FOR}) {
- $base_path = $ENV{HTTP_REFERER};
- $base_path =~ s|^.*?://.*?/|/|;
- } else {
- $base_path = $ENV{REQUEST_URI};
- }
- $base_path =~ s|[^/]+$||;
- $base_path =~ s|/$||;
-
my $session_cookie;
if (defined $main::auth) {
+ my $uri = $self->_get_request_uri;
+ my @segments = $uri->path_segments;
+ pop @segments;
+ $uri->path_segments(@segments);
+
my $session_cookie_value = $main::auth->get_session_id();
$session_cookie_value ||= 'NO_SESSION';
- $session_cookie = $cgi->cookie('-name' => $main::auth->get_session_cookie_name(),
- '-value' => $session_cookie_value,
- '-path' => $base_path);
+ $session_cookie = $cgi->cookie('-name' => $main::auth->get_session_cookie_name(),
+ '-value' => $session_cookie_value,
+ '-path' => $uri->path,
+ '-secure' => $ENV{HTTPS});
}
my %cgi_params = ('-type' => $params{content_type});
@@ -565,6 +595,8 @@ sub create_http_response {
sub header {
$main::lxdebug->enter_sub();
+ # extra code ist currently only used by menuv3 and menuv4 to set their css.
+ # it is strongly deprecated, and will be changed in a future version.
my ($self, $extra_code) = @_;
if ($self->{header}) {
@@ -609,13 +641,22 @@ sub header {
|;
}
- my $fokus = qq| document.$self->{fokus}.focus();| if ($self->{"fokus"});
+ my $fokus = qq|
+
+ | if $self->{"fokus"};
#Set Calendar
my $jsscript = "";
if ($self->{jsscript} == 1) {
$jsscript = qq|
+
@@ -630,7 +671,7 @@ sub header {
? "$self->{title} - $self->{titlebar}"
: $self->{titlebar};
my $ajax = "";
- foreach my $item (@ { $self->{AJAX} }) {
+ for my $item (@ { $self->{AJAX} || [] }) {
$ajax .= $item->show_javascript();
}
@@ -646,13 +687,9 @@ sub header {
$jsscript
$ajax
-
+ $fokus
+
+
@@ -692,13 +729,27 @@ sub ajax_response_header {
return $output;
}
+sub redirect_header {
+ my $self = shift;
+ my $new_url = shift;
+
+ my $base_uri = $self->_get_request_uri;
+ my $new_uri = URI->new_abs($new_url, $base_uri);
+
+ die "Headers already sent" if $::self->{header};
+ $self->{header} = 1;
+
+ my $cgi = $main::cgi || CGI->new('');
+ return $cgi->redirect($new_uri);
+}
+
sub _prepare_html_template {
$main::lxdebug->enter_sub();
my ($self, $file, $additional_params) = @_;
my $language;
- if (!defined(%main::myconfig) || !defined($main::myconfig{"countrycode"})) {
+ if (!%::myconfig || !$::myconfig{"countrycode"}) {
$language = $main::language;
} else {
$language = $main::myconfig{"countrycode"};
@@ -742,6 +793,7 @@ sub _prepare_html_template {
$jsc_dateformat =~ s/m+/\%m/gi;
$jsc_dateformat =~ s/y+/\%Y/gi;
$additional_params->{"myconfig_jsc_dateformat"} = $jsc_dateformat;
+ $additional_params->{"myconfig"} ||= \%::myconfig;
}
$additional_params->{"conf_dbcharset"} = $main::dbcharset;
@@ -749,6 +801,8 @@ sub _prepare_html_template {
$additional_params->{"conf_lizenzen"} = $main::lizenzen;
$additional_params->{"conf_latex_templates"} = $main::latex;
$additional_params->{"conf_opendocument_templates"} = $main::opendocument_templates;
+ $additional_params->{"conf_vertreter"} = $main::vertreter;
+ $additional_params->{"conf_show_best_before"} = $main::show_best_before;
if (%main::debug_options) {
map { $additional_params->{'DEBUG_' . uc($_)} = $main::debug_options{$_} } keys %main::debug_options;
@@ -979,9 +1033,9 @@ sub format_amount {
$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" ) ;
+ ($dash =~ /-/) ? ($neg ? "($amount)" : "$amount" ) :
+ ($dash =~ /DRCR/) ? ($neg ? "$amount " . $main::locale->text('DR') : "$amount " . $main::locale->text('CR') ) :
+ ($neg ? "-$amount" : "$amount" ) ;
};
@@ -1103,13 +1157,13 @@ sub round_amount {
my ($self, $amount, $places) = @_;
my $round_amount;
- # Rounding like "Kaufmannsrunden"
- # Descr. http://de.wikipedia.org/wiki/Rundung
- # Inspired by
- # http://www.perl.com/doc/FAQs/FAQ/oldfaq-html/Q4.13.html
- # Solves Bug: 189
- # Udo Spallek
- $amount = $amount * (10**($places));
+ # Rounding like "Kaufmannsrunden" (see http://de.wikipedia.org/wiki/Rundung )
+
+ # Round amounts to eight places before rounding to the requested
+ # number of places. This gets rid of errors due to internal floating
+ # point representation.
+ $amount = $self->round_amount($amount, 8) if $places < 8;
+ $amount = $amount * (10**($places));
$round_amount = int($amount + .5 * ($amount <=> 0)) / (10**($places));
$main::lxdebug->leave_sub(2);
@@ -1133,7 +1187,7 @@ sub parse_template {
if ($self->{"format"} =~ /(opendocument|oasis)/i) {
$template = OpenDocumentTemplate->new($self->{"IN"}, $self, $myconfig, $userspath);
- $ext_for_format = 'odt';
+ $ext_for_format = $self->{"format"} =~ m/pdf/ ? 'pdf' : 'odt';
} elsif ($self->{"format"} =~ /(postscript|pdf)/i) {
$ENV{"TEXINPUTS"} = ".:" . getcwd() . "/" . $myconfig->{"templates"} . ":" . $ENV{"TEXINPUTS"};
@@ -1154,6 +1208,10 @@ sub parse_template {
} elsif ( $self->{"format"} =~ /elstertaxbird/i ) {
$template = XMLTemplate->new($self->{"IN"}, $self, $myconfig, $userspath);
+ } elsif ( $self->{"format"} =~ /excel/i ) {
+ $template = ExcelTemplate->new($self->{"IN"}, $self, $myconfig, $userspath);
+ $ext_for_format = 'xls';
+
} elsif ( defined $self->{'format'}) {
$self->error("Outputformat not defined. This may be a future feature: $self->{'format'}");
@@ -1293,6 +1351,7 @@ Content-Length: $numbytes
while () {
print OUT $_;
+
}
close(OUT);
@@ -1312,6 +1371,7 @@ Content-Length: $numbytes
}
sub get_formname_translation {
+ $main::lxdebug->enter_sub();
my ($self, $formname) = @_;
$formname ||= $self->{formname};
@@ -1331,12 +1391,15 @@ sub get_formname_translation {
storno_packing_list => $main::locale->text('Storno Packing List'),
sales_delivery_order => $main::locale->text('Delivery Order'),
purchase_delivery_order => $main::locale->text('Delivery Order'),
+ dunning => $main::locale->text('Dunning'),
);
+ $main::lxdebug->leave_sub();
return $formname_translations{$formname}
}
sub get_number_prefix_for_type {
+ $main::lxdebug->enter_sub();
my ($self) = @_;
my $prefix =
@@ -1345,22 +1408,27 @@ sub get_number_prefix_for_type {
: ($self->{type} =~ /_delivery_order$/) ? 'do'
: 'ord';
+ $main::lxdebug->leave_sub();
return $prefix;
}
sub get_extension_for_format {
+ $main::lxdebug->enter_sub();
my ($self) = @_;
my $extension = $self->{format} =~ /pdf/i ? ".pdf"
: $self->{format} =~ /postscript/i ? ".ps"
: $self->{format} =~ /opendocument/i ? ".odt"
+ : $self->{format} =~ /excel/i ? ".xls"
: $self->{format} =~ /html/i ? ".html"
: "";
+ $main::lxdebug->leave_sub();
return $extension;
}
sub generate_attachment_filename {
+ $main::lxdebug->enter_sub();
my ($self) = @_;
my $attachment_filename = $main::locale->unquote_special_chars('HTML', $self->get_formname_translation());
@@ -1379,10 +1447,12 @@ sub generate_attachment_filename {
$attachment_filename = $main::locale->quote_special_chars('filenames', $attachment_filename);
$attachment_filename =~ s|[\s/\\]+|_|g;
+ $main::lxdebug->leave_sub();
return $attachment_filename;
}
sub generate_email_subject {
+ $main::lxdebug->enter_sub();
my ($self) = @_;
my $subject = $main::locale->unquote_special_chars('HTML', $self->get_formname_translation());
@@ -1392,6 +1462,7 @@ sub generate_email_subject {
$subject .= " " . $self->{"${prefix}number"}
}
+ $main::lxdebug->leave_sub();
return $subject;
}
@@ -1409,7 +1480,7 @@ sub cleanup {
close(FH);
}
- if ($self->{tmpfile}) {
+ if ($self->{tmpfile} && ! $::keep_temp_files) {
$self->{tmpfile} =~ s|.*/||g;
# strip extension
$self->{tmpfile} =~ s/\.\w+$//g;
@@ -1508,7 +1579,7 @@ sub get_standard_dbh {
my ($self, $myconfig) = @_;
if ($standard_dbh && !$standard_dbh->{Active}) {
- $main::lxdebug->message(LXDebug::INFO, "get_standard_dbh: \$standard_dbh is defined but not Active anymore");
+ $main::lxdebug->message(LXDebug->INFO(), "get_standard_dbh: \$standard_dbh is defined but not Active anymore");
undef $standard_dbh;
}
@@ -1703,7 +1774,7 @@ sub check_exchangerate {
return $exchangerate;
}
-sub get_default_currency {
+sub get_all_currencies {
$main::lxdebug->enter_sub();
my ($self, $myconfig) = @_;
@@ -1711,14 +1782,24 @@ sub get_default_currency {
my $query = qq|SELECT curr FROM defaults|;
- my ($curr) = selectrow_query($self, $dbh, $query);
- my ($defaultcurrency) = split m/:/, $curr;
+ my ($curr) = selectrow_query($self, $dbh, $query);
+ my @currencies = grep { $_ } map { s/\s//g; $_ } split m/:/, $curr;
$main::lxdebug->leave_sub();
- return $defaultcurrency;
+ return @currencies;
}
+sub get_default_currency {
+ $main::lxdebug->enter_sub();
+
+ my ($self, $myconfig) = @_;
+ my @currencies = $self->get_all_currencies($myconfig);
+
+ $main::lxdebug->leave_sub();
+
+ return $currencies[0];
+}
sub set_payment_options {
$main::lxdebug->enter_sub();
@@ -1767,6 +1848,7 @@ sub set_payment_options {
$amounts{invtotal} = $self->{invtotal};
$amounts{total} = $self->{total};
}
+ $amounts{skonto_in_percent} = 100.0 * $self->{percent_skonto};
map { $amounts{$_} = $self->parse_amount($myconfig, $amounts{$_}) } keys %amounts;
@@ -1820,6 +1902,8 @@ sub set_payment_options {
map { $self->{payment_terms} =~ s/<%${_}%>/$formatted_amounts{$_}/g; } keys %formatted_amounts;
+ $self->{skonto_in_percent} = $formatted_amounts{skonto_in_percent};
+
$main::lxdebug->leave_sub();
}
@@ -1944,6 +2028,8 @@ sub get_employee {
my ($self, $dbh) = @_;
+ $dbh ||= $self->get_standard_dbh(\%main::myconfig);
+
my $query = qq|SELECT id, name FROM employee WHERE login = ?|;
($self->{"employee_id"}, $self->{"employee"}) = selectrow_query($self, $dbh, $query, $self->{login});
$self->{"employee_id"} *= 1;
@@ -1986,11 +2072,11 @@ sub get_duedate {
my ($self, $myconfig, $reference_date) = @_;
- my $reference_date = $reference_date ? conv_dateq($reference_date) . '::DATE' : 'current_date';
+ $reference_date = $reference_date ? conv_dateq($reference_date) . '::DATE' : 'current_date';
- my $dbh = $self->get_standard_dbh($myconfig);
- my $query = qq|SELECT ${reference_date} + terms_netto FROM payment_terms WHERE id = ?|;
- my ($duedate) = selectrow_query($self, $dbh, $query, $self->{payment_id});
+ my $dbh = $self->get_standard_dbh($myconfig);
+ my $query = qq|SELECT ${reference_date} + terms_netto FROM payment_terms WHERE id = ?|;
+ my ($duedate) = selectrow_query($self, $dbh, $query, $self->{payment_id});
$main::lxdebug->leave_sub();
@@ -2117,7 +2203,7 @@ sub _get_charts {
my $transdate = quote_db_date($params->{transdate});
my $query =
- qq|SELECT c.id, c.accno, c.description, c.link, tk.taxkey_id, tk.tax_id | .
+ qq|SELECT c.id, c.accno, c.description, c.link, c.charttype, tk.taxkey_id, tk.tax_id | .
qq|FROM chart c | .
qq|LEFT JOIN taxkeys tk ON | .
qq|(tk.id = (SELECT id FROM taxkeys | .
@@ -2190,9 +2276,15 @@ sub _get_business_types {
my ($self, $dbh, $key) = @_;
- $key = "all_business_types" unless ($key);
- $self->{$key} =
- selectall_hashref_query($self, $dbh, qq|SELECT * FROM business|);
+ my $options = ref $key eq 'HASH' ? $key : { key => $key };
+ $options->{key} ||= "all_business_types";
+ my $where = '';
+
+ if (exists $options->{salesman}) {
+ $where = 'WHERE ' . ($options->{salesman} ? '' : 'NOT ') . 'COALESCE(salesman)';
+ }
+
+ $self->{ $options->{key} } = selectall_hashref_query($self, $dbh, qq|SELECT * FROM business $where ORDER BY lower(description)|);
$main::lxdebug->leave_sub();
}
@@ -2256,14 +2348,15 @@ $main::lxdebug->enter_sub();
sub _get_customers {
$main::lxdebug->enter_sub();
- my ($self, $dbh, $key, $limit) = @_;
-
- $key = "all_customers" unless ($key);
- my $limit_clause = "LIMIT $limit" if $limit;
+ my ($self, $dbh, $key) = @_;
- my $query = qq|SELECT * FROM customer WHERE NOT obsolete ORDER BY name $limit_clause|;
+ my $options = ref $key eq 'HASH' ? $key : { key => $key };
+ $options->{key} ||= "all_customers";
+ my $limit_clause = "LIMIT $options->{limit}" if $options->{limit};
+ my $where = $options->{business_is_salesman} ? qq| AND business_id IN (SELECT id FROM business WHERE salesman)| : '';
- $self->{$key} = selectall_hashref_query($self, $dbh, $query);
+ my $query = qq|SELECT * FROM customer WHERE NOT obsolete $where ORDER BY name $limit_clause|;
+ $self->{ $options->{key} } = selectall_hashref_query($self, $dbh, $query);
$main::lxdebug->leave_sub();
}
@@ -2430,11 +2523,7 @@ sub get_lists {
}
if($params{"customers"}) {
- if (ref $params{"customers"} eq 'HASH') {
- $self->_get_customers($dbh, $params{"customers"}{key}, $params{"customers"}{limit});
- } else {
- $self->_get_customers($dbh, $params{"customers"});
- }
+ $self->_get_customers($dbh, $params{"customers"});
}
if($params{"vendors"}) {
@@ -2536,7 +2625,7 @@ sub all_vc {
my ($count) = selectrow_query($self, $dbh, $query);
# build selection list
- if ($count < $myconfig->{vclimit}) {
+ if ($count <= $myconfig->{vclimit}) {
$query = qq|SELECT id, name, salesman_id
FROM $table WHERE NOT obsolete
ORDER BY name|;
@@ -2656,7 +2745,7 @@ sub all_departments {
ORDER BY description|;
$self->{all_departments} = selectall_hashref_query($self, $dbh, $query);
- delete($self->{all_departments}) unless (@{ $self->{all_departments} });
+ delete($self->{all_departments}) unless (@{ $self->{all_departments} || [] });
$main::lxdebug->leave_sub();
}
@@ -2812,7 +2901,7 @@ sub create_links {
(startdate <= a.transdate) ORDER BY startdate DESC LIMIT 1))
WHERE a.trans_id = ?
AND a.fx_transaction = '0'
- ORDER BY a.oid, a.transdate|;
+ ORDER BY a.acc_trans_id, a.transdate|;
$sth = $dbh->prepare($query);
do_statement($self, $sth, $query, $self->{id});
@@ -2936,7 +3025,9 @@ sub lastname_used {
sub current_date {
$main::lxdebug->enter_sub();
- my ($self, $myconfig, $thisdate, $days) = @_;
+ my $self = shift;
+ my $myconfig = shift || \%::myconfig;
+ my ($thisdate, $days) = @_;
my $dbh = $self->get_standard_dbh($myconfig);
my $query;
@@ -3168,9 +3259,8 @@ sub get_history {
qq|SELECT h.employee_id, h.itime::timestamp(0) AS itime, h.addition, h.what_done, emp.name, h.snumbers, h.trans_id AS id | .
qq|FROM history_erp h | .
qq|LEFT JOIN employee emp ON (emp.id = h.employee_id) | .
- qq|WHERE trans_id = | . $trans_id
- . $restriction . qq| |
- . $order;
+ qq|WHERE (trans_id = | . $trans_id . qq|) $restriction | .
+ $order;
my $sth = $dbh->prepare($query) || $self->dberror($query);
@@ -3245,6 +3335,8 @@ sub update_business {
WHERE id = ? FOR UPDATE|;
my ($var) = selectrow_query($self, $dbh, $query, $business_id);
+ return undef unless $var;
+
if ($var =~ m/\d+$/) {
my $new_var = (substr $var, $-[0]) * 1 + 1;
my $len_diff = length($var) - $-[0] - length($new_var);
@@ -3383,7 +3475,7 @@ sub backup_vars {
my $self = shift;
my @vars = @_;
- map { $self->{_VAR_BACKUP}->{$_} = $self->{$_} if $self->{$_} } @vars;
+ map { $self->{_VAR_BACKUP}->{$_} = $self->{$_} if exists $self->{$_} } @vars;
$main::lxdebug->leave_sub();
}
@@ -3394,9 +3486,113 @@ sub restore_vars {
my $self = shift;
my @vars = @_;
- map { $self->{$_} = $self->{_VAR_BACKUP}->{$_} if $self->{_VAR_BACKUP}->{$_} } @vars;
+ map { $self->{$_} = $self->{_VAR_BACKUP}->{$_} if exists $self->{_VAR_BACKUP}->{$_} } @vars;
$main::lxdebug->leave_sub();
}
1;
+
+__END__
+
+=head1 NAME
+
+SL::Form.pm - main data object.
+
+=head1 SYNOPSIS
+
+This is the main data object of Lx-Office.
+Unfortunately it also acts as a god object for certain data retrieval procedures used in the entry points.
+Points of interest for a beginner are:
+
+ - $form->error - renders a generic error in html. accepts an error message
+ - $form->get_standard_dbh - returns a database connection for the
+
+=head1 SPECIAL FUNCTIONS
+
+=over 4
+
+=item _store_value()
+
+parses a complex var name, and stores it in the form.
+
+syntax:
+ $form->_store_value($key, $value);
+
+keys must start with a string, and can contain various tokens.
+supported key structures are:
+
+1. simple access
+ simple key strings work as expected
+
+ id => $form->{id}
+
+2. hash access.
+ separating two keys by a dot (.) will result in a hash lookup for the inner value
+ this is similar to the behaviour of java and templating mechanisms.
+
+ filter.description => $form->{filter}->{description}
+
+3. array+hashref access
+
+ adding brackets ([]) before the dot will cause the next hash to be put into an array.
+ using [+] instead of [] will force a new array index. this is useful for recurring
+ data structures like part lists. put a [+] into the first varname, and use [] on the
+ following ones.
+
+ repeating these names in your template:
+
+ invoice.items[+].id
+ invoice.items[].parts_id
+
+ will result in:
+
+ $form->{invoice}->{items}->[
+ {
+ id => ...
+ parts_id => ...
+ },
+ {
+ id => ...
+ parts_id => ...
+ }
+ ...
+ ]
+
+4. arrays
+
+ using brackets at the end of a name will result in a pure array to be created.
+ note that you mustn't use [+], which is reserved for array+hash access and will
+ result in undefined behaviour in array context.
+
+ filter.status[] => $form->{status}->[ val1, val2, ... ]
+
+=item update_business PARAMS
+
+PARAMS (not named):
+ \%config, - config hashref
+ $business_id, - business id
+ $dbh - optional database handle
+
+handles business (thats customer/vendor types) sequences.
+
+special behaviour for empty strings in customerinitnumber field:
+will in this case not increase the value, and return undef.
+
+=item redirect_header $url
+
+Generates a HTTP redirection header for the new C<$url>. Constructs an
+absolute URL including scheme, host name and port. If C<$url> is a
+relative URL then it is considered relative to Lx-Office base URL.
+
+This function Cs if headers have already been created with
+C<$::form-Eheader>.
+
+Examples:
+
+ print $::form->redirect_header('oe.pl?action=edit&id=1234');
+ print $::form->redirect_header('http://www.lx-office.org/');
+
+=back
+
+=cut