Projekt

Allgemein

Profil

Herunterladen (55,7 KB) Statistiken
| Zweig: | Markierung: | Revision:
626e0240 Stephan Köhler
#====================================================================
d319704a Moritz Bunkus
# LX-Office ERP
# Copyright (C) 2004
# Based on SQL-Ledger Version 2.1.9
# Web http://www.lx-office.org
#
#=====================================================================
# SQL-Ledger Accounting
# Copyright (C) 1999-2003
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
# Contributors:
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#======================================================================
#
# Order entry module
# Quotation
#======================================================================

package OE;

0a6affab Sven Schöling
use List::Util qw(max first);
92331b8e Moritz Bunkus
use YAML;

54e4131e Moritz Bunkus
use SL::AM;
8e206587 Moritz Bunkus
use SL::Common;
ef220490 Moritz Bunkus
use SL::CVar;
3b9c2119 Moritz Bunkus
use SL::DB::Order;
92331b8e Moritz Bunkus
use SL::DB::PeriodicInvoicesConfig;
3b9c2119 Moritz Bunkus
use SL::DB::Status;
e90048c8 Bernd Bleßmann
use SL::DB::Tax;
8a996479 Moritz Bunkus
use SL::DBUtils;
5f6d6d4e Moritz Bunkus
use SL::HTML::Restrict;
47c3bf62 Moritz Bunkus
use SL::IC;
aff32344 Moritz Bunkus
use SL::TransNumber;
54e4131e Moritz Bunkus
c510d88b Sven Schöling
use strict;

d319704a Moritz Bunkus
sub transactions {
$main::lxdebug->enter_sub();

my ($self, $myconfig, $form) = @_;

# connect to database
76a25c8c Sven Schöling
my $dbh = $form->get_standard_dbh;
d319704a Moritz Bunkus
my $query;
my $ordnumber = 'ordnumber';
my $quotation = '0';

72eaa1a7 Moritz Bunkus
my @values;
9d0ebf28 Moritz Bunkus
my $where;

92331b8e Moritz Bunkus
my ($periodic_invoices_columns, $periodic_invoices_joins);

9d0ebf28 Moritz Bunkus
my $rate = ($form->{vc} eq 'customer') ? 'buy' : 'sell';

if ($form->{type} =~ /_quotation$/) {
$quotation = '1';
$ordnumber = 'quonumber';
92331b8e Moritz Bunkus
} elsif ($form->{type} eq 'sales_order') {
$periodic_invoices_columns = qq| , COALESCE(pcfg.active, 'f') AS periodic_invoices |;
$periodic_invoices_joins = qq| LEFT JOIN periodic_invoices_configs pcfg ON (o.id = pcfg.oe_id) |;
9d0ebf28 Moritz Bunkus
}

my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";

50133d13 Sven Schöling
my %billed_amount;
my %billed_netamount;
if ($form->{l_remaining_amount} || $form->{l_remaining_netamount}) {
$query = <<'';
SELECT from_id, ar.amount, ar.netamount FROM (
SELECT from_id, to_id
FROM record_links
WHERE from_table = 'oe' AND to_table = 'ar'
UNION
SELECT rl1.from_id, rl2.to_id
FROM record_links rl1
LEFT JOIN record_links rl2 ON (rl1.to_table = rl2.from_table AND rl1.to_id = rl2.from_id)
WHERE rl1.from_table = 'oe' AND rl2.to_table = 'ar'
) rl
LEFT JOIN ar ON ar.id = rl.to_id

for my $ref (@{ selectall_hashref_query($form, $dbh, $query) }) {
$billed_amount{ $ref->{from_id}} += $ref->{amount};
$billed_netamount{$ref->{from_id}} += $ref->{netamount};
}
}

9d0ebf28 Moritz Bunkus
$query =
qq|SELECT o.id, o.ordnumber, o.transdate, o.reqdate, | .
7d026c7c Niclas Zimmermann
qq| o.amount, ct.${vc}number, ct.name, o.netamount, o.${vc}_id, o.globalproject_id, | .
b96c67e5 Moritz Bunkus
qq| o.closed, o.delivered, o.quonumber, o.cusordnumber, o.shippingpoint, o.shipvia, | .
ce3ce404 Moritz Bunkus
qq| o.transaction_description, | .
4d8a6515 Philip Reetz
qq| o.marge_total, o.marge_percent, | .
9d0ebf28 Moritz Bunkus
qq| ex.$rate AS exchangerate, | .
qq| pr.projectnumber AS globalprojectnumber, | .
15bcb411 Sven Schöling
qq| e.name AS employee, s.name AS salesman, | .
3fcf64fc Bernd Bleßmann
qq| ct.${vc}number AS vcnumber, ct.country, ct.ustid, ct.business_id, | .
qq| tz.description AS taxzone | .
92331b8e Moritz Bunkus
$periodic_invoices_columns .
3da73190 Moritz Bunkus
qq| , o.order_probability, o.expected_billing_date, (o.netamount * o.order_probability / 100) AS expected_netamount | .
9d0ebf28 Moritz Bunkus
qq|FROM oe o | .
qq|JOIN $vc ct ON (o.${vc}_id = ct.id) | .
qq|LEFT JOIN employee e ON (o.employee_id = e.id) | .
4a19c3d4 Udo Spallek
qq|LEFT JOIN employee s ON (o.salesman_id = s.id) | .
a4d74009 Niclas Zimmermann
qq|LEFT JOIN exchangerate ex ON (ex.currency_id = o.currency_id | .
9d0ebf28 Moritz Bunkus
qq| AND ex.transdate = o.transdate) | .
qq|LEFT JOIN project pr ON (o.globalproject_id = pr.id) | .
3fcf64fc Bernd Bleßmann
qq|LEFT JOIN tax_zones tz ON (o.taxzone_id = tz.id) | .
92331b8e Moritz Bunkus
qq|$periodic_invoices_joins | .
9d0ebf28 Moritz Bunkus
qq|WHERE (o.quotation = ?) |;
push(@values, $quotation);

df005c49 Sven Schöling
my ($null, $split_department_id) = split /--/, $form->{department};
my $department_id = $form->{department_id} || $split_department_id;
9d0ebf28 Moritz Bunkus
if ($department_id) {
$query .= qq| AND o.department_id = ?|;
push(@values, $department_id);
}
72eaa1a7 Moritz Bunkus
if ($form->{"project_id"}) {
9d0ebf28 Moritz Bunkus
$query .=
72eaa1a7 Moritz Bunkus
qq|AND ((globalproject_id = ?) OR EXISTS | .
qq| (SELECT * FROM orderitems oi | .
qq| WHERE oi.project_id = ? AND oi.trans_id = o.id))|;
777d9b30 Sven Schöling
push(@values, conv_i($form->{"project_id"}), conv_i($form->{"project_id"}));
}

if ($form->{"projectnumber"}) {
$query .= <<SQL;
7e47ffd0 Bernd Bleßmann
AND ((pr.projectnumber ILIKE ?) OR EXISTS (
777d9b30 Sven Schöling
SELECT * FROM orderitems oi
LEFT JOIN project proi ON proi.id = oi.project_id
WHERE proi.projectnumber ILIKE ? AND oi.trans_id = o.id
7e47ffd0 Bernd Bleßmann
))
777d9b30 Sven Schöling
SQL
push @values, "%" . $form->{"projectnumber"} . "%", "%" . $form->{"projectnumber"} . "%" ;
72eaa1a7 Moritz Bunkus
}
d319704a Moritz Bunkus
fac049a0 Bernd Bleßmann
if ($form->{"business_id"}) {
$query .= " AND ct.business_id = ?";
push(@values, $form->{"business_id"});
}

9d0ebf28 Moritz Bunkus
if ($form->{"${vc}_id"}) {
$query .= " AND o.${vc}_id = ?";
push(@values, $form->{"${vc}_id"});
d319704a Moritz Bunkus
9d0ebf28 Moritz Bunkus
} elsif ($form->{$vc}) {
$query .= " AND ct.name ILIKE ?";
push(@values, '%' . $form->{$vc} . '%');
d319704a Moritz Bunkus
}

c9e93ded Jan Büren
if (!$main::auth->assert('sales_all_edit', 1)) {
$query .= " AND o.employee_id = (select id from employee where login= ?)";
push @values, $form->{login};
}
9ba2705f Moritz Bunkus
if ($form->{employee_id}) {
$query .= " AND o.employee_id = ?";
push @values, conv_i($form->{employee_id});
}
06d98024 Sven Schöling
4a19c3d4 Udo Spallek
if ($form->{salesman_id}) {
$query .= " AND o.salesman_id = ?";
push @values, conv_i($form->{salesman_id});
}
9ba2705f Moritz Bunkus
d319704a Moritz Bunkus
if (!$form->{open} && !$form->{closed}) {
$query .= " AND o.id = 0";
} elsif (!($form->{open} && $form->{closed})) {
$query .= ($form->{open}) ? " AND o.closed = '0'" : " AND o.closed = '1'";
}

222c7e21 Moritz Bunkus
if (($form->{"notdelivered"} || $form->{"delivered"}) &&
($form->{"notdelivered"} ne $form->{"delivered"})) {
$query .= $form->{"delivered"} ?
" AND o.delivered " : " AND NOT o.delivered";
}

9d0ebf28 Moritz Bunkus
if ($form->{$ordnumber}) {
e70d4cf2 Moritz Bunkus
$query .= qq| AND o.$ordnumber ILIKE ?|;
9d0ebf28 Moritz Bunkus
push(@values, '%' . $form->{$ordnumber} . '%');
}

b96c67e5 Moritz Bunkus
if ($form->{cusordnumber}) {
$query .= qq| AND o.cusordnumber ILIKE ?|;
push(@values, '%' . $form->{cusordnumber} . '%');
}

9d0ebf28 Moritz Bunkus
if($form->{transdatefrom}) {
$query .= qq| AND o.transdate >= ?|;
push(@values, conv_date($form->{transdatefrom}));
}
d319704a Moritz Bunkus
9d0ebf28 Moritz Bunkus
if($form->{transdateto}) {
$query .= qq| AND o.transdate <= ?|;
push(@values, conv_date($form->{transdateto}));
}

813b99ca Geoffrey Richardson
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}));
}

