X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;ds=sidebyside;f=bin%2Fmozilla%2Fio.pl;h=6826833d758dcb2be26d683a471c732cd52cc8fc;hb=6768ddad54d2a675939e1167536f4943628de2bb;hp=365afab02e59e37e7e29e70b77193f2297170d41;hpb=e3b47235028494b18ced5e94f44c270b835bcd8f;p=kivitendo-erp.git
diff --git a/bin/mozilla/io.pl b/bin/mozilla/io.pl
index 365afab02..6826833d7 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;
@@ -55,7 +57,7 @@ use SL::DB::Language;
use SL::DB::Printer;
use SL::DB::Vendor;
use SL::Helper::CreatePDF;
-use SL::Helper::Flash;
+use SL::Helper::Flash qw(flash);
require "bin/mozilla/common.pl";
@@ -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
@@ -310,7 +319,8 @@ sub display_row {
$ship_qty *= $all_units->{$form->{"partunit_$i"}}->{factor};
$ship_qty /= ( $all_units->{$form->{"unit_$i"}}->{factor} || 1 );
- $column_data{ship} = $form->format_amount(\%myconfig, $form->round_amount($ship_qty, 2) * 1) . ' ' . $form->{"unit_$i"};
+ $column_data{ship} = $form->format_amount(\%myconfig, $form->round_amount($ship_qty, 2) * 1) . ' ' . $form->{"unit_$i"}
+ . $cgi->hidden(-name => "ship_$i", -value => $form->format_amount(\%myconfig, $form->{"ship_$i"}, $qty_dec));
my $ship_missing_qty = $form->{"qty_$i"} - $ship_qty;
my $ship_missing_amount = $form->round_amount($ship_missing_qty * $form->{"sellprice_$i"} * (100 - $form->{"discount_$i"}) / 100 / $price_factor, 2);
@@ -336,7 +346,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 +354,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 +363,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 +374,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 +418,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 +431,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 +478,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 };
}
@@ -502,11 +504,14 @@ sub select_item {
_check_io_auth();
my $previous_form = $::auth->save_form_in_session(form => $::form);
- $::form->{title} = $::locale->text('Select from one of the items below');
+ $::form->{title} = $::myconfig{item_multiselect} ?
+ $::locale->text('Set count for one or more of the items to select them'):
+ $::locale->text('Select from one of the items below');
$::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} };
@@ -557,7 +562,7 @@ sub item_selected {
}
map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
- qw(sellprice listprice weight);
+ qw(sellprice weight);
if ( $mode eq 'IC' ) {
# assembly mode:
@@ -579,101 +584,98 @@ sub item_selected {
delete $form->{item_list};
- 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}'";
- }
+ 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}'";
+ my $new_item = $form->{item_list}->[0] || croak "No item found for mode '${mode}' and ID '${id}'";
- # if there was a price entered, override it
- my $sellprice;
- unless ( $mode eq 'IC' ) {
- $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
- };
+ # if there was a price entered, override it
+ my $sellprice;
+ unless ( $mode eq 'IC' ) {
+ $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$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);
+ 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);
- my $ic_cvar_configs = CVar->get_configs(module => 'IC');
- push @new_fields, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
+ 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;
+ 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;
+ 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;
- if ($best_price) {
- $::form->{"sellprice_$i"} = $best_price->price;
- $::form->{"active_price_source_$i"} = $best_price->source;
- }
+ if ($best_price) {
+ $::form->{"sellprice_$i"} = $best_price->price;
+ $::form->{"active_price_source_$i"} = $best_price->source;
+ }
- my $best_discount = $price_source->best_discount;
+ 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);
+ }
}
- }
- # 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"} / 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};
+ 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};
- $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 listprice lastcost qty) if $form->{item} ne 'assembly';
+ # 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};
}
@@ -731,7 +733,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);
@@ -764,15 +766,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();
@@ -867,7 +860,7 @@ sub validate_items {
if ($form->{rowcount} == 1) {
flash('warning', $::locale->text('The action you\'ve chosen has not been executed because the document does not contain any item yet.'));
&update;
- ::end_of_request();
+ $::dispatcher->end_request;
}
for my $i (1 .. $form->{rowcount} - 1) {
@@ -895,10 +888,22 @@ sub order {
$form->{old_employee_id} = $form->{employee_id};
$form->{old_salesman_id} = $form->{salesman_id};
- # link doc invoice -> quotation (single id no multi mode)
- $form->{convert_from_ar_ids} = delete $form->{id};
-
delete $form->{$_} foreach (qw(printed emailed queued));
+
+ # When creating a new sales order from a saved sales invoice, reset id,
+ # ordnumber, transdate and deliverydate as we are creating a new order. This
+ # workflow is probably mainly used as a template mechanism for creating new
+ # orders from existing invoices, so we probably don't want to link the items.
+ # Is this order function called anywhere else?
+ # The worksflows in oe already call sales_order and purchase_order in oe, not
+ # this general function which now only seems to be called from saved sales
+ # invoices
+ # Why is ordnumber set to invnumber above, does this ever make sense?
+
+ if ( $form->{script} eq 'is.pl' && $form->{type} eq 'invoice' ) {
+ delete $form->{$_} foreach (qw(ordnumber id transdate deliverydate));
+ };
+
my $buysell;
if ($form->{script} eq 'ir.pl' || $form->{type} eq 'request_quotation') {
$form->{title} = $locale->text('Add Purchase Order');
@@ -922,7 +927,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");
@@ -937,7 +942,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"};
}
@@ -961,9 +966,6 @@ sub quotation {
if ($form->{type} =~ /(sales|purchase)_order/) {
$form->{"converted_from_orderitems_id_$_"} = delete $form->{"orderitems_id_$_"} for 1 .. $form->{"rowcount"};
}
- # link doc order -> quotation (single id no multi mode)
- $form->{convert_from_oe_ids} = delete $form->{id};
-
if ($form->{second_run}) {
$form->{print_and_post} = 0;
}
@@ -1005,7 +1007,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;
@@ -1066,6 +1068,7 @@ sub edit_e_mail {
a_filename => $attachment_filename,
subject => $subject,
print_options => print_options('inline' => 1),
+ action => 'send_email',
HIDDEN => [ map +{ name => $_, value => $form->{$_} }, @hidden_keys ],
SHOW_BCC => $::auth->assert('email_bcc', 'may fail') });
@@ -1093,144 +1096,32 @@ sub send_email {
$main::lxdebug->leave_sub();
}
-# generate the printing options displayed at the bottom of oe and is forms.
-# this function will attempt to guess what type of form is displayed, and will generate according options
-#
-# about the coding:
-# this version builds the arrays of options pretty directly. if you have trouble understanding how,
-# the opthash function builds hashrefs which are then pieced together for the template arrays.
-# unneeded options are "undef"ed out, and then grepped out.
-#
-# the inline options is untested, but intended to be used later in metatemplating
sub print_options {
- $main::lxdebug->enter_sub();
+ $::lxdebug->enter_sub();
- my $form = $main::form;
- my %myconfig = %main::myconfig;
- my $locale = $main::locale;
+ my (%options) = @_;
_check_io_auth();
- my %options = @_;
-
- # names 3 parameters and returns a hashref, for use in templates
- sub opthash { +{ value => shift, selected => shift, oname => shift } }
- my (@FORMNAME, @LANGUAGE_ID, @FORMAT, @SENDMODE, @MEDIA, @PRINTER_ID, @SELECTS) = ();
-
- # note: "||"-selection is only correct for values where "0" is _not_ a correct entry
- $form->{sendmode} = "attachment";
- $form->{format} = $form->{format} || $myconfig{template_format} || "pdf";
- $form->{copies} = $form->{copies} || $myconfig{copies} || 3;
- $form->{media} = $form->{media} || $myconfig{default_media} || "screen";
- $form->{printer_id} = defined $form->{printer_id} ? $form->{printer_id} :
- defined $myconfig{default_printer_id} ? $myconfig{default_printer_id} : "";
-
- $form->{PD}{ $form->{formname} } = "selected";
- $form->{DF}{ $form->{format} } = "selected";
- $form->{OP}{ $form->{media} } = "selected";
- $form->{SM}{ $form->{formname} } = "selected";
-
- push @FORMNAME, grep $_,
- ($form->{type} eq 'purchase_order') ? (
- opthash("purchase_order", $form->{PD}{purchase_order}, $locale->text('Purchase Order')),
- opthash("bin_list", $form->{PD}{bin_list}, $locale->text('Bin List'))
- ) : undef,
- ($form->{type} eq 'credit_note') ?
- opthash("credit_note", $form->{PD}{credit_note}, $locale->text('Credit Note')) : undef,
- ($form->{type} eq 'sales_order') ? (
- opthash("sales_order", $form->{PD}{sales_order}, $locale->text('Confirmation')),
- opthash("proforma", $form->{PD}{proforma}, $locale->text('Proforma Invoice')),
- ) : undef,
- ($form->{type} =~ /sales_quotation$/) ?
- opthash('sales_quotation', $form->{PD}{sales_quotation}, $locale->text('Quotation')) : undef,
- ($form->{type} =~ /request_quotation$/) ?
- opthash('request_quotation', $form->{PD}{request_quotation}, $locale->text('Request for Quotation')) : undef,
- ($form->{type} eq 'invoice') ? (
- opthash("invoice", $form->{PD}{invoice}, $locale->text('Invoice')),
- opthash("proforma", $form->{PD}{proforma}, $locale->text('Proforma Invoice')),
- ) : undef,
- ($form->{type} eq 'invoice' && $form->{storno}) ? (
- opthash("storno_invoice", $form->{PD}{storno_invoice}, $locale->text('Storno Invoice')),
- ) : undef,
- ($form->{type} =~ /_delivery_order$/) ? (
- opthash($form->{type}, $form->{PD}{$form->{type}}, $locale->text('Delivery Order')),
- opthash('pick_list', $form->{PD}{pick_list}, $locale->text('Pick List')),
- ) : undef;
-
- push @SENDMODE,
- opthash("attachment", $form->{SM}{attachment}, $locale->text('Attachment')),
- opthash("inline", $form->{SM}{inline}, $locale->text('In-line'))
- if ($form->{media} eq 'email');
-
- my $printable_templates = any { $::lx_office_conf{print_templates}->{$_} } qw(latex opendocument);
- push @MEDIA, grep $_,
- opthash("screen", $form->{OP}{screen}, $locale->text('Screen')),
- ($printable_templates && $form->{printers} && scalar @{ $form->{printers} }) ?
- opthash("printer", $form->{OP}{printer}, $locale->text('Printer')) : undef,
- ($printable_templates && !$options{no_queue}) ?
- opthash("queue", $form->{OP}{queue}, $locale->text('Queue')) : undef
- if ($form->{media} ne 'email');
-
- push @FORMAT, grep $_,
- ($::lx_office_conf{print_templates}->{opendocument} && $::lx_office_conf{applications}->{openofficeorg_writer} && $::lx_office_conf{applications}->{xvfb}
- && (-x $::lx_office_conf{applications}->{openofficeorg_writer}) && (-x $::lx_office_conf{applications}->{xvfb})
- && !$options{no_opendocument_pdf}) ?
- opthash("opendocument_pdf", $form->{DF}{"opendocument_pdf"}, $locale->text("PDF (OpenDocument/OASIS)")) : undef,
- ($::lx_office_conf{print_templates}->{latex}) ?
- opthash("pdf", $form->{DF}{pdf}, $locale->text('PDF')) : undef,
- ($::lx_office_conf{print_templates}->{latex} && !$options{no_postscript}) ?
- opthash("postscript", $form->{DF}{postscript}, $locale->text('Postscript')) : undef,
- (!$options{no_html}) ?
- opthash("html", $form->{DF}{html}, "HTML") : undef,
- ($::lx_office_conf{print_templates}->{opendocument} && !$options{no_opendocument}) ?
- opthash("opendocument", $form->{DF}{opendocument}, $locale->text("OpenDocument/OASIS")) : undef,
- ($::lx_office_conf{print_templates}->{excel} && !$options{no_excel}) ?
- opthash("excel", $form->{DF}{excel}, $locale->text("Excel")) : undef;
-
- push @LANGUAGE_ID,
- map { opthash($_->{id}, ($_->{id} eq $form->{language_id} ? 'selected' : ''), $_->{description}) } +{}, @{ $form->{languages} }
- if (ref $form->{languages} eq 'ARRAY');
-
- push @PRINTER_ID,
- map { opthash($_->{id}, ($_->{id} eq $form->{printer_id} ? 'selected' : ''), $_->{printer_description}) } +{}, @{ $form->{printers} }
- if ((ref $form->{printers} eq 'ARRAY') && scalar @{ $form->{printers } });
-
- @SELECTS = map {
- sname => $_->[1],
- DATA => $_->[0],
- show => !$options{"hide_" . $_->[1]} && scalar @{ $_->[0] }
- },
- [ \@FORMNAME, 'formname', ],
- [ \@LANGUAGE_ID, 'language_id', ],
- [ \@FORMAT, 'format', ],
- [ \@SENDMODE, 'sendmode', ],
- [ \@MEDIA, 'media', ],
- [ \@PRINTER_ID, 'printer_id', ];
-
- my %dont_display_groupitems = (
- 'dunning' => 1,
- );
-
- my %template_vars = (
- display_copies => scalar @{ $form->{printers} || [] } && $::lx_office_conf{print_templates}->{latex} && $form->{media} ne 'email',
- display_remove_draft => (!$form->{id} && $form->{draft_id}),
- display_groupitems => !$dont_display_groupitems{$form->{type}},
- groupitems_checked => $form->{groupitems} ? "checked" : '',
- remove_draft_checked => $form->{remove_draft} ? "checked" : ''
- );
+ my $inline = delete $options{inline};
- my $print_options = $form->parse_html_template("generic/print_options", { SELECTS => \@SELECTS, %template_vars } );
+ require SL::Helper::PrintOptions;
+ my $print_options = SL::Helper::PrintOptions->get_print_options(
+ form => $::form,
+ myconfig => \%::myconfig,
+ locale => $::locale,
+ options => \%options);
- if ($options{inline}) {
- $main::lxdebug->leave_sub();
+ if ($inline) {
+ $::lxdebug->leave_sub();
return $print_options;
}
print $print_options;
-
- $main::lxdebug->leave_sub();
+ $::lxdebug->leave_sub();
}
+
sub print {
$main::lxdebug->enter_sub();
@@ -1251,7 +1142,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;
}
@@ -1265,7 +1156,7 @@ sub print {
$form->{formname} = $formname;
&edit();
$::lxdebug->leave_sub();
- ::end_of_request();
+ $::dispatcher->end_request;
}
&print_form($old_form);
@@ -1365,6 +1256,17 @@ sub print_form {
$order = 1;
}
+ if (($form->{type} eq 'sales_order') && ($form->{formname} eq 'ic_supply') ) {
+ $inv = "inv";
+ $due = "due";
+ $form->{"${inv}date"} = $form->{transdate};
+ $form->{"invdate"} = $form->{transdate};
+ $form->{invnumber} = $form->{ordnumber};
+ $form->{label} = $locale->text('Intra-Community supply');
+ $numberfld = "sonumber";
+ $order = 1;
+ }
+
if ($form->{formname} eq 'request_quotation') {
$inv = "quo";
$due = "req";
@@ -1505,11 +1407,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+$/ ||
@@ -1696,7 +1600,7 @@ sub print_form {
}
call_sub($display_form);
- ::end_of_request();
+ $::dispatcher->end_request;
}
my $msg =
@@ -1710,7 +1614,7 @@ sub print_form {
}
if ($form->{printing}) {
call_sub($display_form);
- ::end_of_request();
+ $::dispatcher->end_request;
}
$main::lxdebug->leave_sub();
@@ -1763,22 +1667,25 @@ sub ship_to {
map { $::form->{$_} = $::form->parse_amount(\%::myconfig, $::form->{$_}) } qw(exchangerate creditlimit creditremaining);
# get details for customer/vendor
- call_sub($::form->{vc} . "_details", qw(name department_1 department_2 street zipcode city country contact email phone fax), $::form->{vc} . "number");
-
+ call_sub($::form->{vc} . "_details", qw(name department_1 department_2 street zipcode city country gln contact email phone fax), $::form->{vc} . "number");
$::form->{rowcount}--;
- my @shipto_vars = qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry
+ my $cvars = SL::DB::Shipto->new->cvars_by_config;
+ my @shipto_vars = qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry shiptogln
shiptocontact shiptocp_gender shiptophone shiptofax shiptoemail
shiptodepartment_1 shiptodepartment_2);
- my $previous_form = $::auth->save_form_in_session(skip_keys => [ @shipto_vars, qw(header shipto_id) ]);
+ my $previous_form = $::auth->save_form_in_session(skip_keys => [ @shipto_vars, qw(header shipto_id), map { "shiptocvar_" . $_->config->name } @{ $cvars } ]);
$::form->{title} = $::locale->text('Ship to');
$::form->header;
my $vc_obj = ($::form->{vc} eq 'customer' ? "SL::DB::Customer" : "SL::DB::Vendor")->new(id => $::form->{$::form->{vc} . "_id"})->load;
+ $_->value($::form->{"shiptocvar_" . $_->config->name}) for @{ $cvars };
+
print $::form->parse_html_template('io/ship_to', { previousform => $previous_form,
nextsub => $::form->{display_form} || 'display_form',
vc_obj => $vc_obj,
+ cvars => $cvars,
});
$main::lxdebug->leave_sub();
@@ -1809,20 +1716,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 {
@@ -1830,8 +1752,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;
@@ -1860,36 +1781,21 @@ sub _update_ship {
my $all_units = AM->retrieve_all_units();
- my %ship = DO->get_shipped_qty('type' => ($form->{type} eq 'purchase_order') ? 'purchase' : 'sales',
- 'oe_id' => $form->{id},);
+ my %ship = DO->get_shipped_qty('oe_id' => $form->{id});
foreach my $i (1..$form->{rowcount}) {
next unless ($form->{"id_${i}"});
$form->{"ship_$i"} = 0;
- my $ship_entry = $ship{$form->{"id_$i"}};
-
- next if (!$ship_entry || ($ship_entry->{qty} <= 0));
+ my $ship_entry = $ship{$i};
- my $rowqty =
- ($form->{simple_save} ? $form->{"qty_$i"} : $form->parse_amount(\%myconfig, $form->{"qty_$i"}))
- * $all_units->{$form->{"unit_$i"}}->{factor}
- / $all_units->{$form->{"partunit_$i"}}->{factor};
+ next if (!$ship_entry || ($ship_entry->{qty_ordered} <= 0));
- $form->{"ship_$i"} = min($rowqty, $ship_entry->{qty});
- $ship_entry->{qty} -= $form->{"ship_$i"};
- }
-
- foreach my $i (1..$form->{rowcount}) {
- next unless ($form->{"id_${i}"});
-
- my $ship_entry = $ship{$form->{"id_$i"}};
-
- next if (!$ship_entry || ($ship_entry->{qty} <= 0.01));
-
- $form->{"ship_$i"} += $ship_entry->{qty};
- $ship_entry->{qty} = 0;
+ my $rowqty = $ship_entry->{qty_ordered} - $ship_entry->{qty_notdelivered};
+ $rowqty *= $all_units->{$form->{"unit_$i"}}->{factor} /
+ $all_units->{$form->{"partunit_$i"}}->{factor} if !$form->{simple_save};
+ $form->{"ship_$i"} = $rowqty;
}
$main::lxdebug->leave_sub();
@@ -2038,15 +1944,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"};
}
}
@@ -2058,6 +1967,7 @@ sub _make_record_item {
}
sub _make_record {
+ Form::disconnect_standard_dbh;
my $class = {
sales_order => 'Order',
purchase_order => 'Order',