X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=bin%2Fmozilla%2Fio.pl;h=3d3d94c6bfbadde3080f67cd49560f545d2bd38e;hb=4ddcd46105d2a7afc41220ba51a703f9e2aef034;hp=40d31236249aac98292db49e1d1450d3e792ce88;hpb=faea2c48e131611c827519cd0939dac3e43aada6;p=kivitendo-erp.git diff --git a/bin/mozilla/io.pl b/bin/mozilla/io.pl index 40d312362..3d3d94c6b 100644 --- a/bin/mozilla/io.pl +++ b/bin/mozilla/io.pl @@ -41,8 +41,10 @@ use CGI; use List::MoreUtils qw(any uniq apply); use List::Util qw(min max first); +use SL::ClientJS; use SL::CVar; use SL::Common; +use SL::Controller::Base; use SL::CT; use SL::Locale::String qw(t8); use SL::IC; @@ -138,8 +140,10 @@ sub display_row { my $is_delivery_order = $form->{type} =~ /_delivery_order$/; my $is_quotation = $form->{type} =~ /_quotation$/; my $is_invoice = $form->{type} =~ /invoice/; + my $is_credit_note = $form->{type} =~ /credit_note/; my $is_s_p_order = (first { $_ eq $form->{type} } qw(sales_order purchase_order)); my $show_ship_missing = $is_s_p_order && $::instance_conf->get_sales_purchase_order_ship_missing_column; + my $show_marge = (!$is_purchase || $is_invoice || $is_credit_note) && !$is_delivery_order; if ($is_delivery_order) { if ($form->{type} eq 'sales_delivery_order') { @@ -154,35 +158,46 @@ sub display_row { } # column_index - my @header_sort = qw(runningnumber partnumber description ship qty unit weight sellprice discount linetotal); - my @HEADER = ( - { id => 'runningnumber', width => 5, value => $locale->text('No.'), display => 1, }, - { id => 'partnumber', width => 8, value => $locale->text('Number'), display => 1, }, - { id => 'description', width => 30, value => $locale->text('Part Description'), display => 1, }, - { id => 'ship', width => 5, value => $locale->text('Delivered'), display => $is_s_p_order, }, - { id => 'ship_missing', width => 5, value => $locale->text('Not delivered'), display => $show_ship_missing, }, - { id => 'qty', width => 5, value => $locale->text('Qty'), display => 1, }, - { id => 'price_factor', width => 5, value => $locale->text('Price Factor'), display => !$is_delivery_order, }, - { id => 'unit', width => 5, value => $locale->text('Unit'), display => 1, }, - { id => 'weight', width => 5, value => $locale->text('Weight'), display => $defaults->{show_weight}, }, - { id => 'serialnr', width => 10, value => $locale->text('Serial No.'), display => 0, }, - { id => 'projectnr', width => 10, value => $locale->text('Project'), display => 0, }, - { id => 'price_source', width => 5, value => $locale->text('Price Source'), display => !$is_delivery_order, }, - { id => 'sellprice', width => 15, value => $locale->text('Price'), display => !$is_delivery_order, }, - { id => 'discount', width => 5, value => $locale->text('Discount'), display => !$is_delivery_order, }, - { id => 'linetotal', width => 10, value => $locale->text('Extended'), display => !$is_delivery_order, }, - { id => 'bin', width => 10, value => $locale->text('Bin'), display => 0, }, - { id => 'stock_in_out', width => 10, value => $stock_in_out_title, display => $is_delivery_order, }, + my @header_sort = qw( + runningnumber partnumber description ship ship_missing qty price_factor + unit weight price_source sellprice discount linetotal + bin stock_in_out ); - my @column_index = map { $_->{id} } grep { $_->{display} } @HEADER; - + my @row2_sort = qw( + serialnr projectnr reqdate subtotal marge listprice lastcost onhand + ); + my %column_def = ( + runningnumber => { width => 5, value => $locale->text('No.'), display => 1, }, + partnumber => { width => 8, value => $locale->text('Number'), display => 1, }, + description => { width => 30, value => $locale->text('Part Description'), display => 1, }, + ship => { width => 5, value => $locale->text('Delivered'), display => $is_s_p_order, }, + ship_missing => { width => 5, value => $locale->text('Not delivered'), display => $show_ship_missing, }, + qty => { width => 5, value => $locale->text('Qty'), display => 1, }, + price_factor => { width => 5, value => $locale->text('Price Factor'), display => !$is_delivery_order, }, + unit => { width => 5, value => $locale->text('Unit'), display => 1, }, + weight => { width => 5, value => $locale->text('Weight'), display => $defaults->{show_weight}, }, + serialnr => { width => 10, value => $locale->text('Serial No.'), display => !$is_quotation }, + projectnr => { width => 10, value => $locale->text('Project'), display => 1, }, + price_source => { width => 5, value => $locale->text('Price Source'), display => !$is_delivery_order, }, + sellprice => { width => 15, value => $locale->text('Price'), display => !$is_delivery_order, }, + discount => { width => 5, value => $locale->text('Discount'), display => !$is_delivery_order, }, + linetotal => { width => 10, value => $locale->text('Extended'), display => !$is_delivery_order, }, + bin => { width => 10, value => $locale->text('Bin'), display => 0, }, + stock_in_out => { width => 10, value => $stock_in_out_title, display => $is_delivery_order, }, + reqdate => { value => $locale->text('Reqdate'), display => $is_s_p_order || $is_delivery_order || $is_invoice, }, + subtotal => { value => $locale->text('Subtotal'), display => 1, }, + marge => { value => $locale->text('Ertrag'), display => $show_marge, }, + listprice => { value => $locale->text('LP'), display => $show_marge, }, + lastcost => { value => $locale->text('EK'), display => $show_marge, }, + onhand => { value => $locale->text('On Hand'), display => 1, }, + ); + my @HEADER = map { $column_def{$_} } @header_sort; # cache units my $all_units = AM->retrieve_units(\%myconfig, $form); my %price_factors = map { $_->{id} => $_->{factor} } @{ $form->{ALL_PRICE_FACTORS} }; - my $colspan = scalar @column_index; $form->{invsubtotal} = 0; map { $form->{"${_}_base"} = 0 } (split(/ /, $form->{taxaccounts})); @@ -193,12 +208,6 @@ sub display_row { # /about details # translations, unused commented out -# $runningnumber = $locale->text('No.'); -# my $deliverydate = $locale->text('Delivery Date'); - my $serialnumber = $locale->text('Serial No.'); - my $projectnumber = $locale->text('Project'); -# $partsgroup = $locale->text('Group'); - my $reqdate = $locale->text('Reqdate'); my $deliverydate = $locale->text('Required by'); # special alignings @@ -336,7 +345,7 @@ sub display_row { if ($form->{"id_${i}"} && !$is_delivery_order) { my $price_source = SL::PriceSource->new(record_item => $record_item, record => $record); my $price = $price_source->price_from_source($::form->{"active_price_source_$i"}); - my $discount = $price_source->price_from_source($::form->{"active_discount_source_$i"}); + my $discount = $price_source->discount_from_source($::form->{"active_discount_source_$i"}); my $best_price = $price_source->best_price; my $best_discount = $price_source->best_discount; $column_data{price_source} .= $cgi->button(-value => $price->source_description, -onClick => "kivi.io.price_chooser($i)"); @@ -344,8 +353,8 @@ sub display_row { $column_data{price_source} .= ' ' . $cgi->img({src => 'image/flag-red.png', alt => $price->invalid, title => $price->invalid }) if $price->invalid; $column_data{price_source} .= ' ' . $cgi->img({src => 'image/flag-red.png', alt => $price->missing, title => $price->missing }) if $price->missing; if (!$price->missing && !$price->invalid) { - $column_data{price_source} .= ' ' . $cgi->img({src => 'image/up.png', alt => t8('This price has since gone up'), title => t8('This price has since gone up' ) }) if $price->price > $record_item->sellprice; - $column_data{price_source} .= ' ' . $cgi->img({src => 'image/down.png', alt => t8('This price has since gone down'), title => t8('This price has since gone down') }) if $price->price < $record_item->sellprice; + $column_data{price_source} .= ' ' . $cgi->img({src => 'image/up.png', alt => t8('This price has since gone up'), title => t8('This price has since gone up' ) }) if $price->price - $record_item->sellprice > 0.01; + $column_data{price_source} .= ' ' . $cgi->img({src => 'image/down.png', alt => t8('This price has since gone down'), title => t8('This price has since gone down') }) if $price->price - $record_item->sellprice < -0.01; $column_data{price_source} .= ' ' . $cgi->img({src => 'image/ok.png', alt => t8('There is a better price available'), title => t8('There is a better price available') }) if $best_price && $price->source ne $price_source->best_price->source; } } @@ -353,8 +362,8 @@ sub display_row { $column_data{discount_source} .= ' ' . $cgi->img({src => 'image/flag-red.png', alt => $discount->invalid, title => $discount->invalid }) if $discount->invalid; $column_data{discount_source} .= ' ' . $cgi->img({src => 'image/flag-red.png', alt => $discount->missing, title => $discount->missing }) if $discount->missing; if (!$discount->missing && !$discount->invalid) { - $column_data{price_source} .= ' ' . $cgi->img({src => 'image/up.png', alt => t8('This discount has since gone up'), title => t8('This discount has since gone up') }) if $discount->discount * 100 > $record_item->discount; - $column_data{price_source} .= ' ' . $cgi->img({src => 'image/down.png', alt => t8('This discount has since gone down'), title => t8('This discount has since gone down') }) if $discount->discount * 100 < $record_item->discount; + $column_data{price_source} .= ' ' . $cgi->img({src => 'image/up.png', alt => t8('This discount has since gone up'), title => t8('This discount has since gone up') }) if $discount->discount * 100 - $record_item->discount > 0.01; + $column_data{price_source} .= ' ' . $cgi->img({src => 'image/down.png', alt => t8('This discount has since gone down'), title => t8('This discount has since gone down') }) if $discount->discount * 100 - $record_item->discount < -0.01; $column_data{price_source} .= ' ' . $cgi->img({src => 'image/ok.png', alt => t8('There is a better discount available'), title => t8('There is a better discount available') }) if $best_discount && $discount->source ne $price_source->best_discount->source; } } @@ -364,18 +373,15 @@ sub display_row { $column_data{stock_in_out} = calculate_stock_in_out($i); } - my @ROW1 = map { value => $column_data{$_}, align => $align{$_}, nowrap => $nowrap{$_} }, @column_index; - - # second row - my @ROW2 = (); - push @ROW2, { value => qq|$serialnumber | } - if $form->{type} !~ /_quotation/; - push @ROW2, { value => qq|$projectnumber | . NTI($cgi->popup_menu('-name' => "project_id_$i", '-values' => \@projectnumber_values, - '-labels' => \%projectnumber_labels, '-default' => $form->{"project_id_$i"})) }; - push @ROW2, { value => qq|$reqdate | } - if ($form->{type} =~ /order/ || $form->{type} =~ /invoice/); - push @ROW2, { value => sprintf qq|%s |, - $locale->text('Subtotal'), $form->{"subtotal_$i"} ? 'checked' : '' }; + $column_data{serialnr} = qq||; + $column_data{projectnr} = NTI($cgi->popup_menu( + '-name' => "project_id_$i", + '-values' => \@projectnumber_values, + '-labels' => \%projectnumber_labels, + '-default' => $form->{"project_id_$i"} + )); + $column_data{reqdate} = qq||; + $column_data{subtotal} = sprintf qq||, $form->{"subtotal_$i"} ? 'checked' : ''; # begin marge calculations $form->{"lastcost_$i"} *= 1; @@ -411,17 +417,10 @@ sub display_row { map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) } qw(marge_absolut marge_percent); - push @ROW2, { value => sprintf qq| - %s %s  %s%% -  %s %s -  %s |, - $marge_color, $locale->text('Ertrag'),$form->{"marge_absolut_$i"}, $form->{"marge_percent_$i"}, - $locale->text('LP'), $form->format_amount(\%myconfig, $form->{"listprice_$i"}, 2), - $locale->text('EK'), $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces) } - if $form->{"id_$i"} && ($form->{type} =~ /^sales_/ || $form->{type} =~ /invoice/ || $form->{type} =~ /^credit_note$/ ) && !$is_delivery_order; - - $form->{"listprice_$i"} = $form->format_amount(\%myconfig, $form->{"listprice_$i"}, 2) - if $form->{"id_$i"} && ($form->{type} =~ /^sales_/ || $form->{type} =~ /invoice/) ; + $column_data{marge} = sprintf qq|%s  %s%%|, + $marge_color, $form->{"marge_absolut_$i"}, $form->{"marge_percent_$i"}; + $column_data{listprice} = $form->format_amount(\%myconfig, $form->{"listprice_$i"}, 2); + $column_data{lastcost} = sprintf qq||, $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces); # / marge calculations ending # Calculate total weight @@ -431,15 +430,16 @@ sub display_row { if ($form->{"id_$i"}) { my $part = IC->get_basic_part_info(id => $form->{"id_$i"}); my $onhand_color = $part->{onhand} < $part->{rop} ? 'color="#ff0000"' : ''; - push @ROW2, { value => sprintf "%s %s %s", - $locale->text('On Hand'), + $column_data{onhand} = sprintf "%s %s", $onhand_color, $form->format_amount(\%myconfig, $part->{onhand}, 2), - $part->{unit} - }; + $part->{unit}; } # / calculate onhand + my @ROW1 = map { { value => $column_data{$_}, align => $align{$_}, nowrap => $nowrap{$_} } } grep { $column_def{$_}{display} } @header_sort; + my @ROW2 = map { { value => sprintf "%s %s", $column_def{$_}{value}, $column_data{$_} } } grep { $column_def{$_}{display} } @row2_sort; + my @hidden_vars; # add hidden ids for persistent (item|invoice)_ids and previous (converted_from*) ids if ($is_quotation) { @@ -477,6 +477,7 @@ sub display_row { # Benutzerdefinierte Variablen für Waren/Dienstleistungen/Erzeugnisse _render_custom_variables_inputs(ROW2 => \@ROW2, row => $i, part_id => $form->{"id_$i"}); + my $colspan = scalar @ROW1; push @ROWS, { ROW1 => \@ROW1, ROW2 => \@ROW2, HIDDENS => \@HIDDENS, colspan => $colspan, error => $form->{"row_error_$i"}, obj => $record_item }; } @@ -497,8 +498,8 @@ sub select_item { $main::lxdebug->enter_sub(); my %params = @_; - my $mode = $params{mode} || croak "Missing parameter 'mode'"; - + my $mode = $params{mode} || croak "Missing parameter 'mode'"; + my $pre_entered_qty = $params{pre_entered_qty} || 1; _check_io_auth(); my $previous_form = $::auth->save_form_in_session(form => $::form); @@ -506,18 +507,21 @@ sub select_item { $::form->header; my @item_list = map { - $_->{display_sellprice} /= $_->{price_factor} if ($_->{price_factor}); + # maybe there is a better backend function or way to calc + $_->{display_sellprice} = ($_->{price_factor}) ? $_->{sellprice} / $_->{price_factor} : $_->{sellprice}; $_; } @{ $::form->{item_list} }; # delete action variable delete @{$::form}{qw(action item_list)}; - print $::form->parse_html_template('io/select_item', { PREVIOUS_FORM => $previous_form, - MODE => $mode, - ITEM_LIST => \@item_list, - IS_ASSEMBLY => $mode eq 'IC', - IS_PURCHASE => $mode eq 'IS' }); + print $::form->parse_html_template('io/select_item', { PREVIOUS_FORM => $previous_form, + MODE => $mode, + ITEM_LIST => \@item_list, + IS_ASSEMBLY => $mode eq 'IC', + IS_PURCHASE => $mode eq 'IS', + SHOW_NOTES => $::instance_conf->get_show_longdescription_select_item(), + PRE_ENTERED_QTY => $pre_entered_qty, }); $main::lxdebug->leave_sub(); } @@ -536,117 +540,142 @@ sub item_selected { $::auth->restore_form_from_session($form->{select_item_previous_form} || croak('Missing previous form ID'), form => $form); - my $mode = delete($form->{select_item_mode}) || croak 'Missing item selection mode'; - my $id = delete($form->{select_item_id}) || croak 'Missing item selection ID'; - my $i = $form->{ $mode eq 'IC' ? 'assembly_rows' : 'rowcount' }; + my $mode = delete($form->{select_item_mode}) || croak 'Missing item selection mode'; + my $row_key = $mode eq 'IC' ? 'assembly_rows' : 'rowcount'; + my $curr_row = $form->{ $row_key }; - if ( $mode eq 'IC' ) { - # assembly mode: - # the qty variables of the existing assembly items are all still formatted, so we parse them here (1 .. $i-1) - # including the qty of the just added part ($i) - $form->{"qty_$_"} = $form->parse_amount(\%myconfig, $form->{"qty_$_"}) for (1 .. $i); - }; + my $row = $curr_row; + + if ($myconfig{item_multiselect}) { + foreach (grep(/^select_qty_/, keys(%{ $form }))) { + next unless $form->{$_}; + $_ =~ /^select_qty_(\d+)/; + $form->{"id_${row}"} = $1; + $form->{"qty_${row}"} = $form->{$_}; + $row++; + } + } else { + $form->{"id_${row}"} = delete($form->{select_item_id}) || croak 'Missing item selection ID'; + $row++; + } - $form->{"id_${i}"} = $id; + map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } + qw(sellprice weight); - if ($mode eq 'IS') { - IS->retrieve_item(\%myconfig, \%$form); - } elsif ($mode eq 'IR') { - IR->retrieve_item(\%myconfig, \%$form); - } elsif ($mode eq 'IC') { - IC->assembly_item(\%myconfig, \%$form); + if ( $mode eq 'IC' ) { + # assembly mode: + # the qty variables of the existing assembly items are all still formatted, so we parse them here + # including the qty of the just added part + $form->{"qty_$_"} = $form->parse_amount(\%myconfig, $form->{"qty_$_"}) for (1 .. $row - 1); } else { - croak "Invalid item selection mode '${mode}'"; + if ($myconfig{item_multiselect}) { + # other modes and multiselection: + # parse all newly entered qtys + $form->{"qty_$_"} = $form->parse_amount(\%myconfig, $form->{"qty_$_"}) for ($curr_row .. $row - 1); + } } - my $new_item = $form->{item_list}->[0] || croak "No item found for mode '${mode}' and ID '${id}'"; + for my $i ($curr_row .. $row - 1) { + $form->{ $row_key } = $i; - # if there was a price entered, override it - my $sellprice; - unless ( $mode eq 'IC' ) { - $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"}); - }; + my $id = $form->{"id_${i}"}; - my @new_fields = - qw(id partnumber description sellprice listprice inventory_accno - income_accno expense_accno bin unit weight assembly taxaccounts - partsgroup formel longdescription not_discountable partnotes lastcost - price_factor_id price_factor); + delete $form->{item_list}; - my $ic_cvar_configs = CVar->get_configs(module => 'IC'); - push @new_fields, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs }; + if ($mode eq 'IS') { + IS->retrieve_item(\%myconfig, \%$form); + } elsif ($mode eq 'IR') { + IR->retrieve_item(\%myconfig, \%$form); + } elsif ($mode eq 'IC') { + IC->assembly_item(\%myconfig, \%$form); + } else { + croak "Invalid item selection mode '${mode}'"; + } + + my $new_item = $form->{item_list}->[0] || croak "No item found for mode '${mode}' and ID '${id}'"; - map { $form->{"${_}_$i"} = $new_item->{$_} } @new_fields; + # if there was a price entered, override it + my $sellprice; + unless ( $mode eq 'IC' ) { + $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"}); + }; - if (my $record = _make_record()) { - my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record); - my $best_price = $price_source->best_price; + my @new_fields = + qw(id partnumber description sellprice listprice inventory_accno + income_accno expense_accno bin unit weight assembly taxaccounts + partsgroup formel longdescription not_discountable partnotes lastcost + price_factor_id price_factor); - if ($best_price) { - $::form->{"sellprice_$i"} = $best_price->price; - $::form->{"active_price_source_$i"} = $best_price->source; - } + my $ic_cvar_configs = CVar->get_configs(module => 'IC'); + push @new_fields, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs }; + + map { $form->{"${_}_$i"} = $new_item->{$_} } @new_fields; + + if (my $record = _make_record()) { + my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record); + my $best_price = $price_source->best_price; - my $best_discount = $price_source->best_discount; + if ($best_price) { + $::form->{"sellprice_$i"} = $best_price->price; + $::form->{"active_price_source_$i"} = $best_price->source; + } + + my $best_discount = $price_source->best_discount; - if ($best_discount) { - $::form->{"discount_$i"} = $best_discount->discount; - $::form->{"active_discount_source_$i"} = $best_discount->source; + if ($best_discount) { + $::form->{"discount_$i"} = $best_discount->discount; + $::form->{"active_discount_source_$i"} = $best_discount->source; + } } - } - $form->{"marge_price_factor_$i"} = $new_item->{price_factor}; + $form->{"marge_price_factor_$i"} = $new_item->{price_factor}; - if ($form->{"part_payment_id_$i"} ne "") { - $form->{payment_id} = $form->{"part_payment_id_$i"}; - } + if ($form->{"part_payment_id_$i"} ne "") { + $form->{payment_id} = $form->{"part_payment_id_$i"}; + } - my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); - $dec = length $dec; - my $decimalplaces = ($dec > 2) ? $dec : 2; + my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/); + $dec = length $dec; + my $decimalplaces = ($dec > 2) ? $dec : 2; - if ($sellprice) { - $form->{"sellprice_$i"} = $sellprice; - } else { + if ($sellprice) { + $form->{"sellprice_$i"} = $sellprice; + } else { - # if there is an exchange rate adjust sellprice - if (($form->{exchangerate} * 1) != 0) { - $form->{"sellprice_$i"} /= $form->{exchangerate}; - $form->{"sellprice_$i"} = - $form->round_amount($form->{"sellprice_$i"}, $decimalplaces); + # if there is an exchange rate adjust sellprice + if (($form->{exchangerate} * 1) != 0) { + $form->{"sellprice_$i"} /= $form->{exchangerate}; + $form->{"sellprice_$i"} = + $form->round_amount($form->{"sellprice_$i"}, $decimalplaces); + } } - } - map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } - qw(sellprice listprice weight); + # at this stage qty of newly added part needs to be have been parsed + $form->{weight} += ($form->{"weight_$i"} * $form->{"qty_$i"}); - # at this stage qty of newly added part needs to be have been parsed - $form->{weight} += ($form->{"weight_$i"} * $form->{"qty_$i"}); + if ($form->{"not_discountable_$i"}) { + $form->{"discount_$i"} = 0; + } - if ($form->{"not_discountable_$i"}) { - $form->{"discount_$i"} = 0; - } + my $amount = + $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"}) * $form->{"qty_$i"}; + map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"}); + map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded}; - my $amount = - $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * - $form->{"qty_$i"}; - map { $form->{"${_}_base"} += $amount } - (split / /, $form->{"taxaccounts_$i"}); - map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, - $form->{"taxaccounts_$i"} - if !$form->{taxincluded}; + $form->{creditremaining} -= $amount; - $form->{creditremaining} -= $amount; + $form->{"runningnumber_$i"} = $i; - $form->{"runningnumber_$i"} = $i; + # format amounts + map { + $form->{"${_}_$i"} = + $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) + } qw(sellprice lastcost qty) if $form->{item} ne 'assembly'; + $form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100.0) if $form->{item} ne 'assembly'; - delete $form->{nextsub}; + delete $form->{nextsub}; - # format amounts - map { - $form->{"${_}_$i"} = - $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) - } qw(sellprice listprice lastcost) if $form->{item} ne 'assembly'; + } &display_form; @@ -702,7 +731,7 @@ sub check_form { #$form->{sellprice} = 0; $form->{weight} = 0; map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } - qw(listprice sellprice rop stock); + qw(sellprice rop stock); my @flds = qw(id qty unit bom partnumber description sellprice weight runningnumber partsgroup lastcost); @@ -735,15 +764,6 @@ sub check_form { $form->{creditremaining} -= &invoicetotal; } - #sk - # if pricegroups - if ( $form->{type} =~ (/sales_quotation/) - or (($form->{level} =~ /Sales/) and ($form->{type} =~ /invoice/)) - or (($form->{level} eq undef) and ($form->{type} =~ /invoice/)) - or ($form->{type} =~ /sales_order/)) { - - } - &display_form; $main::lxdebug->leave_sub(); @@ -893,7 +913,7 @@ sub order { my $script = $form->{"script"}; $script =~ s|.*/||; $script =~ s|.pl$||; - $locale = new Locale($::lx_office_conf{system}->{language}, $script); + $locale = Locale->new($::lx_office_conf{system}->{language}, $script); map { $form->{"select$_"} = "" } ($form->{vc}, "currency"); @@ -908,7 +928,7 @@ sub order { for my $i (1 .. $form->{rowcount}) { map({ $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if ($form->{"${_}_${i}"}) } - qw(ship qty sellprice listprice basefactor discount)); + qw(ship qty sellprice basefactor discount)); $form->{"converted_from_invoice_id_$i"} = delete $form->{"invoice_id_$i"}; } @@ -976,7 +996,7 @@ sub quotation { map({ $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if ($form->{"${_}_${i}"}) } - qw(ship qty sellprice listprice basefactor discount lastcost)); + qw(ship qty sellprice basefactor discount lastcost)); } &prepare_order; @@ -1180,6 +1200,7 @@ sub print_options { my %dont_display_groupitems = ( 'dunning' => 1, + 'letter' => 1, ); my %template_vars = ( @@ -1222,7 +1243,7 @@ sub print { $form->error($locale->text('Select postscript or PDF!')) if ($form->{format} !~ /(postscript|pdf)/); - $old_form = new Form; + $old_form = Form->new; map { $old_form->{$_} = $form->{$_} } keys %$form; } @@ -1359,7 +1380,7 @@ sub print_form { } $form->{TEMPLATE_DRIVER_OPTIONS} = { }; - if (any { $form->{type} eq $_ } qw(sales_quotation sales_order sales_delivery_order invoice request_quotation purchase_order purchase_delivery_order)) { + if (any { $form->{type} eq $_ } qw(sales_quotation sales_order sales_delivery_order invoice request_quotation purchase_order purchase_delivery_order credit_note)) { $form->{TEMPLATE_DRIVER_OPTIONS}->{variable_content_types} = { longdescription => 'html', partnotes => 'html', @@ -1476,11 +1497,13 @@ sub print_form { format_dates($output_dateformat, $output_longdates, qw(invdate orddate quodate pldate duedate reqdate transdate shippingdate deliverydate validitydate paymentdate - datepaid transdate_oe deliverydate_oe dodate + datepaid transdate_oe transdate_do transdate_quo deliverydate_oe dodate employee_startdate employee_enddate ), grep({ /^datepaid_\d+$/ || /^transdate_oe_\d+$/ || + /^transdate_do_\d+$/ || + /^transdate_quo_\d+$/ || /^deliverydate_oe_\d+$/ || /^reqdate_\d+$/ || /^deliverydate_\d+$/ || @@ -1780,20 +1803,35 @@ sub relink_accounts { $main::lxdebug->leave_sub(); } -sub set_duedate { - $main::lxdebug->enter_sub(); +sub get_payment_terms_for_invoice { + my $terms = $::form->{payment_id} ? SL::DB::PaymentTerm->new(id => $::form->{payment_id}) ->load + : $::form->{customer_id} ? SL::DB::Customer ->new(id => $::form->{customer_id})->load->payment + : $::form->{vendor_id} ? SL::DB::Vendor ->new(id => $::form->{vendor_id}) ->load->payment + : undef; - my $form = $main::form; - my %myconfig = %main::myconfig; + return $terms; +} +sub set_duedate { _check_io_auth(); - my $invdate = $form->{invdate} eq 'undefined' ? undef : $form->{invdate}; - my $duedate = $form->get_duedate(\%myconfig, $invdate); + my $js = SL::ClientJS->new(controller => SL::Controller::Base->new); + my $terms = get_payment_terms_for_invoice(); + my $invdate = $::form->{invdate} eq 'undefined' ? DateTime->today_local : DateTime->from_kivitendo($::form->{invdate}); + my $duedate = $terms ? $terms->calc_date(reference_date => $invdate, due_date => $::form->{duedate})->to_kivitendo : ($::form->{duedate} || $invdate->to_kivitendo); - print $form->ajax_response_header() . ($duedate || $invdate); + if ($terms && $terms->auto_calculation) { + $js->hide('#duedate_container') + ->show('#duedate_fixed') + ->html('#duedate_fixed', $duedate); - $main::lxdebug->leave_sub(); + } else { + $js->show('#duedate_container') + ->hide('#duedate_fixed'); + } + + $js->val('#duedate', $duedate) + ->render; } sub _update_part_information { @@ -1801,8 +1839,7 @@ sub _update_part_information { my $form = $main::form; - my %part_information = IC->get_basic_part_info('id' => [ grep { $_ } map { $form->{"id_${_}"} } (1..$form->{rowcount}) ], - 'vendor_id' => $form->{vendor_id}); + my %part_information = IC->get_basic_part_info('id' => [ grep { $_ } map { $form->{"id_${_}"} } (1..$form->{rowcount}) ]); $form->{PART_INFORMATION} = \%part_information; @@ -2009,15 +2046,18 @@ sub _make_record_item { : $class->new; for my $method (apply { s/_$row$// } grep { /_$row$/ } keys %$::form) { - next unless $obj->meta->column($method); - if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) { - $obj->${\"$method\_as_date"}($::form->{"$method\_$row"}); - } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) { - $obj->${\"$method\_as_number"}($::form->{"$method\_$row"}); - } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) { - $obj->$method(!!$::form->{$method}); + if ($obj->meta->column($method)) { + if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) { + $obj->${\"$method\_as_date"}($::form->{"$method\_$row"}); + } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) { + $obj->${\"$method\_as_number"}($::form->{"$method\_$row"}); + } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) { + $obj->$method(!!$::form->{$method}); + } else { + $obj->$method($::form->{"$method\_$row"}); + } } else { - $obj->$method($::form->{"$method\_$row"}); + $obj->{__additional_form_attributes}{$method} = $::form->{"$method\_$row"}; } }