3fcf64fc Bernd Bleßmann
if ($form->{shippingpoint}) {
$query .= qq| AND o.shippingpoint ILIKE ?|;
push(@values, '%' . $form->{shippingpoint} . '%');
}

if ($form->{taxzone_id} ne '') { # taxzone_id could be 0
$query .= qq| AND tz.id = ?|;
push(@values, $form->{taxzone_id});
}

ce3ce404 Moritz Bunkus
if ($form->{transaction_description}) {
$query .= qq| AND o.transaction_description ILIKE ?|;
push(@values, '%' . $form->{transaction_description} . '%');
}

92331b8e Moritz Bunkus
if ($form->{periodic_invoices_active} ne $form->{periodic_invoices_inactive}) {
74fca575 Sven Schöling
my $not = $form->{periodic_invoices_inactive} ? 'NOT' : '';
92331b8e Moritz Bunkus
$query .= qq| AND ${not} COALESCE(pcfg.active, 'f')|;
}

2ea1a379 Moritz Bunkus
if ($form->{reqdate_unset_or_old}) {
$query .= qq| AND ((o.reqdate IS NULL) OR (o.reqdate < date_trunc('month', current_date)))|;
}

3da73190 Moritz Bunkus
if (($form->{order_probability_value} || '') ne '') {
my $op = $form->{order_probability_value} eq 'le' ? '<=' : '>=';
$query .= qq| AND (o.order_probability ${op} ?)|;
push @values, $form->{order_probability_value};
}

if ($form->{expected_billing_date_from}) {
$query .= qq| AND (o.expected_billing_date >= ?)|;
push @values, conv_date($form->{expected_billing_date_from});
}

if ($form->{expected_billing_date_to}) {
$query .= qq| AND (o.expected_billing_date <= ?)|;
push @values, conv_date($form->{expected_billing_date_to});
}

c654c46b Moritz Bunkus
my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
0000e2ae Moritz Bunkus
my $sortorder = join(', ', map { "${_} ${sortdir} " } ("o.id", $form->sort_columns("transdate", $ordnumber, "name")));
d38dee8d Moritz Bunkus
my %allowed_sort_columns = (
"transdate" => "o.transdate",
"reqdate" => "o.reqdate",
"id" => "o.id",
"ordnumber" => "o.ordnumber",
b96c67e5 Moritz Bunkus
"cusordnumber" => "o.cusordnumber",
d38dee8d Moritz Bunkus
"quonumber" => "o.quonumber",
"name" => "ct.name",
"employee" => "e.name",
56ce7563 Bernd Bleßmann
"salesman" => "s.name",
d38dee8d Moritz Bunkus
"shipvia" => "o.shipvia",
3fcf64fc Bernd Bleßmann
"transaction_description" => "o.transaction_description",
"shippingpoint" => "o.shippingpoint",
"taxzone" => "tz.description",
d38dee8d Moritz Bunkus
);
9d0ebf28 Moritz Bunkus
if ($form->{sort} && grep($form->{sort}, keys(%allowed_sort_columns))) {
0000e2ae Moritz Bunkus
$sortorder = $allowed_sort_columns{$form->{sort}} . " ${sortdir}";
9d0ebf28 Moritz Bunkus
}
$query .= qq| ORDER by | . $sortorder;
d319704a Moritz Bunkus
my $sth = $dbh->prepare($query);
72eaa1a7 Moritz Bunkus
$sth->execute(@values) ||
$form->dberror($query . " (" . join(", ", @values) . ")");

d319704a Moritz Bunkus
my %id = ();
9d0ebf28 Moritz Bunkus
$form->{OE} = [];
90daea72 Sven Schöling
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
50133d13 Sven Schöling
$ref->{billed_amount} = $billed_amount{$ref->{id}};
$ref->{billed_netamount} = $billed_netamount{$ref->{id}};
$ref->{remaining_amount} = $ref->{amount} - $ref->{billed_amount};
$ref->{remaining_netamount} = $ref->{netamount} - $ref->{billed_netamount};
d319704a Moritz Bunkus
$ref->{exchangerate} = 1 unless $ref->{exchangerate};
push @{ $form->{OE} }, $ref if $ref->{id} != $id{ $ref->{id} };
$id{ $ref->{id} } = $ref->{id};
}

$sth->finish;

$main::lxdebug->leave_sub();
}

7a7f33b5 Moritz Bunkus
sub transactions_for_todo_list {
$main::lxdebug->enter_sub();

my $self = shift;
my %params = @_;

my $myconfig = \%main::myconfig;
my $form = $main::form;

my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);

my $query = qq|SELECT id FROM employee WHERE login = ?|;
my ($e_id) = selectrow_query($form, $dbh, $query, $form->{login});

$query =
qq|SELECT oe.id, oe.transdate, oe.reqdate, oe.quonumber, oe.transaction_description, oe.amount,
58ff4d6a Moritz Bunkus
CASE WHEN (COALESCE(oe.customer_id, 0) = 0) THEN 'vendor' ELSE 'customer' END AS vc,
7a7f33b5 Moritz Bunkus
c.name AS customer,
c9860c6f Moritz Bunkus
v.name AS vendor,
7a7f33b5 Moritz Bunkus
e.name AS employee
FROM oe
LEFT JOIN customer c ON (oe.customer_id = c.id)
c9860c6f Moritz Bunkus
LEFT JOIN vendor v ON (oe.vendor_id = v.id)
7a7f33b5 Moritz Bunkus
LEFT JOIN employee e ON (oe.employee_id = e.id)
WHERE (COALESCE(quotation, FALSE) = TRUE)
AND (COALESCE(closed, FALSE) = FALSE)
AND ((oe.employee_id = ?) OR (oe.salesman_id = ?))
AND NOT (oe.reqdate ISNULL)
AND (oe.reqdate < current_date)
ORDER BY transdate|;

my $quotations = selectall_hashref_query($form, $dbh, $query, $e_id, $e_id);

$main::lxdebug->leave_sub();

return $quotations;
}

