Projekt

Allgemein

Profil

Herunterladen (28 KB) Statistiken
| Zweig: | Markierung: | Revision:
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) 2001
#
# 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
f7b15d43 Christian Wittmer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1335, USA.
d319704a Moritz Bunkus
#======================================================================
#
# General ledger backend code
#
# CHANGE LOG:
# DS. 2000-07-04 Created
# DS. 2001-06-12 Changed relations from accno to chart_id
#
#======================================================================

package GL;

ad635c66 Moritz Bunkus
use List::Util qw(first);

f3edd66d Stephan Köhler
use Data::Dumper;
7e7a1369 Sven Schöling
use SL::DATEV qw(:CONSTANTS);
0437033e Moritz Bunkus
use SL::DBUtils;
ad635c66 Moritz Bunkus
use SL::DB::Chart;
c954dea7 Moritz Bunkus
use SL::DB::Draft;
b3e58871 Moritz Bunkus
use SL::Util qw(trim);
09372651 Sven Schöling
use SL::DB;
f3edd66d Stephan Köhler
76c486e3 Sven Schöling
use strict;

d319704a Moritz Bunkus
sub delete_transaction {
my ($self, $myconfig, $form) = @_;
2ae62d30 Stephan Köhler
$main::lxdebug->enter_sub();
d319704a Moritz Bunkus
c078749a Bernd Bleßmann
SL::DB->client->with_transaction(sub {
09372651 Sven Schöling
do_query($form, SL::DB->client->dbh, qq|DELETE FROM gl WHERE id = ?|, conv_i($form->{id}));
6b23fb21 Sven Schöling
1;
}) or do { die SL::DB->client->error };
d319704a Moritz Bunkus
$main::lxdebug->leave_sub();
09372651 Sven Schöling
}
d319704a Moritz Bunkus
09372651 Sven Schöling
sub post_transaction {
my ($self, $myconfig, $form) = @_;
$main::lxdebug->enter_sub();

my $rc = SL::DB->client->with_transaction(\&_post_transaction, $self, $myconfig, $form);
2ae62d30 Stephan Köhler
09372651 Sven Schöling
$::lxdebug->leave_sub;
return $rc;
d319704a Moritz Bunkus
}

09372651 Sven Schöling
sub _post_transaction {
d319704a Moritz Bunkus
my ($self, $myconfig, $form) = @_;
2ae62d30 Stephan Köhler
$main::lxdebug->enter_sub();
d319704a Moritz Bunkus
my ($debit, $credit) = (0, 0);
my $project_id;

my $i;

09372651 Sven Schöling
my $dbh = SL::DB->client->dbh;
d319704a Moritz Bunkus
# post the transaction
# make up a unique handle and store in reference field
# then retrieve the record based on the unique handle to get the id
# replace the reference field with the actual variable
# add records to acc_trans

# if there is a $form->{id} replace the old transaction
# delete all acc_trans entries and add the new ones

if (!$form->{taxincluded}) {
$form->{taxincluded} = 0;
}

76c486e3 Sven Schöling
my ($query, $sth, @values, $taxkey, $rate, $posted);
2ae62d30 Stephan Köhler
d319704a Moritz Bunkus
if ($form->{id}) {

# delete individual transactions
05fea791 Moritz Bunkus
$query = qq|DELETE FROM acc_trans WHERE trans_id = ?|;
@values = (conv_i($form->{id}));
do_query($form, $dbh, $query, @values);
d319704a Moritz Bunkus
} else {
05fea791 Moritz Bunkus
$query = qq|SELECT nextval('glid')|;
($form->{id}) = selectrow_query($form, $dbh, $query);
d319704a Moritz Bunkus
05fea791 Moritz Bunkus
$query =
qq|INSERT INTO gl (id, employee_id) | .
qq|VALUES (?, (SELECT id FROM employee WHERE login = ?))|;
4bd1e2f8 Sven Schöling
@values = ($form->{id}, $::myconfig{login});
05fea791 Moritz Bunkus
do_query($form, $dbh, $query, @values);
d319704a Moritz Bunkus
}
2ae62d30 Stephan Köhler
e2305bab Philip Reetz
$form->{ob_transaction} *= 1;
$form->{cb_transaction} *= 1;

05fea791 Moritz Bunkus
$query =
qq|UPDATE gl SET
reference = ?, description = ?, notes = ?,
36666afc Bernd Bleßmann
transdate = ?, deliverydate = ?, department_id = ?, taxincluded = ?,
e2305bab Philip Reetz
storno = ?, storno_id = ?, ob_transaction = ?, cb_transaction = ?
05fea791 Moritz Bunkus
WHERE id = ?|;
d319704a Moritz Bunkus
05fea791 Moritz Bunkus
@values = ($form->{reference}, $form->{description}, $form->{notes},
36666afc Bernd Bleßmann
conv_date($form->{transdate}), conv_date($form->{deliverydate}), conv_i($form->{department_id}), $form->{taxincluded} ? 't' : 'f',
e2305bab Philip Reetz
$form->{storno} ? 't' : 'f', conv_i($form->{storno_id}), $form->{ob_transaction} ? 't' : 'f', $form->{cb_transaction} ? 't' : 'f',
05fea791 Moritz Bunkus
conv_i($form->{id}));
do_query($form, $dbh, $query, @values);
d319704a Moritz Bunkus
# insert acc_trans transactions
2ae62d30 Stephan Köhler
for $i (1 .. $form->{rowcount}) {
05fea791 Moritz Bunkus
($form->{"tax_id_$i"}) = split(/--/, $form->{"taxchart_$i"});
744cfc20 Philip Reetz
if ($form->{"tax_id_$i"} ne "") {
05fea791 Moritz Bunkus
$query = qq|SELECT taxkey, rate FROM tax WHERE id = ?|;
($taxkey, $rate) = selectrow_query($form, $dbh, $query, conv_i($form->{"tax_id_$i"}));
744cfc20 Philip Reetz
}

d319704a Moritz Bunkus
my $amount = 0;
2ae62d30 Stephan Köhler
my $debit = $form->{"debit_$i"};
my $credit = $form->{"credit_$i"};
my $tax = $form->{"tax_$i"};

if ($credit) {
d319704a Moritz Bunkus
$amount = $credit;
2ae62d30 Stephan Köhler
$posted = 0;
d319704a Moritz Bunkus
}
2ae62d30 Stephan Köhler
if ($debit) {
d319704a Moritz Bunkus
$amount = $debit * -1;
2ae62d30 Stephan Köhler
$tax = $tax * -1;
$posted = 0;
d319704a Moritz Bunkus
}

0437033e Moritz Bunkus
$project_id = conv_i($form->{"project_id_$i"});

2ae62d30 Stephan Köhler
# if there is an amount, add the record
if ($amount != 0) {
05fea791 Moritz Bunkus
$query =
qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
d1408ca1 Niclas Zimmermann
source, memo, project_id, taxkey, ob_transaction, cb_transaction, tax_id, chart_link)
ad635c66 Moritz Bunkus
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT link FROM chart WHERE id = ?))|;
@values = (conv_i($form->{id}), $form->{"accno_id_$i"}, $amount, conv_date($form->{transdate}),
$form->{"source_$i"}, $form->{"memo_$i"}, $project_id, $taxkey, $form->{ob_transaction} ? 't' : 'f', $form->{cb_transaction} ? 't' : 'f', conv_i($form->{"tax_id_$i"}), $form->{"accno_id_$i"});
05fea791 Moritz Bunkus
do_query($form, $dbh, $query, @values);
d319704a Moritz Bunkus
}

