From ac5b087ea2d9ba7428d367aaeb288534158fee9a Mon Sep 17 00:00:00 2001 From: christopherm Date: Fri, 1 Sep 2006 01:16:38 +0000 Subject: Initial Import git-svn-id: https://ledger-smb.svn.sourceforge.net/svnroot/ledger-smb/ledger-smb@1 4979c152-3d1c-0410-bac9-87ea11338e46 --- LedgerSMB/AA.pm | 937 ++++++++++++++++ LedgerSMB/AM.pm | 1832 ++++++++++++++++++++++++++++++ LedgerSMB/BP.pm | 326 ++++++ LedgerSMB/CA.pm | 378 +++++++ LedgerSMB/CP.pm | 684 ++++++++++++ LedgerSMB/CT.pm | 1080 ++++++++++++++++++ LedgerSMB/Form.pm | 2942 +++++++++++++++++++++++++++++++++++++++++++++++++ LedgerSMB/GL.pm | 526 +++++++++ LedgerSMB/HR.pm | 555 ++++++++++ LedgerSMB/IC.pm | 1714 ++++++++++++++++++++++++++++ LedgerSMB/IR.pm | 1123 +++++++++++++++++++ LedgerSMB/IS.pm | 1684 ++++++++++++++++++++++++++++ LedgerSMB/Inifile.pm | 74 ++ LedgerSMB/JC.pm | 582 ++++++++++ LedgerSMB/Mailer.pm | 149 +++ LedgerSMB/Menu.pm | 91 ++ LedgerSMB/Num2text.pm | 149 +++ LedgerSMB/OE.pm | 2238 +++++++++++++++++++++++++++++++++++++ LedgerSMB/OP.pm | 101 ++ LedgerSMB/PE.pm | 1499 +++++++++++++++++++++++++ LedgerSMB/RC.pm | 391 +++++++ LedgerSMB/RP.pm | 2103 +++++++++++++++++++++++++++++++++++ LedgerSMB/Session.pm | 143 +++ LedgerSMB/User.pm | 927 ++++++++++++++++ 24 files changed, 22228 insertions(+) create mode 100755 LedgerSMB/AA.pm create mode 100755 LedgerSMB/AM.pm create mode 100755 LedgerSMB/BP.pm create mode 100755 LedgerSMB/CA.pm create mode 100755 LedgerSMB/CP.pm create mode 100755 LedgerSMB/CT.pm create mode 100755 LedgerSMB/Form.pm create mode 100755 LedgerSMB/GL.pm create mode 100755 LedgerSMB/HR.pm create mode 100755 LedgerSMB/IC.pm create mode 100755 LedgerSMB/IR.pm create mode 100755 LedgerSMB/IS.pm create mode 100755 LedgerSMB/Inifile.pm create mode 100755 LedgerSMB/JC.pm create mode 100755 LedgerSMB/Mailer.pm create mode 100755 LedgerSMB/Menu.pm create mode 100755 LedgerSMB/Num2text.pm create mode 100755 LedgerSMB/OE.pm create mode 100755 LedgerSMB/OP.pm create mode 100755 LedgerSMB/PE.pm create mode 100755 LedgerSMB/RC.pm create mode 100755 LedgerSMB/RP.pm create mode 100755 LedgerSMB/Session.pm create mode 100755 LedgerSMB/User.pm (limited to 'LedgerSMB') diff --git a/LedgerSMB/AA.pm b/LedgerSMB/AA.pm new file mode 100755 index 00000000..92816650 --- /dev/null +++ b/LedgerSMB/AA.pm @@ -0,0 +1,937 @@ +#===================================================================== +# LedgerSMB +# Small Medium Business Accounting software +# +# See COPYRIGHT file for copyright information +#====================================================================== +# +# This file has undergone whitespace cleanup. +# +#====================================================================== +# +# AR/AP backend routines +# common routines +# +#====================================================================== + +package AA; + + +sub post_transaction { + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + my $query; + my $sth; + + my $null; + ($null, $form->{department_id}) = split(/--/, $form->{department}); + $form->{department_id} *= 1; + + my $ml = 1; + my $table = 'ar'; + my $buysell = 'buy'; + my $ARAP = 'AR'; + my $invnumber = "sinumber"; + my $keepcleared; + + if ($form->{vc} eq 'vendor') { + $table = 'ap'; + $buysell = 'sell'; + $ARAP = 'AP'; + $ml = -1; + $invnumber = "vinumber"; + } + + if ($form->{currency} eq $form->{defaultcurrency}) { + $form->{exchangerate} = 1; + } else { + $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, $buysell); + + $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate}); + } + + my @taxaccounts = split / /, $form->{taxaccounts}; + my $tax = 0; + my $fxtax = 0; + my $amount; + my $diff; + + my %tax = (); + my $accno; + + # add taxes + foreach $accno (@taxaccounts) { + $fxtax += $tax{fxamount}{$accno} = $form->parse_amount($myconfig, $form->{"tax_$accno"}); + $tax += $tax{fxamount}{$accno}; + + push @{ $form->{acc_trans}{taxes} }, { + accno => $accno, + amount => $tax{fxamount}{$accno}, + project_id => 'NULL', + fx_transaction => 0 }; + + $amount = $tax{fxamount}{$accno} * $form->{exchangerate}; + $tax{amount}{$accno} = $form->round_amount($amount - $diff, 2); + $diff = $tax{amount}{$accno} - ($amount - $diff); + $amount = $tax{amount}{$accno} - $tax{fxamount}{$accno}; + $tax += $amount; + + if ($form->{currency} ne $form->{defaultcurrency}) { + push @{ $form->{acc_trans}{taxes} }, { + accno => $accno, + amount => $amount, + project_id => 'NULL', + fx_transaction => 1 }; + } + + } + + my %amount = (); + my $fxinvamount = 0; + for (1 .. $form->{rowcount}) { + $fxinvamount += $amount{fxamount}{$_} = $form->parse_amount($myconfig, $form->{"amount_$_"}) + } + + $form->{taxincluded} *= 1; + + my $i; + my $project_id; + my $cleared = 0; + + $diff = 0; + # deduct tax from amounts if tax included + for $i (1 .. $form->{rowcount}) { + + if ($amount{fxamount}{$i}) { + + if ($form->{taxincluded}) { + $amount = ($fxinvamount) ? $fxtax * $amount{fxamount}{$i} / $fxinvamount : 0; + $amount{fxamount}{$i} -= $amount; + } + + # multiply by exchangerate + $amount = $amount{fxamount}{$i} * $form->{exchangerate}; + $amount{amount}{$i} = $form->round_amount($amount - $diff, 2); + $diff = $amount{amount}{$i} - ($amount - $diff); + + ($null, $project_id) = split /--/, $form->{"projectnumber_$i"}; + $project_id ||= 'NULL'; + ($accno) = split /--/, $form->{"${ARAP}_amount_$i"}; + + if ($keepcleared) { + $cleared = ($form->{"cleared_$i"}) ? 1 : 0; + } + + push @{ $form->{acc_trans}{lineitems} }, { + accno => $accno, + amount => $amount{fxamount}{$i}, + project_id => $project_id, + description => $form->{"description_$i"}, + cleared => $cleared, + fx_transaction => 0 }; + + if ($form->{currency} ne $form->{defaultcurrency}) { + $amount = $amount{amount}{$i} - $amount{fxamount}{$i}; + push @{ $form->{acc_trans}{lineitems} }, { + accno => $accno, + amount => $amount, + project_id => $project_id, + description => $form->{"description_$i"}, + cleared => $cleared, + fx_transaction => 1 }; + } + } + } + + + my $invnetamount = 0; + for (@{ $form->{acc_trans}{lineitems} }) { $invnetamount += $_->{amount} } + my $invamount = $invnetamount + $tax; + + # adjust paidaccounts if there is no date in the last row + $form->{paidaccounts}-- unless ($form->{"datepaid_$form->{paidaccounts}"}); + + my $paid = 0; + my $fxamount; + + $diff = 0; + # add payments + for $i (1 .. $form->{paidaccounts}) { + $fxamount = $form->parse_amount($myconfig, $form->{"paid_$i"}); + + if ($fxamount) { + $paid += $fxamount; + + $paidamount = $fxamount * $form->{exchangerate}; + + $amount = $form->round_amount($paidamount - $diff, 2); + $diff = $amount - ($paidamount - $diff); + + $form->{datepaid} = $form->{"datepaid_$i"}; + + $paid{fxamount}{$i} = $fxamount; + $paid{amount}{$i} = $amount; + } + } + + $fxinvamount += $fxtax unless $form->{taxincluded}; + $fxinvamount = $form->round_amount($fxinvamount, 2); + $invamount = $form->round_amount($invamount, 2); + $paid = $form->round_amount($paid, 2); + + $paid = ($fxinvamount == $paid) ? $invamount : $form->round_amount($paid * $form->{exchangerate}, 2); + + $query = q|SELECT fxgain_accno_id, fxloss_accno_id + FROM defaults|; + + my ($fxgain_accno_id, $fxloss_accno_id) = $dbh->selectrow_array($query); + + ($null, $form->{employee_id}) = split /--/, $form->{employee}; + unless ($form->{employee_id}) { + ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh); + } + + # check if id really exists + if ($form->{id}) { + $keepcleared = 1; + $query = qq|SELECT id FROM $table + WHERE id = $form->{id}|; + + if ($dbh->selectrow_array($query)) { + # delete detail records + $query = qq|DELETE FROM acc_trans + WHERE trans_id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + } + } else { + + my $uid = localtime; + $uid .= "$$"; + + $query = qq|INSERT INTO $table (invnumber) + VALUES ('$uid')|; + + $dbh->do($query) || $form->dberror($query); + + $query = qq|SELECT id FROM $table + WHERE invnumber = '$uid'|; + + ($form->{id}) = $dbh->selectrow_array($query); + } + + + # record last payment date in ar/ap table + $form->{datepaid} = $form->{transdate} unless $form->{datepaid}; + my $datepaid = ($paid) ? qq|'$form->{datepaid}'| : 'NULL'; + + $form->{invnumber} = $form->update_defaults($myconfig, $invnumber) unless $form->{invnumber}; + + $query = qq|UPDATE $table SET invnumber = |.$dbh->quote($form->{invnumber}).qq|, + ordnumber = |.$dbh->quote($form->{ordnumber}).qq|, + transdate = '$form->{transdate}', + $form->{vc}_id = $form->{"$form->{vc}_id"}, + taxincluded = '$form->{taxincluded}', + amount = $invamount, + duedate = '$form->{duedate}', + paid = $paid, + datepaid = $datepaid, + netamount = $invnetamount, + curr = '$form->{currency}', + notes = |.$dbh->quote($form->{notes}).qq|, + department_id = $form->{department_id}, + employee_id = $form->{employee_id}, + ponumber = |.$dbh->quote($form->{ponumber}).qq| + WHERE id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + + # update exchangerate + my $buy = $form->{exchangerate}; + my $sell = 0; + if ($form->{vc} eq 'vendor') { + $buy = 0; + $sell = $form->{exchangerate}; + } + + if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) { + $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $buy, $sell); + } + + my $ref; + + # add individual transactions + foreach $ref (@{ $form->{acc_trans}{lineitems} }) { + + # insert detail records in acc_trans + if ($ref->{amount}) { + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, + project_id, memo, fx_transaction, cleared) + VALUES ($form->{id}, (SELECT id FROM chart + WHERE accno = '$ref->{accno}'), + $ref->{amount} * $ml, '$form->{transdate}', + $ref->{project_id}, |.$dbh->quote($ref->{description}).qq|, + '$ref->{fx_transaction}', '$ref->{cleared}')|; + + $dbh->do($query) || $form->dberror($query); + } + } + + # save taxes + foreach $ref (@{ $form->{acc_trans}{taxes} }) { + if ($ref->{amount}) { + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate, fx_transaction) + VALUES ($form->{id}, + (SELECT id FROM chart + WHERE accno = '$ref->{accno}'), + $ref->{amount} * $ml, '$form->{transdate}', + '$ref->{fx_transaction}')|; + + $dbh->do($query) || $form->dberror($query); + } + } + + + my $arap; + + # record ar/ap + if (($arap = $invamount)) { + ($accno) = split /--/, $form->{$ARAP}; + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate) + VALUES ($form->{id}, + (SELECT id FROM chart + WHERE accno = '$accno'), + $invamount * -1 * $ml, '$form->{transdate}')|; + + $dbh->do($query) || $form->dberror($query); + } + + # if there is no amount force ar/ap + if ($fxinvamount == 0) { + $arap = 1; + } + + + my $exchangerate; + + # add paid transactions + for $i (1 .. $form->{paidaccounts}) { + + if ($paid{fxamount}{$i}) { + + ($accno) = split(/--/, $form->{"${ARAP}_paid_$i"}); + $form->{"datepaid_$i"} = $form->{transdate} unless ($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"}, $buysell); + + $form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"}); + } + + # if there is no amount + if ($fxinvamount == 0) { + $form->{exchangerate} = $form->{"exchangerate_$i"}; + } + + # ar/ap amount + if ($arap) { + ($accno) = split /--/, $form->{$ARAP}; + + # add ar/ap + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,transdate) + VALUES ($form->{id}, (SELECT id FROM chart + WHERE accno = '$accno'), + $paid{amount}{$i} * $ml, '$form->{"datepaid_$i"}')|; + + $dbh->do($query) || $form->dberror($query); + } + + $arap = $paid{amount}{$i}; + + + # add payment + if ($paid{fxamount}{$i}) { + + ($accno) = split /--/, $form->{"${ARAP}_paid_$i"}; + + my $cleared = ($form->{"cleared_$i"}) ? 1 : 0; + + $amount = $paid{fxamount}{$i}; + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate, source, memo, cleared) + VALUES ($form->{id}, (SELECT id FROM chart + WHERE accno = '$accno'), + $amount * -1 * $ml, '$form->{"datepaid_$i"}', | + .$dbh->quote($form->{"source_$i"}).qq|, | + .$dbh->quote($form->{"memo_$i"}).qq|, '$cleared')|; + + $dbh->do($query) || $form->dberror($query); + + if ($form->{currency} ne $form->{defaultcurrency}) { + + # exchangerate gain/loss + $amount = ($form->round_amount($paid{fxamount}{$i} * $form->{exchangerate},2) - $form->round_amount($paid{fxamount}{$i} * $form->{"exchangerate_$i"},2)) * -1; + + if ($amount) { + + my $accno_id = (($amount * $ml) > 0) ? $fxgain_accno_id : $fxloss_accno_id; + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate, fx_transaction, cleared) + VALUES ($form->{id}, $accno_id, + $amount * $ml, '$form->{"datepaid_$i"}', '1', + '$cleared')|; + + $dbh->do($query) || $form->dberror($query); + } + + # exchangerate difference + $amount = $paid{amount}{$i} - $paid{fxamount}{$i} + $amount; + + $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, + transdate, fx_transaction, cleared, source) + VALUES ($form->{id}, (SELECT id FROM chart + WHERE accno = '$accno'), + $amount * -1 * $ml, '$form->{"datepaid_$i"}', '1', + '$cleared', | + .$dbh->quote($form->{"source_$i"}).qq|)|; + + $dbh->do($query) || $form->dberror($query); + + } + + # update exchangerate record + $buy = $form->{"exchangerate_$i"}; + $sell = 0; + + if ($form->{vc} eq 'vendor') { + $buy = 0; + $sell = $form->{"exchangerate_$i"}; + } + + if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) { + $form->update_exchangerate($dbh, $form->{currency}, $form->{"datepaid_$i"}, $buy, $sell); + } + } + } + } + + # save printed and queued + $form->save_status($dbh); + + my %audittrail = ( tablename => $table, + reference => $form->{invnumber}, + formname => 'transaction', + action => 'posted', + id => $form->{id} ); + + $form->audittrail($dbh, "", \%audittrail); + + $form->save_recurring($dbh, $myconfig); + + my $rc = $dbh->commit; + + $dbh->disconnect; + + $rc; + +} + + +sub delete_transaction { + my ($self, $myconfig, $form) = @_; + + # connect to database, turn AutoCommit off + my $dbh = $form->dbconnect_noauto($myconfig); + + my $table = ($form->{vc} eq 'customer') ? 'ar' : 'ap'; + + my %audittrail = ( tablename => $table, + reference => $form->{invnumber}, + formname => 'transaction', + action => 'deleted', + id => $form->{id} ); + + $form->audittrail($dbh, "", \%audittrail); + + my $query = qq|DELETE FROM $table 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); + + # get 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; +} + + + +sub transactions { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + my $null; + my $var; + my $paid = "a.paid"; + my $ml = 1; + my $ARAP = 'AR'; + my $table = 'ar'; + my $buysell = 'buy'; + my $acc_trans_join; + my $acc_trans_flds; + + if ($form->{vc} eq 'vendor') { + $ml = -1; + $ARAP = 'AP'; + $table = 'ap'; + $buysell = 'sell'; + } + + ($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 * $ml + FROM acc_trans ac + JOIN chart c ON (c.id = ac.chart_id) + WHERE ac.trans_id = a.id + AND (c.link LIKE '%${ARAP}_paid%' OR c.link = '')|; + $paid .= qq| + AND ac.transdate <= '$form->{transdateto}'| if $form->{transdateto}; + $form->{summary} = 1; + } + + + if (!$form->{summary}) { + $acc_trans_flds = qq|, c.accno, ac.source, + pr.projectnumber, ac.memo AS description, + ac.amount AS linetotal, + i.description AS linedescription|; + + $acc_trans_join = qq| JOIN acc_trans ac ON (a.id = ac.trans_id) + JOIN chart c ON (c.id = ac.chart_id) + LEFT JOIN project pr ON (pr.id = ac.project_id) + LEFT JOIN invoice i ON (i.id = ac.invoice_id)|; + } + + my $query = qq|SELECT a.id, a.invnumber, a.ordnumber, a.transdate, + 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, vc.name, + a.$form->{vc}_id, a.till, m.name AS manager, a.curr, + ex.$buysell AS exchangerate, d.description AS department, + a.ponumber $acc_trans_flds + FROM $table a + JOIN $form->{vc} vc ON (a.$form->{vc}_id = vc.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) + LEFT JOIN department d ON (a.department_id = d.id) + $acc_trans_join|; + + 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, + department => 22, + ponumber => 23, + accno => 24, + source => 25, + project => 26, + description => 27); + + + 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->{"$form->{vc}_id"}) { + $where .= qq| AND a.$form->{vc}_id = $form->{"$form->{vc}_id"}|; + } else { + if ($form->{$form->{vc}}) { + $var = $form->like(lc $form->{$form->{vc}}); + $where .= " AND lower(vc.name) LIKE '$var'"; + } + } + + for (qw(department employee)) { + if ($form->{$_}) { + ($null, $var) = split /--/, $form->{$_}; + $where .= " AND a.${_}_id = $var"; + } + } + + for (qw(invnumber ordnumber)) { + if ($form->{$_}) { + $var = $form->like(lc $form->{$_}); + $where .= " AND lower(a.$_) LIKE '$var'"; + $form->{open} = $form->{closed} = 0; + } + } + + for (qw(ponumber shipvia notes)) { + if ($form->{$_}) { + $var = $form->like(lc $form->{$_}); + $where .= " AND lower(a.$_) LIKE '$var'"; + } + } + + if ($form->{description}) { + if ($acc_trans_flds) { + $var = $form->like(lc $form->{description}); + $where .= " AND lower(ac.memo) LIKE '$var' + OR lower(i.description) LIKE '$var'"; + } else { + $where .= " AND a.id = 0"; + } + } + + if ($form->{source}) { + if ($acc_trans_flds) { + $var = $form->like(lc $form->{source}); + $where .= " AND lower(ac.source) LIKE '$var'"; + } else { + $where .= " AND a.id = 0"; + } + } + + + $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}) { + $where .= " AND a.amount != a.paid" if ($form->{open}); + $where .= " AND a.amount = a.paid" if ($form->{closed}); + } + } + + if ($form->{till} ne "") { + $where .= " AND a.invoice = '1' + AND a.till IS NOT NULL"; + + if ($myconfig->{role} eq 'user') { + $where .= " AND e.login = '$form->{login}'"; + } + } + + if ($form->{$ARAP}) { + my ($accno) = split /--/, $form->{$ARAP}; + + $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')|; + } + + if ($form->{description}) { + $var = $form->like(lc $form->{description}); + $where .= qq| AND (a.id IN (SELECT DISTINCT trans_id + FROM acc_trans + WHERE lower(memo) LIKE '$var') + OR a.id IN (SELECT DISTINCT trans_id + FROM invoice + WHERE lower(description) LIKE '$var'))|; + } + + $query .= "WHERE $where + ORDER BY $sortorder"; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + $ref->{exchangerate} = 1 unless $ref->{exchangerate}; + + if ($ref->{linetotal} <= 0) { + $ref->{debit} = $ref->{linetotal} * -1; + $ref->{credit} = 0; + } else { + $ref->{debit} = 0; + $ref->{credit} = $ref->{linetotal}; + } + + if ($ref->{invoice}) { + $ref->{description} ||= $ref->{linedescription}; + } + + if ($form->{outstanding}) { + next if $form->round_amount($ref->{amount}, 2) == $form->round_amount($ref->{paid}, 2); + } + + push @{ $form->{transactions} }, $ref; + } + + $sth->finish; + $dbh->disconnect; +} + + +# this is used in IS, IR to retrieve the name +sub get_name { + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $dateformat = $myconfig->{dateformat}; + + 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->{"$form->{vc}_id"} *= 1; + # get customer/vendor + my $query = qq|SELECT c.name AS $form->{vc}, c.discount, c.creditlimit, c.terms, + c.email, c.cc, c.bcc, c.taxincluded, + 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 $form->{vc} 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->{"$form->{vc}_id"}|; + + my $sth = $dbh->prepare($query); + + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + + if ($form->{id}) { + for (qw(currency employee employee_id intnotes)) { delete $ref->{$_} } + } + + for (keys %$ref) { $form->{$_} = $ref->{$_} } + $sth->finish; + + my $buysell = ($form->{vc} eq 'customer') ? "buy" : "sell"; + + # 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}, $buysell); + } + + $form->{forex} = $form->{exchangerate}; + + # if no employee, default to login + ($form->{employee}, $form->{employee_id}) = $form->get_employee($dbh) unless $form->{employee_id}; + + my $arap = ($form->{vc} eq 'customer') ? 'ar' : 'ap'; + my $ARAP = uc $arap; + + $form->{creditremaining} = $form->{creditlimit}; + $query = qq|SELECT SUM(amount - paid) + FROM $arap + WHERE $form->{vc}_id = $form->{"$form->{vc}_id"}|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + ($form->{creditremaining}) -= $sth->fetchrow_array; + + $sth->finish; + + $query = qq|SELECT o.amount, (SELECT e.$buysell FROM exchangerate e + WHERE e.curr = o.curr + AND e.transdate = o.transdate) + FROM oe o + WHERE o.$form->{vc}_id = $form->{"$form->{vc}_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 did not converted an order or invoice + if (!$form->{shipto}) { + + for (qw(shiptoname shiptoaddress1 shiptoaddress2 shiptocity + shiptostate shiptozipcode shiptocountry shiptocontact + shiptophone shiptofax shiptoemail)) { + delete $form->{$_} + } + + ## needs fixing (SELECT *) + $query = qq|SELECT * + FROM shipto + WHERE trans_id = $form->{"$form->{vc}_id"}|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + for (keys %$ref) { $form->{$_} = $ref->{$_} } + $sth->finish; + } + + # get taxes + $query = qq|SELECT c.accno + FROM chart c + JOIN $form->{vc}tax ct ON (ct.chart_id = c.id) + WHERE ct.$form->{vc}_id = $form->{"$form->{vc}_id"}|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my %tax; + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + $tax{$ref->{accno}} = 1; + } + + $sth->finish; + + my $where = qq|AND (t.validto >= '$form->{transdate}' OR t.validto IS NULL)| if $form->{transdate}; + + # get tax rates and description + $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber + FROM chart c + JOIN tax t ON (c.id = t.chart_id) + WHERE c.link LIKE '%${ARAP}_tax%' + $where + ORDER BY accno, validto|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $form->{taxaccounts} = ""; + my %a = (); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + + if ($tax{$ref->{accno}}) { + if (not exists $a{$ref->{accno}}) { + for (qw(rate description taxnumber)) { $form->{"$ref->{accno}_$_"} = $ref->{$_} } + $form->{taxaccounts} .= "$ref->{accno} "; + $a{$ref->{accno}} = 1; + } + } + } + + $sth->finish; + chop $form->{taxaccounts}; + + # setup last accounts used for this customer/vendor + 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 $arap 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.$form->{vc}_id = $form->{"$form->{vc}_id"} + AND a.id IN (SELECT max(id) + FROM $arap + WHERE $form->{vc}_id = $form->{"$form->{vc}_id"})|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $i = 0; + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + $form->{department} = $ref->{department}; + $form->{department_id} = $ref->{department_id}; + + if ($ref->{link} =~ /_amount/) { + $i++; + $form->{"$form->{ARAP}_amount_$i"} = "$ref->{accno}--$ref->{description}" if $ref->{accno}; + $form->{"projectnumber_$i"} = "$ref->{projectnumber}--$ref->{project_id}" if $ref->{project_id}; + } + + if ($ref->{link} eq $form->{ARAP}) { + $form->{$form->{ARAP}} = $form->{"$form->{ARAP}_1"} = "$ref->{accno}--$ref->{description}" if $ref->{accno}; + } + } + + $sth->finish; + $form->{rowcount} = $i if ($i && !$form->{type}); + } + + $dbh->disconnect; +} + +1; diff --git a/LedgerSMB/AM.pm b/LedgerSMB/AM.pm new file mode 100755 index 00000000..ed4477bf --- /dev/null +++ b/LedgerSMB/AM.pm @@ -0,0 +1,1832 @@ +#===================================================================== +# LedgerSMB +# Small Medium Business Accounting software +# +# See COPYRIGHT file for copyright information +#====================================================================== +# +# This file has undergone whitespace cleanup. +# +#====================================================================== +# +# Administration module +# Chart of Accounts +# template routines +# preferences +# +#====================================================================== + +package AM; + + +sub get_account { + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT accno, description, charttype, gifi_accno, + category, link, contra + FROM chart + WHERE id = $form->{id}|; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + for (keys %$ref) { $form->{$_} = $ref->{$_} } + $sth->finish; + + # get default accounts + $query = qq|SELECT inventory_accno_id, income_accno_id, expense_accno_id, + fxgain_accno_id, fxloss_accno_id + FROM defaults|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + for (keys %$ref) { $form->{$_} = $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; + +} + + +sub save_account { + + my ($self, $myconfig, $form) = @_; + + # connect to database, turn off AutoCommit + my $dbh = $form->dbconnect_noauto($myconfig); + + $form->{link} = ""; + foreach my $item ($form->{AR}, + $form->{AR_amount}, + $form->{AR_tax}, + $form->{AR_paid}, + $form->{AP}, + $form->{AP_amount}, + $form->{AP_tax}, + $form->{AP_paid}, + $form->{IC}, + $form->{IC_income}, + $form->{IC_sale}, + $form->{IC_expense}, + $form->{IC_cogs}, + $form->{IC_taxpart}, + $form->{IC_taxservice}) { + $form->{link} .= "${item}:" if ($item); + } + + chop $form->{link}; + + # strip blanks from accno + for (qw(accno gifi_accno)) { $form->{$_} =~ s/( |')//g } + + foreach my $item (qw(accno gifi_accno description)) { + $form->{$item} =~ s/-(-+)/-/g; + $form->{$item} =~ s/ ( )+/ /g; + } + + my $query; + my $sth; + + $form->{contra} *= 1; + + # if we have an id then replace the old record + if ($form->{id}) { + $query = qq|UPDATE chart SET accno = '$form->{accno}', + description = |.$dbh->quote($form->{description}).qq|, + charttype = '$form->{charttype}', + gifi_accno = '$form->{gifi_accno}', + category = '$form->{category}', + link = '$form->{link}', + contra = '$form->{contra}' + WHERE id = $form->{id}|; + } else { + $query = qq|INSERT INTO chart (accno, description, charttype, + gifi_accno, category, link, contra) + VALUES ('$form->{accno}',| + .$dbh->quote($form->{description}).qq|, + '$form->{charttype}', '$form->{gifi_accno}', + '$form->{category}', '$form->{link}', '$form->{contra}')|; + } + + $dbh->do($query) || $form->dberror($query); + + + $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->{AR_tax} || $form->{AP_tax}) { + + # add account if it doesn't exist in tax + $query = qq|SELECT chart_id + FROM tax + WHERE chart_id = $chart_id|; + + my ($tax_id) = $dbh->selectrow_array($query); + + # add tax if it doesn't exist + unless ($tax_id) { + $query = qq|INSERT INTO tax (chart_id, rate) + VALUES ($chart_id, 0)|; + + $dbh->do($query) || $form->dberror($query); + } + + } else { + + # remove tax + if ($form->{id}) { + $query = qq|DELETE FROM tax + WHERE chart_id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + } + } + + # commit + my $rc = $dbh->commit; + $dbh->disconnect; + + $rc; +} + + + +sub delete_account { + + my ($self, $myconfig, $form) = @_; + + # connect to database, turn off AutoCommit + my $dbh = $form->dbconnect_noauto($myconfig); + + ## needs fixing (SELECT *...) + 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 + WHERE id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + + # set inventory_accno_id, income_accno_id, expense_accno_id to defaults + $query = qq|UPDATE parts + SET inventory_accno_id = (SELECT inventory_accno_id + FROM defaults) + WHERE inventory_accno_id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + + $query = qq|UPDATE parts + SET income_accno_id = (SELECT income_accno_id + FROM defaults) + WHERE income_accno_id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + + $query = qq|UPDATE parts + SET expense_accno_id = (SELECT expense_accno_id + FROM defaults) + WHERE expense_accno_id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + + foreach my $table (qw(partstax customertax vendortax tax)) { + $query = qq|DELETE FROM $table + WHERE chart_id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + } + + # commit and redirect + my $rc = $dbh->commit; + $dbh->disconnect; + + $rc; +} + + +sub gifi_accounts { + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT accno, description + FROM gifi + ORDER BY accno|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + + $dbh->disconnect; +} + + + +sub get_gifi { + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT accno, description + FROM gifi + WHERE accno = '$form->{accno}'|; + + ($form->{accno}, $form->{description}) = $dbh->selectrow_array($query); + + # check for transactions ## needs fixing (SELECT *...) + $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}; + + $dbh->disconnect; + +} + + +sub save_gifi { + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $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 = |.$dbh->quote($form->{description}).qq| + WHERE accno = '$form->{id}'|; + + } else { + $query = qq|INSERT INTO gifi (accno, description) + VALUES ('$form->{accno}',| + .$dbh->quote($form->{description}).qq|)|; + } + + $dbh->do($query) || $form->dberror; + $dbh->disconnect; + +} + + +sub delete_gifi { + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + # id is the old account number! + $query = qq|DELETE FROM gifi + WHERE accno = '$form->{id}'|; + + $dbh->do($query) || $form->dberror($query); + $dbh->disconnect; + +} + + +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 description $form->{direction}|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + $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 description $form->{direction}|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + $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); + + for (keys %$ref) { $form->{$_} = $ref->{$_} } + + # see if it is in use ## needs fixing (SELECT * ...) + $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 description $form->{direction}|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{ALL} }, $ref; + } + + $sth->finish; + $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; + } + + $sth->finish; + $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); + for (keys %$ref) { $form->{$_} = $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; + } + + $sth->finish; + $dbh->disconnect; + +} + + +sub get_language { + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + ## needs fixing (SELECT *...) + 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); + + for (keys %$ref) { $form->{$_} = $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 recurring_transactions { + + my ($self, $myconfig, $form) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT curr FROM defaults|; + + my ($defaultcurrency) = $dbh->selectrow_array($query); + $defaultcurrency =~ s/:.*//g; + + $form->{sort} ||= "nextdate"; + my @a = ($form->{sort}); + my $sortorder = $form->sort_order(\@a); + + $query = qq|SELECT 'ar' AS module, 'ar' AS transaction, a.invoice, + n.name AS description, a.amount, + s.*, se.formname AS recurringemail, + sp.formname AS recurringprint, + s.nextdate - current_date AS overdue, 'customer' AS vc, + ex.buy AS exchangerate, a.curr, + (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired + FROM recurring s + JOIN ar a ON (a.id = s.id) + JOIN customer n ON (n.id = a.customer_id) + LEFT JOIN recurringemail se ON (se.id = s.id) + LEFT JOIN recurringprint sp ON (sp.id = s.id) + LEFT JOIN exchangerate ex ON (ex.curr = a.curr AND a.transdate = ex.transdate) + + UNION + + SELECT 'ap' AS module, 'ap' AS transaction, a.invoice, + n.name AS description, a.amount, + s.*, se.formname AS recurringemail, + sp.formname AS recurringprint, + s.nextdate - current_date AS overdue, 'vendor' AS vc, + ex.sell AS exchangerate, a.curr, + (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired + FROM recurring s + JOIN ap a ON (a.id = s.id) + JOIN vendor n ON (n.id = a.vendor_id) + LEFT JOIN recurringemail se ON (se.id = s.id) + LEFT JOIN recurringprint sp ON (sp.id = s.id) + LEFT JOIN exchangerate ex ON (ex.curr = a.curr AND a.transdate = ex.transdate) + + UNION + + SELECT 'gl' AS module, 'gl' AS transaction, FALSE AS invoice, + a.description, (SELECT SUM(ac.amount) + FROM acc_trans ac + WHERE ac.trans_id = a.id + AND ac.amount > 0) AS amount, + s.*, se.formname AS recurringemail, + sp.formname AS recurringprint, + s.nextdate - current_date AS overdue, '' AS vc, + '1' AS exchangerate, '$defaultcurrency' AS curr, + (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired + FROM recurring s + JOIN gl a ON (a.id = s.id) + LEFT JOIN recurringemail se ON (se.id = s.id) + LEFT JOIN recurringprint sp ON (sp.id = s.id) + + UNION + + SELECT 'oe' AS module, 'so' AS transaction, FALSE AS invoice, + n.name AS description, a.amount, + s.*, se.formname AS recurringemail, + sp.formname AS recurringprint, + s.nextdate - current_date AS overdue, 'customer' AS vc, + ex.buy AS exchangerate, a.curr, + (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired + FROM recurring s + JOIN oe a ON (a.id = s.id) + JOIN customer n ON (n.id = a.customer_id) + LEFT JOIN recurringemail se ON (se.id = s.id) + LEFT JOIN recurringprint sp ON (sp.id = s.id) + LEFT JOIN exchangerate ex ON (ex.curr = a.curr AND a.transdate = ex.transdate) + WHERE a.quotation = '0' + + UNION + + SELECT 'oe' AS module, 'po' AS transaction, FALSE AS invoice, + n.name AS description, a.amount, + s.*, se.formname AS recurringemail, + sp.formname AS recurringprint, + s.nextdate - current_date AS overdue, 'vendor' AS vc, + ex.sell AS exchangerate, a.curr, + (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired + FROM recurring s + JOIN oe a ON (a.id = s.id) + JOIN vendor n ON (n.id = a.vendor_id) + LEFT JOIN recurringemail se ON (se.id = s.id) + LEFT JOIN recurringprint sp ON (sp.id = s.id) + LEFT JOIN exchangerate ex ON (ex.curr = a.curr AND a.transdate = ex.transdate) + WHERE a.quotation = '0' + + ORDER BY $sortorder|; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $id; + my $transaction; + my %e = (); + my %p = (); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + + $ref->{exchangerate} ||= 1; + + if ($ref->{id} != $id) { + + if (%e) { + $form->{transactions}{$transaction}->[$i]->{recurringemail} = ""; + for (keys %e) { $form->{transactions}{$transaction}->[$i]->{recurringemail} .= "${_}:" } + chop $form->{transactions}{$transaction}->[$i]->{recurringemail}; + } + + if (%p) { + $form->{transactions}{$transaction}->[$i]->{recurringprint} = ""; + for (keys %p) { $form->{transactions}{$transaction}->[$i]->{recurringprint} .= "${_}:" } + chop $form->{transactions}{$transaction}->[$i]->{recurringprint}; + } + + %e = (); + %p = (); + + push @{ $form->{transactions}{$ref->{transaction}} }, $ref; + + $id = $ref->{id}; + $i = $#{ $form->{transactions}{$ref->{transaction}} }; + + } + + $transaction = $ref->{transaction}; + + $e{$ref->{recurringemail}} = 1 if $ref->{recurringemail}; + $p{$ref->{recurringprint}} = 1 if $ref->{recurringprint}; + + } + + $sth->finish; + + # this is for the last row + if (%e) { + $form->{transactions}{$transaction}->[$i]->{recurringemail} = ""; + for (keys %e) { $form->{transactions}{$transaction}->[$i]->{recurringemail} .= "${_}:" } + chop $form->{transactions}{$transaction}->[$i]->{recurringemail}; + } + + if (%p) { + $form->{transactions}{$transaction}->[$i]->{recurringprint} = ""; + for (keys %p) { $form->{transactions}{$transaction}->[$i]->{recurringprint} .= "${_}:" } + chop $form->{transactions}{$transaction}->[$i]->{recurringprint}; + } + + + $dbh->disconnect; + +} + +sub recurring_details { + + my ($self, $myconfig, $form, $id) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT s.*, ar.id AS arid, ar.invoice AS arinvoice, + ap.id AS apid, ap.invoice AS apinvoice, + ar.duedate - ar.transdate AS overdue, + ar.datepaid - ar.transdate AS paid, + oe.reqdate - oe.transdate AS req, + oe.id AS oeid, oe.customer_id, oe.vendor_id + FROM recurring s + LEFT JOIN ar ON (ar.id = s.id) + LEFT JOIN ap ON (ap.id = s.id) + LEFT JOIN oe ON (oe.id = s.id) + WHERE s.id = $id|; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + $form->{vc} = "customer" if $ref->{customer_id}; + $form->{vc} = "vendor" if $ref->{vendor_id}; + for (keys %$ref) { $form->{$_} = $ref->{$_} } + $sth->finish; + + $form->{invoice} = ($form->{arid} && $form->{arinvoice}); + $form->{invoice} = ($form->{apid} && $form->{apinvoice}) unless $form->{invoice}; + + $query = qq|SELECT * + FROM recurringemail + WHERE id = $id|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $form->{recurringemail} = ""; + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + $form->{recurringemail} .= "$ref->{formname}:$ref->{format}:"; + $form->{message} = $ref->{message}; + } + + $sth->finish; + + $query = qq|SELECT * + FROM recurringprint + WHERE id = $id|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $form->{recurringprint} = ""; + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + $form->{recurringprint} .= "$ref->{formname}:$ref->{format}:$ref->{printer}:"; + } + + $sth->finish; + + chop $form->{recurringemail}; + chop $form->{recurringprint}; + + for (qw(arinvoice apinvoice)) { delete $form->{$_} } + + $dbh->disconnect; + +} + + +sub update_recurring { + + my ($self, $myconfig, $form, $id) = @_; + + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT nextdate, repeat, unit + FROM recurring + WHERE id = $id|; + + my ($nextdate, $repeat, $unit) = $dbh->selectrow_array($query); + + my %advance = ( 'Pg' => "(date '$nextdate' + interval '$repeat $unit')", + 'DB2' => qq|(date ('$nextdate') + "$repeat $unit")|,); + + $interval{Oracle} = $interval{PgPP} = $interval{Pg}; + + # check if it is the last date + $query = qq|SELECT $advance{$myconfig->{dbdriver}} > enddate + FROM recurring + WHERE id = $id|; + + my ($last_repeat) = $dbh->selectrow_array($query); + if ($last_repeat) { + $advance{$myconfig->{dbdriver}} = "NULL"; + } + + $query = qq|UPDATE recurring + SET nextdate = $advance{$myconfig->{dbdriver}} + WHERE id = $id|; + + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + +} + + +sub load_template { + + my ($self, $form) = @_; + + open(TEMPLATE, "$form->{file}") or $form->error("$form->{file} : $!"); + + while (