d319704a Moritz Bunkus
sub save {
$main::lxdebug->enter_sub();

my ($self, $myconfig, $form) = @_;

# connect to database, turn off autocommit
92331b8e Moritz Bunkus
my $dbh = $form->get_standard_dbh;
5f6d6d4e Moritz Bunkus
my $restricter = SL::HTML::Restrict->create;
d319704a Moritz Bunkus
9d0ebf28 Moritz Bunkus
my ($query, @values, $sth, $null);
d319704a Moritz Bunkus
my $exchangerate = 0;

9d0ebf28 Moritz Bunkus
my $all_units = AM->retrieve_units($myconfig, $form);
$form->{all_units} = $all_units;
54e4131e Moritz Bunkus
ef220490 Moritz Bunkus
my $ic_cvar_configs = CVar->get_configs(module => 'IC',
dbh => $dbh);

e6ef45f2 Moritz Bunkus
$form->{employee_id} = (split /--/, $form->{employee})[1] if !$form->{employee_id};
d319704a Moritz Bunkus
unless ($form->{employee_id}) {
$form->get_employee($dbh);
}

my $ml = ($form->{type} eq 'sales_order') ? 1 : -1;

aff32344 Moritz Bunkus
my $number_field = $form->{type} =~ m{order} ? 'ordnumber' : 'quonumber';
my $trans_number = SL::TransNumber->new(type => $form->{type}, dbh => $dbh, number => $form->{$number_field}, id => $form->{id});
$form->{$number_field} ||= $trans_number->create_unique;

d319704a Moritz Bunkus
if ($form->{id}) {
ef220490 Moritz Bunkus
$query = qq|DELETE FROM custom_variables
WHERE (config_id IN (SELECT id FROM custom_variable_configs WHERE module = 'IC'))
AND (sub_module = 'orderitems')
AND (trans_id IN (SELECT id FROM orderitems WHERE trans_id = ?))|;
do_query($form, $dbh, $query, $form->{id});
d319704a Moritz Bunkus
9d0ebf28 Moritz Bunkus
$query = qq|DELETE FROM orderitems WHERE trans_id = ?|;
do_query($form, $dbh, $query, $form->{id});
d319704a Moritz Bunkus
9d0ebf28 Moritz Bunkus
$query = qq|DELETE FROM shipto | .
qq|WHERE trans_id = ? AND module = 'OE'|;
do_query($form, $dbh, $query, $form->{id});
d319704a Moritz Bunkus
} else {

9d0ebf28 Moritz Bunkus
$query = qq|SELECT nextval('id')|;
($form->{id}) = selectrow_query($form, $dbh, $query);
d319704a Moritz Bunkus
a4d74009 Niclas Zimmermann
$query = qq|INSERT INTO oe (id, ordnumber, employee_id, currency_id) VALUES (?, '', ?, (SELECT currency_id FROM defaults))|;
9d0ebf28 Moritz Bunkus
do_query($form, $dbh, $query, $form->{id}, $form->{employee_id});
d319704a Moritz Bunkus
}

6cdecee0 Moritz Bunkus
my $amount = 0;
my $linetotal = 0;
my $discount = 0;
d319704a Moritz Bunkus
my $project_id;
my $reqdate;
my $taxrate;
90daea72 Sven Schöling
my $taxbase;
my $taxdiff;
6cdecee0 Moritz Bunkus
my $taxamount = 0;
d319704a Moritz Bunkus
my $fxsellprice;
my %taxbase;
my @taxaccounts;
my %taxaccounts;
my $netamount = 0;

1e251313 Moritz Bunkus
$form->get_lists('price_factors' => 'ALL_PRICE_FACTORS');
my %price_factors = map { $_->{id} => $_->{factor} } @{ $form->{ALL_PRICE_FACTORS} };
my $price_factor;

d319704a Moritz Bunkus
for my $i (1 .. $form->{rowcount}) {

b6dc5623 Sven Schöling
map({ $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) } qw(qty ship));
d319704a Moritz Bunkus
8c89bb02 Moritz Bunkus
if ($form->{"id_$i"}) {
d319704a Moritz Bunkus
54e4131e Moritz Bunkus
# get item baseunit
9d0ebf28 Moritz Bunkus
$query = qq|SELECT unit FROM parts WHERE id = ?|;
my ($item_unit) = selectrow_query($form, $dbh, $query, $form->{"id_$i"});

my $basefactor = 1;
if (defined($all_units->{$item_unit}->{factor}) &&
(($all_units->{$item_unit}->{factor} * 1) != 0)) {
b6dc5623 Sven Schöling
$basefactor = $all_units->{$form->{"unit_$i"}}->{factor} / $all_units->{$item_unit}->{factor};
54e4131e Moritz Bunkus
}
9d0ebf28 Moritz Bunkus
my $baseqty = $form->{"qty_$i"} * $basefactor;
d319704a Moritz Bunkus
4d8a6515 Philip Reetz
$form->{"marge_percent_$i"} = $form->parse_amount($myconfig, $form->{"marge_percent_$i"}) * 1;
da804bf2 Geoffrey Richardson
$form->{"marge_absolut_$i"} = $form->parse_amount($myconfig, $form->{"marge_absolut_$i"}) * 1;
1ffb4200 Moritz Bunkus
da804bf2 Geoffrey Richardson
$form->{"lastcost_$i"} = $form->parse_amount($myconfig, $form->{"lastcost_$i"});
4d8a6515 Philip Reetz
2e5f7860 Bernd Bleßmann
# keep entered selling price
my $fxsellprice =
$form->parse_amount($myconfig, $form->{"sellprice_$i"});
d319704a Moritz Bunkus
2e5f7860 Bernd Bleßmann
my ($dec) = ($fxsellprice =~ /\.(\d+)/);
$dec = length $dec;
d319704a Moritz Bunkus
my $decimalplaces = ($dec > 2) ? $dec : 2;

2e5f7860 Bernd Bleßmann
# undo discount formatting
$form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
d319704a Moritz Bunkus
2e5f7860 Bernd Bleßmann
# deduct discount
$form->{"sellprice_$i"} = $fxsellprice * (1 - $form->{"discount_$i"});
d319704a Moritz Bunkus
2e5f7860 Bernd Bleßmann
# round linetotal at least to 2 decimal places
1e251313 Moritz Bunkus
$price_factor = $price_factors{ $form->{"price_factor_id_$i"} } || 1;
$linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"} / $price_factor, 2);
d319704a Moritz Bunkus
2e5f7860 Bernd Bleßmann
$form->{"inventory_accno_$i"} *= 1;
$form->{"expense_accno_$i"} *= 1;

9d0ebf28 Moritz Bunkus
@taxaccounts = split(/ /, $form->{"taxaccounts_$i"});
d319704a Moritz Bunkus
$taxrate = 0;
$taxdiff = 0;

map { $taxrate += $form->{"${_}_rate"} } @taxaccounts;

if ($form->{taxincluded}) {
$taxamount = $linetotal * $taxrate / (1 + $taxrate);
$taxbase = $linetotal - $taxamount;

# we are not keeping a natural price, do not round
$form->{"sellprice_$i"} =
$form->{"sellprice_$i"} * (1 / (1 + $taxrate));
} else {
$taxamount = $linetotal * $taxrate;
$taxbase = $linetotal;
}

if ($form->round_amount($taxrate, 7) == 0) {
if ($form->{taxincluded}) {
90daea72 Sven Schöling
foreach my $item (@taxaccounts) {
b6dc5623 Sven Schöling
$taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
d319704a Moritz Bunkus
$taxaccounts{$item} += $taxamount;
$taxdiff += $taxamount;
b6dc5623 Sven Schöling
$taxbase{$item} += $taxbase;
d319704a Moritz Bunkus
}
$taxaccounts{ $taxaccounts[0] } += $taxdiff;
} else {
90daea72 Sven Schöling
foreach my $item (@taxaccounts) {
d319704a Moritz Bunkus
$taxaccounts{$item} += $linetotal * $form->{"${item}_rate"};
$taxbase{$item} += $taxbase;
}
}
} else {
90daea72 Sven Schöling
foreach my $item (@taxaccounts) {
b6dc5623 Sven Schöling
$taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
d319704a Moritz Bunkus
$taxbase{$item} += $taxbase;
}
}

1e251313 Moritz Bunkus
$netamount += $form->{"sellprice_$i"} * $form->{"qty_$i"} / $price_factor;
d319704a Moritz Bunkus
b6dc5623 Sven Schöling
$reqdate = ($form->{"reqdate_$i"}) ? $form->{"reqdate_$i"} : undef;
d319704a Moritz Bunkus
b632cee8 Moritz Bunkus
# Get pricegroup_id and save it. Unfortunately the interface
# also uses ID "0" for signalling that none is selected, but "0"
# must not be stored in the database. Therefore we cannot simply
# use conv_i().
9d0ebf28 Moritz Bunkus
($null, my $pricegroup_id) = split(/--/, $form->{"sellprice_pg_$i"});
07d71c33 Stephan Köhler
$pricegroup_id *= 1;
b632cee8 Moritz Bunkus
$pricegroup_id = undef if !$pricegroup_id;
07d71c33 Stephan Köhler
d319704a Moritz Bunkus
# save detail record in orderitems table
ef220490 Moritz Bunkus
my $orderitems_id = $form->{"orderitems_id_$i"};
($orderitems_id) = selectfirst_array_query($form, $dbh, qq|SELECT nextval('orderitemsid')|) if (!$orderitems_id);

9d0ebf28 Moritz Bunkus
@values = ();
ef220490 Moritz Bunkus
$query = qq|INSERT INTO orderitems (
id, trans_id, parts_id, description, longdescription, qty, base_qty,
sellprice, discount, unit, reqdate, project_id, serialnumber, ship,
pricegroup_id, ordnumber, transdate, cusordnumber, subtotal,
marge_percent, marge_total, lastcost, price_factor_id, price_factor, marge_price_factor)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
(SELECT factor FROM price_factors WHERE id = ?), ?)|;
83914eeb Moritz Bunkus
push(@values,
ef220490 Moritz Bunkus
conv_i($orderitems_id), conv_i($form->{id}), conv_i($form->{"id_$i"}),
5f6d6d4e Moritz Bunkus
$form->{"description_$i"}, $restricter->process($form->{"longdescription_$i"}),
9d0ebf28 Moritz Bunkus
$form->{"qty_$i"}, $baseqty,
$fxsellprice, $form->{"discount_$i"},
$form->{"unit_$i"}, conv_date($reqdate), conv_i($form->{"project_id_$i"}),
b632cee8 Moritz Bunkus
$form->{"serialnumber_$i"}, $form->{"ship_$i"}, $pricegroup_id,
9d0ebf28 Moritz Bunkus
$form->{"ordnumber_$i"}, conv_date($form->{"transdate_$i"}),
6cdecee0 Moritz Bunkus
$form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f',
da804bf2 Geoffrey Richardson
$form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"},
1e251313 Moritz Bunkus
$form->{"lastcost_$i"},
conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
conv_i($form->{"marge_price_factor_$i"}));
9d0ebf28 Moritz Bunkus
do_query($form, $dbh, $query, @values);
d319704a Moritz Bunkus
$form->{"sellprice_$i"} = $fxsellprice;
$form->{"discount_$i"} *= 100;
ef220490 Moritz Bunkus
CVar->save_custom_variables(module => 'IC',
sub_module => 'orderitems',
trans_id => $orderitems_id,
configs => $ic_cvar_configs,
variables => $form,
name_prefix => 'ic_',
name_postfix => "_$i",
dbh => $dbh);
d319704a Moritz Bunkus
}
}