2ae62d30 Stephan Köhler
if ($tax != 0) {
# add taxentry
05fea791 Moritz Bunkus
$query =
qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
d1408ca1 Niclas Zimmermann
source, memo, project_id, taxkey, tax_id, chart_link)
05fea791 Moritz Bunkus
VALUES (?, (SELECT chart_id FROM tax WHERE id = ?),
0a7acc87 Niclas Zimmermann
?, ?, ?, ?, ?, ?, ?, (SELECT link
FROM chart
WHERE id = (SELECT chart_id
FROM tax
3af5e2e0 Niclas Zimmermann
WHERE id = ?)))|;
05fea791 Moritz Bunkus
@values = (conv_i($form->{id}), conv_i($form->{"tax_id_$i"}),
$tax, conv_date($form->{transdate}), $form->{"source_$i"},
d1408ca1 Niclas Zimmermann
$form->{"memo_$i"}, $project_id, $taxkey, conv_i($form->{"tax_id_$i"}), conv_i($form->{"tax_id_$i"}));
05fea791 Moritz Bunkus
do_query($form, $dbh, $query, @values);
2ae62d30 Stephan Köhler
}
d319704a Moritz Bunkus
}

dc7f3c9a Moritz Bunkus
if ($form->{storno} && $form->{storno_id}) {
do_query($form, $dbh, qq|UPDATE gl SET storno = 't' WHERE id = ?|, conv_i($form->{storno_id}));
}

c954dea7 Moritz Bunkus
if ($form->{draft_id}) {
SL::DB::Manager::Draft->delete_all(where => [ id => delete($form->{draft_id}) ]);
}

7e7a1369 Sven Schöling
# safety check datev export
3424bf80 Bernd Bleßmann
if ($::instance_conf->get_datev_check_on_gl_transaction) {
7e7a1369 Sven Schöling
0a64ac3d Geoffrey Richardson
# create datev object
7e7a1369 Sven Schöling
my $datev = SL::DATEV->new(
dbh => $dbh,
e04c32d3 Niclas Zimmermann
trans_id => $form->{id},
7e7a1369 Sven Schöling
);

0a64ac3d Geoffrey Richardson
$datev->generate_datev_data;
7e7a1369 Sven Schöling
if ($datev->errors) {
die join "\n", $::locale->text('DATEV check returned errors:'), $datev->errors;
}
}

09372651 Sven Schöling
return 1;
d319704a Moritz Bunkus
}

