summaryrefslogtreecommitdiff
path: root/bin/mozilla/gl.pl
blob: 3e238609705fbe03022b93ef5cee45c0a9b14075 (plain)
  1. #=====================================================================
  2. # LedgerSMB Small Medium Business Accounting
  3. # http://www.ledgersmb.org/
  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) 2001
  17. #
  18. # Author: DWS Systems Inc.
  19. # Web: http://www.sql-ledger.org
  20. #
  21. # Contributors:
  22. #
  23. #
  24. # Author: DWS Systems Inc.
  25. # Web: http://www.ledgersmb.org/
  26. #
  27. # Contributors:
  28. #
  29. # This program is free software; you can redistribute it and/or modify
  30. # it under the terms of the GNU General Public License as published by
  31. # the Free Software Foundation; either version 2 of the License, or
  32. # (at your option) any later version.
  33. #
  34. # This program is distributed in the hope that it will be useful,
  35. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  36. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  37. # GNU General Public License for more details.
  38. # You should have received a copy of the GNU General Public License
  39. # along with this program; if not, write to the Free Software
  40. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  41. #======================================================================
  42. #
  43. # Genereal Ledger
  44. #
  45. #======================================================================
  46. use LedgerSMB::GL;
  47. use LedgerSMB::PE;
  48. require "$form->{path}/arap.pl";
  49. 1;
  50. # end of main
  51. # this is for our long dates
  52. # $locale->text('January')
  53. # $locale->text('February')
  54. # $locale->text('March')
  55. # $locale->text('April')
  56. # $locale->text('May ')
  57. # $locale->text('June')
  58. # $locale->text('July')
  59. # $locale->text('August')
  60. # $locale->text('September')
  61. # $locale->text('October')
  62. # $locale->text('November')
  63. # $locale->text('December')
  64. # this is for our short month
  65. # $locale->text('Jan')
  66. # $locale->text('Feb')
  67. # $locale->text('Mar')
  68. # $locale->text('Apr')
  69. # $locale->text('May')
  70. # $locale->text('Jun')
  71. # $locale->text('Jul')
  72. # $locale->text('Aug')
  73. # $locale->text('Sep')
  74. # $locale->text('Oct')
  75. # $locale->text('Nov')
  76. # $locale->text('Dec')
  77. sub add {
  78. $form->{title} = "Add";
  79. $form->{callback} = "$form->{script}?action=add&transfer=$form->{transfer}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback};
  80. &create_links;
  81. $form->{rowcount} = ($form->{transfer}) ? 3 : 9;
  82. $form->{oldtransdate} = $form->{transdate};
  83. $form->{focus} = "reference";
  84. # departments
  85. if (@{ $form->{all_department} }) {
  86. $form->{selectdepartment} = "<option>\n";
  87. for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| }
  88. }
  89. &display_form(1);
  90. }
  91. sub edit {
  92. &create_links;
  93. $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto}));
  94. # readonly
  95. if (! $form->{readonly}) {
  96. $form->{readonly} = 1 if $myconfig{acs} =~ /General Ledger--Add Transaction/;
  97. }
  98. $form->{title} = "Edit";
  99. $i = 1;
  100. foreach $ref (@{ $form->{GL} }) {
  101. $form->{"accno_$i"} = "$ref->{accno}--$ref->{description}";
  102. $form->{"projectnumber_$i"} = "$ref->{projectnumber}--$ref->{project_id}";
  103. for (qw(fx_transaction source memo)) { $form->{"${_}_$i"} = $ref->{$_} }
  104. if ($ref->{amount} < 0) {
  105. $form->{totaldebit} -= $ref->{amount};
  106. $form->{"debit_$i"} = $ref->{amount} * -1;
  107. } else {
  108. $form->{totalcredit} += $ref->{amount};
  109. $form->{"credit_$i"} = $ref->{amount};
  110. }
  111. $i++;
  112. }
  113. $form->{rowcount} = $i;
  114. $form->{focus} = "debit_$i";
  115. &form_header;
  116. &display_rows;
  117. &form_footer;
  118. }
  119. sub create_links {
  120. GL->transaction(\%myconfig, \%$form);
  121. for (@{ $form->{all_accno} }) { $form->{selectaccno} .= "<option>$_->{accno}--$_->{description}\n" }
  122. # projects
  123. if (@{ $form->{all_project} }) {
  124. $form->{selectprojectnumber} = "<option>\n";
  125. for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| }
  126. }
  127. # departments
  128. if (@{ $form->{all_department} }) {
  129. $form->{department} = "$form->{department}--$form->{department_id}";
  130. $form->{selectdepartment} = "<option>\n";
  131. for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| }
  132. }
  133. }
  134. sub search {
  135. $form->{title} = $locale->text('General Ledger')." ".$locale->text('Reports');
  136. $colspan = 5;
  137. $form->all_departments(\%myconfig);
  138. # departments
  139. if (@{ $form->{all_department} }) {
  140. $form->{selectdepartment} = "<option>\n";
  141. for (@{ $form->{all_department} }) { $form->{selectdepartment} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| }
  142. $l_department = qq|<input name="l_department" class=checkbox type=checkbox value=Y> |.$locale->text('Department');
  143. $department = qq|
  144. <tr>
  145. <th align=right nowrap>|.$locale->text('Department').qq|</th>
  146. <td colspan=$colspan><select name=department>$form->{selectdepartment}</select></td>
  147. </tr>
  148. |;
  149. }
  150. if (@{ $form->{all_years} }) {
  151. # accounting years
  152. $form->{selectaccountingyear} = "<option>\n";
  153. for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| }
  154. $form->{selectaccountingmonth} = "<option>\n";
  155. for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| }
  156. $selectfrom = qq|
  157. <tr>
  158. <th align=right>|.$locale->text('Period').qq|</th>
  159. <td colspan=$colspan>
  160. <select name=month>$form->{selectaccountingmonth}</select>
  161. <select name=year>$form->{selectaccountingyear}</select>
  162. <input name=interval class=radio type=radio value=0 checked>&nbsp;|.$locale->text('Current').qq|
  163. <input name=interval class=radio type=radio value=1>&nbsp;|.$locale->text('Month').qq|
  164. <input name=interval class=radio type=radio value=3>&nbsp;|.$locale->text('Quarter').qq|
  165. <input name=interval class=radio type=radio value=12>&nbsp;|.$locale->text('Year').qq|
  166. </td>
  167. </tr>
  168. |;
  169. }
  170. @a = ();
  171. push @a, qq|<input name="l_id" class=checkbox type=checkbox value=Y> |.$locale->text('ID');
  172. push @a, qq|<input name="l_transdate" class=checkbox type=checkbox value=Y checked> |.$locale->text('Date');
  173. push @a, qq|<input name="l_reference" class=checkbox type=checkbox value=Y checked> |.$locale->text('Reference');
  174. push @a, qq|<input name="l_description" class=checkbox type=checkbox value=Y checked> |.$locale->text('Description');
  175. push @a, qq|<input name="l_notes" class=checkbox type=checkbox value=Y> |.$locale->text('Notes');
  176. push @a, $l_department if $l_department;
  177. push @a, qq|<input name="l_debit" class=checkbox type=checkbox value=Y checked> |.$locale->text('Debit');
  178. push @a, qq|<input name="l_credit" class=checkbox type=checkbox value=Y checked> |.$locale->text('Credit');
  179. push @a, qq|<input name="l_source" class=checkbox type=checkbox value=Y checked> |.$locale->text('Source');
  180. push @a, qq|<input name="l_memo" class=checkbox type=checkbox value=Y> |.$locale->text('Memo');
  181. push @a, qq|<input name="l_accno" class=checkbox type=checkbox value=Y checked> |.$locale->text('Account');
  182. push @a, qq|<input name="l_gifi_accno" class=checkbox type=checkbox value=Y> |.$locale->text('GIFI');
  183. $form->header;
  184. print qq|
  185. <body>
  186. <form method=post action=$form->{script}>
  187. <input type=hidden name=sort value=transdate>
  188. <table width=100%>
  189. <tr>
  190. <th class=listtop>$form->{title}</th>
  191. </tr>
  192. <tr height="5"></tr>
  193. <tr>
  194. <td>
  195. <table>
  196. <tr>
  197. <th align=right>|.$locale->text('Reference').qq|</th>
  198. <td><input name=reference size=20></td>
  199. </tr>
  200. <tr>
  201. <th align=right>|.$locale->text('Source').qq|</th>
  202. <td><input name=source size=20></td>
  203. <th align=right>|.$locale->text('Memo').qq|</th>
  204. <td><input name=memo size=20></td>
  205. </tr>
  206. $department
  207. <tr>
  208. <th align=right>|.$locale->text('Description').qq|</th>
  209. <td colspan=$colspan><input name=description size=60></td>
  210. </tr>
  211. <tr>
  212. <th align=right>|.$locale->text('Notes').qq|</th>
  213. <td colspan=$colspan><input name=notes size=60></td>
  214. </tr>
  215. <tr>
  216. <th align=right>|.$locale->text('From').qq|</th>
  217. <td><input name=datefrom size=11 title="$myconfig{dateformat}"></td>
  218. <th align=right>|.$locale->text('To').qq|</th>
  219. <td><input name=dateto size=11 title="$myconfig{dateformat}"></td>
  220. </tr>
  221. $selectfrom
  222. <tr>
  223. <th align=right>|.$locale->text('Amount').qq| >=</th>
  224. <td><input name=amountfrom size=11></td>
  225. <th align=right>|.$locale->text('Amount').qq| <=</th>
  226. <td><input name=amountto size=11></td>
  227. </tr>
  228. <tr>
  229. <th align=right>|.$locale->text('Include in Report').qq|</th>
  230. <td colspan=$colspan>
  231. <table>
  232. <tr>
  233. <td>
  234. <input name="category" class=radio type=radio value=X checked>&nbsp;|.$locale->text('All').qq|
  235. <input name="category" class=radio type=radio value=A>&nbsp;|.$locale->text('Asset').qq|
  236. <input name="category" class=radio type=radio value=L>&nbsp;|.$locale->text('Liability').qq|
  237. <input name="category" class=radio type=radio value=Q>&nbsp;|.$locale->text('Equity').qq|
  238. <input name="category" class=radio type=radio value=I>&nbsp;|.$locale->text('Income').qq|
  239. <input name="category" class=radio type=radio value=E>&nbsp;|.$locale->text('Expense').qq|
  240. </td>
  241. </tr>
  242. <tr>
  243. <table>
  244. |;
  245. while (@a) {
  246. print qq|<tr>\n|;
  247. for (1 .. 5) {
  248. print qq|<td nowrap>|. shift @a;
  249. print qq|</td>\n|;
  250. }
  251. print qq|</tr>\n|;
  252. }
  253. print qq|
  254. <tr>
  255. <td nowrap><input name="l_subtotal" class=checkbox type=checkbox value=Y> |.$locale->text('Subtotal').qq|</td>
  256. </tr>
  257. </table>
  258. </tr>
  259. </table>
  260. </tr>
  261. </table>
  262. </td>
  263. </tr>
  264. <tr>
  265. <td><hr size=3 noshade></td>
  266. </tr>
  267. </table>
  268. <input type=hidden name=nextsub value=generate_report>
  269. |;
  270. $form->hide_form(qw(path login sessionid));
  271. print qq|
  272. <br>
  273. <input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
  274. </form>
  275. |;
  276. if ($form->{menubar}) {
  277. require "$form->{path}/menu.pl";
  278. &menubar;
  279. }
  280. print qq|
  281. </body>
  282. </html>
  283. |;
  284. }
  285. sub generate_report {
  286. $form->{sort} = "transdate" unless $form->{sort};
  287. GL->all_transactions(\%myconfig, \%$form);
  288. $href = "$form->{script}?action=generate_report&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  289. $form->sort_order();
  290. $callback = "$form->{script}?action=generate_report&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  291. %acctype = ( 'A' => $locale->text('Asset'),
  292. 'L' => $locale->text('Liability'),
  293. 'Q' => $locale->text('Equity'),
  294. 'I' => $locale->text('Income'),
  295. 'E' => $locale->text('Expense'),
  296. );
  297. $form->{title} = $locale->text('General Ledger');
  298. $ml = ($form->{category} =~ /(A|E)/) ? -1 : 1;
  299. unless ($form->{category} eq 'X') {
  300. $form->{title} .= " : ".$locale->text($acctype{$form->{category}});
  301. }
  302. if ($form->{accno}) {
  303. $href .= "&accno=".$form->escape($form->{accno});
  304. $callback .= "&accno=".$form->escape($form->{accno},1);
  305. $option = $locale->text('Account')." : $form->{accno} $form->{account_description}";
  306. }
  307. if ($form->{gifi_accno}) {
  308. $href .= "&gifi_accno=".$form->escape($form->{gifi_accno});
  309. $callback .= "&gifi_accno=".$form->escape($form->{gifi_accno},1);
  310. $option .= "\n<br>" if $option;
  311. $option .= $locale->text('GIFI')." : $form->{gifi_accno} $form->{gifi_account_description}";
  312. }
  313. if ($form->{source}) {
  314. $href .= "&source=".$form->escape($form->{source});
  315. $callback .= "&source=".$form->escape($form->{source},1);
  316. $option .= "\n<br>" if $option;
  317. $option .= $locale->text('Source')." : $form->{source}";
  318. }
  319. if ($form->{memo}) {
  320. $href .= "&memo=".$form->escape($form->{memo});
  321. $callback .= "&memo=".$form->escape($form->{memo},1);
  322. $option .= "\n<br>" if $option;
  323. $option .= $locale->text('Memo')." : $form->{memo}";
  324. }
  325. if ($form->{reference}) {
  326. $href .= "&reference=".$form->escape($form->{reference});
  327. $callback .= "&reference=".$form->escape($form->{reference},1);
  328. $option .= "\n<br>" if $option;
  329. $option .= $locale->text('Reference')." : $form->{reference}";
  330. }
  331. if ($form->{department}) {
  332. $href .= "&department=".$form->escape($form->{department});
  333. $callback .= "&department=".$form->escape($form->{department},1);
  334. ($department) = split /--/, $form->{department};
  335. $option .= "\n<br>" if $option;
  336. $option .= $locale->text('Department')." : $department";
  337. }
  338. if ($form->{description}) {
  339. $href .= "&description=".$form->escape($form->{description});
  340. $callback .= "&description=".$form->escape($form->{description},1);
  341. $option .= "\n<br>" if $option;
  342. $option .= $locale->text('Description')." : $form->{description}";
  343. }
  344. if ($form->{notes}) {
  345. $href .= "&notes=".$form->escape($form->{notes});
  346. $callback .= "&notes=".$form->escape($form->{notes},1);
  347. $option .= "\n<br>" if $option;
  348. $option .= $locale->text('Notes')." : $form->{notes}";
  349. }
  350. if ($form->{datefrom}) {
  351. $href .= "&datefrom=$form->{datefrom}";
  352. $callback .= "&datefrom=$form->{datefrom}";
  353. $option .= "\n<br>" if $option;
  354. $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{datefrom}, 1);
  355. }
  356. if ($form->{dateto}) {
  357. $href .= "&dateto=$form->{dateto}";
  358. $callback .= "&dateto=$form->{dateto}";
  359. if ($form->{datefrom}) {
  360. $option .= " ";
  361. } else {
  362. $option .= "\n<br>" if $option;
  363. }
  364. $option .= $locale->text('To')." ".$locale->date(\%myconfig, $form->{dateto}, 1);
  365. }
  366. if ($form->{amountfrom}) {
  367. $href .= "&amountfrom=$form->{amountfrom}";
  368. $callback .= "&amountfrom=$form->{amountfrom}";
  369. $option .= "\n<br>" if $option;
  370. $option .= $locale->text('Amount')." >= ".$form->format_amount(\%myconfig, $form->{amountfrom}, 2);
  371. }
  372. if ($form->{amountto}) {
  373. $href .= "&amountto=$form->{amountto}";
  374. $callback .= "&amountto=$form->{amountto}";
  375. if ($form->{amountfrom}) {
  376. $option .= " <= ";
  377. } else {
  378. $option .= "\n<br>" if $option;
  379. $option .= $locale->text('Amount')." <= ";
  380. }
  381. $option .= $form->format_amount(\%myconfig, $form->{amountto}, 2);
  382. }
  383. @columns = $form->sort_columns(qw(transdate id reference description notes source memo debit credit accno gifi_accno department));
  384. pop @columns if $form->{department};
  385. if ($form->{link} =~ /_paid/) {
  386. @columns = $form->sort_columns(qw(transdate id reference description notes source memo cleared debit credit accno gifi_accno));
  387. $form->{l_cleared} = "Y";
  388. }
  389. if ($form->{accno} || $form->{gifi_accno}) {
  390. @columns = grep !/(accno|gifi_accno)/, @columns;
  391. push @columns, "balance";
  392. $form->{l_balance} = "Y";
  393. }
  394. foreach $item (@columns) {
  395. if ($form->{"l_$item"} eq "Y") {
  396. push @column_index, $item;
  397. # add column to href and callback
  398. $callback .= "&l_$item=Y";
  399. $href .= "&l_$item=Y";
  400. }
  401. }
  402. if ($form->{l_subtotal} eq 'Y') {
  403. $callback .= "&l_subtotal=Y";
  404. $href .= "&l_subtotal=Y";
  405. }
  406. $callback .= "&category=$form->{category}";
  407. $href .= "&category=$form->{category}";
  408. $column_header{id} = "<th><a class=listheading href=$href&sort=id>".$locale->text('ID')."</a></th>";
  409. $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>";
  410. $column_header{reference} = "<th><a class=listheading href=$href&sort=reference>".$locale->text('Reference')."</a></th>";
  411. $column_header{source} = "<th><a class=listheading href=$href&sort=source>".$locale->text('Source')."</a></th>";
  412. $column_header{memo} = "<th><a class=listheading href=$href&sort=memo>".$locale->text('Memo')."</a></th>";
  413. $column_header{description} = "<th><a class=listheading href=$href&sort=description>".$locale->text('Description')."</a></th>";
  414. $column_header{department} = "<th><a class=listheading href=$href&sort=department>".$locale->text('Department')."</a></th>";
  415. $column_header{notes} = "<th class=listheading>".$locale->text('Notes')."</th>";
  416. $column_header{debit} = "<th class=listheading>".$locale->text('Debit')."</th>";
  417. $column_header{credit} = "<th class=listheading>".$locale->text('Credit')."</th>";
  418. $column_header{accno} = "<th><a class=listheading href=$href&sort=accno>".$locale->text('Account')."</a></th>";
  419. $column_header{gifi_accno} = "<th><a class=listheading href=$href&sort=gifi_accno>".$locale->text('GIFI')."</a></th>";
  420. $column_header{balance} = "<th>".$locale->text('Balance')."</th>";
  421. $column_header{cleared} = qq|<th>|.$locale->text('R').qq|</th>|;
  422. $form->header;
  423. print qq|
  424. <body>
  425. <table width=100%>
  426. <tr>
  427. <th class=listtop>$form->{title}</th>
  428. </tr>
  429. <tr height="5"></tr>
  430. <tr>
  431. <td>$option</td>
  432. </tr>
  433. <tr>
  434. <td>
  435. <table width=100%>
  436. <tr class=listheading>
  437. |;
  438. for (@column_index) { print "$column_header{$_}\n" }
  439. print "
  440. </tr>
  441. ";
  442. # add sort to callback
  443. $form->{callback} = "$callback&sort=$form->{sort}";
  444. $callback = $form->escape($form->{callback});
  445. $cml = 1;
  446. # initial item for subtotals
  447. if (@{ $form->{GL} }) {
  448. $sameitem = $form->{GL}->[0]->{$form->{sort}};
  449. $cml = -1 if $form->{contra};
  450. }
  451. if (($form->{accno} || $form->{gifi_accno}) && $form->{balance}) {
  452. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  453. $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml * $cml, 2, 0)."</td>";
  454. $i++; $i %= 2;
  455. print qq|
  456. <tr class=listrow$i>
  457. |;
  458. for (@column_index) { print "$column_data{$_}\n" }
  459. print qq|
  460. </tr>
  461. |;
  462. }
  463. # reverse href
  464. $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC";
  465. $form->sort_order();
  466. $href =~ s/direction=$form->{direction}/direction=$direction/;
  467. $i = 0;
  468. foreach $ref (@{ $form->{GL} }) {
  469. # if item ne sort print subtotal
  470. if ($form->{l_subtotal} eq 'Y') {
  471. if ($sameitem ne $ref->{$form->{sort}}) {
  472. &gl_subtotal;
  473. }
  474. }
  475. $form->{balance} += $ref->{amount};
  476. $subtotaldebit += $ref->{debit};
  477. $subtotalcredit += $ref->{credit};
  478. $totaldebit += $ref->{debit};
  479. $totalcredit += $ref->{credit};
  480. $ref->{debit} = $form->format_amount(\%myconfig, $ref->{debit}, 2, "&nbsp;");
  481. $ref->{credit} = $form->format_amount(\%myconfig, $ref->{credit}, 2, "&nbsp;");
  482. for (qw(id transdate)) { $column_data{$_} = "<td>$ref->{$_}</td>" }
  483. $column_data{reference} = "<td><a href=$ref->{module}.pl?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{reference}</td>";
  484. $ref->{notes} =~ s/\r?\n/<br>/g;
  485. for (qw(description source memo notes department)) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  486. $column_data{debit} = "<td align=right>$ref->{debit}</td>";
  487. $column_data{credit} = "<td align=right>$ref->{credit}</td>";
  488. $column_data{accno} = "<td><a href=$href&accno=$ref->{accno}&callback=$callback>$ref->{accno}</a></td>";
  489. $column_data{gifi_accno} = "<td><a href=$href&gifi_accno=$ref->{gifi_accno}&callback=$callback>$ref->{gifi_accno}</a>&nbsp;</td>";
  490. $column_data{balance} = "<td align=right>".$form->format_amount(\%myconfig, $form->{balance} * $ml * $cml, 2, 0)."</td>";
  491. $column_data{cleared} = ($ref->{cleared}) ? "<td>*</td>" : "<td>&nbsp;</td>";
  492. if ($ref->{id} != $sameid) {
  493. $i++; $i %= 2;
  494. }
  495. print "
  496. <tr class=listrow$i>";
  497. for (@column_index) { print "$column_data{$_}\n" }
  498. print "</tr>";
  499. $sameid = $ref->{id};
  500. }
  501. &gl_subtotal if ($form->{l_subtotal} eq 'Y');
  502. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  503. $column_data{debit} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $totaldebit, 2, "&nbsp;")."</th>";
  504. $column_data{credit} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $totalcredit, 2, "&nbsp;")."</th>";
  505. $column_data{balance} = "<th align=right class=listtotal>".$form->format_amount(\%myconfig, $form->{balance} * $ml * $cml, 2, 0)."</th>";
  506. print qq|
  507. <tr class=listtotal>
  508. |;
  509. for (@column_index) { print "$column_data{$_}\n" }
  510. $i = 1;
  511. if ($myconfig{acs} !~ /General Ledger--General Ledger/) {
  512. $button{'General Ledger--Add Transaction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('GL Transaction').qq|"> |;
  513. $button{'General Ledger--Add Transaction'}{order} = $i++;
  514. }
  515. if ($myconfig{acs} !~ /AR--AR/) {
  516. $button{'AR--Add Transaction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('AR Transaction').qq|"> |;
  517. $button{'AR--Add Transaction'}{order} = $i++;
  518. $button{'AR--Sales Invoice'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Sales Invoice ').qq|"> |;
  519. $button{'AR--Sales Invoice'}{order} = $i++;
  520. }
  521. if ($myconfig{acs} !~ /AP--AP/) {
  522. $button{'AP--Add Transaction'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('AP Transaction').qq|"> |;
  523. $button{'AP--Add Transaction'}{order} = $i++;
  524. $button{'AP--Vendor Invoice'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Vendor Invoice ').qq|"> |;
  525. $button{'AP--Vendor Invoice'}{order} = $i++;
  526. }
  527. foreach $item (split /;/, $myconfig{acs}) {
  528. delete $button{$item};
  529. }
  530. print qq|
  531. </tr>
  532. </table>
  533. </td>
  534. </tr>
  535. <tr>
  536. <td><hr size=3 noshade></td>
  537. </tr>
  538. </table>
  539. <br>
  540. <form method=post action=$form->{script}>
  541. |;
  542. $form->hide_form(qw(callback path login sessionid));
  543. foreach $item (sort { $a->{order} <=> $b->{order} } %button) {
  544. print $item->{code};
  545. }
  546. if ($form->{menubar}) {
  547. require "$form->{path}/menu.pl";
  548. &menubar;
  549. }
  550. print qq|
  551. </form>
  552. </body>
  553. </html>
  554. |;
  555. }
  556. sub gl_subtotal {
  557. $subtotaldebit = $form->format_amount(\%myconfig, $subtotaldebit, 2, "&nbsp;");
  558. $subtotalcredit = $form->format_amount(\%myconfig, $subtotalcredit, 2, "&nbsp;");
  559. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  560. $column_data{debit} = "<th align=right class=listsubtotal>$subtotaldebit</td>";
  561. $column_data{credit} = "<th align=right class=listsubtotal>$subtotalcredit</td>";
  562. print "<tr class=listsubtotal>";
  563. for (@column_index) { print "$column_data{$_}\n" }
  564. print "</tr>";
  565. $subtotaldebit = 0;
  566. $subtotalcredit = 0;
  567. $sameitem = $ref->{$form->{sort}};
  568. }
  569. sub update {
  570. if ($form->{transdate} ne $form->{oldtransdate}) {
  571. if ($form->{selectprojectnumber}) {
  572. $form->all_projects(\%myconfig, undef, $form->{transdate});
  573. if (@{ $form->{all_project} }) {
  574. $form->{selectprojectnumber} = "<option>\n";
  575. for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| }
  576. $form->{selectprojectnumber} = $form->escape($form->{selectprojectnumber},1);
  577. }
  578. }
  579. $form->{oldtransdate} = $form->{transdate};
  580. }
  581. @a = ();
  582. $count = 0;
  583. @flds = qw(accno debit credit projectnumber fx_transaction source memo);
  584. for $i (1 .. $form->{rowcount}) {
  585. unless (($form->{"debit_$i"} eq "") && ($form->{"credit_$i"} eq "")) {
  586. for (qw(debit credit)) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) }
  587. push @a, {};
  588. $j = $#a;
  589. for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
  590. $count++;
  591. }
  592. }
  593. for $i (1 .. $count) {
  594. $j = $i - 1;
  595. for (@flds) { $form->{"${_}_$i"} = $a[$j]->{$_} }
  596. }
  597. for $i ($count + 1 .. $form->{rowcount}) {
  598. for (@flds) { delete $form->{"${_}_$i"} }
  599. }
  600. $form->{rowcount} = $count + 1;
  601. &display_form;
  602. }
  603. sub display_form {
  604. my ($init) = @_;
  605. &form_header;
  606. &display_rows($init);
  607. &form_footer;
  608. }
  609. sub display_rows {
  610. my ($init) = @_;
  611. $form->{selectprojectnumber} = $form->unescape($form->{selectprojectnumber}) if $form->{selectprojectnumber};
  612. $form->{totaldebit} = 0;
  613. $form->{totalcredit} = 0;
  614. for $i (1 .. $form->{rowcount}) {
  615. $source = qq|
  616. <td><input name="source_$i" size=10 value="$form->{"source_$i"}"></td>|;
  617. $memo = qq|
  618. <td><input name="memo_$i" value="$form->{"memo_$i"}"></td>|;
  619. if ($init) {
  620. $accno = qq|
  621. <td><select name="accno_$i">$form->{selectaccno}</select></td>|;
  622. if ($form->{selectprojectnumber}) {
  623. $project = qq|
  624. <td><select name="projectnumber_$i">$form->{selectprojectnumber}</select></td>|;
  625. }
  626. if ($form->{transfer}) {
  627. $fx_transaction = qq|
  628. <td><input name="fx_transaction_$i" class=checkbox type=checkbox value=1></td>
  629. |;
  630. }
  631. } else {
  632. $form->{totaldebit} += $form->{"debit_$i"};
  633. $form->{totalcredit} += $form->{"credit_$i"};
  634. for (qw(debit credit)) { $form->{"${_}_$i"} = ($form->{"${_}_$i"}) ? $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2) : "" }
  635. if ($i < $form->{rowcount}) {
  636. $accno = qq|<td>$form->{"accno_$i"}</td>|;
  637. if ($form->{selectprojectnumber}) {
  638. $form->{"projectnumber_$i"} = "" if $form->{selectprojectnumber} !~ /$form->{"projectnumber_$i"}/;
  639. $project = $form->{"projectnumber_$i"};
  640. $project =~ s/--.*//;
  641. $project = qq|<td>$project</td>|;
  642. }
  643. if ($form->{transfer}) {
  644. $checked = ($form->{"fx_transaction_$i"}) ? "1" : "";
  645. $x = ($checked) ? "x" : "";
  646. $fx_transaction = qq|
  647. <td><input type=hidden name="fx_transaction_$i" value="$checked">$x</td>
  648. |;
  649. }
  650. $form->hide_form("accno_$i", "projectnumber_$i");
  651. } else {
  652. $accno = qq|
  653. <td><select name="accno_$i">$form->{selectaccno}</select></td>|;
  654. if ($form->{selectprojectnumber}) {
  655. $project = qq|
  656. <td><select name="projectnumber_$i">$form->{selectprojectnumber}</select></td>|;
  657. }
  658. if ($form->{transfer}) {
  659. $fx_transaction = qq|
  660. <td><input name="fx_transaction_$i" class=checkbox type=checkbox value=1></td>
  661. |;
  662. }
  663. }
  664. }
  665. print qq|<tr valign=top>
  666. $accno
  667. $fx_transaction
  668. <td><input name="debit_$i" size=12 value="$form->{"debit_$i"}" accesskey=$i></td>
  669. <td><input name="credit_$i" size=12 value=$form->{"credit_$i"}></td>
  670. $source
  671. $memo
  672. $project
  673. </tr>
  674. |;
  675. }
  676. $form->hide_form(qw(rowcount selectaccno));
  677. print qq|
  678. <input type=hidden name=selectprojectnumber value="|.$form->escape($form->{selectprojectnumber},1).qq|">|;
  679. }
  680. sub form_header {
  681. $title = $form->{title};
  682. if ($form->{transfer}) {
  683. $form->{title} = $locale->text("$title Cash Transfer Transaction");
  684. } else {
  685. $form->{title} = $locale->text("$title General Ledger Transaction");
  686. }
  687. # $locale->text('Add Cash Transfer Transaction')
  688. # $locale->text('Edit Cash Transfer Transaction')
  689. # $locale->text('Add General Ledger Transaction')
  690. # $locale->text('Edit General Ledger Transaction')
  691. $form->{selectdepartment} = $form->unescape($form->{selectdepartment});
  692. $form->{selectdepartment} =~ s/ selected//;
  693. $form->{selectdepartment} =~ s/(<option value="\Q$form->{department}\E")/$1 selected/;
  694. for (qw(reference description notes)) { $form->{$_} = $form->quote($form->{$_}) }
  695. if (($rows = $form->numtextrows($form->{description}, 50)) > 1) {
  696. $description = qq|<textarea name=description rows=$rows cols=50 wrap=soft>$form->{description}</textarea>|;
  697. } else {
  698. $description = qq|<input name=description size=50 value="$form->{description}">|;
  699. }
  700. if (($rows = $form->numtextrows($form->{notes}, 50)) > 1) {
  701. $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|;
  702. } else {
  703. $notes = qq|<input name=notes size=50 value="$form->{notes}">|;
  704. }
  705. $department = qq|
  706. <tr>
  707. <th align=right nowrap>|.$locale->text('Department').qq|</th>
  708. <td><select name=department>$form->{selectdepartment}</select></td>
  709. <input type=hidden name=selectdepartment value="|.$form->escape($form->{selectdepartment},1).qq|">
  710. </tr>
  711. | if $form->{selectdepartment};
  712. $project = qq|
  713. <th class=listheading>|.$locale->text('Project').qq|</th>
  714. | if $form->{selectprojectnumber};
  715. if ($form->{transfer}) {
  716. $fx_transaction = qq|
  717. <th class=listheading>|.$locale->text('FX').qq|</th>
  718. |;
  719. }
  720. $focus = ($form->{focus}) ? $form->{focus} : "debit_$form->{rowcount}";
  721. $form->header;
  722. print qq|
  723. <body onload="document.forms[0].${focus}.focus()" />
  724. <form method=post action=$form->{script}>
  725. |;
  726. $form->hide_form(qw(id transfer selectaccno closedto locked oldtransdate recurring));
  727. print qq|
  728. <input type=hidden name=title value="$title">
  729. <table width=100%>
  730. <tr>
  731. <th class=listtop>$form->{title}</th>
  732. </tr>
  733. <tr height="5"></tr>
  734. <tr>
  735. <td>
  736. <table>
  737. <tr>
  738. <th align=right>|.$locale->text('Reference').qq|</th>
  739. <td><input name=reference size=20 value="$form->{reference}"></td>
  740. <th align=right>|.$locale->text('Date').qq|</th>
  741. <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td>
  742. </tr>
  743. $department
  744. <tr>
  745. <th align=right>|.$locale->text('Description').qq|</th>
  746. <td colspan=3>$description</td>
  747. </tr>
  748. <tr>
  749. <th align=right>|.$locale->text('Notes').qq|</th>
  750. <td colspan=3>$notes</td>
  751. </tr>
  752. </table>
  753. </td>
  754. </tr>
  755. <tr>
  756. <td>
  757. <table width=100%>
  758. <tr class=listheading>
  759. <th class=listheading>|.$locale->text('Account').qq|</th>
  760. $fx_transaction
  761. <th class=listheading>|.$locale->text('Debit').qq|</th>
  762. <th class=listheading>|.$locale->text('Credit').qq|</th>
  763. <th class=listheading>|.$locale->text('Source').qq|</th>
  764. <th class=listheading>|.$locale->text('Memo').qq|</th>
  765. $project
  766. </tr>
  767. |;
  768. }
  769. sub form_footer {
  770. for (qw(totaldebit totalcredit)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2, "&nbsp;") }
  771. $project = qq|
  772. <th>&nbsp;</th>
  773. | if $form->{selectprojectnumber};
  774. if ($form->{transfer}) {
  775. $fx_transaction = qq|
  776. <th>&nbsp;</th>
  777. |;
  778. }
  779. print qq|
  780. <tr class=listtotal>
  781. <th>&nbsp;</th>
  782. $fx_transaction
  783. <th class=listtotal align=right>$form->{totaldebit}</th>
  784. <th class=listtotal align=right>$form->{totalcredit}</th>
  785. <th>&nbsp;</th>
  786. <th>&nbsp;</th>
  787. $project
  788. </tr>
  789. </table>
  790. </td>
  791. </tr>
  792. <tr>
  793. <td><hr size=3 noshade></td>
  794. </tr>
  795. </table>
  796. |;
  797. $form->hide_form(qw(path login sessionid callback));
  798. $transdate = $form->datetonum(\%myconfig, $form->{transdate});
  799. $closedto = $form->datetonum(\%myconfig, $form->{closedto});
  800. # type=submit $locale->text('Update')
  801. # type=submit $locale->text('Post')
  802. # type=submit $locale->text('Schedule')
  803. # type=submit $locale->text('Post as new')
  804. # type=submit $locale->text('Delete')
  805. if (! $form->{readonly}) {
  806. %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') },
  807. 'Post' => { ndx => 3, key => 'O', value => $locale->text('Post') },
  808. 'Post as new' => { ndx => 6, key => 'N', value => $locale->text('Post as new') },
  809. 'Schedule' => { ndx => 7, key => 'H', value => $locale->text('Schedule') },
  810. 'Delete' => { ndx => 8, key => 'D', value => $locale->text('Delete') },
  811. );
  812. %a = ();
  813. if ($form->{id}) {
  814. for ('Update', 'Post as new', 'Schedule') { $a{$_} = 1 }
  815. if (! $form->{locked}) {
  816. if ($transdate > $closedto) {
  817. for ('Post', 'Delete') { $a{$_} = 1 }
  818. }
  819. }
  820. } else {
  821. if ($transdate > $closedto) {
  822. for ("Update", "Post", "Schedule") { $a{$_} = 1 }
  823. }
  824. }
  825. for (keys %button) { delete $button{$_} if ! $a{$_} }
  826. for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) }
  827. }
  828. if ($form->{recurring}) {
  829. print qq|<div align=right>|.$locale->text('Scheduled').qq|</div>|;
  830. }
  831. if ($form->{menubar}) {
  832. require "$form->{path}/menu.pl";
  833. &menubar;
  834. }
  835. print qq|
  836. </form>
  837. </body>
  838. </html>
  839. |;
  840. }
  841. sub delete {
  842. $form->header;
  843. print qq|
  844. <body>
  845. <form method=post action=$form->{script}>
  846. |;
  847. delete $form->{action};
  848. $form->hide_form;
  849. print qq|
  850. <h2 class=confirm>|.$locale->text('Confirm!').qq|</h2>
  851. <h4>|.$locale->text('Are you sure you want to delete Transaction').qq| $form->{reference}</h4>
  852. <input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
  853. </form>
  854. |;
  855. }
  856. sub yes {
  857. if (GL->delete_transaction(\%myconfig, \%$form)) {
  858. $form->redirect($locale->text('Transaction deleted!'));
  859. } else {
  860. $form->error($locale->text('Cannot delete transaction!'));
  861. }
  862. }
  863. sub post {
  864. $form->isblank("transdate", $locale->text('Transaction Date missing!'));
  865. $transdate = $form->datetonum(\%myconfig, $form->{transdate});
  866. $closedto = $form->datetonum(\%myconfig, $form->{closedto});
  867. $form->error($locale->text('Cannot post transaction for a closed period!')) if ($transdate <= $closedto);
  868. # add up debits and credits
  869. for $i (1 .. $form->{rowcount}) {
  870. $dr = $form->parse_amount(\%myconfig, $form->{"debit_$i"});
  871. $cr = $form->parse_amount(\%myconfig, $form->{"credit_$i"});
  872. if ($dr && $cr) {
  873. $form->error($locale->text('Cannot post transaction with a debit and credit entry for the same account!'));
  874. }
  875. $debit += $dr;
  876. $credit += $cr;
  877. }
  878. if ($form->round_amount($debit, 2) != $form->round_amount($credit, 2)) {
  879. $form->error($locale->text('Out of balance transaction!'));
  880. }
  881. if (! $form->{repost}) {
  882. if ($form->{id}) {
  883. &repost;
  884. exit;
  885. }
  886. }
  887. if (GL->post_transaction(\%myconfig, \%$form)) {
  888. $form->redirect($locale->text('Transaction posted!'));
  889. } else {
  890. $form->error($locale->text('Cannot post transaction!'));
  891. }
  892. }