summaryrefslogtreecommitdiff
path: root/LedgerSMB/GL.pm
blob: 3acc89267c8ac333459b855b88db8aaeed37f128 (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. #
  5. # Copyright (C) 2006
  6. # This work contains copyrighted information from a number of sources all used
  7. # with permission.
  8. #
  9. # This file contains source code included with or based on SQL-Ledger which
  10. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  11. # under the GNU General Public License version 2 or, at your option, any later
  12. # version. For a full list including contact information of contributors,
  13. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  14. #
  15. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  16. # Copyright (C) 2000
  17. #
  18. # Author: DWS Systems Inc.
  19. # Web: http://www.sql-ledger.org
  20. #
  21. # Contributors:
  22. #
  23. #======================================================================
  24. #
  25. # This file has undergone whitespace cleanup.
  26. #
  27. #======================================================================
  28. #
  29. # General ledger backend code
  30. #
  31. #======================================================================
  32. package GL;
  33. sub delete_transaction {
  34. my ($self, $myconfig, $form) = @_;
  35. # connect to database
  36. my $dbh = $form->dbconnect_noauto($myconfig);
  37. my %audittrail = ( tablename => 'gl',
  38. reference => $form->{reference},
  39. formname => 'transaction',
  40. action => 'deleted',
  41. id => $form->{id} );
  42. $form->audittrail($dbh, "", \%audittrail);
  43. my $query = qq|DELETE FROM gl WHERE id = $form->{id}|;
  44. $dbh->do($query) || $form->dberror($query);
  45. $query = qq|DELETE FROM acc_trans WHERE trans_id = $form->{id}|;
  46. $dbh->do($query) || $form->dberror($query);
  47. # commit and redirect
  48. my $rc = $dbh->commit;
  49. $dbh->disconnect;
  50. $rc;
  51. }
  52. sub post_transaction {
  53. my ($self, $myconfig, $form) = @_;
  54. my $null;
  55. my $project_id;
  56. my $department_id;
  57. my $i;
  58. # connect to database, turn off AutoCommit
  59. my $dbh = $form->dbconnect_noauto($myconfig);
  60. my $query;
  61. my $sth;
  62. if ($form->{id}) {
  63. $query = qq|SELECT id FROM gl WHERE id = $form->{id}|;
  64. ($form->{id}) = $dbh->selectrow_array($query);
  65. if ($form->{id}) {
  66. # delete individual transactions
  67. $query = qq|DELETE FROM acc_trans
  68. WHERE trans_id = $form->{id}|;
  69. $dbh->do($query) || $form->dberror($query);
  70. }
  71. }
  72. if (! $form->{id}) {
  73. my $uid = localtime;
  74. $uid .= "$$";
  75. $query = qq|INSERT INTO gl (reference, employee_id)
  76. VALUES ('$uid', (SELECT id FROM employee
  77. WHERE login = '$form->{login}'))|;
  78. $dbh->do($query) || $form->dberror($query);
  79. $query = qq|SELECT id
  80. FROM gl
  81. WHERE reference = '$uid'|;
  82. ($form->{id}) = $dbh->selectrow_array($query);
  83. }
  84. ($null, $department_id) = split /--/, $form->{department};
  85. $department_id *= 1;
  86. $form->{reference} = $form->update_defaults($myconfig, 'glnumber', $dbh) unless $form->{reference};
  87. $form->{reference} ||= $form->{id};
  88. $query = qq|UPDATE gl
  89. SET reference = |.$dbh->quote($form->{reference}).qq|,
  90. description = |.$dbh->quote($form->{description}).qq|,
  91. notes = |.$dbh->quote($form->{notes}).qq|,
  92. transdate = '$form->{transdate}',
  93. department_id = $department_id
  94. WHERE id = $form->{id}|;
  95. $dbh->do($query) || $form->dberror($query);
  96. my $amount = 0;
  97. my $posted = 0;
  98. my $debit;
  99. my $credit;
  100. # insert acc_trans transactions
  101. for $i (1 .. $form->{rowcount}) {
  102. $debit = $form->parse_amount($myconfig, $form->{"debit_$i"});
  103. $credit = $form->parse_amount($myconfig, $form->{"credit_$i"});
  104. # extract accno
  105. ($accno) = split(/--/, $form->{"accno_$i"});
  106. if ($credit) {
  107. $amount = $credit;
  108. $posted = 0;
  109. }
  110. if ($debit) {
  111. $amount = $debit * -1;
  112. $posted = 0;
  113. }
  114. # add the record
  115. if (! $posted) {
  116. ($null, $project_id) = split /--/, $form->{"projectnumber_$i"};
  117. $project_id ||= 'NULL';
  118. for (qw(fx_transaction cleared)) { $form->{"${_}_$i"} *= 1 }
  119. $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
  120. transdate, source, project_id,
  121. fx_transaction, memo, cleared)
  122. VALUES ($form->{id}, (SELECT id
  123. FROM chart
  124. WHERE accno = '$accno'),
  125. $amount, '$form->{transdate}', |.
  126. $dbh->quote($form->{"source_$i"}) .qq|,
  127. $project_id, '$form->{"fx_transaction_$i"}', |.
  128. $dbh->quote($form->{"memo_$i"}).qq|,
  129. '$form->{"cleared_$i"}')|;
  130. $dbh->do($query) || $form->dberror($query);
  131. $posted = 1;
  132. }
  133. }
  134. my %audittrail = ( tablename => 'gl',
  135. reference => $form->{reference},
  136. formname => 'transaction',
  137. action => 'posted',
  138. id => $form->{id} );
  139. $form->audittrail($dbh, "", \%audittrail);
  140. $form->save_recurring($dbh, $myconfig);
  141. # commit and redirect
  142. my $rc = $dbh->commit;
  143. $dbh->disconnect;
  144. $rc;
  145. }
  146. sub all_transactions {
  147. my ($self, $myconfig, $form) = @_;
  148. # connect to database
  149. my $dbh = $form->dbconnect($myconfig);
  150. my $query;
  151. my $sth;
  152. my $var;
  153. my $null;
  154. my ($glwhere, $arwhere, $apwhere) = ("1 = 1", "1 = 1", "1 = 1");
  155. if ($form->{reference} ne "") {
  156. $var = $form->like(lc $form->{reference});
  157. $glwhere .= " AND lower(g.reference) LIKE '$var'";
  158. $arwhere .= " AND lower(a.invnumber) LIKE '$var'";
  159. $apwhere .= " AND lower(a.invnumber) LIKE '$var'";
  160. }
  161. if ($form->{department} ne "") {
  162. ($null, $var) = split /--/, $form->{department};
  163. $glwhere .= " AND g.department_id = $var";
  164. $arwhere .= " AND a.department_id = $var";
  165. $apwhere .= " AND a.department_id = $var";
  166. }
  167. if ($form->{source} ne "") {
  168. $var = $form->like(lc $form->{source});
  169. $glwhere .= " AND lower(ac.source) LIKE '$var'";
  170. $arwhere .= " AND lower(ac.source) LIKE '$var'";
  171. $apwhere .= " AND lower(ac.source) LIKE '$var'";
  172. }
  173. if ($form->{memo} ne "") {
  174. $var = $form->like(lc $form->{memo});
  175. $glwhere .= " AND lower(ac.memo) LIKE '$var'";
  176. $arwhere .= " AND lower(ac.memo) LIKE '$var'";
  177. $apwhere .= " AND lower(ac.memo) LIKE '$var'";
  178. }
  179. ($form->{datefrom}, $form->{dateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
  180. if ($form->{datefrom}) {
  181. $glwhere .= " AND ac.transdate >= '$form->{datefrom}'";
  182. $arwhere .= " AND ac.transdate >= '$form->{datefrom}'";
  183. $apwhere .= " AND ac.transdate >= '$form->{datefrom}'";
  184. }
  185. if ($form->{dateto}) {
  186. $glwhere .= " AND ac.transdate <= '$form->{dateto}'";
  187. $arwhere .= " AND ac.transdate <= '$form->{dateto}'";
  188. $apwhere .= " AND ac.transdate <= '$form->{dateto}'";
  189. }
  190. if ($form->{amountfrom}) {
  191. $glwhere .= " AND abs(ac.amount) >= $form->{amountfrom}";
  192. $arwhere .= " AND abs(ac.amount) >= $form->{amountfrom}";
  193. $apwhere .= " AND abs(ac.amount) >= $form->{amountfrom}";
  194. }
  195. if ($form->{amountto}) {
  196. $glwhere .= " AND abs(ac.amount) <= $form->{amountto}";
  197. $arwhere .= " AND abs(ac.amount) <= $form->{amountto}";
  198. $apwhere .= " AND abs(ac.amount) <= $form->{amountto}";
  199. }
  200. if ($form->{description}) {
  201. $var = $form->like(lc $form->{description});
  202. $glwhere .= " AND lower(g.description) LIKE '$var'";
  203. $arwhere .= " AND (lower(ct.name) LIKE '$var'
  204. OR lower(ac.memo) LIKE '$var'
  205. OR a.id IN (SELECT DISTINCT trans_id
  206. FROM invoice
  207. WHERE lower(description) LIKE '$var'))";
  208. $apwhere .= " AND (lower(ct.name) LIKE '$var'
  209. OR lower(ac.memo) LIKE '$var'
  210. OR a.id IN (SELECT DISTINCT trans_id
  211. FROM invoice
  212. WHERE lower(description) LIKE '$var'))";
  213. }
  214. if ($form->{notes}) {
  215. $var = $form->like(lc $form->{notes});
  216. $glwhere .= " AND lower(g.notes) LIKE '$var'";
  217. $arwhere .= " AND lower(a.notes) LIKE '$var'";
  218. $apwhere .= " AND lower(a.notes) LIKE '$var'";
  219. }
  220. if ($form->{accno}) {
  221. $glwhere .= " AND c.accno = '$form->{accno}'";
  222. $arwhere .= " AND c.accno = '$form->{accno}'";
  223. $apwhere .= " AND c.accno = '$form->{accno}'";
  224. }
  225. if ($form->{gifi_accno}) {
  226. $glwhere .= " AND c.gifi_accno = '$form->{gifi_accno}'";
  227. $arwhere .= " AND c.gifi_accno = '$form->{gifi_accno}'";
  228. $apwhere .= " AND c.gifi_accno = '$form->{gifi_accno}'";
  229. }
  230. if ($form->{category} ne 'X') {
  231. $glwhere .= " AND c.category = '$form->{category}'";
  232. $arwhere .= " AND c.category = '$form->{category}'";
  233. $apwhere .= " AND c.category = '$form->{category}'";
  234. }
  235. if ($form->{accno}) {
  236. # get category for account
  237. $query = qq|SELECT category, link, contra, description
  238. FROM chart
  239. WHERE accno = '$form->{accno}'|;
  240. ($form->{category}, $form->{link}, $form->{contra},
  241. $form->{account_description}) = $dbh->selectrow_array($query);
  242. if ($form->{datefrom}) {
  243. $query = qq|SELECT SUM(ac.amount)
  244. FROM acc_trans ac
  245. JOIN chart c ON (ac.chart_id = c.id)
  246. WHERE c.accno = '$form->{accno}'
  247. AND ac.transdate < date '$form->{datefrom}' |;
  248. ($form->{balance}) = $dbh->selectrow_array($query);
  249. }
  250. }
  251. if ($form->{gifi_accno}) {
  252. # get category for account
  253. $query = qq|SELECT c.category, c.link, c.contra, g.description
  254. FROM chart c
  255. LEFT JOIN gifi g ON (g.accno = c.gifi_accno)
  256. WHERE c.gifi_accno = '$form->{gifi_accno}'|;
  257. ($form->{category}, $form->{link}, $form->{contra},
  258. $form->{gifi_account_description}) = $dbh->selectrow_array($query);
  259. if ($form->{datefrom}) {
  260. $query = qq|SELECT SUM(ac.amount)
  261. FROM acc_trans ac
  262. JOIN chart c ON (ac.chart_id = c.id)
  263. WHERE c.gifi_accno = '$form->{gifi_accno}'
  264. AND ac.transdate < date '$form->{datefrom}' |;
  265. ($form->{balance}) = $dbh->selectrow_array($query);
  266. }
  267. }
  268. my $false = ($myconfig->{dbdriver} =~ /Pg/) ? FALSE : q|'0'|;
  269. my %ordinal = ( id => 1,
  270. reference => 4,
  271. description => 5,
  272. transdate => 6,
  273. source => 7,
  274. accno => 9,
  275. department => 15,
  276. memo => 16 );
  277. my @a = (id, transdate, reference, source, description, accno);
  278. my $sortorder = $form->sort_order(\@a, \%ordinal);
  279. my $query = qq|SELECT g.id, 'gl' AS type, $false AS invoice, g.reference,
  280. g.description, ac.transdate, ac.source,
  281. ac.amount, c.accno, c.gifi_accno, g.notes, c.link,
  282. '' AS till, ac.cleared, d.description AS department,
  283. ac.memo
  284. FROM gl AS g
  285. JOIN acc_trans ac ON (g.id = ac.trans_id)
  286. JOIN chart c ON (ac.chart_id = c.id)
  287. LEFT JOIN department d ON (d.id = g.department_id)
  288. WHERE $glwhere
  289. UNION ALL
  290. SELECT a.id, 'ar' AS type, a.invoice, a.invnumber,
  291. ct.name, ac.transdate, ac.source,
  292. ac.amount, c.accno, c.gifi_accno, a.notes, c.link,
  293. a.till, ac.cleared, d.description AS department,
  294. ac.memo
  295. FROM ar a
  296. JOIN acc_trans ac ON (a.id = ac.trans_id)
  297. JOIN chart c ON (ac.chart_id = c.id)
  298. JOIN customer ct ON (a.customer_id = ct.id)
  299. LEFT JOIN department d ON (d.id = a.department_id)
  300. WHERE $arwhere
  301. UNION ALL
  302. SELECT a.id, 'ap' AS type, a.invoice, a.invnumber,
  303. ct.name, ac.transdate, ac.source,
  304. ac.amount, c.accno, c.gifi_accno, a.notes, c.link,
  305. a.till, ac.cleared, d.description AS department,
  306. ac.memo
  307. FROM ap a
  308. JOIN acc_trans ac ON (a.id = ac.trans_id)
  309. JOIN chart c ON (ac.chart_id = c.id)
  310. JOIN vendor ct ON (a.vendor_id = ct.id)
  311. LEFT JOIN department d ON (d.id = a.department_id)
  312. WHERE $apwhere
  313. ORDER BY $sortorder|;
  314. my $sth = $dbh->prepare($query);
  315. $sth->execute || $form->dberror($query);
  316. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  317. # gl
  318. if ($ref->{type} eq "gl") {
  319. $ref->{module} = "gl";
  320. }
  321. # ap
  322. if ($ref->{type} eq "ap") {
  323. if ($ref->{invoice}) {
  324. $ref->{module} = "ir";
  325. } else {
  326. $ref->{module} = "ap";
  327. }
  328. }
  329. # ar
  330. if ($ref->{type} eq "ar") {
  331. if ($ref->{invoice}) {
  332. $ref->{module} = ($ref->{till}) ? "ps" : "is";
  333. } else {
  334. $ref->{module} = "ar";
  335. }
  336. }
  337. if ($ref->{amount} < 0) {
  338. $ref->{debit} = $ref->{amount} * -1;
  339. $ref->{credit} = 0;
  340. } else {
  341. $ref->{credit} = $ref->{amount};
  342. $ref->{debit} = 0;
  343. }
  344. push @{ $form->{GL} }, $ref;
  345. }
  346. $sth->finish;
  347. $dbh->disconnect;
  348. }
  349. sub transaction {
  350. my ($self, $myconfig, $form) = @_;
  351. my ($query, $sth, $ref);
  352. # connect to database
  353. my $dbh = $form->dbconnect($myconfig);
  354. if ($form->{id}) {
  355. $query = "SELECT closedto, revtrans
  356. FROM defaults";
  357. $sth = $dbh->prepare($query);
  358. $sth->execute || $form->dberror($query);
  359. ($form->{closedto}, $form->{revtrans}) = $sth->fetchrow_array;
  360. $sth->finish;
  361. $query = qq|SELECT g.*, d.description AS department
  362. FROM gl g
  363. LEFT JOIN department d ON (d.id = g.department_id)
  364. WHERE g.id = $form->{id}|;
  365. $sth = $dbh->prepare($query);
  366. $sth->execute || $form->dberror($query);
  367. $ref = $sth->fetchrow_hashref(NAME_lc);
  368. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  369. $sth->finish;
  370. # retrieve individual rows
  371. $query = qq|SELECT ac.*, c.accno, c.description, p.projectnumber
  372. FROM acc_trans ac
  373. JOIN chart c ON (ac.chart_id = c.id)
  374. LEFT JOIN project p ON (p.id = ac.project_id)
  375. WHERE ac.trans_id = $form->{id}
  376. ORDER BY accno|;
  377. $sth = $dbh->prepare($query);
  378. $sth->execute || $form->dberror($query);
  379. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  380. if ($ref->{fx_transaction}) {
  381. $form->{transfer} = 1;
  382. }
  383. push @{ $form->{GL} }, $ref;
  384. }
  385. # get recurring transaction
  386. $form->get_recurring($dbh);
  387. } else {
  388. $query = "SELECT current_date AS transdate, closedto, revtrans
  389. FROM defaults";
  390. $sth = $dbh->prepare($query);
  391. $sth->execute || $form->dberror($query);
  392. ($form->{transdate}, $form->{closedto}, $form->{revtrans}) = $sth->fetchrow_array;
  393. }
  394. $sth->finish;
  395. # get chart of accounts
  396. $query = qq|SELECT accno,description
  397. FROM chart
  398. WHERE charttype = 'A'
  399. ORDER BY accno|;
  400. $sth = $dbh->prepare($query);
  401. $sth->execute || $form->dberror($query);
  402. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  403. push @{ $form->{all_accno} }, $ref;
  404. }
  405. $sth->finish;
  406. # get departments
  407. $form->all_departments($myconfig, $dbh);
  408. # get projects
  409. $form->all_projects($myconfig, $dbh, $form->{transdate});
  410. $dbh->disconnect;
  411. }
  412. 1;