sub all_transactions {
my ($self, $myconfig, $form) = @_;
2ae62d30 Stephan Köhler
$main::lxdebug->enter_sub();
d319704a Moritz Bunkus
20fb5523 Sven Schöling
my $dbh = SL::DB->client->dbh;
76c486e3 Sven Schöling
my ($query, $sth, $source, $null, $space);
d319704a Moritz Bunkus
my ($glwhere, $arwhere, $apwhere) = ("1 = 1", "1 = 1", "1 = 1");
05fea791 Moritz Bunkus
my (@glvalues, @arvalues, @apvalues);
d319704a Moritz Bunkus
if ($form->{reference}) {
05fea791 Moritz Bunkus
$glwhere .= qq| AND g.reference ILIKE ?|;
$arwhere .= qq| AND a.invnumber ILIKE ?|;
$apwhere .= qq| AND a.invnumber ILIKE ?|;
bed19453 Moritz Bunkus
push(@glvalues, like($form->{reference}));
push(@arvalues, like($form->{reference}));
push(@apvalues, like($form->{reference}));
d319704a Moritz Bunkus
}
05fea791 Moritz Bunkus
f0747a2f Geoffrey Richardson
if ($form->{department_id}) {
05fea791 Moritz Bunkus
$glwhere .= qq| AND g.department_id = ?|;
$arwhere .= qq| AND a.department_id = ?|;
$apwhere .= qq| AND a.department_id = ?|;
f0747a2f Geoffrey Richardson
push(@glvalues, $form->{department_id});
push(@arvalues, $form->{department_id});
push(@apvalues, $form->{department_id});
d319704a Moritz Bunkus
}

if ($form->{source}) {
6c7334b3 Philip Reetz
$glwhere .= " AND ac.trans_id IN (SELECT trans_id from acc_trans WHERE source ILIKE ?)";
$arwhere .= " AND ac.trans_id IN (SELECT trans_id from acc_trans WHERE source ILIKE ?)";
$apwhere .= " AND ac.trans_id IN (SELECT trans_id from acc_trans WHERE source ILIKE ?)";
bed19453 Moritz Bunkus
push(@glvalues, like($form->{source}));
push(@arvalues, like($form->{source}));
push(@apvalues, like($form->{source}));
d319704a Moritz Bunkus
}
05fea791 Moritz Bunkus
4000272e Jan Büren
# default Datumseinschränkung falls nicht oder falsch übergeben (sollte nie passieren)
$form->{datesort} = 'transdate' unless $form->{datesort} =~ /^(transdate|gldate)$/;

b3e58871 Moritz Bunkus
if (trim($form->{datefrom})) {
4000272e Jan Büren
$glwhere .= " AND ac.$form->{datesort} >= ?";
$arwhere .= " AND ac.$form->{datesort} >= ?";
$apwhere .= " AND ac.$form->{datesort} >= ?";
b3e58871 Moritz Bunkus
push(@glvalues, trim($form->{datefrom}));
push(@arvalues, trim($form->{datefrom}));
push(@apvalues, trim($form->{datefrom}));
d319704a Moritz Bunkus
}
05fea791 Moritz Bunkus
b3e58871 Moritz Bunkus
if (trim($form->{dateto})) {
4000272e Jan Büren
$glwhere .= " AND ac.$form->{datesort} <= ?";
$arwhere .= " AND ac.$form->{datesort} <= ?";
$apwhere .= " AND ac.$form->{datesort} <= ?";
b3e58871 Moritz Bunkus
push(@glvalues, trim($form->{dateto}));
push(@arvalues, trim($form->{dateto}));
push(@apvalues, trim($form->{dateto}));
d319704a Moritz Bunkus
}
05fea791 Moritz Bunkus
b3e58871 Moritz Bunkus
if (trim($form->{description})) {
05fea791 Moritz Bunkus
$glwhere .= " AND g.description ILIKE ?";
$arwhere .= " AND ct.name ILIKE ?";
$apwhere .= " AND ct.name ILIKE ?";
bed19453 Moritz Bunkus
push(@glvalues, like($form->{description}));
push(@arvalues, like($form->{description}));
push(@apvalues, like($form->{description}));
d319704a Moritz Bunkus
}
c2796317 Bernd Bleßmann
3f4f01dc Moritz Bunkus
if ($form->{employee_id}) {
4000272e Jan Büren
$glwhere .= " AND g.employee_id = ? ";
$arwhere .= " AND a.employee_id = ? ";
$apwhere .= " AND a.employee_id = ? ";
push(@glvalues, conv_i($form->{employee_id}));
push(@arvalues, conv_i($form->{employee_id}));
push(@apvalues, conv_i($form->{employee_id}));
}
05fea791 Moritz Bunkus
b3e58871 Moritz Bunkus
if (trim($form->{notes})) {
05fea791 Moritz Bunkus
$glwhere .= " AND g.notes ILIKE ?";
$arwhere .= " AND a.notes ILIKE ?";
$apwhere .= " AND a.notes ILIKE ?";
bed19453 Moritz Bunkus
push(@glvalues, like($form->{notes}));
push(@arvalues, like($form->{notes}));
push(@apvalues, like($form->{notes}));
d319704a Moritz Bunkus
}
05fea791 Moritz Bunkus
d319704a Moritz Bunkus
if ($form->{accno}) {
$glwhere .= " AND c.accno = '$form->{accno}'";
$arwhere .= " AND c.accno = '$form->{accno}'";
$apwhere .= " AND c.accno = '$form->{accno}'";
}
05fea791 Moritz Bunkus
d319704a Moritz Bunkus
if ($form->{category} ne 'X') {
eb693e82 Moritz Bunkus
$glwhere .= qq| AND g.id in (SELECT trans_id FROM acc_trans ac2 WHERE ac2.chart_id IN (SELECT id FROM chart c2 WHERE c2.category = ?))|;
$arwhere .= qq| AND a.id in (SELECT trans_id FROM acc_trans ac2 WHERE ac2.chart_id IN (SELECT id FROM chart c2 WHERE c2.category = ?))|;
$apwhere .= qq| AND a.id in (SELECT trans_id FROM acc_trans ac2 WHERE ac2.chart_id IN (SELECT id FROM chart c2 WHERE c2.category = ?))|;
05fea791 Moritz Bunkus
push(@glvalues, $form->{category});
push(@arvalues, $form->{category});
push(@apvalues, $form->{category});
d319704a Moritz Bunkus
}
05fea791 Moritz Bunkus
134ecd71 Moritz Bunkus
if ($form->{project_id}) {
05fea791 Moritz Bunkus
$glwhere .= qq| AND g.id IN (SELECT DISTINCT trans_id FROM acc_trans WHERE project_id = ?)|;
134ecd71 Moritz Bunkus
$arwhere .=
05fea791 Moritz Bunkus
qq| AND ((a.globalproject_id = ?) OR
(a.id IN (SELECT DISTINCT trans_id FROM acc_trans WHERE project_id = ?)))|;
134ecd71 Moritz Bunkus
$apwhere .=
05fea791 Moritz Bunkus
qq| AND ((a.globalproject_id = ?) OR
(a.id IN (SELECT DISTINCT trans_id FROM acc_trans WHERE project_id = ?)))|;
my $project_id = conv_i($form->{project_id});
push(@glvalues, $project_id);
push(@arvalues, $project_id, $project_id);
push(@apvalues, $project_id, $project_id);
134ecd71 Moritz Bunkus
}

76c486e3 Sven Schöling
my ($project_columns, $project_join);
134ecd71 Moritz Bunkus
if ($form->{"l_projectnumbers"}) {
05fea791 Moritz Bunkus
$project_columns = qq|, ac.project_id, pr.projectnumber|;
$project_join = qq|LEFT JOIN project pr ON (ac.project_id = pr.id)|;
134ecd71 Moritz Bunkus
}
d319704a Moritz Bunkus
if ($form->{accno}) {
# get category for account
05fea791 Moritz Bunkus
$query = qq|SELECT category FROM chart WHERE accno = ?|;
($form->{ml}) = selectrow_query($form, $dbh, $query, $form->{accno});
d319704a Moritz Bunkus
if ($form->{datefrom}) {
05fea791 Moritz Bunkus
$query =
qq|SELECT SUM(ac.amount)
FROM acc_trans ac
LEFT JOIN chart c ON (ac.chart_id = c.id)
4000272e Jan Büren
WHERE (c.accno = ?) AND (ac.$form->{datesort} < ?)|;
05fea791 Moritz Bunkus
($form->{balance}) = selectrow_query($form, $dbh, $query, $form->{accno}, conv_date($form->{datefrom}));
d319704a Moritz Bunkus
}
}

4b48d335 Moritz Bunkus
my %sort_columns = (
'id' => [ qw(id) ],
'transdate' => [ qw(transdate id) ],
4000272e Jan Büren
'gldate' => [ qw(gldate id) ],
4b48d335 Moritz Bunkus
'reference' => [ qw(lower_reference id) ],
'description' => [ qw(lower_description id) ],
'accno' => [ qw(accno transdate id) ],
);
my %lowered_columns = (
'reference' => { 'gl' => 'g.reference', 'arap' => 'a.invnumber', },
'source' => { 'gl' => 'ac.source', 'arap' => 'ac.source', },
'description' => { 'gl' => 'g.description', 'arap' => 'ct.name', },
);
c2796317 Bernd Bleßmann
4000272e Jan Büren
# sortdir = sort direction (ascending or descending)
4b48d335 Moritz Bunkus
my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
4000272e Jan Büren
my $sortkey = $sort_columns{$form->{sort}} ? $form->{sort} : $form->{datesort}; # default used to be transdate
4b48d335 Moritz Bunkus
my $sortorder = join ', ', map { "$_ $sortdir" } @{ $sort_columns{$sortkey} };

my %columns_for_sorting = ( 'gl' => '', 'arap' => '', );
foreach my $spec (@{ $sort_columns{$sortkey} }) {
next if ($spec !~ m/^lower_(.*)$/);

my $column = $1;
map { $columns_for_sorting{$_} .= sprintf(', lower(%s) AS lower_%s', $lowered_columns{$column}->{$_}, $column) } qw(gl arap);
081a4f97 Moritz Bunkus
}

76c486e3 Sven Schöling
$query =
05fea791 Moritz Bunkus
qq|SELECT
90bb521a Moritz Bunkus
ac.acc_trans_id, g.id, 'gl' AS type, FALSE AS invoice, g.reference, ac.taxkey, c.link,
4000272e Jan Büren
g.description, ac.transdate, ac.gldate, ac.source, ac.trans_id,
ac.amount, c.accno, g.notes, t.chart_id,
CASE WHEN (COALESCE(e.name, '') = '') THEN e.login ELSE e.name END AS employee
05fea791 Moritz Bunkus
$project_columns
4b48d335 Moritz Bunkus
$columns_for_sorting{gl}
3286128e Jan Büren
FROM gl g
LEFT JOIN employee e ON (g.employee_id = e.id),
acc_trans ac $project_join, chart c
05fea791 Moritz Bunkus
LEFT JOIN tax t ON (t.chart_id = c.id)
WHERE $glwhere
AND (ac.chart_id = c.id)
AND (g.id = ac.trans_id)

UNION

6ff01fdb Moritz Bunkus
SELECT ac.acc_trans_id, a.id, 'ar' AS type, a.invoice, a.invnumber, ac.taxkey, c.link,
4000272e Jan Büren
ct.name, ac.transdate, ac.gldate, ac.source, ac.trans_id,
ac.amount, c.accno, a.notes, t.chart_id,
CASE WHEN (COALESCE(e.name, '') = '') THEN e.login ELSE e.name END AS employee
05fea791 Moritz Bunkus
$project_columns
4b48d335 Moritz Bunkus
$columns_for_sorting{arap}
3286128e Jan Büren
FROM ar a
LEFT JOIN employee e ON (a.employee_id = e.id),
acc_trans ac $project_join, customer ct, chart c
05fea791 Moritz Bunkus
LEFT JOIN tax t ON (t.chart_id=c.id)
WHERE $arwhere
AND (ac.chart_id = c.id)
AND (a.customer_id = ct.id)
AND (a.id = ac.trans_id)

UNION

6ff01fdb Moritz Bunkus
SELECT ac.acc_trans_id, a.id, 'ap' AS type, a.invoice, a.invnumber, ac.taxkey, c.link,
4000272e Jan Büren
ct.name, ac.transdate, ac.gldate, ac.source, ac.trans_id,
ac.amount, c.accno, a.notes, t.chart_id,
CASE WHEN (COALESCE(e.name, '') = '') THEN e.login ELSE e.name END AS employee
05fea791 Moritz Bunkus
$project_columns
4b48d335 Moritz Bunkus
$columns_for_sorting{arap}
3286128e Jan Büren
FROM ap a
LEFT JOIN employee e ON (a.employee_id = e.id),
acc_trans ac $project_join, vendor ct, chart c
05fea791 Moritz Bunkus
LEFT JOIN tax t ON (t.chart_id=c.id)
WHERE $apwhere
AND (ac.chart_id = c.id)
AND (a.vendor_id = ct.id)
AND (a.id = ac.trans_id)

6ff01fdb Moritz Bunkus
ORDER BY $sortorder, acc_trans_id $sortdir|;
4000272e Jan Büren
# ORDER BY gldate DESC, id DESC, acc_trans_id DESC
05fea791 Moritz Bunkus
my @values = (@glvalues, @arvalues, @apvalues);
d5488529 Moritz Bunkus
# Show all $query in Debuglevel LXDebug::QUERY
76c486e3 Sven Schöling
my $callingdetails = (caller (0))[3];
dump_query(LXDebug->QUERY(), "$callingdetails", $query, @values);
05fea791 Moritz Bunkus
$sth = prepare_execute_query($form, $dbh, $query, @values);
081a4f97 Moritz Bunkus
my $trans_id = "";
42fc1e70 Stephan Köhler
my $trans_id2 = "";
76c486e3 Sven Schöling
my $balance;
d5488529 Moritz Bunkus
322b14b7 Moritz Bunkus
my ($i, $j, $k, $l, $ref, $ref2);

05fea791 Moritz Bunkus
$form->{GL} = [];
76c486e3 Sven Schöling
while (my $ref0 = $sth->fetchrow_hashref("NAME_lc")) {
05fea791 Moritz Bunkus
42fc1e70 Stephan Köhler
$trans_id = $ref0->{id};
05fea791 Moritz Bunkus
6c7334b3 Philip Reetz
my $source = $ref0->{source};
undef($ref0->{source});

d5488529 Moritz Bunkus
if ($trans_id != $trans_id2) { # first line of a booking
05fea791 Moritz Bunkus
42fc1e70 Stephan Köhler
if ($trans_id2) {
05fea791 Moritz Bunkus
push(@{ $form->{GL} }, $ref);
42fc1e70 Stephan Köhler
$balance = 0;
d319704a Moritz Bunkus
}
05fea791 Moritz Bunkus
081a4f97 Moritz Bunkus
$ref = $ref0;
42fc1e70 Stephan Köhler
$trans_id2 = $ref->{id};
081a4f97 Moritz Bunkus
42fc1e70 Stephan Köhler
# gl
if ($ref->{type} eq "gl") {
$ref->{module} = "gl";
d319704a Moritz Bunkus
}
081a4f97 Moritz Bunkus
42fc1e70 Stephan Köhler
# ap
if ($ref->{type} eq "ap") {
if ($ref->{invoice}) {
$ref->{module} = "ir";
} else {
$ref->{module} = "ap";
}
d319704a Moritz Bunkus
}
081a4f97 Moritz Bunkus
42fc1e70 Stephan Köhler
# ar
if ($ref->{type} eq "ar") {
if ($ref->{invoice}) {
$ref->{module} = "is";
} else {
$ref->{module} = "ar";
}
}
134ecd71 Moritz Bunkus
$ref->{"projectnumbers"} = {};
$ref->{"projectnumbers"}->{$ref->{"projectnumber"}} = 1 if ($ref->{"projectnumber"});

42fc1e70 Stephan Köhler
$balance = $ref->{amount};
05fea791 Moritz Bunkus
# Linenumbers of General Ledger
d5488529 Moritz Bunkus
$k = 0; # Debit # AP # Soll
$l = 0; # Credit # AR # Haben
$i = 0; # Debit Tax # AP_tax # VSt
$j = 0; # Credit Tax # AR_tax # USt
05fea791 Moritz Bunkus
d5488529 Moritz Bunkus
if ($ref->{chart_id} > 0) { # all tax accounts first line, no line increasing
if ($ref->{amount} < 0) {
if ($ref->{link} =~ /AR_tax/) {
$ref->{credit_tax}{$j} = $ref->{amount};
05fea791 Moritz Bunkus
$ref->{credit_tax_accno}{$j} = $ref->{accno};
6c7334b3 Philip Reetz
}
d5488529 Moritz Bunkus
if ($ref->{link} =~ /AP_tax/) {
$ref->{debit_tax}{$i} = $ref->{amount} * -1;
05fea791 Moritz Bunkus
$ref->{debit_tax_accno}{$i} = $ref->{accno};
d5488529 Moritz Bunkus
}
42fc1e70 Stephan Köhler
} else {
d5488529 Moritz Bunkus
if ($ref->{link} =~ /AR_tax/) {
$ref->{credit_tax}{$j} = $ref->{amount};
05fea791 Moritz Bunkus
$ref->{credit_tax_accno}{$j} = $ref->{accno};
d5488529 Moritz Bunkus
}
if ($ref->{link} =~ /AP_tax/) {
$ref->{debit_tax}{$i} = $ref->{amount} * -1;
05fea791 Moritz Bunkus
$ref->{debit_tax_accno}{$i} = $ref->{accno};
d5488529 Moritz Bunkus
}
}
} else { #all other accounts first line
6c7334b3 Philip Reetz
d5488529 Moritz Bunkus
if ($ref->{amount} < 0) {
42fc1e70 Stephan Köhler
$ref->{debit}{$k} = $ref->{amount} * -1;
$ref->{debit_accno}{$k} = $ref->{accno};
$ref->{debit_taxkey}{$k} = $ref->{taxkey};
f4a48b30 Moritz Bunkus
$ref->{ac_transdate}{$k} = $ref->{transdate};
6c7334b3 Philip Reetz
$ref->{source}{$k} = $source;
42fc1e70 Stephan Köhler
} else {
d5488529 Moritz Bunkus
$ref->{credit}{$l} = $ref->{amount} * 1;
42fc1e70 Stephan Köhler
$ref->{credit_accno}{$l} = $ref->{accno};
$ref->{credit_taxkey}{$l} = $ref->{taxkey};
f4a48b30 Moritz Bunkus
$ref->{ac_transdate}{$l} = $ref->{transdate};
6c7334b3 Philip Reetz
$ref->{source}{$l} = $source;
42fc1e70 Stephan Köhler
}
d319704a Moritz Bunkus
}
d5488529 Moritz Bunkus
} else { # following lines of a booking, line increasing

081a4f97 Moritz Bunkus
$ref2 = $ref0;
76c486e3 Sven Schöling
# $trans_old = $trans_id2; # doesn't seem to be used anymore
42fc1e70 Stephan Köhler
$trans_id2 = $ref2->{id};
05fea791 Moritz Bunkus
081a4f97 Moritz Bunkus
$balance =
(int($balance * 100000) + int(100000 * $ref2->{amount})) / 100000;
d5488529 Moritz Bunkus
134ecd71 Moritz Bunkus
$ref->{"projectnumbers"}->{$ref2->{"projectnumber"}} = 1 if ($ref2->{"projectnumber"});
d5488529 Moritz Bunkus
if ($ref2->{chart_id} > 0) { # all tax accounts, following lines
if ($ref2->{amount} < 0) {
if ($ref2->{link} =~ /AR_tax/) {
if ($ref->{credit_tax_accno}{$j} ne "") {
$j++;
}
$ref->{credit_tax}{$j} = $ref2->{amount};
05fea791 Moritz Bunkus
$ref->{credit_tax_accno}{$j} = $ref2->{accno};
d5488529 Moritz Bunkus
}
if ($ref2->{link} =~ /AP_tax/) {
if ($ref->{debit_tax_accno}{$i} ne "") {
$i++;
}
$ref->{debit_tax}{$i} = $ref2->{amount} * -1;
05fea791 Moritz Bunkus
$ref->{debit_tax_accno}{$i} = $ref2->{accno};
42fc1e70 Stephan Köhler
}
081a4f97 Moritz Bunkus
} else {
d5488529 Moritz Bunkus
if ($ref2->{link} =~ /AR_tax/) {
if ($ref->{credit_tax_accno}{$j} ne "") {
$j++;
}
$ref->{credit_tax}{$j} = $ref2->{amount};
05fea791 Moritz Bunkus
$ref->{credit_tax_accno}{$j} = $ref2->{accno};
d5488529 Moritz Bunkus
}
if ($ref2->{link} =~ /AP_tax/) {
if ($ref->{debit_tax_accno}{$i} ne "") {
$i++;
}
$ref->{debit_tax}{$i} = $ref2->{amount} * -1;
05fea791 Moritz Bunkus
$ref->{debit_tax_accno}{$i} = $ref2->{accno};
d5488529 Moritz Bunkus
}
}
} else { # all other accounts, following lines
if ($ref2->{amount} < 0) {
081a4f97 Moritz Bunkus
if ($ref->{debit_accno}{$k} ne "") {
$k++;
}
6c7334b3 Philip Reetz
if ($ref->{source}{$k} ne "") {
$space = " | ";
} else {
$space = "";
}
d5488529 Moritz Bunkus
$ref->{debit}{$k} = $ref2->{amount} * - 1;
081a4f97 Moritz Bunkus
$ref->{debit_accno}{$k} = $ref2->{accno};
$ref->{debit_taxkey}{$k} = $ref2->{taxkey};
f4a48b30 Moritz Bunkus
$ref->{ac_transdate}{$k} = $ref2->{transdate};
6c7334b3 Philip Reetz
$ref->{source}{$k} = $source . $space . $ref->{source}{$k};
081a4f97 Moritz Bunkus
} else {
if ($ref->{credit_accno}{$l} ne "") {
$l++;
}
6c7334b3 Philip Reetz
if ($ref->{source}{$l} ne "") {
$space = " | ";
} else {
$space = "";
}
081a4f97 Moritz Bunkus
$ref->{credit}{$l} = $ref2->{amount};
$ref->{credit_accno}{$l} = $ref2->{accno};
$ref->{credit_taxkey}{$l} = $ref2->{taxkey};
f4a48b30 Moritz Bunkus
$ref->{ac_transdate}{$l} = $ref2->{transdate};
6c7334b3 Philip Reetz
$ref->{source}{$l} = $ref->{source}{$l} . $space . $source;
081a4f97 Moritz Bunkus
}
}
d319704a Moritz Bunkus
}
}
6c7334b3 Philip Reetz
42fc1e70 Stephan Köhler
push @{ $form->{GL} }, $ref;
d319704a Moritz Bunkus
$sth->finish;

if ($form->{accno}) {
05fea791 Moritz Bunkus
$query = qq|SELECT c.description FROM chart c WHERE c.accno = ?|;
($form->{account_description}) = selectrow_query($form, $dbh, $query, $form->{accno});
d319704a Moritz Bunkus
}

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

sub transaction {
my ($self, $myconfig, $form) = @_;
2ae62d30 Stephan Köhler
$main::lxdebug->enter_sub();
d319704a Moritz Bunkus
05fea791 Moritz Bunkus
my ($query, $sth, $ref, @values);
d319704a Moritz Bunkus
20fb5523 Sven Schöling
my $dbh = SL::DB->client->dbh;
2ae62d30 Stephan Köhler
05fea791 Moritz Bunkus
$query = qq|SELECT closedto, revtrans FROM defaults|;
($form->{closedto}, $form->{revtrans}) = selectrow_query($form, $dbh, $query);

e2e06cbb Moritz Bunkus
$query = qq|SELECT id, gldate
FROM gl
WHERE id = (SELECT max(id) FROM gl)|;
($form->{previous_id}, $form->{previous_gldate}) = selectrow_query($form, $dbh, $query);

d319704a Moritz Bunkus
if ($form->{id}) {
05fea791 Moritz Bunkus
$query =
36666afc Bernd Bleßmann
qq|SELECT g.reference, g.description, g.notes, g.transdate, g.deliverydate,
g.storno, g.storno_id,
f0747a2f Geoffrey Richardson
g.department_id, d.description AS department,
e.name AS employee, g.taxincluded, g.gldate,
e2305bab Philip Reetz
g.ob_transaction, g.cb_transaction
05fea791 Moritz Bunkus
FROM gl g
LEFT JOIN department d ON (d.id = g.department_id)
LEFT JOIN employee e ON (e.id = g.employee_id)
WHERE g.id = ?|;
$ref = selectfirst_hashref_query($form, $dbh, $query, conv_i($form->{id}));
d319704a Moritz Bunkus
map { $form->{$_} = $ref->{$_} } keys %$ref;

# retrieve individual rows
05fea791 Moritz Bunkus
$query =
6f891148 Philip Reetz
qq|SELECT c.accno, t.taxkey AS accnotaxkey, a.amount, a.memo, a.source,
05fea791 Moritz Bunkus
a.transdate, a.cleared, a.project_id, p.projectnumber,
ad635c66 Moritz Bunkus
a.taxkey, t.rate AS taxrate, t.id, a.chart_id,
05fea791 Moritz Bunkus
(SELECT c1.accno
FROM chart c1, tax t1
WHERE (t1.id = t.id) AND (c1.id = t.chart_id)) AS taxaccno,
8eca5e84 Sven Schöling
(SELECT tk.tax_id
FROM taxkeys tk
WHERE (tk.chart_id = a.chart_id) AND (tk.startdate <= a.transdate)
ORDER BY tk.startdate desc LIMIT 1) AS tax_id
05fea791 Moritz Bunkus
FROM acc_trans a
JOIN chart c ON (c.id = a.chart_id)
LEFT JOIN project p ON (p.id = a.project_id)
9d2d867c Niclas Zimmermann
LEFT JOIN tax t ON (t.id = a.tax_id)
05fea791 Moritz Bunkus
WHERE (a.trans_id = ?)
AND (a.fx_transaction = '0')
6ff01fdb Moritz Bunkus
ORDER BY a.acc_trans_id, a.transdate|;
05fea791 Moritz Bunkus
$form->{GL} = selectall_hashref_query($form, $dbh, $query, conv_i($form->{id}));
d319704a Moritz Bunkus
} else {
2387a1fc Moritz Bunkus
$query =
05fea791 Moritz Bunkus
qq|SELECT COALESCE(
(SELECT transdate
FROM gl
WHERE id = (SELECT MAX(id) FROM gl)
LIMIT 1),
current_date)|;
($form->{transdate}) = selectrow_query($form, $dbh, $query);
d319704a Moritz Bunkus
}

05fea791 Moritz Bunkus
# get tax description
$query = qq|SELECT * FROM tax ORDER BY taxkey|;
$form->{TAX} = selectall_hashref_query($form, $dbh, $query);
d319704a Moritz Bunkus
05fea791 Moritz Bunkus
# get chart of accounts
$query =
qq|SELECT c.accno, c.description, c.link, tk.taxkey_id, tk.tax_id
FROM chart c
LEFT JOIN taxkeys tk ON (tk.id =
(SELECT id
FROM taxkeys
WHERE (taxkeys.chart_id = c.id)
AND (startdate <= ?)
ORDER BY startdate DESC
LIMIT 1))
ORDER BY c.accno|;
$form->{chart} = selectall_hashref_query($form, $dbh, $query, conv_date($form->{transdate}));
d319704a Moritz Bunkus
05fea791 Moritz Bunkus
$main::lxdebug->leave_sub();
d319704a Moritz Bunkus
}

090de47c Sven Schöling
sub storno {
09372651 Sven Schöling
my ($self, $form, $myconfig, $id) = @_;
090de47c Sven Schöling
$main::lxdebug->enter_sub();

09372651 Sven Schöling
my $rc = SL::DB->client->with_transaction(\&_storno, $self, $form, $myconfig, $id);

$::lxdebug->leave_sub;
return $rc;
}

sub _storno {
090de47c Sven Schöling
my ($self, $form, $myconfig, $id) = @_;

my ($query, $new_id, $storno_row, $acc_trans_rows);
09372651 Sven Schöling
my $dbh = SL::DB->client->dbh;
090de47c Sven Schöling
$query = qq|SELECT nextval('glid')|;
($new_id) = selectrow_query($form, $dbh, $query);

$query = qq|SELECT * FROM gl WHERE id = ?|;
$storno_row = selectfirst_hashref_query($form, $dbh, $query, $id);

46e64bc4 Geoffrey Richardson
$storno_row->{id} = $new_id;
$storno_row->{storno_id} = $id;
$storno_row->{storno} = 't';
$storno_row->{reference} = 'Storno-' . $storno_row->{reference};

$query = qq|SELECT id FROM employee WHERE login = ?|;
my ($employee_id) = selectrow_query($form, $dbh, $query, $::myconfig{login});
$storno_row->{employee_id} = $employee_id;
090de47c Sven Schöling
5310fca1 Geoffrey Richardson
delete @$storno_row{qw(itime mtime gldate)};
090de47c Sven Schöling
$query = sprintf 'INSERT INTO gl (%s) VALUES (%s)', join(', ', keys %$storno_row), join(', ', map '?', values %$storno_row);
do_query($form, $dbh, $query, (values %$storno_row));

bee7eaaa Sven Schöling
$query = qq|UPDATE gl SET storno = 't' WHERE id = ?|;
do_query($form, $dbh, $query, $id);

090de47c Sven Schöling
# now copy acc_trans entries
$query = qq|SELECT * FROM acc_trans WHERE trans_id = ?|;
76c486e3 Sven Schöling
my $rowref = selectall_hashref_query($form, $dbh, $query, $id);
090de47c Sven Schöling
for my $row (@$rowref) {
5310fca1 Geoffrey Richardson
delete @$row{qw(itime mtime acc_trans_id gldate)};
090de47c Sven Schöling
$query = sprintf 'INSERT INTO acc_trans (%s) VALUES (%s)', join(', ', keys %$row), join(', ', map '?', values %$row);
$row->{trans_id} = $new_id;
$row->{amount} *= -1;
do_query($form, $dbh, $query, (values %$row));
}

09372651 Sven Schöling
return 1;
090de47c Sven Schöling
}

34366eda Moritz Bunkus
sub get_chart_balances {
ad635c66 Moritz Bunkus
my ($self, @chart_ids) = @_;
34366eda Moritz Bunkus
ad635c66 Moritz Bunkus
return () unless @chart_ids;
34366eda Moritz Bunkus
ad635c66 Moritz Bunkus
my $placeholders = join ', ', ('?') x scalar(@chart_ids);
34366eda Moritz Bunkus
my $query = qq|SELECT chart_id, SUM(amount) AS sum
FROM acc_trans
ad635c66 Moritz Bunkus
WHERE chart_id IN (${placeholders})
34366eda Moritz Bunkus
GROUP BY chart_id|;

ad635c66 Moritz Bunkus
my %balances = selectall_as_map($::form, $::form->get_standard_dbh(\%::myconfig), $query, 'chart_id', 'sum', @chart_ids);
34366eda Moritz Bunkus
ad635c66 Moritz Bunkus
return %balances;
34366eda Moritz Bunkus
}

ad635c66 Moritz Bunkus
sub get_active_taxes_for_chart {
e765ebf8 Geoffrey Richardson
my ($self, $chart_id, $transdate, $tax_id) = @_;
e82db1a7 Niclas Zimmermann
ad635c66 Moritz Bunkus
my $chart = SL::DB::Chart->new(id => $chart_id)->load;
my $active_taxkey = $chart->get_active_taxkey($transdate);
e765ebf8 Geoffrey Richardson
my $where = [ chart_categories => { like => '%' . $chart->category . '%' } ];

if ( defined $tax_id && $tax_id >= 0 ) {
$where = [ or => [ chart_categories => { like => '%' . $chart->category . '%' },
id => $tax_id
]
];
}

ad635c66 Moritz Bunkus
my $taxes = SL::DB::Manager::Tax->get_all(
e765ebf8 Geoffrey Richardson
where => $where,
ad635c66 Moritz Bunkus
sort_by => 'taxkey, rate',
);
e82db1a7 Niclas Zimmermann
ad635c66 Moritz Bunkus
my $default_tax = first { $active_taxkey->tax_id == $_->id } @{ $taxes };
$default_tax->{is_default} = 1 if $default_tax;
e82db1a7 Niclas Zimmermann
ad635c66 Moritz Bunkus
return @{ $taxes };
e82db1a7 Niclas Zimmermann
}
34366eda Moritz Bunkus
d319704a Moritz Bunkus
1;
e765ebf8 Geoffrey Richardson
__END__

=pod

=encoding utf8

=head1 NAME

SL::GL - some useful GL functions

=head1 FUNCTIONS

=over 4

72911d5e Jan Büren
=item C<get_active_taxes_for_chart> $transdate $tax_id
e765ebf8 Geoffrey Richardson
72911d5e Jan Büren
Returns a list of valid taxes for a certain chart.
e765ebf8 Geoffrey Richardson
72911d5e Jan Büren
If the optional param transdate exists one entry in the returning list
330df4c5 Bernd Bleßmann
may get the attribute C<is_default> for this specific tax-dependent date.
e765ebf8 Geoffrey Richardson
The possible entries are filtered by the charttype of the tax, i.e. only taxes
whose chart_categories match the category of the chart will be shown.

In the case of existing records, e.g. when opening an old ar record, due to
changes in the configurations the desired tax might not be available in the
dropdown anymore. If we are loading an old record and know its tax_id (from
acc_trans), we can pass $tax_id as the third parameter and be sure that the
original tax always appears in the dropdown.

72911d5e Jan Büren
The functions returns an array which may be used for building dropdowns in ar/ap/gl code.
f60e94b5 Bernd Bleßmann
e765ebf8 Geoffrey Richardson
=back

=head1 TODO

=head1 BUGS

Nothing here yet.

=head1 AUTHOR

G. Richardson E<lt>grichardson@kivitec.de<gt>

=cut