9d0ebf28 Moritz Bunkus
$reqdate = ($form->{reqdate}) ? $form->{reqdate} : undef;
d319704a Moritz Bunkus
# add up the tax
my $tax = 0;
map { $tax += $form->round_amount($taxaccounts{$_}, 2) } keys %taxaccounts;

$amount = $form->round_amount($netamount + $tax, 2);
$netamount = $form->round_amount($netamount, 2);

if ($form->{currency} eq $form->{defaultcurrency}) {
$form->{exchangerate} = 1;
} else {
b6dc5623 Sven Schöling
$exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? 'buy' : 'sell');
d319704a Moritz Bunkus
}

a53233e5 Sven Schöling
$form->{exchangerate} = $exchangerate || $form->parse_amount($myconfig, $form->{exchangerate});
d319704a Moritz Bunkus
6d1df9ca Moritz Bunkus
my $quotation = $form->{type} =~ /_order$/ ? 'f' : 't';
d319704a Moritz Bunkus
8cdaa6f0 Sven Schöling
($null, $form->{department_id}) = split(/--/, $form->{department}) if $form->{department};
d319704a Moritz Bunkus
# save OE record
9d0ebf28 Moritz Bunkus
$query =
6cdecee0 Moritz Bunkus
qq|UPDATE oe SET
ordnumber = ?, quonumber = ?, cusordnumber = ?, transdate = ?, vendor_id = ?,
customer_id = ?, amount = ?, netamount = ?, reqdate = ?, taxincluded = ?,
a4d74009 Niclas Zimmermann
shippingpoint = ?, shipvia = ?, notes = ?, intnotes = ?, currency_id = (SELECT id FROM currencies WHERE name=?), closed = ?,
6cdecee0 Moritz Bunkus
delivered = ?, proforma = ?, quotation = ?, department_id = ?, language_id = ?,
03d3d025 Bernd Bleßmann
taxzone_id = ?, shipto_id = ?, payment_id = ?, delivery_vendor_id = ?, delivery_customer_id = ?,delivery_term_id = ?,
6cdecee0 Moritz Bunkus
globalproject_id = ?, employee_id = ?, salesman_id = ?, cp_id = ?, transaction_description = ?, marge_total = ?, marge_percent = ?
3da73190 Moritz Bunkus
, order_probability = ?, expected_billing_date = ?
6cdecee0 Moritz Bunkus
WHERE id = ?|;
9d0ebf28 Moritz Bunkus
abd2032c Moritz Bunkus
@values = ($form->{ordnumber} || '', $form->{quonumber},
9d0ebf28 Moritz Bunkus
$form->{cusordnumber}, conv_date($form->{transdate}),
conv_i($form->{vendor_id}), conv_i($form->{customer_id}),
$amount, $netamount, conv_date($reqdate),
$form->{taxincluded} ? 't' : 'f', $form->{shippingpoint},
$form->{shipvia}, $form->{notes}, $form->{intnotes},
d331a3d7 Niclas Zimmermann
$form->{currency}, $form->{closed} ? 't' : 'f',
9d0ebf28 Moritz Bunkus
$form->{delivered} ? "t" : "f", $form->{proforma} ? 't' : 'f',
$quotation, conv_i($form->{department_id}),
conv_i($form->{language_id}), conv_i($form->{taxzone_id}),
conv_i($form->{shipto_id}), conv_i($form->{payment_id}),
conv_i($form->{delivery_vendor_id}),
conv_i($form->{delivery_customer_id}),
03d3d025 Bernd Bleßmann
conv_i($form->{delivery_term_id}),
9d0ebf28 Moritz Bunkus
conv_i($form->{globalproject_id}), conv_i($form->{employee_id}),
conv_i($form->{salesman_id}), conv_i($form->{cp_id}),
ce3ce404 Moritz Bunkus
$form->{transaction_description},
6cdecee0 Moritz Bunkus
$form->{marge_total} * 1, $form->{marge_percent} * 1,
3da73190 Moritz Bunkus
$form->{order_probability} * 1, conv_date($form->{expected_billing_date}),
9d0ebf28 Moritz Bunkus
conv_i($form->{id}));
do_query($form, $dbh, $query, @values);
d319704a Moritz Bunkus
$form->{ordtotal} = $amount;

$form->{name} = $form->{ $form->{vc} };
5cf977e5 Moritz Bunkus
$form->{name} =~ s/--\Q$form->{"$form->{vc}_id"}\E//;
54e4131e Moritz Bunkus
b6213d35 Moritz Bunkus
# add shipto
54e4131e Moritz Bunkus
if (!$form->{shipto_id}) {
$form->add_shipto($dbh, $form->{id}, "OE");
}
d319704a Moritz Bunkus
# save printed, emailed, queued
$form->save_status($dbh);

94e11003 Moritz Bunkus
# Link this record to the records it was created from.
b7b5192a Moritz Bunkus
$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};
94e11003 Moritz Bunkus
delete $form->{convert_from_oe_ids};

b7b5192a Moritz Bunkus
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});
}

d319704a Moritz Bunkus
if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
if ($form->{vc} eq 'customer') {
b6dc5623 Sven Schöling
$form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $form->{exchangerate}, 0);
d319704a Moritz Bunkus
}
if ($form->{vc} eq 'vendor') {
b6dc5623 Sven Schöling
$form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, 0, $form->{exchangerate});
d319704a Moritz Bunkus
}
}

06bbc8e7 Moritz Bunkus
$form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
"quonumber" : "ordnumber"};

be6f6cfd Moritz Bunkus
Common::webdav_folder($form);
8e206587 Moritz Bunkus
b6dc5623 Sven Schöling
my $rc = $dbh->commit;

0fc62572 Moritz Bunkus
$self->save_periodic_invoices_config(dbh => $dbh,
oe_id => $form->{id},
config_yaml => $form->{periodic_invoices_config})
if ($form->{type} eq 'sales_order');

d319704a Moritz Bunkus
$main::lxdebug->leave_sub();

return $rc;
}

92331b8e Moritz Bunkus
sub save_periodic_invoices_config {
my ($self, %params) = @_;

return if !$params{oe_id};

my $config = $params{config_yaml} ? YAML::Load($params{config_yaml}) : undef;
return if 'HASH' ne ref $config;

my $obj = SL::DB::Manager::PeriodicInvoicesConfig->find_by(oe_id => $params{oe_id})
|| SL::DB::PeriodicInvoicesConfig->new(oe_id => $params{oe_id});
$obj->update_attributes(%{ $config });
}

f49ad7f1 Moritz Bunkus
sub load_periodic_invoice_config {
my $self = shift;
my $form = shift;

delete $form->{periodic_invoices_config};

if ($form->{id}) {
my $config_obj = SL::DB::Manager::PeriodicInvoicesConfig->find_by(oe_id => $form->{id});

if ($config_obj) {
f48af817 Moritz Bunkus
my $config = { map { $_ => $config_obj->$_ } qw(active terminated periodicity start_date_as_date end_date_as_date first_billing_date_as_date extend_automatically_by ar_chart_id
f49ad7f1 Moritz Bunkus
print printer_id copies) };
$form->{periodic_invoices_config} = YAML::Dump($config);
}
}
}

b7b5192a Moritz Bunkus
sub _close_quotations_rfqs {
626e0240 Stephan Köhler
$main::lxdebug->enter_sub();

b7b5192a Moritz Bunkus
my $self = shift;
my %params = @_;
626e0240 Stephan Köhler
b7b5192a Moritz Bunkus
Common::check_params(\%params, qw(from_id to_id));
081a4f97 Moritz Bunkus
b7b5192a Moritz Bunkus
my $myconfig = \%main::myconfig;
my $form = $main::form;
626e0240 Stephan Köhler
b7b5192a Moritz Bunkus
my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
626e0240 Stephan Köhler
b7b5192a Moritz Bunkus
my $query = qq|SELECT quotation FROM oe WHERE id = ?|;
my $sth = prepare_query($form, $dbh, $query);
8a996479 Moritz Bunkus
b7b5192a Moritz Bunkus
do_statement($form, $sth, $query, conv_i($params{to_id}));
8a996479 Moritz Bunkus
b7b5192a Moritz Bunkus
my ($quotation) = $sth->fetchrow_array();
8a996479 Moritz Bunkus
b7b5192a Moritz Bunkus
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});
}
8a996479 Moritz Bunkus
$main::lxdebug->leave_sub();
}

