summaryrefslogtreecommitdiff
path: root/sql-ledger/SL
diff options
context:
space:
mode:
authorivan <ivan>2004-11-15 10:35:56 +0000
committerivan <ivan>2004-11-15 10:35:56 +0000
commit32306b5f8ffe4ce594409aa6e89626740b225a39 (patch)
tree8dba82e8424ebe8d089b4e0ef579d87db06742a3 /sql-ledger/SL
parent52072fcd26f2faf57923f598c358e7f47c4e2643 (diff)
import sql-ledger 2.4.4SQL_LEDGER
Diffstat (limited to 'sql-ledger/SL')
-rw-r--r--sql-ledger/SL/AM.pm1096
-rw-r--r--sql-ledger/SL/AP.pm295
-rw-r--r--sql-ledger/SL/AR.pm377
-rw-r--r--sql-ledger/SL/BP.pm371
-rw-r--r--sql-ledger/SL/CA.pm404
-rw-r--r--sql-ledger/SL/CP.pm242
-rw-r--r--sql-ledger/SL/CT.pm949
-rw-r--r--sql-ledger/SL/Form.pm1618
-rw-r--r--sql-ledger/SL/GL.pm284
-rw-r--r--sql-ledger/SL/HR.pm558
-rw-r--r--sql-ledger/SL/IC.pm1037
-rw-r--r--sql-ledger/SL/IR.pm544
-rw-r--r--sql-ledger/SL/IS.pm911
-rw-r--r--sql-ledger/SL/Inifile.pm7
-rw-r--r--sql-ledger/SL/Mailer.pm23
-rw-r--r--sql-ledger/SL/Menu.pm26
-rw-r--r--sql-ledger/SL/Num2text.pm4
-rw-r--r--sql-ledger/SL/OE.pm1345
-rw-r--r--sql-ledger/SL/OP.pm118
-rw-r--r--sql-ledger/SL/PE.pm399
-rw-r--r--sql-ledger/SL/RC.pm462
-rw-r--r--sql-ledger/SL/RP.pm1785
-rw-r--r--sql-ledger/SL/User.pm363
23 files changed, 10703 insertions, 2515 deletions
diff --git a/sql-ledger/SL/AM.pm b/sql-ledger/SL/AM.pm
index d691b3ce6..dbdd61111 100644
--- a/sql-ledger/SL/AM.pm
+++ b/sql-ledger/SL/AM.pm
@@ -1,12 +1,12 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
-# Contributors:
+# Contributors: Jim Rawlings <jim@your-dba.com>
#
# 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
@@ -51,9 +51,6 @@ sub get_account {
$form->{"$key"} = $ref->{"$key"};
}
- $sth->finish;
-
-
# get default accounts
$query = qq|SELECT inventory_accno_id, income_accno_id, expense_accno_id
FROM defaults|;
@@ -61,10 +58,15 @@ sub get_account {
$sth->execute || $form->dberror($query);
$ref = $sth->fetchrow_hashref(NAME_lc);
-
map { $form->{$_} = $ref->{$_} } keys %ref;
-
$sth->finish;
+
+ # check if we have any transactions
+ $query = qq|SELECT trans_id FROM acc_trans
+ WHERE chart_id = $form->{id}|;
+ ($form->{orphaned}) = $dbh->selectrow_array($query);
+ $form->{orphaned} = !$form->{orphaned};
+
$dbh->disconnect;
}
@@ -76,11 +78,6 @@ sub save_account {
# connect to database, turn off AutoCommit
my $dbh = $form->dbconnect_noauto($myconfig);
- # sanity check, can't have AR with AR_...
- if ($form->{AR} || $form->{AP} || $form->{IC}) {
- map { delete $form->{$_} } qw(AR_amount AR_tax AR_paid AP_amount AP_tax AP_paid IC_sale IC_cogs IC_taxpart IC_income IC_expense IC_taxservice);
- }
-
$form->{link} = "";
foreach my $item ($form->{AR},
$form->{AR_amount},
@@ -103,18 +100,22 @@ sub save_account {
}
chop $form->{link};
- # if we have an id then replace the old record
- $form->{description} =~ s/'/''/g;
-
# strip blanks from accno
- map { $form->{$_} =~ s/ //g; } qw(accno gifi_accno);
+ map { $form->{$_} =~ s/( |')//g } qw(accno gifi_accno);
+
+ foreach my $item (qw(accno gifi_accno description)) {
+ $form->{$item} =~ s/-(-+)/-/g;
+ $form->{$item} =~ s/ ( )+/ /g;
+ }
- my ($query, $sth);
+ my $query;
+ my $sth;
+ # if we have an id then replace the old record
if ($form->{id}) {
$query = qq|UPDATE chart SET
accno = '$form->{accno}',
- description = '$form->{description}',
+ description = |.$dbh->quote($form->{description}).qq|,
charttype = '$form->{charttype}',
gifi_accno = '$form->{gifi_accno}',
category = '$form->{category}',
@@ -123,38 +124,31 @@ sub save_account {
} else {
$query = qq|INSERT INTO chart
(accno, description, charttype, gifi_accno, category, link)
- VALUES ('$form->{accno}', '$form->{description}',
+ VALUES ('$form->{accno}',|
+ .$dbh->quote($form->{description}).qq|,
'$form->{charttype}', '$form->{gifi_accno}',
'$form->{category}', '$form->{link}')|;
}
$dbh->do($query) || $form->dberror($query);
-
- if ($form->{IC_taxpart} || $form->{IC_taxservice} || $form->{CT_tax}) {
- my $chart_id = $form->{id};
-
- unless ($form->{id}) {
- # get id from chart
- $query = qq|SELECT id
- FROM chart
- WHERE accno = '$form->{accno}'|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- ($chart_id) = $sth->fetchrow_array;
- $sth->finish;
- }
-
+ $chart_id = $form->{id};
+
+ if (! $form->{id}) {
+ # get id from chart
+ $query = qq|SELECT id
+ FROM chart
+ WHERE accno = '$form->{accno}'|;
+ ($chart_id) = $dbh->selectrow_array($query);
+ }
+
+ if ($form->{IC_taxpart} || $form->{IC_taxservice} || $form->{CT_tax}) {
+
# add account if it doesn't exist in tax
$query = qq|SELECT chart_id
FROM tax
WHERE chart_id = $chart_id|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- my ($tax_id) = $sth->fetchrow_array;
- $sth->finish;
+ my ($tax_id) = $dbh->selectrow_array($query);
# add tax if it doesn't exist
unless ($tax_id) {
@@ -171,7 +165,6 @@ sub save_account {
}
}
-
# commit
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -187,6 +180,14 @@ sub delete_account {
# connect to database, turn off AutoCommit
my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my $query = qq|SELECT * FROM acc_trans
+ WHERE chart_id = $form->{id}|;
+ if ($dbh->selectrow_array($query)) {
+ $dbh->disconnect;
+ return;
+ }
+
# delete chart of account record
$query = qq|DELETE FROM chart
@@ -244,7 +245,6 @@ sub gifi_accounts {
push @{ $form->{ALL} }, $ref;
}
- $sth->finish;
$dbh->disconnect;
}
@@ -260,14 +260,17 @@ sub get_gifi {
my $query = qq|SELECT accno, description
FROM gifi
WHERE accno = '$form->{accno}'|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- my $ref = $sth->fetchrow_hashref(NAME_lc);
-
- map { $form->{$_} = $ref->{$_} } keys %$ref;
+ ($form->{accno}, $form->{description}) = $dbh->selectrow_array($query);
+
+ # check for transactions
+ $query = qq|SELECT * FROM acc_trans a
+ JOIN chart c ON (a.chart_id = c.id)
+ JOIN gifi g ON (c.gifi_accno = g.accno)
+ WHERE g.accno = '$form->{accno}'|;
+ ($form->{orphaned}) = $dbh->selectrow_array($query);
+ $form->{orphaned} = !$form->{orphaned};
- $sth->finish;
$dbh->disconnect;
}
@@ -279,21 +282,26 @@ sub save_gifi {
# connect to database
my $dbh = $form->dbconnect($myconfig);
- $form->{description} =~ s/'/''/g;
- $form->{accno} =~ s/ //g;
+ $form->{accno} =~ s/( |')//g;
+
+ foreach my $item (qw(accno description)) {
+ $form->{$item} =~ s/-(-+)/-/g;
+ $form->{$item} =~ s/ ( )+/ /g;
+ }
# id is the old account number!
if ($form->{id}) {
$query = qq|UPDATE gifi SET
accno = '$form->{accno}',
- description = '$form->{description}'
+ description = |.$dbh->quote($form->{description}).qq|
WHERE accno = '$form->{id}'|;
} else {
$query = qq|INSERT INTO gifi
(accno, description)
- VALUES ('$form->{accno}', '$form->{description}')|;
+ VALUES ('$form->{accno}',|
+ .$dbh->quote($form->{description}).qq|)|;
}
- $dbh->do($query) || $form->dberror($query);
+ $dbh->do($query) || $form->dberror;
$dbh->disconnect;
@@ -316,6 +324,462 @@ sub delete_gifi {
}
+sub warehouses {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->sort_order();
+ my $query = qq|SELECT id, description
+ FROM warehouse
+ ORDER BY 2 $form->{direction}|;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{ALL} }, $ref;
+ }
+
+ $dbh->disconnect;
+
+}
+
+
+
+sub get_warehouse {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT description
+ FROM warehouse
+ WHERE id = $form->{id}|;
+ ($form->{description}) = $dbh->selectrow_array($query);
+
+ # see if it is in use
+ $query = qq|SELECT * FROM inventory
+ WHERE warehouse_id = $form->{id}|;
+ ($form->{orphaned}) = $dbh->selectrow_array($query);
+ $form->{orphaned} = !$form->{orphaned};
+
+ $dbh->disconnect;
+
+}
+
+
+sub save_warehouse {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->{description} =~ s/-(-)+/-/g;
+ $form->{description} =~ s/ ( )+/ /g;
+
+ if ($form->{id}) {
+ $query = qq|UPDATE warehouse SET
+ description = |.$dbh->quote($form->{description}).qq|
+ WHERE id = $form->{id}|;
+ } else {
+ $query = qq|INSERT INTO warehouse
+ (description)
+ VALUES (|.$dbh->quote($form->{description}).qq|)|;
+ }
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub delete_warehouse {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $query = qq|DELETE FROM warehouse
+ WHERE id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+
+sub departments {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->sort_order();
+ my $query = qq|SELECT id, description, role
+ FROM department
+ ORDER BY 2 $form->{direction}|;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{ALL} }, $ref;
+ }
+
+ $dbh->disconnect;
+
+}
+
+
+
+sub get_department {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT description, role
+ FROM department
+ WHERE id = $form->{id}|;
+ ($form->{description}, $form->{role}) = $dbh->selectrow_array($query);
+
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+ # see if it is in use
+ $query = qq|SELECT * FROM dpt_trans
+ WHERE department_id = $form->{id}|;
+ ($form->{orphaned}) = $dbh->selectrow_array($query);
+ $form->{orphaned} = !$form->{orphaned};
+
+ $dbh->disconnect;
+
+}
+
+
+sub save_department {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->{description} =~ s/-(-)+/-/g;
+ $form->{description} =~ s/ ( )+/ /g;
+
+ if ($form->{id}) {
+ $query = qq|UPDATE department SET
+ description = |.$dbh->quote($form->{description}).qq|,
+ role = '$form->{role}'
+ WHERE id = $form->{id}|;
+ } else {
+ $query = qq|INSERT INTO department
+ (description, role)
+ VALUES (|
+ .$dbh->quote($form->{description}).qq|, '$form->{role}')|;
+ }
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub delete_department {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $query = qq|DELETE FROM department
+ WHERE id = $form->{id}|;
+ $dbh->do($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub business {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->sort_order();
+ my $query = qq|SELECT id, description, discount
+ FROM business
+ ORDER BY 2 $form->{direction}|;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{ALL} }, $ref;
+ }
+
+ $dbh->disconnect;
+
+}
+
+
+
+sub get_business {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT description, discount
+ FROM business
+ WHERE id = $form->{id}|;
+ ($form->{description}, $form->{discount}) = $dbh->selectrow_array($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub save_business {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->{description} =~ s/-(-)+/-/g;
+ $form->{description} =~ s/ ( )+/ /g;
+ $form->{discount} /= 100;
+
+ if ($form->{id}) {
+ $query = qq|UPDATE business SET
+ description = |.$dbh->quote($form->{description}).qq|,
+ discount = $form->{discount}
+ WHERE id = $form->{id}|;
+ } else {
+ $query = qq|INSERT INTO business
+ (description, discount)
+ VALUES (|
+ .$dbh->quote($form->{description}).qq|, $form->{discount})|;
+ }
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub delete_business {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $query = qq|DELETE FROM business
+ WHERE id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub sic {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->{sort} = "code" unless $form->{sort};
+ my @a = qw(code description);
+ my %ordinal = ( code => 1,
+ description => 3 );
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+ my $query = qq|SELECT code, sictype, description
+ FROM sic
+ ORDER BY $sortorder|;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{ALL} }, $ref;
+ }
+
+ $dbh->disconnect;
+
+}
+
+
+
+sub get_sic {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT code, sictype, description
+ FROM sic
+ WHERE code = |.$dbh->quote($form->{code});
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $ref = $sth->fetchrow_hashref(NAME_lc);
+
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+ $sth->finish;
+ $dbh->disconnect;
+
+}
+
+
+sub save_sic {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ foreach my $item (qw(code description)) {
+ $form->{$item} =~ s/-(-)+/-/g;
+ }
+
+ # if there is an id
+ if ($form->{id}) {
+ $query = qq|UPDATE sic SET
+ code = |.$dbh->quote($form->{code}).qq|,
+ sictype = '$form->{sictype}',
+ description = |.$dbh->quote($form->{description}).qq|
+ WHERE code = |.$dbh->quote($form->{id});
+ } else {
+ $query = qq|INSERT INTO sic
+ (code, sictype, description)
+ VALUES (|
+ .$dbh->quote($form->{code}).qq|,
+ '$form->{sictype}',|
+ .$dbh->quote($form->{description}).qq|)|;
+ }
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub delete_sic {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $query = qq|DELETE FROM sic
+ WHERE code = |.$dbh->quote($form->{code});
+ $dbh->do($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub language {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->{sort} = "code" unless $form->{sort};
+ my @a = qw(code description);
+ my %ordinal = ( code => 1,
+ description => 2 );
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ my $query = qq|SELECT code, description
+ FROM language
+ ORDER BY $sortorder|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{ALL} }, $ref;
+ }
+
+ $dbh->disconnect;
+
+}
+
+
+
+sub get_language {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT *
+ FROM language
+ WHERE code = |.$dbh->quote($form->{code});
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $ref = $sth->fetchrow_hashref(NAME_lc);
+
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+ $sth->finish;
+
+ $dbh->disconnect;
+
+}
+
+
+sub save_language {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $form->{code} =~ s/ //g;
+ foreach my $item (qw(code description)) {
+ $form->{$item} =~ s/-(-)+/-/g;
+ $form->{$item} =~ s/ ( )+/-/g;
+ }
+
+ # if there is an id
+ if ($form->{id}) {
+ $query = qq|UPDATE language SET
+ code = |.$dbh->quote($form->{code}).qq|,
+ description = |.$dbh->quote($form->{description}).qq|
+ WHERE code = |.$dbh->quote($form->{id});
+ } else {
+ $query = qq|INSERT INTO language
+ (code, description)
+ VALUES (|
+ .$dbh->quote($form->{code}).qq|,|
+ .$dbh->quote($form->{description}).qq|)|;
+ }
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub delete_language {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $query = qq|DELETE FROM language
+ WHERE code = |.$dbh->quote($form->{code});
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+
sub load_template {
my ($self, $form) = @_;
@@ -348,6 +812,42 @@ sub save_template {
sub save_preferences {
my ($self, $myconfig, $form, $memberfile, $userspath) = @_;
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ # update name
+ my $query = qq|UPDATE employee
+ SET name = |.$dbh->quote($form->{name}).qq|,
+ role = '$form->{role}'
+ WHERE login = '$form->{login}'|;
+ $dbh->do($query) || $form->dberror($query);
+
+ # get default currency
+ $query = qq|SELECT curr, businessnumber
+ FROM defaults|;
+ ($form->{currency}, $form->{businessnumber}) = $dbh->selectrow_array($query);
+ $form->{currency} =~ s/:.*//;
+
+ $dbh->disconnect;
+
+ my $myconfig = new User "$memberfile", "$form->{login}";
+
+ foreach my $item (keys %$form) {
+ $myconfig->{$item} = $form->{$item};
+ }
+
+ $myconfig->{password} = $form->{new_password} if ($form->{old_password} ne $form->{new_password});
+
+ $myconfig->save_member($memberfile, $userspath);
+
+ 1;
+
+}
+
+
+sub save_defaults {
+ my ($self, $myconfig, $form) = @_;
+
map { ($form->{$_}) = split /--/, $form->{$_} } qw(inventory_accno income_accno expense_accno fxgain_accno fxloss_accno);
my @a;
@@ -358,8 +858,6 @@ sub save_preferences {
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
- # these defaults are database wide
- # user specific variables are in myconfig
# save defaults
my $query = qq|UPDATE defaults SET
inventory_accno_id =
@@ -377,28 +875,27 @@ sub save_preferences {
fxloss_accno_id =
(SELECT id FROM chart
WHERE accno = '$form->{fxloss_accno}'),
- invnumber = '$form->{invnumber}',
+ sinumber = '$form->{sinumber}',
+ vinumber = '$form->{vinumber}',
sonumber = '$form->{sonumber}',
ponumber = '$form->{ponumber}',
+ sqnumber = '$form->{sqnumber}',
+ rfqnumber = '$form->{rfqnumber}',
+ partnumber = '$form->{partnumber}',
+ employeenumber = '$form->{employeenumber}',
+ customernumber = '$form->{customernumber}',
+ vendornumber = '$form->{vendornumber}',
yearend = '$form->{yearend}',
curr = '$form->{curr}',
- weightunit = '$form->{weightunit}',
- businessnumber = '$form->{businessnumber}'
- |;
+ weightunit = |.$dbh->quote($form->{weightunit}).qq|,
+ businessnumber = |.$dbh->quote($form->{businessnumber});
$dbh->do($query) || $form->dberror($query);
- # update name
- my $name = $form->{name};
- $name =~ s/'/''/g;
- $query = qq|UPDATE employee
- SET name = '$name'
- WHERE login = '$form->{login}'|;
- $dbh->do($query) || $form->dberror($query);
-
foreach my $item (split / /, $form->{taxaccounts}) {
+ $form->{$item} = $form->parse_amount($myconfig, $form->{$item}) / 100;
$query = qq|UPDATE tax
- SET rate = |.($form->{$item} / 100).qq|,
- taxnumber = '$form->{"taxnumber_$item"}'
+ SET rate = $form->{$item},
+ taxnumber = |.$dbh->quote($form->{"taxnumber_$item"}).qq|
WHERE chart_id = $item|;
$dbh->do($query) || $form->dberror($query);
}
@@ -406,17 +903,6 @@ sub save_preferences {
my $rc = $dbh->commit;
$dbh->disconnect;
- # save first currency in myconfig
- $form->{currency} = substr($form->{curr},0,3);
-
- my $myconfig = new User "$memberfile", "$form->{login}";
-
- foreach my $item (keys %$form) {
- $myconfig->{$item} = $form->{$item};
- }
-
- $myconfig->save_member($memberfile, $userspath);
-
$rc;
}
@@ -449,7 +935,7 @@ sub defaultaccounts {
WHERE link LIKE '%IC%'
ORDER BY accno|;
$sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
+ $sth->execute || $form->dberror($query);
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
foreach my $key (split(/:/, $ref->{link})) {
@@ -475,7 +961,7 @@ sub defaultaccounts {
AND charttype = 'A'
ORDER BY accno|;
$sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
+ $sth->execute || $form->dberror($query);
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
%{ $form->{IC}{FX_gain}{$ref->{accno}} } = ( id => $ref->{id},
@@ -489,7 +975,7 @@ sub defaultaccounts {
AND charttype = 'A'
ORDER BY accno|;
$sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
+ $sth->execute || $form->dberror($query);
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
%{ $form->{IC}{FX_loss}{$ref->{accno}} } = ( id => $ref->{id},
@@ -521,51 +1007,138 @@ sub defaultaccounts {
sub backup {
- my ($self, $myconfig, $form, $userspath) = @_;
+ my ($self, $myconfig, $form, $userspath, $gzip) = @_;
- my ($tmpfile, $out, $mail);
+ my $mail;
+ my $err;
- if ($form->{media} eq 'email') {
+ my @t = localtime(time);
+ $t[4]++;
+ $t[5] += 1900;
+ $t[3] = substr("0$t[3]", -2);
+ $t[4] = substr("0$t[4]", -2);
+
+ my $boundary = time;
+ my $tmpfile = "$userspath/$boundary.$myconfig->{dbname}-$form->{dbversion}-$t[5]$t[4]$t[3].sql";
+ my $out = $form->{OUT};
+ $form->{OUT} = ">$tmpfile";
+
+ open(OUT, "$form->{OUT}") or $form->error("$form->{OUT} : $!");
+
+ # get sequences, functions and triggers
+ my @tables = ();
+ my @sequences = ();
+ my @functions = ();
+ my @triggers = ();
+ my @schema = ();
+
+ # get dbversion from -tables.sql
+ my $file = "$myconfig->{dbdriver}-tables.sql";
- my $boundary = time;
- $tmpfile = "$userspath/$boundary.$myconfig->{dbname}-$form->{dbversion}.sql";
- $out = $form->{OUT};
- $form->{OUT} = ">$tmpfile";
-
- use SL::Mailer;
- $mail = new Mailer;
+ open(FH, "sql/$file") or $form->error("sql/$file : $!");
- $mail->{to} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
- $mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
- $mail->{subject} = "SQL-Ledger Backup / $myconfig->{dbname}-$form->{dbversion}.sql";
- @{ $mail->{attachments} } = ($tmpfile);
- $mail->{version} = $form->{version};
- $mail->{fileid} = "$boundary.";
+ my @a = <FH>;
+ close(FH);
- $myconfig->{signature} =~ s/\\n/\r\n/g;
- $mail->{message} = "--\n$myconfig->{signature}";
+ @dbversion = grep /defaults \(version\)/, @a;
+
+ $dbversion = "@dbversion";
+ $dbversion =~ /(\d+\.\d+\.\d+)/;
+ $dbversion = User::calc_version($1);
+
+ opendir SQLDIR, "sql/." or $form->error($!);
+ @a = grep /$myconfig->{dbdriver}-upgrade-.*?\.sql$/, readdir SQLDIR;
+ closedir SQLDIR;
+
+ my $mindb;
+ my $maxdb;
+
+ foreach my $line (@a) {
+
+ $upgradescript = $line;
+ $line =~ s/(^$myconfig->{dbdriver}-upgrade-|\.sql$)//g;
- }
+ ($mindb, $maxdb) = split /-/, $line;
+ $mindb = User::calc_version($mindb);
+
+ next if $mindb < $dbversion;
- if ($form->{OUT}) {
- open(OUT, "$form->{OUT}") or $form->error("$form->{OUT} : $!");
- } else {
- open(OUT, ">-") or $form->error("STDOUT : $!");
+ $maxdb = User::calc_version($maxdb);
+
+ $upgradescripts{$maxdb} = $upgradescript;
}
- if ($form->{media} eq 'file') {
- print OUT qq|Content-Type: Application/File;
-Content-Disposition: filename="$myconfig->{dbname}-$form->{dbversion}.sql"\n\n|;
+
+ $upgradescripts{$dbversion} = "$myconfig->{dbdriver}-tables.sql";
+ $upgradescripts{functions} = "$myconfig->{dbdriver}-functions.sql";
+
+ if (-f "sql/$myconfig->{dbdriver}-custom_tables.sql") {
+ $upgradescripts{customtables} = "$myconfig->{dbdriver}-custom_tables.sql";
}
+ if (-f "sql/$myconfig->{dbdriver}-custom_functions.sql") {
+ $upgradescripts{customfunctions} = "$myconfig->{dbdriver}-custom_functions.sql";
+ }
+
+ foreach my $key (sort keys %upgradescripts) {
+
+ $file = $upgradescripts{$key};
+
+ open(FH, "sql/$file") or $form->error("sql/$file : $!");
+
+ push @schema, qq|-- $file\n|;
+
+ while (<FH>) {
+
+ if (/create table (\w+)/i) {
+ push @tables, $1;
+ }
+
+ if (/create sequence (\w+)/i) {
+ push @sequences, $1;
+ }
+
+ if (/end function/i) {
+ push @functions, $_;
+ $function = 0;
+ next;
+ }
+
+ if (/create function /i) {
+ $function = 1;
+ }
+
+ if ($function) {
+ push @functions, $_;
+ next;
+ }
+
+ if (/end trigger/i) {
+ push @triggers, $_;
+ $trigger = 0;
+ next;
+ }
+
+ if (/create trigger/i) {
+ $trigger = 1;
+ }
+
+ if ($trigger) {
+ push @triggers, $_;
+ next;
+ }
+
+ push @schema, $_ if $_ !~ /^(insert|--)/i;
+
+ }
+ close(FH);
+
+ }
+
# connect to database
my $dbh = $form->dbconnect($myconfig);
- # get all the tables
- my @tables = $dbh->tables;
-
my $today = scalar localtime;
-
$myconfig->{dbhost} = 'localhost' unless $myconfig->{dbhost};
@@ -577,39 +1150,56 @@ Content-Disposition: filename="$myconfig->{dbname}-$form->{dbversion}.sql"\n\n|;
-- User: $myconfig->{name}
-- Date: $today
--
--- set options
+|;
+
+
+ my $restrict = ($myconfig->{dbdriver} eq 'DB2') ? "RESTRICT" : "";
+
+ @tables = grep !/^temp/, @tables;
+ # drop tables and sequences
+ map { print OUT qq|DROP TABLE $_;\n| } @tables;
+ map { print OUT qq|DROP SEQUENCE $_ $restrict;\n| } @sequences;
+
+ print OUT "--\n";
+
+ # triggers and index files are dropped with the tables
+
+ # drop functions
+ foreach $item (@functions) {
+ if ($item =~ /create function (.*\))/i) {
+ print OUT qq|DROP FUNCTION $1;\n|;
+ }
+ }
+
+ # add schema
+ print OUT @schema;
+ print OUT "\n";
+
+ print OUT qq|-- set options
$myconfig->{dboptions};
--
|;
+ my $query;
+ my $sth;
+ my @arr;
+ my $fields;
+
foreach $table (@tables) {
- my $query = qq|SELECT * FROM $table|;
-
- my $sth = $dbh->prepare($query);
+
+ $query = qq|SELECT * FROM $table|;
+ $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
$query = qq|INSERT INTO $table (|;
- map { $query .= qq|$sth->{NAME}->[$_],| } (0 .. $sth->{NUM_OF_FIELDS} - 1);
- chop $query;
-
+ $query .= join ',', (map { $sth->{NAME}->[$_] } (0 .. $sth->{NUM_OF_FIELDS} - 1));
$query .= qq|) VALUES|;
- print OUT qq|--
-DELETE FROM $table;
-|;
- while (my @arr = $sth->fetchrow_array) {
+ while (@arr = $sth->fetchrow_array) {
$fields = "(";
- foreach my $item (@arr) {
- if (defined $item) {
- $item =~ s/'/''/g;
- $fields .= qq|'$item',|;
- } else {
- $fields .= 'NULL,';
- }
- }
-
- chop $fields;
+
+ $fields .= join ',', map { $dbh->quote($_) } @arr;
$fields .= ")";
print OUT qq|$query $fields;\n|;
@@ -618,28 +1208,103 @@ DELETE FROM $table;
$sth->finish;
}
- $query = qq|SELECT last_value FROM id|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- my ($id) = $sth->fetchrow_array;
- $sth->finish;
+ # create sequences and triggers
+ foreach $item (@sequences) {
+ if ($myconfig->{dbdriver} eq 'DB2') {
+ $query = qq|SELECT NEXTVAL FOR $item FROM sysibm.sysdummy1|;
+ } else {
+ $query = qq|SELECT last_value FROM $item|;
+ }
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+ my ($id) = $sth->fetchrow_array;
+ $sth->finish;
+ $id++;
- print OUT qq|--
-DROP SEQUENCE id;
-CREATE SEQUENCE id START $id;
-|;
+ print OUT qq|--
+DROP SEQUENCE $item $restrict;\n|;
+
+ if ($myconfig->{dbdriver} eq 'DB2') {
+ print OUT qq|CREATE SEQUENCE $item AS INTEGER START WITH $id INCREMENT BY 1 MAXVALUE 2147483647 MINVALUE 1 CACHE 5;\n|;
+ } else {
+ print OUT qq|CREATE SEQUENCE $item START $id;\n|;
+ }
+ }
+
+ print OUT "--\n";
+
+ # functions
+ map { print OUT $_ } @functions;
+
+ # triggers
+ map { print OUT $_ } @triggers;
+
+ # add the index files
+ open(FH, "sql/$myconfig->{dbdriver}-indices.sql");
+ @a = <FH>;
+ close(FH);
+ print OUT @a;
close(OUT);
$dbh->disconnect;
+ # compress backup if gzip defined
+ my $suffix = "";
+ if ($gzip) {
+ my @args = split / /, $gzip;
+ my @s = @args;
+
+ push @args, "$tmpfile";
+ system(@args) == 0 or $form->error("$args[0] : $?");
+
+ shift @s;
+ my %s = @s;
+ $suffix = ${-S} || ".gz";
+ $tmpfile .= $suffix;
+ }
+
if ($form->{media} eq 'email') {
- my $err = $mail->send($out);
- $_ = $tmpfile;
- unlink;
+
+ use SL::Mailer;
+ $mail = new Mailer;
+
+ $mail->{to} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
+ $mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
+ $mail->{subject} = "SQL-Ledger Backup / $myconfig->{dbname}-$form->{dbversion}-$t[5]$t[4]$t[3].sql$suffix";
+ @{ $mail->{attachments} } = ($tmpfile);
+ $mail->{version} = $form->{version};
+ $mail->{fileid} = "$boundary.";
+
+ $myconfig->{signature} =~ s/\\n/\r\n/g;
+ $mail->{message} = "-- \n$myconfig->{signature}";
+
+ $err = $mail->send($out);
}
+
+ if ($form->{media} eq 'file') {
+
+ open(IN, "$tmpfile") or $form->error("$tmpfile : $!");
+ open(OUT, ">-") or $form->error("STDOUT : $!");
+
+ print OUT qq|Content-Type: application/file;
+Content-Disposition: attachment; filename="$myconfig->{dbname}-$form->{dbversion}-$t[5]$t[4]$t[3].sql$suffix"
+
+|;
+
+ while (<IN>) {
+ print OUT $_;
+ }
+
+ close(IN);
+ close(OUT);
+ }
+
+ unlink "$tmpfile";
+
}
@@ -648,13 +1313,9 @@ sub closedto {
my $dbh = $form->dbconnect($myconfig);
- my $query = qq|SELECT closedto, revtrans FROM defaults|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- ($form->{closedto}, $form->{revtrans}) = $sth->fetchrow_array;
-
- $sth->finish;
+ my $query = qq|SELECT closedto, revtrans, audittrail
+ FROM defaults|;
+ ($form->{closedto}, $form->{revtrans}, $form->{audittrail}) = $dbh->selectrow_array($query);
$dbh->disconnect;
@@ -664,15 +1325,15 @@ sub closedto {
sub closebooks {
my ($self, $myconfig, $form) = @_;
- my $dbh = $form->dbconnect($myconfig);
+ my $dbh = $form->dbconnect_noauto($myconfig);
if ($form->{revtrans}) {
-
+
$query = qq|UPDATE defaults SET closedto = NULL,
revtrans = '1'|;
} else {
if ($form->{closedto}) {
-
+
$query = qq|UPDATE defaults SET closedto = '$form->{closedto}',
revtrans = '0'|;
} else {
@@ -682,13 +1343,136 @@ sub closebooks {
}
}
+ if ($form->{audittrail}) {
+ $query .= qq|, audittrail = '1'|;
+ } else {
+ $query .= qq|, audittrail = '0'|;
+ }
+
# set close in defaults
$dbh->do($query) || $form->dberror($query);
+
+ if ($form->{removeaudittrail}) {
+ $query = qq|DELETE FROM audittrail
+ WHERE transdate < '$form->{removeaudittrail}'|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+
+ $dbh->commit;
$dbh->disconnect;
}
+sub earningsaccounts {
+ my ($self, $myconfig, $form) = @_;
+
+ my ($query, $sth, $ref);
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ # get chart of accounts
+ $query = qq|SELECT accno,description
+ FROM chart
+ WHERE charttype = 'A'
+ AND category = 'Q'
+ ORDER by accno|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+ $form->{chart} = "";
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{chart} }, $ref;
+ }
+ $sth->finish;
+
+ $dbh->disconnect;
+
+}
+
+
+sub post_yearend {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database, turn off AutoCommit
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my $query;
+ my $uid = time;
+ $uid .= $form->{login};
+
+ $query = qq|INSERT INTO gl (reference, employee_id)
+ VALUES ('$uid', (SELECT id FROM employee
+ WHERE login = '$form->{login}'))|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|SELECT id FROM gl
+ WHERE reference = '$uid'|;
+ ($form->{id}) = $dbh->selectrow_array($query);
+
+ $query = qq|UPDATE gl SET
+ reference = |.$dbh->quote($form->{reference}).qq|,
+ description = |.$dbh->quote($form->{description}).qq|,
+ notes = |.$dbh->quote($form->{notes}).qq|,
+ transdate = '$form->{transdate}',
+ department_id = 0
+ WHERE id = $form->{id}|;
+
+ $dbh->do($query) || $form->dberror($query);
+
+ my $amount;
+ my $accno;
+
+ # insert acc_trans transactions
+ for my $i (1 .. $form->{rowcount}) {
+ # extract accno
+ ($accno) = split(/--/, $form->{"accno_$i"});
+ $amount = 0;
+
+ if ($form->{"credit_$i"} != 0) {
+ $amount = $form->{"credit_$i"};
+ }
+ if ($form->{"debit_$i"} != 0) {
+ $amount = $form->{"debit_$i"} * -1;
+ }
+
+
+ # if there is an amount, add the record
+ if ($amount != 0) {
+ $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
+ source)
+ VALUES
+ ($form->{id}, (SELECT id
+ FROM chart
+ WHERE accno = '$accno'),
+ $amount, '$form->{transdate}', |
+ .$dbh->quote($form->{reference}).qq|)|;
+
+ $dbh->do($query) || $form->dberror($query);
+ }
+ }
+
+ $query = qq|INSERT INTO yearend (trans_id, transdate)
+ VALUES ($form->{id}, '$form->{transdate}')|;
+ $dbh->do($query) || $form->dberror($query);
+
+ my %audittrail = ( tablename => 'gl',
+ reference => $form->{reference},
+ formname => 'yearend',
+ action => 'posted',
+ id => $form->{id} );
+ $form->audittrail($dbh, "", \%audittrail);
+
+ # commit and redirect
+ my $rc = $dbh->commit;
+ $dbh->disconnect;
+
+ $rc;
+
+}
+
+
1;
diff --git a/sql-ledger/SL/AP.pm b/sql-ledger/SL/AP.pm
index e1870f872..05bc77a3a 100644
--- a/sql-ledger/SL/AP.pm
+++ b/sql-ledger/SL/AP.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -36,12 +36,17 @@ sub post_transaction {
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
- my ($null, $taxrate, $amount);
+ my $null;
+ my $taxrate;
+ my $amount;
my $exchangerate = 0;
# split and store id numbers in link accounts
- ($form->{AP}{payables}) = split(/--/, $form->{AP});
- map { ($form->{AP}{"amount_$_"}) = split(/--/, $form->{"AP_amount_$_"}) } (1 .. $form->{rowcount});
+ map { ($form->{AP_amounts}{"amount_$_"}) = split(/--/, $form->{"AP_amount_$_"}) } (1 .. $form->{rowcount});
+ ($form->{AP_amounts}{payables}) = split(/--/, $form->{AP});
+
+ ($null, $form->{department_id}) = split(/--/, $form->{department});
+ $form->{department_id} *= 1;
if ($form->{currency} eq $form->{defaultcurrency}) {
$form->{exchangerate} = 1;
@@ -54,71 +59,59 @@ sub post_transaction {
# reverse and parse amounts
for my $i (1 .. $form->{rowcount}) {
$form->{"amount_$i"} = $form->round_amount($form->parse_amount($myconfig, $form->{"amount_$i"}) * $form->{exchangerate} * -1, 2);
- $amount += ($form->{"amount_$i"} * -1);
+ $form->{netamount} += ($form->{"amount_$i"} * -1);
}
- # this is for ap
- $form->{amount} = $amount;
# taxincluded doesn't make sense if there is no amount
- $form->{taxincluded} = 0 if ($form->{amount} == 0);
+ $form->{taxincluded} = 0 if ($form->{netamount} == 0);
for my $item (split / /, $form->{taxaccounts}) {
- $form->{AP}{"tax_$item"} = $item;
+ $form->{AP_amounts}{"tax_$item"} = $item;
- $amount = $form->round_amount($form->parse_amount($myconfig, $form->{"tax_$item"}), 2);
-
- $form->{"tax_$item"} = $form->round_amount($amount * $form->{exchangerate}, 2) * -1;
- $form->{total_tax} += ($form->{"tax_$item"} * -1);
+ $form->{"tax_$item"} = $form->round_amount($form->parse_amount($myconfig, $form->{"tax_$item"}) * $form->{exchangerate}, 2) * -1;
+ $form->{tax} += ($form->{"tax_$item"} * -1);
}
# adjust paidaccounts if there is no date in the last row
$form->{paidaccounts}-- unless ($form->{"datepaid_$form->{paidaccounts}"});
- $form->{invpaid} = 0;
+ $form->{paid} = 0;
# add payments
for my $i (1 .. $form->{paidaccounts}) {
$form->{"paid_$i"} = $form->round_amount($form->parse_amount($myconfig, $form->{"paid_$i"}), 2);
- $form->{invpaid} += $form->{"paid_$i"};
+ $form->{paid} += $form->{"paid_$i"};
$form->{datepaid} = $form->{"datepaid_$i"};
}
- $form->{invpaid} = $form->round_amount($form->{invpaid} * $form->{exchangerate}, 2);
if ($form->{taxincluded} *= 1) {
for $i (1 .. $form->{rowcount}) {
- $tax = $form->{total_tax} * $form->{"amount_$i"} / $form->{amount};
+ $tax = ($form->{netamount}) ? $form->{tax} * $form->{"amount_$i"} / $form->{netamount} : 0;
$amount = $form->{"amount_$i"} - $tax;
$form->{"amount_$i"} = $form->round_amount($amount, 2);
$diff += $amount - $form->{"amount_$i"};
}
- # deduct taxes from amount
- $form->{amount} -= $form->{total_tax};
+ $form->{netamount} -= $form->{tax};
# deduct difference from amount_1
$form->{amount_1} += $form->round_amount($diff, 2);
}
- $form->{netamount} = $form->{amount};
+ $form->{amount} = $form->{netamount} + $form->{tax};
+ $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate}, 2);
- # store invoice total, this goes into ap table
- $form->{invtotal} = $form->{amount} + $form->{total_tax};
-
- # amount for total AP
- $form->{payables} = $form->{invtotal};
-
-
- my ($query, $sth);
+ my $query;
+ my $sth;
# if we have an id delete old records
if ($form->{id}) {
# delete detail records
$query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
-
$dbh->do($query) || $form->dberror($query);
} else {
@@ -132,37 +125,33 @@ sub post_transaction {
$query = qq|SELECT id FROM ap
WHERE invnumber = '$uid'|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- ($form->{id}) = $sth->fetchrow_array;
- $sth->finish;
-
+ ($form->{id}) = $dbh->selectrow_array($query);
}
- # escape '
- $form->{notes} =~ s/'/''/g;
-
$form->{datepaid} = $form->{transdate} unless ($form->{datepaid});
- my $datepaid = ($form->{invpaid} != 0) ? qq|'$form->{datepaid}'| : 'NULL';
+ my $datepaid = ($form->{paid} != 0) ? qq|'$form->{datepaid}'| : 'NULL';
$query = qq|UPDATE ap SET
- invnumber = '$form->{invnumber}',
+ invnumber = |.$dbh->quote($form->{invnumber}).qq|,
transdate = '$form->{transdate}',
- ordnumber = '$form->{ordnumber}',
+ ordnumber = |.$dbh->quote($form->{ordnumber}).qq|,
vendor_id = $form->{vendor_id},
taxincluded = '$form->{taxincluded}',
- amount = $form->{invtotal},
- duedate = '$form->{duedate}',
- paid = $form->{invpaid},
+ amount = $form->{amount},
+ duedate = |.$form->dbquote($form->{duedate}, SQL_DATE).qq|,
+ paid = $form->{paid},
datepaid = $datepaid,
netamount = $form->{netamount},
- curr = '$form->{currency}',
- notes = '$form->{notes}'
+ curr = |.$dbh->quote($form->{currency}).qq|,
+ notes = |.$dbh->quote($form->{notes}).qq|,
+ department_id = $form->{department_id}
WHERE id = $form->{id}
|;
$dbh->do($query) || $form->dberror($query);
+ # amount for AP account
+ $form->{payables} = $form->{amount};
+
# update exchangerate
if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
@@ -170,12 +159,14 @@ sub post_transaction {
}
# add individual transactions
- foreach my $item (keys %{ $form->{AP} }) {
+ foreach my $item (keys %{ $form->{AP_amounts} }) {
+
if ($form->{$item} != 0) {
+
$project_id = 'NULL';
if ($item =~ /amount_/) {
- if ($form->{"project_id_$'"} && $form->{"projectnumber_$'"}) {
- $project_id = $form->{"project_id_$'"};
+ if ($form->{"projectnumber_$'"}) {
+ ($null, $project_id) = split /--/, $form->{"projectnumber_$'"}
}
}
@@ -183,20 +174,25 @@ sub post_transaction {
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
project_id)
VALUES ($form->{id}, (SELECT id FROM chart
- WHERE accno = '$form->{AP}{$item}'),
+ WHERE accno = '$form->{AP_amounts}{$item}'),
$form->{$item}, '$form->{transdate}', $project_id)|;
$dbh->do($query) || $form->dberror($query);
}
}
# if there is no amount but a payment record a payable
- if ($form->{amount} == 0 && $form->{invtotal} == 0) {
- $form->{payables} = $form->{invpaid};
+ if ($form->{amount} == 0) {
+ $form->{payables} = $form->{paid};
+ $form->{payables} -= $form->{paid_1} if $form->{amount_1} != 0;
}
# add paid transactions
for my $i (1 .. $form->{paidaccounts}) {
if ($form->{"paid_$i"} != 0) {
+
+ # get paid account
+ ($form->{AP_amounts}{"paid_$i"}) = split(/--/, $form->{"AP_paid_$i"});
+ $form->{"datepaid_$i"} = $form->{transdate} unless ($form->{"datepaid_$i"});
$exchangerate = 0;
if ($form->{currency} eq $form->{defaultcurrency}) {
@@ -208,22 +204,18 @@ sub post_transaction {
}
- # get paid account
- ($form->{AP}{"paid_$i"}) = split(/--/, $form->{"AP_paid_$i"});
- $form->{"datepaid_$i"} = $form->{transdate} unless ($form->{"datepaid_$i"});
-
- # if there is no amount and invtotal is zero there is no exchangerate
- if ($form->{amount} == 0 && $form->{invtotal} == 0) {
+ # if there is no amount
+ if ($form->{amount} == 0 && $form->{netamount} == 0) {
$form->{exchangerate} = $form->{"exchangerate_$i"};
}
$amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} * -1, 2);
- if ($form->{payables}) {
+ if ($form->{payables} != 0) {
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
transdate)
VALUES ($form->{id},
- (SELECT id FROM chart
- WHERE accno = '$form->{AP}{payables}'),
+ (SELECT id FROM chart
+ WHERE accno = '$form->{AP_amounts}{payables}'),
$amount, '$form->{"datepaid_$i"}')|;
$dbh->do($query) || $form->dberror($query);
}
@@ -231,12 +223,13 @@ sub post_transaction {
# add payment
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
- transdate, source)
+ transdate, source, memo)
VALUES ($form->{id},
- (SELECT id FROM chart
- WHERE accno = '$form->{AP}{"paid_$i"}'),
- $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
- '$form->{"source_$i"}')|;
+ (SELECT id FROM chart
+ WHERE accno = '$form->{AP_amounts}{"paid_$i"}'),
+ $form->{"paid_$i"}, '$form->{"datepaid_$i"}', |
+ .$dbh->quote($form->{"source_$i"}).qq|, |
+ .$dbh->quote($form->{"memo_$i"}).qq|)|;
$dbh->do($query) || $form->dberror($query);
# add exchange rate difference
@@ -245,8 +238,8 @@ sub post_transaction {
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
transdate, fx_transaction, cleared)
VALUES ($form->{id},
- (SELECT id FROM chart
- WHERE accno = '$form->{AP}{"paid_$i"}'),
+ (SELECT id FROM chart
+ WHERE accno = '$form->{AP_amounts}{"paid_$i"}'),
$amount, '$form->{"datepaid_$i"}', '1', '0')|;
$dbh->do($query) || $form->dberror($query);
@@ -260,7 +253,7 @@ sub post_transaction {
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
transdate, fx_transaction, cleared)
VALUES ($form->{id}, (SELECT id FROM chart
- WHERE accno = '$accno'),
+ WHERE accno = '$accno'),
$amount, '$form->{"datepaid_$i"}', '1', '0')|;
$dbh->do($query) || $form->dberror($query);
}
@@ -271,6 +264,16 @@ sub post_transaction {
}
}
}
+
+ # save printed and queued
+ $form->save_status($dbh);
+
+ my %audittrail = ( tablename => 'ap',
+ reference => $form->{invnumber},
+ formname => 'transaction',
+ action => 'posted',
+ id => $form->{id} );
+ $form->audittrail($dbh, "", \%audittrail);
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -283,24 +286,52 @@ sub post_transaction {
sub delete_transaction {
- my ($self, $myconfig, $form) = @_;
+ my ($self, $myconfig, $form, $spool) = @_;
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
- # check for other foreign currency transactions
- $form->delete_exchangerate($dbh) if ($form->{currency} ne $form->{defaultcurrency});
-
+ my %audittrail = ( tablename => 'ap',
+ reference => $form->{invnumber},
+ formname => 'transaction',
+ action => 'deleted',
+ id => $form->{id} );
+ $form->audittrail($dbh, "", \%audittrail);
+
my $query = qq|DELETE FROM ap WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
$query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
+
+ # delete spool files
+ $query = qq|SELECT spoolfile FROM status
+ WHERE trans_id = $form->{id}
+ AND spoolfile IS NOT NULL|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $spoolfile;
+ my @spoolfiles = ();
+
+ while (($spoolfile) = $sth->fetchrow_array) {
+ push @spoolfiles, $spoolfile;
+ }
+ $sth->finish;
+
+ $query = qq|DELETE FROM status WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
# commit and redirect
my $rc = $dbh->commit;
$dbh->disconnect;
+ if ($rc) {
+ foreach $spoolfile (@spoolfiles) {
+ unlink "$spool/$spoolfile" if $spoolfile;
+ }
+ }
+
$rc;
}
@@ -313,62 +344,114 @@ sub ap_transactions {
# connect to database
my $dbh = $form->dbconnect($myconfig);
-
- my $incemp = qq|, (SELECT e.name FROM employee e
- WHERE a.employee_id = e.id) AS employee
- | if ($form->{l_employee});
-
+ my $var;
+
+ my $paid = "a.paid";
+
+ if ($form->{outstanding}) {
+ $paid = qq|SELECT SUM(ac.amount)
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ WHERE ac.trans_id = a.id
+ AND (c.link LIKE '%AP_paid%' OR c.link = '')|;
+ $paid .= qq|
+ AND ac.transdate <= '$form->{transdateto}'| if $form->{transdateto};
+ }
+
my $query = qq|SELECT a.id, a.invnumber, a.transdate, a.duedate,
- a.amount, a.paid, a.ordnumber, v.name, a.invoice,
- a.netamount, a.datepaid, a.notes
-
- $incemp
-
- FROM ap a, vendor v
- WHERE a.vendor_id = v.id|;
-
+ a.amount, ($paid) AS paid, a.ordnumber, v.name,
+ a.invoice, a.netamount, a.datepaid, a.notes,
+ a.vendor_id, e.name AS employee, m.name AS manager,
+ a.curr, ex.sell AS exchangerate
+ FROM ap a
+ JOIN vendor v ON (a.vendor_id = v.id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ LEFT JOIN employee m ON (e.managerid = m.id)
+ LEFT JOIN exchangerate ex ON (ex.curr = a.curr
+ AND ex.transdate = a.transdate)
+ |;
+
+ my %ordinal = ( 'id' => 1,
+ 'invnumber' => 2,
+ 'transdate' => 3,
+ 'duedate' => 4,
+ 'ordnumber' => 7,
+ 'name' => 8,
+ 'datepaid' => 11,
+ 'employee' => 14,
+ 'manager' => 15,
+ 'curr' => 16
+ );
+
+ my @a = (transdate, invnumber, name);
+ push @a, "employee" if $form->{l_employee};
+ push @a, "manager" if $form->{l_manager};
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ my $where = "1 = 1";
+
if ($form->{vendor_id}) {
- $query .= " AND a.vendor_id = $form->{vendor_id}";
+ $where .= " AND a.vendor_id = $form->{vendor_id}";
} else {
if ($form->{vendor}) {
- my $vendor = $form->like(lc $form->{vendor});
- $query .= " AND lower(v.name) LIKE '$vendor'";
+ $var = $form->like(lc $form->{vendor});
+ $where .= " AND lower(v.name) LIKE '$var'";
}
}
+ if ($form->{department}) {
+ my ($null, $department_id) = split /--/, $form->{department};
+ $where .= " AND a.department_id = $department_id";
+ }
if ($form->{invnumber}) {
- my $invnumber = $form->like(lc $form->{invnumber});
- $query .= " AND lower(a.invnumber) LIKE '$invnumber'";
+ $var = $form->like(lc $form->{invnumber});
+ $where .= " AND lower(a.invnumber) LIKE '$var'";
+ $form->{open} = $form->{closed} = 0;
}
if ($form->{ordnumber}) {
- my $ordnumber = $form->like(lc $form->{ordnumber});
- $query .= " AND lower(a.ordnumber) LIKE '$ordnumber'";
+ $var = $form->like(lc $form->{ordnumber});
+ $where .= " AND lower(a.ordnumber) LIKE '$var'";
+ $form->{open} = $form->{closed} = 0;
}
if ($form->{notes}) {
- my $notes = $form->like(lc $form->{notes});
- $query .= " AND lower(a.notes) LIKE '$notes'";
+ $var = $form->like(lc $form->{notes});
+ $where .= " AND lower(a.notes) LIKE '$var'";
}
- $query .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
- $query .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+ ($form->{transdatefrom}, $form->{transdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
+
+ $where .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $where .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
if ($form->{open} || $form->{closed}) {
unless ($form->{open} && $form->{closed}) {
- $query .= " AND a.amount <> a.paid" if ($form->{open});
- $query .= " AND a.amount = a.paid" if ($form->{closed});
+ $where .= " AND a.amount != a.paid" if ($form->{open});
+ $where .= " AND a.amount = a.paid" if ($form->{closed});
}
}
- my @a = (transdate, invnumber, name);
- push @a, "employee" if $self->{l_employee};
- my $sortorder = join ', ', $form->sort_columns(@a);
- $sortorder = $form->{sort} unless $sortorder;
- $query .= " ORDER by $sortorder";
+ if ($form->{AP}) {
+ my ($accno) = split /--/, $form->{AP};
+ $where .= qq|
+ AND a.id IN (SELECT ac.trans_id
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ WHERE a.id = ac.trans_id
+ AND c.accno = '$accno')
+ |;
+ }
+
+ $query .= "WHERE $where
+ ORDER by $sortorder";
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $ap = $sth->fetchrow_hashref(NAME_lc)) {
- push @{ $form->{AP} }, $ap;
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $ref->{exchangerate} = 1 unless $ref->{exchangerate};
+ if ($form->{outstanding}) {
+ next if $form->round_amount($ref->{amount}, 2) == $form->round_amount($ref->{paid}, 2);
+ }
+ push @{ $form->{transactions} }, $ref;
}
$sth->finish;
diff --git a/sql-ledger/SL/AR.pm b/sql-ledger/SL/AR.pm
index 4ea3d82c3..80487e406 100644
--- a/sql-ledger/SL/AR.pm
+++ b/sql-ledger/SL/AR.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -32,81 +32,87 @@ package AR;
sub post_transaction {
my ($self, $myconfig, $form) = @_;
- my ($null, $taxrate, $amount, $tax, $diff);
+ my $null;
+ my $taxrate;
+ my $amount;
+ my $tax;
+ my $diff;
my $exchangerate = 0;
my $i;
# split and store id numbers in link accounts
- map { ($form->{AR}{"amount_$_"}) = split(/--/, $form->{"AR_amount_$_"}) } (1 .. $form->{rowcount});
- ($form->{AR}{receivables}) = split(/--/, $form->{AR});
-
+ map { ($form->{AR_amounts}{"amount_$_"}) = split(/--/, $form->{"AR_amount_$_"}) } (1 .. $form->{rowcount});
+ ($form->{AR_amounts}{receivables}) = split(/--/, $form->{AR});
+
+ ($null, $form->{department_id}) = split(/--/, $form->{department});
+ $form->{department_id} *= 1;
+
if ($form->{currency} eq $form->{defaultcurrency}) {
$form->{exchangerate} = 1;
} else {
$exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, 'buy');
+
+ $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
}
-
- $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
for $i (1 .. $form->{rowcount}) {
$form->{"amount_$i"} = $form->round_amount($form->parse_amount($myconfig, $form->{"amount_$i"}) * $form->{exchangerate}, 2);
- $amount += $form->{"amount_$i"};
+
+ $form->{netamount} += $form->{"amount_$i"};
+
}
- # this is for ar
- $form->{amount} = $amount;
-
+
# taxincluded doesn't make sense if there is no amount
- $form->{taxincluded} = 0 if ($form->{amount} == 0);
+ $form->{taxincluded} = 0 if ($form->{netamount} == 0);
foreach my $item (split / /, $form->{taxaccounts}) {
- $form->{AR}{"tax_$item"} = $item;
-
- $amount = $form->round_amount($form->parse_amount($myconfig, $form->{"tax_$item"}), 2);
-
- $form->{"tax_$item"} = $form->round_amount($amount * $form->{exchangerate}, 2);
- $form->{total_tax} += $form->{"tax_$item"};
+ $form->{AR_amounts}{"tax_$item"} = $item;
+ $form->{"tax_$item"} = $form->round_amount($form->parse_amount($myconfig, $form->{"tax_$item"}) * $form->{exchangerate}, 2);
+ $form->{tax} += $form->{"tax_$item"};
}
# adjust paidaccounts if there is no date in the last row
$form->{paidaccounts}-- unless ($form->{"datepaid_$form->{paidaccounts}"});
- $form->{invpaid} = 0;
+ $form->{paid} = 0;
# add payments
for $i (1 .. $form->{paidaccounts}) {
$form->{"paid_$i"} = $form->round_amount($form->parse_amount($myconfig, $form->{"paid_$i"}), 2);
- $form->{invpaid} += $form->{"paid_$i"};
+ $form->{paid} += $form->{"paid_$i"};
$form->{datepaid} = $form->{"datepaid_$i"};
- # reverse payment
- $form->{"paid_$i"} *= -1;
-
}
-
- $form->{invpaid} = $form->round_amount($form->{invpaid} * $form->{exchangerate}, 2);
+
if ($form->{taxincluded} *= 1) {
for $i (1 .. $form->{rowcount}) {
- $tax = $form->{total_tax} * $form->{"amount_$i"} / $form->{amount};
+ $tax = ($form->{netamount}) ? $form->{tax} * $form->{"amount_$i"} / $form->{netamount} : 0;
$amount = $form->{"amount_$i"} - $tax;
$form->{"amount_$i"} = $form->round_amount($amount, 2);
$diff += $amount - $form->{"amount_$i"};
}
- $form->{amount} -= $form->{total_tax};
+ $form->{netamount} -= $form->{tax};
# deduct difference from amount_1
$form->{amount_1} += $form->round_amount($diff, 2);
}
- # store invoice total, this goes into ar table
- $form->{invtotal} = $form->{amount} + $form->{total_tax};
+ $form->{amount} = $form->{netamount} + $form->{tax};
+ $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate}, 2);
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
- my ($query, $sth);
+ my $query;
+ my $sth;
+
+ ($null, $form->{employee_id}) = split /--/, $form->{employee};
+ unless ($form->{employee_id}) {
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh);
+ }
# if we have an id delete old records
if ($form->{id}) {
@@ -119,47 +125,41 @@ sub post_transaction {
my $uid = time;
$uid .= $form->{login};
- $query = qq|INSERT INTO ar (invnumber, employee_id)
- VALUES ('$uid', (SELECT id FROM employee
- WHERE login = '$form->{login}') )|;
+ $query = qq|INSERT INTO ar (invnumber)
+ VALUES ('$uid')|;
$dbh->do($query) || $form->dberror($query);
$query = qq|SELECT id FROM ar
WHERE invnumber = '$uid'|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- ($form->{id}) = $sth->fetchrow_array;
- $sth->finish;
-
+ ($form->{id}) = $dbh->selectrow_array($query);
}
- # escape '
- $form->{notes} =~ s/'/''/g;
-
+
# record last payment date in ar table
$form->{datepaid} = $form->{transdate} unless $form->{datepaid};
- my $datepaid = ($form->{invpaid} != 0) ? qq|'$form->{datepaid}'| : 'NULL';
-
+ my $datepaid = ($form->{paid} != 0) ? qq|'$form->{datepaid}'| : 'NULL';
+
$query = qq|UPDATE ar set
- invnumber = '$form->{invnumber}',
- ordnumber = '$form->{ordnumber}',
+ invnumber = |.$dbh->quote($form->{invnumber}).qq|,
+ ordnumber = |.$dbh->quote($form->{ordnumber}).qq|,
transdate = '$form->{transdate}',
customer_id = $form->{customer_id},
taxincluded = '$form->{taxincluded}',
- amount = $form->{invtotal},
+ amount = $form->{amount},
duedate = '$form->{duedate}',
- paid = $form->{invpaid},
+ paid = $form->{paid},
datepaid = $datepaid,
- netamount = $form->{amount},
+ netamount = $form->{netamount},
curr = '$form->{currency}',
- notes = '$form->{notes}'
+ notes = |.$dbh->quote($form->{notes}).qq|,
+ department_id = $form->{department_id},
+ employee_id = $form->{employee_id}
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
# amount for AR account
- $form->{receivables} = $form->round_amount($form->{invtotal} * -1, 2);
+ $form->{receivables} = $form->{amount} * -1;
# update exchangerate
@@ -168,12 +168,14 @@ sub post_transaction {
}
# add individual transactions for AR, amount and taxes
- foreach my $item (keys %{ $form->{AR} }) {
+ foreach my $item (keys %{ $form->{AR_amounts} }) {
+
if ($form->{$item} != 0) {
+
$project_id = 'NULL';
if ($item =~ /amount_/) {
- if ($form->{"project_id_$'"} && $form->{"projectnumber_$'"}) {
- $project_id = $form->{"project_id_$'"};
+ if ($form->{"projectnumber_$'"}) {
+ ($null, $project_id) = split /--/, $form->{"projectnumber_$'"};
}
}
@@ -181,22 +183,22 @@ sub post_transaction {
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
project_id)
VALUES ($form->{id}, (SELECT id FROM chart
- WHERE accno = '$form->{AR}{$item}'),
+ WHERE accno = '$form->{AR_amounts}{$item}'),
$form->{$item}, '$form->{transdate}', $project_id)|;
$dbh->do($query) || $form->dberror($query);
}
}
- # if there is no amount but a payment record a receivables
- if ($form->{amount} == 0 && $form->{invtotal} == 0) {
- $form->{receivables} = $form->{invpaid} * -1;
+ if ($form->{amount} == 0) {
+ $form->{receivables} = $form->{paid};
+ $form->{receivables} -= $form->{paid_1} if $form->{amount_1} != 0;
}
-
+
# add paid transactions
for my $i (1 .. $form->{paidaccounts}) {
if ($form->{"paid_$i"} != 0) {
- ($form->{AR}{"paid_$i"}) = split(/--/, $form->{"AR_paid_$i"});
+ ($form->{AR_amounts}{"paid_$i"}) = split(/--/, $form->{"AR_paid_$i"});
$form->{"datepaid_$i"} = $form->{transdate} unless ($form->{"datepaid_$i"});
$exchangerate = 0;
@@ -208,14 +210,14 @@ sub post_transaction {
$form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"});
}
-
- # if there is no amount and invtotal is zero there is no exchangerate
- if ($form->{amount} == 0 && $form->{invtotal} == 0) {
+
+ # if there is no amount
+ if ($form->{amount} == 0 && $form->{netamount} == 0) {
$form->{exchangerate} = $form->{"exchangerate_$i"};
}
# receivables amount
- $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} * -1, 2);
+ $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate}, 2);
if ($form->{receivables} != 0) {
# add receivable
@@ -223,47 +225,51 @@ sub post_transaction {
transdate)
VALUES ($form->{id},
(SELECT id FROM chart
- WHERE accno = '$form->{AR}{receivables}'),
+ WHERE accno = '$form->{AR_amounts}{receivables}'),
$amount, '$form->{"datepaid_$i"}')|;
$dbh->do($query) || $form->dberror($query);
}
$form->{receivables} = $amount;
- # add payment
- $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
- transdate, source)
- VALUES ($form->{id},
- (SELECT id FROM chart
- WHERE accno = '$form->{AR}{"paid_$i"}'),
- $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
- '$form->{"source_$i"}')|;
- $dbh->do($query) || $form->dberror($query);
-
-
- # exchangerate difference for payment
- $amount = $form->round_amount($form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1), 2);
-
- if ($amount != 0) {
+ if ($form->{"paid_$i"} != 0) {
+ # add payment
+ $amount = $form->{"paid_$i"} * -1;
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
- transdate, fx_transaction, cleared)
+ transdate, source, memo)
VALUES ($form->{id},
- (SELECT id FROM chart
- WHERE accno = '$form->{AR}{"paid_$i"}'),
- $amount, '$form->{"datepaid_$i"}', '1', '0')|;
+ (SELECT id FROM chart
+ WHERE accno = '$form->{AR_amounts}{"paid_$i"}'),
+ $amount, '$form->{"datepaid_$i"}', |
+ .$dbh->quote($form->{"source_$i"}).qq|, |
+ .$dbh->quote($form->{"memo_$i"}).qq|)|;
$dbh->do($query) || $form->dberror($query);
- }
- # exchangerate gain/loss
- $amount = $form->round_amount($form->{"paid_$i"} * ($form->{exchangerate} - $form->{"exchangerate_$i"}), 2);
-
- if ($amount != 0) {
- $accno = ($amount > 0) ? $form->{fxgain_accno} : $form->{fxloss_accno};
- $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
- transdate, fx_transaction, cleared)
- VALUES ($form->{id}, (SELECT id FROM chart
- WHERE accno = '$accno'),
- $amount, '$form->{"datepaid_$i"}', '1', '0')|;
- $dbh->do($query) || $form->dberror($query);
+
+ # exchangerate difference for payment
+ $amount = $form->round_amount($form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) * -1, 2);
+
+ if ($amount != 0) {
+ $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+ transdate, fx_transaction, cleared)
+ VALUES ($form->{id},
+ (SELECT id FROM chart
+ WHERE accno = '$form->{AR_amounts}{"paid_$i"}'),
+ $amount, '$form->{"datepaid_$i"}', '1', '0')|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+
+ # exchangerate gain/loss
+ $amount = $form->round_amount($form->{"paid_$i"} * ($form->{exchangerate} - $form->{"exchangerate_$i"}) * -1, 2);
+
+ if ($amount != 0) {
+ $accno = ($amount > 0) ? $form->{fxgain_accno} : $form->{fxloss_accno};
+ $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
+ transdate, fx_transaction, cleared)
+ VALUES ($form->{id}, (SELECT id FROM chart
+ WHERE accno = '$accno'),
+ $amount, '$form->{"datepaid_$i"}', '1', '0')|;
+ $dbh->do($query) || $form->dberror($query);
+ }
}
# update exchangerate record
@@ -273,7 +279,17 @@ sub post_transaction {
}
}
-
+ # save printed and queued
+ $form->save_status($dbh);
+
+ my %audittrail = ( tablename => 'ar',
+ reference => $form->{invnumber},
+ formname => 'transaction',
+ action => 'posted',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
+
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -288,19 +304,48 @@ sub delete_transaction {
# connect to database, turn AutoCommit off
my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my %audittrail = ( tablename => 'ar',
+ reference => $form->{invnumber},
+ formname => 'transaction',
+ action => 'deleted',
+ id => $form->{id} );
- # check for other foreign currency transactions
- $form->delete_exchangerate($dbh) if ($form->{currency} ne $form->{defaultcurrency});
-
+ $form->audittrail($dbh, "", \%audittrail);
+
my $query = qq|DELETE FROM ar WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
$query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
+
+ # delete spool files
+ $query = qq|SELECT spoolfile FROM status
+ WHERE trans_id = $form->{id}
+ AND spoolfile IS NOT NULL|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $spoolfile;
+ my @spoolfiles = ();
+
+ while (($spoolfile) = $sth->fetchrow_array) {
+ push @spoolfiles, $spoolfile;
+ }
+ $sth->finish;
+
+ $query = qq|DELETE FROM status WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
# commit
my $rc = $dbh->commit;
$dbh->disconnect;
+
+ if ($rc) {
+ foreach $spoolfile (@spoolfiles) {
+ unlink "$spool/$spoolfile" if $spoolfile;
+ }
+ }
$rc;
@@ -313,62 +358,128 @@ sub ar_transactions {
# connect to database
my $dbh = $form->dbconnect($myconfig);
+ my $var;
+
+ my $paid = "a.paid";
+
+ ($form->{transdatefrom}, $form->{transdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
+
+ if ($form->{outstanding}) {
+ $paid = qq|SELECT SUM(ac.amount) * -1
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ WHERE ac.trans_id = a.id
+ AND (c.link LIKE '%AR_paid%' OR c.link = '')|;
+ $paid .= qq|
+ AND ac.transdate <= '$form->{transdateto}'| if $form->{transdateto};
+ }
- my $incemp = qq|, (SELECT e.name FROM employee e
- WHERE a.employee_id = e.id) AS employee
- | if ($form->{l_employee});
-
my $query = qq|SELECT a.id, a.invnumber, a.ordnumber, a.transdate,
- a.duedate, a.netamount, a.amount, a.paid, c.name,
- a.invoice, a.datepaid, a.terms, a.notes, a.shippingpoint
-
- $incemp
-
- FROM ar a, customer c
- WHERE a.customer_id = c.id|;
+ a.duedate, a.netamount, a.amount, ($paid) AS paid,
+ a.invoice, a.datepaid, a.terms, a.notes,
+ a.shipvia, a.shippingpoint, e.name AS employee, c.name,
+ a.customer_id, a.till, m.name AS manager, a.curr,
+ ex.buy AS exchangerate
+ FROM ar a
+ JOIN customer c ON (a.customer_id = c.id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ LEFT JOIN employee m ON (e.managerid = m.id)
+ LEFT JOIN exchangerate ex ON (ex.curr = a.curr
+ AND ex.transdate = a.transdate)
+ |;
+
+ my %ordinal = ( 'id' => 1,
+ 'invnumber' => 2,
+ 'ordnumber' => 3,
+ 'transdate' => 4,
+ 'duedate' => 5,
+ 'datepaid' => 10,
+ 'shipvia' => 13,
+ 'shippingpoint' => 14,
+ 'employee' => 15,
+ 'name' => 16,
+ 'manager' => 19,
+ 'curr' => 20
+ );
+
+
+ my @a = (transdate, invnumber, name);
+ push @a, "employee" if $form->{l_employee};
+ push @a, "manager" if $form->{l_manager};
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+ my $where = "1 = 1";
if ($form->{customer_id}) {
- $query .= " AND a.customer_id = $form->{customer_id}";
+ $where .= " AND a.customer_id = $form->{customer_id}";
} else {
if ($form->{customer}) {
- my $customer = $form->like(lc $form->{customer});
- $query .= " AND lower(c.name) LIKE '$customer'";
+ $var = $form->like(lc $form->{customer});
+ $where .= " AND lower(c.name) LIKE '$var'";
}
}
+ if ($form->{department}) {
+ my ($null, $department_id) = split /--/, $form->{department};
+ $where .= " AND a.department_id = $department_id";
+ }
if ($form->{invnumber}) {
- my $invnumber = $form->like(lc $form->{invnumber});
- $query .= " AND lower(a.invnumber) LIKE '$invnumber'";
+ $var = $form->like(lc $form->{invnumber});
+ $where .= " AND lower(a.invnumber) LIKE '$var'";
+ $form->{open} = $form->{closed} = 0;
}
if ($form->{ordnumber}) {
- my $ordnumber = $form->like(lc $form->{ordnumber});
- $query .= " AND lower(a.ordnumber) LIKE '$ordnumber'";
+ $var = $form->like(lc $form->{ordnumber});
+ $where .= " AND lower(a.ordnumber) LIKE '$var'";
+ $form->{open} = $form->{closed} = 0;
+ }
+ if ($form->{shipvia}) {
+ $var = $form->like(lc $form->{shipvia});
+ $where .= " AND lower(a.shipvia) LIKE '$var'";
}
if ($form->{notes}) {
- my $notes = $form->like(lc $form->{notes});
- $query .= " AND lower(a.notes) LIKE '$notes'";
+ $var = $form->like(lc $form->{notes});
+ $where .= " AND lower(a.notes) LIKE '$var'";
}
-
- $query .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
- $query .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+ $where .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $where .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
if ($form->{open} || $form->{closed}) {
unless ($form->{open} && $form->{closed}) {
- $query .= " AND a.amount <> a.paid" if ($form->{open});
- $query .= " AND a.amount = a.paid" if ($form->{closed});
+ $where .= " AND a.amount != a.paid" if ($form->{open});
+ $where .= " AND a.amount = a.paid" if ($form->{closed});
}
}
- my @a = (transdate, invnumber, name);
- push @a, "employee" if $form->{l_employee};
- my $sortorder = join ', ', $form->sort_columns(@a);
- $sortorder = $form->{sort} unless $sortorder;
-
- $query .= " ORDER by $sortorder";
+ if ($form->{till}) {
+ $where .= " AND a.invoice = '1'
+ AND NOT a.till IS NULL";
+ if ($myconfig->{role} eq 'user') {
+ $where .= " AND e.login = '$form->{login}'";
+ }
+ }
+
+ if ($form->{AR}) {
+ my ($accno) = split /--/, $form->{AR};
+ $where .= qq|
+ AND a.id IN (SELECT ac.trans_id
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ WHERE a.id = ac.trans_id
+ AND c.accno = '$accno')
+ |;
+ }
+ $query .= "WHERE $where
+ ORDER by $sortorder";
+
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $ar = $sth->fetchrow_hashref(NAME_lc)) {
- push @{ $form->{AR} }, $ar;
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $ref->{exchangerate} = 1 unless $ref->{exchangerate};
+ if ($form->{outstanding}) {
+ next if $form->round_amount($ref->{amount}, 2) == $form->round_amount($ref->{paid}, 2);
+ }
+ push @{ $form->{transactions} }, $ref;
}
$sth->finish;
diff --git a/sql-ledger/SL/BP.pm b/sql-ledger/SL/BP.pm
new file mode 100644
index 000000000..d85077db2
--- /dev/null
+++ b/sql-ledger/SL/BP.pm
@@ -0,0 +1,371 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 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.
+#======================================================================
+#
+# Batch printing module backend routines
+#
+#======================================================================
+
+package BP;
+
+
+sub get_vc {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my %arap = ( invoice => ['ar'],
+ packing_list => ['oe', 'ar'],
+ sales_order => ['oe'],
+ work_order => ['oe'],
+ pick_list => ['oe', 'ar'],
+ purchase_order => ['oe'],
+ bin_list => ['oe'],
+ sales_quotation => ['oe'],
+ request_quotation => ['oe'],
+ check => ['ap'],
+ receipt => ['ar']
+ );
+
+ my $query = "";
+ my $sth;
+ my $n;
+ my $count;
+ my $item;
+
+ foreach $item (@{ $arap{$form->{type}} }) {
+ $query = qq|
+ SELECT count(*)
+ FROM (SELECT DISTINCT vc.id
+ FROM $form->{vc} vc, $item a, status s
+ WHERE a.$form->{vc}_id = vc.id
+ AND s.trans_id = a.id
+ AND s.formname = '$form->{type}'
+ AND s.spoolfile IS NOT NULL) AS total|;
+ ($n) = $dbh->selectrow_array($query);
+ $count += $n;
+ }
+
+
+ # build selection list
+ my $union = "";
+ $query = "";
+ if ($count < $myconfig->{vclimit}) {
+ foreach $item (@{ $arap{$form->{type}} }) {
+ $query .= qq|
+ $union
+ SELECT DISTINCT vc.id, vc.name
+ FROM $form->{vc} vc, $item a, status s
+ WHERE a.$form->{vc}_id = vc.id
+ AND s.trans_id = a.id
+ AND s.formname = '$form->{type}'
+ AND s.spoolfile IS NOT NULL|;
+ $union = "UNION";
+ }
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{"all_$form->{vc}"} }, $ref;
+ }
+ $sth->finish;
+ }
+
+ $form->all_years($dbh, $myconfig);
+
+ $dbh->disconnect;
+
+}
+
+
+
+sub payment_accounts {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT DISTINCT c.accno, c.description
+ FROM status s, chart c
+ WHERE s.chart_id = c.id
+ AND s.formname = '$form->{type}'|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{accounts} }, $ref;
+ }
+
+ $sth->finish;
+ $dbh->disconnect;
+
+}
+
+
+sub get_spoolfiles {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query;
+ my $invnumber = "invnumber";
+ my $item;
+
+ my %arap = ( invoice => ['ar'],
+ packing_list => ['oe', 'ar'],
+ sales_order => ['oe'],
+ work_order => ['oe'],
+ pick_list => ['oe', 'ar'],
+ purchase_order => ['oe'],
+ bin_list => ['oe'],
+ sales_quotation => ['oe'],
+ request_quotation => ['oe'],
+ check => ['ap'],
+ receipt => ['ar']
+ );
+
+
+ if ($form->{type} eq 'check' || $form->{type} eq 'receipt') {
+
+ my ($accno) = split /--/, $form->{account};
+
+ $query = qq|SELECT a.id, vc.name, a.invnumber, ac.transdate, s.spoolfile,
+ a.invoice, '$arap{$form->{type}}[0]' AS module
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ JOIN $arap{$form->{type}}[0] a ON (a.id = ac.trans_id)
+ JOIN status s ON (s.trans_id = a.id)
+ JOIN $form->{vc} vc ON (vc.id = a.$form->{vc}_id)
+ WHERE s.formname = '$form->{type}'
+ AND c.accno = '$accno'
+ AND NOT ac.fx_transaction|;
+
+ if ($form->{"$form->{vc}_id"}) {
+ $query .= qq| AND a.$form->{vc}_id = $form->{"$form->{vc}_id"}|;
+ } else {
+ if ($form->{$form->{vc}}) {
+ $item = $form->like(lc $form->{$form->{vc}});
+ $query .= " AND lower(vc.name) LIKE '$item'";
+ }
+ }
+ if ($form->{invnumber}) {
+ $item = $form->like(lc $form->{invnumber});
+ $query .= " AND lower(a.invnumber) LIKE '$item'";
+ }
+ if ($form->{ordnumber}) {
+ $item = $form->like(lc $form->{ordnumber});
+ $query .= " AND lower(a.ordnumber) LIKE '$item'";
+ }
+ if ($form->{quonumber}) {
+ $item = $form->like(lc $form->{quonumber});
+ $query .= " AND lower(a.quonumber) LIKE '$item'";
+ }
+
+ $query .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $query .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+
+ } else {
+
+ foreach $item (@{ $arap{$form->{type}} }) {
+
+ $invoice = "a.invoice";
+ $invnumber = "invnumber";
+
+ if ($item eq 'oe') {
+ $invnumber = "ordnumber";
+ $invoice = "'0'";
+ }
+
+ $query .= qq|
+ $union
+ SELECT a.id, vc.name, a.$invnumber AS invnumber, a.transdate,
+ a.ordnumber, a.quonumber, $invoice AS invoice,
+ '$item' AS module, s.spoolfile
+ FROM $item a, $form->{vc} vc, status s
+ WHERE s.trans_id = a.id
+ AND s.spoolfile IS NOT NULL
+ AND s.formname = '$form->{type}'
+ AND a.$form->{vc}_id = vc.id|;
+
+ if ($form->{"$form->{vc}_id"}) {
+ $query .= qq| AND a.$form->{vc}_id = $form->{"$form->{vc}_id"}|;
+ } else {
+ if ($form->{$form->{vc}}) {
+ $item = $form->like(lc $form->{$form->{vc}});
+ $query .= " AND lower(vc.name) LIKE '$item'";
+ }
+ }
+ if ($form->{invnumber}) {
+ $item = $form->like(lc $form->{invnumber});
+ $query .= " AND lower(a.invnumber) LIKE '$item'";
+ }
+ if ($form->{ordnumber}) {
+ $item = $form->like(lc $form->{ordnumber});
+ $query .= " AND lower(a.ordnumber) LIKE '$item'";
+ }
+ if ($form->{quonumber}) {
+ $item = $form->like(lc $form->{quonumber});
+ $query .= " AND lower(a.quonumber) LIKE '$item'";
+ }
+
+ $query .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $query .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+ $union = "UNION";
+
+ }
+ }
+
+ my %ordinal = ( 'name' => 2,
+ 'invnumber' => 3,
+ 'transdate' => 4,
+ 'ordnumber' => 5,
+ 'quonumber' => 6
+ );
+ my @a = (transdate, $invnumber, name);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ $query .= " ORDER by $sortorder";
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{SPOOL} }, $ref;
+ }
+
+ $sth->finish;
+ $dbh->disconnect;
+
+}
+
+
+sub delete_spool {
+ my ($self, $myconfig, $form, $spool) = @_;
+
+ # connect to database, turn AutoCommit off
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my $query;
+ my %audittrail;
+
+ if ($form->{type} =~ /(check|receipt)/) {
+ $query = qq|DELETE FROM status
+ WHERE spoolfile = ?|;
+ } else {
+ $query = qq|UPDATE status SET
+ spoolfile = NULL,
+ printed = '1'
+ WHERE spoolfile = ?|;
+ }
+ my $sth = $dbh->prepare($query) || $form->dberror($query);
+
+
+ foreach my $i (1 .. $form->{rowcount}) {
+ if ($form->{"checked_$i"}) {
+ $sth->execute($form->{"spoolfile_$i"}) || $form->dberror($query);
+ $sth->finish;
+
+ %audittrail = ( tablename => $form->{module},
+ reference => $form->{"reference_$i"},
+ formname => $form->{type},
+ action => 'dequeued',
+ id => $form->{"id_$i"} );
+
+ $form->audittrail($dbh, "", \%audittrail);
+ }
+ }
+
+ # commit
+ my $rc = $dbh->commit;
+ $dbh->disconnect;
+
+ if ($rc) {
+ foreach my $i (1 .. $form->{rowcount}) {
+ $_ = qq|$spool/$form->{"spoolfile_$i"}|;
+ if ($form->{"checked_$i"}) {
+ unlink;
+ }
+ }
+ }
+
+ $rc;
+
+}
+
+
+sub print_spool {
+ my ($self, $myconfig, $form, $spool) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my %audittrail;
+
+ my $query = qq|UPDATE status SET
+ printed = '1'
+ WHERE formname = '$form->{type}'
+ AND spoolfile = ?|;
+ my $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ foreach my $i (1 .. $form->{rowcount}) {
+ if ($form->{"checked_$i"}) {
+ open(OUT, $form->{OUT}) or $form->error("$form->{OUT} : $!");
+
+ $spoolfile = qq|$spool/$form->{"spoolfile_$i"}|;
+
+ # send file to printer
+ open(IN, $spoolfile) or $form->error("$spoolfile : $!");
+
+ while (<IN>) {
+ print OUT $_;
+ }
+ close(IN);
+ close(OUT);
+
+ $sth->execute($form->{"spoolfile_$i"}) || $form->dberror($query);
+ $sth->finish;
+
+ %audittrail = ( tablename => $form->{module},
+ reference => $form->{"reference_$i"},
+ formname => $form->{type},
+ action => 'printed',
+ id => $form->{"id_$i"} );
+
+ $form->audittrail($dbh, "", \%audittrail);
+
+ $dbh->commit;
+ }
+ }
+
+ $dbh->disconnect;
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/CA.pm b/sql-ledger/SL/CA.pm
index b71749d7c..2ae78bd5c 100644
--- a/sql-ledger/SL/CA.pm
+++ b/sql-ledger/SL/CA.pm
@@ -21,10 +21,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#======================================================================
-# chart of accounts
#
-# CHANGE LOG:
-# DS. 2000-07-04 Created
+# chart of accounts
#
#======================================================================
@@ -107,117 +105,339 @@ sub all_transactions {
while (my ($id) = $sth->fetchrow_array) {
push @id, $id;
}
-
$sth->finish;
- my $where = '1 = 1';
- # build WHERE clause from dates if any
+ my $fromdate_where;
+ my $todate_where;
+
+ ($form->{fromdate}, $form->{todate}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
+
if ($form->{fromdate}) {
- $where .= " AND ac.transdate >= '$form->{fromdate}'";
+ $fromdate_where = qq|
+ AND ac.transdate >= '$form->{fromdate}'
+ |;
}
if ($form->{todate}) {
- $where .= " AND ac.transdate <= '$form->{todate}'";
+ $todate_where .= qq|
+ AND ac.transdate <= '$form->{todate}'
+ |;
}
+
- my $sortorder = join ', ', $form->sort_columns(qw(transdate reference description));
- my $false = ($myconfig->{dbdriver} eq 'Pg') ? FALSE : q|'0'|;
+ my $false = ($myconfig->{dbdriver} =~ /Pg/) ? FALSE : q|'0'|;
# Oracle workaround, use ordinal positions
my %ordinal = ( transdate => 4,
reference => 2,
description => 3 );
- map { $sortorder =~ s/$_/$ordinal{$_}/ } keys %ordinal;
-
- if ($form->{accno}) {
+ my @a = qw(transdate reference description);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ my $null;
+ my $department_id;
+ my $dpt_where;
+ my $dpt_join;
+
+ ($null, $department_id) = split /--/, $form->{department};
+
+ if ($department_id) {
+ $dpt_join = qq|
+ JOIN department t ON (t.id = a.department_id)
+ |;
+ $dpt_where = qq|
+ AND t.id = $department_id
+ |;
+ }
+
+ my $project;
+ my $project_id;
+ if ($form->{projectnumber}) {
+ ($null, $project_id) = split /--/, $form->{projectnumber};
+ $project = qq|
+ AND ac.project_id = $project_id
+ |;
+ }
+
+ if ($form->{accno} || $form->{gifi_accno}) {
# get category for account
- $query = qq|SELECT category
+ $query = qq|SELECT category, link
FROM chart
WHERE accno = '$form->{accno}'|;
+
+ if ($form->{accounttype} eq 'gifi') {
+ $query = qq|SELECT category, link
+ FROM chart
+ WHERE gifi_accno = '$form->{gifi_accno}'
+ AND charttype = 'A'|;
+ }
+
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- ($form->{category}) = $sth->fetchrow_array;
+ ($form->{category}, $form->{link}) = $sth->fetchrow_array;
$sth->finish;
if ($form->{fromdate}) {
+
# get beginning balance
$query = qq|SELECT SUM(ac.amount)
- FROM acc_trans ac, chart c
- WHERE ac.chart_id = c.id
- AND c.accno = '$form->{accno}'
- AND ac.transdate < date '$form->{fromdate}'
+ FROM acc_trans ac
+ JOIN chart c ON (ac.chart_id = c.id)
+ $dpt_join
+ WHERE c.accno = '$form->{accno}'
+ AND ac.transdate < '$form->{fromdate}'
+ $dpt_where
+ $project
|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- ($form->{balance}) = $sth->fetchrow_array;
- $sth->finish;
- }
- }
-
- if ($form->{accounttype} eq 'gifi' && $form->{gifi_accno}) {
- # get category for account
- $query = qq|SELECT category
- FROM chart
- WHERE gifi_accno = '$form->{gifi_accno}'|;
- $sth = $dbh->prepare($query);
+ if ($project_id) {
+
+ $query .= qq|
+
+ UNION
+
+ SELECT SUM(ac.sellprice * ac.qty)
+ FROM invoice ac
+ JOIN ar a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.income_accno_id = c.id)
+ $dpt_join
+ WHERE c.accno = '$form->{accno}'
+ AND a.transdate < '$form->{fromdate}'
+ AND c.category = 'I'
+ $dpt_where
+ $project
+
+ UNION
+
+ SELECT SUM(ac.sellprice * ac.qty)
+ FROM invoice ac
+ JOIN ap a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE c.accno = '$form->{accno}'
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ AND a.transdate < '$form->{fromdate}'
+ AND c.category = 'E'
+ $dpt_where
+ $project
+
+ UNION
+
+ SELECT SUM(ac.sellprice * ac.allocated) * -1
+ FROM invoice ac
+ JOIN ap a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE c.accno = '$form->{accno}'
+ AND ac.assemblyitem = '0'
+ AND a.transdate < '$form->{fromdate}'
+ AND c.category = 'E'
+ $dpt_where
+ $project
+ |;
- $sth->execute || $form->dberror($query);
- ($form->{category}) = $sth->fetchrow_array;
- $sth->finish;
-
- if ($form->{fromdate}) {
- # get beginning balance
- $query = qq|SELECT SUM(ac.amount)
- FROM acc_trans ac, chart c
- WHERE ac.chart_id = c.id
- AND c.gifi_accno = '$form->{gifi_accno}'
- AND ac.transdate < date '$form->{fromdate}'
+ }
+
+ if ($form->{accounttype} eq 'gifi') {
+ $query = qq|SELECT SUM(ac.amount)
+ FROM acc_trans ac
+ JOIN chart c ON (ac.chart_id = c.id)
+ $dpt_join
+ WHERE c.gifi_accno = '$form->{gifi_accno}'
+ AND ac.transdate < '$form->{fromdate}'
+ $dpt_where
+ $project
+ |;
+
+ if ($project_id) {
+
+ $query .= qq|
+
+ UNION
+
+ SELECT SUM(ac.sellprice * ac.qty)
+ FROM invoice ac
+ JOIN ar a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.income_accno_id = c.id)
+ $dpt_join
+ WHERE c.gifi_accno = '$form->{gifi_accno}'
+ AND a.transdate < '$form->{fromdate}'
+ AND c.category = 'I'
+ $dpt_where
+ $project
+
+ UNION
+
+ SELECT SUM(ac.sellprice * ac.qty)
+ FROM invoice ac
+ JOIN ap a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE c.gifi_accno = '$form->{gifi_accno}'
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ AND a.transdate < '$form->{fromdate}'
+ AND c.category = 'E'
+ $dpt_where
+ $project
+
+ UNION
+
+ SELECT SUM(ac.sellprice * ac.allocated) * -1
+ FROM invoice ac
+ JOIN ap a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE c.gifi_accno = '$form->{gifi_accno}'
+ AND ac.assemblyitem = '0'
+ AND a.transdate < '$form->{fromdate}'
+ AND c.category = 'E'
+ $dpt_where
+ $project
|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- ($form->{balance}) = $sth->fetchrow_array;
- $sth->finish;
+ }
+ }
+
+ ($form->{balance}) = $dbh->selectrow_array($query);
+
}
}
-
+
$query = "";
-
+ my $union = "";
+
foreach my $id (@id) {
# get all transactions
- $query .= qq|
- SELECT g.id, g.reference, g.description, ac.transdate,
- $false AS invoice,
- ac.amount, 'gl' as charttype
- FROM gl g, acc_trans ac
- WHERE $where
- AND ac.chart_id = $id
- AND ac.trans_id = g.id
- UNION ALL
- SELECT a.id, a.invnumber, c.name, ac.transdate,
- a.invoice,
- ac.amount, 'ar' as charttype
- FROM ar a, acc_trans ac, customer c
- WHERE $where
- AND ac.chart_id = $id
- AND ac.trans_id = a.id
- AND a.customer_id = c.id
- UNION ALL
- SELECT a.id, a.invnumber, v.name, ac.transdate,
- a.invoice,
- ac.amount, 'ap' as charttype
- FROM ap a, acc_trans ac, vendor v
- WHERE $where
- AND ac.chart_id = $id
- AND ac.trans_id = a.id
- AND a.vendor_id = v.id
- UNION ALL|;
+ $query .= qq|$union
+ SELECT a.id, a.reference, a.description, ac.transdate,
+ $false AS invoice, ac.amount, 'gl' as module, ac.cleared,
+ '' AS till
+ FROM gl a
+ JOIN acc_trans ac ON (ac.trans_id = a.id)
+ $dpt_join
+ WHERE ac.chart_id = $id
+ $fromdate_where
+ $todate_where
+ $dpt_where
+ $project
+
+ UNION ALL
+
+ SELECT a.id, a.invnumber, c.name, ac.transdate,
+ a.invoice, ac.amount, 'ar' as module, ac.cleared,
+ a.till
+ FROM ar a
+ JOIN acc_trans ac ON (ac.trans_id = a.id)
+ JOIN customer c ON (a.customer_id = c.id)
+ $dpt_join
+ WHERE ac.chart_id = $id
+ $fromdate_where
+ $todate_where
+ $dpt_where
+ $project
+
+ UNION ALL
+
+ SELECT a.id, a.invnumber, v.name, ac.transdate,
+ a.invoice, ac.amount, 'ap' as module, ac.cleared,
+ a.till
+ FROM ap a
+ JOIN acc_trans ac ON (ac.trans_id = a.id)
+ JOIN vendor v ON (a.vendor_id = v.id)
+ $dpt_join
+ WHERE ac.chart_id = $id
+ $fromdate_where
+ $todate_where
+ $dpt_where
+ $project
+ |;
+
+ if ($project_id) {
+
+ $fromdate_where =~ s/ac\./a\./;
+ $todate_where =~ s/ac\./a\./;
+
+ $query .= qq|
+
+ UNION ALL
+
+ -- sold items
+
+ SELECT a.id, a.invnumber, c.name, a.transdate,
+ a.invoice, ac.sellprice * ac.qty, 'ar' as module, '0' AS cleared,
+ a.till
+ FROM ar a
+ JOIN invoice ac ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN customer c ON (a.customer_id = c.id)
+ $dpt_join
+ WHERE p.income_accno_id = $id
+ $fromdate_where
+ $todate_where
+ $dpt_where
+ $project
+
+ UNION ALL
+
+ -- bought services
+
+ SELECT a.id, a.invnumber, v.name, a.transdate,
+ a.invoice, ac.sellprice * ac.qty, 'ap' as module, '0' AS cleared,
+ a.till
+ FROM ap a
+ JOIN invoice ac ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN vendor v ON (a.vendor_id = v.id)
+ $dpt_join
+ WHERE p.expense_accno_id = $id
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ $fromdate_where
+ $todate_where
+ $dpt_where
+ $project
+
+ UNION ALL
+
+ -- cogs
+
+ SELECT a.id, a.invnumber, v.name, a.transdate,
+ a.invoice, ac.sellprice * ac.allocated * -1, 'ap' as module, '0' AS cleared,
+ a.till
+ FROM ap a
+ JOIN invoice ac ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN vendor v ON (a.vendor_id = v.id)
+ $dpt_join
+ WHERE p.expense_accno_id = $id
+ AND ac.assemblyitem = '0'
+ $fromdate_where
+ $todate_where
+ $dpt_where
+ $project
+
+ |;
+
+ $fromdate_where =~ s/a\./ac\./;
+ $todate_where =~ s/a\./ac\./;
+
+ }
+
+ $union = qq|
+ UNION ALL
+ |;
}
- $query =~ s/UNION ALL$//;
$query .= qq|
ORDER BY $sortorder|;
@@ -225,32 +445,36 @@ sub all_transactions {
$sth->execute || $form->dberror($query);
while (my $ca = $sth->fetchrow_hashref(NAME_lc)) {
-
+
# gl
- if ($ca->{charttype} eq "gl") {
+ if ($ca->{module} eq "gl") {
$ca->{module} = "gl";
}
# ap
- if ($ca->{charttype} eq "ap") {
+ if ($ca->{module} eq "ap") {
$ca->{module} = ($ca->{invoice}) ? 'ir' : 'ap';
+ $ca->{module} = 'ps' if $ca->{till};
}
# ar
- if ($ca->{charttype} eq "ar") {
+ if ($ca->{module} eq "ar") {
$ca->{module} = ($ca->{invoice}) ? 'is' : 'ar';
+ $ca->{module} = 'ps' if $ca->{till};
}
- if ($ca->{amount} < 0) {
- $ca->{debit} = $ca->{amount} * -1;
- $ca->{credit} = 0;
- } else {
- $ca->{credit} = $ca->{amount};
- $ca->{debit} = 0;
- }
-
- push @{ $form->{CA} }, $ca;
+ if ($ca->{amount}) {
+ if ($ca->{amount} < 0) {
+ $ca->{debit} = $ca->{amount} * -1;
+ $ca->{credit} = 0;
+ } else {
+ $ca->{credit} = $ca->{amount};
+ $ca->{debit} = 0;
+ }
+ push @{ $form->{CA} }, $ca;
+ }
+
}
$sth->finish;
diff --git a/sql-ledger/SL/CP.pm b/sql-ledger/SL/CP.pm
index f84bd1594..539ff6d9a 100644
--- a/sql-ledger/SL/CP.pm
+++ b/sql-ledger/SL/CP.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2002
+# Copyright (C) 2003
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -57,26 +57,32 @@ sub paymentaccounts {
# connect to database
my $dbh = $form->dbconnect($myconfig);
- my $query = qq|SELECT accno, description
+ my $query = qq|SELECT accno, description, link
FROM chart
- WHERE link LIKE '%$form->{arap}_paid%'
+ WHERE link LIKE '%$form->{ARAP}%'
ORDER BY accno|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
+ $form->{PR}{$form->{ARAP}} = ();
+ $form->{PR}{"$form->{ARAP}_paid"} = ();
+
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- push @{ $form->{PR} }, $ref;
+ foreach my $item (split /:/, $ref->{link}) {
+ if ($item eq $form->{ARAP}) {
+ push @{ $form->{PR}{$form->{ARAP}} }, $ref;
+ }
+ if ($item eq "$form->{ARAP}_paid") {
+ push @{ $form->{PR}{"$form->{ARAP}_paid"} }, $ref;
+ }
+ }
}
$sth->finish;
# get currencies and closedto
- $query = qq|SELECT curr, closedto
+ $query = qq|SELECT curr, closedto, current_date
FROM defaults|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- ($form->{currencies}, $form->{closedto}) = $sth->fetchrow_array;
- $sth->finish;
+ ($form->{currencies}, $form->{closedto}, $form->{datepaid}) = $dbh->selectrow_array($query);
$dbh->disconnect;
@@ -89,15 +95,14 @@ sub get_openvc {
my $dbh = $form->dbconnect($myconfig);
my $arap = ($form->{vc} eq 'customer') ? 'ar' : 'ap';
-
my $query = qq|SELECT count(*)
FROM $form->{vc} ct, $arap a
WHERE a.$form->{vc}_id = ct.id
AND a.amount != a.paid|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- my ($count) = $sth->fetchrow_array;
- $sth->finish;
+ my ($count) = $dbh->selectrow_array($query);
+
+ my $sth;
+ my $ref;
# build selection list
if ($count < $myconfig->{vclimit}) {
@@ -109,7 +114,7 @@ sub get_openvc {
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
push @{ $form->{"all_$form->{vc}"} }, $ref;
}
@@ -117,6 +122,44 @@ sub get_openvc {
}
+ if ($form->{ARAP} eq 'AR') {
+ $query = qq|SELECT id, description
+ FROM department
+ WHERE role = 'P'
+ ORDER BY 2|;
+ } else {
+ $query = qq|SELECT id, description
+ FROM department
+ ORDER BY 2|;
+ }
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_departments} }, $ref;
+ }
+ $sth->finish;
+
+ # get language codes
+ $query = qq|SELECT *
+ FROM language
+ ORDER BY 2|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ $form->{all_languages} = ();
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_languages} }, $ref;
+ }
+ $sth->finish;
+
+ # get currency for first name
+ if ($form->{"all_$form->{vc}"}) {
+ $query = qq|SELECT curr FROM $form->{vc}
+ WHERE id = $form->{"all_$form->{vc}"}->[0]->{id}|;
+ ($form->{currency}) = $dbh->selectrow_array($query);
+ }
+
$dbh->disconnect;
}
@@ -124,36 +167,34 @@ sub get_openvc {
sub get_openinvoices {
my ($self, $myconfig, $form) = @_;
-
- return unless $form->{"$form->{vc}_id"};
-
+
+ my $null;
+ my $department_id;
+
# connect to database
my $dbh = $form->dbconnect($myconfig);
-
+
my $where = qq|WHERE $form->{vc}_id = $form->{"$form->{vc}_id"}
AND curr = '$form->{currency}'
- AND NOT amount = paid|;
+ AND amount != paid|;
- if ($form->{transdatefrom}) {
- $where .= " AND transdate >= '$form->{transdatefrom}'";
- }
- if ($form->{transdateto}) {
- $where .= " AND transdate <= '$form->{transdateto}'";
- }
-
- my ($arap, $buysell);
+ my ($buysell);
if ($form->{vc} eq 'customer') {
- $arap = "ar";
$buysell = "buy";
} else {
- $arap = "ap";
$buysell = "sell";
}
+ ($null, $department_id) = split /--/, $form->{department};
+ if ($department_id) {
+ $where .= qq|
+ AND department_id = $department_id|;
+ }
+
my $query = qq|SELECT id, invnumber, transdate, amount, paid, curr
- FROM $arap
+ FROM $form->{arap}
$where
- ORDER BY id|;
+ ORDER BY transdate, invnumber|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -172,10 +213,12 @@ sub get_openinvoices {
sub process_payment {
my ($self, $myconfig, $form) = @_;
-
+
# connect to database, turn AutoCommit off
my $dbh = $form->dbconnect_noauto($myconfig);
+ my $sth;
+
my ($paymentaccno) = split /--/, $form->{account};
# if currency ne defaultcurrency update exchangerate
@@ -193,70 +236,94 @@ sub process_payment {
my $query = qq|SELECT fxgain_accno_id, fxloss_accno_id
FROM defaults|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- my ($fxgain_accno_id, $fxloss_accno_id) = $sth->fetchrow_array;
- $sth->finish;
+ my ($fxgain_accno_id, $fxloss_accno_id) = $dbh->selectrow_array($query);
- my ($ARAP, $arap, $buysell);
+ my ($buysell);
if ($form->{vc} eq 'customer') {
- $ARAP = "AR";
- $arap = "ar";
$buysell = "buy";
} else {
- $ARAP = "AP";
- $arap = "ap";
$buysell = "sell";
}
+
+ my $ml;
+ my $where;
+
+ if ($form->{ARAP} eq 'AR') {
+ $ml = 1;
+ $where = qq|
+ (c.link = 'AR'
+ OR c.link LIKE 'AR:%')
+ |;
+ } else {
+ $ml = -1;
+ $where = qq|
+ (c.link = 'AP'
+ OR c.link LIKE '%:AP'
+ OR c.link LIKE '%:AP:%')
+ |;
+ }
+ my $paymentamount = $form->parse_amount($myconfig, $form->{amount});
+
+ my $null;
+ ($null, $form->{department_id}) = split /--/, $form->{department};
+ $form->{department_id} *= 1;
+
+
+ # query to retrieve paid amount
+ $query = qq|SELECT paid FROM $form->{arap}
+ WHERE id = ?
+ FOR UPDATE|;
+ my $pth = $dbh->prepare($query) || $form->dberror($query);
+
+ my %audittrail;
+
# go through line by line
for my $i (1 .. $form->{rowcount}) {
- if ($form->{"paid_$i"}) {
+ $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
+ $form->{"due_$i"} = $form->parse_amount($myconfig, $form->{"due_$i"});
+
+ if ($form->{"checked_$i"} && $form->{"paid_$i"}) {
- $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
+ $paymentamount -= $form->{"paid_$i"};
# get exchangerate for original
- $query = qq|SELECT $buysell FROM exchangerate e, $arap a
+ $query = qq|SELECT $buysell
+ FROM exchangerate e
+ JOIN $form->{arap} a ON (a.transdate = e.transdate)
WHERE e.curr = '$form->{currency}'
- AND a.transdate = e.transdate
AND a.id = $form->{"id_$i"}|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- my ($exchangerate) = $sth->fetchrow_array;
- $sth->finish;
+ my ($exchangerate) = $dbh->selectrow_array($query);
$exchangerate = 1 unless $exchangerate;
- $query = qq|SELECT c.id FROM chart c, acc_trans a
- WHERE a.chart_id = c.id
- AND c.link = '$ARAP'
+ $query = qq|SELECT c.id
+ FROM chart c
+ JOIN acc_trans a ON (a.chart_id = c.id)
+ WHERE $where
AND a.trans_id = $form->{"id_$i"}|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- my ($id) = $sth->fetchrow_array;
- $sth->finish;
-
- my $amount = $form->round_amount($form->{"paid_$i"} * $exchangerate * -1, 2);
- $ml = ($ARAP eq 'AR') ? -1 : 1;
+ my ($id) = $dbh->selectrow_array($query);
+
+ $amount = $form->round_amount($form->{"paid_$i"} * $exchangerate, 2);
+
# add AR/AP
- $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate, amount)
- VALUES ($form->{"id_$i"}, $id,
- '$form->{datepaid}', $amount * $ml)|;
+ $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate,
+ amount)
+ VALUES ($form->{"id_$i"}, $id, '$form->{datepaid}',
+ $amount * $ml)|;
$dbh->do($query) || $form->dberror($query);
# add payment
- $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate, amount,
- source)
+ $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate,
+ amount, source, memo)
VALUES ($form->{"id_$i"},
(SELECT id FROM chart
WHERE accno = '$paymentaccno'),
- '$form->{datepaid}', $form->{"paid_$i"} * $ml,
- '$form->{source}')|;
+ '$form->{datepaid}', $form->{"paid_$i"} * $ml * -1, |
+ .$dbh->quote($form->{source}).qq|, |
+ .$dbh->quote($form->{memo}).qq|)|;
$dbh->do($query) || $form->dberror($query);
# add exchangerate difference if currency ne defaultcurrency
@@ -269,12 +336,11 @@ sub process_payment {
VALUES ($form->{"id_$i"},
(SELECT id FROM chart
WHERE accno = '$paymentaccno'),
- '$form->{datepaid}', $amount * $ml, '0', '1')|;
+ '$form->{datepaid}', $amount * $ml * -1, '0', '1')|;
$dbh->do($query) || $form->dberror($query);
# gain/loss
-
- $amount = $form->round_amount($form->{"paid_$i"} * ($exchangerate - $form->{exchangerate}) * $ml, 2);
+ $amount = $form->round_amount($form->{"paid_$i"} * ($exchangerate - $form->{exchangerate}) * $ml * -1, 2);
if ($amount != 0) {
my $accno_id = ($amount > 0) ? $fxgain_accno_id : $fxloss_accno_id;
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate,
@@ -287,15 +353,37 @@ sub process_payment {
$form->{"paid_$i"} = $form->round_amount($form->{"paid_$i"} * $exchangerate, 2);
+ $pth->execute($form->{"id_$i"}) || $form->dberror;
+ ($amount) = $pth->fetchrow_array;
+ $pth->finish;
+
+ $amount += $form->{"paid_$i"};
+
# update AR/AP transaction
- $query = qq|UPDATE $arap set
- paid = paid + $form->{"paid_$i"},
+ $query = qq|UPDATE $form->{arap} set
+ paid = $amount,
datepaid = '$form->{datepaid}'
WHERE id = $form->{"id_$i"}|;
$dbh->do($query) || $form->dberror($query);
+
+ %audittrail = ( tablename => $form->{arap},
+ reference => $form->{source},
+ formname => $form->{formname},
+ action => 'posted',
+ id => $form->{"id_$i"} );
+
+ $form->audittrail($dbh, "", \%audittrail);
+
}
}
-
+
+
+ # record a AR/AP with a payment
+ if ($form->round_amount($paymentamount, 2) != 0) {
+ $form->{invnumber} = "";
+ OP::overpayment("", $myconfig, $form, $dbh, $paymentamount, $ml, 1);
+ }
+
my $rc = $dbh->commit;
$dbh->disconnect;
diff --git a/sql-ledger/SL/CT.pm b/sql-ledger/SL/CT.pm
index 7c42cb843..bfcc2196a 100644
--- a/sql-ledger/SL/CT.pm
+++ b/sql-ledger/SL/CT.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -24,51 +24,87 @@
#
# backend code for customers and vendors
#
-# CHANGE LOG:
-# DS. 2000-07-04 Created
-#
#======================================================================
package CT;
-sub get_tuple {
+sub create_links {
my ($self, $myconfig, $form) = @_;
my $dbh = $form->dbconnect($myconfig);
- my $query = qq|SELECT *
- FROM $form->{db}
- WHERE id = $form->{id}|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
+ my $query;
+ my $sth;
+ my $ref;
+
+ if ($form->{id}) {
+ $query = qq|SELECT ct.*, b.description AS business, s.*,
+ e.name AS employee, g.pricegroup AS pricegroup,
+ l.description AS language, ct.curr
+ FROM $form->{db} ct
+ LEFT JOIN business b ON (ct.business_id = b.id)
+ LEFT JOIN shipto s ON (ct.id = s.trans_id)
+ LEFT JOIN employee e ON (ct.employee_id = e.id)
+ LEFT JOIN pricegroup g ON (g.id = ct.pricegroup_id)
+ LEFT JOIN language l ON (l.code = ct.language_code)
+ WHERE ct.id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
- my $ref = $sth->fetchrow_hashref(NAME_lc);
+ $ref = $sth->fetchrow_hashref(NAME_lc);
- map { $form->{$_} = $ref->{$_} } keys %$ref;
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
- $sth->finish;
+ $sth->finish;
+ # check if it is orphaned
+ my $arap = ($form->{db} eq 'customer') ? "ar" : "ap";
+ $query = qq|SELECT a.id
+ FROM $arap a
+ JOIN $form->{db} ct ON (a.$form->{db}_id = ct.id)
+ WHERE ct.id = $form->{id}
+ UNION
+ SELECT a.id
+ FROM oe a
+ JOIN $form->{db} ct ON (a.$form->{db}_id = ct.id)
+ WHERE ct.id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ unless ($sth->fetchrow_array) {
+ $form->{status} = "orphaned";
+ }
+ $sth->finish;
- # get ship to
- $query = qq|SELECT *
- FROM shipto
- WHERE trans_id = $form->{id}|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- $ref = $sth->fetchrow_hashref(NAME_lc);
+ # get taxes for customer/vendor
+ $query = qq|SELECT c.accno
+ FROM chart c
+ JOIN $form->{db}tax t ON (t.chart_id = c.id)
+ WHERE t.$form->{db}_id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
- map { $form->{$_} = $ref->{$_} } keys %$ref;
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $form->{tax}{$ref->{accno}}{taxable} = 1;
+ }
+ $sth->finish;
- $sth->finish;
+ } else {
+
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh);
+ $query = qq|SELECT current_date FROM defaults|;
+ ($form->{startdate}) = $dbh->selectrow_array($query);
+
+ }
# get tax labels
- $query = qq|SELECT accno, description
- FROM chart, tax
- WHERE link LIKE '%CT_tax%'
- AND chart.id = tax.chart_id
- ORDER BY accno|;
+ $query = qq|SELECT c.accno, c.description
+ FROM chart c
+ JOIN tax t ON (t.chart_id = c.id)
+ WHERE c.link LIKE '%CT_tax%'
+ ORDER BY c.accno|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -79,94 +115,67 @@ sub get_tuple {
$sth->finish;
chop $form->{taxaccounts};
- # get taxes for customer/vendor
- $query = qq|SELECT chart_id, accno
- FROM $form->{db}tax, chart
- WHERE chart_id = chart.id
- AND $form->{db}_id = $form->{id}|;
+
+ # get business types
+ $query = qq|SELECT *
+ FROM business
+ ORDER BY 2|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
-
+
while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
- $form->{tax}{$ref->{accno}}{taxable} = 1;
+ push @{ $form->{all_business} }, $ref;
}
$sth->finish;
-
- $dbh->disconnect;
-
-}
-
-
-sub taxaccounts {
- my ($self, $myconfig, $form) = @_;
-
- my $dbh = $form->dbconnect($myconfig);
-
- # get tax labels
- my $query = qq|SELECT accno, description
- FROM chart, tax
- WHERE link LIKE '%CT_tax%'
- AND chart.id = tax.chart_id
- ORDER BY accno|;
+ # this is for the salesperson
+ $query = qq|SELECT id, name
+ FROM employee
+ WHERE sales = '1'
+ ORDER BY 2|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
-
- while (my $taxref = $sth->fetchrow_hashref(NAME_lc)) {
- $form->{taxaccounts} .= "$taxref->{accno} ";
- $form->{tax}{$taxref->{accno}}{description} = $taxref->{description};
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_employee} }, $ref;
}
$sth->finish;
- chop $form->{taxaccounts};
-
- $dbh->disconnect;
-
-}
-
-
-sub delete_customer {
- my ($self, $myconfig, $form) = @_;
-
- # connect to database, turn AutoCommit off
- my $dbh = $form->dbconnect_noauto($myconfig);
-
- my $query = qq|SELECT id FROM ar
- WHERE customer_id = $form->{id}
- UNION
- SELECT id FROM oe
- WHERE customer_id = $form->{id}|;
- my $sth = $dbh->prepare($query) || $form->dberror($query);
- $sth->execute;
- my ($rc) = $sth->fetchrow_array;
+ # get language
+ $query = qq|SELECT *
+ FROM language
+ ORDER BY 2|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_language} }, $ref;
+ }
$sth->finish;
-
- if ($rc) {
- $dbh->disconnect;
- $rc = -1;
- } else {
-
- # delete customer
- $query = qq|DELETE FROM customer
- WHERE id = $form->{id}|;
- $dbh->do($query) || $form->dberror($query);
-
- $query = qq|DELETE FROM shipto
- WHERE trans_id = $form->{id}|;
- $dbh->do($query) || $form->dberror($query);
-
- $query = qq|DELETE FROM customertax
- WHERE customer_id = $form->{id}|;
- $dbh->do($query) || $form->dberror($query);
-
- # commit and redirect
- $rc = $dbh->commit;
- $dbh->disconnect;
-
+
+ # get pricegroups
+ $query = qq|SELECT *
+ FROM pricegroup
+ ORDER BY 2|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_pricegroup} }, $ref;
}
-
- $rc;
+ $sth->finish;
+
+ # get currencies
+ $query = qq|SELECT curr AS currencies
+ FROM defaults|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+ ($form->{currencies}) = $sth->fetchrow_array;
+ $sth->finish;
+
+ $dbh->disconnect;
+
}
@@ -174,18 +183,24 @@ sub save_customer {
my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->dbconnect($myconfig);
-
- # escape '
- map { $form->{$_} =~ s/'/''/g } qw(customernumber name addr1 addr2 addr3 addr4 contact notes);
-
+ my $dbh = $form->dbconnect_noauto($myconfig);
+ my $query;
+ my $sth;
+ my $null;
+
+ # remove double spaces
+ $form->{name} =~ s/ / /g;
+ # remove double minus and minus at the end
+ $form->{name} =~ s/--+/-/g;
+ $form->{name} =~ s/-+$//;
+
# assign value discount, terms, creditlimit
+ $form->{discount} = $form->parse_amount($myconfig, $form->{discount});
$form->{discount} /= 100;
$form->{terms} *= 1;
$form->{taxincluded} *= 1;
$form->{creditlimit} = $form->parse_amount($myconfig, $form->{creditlimit});
- my ($query, $sth);
if ($form->{id}) {
$query = qq|DELETE FROM customertax
@@ -195,6 +210,15 @@ sub save_customer {
$query = qq|DELETE FROM shipto
WHERE trans_id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
+
+ # retrieve enddate
+ if ($form->{type} && $form->{enddate}) {
+ my $now;
+ $query = qq|SELECT enddate, current_date AS now FROM customer|;
+ ($form->{enddate}, $now) = $dbh->selectrow_array($query);
+ $form->{enddate} = $now if $form->{enddate} lt $now;
+ }
+
} else {
my $uid = time;
$uid .= $form->{login};
@@ -212,25 +236,55 @@ sub save_customer {
$sth->finish;
}
-
+
+ my $employee_id;
+ ($null, $employee_id) = split /--/, $form->{employee};
+ $employee_id *= 1;
+
+ my $pricegroup_id;
+ ($null, $pricegroup_id) = split /--/, $form->{pricegroup};
+ $pricegroup_id *= 1;
+
+ my $business_id;
+ ($null, $business_id) = split /--/, $form->{business};
+ $business_id *= 1;
+
+ my $language_code;
+ ($null, $language_code) = split /--/, $form->{language};
+
+ $form->{customernumber} = $form->update_defaults($myconfig, "customernumber", $dbh) if ! $form->{customernumber};
+
$query = qq|UPDATE customer SET
- customernumber = '$form->{customernumber}',
- name = '$form->{name}',
- addr1 = '$form->{addr1}',
- addr2 = '$form->{addr2}',
- addr3 = '$form->{addr3}',
- addr4 = '$form->{addr4}',
- contact = '$form->{contact}',
+ customernumber = |.$dbh->quote($form->{customernumber}).qq|,
+ name = |.$dbh->quote($form->{name}).qq|,
+ address1 = |.$dbh->quote($form->{address1}).qq|,
+ address2 = |.$dbh->quote($form->{address2}).qq|,
+ city = |.$dbh->quote($form->{city}).qq|,
+ state = |.$dbh->quote($form->{state}).qq|,
+ zipcode = |.$dbh->quote($form->{zipcode}).qq|,
+ country = |.$dbh->quote($form->{country}).qq|,
+ contact = |.$dbh->quote($form->{contact}).qq|,
phone = '$form->{phone}',
fax = '$form->{fax}',
email = '$form->{email}',
cc = '$form->{cc}',
bcc = '$form->{bcc}',
- notes = '$form->{notes}',
+ notes = |.$dbh->quote($form->{notes}).qq|,
discount = $form->{discount},
creditlimit = $form->{creditlimit},
terms = $form->{terms},
- taxincluded = '$form->{taxincluded}'
+ taxincluded = '$form->{taxincluded}',
+ business_id = $business_id,
+ taxnumber = |.$dbh->quote($form->{taxnumber}).qq|,
+ sic_code = '$form->{sic}',
+ iban = '$form->{iban}',
+ bic = '$form->{bic}',
+ employee_id = $employee_id,
+ pricegroup_id = $pricegroup_id,
+ language_code = '$language_code',
+ curr = '$form->{curr}',
+ startdate = |.$form->dbquote($form->{startdate}, SQL_DATE).qq|,
+ enddate = |.$form->dbquote($form->{enddate}, SQL_DATE).qq|
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
@@ -248,6 +302,7 @@ sub save_customer {
# add shipto
$form->add_shipto($dbh, $form->{id});
+ $dbh->commit;
$dbh->disconnect;
}
@@ -257,15 +312,24 @@ sub save_vendor {
my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->dbconnect($myconfig);
+ my $dbh = $form->dbconnect_noauto($myconfig);
- # escape '
- map { $form->{$_} =~ s/'/''/g } qw(vendornumber name addr1 addr2 addr3 addr4 contact notes);
+ my $query;
+ my $sth;
+ my $null;
+
+ # remove double spaces
+ $form->{name} =~ s/ / /g;
+ # remove double minus and minus at the end
+ $form->{name} =~ s/--+/-/g;
+ $form->{name} =~ s/-+$//;
+ $form->{discount} = $form->parse_amount($myconfig, $form->{discount});
+ $form->{discount} /= 100;
$form->{terms} *= 1;
$form->{taxincluded} *= 1;
-
- my $query;
+ $form->{creditlimit} = $form->parse_amount($myconfig, $form->{creditlimit});
+
if ($form->{id}) {
$query = qq|DELETE FROM vendortax
@@ -293,23 +357,55 @@ sub save_vendor {
}
-
+ my $employee_id;
+ ($null, $employee_id) = split /--/, $form->{employee};
+ $employee_id *= 1;
+
+ my $pricegroup_id;
+ ($null, $pricegroup_id) = split /--/, $form->{pricegroup};
+ $pricegroup_id *= 1;
+
+ my $business_id;
+ ($null, $business_id) = split /--/, $form->{business};
+ $business_id *= 1;
+
+ my $language_code;
+ ($null, $language_code) = split /--/, $form->{language};
+
+ $form->{vendornumber} = $form->update_defaults($myconfig, "vendornumber", $dbh) if ! $form->{vendornumber};
+
$query = qq|UPDATE vendor SET
- vendornumber = '$form->{vendornumber}',
- name = '$form->{name}',
- addr1 = '$form->{addr1}',
- addr2 = '$form->{addr2}',
- addr3 = '$form->{addr3}',
- addr4 = '$form->{addr4}',
- contact = '$form->{contact}',
+ vendornumber = |.$dbh->quote($form->{vendornumber}).qq|,
+ name = |.$dbh->quote($form->{name}).qq|,
+ address1 = |.$dbh->quote($form->{address1}).qq|,
+ address2 = |.$dbh->quote($form->{address2}).qq|,
+ city = |.$dbh->quote($form->{city}).qq|,
+ state = |.$dbh->quote($form->{state}).qq|,
+ zipcode = |.$dbh->quote($form->{zipcode}).qq|,
+ country = |.$dbh->quote($form->{country}).qq|,
+ contact = |.$dbh->quote($form->{contact}).qq|,
phone = '$form->{phone}',
fax = '$form->{fax}',
email = '$form->{email}',
cc = '$form->{cc}',
bcc = '$form->{bcc}',
- notes = '$form->{notes}',
+ notes = |.$dbh->quote($form->{notes}).qq|,
terms = $form->{terms},
- taxincluded = '$form->{taxincluded}'
+ discount = $form->{discount},
+ creditlimit = $form->{creditlimit},
+ taxincluded = '$form->{taxincluded}',
+ gifi_accno = '$form->{gifi_accno}',
+ business_id = $business_id,
+ taxnumber = |.$dbh->quote($form->{taxnumber}).qq|,
+ sic_code = '$form->{sic}',
+ iban = '$form->{iban}',
+ bic = '$form->{bic}',
+ employee_id = $employee_id,
+ language_code = '$language_code',
+ pricegroup_id = $pricegroup_id,
+ curr = '$form->{curr}',
+ startdate = |.$form->dbquote($form->{startdate}, SQL_DATE).qq|,
+ enddate = |.$form->dbquote($form->{enddate}, SQL_DATE).qq|
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
@@ -327,113 +423,422 @@ sub save_vendor {
# add shipto
$form->add_shipto($dbh, $form->{id});
+ $dbh->commit;
$dbh->disconnect;
}
-sub delete_vendor {
+sub delete {
my ($self, $myconfig, $form) = @_;
- # connect to database, turn AutoCommit off
- my $dbh = $form->dbconnect_noauto($myconfig);
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ # delete customer/vendor
+ my $query = qq|DELETE FROM $form->{db}
+ WHERE id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
- # check if there are any transactions on file
- my $query = qq|SELECT id FROM ap
- WHERE vendor_id = $form->{id}
- UNION
- SELECT id FROM oe
- WHERE vendor_id = $form->{id}|;
- my $sth = $dbh->prepare($query) || $form->dberror($query);
- $sth->execute;
+}
+
+
+sub search {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $where = "1 = 1";
+ $form->{sort} = ($form->{sort}) ? $form->{sort} : "name";
+ my @a = qw(name);
+ my $sortorder = $form->sort_order(\@a);
+
+ my $var;
+ my $item;
+
+ @a = ("$form->{db}number");
+ push @a, qw(name contact city state zipcode country notes email);
- my ($rc) = $sth->fetchrow_array;
- $sth->finish;
+ foreach $item (@a) {
+ if ($form->{$item}) {
+ $var = $form->like(lc $form->{$item});
+ $where .= " AND lower(ct.$item) LIKE '$var'";
+ }
+ }
+ if ($form->{address}) {
+ $var = $form->like(lc $form->{address});
+ $where .= " AND (lower(ct.address1) LIKE '$var' OR lower(ct.address2) LIKE '$var')";
+ }
+
+ if ($form->{status} eq 'orphaned') {
+ $where .= qq| AND ct.id NOT IN (SELECT o.$form->{db}_id
+ FROM oe o, $form->{db} cv
+ WHERE cv.id = o.$form->{db}_id)|;
+ if ($form->{db} eq 'customer') {
+ $where .= qq| AND ct.id NOT IN (SELECT a.customer_id
+ FROM ar a, customer cv
+ WHERE cv.id = a.customer_id)|;
+ }
+ if ($form->{db} eq 'vendor') {
+ $where .= qq| AND ct.id NOT IN (SELECT a.vendor_id
+ FROM ap a, vendor cv
+ WHERE cv.id = a.vendor_id)|;
+ }
+ $form->{l_invnumber} = $form->{l_ordnumber} = $form->{l_quonumber} = "";
+ }
- if ($rc) {
- $dbh->disconnect;
- $rc = -1;
- } else {
+
+ my $query = qq|SELECT ct.*, b.description AS business,
+ e.name AS employee, g.pricegroup, l.description AS language,
+ m.name AS manager
+ FROM $form->{db} ct
+ LEFT JOIN business b ON (ct.business_id = b.id)
+ LEFT JOIN employee e ON (ct.employee_id = e.id)
+ LEFT JOIN employee m ON (m.id = e.managerid)
+ LEFT JOIN pricegroup g ON (ct.pricegroup_id = g.id)
+ LEFT JOIN language l ON (l.code = ct.language_code)
+ WHERE $where|;
+
+ # redo for invoices, orders and quotations
+ if ($form->{l_transnumber} || $form->{l_invnumber} || $form->{l_ordnumber} || $form->{l_quonumber}) {
+
+ my ($ar, $union, $module);
+ $query = "";
+ my $transwhere;
+ my $openarap = "";
+ my $openoe = "";
- # delete vendor
- $query = qq|DELETE FROM vendor
- WHERE id = $form->{id}|;
- $dbh->do($query) || $form->dberror($query);
+ if ($form->{open} || $form->{closed}) {
+ unless ($form->{open} && $form->{closed}) {
+ $openarap = " AND a.amount != a.paid" if $form->{open};
+ $openarap = " AND a.amount = a.paid" if $form->{closed};
+ $openoe = " AND o.closed = '0'" if $form->{open};
+ $openoe = " AND o.closed = '1'" if $form->{closed};
+ }
+ }
+
+ if ($form->{l_transnumber}) {
+ $ar = ($form->{db} eq 'customer') ? 'ar' : 'ap';
+ $module = $ar;
+
+ $transwhere = "";
+ $transwhere .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $transwhere .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+
+ $query = qq|SELECT ct.*, b.description AS business,
+ a.invnumber, a.ordnumber, a.quonumber, a.id AS invid,
+ '$ar' AS module, 'invoice' AS formtype,
+ (a.amount = a.paid) AS closed, a.amount, a.netamount
+ FROM $form->{db} ct
+ JOIN $ar a ON (a.$form->{db}_id = ct.id)
+ LEFT JOIN business b ON (ct.business_id = b.id)
+ WHERE $where
+ AND a.invoice = '0'
+ $transwhere
+ $openarap
+ |;
+
+ $union = qq|
+ UNION|;
+
+ }
- $query = qq|DELETE FROM shipto
- WHERE trans_id = $form->{id}|;
- $dbh->do($query) || $form->dberror($query);
+ if ($form->{l_invnumber}) {
+ $ar = ($form->{db} eq 'customer') ? 'ar' : 'ap';
+ $module = ($ar eq 'ar') ? 'is' : 'ir';
- $query = qq|DELETE FROM vendortax
- WHERE vendor_id = $form->{id}|;
- $dbh->do($query) || $form->dberror($query);
+ $transwhere = "";
+ $transwhere .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $transwhere .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+ $query .= qq|$union
+ SELECT ct.*, b.description AS business,
+ a.invnumber, a.ordnumber, a.quonumber, a.id AS invid,
+ '$module' AS module, 'invoice' AS formtype,
+ (a.amount = a.paid) AS closed, a.amount, a.netamount
+ FROM $form->{db} ct
+ JOIN $ar a ON (a.$form->{db}_id = ct.id)
+ LEFT JOIN business b ON (ct.business_id = b.id)
+ WHERE $where
+ AND a.invoice = '1'
+ $transwhere
+ $openarap
+ |;
+
+ $union = qq|
+ UNION|;
+
+ }
+
+ if ($form->{l_ordnumber}) {
+
+ $transwhere = "";
+ $transwhere .= " AND o.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $transwhere .= " AND o.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+ $query .= qq|$union
+ SELECT ct.*, b.description AS business,
+ ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid,
+ 'oe' AS module, 'order' AS formtype,
+ o.closed, o.amount, o.netamount
+ FROM $form->{db} ct
+ JOIN oe o ON (o.$form->{db}_id = ct.id)
+ LEFT JOIN business b ON (ct.business_id = b.id)
+ WHERE $where
+ AND o.quotation = '0'
+ $transwhere
+ $openoe
+ |;
+
+ $union = qq|
+ UNION|;
+
+ }
+
+ if ($form->{l_quonumber}) {
+
+ $transwhere = "";
+ $transwhere .= " AND o.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $transwhere .= " AND o.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+ $query .= qq|$union
+ SELECT ct.*, b.description AS business,
+ ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid,
+ 'oe' AS module, 'quotation' AS formtype,
+ o.closed, o.amount, o.netamount
+ FROM $form->{db} ct
+ JOIN oe o ON (o.$form->{db}_id = ct.id)
+ LEFT JOIN business b ON (ct.business_id = b.id)
+ WHERE $where
+ AND o.quotation = '1'
+ $transwhere
+ $openoe
+ |;
- # commit and redirect
- $rc = $dbh->commit;
- $dbh->disconnect;
+ }
+ $sortorder .= ", invid";
}
- $rc;
+ $query .= qq|
+ ORDER BY $sortorder|;
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $ref->{address} = "";
+ map { $ref->{address} .= "$ref->{$_} "; } qw(address1 address2 city state zipcode country);
+ push @{ $form->{CT} }, $ref;
+ }
+
+ $sth->finish;
+ $dbh->disconnect;
}
-sub search {
+sub get_history {
my ($self, $myconfig, $form) = @_;
-
+
# connect to database
my $dbh = $form->dbconnect($myconfig);
+ my $query;
my $where = "1 = 1";
- $form->{sort} = "name" unless ($form->{sort});
+ $form->{sort} = "partnumber" unless $form->{sort};
+ my $sortorder = $form->{sort};
+ my %ordinal = ();
+ my $var;
+ my $table;
+
+ # setup ASC or DESC
+ $form->sort_order();
if ($form->{"$form->{db}number"}) {
- my $companynumber = $form->like(lc $form->{"$form->{db}number"});
- $where .= " AND lower($form->{db}number) LIKE '$companynumber'";
+ $var = $form->like(lc $form->{"$form->{db}number"});
+ $where .= " AND lower(ct.$form->{db}number) LIKE '$var'";
}
if ($form->{name}) {
- my $name = $form->like(lc $form->{name});
- $where .= " AND lower(name) LIKE '$name'";
+ $var = $form->like(lc $form->{name});
+ $where .= " AND lower(ct.name) LIKE '$var'";
+ }
+ if ($form->{address}) {
+ $var = $form->like(lc $form->{address});
+ $where .= " AND lower(ct.address1) LIKE '$var'";
+ }
+ if ($form->{city}) {
+ $var = $form->like(lc $form->{city});
+ $where .= " AND lower(ct.city) LIKE '$var'";
+ }
+ if ($form->{state}) {
+ $var = $form->like(lc $form->{state});
+ $where .= " AND lower(ct.state) LIKE '$var'";
+ }
+ if ($form->{zipcode}) {
+ $var = $form->like(lc $form->{zipcode});
+ $where .= " AND lower(ct.zipcode) LIKE '$var'";
+ }
+ if ($form->{country}) {
+ $var = $form->like(lc $form->{country});
+ $where .= " AND lower(ct.country) LIKE '$var'";
}
if ($form->{contact}) {
- my $contact = $form->like(lc $form->{contact});
- $where .= " AND lower(contact) LIKE '$contact'";
+ $var = $form->like(lc $form->{contact});
+ $where .= " AND lower(ct.contact) LIKE '$var'";
+ }
+ if ($form->{notes}) {
+ $var = $form->like(lc $form->{notes});
+ $where .= " AND lower(ct.notes) LIKE '$var'";
}
if ($form->{email}) {
- my $email = $form->like(lc $form->{email});
- $where .= " AND lower(email) LIKE '$email'";
+ $var = $form->like(lc $form->{email});
+ $where .= " AND lower(ct.email) LIKE '$var'";
}
- if ($form->{status} eq 'orphaned') {
- $where .= qq| AND id NOT IN (SELECT o.$form->{db}_id
- FROM oe o, $form->{db} ct
- WHERE ct.id = o.$form->{db}_id)|;
- if ($form->{db} eq 'customer') {
- $where .= qq| AND id NOT IN (SELECT a.customer_id
- FROM ar a, customer ct
- WHERE ct.id = a.customer_id)|;
- }
- if ($form->{db} eq 'vendor') {
- $where .= qq| AND id NOT IN (SELECT a.vendor_id
- FROM ap a, vendor ct
- WHERE ct.id = a.vendor_id)|;
+ $where .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $where .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+ if ($form->{open} || $form->{closed}) {
+ unless ($form->{open} && $form->{closed}) {
+ if ($form->{type} eq 'invoice') {
+ $where .= " AND a.amount != a.paid" if $form->{open};
+ $where .= " AND a.amount = a.paid" if $form->{closed};
+ } else {
+ $where .= " AND a.closed = '0'" if $form->{open};
+ $where .= " AND a.closed = '1'" if $form->{closed};
+ }
}
}
- my $query = qq~SELECT id, name, $form->{db}number,
- addr1 || ' ' || addr2 || ' ' || addr3 || ' ' || addr4 AS address,
- contact, phone, fax, email, cc, terms
- FROM $form->{db}
- WHERE $where
- ORDER BY $form->{sort}~;
+ my $invnumber = 'invnumber';
+ my $deldate = 'deliverydate';
+ my $buysell;
+
+ if ($form->{db} eq 'customer') {
+ $buysell = "buy";
+ if ($form->{type} eq 'invoice') {
+ $where .= qq| AND a.invoice = '1' AND i.assemblyitem = '0'|;
+ $table = 'ar';
+ } else {
+ $table = 'oe';
+ if ($form->{type} eq 'order') {
+ $invnumber = 'ordnumber';
+ $where .= qq| AND a.quotation = '0'|;
+ } else {
+ $invnumber = 'quonumber';
+ $where .= qq| AND a.quotation = '1'|;
+ }
+ $deldate = 'reqdate';
+ }
+ }
+ if ($form->{db} eq 'vendor') {
+ $buysell = "sell";
+ if ($form->{type} eq 'invoice') {
+ $where .= qq| AND a.invoice = '1' AND i.assemblyitem = '0'|;
+ $table = 'ap';
+ } else {
+ $table = 'oe';
+ if ($form->{type} eq 'order') {
+ $invnumber = 'ordnumber';
+ $where .= qq| AND a.quotation = '0'|;
+ } else {
+ $invnumber = 'quonumber';
+ $where .= qq| AND a.quotation = '1'|;
+ }
+ $deldate = 'reqdate';
+ }
+ }
+
+ my $invjoin = qq|
+ JOIN invoice i ON (i.trans_id = a.id)|;
+
+ if ($form->{type} eq 'order') {
+ $invjoin = qq|
+ JOIN orderitems i ON (i.trans_id = a.id)|;
+ }
+ if ($form->{type} eq 'quotation') {
+ $invjoin = qq|
+ JOIN orderitems i ON (i.trans_id = a.id)|;
+ $where .= qq| AND a.quotation = '1'|;
+ }
+
+
+ if ($form->{history} eq 'summary') {
+ $query = qq|SELECT curr FROM defaults|;
+ my ($curr) = $dbh->selectrow_array($query);
+ $curr =~ s/:.*//;
+
+ %ordinal = ( partnumber => 8,
+ description => 9
+ );
+ $sortorder = "2 $form->{direction}, 1, $ordinal{$sortorder} $form->{direction}";
+
+ $query = qq|SELECT ct.id AS ctid, ct.name, ct.address1,
+ ct.address2, ct.city, ct.state,
+ p.id AS pid, p.partnumber, i.description, p.unit,
+ sum(i.qty) AS qty, sum(i.sellprice) AS sellprice,
+ '$curr' AS curr,
+ ct.zipcode, ct.country
+ FROM $form->{db} ct
+ JOIN $table a ON (a.$form->{db}_id = ct.id)
+ $invjoin
+ JOIN parts p ON (p.id = i.parts_id)
+ WHERE $where
+ GROUP BY ct.id, ct.name, ct.address1, ct.address2, ct.city,
+ ct.state, ct.zipcode, ct.country,
+ p.id, p.partnumber, i.description, p.unit
+ ORDER BY $sortorder|;
+ } else {
+ %ordinal = ( partnumber => 9,
+ description => 12,
+ "$deldate" => 16,
+ serialnumber => 17,
+ projectnumber => 18
+ );
+
+ $sortorder = "2 $form->{direction}, 1, 11, $ordinal{$sortorder} $form->{direction}";
+
+ $query = qq|SELECT ct.id AS ctid, ct.name, ct.address1,
+ ct.address2, ct.city, ct.state,
+ p.id AS pid, p.partnumber, a.id AS invid,
+ a.$invnumber, a.curr, i.description,
+ i.qty, i.sellprice, i.discount,
+ i.$deldate, i.serialnumber, pr.projectnumber,
+ e.name AS employee, ct.zipcode, ct.country, i.unit|;
+ $query .= qq|, i.fxsellprice| if $form->{type} eq 'invoice';
+
+ if ($form->{type} ne 'invoice') {
+ if ($form->{l_curr}) {
+ $query .= qq|, (SELECT $buysell FROM exchangerate ex
+ WHERE a.curr = ex.curr
+ AND a.transdate = ex.transdate) AS exchangerate|;
+ }
+ }
+
+ $query .= qq|
+ FROM $form->{db} ct
+ JOIN $table a ON (a.$form->{db}_id = ct.id)
+ $invjoin
+ JOIN parts p ON (p.id = i.parts_id)
+ LEFT JOIN project pr ON (pr.id = i.project_id)
+ LEFT JOIN employee e ON (e.id = a.employee_id)
+ WHERE $where
+ ORDER BY $sortorder|;
+ }
+
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
-
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $ref->{address} = "";
+ $ref->{exchangerate} = 1 unless $ref->{exchangerate};
+ map { $ref->{address} .= "$ref->{$_} "; } qw(address1 address2 city state zipcode country);
+ $ref->{id} = $ref->{ctid};
push @{ $form->{CT} }, $ref;
}
@@ -443,5 +848,161 @@ sub search {
}
+sub pricelist {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query;
+
+ if ($form->{db} eq 'customer') {
+ $query = qq|SELECT p.id, p.partnumber, p.description,
+ p.sellprice, pg.partsgroup, p.partsgroup_id,
+ m.pricebreak, m.sellprice,
+ m.validfrom, m.validto, m.curr
+ FROM partscustomer m
+ JOIN parts p ON (p.id = m.parts_id)
+ LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
+ WHERE m.customer_id = $form->{id}
+ ORDER BY partnumber|;
+ }
+ if ($form->{db} eq 'vendor') {
+ $query = qq|SELECT p.id, p.partnumber AS sku, p.description,
+ pg.partsgroup, p.partsgroup_id,
+ m.partnumber, m.leadtime, m.lastcost, m.curr
+ FROM partsvendor m
+ JOIN parts p ON (p.id = m.parts_id)
+ LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
+ WHERE m.vendor_id = $form->{id}
+ ORDER BY p.partnumber|;
+ }
+
+ my $sth;
+ my $ref;
+
+ if ($form->{id}) {
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_partspricelist} }, $ref;
+ }
+ $sth->finish;
+ }
+
+ $query = qq|SELECT curr FROM defaults|;
+ ($form->{currencies}) = $dbh->selectrow_array($query);
+
+ $query = qq|SELECT id, partsgroup FROM partsgroup
+ ORDER BY partsgroup|;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ $form->{all_partsgroup} = ();
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_partsgroup} }, $ref;
+ }
+ $sth->finish;
+
+ $dbh->disconnect;
+
+}
+
+
+sub save_pricelist {
+ my ($self, $myconfig, $form) = @_;
+
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my $query = qq|DELETE FROM parts$form->{db}
+ WHERE $form->{db}_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+
+ foreach $i (1 .. $form->{rowcount}) {
+
+ if ($form->{"id_$i"}) {
+
+ if ($form->{db} eq 'customer') {
+ map { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) } qw(pricebreak sellprice);
+
+ $query = qq|INSERT INTO parts$form->{db} (parts_id, customer_id,
+ pricebreak, sellprice, validfrom, validto, curr)
+ VALUES ($form->{"id_$i"}, $form->{id},
+ $form->{"pricebreak_$i"}, $form->{"sellprice_$i"},|
+ .$form->dbquote($form->{"validfrom_$i"}, SQL_DATE) .qq|,|
+ .$form->dbquote($form->{"validto_$i"}, SQL_DATE) .qq|,
+ '$form->{"curr_$i"}')|;
+ } else {
+ map { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) } qw(leadtime lastcost);
+
+ $query = qq|INSERT INTO parts$form->{db} (parts_id, vendor_id,
+ partnumber, lastcost, leadtime, curr)
+ VALUES ($form->{"id_$i"}, $form->{id},
+ '$form->{"partnumber_$i"}', $form->{"lastcost_$i"},
+ $form->{"leadtime_$i"}, '$form->{"curr_$i"}')|;
+
+ }
+ $dbh->do($query) || $form->dberror($query);
+ }
+
+ }
+
+ $_ = $dbh->commit;
+ $dbh->disconnect;
+
+}
+
+
+
+sub retrieve_item {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $i = $form->{rowcount};
+ my $var;
+ my $null;
+
+ my $where = "WHERE p.obsolete = '0' AND p.income_accno_id > 0";
+
+ if ($form->{"partnumber_$i"}) {
+ $var = $form->like(lc $form->{"partnumber_$i"});
+ $where .= " AND lower(p.partnumber) LIKE '$var'";
+ }
+ if ($form->{"description_$i"}) {
+ $var = $form->like(lc $form->{"description_$i"});
+ $where .= " AND lower(p.description) LIKE '$var'";
+ }
+
+ if ($form->{"partsgroup_$i"}) {
+ ($null, $var) = split /--/, $form->{"partsgroup_$i"};
+ $where .= qq| AND p.partsgroup_id = $var|;
+ }
+
+
+ my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice,
+ p.lastcost, p.unit, pg.partsgroup, p.partsgroup_id
+ FROM parts p
+ LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
+ $where
+ |;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $ref;
+ $form->{item_list} = ();
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{item_list} }, $ref;
+ }
+ $sth->finish;
+ $dbh->disconnect;
+
+}
+
+
1;
diff --git a/sql-ledger/SL/Form.pm b/sql-ledger/SL/Form.pm
index ef5f2ca81..c722b4417 100644
--- a/sql-ledger/SL/Form.pm
+++ b/sql-ledger/SL/Form.pm
@@ -1,6 +1,6 @@
-#=====================================================================
+#=================================================================
# SQL-Ledger Accounting
-# Copyright (C) 1998-2003
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -8,7 +8,8 @@
#
# Contributors: Thomas Bayen <bayen@gmx.de>
# Antti Kaihola <akaihola@siba.fi>
-# Moritz Bunkus (tex code)
+# Moritz Bunkus (tex)
+# Jim Rawlings <jim@your-dba.com> (DB2)
#
# 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
@@ -23,9 +24,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#======================================================================
-# Utilities for parsing forms
-# and supporting routines for linking account numbers
-# used in AR, AP and IS, IR modules
+#
+# main package
#
#======================================================================
@@ -52,11 +52,15 @@ sub new {
$self->{$key} = &unescape("",$value);
}
- $self->{action} = lc $self->{action};
- $self->{action} =~ s/( |-|,)/_/g;
+ $self->{menubar} = 1 if $self->{path} =~ /lynx/i;
+
+ if (substr($self->{action}, 0, 1) !~ /( |\.)/) {
+ $self->{action} = lc $self->{action};
+ $self->{action} =~ s/(( |-|,|#|\/)|\.$)/_/g;
+ }
- $self->{version} = "2.0.8";
- $self->{dbversion} = "2.0.8";
+ $self->{version} = "2.4.4";
+ $self->{dbversion} = "2.4.4";
bless $self, $type;
@@ -68,7 +72,7 @@ sub debug {
print "\n";
- map { print "$_ = $self->{$_}\n" } (sort keys %{$self});
+ map { print "$_ = $self->{$_}\n" } (sort keys %$self);
}
@@ -77,8 +81,8 @@ sub escape {
my ($self, $str, $beenthere) = @_;
# for Apache 2 we escape strings twice
- if (($ENV{SERVER_SOFTWARE} =~ /Apache\/2/) && !$beenthere) {
- $str = $self->escape($str, 1);
+ if (($ENV{SERVER_SIGNATURE} =~ /Apache\/2\.(\d+)\.(\d+)/) && !$beenthere) {
+ $str = $self->escape($str, 1) if $2 < 44;
}
$str =~ s/([^a-zA-Z0-9_.-])/sprintf("%%%02x", ord($1))/ge;
@@ -100,25 +104,43 @@ sub unescape {
}
+sub quote {
+ my ($self, $str) = @_;
+
+ if ($str && ! ref($str)) {
+ $str =~ s/"/&quot;/g;
+ }
+
+ $str;
+
+}
+
+
+sub hide_form {
+ my $self = shift;
+
+ map { print qq|<input type=hidden name=$_ value="|.$self->quote($self->{$_}).qq|">\n| } sort keys %$self;
+
+}
+
+
sub error {
my ($self, $msg) = @_;
if ($ENV{HTTP_USER_AGENT}) {
$msg =~ s/\n/<br>/g;
- print qq|Content-Type: text/html
+ delete $self->{pre};
- <body bgcolor=ffffff>
+ if (!$self->{header}) {
+ $self->header;
+ }
- <h2><font color=red>Error!</font></h2>
+ print qq|<body><h2 class=error>Error!</h2>
- <p><b>$msg</b>
-
- </body>
- </html>
- |;
+ <p><b>$msg</b>|;
- die "Error: $msg\n";
+ exit;
} else {
@@ -132,24 +154,23 @@ sub error {
}
-
sub info {
my ($self, $msg) = @_;
if ($ENV{HTTP_USER_AGENT}) {
$msg =~ s/\n/<br>/g;
+ delete $self->{pre};
+
if (!$self->{header}) {
$self->header;
print qq|
<body>|;
+ $self->{header} = 1;
}
- print qq|
+ print "<br><b>$msg</b>";
- <p><b>$msg</b>
- |;
-
} else {
if ($self->{info_function}) {
@@ -162,16 +183,18 @@ sub info {
}
+
+
sub numtextrows {
my ($self, $str, $cols, $maxrows) = @_;
- my $rows;
+ my $rows = 0;
- map { $rows += int ((length $_)/$cols) + 1 } (split /\r/, $str);
+ map { $rows += int (((length) - 2)/$cols) + 1 } split /\r/, $str;
- $rows = $maxrows if (defined $maxrows && ($rows > $maxrows));
-
- $rows;
+ $maxrows = $rows unless defined $maxrows;
+
+ return ($rows > $maxrows) ? $maxrows : $rows;
}
@@ -194,85 +217,136 @@ sub isblank {
sub header {
- my ($self) = @_;
+ my ($self, $init) = @_;
- my ($nocache, $stylesheet, $charset);
-
- # use expire tag to prevent caching
-# $nocache = qq|<META HTTP-EQUIV="Expires" CONTENT="Tue, 01 Jan 1980 1:00:00 GMT">
-# <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
-#|;
+ return if $self->{header};
- if ($self->{stylesheet} && (-f "css/$self->{stylesheet}")) {
- $stylesheet = qq|<LINK REL="stylesheet" HREF="css/$self->{stylesheet}" TYPE="text/css" TITLE="SQL-Ledger style sheet">
-|;
- }
+ my ($stylesheet, $favicon, $charset);
- if ($self->{charset}) {
- $charset = qq|<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=$self->{charset}">
-|;
- }
+ if ($ENV{HTTP_USER_AGENT}) {
- $self->{titlebar} = ($self->{title}) ? "$self->{title} - $self->{titlebar}" : $self->{titlebar};
-
- print qq|Content-Type: text/html
+ if ($self->{stylesheet} && (-f "css/$self->{stylesheet}")) {
+ $stylesheet = qq|<LINK REL="stylesheet" HREF="css/$self->{stylesheet}" TYPE="text/css" TITLE="SQL-Ledger stylesheet">
+ |;
+ }
+
+ if ($self->{favicon} && (-f "$self->{favicon}")) {
+ $favicon = qq|<LINK REL="shortcut icon" HREF="$self->{favicon}" TYPE="image/x-icon">
+ |;
+ }
+
+ if ($self->{charset}) {
+ $charset = qq|<META HTTP-EQUIV="Content-Type" CONTENT="text/plain; charset=$self->{charset}">
+ |;
+ }
+
+ $self->{titlebar} = ($self->{title}) ? "$self->{title} - $self->{titlebar}" : $self->{titlebar};
+
+ $self->set_cookie($init);
+
+ print qq|Content-Type: text/html
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<head>
<title>$self->{titlebar}</title>
- $nocache
+ $favicon
$stylesheet
$charset
</head>
+$self->{pre}
|;
+ }
+
+ $self->{header} = 1;
}
+sub set_cookie {
+ my ($self, $init) = @_;
+
+ $self->{timeout} = ($self->{timeout} > 0) ? $self->{timeout} : 3600;
+
+ if ($self->{endsession}) {
+ $_ = time;
+ } else {
+ $_ = time + $self->{timeout};
+ }
+
+ if ($ENV{HTTP_USER_AGENT}) {
+
+ my @d = split / +/, scalar gmtime($_);
+ my $today = "$d[0], $d[2]-$d[1]-$d[4] $d[3] GMT";
+
+ if ($init) {
+ $self->{sessionid} = time;
+ }
+ print qq|Set-Cookie: SQL-Ledger-$self->{login}=$self->{sessionid}; expires=$today; path=/;\n| if $self->{login};
+ }
+
+}
+
+
sub redirect {
my ($self, $msg) = @_;
if ($self->{callback}) {
($script, $argv) = split(/\?/, $self->{callback});
-
exec ("perl", "$script", $argv);
} else {
- if ($ENV{HTTP_USER_AGENT}) {
- $msg =~ s/\n/<br>/g;
-
- print qq|Content-Type: text/html
+ $self->info($msg);
+ exit;
+ }
-<body bgcolor=ffffff>
+}
-<h2>$msg</h2>
-</body>
-</html>
-|;
+sub sort_columns {
+ my ($self, @columns) = @_;
- } else {
- print "$msg\n";
+ if ($self->{sort}) {
+ if (@columns) {
+ @columns = grep !/^$self->{sort}$/, @columns;
+ splice @columns, 0, 0, $self->{sort};
}
-
- exit;
-
}
+ @columns;
+
}
-sub sort_columns {
- my ($self, @columns) = @_;
+sub sort_order {
+ my ($self, $columns, $ordinal) = @_;
- @columns = grep !/^$self->{sort}$/, @columns;
- splice @columns, 0, 0, $self->{sort};
+ # setup direction
+ if ($self->{direction}) {
+ if ($self->{sort} eq $self->{oldsort}) {
+ if ($self->{direction} eq 'ASC') {
+ $self->{direction} = "DESC";
+ } else {
+ $self->{direction} = "ASC";
+ }
+ }
+ } else {
+ $self->{direction} = "ASC";
+ }
+ $self->{oldsort} = $self->{sort};
- @columns;
+ my $sortorder = join ',', $self->sort_columns(@{$columns});
+ if ($ordinal) {
+ map { $sortorder =~ s/$_/$ordinal->{$_}/ } keys %$ordinal;
+ }
+ my @a = split /,/, $sortorder;
+ $a[0] = "$a[0] $self->{direction}";
+ $sortorder = join ',', @a;
+
+ $sortorder;
+
}
@@ -298,6 +372,13 @@ sub format_amount {
$amount = join '', reverse split //, $amount;
$amount .= "\.$dec" if ($dec ne "");
}
+
+ if ($myconfig->{numberformat} eq "1'000.00") {
+ $amount =~ s/\d{3,}?/$&'/g;
+ $amount =~ s/'$//;
+ $amount = join '', reverse split //, $amount;
+ $amount .= "\.$dec" if ($dec ne "");
+ }
if ($myconfig->{numberformat} eq '1.000,00') {
$amount =~ s/\d{3,}?/$&./g;
@@ -345,6 +426,10 @@ sub parse_amount {
$amount =~ s/,/\./;
}
+ if ($myconfig->{numberformat} eq "1'000.00") {
+ $amount =~ s/'//g;
+ }
+
$amount =~ s/,//g;
return ($amount * 1);
@@ -358,7 +443,7 @@ sub round_amount {
# $places = 3 if $places == 2;
if (($places * 1) >= 0) {
- # compensate for perl behaviour, add 1/10^$places+3
+ # add 1/10^$places+3
sprintf("%.${places}f", $amount + (1 / (10 ** ($places + 3))) * (($amount > 0) ? 1 : -1));
} else {
$places *= -1;
@@ -371,15 +456,23 @@ sub round_amount {
sub parse_template {
my ($self, $myconfig, $userspath) = @_;
- # { Moritz Bunkus
- # Some variables used for page breaks
my ($chars_per_line, $lines_on_first_page, $lines_on_second_page) = (0, 0, 0);
my ($current_page, $current_line) = (1, 1);
my $pagebreak = "";
my $sum = 0;
- # } Moritz Bunkus
- open(IN, "$self->{templates}/$self->{IN}") or $self->error("$self->{IN} : $!");
+ my $subdir = "";
+ my $err = "";
+
+ if ($self->{language_code}) {
+ if (-f "$self->{templates}/$self->{language_code}/$self->{IN}") {
+ open(IN, "$self->{templates}/$self->{language_code}/$self->{IN}") or $self->error("$self->{IN} : $!");
+ } else {
+ open(IN, "$self->{templates}/$self->{IN}") or $self->error("$self->{IN} : $!");
+ }
+ } else {
+ open(IN, "$self->{templates}/$self->{IN}") or $self->error("$self->{IN} : $!");
+ }
@_ = <IN>;
close(IN);
@@ -389,21 +482,24 @@ sub parse_template {
# OUT is used for the media, screen, printer, email
# for postscript we store a copy in a temporary file
my $fileid = time;
- $self->{tmpfile} = "$userspath/${fileid}.$self->{IN}";
+ my $tmpfile = $self->{IN};
+ $tmpfile =~ s/\./\.$self->{fileid}./ if $self->{fileid};
+ $self->{tmpfile} = "$userspath/${fileid}.${tmpfile}";
+
if ($self->{format} =~ /(postscript|pdf)/ || $self->{media} eq 'email') {
$out = $self->{OUT};
$self->{OUT} = ">$self->{tmpfile}";
}
-
if ($self->{OUT}) {
open(OUT, "$self->{OUT}") or $self->error("$self->{OUT} : $!");
} else {
open(OUT, ">-") or $self->error("STDOUT : $!");
+
$self->header;
+
}
-
# first we generate a tmpfile
# read file and replace <%variable%>
while ($_ = shift) {
@@ -412,28 +508,26 @@ sub parse_template {
$var = $_;
- # { Moritz Bunkus
# detect pagebreak block and its parameters
- if (/<%pagebreak ([0-9]+) ([0-9]+) ([0-9]+)%>/) {
+ if (/\s*<%pagebreak ([0-9]+) ([0-9]+) ([0-9]+)%>/) {
$chars_per_line = $1;
$lines_on_first_page = $2;
$lines_on_second_page = $3;
while ($_ = shift) {
- last if (/<\%end pagebreak%>/);
+ last if (/\s*<%end pagebreak%>/);
$pagebreak .= $_;
}
}
- # } Moritz Bunkus
- if (/<%foreach /) {
+ if (/\s*<%foreach /) {
# this one we need for the count
chomp $var;
- $var =~ s/<%foreach (.+?)%>/$1/;
+ $var =~ s/\s*<%foreach (.+?)%>/$1/;
while ($_ = shift) {
- last if (/<%end /);
+ last if (/\s*<%end /);
# store line in $par
$par .= $_;
@@ -442,7 +536,6 @@ sub parse_template {
# display contents of $self->{number}[] array
for $i (0 .. $#{ $self->{$var} }) {
- # { Moritz Bunkus
# Try to detect whether a manual page break is necessary
# but only if there was a <%pagebreak ...%> block before
@@ -480,26 +573,23 @@ sub parse_template {
$current_line += $lines;
}
$sum += $self->parse_amount($myconfig, $self->{"linetotal"}[$i]);
- # } Moritz Bunkus
-
# don't parse par, we need it for each line
- $_ = $par;
- s/<%(.+?)%>/$self->{$1}[$i]/mg;
- print OUT;
+ print OUT $self->format_line($par, $i);
+
}
next;
}
# if not comes before if!
- if (/<%if not /) {
+ if (/\s*<%if not /) {
# check if it is not set and display
chop;
- s/<%if not (.+?)%>/$1/;
+ s/\s*<%if not (.+?)%>/$1/;
unless ($self->{$_}) {
while ($_ = shift) {
- last if (/<%end /);
+ last if (/\s*<%end /);
# store line in $par
$par .= $_;
@@ -509,20 +599,20 @@ sub parse_template {
} else {
while ($_ = shift) {
- last if (/<%end /);
+ last if (/\s*<%end /);
}
next;
}
}
- if (/<%if /) {
+ if (/\s*<%if /) {
# check if it is set and display
chop;
- s/<%if (.+?)%>/$1/;
+ s/\s*<%if (.+?)%>/$1/;
if ($self->{$_}) {
while ($_ = shift) {
- last if (/<%end /);
+ last if (/\s*<%end /);
# store line in $par
$par .= $_;
@@ -532,26 +622,30 @@ sub parse_template {
} else {
while ($_ = shift) {
- last if (/<%end /);
+ last if (/\s*<%end /);
}
next;
}
}
# check for <%include filename%>
- if (/<%include /) {
+ if (/\s*<%include /) {
# get the filename
chomp $var;
- $var =~ s/<%include (.+?)%>/$1/;
+ $var =~ s/\s*<%include (.+?)%>/$1/;
- # mangle filename if someone tries to be cute
- $var =~ s/\///g;
+ # mangle filename
+ $var =~ s/(\/|\.\.)//g;
# prevent the infinite loop!
next if ($self->{"$var"});
- open(INC, "$self->{templates}/$var") or $self->error($self->cleanup."$self->{templates}/$var : $!");
+ unless (open(INC, "$self->{templates}/$var")) {
+ $err = $!;
+ $self->cleanup;
+ $self->error("$self->{templates}/$var : $err");
+ }
unshift(@_, <INC>);
close(INC);
@@ -560,32 +654,35 @@ sub parse_template {
next;
}
- s/<%(.+?)%>/$self->{$1}/g;
- print OUT;
+ print OUT $self->format_line($_);
+
}
close(OUT);
- # { Moritz Bunkus
# Convert the tex file to postscript
if ($self->{format} =~ /(postscript|pdf)/) {
use Cwd;
$self->{cwd} = cwd();
- chdir("$userspath") or $self->error($self->cleanup."chdir : $!");
+ $self->{tmpdir} = "$self->{cwd}/$userspath";
+
+ unless (chdir("$userspath")) {
+ $err = $!;
+ $self->cleanup;
+ $self->error("chdir : $err");
+ }
$self->{tmpfile} =~ s/$userspath\///g;
- # DS. added screen and email option in addition to printer
- # screen
if ($self->{format} eq 'postscript') {
system("latex --interaction=nonstopmode $self->{tmpfile} > $self->{tmpfile}.err");
$self->error($self->cleanup) if ($?);
-
+
$self->{tmpfile} =~ s/tex$/dvi/;
-
- system("dvips $self->{tmpfile} -o -q > /dev/null");
+
+ system("dvips $self->{tmpfile} -o -q");
$self->error($self->cleanup."dvips : $!") if ($?);
$self->{tmpfile} =~ s/dvi$/ps/;
}
@@ -597,6 +694,7 @@ sub parse_template {
}
+
if ($self->{format} =~ /(postscript|pdf)/ || $self->{media} eq 'email') {
if ($self->{media} eq 'email') {
@@ -605,22 +703,28 @@ sub parse_template {
my $mail = new Mailer;
- $self->{email} =~ s/,/>,</g;
-
map { $mail->{$_} = $self->{$_} } qw(cc bcc subject message version format charset);
- $mail->{to} = qq|"$self->{name}" <$self->{email}>|;
+ $mail->{to} = qq|$self->{email}|;
$mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
$mail->{fileid} = "$fileid.";
# if we send html or plain text inline
- if (($self->{format} eq 'html') && ($self->{sendmode} eq 'inline')) {
- $mail->{contenttype} = "text/html";
+ if (($self->{format} =~ /(html|txt)/) && ($self->{sendmode} eq 'inline')) {
+ my $br = "";
+ $br = "<br>" if $self->{format} eq 'html';
+
+ $mail->{contenttype} = "text/$self->{format}";
- $mail->{message} =~ s/\r\n/<br>\n/g;
- $myconfig->{signature} =~ s/\\n/<br>\n/g;
- $mail->{message} .= "<br>\n--<br>\n$myconfig->{signature}\n<br>";
+ $mail->{message} =~ s/\r\n/$br\n/g;
+ $myconfig->{signature} =~ s/\\n/$br\n/g;
+ $mail->{message} .= "$br\n-- $br\n$myconfig->{signature}\n$br" if $myconfig->{signature};
- open(IN, $self->{tmpfile}) or $self->error($self->cleanup."$self->{tmpfile} : $!");
+ unless (open(IN, $self->{tmpfile})) {
+ $err = $!;
+ $self->cleanup;
+ $self->error("$self->{tmpfile} : $err");
+ }
+
while (<IN>) {
$mail->{message} .= $_;
}
@@ -632,37 +736,57 @@ sub parse_template {
@{ $mail->{attachments} } = ($self->{tmpfile});
$myconfig->{signature} =~ s/\\n/\r\n/g;
- $mail->{message} .= "\r\n--\r\n$myconfig->{signature}";
+ $mail->{message} .= "\r\n-- \r\n$myconfig->{signature}" if $myconfig->{signature};
}
- my $err = $mail->send($out);
- $self->error($self->cleanup."$err") if ($err);
+ if ($err = $mail->send($out)) {
+ $self->cleanup;
+ $self->error($err);
+ }
} else {
$self->{OUT} = $out;
- open(IN, $self->{tmpfile}) or $self->error($self->cleanup."$self->{tmpfile} : $!");
+ unless (open(IN, $self->{tmpfile})) {
+ $err = $!;
+ $self->cleanup;
+ $self->error("$self->{tmpfile} : $err");
+ }
+
+ binmode(IN);
- $self->{copies} = 1 unless $self->{media} eq 'printer';
+ $self->{copies} = 1 if $self->{media} =~ /(screen|email|queue)/;
+
+ chdir("$self->{cwd}");
for my $i (1 .. $self->{copies}) {
-
if ($self->{OUT}) {
- open(OUT, $self->{OUT}) or $self->error($self->cleanup."$self->{OUT} : $!");
+ unless (open(OUT, $self->{OUT})) {
+ $err = $!;
+ $self->cleanup;
+ $self->error("$self->{OUT} : $err");
+ }
} else {
- open(OUT, ">-") or $self->error($self->cleanup."$!: STDOUT");
-
+
# launch application
- print qq|Content-Type: application/$self->{format}; name="$self->{tmpfile}"
- Content-Disposition: filename="$self->{tmpfile}"
+ print qq|Content-Type: application/$self->{format}
+Content-Disposition: attachment; filename="$self->{tmpfile}"\n\n|;
+
+ unless (open(OUT, ">-")) {
+ $err = $!;
+ $self->cleanup;
+ $self->error("STDOUT : $err");
+ }
- |;
}
+
+ binmode(OUT);
while (<IN>) {
print OUT $_;
}
+
close(OUT);
seek IN, 0, 0;
}
@@ -673,7 +797,92 @@ sub parse_template {
$self->cleanup;
}
- # } Moritz Bunkus
+
+}
+
+
+sub format_line {
+ my $self = shift;
+
+ $_ = shift;
+ my $i = shift;
+ my ($str, $pos, $l, $item, $newstr);
+ my $var = "";
+ my %a;
+
+ while (/<%(.+?)%>/) {
+
+ %a = ();
+
+ foreach $item (split / /, $1) {
+ my ($key, $value) = split /=/, $item;
+ if (defined $value) {
+ $a{$key} = $value;
+ } else {
+ $var = $item;
+ }
+ }
+
+ $str = (defined $i) ? $self->{$var}[$i] : $self->{$var};
+
+ if ($a{align} || $a{width} || $a{offset}) {
+
+ $str =~ s/( |\n)+/" " x $a{offset}/ge;
+ $l = length $str;
+
+ if ($l > $a{width}) {
+ if (($pos = rindex $str, " ", $a{width}) > 0) {
+ $newstr = substr($str, 0, $pos);
+ $newstr .= "\n";
+ $str = substr($str, $pos + 1);
+
+ while (length $str > $a{width}) {
+ if (($pos = rindex $str, " ", $a{width}) > 0) {
+ $newstr .= (" " x $a{offset}).substr($str, 0, $pos);
+ $newstr .= "\n";
+ $str = substr($str, $pos + 1);
+ } else {
+ $newstr .= (" " x $a{offset}).substr($str, 0, $a{width});
+ $newstr .= "\n";
+ $str = substr($str, $a{width} + 1);
+ }
+ }
+ }
+ $l = length $str;
+ $str .= " " x ($a{width} - $l);
+ $newstr .= (" " x $a{offset}).$str;
+ $str = $newstr;
+
+ $l = $a{width};
+ }
+
+ # pad left, right or center
+ $pos = lc $a{align};
+ $l = ($a{width} - $l);
+
+ my $pad = " " x $l;
+
+ if ($pos eq 'right') {
+ $str = "$pad$str";
+ }
+
+ if ($pos eq 'left') {
+ $str = "$str$pad";
+ }
+
+ if ($pos eq 'center') {
+ $pad = " " x ($l/2);
+ $str = "$pad$str";
+ $pad = " " x ($l/2 + 1) if ($l % 2);
+ $str .= "$pad";
+ }
+ }
+
+ s/<%(.+?)%>/$str/;
+
+ }
+
+ $_;
}
@@ -681,6 +890,8 @@ sub parse_template {
sub cleanup {
my $self = shift;
+ chdir("$self->{tmpdir}");
+
my @err = ();
if (-f "$self->{tmpfile}.err") {
open(FH, "$self->{tmpfile}.err");
@@ -695,7 +906,6 @@ sub cleanup {
unlink(<$tmpfile.*>);
}
-
chdir("$self->{cwd}");
"@err";
@@ -711,19 +921,22 @@ sub format_string {
$format = 'tex';
}
- my %replace = ( 'order' => { 'html' => [ quotemeta('\n'), ' ' ],
- 'tex' => [ '&', quotemeta('\n'), ' ',
+ my %replace = ( 'order' => { html => [ '<', '>', quotemeta('\n'), ' ' ],
+ txt => [ quotemeta('\n') ],
+ tex => [ '&', quotemeta('\n'), ' ',
'\$', '%', '_', '#', quotemeta('^'),
- '{', '}', '<', '>', '£' ] },
- 'html' => {
+ '{', '}', '<', '>', '£',
+ quotemeta('\\\\') ] },
+ html => { '<' => '&lt;', '>' => '&gt;',
quotemeta('\n') => '<br>', ' ' => '<br>'
},
- 'tex' => {
+ txt => { quotemeta('\n') },
+ tex => {
'&' => '\&', '\$' => '\$', '%' => '\%', '_' => '\_',
'#' => '\#', quotemeta('^') => '\^\\', '{' => '\{', '}' => '\}',
'<' => '$<$', '>' => '$>$',
quotemeta('\n') => '\newline ', ' ' => '\newline ',
- '£' => '\pounds ',
+ '£' => '\pounds ', quotemeta('\\\\') => '$\backslash$'
}
);
@@ -737,27 +950,16 @@ sub format_string {
sub datetonum {
my ($self, $date, $myconfig) = @_;
- if ($date) {
- # get separator
- my $spc = $myconfig->{dateformat};
- $spc =~ s/\w//g;
- $spc = substr($spc, 1, 1);
-
- if ($spc eq '.') {
- $spc = '\.';
- }
- if ($spc eq '/') {
- $spc = '\/';
- }
+ if ($date && $date =~ /\D/) {
if ($myconfig->{dateformat} =~ /^yy/) {
- ($yy, $mm, $dd) = split /$spc/, $date;
+ ($yy, $mm, $dd) = split /\D/, $date;
}
if ($myconfig->{dateformat} =~ /^mm/) {
- ($mm, $dd, $yy) = split /$spc/, $date;
+ ($mm, $dd, $yy) = split /\D/, $date;
}
if ($myconfig->{dateformat} =~ /^dd/) {
- ($dd, $mm, $yy) = split /$spc/, $date;
+ ($dd, $mm, $yy) = split /\D/, $date;
}
$dd *= 1;
@@ -776,7 +978,6 @@ sub datetonum {
}
-
# Database routines used throughout
sub dbconnect {
@@ -803,7 +1004,7 @@ sub dbconnect_noauto {
# set db options
if ($myconfig->{dboptions}) {
- $dbh->do($myconfig->{dboptions}) || $self->dberror($myconfig->{dboptions});
+ $dbh->do($myconfig->{dboptions});
}
$dbh;
@@ -811,18 +1012,45 @@ sub dbconnect_noauto {
}
+sub dbquote {
+ my ($self, $var, $type) = @_;
+
+ my $rv = 'NULL';
+
+ # DBI does not return NULL for SQL_DATE if the date is empty, bug ?
+ if (defined $var) {
+ if (defined $type) {
+ if ($type eq 'SQL_DATE') {
+ $rv = "'$var'" if $var;
+ } elsif ($type eq 'SQL_INT.*') {
+ $rv = int $var;
+ } else {
+ if ($type !~ /SQL_.*CHAR/) {
+ $rv = $var * 1;
+ } else {
+ $var =~ s/'/''/g;
+ $rv = "'$var'";
+ }
+ }
+ } else {
+ $var =~ s/'/''/g;
+ $rv = "'$var'";
+ }
+ }
+
+ $rv;
+
+}
+
+
sub update_balance {
my ($self, $dbh, $table, $field, $where, $value) = @_;
# if we have a value, go do it
if ($value != 0) {
# retrieve balance from table
- my $query = "SELECT $field FROM $table WHERE $where";
- my $sth = $dbh->prepare($query);
-
- $sth->execute || $self->dberror($query);
- my ($balance) = $sth->fetchrow_array;
- $sth->finish;
+ my $query = "SELECT $field FROM $table WHERE $where FOR UPDATE";
+ my ($balance) = $dbh->selectrow_array($query);
$balance += $value;
# update balance
@@ -841,7 +1069,8 @@ sub update_exchangerate {
my $query = qq|SELECT curr FROM exchangerate
WHERE curr = '$curr'
- AND transdate = '$transdate'|;
+ AND transdate = '$transdate'
+ FOR UPDATE|;
my $sth = $dbh->prepare($query);
$sth->execute || $self->dberror($query);
@@ -869,77 +1098,35 @@ sub update_exchangerate {
}
+sub save_exchangerate {
+ my ($self, $myconfig, $currency, $transdate, $rate, $fld) = @_;
+
+ my $dbh = $self->dbconnect($myconfig);
+
+ my ($buy, $sell) = (0, 0);
+ $buy = $rate if $fld eq 'buy';
+ $sell = $rate if $fld eq 'sell';
+
+ $self->update_exchangerate($dbh, $currency, $transdate, $buy, $sell);
+
+ $dbh->disconnect;
+
+}
+
+
sub get_exchangerate {
my ($self, $dbh, $curr, $transdate, $fld) = @_;
my $query = qq|SELECT $fld FROM exchangerate
WHERE curr = '$curr'
AND transdate = '$transdate'|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
-
- my ($exchangerate) = $sth->fetchrow_array;
- $sth->finish;
+ my ($exchangerate) = $dbh->selectrow_array($query);
$exchangerate;
}
-sub delete_exchangerate {
- my ($self, $dbh) = @_;
-
- my @transdate = ();
- my $transdate;
-
- my $query = qq|SELECT DISTINCT transdate
- FROM acc_trans
- WHERE trans_id = $self->{id}|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
-
- while ($transdate = $sth->fetchrow_array) {
- push @transdate, $transdate;
- }
- $sth->finish;
-
- $query = qq|SELECT transdate FROM acc_trans
- WHERE ar.id = trans_id
- AND ar.curr = '$self->{currency}'
- AND transdate IN
- (SELECT transdate FROM acc_trans
- WHERE trans_id = $self->{id})
- AND trans_id != $self->{id}
- UNION SELECT transdate FROM acc_trans
- WHERE ap.id = trans_id
- AND ap.curr = '$self->{currency}'
- AND transdate IN
- (SELECT transdate FROM acc_trans
- WHERE trans_id = $self->{id})
- AND trans_id != $self->{id}
- UNION SELECT transdate FROM oe
- WHERE oe.curr = '$self->{currency}'
- AND transdate IN
- (SELECT transdate FROM acc_trans
- WHERE trans_id = $self->{id})|;
- $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
-
- while ($transdate = $sth->fetchrow_array) {
- @transdate = grep !/^$transdate$/, @transdate;
- }
- $sth->finish;
-
- foreach $transdate (@transdate) {
- $query = qq|DELETE FROM exchangerate
- WHERE curr = '$self->{currency}'
- AND transdate = '$transdate'|;
- $dbh->do($query) || $self->dberror($query);
- }
-
-}
-
-
sub check_exchangerate {
my ($self, $myconfig, $currency, $transdate, $fld) = @_;
@@ -950,11 +1137,8 @@ sub check_exchangerate {
my $query = qq|SELECT $fld FROM exchangerate
WHERE curr = '$currency'
AND transdate = '$transdate'|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
-
- my ($exchangerate) = $sth->fetchrow_array;
- $sth->finish;
+ my ($exchangerate) = $dbh->selectrow_array($query);
+
$dbh->disconnect;
$exchangerate;
@@ -966,20 +1150,25 @@ sub add_shipto {
my ($self, $dbh, $id) = @_;
my $shipto;
- foreach my $item (qw(name addr1 addr2 addr3 addr4 contact phone fax email)) {
+ foreach my $item (qw(name address1 address2 city state zipcode country contact phone fax email)) {
if ($self->{"shipto$item"}) {
$shipto = 1 if ($self->{$item} ne $self->{"shipto$item"});
}
- $self->{"shipto$item"} =~ s/'/''/g;
}
if ($shipto) {
- my $query = qq|INSERT INTO shipto (trans_id, shiptoname, shiptoaddr1,
- shiptoaddr2, shiptoaddr3, shiptoaddr4, shiptocontact,
- shiptophone, shiptofax, shiptoemail) VALUES ($id,
- '$self->{shiptoname}', '$self->{shiptoaddr1}',
- '$self->{shiptoaddr2}', '$self->{shiptoaddr3}',
- '$self->{shiptoaddr4}', '$self->{shiptocontact}',
+ my $query = qq|INSERT INTO shipto (trans_id, shiptoname, shiptoaddress1,
+ shiptoaddress2, shiptocity, shiptostate,
+ shiptozipcode, shiptocountry, shiptocontact,
+ shiptophone, shiptofax, shiptoemail) VALUES ($id, |
+ .$dbh->quote($self->{shiptoname}).qq|, |
+ .$dbh->quote($self->{shiptoaddress1}).qq|, |
+ .$dbh->quote($self->{shiptoaddress2}).qq|, |
+ .$dbh->quote($self->{shiptocity}).qq|, |
+ .$dbh->quote($self->{shiptostate}).qq|, |
+ .$dbh->quote($self->{shiptozipcode}).qq|, |
+ .$dbh->quote($self->{shiptocountry}).qq|, |
+ .$dbh->quote($self->{shiptocontact}).qq|,
'$self->{shiptophone}', '$self->{shiptofax}',
'$self->{shiptoemail}')|;
$dbh->do($query) || $self->dberror($query);
@@ -991,13 +1180,14 @@ sub add_shipto {
sub get_employee {
my ($self, $dbh) = @_;
- my $query = qq|SELECT name FROM employee
- WHERE login = '$self->{login}'|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
-
- ($self->{employee}) = $sth->fetchrow_array;
- $sth->finish;
+ my $login = $self->{login};
+ $login =~ s/@.*//;
+ my $query = qq|SELECT name, id FROM employee
+ WHERE login = '$login'|;
+ my (@a) = $dbh->selectrow_array($query);
+ $a[1] *= 1;
+
+ @a;
}
@@ -1010,16 +1200,28 @@ sub get_name {
my $dbh = $self->dbconnect($myconfig);
my $name = $self->like(lc $self->{$table});
- my $query = qq~SELECT id, name,
- addr1 || ' ' || addr2 || ' ' || addr3 || ' ' || addr4 AS address
- FROM $table
- WHERE lower(name) LIKE '$name'
- ORDER BY name~;
+ my $query = qq~SELECT c.id, c.name, c.address1, c.address2,
+ c.city, c.state, c.zipcode, c.country
+ FROM $table c
+ WHERE lower(c.name) LIKE '$name'
+ ORDER BY c.name~;
+
+ if ($self->{openinvoices}) {
+ $query = qq~SELECT DISTINCT c.id, c.name, c.address1, c.address2,
+ c.city, c.state, c.zipcode, c.country
+ FROM $self->{arap} a
+ JOIN $table c ON (a.${table}_id = c.id)
+ WHERE a.amount != a.paid
+ AND lower(c.name) LIKE '$name'
+ ORDER BY c.name~;
+ }
+
my $sth = $dbh->prepare($query);
$sth->execute || $self->dberror($query);
my $i = 0;
+ @{ $self->{name_list} } = ();
while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
push(@{ $self->{name_list} }, $ref);
$i++;
@@ -1035,47 +1237,221 @@ sub get_name {
# the selection sub is used in the AR, AP, IS, IR and OE module
#
sub all_vc {
- my ($self, $myconfig, $table) = @_;
+ my ($self, $myconfig, $table, $module, $dbh, $enddate) = @_;
- my $dbh = $self->dbconnect($myconfig);
+ my $ref;
+ my $closedb;
+ if (! defined $dbh) {
+ $dbh = $self->dbconnect($myconfig);
+ $closedb = 1;
+ }
+ my $sth;
my $query = qq|SELECT count(*) FROM $table|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
- my ($count) = $sth->fetchrow_array;
- $sth->finish;
+ my $where;
+ if (defined $enddate) {
+ $where = qq|AND (enddate IS NULL OR enddate >= '$enddate')|;
+ $query .= qq| WHERE 1=1
+ $where|;
+ }
+ my ($count) = $dbh->selectrow_array($query);
+
# build selection list
if ($count < $myconfig->{vclimit}) {
$query = qq|SELECT id, name
FROM $table
+ WHERE 1=1
+ $where
ORDER BY name|;
$sth = $dbh->prepare($query);
$sth->execute || $self->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
push @{ $self->{"all_$table"} }, $ref;
}
-
$sth->finish;
}
+
+ # get self
+ if (! $self->{employee_id}) {
+ ($self->{employee}, $self->{employee_id}) = split /--/, $self->{employee};
+ ($self->{employee}, $self->{employee_id}) = $self->get_employee($dbh) unless $self->{employee_id};
+ }
+
+ # setup sales contacts
+ $query = qq|SELECT id, name
+ FROM employee
+ WHERE sales = '1'
+ $where
+ ORDER BY name|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $self->{all_employees} }, $ref;
+ }
+ $sth->finish;
+
+
+ if ($module eq 'AR') {
+ # prepare query for departments
+ $query = qq|SELECT id, description
+ FROM department
+ WHERE role = 'P'
+ ORDER BY 2|;
+
+ } else {
+ $query = qq|SELECT id, description
+ FROM department
+ ORDER BY 2|;
+ }
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $self->{all_departments} }, $ref;
+ }
+ $sth->finish;
+
+
+ # get projects
+ $query = qq|SELECT *
+ FROM project
+ ORDER BY projectnumber|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ $self->{all_projects} = ();
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $self->{all_projects} }, $ref;
+ }
+ $sth->finish;
+
+ # get language codes
+ $query = qq|SELECT *
+ FROM language
+ ORDER BY 2|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ $self->{all_languages} = ();
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $self->{all_languages} }, $ref;
+ }
+ $sth->finish;
+
+ $self->all_years($dbh, $myconfig);
+
+ $dbh->disconnect if $closedb;
+
+}
+
+
+# this is only used for reports
+sub all_projects {
+ my ($self, $myconfig) = @_;
+
+ my $dbh = $self->dbconnect($myconfig);
+
+ my $query = qq|SELECT *
+ FROM project
+ ORDER BY projectnumber|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ $self->{all_projects} = ();
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $self->{all_projects} }, $ref;
+ }
+ $sth->finish;
+
$dbh->disconnect;
}
-sub create_links {
- my ($self, $module, $myconfig, $table) = @_;
+sub all_departments {
+ my ($self, $myconfig, $table) = @_;
+
+ my $dbh = $self->dbconnect($myconfig);
+ my $where = "1 = 1";
+
+ if (defined $table) {
+ if ($table eq 'customer') {
+ $where = " role = 'P'";
+ }
+ }
+
+ my $query = qq|SELECT id, description
+ FROM department
+ WHERE $where
+ ORDER BY 2|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $self->{all_departments} }, $ref;
+ }
+ $sth->finish;
+
+ $self->all_years($dbh, $myconfig);
+
+ $dbh->disconnect;
+
+}
+
- $self->all_vc($myconfig, $table);
+sub all_years {
+ my ($self, $dbh, $myconfig) = @_;
+ # get years
+ my $query = qq|SELECT (SELECT MIN(transdate) FROM acc_trans),
+ (SELECT MAX(transdate) FROM acc_trans)
+ FROM defaults|;
+ my ($startdate, $enddate) = $dbh->selectrow_array($query);
+
+ if ($myconfig->{dateformat} =~ /^yy/) {
+ ($startdate) = split /\W/, $startdate;
+ ($enddate) = split /\W/, $enddate;
+ } else {
+ (@_) = split /\W/, $startdate;
+ $startdate = @_[2];
+ (@_) = split /\W/, $enddate;
+ $enddate = @_[2];
+ }
+
+ while ($enddate >= $startdate) {
+ push @{ $self->{all_years} }, $enddate--;
+ }
+
+ %{ $self->{all_month} } = ( '01' => 'January',
+ '02' => 'February',
+ '03' => 'March',
+ '04' => 'April',
+ '05' => 'May ',
+ '06' => 'June',
+ '07' => 'July',
+ '08' => 'August',
+ '09' => 'September',
+ '10' => 'October',
+ '11' => 'November',
+ '12' => 'December' );
+
+}
+
+
+sub create_links {
+ my ($self, $module, $myconfig, $table) = @_;
+
# get last customers or vendors
my ($query, $sth);
my $dbh = $self->dbconnect($myconfig);
-
+
my %xkeyref = ();
@@ -1090,7 +1466,7 @@ sub create_links {
$self->{accounts} = "";
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- foreach my $key (split(/:/, $ref->{link})) {
+ foreach my $key (split /:/, $ref->{link}) {
if ($key =~ /$module/) {
# cross reference for keys
$xkeyref{$ref->{accno}} = $key;
@@ -1103,18 +1479,21 @@ sub create_links {
}
}
$sth->finish;
-
-
+
if ($self->{id}) {
my $arap = ($table eq 'customer') ? 'ar' : 'ap';
$query = qq|SELECT a.invnumber, a.transdate,
a.${table}_id, a.datepaid, a.duedate, a.ordnumber,
- a.taxincluded, a.curr AS currency, a.notes, c.name AS $table,
- a.amount AS oldinvtotal, a.paid AS oldtotalpaid
- FROM $arap a, $table c
- WHERE a.${table}_id = c.id
- AND a.id = $self->{id}|;
+ a.taxincluded, a.curr AS currency, a.notes, a.intnotes,
+ c.name AS $table, a.department_id, d.description AS department,
+ a.amount AS oldinvtotal, a.paid AS oldtotalpaid,
+ a.employee_id, e.name AS employee, c.language_code
+ FROM $arap a
+ JOIN $table c ON (a.${table}_id = c.id)
+ LEFT JOIN employee e ON (e.id = a.employee_id)
+ LEFT JOIN department d ON (d.id = a.department_id)
+ WHERE a.id = $self->{id}|;
$sth = $dbh->prepare($query);
$sth->execute || $self->dberror($query);
@@ -1124,29 +1503,46 @@ sub create_links {
}
$sth->finish;
+
+ # get printed, emailed
+ $query = qq|SELECT s.printed, s.emailed, s.spoolfile, s.formname
+ FROM status s
+ WHERE s.trans_id = $self->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $self->{printed} .= "$ref->{formname} " if $ref->{printed};
+ $self->{emailed} .= "$ref->{formname} " if $ref->{emailed};
+ $self->{queued} .= "$ref->{formname} $ref->{spoolfile} " if $ref->{spoolfile};
+ }
+ $sth->finish;
+ map { $self->{$_} =~ s/ +$//g } qw(printed emailed queued);
+
+
# get amounts from individual entries
- $query = qq|SELECT c.accno, c.description, a.source, a.amount,
+ $query = qq|SELECT c.accno, c.description, a.source, a.amount, a.memo,
a.transdate, a.cleared, a.project_id, p.projectnumber
FROM acc_trans a
JOIN chart c ON (c.id = a.chart_id)
- LEFT JOIN project p ON (a.project_id = p.id)
+ LEFT JOIN project p ON (p.id = a.project_id)
WHERE a.trans_id = $self->{id}
AND a.fx_transaction = '0'
ORDER BY transdate|;
$sth = $dbh->prepare($query);
$sth->execute || $self->dberror($query);
+
my $fld = ($table eq 'customer') ? 'buy' : 'sell';
- # get exchangerate for currency
+
$self->{exchangerate} = $self->get_exchangerate($dbh, $self->{currency}, $self->{transdate}, $fld);
-
+
# store amounts in {acc_trans}{$key} for multiple accounts
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
$ref->{exchangerate} = $self->get_exchangerate($dbh, $self->{currency}, $ref->{transdate}, $fld);
push @{ $self->{acc_trans}{$xkeyref{$ref->{accno}}} }, $ref;
}
-
$sth->finish;
$query = qq|SELECT d.curr AS currencies, d.closedto, d.revtrans,
@@ -1179,22 +1575,14 @@ sub create_links {
map { $self->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
- if ($self->{"$self->{vc}_id"}) {
- # only setup currency
- ($self->{currency}) = split /:/, $self->{currencies};
-
- } else {
-
+ if (! $self->{"$self->{vc}_id"}) {
$self->lastname_used($dbh, $myconfig, $table, $module);
-
- my $fld = ($table eq 'customer') ? 'buy' : 'sell';
- # get exchangerate for currency
- $self->{exchangerate} = $self->get_exchangerate($dbh, $self->{currency}, $self->{transdate}, $fld);
-
}
}
+ $self->all_vc($myconfig, $table, $module, $dbh, $self->{transdate});
+
$dbh->disconnect;
}
@@ -1204,27 +1592,40 @@ sub lastname_used {
my ($self, $dbh, $myconfig, $table, $module) = @_;
my $arap = ($table eq 'customer') ? "ar" : "ap";
- $arap = 'oe' if ($self->{type} =~ /_order/);
-
+ my $where = "1 = 1";
+ my $sth;
+
+ if ($self->{type} =~ /_order/) {
+ $arap = 'oe';
+ $where = "quotation = '0'";
+ }
+ if ($self->{type} =~ /_quotation/) {
+ $arap = 'oe';
+ $where = "quotation = '1'";
+ }
+
my $query = qq|SELECT id FROM $arap
WHERE id IN (SELECT MAX(id) FROM $arap
- WHERE ${table}_id > 0)|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
-
- my ($trans_id) = $sth->fetchrow_array;
- $sth->finish;
+ WHERE $where
+ AND ${table}_id > 0)|;
+ my ($trans_id) = $dbh->selectrow_array($query);
$trans_id *= 1;
- $query = qq|SELECT ct.name, a.curr, a.${table}_id,
- current_date + ct.terms AS duedate
+
+ my $DAYS = ($myconfig->{dbdriver} eq 'DB2') ? "DAYS" : "";
+
+ $query = qq|SELECT ct.name AS $table, a.curr AS currency, a.${table}_id,
+ current_date + ct.terms $DAYS AS duedate, a.department_id,
+ d.description AS department, ct.notes, ct.curr AS currency
FROM $arap a
JOIN $table ct ON (a.${table}_id = ct.id)
+ LEFT JOIN department d ON (a.department_id = d.id)
WHERE a.id = $trans_id|;
$sth = $dbh->prepare($query);
$sth->execute || $self->dberror($query);
- ($self->{$table}, $self->{currency}, $self->{"${table}_id"}, $self->{duedate}) = $sth->fetchrow_array;
+ my $ref = $sth->fetchrow_hashref(NAME_lc);
+ map { $self->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
}
@@ -1240,17 +1641,30 @@ sub current_date {
$days *= 1;
if ($thisdate) {
my $dateformat = $myconfig->{dateformat};
- $dateformat .= "yy" if $myconfig->{dateformat} !~ /^y/;
+ if ($myconfig->{dateformat} !~ /^y/) {
+ my @a = split /\D/, $thisdate;
+ $dateformat .= "yy" if (length $a[2] > 2);
+ }
- $query = qq|SELECT to_date('$thisdate', '$dateformat') + $days AS thisdate
- FROM defaults|;
- $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
+ if ($thisdate !~ /\D/) {
+ $dateformat = 'yyyymmdd';
+ }
+
+ if ($myconfig->{dbdriver} eq 'DB2') {
+ $query = qq|SELECT date('$thisdate') + $days DAYS AS thisdate
+ FROM defaults|;
+ } else {
+ $query = qq|SELECT to_date('$thisdate', '$dateformat') + $days AS thisdate
+ FROM defaults|;
+ }
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
} else {
$query = qq|SELECT current_date AS thisdate
FROM defaults|;
- $sth = $dbh->prepare($query);
- $sth->execute || $self->dberror($query);
+ $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
}
($thisdate) = $sth->fetchrow_array;
@@ -1264,14 +1678,14 @@ sub current_date {
sub like {
- my ($self, $string) = @_;
+ my ($self, $str) = @_;
- unless ($string =~ /%/) {
- $string = "%$string%";
+ if ($str !~ /(%|_)/) {
+ $str = "%$str%";
}
- $string =~ s/'/''/g;
- $string;
+ $str =~ s/'/''/g;
+ $str;
}
@@ -1298,7 +1712,529 @@ sub redo_rows {
}
+
+sub get_partsgroup {
+ my ($self, $myconfig, $p) = @_;
+
+ my $dbh = $self->dbconnect($myconfig);
+
+ my $query = qq|SELECT DISTINCT pg.id, pg.partsgroup
+ FROM partsgroup pg
+ JOIN parts p ON (p.partsgroup_id = pg.id)|;
+
+ if ($p->{searchitems} eq 'part') {
+ $query .= qq|
+ WHERE p.inventory_accno_id > 0|;
+ }
+ if ($p->{searchitems} eq 'service') {
+ $query .= qq|
+ WHERE p.inventory_accno_id IS NULL|;
+ }
+ if ($p->{searchitems} eq 'assembly') {
+ $query .= qq|
+ WHERE p.assembly = '1'|;
+ }
+ if ($p->{searchitems} eq 'labor') {
+ $query .= qq|
+ WHERE p.inventory_accno_id > 0 AND p.income_accno_id IS NULL|;
+ }
+
+ $query .= qq|
+ ORDER BY partsgroup|;
+
+ if ($p->{all}) {
+ $query = qq|SELECT id, partsgroup FROM partsgroup
+ ORDER BY partsgroup|;
+ }
+
+ if ($p->{language_code}) {
+ $query = qq|SELECT DISTINCT pg.id, pg.partsgroup,
+ t.description AS translation
+ FROM partsgroup pg
+ JOIN parts p ON (p.partsgroup_id = pg.id)
+ LEFT JOIN translation t ON (t.trans_id = pg.id AND t.language_code = '$p->{language_code}')
+ ORDER BY translation|;
+ }
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $self->dberror($query);
+
+ $self->{all_partsgroup} = ();
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $self->{all_partsgroup} }, $ref;
+ }
+ $sth->finish;
+ $dbh->disconnect;
+
+}
+
+
+sub update_status {
+ my ($self, $myconfig) = @_;
+
+ # no id return
+ return unless $self->{id};
+
+ my $i;
+ my $id;
+
+ my $dbh = $self->dbconnect_noauto($myconfig);
+
+ my $query = qq|DELETE FROM status
+ WHERE formname = |.$dbh->quote($self->{formname}).qq|
+ AND trans_id = ?|;
+ my $sth = $dbh->prepare($query) || $self->dberror($query);
+
+ if ($self->{formname} =~ /(check|receipt)/) {
+ for $i (1 .. $self->{rowcount}) {
+ $sth->execute($self->{"id_$i"} * 1) || $self->dberror($query);
+ $sth->finish;
+ }
+ } else {
+ $sth->execute($self->{id}) || $self->dberror($query);
+ $sth->finish;
+ }
+
+ my $printed = ($self->{printed} =~ /$self->{formname}/) ? "1" : "0";
+ my $emailed = ($self->{emailed} =~ /$self->{formname}/) ? "1" : "0";
+ my %queued = split / /, $self->{queued};
+
+ if ($self->{formname} =~ /(check|receipt)/) {
+ # this is a check or receipt, add one entry for each lineitem
+ my ($accno) = split /--/, $self->{account};
+ $query = qq|INSERT INTO status (trans_id, printed, spoolfile, formname,
+ chart_id) VALUES (?, '$printed',|
+ .$dbh->quote($queued{$self->{formname}}).qq|, |
+ .$dbh->quote($self->{formname}).qq|,
+ (SELECT id FROM chart WHERE accno = |
+ .$dbh->quote($accno).qq|))|;
+ $sth = $dbh->prepare($query) || $self->dberror($query);
+
+ for $i (1 .. $self->{rowcount}) {
+ if ($self->{"checked_$i"}) {
+ $sth->execute($self->{"id_$i"}) || $self->dberror($query);
+ $sth->finish;
+ }
+ }
+ } else {
+ $query = qq|INSERT INTO status (trans_id, printed, emailed,
+ spoolfile, formname)
+ VALUES ($self->{id}, '$printed', '$emailed', |
+ .$dbh->quote($queued{$self->{formname}}).qq|, |
+ .$dbh->quote($self->{formname}).qq|)|;
+ $dbh->do($query) || $self->dberror($query);
+ }
+
+ $dbh->commit;
+ $dbh->disconnect;
+
+}
+
+
+sub save_status {
+ my ($self, $dbh) = @_;
+
+ my ($query, $printed, $emailed);
+
+ my $formnames = $self->{printed};
+ my $emailforms = $self->{emailed};
+
+ my $query = qq|DELETE FROM status
+ WHERE formname = '$self->{formname}'
+ AND trans_id = $self->{id}|;
+ $dbh->do($query) || $self->dberror($query);
+
+ if ($self->{queued}) {
+ $query = qq|DELETE FROM status
+ WHERE spoolfile IS NOT NULL
+ AND trans_id = $self->{id}|;
+ $dbh->do($query) || $self->dberror($query);
+
+ my %queued = split / /, $self->{queued};
+
+ foreach my $formname (keys %queued) {
+ $printed = ($self->{printed} =~ /$self->{formname}/) ? "1" : "0";
+ $emailed = ($self->{emailed} =~ /$self->{formname}/) ? "1" : "0";
+
+ $query = qq|INSERT INTO status (trans_id, printed, emailed,
+ spoolfile, formname)
+ VALUES ($self->{id}, '$printed', '$emailed',
+ '$queued{$formname}', '$formname')|;
+ $dbh->do($query) || $self->dberror($query);
+ $formnames =~ s/$formname//;
+ $emailforms =~ s/$formname//;
+
+ }
+ }
+
+ # save printed, emailed info
+ $formnames =~ s/^ +//g;
+ $emailforms =~ s/^ +//g;
+
+ my %status = ();
+ map { $status{$_}{printed} = 1 } split / +/, $formnames;
+ map { $status{$_}{emailed} = 1 } split / +/, $emailforms;
+
+ foreach my $formname (keys %status) {
+ $printed = ($formnames =~ /$self->{formname}/) ? "1" : "0";
+ $emailed = ($emailforms =~ /$self->{formname}/) ? "1" : "0";
+
+ $query = qq|INSERT INTO status (trans_id, printed, emailed, formname)
+ VALUES ($self->{id}, '$printed', '$emailed', '$formname')|;
+ $dbh->do($query) || $self->dberror($query);
+ }
+
+}
+
+
+sub save_intnotes {
+ my ($self, $myconfig, $table) = @_;
+
+ # no id return
+ return unless $self->{id};
+
+ my $dbh = $self->dbconnect($myconfig);
+
+ my $query = qq|UPDATE $table SET
+ intnotes = |.$dbh->quote($self->{intnotes}).qq|
+ WHERE id = $self->{id}|;
+ $dbh->do($query) || $self->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub update_defaults {
+ my ($self, $myconfig, $fld, $dbh) = @_;
+
+ my $closedb;
+
+ if (! defined $dbh) {
+ $dbh = $self->dbconnect_noauto($myconfig);
+ $closedb = 1;
+ }
+
+ my $query = qq|SELECT $fld FROM defaults FOR UPDATE|;
+ ($_) = $dbh->selectrow_array($query);
+
+ $_ = "0" unless $_;
+
+ # check for and replace
+ # <%DATE%>, <%YYMMDD%> or variations of
+ # <%NAME 1 1 3%>, <%BUSINESS%>, <%BUSINESS 10%>, <%CURR...%>
+ # <%DESCRIPTION 1 1 3%>, <%ITEM 1 1 3%>, <%PARTSGROUP 1 1 3%> only for parts
+ # <%PHONE%> for customer and vendors
+
+ my $num = $_;
+ $num =~ s/(<%.*?%>)//g;
+ ($num) = $num =~ /(\d+)/;
+ if (defined $num) {
+ my $incnum;
+ # if we have leading zeros check how long it is
+ if ($num =~ /^0/) {
+ my $l = length $num;
+ $incnum = $num + 1;
+ $l -= length $incnum;
+
+ # pad it out with zeros
+ my $padzero = "0" x $l;
+ $incnum = ("0" x $l) . $incnum;
+ } else {
+ $incnum = $num + 1;
+ }
+
+ s/$num/$incnum/;
+ }
+
+ my $dbvar = $_;
+ my $var = $_;
+ my $str;
+ my $param;
+
+ if (/<%/) {
+ while (/<%/) {
+ s/<%.*?%>//;
+ last unless $&;
+ $param = $&;
+ $str = "";
+
+ if ($param =~ /<%date%>/i) {
+ $str = ($self->split_date($myconfig->{dateformat}, $self->{transdate}))[0];
+ $var =~ s/$param/$str/;
+ }
+
+ if ($param =~ /<%(name|business|description|item|partsgroup|phone|custom)/i) {
+ my $fld = lc $&;
+ $fld =~ s/<%//;
+ if ($fld =~ /name/) {
+ if ($self->{type}) {
+ $fld = $self->{vc};
+ }
+ }
+
+ my $p = $param;
+ $p =~ s/(<|>|%)//g;
+ my @p = split / /, $p;
+ my @n = split / /, uc $self->{$fld};
+ if ($#p > 0) {
+ for (my $i = 1; $i <= $#p; $i++) {
+ $str .= substr($n[$i-1], 0, $p[$i]);
+ }
+ } else {
+ ($str) = split /--/, $self->{$fld};
+ }
+ $var =~ s/$param/$str/;
+
+ $var =~ s/\W//g if $fld eq 'phone';
+ }
+
+ if ($param =~ /<%(yy|mm|dd)/i) {
+ my $p = $param;
+ $p =~ s/(<|>|%)//g;
+ my $spc = $p;
+ $spc =~ s/\w//g;
+ $spc = substr($spc, 0, 1);
+ my %d = ( yy => 1, mm => 2, dd => 3 );
+ my @p = ();
+
+ my @a = $self->split_date($myconfig->{dateformat}, $self->{transdate});
+ map { push @p, $a[$d{$_}] if ($p =~ /$_/) } sort keys %d;
+ $str = join $spc, @p;
+
+ $var =~ s/$param/$str/;
+ }
+
+ if ($param =~ /<%curr/i) {
+ $var =~ s/$param/$self->{currency}/;
+ }
+
+ }
+ }
+
+ $query = qq|UPDATE defaults
+ SET $fld = '$dbvar'|;
+ $dbh->do($query) || $form->dberror($query);
+
+ if ($closedb) {
+ $dbh->commit;
+ $dbh->disconnect;
+ }
+
+ $var;
+
+}
+
+
+sub split_date {
+ my ($self, $dateformat, $date) = @_;
+
+ my @d = localtime;
+ my $mm;
+ my $dd;
+ my $yy;
+ my $rv;
+
+ if (! $date) {
+ $dd = $d[3];
+ $mm = $d[4]++;
+ $yy = substr($d[5],-2);
+ $mm *= 1;
+ $dd *= 1;
+ $mm = "0$mm" if $mm < 10;
+ $dd = "0$dd" if $dd < 10;
+ }
+
+ if ($dateformat =~ /^yy/) {
+ if ($date) {
+ if ($date =~ /\D/) {
+ ($yy, $mm, $dd) = split /\D/, $date;
+ $mm *= 1;
+ $dd *= 1;
+ $mm = "0$mm" if $mm < 10;
+ $dd = "0$dd" if $dd < 10;
+ $yy = substr($yy, -2);
+ $rv = "$yy$mm$dd";
+ } else {
+ $rv = $date;
+ }
+ } else {
+ $rv = "$yy$mm$dd";
+ }
+ }
+
+ if ($dateformat =~ /^mm/) {
+ if ($date) {
+ if ($date =~ /\D/) {
+ ($mm, $dd, $yy) = split /\D/, $date if $date;
+ $mm *= 1;
+ $dd *= 1;
+ $mm = "0$mm" if $mm < 10;
+ $dd = "0$dd" if $dd < 10;
+ $yy = substr($yy, -2);
+ $rv = "$mm$dd$yy";
+ } else {
+ $rv = $date;
+ }
+ } else {
+ $rv = "$mm$dd$yy";
+ }
+ }
+
+ if ($dateformat =~ /^dd/) {
+ if ($date) {
+ if ($date =~ /\D/) {
+ ($dd, $mm, $yy) = split /\D/, $date if $date;
+ $mm *= 1;
+ $dd *= 1;
+ $mm = "0$mm" if $mm < 10;
+ $dd = "0$dd" if $dd < 10;
+ $yy = substr($yy, -2);
+ $rv = "$dd$mm$yy";
+ } else {
+ $rv = $date;
+ }
+ } else {
+ $rv = "$dd$mm$yy";
+ }
+ }
+
+ ($rv, $yy, $mm, $dd);
+
+}
+
+
+sub from_to {
+ my ($self, $yy, $mm, $interval) = @_;
+
+ use Time::Local;
+
+ my @t;
+ my $dd = 1;
+ my $fromdate = "$yy${mm}01";
+ my $bd = 1;
+
+ if (defined $interval) {
+ if ($interval == 12) {
+ $yy++ if $mm > 1;
+ } else {
+ if (($mm += $interval) > 12) {
+ $mm -= 12;
+ $yy++ if $mm > 1;
+ }
+ if ($interval == 0) {
+ @t = localtime(time);
+ $dd = $t[3];
+ $mm = $t[4] + 1;
+ $yy = $t[5] + 1900;
+ $bd = 0;
+ }
+ }
+ } else {
+ if ($mm++ > 12) {
+ $mm -= 12;
+ $yy++;
+ }
+ }
+
+ $mm--;
+ @t = localtime(timelocal(0,0,0,$dd,$mm,$yy) - $bd);
+
+ $t[4]++;
+ $t[4] = substr("0$t[4]",-2);
+ $t[3] = substr("0$t[3]",-2);
+
+ ($fromdate, "$yy$t[4]$t[3]");
+
+}
+
+
+sub audittrail {
+ my ($self, $dbh, $myconfig, $audittrail) = @_;
+
+# table, $reference, $formname, $action, $id, $transdate) = @_;
+
+ my $query;
+ my $rv;
+
+ # if we have an id add audittrail, otherwise get a new timestamp
+
+ if ($audittrail->{id}) {
+ $dbh = $self->dbconnect($myconfig) if $myconfig;
+
+ $query = qq|SELECT audittrail FROM defaults|;
+
+ if ($dbh->selectrow_array($query)) {
+ my ($null, $employee_id) = $self->get_employee($dbh);
+
+ if ($self->{audittrail} && !$myconfig) {
+ chop $self->{audittrail};
+
+ my @a = split /\|/, $self->{audittrail};
+ my %newtrail = ();
+ my $key;
+ my $i;
+ my @flds = qw(tablename reference formname action transdate);
+
+ # put into hash and remove dups
+ while (@a) {
+ $key = "$a[2]$a[3]";
+ $i = 0;
+ $newtrail{$key} = { map { $_ => $a[$i++] } @flds };
+ splice @a, 0, 5;
+ }
+
+ $query = qq|INSERT INTO audittrail (trans_id, tablename, reference,
+ formname, action, employee_id, transdate)
+ VALUES ($audittrail->{id}, ?, ?,
+ ?, ?, $employee_id, ?)|;
+ my $sth = $dbh->prepare($query) || $self->dberror($query);
+
+ foreach $key (sort { $newtrail{$a}{transdate} cmp $newtrail{$b}{transdate} } keys %newtrail) {
+ $i = 1;
+ map { $sth->bind_param($i++, $newtrail{$key}{$_}) } @flds;
+
+ $sth->execute || $self->dberror;
+ $sth->finish;
+ }
+ }
+
+
+ if ($audittrail->{transdate}) {
+ $query = qq|INSERT INTO audittrail (trans_id, tablename, reference,
+ formname, action, employee_id, transdate) VALUES (
+ $audittrail->{id}, '$audittrail->{tablename}', |
+ .$dbh->quote($audittrail->{reference}).qq|',
+ '$audittrail->{formname}', '$audittrail->{action}',
+ $employee_id, '$audittrail->{transdate}')|;
+ } else {
+ $query = qq|INSERT INTO audittrail (trans_id, tablename, reference,
+ formname, action, employee_id) VALUES ($audittrail->{id},
+ '$audittrail->{tablename}', |
+ .$dbh->quote($audittrail->{reference}).qq|,
+ '$audittrail->{formname}', '$audittrail->{action}',
+ $employee_id)|;
+ }
+ $dbh->do($query);
+ }
+ } else {
+ $dbh = $self->dbconnect($myconfig);
+
+ $query = qq|SELECT current_timestamp FROM defaults|;
+ my ($timestamp) = $dbh->selectrow_array($query);
+
+ $rv = "$audittrail->{tablename}|$audittrail->{reference}|$audittrail->{formname}|$audittrail->{action}|$timestamp|";
+ }
+
+ $dbh->disconnect if $myconfig;
+
+ $rv;
+
+}
+
+
+
package Locale;
@@ -1352,27 +2288,26 @@ sub date {
my $longdate = "";
my $longmonth = ($longformat) ? 'LONG_MONTH' : 'SHORT_MONTH';
+
if ($date) {
# get separator
$spc = $myconfig->{dateformat};
$spc =~ s/\w//g;
- $spc = substr($spc, 1, 1);
-
- if ($spc eq '.') {
- $spc = '\.';
- }
- if ($spc eq '/') {
- $spc = '\/';
- }
+ $spc = substr($spc, 0, 1);
- if ($myconfig->{dateformat} =~ /^yy/) {
- ($yy, $mm, $dd) = split /$spc/, $date;
- }
- if ($myconfig->{dateformat} =~ /^mm/) {
- ($mm, $dd, $yy) = split /$spc/, $date;
- }
- if ($myconfig->{dateformat} =~ /^dd/) {
- ($dd, $mm, $yy) = split /$spc/, $date;
+ if ($date =~ /\D/) {
+ if ($myconfig->{dateformat} =~ /^yy/) {
+ ($yy, $mm, $dd) = split /\D/, $date;
+ }
+ if ($myconfig->{dateformat} =~ /^mm/) {
+ ($mm, $dd, $yy) = split /\D/, $date;
+ }
+ if ($myconfig->{dateformat} =~ /^dd/) {
+ ($dd, $mm, $yy) = split /\D/, $date;
+ }
+ } else {
+ $date = substr($date, 2);
+ ($yy, $mm, $dd) = ($date =~ /(..)(..)(..)/);
}
$dd *= 1;
@@ -1381,9 +2316,34 @@ sub date {
$yy = ($yy >= 70 && $yy <= 99) ? $yy + 1900 : $yy;
if ($myconfig->{dateformat} =~ /^dd/) {
- $longdate = "$dd. ".&text($self, $self->{$longmonth}[$mm])." $yy";
+ $mm++;
+ $dd = "0$dd" if ($dd < 10);
+ $mm = "0$mm" if ($mm < 10);
+ $longdate = "$dd$spc$mm$spc$yy";
+
+ if (defined $longformat) {
+ $longdate = "$dd";
+ $longdate .= ($spc eq '.') ? ". " : " ";
+ $longdate .= &text($self, $self->{$longmonth}[--$mm])." $yy";
+ }
+ } elsif ($myconfig->{dateformat} =~ /^yy/) {
+ $mm++;
+ $dd = "0$dd" if ($dd < 10);
+ $mm = "0$mm" if ($mm < 10);
+ $longdate = "$yy$spc$mm$spc$dd";
+
+ if (defined $longformat) {
+ $longdate = &text($self, $self->{$longmonth}[--$mm])." $dd $yy";
+ }
} else {
- $longdate = &text($self, $self->{$longmonth}[$mm])." $dd, $yy";
+ $mm++;
+ $dd = "0$dd" if ($dd < 10);
+ $mm = "0$mm" if ($mm < 10);
+ $longdate = "$mm$spc$dd$spc$yy";
+
+ if (defined $longformat) {
+ $longdate = &text($self, $self->{$longmonth}[--$mm])." $dd $yy";
+ }
}
}
diff --git a/sql-ledger/SL/GL.pm b/sql-ledger/SL/GL.pm
index 5bceb078a..221f71726 100644
--- a/sql-ledger/SL/GL.pm
+++ b/sql-ledger/SL/GL.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -24,10 +24,6 @@
#
# General ledger backend code
#
-# CHANGE LOG:
-# DS. 2000-07-04 Created
-# DS. 2001-06-12 Changed relations from accno to chart_id
-#
#======================================================================
package GL;
@@ -38,6 +34,14 @@ sub delete_transaction {
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my %audittrail = ( tablename => 'gl',
+ reference => $form->{reference},
+ formname => 'transaction',
+ action => 'deleted',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
my $query = qq|DELETE FROM gl WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
@@ -57,34 +61,11 @@ sub delete_transaction {
sub post_transaction {
my ($self, $myconfig, $form) = @_;
- my ($debit, $credit) = (0, 0);
+ my $null;
my $project_id;
-
+ my $department_id;
my $i;
- # check if debit and credit balances
- for $i (1 .. $form->{rowcount}) {
- if ($form->{"debit_$i"} && $form->{"credit_$i"}) {
- return -1;
- }
-
- $form->{"debit_$i"} = $form->parse_amount($myconfig, $form->{"debit_$i"});
- $form->{"credit_$i"} = $form->parse_amount($myconfig, $form->{"credit_$i"});
-
- $debit += $form->{"debit_$i"};
- $credit += $form->{"credit_$i"};
- }
-
- $debit = $form->round_amount($debit, 2);
- $credit = $form->round_amount($credit, 2);
-
- if ($debit != $credit) {
- return -2;
- }
- if (($debit + $credit) == 0) {
- return -3;
- }
-
# connect to database, turn off AutoCommit
my $dbh = $form->dbconnect_noauto($myconfig);
@@ -97,11 +78,8 @@ sub post_transaction {
# if there is a $form->{id} replace the old transaction
# delete all acc_trans entries and add the new ones
- # escape '
- map { $form->{$_} =~ s/'/''/g } qw(reference description);
-
-
- my ($query, $sth);
+ my $query;
+ my $sth;
if ($form->{id}) {
# delete individual transactions
@@ -125,48 +103,75 @@ sub post_transaction {
($form->{id}) = $sth->fetchrow_array;
$sth->finish;
-
}
+ ($null, $department_id) = split /--/, $form->{department};
+ $department_id *= 1;
+
$query = qq|UPDATE gl SET
- reference = '$form->{reference}',
- description = '$form->{description}',
- notes = '$form->{notes}',
- transdate = '$form->{transdate}'
+ reference = |.$dbh->quote($form->{reference}).qq|,
+ description = |.$dbh->quote($form->{description}).qq|,
+ notes = |.$dbh->quote($form->{notes}).qq|,
+ transdate = '$form->{transdate}',
+ department_id = $department_id
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
-
+
+ my $amount = 0;
+ my $posted = 0;
# insert acc_trans transactions
for $i (1 .. $form->{rowcount}) {
+
+ $form->{"debit_$i"} = $form->parse_amount($myconfig, $form->{"debit_$i"});
+ $form->{"credit_$i"} = $form->parse_amount($myconfig, $form->{"credit_$i"});
+
# extract accno
($accno) = split(/--/, $form->{"accno_$i"});
- my $amount = 0;
+ $amount = 0;
if ($form->{"credit_$i"} != 0) {
$amount = $form->{"credit_$i"};
+ $posted = 0;
}
if ($form->{"debit_$i"} != 0) {
$amount = $form->{"debit_$i"} * -1;
+ $posted = 0;
}
- # if there is an amount, add the record
- if ($amount != 0) {
- $project_id = ($form->{"project_id_$i"}) ? $form->{"project_id_$i"} : 'NULL';
+ # add the record
+ if (! $posted) {
+
+ ($null, $project_id) = split /--/, $form->{"projectnumber_$i"};
+ $project_id *= 1;
+ $form->{"fx_transaction_$i"} *= 1;
+
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
- source, project_id)
+ source, project_id, fx_transaction)
VALUES
($form->{id}, (SELECT id
- FROM chart
+ FROM chart
WHERE accno = '$accno'),
- $amount, '$form->{transdate}', '$form->{reference}',
- $project_id)|;
+ $amount, '$form->{transdate}', |
+ .$dbh->quote($form->{reference}).qq|,
+ $project_id, '$form->{"fx_transaction_$i"}')|;
$dbh->do($query) || $form->dberror($query);
+
+ $posted = 1;
}
+
}
+
+ my %audittrail = ( tablename => 'gl',
+ reference => $form->{reference},
+ formname => 'transaction',
+ action => 'posted',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
# commit and redirect
my $rc = $dbh->commit;
@@ -185,21 +190,33 @@ sub all_transactions {
my $dbh = $form->dbconnect($myconfig);
my $query;
my $sth;
+ my $var;
+ my $null;
my ($glwhere, $arwhere, $apwhere) = ("1 = 1", "1 = 1", "1 = 1");
if ($form->{reference}) {
- my $source = $form->like(lc $form->{reference});
- $glwhere .= " AND lower(g.reference) LIKE '$source'";
- $arwhere .= " AND lower(a.invnumber) LIKE '$source'";
- $apwhere .= " AND lower(a.invnumber) LIKE '$source'";
+ $var = $form->like(lc $form->{reference});
+ $glwhere .= " AND lower(g.reference) LIKE '$var'";
+ $arwhere .= " AND lower(a.invnumber) LIKE '$var'";
+ $apwhere .= " AND lower(a.invnumber) LIKE '$var'";
}
+ if ($form->{department}) {
+ ($null, $var) = split /--/, $form->{department};
+ $glwhere .= " AND g.department_id = $var";
+ $arwhere .= " AND a.department_id = $var";
+ $apwhere .= " AND a.department_id = $var";
+ }
+
if ($form->{source}) {
- my $source = $form->like(lc $form->{source});
- $glwhere .= " AND lower(ac.source) LIKE '$source'";
- $arwhere .= " AND lower(ac.source) LIKE '$source'";
- $apwhere .= " AND lower(ac.source) LIKE '$source'";
+ $var = $form->like(lc $form->{source});
+ $glwhere .= " AND lower(ac.source) LIKE '$var'";
+ $arwhere .= " AND lower(ac.source) LIKE '$var'";
+ $apwhere .= " AND lower(ac.source) LIKE '$var'";
}
+
+ ($form->{datefrom}, $form->{dateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
+
if ($form->{datefrom}) {
$glwhere .= " AND ac.transdate >= '$form->{datefrom}'";
$arwhere .= " AND ac.transdate >= '$form->{datefrom}'";
@@ -210,17 +227,27 @@ sub all_transactions {
$arwhere .= " AND ac.transdate <= '$form->{dateto}'";
$apwhere .= " AND ac.transdate <= '$form->{dateto}'";
}
+ if ($form->{amountfrom}) {
+ $glwhere .= " AND abs(ac.amount) >= $form->{amountfrom}";
+ $arwhere .= " AND abs(ac.amount) >= $form->{amountfrom}";
+ $apwhere .= " AND abs(ac.amount) >= $form->{amountfrom}";
+ }
+ if ($form->{amountto}) {
+ $glwhere .= " AND abs(ac.amount) <= $form->{amountto}";
+ $arwhere .= " AND abs(ac.amount) <= $form->{amountto}";
+ $apwhere .= " AND abs(ac.amount) <= $form->{amountto}";
+ }
if ($form->{description}) {
- my $description = $form->like(lc $form->{description});
- $glwhere .= " AND lower(g.description) LIKE '$description'";
- $arwhere .= " AND lower(ct.name) LIKE '$description'";
- $apwhere .= " AND lower(ct.name) LIKE '$description'";
+ $var = $form->like(lc $form->{description});
+ $glwhere .= " AND lower(g.description) LIKE '$var'";
+ $arwhere .= " AND lower(ct.name) LIKE '$var'";
+ $apwhere .= " AND lower(ct.name) LIKE '$var'";
}
if ($form->{notes}) {
- my $notes = $form->like(lc $form->{notes});
- $glwhere .= " AND lower(g.notes) LIKE '$notes'";
- $arwhere .= " AND lower(a.notes) LIKE '$notes'";
- $apwhere .= " AND lower(a.notes) LIKE '$notes'";
+ $var = $form->like(lc $form->{notes});
+ $glwhere .= " AND lower(g.notes) LIKE '$var'";
+ $arwhere .= " AND lower(a.notes) LIKE '$var'";
+ $apwhere .= " AND lower(a.notes) LIKE '$var'";
}
if ($form->{accno}) {
$glwhere .= " AND c.accno = '$form->{accno}'";
@@ -240,68 +267,56 @@ sub all_transactions {
if ($form->{accno}) {
# get category for account
- $query = qq|SELECT category
+ $query = qq|SELECT category, link
FROM chart
WHERE accno = '$form->{accno}'|;
- $sth = $dbh->prepare($query);
-
- $sth->execute || $form->dberror($query);
- ($form->{ml}) = $sth->fetchrow_array;
- $sth->finish;
+ ($form->{ml}, $form->{link}) = $dbh->selectrow_array($query);
if ($form->{datefrom}) {
$query = qq|SELECT SUM(ac.amount)
- FROM acc_trans ac, chart c
- WHERE ac.chart_id = c.id
- AND c.accno = '$form->{accno}'
+ FROM acc_trans ac
+ JOIN chart c ON (ac.chart_id = c.id)
+ WHERE c.accno = '$form->{accno}'
AND ac.transdate < date '$form->{datefrom}'
|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- ($form->{balance}) = $sth->fetchrow_array;
- $sth->finish;
+ ($form->{balance}) = $dbh->selectrow_array($query);
}
}
if ($form->{gifi_accno}) {
# get category for account
- $query = qq|SELECT category
+ $query = qq|SELECT category, link
FROM chart
WHERE gifi_accno = '$form->{gifi_accno}'|;
- $sth = $dbh->prepare($query);
-
- $sth->execute || $form->dberror($query);
- ($form->{ml}) = $sth->fetchrow_array;
- $sth->finish;
+ ($form->{ml}, $form->{link}) = $dbh->selectrow_array($query);
if ($form->{datefrom}) {
$query = qq|SELECT SUM(ac.amount)
- FROM acc_trans ac, chart c
- WHERE ac.chart_id = c.id
- AND c.gifi_accno = '$form->{gifi_accno}'
+ FROM acc_trans ac
+ JOIN chart c ON (ac.chart_id = c.id)
+ WHERE c.gifi_accno = '$form->{gifi_accno}'
AND ac.transdate < date '$form->{datefrom}'
|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- ($form->{balance}) = $sth->fetchrow_array;
- $sth->finish;
+ ($form->{balance}) = $dbh->selectrow_array($query);
}
}
- my $false = ($myconfig->{dbdriver} eq 'Pg') ? FALSE : q|'0'|;
+ my $false = ($myconfig->{dbdriver} =~ /Pg/) ? FALSE : q|'0'|;
- my $sortorder = join ', ', $form->sort_columns(qw(transdate reference source description accno));
- my %ordinal = ( transdate => 6,
+ my %ordinal = ( id => 1,
+ accno => 9,
+ transdate => 6,
reference => 4,
source => 7,
description => 5 );
- map { $sortorder =~ s/$_/$ordinal{$_}/ } keys %ordinal;
+
+ my @a = (id, transdate, reference, source, description, accno);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
my $query = qq|SELECT g.id, 'gl' AS type, $false AS invoice, g.reference,
g.description, ac.transdate, ac.source,
- ac.amount, c.accno, c.gifi_accno, g.notes
+ ac.amount, c.accno, c.gifi_accno, g.notes, c.link,
+ '' AS till, ac.cleared
FROM gl g, acc_trans ac, chart c
WHERE $glwhere
AND ac.chart_id = c.id
@@ -309,7 +324,8 @@ sub all_transactions {
UNION ALL
SELECT a.id, 'ar' AS type, a.invoice, a.invnumber,
ct.name, ac.transdate, ac.source,
- ac.amount, c.accno, c.gifi_accno, a.notes
+ ac.amount, c.accno, c.gifi_accno, a.notes, c.link,
+ a.till, ac.cleared
FROM ar a, acc_trans ac, chart c, customer ct
WHERE $arwhere
AND ac.chart_id = c.id
@@ -318,7 +334,8 @@ sub all_transactions {
UNION ALL
SELECT a.id, 'ap' AS type, a.invoice, a.invnumber,
ct.name, ac.transdate, ac.source,
- ac.amount, c.accno, c.gifi_accno, a.notes
+ ac.amount, c.accno, c.gifi_accno, a.notes, c.link,
+ a.till, ac.cleared
FROM ap a, acc_trans ac, chart c, vendor ct
WHERE $apwhere
AND ac.chart_id = c.id
@@ -328,6 +345,7 @@ sub all_transactions {
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
+
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
# gl
@@ -347,7 +365,7 @@ sub all_transactions {
# ar
if ($ref->{type} eq "ar") {
if ($ref->{invoice}) {
- $ref->{module} = "is";
+ $ref->{module} = ($ref->{till}) ? "ps" : "is";
} else {
$ref->{module} = "ar";
}
@@ -365,6 +383,7 @@ sub all_transactions {
}
+
$sth->finish;
if ($form->{accno}) {
@@ -392,7 +411,7 @@ sub all_transactions {
sub transaction {
my ($self, $myconfig, $form) = @_;
- my ($query, $sth);
+ my ($query, $sth, $ref);
# connect to database
my $dbh = $form->dbconnect($myconfig);
@@ -406,27 +425,33 @@ sub transaction {
($form->{closedto}, $form->{revtrans}) = $sth->fetchrow_array;
$sth->finish;
- $query = "SELECT reference, description, notes, transdate
- FROM gl
- WHERE id = $form->{id}";
+ $query = qq|SELECT g.*,
+ d.description AS department
+ FROM gl g
+ LEFT JOIN department d ON (d.id = g.department_id)
+ WHERE g.id = $form->{id}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- ($form->{reference}, $form->{description}, $form->{notes}, $form->{transdate}) = $sth->fetchrow_array;
+ $ref = $sth->fetchrow_hashref(NAME_lc);
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
# retrieve individual rows
- $query = "SELECT c.accno, a.amount, project_id,
- (SELECT p.projectnumber FROM project p
- WHERE a.project_id = p.id) AS projectnumber
- FROM acc_trans a, chart c
- WHERE a.chart_id = c.id
- AND a.trans_id = $form->{id}
- ORDER BY accno";
+ $query = qq|SELECT c.accno, c.description, ac.amount, ac.project_id,
+ p.projectnumber, ac.fx_transaction
+ FROM acc_trans ac
+ JOIN chart c ON (ac.chart_id = c.id)
+ LEFT JOIN project p ON (p.id = ac.project_id)
+ WHERE ac.trans_id = $form->{id}
+ ORDER BY accno|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ if ($ref->{fx_transaction}) {
+ $form->{transfer} = 1;
+ }
push @{ $form->{GL} }, $ref;
}
} else {
@@ -440,16 +465,43 @@ sub transaction {
$sth->finish;
+ my $paid;
+ if ($form->{transfer}) {
+ $paid = "AND link LIKE '%_paid%'
+ AND NOT (category = 'I'
+ OR category = 'E')
+
+ UNION
+
+ SELECT accno,description
+ FROM chart
+ WHERE id IN (SELECT fxgain_accno_id FROM defaults)
+ OR id IN (SELECT fxloss_accno_id FROM defaults)";
+ }
+
# get chart of accounts
$query = qq|SELECT accno,description
FROM chart
WHERE charttype = 'A'
+ $paid
ORDER by accno|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- $form->{chart} = "";
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_accno} }, $ref;
+ }
+ $sth->finish;
+
+ # get projects
+ $query = qq|SELECT *
+ FROM project
+ ORDER BY projectnumber|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- push @{ $form->{chart} }, $ref;
+ push @{ $form->{all_projects} }, $ref;
}
$sth->finish;
diff --git a/sql-ledger/SL/HR.pm b/sql-ledger/SL/HR.pm
new file mode 100644
index 000000000..6e1bae850
--- /dev/null
+++ b/sql-ledger/SL/HR.pm
@@ -0,0 +1,558 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 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.
+#======================================================================
+#
+# backend code for human resources and payroll
+#
+#======================================================================
+
+package HR;
+
+
+sub get_employee {
+ my ($self, $myconfig, $form) = @_;
+
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query;
+ my $sth;
+ my $ref;
+ my $notid = "";
+
+ if ($form->{id}) {
+ $query = qq|SELECT e.*
+ FROM employee e
+ WHERE e.id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ $ref = $sth->fetchrow_hashref(NAME_lc);
+
+ # check if employee can be deleted, orphaned
+ $form->{status} = "orphaned" unless $ref->{login};
+
+$form->{status} = 'orphaned'; # leave orphaned for now until payroll is done
+
+ $ref->{employeelogin} = $ref->{login};
+ delete $ref->{login};
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+ $sth->finish;
+
+ # get manager
+ $form->{managerid} *= 1;
+ $query = qq|SELECT name
+ FROM employee
+ WHERE id = $form->{managerid}|;
+ ($form->{manager}) = $dbh->selectrow_array($query);
+
+
+######### disabled for now
+if ($form->{deductions}) {
+ # get allowances
+ $query = qq|SELECT d.id, d.description, da.before, da.after, da.rate
+ FROM employeededuction da
+ JOIN deduction d ON (da.deduction_id = d.id)
+ WHERE da.employee_id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $ref->{rate} *= 100;
+ push @{ $form->{all_employeededuction} }, $ref;
+ }
+ $sth->finish;
+}
+
+ $notid = qq|AND id != $form->{id}|;
+
+ }
+
+
+ # get managers
+ $query = qq|SELECT id, name
+ FROM employee
+ WHERE sales = '1'
+ AND role = 'manager'
+ $notid
+ ORDER BY 2|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_manager} }, $ref;
+ }
+ $sth->finish;
+
+
+ # get deductions
+if ($form->{deductions}) {
+ $query = qq|SELECT id, description
+ FROM deduction
+ ORDER BY 2|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_deduction} }, $ref;
+ }
+ $sth->finish;
+}
+
+ $dbh->disconnect;
+
+}
+
+
+
+sub save_employee {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect_noauto($myconfig);
+ my $query;
+ my $sth;
+
+ if (! $form->{id}) {
+ my $uid = time;
+ $uid .= $form->{login};
+
+ $query = qq|INSERT INTO employee (name)
+ VALUES ('$uid')|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|SELECT id FROM employee
+ WHERE name = '$uid'|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ ($form->{id}) = $sth->fetchrow_array;
+ $sth->finish;
+ }
+
+ my ($null, $managerid) = split /--/, $form->{manager};
+ $managerid *= 1;
+ $form->{sales} *= 1;
+
+ $form->{employeenumber} = $form->update_defaults($myconfig, "employeenumber", $dbh) if ! $form->{employeenumber};
+
+ $query = qq|UPDATE employee SET
+ employeenumber = |.$dbh->quote($form->{employeenumber}).qq|,
+ name = |.$dbh->quote($form->{name}).qq|,
+ address1 = |.$dbh->quote($form->{address1}).qq|,
+ address2 = |.$dbh->quote($form->{address2}).qq|,
+ city = |.$dbh->quote($form->{city}).qq|,
+ state = |.$dbh->quote($form->{state}).qq|,
+ zipcode = |.$dbh->quote($form->{zipcode}).qq|,
+ country = |.$dbh->quote($form->{country}).qq|,
+ workphone = '$form->{workphone}',
+ homephone = '$form->{homephone}',
+ startdate = |.$form->dbquote($form->{startdate}, SQL_DATE).qq|,
+ enddate = |.$form->dbquote($form->{enddate}, SQL_DATE).qq|,
+ notes = |.$dbh->quote($form->{notes}).qq|,
+ role = '$form->{role}',
+ sales = '$form->{sales}',
+ email = |.$dbh->quote($form->{email}).qq|,
+ ssn = '$form->{ssn}',
+ dob = |.$form->dbquote($form->{dob}, SQL_DATE).qq|,
+ iban = '$form->{iban}',
+ bic = '$form->{bic}',
+ managerid = $managerid
+ WHERE id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+# for now
+if ($form->{selectdeduction}) {
+ # insert deduction and allowances for payroll
+ $query = qq|DELETE FROM employeededuction
+ WHERE employee_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|INSERT INTO employeededuction (employee_id, deduction_id,
+ before, after, rate) VALUES ($form->{id},?,?,?,?)|;
+ my $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ for ($i = 1; $i <= $form->{deduction_rows}; $i++) {
+ map { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) } qw(before after);
+ ($null, $deduction_id) = split /--/, $form->{"deduction_$i"};
+ if ($deduction_id) {
+ $sth->execute($deduction_id, $form->{"before_$i"}, $form->{"after_$i"}, $form->{"rate_$i"} / 100) || $form->dberror($query);
+ }
+ }
+ $sth->finish;
+}
+
+ $dbh->commit;
+ $dbh->disconnect;
+
+}
+
+
+sub delete_employee {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ # delete employee
+ my $query = qq|DELETE FROM $form->{db}
+ WHERE id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->commit;
+ $dbh->disconnect;
+
+}
+
+
+sub employees {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $where = "1 = 1";
+ $form->{sort} = ($form->{sort}) ? $form->{sort} : "name";
+ my @a = qw(name);
+ my $sortorder = $form->sort_order(\@a);
+
+ my $var;
+
+ if ($form->{startdate}) {
+ $where .= " AND e.startdate >= '$startdate'";
+ }
+ if ($form->{enddate}) {
+ $where .= " AND e.enddate >= '$enddate'";
+ }
+ if ($form->{name}) {
+ $var = $form->like(lc $form->{name});
+ $where .= " AND lower(e.name) LIKE '$var'";
+ }
+ if ($form->{notes}) {
+ $var = $form->like(lc $form->{notes});
+ $where .= " AND lower(e.notes) LIKE '$var'";
+ }
+ if ($form->{status} eq 'sales') {
+ $where .= " AND e.sales = '1'";
+ }
+ if ($form->{status} eq 'orphaned') {
+ $where .= qq| AND e.login IS NULL|;
+ }
+
+ my $query = qq|SELECT e.*, m.name AS manager
+ FROM employee e
+ LEFT JOIN employee m ON (m.id = e.managerid)
+ WHERE $where
+ ORDER BY $sortorder|;
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $ref->{address} = "";
+ map { $ref->{address} .= "$ref->{$_} "; } qw(address1 address2 city state zipcode country);
+ push @{ $form->{all_employee} }, $ref;
+ }
+
+ $sth->finish;
+ $dbh->disconnect;
+
+}
+
+
+sub get_deduction {
+ my ($self, $myconfig, $form) = @_;
+
+ my $dbh = $form->dbconnect($myconfig);
+ my $query;
+ my $sth;
+ my $ref;
+ my $item;
+ my $i;
+
+ if ($form->{id}) {
+ $query = qq|SELECT d.*,
+ c1.accno AS ap_accno,
+ c1.description AS ap_description,
+ c2.accno AS expense_accno,
+ c2.description AS expense_description
+ FROM deduction d
+ LEFT JOIN chart c1 ON (c1.id = d.ap_accno_id)
+ LEFT JOIN chart c2 ON (c2.id = d.expense_accno_id)
+ WHERE d.id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ $ref = $sth->fetchrow_hashref(NAME_lc);
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+ $sth->finish;
+
+ # check if orphaned
+$form->{status} = 'orphaned'; # for now
+
+
+ # get the rates
+ $query = qq|SELECT rate, amount, above, below
+ FROM deductionrate
+ WHERE trans_id = $form->{id}
+ ORDER BY rate, amount|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{deductionrate} }, $ref;
+ }
+ $sth->finish;
+
+ # get all for deductionbase
+ $query = qq|SELECT d.description, d.id, db.maximum
+ FROM deductionbase db
+ JOIN deduction d ON (d.id = db.deduction_id)
+ WHERE db.trans_id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{deductionbase} }, $ref;
+ }
+ $sth->finish;
+
+ # get all for deductionafter
+ $query = qq|SELECT d.description, d.id
+ FROM deductionafter da
+ JOIN deduction d ON (d.id = da.deduction_id)
+ WHERE da.trans_id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{deductionafter} }, $ref;
+ }
+ $sth->finish;
+
+ # build selection list for base and after
+ $query = qq|SELECT id, description
+ FROM deduction
+ WHERE id != $form->{id}
+ ORDER BY 2|;
+
+ } else {
+ # build selection list for base and after
+ $query = qq|SELECT id, description
+ FROM deduction
+ ORDER BY 2|;
+ }
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_deduction} }, $ref;
+ }
+ $sth->finish;
+
+
+ my %category = ( ap => 'L',
+ expense => 'E' );
+
+ foreach $item (keys %category) {
+ $query = qq|SELECT accno, description
+ FROM chart
+ WHERE charttype = 'A'
+ AND category = '$category{$item}'
+ ORDER BY accno|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{"${item}_accounts"} }, $ref;
+ }
+ $sth->finish;
+ }
+
+
+ $dbh->disconnect;
+
+}
+
+
+sub deductions {
+ my ($self, $myconfig, $form) = @_;
+
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT d.id, d.description, d.employeepays, d.employerpays,
+ c1.accno AS ap_accno, c2.accno AS expense_accno,
+ dr.rate, dr.amount, dr.above, dr.below
+ FROM deduction d
+ JOIN deductionrate dr ON (dr.trans_id = d.id)
+ LEFT JOIN chart c1 ON (d.ap_accno_id = c1.id)
+ LEFT JOIN chart c2 ON (d.expense_accno_id = c2.id)
+ ORDER BY 2, 7, 8|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_deduction} }, $ref;
+ }
+
+ $sth->finish;
+ $dbh->disconnect;
+
+}
+
+
+sub save_deduction {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ ($form->{ap_accno}) = split /--/, $form->{ap_accno};
+ ($form->{expense_accno}) = split /--/, $form->{expense_accno};
+
+ my $null;
+ my $deduction_id;
+ my $query;
+ my $sth;
+
+ if (! $form->{id}) {
+ my $uid = time;
+ $uid .= $form->{login};
+
+ $query = qq|INSERT INTO deduction (description)
+ VALUES ('$uid')|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|SELECT id FROM deduction
+ WHERE description = '$uid'|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ ($form->{id}) = $sth->fetchrow_array;
+ $sth->finish;
+ }
+
+
+ map { $form->{$_} = $form->parse_amount($myconfig, $form->{$_}) } qw(employeepays employerpays);
+
+ $query = qq|UPDATE deduction SET
+ description = |.$dbh->quote($form->{description}).qq|,
+ ap_accno_id =
+ (SELECT id FROM chart
+ WHERE accno = '$form->{ap_accno}'),
+ expense_accno_id =
+ (SELECT id FROM chart
+ WHERE accno = '$form->{expense_accno}'),
+ employerpays = '$form->{employerpays}',
+ employeepays = '$form->{employeepays}',
+ fromage = |.$form->dbquote($form->{fromage}, SQL_INT).qq|,
+ toage = |.$form->dbquote($form->{toage}, SQL_INT).qq|
+ WHERE id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+
+ $query = qq|DELETE FROM deductionrate
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|INSERT INTO deductionrate
+ (trans_id, rate, amount, above, below) VALUES (?,?,?,?,?)|;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ for ($i = 1; $i <= $form->{rate_rows}; $i++) {
+ map { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) } qw(rate amount above below);
+ $form->{"rate_$i"} /= 100;
+
+ if ($form->{"rate_$i"} || $form->{"amount_$i"}) {
+ $sth->execute($form->{id}, $form->{"rate_$i"}, $form->{"amount_$i"}, $form->{"above_$i"}, $form->{"below_$i"}) || $form->dberror($query);
+ }
+ }
+ $sth->finish;
+
+
+ $query = qq|DELETE FROM deductionbase
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|INSERT INTO deductionbase
+ (trans_id, deduction_id, maximum) VALUES (?,?,?)|;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ for ($i = 1; $i <= $form->{base_rows}; $i++) {
+ ($null, $deduction_id) = split /--/, $form->{"base_$i"};
+ $form->{"maximum_$i"} = $form->parse_amount($myconfig, $form->{"maximum_$i"});
+ if ($deduction_id) {
+ $sth->execute($form->{id}, $deduction_id, $form->{"maximum_$i"}) || $form->dberror($query);
+ }
+ }
+ $sth->finish;
+
+
+ $query = qq|DELETE FROM deductionafter
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|INSERT INTO deductionafter
+ (trans_id, deduction_id) VALUES (?,?)|;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ for ($i = 1; $i <= $form->{after_rows}; $i++) {
+ ($null, $deduction_id) = split /--/, $form->{"after_$i"};
+ if ($deduction_id) {
+ $sth->execute($form->{id}, $deduction_id) || $form->dberror($query);
+ }
+ }
+ $sth->finish;
+
+ $dbh->commit;
+ $dbh->disconnect;
+
+}
+
+
+sub delete_deduction {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ # delete deduction
+ my $query = qq|DELETE FROM $form->{db}
+ WHERE id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ foreach $item (qw(rate base after)) {
+ $query = qq|DELETE FROM deduction$item
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+
+ $dbh->commit;
+ $dbh->disconnect;
+
+}
+
+1;
+
diff --git a/sql-ledger/SL/IC.pm b/sql-ledger/SL/IC.pm
index f4a2f75ff..cf70b06ca 100644
--- a/sql-ledger/SL/IC.pm
+++ b/sql-ledger/SL/IC.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -34,11 +34,12 @@ sub get_part {
# connect to db
my $dbh = $form->dbconnect($myconfig);
+ my $i;
my $query = qq|SELECT p.*,
c1.accno AS inventory_accno,
- c2.accno AS income_accno,
- c3.accno AS expense_accno,
+ c2.accno AS income_accno,
+ c3.accno AS expense_accno,
pg.partsgroup
FROM parts p
LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
@@ -56,19 +57,23 @@ sub get_part {
$sth->finish;
my %oid = ('Pg' => 'a.oid',
- 'Oracle' => 'a.rowid'
+ 'PgPP' => 'a.oid',
+ 'Oracle' => 'a.rowid',
+ 'DB2' => '1=1'
);
-
-
- # part or service item
+
+ # part, service item or labor
$form->{item} = ($form->{inventory_accno}) ? 'part' : 'service';
+ $form->{item} = 'labor' if ! $form->{income_accno};
+
if ($form->{assembly}) {
$form->{item} = 'assembly';
# retrieve assembly items
$query = qq|SELECT p.id, p.partnumber, p.description,
- p.sellprice, p.weight, a.qty, a.bom, p.unit,
- pg.partsgroup
+ p.sellprice, p.weight, a.qty, a.bom, a.adj, p.unit,
+ p.lastcost, p.listprice,
+ pg.partsgroup, p.assembly, p.partsgroup_id
FROM parts p
JOIN assembly a ON (a.parts_id = p.id)
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
@@ -97,22 +102,20 @@ sub get_part {
$form->{amount}{IC_cogs} = $form->{expense_accno};
- if ($form->{item} ne 'service') {
+ if ($form->{item} =~ /(part|assembly)/) {
# get makes
if ($form->{makemodel}) {
- $query = qq|SELECT name FROM makemodel
+ $query = qq|SELECT make, model
+ FROM makemodel
WHERE parts_id = $form->{id}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- my $i = 1;
- while (($form->{"make_$i"}, $form->{"model_$i"}) = split(/:/, $sth->fetchrow_array)) {
- $i++;
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{makemodels} }, $ref;
}
$sth->finish;
- $form->{makemodel_rows} = $i - 1;
-
}
}
@@ -135,11 +138,11 @@ sub get_part {
$query = qq|SELECT parts_id
FROM invoice
WHERE parts_id = $form->{id}
- UNION
+ UNION
SELECT parts_id
FROM orderitems
WHERE parts_id = $form->{id}
- UNION
+ UNION
SELECT parts_id
FROM assembly
WHERE parts_id = $form->{id}|;
@@ -149,13 +152,51 @@ sub get_part {
($form->{orphaned}) = $sth->fetchrow_array;
$form->{orphaned} = !$form->{orphaned};
$sth->finish;
-
+
+
+ if ($form->{item} =~ /(part|service)/) {
+ # get vendors
+ $query = qq|SELECT v.id, v.name, pv.partnumber,
+ pv.lastcost, pv.leadtime, pv.curr AS vendorcurr
+ FROM partsvendor pv
+ JOIN vendor v ON (v.id = pv.vendor_id)
+ WHERE pv.parts_id = $form->{id}
+ ORDER BY 2|;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{vendormatrix} }, $ref;
+ }
+ $sth->finish;
+ }
+
+ # get matrix
+ if ($form->{item} ne 'labor') {
+ $query = qq|SELECT pc.pricebreak, pc.sellprice AS customerprice,
+ pc.curr AS customercurr,
+ pc.validfrom, pc.validto,
+ c.name, c.id AS cid, g.pricegroup, g.id AS gid
+ FROM partscustomer pc
+ LEFT JOIN customer c ON (c.id = pc.customer_id)
+ LEFT JOIN pricegroup g ON (g.id = pc.pricegroup_id)
+ WHERE pc.parts_id = $form->{id}
+ ORDER BY c.name, g.pricegroup, pc.pricebreak|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{customermatrix} }, $ref;
+ }
+ $sth->finish;
+ }
+
$dbh->disconnect;
}
-
sub save {
my ($self, $myconfig, $form) = @_;
@@ -175,50 +216,55 @@ sub save {
# if there is a $form->{id} then replace the old entry
# delete all makemodel entries and add the new ones
- # escape '
- map { $form->{$_} =~ s/'/''/g } qw(partnumber description notes unit bin);
-
# undo amount formatting
map { $form->{$_} = $form->parse_amount($myconfig, $form->{$_}) } qw(rop weight listprice sellprice lastcost stock);
- # set date to NULL if nothing entered
- $form->{priceupdate} = ($form->{priceupdate}) ? qq|'$form->{priceupdate}'| : "NULL";
+ $form->{lastcost} = $form->{sellprice} if $form->{item} eq 'labor';
$form->{makemodel} = (($form->{make_1}) || ($form->{model_1})) ? 1 : 0;
- $form->{alternate} = 0;
$form->{assembly} = ($form->{item} eq 'assembly') ? 1 : 0;
- $form->{obsolete} *= 1;
- $form->{onhand} *= 1;
-
- my ($query, $sth);
+ map { $form->{$_} *= 1 } qw(alternate obsolete onhand);
+
+ my $query;
+ my $sth;
+ my $i;
+ my $null;
+ my $vendor_id;
+ my $customer_id;
if ($form->{id}) {
# get old price
- $query = qq|SELECT sellprice, weight
+ $query = qq|SELECT listprice, sellprice, lastcost, weight
FROM parts
WHERE id = $form->{id}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- my ($sellprice, $weight) = $sth->fetchrow_array;
+ my ($listprice, $sellprice, $lastcost, $weight) = $sth->fetchrow_array;
$sth->finish;
# if item is part of an assembly adjust all assemblies
- $query = qq|SELECT id, qty
+ $query = qq|SELECT id, qty, adj
FROM assembly
WHERE parts_id = $form->{id}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my ($id, $qty) = $sth->fetchrow_array) {
- &update_assembly($dbh, $form, $id, $qty * 1, $sellprice * 1, $weight * 1);
+ while (my ($id, $qty, $adj) = $sth->fetchrow_array) {
+ &update_assembly($dbh, $form, $id, $qty, $adj, $listprice * 1, $sellprice * 1, $lastcost * 1, $weight * 1);
}
$sth->finish;
-
- if ($form->{item} ne 'service') {
+ if ($form->{item} =~ /(part|service)/) {
+ # delete partsvendor records
+ $query = qq|DELETE FROM partsvendor
+ WHERE parts_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+
+ if ($form->{item} !~ /(service|labor)/) {
# delete makemodel records
$query = qq|DELETE FROM makemodel
WHERE parts_id = $form->{id}|;
@@ -236,20 +282,21 @@ sub save {
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
} else {
- # update BOM only
+ # update BOM, A only
$query = qq|UPDATE assembly
- SET bom = ?
+ SET bom = ?, adj = ?
WHERE id = ?
AND parts_id = ?|;
- $sth = $dbh->prepare($query);
-
+ $sth = $dbh->prepare($query);
+
for $i (1 .. $form->{assembly_rows} - 1) {
- $sth->execute(($form->{"bom_$i"}) ? '1' : '0', $form->{id}, $form->{"id_$i"}) || $form->dberror($query);
+ $sth->execute(($form->{"bom_$i"}) ? '1' : '0', ($form->{"adj_$i"}) ? '1' : '0', $form->{id}, $form->{"id_$i"});
+ $sth->finish;
}
- $sth->finish;
}
-
+
$form->{onhand} += $form->{stock};
+
}
# delete tax records
@@ -257,6 +304,11 @@ sub save {
WHERE parts_id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
+ # delete matrix
+ $query = qq|DELETE FROM partscustomer
+ WHERE parts_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
} else {
my $uid = time;
$uid .= $form->{login};
@@ -277,37 +329,16 @@ sub save {
$form->{onhand} = ($form->{stock} * 1) if $form->{item} eq 'assembly';
}
-
- my $partsgroup_id = 0;
- if ($form->{partsgroup}) {
- my $partsgroup = lc $form->{partsgroup};
- $query = qq|SELECT DISTINCT id FROM partsgroup
- WHERE lower(partsgroup) = '$partsgroup'|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- ($partsgroup_id) = $sth->fetchrow_array;
- $sth->finish;
-
- if (!$partsgroup_id) {
- $query = qq|INSERT INTO partsgroup (partsgroup)
- VALUES ('$form->{partsgroup}')|;
- $dbh->do($query) || $form->dberror($query);
+ my $partsgroup_id;
+ ($null, $partsgroup_id) = split /--/, $form->{partsgroup};
+ $partsgroup_id *= 1;
- $query = qq|SELECT id FROM partsgroup
- WHERE partsgroup = '$form->{partsgroup}'|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
+ $form->{partnumber} = $form->update_defaults($myconfig, "partnumber", $dbh) if ! $form->{partnumber};
- ($partsgroup_id) = $sth->fetchrow_array;
- $sth->finish;
- }
- }
-
-
- $query = qq|UPDATE parts SET
- partnumber = '$form->{partnumber}',
- description = '$form->{description}',
+ $query = qq|UPDATE parts SET
+ partnumber = |.$dbh->quote($form->{partnumber}).qq|,
+ description = |.$dbh->quote($form->{description}).qq|,
makemodel = '$form->{makemodel}',
alternate = '$form->{alternate}',
assembly = '$form->{assembly}',
@@ -315,11 +346,11 @@ sub save {
sellprice = $form->{sellprice},
lastcost = $form->{lastcost},
weight = $form->{weight},
- priceupdate = $form->{priceupdate},
- unit = '$form->{unit}',
- notes = '$form->{notes}',
+ priceupdate = |.$form->dbquote($form->{priceupdate}, SQL_DATE).qq|,
+ unit = |.$dbh->quote($form->{unit}).qq|,
+ notes = |.$dbh->quote($form->{notes}).qq|,
rop = $form->{rop},
- bin = '$form->{bin}',
+ bin = |.$dbh->quote($form->{bin}).qq|,
inventory_accno_id = (SELECT id FROM chart
WHERE accno = '$form->{inventory_accno}'),
income_accno_id = (SELECT id FROM chart
@@ -336,15 +367,13 @@ sub save {
# insert makemodel records
- unless ($form->{item} eq 'service') {
- for my $i (1 .. $form->{makemodel_rows}) {
- # put make and model together
+ if ($form->{item} =~ /(part|assembly)/) {
+ for $i (1 .. $form->{makemodel_rows}) {
if (($form->{"make_$i"}) || ($form->{"model_$i"})) {
- map { $form->{"${_}_$i"} =~ s/'/''/g } qw(make model);
-
- $query = qq|INSERT INTO makemodel (parts_id, name)
- VALUES ($form->{id},
- '$form->{"make_$i"}:$form->{"model_$i"}')|;
+ $query = qq|INSERT INTO makemodel (parts_id, make, model)
+ VALUES ($form->{id},|
+ .$dbh->quote($form->{"make_$i"}).qq|, |
+ .$dbh->quote($form->{"model_$i"}).qq|)|;
$dbh->do($query) || $form->dberror($query);
}
}
@@ -367,27 +396,88 @@ sub save {
if ($form->{item} eq 'assembly') {
if ($form->{orphaned}) {
- for my $i (1 .. $form->{assembly_rows}) {
+ for $i (1 .. $form->{assembly_rows}) {
$form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
if ($form->{"qty_$i"} != 0) {
- $form->{"bom_$i"} *= 1;
- $query = qq|INSERT INTO assembly (id, parts_id, qty, bom)
+ map { $form->{"${_}_$i"} *= 1 } qw(bom adj);
+ $query = qq|INSERT INTO assembly (id, parts_id, qty, bom, adj)
VALUES ($form->{id}, $form->{"id_$i"},
- $form->{"qty_$i"}, '$form->{"bom_$i"}')|;
+ $form->{"qty_$i"}, '$form->{"bom_$i"}',
+ '$form->{"adj_$i"}')|;
$dbh->do($query) || $form->dberror($query);
}
}
}
- # adjust onhand for the assembly
+ # adjust onhand for the parts
if ($form->{onhand} != 0) {
&adjust_inventory($dbh, $form, $form->{id}, $form->{onhand});
}
+
+ @a = localtime; $a[5] += 1900; $a[4]++;
+ my $shippingdate = "$a[5]-$a[4]-$a[3]";
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh);
+
+ # add inventory record
+ if ($form->{stock} != 0) {
+ $query = qq|INSERT INTO inventory (warehouse_id, parts_id, qty,
+ shippingdate, employee_id) VALUES (
+ 0, $form->{id}, $form->{stock}, '$shippingdate',
+ $form->{employee_id})|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+
+ }
+
+
+ # add vendors
+ if ($form->{item} ne 'assembly') {
+ for $i (1 .. $form->{vendor_rows}) {
+ if ($form->{"vendor_$i"} && $form->{"lastcost_$i"}) {
+
+ ($null, $vendor_id) = split /--/, $form->{"vendor_$i"};
+
+ map { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"})} qw(lastcost leadtime);
+
+ $query = qq|INSERT INTO partsvendor (vendor_id, parts_id, partnumber,
+ lastcost, leadtime, curr)
+ VALUES ($vendor_id, $form->{id},|
+ .$dbh->quote($form->{"partnumber_$i"}).qq|,
+ $form->{"lastcost_$i"},
+ $form->{"leadtime_$i"}, '$form->{"vendorcurr_$i"}')|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+ }
+ }
+
+
+ # add pricematrix
+ for $i (1 .. $form->{customer_rows}) {
+
+ map { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"})} qw(pricebreak customerprice);
+
+ if ($form->{"customerprice_$i"}) {
+
+ ($null, $customer_id) = split /--/, $form->{"customer_$i"};
+ $customer_id *= 1;
+
+ ($null, $pricegroup_id) = split /--/, $form->{"pricegroup_$i"};
+ $pricegroup_id *= 1;
+
+ $query = qq|INSERT INTO partscustomer (parts_id, customer_id,
+ pricegroup_id, pricebreak, sellprice, curr,
+ validfrom, validto)
+ VALUES ($form->{id}, $customer_id,
+ $pricegroup_id, $form->{"pricebreak_$i"},
+ $form->{"customerprice_$i"}, '$form->{"customercurr_$i"}',|
+ .$form->dbquote($form->{"validfrom_$i"}, SQL_DATE).qq|, |
+ .$form->dbquote($form->{"validto_$i"}, SQL_DATE).qq|)|;
+ $dbh->do($query) || $form->dberror($query);
+ }
}
-
# commit
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -399,27 +489,43 @@ sub save {
sub update_assembly {
- my ($dbh, $form, $id, $qty, $sellprice, $weight) = @_;
+ my ($dbh, $form, $id, $qty, $adj, $listprice, $sellprice, $lastcost, $weight) = @_;
- my $query = qq|SELECT id, qty
+ my $formlistprice = $form->{listprice};
+ my $formsellprice = $form->{sellprice};
+
+ if (!$adj) {
+ $formlistprice = $listprice;
+ $formsellprice = $sellprice;
+ }
+
+ my $query = qq|SELECT id, qty, adj
FROM assembly
- WHERE parts_id = $id|;
+ WHERE parts_id = $id|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my ($pid, $aqty) = $sth->fetchrow_array) {
- &update_assembly($dbh, $form, $pid, $aqty * $qty, $sellprice, $weight);
+ $form->{$id} = 1;
+
+ while (my ($pid, $aqty, $aadj) = $sth->fetchrow_array) {
+ &update_assembly($dbh, $form, $pid, $aqty * $qty, $aadj, $listprice, $sellprice, $lastcost, $weight) if !$form->{$pid};
}
$sth->finish;
$query = qq|UPDATE parts
- SET sellprice = sellprice +
- $qty * ($form->{sellprice} - $sellprice),
+ SET listprice = listprice +
+ $qty * ($formlistprice - $listprice),
+ sellprice = sellprice +
+ $qty * ($formsellprice - $sellprice),
+ lastcost = lastcost +
+ $qty * ($form->{lastcost} - $lastcost),
weight = weight +
$qty * ($form->{weight} - $weight)
WHERE id = $id|;
$dbh->do($query) || $form->dberror($query);
+ delete $form->{$id};
+
}
@@ -443,6 +549,15 @@ sub retrieve_assemblies {
}
$where .= " AND NOT p.obsolete = '1'";
+ my %ordinal = ( 'partnumber' => 2,
+ 'description' => 3,
+ 'bin' => 4
+ );
+
+ my @a = qw(partnumber description bin);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+
# retrieve assembly items
my $query = qq|SELECT p.id, p.partnumber, p.description,
p.bin, p.onhand, p.rop,
@@ -452,13 +567,58 @@ sub retrieve_assemblies {
AND a.id = p.id) AS inventory
FROM parts p
WHERE $where
- AND assembly = '1'|;
+ AND assembly = '1'
+ ORDER BY $sortorder|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- push @{ $form->{assembly_items} }, $ref if $ref->{inventory};
+ my $inh;
+ if ($form->{checkinventory}) {
+ $query = qq|SELECT p.id, p.onhand, a.qty FROM parts p
+ JOIN assembly a ON (a.parts_id = p.id)
+ WHERE a.id = ?|;
+ $inh = $dbh->prepare($query) || $form->dberror($query);
+ }
+
+ my $onhand = ();
+ my $ref;
+ my $aref;
+ my $stock;
+ my $howmany;
+ my $ok;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ if ($ref->{inventory}) {
+ $ok = 1;
+ if ($form->{checkinventory}) {
+ $inh->execute($ref->{id}) || $form->dberror($query);;
+ $ok = 0;
+ while ($aref = $inh->fetchrow_hashref(NAME_lc)) {
+ $onhand{$aref->{id}} = (exists $onhand{$aref->{id}}) ? $onhand{$aref->{id}} : $aref->{onhand};
+
+ if ($aref->{onhand} >= $aref->{qty}) {
+
+ $howmany = ($aref->{qty}) ? $aref->{onhand}/$aref->{qty} : 1;
+ if ($stock) {
+ $stock = ($stock > $howmany) ? $howmany : $stock;
+ } else {
+ $stock = $howmany;
+ }
+ $ok = 1;
+
+ $onhand{$aref->{id}} -= ($aref->{qty} * $stock);
+
+ } else {
+ $ok = 0;
+ last;
+ }
+ }
+ $inh->finish;
+ $ref->{stock} = (($ref->{rop} - $ref->{qty}) > $stock) ? int $stock : $ref->{rop};
+ }
+ push @{ $form->{assembly_items} }, $ref if $ok;
+ }
}
$sth->finish;
@@ -472,6 +632,11 @@ sub restock_assemblies {
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
+
+ @a = localtime; $a[5] += 1900; $a[4]++;
+ my $shippingdate = "$a[5]-$a[4]-$a[3]";
+
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh);
for my $i (1 .. $form->{rowcount}) {
@@ -480,9 +645,18 @@ sub restock_assemblies {
if ($form->{"qty_$i"} != 0) {
&adjust_inventory($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"});
}
+
+ # add inventory record
+ if ($form->{"qty_$i"} != 0) {
+ $query = qq|INSERT INTO inventory (warehouse_id, parts_id, qty,
+ shippingdate, employee_id) VALUES (
+ 0, $form->{"id_$i"}, $form->{"qty_$i"}, '$shippingdate',
+ $form->{employee_id})|;
+ $dbh->do($query) || $form->dberror($query);
+ }
}
-
+
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -495,9 +669,9 @@ sub adjust_inventory {
my ($dbh, $form, $id, $qty) = @_;
my $query = qq|SELECT p.id, p.inventory_accno_id, p.assembly, a.qty
- FROM parts p
- JOIN assembly a ON (a.parts_id = p.id)
- WHERE a.id = $id|;
+ FROM parts p, assembly a
+ WHERE a.parts_id = p.id
+ AND a.id = $id|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -505,9 +679,10 @@ sub adjust_inventory {
my $allocate = $qty * $ref->{qty};
- # is it a service item, then loop
- $ref->{inventory_accno_id} *= 1;
- next if (($ref->{inventory_accno_id} == 0) && !$ref->{assembly});
+ # is it a service item then loop
+ if (($ref->{inventory_accno_id} *= 1) == 0) {
+ next unless $ref->{assembly}; # assembly
+ }
# adjust parts onhand
$form->update_balance($dbh,
@@ -525,7 +700,7 @@ sub adjust_inventory {
"onhand",
qq|id = $id|,
$qty);
-
+
}
@@ -534,11 +709,6 @@ sub delete {
# connect to database, turn off AutoCommit
my $dbh = $form->dbconnect_noauto($myconfig);
-
- if ($form->{item} eq 'assembly' && $form->{onhand} != 0) {
- # adjust onhand for the assembly
- &adjust_inventory($dbh, $form, $form->{id}, $form->{onhand} * -1);
- }
my $query = qq|DELETE FROM parts
WHERE id = $form->{id}|;
@@ -548,14 +718,26 @@ sub delete {
WHERE parts_id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
+
+ if ($form->{item} ne 'assembly') {
+ $query = qq|DELETE FROM partsvendor
+ WHERE parts_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+
# check if it is a part, assembly or service
- if ($form->{item} eq 'part') {
+ if ($form->{item} ne 'service') {
$query = qq|DELETE FROM makemodel
WHERE parts_id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
}
if ($form->{item} eq 'assembly') {
+ # delete inventory
+ $query = qq|DELETE FROM inventory
+ WHERE parts_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
$query = qq|DELETE FROM assembly
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
@@ -566,6 +748,14 @@ sub delete {
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
}
+
+ $query = qq|DELETE FROM partscustomer
+ WHERE parts_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|DELETE FROM translation
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
# commit
my $rc = $dbh->commit;
@@ -581,7 +771,8 @@ sub assembly_item {
my $i = $form->{assembly_rows};
my $var;
- my $where = "1 = 1";
+ my $null;
+ my $where = "p.obsolete = '0'";
if ($form->{"partnumber_$i"}) {
$var = $form->like(lc $form->{"partnumber_$i"});
@@ -592,12 +783,12 @@ sub assembly_item {
$where .= " AND lower(p.description) LIKE '$var'";
}
if ($form->{"partsgroup_$i"}) {
- $var = $form->like(lc $form->{"partsgroup_$i"});
- $where .= " AND lower(pg.partsgroup) LIKE '$var'";
+ ($null, $var) = split /--/, $form->{"partsgroup_$i"};
+ $where .= qq| AND p.partsgroup_id = $var|;
}
-
+
if ($form->{id}) {
- $where .= " AND NOT p.id = $form->{id}";
+ $where .= " AND p.id != $form->{id}";
}
if ($partnumber) {
@@ -610,8 +801,8 @@ sub assembly_item {
my $dbh = $form->dbconnect($myconfig);
my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice,
- p.weight, p.onhand, p.unit,
- pg.partsgroup
+ p.weight, p.onhand, p.unit, p.lastcost,
+ pg.partsgroup, p.partsgroup_id
FROM parts p
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
WHERE $where|;
@@ -632,9 +823,12 @@ sub all_parts {
my ($self, $myconfig, $form) = @_;
my $where = '1 = 1';
+ my $null;
my $var;
+ my $ref;
+ my $item;
- foreach my $item (qw(partnumber drawing microfiche)) {
+ foreach $item (qw(partnumber drawing microfiche)) {
if ($form->{$item}) {
$var = $form->like(lc $form->{$item});
$where .= " AND lower(p.$item) LIKE '$var'";
@@ -642,32 +836,46 @@ sub all_parts {
}
# special case for description
if ($form->{description}) {
- unless ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) {
+ unless ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered} || $form->{rfq} || $form->{quoted}) {
$var = $form->like(lc $form->{description});
$where .= " AND lower(p.description) LIKE '$var'";
}
}
+
+ # assembly components
+ my $assemblyflds;
+ if ($form->{searchitems} eq 'component') {
+ $assemblyflds = qq|, p1.partnumber AS assemblypartnumber, a.id AS assembly_id|;
+ }
+
+ # special case for serialnumber
+ if ($form->{l_serialnumber}) {
+ if ($form->{serialnumber}) {
+ $var = $form->like(lc $form->{serialnumber});
+ $where .= " AND lower(i.serialnumber) LIKE '$var'";
+ }
+ }
+ if ($form->{warehouse} || $form->{l_warehouse}) {
+ $form->{l_warehouse} = 1;
+ }
+
if ($form->{searchitems} eq 'part') {
- $where .= " AND p.inventory_accno_id > 0";
+ $where .= " AND p.inventory_accno_id > 0 AND p.assembly = '0' AND p.income_accno_id > 0";
}
if ($form->{searchitems} eq 'assembly') {
$form->{bought} = "";
$where .= " AND p.assembly = '1'";
}
if ($form->{searchitems} eq 'service') {
- $where .= " AND p.inventory_accno_id IS NULL AND NOT p.assembly = '1'";
- # irrelevant for services
- $form->{make} = $form->{model} = "";
+ $where .= " AND p.inventory_accno_id IS NULL AND p.assembly = '0'";
+ }
+ if ($form->{searchitems} eq 'labor') {
+ $where .= " AND p.inventory_accno_id > 0 AND p.income_accno_id IS NULL";
}
# items which were never bought, sold or on an order
if ($form->{itemstatus} eq 'orphaned') {
- $form->{onhand} = $form->{short} = 0;
- $form->{bought} = $form->{sold} = 0;
- $form->{onorder} = $form->{ordered} = 0;
- $form->{transdatefrom} = $form->{transdateto} = "";
-
$where .= " AND p.onhand = 0
AND p.id NOT IN (SELECT p.id FROM parts p, invoice i
WHERE p.id = i.parts_id)
@@ -682,80 +890,174 @@ sub all_parts {
}
if ($form->{itemstatus} eq 'obsolete') {
$where .= " AND p.obsolete = '1'";
- $form->{onhand} = $form->{short} = 0;
}
if ($form->{itemstatus} eq 'onhand') {
$where .= " AND p.onhand > 0";
}
if ($form->{itemstatus} eq 'short') {
- $where .= " AND p.onhand < 0";
+ $where .= " AND p.onhand < p.rop";
}
- if ($form->{make}) {
- $var = $form->like(lc $form->{make}).":%";
- $where .= " AND p.id IN (SELECT DISTINCT ON (m.parts_id) m.parts_id
- FROM makemodel m WHERE lower(m.name) LIKE '$var')";
- }
- if ($form->{model}) {
- $var = "%:".$form->like($form->{model});
- $where .= " AND p.id IN (SELECT DISTINCT ON (m.parts_id) m.parts_id
- FROM makemodel m WHERE lower(m.name) LIKE '$var')";
+ my $makemodelflds = qq|, '', ''|;;
+ my $makemodeljoin;
+
+ if ($form->{make} || $form->{l_make} || $form->{model} || $form->{l_model}) {
+ $makemodelflds = qq|, m.make, m.model|;
+ $makemodeljoin = qq|LEFT JOIN makemodel m ON (m.parts_id = p.id)|;
+
+ if ($form->{make}) {
+ $var = $form->like(lc $form->{make});
+ $where .= " AND lower(m.make) LIKE '$var'";
+ }
+ if ($form->{model}) {
+ $var = $form->like(lc $form->{model});
+ $where .= " AND lower(m.model) LIKE '$var'";
+ }
}
if ($form->{partsgroup}) {
- $var = $form->like(lc $form->{partsgroup});
- $where .= " AND lower(pg.partsgroup) LIKE '$var'";
-
+ ($null, $var) = split /--/, $form->{partsgroup};
+ $where .= qq| AND p.partsgroup_id = $var|;
}
# connect to database
my $dbh = $form->dbconnect($myconfig);
+ my %ordinal = ( 'partnumber' => 2,
+ 'description' => 3,
+ 'bin' => 6,
+ 'priceupdate' => 12,
+ 'drawing' => 14,
+ 'microfiche' => 15,
+ 'partsgroup' => 17,
+ 'make' => 19,
+ 'model' => 20,
+ 'assemblypartnumber' => 21
+ );
- my $sortorder = join ', ', $form->sort_columns(qw(partnumber description bin priceupdate partsgroup));
- $sortorder = $form->{sort} unless $sortorder;
+ my @a = qw(partnumber description);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ my $query = qq|SELECT curr FROM defaults|;
+ my ($curr) = $dbh->selectrow_array($query);
+ $curr =~ s/:.*//;
+
+ my $flds = qq|p.id, p.partnumber, p.description, p.onhand, p.unit,
+ p.bin, p.sellprice, p.listprice, p.lastcost, p.rop,
+ p.weight, p.priceupdate, p.image, p.drawing, p.microfiche,
+ p.assembly, pg.partsgroup, '$curr' AS curr
+ $makemodelflds $assemblyflds
+ |;
+
+ $query = qq|SELECT $flds
+ FROM parts p
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ $makemodeljoin
+ WHERE $where
+ ORDER BY $sortorder|;
+
+ # redo query for components report
+ if ($form->{searchitems} eq 'component') {
+
+ $query = qq|SELECT $flds
+ FROM assembly a
+ JOIN parts p ON (a.parts_id = p.id)
+ JOIN parts p1 ON (a.id = p1.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ $makemodeljoin
+ WHERE $where
+ ORDER BY $sortorder|;
+
+ }
- my $query = qq|SELECT p.id, p.partnumber, p.description, p.onhand, p.unit,
- p.bin, p.sellprice, p.listprice, p.lastcost, p.rop, p.weight,
- p.priceupdate, p.image, p.drawing, p.microfiche,
- pg.partsgroup
- FROM parts p
- LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
- WHERE $where
- ORDER BY $sortorder|;
# rebuild query for bought and sold items
- if ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) {
+ if ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered} || $form->{rfq} || $form->{quoted}) {
+
+ $form->sort_order();
+ my @a = qw(partnumber description employee);
+
+ push @a, qw(invnumber serialnumber) if ($form->{bought} || $form->{sold});
+ push @a, "ordnumber" if ($form->{onorder} || $form->{ordered});
+ push @a, "quonumber" if ($form->{rfq} || $form->{quoted});
+
+ %ordinal = ( 'partnumber' => 2,
+ 'description' => 3,
+ 'serialnumber' => 4,
+ 'bin' => 7,
+ 'priceupdate' => 13,
+ 'partsgroup' => 18,
+ 'invnumber' => 19,
+ 'ordnumber' => 20,
+ 'quonumber' => 21,
+ 'name' => 23,
+ 'employee' => 24,
+ 'make' => 27,
+ 'model' => 28
+ );
+ $sortorder = $form->sort_order(\@a, \%ordinal);
+
my $union = "";
$query = "";
if ($form->{bought} || $form->{sold}) {
my $invwhere = "$where";
+ my $transdate = ($form->{method} eq 'accrual') ? "transdate" : "datepaid";
+
$invwhere .= " AND i.assemblyitem = '0'";
- $invwhere .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
- $invwhere .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+ $invwhere .= " AND a.$transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $invwhere .= " AND a.$transdate <= '$form->{transdateto}'" if $form->{transdateto};
if ($form->{description}) {
$var = $form->like(lc $form->{description});
$invwhere .= " AND lower(i.description) LIKE '$var'";
}
- my $flds = qq|p.id, p.partnumber, i.description,
+ if ($form->{open} || $form->{closed}) {
+ if ($form->{open} && $form->{closed}) {
+ if ($form->{method} eq 'cash') {
+ $invwhere .= " AND a.amount = a.paid";
+ }
+ } else {
+ if ($form->{open}) {
+ if ($form->{method} eq 'cash') {
+ $invwhere .= " AND a.id = 0";
+ } else {
+ $invwhere .= " AND NOT a.amount = a.paid";
+ }
+ } else {
+ $invwhere .= " AND a.amount = a.paid";
+ }
+ }
+ } else {
+ $invwhere .= " AND a.id = 0";
+ }
+
+ my $flds = qq|p.id, p.partnumber, i.description, i.serialnumber,
i.qty AS onhand, i.unit, p.bin, i.sellprice,
p.listprice, p.lastcost, p.rop, p.weight,
p.priceupdate, p.image, p.drawing, p.microfiche,
- pg.partsgroup,
- a.invnumber, a.ordnumber, i.trans_id|;
+ p.assembly,
+ pg.partsgroup, a.invnumber, a.ordnumber, a.quonumber,
+ i.trans_id, ct.name, e.name AS employee, a.curr, a.till
+ $makemodelfld|;
+
if ($form->{bought}) {
$query = qq|
SELECT $flds, 'ir' AS module, '' AS type,
- 1 AS exchangerate
- FROM parts p
- JOIN invoice i ON (i.parts_id = p.id)
- JOIN ap a ON (i.trans_id = a.id)
- LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ (SELECT sell FROM exchangerate ex
+ WHERE ex.curr = a.curr
+ AND ex.transdate = a.$transdate) AS exchangerate,
+ i.discount
+ FROM invoice i
+ JOIN parts p ON (p.id = i.parts_id)
+ JOIN ap a ON (a.id = i.trans_id)
+ JOIN vendor ct ON (a.vendor_id = ct.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ $makemodeljoin
WHERE $invwhere|;
$union = "
UNION";
@@ -764,11 +1066,17 @@ sub all_parts {
if ($form->{sold}) {
$query .= qq|$union
SELECT $flds, 'is' AS module, '' AS type,
- 1 As exchangerate
- FROM parts p
- JOIN invoice i ON (i.parts_id = p.id)
- JOIN ar a ON (i.trans_id = a.id)
- LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ (SELECT buy FROM exchangerate ex
+ WHERE ex.curr = a.curr
+ AND ex.transdate = a.$transdate) AS exchangerate,
+ i.discount
+ FROM invoice i
+ JOIN parts p ON (p.id = i.parts_id)
+ JOIN ar a ON (a.id = i.trans_id)
+ JOIN customer ct ON (a.customer_id = ct.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ $makemodeljoin
WHERE $invwhere|;
$union = "
UNION";
@@ -776,59 +1084,158 @@ sub all_parts {
}
if ($form->{onorder} || $form->{ordered}) {
- my $ordwhere = "$where";
- $ordwhere .= " AND o.closed = '0'" unless $form->{closed};
-
- $ordwhere .= " AND o.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
- $ordwhere .= " AND o.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+ my $ordwhere = "$where
+ AND a.quotation = '0'";
+ $ordwhere .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $ordwhere .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
if ($form->{description}) {
$var = $form->like(lc $form->{description});
- $ordwhere .= " AND lower(oi.description) LIKE '$var'";
+ $ordwhere .= " AND lower(i.description) LIKE '$var'";
+ }
+
+ if ($form->{open} || $form->{closed}) {
+ unless ($form->{open} && $form->{closed}) {
+ $ordwhere .= " AND a.closed = '0'" if $form->{open};
+ $ordwhere .= " AND a.closed = '1'" if $form->{closed};
+ }
+ } else {
+ $ordwhere .= " AND a.id = 0";
}
- $flds = qq|p.id, p.partnumber, oi.description,
- oi.qty AS onhand, oi.unit, p.bin, oi.sellprice,
+ $flds = qq|p.id, p.partnumber, i.description, '' AS serialnumber,
+ i.qty AS onhand, i.unit, p.bin, i.sellprice,
p.listprice, p.lastcost, p.rop, p.weight,
p.priceupdate, p.image, p.drawing, p.microfiche,
- pg.partsgroup,
- '' AS invnumber, o.ordnumber, oi.trans_id|;
+ p.assembly,
+ pg.partsgroup, '' AS invnumber, a.ordnumber, a.quonumber,
+ i.trans_id, ct.name,e.name AS employee, a.curr, '0' AS till
+ $makemodelfld|;
if ($form->{ordered}) {
$query .= qq|$union
SELECT $flds, 'oe' AS module, 'sales_order' AS type,
(SELECT buy FROM exchangerate ex
- WHERE ex.curr = o.curr
- AND ex.transdate = o.transdate) AS exchangerate
- FROM parts p
- JOIN orderitems oi ON (oi.parts_id = p.id)
- JOIN oe o ON (oi.trans_id = o.id)
- LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ WHERE ex.curr = a.curr
+ AND ex.transdate = a.transdate) AS exchangerate,
+ i.discount
+ FROM orderitems i
+ JOIN parts p ON (i.parts_id = p.id)
+ JOIN oe a ON (i.trans_id = a.id)
+ JOIN customer ct ON (a.customer_id = ct.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ $makemodeljoin
WHERE $ordwhere
- AND o.customer_id > 0|;
+ AND a.customer_id > 0|;
$union = "
UNION";
}
if ($form->{onorder}) {
- $flds = qq|p.id, p.partnumber, oi.description,
- oi.qty * -1 AS onhand, oi.unit, p.bin, oi.sellprice,
+ $flds = qq|p.id, p.partnumber, i.description, '' AS serialnumber,
+ i.qty AS onhand, i.unit, p.bin, i.sellprice,
p.listprice, p.lastcost, p.rop, p.weight,
p.priceupdate, p.image, p.drawing, p.microfiche,
- pg.partsgroup,
- '' AS invnumber, o.ordnumber, oi.trans_id|;
+ p.assembly,
+ pg.partsgroup, '' AS invnumber, a.ordnumber, a.quonumber,
+ i.trans_id, ct.name,e.name AS employee, a.curr, '0' AS till
+ $makemodelfld|;
$query .= qq|$union
SELECT $flds, 'oe' AS module, 'purchase_order' AS type,
(SELECT sell FROM exchangerate ex
- WHERE ex.curr = o.curr
- AND ex.transdate = o.transdate) AS exchangerate
- FROM parts p
- JOIN orderitems oi ON (oi.parts_id = p.id)
- JOIN oe o ON (oi.trans_id = o.id)
- LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ WHERE ex.curr = a.curr
+ AND ex.transdate = a.transdate) AS exchangerate,
+ i.discount
+ FROM orderitems i
+ JOIN parts p ON (i.parts_id = p.id)
+ JOIN oe a ON (i.trans_id = a.id)
+ JOIN vendor ct ON (a.vendor_id = ct.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ $makemodeljoin
WHERE $ordwhere
- AND o.vendor_id > 0|;
+ AND a.vendor_id > 0|;
+ }
+
+ }
+
+ if ($form->{rfq} || $form->{quoted}) {
+ my $quowhere = "$where
+ AND a.quotation = '1'";
+ $quowhere .= " AND a.transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
+ $quowhere .= " AND a.transdate <= '$form->{transdateto}'" if $form->{transdateto};
+
+ if ($form->{description}) {
+ $var = $form->like(lc $form->{description});
+ $quowhere .= " AND lower(i.description) LIKE '$var'";
+ }
+
+ if ($form->{open} || $form->{closed}) {
+ unless ($form->{open} && $form->{closed}) {
+ $ordwhere .= " AND a.closed = '0'" if $form->{open};
+ $ordwhere .= " AND a.closed = '1'" if $form->{closed};
+ }
+ } else {
+ $ordwhere .= " AND a.id = 0";
+ }
+
+
+ $flds = qq|p.id, p.partnumber, i.description, '' AS serialnumber,
+ i.qty AS onhand, i.unit, p.bin, i.sellprice,
+ p.listprice, p.lastcost, p.rop, p.weight,
+ p.priceupdate, p.image, p.drawing, p.microfiche,
+ p.assembly,
+ pg.partsgroup, '' AS invnumber, a.ordnumber, a.quonumber,
+ i.trans_id, ct.name, e.name AS employee, a.curr, '0' AS till
+ $makemodelfld|;
+
+ if ($form->{quoted}) {
+ $query .= qq|$union
+ SELECT $flds, 'oe' AS module, 'sales_quotation' AS type,
+ (SELECT buy FROM exchangerate ex
+ WHERE ex.curr = a.curr
+ AND ex.transdate = a.transdate) AS exchangerate,
+ i.discount
+ FROM orderitems i
+ JOIN parts p ON (i.parts_id = p.id)
+ JOIN oe a ON (i.trans_id = a.id)
+ JOIN customer ct ON (a.customer_id = ct.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ $makemodeljoin
+ WHERE $quowhere
+ AND a.customer_id > 0|;
+ $union = "
+ UNION";
+ }
+
+ if ($form->{rfq}) {
+ $flds = qq|p.id, p.partnumber, i.description, '' AS serialnumber,
+ i.qty AS onhand, i.unit, p.bin, i.sellprice,
+ p.listprice, p.lastcost, p.rop, p.weight,
+ p.priceupdate, p.image, p.drawing, p.microfiche,
+ p.assembly,
+ pg.partsgroup, '' AS invnumber, a.ordnumber, a.quonumber,
+ i.trans_id, ct.name, e.name AS employee, a.curr, '0' AS till
+ $makemodelfld|;
+
+ $query .= qq|$union
+ SELECT $flds, 'oe' AS module, 'request_quotation' AS type,
+ (SELECT sell FROM exchangerate ex
+ WHERE ex.curr = a.curr
+ AND ex.transdate = a.transdate) AS exchangerate,
+ i.discount
+ FROM orderitems i
+ JOIN parts p ON (i.parts_id = p.id)
+ JOIN oe a ON (i.trans_id = a.id)
+ JOIN vendor ct ON (a.vendor_id = ct.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ $makemodeljoin
+ WHERE $quowhere
+ AND a.vendor_id > 0|;
}
}
@@ -838,45 +1245,99 @@ sub all_parts {
}
+
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
push @{ $form->{parts} }, $ref;
}
-
$sth->finish;
-
- # include individual items for assemblies
+ my @a = ();
+
+ # include individual items for assembly
if ($form->{searchitems} eq 'assembly' && $form->{bom}) {
+
+ if ($form->{sold} || $form->{ordered} || $form->{quoted}) {
+ $flds = qq|p.id, p.partnumber, p.description, a.qty AS onhand, p.unit,
+ p.bin, p.sellprice, p.listprice, p.lastcost, p.rop,
+ p.weight, p.priceupdate, p.image, p.drawing, p.microfiche,
+ p.assembly, pg.partsgroup
+ $makemodelflds $assemblyflds
+ |;
+ } else {
+ # replace p.onhand with a.qty AS onhand
+ $flds =~ s/p.onhand/a.qty AS onhand/;
+ }
+
+ while ($item = shift @{ $form->{parts} }) {
+ push @a, $item;
+ $flds =~ s/a\.qty.*AS onhand/a\.qty * $item->{onhand} AS onhand/;
+ push @a, &include_assembly($dbh, $form, $item->{id}, $flds, $makemodeljoin);
+ push @a, {id => $item->{id}};
+ }
+
+ # copy assemblies to $form->{parts}
+ @{ $form->{parts} } = @a;
+
+ }
+
+
+ @a = ();
+ if ($form->{l_warehouse} || $form->{l_warehouse}) {
+
+ if ($form->{warehouse}) {
+ ($null, $var) = split /--/, $form->{warehouse};
+ $var *= 1;
+ $query = qq|SELECT SUM(qty) AS onhand, '$null' AS description
+ FROM inventory
+ WHERE warehouse_id = $var
+ AND parts_id = ?|;
+ } else {
+
+ $query = qq|SELECT SUM(i.qty) AS onhand, w.description AS warehouse
+ FROM inventory i
+ JOIN warehouse w ON (w.id = i.warehouse_id)
+ WHERE i.parts_id = ?
+ GROUP BY w.description|;
+ }
+
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+
foreach $item (@{ $form->{parts} }) {
- push @assemblies, $item;
- $query = qq|SELECT p.id, p.partnumber, p.description, a.qty AS onhand,
- p.unit, p.bin,
- p.sellprice, p.listprice, p.lastcost,
- p.rop, p.weight, p.priceupdate,
- p.image, p.drawing, p.microfiche
- FROM parts p
- JOIN assembly a ON (p.id = a.parts_id)
- WHERE a.id = $item->{id}|;
-
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- $ref->{assemblyitem} = 1;
- push @assemblies, $ref;
+ if ($item->{onhand} <= 0 && ! $form->{warehouse}) {
+ push @a, $item;
+ next;
}
- $sth->finish;
- push @assemblies, {id => $item->{id}};
+ $sth->execute($item->{id}) || $form->dberror($query);
+
+ if ($form->{warehouse}) {
+
+ $ref = $sth->fetchrow_hashref(NAME_lc);
+ if ($ref->{onhand} > 0) {
+ $item->{onhand} = $ref->{onhand};
+ push @a, $item;
+ }
+ } else {
+
+ push @a, $item;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ if ($ref->{onhand} > 0) {
+ push @a, $ref;
+ }
+ }
+ }
+
+ $sth->finish;
}
- # copy assemblies to $form->{parts}
- @{ $form->{parts} } = @assemblies;
-
+ @{ $form->{parts} } = @a;
+
}
$dbh->disconnect;
@@ -884,11 +1345,54 @@ sub all_parts {
}
+sub include_assembly {
+ my ($dbh, $form, $id, $flds, $makemodeljoin) = @_;
+
+ $form->{stagger}++;
+ if ($form->{stagger} > $form->{pncol}) {
+ $form->{pncol} = $form->{stagger};
+ }
+
+ $form->{$id} = 1;
+
+ my @a = ();
+ my $query = qq|SELECT $flds
+ FROM parts p
+ JOIN assembly a ON (a.parts_id = p.id)
+ LEFT JOIN partsgroup pg ON (pg.id = p.id)
+ $makemodeljoin
+ WHERE a.id = $id|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $ref->{assemblyitem} = 1;
+ $ref->{stagger} = $form->{stagger};
+ push @a, $ref;
+ if ($ref->{assembly} && !$form->{$ref->{id}}) {
+ push @a, &include_assembly($dbh, $form, $ref->{id}, $flds, $makemodeljoin);
+ if ($form->{stagger} > $form->{pncol}) {
+ $form->{pncol} = $form->{stagger};
+ }
+ }
+ }
+ $sth->finish;
+
+ $form->{$id} = 0;
+ $form->{stagger}--;
+
+ @a;
+
+}
+
+
sub create_links {
my ($self, $module, $myconfig, $form) = @_;
# connect to database
my $dbh = $form->dbconnect($myconfig);
+
+ my $ref;
my $query = qq|SELECT accno, description, link
FROM chart
@@ -897,33 +1401,86 @@ sub create_links {
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- foreach my $key (split(/:/, $ref->{link})) {
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ foreach my $key (split /:/, $ref->{link}) {
if ($key =~ /$module/) {
push @{ $form->{"${module}_links"}{$key} }, { accno => $ref->{accno},
description => $ref->{description} };
}
}
}
+ $sth->finish;
+
+ if ($form->{item} ne 'assembly') {
+ $query = qq|SELECT count(*) FROM vendor|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+ my ($count) = $sth->fetchrow_array;
+ $sth->finish;
+
+ if ($count < $myconfig->{vclimit}) {
+ $query = qq|SELECT id, name
+ FROM vendor
+ ORDER BY name|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_vendor} }, $ref;
+ }
+ $sth->finish;
+ }
+ }
+
+ # pricegroups, customers
+ $query = qq|SELECT count(*) FROM customer|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+ my ($count) = $sth->fetchrow_array;
$sth->finish;
+ if ($count < $myconfig->{vclimit}) {
+ $query = qq|SELECT id, name
+ FROM customer
+ ORDER BY name|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_customer} }, $ref;
+ }
+ $sth->finish;
+ }
+
+ $query = qq|SELECT id, pricegroup
+ FROM pricegroup
+ ORDER BY pricegroup|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_pricegroup} }, $ref;
+ }
+ $sth->finish;
+
+
if ($form->{id}) {
- $query = qq|SELECT weightunit
+ $query = qq|SELECT weightunit, curr AS currencies
FROM defaults|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- ($form->{weightunit}) = $sth->fetchrow_array;
+ ($form->{weightunit}, $form->{currencies}) = $sth->fetchrow_array;
$sth->finish;
} else {
- $query = qq|SELECT weightunit, current_date
+ $query = qq|SELECT weightunit, current_date, curr AS currencies
FROM defaults|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- ($form->{weightunit}, $form->{priceupdate}) = $sth->fetchrow_array;
+ ($form->{weightunit}, $form->{priceupdate}, $form->{currencies}) = $sth->fetchrow_array;
$sth->finish;
}
@@ -932,5 +1489,25 @@ sub create_links {
}
+sub get_warehouses {
+ my ($self, $myconfig, $form) = @_;
+
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT id, description
+ FROM warehouse|;
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_warehouses} }, $ref;
+ }
+ $sth->finish;
+
+ $dbh->disconnect;
+
+}
+
1;
diff --git a/sql-ledger/SL/IR.pm b/sql-ledger/SL/IR.pm
index 357533e17..79a619be8 100644
--- a/sql-ledger/SL/IR.pm
+++ b/sql-ledger/SL/IR.pm
@@ -1,12 +1,12 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
-# Contributors:
+# Contributors: Jim Rawlings <jim@your-dba.com>
#
# 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
@@ -35,8 +35,16 @@ sub post_invoice {
# connect to database, turn off autocommit
my $dbh = $form->dbconnect_noauto($myconfig);
- my ($query, $sth, $null, $project_id);
+ my $query;
+ my $sth;
+ my $null;
+ my $project_id;
my $exchangerate = 0;
+ my $allocated;
+ my $taxrate;
+ my $taxamount;
+ my $taxdiff;
+ my $item;
if ($form->{id}) {
@@ -58,10 +66,9 @@ sub post_invoice {
($form->{id}) = $sth->fetchrow_array;
$sth->finish;
+
}
- map { $form->{$_} =~ s/'/''/g } qw(invnumber ordnumber);
-
my ($amount, $linetotal, $lastinventoryaccno, $lastexpenseaccno);
my ($netamount, $invoicediff, $expensediff) = (0, 0, 0);
@@ -78,21 +85,33 @@ sub post_invoice {
$form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
if ($form->{"qty_$i"} != 0) {
+
+ # project
+ $project_id = 'NULL';
+ if ($form->{"projectnumber_$i"}) {
+ ($null, $project_id) = split /--/, $form->{"projectnumber_$i"};
+ }
+
+ # undo discount formatting
+ $form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
- map { $form->{"${_}_$i"} =~ s/'/''/g } qw(partnumber description unit);
-
- my ($allocated, $taxrate) = (0, 0);
- my $taxamount;
+ @taxaccounts = split / /, $form->{"taxaccounts_$i"};
+ $taxdiff = 0;
+ $allocated = 0;
+ $taxrate = 0;
- $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
- my $fxsellprice = $form->{"sellprice_$i"};
-
+ # keep entered selling price
+ my $fxsellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+
my ($dec) = ($fxsellprice =~ /\.(\d+)/);
$dec = length $dec;
my $decimalplaces = ($dec > 2) ? $dec : 2;
+ # deduct discount
+ my $discount = $form->round_amount($fxsellprice * $form->{"discount_$i"}, $decimalplaces);
+ $form->{"sellprice_$i"} = $fxsellprice - $discount;
- map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
+ map { $taxrate += $form->{"${_}_rate"} } @taxaccounts;
if ($form->{"inventory_accno_$i"}) {
@@ -106,10 +125,22 @@ sub post_invoice {
}
$netamount += $linetotal;
-
- if ($taxamount != 0) {
- map { $form->{amount}{$form->{id}}{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } split / /, $form->{"taxaccounts_$i"};
+
+ if (@taxaccounts && $form->round_amount($taxamount, 2) == 0) {
+ if ($form->{taxincluded}) {
+ foreach $item (@taxaccounts) {
+ $taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
+ $taxdiff += $taxamount;
+ $form->{amount}{$form->{id}}{$item} -= $taxamount;
+ }
+ $form->{amount}{$form->{id}}{$taxaccounts[0]} += $taxdiff;
+ } else {
+ map { $form->{amount}{$form->{id}}{$_} -= $linetotal * $form->{"${_}_rate"} } @taxaccounts;
+ }
+ } else {
+ map { $form->{amount}{$form->{id}}{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } @taxaccounts;
}
+
# add purchase to inventory, this one is without the tax!
$amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * $form->{exchangerate};
@@ -126,11 +157,11 @@ sub post_invoice {
# update parts table
- $query = qq|UPDATE parts SET
- lastcost = $form->{"sellprice_$i"},
- onhand = onhand + $form->{"qty_$i"}
- WHERE id = $form->{"id_$i"}|;
- $dbh->do($query) || $form->dberror($query);
+ $form->update_balance($dbh,
+ "parts",
+ "onhand",
+ qq|id = $form->{"id_$i"}|,
+ $form->{"qty_$i"}) unless $form->{shipped};
# check if we sold the item already and
@@ -159,7 +190,7 @@ sub post_invoice {
$linetotal = $form->round_amount($form->{"sellprice_$i"} * $qty, 2);
-
+
if ($ref->{allocated} < 0) {
# we have an entry for it already, adjust amount
$form->update_balance($dbh,
@@ -222,9 +253,22 @@ sub post_invoice {
$netamount += $linetotal;
- if ($taxamount != 0) {
- map { $form->{amount}{$form->{id}}{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } split / /, $form->{"taxaccounts_$i"};
+ if (@taxaccounts && $form->round_amount($taxamount, 2) == 0) {
+ if ($form->{taxincluded}) {
+ foreach $item (@taxaccounts) {
+ $taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
+ $totaltax += $taxamount;
+ $taxdiff += $taxamount;
+ $form->{amount}{$form->{id}}{$item} -= $taxamount;
+ }
+ $form->{amount}{$form->{id}}{$taxaccounts[0]} += $taxdiff;
+ } else {
+ map { $form->{amount}{$form->{id}}{$_} -= $linetotal * $form->{"${_}_rate"} } @taxaccounts;
+ }
+ } else {
+ map { $form->{amount}{$form->{id}}{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } @taxaccounts;
}
+
$amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * $form->{exchangerate};
$linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2) * $form->{exchangerate};
@@ -241,38 +285,32 @@ sub post_invoice {
# adjust and round sellprice
$form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces);
- # update lastcost
- $query = qq|UPDATE parts SET
- lastcost = $form->{"sellprice_$i"}
- WHERE id = $form->{"id_$i"}|;
- $dbh->do($query) || $form->dberror($query);
-
}
- $project_id = 'NULL';
- if ($form->{"project_id_$i"}) {
- $project_id = $form->{"project_id_$i"};
- }
- $deliverydate = ($form->{"deliverydate_$i"}) ? qq|'$form->{"deliverydate_$i"}'| : "NULL";
-
+
# save detail record in invoice table
$query = qq|INSERT INTO invoice (trans_id, parts_id, description, qty,
- sellprice, fxsellprice, allocated, unit, deliverydate)
- VALUES ($form->{id}, $form->{"id_$i"},
- '$form->{"description_$i"}', |. ($form->{"qty_$i"} * -1) .qq|,
- $form->{"sellprice_$i"}, $fxsellprice, $allocated,
- '$form->{"unit_$i"}', $deliverydate)|;
+ sellprice, fxsellprice, discount, allocated,
+ unit, deliverydate, project_id, serialnumber)
+ VALUES ($form->{id}, $form->{"id_$i"}, |
+ .$dbh->quote($form->{"description_$i"}).qq|, |
+ .($form->{"qty_$i"} * -1) .qq|,
+ $form->{"sellprice_$i"}, $fxsellprice,
+ $form->{"discount_$i"}, $allocated, |
+ .$dbh->quote($form->{"unit_$i"}).qq|, |
+ .$form->dbquote($form->{"deliverydate_$i"}, SQL_DATE).qq|,
+ $project_id, |
+ .$dbh->quote($form->{"serialnumber_$i"}).qq|)|;
$dbh->do($query) || $form->dberror($query);
}
}
- $form->{datepaid} = $form->{invdate};
+ $form->{datepaid} = $form->{transdate};
# all amounts are in natural state, netamount includes the taxes
# if tax is included, netamount is rounded to 2 decimal places,
- # taxes are not
# total payments
for my $i (1 .. $form->{paidaccounts}) {
@@ -292,7 +330,7 @@ sub post_invoice {
$paiddiff = $amount - $netamount * $form->{exchangerate};
$netamount = $amount;
- foreach my $item (split / /, $form->{taxaccounts}) {
+ foreach $item (split / /, $form->{taxaccounts}) {
$amount = $form->{amount}{$form->{id}}{$item} * $form->{exchangerate};
$form->{amount}{$form->{id}}{$item} = $form->round_amount($amount, 2);
$amount = $form->{amount}{$form->{id}}{$item} * -1;
@@ -302,7 +340,7 @@ sub post_invoice {
$invoicediff += $paiddiff;
$expensediff += $paiddiff;
-
+
######## this only applies to tax included
if ($lastinventoryaccno) {
$form->{amount}{$form->{id}}{$lastinventoryaccno} -= $invoicediff;
@@ -335,7 +373,7 @@ sub post_invoice {
# update exchangerate
if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
- $form->update_exchangerate($dbh, $form->{currency}, $form->{invdate}, 0, $form->{exchangerate});
+ $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, 0, $form->{exchangerate});
}
# record acc_trans transactions
@@ -345,8 +383,9 @@ sub post_invoice {
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
transdate)
VALUES ($trans_id, (SELECT id FROM chart
- WHERE accno = '$accno'),
- $form->{amount}{$trans_id}{$accno}, '$form->{invdate}')|;
+ WHERE accno = '$accno'),
+ $form->{amount}{$trans_id}{$accno},
+ '$form->{transdate}')|;
$dbh->do($query) || $form->dberror($query);
}
}
@@ -368,7 +407,7 @@ sub post_invoice {
if ($form->{"paid_$i"} != 0) {
my ($accno) = split /--/, $form->{"AP_paid_$i"};
- $form->{"datepaid_$i"} = $form->{invdate} unless ($form->{"datepaid_$i"});
+ $form->{"datepaid_$i"} = $form->{transdate} unless ($form->{"datepaid_$i"});
$form->{datepaid} = $form->{"datepaid_$i"};
$amount = ($form->round_amount($form->{"paid_$i"} * $form->{exchangerate} + $paiddiff, 2)) * -1;
@@ -387,11 +426,12 @@ sub post_invoice {
# record payment
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
- source)
+ source, memo)
VALUES ($form->{id}, (SELECT id FROM chart
WHERE accno = '$accno'),
- $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
- '$form->{"source_$i"}')|;
+ $form->{"paid_$i"}, '$form->{"datepaid_$i"}', |
+ .$dbh->quote($form->{"source_$i"}).qq|, |
+ .$dbh->quote($form->{"memo_$i"}).qq|)|;
$dbh->do($query) || $form->dberror($query);
@@ -411,7 +451,7 @@ sub post_invoice {
# gain/loss
- $amount = ($form->{"paid_$i"} * $form->{exchangerate}) - ($form->{"paid_$i"} * $form->{"exchangerate_$i"});
+ $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate},2) - $form->round_amount($form->{"paid_$i"} * $form->{"exchangerate_$i"},2);
if ($amount > 0) {
$form->{fx}{$form->{fxgain_accno}}{$form->{"datepaid_$i"}} += $amount;
} else {
@@ -447,24 +487,29 @@ sub post_invoice {
# set values which could be empty
$form->{taxincluded} *= 1;
- my $datepaid = ($form->{paid}) ? qq|'$form->{datepaid}'| : "NULL";
- my $duedate = ($form->{duedate}) ? qq|'$form->{duedate}'| : "NULL";
+ ($null, $form->{department_id}) = split(/--/, $form->{department});
+ $form->{department_id} *= 1;
+
# save AP record
$query = qq|UPDATE ap set
- invnumber = '$form->{invnumber}',
- ordnumber = '$form->{ordnumber}',
- transdate = '$form->{invdate}',
+ invnumber = |.$dbh->quote($form->{invnumber}).qq|,
+ ordnumber = |.$dbh->quote($form->{ordnumber}).qq|,
+ quonumber = |.$dbh->quote($form->{quonumber}).qq|,
+ transdate = '$form->{transdate}',
vendor_id = $form->{vendor_id},
amount = $amount,
netamount = $netamount,
paid = $form->{paid},
- datepaid = $datepaid,
- duedate = $duedate,
+ datepaid = |.$form->dbquote($form->{datepaid}, SQL_DATE).qq|,
+ duedate = |.$form->dbquote($form->{duedate}, SQL_DATE).qq|,
invoice = '1',
taxincluded = '$form->{taxincluded}',
- notes = '$form->{notes}',
- curr = '$form->{currency}'
+ notes = |.$dbh->quote($form->{notes}).qq|,
+ intnotes = |.$dbh->quote($form->{intnotes}).qq|,
+ curr = '$form->{currency}',
+ department_id = $form->{department_id},
+ language_code = '$form->{language_code}'
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
@@ -473,10 +518,13 @@ sub post_invoice {
$form->{name} =~ s/--$form->{vendor_id}//;
$form->add_shipto($dbh, $form->{id});
- # delete zero entries
- $query = qq|DELETE FROM acc_trans
- WHERE amount = 0|;
- $dbh->do($query) || $form->dberror($query);
+ my %audittrail = ( tablename => 'ap',
+ reference => $form->{invnumber},
+ formname => $form->{type},
+ action => 'posted',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -526,12 +574,13 @@ sub reverse_invoice {
while (my $pthref = $sth->fetchrow_hashref(NAME_lc)) {
my $qty = $ref->{allocated};
+
if (($ref->{allocated} + $pthref->{allocated}) > 0) {
$qty = $pthref->{allocated} * -1;
}
my $amount = $form->round_amount($ref->{sellprice} * $qty, 2);
-
+
#adjust allocated
$form->update_balance($dbh,
"invoice",
@@ -551,6 +600,11 @@ sub reverse_invoice {
qq|trans_id = $pthref->{trans_id} AND chart_id = $ref->{inventory_accno_id} AND transdate = '$pthref->{transdate}'|,
$amount * -1);
+ $query = qq|DELETE FROM acc_trans
+ WHERE trans_id = $pthref->{trans_id}
+ AND amount = 0|;
+ $dbh->do($query) || $form->dberror($query);
+
last if (($ref->{allocated} -= $qty) <= 0);
}
$sth->finish;
@@ -582,17 +636,17 @@ sub delete_invoice {
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
-
- # check for other foreign currency transactions
- $form->delete_exchangerate($dbh) if ($form->{currency} ne $form->{defaultcurrency});
+
+ my %audittrail = ( tablename => 'ap',
+ reference => $form->{invnumber},
+ formname => $form->{type},
+ action => 'deleted',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
&reverse_invoice($dbh, $form);
- # delete zero entries
- my $query = qq|DELETE FROM acc_trans
- WHERE amount = 0|;
- $dbh->do($query) || $form->dberror($query);
-
# delete AP record
my $query = qq|DELETE FROM ap
WHERE id = $form->{id}|;
@@ -640,8 +694,8 @@ sub retrieve_invoice {
WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
(SELECT c.accno FROM chart c
WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
- d.ponumber AS invnumber, d.curr AS currencies,
- current_date AS invdate
+ d.curr AS currencies,
+ current_date AS transdate
FROM defaults d|;
}
my $sth = $dbh->prepare($query);
@@ -655,8 +709,9 @@ sub retrieve_invoice {
if ($form->{id}) {
# retrieve invoice
- $query = qq|SELECT a.invnumber, a.transdate AS invdate, a.duedate,
- a.ordnumber, a.paid, a.taxincluded, a.notes, a.curr AS currency
+ $query = qq|SELECT a.invnumber, a.transdate, a.duedate,
+ a.ordnumber, a.quonumber, a.paid, a.taxincluded, a.notes,
+ a.intnotes, a.curr AS currency, a.vendor_id, a.language_code
FROM ap a
WHERE id = $form->{id}|;
$sth = $dbh->prepare($query);
@@ -666,8 +721,6 @@ sub retrieve_invoice {
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
- $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, "sell");
-
# get shipto
$query = qq|SELECT * FROM shipto
WHERE trans_id = $form->{id}|;
@@ -682,11 +735,12 @@ sub retrieve_invoice {
$query = qq|SELECT c1.accno AS inventory_accno,
c2.accno AS income_accno,
c3.accno AS expense_accno,
- p.partnumber, i.description, i.qty, i.fxsellprice AS sellprice,
+ p.partnumber, i.description, i.qty, i.fxsellprice, i.sellprice,
i.parts_id AS id, i.unit, p.bin, i.deliverydate,
pr.projectnumber,
- i.project_id,
- pg.partsgroup
+ i.project_id, i.serialnumber, i.discount,
+ pg.partsgroup, p.partsgroup_id, p.partnumber AS sku,
+ t.description AS partsgrouptranslation
FROM invoice i
JOIN parts p ON (i.parts_id = p.id)
LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
@@ -694,33 +748,58 @@ sub retrieve_invoice {
LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
LEFT JOIN project pr ON (i.project_id = pr.id)
LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
- WHERE trans_id = $form->{id}
+ LEFT JOIN translation t ON (t.trans_id = p.partsgroup_id AND t.language_code = '$form->{language_code}')
+ WHERE i.trans_id = $form->{id}
ORDER BY i.id|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
+ # exchangerate defaults
+ &exchangerate_defaults($dbh, $form);
+
+ # price matrix and vendor partnumber
+ $query = qq|SELECT partnumber
+ FROM partsvendor
+ WHERE parts_id = ?
+ AND vendor_id = $form->{vendor_id}|;
+ my $pmh = $dbh->prepare($query) || $form->dberror($query);
+
+ # tax rates for part
+ $query = qq|SELECT c.accno
+ FROM chart c
+ JOIN partstax pt ON (pt.chart_id = c.id)
+ WHERE pt.parts_id = ?|;
+ my $tth = $dbh->prepare($query);
+
+ my $ptref;
+ my $taxrate;
+
while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
- # get tax rates for part
- $query = qq|SELECT c.accno
- FROM chart c, partstax pt
- WHERE pt.chart_id = c.id
- AND pt.parts_id = $ref->{id}|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
+ ($decimalplaces) = ($ref->{fxsellprice} =~ /\.(\d+)/);
+ $decimalplaces = length $decimalplaces;
+ $decimalplaces = 2 unless $decimalplaces;
+ $tth->execute($ref->{id});
$ref->{taxaccounts} = "";
- my $taxrate = 0;
+ $taxrate = 0;
- while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ptref = $tth->fetchrow_hashref(NAME_lc)) {
$ref->{taxaccounts} .= "$ptref->{accno} ";
$taxrate += $form->{"$ptref->{accno}_rate"};
}
- $sth->finish;
+ $tth->finish;
chop $ref->{taxaccounts};
+ # price matrix
+ $ref->{sellprice} = $form->round_amount($ref->{fxsellprice} * $form->{$form->{currency}}, 2);
+ &price_matrix($pmh, $ref, $decimalplaces, $form);
+
+ $ref->{sellprice} = $ref->{fxsellprice};
$ref->{qty} *= -1;
+
+ $ref->{partsgroup} = $ref->{partsgrouptranslation} if $ref->{partsgrouptranslation};
push @{ $form->{invoice_details} }, $ref;
@@ -728,16 +807,6 @@ sub retrieve_invoice {
$sth->finish;
- } else {
-
- # up invoice number by 1
- $form->{invnumber}++;
-
- # save the new number
- $query = qq|UPDATE defaults
- SET ponumber = '$form->{invnumber}'|;
- $dbh->do($query) || $form->dberror($query);
-
}
@@ -757,27 +826,90 @@ sub get_vendor {
my $dbh = $form->dbconnect($myconfig);
my $dateformat = $myconfig->{dateformat};
- $dateformat .= "yy" if $myconfig->{dateformat} !~ /^y/;
+ if ($myconfig->{dateformat} !~ /^y/) {
+ my @a = split /\W/, $form->{transdate};
+ $dateformat .= "yy" if (length $a[2] > 2);
+ }
- my $duedate = ($form->{invdate}) ? "to_date('$form->{invdate}', '$dateformat')" : "current_date";
+ if ($form->{transdate} !~ /\W/) {
+ $dateformat = 'yyyymmdd';
+ }
+
+ my $duedate;
+
+ if ($myconfig->{dbdriver} eq 'DB2') {
+ $duedate = ($form->{transdate}) ? "date('$form->{transdate}') + v.terms DAYS" : "current_date + v.terms DAYS";
+ } else {
+ $duedate = ($form->{transdate}) ? "to_date('$form->{transdate}', '$dateformat') + v.terms" : "current_date + v.terms";
+ }
$form->{vendor_id} *= 1;
# get vendor
- my $query = qq|SELECT taxincluded, terms, email, cc, bcc,
- addr1, addr2, addr3, addr4,
- $duedate + terms AS duedate
- FROM vendor
- WHERE id = $form->{vendor_id}|;
+ my $query = qq|SELECT v.name AS vendor, v.creditlimit, v.terms,
+ v.email, v.cc, v.bcc, v.taxincluded,
+ v.address1, v.address2, v.city, v.state,
+ v.zipcode, v.country, v.curr AS currency, v.language_code,
+ $duedate AS duedate, v.notes AS intnotes,
+ e.name AS employee, e.id AS employee_id
+ FROM vendor v
+ LEFT JOIN employee e ON (e.id = v.employee_id)
+ WHERE v.id = $form->{vendor_id}|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
$ref = $sth->fetchrow_hashref(NAME_lc);
+
+ if ($form->{id}) {
+ map { delete $ref->{$_} } qw(currency taxincluded employee employee_id intnotes);
+ }
+
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
+
+ # if no currency use defaultcurrency
+ $form->{currency} = ($form->{currency}) ? $form->{currency} : $form->{defaultcurrency};
+
+ $form->{exchangerate} = 0 if $form->{currency} eq $form->{defaultcurrency};
+ if ($form->{transdate} && ($form->{currency} ne $form->{defaultcurrency})) {
+ $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{transdate}, "sell");
+ }
+ $form->{forex} = $form->{exchangerate};
+
+ # if no employee, default to login
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh) unless $form->{employee_id};
+
+ $form->{creditremaining} = $form->{creditlimit};
+ $query = qq|SELECT SUM(amount - paid)
+ FROM ap
+ WHERE vendor_id = $form->{vendor_id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ ($form->{creditremaining}) -= $sth->fetchrow_array;
+
+ $sth->finish;
+ $query = qq|SELECT o.amount,
+ (SELECT e.sell FROM exchangerate e
+ WHERE e.curr = o.curr
+ AND e.transdate = o.transdate)
+ FROM oe o
+ WHERE o.vendor_id = $form->{vendor_id}
+ AND o.quotation = '0'
+ AND o.closed = '0'|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my ($amount, $exch) = $sth->fetchrow_array) {
+ $exch = 1 unless $exch;
+ $form->{creditremaining} -= $amount * $exch;
+ }
+ $sth->finish;
+
+
# get shipto if we do not convert an order or invoice
if (!$form->{shipto}) {
- map { delete $form->{$_} } qw(shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shiptocontact shiptophone shiptofax shiptoemail);
+ map { delete $form->{$_} } qw(shiptoname shiptoaddress1 shiptoaddress2 shiptocity shiptostate shiptozipcode shiptocountry shiptocontact shiptophone shiptofax shiptoemail);
$query = qq|SELECT * FROM shipto
WHERE trans_id = $form->{vendor_id}|;
@@ -791,9 +923,9 @@ sub get_vendor {
# get taxes for vendor
$query = qq|SELECT c.accno
- FROM chart c, vendortax v
- WHERE v.chart_id = c.id
- AND v.vendor_id = $form->{vendor_id}|;
+ FROM chart c
+ JOIN vendortax v ON (v.chart_id = c.id)
+ WHERE v.vendor_id = $form->{vendor_id}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -805,10 +937,10 @@ sub get_vendor {
# get tax rates and description
- $query = qq|SELECT c.accno, c.description, c.link, t.rate
- FROM chart c, tax t
- WHERE c.id = t.chart_id
- AND c.link LIKE '%CT_tax%'
+ $query = qq|SELECT c.accno, c.description, c.link, t.rate, t.taxnumber
+ FROM chart c
+ JOIN tax t ON (c.id = t.chart_id)
+ WHERE c.link LIKE '%CT_tax%'
ORDER BY accno|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -820,6 +952,7 @@ sub get_vendor {
if ($vendortax{$ref->{accno}}) {
$form->{"$ref->{accno}_rate"} = $ref->{rate};
$form->{"$ref->{accno}_description"} = $ref->{description};
+ $form->{"$ref->{accno}_taxnumber"} = $ref->{taxnumber};
$form->{taxaccounts} .= "$ref->{accno} ";
}
@@ -838,24 +971,32 @@ sub get_vendor {
chop $form->{taxpart};
chop $form->{taxservice};
- if (!$form->{id} && $form->{type} !~ /_order/) {
+
+ if (!$form->{id} && $form->{type} !~ /_(order|quotation)/) {
# setup last accounts used
- $query = qq|SELECT c.accno, c.description, c.link, c.category
- FROM chart c
+ $query = qq|SELECT c.accno, c.description, c.link, c.category,
+ ac.project_id, p.projectnumber, a.department_id,
+ d.description AS department
+ FROM chart c
JOIN acc_trans ac ON (ac.chart_id = c.id)
JOIN ap a ON (a.id = ac.trans_id)
+ LEFT JOIN project p ON (ac.project_id = p.id)
+ LEFT JOIN department d ON (a.department_id = d.id)
WHERE a.vendor_id = $form->{vendor_id}
- AND NOT (c.link LIKE '%_tax%' OR c.link LIKE '%_paid%')
AND a.id IN (SELECT max(id) FROM ap
- WHERE vendor_id = $form->{vendor_id})|;
+ WHERE vendor_id = $form->{vendor_id})|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
-
+
my $i = 0;
while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
- if ($ref->{category} eq 'E') {
+ $form->{department} = $ref->{department};
+ $form->{department_id} = $ref->{department_id};
+
+ if ($ref->{link} =~ /_amount/) {
$i++;
$form->{"AP_amount_$i"} = "$ref->{accno}--$ref->{description}";
+ $form->{"projectnumber_$i"} = "$ref->{projectnumber}--$ref->{project_id}";
}
if ($ref->{category} eq 'L') {
$form->{AP} = $form->{AP_1} = "$ref->{accno}--$ref->{description}";
@@ -874,10 +1015,11 @@ sub retrieve_item {
my ($self, $myconfig, $form) = @_;
my $i = $form->{rowcount};
+ my $null;
my $var;
# don't include assemblies or obsolete parts
- my $where = "NOT p.assembly = '1' AND NOT p.obsolete = '1'";
+ my $where = "WHERE p.assembly = '0' AND p.obsolete = '0'";
if ($form->{"partnumber_$i"}) {
$var = $form->like(lc $form->{"partnumber_$i"});
@@ -886,18 +1028,22 @@ sub retrieve_item {
if ($form->{"description_$i"}) {
$var = $form->like(lc $form->{"description_$i"});
- $where .= " AND lower(p.description) LIKE '$var'";
+ if ($form->{language_code}) {
+ $where .= " AND lower(t1.description) LIKE '$var'";
+ } else {
+ $where .= " AND lower(p.description) LIKE '$var'";
+ }
}
if ($form->{"partsgroup_$i"}) {
- $var = $form->like(lc $form->{"partsgroup_$i"});
- $where .= " AND lower(pg.partsgroup) LIKE '$var'";
+ ($null, $var) = split /--/, $form->{"partsgroup_$i"};
+ $where .= qq| AND p.partsgroup_id = $var|;
}
-
+
if ($form->{"description_$i"}) {
- $where .= " ORDER BY description";
+ $where .= " ORDER BY 3";
} else {
- $where .= " ORDER BY partnumber";
+ $where .= " ORDER BY 2";
}
# connect to database
@@ -907,33 +1053,67 @@ sub retrieve_item {
c1.accno AS inventory_accno,
c2.accno AS income_accno,
c3.accno AS expense_accno,
- pg.partsgroup
+ pg.partsgroup, p.partsgroup_id,
+ p.lastcost AS sellprice, p.unit, p.bin, p.onhand,
+ p.partnumber AS sku, p.weight,
+ t1.description AS translation,
+ t2.description AS grouptranslation
FROM parts p
LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
- WHERE $where|;
+ LEFT JOIN translation t1 ON (t1.trans_id = p.id AND t1.language_code = '$form->{language_code}')
+ LEFT JOIN translation t2 ON (t2.trans_id = p.partsgroup_id AND t2.language_code = '$form->{language_code}')
+ $where|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
+
+ # foreign currency
+ &exchangerate_defaults($dbh, $form);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- # get tax rates for part
- $query = qq|SELECT c.accno
- FROM chart c
- JOIN partstax pt ON (pt.chart_id = c.id)
- WHERE pt.parts_id = $ref->{id}|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
+ # taxes
+ $query = qq|SELECT c.accno
+ FROM chart c
+ JOIN partstax pt ON (pt.chart_id = c.id)
+ WHERE pt.parts_id = ?|;
+ my $tth = $dbh->prepare($query) || $form->dberror($query);
+
+ # price matrix
+ $query = qq|SELECT p.*
+ FROM partsvendor p
+ WHERE p.parts_id = ?
+ AND vendor_id = $form->{vendor_id}|;
+ my $pmh = $dbh->prepare($query) || $form->dberror($query);
+
+ my $ref;
+ my $ptref;
+ my $decimalplaces;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+ ($decimalplaces) = ($ref->{sellprice} =~ /\.(\d+)/);
+ $decimalplaces = length $decimalplaces;
+ $decimalplaces = 2 unless $decimalplaces;
+
+ # get taxes for part
+ $tth->execute($ref->{id});
$ref->{taxaccounts} = "";
- while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ptref = $tth->fetchrow_hashref(NAME_lc)) {
$ref->{taxaccounts} .= "$ptref->{accno} ";
}
- $sth->finish;
+ $tth->finish;
chop $ref->{taxaccounts};
+
+ # get vendor price and partnumber
+ &price_matrix($pmh, $ref, $decimalplaces, $form, $myconfig);
+
+ $ref->{description} = $ref->{translation} if $ref->{translation};
+ $ref->{partsgroup} = $ref->{grouptranslation} if $ref->{grouptranslation};
push @{ $form->{item_list} }, $ref;
+
}
$sth->finish;
@@ -942,6 +1122,72 @@ sub retrieve_item {
}
+sub exchangerate_defaults {
+ my ($dbh, $form) = @_;
+
+ my $var;
+
+ # get default currencies
+ my $query = qq|SELECT substr(curr,1,3), curr FROM defaults|;
+ my $eth = $dbh->prepare($query) || $form->dberror($query);
+ $eth->execute;
+ ($form->{defaultcurrency}, $form->{currencies}) = $eth->fetchrow_array;
+ $eth->finish;
+
+ $query = qq|SELECT sell
+ FROM exchangerate
+ WHERE curr = ?
+ AND transdate = ?|;
+ my $eth1 = $dbh->prepare($query) || $form->dberror($query);
+
+ $query = qq~SELECT max(transdate || ' ' || sell || ' ' || curr)
+ FROM exchangerate
+ WHERE curr = ?~;
+ my $eth2 = $dbh->prepare($query) || $form->dberror($query);
+
+ # get exchange rates for transdate or max
+ foreach $var (split /:/, substr($form->{currencies},4)) {
+ $eth1->execute($var, $form->{transdate});
+ ($form->{$var}) = $eth1->fetchrow_array;
+ if (! $form->{$var} ) {
+ $eth2->execute($var);
+
+ ($form->{$var}) = $eth2->fetchrow_array;
+ ($null, $form->{$var}) = split / /, $form->{$var};
+ $form->{$var} = 1 unless $form->{$var};
+ $eth2->finish;
+ }
+ $eth1->finish;
+ }
+
+ $form->{$form->{defaultcurrency}} = 1;
+
+}
+
+
+sub price_matrix {
+ my ($pmh, $ref, $decimalplaces, $form, $myconfig) = @_;
+
+ $pmh->execute($ref->{id});
+ my $mref = $pmh->fetchrow_hashref(NAME_lc);
+
+ if ($mref->{partnumber}) {
+ $ref->{partnumber} = $mref->{partnumber};
+ }
+
+ if ($mref->{lastcost}) {
+ # do a conversion
+ $ref->{sellprice} = $form->round_amount($mref->{lastcost} * $form->{$mref->{curr}}, $decimalplaces);
+ }
+ $pmh->finish;
+
+ $ref->{sellprice} *= 1;
+
+ # add 0:price to matrix
+ $ref->{pricematrix} = "0:$ref->{sellprice}";
+
+}
+
sub vendor_details {
my ($self, $myconfig, $form) = @_;
@@ -950,8 +1196,10 @@ sub vendor_details {
my $dbh = $form->dbconnect($myconfig);
# get rest for the vendor
- my $query = qq|SELECT vendornumber, name, addr1, addr2, addr3, addr4,
- contact, phone as vendorphone, fax as vendorfax, vendornumber
+ my $query = qq|SELECT vendornumber, name, address1, address2, city, state,
+ zipcode, country,
+ contact, phone as vendorphone, fax as vendorfax, vendornumber,
+ taxnumber, sic_code AS sic, iban, bic
FROM vendor
WHERE id = $form->{vendor_id}|;
my $sth = $dbh->prepare($query);
diff --git a/sql-ledger/SL/IS.pm b/sql-ledger/SL/IS.pm
index dc11e3677..788dd9568 100644
--- a/sql-ledger/SL/IS.pm
+++ b/sql-ledger/SL/IS.pm
@@ -1,12 +1,12 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 1998-2002
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
-# Contributors:
+# Contributors: Jim Rawlings <jim@your-dba.com>
#
# 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
@@ -32,12 +32,12 @@ package IS;
sub invoice_details {
my ($self, $myconfig, $form) = @_;
- $form->{duedate} = $form->{invdate} unless ($form->{duedate});
+ $form->{duedate} = $form->{transdate} unless ($form->{duedate});
# connect to database
my $dbh = $form->dbconnect($myconfig);
- my $query = qq|SELECT date '$form->{duedate}' - date '$form->{invdate}'
+ my $query = qq|SELECT date '$form->{duedate}' - date '$form->{transdate}'
AS terms
FROM defaults|;
my $sth = $dbh->prepare($query);
@@ -46,52 +46,121 @@ sub invoice_details {
($form->{terms}) = $sth->fetchrow_array;
$sth->finish;
+ # this is for the template
+ $form->{invdate} = $form->{transdate};
+
my $tax = 0;
my $item;
my $i;
- my @partsgroup = ();
+ my @sortlist = ();
+ my $projectnumber;
+ my $projectnumber_id;
+ my $translation;
my $partsgroup;
- my %oid = ( 'Pg' => 'oid',
- 'Oracle' => 'rowid' );
+
+ my %oid = ( 'Pg' => 'oid',
+ 'PgPP' => 'oid',
+ 'Oracle' => 'rowid',
+ 'DB2' => '1=1'
+ );
# sort items by partsgroup
for $i (1 .. $form->{rowcount}) {
+ $projectnumber = "";
$partsgroup = "";
- if ($form->{"partsgroup_$i"} && $form->{groupitems}) {
- $form->format_string("partsgroup_$i");
- $partsgroup = $form->{"partsgroup_$i"};
+ $projectnumber_id = 0;
+ if ($form->{"projectnumber_$i"} && $form->{groupprojectnumber}) {
+ ($projectnumber, $projectnumber_id) = split /--/, $form->{"projectnumber_$i"};
}
- push @partsgroup, [ $i, $partsgroup ];
+ if ($form->{"partsgroup_$i"} && $form->{grouppartsgroup}) {
+ ($partsgroup) = split /--/, $form->{"partsgroup_$i"};
+ }
+ push @sortlist, [ $i, "$projectnumber$partsgroup", $projectnumber, $projectnumber_id, $partsgroup ];
+
+
+ # sort the whole thing by project and group
+ @sortlist = sort { $a->[1] cmp $b->[1] } @sortlist;
+
}
+ my @taxaccounts;
+ my %taxaccounts;
+ my $taxrate;
+ my $taxamount;
+ my $taxbase;
+ my $taxdiff;
+
+ $query = qq|SELECT p.description, t.description
+ FROM project p
+ LEFT JOIN translation t ON (t.trans_id = p.id AND t.language_code = '$form->{language_code}')
+ WHERE id = ?|;
+ my $prh = $dbh->prepare($query) || $form->dberror($query);
+
+ my $runningnumber = 1;
my $sameitem = "";
- foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
+ my $subtotal;
+ my $k = scalar @sortlist;
+ my $j = 0;
+
+ foreach $item (@sortlist) {
$i = $item->[0];
+ $j++;
+
+ if ($form->{groupprojectnumber} || $form->{grouppartsgroup}) {
+ if ($item->[1] ne $sameitem) {
+
+ $projectnumber = "";
+ if ($form->{groupprojectnumber} && $item->[2]) {
+ # get project description
+ $prh->execute($item->[3]) || $form->dberror($query);
+
+ ($projectnumber, $translation) = $prh->fetchrow_array;
+ $prh->finish;
+
+ $projectnumber = ($translation) ? "$item->[2], $translation" : "$item->[2], $projectnumber";
+ }
+
+ if ($form->{grouppartsgroup} && $item->[4]) {
+ $projectnumber .= " / " if $projectnumber;
+ $projectnumber .= $item->[4];
+ }
- if ($item->[1] ne $sameitem) {
- push(@{ $form->{description} }, qq|$item->[1]|);
- $sameitem = $item->[1];
+ $form->{projectnumber} = $projectnumber;
+ $form->format_string(projectnumber);
- map { push(@{ $form->{$_} }, "") } qw(runningnumber number bin qty unit deliverydate sellprice listprice netprice discount linetotal);
+ push(@{ $form->{description} }, qq|$form->{projectnumber}|);
+ $sameitem = $item->[1];
+
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber number sku serialnumber bin qty unit deliverydate projectnumber sellprice listprice netprice discount discountrate linetotal weight);
+ }
}
-
+
$form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
if ($form->{"qty_$i"} != 0) {
+ $form->{totalqty} += $form->{"qty_$i"};
+ $form->{totalship} += $form->{"ship_$i"};
+ $form->{totalweight} += ($form->{"qty_$i"} * $form->{"weight_$i"});
+
# add number, description and qty to $form->{number}, ....
- push(@{ $form->{runningnumber} }, $i);
+ push(@{ $form->{runningnumber} }, $runningnumber++);
push(@{ $form->{number} }, qq|$form->{"partnumber_$i"}|);
+ push(@{ $form->{sku} }, qq|$form->{"sku_$i"}|);
+ push(@{ $form->{serialnumber} }, qq|$form->{"serialnumber_$i"}|);
push(@{ $form->{bin} }, qq|$form->{"bin_$i"}|);
push(@{ $form->{description} }, qq|$form->{"description_$i"}|);
push(@{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"}));
push(@{ $form->{unit} }, qq|$form->{"unit_$i"}|);
push(@{ $form->{deliverydate} }, qq|$form->{"deliverydate_$i"}|);
+ push(@{ $form->{projectnumber} }, qq|$form->{"projectnumber_$i"}|);
push(@{ $form->{sellprice} }, $form->{"sellprice_$i"});
# listprice
push(@{ $form->{listprice} }, $form->{"listprice_$i"});
+
+ push(@{ $form->{weight} }, $form->{"weight_$i"});
my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
my ($dec) = ($sellprice =~ /\.(\d+)/);
@@ -111,45 +180,68 @@ sub invoice_details {
$linetotal = ($linetotal != 0) ? $linetotal : " ";
push(@{ $form->{discount} }, $discount);
+ push(@{ $form->{discountrate} }, $form->format_amount($myconfig, $form->{"discount_$i"}));
$form->{total} += $linetotal;
+ # this is for the subtotals for grouping
+ $subtotal += $linetotal;
+
push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2));
- my $taxrate = 0;
- my ($taxamount, $taxbase);
+ @taxaccounts = split / /, $form->{"taxaccounts_$i"};
+ $taxrate = 0;
+ $taxdiff = 0;
- map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
+ map { $taxrate += $form->{"${_}_rate"} } @taxaccounts;
if ($form->{taxincluded}) {
# calculate tax
- $taxamount = $linetotal * ($taxrate / (1 + $taxrate));
+ $taxamount = $linetotal * $taxrate / (1 + $taxrate);
$taxbase = $linetotal - $taxamount;
} else {
$taxamount = $linetotal * $taxrate;
$taxbase = $linetotal;
}
-
- if ($taxamount != 0) {
- foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
+
+ if (@taxaccounts && $form->round_amount($taxamount, 2) == 0) {
+ if ($form->{taxincluded}) {
+ foreach $item (@taxaccounts) {
+ $taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
+
+ $taxaccounts{$item} += $taxamount;
+ $taxdiff += $taxamount;
+
+ $taxbase{$item} += $taxbase;
+ }
+ $taxaccounts{$taxaccounts[0]} += $taxdiff;
+ } else {
+ foreach $item (@taxaccounts) {
+ $taxaccounts{$item} += $linetotal * $form->{"${item}_rate"};
+ $taxbase{$item} += $taxbase;
+ }
+ }
+ } else {
+ foreach $item (@taxaccounts) {
$taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
$taxbase{$item} += $taxbase;
}
}
+
if ($form->{"assembly_$i"}) {
- $sameitem = "";
+ my $sm = "";
# get parts and push them onto the stack
my $sortorder = "";
- if ($form->{groupitems}) {
+ if ($form->{groupitems}) {
$sortorder = qq|ORDER BY pg.partsgroup, a.$oid{$myconfig->{dbdriver}}|;
} else {
$sortorder = qq|ORDER BY a.$oid{$myconfig->{dbdriver}}|;
}
$query = qq|SELECT p.partnumber, p.description, p.unit, a.qty,
- pg.partsgroup
+ pg.partsgroup, p.partnumber AS sku
FROM assembly a
JOIN parts p ON (a.parts_id = p.id)
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
@@ -160,33 +252,59 @@ sub invoice_details {
$sth->execute || $form->dberror($query);
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
- map { push(@{ $form->{$_} }, "") } qw(runningnumber number unit qty bin sellprice listprice netprice discount linetotal);
- $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
- push(@{ $form->{description} }, $sameitem);
+ if ($form->{grouppartsgroup} && $ref->{partsgroup} ne $sameitem) {
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber number sku serialnumber unit qty bin deliverydate projectnumber sellprice listprice netprice discount discountrate linetotal weight);
+ $sm = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
+ push(@{ $form->{description} }, $sm);
}
- push(@{ $form->{number} }, qq|$ref->{partnumber}|);
- push(@{ $form->{description} }, qq|$ref->{description}|);
- push(@{ $form->{unit} }, qq|$ref->{unit}|);
- push(@{ $form->{qty} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}));
-
- map { push(@{ $form->{$_} }, "") } qw(runningnumber bin sellprice listprice netprice discount linetotal);
+ map { $form->{"a_$_"} = $ref->{$_} } qw(partnumber description);
+ $form->format_string("a_partnumber", "a_description");
+
+ push(@{ $form->{description} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq| -- $form->{"a_partnumber"}, $form->{"a_description"}|);
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber number sku serialnumber unit qty bin deliverydate projectnumber sellprice listprice netprice discount discountrate linetotal weight);
}
$sth->finish;
}
-
}
+
+ # add subtotal
+ if ($form->{groupprojectnumber} || $form->{grouppartsgroup}) {
+ if ($subtotal) {
+ if ($j < $k) {
+ # look at next item
+ if ($sortlist[$j]->[1] ne $sameitem) {
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber number sku serialnumber bin qty unit deliverydate projectnumber sellprice listprice netprice discount discountrate weight);
+ push(@{ $form->{description} }, $form->{groupsubtotaldescription});
+ if (exists $form->{groupsubtotaldescription}) {
+ push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $subtotal, 2));
+ } else {
+ push(@{ $form->{linetotal} }, "");
+ }
+ $subtotal = 0;
+ }
+ } else {
+
+ # got last item
+ if (exists $form->{groupsubtotaldescription}) {
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber number sku serialnumber bin qty unit deliverydate projectnumber sellprice listprice netprice discount discountrate weight);
+ push(@{ $form->{description} }, $form->{groupsubtotaldescription});
+ push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $subtotal, 2));
+ }
+ }
+ }
+ }
+
}
foreach my $item (sort keys %taxaccounts) {
if ($form->round_amount($taxaccounts{$item}, 2) != 0) {
push(@{ $form->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
-
+
$tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
-
+
push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount));
push(@{ $form->{taxdescription} }, $form->{"${item}_description"});
push(@{ $form->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
@@ -202,22 +320,35 @@ sub invoice_details {
push(@{ $form->{paymentaccount} }, $description);
push(@{ $form->{paymentdate} }, $form->{"datepaid_$i"});
push(@{ $form->{paymentsource} }, $form->{"source_$i"});
+ push(@{ $form->{paymentmemo} }, $form->{"memo_$i"});
$form->{paid} += $form->parse_amount($myconfig, $form->{"paid_$i"});
}
}
+ map { $form->{$_} = $form->format_amount($myconfig, $form->{$_}) } qw(totalqty totalship totalweight);
$form->{subtotal} = $form->format_amount($myconfig, $form->{total}, 2);
$form->{invtotal} = ($form->{taxincluded}) ? $form->{total} : $form->{total} + $tax;
+
+ use SL::CP;
+ my $c;
+ if ($form->{language_code}) {
+ $c = new CP $form->{language_code};
+ } else {
+ $c = new CP $myconfig->{countrycode};
+ }
+ $c->init;
+ my $whole;
+ ($whole, $form->{decimal}) = split /\./, $form->{invtotal};
+ $form->{decimal} .= "00";
+ $form->{decimal} = substr($form->{decimal}, 0, 2);
+ $form->{text_amount} = $c->num2text($whole);
+
$form->{total} = $form->format_amount($myconfig, $form->{invtotal} - $form->{paid}, 2);
$form->{invtotal} = $form->format_amount($myconfig, $form->{invtotal}, 2);
$form->{paid} = $form->format_amount($myconfig, $form->{paid}, 2);
- # myconfig variables
- map { $form->{$_} = $myconfig->{$_} } (qw(company address tel fax signature businessnumber));
- $form->{username} = $myconfig->{name};
-
$dbh->disconnect;
}
@@ -248,8 +379,10 @@ sub customer_details {
my $dbh = $form->dbconnect($myconfig);
# get rest for the customer
- my $query = qq|SELECT customernumber, name, addr1, addr2, addr3, addr4,
- phone as customerphone, fax as customerfax, contact
+ my $query = qq|SELECT customernumber, name, address1, address2, city,
+ state, zipcode, country,
+ phone as customerphone, fax as customerfax, contact,
+ taxnumber, sic_code AS sic, iban, bic
FROM customer
WHERE id = $form->{customer_id}|;
my $sth = $dbh->prepare($query);
@@ -270,8 +403,19 @@ sub post_invoice {
# connect to database, turn off autocommit
my $dbh = $form->dbconnect_noauto($myconfig);
- my ($query, $sth, $null, $project_id, $deliverydate);
+ my $query;
+ my $sth;
+ my $null;
+ my $project_id;
my $exchangerate = 0;
+
+ ($null, $form->{employee_id}) = split /--/, $form->{employee};
+ unless ($form->{employee_id}) {
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh);
+ }
+
+ ($null, $form->{department_id}) = split(/--/, $form->{department});
+ $form->{department_id} *= 1;
if ($form->{id}) {
@@ -282,8 +426,7 @@ sub post_invoice {
$uid .= $form->{login};
$query = qq|INSERT INTO ar (invnumber, employee_id)
- VALUES ('$uid', (SELECT id FROM employee
- WHERE login = '$form->{login}') )|;
+ VALUES ('$uid', $form->{employee_id})|;
$dbh->do($query) || $form->dberror($query);
$query = qq|SELECT id FROM ar
@@ -295,9 +438,6 @@ sub post_invoice {
$sth->finish;
}
-
- map { $form->{$_} =~ s/'/''/g } (qw(invnumber shippingpoint notes message));
-
my ($netamount, $invoicediff) = (0, 0);
my ($amount, $linetotal, $lastincomeaccno);
@@ -315,8 +455,12 @@ sub post_invoice {
if ($form->{"qty_$i"} != 0) {
- map { $form->{"${_}_$i"} =~ s/'/''/g } (qw(partnumber description unit));
-
+ # project
+ $project_id = 'NULL';
+ if ($form->{"projectnumber_$i"}) {
+ ($null, $project_id) = split /--/, $form->{"projectnumber_$i"};
+ }
+
# undo discount formatting
$form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
@@ -349,7 +493,7 @@ sub post_invoice {
$netamount += $linetotal;
- if ($taxamount != 0) {
+ if ($form->round_amount($taxamount, 2) != 0) {
map { $form->{amount}{$form->{id}}{$_} += $taxamount * $form->{"${_}_rate"} / $taxrate } split / /, $form->{"taxaccounts_$i"};
}
@@ -362,11 +506,10 @@ sub post_invoice {
# this is the difference from the inventory
$invoicediff += ($amount - $linetotal);
-
+
$form->{amount}{$form->{id}}{$form->{"income_accno_$i"}} += $linetotal;
$lastincomeaccno = $form->{"income_accno_$i"};
-
# adjust and round sellprice
$form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces);
@@ -377,9 +520,9 @@ sub post_invoice {
if ($form->{"assembly_$i"}) {
# do not update if assembly consists of all services
$query = qq|SELECT sum(p.inventory_accno_id)
- FROM parts p, assembly a
- WHERE a.parts_id = p.id
- AND a.id = $form->{"id_$i"}|;
+ FROM parts p
+ JOIN assembly a ON (a.parts_id = p.id)
+ WHERE a.id = $form->{"id_$i"}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -388,7 +531,7 @@ sub post_invoice {
"parts",
"onhand",
qq|id = $form->{"id_$i"}|,
- $form->{"qty_$i"} * -1);
+ $form->{"qty_$i"} * -1) unless $form->{shipped};
}
$sth->finish;
@@ -399,36 +542,35 @@ sub post_invoice {
"parts",
"onhand",
qq|id = $form->{"id_$i"}|,
- $form->{"qty_$i"} * -1);
+ $form->{"qty_$i"} * -1) unless $form->{shipped};
$allocated = &cogs($dbh, $form, $form->{"id_$i"}, $form->{"qty_$i"});
}
}
- $project_id = 'NULL';
- if ($form->{"project_id_$i"}) {
- $project_id = $form->{"project_id_$i"};
- }
- $deliverydate = ($form->{"deliverydate_$i"}) ? qq|'$form->{"deliverydate_$i"}'| : "NULL";
-
+
# save detail record in invoice table
$query = qq|INSERT INTO invoice (trans_id, parts_id, description, qty,
sellprice, fxsellprice, discount, allocated, assemblyitem,
- unit, deliverydate, project_id)
- VALUES ($form->{id}, $form->{"id_$i"},
- '$form->{"description_$i"}', $form->{"qty_$i"},
- $form->{"sellprice_$i"}, $fxsellprice,
- $form->{"discount_$i"}, $allocated, 'f',
- '$form->{"unit_$i"}', $deliverydate, $project_id)|;
+ unit, deliverydate, project_id, serialnumber)
+ VALUES ($form->{id}, $form->{"id_$i"}, |
+ .$dbh->quote($form->{"description_$i"}).qq|,
+ $form->{"qty_$i"}, $form->{"sellprice_$i"}, $fxsellprice,
+ $form->{"discount_$i"}, $allocated, 'f', |
+ .$dbh->quote($form->{"unit_$i"}).qq|, |
+ .$form->dbquote($form->{"deliverydate_$i"}, SQL_DATE).qq|,
+ $project_id, |
+ .$dbh->quote($form->{"serialnumber_$i"}).qq|)|;
$dbh->do($query) || $form->dberror($query);
}
}
- $form->{datepaid} = $form->{invdate};
+ $form->{datepaid} = $form->{transdate};
# total payments, don't move we need it here
+ $form->{paid} = 0;
for my $i (1 .. $form->{paidaccounts}) {
$form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
$form->{paid} += $form->{"paid_$i"};
@@ -472,12 +614,10 @@ sub post_invoice {
}
}
-
- $form->{amount}{$form->{id}}{$form->{AR}} = $netamount + $tax;
+ $diff = 0 if $form->{paidaccounts} < 2;
- if ($form->{paid} != 0) {
- $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate} + $diff, 2);
- }
+ $form->{amount}{$form->{id}}{$form->{AR}} = $netamount + $tax;
+ $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate} + $diff, 2);
# reverse AR
$form->{amount}{$form->{id}}{$form->{AR}} *= -1;
@@ -485,17 +625,18 @@ sub post_invoice {
# update exchangerate
if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
- $form->update_exchangerate($dbh, $form->{currency}, $form->{invdate}, $form->{exchangerate}, 0);
+ $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $form->{exchangerate}, 0);
}
foreach my $trans_id (keys %{$form->{amount}}) {
foreach my $accno (keys %{ $form->{amount}{$trans_id} }) {
if (($form->{amount}{$trans_id}{$accno} = $form->round_amount($form->{amount}{$trans_id}{$accno}, 2)) != 0) {
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
- transdate)
+ transdate)
VALUES ($trans_id, (SELECT id FROM chart
- WHERE accno = '$accno'),
- $form->{amount}{$trans_id}{$accno}, '$form->{invdate}')|;
+ WHERE accno = '$accno'),
+ $form->{amount}{$trans_id}{$accno},
+ '$form->{transdate}')|;
$dbh->do($query) || $form->dberror($query);
}
}
@@ -509,17 +650,29 @@ sub post_invoice {
}
}
+
# force AR entry if 0
- $form->{amount}{$form->{id}}{$form->{AR}} = 1 if ($form->{amount}{$form->{id}}{$form->{AR}} == 0);
+ $form->{amount}{$form->{id}}{$form->{AR}} = $form->{paid} if ($form->{amount}{$form->{id}}{$form->{AR}} == 0);
# record payments and offsetting AR
for my $i (1 .. $form->{paidaccounts}) {
if ($form->{"paid_$i"} != 0) {
my ($accno) = split /--/, $form->{"AR_paid_$i"};
- $form->{"datepaid_$i"} = $form->{invdate} unless ($form->{"datepaid_$i"});
+ $form->{"datepaid_$i"} = $form->{transdate} unless ($form->{"datepaid_$i"});
$form->{datepaid} = $form->{"datepaid_$i"};
+ $exchangerate = 0;
+
+ if ($form->{currency} eq $form->{defaultcurrency}) {
+ $form->{"exchangerate_$i"} = 1;
+ } else {
+ $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'buy');
+
+ $form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"});
+ }
+
+
# record AR
$amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} + $diff, 2);
@@ -536,31 +689,20 @@ sub post_invoice {
$form->{"paid_$i"} *= -1;
$query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
- source)
+ source, memo)
VALUES ($form->{id}, (SELECT id FROM chart
WHERE accno = '$accno'),
- $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
- '$form->{"source_$i"}')|;
+ $form->{"paid_$i"}, '$form->{"datepaid_$i"}', |
+ .$dbh->quote($form->{"source_$i"}).qq|, |
+ .$dbh->quote($form->{"memo_$i"}).qq|)|;
$dbh->do($query) || $form->dberror($query);
-
- $exchangerate = 0;
-
- if ($form->{currency} eq $form->{defaultcurrency}) {
- $form->{"exchangerate_$i"} = 1;
- } else {
- $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'buy');
-
- $form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"});
- }
-
-
+
# exchangerate difference
$form->{fx}{$accno}{$form->{"datepaid_$i"}} += $form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) + $diff;
-
# gain/loss
- $amount = $form->{"paid_$i"} * $form->{exchangerate} - $form->{"paid_$i"} * $form->{"exchangerate_$i"};
+ $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate},2) - $form->round_amount($form->{"paid_$i"} * $form->{"exchangerate_$i"},2);
if ($amount > 0) {
$form->{fx}{$form->{fxgain_accno}}{$form->{"datepaid_$i"}} += $amount;
} else {
@@ -599,39 +741,34 @@ sub post_invoice {
# set values which could be empty to 0
$form->{terms} *= 1;
$form->{taxincluded} *= 1;
- my $datepaid = ($form->{paid}) ? qq|'$form->{datepaid}'| : "NULL";
- my $duedate = ($form->{duedate}) ? qq|'$form->{duedate}'| : "NULL";
-
- # fill in subject if there is none
- $form->{subject} = qq|$form->{label} $form->{invnumber}| unless $form->{subject};
- # if there is a message stuff it into the notes
- my $cc = "Cc: $form->{cc}\\r\n" if $form->{cc};
- my $bcc = "Bcc: $form->{bcc}\\r\n" if $form->{bcc};
- $form->{notes} .= qq|\r
-\r
-[email]\r
-To: $form->{email}\r
-$cc${bcc}Subject: $form->{subject}\r
-\r
-Message: $form->{message}\r| if $form->{message};
+ # if this is from a till
+ my $till = ($form->{till}) ? qq|'$form->{till}'| : "NULL";
+
# save AR record
$query = qq|UPDATE ar set
- invnumber = '$form->{invnumber}',
- ordnumber = '$form->{ordnumber}',
- transdate = '$form->{invdate}',
+ invnumber = |.$dbh->quote($form->{invnumber}).qq|,
+ ordnumber = |.$dbh->quote($form->{ordnumber}).qq|,
+ quonumber = |.$dbh->quote($form->{quonumber}).qq|,
+ transdate = '$form->{transdate}',
customer_id = $form->{customer_id},
amount = $amount,
netamount = $netamount,
paid = $form->{paid},
- datepaid = $datepaid,
- duedate = $duedate,
+ datepaid = |.$form->dbquote($form->{datepaid}, SQL_DATE).qq|,
+ duedate = |.$form->dbquote($form->{duedate}, SQL_DATE).qq|,
invoice = '1',
- shippingpoint = '$form->{shippingpoint}',
+ shippingpoint = |.$dbh->quote($form->{shippingpoint}).qq|,
+ shipvia = |.$dbh->quote($form->{shipvia}).qq|,
terms = $form->{terms},
- notes = '$form->{notes}',
+ notes = |.$dbh->quote($form->{notes}).qq|,
+ intnotes = |.$dbh->quote($form->{intnotes}).qq|,
taxincluded = '$form->{taxincluded}',
- curr = '$form->{currency}'
+ curr = '$form->{currency}',
+ department_id = $form->{department_id},
+ employee_id = $form->{employee_id},
+ till = $till,
+ language_code = '$form->{language_code}'
WHERE id = $form->{id}
|;
$dbh->do($query) || $form->dberror($query);
@@ -641,6 +778,17 @@ Message: $form->{message}\r| if $form->{message};
$form->{name} =~ s/--$form->{customer_id}//;
$form->add_shipto($dbh, $form->{id});
+ # save printed, emailed and queued
+ $form->save_status($dbh);
+
+ my %audittrail = ( tablename => 'ar',
+ reference => $form->{invnumber},
+ formname => $form->{type},
+ action => 'posted',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
+
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -656,9 +804,9 @@ sub process_assembly {
p.partnumber, p.description, p.unit,
p.inventory_accno_id, p.income_accno_id,
p.expense_accno_id
- FROM assembly a, parts p
- WHERE a.parts_id = p.id
- AND a.id = $id|;
+ FROM assembly a
+ JOIN parts p ON (a.parts_id = p.id)
+ WHERE a.id = $id|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -670,8 +818,6 @@ sub process_assembly {
$ref->{inventory_accno_id} *= 1;
$ref->{expense_accno_id} *= 1;
- map { $ref->{$_} =~ s/'/''/g } (qw(partnumber description unit));
-
# multiply by number of assemblies
$ref->{qty} *= $totalqty;
@@ -688,9 +834,10 @@ sub process_assembly {
$query = qq|INSERT INTO invoice (trans_id, description, parts_id, qty,
sellprice, fxsellprice, allocated, assemblyitem, unit)
VALUES
- ($form->{id}, '$ref->{description}',
- $ref->{parts_id}, $ref->{qty}, 0, 0, $allocated, 't',
- '$ref->{unit}')|;
+ ($form->{id}, |
+ .$dbh->quote($ref->{description}).qq|,
+ $ref->{parts_id}, $ref->{qty}, 0, 0, $allocated, 't', |
+ .$dbh->quote($ref->{unit}).qq|)|;
$dbh->do($query) || $form->dberror($query);
}
@@ -702,14 +849,12 @@ sub process_assembly {
sub cogs {
my ($dbh, $form, $id, $totalqty) = @_;
-
+
my $query = qq|SELECT i.id, i.trans_id, i.qty, i.allocated, i.sellprice,
- (SELECT c.accno FROM chart c
- WHERE p.inventory_accno_id = c.id)
- AS inventory_accno,
- (SELECT c.accno FROM chart c
- WHERE p.expense_accno_id = c.id)
- AS expense_accno
+ (SELECT c.accno FROM chart c
+ WHERE p.inventory_accno_id = c.id) AS inventory_accno,
+ (SELECT c.accno FROM chart c
+ WHERE p.expense_accno_id = c.id) AS expense_accno
FROM invoice i, parts p
WHERE i.parts_id = p.id
AND i.parts_id = $id
@@ -762,9 +907,9 @@ sub reverse_invoice {
# reverse inventory items
my $query = qq|SELECT i.id, i.parts_id, i.qty, i.assemblyitem, p.assembly,
p.inventory_accno_id
- FROM invoice i, parts p
- WHERE i.parts_id = p.id
- AND i.trans_id = $form->{id}|;
+ FROM invoice i
+ JOIN parts p ON (i.parts_id = p.id)
+ WHERE i.trans_id = $form->{id}|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -773,7 +918,7 @@ sub reverse_invoice {
if ($ref->{inventory_accno_id} || $ref->{assembly}) {
# if the invoice item is not an assemblyitem adjust parts onhand
- unless ($ref->{assemblyitem}) {
+ if (!$ref->{assemblyitem}) {
# adjust onhand in parts table
$form->update_balance($dbh,
"parts",
@@ -834,23 +979,54 @@ sub reverse_invoice {
sub delete_invoice {
- my ($self, $myconfig, $form) = @_;
+ my ($self, $myconfig, $form, $spool) = @_;
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
- # check for other foreign currency transactions
- $form->delete_exchangerate($dbh) if ($form->{currency} ne $form->{defaultcurrency});
-
&reverse_invoice($dbh, $form);
+ my %audittrail = ( tablename => 'ar',
+ reference => $form->{invnumber},
+ formname => $form->{type},
+ action => 'deleted',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
+
# delete AR record
my $query = qq|DELETE FROM ar
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
+ # delete spool files
+ $query = qq|SELECT spoolfile FROM status
+ WHERE trans_id = $form->{id}
+ AND spoolfile IS NOT NULL|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $spoolfile;
+ my @spoolfiles = ();
+
+ while (($spoolfile) = $sth->fetchrow_array) {
+ push @spoolfiles, $spoolfile;
+ }
+ $sth->finish;
+
+ # delete status entries
+ $query = qq|DELETE FROM status
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
my $rc = $dbh->commit;
$dbh->disconnect;
+
+ if ($rc) {
+ foreach $spoolfile (@spoolfiles) {
+ unlink "$spool/$spoolfile" if $spoolfile;
+ }
+ }
$rc;
@@ -865,7 +1041,7 @@ sub retrieve_invoice {
my $dbh = $form->dbconnect_noauto($myconfig);
my $query;
-
+
if ($form->{id}) {
# get default accounts and last invoice number
$query = qq|SELECT (SELECT c.accno FROM chart c
@@ -891,7 +1067,7 @@ sub retrieve_invoice {
WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
(SELECT c.accno FROM chart c
WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
- d.invnumber, d.curr AS currencies, current_date AS invdate
+ d.curr AS currencies, current_date AS transdate
FROM defaults d|;
}
my $sth = $dbh->prepare($query);
@@ -905,11 +1081,14 @@ sub retrieve_invoice {
if ($form->{id}) {
# retrieve invoice
- $query = qq|SELECT a.invnumber, a.ordnumber, a.transdate AS invdate, a.paid,
- a.shippingpoint, a.terms, a.notes, a.duedate, a.taxincluded,
- a.curr AS currency, (SELECT e.name FROM employee e
- WHERE e.id = a.employee_id) AS employee
+ $query = qq|SELECT a.invnumber, a.ordnumber, a.quonumber,
+ a.transdate, a.paid,
+ a.shippingpoint, a.shipvia, a.terms, a.notes, a.intnotes,
+ a.duedate, a.taxincluded, a.curr AS currency,
+ a.employee_id, e.name AS employee, a.till, a.customer_id,
+ a.language_code
FROM ar a
+ LEFT JOIN employee e ON (e.id = a.employee_id)
WHERE a.id = $form->{id}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -918,8 +1097,6 @@ sub retrieve_invoice {
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
- $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, "buy");
-
# get shipto
$query = qq|SELECT * FROM shipto
WHERE trans_id = $form->{id}|;
@@ -929,70 +1106,82 @@ sub retrieve_invoice {
$ref = $sth->fetchrow_hashref(NAME_lc);
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
-
+
# retrieve individual items
- $query = qq|SELECT c1.accno AS inventory_accno,
- c2.accno AS income_accno,
- c3.accno AS expense_accno,
- i.description, i.qty, i.fxsellprice AS sellprice,
+ $query = qq|SELECT (SELECT c.accno FROM chart c
+ WHERE p.inventory_accno_id = c.id)
+ AS inventory_accno,
+ (SELECT c.accno FROM chart c
+ WHERE p.income_accno_id = c.id)
+ AS income_accno,
+ (SELECT c.accno FROM chart c
+ WHERE p.expense_accno_id = c.id)
+ AS expense_accno,
+ i.description, i.qty, i.fxsellprice, i.sellprice,
i.discount, i.parts_id AS id, i.unit, i.deliverydate,
- pr.projectnumber,
- i.project_id,
+ i.project_id, pr.projectnumber, i.serialnumber,
p.partnumber, p.assembly, p.bin,
- pg.partsgroup
+ pg.partsgroup, p.partsgroup_id, p.partnumber AS sku,
+ p.listprice, p.lastcost, p.weight,
+ t.description AS partsgrouptranslation
FROM invoice i
- JOIN parts p ON (i.parts_id = p.id)
- LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
- LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
- LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
- LEFT JOIN project pr ON (i.project_id = pr.id)
- LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ JOIN parts p ON (i.parts_id = p.id)
+ LEFT JOIN project pr ON (i.project_id = pr.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ LEFT JOIN translation t ON (t.trans_id = p.partsgroup_id AND t.language_code = '$form->{language_code}')
WHERE i.trans_id = $form->{id}
AND NOT i.assemblyitem = '1'
ORDER BY i.id|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
+ # foreign currency
+ &exchangerate_defaults($dbh, $form);
+
+ # query for price matrix
+ my $pmh = &price_matrix_query($dbh, $form);
+
+ # taxes
+ $query = qq|SELECT c.accno
+ FROM chart c
+ JOIN partstax pt ON (pt.chart_id = c.id)
+ WHERE pt.parts_id = ?|;
+ my $tth = $dbh->prepare($query) || $form->dberror($query);
+
+ my $taxrate;
+ my $ptref;
+
while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
- # get taxes
- $query = qq|SELECT c.accno
- FROM chart c, partstax pt
- WHERE pt.chart_id = c.id
- AND pt.parts_id = $ref->{id}|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
+
+ ($decimalplaces) = ($ref->{fxsellprice} =~ /\.(\d+)/);
+ $decimalplaces = length $decimalplaces;
+ $decimalplaces = 2 unless $decimalplaces;
+
+ $tth->execute($ref->{id});
$ref->{taxaccounts} = "";
- my $taxrate = 0;
+ $taxrate = 0;
- while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ptref = $tth->fetchrow_hashref(NAME_lc)) {
$ref->{taxaccounts} .= "$ptref->{accno} ";
$taxrate += $form->{"$ptref->{accno}_rate"};
}
- $sth->finish;
+ $tth->finish;
chop $ref->{taxaccounts};
+ # price matrix
+ $ref->{sellprice} = ($ref->{fxsellprice} * $form->{$form->{currency}});
+ &price_matrix($pmh, $ref, $form->{transdate}, $decimalplaces, $form, $myconfig, 1);
+ $ref->{sellprice} = $ref->{fxsellprice};
+
+ $ref->{partsgroup} = $ref->{partsgrouptranslation} if $ref->{partsgrouptranslation};
+
push @{ $form->{invoice_details} }, $ref;
}
$sth->finish;
- } else {
-
- $form->{shippingpoint} = $myconfig->{shippingpoint} unless $form->{shippingpoint};
-
- # up invoice number by 1
- $form->{invnumber}++;
-
- # save the new number
- $query = qq|UPDATE defaults
- SET invnumber = '$form->{invnumber}'|;
- $dbh->do($query) || $form->dberror($query);
-
- $form->get_employee($dbh);
-
}
-
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -1006,27 +1195,60 @@ sub get_customer {
# connect to database
my $dbh = $form->dbconnect($myconfig);
-
+
my $dateformat = $myconfig->{dateformat};
- $dateformat .= "yy" if $myconfig->{dateformat} !~ /^y/;
-
- my $duedate = ($form->{invdate}) ? "to_date('$form->{invdate}', '$dateformat')" : "current_date";
+ if ($myconfig->{dateformat} !~ /^y/) {
+ my @a = split /\W/, $form->{transdate};
+ $dateformat .= "yy" if (length $a[2] > 2);
+ }
+
+ if ($form->{transdate} !~ /\W/) {
+ $dateformat = 'yyyymmdd';
+ }
+
+ my $duedate;
+
+ if ($myconfig->{dbdriver} eq 'DB2') {
+ $duedate = ($form->{transdate}) ? "date('$form->{transdate}') + c.terms DAYS" : "current_date + c.terms DAYS";
+ } else {
+ $duedate = ($form->{transdate}) ? "to_date('$form->{transdate}', '$dateformat') + c.terms" : "current_date + c.terms";
+ }
$form->{customer_id} *= 1;
# get customer
my $query = qq|SELECT c.name AS customer, c.discount, c.creditlimit, c.terms,
c.email, c.cc, c.bcc, c.taxincluded,
- c.addr1, c.addr2, c.addr3, c.addr4,
- $duedate + c.terms AS duedate
+ c.address1, c.address2, c.city, c.state,
+ c.zipcode, c.country, c.curr AS currency, c.language_code,
+ $duedate AS duedate, c.notes AS intnotes,
+ b.discount AS tradediscount, b.description AS business,
+ e.name AS employee, e.id AS employee_id
FROM customer c
+ LEFT JOIN business b ON (b.id = c.business_id)
+ LEFT JOIN employee e ON (e.id = c.employee_id)
WHERE c.id = $form->{customer_id}|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
$ref = $sth->fetchrow_hashref(NAME_lc);
+ if ($form->{id}) {
+ map { delete $ref->{$_} } qw(currency taxincluded employee employee_id intnotes);
+ }
+
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
+
+ # if no currency use defaultcurrency
+ $form->{currency} = ($form->{currency}) ? $form->{currency} : $form->{defaultcurrency};
+ $form->{exchangerate} = 0 if $form->{currency} eq $form->{defaultcurrency};
+ if ($form->{transdate} && ($form->{currency} ne $form->{defaultcurrency})) {
+ $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{transdate}, "buy");
+ }
+ $form->{forex} = $form->{exchangerate};
+
+ # if no employee, default to login
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh) unless $form->{employee_id};
$form->{creditremaining} = $form->{creditlimit};
$query = qq|SELECT SUM(amount - paid)
@@ -1045,6 +1267,7 @@ sub get_customer {
AND e.transdate = o.transdate)
FROM oe o
WHERE o.customer_id = $form->{customer_id}
+ AND o.quotation = '0'
AND o.closed = '0'|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -1058,7 +1281,7 @@ sub get_customer {
# get shipto if we did not converted an order or invoice
if (!$form->{shipto}) {
- map { delete $form->{$_} } qw(shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shiptocontact shiptophone shiptofax shiptoemail);
+ map { delete $form->{$_} } qw(shiptoname shiptoaddress1 shiptoaddress2 shiptocity shiptostate shiptozipcode shiptocountry shiptocontact shiptophone shiptofax shiptoemail);
$query = qq|SELECT * FROM shipto
WHERE trans_id = $form->{customer_id}|;
@@ -1072,9 +1295,9 @@ sub get_customer {
# get taxes we charge for this customer
$query = qq|SELECT c.accno
- FROM chart c, customertax ct
- WHERE ct.chart_id = c.id
- AND ct.customer_id = $form->{customer_id}|;
+ FROM chart c
+ JOIN customertax ct ON (ct.chart_id = c.id)
+ WHERE ct.customer_id = $form->{customer_id}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -1086,9 +1309,9 @@ sub get_customer {
# get tax rates and description
$query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber
- FROM chart c, tax t
- WHERE c.id = t.chart_id
- AND c.link LIKE '%CT_tax%'
+ FROM chart c
+ JOIN tax t ON (c.id = t.chart_id)
+ WHERE c.link LIKE '%CT_tax%'
ORDER BY accno|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -1106,13 +1329,16 @@ sub get_customer {
chop $form->{taxaccounts};
# setup last accounts used for this customer
- if (!$form->{id} && $form->{type} !~ /_order/) {
- $query = qq|SELECT c.accno, c.description, c.link, c.category
+ if (!$form->{id} && $form->{type} !~ /_(order|quotation)/) {
+ $query = qq|SELECT c.accno, c.description, c.link, c.category,
+ ac.project_id, p.projectnumber, a.department_id,
+ d.description AS department
FROM chart c
JOIN acc_trans ac ON (ac.chart_id = c.id)
JOIN ar a ON (a.id = ac.trans_id)
+ LEFT JOIN project p ON (ac.project_id = p.id)
+ LEFT JOIN department d ON (d.id = a.department_id)
WHERE a.customer_id = $form->{customer_id}
- AND NOT (c.link LIKE '%_tax%' OR c.link LIKE '%_paid%')
AND a.id IN (SELECT max(id) FROM ar
WHERE customer_id = $form->{customer_id})|;
$sth = $dbh->prepare($query);
@@ -1120,9 +1346,13 @@ sub get_customer {
my $i = 0;
while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
- if ($ref->{category} eq 'I') {
+ $form->{department} = $ref->{department};
+ $form->{department_id} = $ref->{department_id};
+
+ if ($ref->{link} =~ /_amount/) {
$i++;
$form->{"AR_amount_$i"} = "$ref->{accno}--$ref->{description}";
+ $form->{"projectnumber_$i"} = "$ref->{projectnumber}--$ref->{project_id}";
}
if ($ref->{category} eq 'A') {
$form->{AR} = $form->{AR_1} = "$ref->{accno}--$ref->{description}";
@@ -1133,17 +1363,22 @@ sub get_customer {
}
$dbh->disconnect;
-
+
}
sub retrieve_item {
my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
my $i = $form->{rowcount};
+ my $null;
my $var;
- my $where = "NOT obsolete = '1'";
+
+ my $where = "WHERE p.obsolete = '0' AND NOT p.income_accno_id IS NULL";
if ($form->{"partnumber_$i"}) {
$var = $form->like(lc $form->{"partnumber_$i"});
@@ -1151,72 +1386,93 @@ sub retrieve_item {
}
if ($form->{"description_$i"}) {
$var = $form->like(lc $form->{"description_$i"});
- $where .= " AND lower(p.description) LIKE '$var'";
+ if ($form->{language_code}) {
+ $where .= " AND lower(t1.description) LIKE '$var'";
+ } else {
+ $where .= " AND lower(p.description) LIKE '$var'";
+ }
}
if ($form->{"partsgroup_$i"}) {
- $var = $form->like(lc $form->{"partsgroup_$i"});
- $where .= " AND lower(pg.partsgroup) LIKE '$var'";
+ ($null, $var) = split /--/, $form->{"partsgroup_$i"};
+ $var *= 1;
+ if ($var == 0) {
+ # search by partsgroup, this is for the POS
+ $where .= qq| AND pg.partsgroup = '$form->{"partsgroup_$i"}'|;
+ } else {
+ $where .= qq| AND p.partsgroup_id = $var|;
+ }
}
if ($form->{"description_$i"}) {
- $where .= " ORDER BY description";
+ $where .= " ORDER BY 3";
} else {
- $where .= " ORDER BY partnumber";
+ $where .= " ORDER BY 2";
}
- # connect to database
- my $dbh = $form->dbconnect($myconfig);
-
my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice,
- p.listprice,
- c1.accno AS inventory_accno,
- c2.accno AS income_accno,
- c3.accno AS expense_accno,
- p.unit, p.assembly, p.bin, p.onhand, p.makemodel,
- pg.partsgroup
+ p.listprice, p.lastcost,
+ c1.accno AS inventory_accno,
+ c2.accno AS income_accno,
+ c3.accno AS expense_accno,
+ p.unit, p.assembly, p.bin, p.onhand,
+ pg.partsgroup, p.partsgroup_id, p.partnumber AS sku,
+ p.weight,
+ t1.description AS translation,
+ t2.description AS grouptranslation
FROM parts p
LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
- WHERE $where|;
+ LEFT JOIN translation t1 ON (t1.trans_id = p.id AND t1.language_code = '$form->{language_code}')
+ LEFT JOIN translation t2 ON (t2.trans_id = p.partsgroup_id AND t2.language_code = '$form->{language_code}')
+ $where|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ my $ref;
+ my $ptref;
+
+ # setup exchange rates
+ &exchangerate_defaults($dbh, $form);
+
+ # taxes
+ $query = qq|SELECT c.accno
+ FROM chart c
+ JOIN partstax pt ON (c.id = pt.chart_id)
+ WHERE pt.parts_id = ?|;
+ my $tth = $dbh->prepare($query) || $form->dberror($query);
+
+ # price matrix
+ my $pmh = &price_matrix_query($dbh, $form);
+
+ my $transdate = $form->datetonum($form->{transdate}, $myconfig);
+ my $decimalplaces;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+ ($decimalplaces) = ($ref->{sellprice} =~ /\.(\d+)/);
+ $decimalplaces = length $decimalplaces;
+ $decimalplaces = 2 unless $decimalplaces;
+
# get taxes for part
- $query = qq|SELECT c.accno
- FROM chart c
- JOIN partstax pt ON (c.id = pt.chart_id)
- WHERE pt.parts_id = $ref->{id}|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
+ $tth->execute($ref->{id});
$ref->{taxaccounts} = "";
- while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ptref = $tth->fetchrow_hashref(NAME_lc)) {
$ref->{taxaccounts} .= "$ptref->{accno} ";
}
- $sth->finish;
+ $tth->finish;
chop $ref->{taxaccounts};
- # get makemodel
- if ($ref->{makemodel}) {
- $query = qq|SELECT name
- FROM makemodel
- WHERE parts_id = $ref->{id}|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- $ref->{makemodel} = "";
- while (my $ptref = $sth->fetchrow_hashref(NAME_lc)) {
- $ref->{makemodel} .= "$ptref->{name}:";
- }
- $sth->finish;
- chop $ref->{makemodel};
- }
+ # get matrix
+ &price_matrix($pmh, $ref, $transdate, $decimalplaces, $form, $myconfig);
+ $ref->{description} = $ref->{translation} if $ref->{translation};
+ $ref->{partsgroup} = $ref->{grouptranslation} if $ref->{grouptranslation};
+
push @{ $form->{item_list} }, $ref;
}
@@ -1227,5 +1483,150 @@ sub retrieve_item {
}
+sub price_matrix_query {
+ my ($dbh, $form) = @_;
+
+ my $query = qq|SELECT p.*, g.pricegroup
+ FROM partscustomer p
+ LEFT JOIN pricegroup g ON (g.id = p.pricegroup_id)
+ WHERE p.parts_id = ?
+ AND p.customer_id = $form->{customer_id}
+
+ UNION
+
+ SELECT p.*, g.pricegroup
+ FROM partscustomer p
+ LEFT JOIN pricegroup g ON (g.id = p.pricegroup_id)
+ JOIN customer c ON (c.pricegroup_id = g.id)
+ WHERE p.parts_id = ?
+ AND c.id = $form->{customer_id}
+
+ UNION
+
+ SELECT p.*, '' AS pricegroup
+ FROM partscustomer p
+ WHERE p.customer_id = 0
+ AND p.pricegroup_id = 0
+ AND p.parts_id = ?
+
+ ORDER BY customer_id DESC, pricegroup_id DESC, pricebreak
+
+ |;
+ my $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ $sth;
+
+}
+
+
+sub price_matrix {
+ my ($pmh, $ref, $transdate, $decimalplaces, $form, $myconfig, $init) = @_;
+
+ $pmh->execute($ref->{id}, $ref->{id}, $ref->{id});
+
+ $ref->{pricematrix} = "";
+ my $customerprice;
+ my $pricegroup;
+ my $sellprice;
+ my $mref;
+
+ while ($mref = $pmh->fetchrow_hashref(NAME_lc)) {
+
+ $customerprice = 0;
+ $pricegroup = 0;
+
+ # check date
+ if ($mref->{validfrom}) {
+ next if $transdate < $form->datetonum($mref->{validfrom}, $myconfig);
+ }
+ if ($mref->{validto}) {
+ next if $transdate > $form->datetonum($mref->{validto}, $myconfig);
+ }
+
+ # convert price
+ $sellprice = $form->round_amount($mref->{sellprice} * $form->{$mref->{curr}}, $decimalplaces);
+
+ if ($mref->{customer_id}) {
+ $ref->{sellprice} = $sellprice unless $mref->{pricebreak};
+ $ref->{pricematrix} .= "$mref->{pricebreak}:$sellprice ";
+ $customerprice = 1;
+ }
+
+ if ($mref->{pricegroup_id}) {
+ if (! $customerprice) {
+ $ref->{sellprice} = $sellprice unless $mref->{pricebreak};
+ $ref->{pricematrix} .= "$mref->{pricebreak}:$sellprice ";
+ $pricegroup = 1;
+ }
+ }
+
+ if (! $customerprice && ! $pricegroup) {
+ $ref->{sellprice} = $sellprice unless $mref->{pricebreak};
+ $ref->{pricematrix} .= "$mref->{pricebreak}:$sellprice ";
+ }
+
+ if ($form->{tradediscount}) {
+ $ref->{sellprice} = $form->round_amount($ref->{sellprice} / (1 - $form->{tradediscount}), $decimalplaces);
+ }
+
+ }
+ $pmh->finish;
+
+ if ($ref->{pricematrix} !~ /^0:/) {
+ if ($init) {
+ $sellprice = $form->round_amount($ref->{sellprice}, $decimalplaces);
+ } else {
+ $sellprice = $form->round_amount($ref->{sellprice} * (1 - $form->{tradediscount}), $decimalplaces);
+ }
+ $ref->{pricematrix} = "0:$sellprice ".$ref->{pricematrix};
+ }
+ chop $ref->{pricematrix};
+
+}
+
+
+sub exchangerate_defaults {
+ my ($dbh, $form) = @_;
+
+ my $var;
+
+ # get default currencies
+ my $query = qq|SELECT substr(curr,1,3), curr FROM defaults|;
+ my $eth = $dbh->prepare($query) || $form->dberror($query);
+ $eth->execute;
+ ($form->{defaultcurrency}, $form->{currencies}) = $eth->fetchrow_array;
+ $eth->finish;
+
+ $query = qq|SELECT buy
+ FROM exchangerate
+ WHERE curr = ?
+ AND transdate = ?|;
+ my $eth1 = $dbh->prepare($query) || $form->dberror($query);
+
+ $query = qq~SELECT max(transdate || ' ' || buy || ' ' || curr)
+ FROM exchangerate
+ WHERE curr = ?~;
+ my $eth2 = $dbh->prepare($query) || $form->dberror($query);
+
+ # get exchange rates for transdate or max
+ foreach $var (split /:/, substr($form->{currencies},4)) {
+ $eth1->execute($var, $form->{transdate});
+ ($form->{$var}) = $eth1->fetchrow_array;
+ if (! $form->{$var} ) {
+ $eth2->execute($var);
+
+ ($form->{$var}) = $eth2->fetchrow_array;
+ ($null, $form->{$var}) = split / /, $form->{$var};
+ $form->{$var} = 1 unless $form->{$var};
+ $eth2->finish;
+ }
+ $eth1->finish;
+ }
+
+ $form->{$form->{defaultcurrency}} = 1;
+
+}
+
+
1;
diff --git a/sql-ledger/SL/Inifile.pm b/sql-ledger/SL/Inifile.pm
index e9de47a8f..8ccf4334d 100644
--- a/sql-ledger/SL/Inifile.pm
+++ b/sql-ledger/SL/Inifile.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2002
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -12,7 +12,7 @@
# 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
@@ -35,7 +35,8 @@ sub new {
my $id = "";
my $skip;
-
+
+ $self ||= {};
$type = ref($self) || $self;
open FH, "$file" or Form->error("$file : $!");
diff --git a/sql-ledger/SL/Mailer.pm b/sql-ledger/SL/Mailer.pm
index 934ad3690..712b1d727 100644
--- a/sql-ledger/SL/Mailer.pm
+++ b/sql-ledger/SL/Mailer.pm
@@ -1,12 +1,12 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2002
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
-# Contributors:
+# 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
@@ -21,6 +21,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#======================================================================
+#
+# mailer package
+#
+#======================================================================
package Mailer;
@@ -54,7 +58,15 @@ sub send {
my ($cc, $bcc);
$cc = "Cc: $self->{cc}\n" if $self->{cc};
$bcc = "Bcc: $self->{bcc}\n" if $self->{bcc};
-
+
+ foreach my $item (qw(from to cc bcc)) {
+ $self->{$item} =~ s/\\_/_/g;
+ $self->{$item} =~ s/\&lt;/</g;
+ $self->{$item} =~ s/\$<\$/</g;
+ $self->{$item} =~ s/\&gt;/>/g;
+ $self->{$item} =~ s/\$>\$/>/g;
+ }
+
print OUT qq|From: $self->{from}
To: $self->{to}
${cc}${bcc}Subject: $self->{subject}
@@ -67,12 +79,15 @@ MIME-Version: 1.0
if ($self->{attachments}) {
print OUT qq|Content-Type: multipart/mixed; boundary="$boundary"
---${boundary}
+|;
+ if ($self->{message}) {
+ print OUT qq|--${boundary}
Content-Type: $self->{contenttype}; charset="$self->{charset}"
$self->{message}
|;
+ }
foreach my $attachment (@{ $self->{attachments} }) {
diff --git a/sql-ledger/SL/Menu.pm b/sql-ledger/SL/Menu.pm
index 661d35408..0df3067aa 100644
--- a/sql-ledger/SL/Menu.pm
+++ b/sql-ledger/SL/Menu.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2002
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -12,7 +12,7 @@
# 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
@@ -35,13 +35,13 @@ sub new {
use SL::Inifile;
my $self = Inifile->new($menufile, $level);
- bless $self, $type;
+ bless $self, $type if $self;
}
sub menuitem {
- my ($self, $myconfig, $form, $item) = @_;
+ my ($self, $myconfig, $form, $item, $level) = @_;
my $module = $form->{script};
my $action = "section_menu";
@@ -56,9 +56,10 @@ sub menuitem {
if ($self->{$item}{target}) {
$target = $self->{$item}{target};
}
+
+ $level = $form->escape($item);
+ my $str = qq|<a href=$module?path=$form->{path}&action=$action&level=$level&login=$form->{login}&timeout=$form->{timeout}&sessionid=$form->{sessionid}|;
- my $level = $form->escape($item);
- my $str = qq|<a href=$module?path=$form->{path}&action=$action&level=$level&login=$form->{login}&password=$form->{password}|;
my @vars = qw(module action target href);
if ($self->{$item}{href}) {
@@ -68,20 +69,23 @@ sub menuitem {
map { delete $self->{$item}{$_} } @vars;
-
+ delete $self->{$item}{submenu};
+
# add other params
foreach my $key (keys %{ $self->{$item} }) {
- $str .= "&".$form->escape($key,1)."=";
+ $str .= "&".$form->escape($key)."=";
($value, $conf) = split /=/, $self->{$item}{$key}, 2;
$value = $myconfig->{$value}."/$conf" if ($conf);
- $str .= $form->escape($value, 1);
+ $str .= $form->escape($value);
}
+ $str .= qq|#id$form->{tag}| if $target eq 'acc_menu';
+
if ($target) {
$str .= qq| target=$target|;
}
-
- $str .= ">";
+
+ $str .= qq|>|;
}
diff --git a/sql-ledger/SL/Num2text.pm b/sql-ledger/SL/Num2text.pm
index f09121c23..06eee7183 100644
--- a/sql-ledger/SL/Num2text.pm
+++ b/sql-ledger/SL/Num2text.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2002
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -77,7 +77,7 @@ sub num2text {
my @textnumber = ();
# split amount into chunks of 3
- my @num = reverse split //, $amount;
+ my @num = reverse split //, abs($amount);
my @numblock = ();
my @a;
my $i;
diff --git a/sql-ledger/SL/OE.pm b/sql-ledger/SL/OE.pm
index a742ca7a2..dfa424c31 100644
--- a/sql-ledger/SL/OE.pm
+++ b/sql-ledger/SL/OE.pm
@@ -23,6 +23,7 @@
#======================================================================
#
# Order entry module
+# Quotation
#
#======================================================================
@@ -36,46 +37,133 @@ sub transactions {
my $dbh = $form->dbconnect($myconfig);
my $query;
+ my $ordnumber = 'ordnumber';
+ my $quotation = '0';
+ my ($null, $department_id) = split /--/, $form->{department};
+ my $department = " AND o.department_id = $department_id" if $department_id;
+
my $rate = ($form->{vc} eq 'customer') ? 'buy' : 'sell';
+
+ ($form->{transdatefrom}, $form->{transdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
+
+ if ($form->{type} =~ /_quotation$/) {
+ $quotation = '1';
+ $ordnumber = 'quonumber';
+ }
+ my $number = $form->like(lc $form->{$ordnumber});
+ my $name = $form->like(lc $form->{$form->{vc}});
+
my $query = qq|SELECT o.id, o.ordnumber, o.transdate, o.reqdate,
o.amount, ct.name, o.netamount, o.$form->{vc}_id,
- (SELECT $rate FROM exchangerate ex
- WHERE ex.curr = o.curr
- AND ex.transdate = o.transdate) AS exchangerate,
- o.closed
- FROM oe o, $form->{vc} ct
- WHERE o.$form->{vc}_id = ct.id|;
-
- my $ordnumber = $form->like(lc $form->{ordnumber});
+ ex.$rate AS exchangerate,
+ o.closed, o.quonumber, o.shippingpoint, o.shipvia,
+ e.name AS employee, m.name AS manager, o.curr
+ FROM oe o
+ JOIN $form->{vc} ct ON (o.$form->{vc}_id = ct.id)
+ LEFT JOIN employee e ON (o.employee_id = e.id)
+ LEFT JOIN employee m ON (e.managerid = m.id)
+ LEFT JOIN exchangerate ex ON (ex.curr = o.curr
+ AND ex.transdate = o.transdate)
+ WHERE o.quotation = '$quotation'
+ $department|;
+
+ my %ordinal = ( 'id' => 1,
+ 'ordnumber' => 2,
+ 'transdate' => 3,
+ 'reqdate' => 4,
+ 'name' => 6,
+ 'quonumber' => 11,
+ 'shipvia' => 13,
+ 'employee' => 14,
+ 'manager' => 15
+ );
+
+ my @a = (transdate, $ordnumber, name);
+ push @a, "employee" if $form->{l_employee};
+ if ($form->{type} !~ /(ship|receive)_order/) {
+ push @a, "manager" if $form->{l_manager};
+ }
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ # build query if type eq (ship|receive)_order
+ if ($form->{type} =~ /(ship|receive)_order/) {
+
+ my ($warehouse, $warehouse_id) = split /--/, $form->{warehouse};
+
+ $query = qq|SELECT DISTINCT o.id, o.ordnumber, o.transdate,
+ o.reqdate, o.amount, ct.name, o.netamount, o.$form->{vc}_id,
+ ex.$rate AS exchangerate,
+ o.closed, o.quonumber, o.shippingpoint, o.shipvia,
+ e.name AS employee, o.curr
+ FROM oe o
+ JOIN $form->{vc} ct ON (o.$form->{vc}_id = ct.id)
+ JOIN orderitems oi ON (oi.trans_id = o.id)
+ JOIN parts p ON (p.id = oi.parts_id)|;
+
+ if ($warehouse_id && $form->{type} eq 'ship_order') {
+ $query .= qq|
+ JOIN inventory i ON (oi.parts_id = i.parts_id)
+ |;
+ }
+
+ $query .= qq|
+ LEFT JOIN employee e ON (o.employee_id = e.id)
+ LEFT JOIN exchangerate ex ON (ex.curr = o.curr
+ AND ex.transdate = o.transdate)
+ WHERE o.quotation = '0'
+ AND (p.inventory_accno_id > 0 OR p.assembly = '1')
+ AND oi.qty != oi.ship
+ $department|;
+
+ if ($warehouse_id && $form->{type} eq 'ship_order') {
+ $query .= qq|
+ AND i.warehouse_id = $warehouse_id
+ AND i.qty >= (oi.qty - oi.ship)
+ |;
+ }
+
+ }
+
if ($form->{"$form->{vc}_id"}) {
$query .= qq| AND o.$form->{vc}_id = $form->{"$form->{vc}_id"}|;
} else {
if ($form->{$form->{vc}}) {
- my $name = $form->like(lc $form->{$form->{vc}});
- $query .= " AND lower(name) LIKE '$name'";
+ $query .= " AND lower(ct.name) LIKE '$name'";
}
}
- unless ($form->{open} && $form->{closed}) {
+ 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'";
}
- my $sortorder = join ', ', $form->sort_columns(qw(transdate ordnumber name));
- $sortorder = $form->{sort} unless $sortorder;
-
- $query .= " AND lower(ordnumber) LIKE '$ordnumber'" if $form->{ordnumber};
- $query .= " AND transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
- $query .= " AND transdate <= '$form->{transdateto}'" if $form->{transdateto};
+ if ($form->{$ordnumber}) {
+ $query .= " AND lower($ordnumber) LIKE '$number'";
+ }
+ if ($form->{shipvia}) {
+ $var = $form->like(lc $form->{shipvia});
+ $query .= " AND lower(o.shipvia) LIKE '$var'";
+ }
+ if ($form->{transdatefrom}) {
+ $query .= " AND o.transdate >= '$form->{transdatefrom}'";
+ }
+ if ($form->{transdateto}) {
+ $query .= " AND o.transdate <= '$form->{transdateto}'";
+ }
+
$query .= " ORDER by $sortorder";
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $oe = $sth->fetchrow_hashref(NAME_lc)) {
- $oe->{exchangerate} = 1 unless $oe->{exchangerate};
- push @{ $form->{OE} }, $oe;
+ my %id = ();
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $ref->{exchangerate} = 1 unless $ref->{exchangerate};
+ push @{ $form->{OE} }, $ref if $ref->{id} != $id{$ref->{id}};
+ $id{$ref->{id}} = $ref->{id};
}
$sth->finish;
@@ -84,17 +172,29 @@ sub transactions {
}
-sub save_order {
+sub save {
my ($self, $myconfig, $form) = @_;
# connect to database, turn off autocommit
my $dbh = $form->dbconnect_noauto($myconfig);
- my ($query, $sth);
+ my $query;
+ my $sth;
+ my $null;
my $exchangerate = 0;
+ ($null, $form->{employee_id}) = split /--/, $form->{employee};
+ unless ($form->{employee_id}) {
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh);
+ $form->{employee} = "$form->{employee}--$form->{employee_id}";
+ }
+
+ my $ml = ($form->{type} eq 'sales_order') ? 1 : -1;
+
if ($form->{id}) {
-
+
+ &adj_onhand($dbh, $form, $ml) if $form->{type} =~ /_order$/;
+
$query = qq|DELETE FROM orderitems
WHERE trans_id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
@@ -108,8 +208,7 @@ sub save_order {
$uid .= $form->{login};
$query = qq|INSERT INTO oe (ordnumber, employee_id)
- VALUES ('$uid', (SELECT id FROM employee
- WHERE login = '$form->{login}') )|;
+ VALUES ('$uid', $form->{employee_id})|;
$dbh->do($query) || $form->dberror($query);
$query = qq|SELECT id FROM oe
@@ -119,28 +218,30 @@ sub save_order {
($form->{id}) = $sth->fetchrow_array;
$sth->finish;
+
}
- map { $form->{$_} =~ s/'/''/g } qw(ordnumber shippingpoint notes message);
-
- my ($amount, $linetotal, $discount, $project_id, $reqdate);
- my ($taxrate, $taxamount, $fxsellprice);
- my %taxbase = ();
- my %taxaccounts = ();
- my ($netamount, $tax) = (0, 0);
+ my $amount;
+ my $linetotal;
+ my $discount;
+ my $project_id;
+ my $taxrate;
+ my $taxamount;
+ my $fxsellprice;
+ my %taxbase;
+ my @taxaccounts;
+ my %taxaccounts;
+ my $netamount = 0;
for my $i (1 .. $form->{rowcount}) {
-
- $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
-
- if ($form->{"qty_$i"} != 0) {
-
- map { $form->{"${_}_$i"} =~ s/'/''/g } qw(partnumber description unit);
-
- # set values to 0 if nothing entered
- $form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
- $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+ map { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) } qw(qty ship);
+
+ $form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
+ $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
+
+ if ($form->{"qty_$i"}) {
+
$fxsellprice = $form->{"sellprice_$i"};
my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
@@ -150,9 +251,16 @@ sub save_order {
$discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}, $decimalplaces);
$form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces);
+ $form->{"inventory_accno_$i"} *= 1;
+ $form->{"expense_accno_$i"} *= 1;
+
$linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
+
+ @taxaccounts = split / /, $form->{"taxaccounts_$i"};
$taxrate = 0;
- map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
+ $taxdiff = 0;
+
+ map { $taxrate += $form->{"${_}_rate"} } @taxaccounts;
if ($form->{taxincluded}) {
$taxamount = $linetotal * $taxrate / (1 + $taxrate);
@@ -164,28 +272,54 @@ sub save_order {
$taxbase = $linetotal;
}
- if ($taxamount != 0) {
- foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
+ if (@taxaccounts && $form->round_amount($taxamount, 2) == 0) {
+ if ($form->{taxincluded}) {
+ foreach $item (@taxaccounts) {
+ $taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
+
+ $taxaccounts{$item} += $taxamount;
+ $taxdiff += $taxamount;
+
+ $taxbase{$item} += $taxbase;
+ }
+ $taxaccounts{$taxaccounts[0]} += $taxdiff;
+ } else {
+ foreach $item (@taxaccounts) {
+ $taxaccounts{$item} += $linetotal * $form->{"${item}_rate"};
+ $taxbase{$item} += $taxbase;
+ }
+ }
+ } else {
+ foreach $item (@taxaccounts) {
$taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
$taxbase{$item} += $taxbase;
}
}
-
+
+
$netamount += $form->{"sellprice_$i"} * $form->{"qty_$i"};
$project_id = 'NULL';
- if ($form->{"project_id_$i"}) {
- $project_id = $form->{"project_id_$i"};
+ if ($form->{"projectnumber_$i"}) {
+ ($null, $project_id) = split /--/, $form->{"projectnumber_$i"};
+ $project_id *= 1;
}
- $reqdate = ($form->{"reqdate_$i"}) ? qq|'$form->{"reqdate_$i"}'| : "NULL";
# save detail record in orderitems table
- $query = qq|INSERT INTO orderitems
- (trans_id, parts_id, description, qty, sellprice, discount,
- unit, reqdate, project_id) VALUES (
- $form->{id}, $form->{"id_$i"}, '$form->{"description_$i"}',
- $form->{"qty_$i"}, $fxsellprice, $form->{"discount_$i"},
- '$form->{"unit_$i"}', $reqdate, $project_id)|;
+ $query = qq|INSERT INTO orderitems (|;
+ $query .= "id, " if $form->{"orderitems_id_$i"};
+ $query .= qq|trans_id, parts_id, description, qty, sellprice, discount,
+ unit, reqdate, project_id, serialnumber, ship)
+ VALUES (|;
+ $query .= qq|$form->{"orderitems_id_$i"},| if $form->{"orderitems_id_$i"};
+ $query .= qq|$form->{id}, $form->{"id_$i"}, |
+ .$dbh->quote($form->{"description_$i"}).qq|,
+ $form->{"qty_$i"}, $fxsellprice, $form->{"discount_$i"}, |
+ .$dbh->quote($form->{"unit_$i"}).qq|, |
+ .$form->dbquote($form->{"reqdate_$i"}, SQL_DATE).qq|,
+ $project_id, |
+ .$dbh->quote($form->{"serialnumber_$i"}).qq|,
+ $form->{"ship_$i"})|;
$dbh->do($query) || $form->dberror($query);
$form->{"sellprice_$i"} = $fxsellprice;
@@ -195,15 +329,11 @@ sub save_order {
# set values which could be empty
- map { $form->{$_} *= 1 } qw(vendor_id customer_id taxincluded closed);
+ map { $form->{$_} *= 1 } qw(vendor_id customer_id taxincluded closed quotation);
- $reqdate = ($form->{reqdate}) ? qq|'$form->{reqdate}'| : "NULL";
-
# add up the tax
- foreach my $item (sort keys %taxaccounts) {
- $taxamount = $form->round_amount($taxaccounts{$item}, 2);
- $tax += $taxamount;
- }
+ 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);
@@ -216,33 +346,32 @@ sub save_order {
$form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
- # fill in subject if there is none
- $form->{subject} = qq|$form->{label} $form->{ordnumber}| unless $form->{subject};
- # if there is a message stuff it into the notes
- my $cc = "Cc: $form->{cc}\\r\n" if $form->{cc};
- my $bcc = "Bcc: $form->{bcc}\\r\n" if $form->{bcc};
- $form->{notes} .= qq|\r
-\r
-[email]\r
-To: $form->{email}\r
-$cc${bcc}Subject: $form->{subject}\r
-\r
-Message: $form->{message}\r| if $form->{message};
+ my $quotation = ($form->{type} =~ /_order$/) ? '0' : '1';
+
+ ($null, $form->{department_id}) = split(/--/, $form->{department});
+ $form->{department_id} *= 1;
# save OE record
$query = qq|UPDATE oe set
- ordnumber = '$form->{ordnumber}',
- transdate = '$form->{orddate}',
+ ordnumber = |.$dbh->quote($form->{ordnumber}).qq|,
+ quonumber = |.$dbh->quote($form->{quonumber}).qq|,
+ transdate = '$form->{transdate}',
vendor_id = $form->{vendor_id},
customer_id = $form->{customer_id},
amount = $amount,
netamount = $netamount,
- reqdate = $reqdate,
+ reqdate = |.$form->dbquote($form->{reqdate}, SQL_DATE).qq|,
taxincluded = '$form->{taxincluded}',
- shippingpoint = '$form->{shippingpoint}',
- notes = '$form->{notes}',
+ shippingpoint = |.$dbh->quote($form->{shippingpoint}).qq|,
+ shipvia = |.$dbh->quote($form->{shipvia}).qq|,
+ notes = |.$dbh->quote($form->{notes}).qq|,
+ intnotes = |.$dbh->quote($form->{intnotes}).qq|,
curr = '$form->{currency}',
- closed = '$form->{closed}'
+ closed = '$form->{closed}',
+ quotation = '$quotation',
+ department_id = $form->{department_id},
+ employee_id = $form->{employee_id},
+ language_code = '$form->{language_code}'
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
@@ -252,16 +381,34 @@ Message: $form->{message}\r| if $form->{message};
$form->{name} = $form->{$form->{vc}};
$form->{name} =~ s/--$form->{"$form->{vc}_id"}//;
$form->add_shipto($dbh, $form->{id});
-
+
+ # save printed, emailed, queued
+ $form->save_status($dbh);
+
if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
if ($form->{vc} eq 'customer') {
- $form->update_exchangerate($dbh, $form->{currency}, $form->{orddate}, $form->{exchangerate}, 0);
+ $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $form->{exchangerate}, 0);
}
if ($form->{vc} eq 'vendor') {
- $form->update_exchangerate($dbh, $form->{currency}, $form->{orddate}, 0, $form->{exchangerate});
+ $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, 0, $form->{exchangerate});
}
}
+
+ if ($form->{type} =~ /_order$/) {
+ # adjust onhand
+ &adj_onhand($dbh, $form, $ml * -1);
+ &adj_inventory($dbh, $myconfig, $form);
+ }
+
+ my %audittrail = ( tablename => 'oe',
+ reference => ($form->{type} =~ /_order$/) ? $form->{ordnumber} : $form->{quonumber},
+ formname => $form->{type},
+ action => 'saved',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
+
my $rc = $dbh->commit;
$dbh->disconnect;
@@ -271,38 +418,56 @@ Message: $form->{message}\r| if $form->{message};
-sub delete_order {
- my ($self, $myconfig, $form) = @_;
+sub delete {
+ my ($self, $myconfig, $form, $spool) = @_;
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
- my $query;
+ # delete spool files
+ my $query = qq|SELECT spoolfile FROM status
+ WHERE trans_id = $form->{id}
+ AND spoolfile IS NOT NULL|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
- # can't use $form->delete_exchangerate
- if ($form->{currency} ne $form->{defaultcurrency}) {
- $query = qq|SELECT transdate FROM acc_trans
- WHERE ar.id = trans_id
- AND ar.curr = '$form->{currency}'
- AND transdate = '$form->{orddate}'
- UNION SELECT transdate FROM acc_trans
- WHERE ap.id = trans_id
- AND ap.curr = '$form->{currency}'
- AND transdate = '$form->{orddate}'|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- my ($transdate) = $sth->fetchrow_array;
- $sth->finish;
+ my $spoolfile;
+ my @spoolfiles = ();
+
+ while (($spoolfile) = $sth->fetchrow_array) {
+ push @spoolfiles, $spoolfile;
+ }
+ $sth->finish;
+
+
+ $query = qq|SELECT o.parts_id, o.ship, p.inventory_accno_id
+ FROM orderitems o
+ JOIN parts p ON (p.id = o.parts_id)
+ WHERE trans_id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
- if (!$transdate) {
- $query = qq|DELETE FROM exchangerate
- WHERE curr = '$form->{currency}'
- AND transdate = '$form->{orddate}'|;
- $dbh->do($query) || $self->dberror($query);
+ if ($form->{type} =~ /_order$/) {
+ $ml = ($form->{type} eq 'purchase_order') ? -1 : 1;
+ while (my ($id, $ship, $inv) = $sth->fetchrow_array) {
+ $form->update_balance($dbh,
+ "parts",
+ "onhand",
+ qq|id = $id|,
+ $ship * $ml) if $inv;
}
}
-
+ $sth->finish;
+
+ # delete inventory
+ $query = qq|DELETE FROM inventory
+ WHERE oe_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ # delete status entries
+ $query = qq|DELETE FROM status
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
# delete OE record
$query = qq|DELETE FROM oe
@@ -318,22 +483,37 @@ sub delete_order {
WHERE trans_id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
+ my %audittrail = ( tablename => 'oe',
+ reference => ($form->{type} =~ /_order$/) ? $form->{ordnumber} : $form->{quonumber},
+ formname => $form->{type},
+ action => 'deleted',
+ id => $form->{id} );
+
+ $form->audittrail($dbh, "", \%audittrail);
+
my $rc = $dbh->commit;
$dbh->disconnect;
+ if ($rc) {
+ foreach $spoolfile (@spoolfiles) {
+ unlink "$spool/$spoolfile" if $spoolfile;
+ }
+ }
+
$rc;
}
-sub retrieve_order {
+sub retrieve {
my ($self, $myconfig, $form) = @_;
# connect to database
- my $dbh = $form->dbconnect_noauto($myconfig);
+ my $dbh = $form->dbconnect($myconfig);
my $query;
+ my $var;
if ($form->{id}) {
# get default accounts and last order number
@@ -350,7 +530,6 @@ sub retrieve_order {
d.curr AS currencies
FROM defaults d|;
} else {
- my $ordnumber = ($form->{vc} eq 'customer') ? 'sonumber' : 'ponumber';
$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
@@ -361,8 +540,8 @@ sub retrieve_order {
WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
(SELECT c.accno FROM chart c
WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
- $ordnumber AS ordnumber, d.curr AS currencies,
- current_date AS orddate, current_date AS reqdate
+ d.curr AS currencies,
+ current_date AS transdate
FROM defaults d|;
}
my $sth = $dbh->prepare($query);
@@ -372,20 +551,21 @@ sub retrieve_order {
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
- ($form->{currency}) = split /:/, $form->{currencies};
if ($form->{id}) {
# retrieve order
- $query = qq|SELECT o.ordnumber, o.transdate AS orddate, o.reqdate,
- o.taxincluded, o.shippingpoint, o.notes, o.curr AS currency,
- (SELECT name FROM employee e
- WHERE e.id = o.employee_id) AS employee,
+ $query = qq|SELECT o.ordnumber, o.transdate, o.reqdate,
+ o.taxincluded, o.shippingpoint, o.shipvia, o.notes, o.intnotes,
+ o.curr AS currency, e.name AS employee, o.employee_id,
o.$form->{vc}_id, cv.name AS $form->{vc}, o.amount AS invtotal,
- o.closed, o.reqdate
- FROM oe o, $form->{vc} cv
- WHERE o.$form->{vc}_id = cv.id
- AND o.id = $form->{id}|;
+ o.closed, o.reqdate, o.quonumber, o.department_id,
+ d.description AS department, o.language_code
+ FROM oe o
+ JOIN $form->{vc} cv ON (o.$form->{vc}_id = cv.id)
+ LEFT JOIN employee e ON (o.employee_id = e.id)
+ LEFT JOIN department d ON (o.department_id = d.id)
+ WHERE o.id = $form->{id}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -402,20 +582,41 @@ sub retrieve_order {
$ref = $sth->fetchrow_hashref(NAME_lc);
map { $form->{$_} = $ref->{$_} } keys %$ref;
$sth->finish;
-
+
+ # get printed, emailed and queued
+ $query = qq|SELECT s.printed, s.emailed, s.spoolfile, s.formname
+ FROM status s
+ WHERE s.trans_id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ $form->{printed} .= "$ref->{formname} " if $ref->{printed};
+ $form->{emailed} .= "$ref->{formname} " if $ref->{emailed};
+ $form->{queued} .= "$ref->{formname} $ref->{spoolfile} " if $ref->{spoolfile};
+ }
+ $sth->finish;
+ map { $form->{$_} =~ s/ +$//g } qw(printed emailed queued);
+
+
my %oid = ( 'Pg' => 'oid',
+ 'PgPP' => 'oid',
'Oracle' => 'rowid',
- 'DB2' => '' );
+ 'DB2' => '1=1'
+ );
# retrieve individual items
- $query = qq|SELECT c1.accno AS inventory_accno,
- c2.accno AS income_accno,
- c3.accno AS expense_accno,
+ $query = qq|SELECT o.id AS orderitems_id,
+ c1.accno AS inventory_accno,
+ c2.accno AS income_accno,
+ c3.accno AS expense_accno,
p.partnumber, p.assembly, o.description, o.qty,
o.sellprice, o.parts_id AS id, o.unit, o.discount, p.bin,
- o.reqdate, o.project_id,
+ o.reqdate, o.project_id, o.serialnumber, o.ship,
pr.projectnumber,
- pg.partsgroup
+ pg.partsgroup, p.partsgroup_id, p.partnumber AS sku,
+ p.listprice, p.lastcost, p.weight,
+ t.description AS partsgrouptranslation
FROM orderitems o
JOIN parts p ON (o.parts_id = p.id)
LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
@@ -423,116 +624,401 @@ sub retrieve_order {
LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
LEFT JOIN project pr ON (o.project_id = pr.id)
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
- WHERE trans_id = $form->{id}
+ LEFT JOIN translation t ON (t.trans_id = p.partsgroup_id AND t.language_code = '$form->{language_code}')
+ WHERE o.trans_id = $form->{id}
ORDER BY o.$oid{$myconfig->{dbdriver}}|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
+ # foreign exchange rates
+ &exchangerate_defaults($dbh, $form);
+
+ # query for price matrix
+ my $pmh = &price_matrix_query($dbh, $form);
+
+ # taxes
+ $query = qq|SELECT c.accno
+ FROM chart c
+ JOIN partstax pt ON (pt.chart_id = c.id)
+ WHERE pt.parts_id = ?|;
+ my $tth = $dbh->prepare($query) || $form->dberror($query);
+
+ my $taxrate;
+ my $ptref;
+ my $sellprice;
+ my $listprice;
+
while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
- # get tax rates for part
- $query = qq|SELECT c.accno
- FROM chart c, partstax pt
- WHERE pt.chart_id = c.id
- AND pt.parts_id = $ref->{id}|;
- my $pth = $dbh->prepare($query);
- $pth->execute || $form->dberror($query);
+ ($decimalplaces) = ($ref->{sellprice} =~ /\.(\d+)/);
+ $decimalplaces = length $decimalplaces;
+ $decimalplaces = 2 unless $decimalplaces;
+ $tth->execute($ref->{id});
$ref->{taxaccounts} = "";
- my $taxrate = 0;
+ $taxrate = 0;
- while (my $ptref = $pth->fetchrow_hashref(NAME_lc)) {
+ while ($ptref = $tth->fetchrow_hashref(NAME_lc)) {
$ref->{taxaccounts} .= "$ptref->{accno} ";
$taxrate += $form->{"$ptref->{accno}_rate"};
}
- $pth->finish;
+ $tth->finish;
chop $ref->{taxaccounts};
- push @{ $form->{order_details} }, $ref;
+ # preserve prices
+ $sellprice = $ref->{sellprice};
+ $listprice = $ref->{listprice};
+
+ # multiply by exchangerate
+ $ref->{sellprice} = $form->round_amount($ref->{sellprice} * $form->{$form->{currency}}, $decimalplaces);
+ $ref->{listprice} = $form->round_amount($ref->{listprice} * $form->{$form->{currency}}, $decimalplaces);
+
+ # partnumber and price matrix
+ &price_matrix($pmh, $ref, $form->{transdate}, $decimalplaces, $form, $myconfig, 1);
+
+ $ref->{sellprice} = $sellprice;
+ $ref->{listprice} = $listprice;
+
+ $ref->{partsgroup} = $ref->{partsgrouptranslation} if $ref->{partsgrouptranslation};
+
+ push @{ $form->{form_details} }, $ref;
}
$sth->finish;
} else {
- my $ordnumber = ($form->{vc} eq 'customer') ? 'sonumber' : 'ponumber';
- # up order number by 1
- $form->{ordnumber}++;
-
- # save the new number
- $query = qq|UPDATE defaults
- SET $ordnumber = '$form->{ordnumber}'|;
- $dbh->do($query) || $form->dberror($query);
-
- $form->get_employee($dbh);
-
# get last name used
$form->lastname_used($dbh, $myconfig, $form->{vc}) unless $form->{"$form->{vc}_id"};
+ delete $form->{notes};
}
+
+ $dbh->disconnect;
+
+}
+
+
+sub price_matrix_query {
+ my ($dbh, $form) = @_;
+
+ my $query;
+ my $sth;
+
+ if ($form->{customer_id}) {
+ $query = qq|SELECT p.*, g.pricegroup
+ FROM partscustomer p
+ LEFT JOIN pricegroup g ON (g.id = p.pricegroup_id)
+ WHERE p.parts_id = ?
+ AND p.customer_id = $form->{customer_id}
+
+ UNION
+
+ SELECT p.*, g.pricegroup
+ FROM partscustomer p
+ LEFT JOIN pricegroup g ON (g.id = p.pricegroup_id)
+ JOIN customer c ON (c.pricegroup_id = g.id)
+ WHERE p.parts_id = ?
+ AND c.id = $form->{customer_id}
+
+ UNION
+
+ SELECT p.*, '' AS pricegroup
+ FROM partscustomer p
+ WHERE p.customer_id = 0
+ AND p.pricegroup_id = 0
+ AND p.parts_id = ?
+
+ ORDER BY customer_id DESC, pricegroup_id DESC, pricebreak
+ |;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+ }
- $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{orddate}, ($form->{vc} eq 'customer') ? "buy" : "sell");
+ if ($form->{vendor_id}) {
+ # price matrix and vendor's partnumber
+ $query = qq|SELECT partnumber
+ FROM partsvendor
+ WHERE parts_id = ?
+ AND vendor_id = $form->{vendor_id}|;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+ }
- my $rc = $dbh->commit;
- $dbh->disconnect;
+ $sth;
- $rc;
+}
+
+
+sub price_matrix {
+ my ($pmh, $ref, $transdate, $decimalplaces, $form, $myconfig, $init) = @_;
+
+ $ref->{pricematrix} = "";
+ my $customerprice = 0;
+ my $pricegroup = 0;
+ my $sellprice;
+ my $mref;
+ # depends if this is a customer or vendor
+ if ($form->{customer_id}) {
+ $pmh->execute($ref->{id}, $ref->{id}, $ref->{id});
+
+ while ($mref = $pmh->fetchrow_hashref(NAME_lc)) {
+
+ # check date
+ if ($mref->{validfrom}) {
+ next if $transdate < $form->datetonum($mref->{validfrom}, $myconfig);
+ }
+ if ($mref->{validto}) {
+ next if $transdate > $form->datetonum($mref->{validto}, $myconfig);
+ }
+
+ # convert price
+ $sellprice = $form->round_amount($mref->{sellprice} * $form->{$mref->{curr}}, $decimalplaces);
+
+ if ($mref->{customer_id}) {
+ $ref->{sellprice} = $sellprice unless $mref->{pricebreak};
+ $ref->{pricematrix} .= "$mref->{pricebreak}:$sellprice ";
+ $customerprice = 1;
+ }
+
+ if ($mref->{pricegroup_id}) {
+ if (! $customerprice) {
+ $ref->{sellprice} = $sellprice unless $mref->{pricebreak};
+ $ref->{pricematrix} .= "$mref->{pricebreak}:$sellprice ";
+ $pricegroup = 1;
+ }
+ }
+
+ if (! $customerprice && ! $pricegroup) {
+ $ref->{sellprice} = $sellprice unless $mref->{pricebreak};
+ $ref->{pricematrix} .= "$mref->{pricebreak}:$sellprice ";
+ }
+
+ }
+ $pmh->finish;
+
+ if ($ref->{pricematrix} !~ /^0:/) {
+ if ($init) {
+ $sellprice = $form->round_amount($ref->{sellprice}, $decimalplaces);
+ } else {
+ $sellprice = $form->round_amount($ref->{sellprice} * (1 - $form->{tradediscount}), $decimalplaces);
+ }
+ $ref->{pricematrix} = "0:$sellprice ".$ref->{pricematrix};
+ }
+ chop $ref->{pricematrix};
+
+ }
+
+
+ if ($form->{vendor_id}) {
+ $pmh->execute($ref->{id});
+
+ $mref = $pmh->fetchrow_hashref(NAME_lc);
+
+ if ($mref->{partnumber}) {
+ $ref->{partnumber} = $mref->{partnumber};
+ }
+
+ if ($mref->{lastcost}) {
+ # do a conversion
+ $ref->{sellprice} = $form->round_amount($mref->{lastcost} * $form->{$mref->{curr}}, $decimalplaces);
+ }
+ $pmh->finish;
+
+ $ref->{sellprice} *= 1;
+
+ # add 0:price to matrix
+ $ref->{pricematrix} = "0:$ref->{sellprice}";
+
+ }
+
}
+sub exchangerate_defaults {
+ my ($dbh, $form) = @_;
+
+ my $var;
+ my $buysell = ($form->{vc} eq "customer") ? "buy" : "sell";
+
+ # get default currencies
+ my $query = qq|SELECT substr(curr,1,3), curr FROM defaults|;
+ my $eth = $dbh->prepare($query) || $form->dberror($query);
+ $eth->execute;
+ ($form->{defaultcurrency}, $form->{currencies}) = $eth->fetchrow_array;
+ $eth->finish;
+
+ $query = qq|SELECT $buysell
+ FROM exchangerate
+ WHERE curr = ?
+ AND transdate = ?|;
+ my $eth1 = $dbh->prepare($query) || $form->dberror($query);
+ $query = qq~SELECT max(transdate || ' ' || $buysell || ' ' || curr)
+ FROM exchangerate
+ WHERE curr = ?~;
+ my $eth2 = $dbh->prepare($query) || $form->dberror($query);
+
+ # get exchange rates for transdate or max
+ foreach $var (split /:/, substr($form->{currencies},4)) {
+ $eth1->execute($var, $form->{transdate});
+ ($form->{$var}) = $eth1->fetchrow_array;
+ if (! $form->{$var} ) {
+ $eth2->execute($var);
+
+ ($form->{$var}) = $eth2->fetchrow_array;
+ ($null, $form->{$var}) = split / /, $form->{$var};
+ $form->{$var} = 1 unless $form->{$var};
+ $eth2->finish;
+ }
+ $eth1->finish;
+ }
+
+ $form->{$form->{defaultcurrency}} = 1;
+
+}
+
sub order_details {
my ($self, $myconfig, $form) = @_;
# connect to database
my $dbh = $form->dbconnect($myconfig);
+ my $query;
+ my $sth;
- my $tax = 0;
my $item;
my $i;
- my @partsgroup = ();
+ my @sortlist = ();
+ my $projectnumber;
+ my $projectnumber_id;
+ my $translation;
my $partsgroup;
- my %oid = ( 'Pg' => 'oid',
- 'Oracle' => 'rowid' );
- # sort items by partsgroup
+ my %oid = ( 'Pg' => 'oid',
+ 'PgPP' => 'oid',
+ 'Oracle' => 'rowid',
+ 'DB2' => '1=1'
+ );
+
+ # sort items by project and partsgroup
for $i (1 .. $form->{rowcount}) {
+ $projectnumber = "";
$partsgroup = "";
- if ($form->{"partsgroup_$i"} && $form->{groupitems}) {
- $form->format_string("partsgroup_$i");
- $partsgroup = $form->{"partsgroup_$i"};
+ $projectnumber_id = 0;
+ if ($form->{"projectnumber_$i"} && $form->{groupprojectnumber}) {
+ ($projectnumber, $projectnumber_id) = split /--/, $form->{"projectnumber_$i"};
+ }
+ if ($form->{"partsgroup_$i"} && $form->{grouppartsgroup}) {
+ ($partsgroup) = split /--/, $form->{"partsgroup_$i"};
}
- push @partsgroup, [ $i, $partsgroup ];
+ push @sortlist, [ $i, "$projectnumber$partsgroup", $projectnumber, $projectnumber_id, $partsgroup ];
+
+ # sort the whole thing by project and group
+ @sortlist = sort { $a->[1] cmp $b->[1] } @sortlist;
+
}
-
+
+ # if there is a warehouse limit picking
+ if ($form->{warehouse_id} && $form->{formname} =~ /(pick|packing)_list/) {
+ # run query to check for inventory
+ $query = qq|SELECT sum(qty) AS qty
+ FROM inventory
+ WHERE parts_id = ?
+ AND warehouse_id = ?|;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ for $i (1 .. $form->{rowcount}) {
+ $sth->execute($form->{"id_$i"}, $form->{warehouse_id}) || $form->dberror;
+
+ ($qty) = $sth->fetchrow_array;
+ $sth->finish;
+
+ $form->{"qty_$i"} = 0 if $qty == 0;
+
+ if ($form->parse_amount($myconfig, $form->{"ship_$i"}) > $qty) {
+ $form->{"ship_$i"} = $form->format_amount($myconfig, $qty);
+ }
+ }
+ }
+
+ my @taxaccounts;
+ my %taxaccounts;
+ my $taxrate;
+ my $taxamount;
+ my $taxbase;
+ my $taxdiff;
+
+ $query = qq|SELECT p.description, t.description
+ FROM project p
+ LEFT JOIN translation t ON (t.trans_id = p.id AND t.language_code = '$form->{language_code}')
+ WHERE id = ?|;
+ my $prh = $dbh->prepare($query) || $form->dberror($query);
+
+ my $runningnumber = 1;
my $sameitem = "";
- foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
+ my $subtotal;
+ my $k = scalar @sortlist;
+ my $j = 0;
+
+ foreach $item (@sortlist) {
$i = $item->[0];
+ $j++;
+
+ if ($form->{groupprojectnumber} || $form->{grouppartsgroup}) {
+ if ($item->[1] ne $sameitem) {
- if ($item->[1] ne $sameitem) {
- push(@{ $form->{description} }, qq|$item->[1]|);
- $sameitem = $item->[1];
+ $projectnumber = "";
+ if ($form->{groupprojectnumber} && $item->[2]) {
+ # get project description
+ $prh->execute($item->[3]) || $form->dberror($query);
+
+ ($projectnumber, $translation) = $prh->fetchrow_array;
+ $prh->finish;
+
+ $projectnumber = ($translation) ? "$item->[2], $translation" : "$item->[2], $projectnumber";
+ }
+
+ if ($form->{grouppartsgroup} && $item->[4]) {
+ $projectnumber .= " / " if $projectnumber;
+ $projectnumber .= $item->[4];
+ }
+
+ $form->{projectnumber} = $projectnumber;
+ $form->format_string(projectnumber);
+
+ push(@{ $form->{description} }, qq|$form->{projectnumber}|);
+ $sameitem = $item->[1];
- map { push(@{ $form->{$_} }, "") } qw(runningnumber number bin qty unit reqdate sellprice listprice netprice discount linetotal);
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber number sku qty ship unit bin serialnumber reqdate projectnumber sellprice listprice netprice discount discountrate linetotal weight);
+ }
}
$form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
if ($form->{"qty_$i"} != 0) {
+ $form->{totalqty} += $form->{"qty_$i"};
+ $form->{totalship} += $form->{"ship_$i"};
+ $form->{totalweight} += ($form->{"weight_$i"} * $form->{"qty_$i"});
+
# add number, description and qty to $form->{number}, ....
- push(@{ $form->{runningnumber} }, $i);
+ push(@{ $form->{runningnumber} }, $runningnumber++);
push(@{ $form->{number} }, qq|$form->{"partnumber_$i"}|);
+ push(@{ $form->{sku} }, qq|$form->{"sku_$i"}|);
push(@{ $form->{description} }, qq|$form->{"description_$i"}|);
push(@{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"}));
+ push(@{ $form->{ship} }, $form->format_amount($myconfig, $form->{"ship_$i"}));
push(@{ $form->{unit} }, qq|$form->{"unit_$i"}|);
+ push(@{ $form->{bin} }, qq|$form->{"bin_$i"}|);
+ push(@{ $form->{serialnumber} }, qq|$form->{"serialnumber_$i"}|);
push(@{ $form->{reqdate} }, qq|$form->{"reqdate_$i"}|);
+ push(@{ $form->{projectnumber} }, qq|$form->{"projectnumber_$i"}|);
push(@{ $form->{sellprice} }, $form->{"sellprice_$i"});
-
+
push(@{ $form->{listprice} }, $form->{"listprice_$i"});
+ push(@{ $form->{weight} }, $form->{"weight_$i"});
+
my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
my ($dec) = ($sellprice =~ /\.(\d+)/);
$dec = length $dec;
@@ -551,13 +1037,16 @@ sub order_details {
$linetotal = ($linetotal != 0) ? $linetotal : " ";
push(@{ $form->{discount} }, $discount);
+ push(@{ $form->{discountrate} }, $form->format_amount($myconfig, $form->{"discount_$i"}));
$form->{ordtotal} += $linetotal;
+ # this is for the subtotals for grouping
+ $subtotal += $linetotal;
+
push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2));
- my ($taxamount, $taxbase);
- my $taxrate = 0;
+ $taxrate = 0;
map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
@@ -571,7 +1060,7 @@ sub order_details {
}
- if ($taxamount != 0) {
+ if ($form->round_amount($taxamount, 2) != 0) {
foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
$taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
$taxbase{$item} += $taxbase;
@@ -579,55 +1068,54 @@ sub order_details {
}
if ($form->{"assembly_$i"}) {
- $sameitem = "";
-
- # get parts and push them onto the stack
- my $sortorder = "";
- if ($form->{groupitems}) {
- $sortorder = qq|ORDER BY pg.partsgroup, a.$oid{$myconfig->{dbdriver}}|;
- } else {
- $sortorder = qq|ORDER BY a.$oid{$myconfig->{dbdriver}}|;
- }
-
- $query = qq|SELECT p.partnumber, p.description, p.unit, a.qty,
- pg.partsgroup
- FROM assembly a
- JOIN parts p ON (a.parts_id = p.id)
- LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
- WHERE a.bom = '1'
- AND a.id = '$form->{"id_$i"}'
- $sortorder|;
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
-
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
- map { push(@{ $form->{$_} }, "") } qw(runningnumber number unit bin qty sellprice listprice netprice discount linetotal);
- $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
- push(@{ $form->{description} }, $sameitem);
+ $form->{stagger} = -1;
+ &assembly_details($dbh, $form, $form->{"id_$i"}, $oid{$myconfig->{dbdriver}}, $form->{"qty_$i"});
+ }
+
+ }
+
+ # add subtotal
+ if ($form->{groupprojectnumber} || $form->{grouppartsgroup}) {
+ if ($subtotal) {
+ if ($j < $k) {
+ # look at next item
+ if ($sortlist[$j]->[1] ne $sameitem) {
+
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber number sku qty ship unit bin serialnumber reqdate projectnumber sellprice listprice netprice discount discountrate weight);
+
+ push(@{ $form->{description} }, $form->{groupsubtotaldescription});
+
+ if (exists $form->{groupsubtotaldescription}) {
+ push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $subtotal, 2));
+ } else {
+ push(@{ $form->{linetotal} }, "");
+ }
+
+ $subtotal = 0;
}
+
+ } else {
+
+ # got last item
+ if (exists $form->{groupsubtotaldescription}) {
- push(@{ $form->{number} }, qq|$ref->{partnumber}|);
- push(@{ $form->{description} }, qq|$ref->{description}|);
- push(@{ $form->{unit} }, qq|$ref->{unit}|);
- push(@{ $form->{qty} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}));
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber number sku qty ship unit bin serialnumber reqdate projectnumber sellprice listprice netprice discount discountrate weight);
- map { push(@{ $form->{$_} }, "") } qw(runningnumber bin sellprice listprice netprice discount linetotal);
-
+ push(@{ $form->{description} }, $form->{groupsubtotaldescription});
+ push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $subtotal, 2));
+ }
}
- $sth->finish;
}
-
}
}
+ my $tax = 0;
foreach $item (sort keys %taxaccounts) {
if ($form->round_amount($taxaccounts{$item}, 2) != 0) {
push(@{ $form->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
- $taxamount = $form->round_amount($taxaccounts{$item}, 2);
- $tax += $taxamount;
+ $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
push(@{ $form->{taxdescription} }, $form->{"${item}_description"});
@@ -636,36 +1124,455 @@ sub order_details {
}
}
-
+ map { $form->{$_} = $form->format_amount($myconfig, $form->{$_}) } qw(totalqty totalship totalweight);
$form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
$form->{ordtotal} = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
+
+ use SL::CP;
+ my $c;
+ if ($form->{language_code}) {
+ $c = new CP $form->{language_code};
+ } else {
+ $c = new CP $myconfig->{countrycode};
+ }
+ $c->init;
+ my $whole;
+ ($whole, $form->{decimal}) = split /\./, $form->{ordtotal};
+ $form->{decimal} .= "00";
+ $form->{decimal} = substr($form->{decimal}, 0, 2);
+ $form->{text_amount} = $c->num2text($whole);
# format amounts
- $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
-
- # myconfig variables
- map { $form->{$_} = $myconfig->{$_} } (qw(company address tel fax signature businessnumber));
- $form->{username} = $myconfig->{name};
+ $form->{quototal} = $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
$dbh->disconnect;
}
+sub assembly_details {
+ my ($dbh, $form, $id, $oid, $qty) = @_;
+
+ my $sm = "";
+ my $spacer;
+
+ $form->{stagger}++;
+ if ($form->{format} eq 'html') {
+ $spacer = "&nbsp;" x (3 * ($form->{stagger} - 1)) if $form->{stagger} > 1;
+ }
+ if ($form->{format} =~ /(postscript|pdf)/) {
+ if ($form->{stagger} > 1) {
+ $spacer = ($form->{stagger} - 1) * 3;
+ $spacer = '\rule{'.$spacer.'mm}{0mm}';
+ }
+ }
+
+ # get parts and push them onto the stack
+ my $sortorder = "";
+
+ if ($form->{grouppartsgroup}) {
+ $sortorder = qq|ORDER BY pg.partsgroup, a.$oid|;
+ } else {
+ $sortorder = qq|ORDER BY a.$oid|;
+ }
+
+ my $where = ($form->{formname} eq 'work_order') ? "1 = 1" : "a.bom = '1'";
+
+ my $query = qq|SELECT p.partnumber, p.description, p.unit, a.qty,
+ pg.partsgroup, p.partnumber AS sku, p.assembly, p.id, p.bin
+ FROM assembly a
+ JOIN parts p ON (a.parts_id = p.id)
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ WHERE $where
+ AND a.id = '$id'
+ $sortorder|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+ if ($form->{grouppartsgroup} && $ref->{partsgroup} ne $sm) {
+ map { push(@{ $form->{$_} }, "") } qw(number sku unit qty runningnumber ship bin serialnumber reqdate projectnumber sellprice listprice netprice discount discountrate linetotal);
+ $sm = ($ref->{partsgroup}) ? $ref->{partsgroup} : "";
+ push(@{ $form->{description} }, "$spacer$sm");
+ }
+
+ if ($form->{stagger}) {
+ push(@{ $form->{description} }, qq|$spacer$ref->{sku}, $ref->{description}|);
+ map { push(@{ $form->{$_} }, "") } qw(number sku runningnumber ship serialnumber reqdate projectnumber sellprice listprice netprice discount discountrate linetotal);
+ } else {
+ push(@{ $form->{description} }, qq|$ref->{description}|);
+ push(@{ $form->{sku} }, $ref->{partnumber});
+ push(@{ $form->{number} }, $ref->{partnumber});
+
+ map { push(@{ $form->{$_} }, "") } qw(runningnumber ship serialnumber reqdate projectnumber sellprice listprice netprice discount discountrate linetotal);
+ }
+
+ push(@{ $form->{qty} }, $form->format_amount($myconfig, $ref->{qty} * $qty));
+ map { push(@{ $form->{$_} }, $ref->{$_}) } qw(unit bin);
+
+
+ if ($ref->{assembly} && $form->{formname} eq 'work_order') {
+ &assembly_details($dbh, $form, $ref->{id}, $oid, $ref->{qty} * $qty);
+ }
+
+ }
+ $sth->finish;
+
+ $form->{stagger}--;
+
+}
+
+
sub project_description {
my ($self, $dbh, $id) = @_;
my $query = qq|SELECT description
FROM project
WHERE id = $id|;
+ ($_) = $dbh->selectrow_array;
+
+ $_;
+
+}
+
+
+sub get_warehouses {
+ my ($self, $myconfig, $form) = @_;
+
+ my $dbh = $form->dbconnect($myconfig);
+ # setup warehouses
+ my $query = qq|SELECT id, description
+ FROM warehouse
+ ORDER BY 2|;
+
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- ($_) = $sth->fetchrow_array;
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_warehouses} }, $ref;
+ }
+ $sth->finish;
+
+ $dbh->disconnect;
+
+}
+
+
+sub save_inventory {
+ my ($self, $myconfig, $form) = @_;
+
+ my ($null, $warehouse_id) = split /--/, $form->{warehouse};
+ $warehouse_id *= 1;
+
+ my $ml = ($form->{type} eq 'ship_order') ? -1 : 1;
+
+ my $dbh = $form->dbconnect_noauto($myconfig);
+ my $sth;
+ my $wth;
+ my $serialnumber;
+ my $ship;
+
+ my $employee_id;
+ ($null, $employee_id) = split /--/, $form->{employee};
+ ($null, $employee_id) = $form->get_employee($dbh) if ! $employee_id;
+
+ $query = qq|SELECT serialnumber, ship
+ FROM orderitems
+ WHERE trans_id = ?
+ AND id = ?
+ FOR UPDATE|;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ $query = qq|SELECT sum(qty)
+ FROM inventory
+ WHERE parts_id = ?
+ AND warehouse_id = ?|;
+ $wth = $dbh->prepare($query) || $form->dberror($query);
+
+
+ for my $i (1 .. $form->{rowcount}) {
+
+ $ship = (abs($form->{"ship_$i"}) > abs($form->{"qty_$i"})) ? $form->{"qty_$i"} : $form->{"ship_$i"};
+
+ if ($warehouse_id && $form->{type} eq 'ship_order') {
+
+ $wth->execute($form->{"id_$i"}, $warehouse_id) || $form->dberror;
+
+ ($qty) = $wth->fetchrow_array;
+ $wth->finish;
+
+ if ($ship > $qty) {
+ $ship = $qty;
+ }
+ }
+
+
+ if ($ship != 0) {
+
+ $ship *= $ml;
+ $query = qq|INSERT INTO inventory (parts_id, warehouse_id,
+ qty, oe_id, orderitems_id, shippingdate, employee_id)
+ VALUES ($form->{"id_$i"}, $warehouse_id,
+ $ship, $form->{"id"},
+ $form->{"orderitems_id_$i"}, '$form->{shippingdate}',
+ $employee_id)|;
+ $dbh->do($query) || $form->dberror($query);
+
+ # add serialnumber, ship to orderitems
+ $sth->execute($form->{id}, $form->{"orderitems_id_$i"}) || $form->dberror;
+ ($serialnumber, $ship) = $sth->fetchrow_array;
+ $sth->finish;
+
+ $serialnumber .= " " if $serialnumber;
+ $serialnumber .= qq|$form->{"serialnumber_$i"}|;
+ $ship += $form->{"ship_$i"};
+
+ $query = qq|UPDATE orderitems SET
+ serialnumber = '$serialnumber',
+ ship = $ship,
+ reqdate = '$form->{shippingdate}'
+ WHERE trans_id = $form->{id}
+ AND id = $form->{"orderitems_id_$i"}|;
+ $dbh->do($query) || $form->dberror($query);
+
+
+ # update order with ship via
+ $query = qq|UPDATE oe SET
+ shippingpoint = '$form->{shippingpoint}',
+ shipvia = '$form->{shipvia}'
+ WHERE id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+
+ # update onhand for parts
+ $form->update_balance($dbh,
+ "parts",
+ "onhand",
+ qq|id = $form->{"id_$i"}|,
+ $form->{"ship_$i"} * $ml);
+
+ }
+ }
+
+ my $rc = $dbh->commit;
+ $dbh->disconnect;
+
+ $rc;
+
+}
+
+
+sub adj_onhand {
+ my ($dbh, $form, $ml) = @_;
+
+ my $query = qq|SELECT oi.parts_id, oi.ship, p.inventory_accno_id, p.assembly
+ FROM orderitems oi
+ JOIN parts p ON (p.id = oi.parts_id)
+ WHERE oi.trans_id = $form->{id}|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ $query = qq|SELECT sum(p.inventory_accno_id)
+ FROM parts p
+ JOIN assembly a ON (a.parts_id = p.id)
+ WHERE a.id = ?|;
+ my $ath = $dbh->prepare($query) || $form->dberror($query);
+
+ my $ispa;
+ my $ref;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+ if ($ref->{inventory_accno_id} || $ref->{assembly}) {
+
+ # do not update if assembly consists of all services
+ if ($ref->{assembly}) {
+ $ath->execute($ref->{parts_id}) || $form->dberror($query);
+
+ ($ispa) = $ath->fetchrow_array;
+ $ath->finish;
+
+ next unless $ispa;
+
+ }
+
+ # adjust onhand in parts table
+ $form->update_balance($dbh,
+ "parts",
+ "onhand",
+ qq|id = $ref->{parts_id}|,
+ $ref->{ship} * $ml);
+ }
+ }
$sth->finish;
- $_;
+}
+
+
+sub adj_inventory {
+ my ($dbh, $myconfig, $form) = @_;
+
+ my %oid = ( 'Pg' => 'oid',
+ 'PgPP' => 'oid',
+ 'Oracle' => 'rowid',
+ 'DB2' => '1=1'
+ );
+
+ # increase/reduce qty in inventory table
+ my $query = qq|SELECT oi.id, oi.parts_id, oi.ship
+ FROM orderitems oi
+ WHERE oi.trans_id = $form->{id}|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ $query = qq|SELECT $oid{$myconfig->{dbdriver}} AS oid, qty,
+ (SELECT SUM(qty) FROM inventory
+ WHERE oe_id = $form->{id}
+ AND orderitems_id = ?) AS total
+ FROM inventory
+ WHERE oe_id = $form->{id}
+ AND orderitems_id = ?|;
+ my $ith = $dbh->prepare($query) || $form->dberror($query);
+
+ my $qty;
+ my $ml = ($form->{type} =~ /(ship|sales)_order/) ? -1 : 1;
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+ $ith->execute($ref->{id}, $ref->{id}) || $form->dberror($query);
+
+ while (my $inv = $ith->fetchrow_hashref(NAME_lc)) {
+
+ if (($qty = (($inv->{total} * $ml) - $ref->{ship})) >= 0) {
+ $qty = $inv->{qty} if ($qty > ($inv->{qty} * $ml));
+
+ $form->update_balance($dbh,
+ "inventory",
+ "qty",
+ qq|$oid{$myconfig->{dbdriver}} = $inv->{oid}|,
+ $qty * -1 * $ml);
+ }
+ }
+ $ith->finish;
+
+ }
+ $sth->finish;
+
+ # delete inventory entries if qty = 0
+ $query = qq|DELETE FROM inventory
+ WHERE oe_id = $form->{id}
+ AND qty = 0|;
+ $dbh->do($query) || $form->dberror($query);
+
+}
+
+
+sub get_inventory {
+ my ($self, $myconfig, $form) = @_;
+
+ my ($null, $warehouse_id) = split /--/, $form->{warehouse};
+ $warehouse_id *= 1;
+
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT p.id, p.partnumber, p.description, p.onhand,
+ pg.partsgroup
+ FROM parts p
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ WHERE p.onhand > 0|;
+
+ if ($form->{partnumber}) {
+ $var = $form->like(lc $form->{partnumber});
+ $query .= "
+ AND lower(p.partnumber) LIKE '$var'";
+ }
+ if ($form->{description}) {
+ $var = $form->like(lc $form->{description});
+ $query .= "
+ AND lower(p.description) LIKE '$var'";
+ }
+ if ($form->{partsgroup}) {
+ $var = $form->like(lc $form->{partsgroup});
+ $query .= "
+ AND lower(pg.partsgroup) LIKE '$var'";
+ }
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+
+ $query = qq|SELECT sum(i.qty), w.description, w.id
+ FROM inventory i
+ LEFT JOIN warehouse w ON (w.id = i.warehouse_id)
+ WHERE i.parts_id = ?
+ AND i.warehouse_id != $warehouse_id
+ GROUP BY w.description, w.id|;
+ $wth = $dbh->prepare($query) || $form->dberror($query);
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+ $wth->execute($ref->{id}) || $form->dberror;
+
+ while (($qty, $warehouse, $warehouse_id) = $wth->fetchrow_array) {
+ push @{ $form->{all_inventory} }, {'id' => $ref->{id},
+ 'partnumber' => $ref->{partnumber},
+ 'description' => $ref->{description},
+ 'partsgroup' => $ref->{partsgroup},
+ 'qty' => $qty,
+ 'warehouse_id' => $warehouse_id,
+ 'warehouse' => $warehouse} if $qty > 0;
+ }
+ $wth->finish;
+ }
+ $sth->finish;
+
+ $dbh->disconnect;
+
+ # sort inventory
+ @{ $form->{all_inventory} } = sort { $a->{$form->{sort}} cmp $b->{$form->{sort}} } @{ $form->{all_inventory} };
+
+}
+
+
+sub transfer {
+ my ($self, $myconfig, $form) = @_;
+
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my $query = qq|INSERT INTO inventory
+ (warehouse_id, parts_id, qty, shippingdate, employee_id)
+ VALUES (?, ?, ?, ?, ?)|;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh);
+
+ my @a = localtime; $a[5] += 1900; $a[4]++;
+ $shippingdate = "$a[5]-$a[4]-$a[3]";
+
+ for my $i (1 .. $form->{rowcount}) {
+ $qty = $form->parse_amount($myconfig, $form->{"transfer_$i"});
+
+ $qty = $form->{"qty_$i"} if ($qty > $form->{"qty_$i"});
+
+ if ($qty) {
+ # to warehouse
+ $sth->execute($form->{warehouse_id}, $form->{"id_$i"}, $qty, $shippingdate, $form->{employee_id}) || $form->dberror;
+
+ $sth->finish;
+
+ # from warehouse
+ $sth->execute($form->{"warehouse_id_$i"}, $form->{"id_$i"}, $qty * -1, $shippingdate, $form->{employee_id}) || $form->dberror;
+
+ $sth->finish;
+ }
+ }
+
+ my $rc = $dbh->commit;
+ $dbh->disconnect;
+
+ $rc;
}
diff --git a/sql-ledger/SL/OP.pm b/sql-ledger/SL/OP.pm
new file mode 100644
index 000000000..184566c14
--- /dev/null
+++ b/sql-ledger/SL/OP.pm
@@ -0,0 +1,118 @@
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 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.
+#======================================================================
+#
+# Overpayment function
+# used in AR, AP, IS, IR, OE, CP
+#
+#======================================================================
+
+package OP;
+
+sub overpayment {
+ my ($self, $myconfig, $form, $dbh, $amount, $ml) = @_;
+
+ my $fxamount = $form->round_amount($amount * $form->{exchangerate}, 2);
+ my ($paymentaccno) = split /--/, $form->{account};
+
+ my $vc_id = "$form->{vc}_id";
+
+ my $uid = time;
+ $uid .= $form->{login};
+
+ # add AR/AP header transaction with a payment
+ $query = qq|INSERT INTO $form->{arap} (invnumber, employee_id)
+ VALUES ('$uid', (SELECT id FROM employee
+ WHERE login = '$form->{login}'))|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|SELECT id FROM $form->{arap}
+ WHERE invnumber = '$uid'|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ ($uid) = $sth->fetchrow_array;
+ $sth->finish;
+
+ my $invnumber = $form->{invnumber};
+ if (! $invnumber) {
+ $invnumber = $form->update_defaults($myconfig, ($form->{arap} eq 'ar') ? "sinumber" : "vinumber", $dbh);
+ }
+
+ $query = qq|UPDATE $form->{arap} set
+ invnumber = |.$dbh->quote($invnumber).qq|,
+ $vc_id = $form->{"$form->{vc}_id"},
+ transdate = '$form->{datepaid}',
+ datepaid = '$form->{datepaid}',
+ duedate = '$form->{datepaid}',
+ netamount = 0,
+ amount = 0,
+ paid = $fxamount,
+ curr = '$form->{currency}',
+ department_id = $form->{department_id}
+ WHERE id = $uid|;
+ $dbh->do($query) || $form->dberror($query);
+
+ # add AR/AP
+ ($accno) = split /--/, $form->{$form->{ARAP}};
+
+ $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate, amount)
+ VALUES ($uid, (SELECT id FROM chart
+ WHERE accno = '$accno'),
+ '$form->{datepaid}', $fxamount * $ml)|;
+ $dbh->do($query) || $form->dberror($query);
+
+ # add payment
+ $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate,
+ amount, source, memo)
+ VALUES ($uid, (SELECT id FROM chart
+ WHERE accno = '$paymentaccno'),
+ '$form->{datepaid}', $amount * $ml * -1, |
+ .$dbh->quote($form->{source}).qq|, |
+ .$dbh->quote($form->{memo}).qq|)|;
+ $dbh->do($query) || $form->dberror($query);
+
+ # add exchangerate difference
+ if ($fxamount != $amount) {
+ $query = qq|INSERT INTO acc_trans (trans_id, chart_id, transdate,
+ amount, cleared, fx_transaction)
+ VALUES ($uid, (SELECT id FROM chart
+ WHERE accno = '$paymentaccno'),
+ '$form->{datepaid}', ($fxamount - $amount) * $ml * -1,
+ '1', '1')|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+
+ my %audittrail = ( tablename => $form->{arap},
+ reference => $invnumber,
+ formname => ($form->{arap} eq 'ar') ? 'deposit' : 'pre-payment',
+ action => 'posted',
+ id => $uid );
+
+ $form->audittrail($dbh, "", \%audittrail);
+
+}
+
+
+1;
+
diff --git a/sql-ledger/SL/PE.pm b/sql-ledger/SL/PE.pm
index dec04bb4f..f0850a7cf 100644
--- a/sql-ledger/SL/PE.pm
+++ b/sql-ledger/SL/PE.pm
@@ -1,6 +1,6 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 1998-2002
+# Copyright (C) 2003
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
@@ -36,7 +36,11 @@ sub projects {
# connect to database
my $dbh = $form->dbconnect($myconfig);
- my $sortorder = ($form->{sort}) ? $form->{sort} : "projectnumber";
+ $form->{sort} = "projectnumber" unless $form->{sort};
+ my @a = ($form->{sort});
+ my %ordinal = ( projectnumber => 2,
+ description => 3 );
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
my $query = qq|SELECT id, projectnumber, description
FROM project
@@ -103,14 +107,24 @@ sub get_project {
# check if it is orphaned
$query = qq|SELECT count(*)
FROM acc_trans
- WHERE project_id = $form->{id}|;
+ WHERE project_id = $form->{id}
+ UNION
+ SELECT count(*)
+ FROM invoice
+ WHERE project_id = $form->{id}
+ UNION
+ SELECT count(*)
+ FROM orderitems
+ WHERE project_id = $form->{id}
+ |;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- ($form->{orphaned}) = $sth->fetchrow_array;
- $form->{orphaned} = !$form->{orphaned};
-
+ while (my ($count) = $sth->fetchrow_array) {
+ $form->{orphaned} += $count;
+ }
$sth->finish;
+ $form->{orphaned} = !$form->{orphaned};
$dbh->disconnect;
@@ -123,17 +137,17 @@ sub save_project {
# connect to database
my $dbh = $form->dbconnect($myconfig);
- map { $form->{$_} =~ s/'/''/g } (projectnumber, description);
-
if ($form->{id}) {
$query = qq|UPDATE project SET
- projectnumber = '$form->{projectnumber}',
- description = '$form->{description}'
+ projectnumber = |.$dbh->quote($form->{projectnumber}).qq|,
+ description = |.$dbh->quote($form->{description}).qq|
WHERE id = $form->{id}|;
} else {
$query = qq|INSERT INTO project
(projectnumber, description)
- VALUES ('$form->{projectnumber}', '$form->{description}')|;
+ VALUES (|
+ .$dbh->quote($form->{projectnumber}).qq|, |
+ .$dbh->quote($form->{description}).qq|)|;
}
$dbh->do($query) || $form->dberror($query);
@@ -150,7 +164,9 @@ sub partsgroups {
# connect to database
my $dbh = $form->dbconnect($myconfig);
- my $sortorder = ($form->{sort}) ? $form->{sort} : "partsgroup";
+ $form->{sort} = "partsgroup" unless $form->{partsgroup};
+ my @a = (partsgroup);
+ my $sortorder = $form->sort_order(\@a);
my $query = qq|SELECT g.*
FROM partsgroup g|;
@@ -201,17 +217,14 @@ sub save_partsgroup {
# connect to database
my $dbh = $form->dbconnect($myconfig);
- map { $form->{$_} =~ s/'/''/g } (partsgroup);
-
-
if ($form->{id}) {
$query = qq|UPDATE partsgroup SET
- partsgroup = '$form->{partsgroup}'
+ partsgroup = |.$dbh->quote($form->{partsgroup}).qq|
WHERE id = $form->{id}|;
} else {
$query = qq|INSERT INTO partsgroup
(partsgroup)
- VALUES ('$form->{partsgroup}')|;
+ VALUES (|.$dbh->quote($form->{partsgroup}).qq|)|;
}
$dbh->do($query) || $form->dberror($query);
@@ -255,22 +268,372 @@ sub get_partsgroup {
}
+sub pricegroups {
+ my ($self, $myconfig, $form) = @_;
+
+ my $var;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
-sub delete_tuple {
+ $form->{sort} = "pricegroup" unless $form->{sort};
+ my @a = (pricegroup);
+ my $sortorder = $form->sort_order(\@a);
+
+ my $query = qq|SELECT g.*
+ FROM pricegroup g|;
+
+ my $where = "1 = 1";
+
+ if ($form->{pricegroup}) {
+ $var = $form->like(lc $form->{pricegroup});
+ $where .= " AND lower(pricegroup) LIKE '$var'";
+ }
+ $query .= qq|
+ WHERE $where
+ ORDER BY $sortorder|;
+
+ if ($form->{status} eq 'orphaned') {
+ $query = qq|SELECT g.*
+ FROM pricegroup g
+ WHERE $where
+ AND g.id NOT IN (SELECT DISTINCT pricegroup_id
+ FROM partscustomer)
+ ORDER BY $sortorder|;
+ }
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $i = 0;
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{item_list} }, $ref;
+ $i++;
+ }
+
+ $sth->finish;
+ $dbh->disconnect;
+
+ $i;
+
+}
+
+
+sub save_pricegroup {
my ($self, $myconfig, $form) = @_;
# connect to database
my $dbh = $form->dbconnect($myconfig);
+ if ($form->{id}) {
+ $query = qq|UPDATE pricegroup SET
+ pricegroup = |.$dbh->quote($form->{pricegroup}).qq|
+ WHERE id = $form->{id}|;
+ } else {
+ $query = qq|INSERT INTO pricegroup
+ (pricegroup)
+ VALUES (|.$dbh->quote($form->{pricegroup}).qq|)|;
+ }
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
+
+sub get_pricegroup {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT *
+ FROM pricegroup
+ WHERE id = $form->{id}|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $ref = $sth->fetchrow_hashref(NAME_lc);
+
+ map { $form->{$_} = $ref->{$_} } keys %$ref;
+
+ $sth->finish;
+
+ # check if it is orphaned
+ $query = qq|SELECT count(*)
+ FROM partscustomer
+ WHERE pricegroup_id = $form->{id}|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ ($form->{orphaned}) = $sth->fetchrow_array;
+ $form->{orphaned} = !$form->{orphaned};
+
+ $sth->finish;
+
+ $dbh->disconnect;
+
+}
+
+
+sub delete_tuple {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
$query = qq|DELETE FROM $form->{type}
WHERE id = $form->{id}|;
$dbh->do($query) || $form->dberror($query);
+ if ($form->{type} !~ /pricegroup/) {
+ $query = qq|DELETE FROM translation
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+ }
+
+ $dbh->commit;
+ $dbh->disconnect;
+
+}
+
+
+sub description_translations {
+ my ($self, $myconfig, $form) = @_;
+
+ my $where = "1 = 1\n";
+ my $var;
+ my $ref;
+
+ map { $where .= "AND lower(p.$_) LIKE '".$form->like(lc $form->{$_})."'\n" if $form->{$_} } qw(partnumber description);
+
+ $where .= " AND p.obsolete = '0'";
+ $where .= " AND p.id = $form->{id}" if $form->{id};
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my %ordinal = ( 'partnumber' => 2,
+ 'description' => 3
+ );
+
+ my @a = qw(partnumber description);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ my $query = qq|SELECT l.description AS language, t.description AS translation,
+ l.code
+ FROM translation t
+ JOIN language l ON (l.code = t.language_code)
+ WHERE trans_id = ?
+ ORDER BY 1|;
+ my $tth = $dbh->prepare($query);
+
+ $query = qq|SELECT p.id, p.partnumber, p.description
+ FROM parts p
+ WHERE $where
+ ORDER BY $sortorder|;
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $tra;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{translations} }, $ref;
+
+ # get translations for description
+ $tth->execute($ref->{id}) || $form->dberror;
+
+ while ($tra = $tth->fetchrow_hashref(NAME_lc)) {
+ $form->{trans_id} = $ref->{id};
+ $tra->{id} = $ref->{id};
+ push @{ $form->{translations} }, $tra;
+ }
+
+ }
+ $sth->finish;
+
+ &get_language("", $dbh, $form) if $form->{id};
+
+ $dbh->disconnect;
+
+}
+
+
+sub partsgroup_translations {
+ my ($self, $myconfig, $form) = @_;
+
+ my $where = "1 = 1\n";
+ my $ref;
+
+ if ($form->{description}) {
+ $where .= "AND lower(p.partsgroup) LIKE '".$form->like(lc $form->{description})."'";
+ }
+ $where .= " AND p.id = $form->{id}" if $form->{id};
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my $query = qq|SELECT l.description AS language, t.description AS translation,
+ l.code
+ FROM translation t
+ JOIN language l ON (l.code = t.language_code)
+ WHERE trans_id = ?
+ ORDER BY 1|;
+ my $tth = $dbh->prepare($query);
+
+ $form->sort_order();
+
+ $query = qq|SELECT p.id, p.partsgroup AS description
+ FROM partsgroup p
+ WHERE $where
+ ORDER BY 2 $form->{direction}|;
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $tra;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{translations} }, $ref;
+
+ # get translations for partsgroup
+ $tth->execute($ref->{id}) || $form->dberror;
+
+ while ($tra = $tth->fetchrow_hashref(NAME_lc)) {
+ $form->{trans_id} = $ref->{id};
+ push @{ $form->{translations} }, $tra;
+ }
+
+ }
+ $sth->finish;
+
+ &get_language("", $dbh, $form) if $form->{id};
+
+ $dbh->disconnect;
+
+}
+
+
+sub project_translations {
+ my ($self, $myconfig, $form) = @_;
+
+ my $where = "1 = 1\n";
+ my $var;
+ my $ref;
+
+ map { $where .= "AND lower(p.$_) LIKE '".$form->like(lc $form->{$_})."'\n" if $form->{$_} } qw(projectnumber description);
+
+ $where .= " AND p.id = $form->{id}" if $form->{id};
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ my %ordinal = ( 'projectnumber' => 2,
+ 'description' => 3
+ );
+
+ my @a = qw(projectnumber description);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ my $query = qq|SELECT l.description AS language, t.description AS translation,
+ l.code
+ FROM translation t
+ JOIN language l ON (l.code = t.language_code)
+ WHERE trans_id = ?
+ ORDER BY 1|;
+ my $tth = $dbh->prepare($query);
+
+ $query = qq|SELECT p.id, p.projectnumber, p.description
+ FROM project p
+ WHERE $where
+ ORDER BY $sortorder|;
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my $tra;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{translations} }, $ref;
+
+ # get translations for description
+ $tth->execute($ref->{id}) || $form->dberror;
+
+ while ($tra = $tth->fetchrow_hashref(NAME_lc)) {
+ $form->{trans_id} = $ref->{id};
+ $tra->{id} = $ref->{id};
+ push @{ $form->{translations} }, $tra;
+ }
+
+ }
+ $sth->finish;
+
+ &get_language("", $dbh, $form) if $form->{id};
+
+ $dbh->disconnect;
+
+}
+
+
+sub get_language {
+ my ($self, $dbh, $form) = @_;
+
+ # get language
+ my $query = qq|SELECT *
+ FROM language
+ ORDER BY 2|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_language} }, $ref;
+ }
+ $sth->finish;
+
+}
+
+
+sub save_translation {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect_noauto($myconfig);
+
+ my $query = qq|DELETE FROM translation
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $query = qq|INSERT INTO translation (trans_id, language_code, description)
+ VALUES ($form->{id}, ?, ?)|;
+ my $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ foreach my $i (1 .. $form->{translation_rows}) {
+ if ($form->{"language_code_$i"}) {
+ $sth->execute($form->{"language_code_$i"}, $form->{"translation_$i"});
+ $sth->finish;
+ }
+ }
+ $dbh->commit;
$dbh->disconnect;
}
+sub delete_translation {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ $query = qq|DELETE FROM translation
+ WHERE trans_id = $form->{id}|;
+ $dbh->do($query) || $form->dberror($query);
+
+ $dbh->disconnect;
+
+}
+
1;
diff --git a/sql-ledger/SL/RC.pm b/sql-ledger/SL/RC.pm
index 9957d7349..2a8bf9410 100644
--- a/sql-ledger/SL/RC.pm
+++ b/sql-ledger/SL/RC.pm
@@ -38,7 +38,7 @@ sub paymentaccounts {
my $query = qq|SELECT accno, description
FROM chart
WHERE link LIKE '%_paid%'
- AND category = 'A'
+ AND (category = 'A' OR category = 'L')
ORDER BY accno|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
@@ -47,6 +47,9 @@ sub paymentaccounts {
push @{ $form->{PR} }, $ref;
}
$sth->finish;
+
+ $form->all_years($dbh, $myconfig);
+
$dbh->disconnect;
}
@@ -58,92 +61,356 @@ sub payment_transactions {
# connect to database, turn AutoCommit off
my $dbh = $form->dbconnect_noauto($myconfig);
- my ($query, $sth);
-
- # get cleared balance
- if ($form->{fromdate}) {
- $query = qq|SELECT sum(a.amount)
- FROM acc_trans a, chart c
- WHERE a.transdate < date '$form->{fromdate}'
- AND a.cleared = '1'
- AND c.id = a.chart_id
- AND c.accno = '$form->{accno}'
- |;
- } else {
- $query = qq|SELECT sum(a.amount)
- FROM acc_trans a, chart c
- WHERE a.cleared = '1'
- AND c.id = a.chart_id
- AND c.accno = '$form->{accno}'
- |;
- }
+ my $query;
+ my $sth;
+
+ $query = qq|SELECT category FROM chart
+ WHERE accno = '$form->{accno}'|;
+ ($form->{category}) = $dbh->selectrow_array($query);
- $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror($query);
+ my $cleared;
- ($form->{beginningbalance}) = $sth->fetchrow_array;
+ ($form->{fromdate}, $form->{todate}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
- $sth->finish;
+ my $transdate = qq| AND ac.transdate < date '$form->{fromdate}'|;
- my %oid = ( 'Pg' => 'ac.oid',
- 'Oracle' => 'ac.rowid');
-
- $query = qq|SELECT c.name, ac.source, ac.transdate, ac.cleared,
- ac.fx_transaction, ac.amount, a.id,
- $oid{$myconfig->{dbdriver}} AS oid
- FROM customer c, acc_trans ac, ar a, chart ch
- WHERE c.id = a.customer_id
- AND ac.cleared = '0'
- AND ac.trans_id = a.id
- AND ac.chart_id = ch.id
- AND ch.accno = '$form->{accno}'
+ if (! $form->{fromdate}) {
+ $cleared = qq| AND ac.cleared = '1'|;
+ $transdate = "";
+ }
+
+ # get beginning balance
+ $query = qq|SELECT sum(ac.amount)
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ WHERE c.accno = '$form->{accno}'
+ $transdate
+ $cleared
|;
-
- $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
- $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
-
-
- $query .= qq|
-
- UNION
- SELECT v.name, ac.source, ac.transdate, ac.cleared,
- ac.fx_transaction, ac.amount, a.id,
- $oid{$myconfig->{dbdriver}} AS oid
- FROM vendor v, acc_trans ac, ap a, chart ch
- WHERE v.id = a.vendor_id
- AND ac.cleared = '0'
- AND ac.trans_id = a.id
- AND ac.chart_id = ch.id
- AND ch.accno = '$form->{accno}'
- |;
-
- $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
- $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
-
- $query .= qq|
+ ($form->{beginningbalance}) = $dbh->selectrow_array($query);
+
+ # fx balance
+ $query = qq|SELECT sum(ac.amount)
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ WHERE c.accno = '$form->{accno}'
+ AND ac.fx_transaction = '1'
+ $transdate
+ $cleared
+ |;
+ ($form->{fx_balance}) = $dbh->selectrow_array($query);
- UNION
- SELECT g.description, ac.source, ac.transdate, ac.cleared,
- ac.fx_transaction, ac.amount, g.id,
- $oid{$myconfig->{dbdriver}} AS oid
- FROM gl g, acc_trans ac, chart ch
- WHERE g.id = ac.trans_id
- AND ac.cleared = '0'
- AND ac.trans_id = g.id
- AND ac.chart_id = ch.id
- AND ch.accno = '$form->{accno}'
+
+ $transdate = "";
+ if ($form->{todate}) {
+ $transdate = qq| AND ac.transdate <= date '$form->{todate}'|;
+ }
+
+ # get statement balance
+ $query = qq|SELECT sum(ac.amount)
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ WHERE c.accno = '$form->{accno}'
+ $transdate
+ |;
+ ($form->{endingbalance}) = $dbh->selectrow_array($query);
+
+ # fx balance
+ $query = qq|SELECT sum(ac.amount)
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ WHERE c.accno = '$form->{accno}'
+ AND ac.fx_transaction = '1'
+ $transdate
|;
+ ($form->{fx_endingbalance}) = $dbh->selectrow_array($query);
- $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
- $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
- $query .= " ORDER BY 3,7,8";
+ $cleared = qq| AND ac.cleared = '0'| unless $form->{fromdate};
+
+ if ($form->{report}) {
+ $cleared = qq| AND NOT (ac.cleared = '0' OR ac.cleared = '1')|;
+ if ($form->{cleared}) {
+ $cleared = qq| AND ac.cleared = '1'|;
+ }
+ if ($form->{outstanding}) {
+ $cleared = ($form->{cleared}) ? "" : qq| AND ac.cleared = '0'|;
+ }
+ if (! $form->{fromdate}) {
+ $form->{beginningbalance} = 0;
+ $form->{fx_balance} = 0;
+ }
+ }
+
+
+ if ($form->{summary}) {
+ $query = qq|SELECT ac.transdate, ac.source,
+ sum(ac.amount) AS amount, ac.cleared
+ FROM acc_trans ac
+ JOIN chart ch ON (ac.chart_id = ch.id)
+ WHERE ch.accno = '$form->{accno}'
+ AND ac.amount >= 0
+ AND ac.fx_transaction = '0'
+ $cleared|;
+ $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+ $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+ $query .= " GROUP BY ac.source, ac.transdate, ac.cleared";
+ $query .= qq|
+ UNION
+ SELECT ac.transdate, ac.source,
+ sum(ac.amount) AS amount, ac.cleared
+ FROM acc_trans ac
+ JOIN chart ch ON (ac.chart_id = ch.id)
+ WHERE ch.accno = '$form->{accno}'
+ AND ac.amount < 0
+ AND ac.fx_transaction = '0'
+ $cleared|;
+ $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+ $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+ $query .= " GROUP BY ac.source, ac.transdate, ac.cleared";
+
+ $query .= " ORDER BY 1,2";
+
+ } else {
+
+ $query = qq|SELECT ac.transdate, ac.source, ac.fx_transaction,
+ ac.amount, ac.cleared, g.id, g.description
+ FROM acc_trans ac
+ JOIN chart ch ON (ac.chart_id = ch.id)
+ JOIN gl g ON (g.id = ac.trans_id)
+ WHERE ch.accno = '$form->{accno}'
+ AND ac.fx_transaction = '0'
+ $cleared|;
+ $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+ $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+
+ $query .= qq|
+ UNION
+ SELECT ac.transdate, ac.source, ac.fx_transaction,
+ ac.amount, ac.cleared, a.id, n.name
+ FROM acc_trans ac
+ JOIN chart ch ON (ac.chart_id = ch.id)
+ JOIN ar a ON (a.id = ac.trans_id)
+ JOIN customer n ON (n.id = a.customer_id)
+ WHERE ch.accno = '$form->{accno}'
+ AND ac.fx_transaction = '0'
+ $cleared|;
+ $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+ $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+
+ $query .= qq|
+ UNION
+ SELECT ac.transdate, ac.source, ac.fx_transaction,
+ ac.amount, ac.cleared, a.id, n.name
+ FROM acc_trans ac
+ JOIN chart ch ON (ac.chart_id = ch.id)
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN vendor n ON (n.id = a.vendor_id)
+ WHERE ch.accno = '$form->{accno}'
+ AND ac.fx_transaction = '0'
+ $cleared|;
+ $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
+ $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+
+ $query .= " ORDER BY 1,2,3";
+ }
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- while (my $pr = $sth->fetchrow_hashref(NAME_lc)) {
- push @{ $form->{PR} }, $pr;
+ my $dr;
+ my $cr;
+ my $fxs;
+
+ if ($form->{summary}) {
+ $query = qq|SELECT ac.amount, ac.cleared
+ FROM acc_trans ac
+ JOIN ar a ON (a.id = ac.trans_id)
+ JOIN customer n ON (n.id = a.customer_id)
+ WHERE ac.fx_transaction = '1'
+ AND n.name = ?
+ AND ac.transdate = ?
+ AND ac.trans_id IN (SELECT id FROM ar a
+ JOIN acc_trans ac ON (a.id = ac.trans_id)
+ WHERE ac.source = ?)
+ AND ac.cleared = ?
+ AND NOT
+ (ac.chart_id IN
+ (SELECT fxgain_accno_id FROM defaults
+ UNION
+ SELECT fxloss_accno_id FROM defaults))
+ |;
+
+ $query .= qq|
+ UNION
+ SELECT ac.amount, ac.cleared
+ FROM acc_trans ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN vendor n ON (n.id = a.vendor_id)
+ WHERE ac.fx_transaction = '1'
+ AND n.name = ?
+ AND ac.transdate = ?
+ AND ac.trans_id IN (SELECT id FROM ap a
+ JOIN acc_trans ac ON (a.id = ac.trans_id)
+ WHERE ac.source = ?)
+ AND ac.cleared = ?
+ AND NOT
+ (ac.chart_id IN
+ (SELECT fxgain_accno_id FROM defaults
+ UNION
+ SELECT fxloss_accno_id FROM defaults))
+ |;
+
+ } else {
+
+ $query = qq|SELECT ac.amount, ac.cleared
+ FROM acc_trans ac
+ WHERE ac.trans_id = ?
+ AND ac.fx_transaction = '1'
+ $cleared
+ AND NOT
+ (ac.chart_id IN
+ (SELECT fxgain_accno_id FROM defaults
+ UNION
+ SELECT fxloss_accno_id FROM defaults))
+ |;
+
+ }
+
+ $fxs = $dbh->prepare($query);
+
+
+ if ($form->{summary}) {
+ $query = qq|SELECT c.name
+ FROM customer c
+ JOIN ar a ON (c.id = a.customer_id)
+ JOIN acc_trans ac ON (a.id = ac.trans_id)
+ WHERE ac.transdate = ?
+ AND ac.source = ?
+ AND ac.amount > 0
+ $cleared
+ UNION
+ SELECT v.name
+ FROM vendor v
+ JOIN ap a ON (v.id = a.vendor_id)
+ JOIN acc_trans ac ON (a.id = ac.trans_id)
+ WHERE ac.transdate = ?
+ AND ac.source = ?
+ AND ac.amount > 0
+ $cleared
+ UNION
+ SELECT g.description
+ FROM gl g
+ JOIN acc_trans ac ON (g.id = ac.trans_id)
+ WHERE ac.transdate = ?
+ AND ac.source = ?
+ AND ac.amount > 0
+ $cleared
+ |;
+
+ $query .= " ORDER BY 1";
+ $dr = $dbh->prepare($query);
+
+
+ $query = qq|SELECT c.name
+ FROM customer c
+ JOIN ar a ON (c.id = a.customer_id)
+ JOIN acc_trans ac ON (a.id = ac.trans_id)
+ WHERE ac.transdate = ?
+ AND ac.source = ?
+ AND ac.amount < 0
+ $cleared
+ UNION
+ SELECT v.name
+ FROM vendor v
+ JOIN ap a ON (v.id = a.vendor_id)
+ JOIN acc_trans ac ON (a.id = ac.trans_id)
+ WHERE ac.transdate = ?
+ AND ac.source = ?
+ AND ac.amount < 0
+ $cleared
+ UNION
+ SELECT g.description
+ FROM gl g
+ JOIN acc_trans ac ON (g.id = ac.trans_id)
+ WHERE ac.transdate = ?
+ AND ac.source = ?
+ AND ac.amount < 0
+ $cleared
+ |;
+
+ $query .= " ORDER BY 1";
+ $cr = $dbh->prepare($query);
+ }
+
+
+ my $name;
+ my $ref;
+ my $xfref;
+
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+
+ if ($form->{summary}) {
+
+ if ($ref->{amount} > 0) {
+ $dr->execute($ref->{transdate}, $ref->{source}, $ref->{transdate}, $ref->{source}, $ref->{transdate}, $ref->{source});
+ $ref->{oldcleared} = $ref->{cleared};
+ $ref->{name} = ();
+ while (($name) = $dr->fetchrow_array) {
+ push @{ $ref->{name} }, $name;
+ }
+ $dr->finish;
+ } else {
+
+ $cr->execute($ref->{transdate}, $ref->{source}, $ref->{transdate}, $ref->{source}, $ref->{transdate}, $ref->{source});
+ $ref->{oldcleared} = $ref->{cleared};
+ $ref->{name} = ();
+ while (($name) = $cr->fetchrow_array) {
+ push @{ $ref->{name} }, $name;
+ }
+ $cr->finish;
+
+ }
+
+ } else {
+ push @{ $ref->{name} }, $ref->{description};
+ }
+
+ push @{ $form->{PR} }, $ref;
+
+ # include fx transactions
+ $amount = 0;
+ $addfx = 0;
+ $ref->{oldcleared} = $ref->{cleared};
+ if ($form->{summary}) {
+ foreach $name (@{ $ref->{name} }) {
+ $fxs->execute($name, $ref->{transdate}, $ref->{source}, $ref->{cleared}, $name, $ref->{transdate}, $ref->{source}, $ref->{cleared});
+ while ($fxref = $fxs->fetchrow_hashref(NAME_lc)) {
+ $addfx = 1;
+ $amount += $fxref->{amount};
+ }
+ $fxs->finish;
+ }
+ } else {
+ $fxs->execute($ref->{id});
+ while ($fxref = $fxs->fetchrow_hashref(NAME_lc)) {
+ $addfx = 1;
+ $amount += $fxref->{amount};
+ }
+ $fxs->finish;
+ }
+
+ if ($addfx) {
+ $fxref = ();
+ map { $fxref->{$_} = $ref->{$_} } keys %$ref;
+ $fxref->{fx_transaction} = 1;
+ $fxref->{name} = ();
+ $fxref->{source} = "";
+ $fxref->{transdate} = "";
+ $fxref->{amount} = $amount;
+ push @{ $form->{PR} }, $fxref;
+ }
+
}
$sth->finish;
@@ -158,22 +425,43 @@ sub reconcile {
# connect to database
my $dbh = $form->dbconnect($myconfig);
- my ($query, $i);
- my %oid = ( 'Pg' => 'oid',
- 'Oracle' => 'rowid');
+ my $query = qq|SELECT id FROM chart
+ WHERE accno = '$form->{accno}'|;
+ my ($chart_id) = $dbh->selectrow_array($query);
+ $chart_id *= 1;
+
+ $query = qq|SELECT trans_id FROM acc_trans
+ WHERE source = ?
+ AND transdate = ?
+ AND cleared = '0'|;
+ my $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ my $i;
+ my $trans_id;
+
+ $query = qq|UPDATE acc_trans SET cleared = '1'
+ WHERE cleared = '0'
+ AND trans_id = ?
+ AND transdate = ?
+ AND chart_id = $chart_id|;
+ my $tth = $dbh->prepare($query) || $form->dberror($query);
# clear flags
for $i (1 .. $form->{rowcount}) {
- if ($form->{"cleared_$i"}) {
- $query = qq|UPDATE acc_trans SET cleared = '1'
- WHERE $oid{$myconfig->{dbdriver}} = $form->{"oid_$i"}|;
- $dbh->do($query) || $form->dberror($query);
-
- # clear fx_transaction
- if ($form->{"fxoid_$i"}) {
- $query = qq|UPDATE acc_trans SET cleared = '1'
- WHERE $oid{$myconfig->{dbdriver}} = $form->{"fxoid_$i"}|;
- $dbh->do($query) || $form->dberror($query);
+ if ($form->{"cleared_$i"} && ! $form->{"oldcleared_$i"}) {
+ if ($form->{summary}) {
+ $sth->execute($form->{"source_$i"}, $form->{"transdate_$i"}) || $form->dberror;
+
+ while (($trans_id) = $sth->fetchrow_array) {
+ $tth->execute($trans_id, $form->{"transdate_$i"}) || $form->dberror;
+ $tth->finish;
+ }
+ $sth->finish;
+
+ } else {
+
+ $tth->execute($form->{"id_$i"}, $form->{"transdate_$i"}) || $form->dberror;
+ $tth->finish;
}
}
}
diff --git a/sql-ledger/SL/RP.pm b/sql-ledger/SL/RP.pm
index 3f07bb525..791b22bba 100644
--- a/sql-ledger/SL/RP.pm
+++ b/sql-ledger/SL/RP.pm
@@ -1,12 +1,13 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 1998-2002
+# Copyright (C) 2001
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
# Contributors: Benjamin Lee <benjaminlee@consultant.com>
+# Jim Rawlings <jim@your-dba.com>
#
# 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
@@ -29,6 +30,82 @@
package RP;
+sub yearend_statement {
+ my ($self, $myconfig, $form) = @_;
+
+ # connect to database
+ my $dbh = $form->dbconnect($myconfig);
+
+ # if todate < existing yearends, delete GL and yearends
+ my $query = qq|SELECT trans_id FROM yearend
+ WHERE transdate >= '$form->{todate}'|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my @trans_id = ();
+ my $id;
+ while (($id) = $sth->fetchrow_array) {
+ push @trans_id, $id;
+ }
+ $sth->finish;
+
+ $query = qq|DELETE FROM gl
+ WHERE id = ?|;
+ $sth = $dbh->prepare($query) || $form->dberror($query);
+
+ $query = qq|DELETE FROM acc_trans
+ WHERE trans_id = ?|;
+ my $ath = $dbh->prepare($query) || $form->dberror($query);
+
+ foreach $id (@trans_id) {
+ $sth->execute($id);
+ $ath->execute($id);
+ }
+ $sth->finish;
+
+
+ my $last_period = 0;
+ my @categories = qw(I E);
+ my $category;
+
+ $form->{decimalplaces} *= 1;
+
+ &get_accounts($dbh, 0, $form->{fromdate}, $form->{todate}, $form, \@categories);
+
+ # disconnect
+ $dbh->disconnect;
+
+
+ # now we got $form->{I}{accno}{ }
+ # and $form->{E}{accno}{ }
+
+ my %account = ( 'I' => { 'label' => 'income',
+ 'labels' => 'income',
+ 'ml' => 1 },
+ 'E' => { 'label' => 'expense',
+ 'labels' => 'expenses',
+ 'ml' => -1 }
+ );
+
+ foreach $category (@categories) {
+ foreach $key (sort keys %{ $form->{$category} }) {
+ if ($form->{$category}{$key}{charttype} eq 'A') {
+ $form->{"total_$account{$category}{labels}_this_period"} += $form->{$category}{$key}{this} * $account{$category}{ml};
+ }
+ }
+ }
+
+
+ # totals for income and expenses
+ $form->{total_income_this_period} = $form->round_amount($form->{total_income_this_period}, $form->{decimalplaces});
+ $form->{total_expenses_this_period} = $form->round_amount($form->{total_expenses_this_period}, $form->{decimalplaces});
+
+ # total for income/loss
+ $form->{total_this_period} = $form->{total_income_this_period} - $form->{total_expenses_this_period};
+
+}
+
+
sub income_statement {
my ($self, $myconfig, $form) = @_;
@@ -41,13 +118,25 @@ sub income_statement {
$form->{decimalplaces} *= 1;
- &get_accounts($dbh, $last_period, $form->{fromdate}, $form->{todate}, $form, \@categories);
+ if (! ($form->{fromdate} || $form->{todate})) {
+ if ($form->{fromyear} && $form->{frommonth}) {
+ ($form->{fromdate}, $form->{todate}) = $form->from_to($form->{fromyear}, $form->{frommonth}, $form->{interval});
+ }
+ }
+ &get_accounts($dbh, $last_period, $form->{fromdate}, $form->{todate}, $form, \@categories, 1);
+
+ if (! ($form->{comparefromdate} || $form->{comparetodate})) {
+ if ($form->{compareyear} && $form->{comparemonth}) {
+ ($form->{comparefromdate}, $form->{comparetodate}) = $form->from_to($form->{compareyear}, $form->{comparemonth}, $form->{interval});
+ }
+ }
+
# if there are any compare dates
if ($form->{comparefromdate} || $form->{comparetodate}) {
$last_period = 1;
- &get_accounts($dbh, $last_period, $form->{comparefromdate}, $form->{comparetodate}, $form, \@categories);
+ &get_accounts($dbh, $last_period, $form->{comparefromdate}, $form->{comparetodate}, $form, \@categories, 1);
}
@@ -134,7 +223,7 @@ sub income_statement {
}
-
+
# totals for income and expenses
$form->{total_income_this_period} = $form->round_amount($form->{total_income_this_period}, $form->{decimalplaces});
$form->{total_expenses_this_period} = $form->round_amount($form->{total_expenses_this_period}, $form->{decimalplaces});
@@ -160,7 +249,6 @@ sub income_statement {
}
-
sub balance_sheet {
my ($self, $myconfig, $form) = @_;
@@ -168,8 +256,16 @@ sub balance_sheet {
my $dbh = $form->dbconnect($myconfig);
my $last_period = 0;
- my @categories = qw(A L Q);
+ my @categories = qw(A C L Q);
+ my $null;
+
+ if (! $form->{asofdate}) {
+ if ($form->{asofyear} && $form->{asofmonth}) {
+ ($null, $form->{asofdate}) = $form->from_to($form->{asofyear}, $form->{asofmonth});
+ }
+ }
+
# if there are any dates construct a where
if ($form->{asofdate}) {
@@ -180,13 +276,19 @@ sub balance_sheet {
$form->{decimalplaces} *= 1;
- &get_accounts($dbh, $last_period, "", $form->{asofdate}, $form, \@categories);
+ &get_accounts($dbh, $last_period, "", $form->{asofdate}, $form, \@categories, 1);
+
+ if (! $form->{compareasofdate}) {
+ if ($form->{compareasofyear} && $form->{compareasofmonth}) {
+ ($null, $form->{compareasofdate}) = $form->from_to($form->{compareasofyear}, $form->{compareasofmonth});
+ }
+ }
# if there are any compare dates
if ($form->{compareasofdate}) {
$last_period = 1;
- &get_accounts($dbh, $last_period, "", $form->{compareasofdate}, $form, \@categories);
+ &get_accounts($dbh, $last_period, "", $form->{compareasofdate}, $form, \@categories, 1);
$form->{last_period} = "$form->{compareasofdate}";
@@ -212,11 +314,11 @@ sub balance_sheet {
'labels' => 'liabilities',
'ml' => 1 },
'Q' => { 'label' => 'equity',
- 'labels' => 'equities',
+ 'labels' => 'equity',
'ml' => 1 }
);
- foreach $category (@categories) {
+ foreach $category (grep { !/C/ } @categories) {
foreach $key (sort keys %{ $form->{$category} }) {
@@ -284,9 +386,9 @@ sub balance_sheet {
# totals for assets, liabilities
$form->{total_assets_this_period} = $form->round_amount($form->{total_assets_this_period}, $form->{decimalplaces});
$form->{total_liabilities_this_period} = $form->round_amount($form->{total_liabilities_this_period}, $form->{decimalplaces});
-
+ $form->{total_equity_this_period} = $form->round_amount($form->{total_equity_this_period}, $form->{decimalplaces});
- # calculate retained earnings
+ # calculate earnings
$form->{earnings_this_period} = $form->{total_assets_this_period} - $form->{total_liabilities_this_period} - $form->{total_equity_this_period};
push(@{$form->{equity_this_period}}, $form->format_amount($myconfig, $form->{earnings_this_period}, $form->{decimalplaces}, "- "));
@@ -301,7 +403,7 @@ sub balance_sheet {
# totals for assets, liabilities
$form->{total_assets_last_period} = $form->round_amount($form->{total_assets_last_period}, $form->{decimalplaces});
$form->{total_liabilities_last_period} = $form->round_amount($form->{total_liabilities_last_period}, $form->{decimalplaces});
-
+ $form->{total_equity_last_period} = $form->round_amount($form->{total_equity_last_period}, $form->{decimalplaces});
# calculate retained earnings
$form->{earnings_last_period} = $form->{total_assets_last_period} - $form->{total_liabilities_last_period} - $form->{total_equity_last_period};
@@ -327,17 +429,28 @@ sub balance_sheet {
$form->{total_liabilities_this_period} = $form->format_amount($myconfig, $form->{total_liabilities_this_period}, $form->{decimalplaces}, "- ");
$form->{total_equity_this_period} = $form->format_amount($myconfig, $form->{total_equity_this_period}, $form->{decimalplaces}, "- ");
-
-}
+}
sub get_accounts {
- my ($dbh, $last_period, $fromdate, $todate, $form, $categories) = @_;
+ my ($dbh, $last_period, $fromdate, $todate, $form, $categories, $yearend) = @_;
+ my $department_id;
+ my $project_id;
+
+ ($null, $department_id) = split /--/, $form->{department};
+ ($null, $project_id) = split /--/, $form->{projectnumber};
+
my $query;
- my $where = "WHERE 1 = 1";
- my $subwhere;
+ my $dpt_where;
+ my $dpt_join;
+ my $project;
+ my $where = "1 = 1";
+ my $glwhere = "";
+ my $projectwhere = "";
+ my $subwhere = "";
+ my $yearendwhere = "1 = 1";
my $item;
my $category = "AND (";
@@ -380,18 +493,59 @@ sub get_accounts {
$sth->finish;
- $where .= " AND ac.transdate >= '$fromdate'" if $fromdate;
+ if ($fromdate) {
+ $where .= " AND ac.transdate >= '$fromdate'";
+ $projectwhere .= " AND transdate >= '$fromdate'";
+ if ($form->{method} eq 'cash') {
+ $subwhere .= " AND transdate >= '$fromdate'";
+ $glwhere = " AND ac.transdate >= '$fromdate'";
+ }
+ }
if ($todate) {
$where .= " AND ac.transdate <= '$todate'";
- $subwhere = " AND transdate <= '$todate'";
+ $projectwhere .= " AND transdate <= '$todate'";
+ $subwhere .= " AND transdate <= '$todate'";
+ $yearendwhere = "ac.transdate < '$todate'";
}
-
- if ($form->{project_id})
+ if ($yearend) {
+ $ywhere = " AND ac.trans_id NOT IN
+ (SELECT trans_id FROM yearend)";
+
+ if ($fromdate) {
+ $ywhere = " AND ac.trans_id NOT IN
+ (SELECT trans_id FROM yearend
+ WHERE transdate >= '$fromdate')";
+ if ($todate) {
+ $ywhere = " AND ac.trans_id NOT IN
+ (SELECT trans_id FROM yearend
+ WHERE transdate >= '$fromdate'
+ AND transdate <= '$todate')";
+ }
+ }
+
+ if ($todate) {
+ $ywhere = " AND ac.trans_id NOT IN
+ (SELECT trans_id FROM yearend
+ WHERE transdate <= '$todate')";
+ }
+ }
+
+ if ($department_id)
+ {
+ $dpt_join = qq|
+ JOIN department t ON (a.department_id = t.id)
+ |;
+ $dpt_where = qq|
+ AND t.id = $department_id
+ |;
+ }
+
+ if ($project_id)
{
$project = qq|
- AND ac.project_id = $form->{project_id}
+ AND ac.project_id = $project_id
|;
}
@@ -410,7 +564,10 @@ sub get_accounts {
JOIN chart c ON (c.id = ac.chart_id)
JOIN ar a ON (a.id = ac.trans_id)
JOIN gifi g ON (g.accno = c.gifi_accno)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_where
$category
AND ac.trans_id IN
(
@@ -423,14 +580,17 @@ sub get_accounts {
$project
GROUP BY g.accno, g.description, c.category
- UNION
+ UNION ALL
SELECT '' AS accno, SUM(ac.amount) AS amount,
'' AS description, c.category
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
JOIN ar a ON (a.id = ac.trans_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_where
$category
AND c.gifi_accno = ''
AND ac.trans_id IN
@@ -444,7 +604,7 @@ sub get_accounts {
$project
GROUP BY c.category
- UNION
+ UNION ALL
SELECT g.accno, sum(ac.amount) AS amount,
g.description, c.category
@@ -452,7 +612,10 @@ sub get_accounts {
JOIN chart c ON (c.id = ac.chart_id)
JOIN ap a ON (a.id = ac.trans_id)
JOIN gifi g ON (g.accno = c.gifi_accno)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_where
$category
AND ac.trans_id IN
(
@@ -465,14 +628,17 @@ sub get_accounts {
$project
GROUP BY g.accno, g.description, c.category
- UNION
+ UNION ALL
SELECT '' AS accno, SUM(ac.amount) AS amount,
'' AS description, c.category
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
JOIN ap a ON (a.id = ac.trans_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_where
$category
AND c.gifi_accno = ''
AND ac.trans_id IN
@@ -486,7 +652,7 @@ sub get_accounts {
$project
GROUP BY c.category
- UNION
+ UNION ALL
-- add gl
@@ -496,20 +662,28 @@ sub get_accounts {
JOIN chart c ON (c.id = ac.chart_id)
JOIN gifi g ON (g.accno = c.gifi_accno)
JOIN gl a ON (a.id = ac.trans_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $glwhere
+ $dpt_where
$category
AND NOT (c.link = 'AR' OR c.link = 'AP')
$project
GROUP BY g.accno, g.description, c.category
- UNION
+ UNION ALL
SELECT '' AS accno, SUM(ac.amount) AS amount,
'' AS description, c.category
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
JOIN gl a ON (a.id = ac.trans_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $glwhere
+ $dpt_where
$category
AND c.gifi_accno = ''
AND NOT (c.link = 'AR' OR c.link = 'AP')
@@ -517,8 +691,126 @@ sub get_accounts {
GROUP BY c.category
|;
+ if ($yearend) {
+
+ # this is for the yearend
+
+ $query .= qq|
+
+ UNION ALL
+
+ SELECT g.accno, sum(ac.amount) AS amount,
+ g.description, c.category
+ FROM yearend y
+ JOIN acc_trans ac ON (ac.trans_id = y.trans_id)
+ JOIN chart c ON (c.id = ac.chart_id)
+ JOIN gifi g ON (g.accno = c.accno)
+ $dpt_join
+ WHERE $yearendwhere
+ AND c.category = 'Q'
+ $dpt_where
+ $project
+ GROUP BY g.accno, g.description, c.category
+ |;
+ }
+
+ if ($project_id) {
+
+ $query .= qq|
+
+ UNION ALL
+
+ SELECT g.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount,
+ g.description AS description, c.category
+ FROM invoice ac
+ JOIN ar a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.income_accno_id = c.id)
+ JOIN gifi g ON (g.accno = c.gifi_accno)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ $ywhere
+ AND c.category = 'I'
+ $dpt_where
+ AND ac.trans_id IN
+ (
+ SELECT trans_id
+ FROM acc_trans
+ JOIN chart ON (chart_id = id)
+ WHERE link LIKE '%AR_paid%'
+ $subwhere
+ )
+ $project
+ GROUP BY g.accno, g.description, c.category
+
+ UNION ALL
+
+ SELECT g.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount,
+ g.description AS description, c.category
+ FROM invoice ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.expense_accno_id = c.id)
+ JOIN gifi g ON (g.accno = c.gifi_accno)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ $ywhere
+ AND c.category = 'E'
+ $dpt_where
+ AND ac.trans_id IN
+ (
+ SELECT trans_id
+ FROM acc_trans
+ JOIN chart ON (chart_id = id)
+ WHERE link LIKE '%AP_paid%'
+ $subwhere
+ )
+ $project
+ GROUP BY g.accno, g.description, c.category
+
+ UNION ALL
+
+ SELECT g.accno AS accno, SUM(ac.sellprice * ac.allocated) * -1 AS amount,
+ g.description AS description, c.category
+ FROM invoice ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.expense_accno_id = c.id)
+ JOIN gifi g ON (g.accno = c.gifi_accno)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ AND ac.assemblyitem = '0'
+ $ywhere
+ AND c.category = 'E'
+ $dpt_where
+ AND ac.trans_id IN
+ (
+ SELECT trans_id
+ FROM acc_trans
+ JOIN chart ON (chart_id = id)
+ WHERE link LIKE '%AP_paid%'
+ $subwhere
+ )
+ $project
+ GROUP BY g.accno, g.description, c.category
+ |;
+ }
+
} else {
+ if ($department_id)
+ {
+ $dpt_join = qq|
+ JOIN dpt_trans t ON (t.trans_id = ac.trans_id)
+ |;
+ $dpt_where = qq|
+ AND t.department_id = $department_id
+ |;
+
+ }
+
$query = qq|
SELECT g.accno, SUM(ac.amount) AS amount,
@@ -526,32 +818,121 @@ sub get_accounts {
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
JOIN gifi g ON (c.gifi_accno = g.accno)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_from
$category
$project
GROUP BY g.accno, g.description, c.category
- UNION
+ UNION ALL
SELECT '' AS accno, SUM(ac.amount) AS amount,
'' AS description, c.category
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_from
$category
AND c.gifi_accno = ''
$project
- GROUP by c.category
+ GROUP BY c.category
|;
-
+
+ if ($yearend) {
+
+ # this is for the yearend
+
+ $query .= qq|
+
+ UNION ALL
+
+ SELECT g.accno, sum(ac.amount) AS amount,
+ g.description, c.category
+ FROM yearend y
+ JOIN acc_trans ac ON (ac.trans_id = y.trans_id)
+ JOIN chart c ON (c.id = ac.chart_id)
+ JOIN gifi g ON (g.accno = c.accno)
+ $dpt_join
+ WHERE $yearendwhere
+ AND c.category = 'Q'
+ $dpt_where
+ $project
+ GROUP BY g.accno, g.description, c.category
+ |;
+ }
+
+ if ($project_id)
+ {
+
+ $query .= qq|
+
+ UNION ALL
+
+ SELECT g.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount,
+ g.description AS description, c.category
+ FROM invoice ac
+ JOIN ar a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.income_accno_id = c.id)
+ JOIN gifi g ON (c.gifi_accno = g.accno)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ $ywhere
+ AND c.category = 'I'
+ $dpt_where
+ $project
+ GROUP BY g.accno, g.description, c.category
+
+ UNION ALL
+
+ SELECT g.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount,
+ g.description AS description, c.category
+ FROM invoice ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.expense_accno_id = c.id)
+ JOIN gifi g ON (c.gifi_accno = g.accno)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ $ywhere
+ AND c.category = 'E'
+ $dpt_where
+ $project
+ GROUP BY g.accno, g.description, c.category
+
+ UNION ALL
+
+ SELECT g.accno AS accno, SUM(ac.sellprice * ac.allocated) * -1 AS amount,
+ g.description AS description, c.category
+ FROM invoice ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.expense_accno_id = c.id)
+ JOIN gifi g ON (c.gifi_accno = g.accno)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ AND ac.assemblyitem = '0'
+ $ywhere
+ AND c.category = 'E'
+ $dpt_where
+ $project
+ GROUP BY g.accno, g.description, c.category
+ |;
+ }
+
}
- } else {
+ } else { # standard account
if ($form->{method} eq 'cash')
{
-
$query = qq|
SELECT c.accno, sum(ac.amount) AS amount,
@@ -559,7 +940,10 @@ sub get_accounts {
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
JOIN ar a ON (a.id = ac.trans_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_where
$category
AND ac.trans_id IN
(
@@ -573,14 +957,17 @@ sub get_accounts {
$project
GROUP BY c.accno, c.description, c.category
- UNION
+ UNION ALL
SELECT c.accno, sum(ac.amount) AS amount,
c.description, c.category
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
JOIN ap a ON (a.id = ac.trans_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_where
$category
AND ac.trans_id IN
(
@@ -594,39 +981,244 @@ sub get_accounts {
$project
GROUP BY c.accno, c.description, c.category
- UNION
+ UNION ALL
SELECT c.accno, sum(ac.amount) AS amount,
c.description, c.category
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
JOIN gl a ON (a.id = ac.trans_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $glwhere
+ $dpt_from
$category
AND NOT (c.link = 'AR' OR c.link = 'AP')
$project
GROUP BY c.accno, c.description, c.category
|;
+
+ if ($yearend) {
+
+ # this is for the yearend
+
+ $query .= qq|
+
+ UNION ALL
+
+ SELECT c.accno, sum(ac.amount) AS amount,
+ c.description, c.category
+ FROM yearend y
+ JOIN acc_trans ac ON (ac.trans_id = y.trans_id)
+ JOIN chart c ON (c.id = ac.chart_id)
+ $dpt_join
+ WHERE $yearendwhere
+ AND c.category = 'Q'
+ $dpt_where
+ $project
+ GROUP BY c.accno, c.description, c.category
+ |;
+ }
+
+ if ($project_id)
+ {
+
+ $query .= qq|
+
+ UNION ALL
+
+ SELECT c.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount,
+ c.description AS description, c.category
+ FROM invoice ac
+ JOIN ar a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.income_accno_id = c.id)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ $ywhere
+ AND c.category = 'I'
+ $dpt_where
+ AND ac.trans_id IN
+ (
+ SELECT trans_id
+ FROM acc_trans
+ JOIN chart ON (chart_id = id)
+ WHERE link LIKE '%AR_paid%'
+ $subwhere
+ )
+
+ $project
+ GROUP BY c.accno, c.description, c.category
+
+ UNION ALL
+
+ SELECT c.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount,
+ c.description AS description, c.category
+ FROM invoice ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ $ywhere
+ AND c.category = 'E'
+ $dpt_where
+ AND ac.trans_id IN
+ (
+ SELECT trans_id
+ FROM acc_trans
+ JOIN chart ON (chart_id = id)
+ WHERE link LIKE '%AP_paid%'
+ $subwhere
+ )
+
+ $project
+ GROUP BY c.accno, c.description, c.category
+
+ UNION ALL
+
+ SELECT c.accno AS accno, SUM(ac.sellprice * ac.allocated) * -1 AS amount,
+ c.description AS description, c.category
+ FROM invoice ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ AND ac.assemblyitem = '0'
+ $ywhere
+ AND c.category = 'E'
+ $dpt_where
+ AND ac.trans_id IN
+ (
+ SELECT trans_id
+ FROM acc_trans
+ JOIN chart ON (chart_id = id)
+ WHERE link LIKE '%AP_paid%'
+ $subwhere
+ )
+
+ $project
+ GROUP BY c.accno, c.description, c.category
+ |;
+ }
+
} else {
+ if ($department_id)
+ {
+ $dpt_join = qq|
+ JOIN dpt_trans t ON (t.trans_id = ac.trans_id)
+ |;
+ $dpt_where = qq|
+ AND t.department_id = $department_id
+ |;
+ }
+
+
$query = qq|
SELECT c.accno, sum(ac.amount) AS amount,
c.description, c.category
FROM acc_trans ac
JOIN chart c ON (c.id = ac.chart_id)
- $where
+ $dpt_join
+ WHERE $where
+ $ywhere
+ $dpt_where
$category
$project
GROUP BY c.accno, c.description, c.category
|;
+ if ($yearend) {
+
+ # this is for the yearend
+
+ $query .= qq|
+
+ UNION ALL
+
+ SELECT c.accno, sum(ac.amount) AS amount,
+ c.description, c.category
+ FROM yearend y
+ JOIN acc_trans ac ON (ac.trans_id = y.trans_id)
+ JOIN chart c ON (c.id = ac.chart_id)
+ $dpt_join
+ WHERE $yearendwhere
+ AND c.category = 'Q'
+ $dpt_where
+ $project
+ GROUP BY c.accno, c.description, c.category
+ |;
+ }
+
+
+ if ($project_id)
+ {
+
+ $query .= qq|
+
+ UNION ALL
+
+ SELECT c.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount,
+ c.description AS description, c.category
+ FROM invoice ac
+ JOIN ar a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.income_accno_id = c.id)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ $ywhere
+ AND c.category = 'I'
+ $dpt_where
+ $project
+ GROUP BY c.accno, c.description, c.category
+
+ UNION ALL
+
+ SELECT c.accno AS accno, SUM(ac.sellprice * ac.qty) AS amount,
+ c.description AS description, c.category
+ FROM invoice ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ $ywhere
+ AND c.category = 'E'
+ $dpt_where
+ $project
+ GROUP BY c.accno, c.description, c.category
+
+ UNION ALL
+
+ SELECT c.accno AS accno, SUM(ac.sellprice * ac.allocated) * -1 AS amount,
+ c.description AS description, c.category
+ FROM invoice ac
+ JOIN ap a ON (a.id = ac.trans_id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c on (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE 1 = 1 $projectwhere
+ AND ac.assemblyitem = '0'
+ $ywhere
+ AND c.category = 'E'
+ $dpt_where
+ $project
+ GROUP BY c.accno, c.description, c.category
+ |;
+
+ }
}
-
}
-
my @accno;
my $accno;
my $ref;
@@ -640,11 +1232,11 @@ sub get_accounts {
if ($ref->{category} eq 'C') {
$ref->{category} = 'A';
}
-
+
# get last heading account
@accno = grep { $_ le "$ref->{accno}" } @headingaccounts;
$accno = pop @accno;
- if ($accno) {
+ if ($accno && ($accno ne $ref->{accno}) ) {
if ($last_period)
{
$form->{$ref->{category}}{$accno}{last} += $ref->{amount};
@@ -681,7 +1273,7 @@ sub get_accounts {
-sub trial_balance_details {
+sub trial_balance {
my ($self, $myconfig, $form) = @_;
my $dbh = $form->dbconnect($myconfig);
@@ -689,40 +1281,72 @@ sub trial_balance_details {
my ($query, $sth, $ref);
my %balance = ();
my %trb = ();
+ my $null;
+ my $department_id;
+ my $project_id;
+ my @headingaccounts = ();
+ my $dpt_where;
+ my $dpt_join;
+ my $project;
- my $where = "WHERE 1 = 1";
+ my $where = "1 = 1";
+ my $invwhere = $where;
+
+ ($null, $department_id) = split /--/, $form->{department};
+ ($null, $project_id) = split /--/, $form->{projectnumber};
- if ($form->{project_id}) {
- $where .= qq|
- AND a.project_id = $form->{project_id}
+ if ($department_id) {
+ $dpt_join = qq|
+ JOIN dpt_trans t ON (ac.trans_id = t.trans_id)
+ |;
+ $dpt_where = qq|
+ AND t.department_id = $department_id
|;
}
+
+ # project_id only applies to getting transactions
+ # it has nothing to do with a trial balance
+ # but we use the same function to collect information
+
+ if ($project_id) {
+ $project = qq|
+ AND ac.project_id = $project_id
+ |;
+ }
+
+ ($form->{fromdate}, $form->{todate}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
+
# get beginning balances
if ($form->{fromdate}) {
if ($form->{accounttype} eq 'gifi') {
- $query = qq|SELECT g.accno, c.category, SUM(a.amount) AS amount,
+ $query = qq|SELECT g.accno, c.category, SUM(ac.amount) AS amount,
g.description
- FROM acc_trans a
- JOIN chart c ON (a.chart_id = c.id)
+ FROM acc_trans ac
+ JOIN chart c ON (ac.chart_id = c.id)
JOIN gifi g ON (c.gifi_accno = g.accno)
- $where
- AND a.transdate < '$form->{fromdate}'
+ $dpt_join
+ WHERE ac.transdate < '$form->{fromdate}'
+ $dpt_where
+ $project
GROUP BY g.accno, c.category, g.description
|;
} else {
- $query = qq|SELECT c.accno, c.category, SUM(a.amount) AS amount,
+ $query = qq|SELECT c.accno, c.category, SUM(ac.amount) AS amount,
c.description
- FROM acc_trans a
- JOIN chart c ON (a.chart_id = c.id)
- $where
- AND a.transdate < '$form->{fromdate}'
+ FROM acc_trans ac
+ JOIN chart c ON (ac.chart_id = c.id)
+ $dpt_join
+ WHERE ac.transdate < '$form->{fromdate}'
+ $dpt_where
+ $project
GROUP BY c.accno, c.category, c.description
|;
+
}
$sth = $dbh->prepare($query);
@@ -761,7 +1385,6 @@ sub trial_balance_details {
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
- my @headingaccounts = ();
while ($ref = $sth->fetchrow_hashref(NAME_lc))
{
$trb{$ref->{accno}}{description} = $ref->{description};
@@ -776,10 +1399,12 @@ sub trial_balance_details {
if ($form->{fromdate} || $form->{todate}) {
if ($form->{fromdate}) {
- $where .= " AND a.transdate >= '$form->{fromdate}'";
+ $where .= " AND ac.transdate >= '$form->{fromdate}'";
+ $invwhere .= " AND a.transdate >= '$form->{fromdate}'";
}
if ($form->{todate}) {
- $where .= " AND a.transdate <= '$form->{todate}'";
+ $where .= " AND ac.transdate <= '$form->{todate}'";
+ $invwhere .= " AND a.transdate <= '$form->{todate}'";
}
}
@@ -787,82 +1412,214 @@ sub trial_balance_details {
if ($form->{accounttype} eq 'gifi') {
$query = qq|SELECT g.accno, g.description, c.category,
- SUM(a.amount) AS amount
- FROM acc_trans a
- JOIN chart c ON (c.id = a.chart_id)
+ SUM(ac.amount) AS amount
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
JOIN gifi g ON (c.gifi_accno = g.accno)
- $where
+ $dpt_join
+ WHERE $where
+ $dpt_where
+ $project
GROUP BY g.accno, g.description, c.category
-
- UNION
+ |;
+
+ if ($project_id) {
- SELECT '' AS accno, '' AS description, c.category,
- SUM(a.amount) AS amount
- FROM acc_trans a
- JOIN chart c ON (c.id = a.chart_id)
- $where
- AND c.gifi_accno = ''
- GROUP BY c.category
+ $query .= qq|
+
+ -- sold items
+
+ UNION ALL
+
+ SELECT g.accno, g.description, c.category,
+ SUM(ac.sellprice * ac.qty) AS amount
+ FROM invoice ac
+ JOIN ar a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.income_accno_id = c.id)
+ JOIN gifi g ON (c.gifi_accno = g.accno)
+ $dpt_join
+ WHERE $invwhere
+ $dpt_where
+ $project
+ GROUP BY g.accno, g.description, c.category
+
+ UNION ALL
+
+ -- bought services
+
+ SELECT g.accno, g.description, c.category,
+ SUM(ac.sellprice * ac.qty) AS amount
+ FROM invoice ac
+ JOIN ap a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.expense_accno_id = c.id)
+ JOIN gifi g ON (c.gifi_accno = g.accno)
+ $dpt_join
+ WHERE $invwhere
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ $dpt_where
+ $project
+ GROUP BY g.accno, g.description, c.category
+
+ -- COGS
+
+ UNION ALL
+
+ SELECT g.accno, g.description, c.category,
+ SUM(ac.sellprice * ac.allocated) * -1 AS amount
+ FROM invoice ac
+ JOIN ap a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.expense_accno_id = c.id)
+ JOIN gifi g ON (c.gifi_accno = g.accno)
+ $dpt_join
+ WHERE $invwhere
+ AND ac.assemblyitem = '0'
+ $dpt_where
+ $project
+ GROUP BY g.accno, g.description, c.category
+
+ |;
+ }
+
+ $query .= qq|
ORDER BY accno|;
} else {
$query = qq|SELECT c.accno, c.description, c.category,
- SUM(a.amount) AS amount
- FROM acc_trans a
- JOIN chart c ON (c.id = a.chart_id)
- $where
+ SUM(ac.amount) AS amount
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ $dpt_join
+ WHERE $where
+ $dpt_where
+ $project
GROUP BY c.accno, c.description, c.category
+ |;
+
+ if ($project_id) {
+
+ $query .= qq|
+
+ -- sold items
+
+ UNION ALL
+
+ SELECT c.accno, c.description, c.category,
+ SUM(ac.sellprice * ac.qty) AS amount
+ FROM invoice ac
+ JOIN ar a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.income_accno_id = c.id)
+ $dpt_join
+ WHERE $invwhere
+ $dpt_where
+ $project
+ GROUP BY c.accno, c.description, c.category
+
+ UNION ALL
+
+ -- bought services
+
+ SELECT c.accno, c.description, c.category,
+ SUM(ac.sellprice * ac.qty) AS amount
+ FROM invoice ac
+ JOIN ap a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE $invwhere
+ AND p.inventory_accno_id IS NULL
+ AND p.assembly = '0'
+ $dpt_where
+ $project
+ GROUP BY c.accno, c.description, c.category
+
+ -- cogs
+
+ UNION ALL
+
+ SELECT c.accno, c.description, c.category,
+ SUM(ac.sellprice * ac.allocated) * -1 AS amount
+ FROM invoice ac
+ JOIN ap a ON (ac.trans_id = a.id)
+ JOIN parts p ON (ac.parts_id = p.id)
+ JOIN chart c ON (p.expense_accno_id = c.id)
+ $dpt_join
+ WHERE $invwhere
+ AND ac.assemblyitem = '0'
+ $dpt_where
+ $project
+ GROUP BY c.accno, c.description, c.category
+
+ |;
+ }
+
+ $query .= qq|
ORDER BY accno|;
}
-
+
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
-
# prepare query for each account
-
- $query = qq|SELECT (SELECT SUM(a.amount) * -1
- FROM acc_trans a
- JOIN chart c ON (c.id = a.chart_id)
- $where
- AND a.amount < 0
+ $query = qq|SELECT (SELECT SUM(ac.amount) * -1
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ $dpt_join
+ WHERE $where
+ $dpt_where
+ $project
+ AND ac.amount < 0
AND c.accno = ?) AS debit,
- (SELECT SUM(a.amount)
- FROM acc_trans a
- JOIN chart c ON (c.id = a.chart_id)
- $where
- AND a.amount > 0
+
+ (SELECT SUM(ac.amount)
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ $dpt_join
+ WHERE $where
+ $dpt_where
+ $project
+ AND ac.amount > 0
AND c.accno = ?) AS credit
|;
if ($form->{accounttype} eq 'gifi') {
- $query = qq|SELECT (SELECT SUM(a.amount) * -1
- FROM acc_trans a
- JOIN chart c ON (c.id = a.chart_id)
- $where
- AND a.amount < 0
+ $query = qq|SELECT (SELECT SUM(ac.amount) * -1
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ $dpt_join
+ WHERE $where
+ $dpt_where
+ $project
+ AND ac.amount < 0
AND c.gifi_accno = ?) AS debit,
- (SELECT SUM(a.amount)
- FROM acc_trans a
- JOIN chart c ON (c.id = a.chart_id)
- $where
- AND a.amount > 0
+
+ (SELECT SUM(ac.amount)
+ FROM acc_trans ac
+ JOIN chart c ON (c.id = ac.chart_id)
+ $dpt_join
+ WHERE $where
+ $dpt_where
+ $project
+ AND ac.amount > 0
AND c.gifi_accno = ?) AS credit|;
}
-
- $drcr = $dbh->prepare($query);
- # calculate the debit and credit in the period
+ $drcr = $dbh->prepare($query);
+
+ # calculate debit and credit for the period
while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
$trb{$ref->{accno}}{description} = $ref->{description};
$trb{$ref->{accno}}{charttype} = 'A';
$trb{$ref->{accno}}{category} = $ref->{category};
$trb{$ref->{accno}}{amount} += $ref->{amount};
-
}
$sth->finish;
@@ -870,29 +1627,41 @@ sub trial_balance_details {
foreach my $accno (sort keys %trb) {
$ref = ();
-
+
$ref->{accno} = $accno;
map { $ref->{$_} = $trb{$accno}{$_} } qw(description category charttype amount);
$ref->{balance} = $form->round_amount($balance{$ref->{accno}}, 2);
if ($trb{$accno}{charttype} eq 'A') {
- # get DR/CR
- $drcr->execute($ref->{accno}, $ref->{accno}) || $form->dberror($query);
-
- ($debit, $credit) = (0,0);
- while (($debit, $credit) = $drcr->fetchrow_array) {
- $ref->{debit} += $debit;
- $ref->{credit} += $credit;
+ if ($project_id) {
+
+ if ($ref->{amount} < 0) {
+ $ref->{debit} = $ref->{amount} * -1;
+ } else {
+ $ref->{credit} = $ref->{amount};
+ }
+ next if $form->round_amount($ref->{amount}, 2) == 0;
+
+ } else {
+
+ # get DR/CR
+ $drcr->execute($ref->{accno}, $ref->{accno});
+
+ ($debit, $credit) = (0,0);
+ while (($debit, $credit) = $drcr->fetchrow_array) {
+ $ref->{debit} += $debit;
+ $ref->{credit} += $credit;
+ }
+ $drcr->finish;
+
}
- $drcr->finish;
$ref->{debit} = $form->round_amount($ref->{debit}, 2);
$ref->{credit} = $form->round_amount($ref->{credit}, 2);
}
-
# add subtotal
@accno = grep { $_ le "$ref->{accno}" } @headingaccounts;
$accno = pop @accno;
@@ -900,7 +1669,7 @@ sub trial_balance_details {
$trb{$accno}{debit} += $ref->{debit};
$trb{$accno}{credit} += $ref->{credit};
}
-
+
push @{ $form->{TB} }, $ref;
}
@@ -920,7 +1689,6 @@ sub trial_balance_details {
}
-
sub aging {
my ($self, $myconfig, $form) = @_;
@@ -928,10 +1696,15 @@ sub aging {
my $dbh = $form->dbconnect($myconfig);
my $invoice = ($form->{arap} eq 'ar') ? 'is' : 'ir';
+ ($null, $form->{todate}) = $form->from_to($form->{year}, $form->{month}) if $form->{year} && $form->{month};
+
$form->{todate} = $form->current_date($myconfig) unless ($form->{todate});
+
my $where = "1 = 1";
my $name;
+ my $null;
+ my $ref;
if ($form->{"$form->{ct}_id"}) {
$where .= qq| AND ct.id = $form->{"$form->{ct}_id"}|;
@@ -942,11 +1715,22 @@ sub aging {
}
}
+ my $dpt_join;
+ if ($form->{department}) {
+ ($null, $department_id) = split /--/, $form->{department};
+ $dpt_join = qq|
+ JOIN department d ON (a.department_id = d.id)
+ |;
+
+ $where .= qq| AND a.department_id = $department_id|;
+ }
+
# select outstanding vendors or customers, depends on $ct
- my $query = qq|SELECT DISTINCT ct.id, ct.name
- FROM $form->{ct} ct, $form->{arap} a
+ my $query = qq|SELECT DISTINCT ct.id, ct.name, ct.language_code
+ FROM $form->{ct} ct
+ JOIN $form->{arap} a ON (a.$form->{ct}_id = ct.id)
+ $dpt_join
WHERE $where
- AND a.$form->{ct}_id = ct.id
AND a.paid != a.amount
AND (a.transdate <= '$form->{todate}')
ORDER BY ct.name|;
@@ -955,115 +1739,140 @@ sub aging {
$sth->execute || $form->dberror;
my $buysell = ($form->{arap} eq 'ar') ? 'buy' : 'sell';
+
+ my %interval = ( 'Pg' => {
+ 'c0' => "(date '$form->{todate}' - interval '0 days')",
+ 'c30' => "(date '$form->{todate}' - interval '30 days')",
+ 'c60' => "(date '$form->{todate}' - interval '60 days')",
+ 'c90' => "(date '$form->{todate}' - interval '90 days')" },
+ 'DB2' => {
+ 'c0' => "(date ('$form->{todate}') - 0 days)",
+ 'c30' => "(date ('$form->{todate}') - 30 days)",
+ 'c60' => "(date ('$form->{todate}') - 60 days)",
+ 'c90' => "(date ('$form->{todate}') - 90 days)" }
+ );
+
+ $interval{Oracle} = $interval{PgPP} = $interval{Pg};
+
# for each company that has some stuff outstanding
- while ( my ($id) = $sth->fetchrow_array ) {
+ my $id;
+ while (($id, $null, $language_code) = $sth->fetchrow_array ) {
$query = qq|
-
--- between 0-30 days
-
- SELECT $form->{ct}.id AS ctid, $form->{ct}.name,
- addr1, addr2, addr3, addr4, contact,
- phone as customerphone, fax as customerfax, $form->{ct}number,
- "invnumber", "transdate",
- (amount - paid) as "c0", 0.00 as "c30", 0.00 as "c60", 0.00 as "c90",
- "duedate", invoice, $form->{arap}.id,
- (SELECT $buysell FROM exchangerate
- WHERE $form->{arap}.curr = exchangerate.curr
- AND exchangerate.transdate = $form->{arap}.transdate) AS exchangerate
- FROM $form->{arap}, $form->{ct}
- WHERE paid != amount
- AND $form->{arap}.$form->{ct}_id = $form->{ct}.id
- AND $form->{ct}.id = $id
+ SELECT c.id AS ctid, c.name,
+ c.address1, c.address2, c.city, c.state, c.zipcode, c.country,
+ c.contact, c.email,
+ c.phone as customerphone, c.fax as customerfax, c.$form->{ct}number,
+ a.invnumber, a.transdate, a.till, a.ordnumber, a.notes,
+ (a.amount - a.paid) as c0, 0.00 as c30, 0.00 as c60, 0.00 as c90,
+ a.duedate, a.invoice, a.id,
+ (SELECT $buysell FROM exchangerate e
+ WHERE a.curr = e.curr
+ AND e.transdate = a.transdate) AS exchangerate
+ FROM $form->{arap} a
+ JOIN $form->{ct} c ON (a.$form->{ct}_id = c.id)
+ WHERE a.paid != a.amount
+ AND c.id = $id
AND (
- transdate <= (date '$form->{todate}' - interval '0 days')
- AND transdate >= (date '$form->{todate}' - interval '30 days')
+ a.transdate <= $interval{$myconfig->{dbdriver}}{c0}
+ AND a.transdate >= $interval{$myconfig->{dbdriver}}{c30}
)
UNION
--- between 31-60 days
-
- SELECT $form->{ct}.id AS ctid, $form->{ct}.name,
- addr1, addr2, addr3, addr4, contact,
- phone as customerphone, fax as customerfax, $form->{ct}number,
- "invnumber", "transdate",
- 0.00 as "c0", (amount - paid) as "c30", 0.00 as "c60", 0.00 as "c90",
- "duedate", invoice, $form->{arap}.id,
- (SELECT $buysell FROM exchangerate
- WHERE $form->{arap}.curr = exchangerate.curr
- AND exchangerate.transdate = $form->{arap}.transdate) AS exchangerate
- FROM $form->{arap}, $form->{ct}
- WHERE paid != amount
- AND $form->{arap}.$form->{ct}_id = $form->{ct}.id
- AND $form->{ct}.id = $id
+ SELECT c.id AS ctid, c.name,
+ c.address1, c.address2, c.city, c.state, c.zipcode, c.country,
+ c.contact, c.email,
+ c.phone as customerphone, c.fax as customerfax, c.$form->{ct}number,
+ a.invnumber, a.transdate, a.till, a.ordnumber, a.notes,
+ 0.00 as c0, (a.amount - a.paid) as c30, 0.00 as c60, 0.00 as c90,
+ a.duedate, a.invoice, a.id,
+ (SELECT $buysell FROM exchangerate e
+ WHERE a.curr = e.curr
+ AND e.transdate = a.transdate) AS exchangerate
+ FROM $form->{arap} a
+ JOIN $form->{ct} c ON (a.$form->{ct}_id = c.id)
+ WHERE a.paid != a.amount
+ AND c.id = $id
AND (
- transdate < (date '$form->{todate}' - interval '30 days')
- AND transdate >= (date '$form->{todate}' - interval '60 days')
+ a.transdate < $interval{$myconfig->{dbdriver}}{c30}
+ AND a.transdate >= $interval{$myconfig->{dbdriver}}{c60}
)
UNION
--- between 61-90 days
-
- SELECT $form->{ct}.id AS ctid, $form->{ct}.name,
- addr1, addr2, addr3, addr4, contact,
- phone as customerphone, fax as customerfax, $form->{ct}number,
- "invnumber", "transdate",
- 0.00 as "c0", 0.00 as "c30", (amount - paid) as "c60", 0.00 as "c90",
- "duedate", invoice, $form->{arap}.id,
- (SELECT $buysell FROM exchangerate
- WHERE $form->{arap}.curr = exchangerate.curr
- AND exchangerate.transdate = $form->{arap}.transdate) AS exchangerate
- FROM $form->{arap}, $form->{ct}
- WHERE paid != amount
- AND $form->{arap}.$form->{ct}_id = $form->{ct}.id
- AND $form->{ct}.id = $id
+ SELECT c.id AS ctid, c.name,
+ c.address1, c.address2, c.city, c.state, c.zipcode, c.country,
+ c.contact, c.email,
+ c.phone as customerphone, c.fax as customerfax, c.$form->{ct}number,
+ a.invnumber, a.transdate, a.till, a.ordnumber, a.notes,
+ 0.00 as c0, 0.00 as c30, (a.amount - a.paid) as c60, 0.00 as c90,
+ a.duedate, a.invoice, a.id,
+ (SELECT $buysell FROM exchangerate e
+ WHERE a.curr = e.curr
+ AND e.transdate = a.transdate) AS exchangerate
+ FROM $form->{arap} a
+ JOIN $form->{ct} c ON (a.$form->{ct}_id = c.id)
+ WHERE a.paid != a.amount
+ AND c.id = $id
AND (
- transdate < (date '$form->{todate}' - interval '60 days')
- AND transdate >= (date '$form->{todate}' - interval '90 days')
+ a.transdate < $interval{$myconfig->{dbdriver}}{c60}
+ AND a.transdate >= $interval{$myconfig->{dbdriver}}{c90}
)
UNION
--- over 90 days
-
- SELECT $form->{ct}.id AS ctid, $form->{ct}.name,
- addr1, addr2, addr3, addr4, contact,
- phone as customerphone, fax as customerfax, $form->{ct}number,
- "invnumber", "transdate",
- 0.00 as "c0", 0.00 as "c30", 0.00 as "c60", (amount - paid) as "c90",
- "duedate", invoice, $form->{arap}.id,
- (SELECT $buysell FROM exchangerate
- WHERE $form->{arap}.curr = exchangerate.curr
- AND exchangerate.transdate = $form->{arap}.transdate) AS exchangerate
- FROM $form->{arap}, $form->{ct}
- WHERE paid != amount
- AND $form->{arap}.$form->{ct}_id = $form->{ct}.id
- AND $form->{ct}.id = $id
- AND transdate < (date '$form->{todate}' - interval '90 days')
+ SELECT c.id AS ctid, c.name,
+ c.address1, c.address2, c.city, c.state, c.zipcode, c.country,
+ c.contact, c.email,
+ c.phone as customerphone, c.fax as customerfax, c.$form->{ct}number,
+ a.invnumber, a.transdate, a.till, a.ordnumber, a.notes,
+ 0.00 as c0, 0.00 as c30, 0.00 as c60, (a.amount - a.paid) as c90,
+ a.duedate, a.invoice, a.id,
+ (SELECT $buysell FROM exchangerate e
+ WHERE a.curr = e.curr
+ AND e.transdate = a.transdate) AS exchangerate
+ FROM $form->{arap} a
+ JOIN $form->{ct} c ON (a.$form->{ct}_id = c.id)
+ WHERE a.paid != a.amount
+ AND c.id = $id
+ AND a.transdate < $interval{$myconfig->{dbdriver}}{c90}
ORDER BY
- ctid, invnumber, transdate
+ ctid, transdate, invnumber
|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror;
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
$ref->{module} = ($ref->{invoice}) ? $invoice : $form->{arap};
+ $ref->{module} = 'ps' if $ref->{till};
$ref->{exchangerate} = 1 unless $ref->{exchangerate};
+ $ref->{language_code} = $language_code;
push @{ $form->{AG} }, $ref;
}
$sth->finish;
}
+ $sth->finish;
+
+ # get language
+ my $query = qq|SELECT *
+ FROM language
+ ORDER BY 2|;
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+ while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ push @{ $form->{all_language} }, $ref;
+ }
$sth->finish;
+
# disconnect
$dbh->disconnect;
@@ -1079,11 +1888,8 @@ sub get_customer {
my $query = qq|SELECT name, email, cc, bcc
FROM $form->{ct} ct
WHERE ct.id = $form->{"$form->{ct}_id"}|;
- my $sth = $dbh->prepare($query);
- $sth->execute || $form->dberror;
-
- ($form->{$form->{ct}}, $form->{email}, $form->{cc}, $form->{bcc}) = $sth->fetchrow_array;
- $sth->finish;
+ ($form->{$form->{ct}}, $form->{email}, $form->{cc}, $form->{bcc}) = $dbh->selectrow_array($query);
+
$dbh->disconnect;
}
@@ -1096,29 +1902,34 @@ sub get_taxaccounts {
my $dbh = $form->dbconnect($myconfig);
# get tax accounts
- my $query = qq|SELECT accno, description
- FROM chart
- WHERE link LIKE '%CT_tax%'
- ORDER BY accno|;
+ my $query = qq|SELECT c.accno, c.description, t.rate, c.link
+ FROM chart c, tax t
+ WHERE c.link LIKE '%CT_tax%'
+ AND c.id = t.chart_id
+ ORDER BY c.accno|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror;
- while ( my ($accno, $description) = $sth->fetchrow_array ) {
- push @{ $form->{taxaccounts} }, "$accno--$description";
+ my $ref = ();
+ while ($ref = $sth->fetchrow_hashref(NAME_lc) ) {
+ push @{ $form->{taxaccounts} }, $ref;
}
$sth->finish;
# get gifi tax accounts
- my $query = qq|SELECT DISTINCT ON (g.accno) g.accno, g.description
- FROM gifi g, chart c
+ my $query = qq|SELECT DISTINCT g.accno, g.description,
+ sum(t.rate) AS rate
+ FROM gifi g, chart c, tax t
WHERE g.accno = c.gifi_accno
+ AND c.id = t.chart_id
AND c.link LIKE '%CT_tax%'
+ GROUP BY g.accno, g.description
ORDER BY accno|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror;
- while ( my ($accno, $description) = $sth->fetchrow_array ) {
- push @{ $form->{gifi_taxaccounts} }, "$accno--$description";
+ while ($ref = $sth->fetchrow_hashref(NAME_lc) ) {
+ push @{ $form->{gifi_taxaccounts} }, $ref;
}
$sth->finish;
@@ -1134,34 +1945,52 @@ sub tax_report {
# connect to database
my $dbh = $form->dbconnect($myconfig);
+ my ($null, $department_id) = split /--/, $form->{department};
+
# build WHERE
- my $where = qq|WHERE ac.trans_id = a.id
- AND ac.chart_id = ch.id|;
-
+ my $where = "1 = 1";
+ my $cashwhere = "";
- if ($form->{accno} =~ /^gifi_/) {
- my ($null, $accno) = split /_/, $form->{accno};
- $where .= qq| AND ch.gifi_accno = '$accno'|;
- } else {
- $where .= qq| AND ch.accno = '$form->{accno}'|;
+ if ($department_id) {
+ $where .= qq|
+ AND a.department_id = $department_id
+ |;
}
+
+ my $query;
+ my $sth;
+ my $accno;
+ my $rate;
+
+ if ($form->{accno}) {
+ if ($form->{accno} =~ /^gifi_/) {
+ ($null, $accno) = split /_/, $form->{accno};
+ $rate = $form->{"$form->{accno}_rate"};
+ $accno = qq| AND ch.gifi_accno = '$accno'|;
+ } else {
+ $accno = $form->{accno};
+ $rate = $form->{"$form->{accno}_rate"};
+ $accno = qq| AND ch.accno = '$accno'|;
+ }
+ }
+ $rate *= 1;
my $table;
+ my $ARAP;
if ($form->{db} eq 'ar') {
- $where .= " AND n.id = a.customer_id";
$table = "customer";
+ $ARAP = "AR";
}
if ($form->{db} eq 'ap') {
- $where .= " AND n.id = a.vendor_id";
$table = "vendor";
+ $ARAP = "AP";
}
- my $transdate = ($form->{cashbased}) ? "a.datepaid" : "ac.transdate";
- if ($form->{cashbased}) {
- $where .= " AND a.amount = a.paid";
- }
+ my $transdate = "a.transdate";
+ ($form->{fromdate}, $form->{todate}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
+
# if there are any dates construct a where
if ($form->{fromdate} || $form->{todate}) {
if ($form->{fromdate}) {
@@ -1171,29 +2000,372 @@ sub tax_report {
$where .= " AND $transdate <= '$form->{todate}'";
}
}
+
+
+ if ($form->{method} eq 'cash') {
+ $transdate = "a.datepaid";
+
+ my $todate = ($form->{todate}) ? $form->{todate} : $form->current_date($myconfig);
+
+ $cashwhere = qq|
+ AND ac.trans_id IN
+ (
+ SELECT trans_id
+ FROM acc_trans
+ JOIN chart ON (chart_id = id)
+ WHERE link LIKE '%${ARAP}_paid%'
+ AND $transdate <= '$todate'
+ AND a.paid = a.amount
+ )
+ |;
+
+ }
+
+
+ my $ml = ($form->{db} eq 'ar') ? 1 : -1;
- my $query = qq|SELECT a.id, a.invoice, $transdate AS transdate, a.invnumber,
- n.name, a.netamount,|;
- my $sortorder = join ', ', $form->sort_columns(qw(transdate invnumber name));
- $sortorder = $form->{sort} unless $sortorder;
+ my %ordinal = ( 'transdate' => 3,
+ 'invnumber' => 4,
+ 'name' => 5
+ );
- if ($form->{db} eq 'ar') {
- $query .= " ac.amount AS tax";
- }
- if ($form->{db} eq 'ap') {
- $query .= " ac.amount * -1 AS tax";
+ my @a = qw(transdate invnumber name);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+
+ $rate = 1 unless $rate;
+
+ if ($form->{summary}) {
+
+ $query = qq|SELECT a.id, '0' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name, a.netamount,
+ ac.amount * $ml AS tax,
+ a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN chart ch ON (ch.id = ac.chart_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE $where
+ $accno
+ AND a.invoice = '0'
+ $cashwhere
+
+ UNION
+
+ SELECT a.id, '1' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name,
+ sum(ac.sellprice * ac.qty) * $ml AS netamount,
+ sum(ac.sellprice * ac.qty) * $rate * $ml AS tax,
+ a.till
+ FROM invoice ac
+ JOIN partstax pt ON (pt.parts_id = ac.parts_id)
+ JOIN chart ch ON (ch.id = pt.chart_id)
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ JOIN ${table}tax t ON (t.${table}_id = n.id AND t.chart_id = ch.id)
+ WHERE $where
+ $accno
+ AND a.invoice = '1'
+ $cashwhere
+ GROUP BY a.id, a.invoice, $transdate, a.invnumber, n.name,
+ a.till
+ |;
+
+ if ($form->{fromdate}) {
+ # include open transactions from previous period
+ if ($cashwhere) {
+ $query .= qq|
+ UNION
+
+ SELECT a.id, '0' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name, a.netamount,
+ ac.amount * $ml AS tax,
+ a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN chart ch ON (ch.id = ac.chart_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE a.datepaid >= '$form->{fromdate}'
+ $accno
+ AND a.invoice = '0'
+ $cashwhere
+
+ UNION
+
+ SELECT a.id, '1' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name,
+ sum(ac.sellprice * ac.qty) * $ml AS netamount,
+ sum(ac.sellprice * ac.qty) * $rate * $ml AS tax,
+ a.till
+ FROM invoice ac
+ JOIN partstax pt ON (pt.parts_id = ac.parts_id)
+ JOIN chart ch ON (ch.id = pt.chart_id)
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ JOIN ${table}tax t ON (t.${table}_id = n.id AND t.chart_id = ch.id)
+ WHERE a.datepaid >= '$form->{fromdate}'
+ $accno
+ AND a.invoice = '1'
+ $cashwhere
+ GROUP BY a.id, a.invoice, $transdate, a.invnumber, n.name,
+ a.till
+ |;
+ }
+ }
+
+
+ } else {
+
+ $query = qq|SELECT a.id, '0' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name, a.netamount,
+ ac.amount * $ml AS tax,
+ a.notes AS description, a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN chart ch ON (ch.id = ac.chart_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE $where
+ $accno
+ AND a.invoice = '0'
+ $cashwhere
+
+ UNION
+
+ SELECT a.id, '1' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name,
+ i.sellprice * i.qty * $ml AS netamount,
+ i.sellprice * i.qty * $rate * $ml AS tax,
+ i.description, a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN chart ch ON (ch.id = ac.chart_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ JOIN ${table}tax t ON (t.${table}_id = n.id AND t.chart_id = ch.id)
+ JOIN invoice i ON (i.trans_id = a.id)
+ JOIN partstax pt ON (pt.parts_id = i.parts_id AND pt.chart_id = ch.id)
+ WHERE $where
+ $accno
+ AND a.invoice = '1'
+ $cashwhere
+ |;
+
+ if ($form->{fromdate}) {
+ if ($cashwhere) {
+ $query .= qq|
+ UNION
+
+ SELECT a.id, '0' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name, a.netamount,
+ ac.amount * $ml AS tax,
+ a.notes AS description, a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN chart ch ON (ch.id = ac.chart_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE a.datepaid >= '$form->{fromdate}'
+ $accno
+ AND a.invoice = '0'
+ $cashwhere
+
+ UNION
+
+ SELECT a.id, '1' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name,
+ i.sellprice * i.qty * $ml AS netamount,
+ i.sellprice * i.qty * $rate * $ml AS tax,
+ i.description, a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN chart ch ON (ch.id = ac.chart_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ JOIN ${table}tax t ON (t.${table}_id = n.id AND t.chart_id = ch.id)
+ JOIN invoice i ON (i.trans_id = a.id)
+ JOIN partstax pt ON (pt.parts_id = i.parts_id AND pt.chart_id = ch.id)
+ WHERE a.datepaid >= '$form->{fromdate}'
+ $accno
+ AND a.invoice = '1'
+ $cashwhere
+ |;
+ }
+ }
+ }
+
+
+ if ($form->{report} =~ /nontaxable/) {
+
+ if ($form->{summary}) {
+ # only gather up non-taxable transactions
+ $query = qq|SELECT a.id, '0' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name, a.netamount, a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE $where
+ AND a.invoice = '0'
+ AND a.netamount = a.amount
+ $cashwhere
+ GROUP BY a.id, $transdate, a.invnumber, n.name, a.netamount,
+ a.till
+
+ UNION
+
+ SELECT a.id, '1' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name,
+ sum(ac.sellprice * ac.qty) * $ml AS netamount, a.till
+ FROM invoice ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE $where
+ AND a.invoice = '1'
+ AND (
+ a.${table}_id NOT IN (
+ SELECT ${table}_id FROM ${table}tax t (${table}_id)
+ ) OR
+ ac.parts_id NOT IN (
+ SELECT parts_id FROM partstax p (parts_id)
+ )
+ )
+ $cashwhere
+ GROUP BY a.id, a.invnumber, $transdate, n.name, a.till
+ |;
+
+ if ($form->{fromdate}) {
+ if ($cashwhere) {
+ $query .= qq|
+ UNION
+
+ SELECT a.id, '0' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name, a.netamount, a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE a.datepaid >= '$form->{fromdate}'
+ AND a.invoice = '0'
+ AND a.netamount = a.amount
+ $cashwhere
+ GROUP BY a.id, $transdate, a.invnumber, n.name, a.netamount,
+ a.till
+
+ UNION
+
+ SELECT a.id, '1' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name,
+ sum(ac.sellprice * ac.qty) * $ml AS netamount, a.till
+ FROM invoice ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE a.datepaid >= '$form->{fromdate}'
+ AND a.invoice = '1'
+ AND (
+ a.${table}_id NOT IN (
+ SELECT ${table}_id FROM ${table}tax t (${table}_id)
+ ) OR
+ ac.parts_id NOT IN (
+ SELECT parts_id FROM partstax p (parts_id)
+ )
+ )
+ $cashwhere
+ GROUP BY a.id, a.invnumber, $transdate, n.name, a.till
+ |;
+ }
+ }
+
+ } else {
+
+ # gather up details for non-taxable transactions
+ $query = qq|SELECT a.id, '0' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name, a.netamount,
+ a.notes AS description, a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE $where
+ AND a.invoice = '0'
+ AND a.netamount = a.amount
+ $cashwhere
+ GROUP BY a.id, $transdate, a.invnumber, n.name, a.netamount,
+ a.notes, a.till
+
+ UNION
+
+ SELECT a.id, '1' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name,
+ sum(ac.sellprice * ac.qty) * $ml AS netamount,
+ ac.description, a.till
+ FROM invoice ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE $where
+ AND a.invoice = '1'
+ AND (
+ a.${table}_id NOT IN (
+ SELECT ${table}_id FROM ${table}tax t (${table}_id)
+ ) OR
+ ac.parts_id NOT IN (
+ SELECT parts_id FROM partstax p (parts_id)
+ )
+ )
+ $cashwhere
+ GROUP BY a.id, a.invnumber, $transdate, n.name,
+ ac.description, a.till
+ |;
+
+ if ($form->{fromdate}) {
+ if ($cashwhere) {
+ $query .= qq|
+ UNION
+
+ SELECT a.id, '0' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name, a.netamount,
+ a.notes AS description, a.till
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE a.datepaid >= '$form->{fromdate}'
+ AND a.invoice = '0'
+ AND a.netamount = a.amount
+ $cashwhere
+ GROUP BY a.id, $transdate, a.invnumber, n.name, a.netamount,
+ a.notes, a.till
+
+ UNION
+
+ SELECT a.id, '1' AS invoice, $transdate AS transdate,
+ a.invnumber, n.name,
+ sum(ac.sellprice * ac.qty) * $ml AS netamount,
+ ac.description, a.till
+ FROM invoice ac
+ JOIN $form->{db} a ON (a.id = ac.trans_id)
+ JOIN $table n ON (n.id = a.${table}_id)
+ WHERE a.datepaid >= '$form->{fromdate}'
+ AND a.invoice = '1'
+ AND (
+ a.${table}_id NOT IN (
+ SELECT ${table}_id FROM ${table}tax t (${table}_id)
+ ) OR
+ ac.parts_id NOT IN (
+ SELECT parts_id FROM partstax p (parts_id)
+ )
+ )
+ $cashwhere
+ GROUP BY a.id, a.invnumber, $transdate, n.name,
+ ac.description, a.till
+ |;
+ }
+ }
+
+ }
}
+
$query .= qq|
- FROM acc_trans ac, "$form->{db}" a, "$table" n, chart ch
- $where
- ORDER by $sortorder|;
+ ORDER by $sortorder|;
- my $sth = $dbh->prepare($query);
+ $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
while ( my $ref = $sth->fetchrow_hashref(NAME_lc)) {
- push @{ $form->{TR} }, $ref;
+ $ref->{tax} = $form->round_amount($ref->{tax}, 2);
+ push @{ $form->{TR} }, $ref if $ref->{netamount} != 0;
}
$sth->finish;
@@ -1208,21 +2380,23 @@ sub paymentaccounts {
# connect to database, turn AutoCommit off
my $dbh = $form->dbconnect_noauto($myconfig);
- my $arap = uc $form->{db};
- $arap .= "_paid";
+ my $ARAP = uc $form->{db};
# get A(R|P)_paid accounts
my $query = qq|SELECT accno, description
FROM chart
- WHERE link LIKE '%$arap%'|;
+ WHERE link LIKE '%${ARAP}_paid%'
+ ORDER BY accno|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
push @{ $form->{PR} }, $ref;
}
-
$sth->finish;
+
+ $form->all_years($dbh, $myconfig);
+
$dbh->disconnect;
}
@@ -1242,9 +2416,62 @@ sub payments {
if ($form->{db} eq 'ap') {
$table = 'vendor';
}
+
+
+ my $query;
+ my $sth;
+ my $dpt_join;
+ my $where;
+ my $var;
+
+ if ($form->{department_id}) {
+ $dpt_join = qq|
+ JOIN dpt_trans t ON (t.trans_id = ac.trans_id)
+ |;
+
+ $where = qq|
+ AND t.department_id = $form->{department_id}
+ |;
+ }
+
+ ($form->{fromdate}, $form->{todate}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
+
+ if ($form->{fromdate}) {
+ $where .= " AND ac.transdate >= '$form->{fromdate}'";
+ }
+ if ($form->{todate}) {
+ $where .= " AND ac.transdate <= '$form->{todate}'";
+ }
+ if (!$form->{fx_transaction}) {
+ $where .= " AND ac.fx_transaction = '0'";
+ }
- my ($query, $sth);
+ if ($form->{description}) {
+ $var = $form->like(lc $form->{description});
+ $where .= " AND lower(c.name) LIKE '$var'";
+ }
+ if ($form->{source}) {
+ $var = $form->like(lc $form->{source});
+ $where .= " AND lower(ac.source) LIKE '$var'";
+ }
+ if ($form->{memo}) {
+ $var = $form->like(lc $form->{memo});
+ $where .= " AND lower(ac.memo) LIKE '$var'";
+ }
+
+ my %ordinal = ( 'name' => 1,
+ 'transdate' => 2,
+ 'source' => 4,
+ 'employee' => 6,
+ 'till' => 7
+ );
+
+ my @a = qw(name transdate employee);
+ my $sortorder = $form->sort_order(\@a, \%ordinal);
+ my $glwhere = $where;
+ $glwhere =~ s/\(c.name\)/\(g.description\)/;
+
# cycle through each id
foreach my $accno (split(/ /, $form->{paymentaccounts})) {
@@ -1258,37 +2485,51 @@ sub payments {
push @{ $form->{PR} }, $ref;
$sth->finish;
- $query = qq|SELECT c.name, a.invnumber, a.ordnumber,
- ac.transdate,
- ac.amount * $ml AS paid, ac.source, a.invoice, a.id,
- '$form->{db}' AS module
- FROM $table c, acc_trans ac, $form->{db} a
- WHERE c.id = a.${table}_id
- AND ac.trans_id = a.id
- AND ac.chart_id = $ref->{id}|;
-
- $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
- $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
+ $query = qq|SELECT c.name, ac.transdate, sum(ac.amount) * $ml AS paid,
+ ac.source, ac.memo, e.name AS employee, a.till, a.curr
+ FROM acc_trans ac
+ JOIN $form->{db} a ON (ac.trans_id = a.id)
+ JOIN $table c ON (c.id = a.${table}_id)
+ LEFT JOIN employee e ON (a.employee_id = e.id)
+ $dpt_join
+ WHERE ac.chart_id = $ref->{id}
+ $where|;
+
+ if ($form->{till}) {
+ $query .= " AND a.invoice = '1'
+ AND NOT a.till IS NULL";
+
+ if ($myconfig->{role} eq 'user') {
+ $query .= " AND e.login = '$form->{login}'";
+ }
+ }
$query .= qq|
+ GROUP BY c.name, ac.transdate, ac.source, ac.memo,
+ e.name, a.till, a.curr
+ |;
+
+ if (! $form->{till}) {
+# don't need gl for a till
+
+ $query .= qq|
UNION
- SELECT g.description, g.reference, NULL AS ordnumber,
- ac.transdate,
- ac.amount * $ml AS paid, ac.source, '0' as invoice, g.id,
- 'gl' AS module
- FROM gl g, acc_trans ac
- WHERE g.id = ac.trans_id
- AND ac.chart_id = $ref->{id}
- AND (ac.amount * $ml) > 0
+ SELECT g.description, ac.transdate, sum(ac.amount) * $ml AS paid, ac.source,
+ ac.memo, e.name AS employee, '' AS till, '' AS curr
+ FROM acc_trans ac
+ JOIN gl g ON (g.id = ac.trans_id)
+ LEFT JOIN employee e ON (g.employee_id = e.id)
+ $dpt_join
+ WHERE ac.chart_id = $ref->{id}
+ $glwhere
+ AND (ac.amount * $ml) > 0
+ GROUP BY g.description, ac.transdate, ac.source, ac.memo, e.name
|;
- $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
- $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
-
+ }
- my $sortorder = join ', ', $form->sort_columns(qw(name invnumber ordnumber transdate source));
-
- $query .= " ORDER BY $sortorder";
+ $query .= qq|
+ ORDER BY $sortorder|;
$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);
diff --git a/sql-ledger/SL/User.pm b/sql-ledger/SL/User.pm
index d9b463d6b..e7e0b9cbc 100644
--- a/sql-ledger/SL/User.pm
+++ b/sql-ledger/SL/User.pm
@@ -1,18 +1,18 @@
#=====================================================================
# SQL-Ledger Accounting
-# Copyright (C) 2001
+# Copyright (C) 2000
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
-# Contributors:
+# Contributors: Jim Rawlings <jim@your-dba.com>
#
# 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
@@ -34,7 +34,6 @@ sub new {
my $self = {};
if ($login ne "") {
- # check if the file is locked
&error("", "$memfile locked!") if (-f "${memfile}.LCK");
open(MEMBER, "$memfile") or &error("", "$memfile : $!");
@@ -46,7 +45,7 @@ sub new {
next if /^(#|\s)/;
# remove comments
- s/\s#.*//g;
+ s/^\s*#.*//g;
# remove any trailing whitespace
s/^\s*(.*?)\s*$/$1/;
@@ -96,17 +95,18 @@ sub country_codes {
sub login {
my ($self, $form, $userspath) = @_;
-
+ my $rc = -3;
+
if ($self->{login}) {
-
+
if ($self->{password}) {
- $form->{password} = crypt $form->{password}, substr($self->{login}, 0, 2);
- if ($self->{password} ne $form->{password}) {
+ my $password = crypt $form->{password}, substr($self->{login}, 0, 2);
+ if ($self->{password} ne $password) {
return -1;
}
}
- unless (-e "$userspath/$self->{login}.conf") {
+ unless (-f "$userspath/$self->{login}.conf") {
$self->create_config("$userspath/$self->{login}.conf");
}
@@ -114,7 +114,7 @@ sub login {
$myconfig{dbpasswd} = unpack 'u', $myconfig{dbpasswd};
# check if database is down
- my $dbh = DBI->connect($myconfig{dbconnect}, $myconfig{dbuser}, $myconfig{dbpasswd}) or $self->error(DBI::errstr);
+ my $dbh = DBI->connect($myconfig{dbconnect}, $myconfig{dbuser}, $myconfig{dbpasswd}) or $self->error($DBI::errstr);
# we got a connection, check the version
my $query = qq|SELECT version FROM defaults|;
@@ -126,28 +126,46 @@ sub login {
# add login to employee table if it does not exist
# no error check for employee table, ignore if it does not exist
- $query = qq|SELECT id FROM employee WHERE login = '$self->{login}'|;
+ my $login = $self->{login};
+ $login =~ s/@.*//;
+ $query = qq|SELECT id FROM employee WHERE login = '$login'|;
$sth = $dbh->prepare($query);
$sth->execute;
- my ($login) = $sth->fetchrow_array;
+ my ($id) = $sth->fetchrow_array;
$sth->finish;
- if (!$login) {
- $query = qq|INSERT INTO employee (login, name, workphone)
- VALUES ('$self->{login}', '$myconfig{name}', '$myconfig{tel}')|;
+ if (! $id) {
+ my ($employeenumber) = $form->update_defaults(\%myconfig, "employeenumber", $dbh);
+
+ $query = qq|INSERT INTO employee (login, employeenumber, name, workphone,
+ role)
+ VALUES ('$login', '$employeenumber', '$myconfig{name}',
+ '$myconfig{tel}', '$myconfig{role}')|;
$dbh->do($query);
}
$dbh->disconnect;
+ $rc = 0;
+
+
if ($form->{dbversion} ne $dbversion) {
- return -2;
+ $rc = -4;
+ $dbupdate = (calc_version($dbversion) < calc_version($form->{dbversion}));
}
- } else {
- return -3;
+ if ($dbupdate) {
+ $rc = -5;
+
+ # if DB2 bale out
+ if ($myconfig{dbdriver} eq 'DB2') {
+ $rc = -2;
+ }
+ }
}
+ $rc;
+
}
@@ -173,11 +191,12 @@ sub dbconnect_vars {
'dd.mm.yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD.MM.YY\'',
}
);
-
+
+
$form->{dboptions} = $dboptions{$form->{dbdriver}}{$form->{dateformat}};
- if ($form->{dbdriver} eq 'Pg') {
- $form->{dbconnect} = "dbi:Pg:dbname=$db";
+ if ($form->{dbdriver} =~ /Pg/) {
+ $form->{dbconnect} = "dbi:$form->{dbdriver}:dbname=$db";
}
if ($form->{dbdriver} eq 'Oracle') {
@@ -198,7 +217,8 @@ sub dbdrivers {
my @drivers = DBI->available_drivers();
- return (grep { /(Pg|Oracle)$/ } @drivers);
+# return (grep { /(Pg|Oracle|DB2)/ } @drivers);
+ return (grep { /Pg$/ } @drivers);
}
@@ -265,6 +285,28 @@ sub dbsources {
}
}
+
+# JJR
+ if ($form->{dbdriver} eq 'DB2') {
+ if ($form->{only_acc_db}) {
+ $query = qq|SELECT tabschema FROM syscat.tables WHERE tabname = 'DEFAULTS'|;
+ } else {
+ $query = qq|SELECT DISTINCT schemaname FROM syscat.schemata WHERE definer != 'SYSIBM' AND schemaname != 'NULLID'|;
+ }
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my ($db) = $sth->fetchrow_array) {
+ push @dbsources, $db;
+ }
+ }
+# End JJR
+
+# the above is not used but leave it in for future reference
+# DS, Oct. 28, 2003
+
+
$sth->finish;
$dbh->disconnect;
@@ -306,21 +348,36 @@ sub dbcreate {
$dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
# create the tables
- my $filename = qq|sql/$form->{dbdriver}-tables.sql|;
- $self->processquery($form, $dbh, $filename);
+ my $dbdriver = ($form->{dbdriver} =~ /Pg/) ? 'Pg' : $form->{dbdriver};
+
+ my $filename = qq|sql/${dbdriver}-tables.sql|;
+ $self->process_query($form, $dbh, $filename);
+
+ # create functions
+ $filename = qq|sql/${dbdriver}-functions.sql|;
+ $self->process_query($form, $dbh, $filename);
# load gifi
($filename) = split /_/, $form->{chart};
$filename =~ s/_//;
- $self->processquery($form, $dbh, "sql/${filename}-gifi.sql");
-
+ $self->process_query($form, $dbh, "sql/${filename}-gifi.sql");
+
# load chart of accounts
$filename = qq|sql/$form->{chart}-chart.sql|;
- $self->processquery($form, $dbh, $filename);
+ $self->process_query($form, $dbh, $filename);
# create indices
- $filename = qq|sql/$form->{dbdriver}-indices.sql|;
- $self->processquery($form, $dbh, $filename);
+ $filename = qq|sql/${dbdriver}-indices.sql|;
+ $self->process_query($form, $dbh, $filename);
+
+ # create custom tables and functions
+ my $item;
+ foreach $item (qw(tables functions)) {
+ $filename = "sql/${dbdriver}-custom_${item}.sql";
+ if (-f "$filename") {
+ $self->process_query($form, $dbh, $filename);
+ }
+ }
$dbh->disconnect;
@@ -328,26 +385,59 @@ sub dbcreate {
-sub processquery {
+sub process_query {
my ($self, $form, $dbh, $filename) = @_;
return unless (-f $filename);
open(FH, "$filename") or $form->error("$filename : $!\n");
my $query = "";
+ my $loop = 0;
+ my $sth;
+
while (<FH>) {
- $query .= $_;
+ if ($loop && /^--\s*end\s*(procedure|function|trigger)/i) {
+ $loop = 0;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+ $sth->finish;
+
+ $query = "";
+ next;
+ }
+
+ if ($loop || /^create *(or replace)? *(procedure|function|trigger)/i) {
+ $loop = 1;
+ next if /^(--.*|\s+)$/;
+
+ $query .= $_;
+ next;
+ }
+
+ # don't add comments or empty lines
+ next if /^(--.*|\s+)$/;
+
+ # anything else, add to query
+ $query .= $_;
+
if (/;\s*$/) {
# strip ;... Oracle doesn't like it
$query =~ s/;\s*$//;
- $dbh->do($query) || $form->dberror($query);
+ $query =~ s/\\'/''/g;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+ $sth->finish;
+
$query = "";
}
+
}
close FH;
-
+
}
@@ -377,7 +467,7 @@ sub dbsources_unused {
my @dbexcl = ();
my @dbsources = ();
- $form->error('File locked!') if (-f "${memfile}.LCK");
+ $form->error("$memfile locked!") if (-f "${memfile}.LCK");
# open members file
open(FH, "$memfile") or $form->error("$memfile : $!");
@@ -418,7 +508,7 @@ sub dbneedsupdate {
my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
- if ($form->{dbdriver} eq 'Pg') {
+ if ($form->{dbdriver} =~ /Pg/) {
$query = qq|SELECT d.datname FROM pg_database d, pg_user u
WHERE d.datdba = u.usesysid
@@ -483,6 +573,37 @@ sub dbneedsupdate {
}
$sth->finish;
}
+
+
+# JJR
+ if ($form->{dbdriver} eq 'DB2') {
+ $query = qq|SELECT tabschema FROM syscat.tables WHERE tabname = 'DEFAULTS'|;
+
+ $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ while (my ($db) = $sth->fetchrow_array) {
+
+ &dbconnect_vars($form, $db);
+
+ my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
+
+ $query = qq|SELECT version FROM defaults|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute;
+
+ if (my ($version) = $sth->fetchrow_array) {
+ $dbsources{$db} = $version;
+ }
+ $sth->finish;
+ $dbh->disconnect;
+ }
+ $sth->finish;
+ }
+# End JJR
+
+# code for DB2 is not used, keep for future reference
+# DS, Oct. 28, 2003
$dbh->disconnect;
@@ -498,15 +619,16 @@ sub dbupdate {
my @upgradescripts = ();
my $query;
+ my $rc = -2;
if ($form->{dbupdate}) {
# read update scripts into memory
- opendir SQLDIR, "sql/." or $form-error($!);
- @upgradescripts = sort grep /$form->{dbdriver}-upgrade-.*?\.sql/, readdir SQLDIR;
+ opendir SQLDIR, "sql/." or $form->error($!);
+ @upgradescripts = sort script_version grep /$form->{dbdriver}-upgrade-.*?\.sql$/, readdir SQLDIR;
closedir SQLDIR;
}
-
+
foreach my $db (split / /, $form->{dbupdate}) {
next unless $form->{$db};
@@ -514,7 +636,7 @@ sub dbupdate {
# strip db from dataset
$db =~ s/^db//;
&dbconnect_vars($form, $db);
-
+
my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) or $form->dberror;
# check version
@@ -528,37 +650,87 @@ sub dbupdate {
next unless $version;
+ $version = calc_version($version);
+ my $dbversion = calc_version($form->{dbversion});
+
foreach my $upgradescript (@upgradescripts) {
my $a = $upgradescript;
$a =~ s/(^$form->{dbdriver}-upgrade-|\.sql$)//g;
my ($mindb, $maxdb) = split /-/, $a;
+ $mindb = calc_version($mindb);
+ $maxdb = calc_version($maxdb);
- next if ($version ge $maxdb);
+ next if ($version >= $maxdb);
- # if there is no upgrade script exit
- last if ($version lt $mindb);
+ # exit if there is no upgrade script or version == mindb
+ last if ($version < $mindb || $version >= $dbversion);
# apply upgrade
- $self->processquery($form, $dbh, "sql/$upgradescript");
+ $self->process_query($form, $dbh, "sql/$upgradescript");
$version = $maxdb;
}
+ $rc = 0;
$dbh->disconnect;
}
+
+ $rc;
+
}
+sub calc_version {
+
+ my @v = split /\./, $_[0];
+ my $version = 0;
+ my $i;
+
+ for ($i = 0; $i <= $#v; $i++) {
+ $version *= 1000;
+ $version += $v[$i];
+ }
+
+ return $version;
+
+}
+
+
+sub script_version {
+ my ($my_a, $my_b) = ($a, $b);
+
+ my ($a_from, $a_to, $b_from, $b_to);
+ my ($res_a, $res_b, $i);
+
+ $my_a =~ s/.*-upgrade-//;
+ $my_a =~ s/.sql$//;
+ $my_b =~ s/.*-upgrade-//;
+ $my_b =~ s/.sql$//;
+ ($a_from, $a_to) = split(/-/, $my_a);
+ ($b_from, $b_to) = split(/-/, $my_b);
+
+ $res_a = calc_version($a_from);
+ $res_b = calc_version($b_from);
+
+ if ($res_a == $res_b) {
+ $res_a = calc_version($a_to);
+ $res_b = calc_version($b_to);
+ }
+
+ return $res_a <=> $res_b;
+
+}
+
sub create_config {
my ($self, $filename) = @_;
@config = &config_vars;
-
+
open(CONF, ">$filename") or $self->error("$filename : $!");
# create the config file
@@ -568,6 +740,7 @@ sub create_config {
|;
foreach $key (sort @config) {
+ $self->{$key} =~ s/\\/\\\\/g;
$self->{$key} =~ s/'/\\'/g;
print CONF qq| $key => '$self->{$key}',\n|;
}
@@ -583,17 +756,17 @@ sub create_config {
sub save_member {
my ($self, $memberfile, $userspath) = @_;
- my $newmember = 1;
-
# format dbconnect and dboptions string
- map { $self->{$_} = lc $self->{$_} } qw(dbname host);
&dbconnect_vars($self, $self->{dbname});
- $self->error('File locked!') if (-f "${memberfile}.LCK");
+ $self->error("$memberfile locked!") if (-f "${memberfile}.LCK");
open(FH, ">${memberfile}.LCK") or $self->error("${memberfile}.LCK : $!");
close(FH);
- open(CONF, "+<$memberfile") or $self->error("$memberfile : $!");
+ if (! open(CONF, "+<$memberfile")) {
+ unlink "${memberfile}.LCK";
+ $self->error("$memberfile : $!");
+ }
@config = <CONF>;
@@ -601,10 +774,7 @@ sub save_member {
truncate(CONF, 0);
while ($line = shift @config) {
- if ($line =~ /^\[$self->{login}\]/) {
- $newmember = 0;
- last;
- }
+ last if ($line =~ /^\[$self->{login}\]/);
print CONF $line;
}
@@ -622,7 +792,7 @@ sub save_member {
print CONF qq|[$self->{login}]\n|;
- if ((($self->{dbpasswd} ne $self->{old_dbpasswd}) || $newmember) && $self->{root}) {
+ if ($self->{root}) {
$self->{dbpasswd} = pack 'u', $self->{dbpasswd};
chop $self->{dbpasswd};
}
@@ -636,10 +806,9 @@ sub save_member {
} else {
@config = &config_vars;
}
-
+
# replace \r\n with \n
- $self->{address} =~ s/\r\n/\\n/g if $self->{address};
- $self->{signature} =~ s/\r\n/\\n/g if $self->{signature};
+ map { $self->{$_} =~ s/\r\n/\\n/g } qw(address signature);
foreach $key (sort @config) {
print CONF qq|$key=$self->{$key}\n|;
@@ -650,18 +819,84 @@ sub save_member {
unlink "${memberfile}.LCK";
# create conf file
- $self->create_config("$userspath/$self->{login}.conf") unless $self->{'root login'};
-
+ if (! $self->{'root login'}) {
+ $self->create_config("$userspath/$self->{login}.conf");
+
+ $self->{dbpasswd} =~ s/\\'/'/g;
+ $self->{dbpasswd} =~ s/\\\\/\\/g;
+ $self->{dbpasswd} = unpack 'u', $self->{dbpasswd};
+
+ # check if login is in database
+ my $dbh = DBI->connect($self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd}, {AutoCommit => 0}) or $self->error($DBI::errstr);
+
+ # add login to employee table if it does not exist
+ # no error check for employee table, ignore if it does not exist
+ my $login = $self->{login};
+ $login =~ s/@.*//;
+ my $query = qq|SELECT id FROM employee WHERE login = '$login'|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute;
+
+ my ($id) = $sth->fetchrow_array;
+ $sth->finish;
+
+ if ($id) {
+ $query = qq|UPDATE employee SET
+ role = '$self->{role}',
+ email = '$self->{email}',
+ name = '$self->{name}'
+ WHERE login = '$login'|;
+
+ } else {
+ my ($employeenumber) = Form::update_defaults("", \%$self, "employeenumber", $dbh);
+ $query = qq|INSERT INTO employee (login, employeenumber, name, workphone,
+ role, email)
+ VALUES ('$login', '$employeenumber', '$self->{name}',
+ '$self->{tel}', '$self->{role}', '$self->{email}')|;
+ }
+
+ $dbh->do($query);
+ $dbh->commit;
+ $dbh->disconnect;
+
+ }
+
}
+sub delete_login {
+ my ($self, $form) = @_;
+
+ my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}, {AutoCommit} => 0) or $form->dberror;
+
+ my $login = $form->{login};
+ $login =~ s/@.*//;
+ my $query = qq|SELECT id FROM employee
+ WHERE login = '$login'|;
+ my $sth = $dbh->prepare($query);
+ $sth->execute || $form->dberror($query);
+
+ my ($id) = $sth->fetchrow_array;
+ $sth->finish;
+
+ my $query = qq|UPDATE employee
+ login = NULL
+ WHERE login = '$login'|;
+ $dbh->do($query);
+
+ $dbh->commit;
+ $dbh->disconnect;
+
+}
+
+
sub config_vars {
- my @conf = qw(acs address admin businessnumber charset company countrycode
+ my @conf = qw(acs address businessnumber charset company countrycode
currency dateformat dbconnect dbdriver dbhost dbport dboptions
dbname dbuser dbpasswd email fax name numberformat password
- printer sid shippingpoint signature stylesheet tel templates
- vclimit);
+ printer role sid signature stylesheet tel templates vclimit
+ menuwidth timeout);
@conf;
@@ -674,8 +909,6 @@ sub error {
if ($ENV{HTTP_USER_AGENT}) {
print qq|Content-Type: text/html
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-
<body bgcolor=ffffff>
<h2><font color=red>Error!</font></h2>