use SL::User;
use Template;
use List::Util qw(first max min sum);
+use List::MoreUtils qw(any);
my $standard_dbh;
}
}
+=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, ... ]
+
+=cut
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);
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;
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;
}
}
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});
}
}
}
+ $main::lxdebug->leave_sub();
}
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)) {
+ if ($self->{INPUT_ENCODING} && (lc $self->{INPUT_ENCODING} ne $db_charset)) {
require Text::Iconv;
- my $iconv = Text::Iconv->new($parameters->{INPUT_ENCODING}, $db_charset);
+ 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.0";
$main::lxdebug->leave_sub();
}
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 (@_) {
print($main::cgi->hidden("-name" => $_, "-default" => $self->{$_}) . "\n");
}
}
-
+ $main::lxdebug->leave_sub();
}
sub error {
$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" ) ;
};
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"};
}
sub get_formname_translation {
+ $main::lxdebug->enter_sub();
my ($self, $formname) = @_;
$formname ||= $self->{formname};
purchase_delivery_order => $main::locale->text('Delivery Order'),
);
+ $main::lxdebug->leave_sub();
return $formname_translations{$formname}
}
sub get_number_prefix_for_type {
+ $main::lxdebug->enter_sub();
my ($self) = @_;
my $prefix =
: ($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} =~ /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());
$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());
$subject .= " " . $self->{"${prefix}number"}
}
+ $main::lxdebug->leave_sub();
return $subject;
}
sub get_duedate {
$main::lxdebug->enter_sub();
- my ($self, $myconfig) = @_;
+ my ($self, $myconfig, $reference_date) = @_;
- my $dbh = $self->get_standard_dbh($myconfig);
- my $query = qq|SELECT current_date + terms_netto FROM payment_terms WHERE id = ?|;
- ($self->{duedate}) = selectrow_query($self, $dbh, $query, $self->{payment_id});
+ my $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});
$main::lxdebug->leave_sub();
+
+ return $duedate;
}
sub _get_contacts {
(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});
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);
return $var;
}
+=item update_business
+
+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.
+
+=cut
sub update_business {
$main::lxdebug->enter_sub();
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);
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();
}
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();
}