d319704a Moritz Bunkus
sub delete {
$main::lxdebug->enter_sub();

8cd05ad6 Moritz Bunkus
my ($self, $myconfig, $form) = @_;
d319704a Moritz Bunkus
3b9c2119 Moritz Bunkus
my $rc = SL::DB::Order->new->db->with_transaction(sub {
my @spoolfiles = grep { $_ } map { $_->spoolfile } @{ SL::DB::Manager::Status->get_all(where => [ trans_id => $form->{id} ]) };
d319704a Moritz Bunkus
3b9c2119 Moritz Bunkus
SL::DB::Order->new(id => $form->{id})->delete;
ddf1c00a Moritz Bunkus
8cd05ad6 Moritz Bunkus
my $spool = $::lx_office_conf{paths}->{spool};
3b9c2119 Moritz Bunkus
unlink map { "$spool/$_" } @spoolfiles if $spool;

1;
});
d319704a Moritz Bunkus
$main::lxdebug->leave_sub();

return $rc;
}

sub retrieve {
$main::lxdebug->enter_sub();

my ($self, $myconfig, $form) = @_;

# connect to database
b2cb10d1 Sven Schöling
my $dbh = $form->get_standard_dbh;
d319704a Moritz Bunkus
f5c548f0 Moritz Bunkus
my ($query, $query_add, @values, @ids, $sth);
d319704a Moritz Bunkus
626e0240 Stephan Köhler
# translate the ids (given by id_# and trans_id_#) into one array of ids, so we can join them later
081a4f97 Moritz Bunkus
map {
push @ids, $form->{"trans_id_$_"}
9d0ebf28 Moritz Bunkus
if ($form->{"multi_id_$_"} and $form->{"trans_id_$_"})
081a4f97 Moritz Bunkus
} (1 .. $form->{"rowcount"});
626e0240 Stephan Köhler
94e11003 Moritz Bunkus
if ($form->{rowcount} && scalar @ids) {
$form->{convert_from_oe_ids} = join ' ', @ids;
}

081a4f97 Moritz Bunkus
# if called in multi id mode, and still only got one id, switch back to single id
626e0240 Stephan Köhler
if ($form->{"rowcount"} and $#ids == 0) {
$form->{"id"} = $ids[0];
undef @ids;
}

90daea72 Sven Schöling
# and remember for the rest of the function
my $is_collective_order = scalar @ids;

34ca68b5 Moritz Bunkus
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|;
}
f5c548f0 Moritz Bunkus
# get default accounts
$query = qq|SELECT (SELECT c.accno FROM chart c WHERE d.inventory_accno_id = c.id) AS inventory_accno,
(SELECT c.accno FROM chart c WHERE d.income_accno_id = c.id) AS income_accno,
(SELECT c.accno FROM chart c WHERE d.expense_accno_id = c.id) AS expense_accno,
(SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
d331a3d7 Niclas Zimmermann
(SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno
f5c548f0 Moritz Bunkus
$query_add
FROM defaults d|;
my $ref = selectfirst_hashref_query($form, $dbh, $query);
d319704a Moritz Bunkus
map { $form->{$_} = $ref->{$_} } keys %$ref;

d331a3d7 Niclas Zimmermann
$form->{currency} = $form->get_default_currency($myconfig);
d319704a Moritz Bunkus
081a4f97 Moritz Bunkus
# set reqdate if this is an invoice->order conversion. If someone knows a better check to ensure
487d4f1f Stephan Köhler
# we come from invoices, feel free.
081a4f97 Moritz Bunkus
$form->{reqdate} = $form->{deliverydate}
if ( $form->{deliverydate}
and $form->{callback} =~ /action=ar_transactions/);
487d4f1f Stephan Köhler
9d0ebf28 Moritz Bunkus
my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";

626e0240 Stephan Köhler
if ($form->{id} or @ids) {
d319704a Moritz Bunkus
626e0240 Stephan Köhler
# retrieve order for single id
# NOTE: this query is intended to fetch all information only ONCE.
081a4f97 Moritz Bunkus
# so if any of these infos is important (or even different) for any item,
626e0240 Stephan Köhler
# it will be killed out and then has to be fetched from the item scope query further down
9d0ebf28 Moritz Bunkus
$query =
60eb41d8 Sven Schöling
qq|SELECT o.cp_id, o.ordnumber, o.transdate, o.reqdate,
o.taxincluded, o.shippingpoint, o.shipvia, o.notes, o.intnotes,
a4d74009 Niclas Zimmermann
(SELECT cu.name FROM currencies cu WHERE cu.id=o.currency_id) AS currency, e.name AS employee, o.employee_id, o.salesman_id,
60eb41d8 Sven Schöling
o.${vc}_id, cv.name AS ${vc}, o.amount AS invtotal,
o.closed, o.reqdate, o.quonumber, o.department_id, o.cusordnumber,
d.description AS department, o.payment_id, o.language_id, o.taxzone_id,
o.delivery_customer_id, o.delivery_vendor_id, o.proforma, o.shipto_id,
03d3d025 Bernd Bleßmann
o.globalproject_id, o.delivered, o.transaction_description, o.delivery_term_id
3da73190 Moritz Bunkus
, o.order_probability, o.expected_billing_date
60eb41d8 Sven Schöling
FROM oe o
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) | .
06d98024 Sven Schöling
($form->{id}
? "WHERE o.id = ?"
60eb41d8 Sven Schöling
: "WHERE o.id IN (" . join(', ', map("? ", @ids)) . ")"
);
9d0ebf28 Moritz Bunkus
@values = $form->{id} ? ($form->{id}) : @ids;
$sth = prepare_execute_query($form, $dbh, $query, @values);
d319704a Moritz Bunkus
90daea72 Sven Schöling
$ref = $sth->fetchrow_hashref("NAME_lc");
d319704a Moritz Bunkus
2a795624 Moritz Bunkus
if ($ref) {
map { $form->{$_} = $ref->{$_} } keys %$ref;
54e4131e Moritz Bunkus
2a795624 Moritz Bunkus
$form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ? "quonumber" : "ordnumber"};

# set all entries for multiple ids blank that yield different information
while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
map { $form->{$_} = '' if ($ref->{$_} ne $form->{$_}) } keys %$ref;
}
d319704a Moritz Bunkus
}
626e0240 Stephan Köhler
# if not given, fill transdate with current_date
081a4f97 Moritz Bunkus
$form->{transdate} = $form->current_date($myconfig)
unless $form->{transdate};
626e0240 Stephan Köhler
d319704a Moritz Bunkus
$sth->finish;
626e0240 Stephan Köhler
54e4131e Moritz Bunkus
if ($form->{delivery_customer_id}) {
9d0ebf28 Moritz Bunkus
$query = qq|SELECT name FROM customer WHERE id = ?|;
60eb41d8 Sven Schöling
($form->{delivery_customer_string}) = selectrow_query($form, $dbh, $query, $form->{delivery_customer_id});
54e4131e Moritz Bunkus
}

if ($form->{delivery_vendor_id}) {
9d0ebf28 Moritz Bunkus
$query = qq|SELECT name FROM customer WHERE id = ?|;
60eb41d8 Sven Schöling
($form->{delivery_vendor_string}) = selectrow_query($form, $dbh, $query, $form->{delivery_vendor_id});
54e4131e Moritz Bunkus
}

081a4f97 Moritz Bunkus
# shipto and pinted/mailed/queued status makes only sense for single id retrieve
626e0240 Stephan Köhler
if (!@ids) {
60eb41d8 Sven Schöling
$query = qq|SELECT s.* FROM shipto s WHERE s.trans_id = ? AND s.module = 'OE'|;
9d0ebf28 Moritz Bunkus
$sth = prepare_execute_query($form, $dbh, $query, $form->{id});
626e0240 Stephan Köhler
90daea72 Sven Schöling
$ref = $sth->fetchrow_hashref("NAME_lc");
54e4131e Moritz Bunkus
delete($ref->{id});
626e0240 Stephan Köhler
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;

# get printed, emailed and queued
60eb41d8 Sven Schöling
$query = qq|SELECT s.printed, s.emailed, s.spoolfile, s.formname FROM status s WHERE s.trans_id = ?|;
9d0ebf28 Moritz Bunkus
$sth = prepare_execute_query($form, $dbh, $query, $form->{id});
626e0240 Stephan Köhler
90daea72 Sven Schöling
while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
626e0240 Stephan Köhler
$form->{printed} .= "$ref->{formname} " if $ref->{printed};
$form->{emailed} .= "$ref->{formname} " if $ref->{emailed};
60eb41d8 Sven Schöling
$form->{queued} .= "$ref->{formname} $ref->{spoolfile} " if $ref->{spoolfile};
626e0240 Stephan Köhler
}
$sth->finish;
map { $form->{$_} =~ s/ +$//g } qw(printed emailed queued);
081a4f97 Moritz Bunkus
} # if !@ids
d319704a Moritz Bunkus
60eb41d8 Sven Schöling
my $transdate = $form->{transdate} ? $dbh->quote($form->{transdate}) : "current_date";
2e5a8be3 Moritz Bunkus
9d0ebf28 Moritz Bunkus
$form->{taxzone_id} = 0 unless ($form->{taxzone_id});

