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