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