d319704a Moritz Bunkus
# retrieve individual items
626e0240 Stephan Köhler
# this query looks up all information about the items
# stuff different from the whole will not be overwritten, but saved with a suffix.
9d0ebf28 Moritz Bunkus
$query =
60eb41d8 Sven Schöling
qq|SELECT o.id AS orderitems_id,
06d98024 Sven Schöling
c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid,
60eb41d8 Sven Schöling
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,
64515aa9 Bernd Bleßmann
p.partnumber, p.assembly, p.listprice, o.description, o.qty,
82c4717d Jan Büren
o.sellprice, o.parts_id AS id, o.unit, o.discount, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id,
60eb41d8 Sven Schöling
o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost,
o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription,
1e251313 Moritz Bunkus
o.price_factor_id, o.price_factor, o.marge_price_factor,
60eb41d8 Sven Schöling
pr.projectnumber, p.formel,
pg.partsgroup, o.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=o.pricegroup_id) as pricegroup
FROM orderitems o
JOIN parts p ON (o.parts_id = p.id)
JOIN oe ON (o.trans_id = oe.id)
LEFT JOIN chart c1 ON ((SELECT inventory_accno_id FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c1.id)
LEFT JOIN chart c2 ON ((SELECT income_accno_id_$form->{taxzone_id} FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c2.id)
LEFT JOIN chart c3 ON ((SELECT expense_accno_id_$form->{taxzone_id} FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c3.id)
LEFT JOIN project pr ON (o.project_id = pr.id)
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | .
($form->{id}
? qq|WHERE o.trans_id = ?|
: qq|WHERE o.trans_id IN (| . join(", ", map("?", @ids)) . qq|)|) .
90bb521a Moritz Bunkus
qq|ORDER BY o.oid|;
9d0ebf28 Moritz Bunkus
@ids = $form->{id} ? ($form->{id}) : @ids;
$sth = prepare_execute_query($form, $dbh, $query, @values);
d319704a Moritz Bunkus
90daea72 Sven Schöling
while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
ef220490 Moritz Bunkus
# Retrieve custom variables.
my $cvars = CVar->get_custom_variables(dbh => $dbh,
module => 'IC',
sub_module => 'orderitems',
trans_id => $ref->{orderitems_id},
);
map { $ref->{"ic_cvar_$_->{name}"} = $_->{value} } @{ $cvars };

# Handle accounts.
54e4131e Moritz Bunkus
if (!$ref->{"part_inventory_accno_id"}) {
map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid));
}
delete($ref->{"part_inventory_accno_id"});
081a4f97 Moritz Bunkus
041a8bb7 Stephan Köhler
# in collective order, copy global ordnumber, transdate, cusordnumber into item scope
081a4f97 Moritz Bunkus
# unless already present there
041a8bb7 Stephan Köhler
# remove _oe entries afterwards
map { $ref->{$_} = $ref->{"${_}_oe"} if ($ref->{$_} eq '') }
081a4f97 Moritz Bunkus
qw|ordnumber transdate cusordnumber|
if (@ids);
map { delete $ref->{$_} } qw|ordnumber_oe transdate_oe cusordnumber_oe|;
d319704a Moritz Bunkus
54e4131e Moritz Bunkus

9d0ebf28 Moritz Bunkus
while ($ref->{inventory_new_chart} && ($ref->{inventory_valid} >= 0)) {
my $query =
qq|SELECT accno AS inventory_accno, | .
qq| new_chart_id AS inventory_new_chart, | .
qq| date($transdate) - valid_from AS inventory_valid | .
qq|FROM chart WHERE id = $ref->{inventory_new_chart}|;
($ref->{inventory_accno}, $ref->{inventory_new_chart},
$ref->{inventory_valid}) = selectrow_query($form, $dbh, $query);
}
54e4131e Moritz Bunkus
9d0ebf28 Moritz Bunkus
while ($ref->{income_new_chart} && ($ref->{income_valid} >= 0)) {
my $query =
qq|SELECT accno AS income_accno, | .
qq| new_chart_id AS income_new_chart, | .
qq| date($transdate) - valid_from AS income_valid | .
qq|FROM chart WHERE id = $ref->{income_new_chart}|;
($ref->{income_accno}, $ref->{income_new_chart},
$ref->{income_valid}) = selectrow_query($form, $dbh, $query);
}
54e4131e Moritz Bunkus
9d0ebf28 Moritz Bunkus
while ($ref->{expense_new_chart} && ($ref->{expense_valid} >= 0)) {
my $query =
qq|SELECT accno AS expense_accno, | .
qq| new_chart_id AS expense_new_chart, | .
qq| date($transdate) - valid_from AS expense_valid | .
qq|FROM chart WHERE id = $ref->{expense_new_chart}|;
($ref->{expense_accno}, $ref->{expense_new_chart},
$ref->{expense_valid}) = selectrow_query($form, $dbh, $query);
}
37df0ebf Sven Schöling
b518ce7a Moritz Bunkus
# delete orderitems_id in collective orders, so that they get cloned no matter what
delete $ref->{orderitems_id} if (@ids);

d319704a Moritz Bunkus
# get tax rates and description
90daea72 Sven Schöling
my $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno};
9d0ebf28 Moritz Bunkus
$query =
qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber | .
qq|FROM tax t LEFT JOIN chart c on (c.id = t.chart_id) | .
qq|WHERE t.id IN (SELECT tk.tax_id FROM taxkeys tk | .
qq| WHERE tk.chart_id = (SELECT id FROM chart WHERE accno = ?) | .
qq| AND startdate <= $transdate ORDER BY startdate DESC LIMIT 1) | .
qq|ORDER BY c.accno|;
90daea72 Sven Schöling
my $stw = prepare_execute_query($form, $dbh, $query, $accno_id);
d319704a Moritz Bunkus
$ref->{taxaccounts} = "";
54e4131e Moritz Bunkus
my $i = 0;
90daea72 Sven Schöling
while (my $ptr = $stw->fetchrow_hashref("NAME_lc")) {
54e4131e Moritz Bunkus
if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) {
$i++;
$ptr->{accno} = $i;
}
d319704a Moritz Bunkus
$ref->{taxaccounts} .= "$ptr->{accno} ";
5cf977e5 Moritz Bunkus
if (!($form->{taxaccounts} =~ /\Q$ptr->{accno}\E/)) {
d319704a Moritz Bunkus
$form->{"$ptr->{accno}_rate"} = $ptr->{rate};
54e4131e Moritz Bunkus
$form->{"$ptr->{accno}_description"} = $ptr->{taxdescription};
d319704a Moritz Bunkus
$form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber};
$form->{taxaccounts} .= "$ptr->{accno} ";
}

}

chop $ref->{taxaccounts};
ef220490 Moritz Bunkus
d319704a Moritz Bunkus
push @{ $form->{form_details} }, $ref;
$stw->finish;
}
$sth->finish;

} else {

# get last name used
$form->lastname_used($dbh, $myconfig, $form->{vc})
unless $form->{"$form->{vc}_id"};

}

60eb41d8 Sven Schöling
$form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? "buy" : "sell");
d319704a Moritz Bunkus
be6f6cfd Moritz Bunkus
Common::webdav_folder($form);
d319704a Moritz Bunkus
f49ad7f1 Moritz Bunkus
$self->load_periodic_invoice_config($form);

d319704a Moritz Bunkus
my $rc = $dbh->commit;

$main::lxdebug->leave_sub();

return $rc;
}

9bc40390 Sven Schöling
sub retrieve_simple {
$main::lxdebug->enter_sub();

my $self = shift;
my %params = @_;

Common::check_params(\%params, qw(id));

my $myconfig = \%main::myconfig;
my $form = $main::form;

my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);

my $oe_query = qq|SELECT * FROM oe WHERE id = ?|;
my $oi_query = qq|SELECT * FROM orderitems WHERE trans_id = ?|;

879070c7 Sven Schöling
my $order = selectfirst_hashref_query($form, $dbh, $oe_query, conv_i($params{id}));
$order->{orderitems} = selectall_hashref_query( $form, $dbh, $oi_query, conv_i($params{id}));
9bc40390 Sven Schöling
$main::lxdebug->leave_sub();

return $order;
}

d319704a Moritz Bunkus
sub order_details {
$main::lxdebug->enter_sub();

my ($self, $myconfig, $form) = @_;

# connect to database
76a25c8c Sven Schöling
my $dbh = $form->get_standard_dbh;
d319704a Moritz Bunkus
my $query;
9d0ebf28 Moritz Bunkus
my @values = ();
d319704a Moritz Bunkus
my $sth;
54e4131e Moritz Bunkus
my $nodiscount;
my $yesdiscount;
my $nodiscount_subtotal = 0;
my $discount_subtotal = 0;
d319704a Moritz Bunkus
my $item;
my $i;
my @partsgroup = ();
my $partsgroup;
54e4131e Moritz Bunkus
my $position = 0;
my $subtotal_header = 0;
my $subposition = 0;
90daea72 Sven Schöling
my %taxaccounts;
my %taxbase;
my $tax_rate;
my $taxamount;

fde1df0b Sven Schöling
my (@project_ids);
96d10ecc Moritz Bunkus
push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"});

0a6affab Sven Schöling
$form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
'departments' => 'ALL_DEPARTMENTS');
1e251313 Moritz Bunkus
my %price_factors;

