#===================================================================== # LedgerSMB # Small Medium Business Accounting software # http://www.ledgersmb.org/ # # Copyright (C) 2006 # This work contains copyrighted information from a number of sources all used # with permission. # # This file contains source code included with or based on SQL-Ledger which # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed # under the GNU General Public License version 2 or, at your option, any later # version. For a full list including contact information of contributors, # maintainers, and copyright holders, see the CONTRIBUTORS file. # # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork): # Copyright (C) 2002 # # Author: DWS Systems Inc. # Web: http://www.sql-ledger.org # # Contributors: # #====================================================================== # # This file has undergone whitespace cleanup. # #====================================================================== # # Account reconciliation routines # #====================================================================== package RC; sub getposlines{ my ($self, $myconfig, $form) = @_; %pos_config = %{$form->{pos_config}}; %pos_sources = %{$form->{pos_sources}}; my $sources = ''; foreach $key (keys %pos_sources){ $sources .= ", '$key'"; } $sources =~ s/^,\s*//; my $dbh = $form->{dbh}; my $query = qq| SELECT sum(amount) AS amount, source FROM acc_trans WHERE chart_id = (SELECT id FROM chart WHERE accno = ?) AND transdate = date 'NOW' AND cleared IS NOT TRUE GROUP BY source|; my $sth = $dbh->prepare($query); $sth->execute($pos_config{till_accno}) || $form->dberror($query); while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { push @{$form->{TB}}, $ref; } $sth->finish; my $query = qq| SELECT sum(amount) AS sum FROM acc_trans WHERE chart_id = (SELECT id FROM chart WHERE accno = ?) AND transdate = date 'NOW' AND cleared IS NOT TRUE|; my $sth = $dbh->prepare($query); $sth->execute($pos_config{till_accno}) || $form->dberror($query); my $ref = $sth->fetchrow_hashref(NAME_lc); $form->{sum} = $ref->{sum}; $sth->finish; } sub clear_till { my ($self, $myconfig, $form) = @_; %pos_config = %{$form->{pos_config}}; %pos_sources = %{$form->{pos_sources}}; my $sources = ''; foreach $key (keys %pos_sources){ $sources .= ", '$key'"; } $sources =~ s/^,\s//; my $dbh = $form->{dbh}; my $query = qq| UPDATE acc_trans SET cleared = TRUE WHERE chart_id = (SELECT id FROM chart WHERE accno = ?) AND transdate = date 'NOW'|; my $sth = $dbh->prepare($query); $sth->execute($pos_config{till_accno}) || $form->dberror($query); } sub getbalance{ my ($self, $myconfig, $form) = @_; my $dbh = $form->{dbh}; my $query = qq| SELECT sum(amount) AS balance FROM acc_trans WHERE chart_id = (SELECT id FROM chart WHERE accno = ?)|; my $sth = $dbh->prepare($query); $sth->execute($form->{accno}) || $form->dberror($query); my $ref = $sth->fetchrow_hashref(NAME_lc); $form->{balance} = $ref->{balance}; } sub paymentaccounts { my ($self, $myconfig, $form) = @_; my $dbh = $form->{dbh}; my $query = qq| SELECT accno, description FROM chart WHERE link LIKE '%_paid%' AND (category = 'A' OR category = 'L') 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($myconfig, $dbh); } sub payment_transactions { my ($self, $myconfig, $form) = @_; my $dbh = $form->{dbh}; my $query; my $sth; $query = qq|SELECT category FROM chart WHERE accno = ?|; $sth = $dbh->prepare($query); $sth->execute($form->{accno}); ($form->{category}) = $sth->fetchrow_array(); my $cleared; ($form->{fromdate}, $form->{todate}) = $form->from_to( $form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month}; my $transdate = qq| AND ac.transdate < date |. $dbh->quote($form->{fromdate}); 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 ch ON (ch.id = ac.chart_id) WHERE ch.accno = ? $transdate $cleared |; $sth = $dbh->prepare($query); $sth->execute($form->{accno}); ($form->{beginningbalance}) = $sth->fetchrow_array(); $query = qq| SELECT sum(ac.amount) FROM acc_trans ac JOIN chart ch ON (ch.id = ac.chart_id) WHERE ch.accno = ? AND ac.fx_transaction = '1' $transdate $cleared|; $sth = $dbh->prepare($query); $sth->execute($form->{accno}); ($form->{fx_balance}) = $sth->fetchrow_array(); $transdate = ""; if ($form->{todate}) { $transdate = qq| AND ac.transdate <= date |. $dbh->quote($form->{todate}); } # get statement balance $query = qq| SELECT sum(ac.amount) FROM acc_trans ac JOIN chart ch ON (ch.id = ac.chart_id) WHERE ch.accno = ? $transdate|; $sth = $dbh->prepare($query); $sth->execute($form->{accno}); ($form->{endingbalance}) = $sth->fetchrow_array(); # fx balance $query = qq| SELECT sum(ac.amount) FROM acc_trans ac JOIN chart ch ON (ch.id = ac.chart_id) WHERE ch.accno = ? AND ac.fx_transaction = '1' $transdate |; $sth = $dbh->prepare($query); $sth->execute($form->{accno}); ($form->{fx_endingbalance}) = $sth->fetchrow_array(); $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; } } my $fx_transaction; if ($form->{fx_transaction}) { $fx_transaction = qq| AND NOT (ac.chart_id IN (SELECT value AS fxgain_accno_id FROM defaults WHERE setting_key = 'fxgain_accno_id' UNION SELECT value AS fxloss_accno_id FROM defaults WHERE setting_key = 'fxloss_accno_id))|; } else { $fx_transaction = qq| AND ac.fx_transaction = '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 = |.$dbh->quote($form->{accno}).qq| AND ac.amount >= 0 $fx_transaction $cleared|; $query .= " AND ac.transdate >= ".$dbh->quote($form->{fromdate}) if $form->{fromdate}; $query .= " AND ac.transdate <= ".$dbh->quote($form->{todate}) if $form->{todate}; $query .= " GROUP BY ac.source, ac.transdate, ac.cleared"; $query .= qq| UNION ALL 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 = |.$dbh->quote($form->{accno}).qq| AND ac.amount < 0 $fx_transaction $cleared|; $query .= " AND ac.transdate >= ".$dbh->quote($form->{fromdate}) if $form->{fromdate}; $query .= " AND ac.transdate <= ".$dbh->quote($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 = |.$dbh->quote($form->{accno}).qq| $fx_transaction $cleared|; $query .= " AND ac.transdate >= ".$dbh->quote($form->{fromdate}) if $form->{fromdate}; $query .= " AND ac.transdate <= ".$dbh->quote($form->{todate}) if $form->{todate}; $query .= qq| UNION ALL 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 = |.$dbh->quote($form->{accno}).qq| $fx_transaction $cleared|; $query .= " AND ac.transdate >= ".$dbh->quote($form->{fromdate}) if $form->{fromdate}; $query .= " AND ac.transdate <= ".$dbh->quote($form->{todate}) if $form->{todate}; $query .= qq| UNION ALL 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 = |.$dbh->quote($form->{accno}).qq| $fx_transaction $cleared|; $query .= " AND ac.transdate >= ".$dbh->quote($form->{fromdate}) if $form->{fromdate}; $query .= " AND ac.transdate <= ".$dbh->quote($form->{todate}) if $form->{todate}; $query .= " ORDER BY 1,2,3"; } $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); my $dr; my $cr; 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) JOIN chart ch ON (ac.chart_id = ch.id) WHERE ac.transdate = ? AND ch.accno = |.$dbh->quote($form->{accno}).qq| AND (ac.source = ? OR ac.source IS NULL) 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) JOIN chart ch ON (ac.chart_id = ch.id) WHERE ac.transdate = ? AND ch.accno = |.$dbh->quote($form->{accno}).qq| AND (ac.source = ? OR ac.source IS NULL) AND ac.amount > 0 $cleared UNION SELECT g.description FROM gl g JOIN acc_trans ac ON (g.id = ac.trans_id) JOIN chart ch ON (ac.chart_id = ch.id) WHERE ac.transdate = ? AND ch.accno = |.$dbh->quote($form->{accno}).qq| AND (ac.source = ? OR ac.source IS NULL) 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) JOIN chart ch ON (ac.chart_id = ch.id) WHERE ac.transdate = ? AND ch.accno = |.$dbh->quote($form->{accno}).qq| AND (ac.source = ? OR ac.source IS NULL) 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) JOIN chart ch ON (ac.chart_id = ch.id) WHERE ac.transdate = ? AND ch.accno = |.$dbh->quote($form->{accno}).qq| AND (ac.source = ? OR ac.source IS NULL) AND ac.amount < 0 $cleared UNION SELECT g.description FROM gl g JOIN acc_trans ac ON (g.id = ac.trans_id) JOIN chart ch ON (ac.chart_id = ch.id) WHERE ac.transdate = ? AND ch.accno = |.$dbh->quote($form->{accno}).qq| AND (ac.source = ? OR ac.source IS NULL) AND ac.amount < 0 $cleared|; $query .= " ORDER BY 1"; $cr = $dbh->prepare($query); } my $name; my $ref; 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; } $sth->finish; $dbh->commit; } sub reconcile { my ($self, $myconfig, $form) = @_; my $dbh = $form->{dbh}; 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 = ? OR source IS NULL) AND transdate = ? AND cleared = '0' AND chart_id = |.$dbh->quote($chart_id); 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 = |.$dbh->quote($chart_id); my $tth = $dbh->prepare($query) || $form->dberror($query); # clear flags for $i (1 .. $form->{rowcount}) { 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; } } } $dbh->commit; } 1;