X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FForm.pm;h=b5af00359285ac5f83435f49150732875c3e7bc5;hb=4e0bef2d1ee1fa29e3fa85a97f34e707fe4e287d;hp=c59669c41a77a075a8fe873f3e84b2783edbeaee;hpb=7915128cc09f9756439ab9216a82ada3870893c3;p=kivitendo-erp.git diff --git a/SL/Form.pm b/SL/Form.pm index c59669c41..b5af00359 100644 --- a/SL/Form.pm +++ b/SL/Form.pm @@ -75,6 +75,7 @@ use SL::PrefixedNumber; use SL::Request; use SL::Template; use SL::User; +use SL::Util; use SL::X; use Template; use URI; @@ -469,7 +470,7 @@ sub header { # standard css for all # this should gradually move to the layouts that need it $layout->use_stylesheet("$_.css") for qw( - main menu common list_accounts jquery.autocomplete + common main menu list_accounts jquery.autocomplete jquery.multiselect2side ui-lightness/jquery-ui jquery-ui.custom @@ -480,7 +481,7 @@ sub header { jquery jquery-ui jquery.cookie jquery.checkall jquery.download jquery/jquery.form jquery/fixes client_js jquery/jquery.tooltipster.min - common part_selection switchmenuframe + common part_selection ), "jquery/ui/i18n/jquery.ui.datepicker-$::myconfig{countrycode}"); $self->{favicon} ||= "favicon.ico"; @@ -585,17 +586,6 @@ sub set_standard_title { $::lxdebug->leave_sub; } -sub prepare_global_vars { - my ($self) = @_; - - $self->{AUTH} = $::auth; - $self->{INSTANCE_CONF} = $::instance_conf; - $self->{LOCALE} = $::locale; - $self->{LXCONFIG} = $::lx_office_conf; - $self->{LXDEBUG} = $::lxdebug; - $self->{MYCONFIG} = \%::myconfig; -} - sub _prepare_html_template { $main::lxdebug->enter_sub(); @@ -618,39 +608,15 @@ sub _prepare_html_template { my $info = "Web page template '${file}' not found.\n"; $::form->header; print qq|
$info
|; - ::end_of_request(); - } - - if ($self->{"DEBUG"}) { - $additional_params->{"DEBUG"} = $self->{"DEBUG"}; - } - - if ($additional_params->{"DEBUG"}) { - $additional_params->{"DEBUG"} = - "
DEBUG INFORMATION:
" . $additional_params->{"DEBUG"} . "
"; - } - - if (%main::myconfig) { - $::myconfig{jsc_dateformat} = apply { - s/d+/\%d/gi; - s/m+/\%m/gi; - s/y+/\%Y/gi; - } $::myconfig{"dateformat"}; - $additional_params->{"myconfig"} ||= \%::myconfig; - map { $additional_params->{"myconfig_${_}"} = $main::myconfig{$_}; } keys %::myconfig; + $::dispatcher->end_request; } + $additional_params->{AUTH} = $::auth; $additional_params->{INSTANCE_CONF} = $::instance_conf; - - if (my $debug_options = $::lx_office_conf{debug}{options}) { - map { $additional_params->{'DEBUG_' . uc($_)} = $debug_options->{$_} } keys %$debug_options; - } - - if ($main::auth && $main::auth->{RIGHTS} && $main::auth->{RIGHTS}->{$self->{login}}) { - while (my ($key, $value) = each %{ $main::auth->{RIGHTS}->{$self->{login}} }) { - $additional_params->{"AUTH_RIGHTS_" . uc($key)} = $value; - } - } + $additional_params->{LOCALE} = $::locale; + $additional_params->{LXCONFIG} = \%::lx_office_conf; + $additional_params->{LXDEBUG} = $::lxdebug; + $additional_params->{MYCONFIG} = \%::myconfig; $main::lxdebug->leave_sub(); @@ -719,7 +685,7 @@ sub show_generic_error { SL::ClientJS->new ->error($error) ->render(SL::Controller::Base->new); - ::end_of_request(); + $::dispatcher->end_request; } my $add_params = { @@ -750,7 +716,7 @@ sub show_generic_error { $main::lxdebug->leave_sub(); - ::end_of_request(); + $::dispatcher->end_request; } sub show_generic_information { @@ -770,7 +736,7 @@ sub show_generic_information { $main::lxdebug->leave_sub(); - ::end_of_request(); + $::dispatcher->end_request; } sub _store_redirect_info_in_session { @@ -796,7 +762,7 @@ sub redirect { print $::form->redirect_header($self->{callback}); } - ::end_of_request(); + $::dispatcher->end_request; $main::lxdebug->leave_sub(); } @@ -839,7 +805,7 @@ sub format_amount { if ($places || $p[1]) { $amount .= $d[0] . ( $p[1] || '' ) - . (0 x (abs($places || 0) - length ($p[1]||''))); # pad the fraction + . (0 x max(abs($places || 0) - length ($p[1]||''), 0)); # pad the fraction } $amount = do { @@ -971,10 +937,17 @@ sub parse_amount { } sub round_amount { - my ($self, $amount, $places) = @_; + my ($self, $amount, $places, $adjust) = @_; return 0 if !defined $amount; + $places //= 0; + + if ($adjust) { + my $precision = $::instance_conf->get_precision || 0.01; + return $self->round_amount( $self->round_amount($amount / $precision, 0) * $precision, $places); + } + # We use Perl's knowledge of string representation for # rounding. First, convert the floating point number to a string # with a high number of places. Then split the string on the decimal @@ -1259,7 +1232,8 @@ sub get_formname_translation { sales_delivery_order => $main::locale->text('Delivery Order'), purchase_delivery_order => $main::locale->text('Delivery Order'), dunning => $main::locale->text('Dunning'), - letter => $main::locale->text('Letter') + letter => $main::locale->text('Letter'), + ic_supply => $main::locale->text('Intra-Community supply'), ); $main::lxdebug->leave_sub(); @@ -1723,16 +1697,17 @@ sub get_default_currency { } sub set_payment_options { - my ($self, $myconfig, $transdate) = @_; + my ($self, $myconfig, $transdate, $type) = @_; my $terms = $self->{payment_id} ? SL::DB::PaymentTerm->new(id => $self->{payment_id})->load : undef; return if !$terms; + my $is_invoice = $type =~ m{invoice}i; + $transdate ||= $self->{invdate} || $self->{transdate}; my $due_date = $self->{duedate} || $self->{reqdate}; $self->{$_} = $terms->$_ for qw(terms_netto terms_skonto percent_skonto); - $self->{payment_terms} = $terms->description_long; $self->{payment_description} = $terms->description; $self->{netto_date} = $terms->calc_date(reference_date => $transdate, due_date => $due_date, terms => 'net')->to_kivitendo; $self->{skonto_date} = $terms->calc_date(reference_date => $transdate, due_date => $due_date, terms => 'discount')->to_kivitendo; @@ -1765,39 +1740,26 @@ sub set_payment_options { } if ($self->{"language_id"}) { - my $dbh = $self->get_standard_dbh($myconfig); - my $query = - qq|SELECT t.translation, l.output_numberformat, l.output_dateformat, l.output_longdates | . - qq|FROM generic_translations t | . - qq|LEFT JOIN language l ON t.language_id = l.id | . - qq|WHERE (t.language_id = ?) - AND (t.translation_id = ?) - AND (t.translation_type = 'SL::DB::PaymentTerm/description_long')|; - my ($description_long, $output_numberformat, $output_dateformat, - $output_longdates) = - selectrow_query($self, $dbh, $query, - $self->{"language_id"}, $self->{"payment_id"}); - - $self->{payment_terms} = $description_long if ($description_long); - - if ($output_dateformat) { + my $language = SL::DB::Language->new(id => $self->{language_id})->load; + + $self->{payment_terms} = $type =~ m{invoice}i ? $terms->translated_attribute('description_long_invoice', $language->id) : undef; + $self->{payment_terms} ||= $terms->translated_attribute('description_long', $language->id); + + if ($language->output_dateformat) { foreach my $key (qw(netto_date skonto_date)) { - $self->{$key} = - $main::locale->reformat_date($myconfig, $self->{$key}, - $output_dateformat, - $output_longdates); + $self->{$key} = $::locale->reformat_date($myconfig, $self->{$key}, $language->output_dateformat, $language->output_longdates); } } - if ($output_numberformat && - ($output_numberformat ne $myconfig->{"numberformat"})) { - my $saved_numberformat = $myconfig->{"numberformat"}; - $myconfig->{"numberformat"} = $output_numberformat; - map { $formatted_amounts{$_} = $self->format_amount($myconfig, $amounts{$_}) } keys %amounts; - $myconfig->{"numberformat"} = $saved_numberformat; + if ($language->output_numberformat && ($language->output_numberformat ne $myconfig->{numberformat})) { + local $myconfig->{numberformat}; + $myconfig->{"numberformat"} = $language->output_numberformat; + $formatted_amounts{$_} = $self->format_amount($myconfig, $amounts{$_}) for keys %amounts; } } + $self->{payment_terms} = $self->{payment_terms} || ($is_invoice ? $terms->description_long_invoice : undef) || $terms->description_long; + $self->{payment_terms} =~ s/<%netto_date%>/$self->{netto_date}/g; $self->{payment_terms} =~ s/<%skonto_date%>/$self->{skonto_date}/g; $self->{payment_terms} =~ s/<%currency%>/$self->{currency}/g; @@ -1864,20 +1826,25 @@ sub get_shipto { my $query = qq|SELECT * FROM shipto WHERE shipto_id = ?|; my $ref = selectfirst_hashref_query($self, $dbh, $query, $self->{shipto_id}); map({ $self->{$_} = $ref->{$_} } keys(%$ref)); + + my $cvars = CVar->get_custom_variables( + dbh => $dbh, + module => 'ShipTo', + trans_id => $self->{shipto_id}, + ); + $self->{"shiptocvar_$_->{name}"} = $_->{value} for @{ $cvars }; } $main::lxdebug->leave_sub(); } sub add_shipto { - $main::lxdebug->enter_sub(); - my ($self, $dbh, $id, $module) = @_; my $shipto; my @values; - foreach my $item (qw(name department_1 department_2 street zipcode city country + foreach my $item (qw(name department_1 department_2 street zipcode city country gln contact cp_gender phone fax email)) { if ($self->{"shipto$item"}) { $shipto = 1 if ($self->{$item} ne $self->{"shipto$item"}); @@ -1885,52 +1852,68 @@ sub add_shipto { push(@values, $self->{"shipto${item}"}); } - if ($shipto) { - if ($self->{shipto_id}) { - my $query = qq|UPDATE shipto set - shiptoname = ?, - shiptodepartment_1 = ?, - shiptodepartment_2 = ?, - shiptostreet = ?, - shiptozipcode = ?, - shiptocity = ?, - shiptocountry = ?, - shiptocontact = ?, - shiptocp_gender = ?, - shiptophone = ?, - shiptofax = ?, - shiptoemail = ? - WHERE shipto_id = ?|; - do_query($self, $dbh, $query, @values, $self->{shipto_id}); - } else { - my $query = qq|SELECT * FROM shipto - WHERE shiptoname = ? AND - shiptodepartment_1 = ? AND - shiptodepartment_2 = ? AND - shiptostreet = ? AND - shiptozipcode = ? AND - shiptocity = ? AND - shiptocountry = ? AND - shiptocontact = ? AND - shiptocp_gender = ? AND - shiptophone = ? AND - shiptofax = ? AND - shiptoemail = ? AND - module = ? AND - trans_id = ?|; - my $insert_check = selectfirst_hashref_query($self, $dbh, $query, @values, $module, $id); - if(!$insert_check){ - $query = - qq|INSERT INTO shipto (trans_id, shiptoname, shiptodepartment_1, shiptodepartment_2, - shiptostreet, shiptozipcode, shiptocity, shiptocountry, - shiptocontact, shiptocp_gender, shiptophone, shiptofax, shiptoemail, module) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|; - do_query($self, $dbh, $query, $id, @values, $module); - } + return if !$shipto; + + my $shipto_id = $self->{shipto_id}; + + if ($self->{shipto_id}) { + my $query = qq|UPDATE shipto set + shiptoname = ?, + shiptodepartment_1 = ?, + shiptodepartment_2 = ?, + shiptostreet = ?, + shiptozipcode = ?, + shiptocity = ?, + shiptocountry = ?, + shiptogln = ?, + shiptocontact = ?, + shiptocp_gender = ?, + shiptophone = ?, + shiptofax = ?, + shiptoemail = ? + WHERE shipto_id = ?|; + do_query($self, $dbh, $query, @values, $self->{shipto_id}); + } else { + my $query = qq|SELECT * FROM shipto + WHERE shiptoname = ? AND + shiptodepartment_1 = ? AND + shiptodepartment_2 = ? AND + shiptostreet = ? AND + shiptozipcode = ? AND + shiptocity = ? AND + shiptocountry = ? AND + shiptogln = ? AND + shiptocontact = ? AND + shiptocp_gender = ? AND + shiptophone = ? AND + shiptofax = ? AND + shiptoemail = ? AND + module = ? AND + trans_id = ?|; + my $insert_check = selectfirst_hashref_query($self, $dbh, $query, @values, $module, $id); + if(!$insert_check){ + my $insert_query = + qq|INSERT INTO shipto (trans_id, shiptoname, shiptodepartment_1, shiptodepartment_2, + shiptostreet, shiptozipcode, shiptocity, shiptocountry, shiptogln, + shiptocontact, shiptocp_gender, shiptophone, shiptofax, shiptoemail, module) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|; + do_query($self, $dbh, $insert_query, $id, @values, $module); + + $insert_check = selectfirst_hashref_query($self, $dbh, $query, @values, $module, $id); } + + $shipto_id = $insert_check->{shipto_id}; } - $main::lxdebug->leave_sub(); + return unless $shipto_id; + + CVar->save_custom_variables( + dbh => $dbh, + module => 'ShipTo', + trans_id => $shipto_id, + variables => $self, + name_prefix => 'shipto', + ); } sub get_employee { @@ -2504,10 +2487,10 @@ sub get_name { my $where; if ($self->{customernumber} ne "") { $where = qq|(vc.customernumber ILIKE ?)|; - push(@values, '%' . $self->{customernumber} . '%'); + push(@values, like($self->{customernumber})); } else { $where = qq|(vc.name ILIKE ?)|; - push(@values, '%' . $self->{$table} . '%'); + push(@values, like($self->{$table})); } $query = @@ -2524,7 +2507,7 @@ sub get_name { JOIN $table vc ON (a.${table}_id = vc.id) WHERE NOT (a.amount = a.paid) AND (vc.name ILIKE ?) ORDER BY vc.name~; - push(@values, '%' . $self->{$table} . '%'); + push(@values, like($self->{$table})); } $self->{name_list} = selectall_hashref_query($self, $dbh, $query, @values); @@ -2607,6 +2590,19 @@ sub all_vc { $main::lxdebug->leave_sub(); } +sub new_lastmtime { + my ($self, $table, $option) = @_; + + return unless $self->{id}; + croak ("wrong call, no valid table defined") unless $table =~ /^(oe|ar|ap|delivery_orders|parts)$/; + + my $query = "SELECT mtime, itime FROM " . $table . " WHERE id = ?"; + my $ref = selectfirst_hashref_query($self, $self->get_standard_dbh, $query, $self->{id}); + $ref->{mtime} ||= $ref->{itime}; + $self->{lastmtime} = $ref->{mtime}; + $main::lxdebug->message(LXDebug->DEBUG2(),"new lastmtime=".$self->{lastmtime}); +} + sub mtime_ischanged { my ($self, $table, $option) = @_; @@ -2622,7 +2618,7 @@ sub mtime_ischanged { t8("The document has been changed by another user. No mail was sent. Please reopen it in another window and copy the changes to the new window") : t8("The document has been changed by another user. Please reopen it in another window and copy the changes to the new window") ); - ::end_of_request(); + $::dispatcher->end_request; } } @@ -2736,7 +2732,7 @@ sub create_links { $sth = $dbh->prepare($query); - do_statement($self, $sth, $query, '%' . $module . '%'); + do_statement($self, $sth, $query, like($module)); $self->{accounts} = ""; while ($ref = $sth->fetchrow_hashref("NAME_lc")) { @@ -2811,7 +2807,7 @@ sub create_links { ORDER BY c.accno|; $sth = $dbh->prepare($query); - do_statement($self, $sth, $query, "%$module%"); + do_statement($self, $sth, $query, like($module)); $self->{accounts} = ""; while ($ref = $sth->fetchrow_hashref("NAME_lc")) { @@ -2878,7 +2874,9 @@ sub create_links { d.closedto, d.revtrans, (SELECT cu.name FROM currencies cu WHERE cu.id=d.currency_id) AS defaultcurrency, (SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno, - (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno + (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno, + (SELECT c.accno FROM chart c WHERE d.rndgain_accno_id = c.id) AS rndgain_accno, + (SELECT c.accno FROM chart c WHERE d.rndloss_accno_id = c.id) AS rndloss_accno FROM defaults d|; $ref = selectfirst_hashref_query($self, $dbh, $query); map { $self->{$_} = $ref->{$_} } keys %$ref; @@ -2891,7 +2889,9 @@ sub create_links { current_date AS transdate, d.closedto, d.revtrans, (SELECT cu.name FROM currencies cu WHERE cu.id=d.currency_id) AS defaultcurrency, (SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno, - (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno + (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno, + (SELECT c.accno FROM chart c WHERE d.rndgain_accno_id = c.id) AS rndgain_accno, + (SELECT c.accno FROM chart c WHERE d.rndloss_accno_id = c.id) AS rndloss_accno FROM defaults d|; $ref = selectfirst_hashref_query($self, $dbh, $query); map { $self->{$_} = $ref->{$_} } keys %$ref; @@ -2998,22 +2998,6 @@ sub current_date { return $thisdate; } -sub like { - $main::lxdebug->enter_sub(); - - my ($self, $string) = @_; - - if ($string !~ /%/) { - $string = "%$string%"; - } - - $string =~ s/\'/\'\'/g; - - $main::lxdebug->leave_sub(); - - return $string; -} - sub redo_rows { $main::lxdebug->enter_sub(); @@ -3382,10 +3366,17 @@ sub prepare_for_printing { $self->{"employee_${_}"} = $defaults->$_ for qw(address businessnumber co_ustid company duns sepa_creditor_id taxnumber); } - # Load shipping address from database if shipto_id is set. - if ($self->{shipto_id}) { - my $shipto = SL::DB::Shipto->new(shipto_id => $self->{shipto_id})->load; + # Load shipping address from database. If shipto_id is set then it's + # one from the customer's/vendor's master data. Otherwise look an a + # customized address linking back to the current record. + my $shipto_module = $self->{type} =~ /_delivery_order$/ ? 'DO' + : $self->{type} =~ /sales_order|sales_quotation|request_quotation|purchase_order/ ? 'OE' + : 'AR'; + my $shipto = $self->{shipto_id} ? SL::DB::Shipto->new(shipto_id => $self->{shipto_id})->load + : SL::DB::Manager::Shipto->get_first(where => [ module => $shipto_module, trans_id => $self->{id} ]); + if ($shipto) { $self->{$_} = $shipto->$_ for grep { m{^shipto} } map { $_->name } @{ $shipto->meta->columns }; + $self->{"shiptocvar_" . $_->config->name} = $_->value_as_text for @{ $shipto->cvars_by_config }; } my $language = $self->{language} ? '_' . $self->{language} : ''; @@ -3671,11 +3662,12 @@ sub calculate_tax { my ($self,$amount,$taxrate,$taxincluded,$roundplaces) = @_; - $roundplaces = 2 unless defined $roundplaces; + $roundplaces //= 2; + $taxincluded //= 0; my $tax; - if ($taxincluded *= 1) { + if ($taxincluded) { # calculate tax (unrounded), subtract from amount, round amount and round tax $tax = $amount - ($amount / ($taxrate + 1)); # equivalent to: taxrate * amount / (taxrate + 1) $amount = $self->round_amount($amount - $tax, $roundplaces);