summaryrefslogtreecommitdiff
path: root/LedgerSMB/RC.pm
blob: 47a8a4c430d8966b250359a3275843188d00c8a2 (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. # http://www.ledgersmb.org/
  5. #
  6. # Copyright (C) 2006
  7. # This work contains copyrighted information from a number of sources all used
  8. # with permission.
  9. #
  10. # This file contains source code included with or based on SQL-Ledger which
  11. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  12. # under the GNU General Public License version 2 or, at your option, any later
  13. # version. For a full list including contact information of contributors,
  14. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  15. #
  16. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  17. # Copyright (C) 2002
  18. #
  19. # Author: DWS Systems Inc.
  20. # Web: http://www.sql-ledger.org
  21. #
  22. # Contributors:
  23. #
  24. #======================================================================
  25. #
  26. # This file has NOT undergone whitespace cleanup.
  27. #
  28. #======================================================================
  29. #
  30. # Account reconciliation routines
  31. #
  32. #======================================================================
  33. package RC;
  34. sub getposlines{
  35. my ($self, $myconfig, $form) = @_;
  36. %pos_config = %{$form->{pos_config}};
  37. %pos_sources = %{$form->{pos_sources}};
  38. my $sources = '';
  39. foreach $key (keys %pos_sources){
  40. $sources .= ", '$key'";
  41. }
  42. $sources =~ s/^,\s*//;
  43. my $dbh = $form->{dbh};
  44. # Considering the query below to be safe since all variables are from config
  45. # files rather than user input.
  46. my $query = qq|
  47. SELECT sum(amount) AS amount, source FROM acc_trans
  48. WHERE chart_id =
  49. (SELECT id FROM chart WHERE accno = '$pos_config{till_accno}')
  50. AND transdate = date 'NOW'
  51. AND cleared IS NOT TRUE
  52. GROUP BY source
  53. |;
  54. my $sth = $dbh->prepare($query);
  55. $sth->execute || $form->dberror($query);
  56. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  57. push @{$form->{TB}}, $ref;
  58. }
  59. $sth->finish;
  60. my $query = qq|
  61. SELECT sum(amount) AS sum FROM acc_trans
  62. WHERE chart_id =
  63. (SELECT id FROM chart WHERE accno = '$pos_config{till_accno}')
  64. AND transdate = date 'NOW'
  65. AND cleared IS NOT TRUE
  66. |;
  67. my $sth = $dbh->prepare($query);
  68. $sth->execute || $form->dberror($query);
  69. my $ref = $sth->fetchrow_hashref(NAME_lc);
  70. $form->{sum} = $ref->{sum};
  71. $sth->finish;
  72. }
  73. sub clear_till {
  74. my ($self, $myconfig, $form) = @_;
  75. %pos_config = %{$form->{pos_config}};
  76. %pos_sources = %{$form->{pos_sources}};
  77. my $sources = '';
  78. foreach $key (keys %pos_sources){
  79. $sources .= ", '$key'";
  80. }
  81. $sources =~ s/^,\s//;
  82. my $dbh = $form->{dbh};
  83. my $query = qq|
  84. UPDATE acc_trans
  85. SET cleared = TRUE
  86. WHERE chart_id =
  87. (SELECT id FROM chart WHERE accno = '$pos_config{till_accno}')
  88. AND transdate = date 'NOW'
  89. |;
  90. my $sth = $dbh->prepare($query);
  91. $sth->execute || $form->dberror($query);
  92. }
  93. sub getbalance{
  94. my ($self, $myconfig, $form) = @_;
  95. my $dbh = $form->{dbh};
  96. my $query = qq|SELECT sum(amount) AS balance
  97. FROM acc_trans
  98. WHERE chart_id =
  99. (SELECT id FROM chart WHERE accno = '$form->{accno}')|;
  100. my $sth = $dbh->prepare($query);
  101. $sth->execute || $form->dberror($query);
  102. my $ref = $sth->fetchrow_hashref(NAME_lc);
  103. $form->{balance} = $ref->{balance};
  104. }
  105. sub paymentaccounts {
  106. my ($self, $myconfig, $form) = @_;
  107. # connect to database
  108. my $dbh = $form->{dbh};
  109. my $query = qq|SELECT accno, description
  110. FROM chart
  111. WHERE link LIKE '%_paid%'
  112. AND (category = 'A' OR category = 'L')
  113. ORDER BY accno|;
  114. my $sth = $dbh->prepare($query);
  115. $sth->execute || $form->dberror($query);
  116. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  117. push @{ $form->{PR} }, $ref;
  118. }
  119. $sth->finish;
  120. $form->all_years($myconfig, $dbh);
  121. $dbh->disconnect;
  122. }
  123. sub payment_transactions {
  124. my ($self, $myconfig, $form) = @_;
  125. # connect to database, turn AutoCommit off
  126. my $dbh = $form->dbconnect_noauto($myconfig);
  127. my $query;
  128. my $sth;
  129. $query = qq|SELECT category FROM chart
  130. WHERE accno = '$form->{accno}'|;
  131. ($form->{category}) = $dbh->selectrow_array($query);
  132. my $cleared;
  133. ($form->{fromdate}, $form->{todate}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
  134. my $transdate = qq| AND ac.transdate < date '$form->{fromdate}'|;
  135. if (! $form->{fromdate}) {
  136. $cleared = qq| AND ac.cleared = '1'|;
  137. $transdate = "";
  138. }
  139. # get beginning balance
  140. $query = qq|SELECT sum(ac.amount)
  141. FROM acc_trans ac
  142. JOIN chart ch ON (ch.id = ac.chart_id)
  143. WHERE ch.accno = '$form->{accno}'
  144. $transdate
  145. $cleared
  146. |;
  147. ($form->{beginningbalance}) = $dbh->selectrow_array($query);
  148. # fx balance
  149. $query = qq|SELECT sum(ac.amount)
  150. FROM acc_trans ac
  151. JOIN chart ch ON (ch.id = ac.chart_id)
  152. WHERE ch.accno = '$form->{accno}'
  153. AND ac.fx_transaction = '1'
  154. $transdate
  155. $cleared
  156. |;
  157. ($form->{fx_balance}) = $dbh->selectrow_array($query);
  158. $transdate = "";
  159. if ($form->{todate}) {
  160. $transdate = qq| AND ac.transdate <= date '$form->{todate}'|;
  161. }
  162. # get statement balance
  163. $query = qq|SELECT sum(ac.amount)
  164. FROM acc_trans ac
  165. JOIN chart ch ON (ch.id = ac.chart_id)
  166. WHERE ch.accno = '$form->{accno}'
  167. $transdate
  168. |;
  169. ($form->{endingbalance}) = $dbh->selectrow_array($query);
  170. # fx balance
  171. $query = qq|SELECT sum(ac.amount)
  172. FROM acc_trans ac
  173. JOIN chart ch ON (ch.id = ac.chart_id)
  174. WHERE ch.accno = '$form->{accno}'
  175. AND ac.fx_transaction = '1'
  176. $transdate
  177. |;
  178. ($form->{fx_endingbalance}) = $dbh->selectrow_array($query);
  179. $cleared = qq| AND ac.cleared = '0'| unless $form->{fromdate};
  180. if ($form->{report}) {
  181. $cleared = qq| AND NOT (ac.cleared = '0' OR ac.cleared = '1')|;
  182. if ($form->{cleared}) {
  183. $cleared = qq| AND ac.cleared = '1'|;
  184. }
  185. if ($form->{outstanding}) {
  186. $cleared = ($form->{cleared}) ? "" : qq| AND ac.cleared = '0'|;
  187. }
  188. if (! $form->{fromdate}) {
  189. $form->{beginningbalance} = 0;
  190. $form->{fx_balance} = 0;
  191. }
  192. }
  193. my $fx_transaction;
  194. if ($form->{fx_transaction}) {
  195. $fx_transaction = qq|
  196. AND NOT
  197. (ac.chart_id IN
  198. (SELECT fxgain_accno_id FROM defaults
  199. UNION
  200. SELECT fxloss_accno_id FROM defaults))|;
  201. } else {
  202. $fx_transaction = qq|
  203. AND ac.fx_transaction = '0'|;
  204. }
  205. if ($form->{summary}) {
  206. $query = qq|SELECT ac.transdate, ac.source,
  207. sum(ac.amount) AS amount, ac.cleared
  208. FROM acc_trans ac
  209. JOIN chart ch ON (ac.chart_id = ch.id)
  210. WHERE ch.accno = '$form->{accno}'
  211. AND ac.amount >= 0
  212. $fx_transaction
  213. $cleared|;
  214. $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
  215. $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
  216. $query .= " GROUP BY ac.source, ac.transdate, ac.cleared";
  217. $query .= qq|
  218. UNION ALL
  219. SELECT ac.transdate, ac.source,
  220. sum(ac.amount) AS amount, ac.cleared
  221. FROM acc_trans ac
  222. JOIN chart ch ON (ac.chart_id = ch.id)
  223. WHERE ch.accno = '$form->{accno}'
  224. AND ac.amount < 0
  225. $fx_transaction
  226. $cleared|;
  227. $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
  228. $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
  229. $query .= " GROUP BY ac.source, ac.transdate, ac.cleared";
  230. $query .= " ORDER BY 1,2";
  231. } else {
  232. $query = qq|SELECT ac.transdate, ac.source, ac.fx_transaction,
  233. ac.amount, ac.cleared, g.id, g.description
  234. FROM acc_trans ac
  235. JOIN chart ch ON (ac.chart_id = ch.id)
  236. JOIN gl g ON (g.id = ac.trans_id)
  237. WHERE ch.accno = '$form->{accno}'
  238. $fx_transaction
  239. $cleared|;
  240. $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
  241. $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
  242. $query .= qq|
  243. UNION ALL
  244. SELECT ac.transdate, ac.source, ac.fx_transaction,
  245. ac.amount, ac.cleared, a.id, n.name
  246. FROM acc_trans ac
  247. JOIN chart ch ON (ac.chart_id = ch.id)
  248. JOIN ar a ON (a.id = ac.trans_id)
  249. JOIN customer n ON (n.id = a.customer_id)
  250. WHERE ch.accno = '$form->{accno}'
  251. $fx_transaction
  252. $cleared|;
  253. $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
  254. $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
  255. $query .= qq|
  256. UNION ALL
  257. SELECT ac.transdate, ac.source, ac.fx_transaction,
  258. ac.amount, ac.cleared, a.id, n.name
  259. FROM acc_trans ac
  260. JOIN chart ch ON (ac.chart_id = ch.id)
  261. JOIN ap a ON (a.id = ac.trans_id)
  262. JOIN vendor n ON (n.id = a.vendor_id)
  263. WHERE ch.accno = '$form->{accno}'
  264. $fx_transaction
  265. $cleared|;
  266. $query .= " AND ac.transdate >= '$form->{fromdate}'" if $form->{fromdate};
  267. $query .= " AND ac.transdate <= '$form->{todate}'" if $form->{todate};
  268. $query .= " ORDER BY 1,2,3";
  269. }
  270. $sth = $dbh->prepare($query);
  271. $sth->execute || $form->dberror($query);
  272. my $dr;
  273. my $cr;
  274. if ($form->{summary}) {
  275. $query = qq|SELECT c.name
  276. FROM customer c
  277. JOIN ar a ON (c.id = a.customer_id)
  278. JOIN acc_trans ac ON (a.id = ac.trans_id)
  279. JOIN chart ch ON (ac.chart_id = ch.id)
  280. WHERE ac.transdate = ?
  281. AND ch.accno = '$form->{accno}'
  282. AND (ac.source = ? OR ac.source IS NULL)
  283. AND ac.amount >= 0
  284. $cleared
  285. UNION
  286. SELECT v.name
  287. FROM vendor v
  288. JOIN ap a ON (v.id = a.vendor_id)
  289. JOIN acc_trans ac ON (a.id = ac.trans_id)
  290. JOIN chart ch ON (ac.chart_id = ch.id)
  291. WHERE ac.transdate = ?
  292. AND ch.accno = '$form->{accno}'
  293. AND (ac.source = ? OR ac.source IS NULL)
  294. AND ac.amount > 0
  295. $cleared
  296. UNION
  297. SELECT g.description
  298. FROM gl g
  299. JOIN acc_trans ac ON (g.id = ac.trans_id)
  300. JOIN chart ch ON (ac.chart_id = ch.id)
  301. WHERE ac.transdate = ?
  302. AND ch.accno = '$form->{accno}'
  303. AND (ac.source = ? OR ac.source IS NULL)
  304. AND ac.amount >= 0
  305. $cleared
  306. |;
  307. $query .= " ORDER BY 1";
  308. $dr = $dbh->prepare($query);
  309. $query = qq|SELECT c.name
  310. FROM customer c
  311. JOIN ar a ON (c.id = a.customer_id)
  312. JOIN acc_trans ac ON (a.id = ac.trans_id)
  313. JOIN chart ch ON (ac.chart_id = ch.id)
  314. WHERE ac.transdate = ?
  315. AND ch.accno = '$form->{accno}'
  316. AND (ac.source = ? OR ac.source IS NULL)
  317. AND ac.amount < 0
  318. $cleared
  319. UNION
  320. SELECT v.name
  321. FROM vendor v
  322. JOIN ap a ON (v.id = a.vendor_id)
  323. JOIN acc_trans ac ON (a.id = ac.trans_id)
  324. JOIN chart ch ON (ac.chart_id = ch.id)
  325. WHERE ac.transdate = ?
  326. AND ch.accno = '$form->{accno}'
  327. AND (ac.source = ? OR ac.source IS NULL)
  328. AND ac.amount < 0
  329. $cleared
  330. UNION
  331. SELECT g.description
  332. FROM gl g
  333. JOIN acc_trans ac ON (g.id = ac.trans_id)
  334. JOIN chart ch ON (ac.chart_id = ch.id)
  335. WHERE ac.transdate = ?
  336. AND ch.accno = '$form->{accno}'
  337. AND (ac.source = ? OR ac.source IS NULL)
  338. AND ac.amount < 0
  339. $cleared
  340. |;
  341. $query .= " ORDER BY 1";
  342. $cr = $dbh->prepare($query);
  343. }
  344. my $name;
  345. my $ref;
  346. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  347. if ($form->{summary}) {
  348. if ($ref->{amount} > 0) {
  349. $dr->execute($ref->{transdate}, $ref->{source}, $ref->{transdate}, $ref->{source}, $ref->{transdate}, $ref->{source});
  350. $ref->{oldcleared} = $ref->{cleared};
  351. $ref->{name} = ();
  352. while (($name) = $dr->fetchrow_array) {
  353. push @{ $ref->{name} }, $name;
  354. }
  355. $dr->finish;
  356. } else {
  357. $cr->execute($ref->{transdate}, $ref->{source}, $ref->{transdate}, $ref->{source}, $ref->{transdate}, $ref->{source});
  358. $ref->{oldcleared} = $ref->{cleared};
  359. $ref->{name} = ();
  360. while (($name) = $cr->fetchrow_array) {
  361. push @{ $ref->{name} }, $name;
  362. }
  363. $cr->finish;
  364. }
  365. } else {
  366. push @{ $ref->{name} }, $ref->{description};
  367. }
  368. push @{ $form->{PR} }, $ref;
  369. }
  370. $sth->finish;
  371. $dbh->disconnect;
  372. }
  373. sub reconcile {
  374. my ($self, $myconfig, $form) = @_;
  375. # connect to database
  376. my $dbh = $form->dbconnect($myconfig);
  377. my $query = qq|SELECT id FROM chart
  378. WHERE accno = '$form->{accno}'|;
  379. my ($chart_id) = $dbh->selectrow_array($query);
  380. $chart_id *= 1;
  381. $query = qq|SELECT trans_id FROM acc_trans
  382. WHERE (source = ? OR source IS NULL)
  383. AND transdate = ?
  384. AND cleared = '0'
  385. AND chart_id = $chart_id|;
  386. my $sth = $dbh->prepare($query) || $form->dberror($query);
  387. my $i;
  388. my $trans_id;
  389. $query = qq|UPDATE acc_trans SET cleared = '1'
  390. WHERE cleared = '0'
  391. AND trans_id = ?
  392. AND transdate = ?
  393. AND chart_id = $chart_id|;
  394. my $tth = $dbh->prepare($query) || $form->dberror($query);
  395. # clear flags
  396. for $i (1 .. $form->{rowcount}) {
  397. if ($form->{"cleared_$i"} && ! $form->{"oldcleared_$i"}) {
  398. if ($form->{summary}) {
  399. $sth->execute($form->{"source_$i"}, $form->{"transdate_$i"}) || $form->dberror;
  400. while (($trans_id) = $sth->fetchrow_array) {
  401. $tth->execute($trans_id, $form->{"transdate_$i"}) || $form->dberror;
  402. $tth->finish;
  403. }
  404. $sth->finish;
  405. } else {
  406. $tth->execute($form->{"id_$i"}, $form->{"transdate_$i"}) || $form->dberror;
  407. $tth->finish;
  408. }
  409. }
  410. }
  411. $dbh->disconnect;
  412. }
  413. 1;