X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FOE.pm;h=9adbee2eb9782443e4958461808f0aabe16865da;hb=e05d94ad1109d058352354ecd8964c91ac0da1aa;hp=2e0ac4212a40773e6b379291ca24b19db5437393;hpb=a53233e56a9d4001b47bcf412b4bfe46910d3117;p=kivitendo-erp.git diff --git a/SL/OE.pm b/SL/OE.pm index 2e0ac4212..9adbee2eb 100644 --- a/SL/OE.pm +++ b/SL/OE.pm @@ -34,11 +34,11 @@ package OE; -use List::Util qw(max); - +use List::Util qw(max first); use SL::AM; use SL::Common; use SL::DBUtils; +use SL::IC; sub transactions { $main::lxdebug->enter_sub(); @@ -83,7 +83,8 @@ sub transactions { qq|WHERE (o.quotation = ?) |; push(@values, $quotation); - my ($null, $department_id) = split /--/, $form->{department}; + my ($null, $split_department_id) = split /--/, $form->{department}; + my $department_id = $form->{department_id} || $split_department_id; if ($department_id) { $query .= qq| AND o.department_id = ?|; push(@values, $department_id); @@ -110,7 +111,7 @@ sub transactions { $query .= " AND o.employee_id = ?"; push @values, conv_i($form->{employee_id}); } - + if ($form->{salesman_id}) { $query .= " AND o.salesman_id = ?"; push @values, conv_i($form->{salesman_id}); @@ -143,12 +144,23 @@ sub transactions { push(@values, conv_date($form->{transdateto})); } + if($form->{reqdatefrom}) { + $query .= qq| AND o.reqdate >= ?|; + push(@values, conv_date($form->{reqdatefrom})); + } + + if($form->{reqdateto}) { + $query .= qq| AND o.reqdate <= ?|; + push(@values, conv_date($form->{reqdateto})); + } + if ($form->{transaction_description}) { $query .= qq| AND o.transaction_description ILIKE ?|; push(@values, '%' . $form->{transaction_description} . '%'); } - my $sortorder = join(', ', ("o.id", $form->sort_columns("transdate", $ordnumber, "name"))); + my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC'; + my $sortorder = join(', ', map { "${_} ${sortdir} " } ("o.id", $form->sort_columns("transdate", $ordnumber, "name"))); my %allowed_sort_columns = ( "transdate" => "o.transdate", "reqdate" => "o.reqdate", @@ -162,7 +174,7 @@ sub transactions { "transaction_description" => "o.transaction_description" ); if ($form->{sort} && grep($form->{sort}, keys(%allowed_sort_columns))) { - $sortorder = $allowed_sort_columns{$form->{sort}}; + $sortorder = $allowed_sort_columns{$form->{sort}} . " ${sortdir}"; } $query .= qq| ORDER by | . $sortorder; @@ -200,10 +212,13 @@ sub transactions_for_todo_list { $query = qq|SELECT oe.id, oe.transdate, oe.reqdate, oe.quonumber, oe.transaction_description, oe.amount, + CASE WHEN (COALESCE(oe.customer_id, 0) = 0) THEN 'vendor' ELSE 'customer' END AS vc, c.name AS customer, + v.name AS vendor, e.name AS employee FROM oe LEFT JOIN customer c ON (oe.customer_id = c.id) + LEFT JOIN vendor v ON (oe.vendor_id = v.id) LEFT JOIN employee e ON (oe.employee_id = e.id) WHERE (COALESCE(quotation, FALSE) = TRUE) AND (COALESCE(closed, FALSE) = FALSE) @@ -432,7 +447,7 @@ sub save { globalproject_id = ?, employee_id = ?, salesman_id = ?, cp_id = ?, transaction_description = ?, marge_total = ?, marge_percent = ? WHERE id = ?|; - @values = ($form->{ordnumber}, $form->{quonumber}, + @values = ($form->{ordnumber} || '', $form->{quonumber}, $form->{cusordnumber}, conv_date($form->{transdate}), conv_i($form->{vendor_id}), conv_i($form->{customer_id}), $amount, $netamount, conv_date($reqdate), @@ -465,6 +480,26 @@ sub save { # save printed, emailed, queued $form->save_status($dbh); + # Link this record to the records it was created from. + $form->{convert_from_oe_ids} =~ s/^\s+//; + $form->{convert_from_oe_ids} =~ s/\s+$//; + my @convert_from_oe_ids = split m/\s+/, $form->{convert_from_oe_ids}; + delete $form->{convert_from_oe_ids}; + + if (scalar @convert_from_oe_ids) { + RecordLinks->create_links('dbh' => $dbh, + 'mode' => 'ids', + 'from_table' => 'oe', + 'from_ids' => \@convert_from_oe_ids, + 'to_table' => 'oe', + 'to_id' => $form->{id}, + ); + + $self->_close_quotations_rfqs('dbh' => $dbh, + 'from_id' => \@convert_from_oe_ids, + 'to_id' => $form->{id}); + } + if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) { if ($form->{vc} eq 'customer') { $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $form->{exchangerate}, 0); @@ -487,40 +522,48 @@ sub save { return $rc; } -# this function closes multiple orders given in $form->{ordnumber_#}. -# use this for multiple orders that don't have to be saved back -# single orders should use OE::save instead. -sub close_orders { +sub _close_quotations_rfqs { $main::lxdebug->enter_sub(); - my ($self, $myconfig, $form) = @_; + my $self = shift; + my %params = @_; - # get ids from $form - map { push @ids, $form->{"ordnumber_$_"} if $form->{"ordnumber_$_"} } - (1 .. $form->{rowcount}); + Common::check_params(\%params, qw(from_id to_id)); - my $dbh = $form->dbconnect($myconfig); - $query = qq|UPDATE oe SET | . - qq|closed = TRUE | . - qq|WHERE ordnumber IN (| - . join(', ', map { $dbh->quote($_) } @ids) . qq|)|; - $dbh->do($query) || $form->dberror($query); - $dbh->disconnect; + my $myconfig = \%main::myconfig; + my $form = $main::form; - $main::lxdebug->leave_sub(); -} + my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig); -sub close_order { - $main::lxdebug->enter_sub(); + my $query = qq|SELECT quotation FROM oe WHERE id = ?|; + my $sth = prepare_query($form, $dbh, $query); - my ($self, $myconfig, $form) = @_; + do_statement($form, $sth, $query, conv_i($params{to_id})); - return $main::lxdebug->leave_sub() unless ($form->{"id"}); + my ($quotation) = $sth->fetchrow_array(); - my $dbh = $form->dbconnect($myconfig); - do_query($form, $dbh, qq|UPDATE oe SET closed = TRUE where id = ?|, - $form->{"id"}); - $dbh->disconnect; + if ($quotation) { + $main::lxdebug->leave_sub(); + return; + } + + my @close_ids; + + foreach my $from_id (@{ $params{from_id} }) { + $from_id = conv_i($from_id); + do_statement($form, $sth, $query, $from_id); + ($quotation) = $sth->fetchrow_array(); + push @close_ids, $from_id if ($quotation); + } + + $sth->finish(); + + if (scalar @close_ids) { + $query = qq|UPDATE oe SET closed = TRUE WHERE id IN (| . join(', ', ('?') x scalar @close_ids) . qq|)|; + do_query($form, $dbh, $query, @close_ids); + + $dbh->commit() unless ($params{dbh}); + } $main::lxdebug->leave_sub(); } @@ -600,13 +643,22 @@ sub retrieve { if ($form->{"multi_id_$_"} and $form->{"trans_id_$_"}) } (1 .. $form->{"rowcount"}); + if ($form->{rowcount} && scalar @ids) { + $form->{convert_from_oe_ids} = join ' ', @ids; + } + # if called in multi id mode, and still only got one id, switch back to single id if ($form->{"rowcount"} and $#ids == 0) { $form->{"id"} = $ids[0]; undef @ids; } - $query_add = qq|, current_date AS transdate, current_date AS reqdate| if (!$form->{id}); + my $query_add = ''; + if (!$form->{id}) { + my $wday = (localtime(time))[6]; + my $next_workday = $wday == 5 ? 3 : $wday == 6 ? 2 : 1; + $query_add = qq|, current_date AS transdate, date(current_date + interval '${next_workday} days') AS reqdate|; + } # get default accounts $query = qq|SELECT (SELECT c.accno FROM chart c WHERE d.inventory_accno_id = c.id) AS inventory_accno, @@ -620,7 +672,7 @@ sub retrieve { my $ref = selectfirst_hashref_query($form, $dbh, $query); map { $form->{$_} = $ref->{$_} } keys %$ref; - ($form->{currency}) = split(/:/, $form->{currencies}); + ($form->{currency}) = split(/:/, $form->{currencies}) unless ($form->{currency}); # set reqdate if this is an invoice->order conversion. If someone knows a better check to ensure # we come from invoices, feel free. @@ -649,8 +701,8 @@ sub retrieve { JOIN ${vc} cv ON (o.${vc}_id = cv.id) LEFT JOIN employee e ON (o.employee_id = e.id) LEFT JOIN department d ON (o.department_id = d.id) | . - ($form->{id} - ? "WHERE o.id = ?" + ($form->{id} + ? "WHERE o.id = ?" : "WHERE o.id IN (" . join(', ', map("? ", @ids)) . ")" ); @values = $form->{id} ? ($form->{id}) : @ids; @@ -718,7 +770,7 @@ sub retrieve { # stuff different from the whole will not be overwritten, but saved with a suffix. $query = qq|SELECT o.id AS orderitems_id, - c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid, + c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid, c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid, c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid, oe.ordnumber AS ordnumber_oe, oe.transdate AS transdate_oe, oe.cusordnumber AS cusordnumber_oe, @@ -876,7 +928,8 @@ sub order_details { push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"}); - $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS'); + $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS', + 'departments' => 'ALL_DEPARTMENTS'); my %price_factors; foreach my $pfac (@{ $form->{ALL_PRICE_FACTORS} }) { @@ -885,6 +938,13 @@ sub order_details { $pfac->{formatted_factor} = $form->format_amount($myconfig, $pfac->{factor}); } + # lookup department + foreach my $dept (@{ $form->{ALL_DEPARTMENTS} }) { + next unless $dept->{id} eq $form->{department_id}; + $form->{department} = $dept->{description}; + last; + } + # sort items by partsgroup for $i (1 .. $form->{rowcount}) { $partsgroup = ""; @@ -907,22 +967,30 @@ sub order_details { $form->{"globalprojectnumber"} = $projectnumbers{$form->{"globalproject_id"}}; + $form->{discount} = []; + + IC->prepare_parts_for_printing(); + my @arrays = qw(runningnumber number description longdescription qty ship unit bin partnotes serialnumber reqdate sellprice listprice netprice discount p_discount discount_sub nodiscount_sub linetotal nodiscount_linetotal tax_rate projectnumber - price_factor price_factor_name); + price_factor price_factor_name partsgroup); + + my @tax_arrays = qw(taxbase tax taxdescription taxrate taxnumber); + + $form->{TEMPLATE_ARRAYS} = { map { $_ => [] } (@arrays, @tax_arrays) }; my $sameitem = ""; foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) { $i = $item->[0]; if ($item->[1] ne $sameitem) { - push(@{ $form->{description} }, qq|$item->[1]|); + push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, qq|$item->[1]|); $sameitem = $item->[1]; - map({ push(@{ $form->{$_} }, "") } grep({ $_ ne "description" } @arrays)); + map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays)); } $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"}); @@ -947,37 +1015,41 @@ sub order_details { my $price_factor = $price_factors{$form->{"price_factor_id_$i"}} || { 'factor' => 1 }; - push @{ $form->{runningnumber} }, $position; - push @{ $form->{number} }, $form->{"partnumber_$i"}; - push @{ $form->{description} }, $form->{"description_$i"}; - push @{ $form->{longdescription} }, $form->{"longdescription_$i"}; - push @{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"}); - push @{ $form->{ship} }, $form->format_amount($myconfig, $form->{"ship_$i"}); - push @{ $form->{unit} }, $form->{"unit_$i"}; - push @{ $form->{bin} }, $form->{"bin_$i"}; - push @{ $form->{partnotes} }, $form->{"partnotes_$i"}; - push @{ $form->{serialnumber} }, $form->{"serialnumber_$i"}; - push @{ $form->{reqdate} }, $form->{"reqdate_$i"}; - push @{ $form->{sellprice} }, $form->{"sellprice_$i"}; - push @{ $form->{listprice} }, $form->{"listprice_$i"}; - push @{ $form->{price_factor} }, $price_factor->{formatted_factor}; - push @{ $form->{price_factor_name} }, $price_factor->{description}; + push @{ $form->{TEMPLATE_ARRAYS}->{runningnumber} }, $position; + push @{ $form->{TEMPLATE_ARRAYS}->{number} }, $form->{"partnumber_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{description} }, $form->{"description_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{longdescription} }, $form->{"longdescription_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"}); + push @{ $form->{TEMPLATE_ARRAYS}->{ship} }, $form->format_amount($myconfig, $form->{"ship_$i"}); + push @{ $form->{TEMPLATE_ARRAYS}->{unit} }, $form->{"unit_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{bin} }, $form->{"bin_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{partnotes} }, $form->{"partnotes_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{serialnumber} }, $form->{"serialnumber_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{reqdate} }, $form->{"reqdate_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{sellprice} }, $form->{"sellprice_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{listprice} }, $form->{"listprice_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{price_factor} }, $price_factor->{formatted_factor}; + push @{ $form->{TEMPLATE_ARRAYS}->{price_factor_name} }, $price_factor->{description}; + push @{ $form->{TEMPLATE_ARRAYS}->{partsgroup} }, $form->{"partsgroup_$i"}; my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"}); my ($dec) = ($sellprice =~ /\.(\d+)/); my $decimalplaces = max 2, length($dec); - my $discount = $form->round_amount($form->{"qty_$i"} * $sellprice * $form->{"discount_$i"} / 100 / $price_factor->{factor}, $decimalplaces); - my $linetotal = $form->round_amount($form->{"qty_$i"} * $sellprice * (100 - $form->{"discount_$i"}) / 100 / $price_factor->{factor}, 2); + my $parsed_discount = $form->parse_amount($myconfig, $form->{"discount_$i"}); + my $linetotal_exact = $form->{"qty_$i"} * $sellprice * (100 - $parsed_discount) / 100 / $price_factor->{factor}; + my $linetotal = $form->round_amount($linetotal_exact, 2); + my $discount = $form->round_amount($form->{"qty_$i"} * $sellprice * $parsed_discount / 100 / $price_factor->{factor} - ($linetotal - $linetotal_exact), + $decimalplaces); my $nodiscount_linetotal = $form->round_amount($form->{"qty_$i"} * $sellprice / $price_factor->{factor}, 2); $form->{"netprice_$i"} = $form->round_amount($form->{"qty_$i"} ? ($linetotal / $form->{"qty_$i"}) : 0, 2); - push @{ $form->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : ''; + push @{ $form->{TEMPLATE_ARRAYS}->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : ''; $linetotal = ($linetotal != 0) ? $linetotal : ''; - push @{ $form->{discount} }, ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, $decimalplaces) : ''; - push @{ $form->{p_discount} }, $form->{"discount_$i"}; + push @{ $form->{TEMPLATE_ARRAYS}->{discount} }, ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, 2) : ''; + push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} }, $form->{"discount_$i"}; $form->{ordtotal} += $linetotal; $form->{nodiscount_total} += $nodiscount_linetotal; @@ -989,26 +1061,26 @@ sub order_details { } if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) { - push @{ $form->{discount_sub} }, $form->format_amount($myconfig, $discount_subtotal, 2); - push @{ $form->{nodiscount_sub} }, $form->format_amount($myconfig, $nodiscount_subtotal, 2); + push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, $form->format_amount($myconfig, $discount_subtotal, 2); + push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, $form->format_amount($myconfig, $nodiscount_subtotal, 2); $discount_subtotal = 0; $nodiscount_subtotal = 0; $subtotal_header = 0; } else { - push @{ $form->{discount_sub} }, ""; - push @{ $form->{nodiscount_sub} }, ""; + push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, ""; + push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, ""; } if (!$form->{"discount_$i"}) { $nodiscount += $linetotal; } - push @{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2); - push @{ $form->{nodiscount_linetotal} }, $form->format_amount($myconfig, $nodiscount_linetotal, 2); + push @{ $form->{TEMPLATE_ARRAYS}->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2); + push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_linetotal} }, $form->format_amount($myconfig, $nodiscount_linetotal, 2); - push(@{ $form->{projectnumber} }, $projectnumbers{$form->{"project_id_$i"}}); + push(@{ $form->{TEMPLATE_ARRAYS}->{projectnumber} }, $projectnumbers{$form->{"project_id_$i"}}); my ($taxamount, $taxbase); my $taxrate = 0; @@ -1026,14 +1098,14 @@ sub order_details { } if ($taxamount != 0) { - foreach my $item (split / /, $form->{"taxaccounts_$i"}) { - $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate; - $taxbase{$item} += $taxbase; + foreach my $accno (split / /, $form->{"taxaccounts_$i"}) { + $taxaccounts{$accno} += $taxamount * $form->{"${accno}_rate"} / $taxrate; + $taxbase{$accno} += $taxbase; } } $tax_rate = $taxrate * 100; - push(@{ $form->{tax_rate} }, qq|$tax_rate|); + push(@{ $form->{TEMPLATE_ARRAYS}->{tax_rate} }, qq|$tax_rate|); if ($form->{"assembly_$i"}) { $sameitem = ""; @@ -1059,13 +1131,13 @@ sub order_details { while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) { - map({ push(@{ $form->{$_} }, "") } grep({ $_ ne "description" } @arrays)); + map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays)); $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--"; - push(@{ $form->{description} }, $sameitem); + push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $sameitem); } - push(@{ $form->{description} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq|, $ref->{partnumber}, $ref->{description}|); - map({ push(@{ $form->{$_} }, "") } grep({ $_ ne "description" } @arrays)); + push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq|, $ref->{partnumber}, $ref->{description}|); + map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays)); } $sth->finish; } @@ -1075,16 +1147,13 @@ sub order_details { my $tax = 0; foreach $item (sort keys %taxaccounts) { - push(@{ $form->{taxbase} }, - $form->format_amount($myconfig, $taxbase{$item}, 2)); - $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2); - push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2)); - push(@{ $form->{taxdescription} }, $form->{"${item}_description"} . q{ } . 100 * $form->{"${item}_rate"} . q{%}); - push(@{ $form->{taxrate} }, - $form->format_amount($myconfig, $form->{"${item}_rate"} * 100)); - push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"}); + push(@{ $form->{TEMPLATE_ARRAYS}->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2)); + push(@{ $form->{TEMPLATE_ARRAYS}->{tax} }, $form->format_amount($myconfig, $taxamount, 2)); + push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100)); + push(@{ $form->{TEMPLATE_ARRAYS}->{taxdescription} }, $form->{"${item}_description"} . q{ } . 100 * $form->{"${item}_rate"} . q{%}); + push(@{ $form->{TEMPLATE_ARRAYS}->{taxnumber} }, $form->{"${item}_taxnumber"}); } $form->{nodiscount_subtotal} = $form->format_amount($myconfig, $form->{nodiscount_total}, 2);