foreach my $pfac (@{ $form->{ALL_PRICE_FACTORS} }) {
$price_factors{$pfac->{id}} = $pfac;
$pfac->{factor} *= 1;
$pfac->{formatted_factor} = $form->format_amount($myconfig, $pfac->{factor});
}

0a6affab Sven Schöling
# lookup department
66280da7 Sven Schöling
foreach my $dept (@{ $form->{ALL_DEPARTMENTS} }) {
next unless $dept->{id} eq $form->{department_id};
$form->{department} = $dept->{description};
last;
}
0a6affab Sven Schöling
d319704a Moritz Bunkus
# sort items by partsgroup
for $i (1 .. $form->{rowcount}) {
$partsgroup = "";
if ($form->{"partsgroup_$i"} && $form->{groupitems}) {
$partsgroup = $form->{"partsgroup_$i"};
}
push @partsgroup, [$i, $partsgroup];
96d10ecc Moritz Bunkus
push(@project_ids, $form->{"project_id_$i"}) if ($form->{"project_id_$i"});
}

fde1df0b Sven Schöling
my $projects = [];
my %projects_by_id;
96d10ecc Moritz Bunkus
if (@project_ids) {
fde1df0b Sven Schöling
$projects = SL::DB::Manager::Project->get_all(query => [ id => \@project_ids ]);
%projects_by_id = map { $_->id => $_ } @$projects;
d319704a Moritz Bunkus
}

fde1df0b Sven Schöling
if ($projects_by_id{$form->{"globalproject_id"}}) {
896ef9aa Sven Schöling
$form->{globalprojectnumber} = $projects_by_id{$form->{"globalproject_id"}}->projectnumber;
$form->{globalprojectdescription} = $projects_by_id{$form->{"globalproject_id"}}->description;

fde1df0b Sven Schöling
for (@{ $projects_by_id{$form->{"globalproject_id"}}->cvars_by_config }) {
$form->{"project_cvar_" . $_->config->name} = $_->value_as_text;
}
}
96d10ecc Moritz Bunkus
af59820c Moritz Bunkus
$form->{discount} = [];

b0059459 Moritz Bunkus
$form->{TEMPLATE_ARRAYS} = { };
c5651754 Bernd Bleßmann
IC->prepare_parts_for_printing(myconfig => $myconfig, form => $form);
47c3bf62 Moritz Bunkus
ef220490 Moritz Bunkus
my $ic_cvar_configs = CVar->get_configs(module => 'IC');
fde1df0b Sven Schöling
my $project_cvar_configs = CVar->get_configs(module => 'Projects');
ef220490 Moritz Bunkus
96d10ecc Moritz Bunkus
my @arrays =
qw(runningnumber number description longdescription qty ship unit bin
partnotes serialnumber reqdate sellprice listprice netprice
discount p_discount discount_sub nodiscount_sub
c6867c46 Bernd Bleßmann
linetotal nodiscount_linetotal tax_rate projectnumber projectdescription
79c048aa Niclas Zimmermann
price_factor price_factor_name partsgroup weight lineweight);
96d10ecc Moritz Bunkus
ef220490 Moritz Bunkus
push @arrays, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
fde1df0b Sven Schöling
push @arrays, map { "project_cvar_$_->{name}" } @{ $project_cvar_configs };
ef220490 Moritz Bunkus
9c63c160 Moritz Bunkus
my @tax_arrays = qw(taxbase tax taxdescription taxrate taxnumber);

b0059459 Moritz Bunkus
map { $form->{TEMPLATE_ARRAYS}->{$_} = [] } (@arrays, @tax_arrays);
9c63c160 Moritz Bunkus
79c048aa Niclas Zimmermann
my $totalweight = 0;
d319704a Moritz Bunkus
my $sameitem = "";
foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
$i = $item->[0];

if ($item->[1] ne $sameitem) {
9c63c160 Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, qq|$item->[1]|);
d319704a Moritz Bunkus
$sameitem = $item->[1];

9c63c160 Moritz Bunkus
map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
d319704a Moritz Bunkus
}

$form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});

8c89bb02 Moritz Bunkus
if ($form->{"id_$i"} != 0) {
d319704a Moritz Bunkus
# add number, description and qty to $form->{number}, ....
54e4131e Moritz Bunkus
if ($form->{"subtotal_$i"} && !$subtotal_header) {
$subtotal_header = $i;
$position = int($position);
$subposition = 0;
$position++;
} elsif ($subtotal_header) {
$subposition += 1;
$position = int($position);
$position = $position.".".$subposition;
} else {
$position = int($position);
$position++;
}

1e251313 Moritz Bunkus
my $price_factor = $price_factors{$form->{"price_factor_id_$i"}} || { 'factor' => 1 };

9c63c160 Moritz Bunkus
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"});
8461199d Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{qty_nofmt} }, $form->{"qty_$i"};
9c63c160 Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{ship} }, $form->format_amount($myconfig, $form->{"ship_$i"});
8461199d Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{ship_nofmt} }, $form->{"ship_$i"};
9c63c160 Moritz Bunkus
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"};
8461199d Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{sellprice_nofmt} }, $form->parse_amount($myconfig, $form->{"sellprice_$i"});
9c63c160 Moritz Bunkus
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"};
d9c9bc22 Moritz Bunkus
my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
my ($dec) = ($sellprice =~ /\.(\d+)/);
my $decimalplaces = max 2, length($dec);

c126984e Geoffrey Richardson
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 $nodiscount_exact_linetotal = $form->{"qty_$i"} * $sellprice / $price_factor->{factor};
my $nodiscount_linetotal = $form->round_amount($nodiscount_exact_linetotal,2);

my $discount = $nodiscount_linetotal - $linetotal; # is always rounded because $nodiscount_linetotal and $linetotal are rounded

my $discount_round_error = $discount + ($linetotal_exact - $nodiscount_exact_linetotal); # not used

d9c9bc22 Moritz Bunkus
$form->{"netprice_$i"} = $form->round_amount($form->{"qty_$i"} ? ($linetotal / $form->{"qty_$i"}) : 0, 2);

8461199d Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : '';
push @{ $form->{TEMPLATE_ARRAYS}->{netprice_nofmt} }, ($form->{"netprice_$i"} != 0) ? $form->{"netprice_$i"} : '';
d9c9bc22 Moritz Bunkus
$linetotal = ($linetotal != 0) ? $linetotal : '';

8461199d Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{discount} }, ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, 2) : '';
push @{ $form->{TEMPLATE_ARRAYS}->{discount_nofmt} }, ($discount != 0) ? $discount * -1 : '';
push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} }, $form->{"discount_$i"};
d9c9bc22 Moritz Bunkus
$form->{ordtotal} += $linetotal;
54e4131e Moritz Bunkus
$form->{nodiscount_total} += $nodiscount_linetotal;
d9c9bc22 Moritz Bunkus
$form->{discount_total} += $discount;

if ($subtotal_header) {
$discount_subtotal += $linetotal;
$nodiscount_subtotal += $nodiscount_linetotal;
}
54e4131e Moritz Bunkus
if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) {
8461199d Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, $form->format_amount($myconfig, $discount_subtotal, 2);
push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub_nofmt} }, $discount_subtotal;
push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, $form->format_amount($myconfig, $nodiscount_subtotal, 2);
push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub_nofmt} }, $nodiscount_subtotal;
d9c9bc22 Moritz Bunkus
$discount_subtotal = 0;
54e4131e Moritz Bunkus
$nodiscount_subtotal = 0;
d9c9bc22 Moritz Bunkus
$subtotal_header = 0;

54e4131e Moritz Bunkus
} else {
e1a38ef7 Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{$_} }, "" for qw(discount_sub nodiscount_sub discount_sub_nofmt nodiscount_sub_nofmt);
54e4131e Moritz Bunkus
}
d319704a Moritz Bunkus
d9c9bc22 Moritz Bunkus
if (!$form->{"discount_$i"}) {
54e4131e Moritz Bunkus
$nodiscount += $linetotal;
}
d9c9bc22 Moritz Bunkus
fde1df0b Sven Schöling
my $project = $projects_by_id{$form->{"project_id_$i"}} || SL::DB::Project->new;

8461199d Moritz Bunkus
push @{ $form->{TEMPLATE_ARRAYS}->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2);
push @{ $form->{TEMPLATE_ARRAYS}->{linetotal_nofmt} }, $linetotal_exact;
push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_linetotal} }, $form->format_amount($myconfig, $nodiscount_linetotal, 2);
push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_linetotal_nofmt} }, $nodiscount_linetotal;
fde1df0b Sven Schöling
push @{ $form->{TEMPLATE_ARRAYS}->{projectnumber} }, $project->projectnumber;
push @{ $form->{TEMPLATE_ARRAYS}->{projectdescription} }, $project->description;
96d10ecc Moritz Bunkus
79c048aa Niclas Zimmermann
my $lineweight = $form->{"qty_$i"} * $form->{"weight_$i"};
$totalweight += $lineweight;
push @{ $form->{TEMPLATE_ARRAYS}->{weight} }, $form->format_amount($myconfig, $form->{"weight_$i"}, 3);
push @{ $form->{TEMPLATE_ARRAYS}->{weight_nofmt} }, $form->{"weight_$i"};
push @{ $form->{TEMPLATE_ARRAYS}->{lineweight} }, $form->format_amount($myconfig, $lineweight, 3);
push @{ $form->{TEMPLATE_ARRAYS}->{lineweight_nofmt} }, $lineweight;

d319704a Moritz Bunkus
my ($taxamount, $taxbase);
my $taxrate = 0;

9d0ebf28 Moritz Bunkus
map { $taxrate += $form->{"${_}_rate"} } split(/ /, $form->{"taxaccounts_$i"});
d319704a Moritz Bunkus
if ($form->{taxincluded}) {

# calculate tax
$taxamount = $linetotal * $taxrate / (1 + $taxrate);
$taxbase = $linetotal / (1 + $taxrate);
} else {
$taxamount = $linetotal * $taxrate;
$taxbase = $linetotal;
}

if ($taxamount != 0) {
eeb560af Moritz Bunkus
foreach my $accno (split / /, $form->{"taxaccounts_$i"}) {
$taxaccounts{$accno} += $taxamount * $form->{"${accno}_rate"} / $taxrate;
$taxbase{$accno} += $taxbase;
d319704a Moritz Bunkus
}
}

081a4f97 Moritz Bunkus
$tax_rate = $taxrate * 100;
9c63c160 Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{tax_rate} }, qq|$tax_rate|);
eb8a578d Stephan Köhler
d319704a Moritz Bunkus
if ($form->{"assembly_$i"}) {
$sameitem = "";

# get parts and push them onto the stack
my $sortorder = "";
if ($form->{groupitems}) {
90bb521a Moritz Bunkus
$sortorder = qq|ORDER BY pg.partsgroup, a.oid|;
d319704a Moritz Bunkus
} else {
90bb521a Moritz Bunkus
$sortorder = qq|ORDER BY a.oid|;
d319704a Moritz Bunkus
}

9d0ebf28 Moritz Bunkus
$query = qq|SELECT p.partnumber, p.description, p.unit, a.qty, | .
c09536f4 Sven Schöling
qq|pg.partsgroup | .
qq|FROM assembly a | .
qq| JOIN parts p ON (a.parts_id = p.id) | .
qq| LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | .
qq| WHERE a.bom = '1' | .
qq| AND a.id = ? | . $sortorder;
@values = ($form->{"id_$i"});
d319704a Moritz Bunkus
$sth = $dbh->prepare($query);
9d0ebf28 Moritz Bunkus
$sth->execute(@values) || $form->dberror($query);
d319704a Moritz Bunkus
90daea72 Sven Schöling
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
d319704a Moritz Bunkus
if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
9c63c160 Moritz Bunkus
map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
d319704a Moritz Bunkus
$sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
9c63c160 Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $sameitem);
d319704a Moritz Bunkus
}

9c63c160 Moritz Bunkus
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));
d319704a Moritz Bunkus
}
$sth->finish;
}

d729e328 Sven Schöling
push @{ $form->{TEMPLATE_ARRAYS}->{"ic_cvar_$_->{name}"} },
CVar->format_to_template(CVar->parse($form->{"ic_cvar_$_->{name}_$i"}, $_), $_)
for @{ $ic_cvar_configs };
fde1df0b Sven Schöling
push @{ $form->{TEMPLATE_ARRAYS}->{"project_cvar_" . $_->config->name} }, $_->value_as_text for @{ $project->cvars_by_config };
d319704a Moritz Bunkus
}
}

79c048aa Niclas Zimmermann
$form->{totalweight} = $form->format_amount($myconfig, $totalweight, 3);
$form->{totalweight_nofmt} = $totalweight;
fe6275f8 Niclas Zimmermann
my $defaults = AM->get_defaults();
$form->{weightunit} = $defaults->{weightunit};
79c048aa Niclas Zimmermann
d319704a Moritz Bunkus
my $tax = 0;
foreach $item (sort keys %taxaccounts) {
96d10ecc Moritz Bunkus
$tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
d319704a Moritz Bunkus
9c63c160 Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
8461199d Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{taxbase_nofmt} }, $taxbase{$item});
9c63c160 Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
8461199d Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{tax_nofmt} }, $taxamount);
9c63c160 Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
8461199d Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate_nofmt} }, $form->{"${item}_rate"} * 100);
9c63c160 Moritz Bunkus
push(@{ $form->{TEMPLATE_ARRAYS}->{taxnumber} }, $form->{"${item}_taxnumber"});
e90048c8 Bernd Bleßmann
my $tax_obj = SL::DB::Manager::Tax->find_by(taxnumber => $form->{"${item}_taxnumber"});
ed7a0c4a Sven Schöling
my $description = $tax_obj ? $tax_obj->translated_attribute('taxdescription', $form->{language_id}, 0) : '';
e90048c8 Bernd Bleßmann
push(@{ $form->{TEMPLATE_ARRAYS}->{taxdescription} }, $description . q{ } . 100 * $form->{"${item}_rate"} . q{%});
d319704a Moritz Bunkus
}
d9c9bc22 Moritz Bunkus
54e4131e Moritz Bunkus
$form->{nodiscount_subtotal} = $form->format_amount($myconfig, $form->{nodiscount_total}, 2);
d9c9bc22 Moritz Bunkus
$form->{discount_total} = $form->format_amount($myconfig, $form->{discount_total}, 2);
$form->{nodiscount} = $form->format_amount($myconfig, $nodiscount, 2);
$form->{yesdiscount} = $form->format_amount($myconfig, $form->{nodiscount_total} - $nodiscount, 2);
d319704a Moritz Bunkus
92b2f11d Thomas Kasulke
if($form->{taxincluded}) {
8461199d Moritz Bunkus
$form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal} - $tax, 2);
1e26c0d4 Wulf Coulmann
$form->{subtotal_nofmt} = $form->{ordtotal} - $tax;
d9c9bc22 Moritz Bunkus
} else {
8461199d Moritz Bunkus
$form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
1e26c0d4 Wulf Coulmann
$form->{subtotal_nofmt} = $form->{ordtotal};
92b2f11d Thomas Kasulke
}
d9c9bc22 Moritz Bunkus
$form->{ordtotal} = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
d319704a Moritz Bunkus
# format amounts
d9c9bc22 Moritz Bunkus
$form->{quototal} = $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
d319704a Moritz Bunkus
54e4131e Moritz Bunkus
if ($form->{type} =~ /_quotation/) {
$form->set_payment_options($myconfig, $form->{quodate});
} else {
$form->set_payment_options($myconfig, $form->{orddate});
}

d319704a Moritz Bunkus
$form->{username} = $myconfig->{name};

$dbh->disconnect;

03d3d025 Bernd Bleßmann
$form->{delivery_term} = SL::DB::Manager::DeliveryTerm->find_by(id => $form->{delivery_term_id} || undef);
002517b4 Bernd Bleßmann
$form->{delivery_term}->description_long($form->{delivery_term}->translated_attribute('description_long', $form->{language_id})) if $form->{delivery_term} && $form->{language_id};
03d3d025 Bernd Bleßmann
dcb37275 Sven Schöling
$::form->{order} = SL::DB::Manager::Order->find_by(id => $::form->{id});

d319704a Moritz Bunkus
$main::lxdebug->leave_sub();
}

sub project_description {
$main::lxdebug->enter_sub();

my ($self, $dbh, $id) = @_;

9d0ebf28 Moritz Bunkus
my $query = qq|SELECT description FROM project WHERE id = ?|;
90daea72 Sven Schöling
my ($value) = selectrow_query($main::form, $dbh, $query, $id);
d319704a Moritz Bunkus
$main::lxdebug->leave_sub();

9d0ebf28 Moritz Bunkus
return $value;
d319704a Moritz Bunkus
}

1;
66022cbd Sven Schöling
__END__

=head1 NAME

OE.pm - Order entry module

=head1 DESCRIPTION

OE.pm is part of the OE module. OE is responsible for sales and purchase orders, as well as sales quotations and purchase requests. This file abstracts the database tables C<oe> and C<orderitems>.

=head1 FUNCTIONS

=over 4

=item retrieve_simple PARAMS

simple OE retrieval by id. does not look up customer, vendor, units or any other stuff. only oe and orderitems.

my $order = retrieve_simple(id => 2);

$order => {
%_OE_CONTENT,
orderitems => [
%_ORDERITEM_ROW_1,
%_ORDERITEM_ROW_2,
...
]
}

=back

=cut