summaryrefslogtreecommitdiff
path: root/bin/am.pl
blob: 581a19a058392ca740fb3b59ade282e77804886a (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. # http://www.ledgersmb.org/
  5. #
  6. #
  7. # Copyright (C) 2006
  8. # This work contains copyrighted information from a number of sources all used
  9. # with permission.
  10. #
  11. # This file contains source code included with or based on SQL-Ledger which
  12. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  13. # under the GNU General Public License version 2 or, at your option, any later
  14. # version. For a full list including contact information of contributors,
  15. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  16. #
  17. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  18. # Copyright (c) 2001
  19. #
  20. # Author: DWS Systems Inc.
  21. # Web: http://www.sql-ledger.org
  22. #
  23. # Contributors:
  24. #
  25. #======================================================================
  26. #
  27. # This file has NOT undergone whitespace cleanup.
  28. #
  29. #======================================================================
  30. #
  31. # administration
  32. #
  33. #======================================================================
  34. use LedgerSMB::AM;
  35. use LedgerSMB::CA;
  36. use LedgerSMB::Form;
  37. use LedgerSMB::User;
  38. use LedgerSMB::RP;
  39. use LedgerSMB::GL;
  40. use LedgerSMB::Template;
  41. 1;
  42. # end of main
  43. sub add { &{"add_$form->{type}"} }
  44. sub edit { &{"edit_$form->{type}"} }
  45. sub save { &{"save_$form->{type}"} }
  46. sub delete { &{"delete_$form->{type}"} }
  47. sub save_as_new {
  48. delete $form->{id};
  49. &save;
  50. }
  51. sub add_account {
  52. $form->{title} = "Add";
  53. $form->{charttype} = "A";
  54. $form->{callback} =
  55. "$form->{script}?action=list_account&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"
  56. unless $form->{callback};
  57. my %hiddens;
  58. my @buttons;
  59. my $checked = &account_header(\%hiddens);
  60. &form_footer_buttons(\%hiddens, \@buttons);
  61. my $template = LedgerSMB::Template->new_UI(
  62. user => \%myconfig,
  63. locale => $locale,
  64. template => 'am-account-form');
  65. $template->render({
  66. form => $form,
  67. checked => $checked,
  68. buttons => \@buttons,
  69. hiddens => \%hiddens,
  70. });
  71. }
  72. sub edit_account {
  73. $form->{title} = "Edit";
  74. $form->{accno} =~ s/\\'/'/g;
  75. $form->{accno} =~ s/\\\\/\\/g;
  76. AM->get_account( \%myconfig, \%$form );
  77. foreach my $item ( split( /:/, $form->{link} ) ) {
  78. $form->{$item} = "checked";
  79. }
  80. my %hiddens;
  81. my @buttons;
  82. my $checked = &account_header(\%hiddens);
  83. &form_footer_buttons(\%hiddens, \@buttons);
  84. my $template = LedgerSMB::Template->new_UI(
  85. user => \%myconfig,
  86. locale => $locale,
  87. template => 'am-account-form');
  88. $template->render({
  89. form => $form,
  90. checked => $checked,
  91. buttons => \@buttons,
  92. hiddens => \%hiddens,
  93. });
  94. }
  95. sub account_header {
  96. my $hiddens = shift;
  97. $form->{title} = $locale->text("$form->{title} Account");
  98. my %checked;
  99. $checked{ $form->{charttype} } = "checked";
  100. $checked{contra} = "checked" if $form->{contra};
  101. $checked{"$form->{category}_"} = "checked";
  102. for (qw(accno description)) { $form->{$_} = $form->quote( $form->{$_} ) }
  103. # this is for our parser only!
  104. # type=submit $locale->text('Add Account')
  105. # type=submit $locale->text('Edit Account')
  106. $hiddens->{type} = 'account';
  107. $hiddens->{$_} eq $form->{$_} foreach qw(id inventory_accno_id income_accno_id expense_accno_id fxgain_accno_id fxloss_accno_id);
  108. \%checked;
  109. }
  110. sub form_footer_buttons {
  111. my ($hiddens, $buttons) = @_;
  112. $hiddens->{$_} = $form->{$_} foreach qw(callback path login sessionid);
  113. # type=submit $locale->text('Save')
  114. # type=submit $locale->text('Save as new')
  115. # type=submit $locale->text('Delete')
  116. %button = ();
  117. if ( $form->{id} ) {
  118. $button{'save'} =
  119. { ndx => 3, key => 'S', value => $locale->text('Save') };
  120. $button{'save_as_new'} =
  121. { ndx => 7, key => 'N', value => $locale->text('Save as new') };
  122. if ( $form->{orphaned} ) {
  123. $button{'delete'} =
  124. { ndx => 16, key => 'D', value => $locale->text('Delete') };
  125. }
  126. }
  127. else {
  128. $button{'save'} =
  129. { ndx => 3, key => 'S', value => $locale->text('Save') };
  130. }
  131. for ( sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button ) {
  132. push @{$buttons}, {
  133. name => 'action',
  134. value => $_,
  135. accesskey => $button{$_}{key},
  136. title => "$button{$_}{value} [Alt-$button{$_}{key}]",
  137. text => $button{$_}{value},
  138. };
  139. }
  140. ##SC: Temporary removal
  141. ## if ( $form->{lynx} ) {
  142. ## require "bin/menu.pl";
  143. ## &menubar;
  144. ## }
  145. }
  146. sub form_footer {
  147. $form->hide_form(qw(callback path login sessionid));
  148. # type=submit $locale->text('Save')
  149. # type=submit $locale->text('Save as new')
  150. # type=submit $locale->text('Delete')
  151. %button = ();
  152. if ( $form->{id} ) {
  153. $button{'save'} =
  154. { ndx => 3, key => 'S', value => $locale->text('Save') };
  155. $button{'save_as_new'} =
  156. { ndx => 7, key => 'N', value => $locale->text('Save as new') };
  157. if ( $form->{orphaned} ) {
  158. $button{'delete'} =
  159. { ndx => 16, key => 'D', value => $locale->text('Delete') };
  160. }
  161. }
  162. else {
  163. $button{'save'} =
  164. { ndx => 3, key => 'S', value => $locale->text('Save') };
  165. }
  166. for ( sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button ) {
  167. $form->print_button( \%button, $_ );
  168. }
  169. if ( $form->{lynx} ) {
  170. require "bin/menu.pl";
  171. &menubar;
  172. }
  173. print qq|
  174. </form>
  175. </body>
  176. </html>
  177. |;
  178. }
  179. sub save_account {
  180. $form->isblank( "accno", $locale->text('Account Number missing!') );
  181. $form->isblank( "category", $locale->text('Account Type missing!') );
  182. # check for conflicting accounts
  183. if ( $form->{AR} || $form->{AP} || $form->{IC} ) {
  184. $a = "";
  185. for (qw(AR AP IC)) { $a .= $form->{$_} }
  186. $form->error(
  187. $locale->text(
  188. 'Cannot set account for more than one of AR, AP or IC')
  189. ) if length $a > 2;
  190. for (
  191. qw(AR_amount AR_tax AR_paid AP_amount AP_tax AP_paid IC_taxpart IC_taxservice IC_sale IC_cogs IC_income IC_expense)
  192. )
  193. {
  194. $form->error(
  195. "$form->{AR}$form->{AP}$form->{IC} "
  196. . $locale->text(
  197. 'account cannot be set to any other type of account')
  198. ) if $form->{$_};
  199. }
  200. }
  201. foreach $item ( "AR", "AP" ) {
  202. $i = 0;
  203. for ( "${item}_amount", "${item}_paid", "${item}_tax" ) {
  204. $i++ if $form->{$_};
  205. }
  206. $form->error(
  207. $locale->text( 'Cannot set multiple options for [_1]', $item ) )
  208. if $i > 1;
  209. }
  210. if ( AM->save_account( \%myconfig, \%$form ) ) {
  211. $form->redirect( $locale->text('Account saved!') );
  212. }
  213. else {
  214. $form->error( $locale->text('Cannot save account!') );
  215. }
  216. }
  217. sub list_account {
  218. CA->all_accounts( \%myconfig, \%$form );
  219. $form->{title} = $locale->text('Chart of Accounts');
  220. # construct callback
  221. $callback =
  222. "$form->{script}?action=list_account&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  223. $form->{callback} = $callback;
  224. @column_index = qw(accno gifi_accno description debit credit link);
  225. $column_header{accno} = $locale->text('Account');
  226. $column_header{gifi_accno} = $locale->text('GIFI');
  227. $column_header{description} = $locale->text('Description');
  228. $column_header{debit} = $locale->text('Debit');
  229. $column_header{credit} = $locale->text('Credit');
  230. $column_header{link} = $locale->text('Link');
  231. # escape callback
  232. $callback = $form->escape($callback);
  233. my @rows;
  234. foreach my $ca ( @{ $form->{CA} } ) {
  235. my %column_data;
  236. $ca->{debit} = " ";
  237. $ca->{credit} = " ";
  238. if ( $ca->{amount} > 0 ) {
  239. $ca->{credit} =
  240. $form->format_amount( \%myconfig, $ca->{amount}, 2, " " );
  241. }
  242. if ( $ca->{amount} < 0 ) {
  243. $ca->{debit} =
  244. $form->format_amount( \%myconfig, -$ca->{amount}, 2, " " );
  245. }
  246. #$ca->{link} =~ s/:/<br>/og;
  247. $gifi_accno = $form->escape( $ca->{gifi_accno} );
  248. if ( $ca->{charttype} eq "H" ) {
  249. $column_data{class} = 'heading';
  250. $column_data{accno} = {
  251. text => $ca->{accno},
  252. href => "$form->{script}?action=edit_account&id=$ca->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback"};
  253. $column_data{gifi_accno} = {
  254. text => $ca->{gifi_accno},
  255. href => "$form->{script}?action=edit_gifi&accno=$gifi_accno&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback"};
  256. $column_data{description} = $ca->{description};
  257. $column_data{debit} = " ";
  258. $column_data{credit} = " ";
  259. $column_data{link} = " ";
  260. }
  261. else {
  262. $i++;
  263. $i %= 2;
  264. $column_data{i} = $i;
  265. $column_data{accno} = {
  266. text => $ca->{accno},
  267. href => "$form->{script}?action=edit_account&id=$ca->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback"};
  268. $column_data{gifi_accno} = {
  269. text => $ca->{gifi_accno},
  270. href => "$form->{script}?action=edit_gifi&accno=$gifi_accno&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback"};
  271. $column_data{description} = $ca->{description};
  272. $column_data{debit} = $ca->{debit};
  273. $column_data{credit} = $ca->{credit};
  274. $column_data{link} = {text => $ca->{link}, delimiter => ':'};
  275. }
  276. push @rows, \%column_data;
  277. }
  278. my @buttons;
  279. for my $type (qw(CSV XLS ODS)) {
  280. push @buttons, {
  281. name => 'action',
  282. value => lc "${type}_list_account",
  283. text => $locale->text("$type Report"),
  284. type => 'submit',
  285. class => 'submit',
  286. };
  287. }
  288. my %hiddens = (
  289. callback => $callback,
  290. action => 'list_account',
  291. path => $form->{path},
  292. login => $form->{login},
  293. sessionid => $form->{sessionid},
  294. );
  295. my %row_alignment = ('credit' => 'right', 'debit' => 'right');
  296. my $format = uc substr($form->{action}, 0, 3);
  297. my $template = LedgerSMB::Template->new(
  298. user => \%myconfig,
  299. locale => $locale,
  300. path => 'UI',
  301. template => 'form-dynatable',
  302. format => ($format ne 'LIS')? $format: 'HTML');
  303. $template->render({
  304. form => $form,
  305. buttons => \@buttons,
  306. hiddens => \%hiddens,
  307. columns => \@column_index,
  308. heading => \%column_header,
  309. rows => \@rows,
  310. row_alignment => \%row_alignment,
  311. });
  312. }
  313. sub csv_list_account { &list_account }
  314. sub xls_list_account { &list_account }
  315. sub ods_list_account { &list_account }
  316. sub delete_account {
  317. $form->{title} = $locale->text('Delete Account');
  318. foreach $id (
  319. qw(inventory_accno_id income_accno_id expense_accno_id fxgain_accno_id fxloss_accno_id)
  320. )
  321. {
  322. if ( $form->{id} == $form->{$id} ) {
  323. $form->error( $locale->text('Cannot delete default account!') );
  324. }
  325. }
  326. if ( AM->delete_account( \%myconfig, \%$form ) ) {
  327. $form->redirect( $locale->text('Account deleted!') );
  328. }
  329. else {
  330. $form->error( $locale->text('Cannot delete account!') );
  331. }
  332. }
  333. sub list_gifi {
  334. @{ $form->{fields} } = qw(accno description);
  335. $form->{table} = "gifi";
  336. AM->gifi_accounts( \%myconfig, \%$form );
  337. $form->{title} = $locale->text('GIFI');
  338. my %hiddens;
  339. # construct callback
  340. my $callback =
  341. "$form->{script}?action=list_gifi&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  342. $form->{callback} = $callback;
  343. $hiddens{callback} = $callback;
  344. $hiddens{action} = 'list_gifi';
  345. $hiddens{path} = $form->{path};
  346. $hiddens{login} = $form->{login};
  347. $hiddens{sessionid} = $form->{sessionid};
  348. my @column_index = qw(accno description);
  349. my %column_header;
  350. my @rows;
  351. $column_header{accno} = $locale->text('GIFI');
  352. $column_header{description} = $locale->text('Description');
  353. my $i = 0;
  354. foreach $ca ( @{ $form->{ALL} } ) {
  355. my %column_data;
  356. $i++;
  357. $i %= 2;
  358. $column_data{i} = $i;
  359. $accno = $form->escape( $ca->{accno} );
  360. $column_data{accno} = {text => $ca->{accno}, href =>
  361. qq|$form->{script}?action=edit_gifi&coa=1&accno=$accno&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback|};
  362. $column_data{description} = $ca->{description};
  363. push @rows, \%column_data;
  364. }
  365. my @buttons;
  366. push @buttons, {
  367. name => 'action',
  368. value => 'csv_list_gifi',
  369. text => $locale->text('CSV Report'),
  370. type => 'submit',
  371. class => 'submit',
  372. };
  373. my $template = LedgerSMB::Template->new(
  374. user => \%myconfig,
  375. locale => $locale,
  376. path => 'UI',
  377. template => 'form-dynatable',
  378. format => ($form->{action} =~ /^csv/)? 'CSV': 'HTML');
  379. $template->render({
  380. form => \%$form,
  381. hiddens => \%hiddens,
  382. buttons => \@buttons,
  383. columns => \@column_index,
  384. heading => \%column_header,
  385. rows => \@rows,
  386. });
  387. }
  388. sub csv_list_gifi { &list_gifi }
  389. sub add_gifi {
  390. $form->{title} = "Add";
  391. # construct callback
  392. $form->{callback} =
  393. "$form->{script}?action=list_gifi&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  394. $form->{coa} = 1;
  395. my %hiddens;
  396. my @buttons;
  397. &gifi_header(\%hiddens);
  398. &gifi_footer(\%hiddens, \@buttons);
  399. my $template = LedgerSMB::Template->new_UI(
  400. user => \%myconfig,
  401. locale => $locale,
  402. template => 'am-gifi-form');
  403. $template->render({
  404. form => $form,
  405. buttons => \@buttons,
  406. hiddens => \%hiddens,
  407. });
  408. }
  409. sub edit_gifi {
  410. $form->{title} = "Edit";
  411. AM->get_gifi( \%myconfig, \%$form );
  412. $form->error( $locale->text('Account does not exist!') )
  413. unless $form->{accno};
  414. my %hiddens;
  415. my @buttons;
  416. &gifi_header(\%hiddens);
  417. &gifi_footer(\%hiddens, \@buttons);
  418. my $template = LedgerSMB::Template->new_UI(
  419. user => \%myconfig,
  420. locale => $locale,
  421. template => 'am-gifi-form');
  422. $template->render({
  423. form => $form,
  424. buttons => \@buttons,
  425. hiddens => \%hiddens,
  426. });
  427. }
  428. sub gifi_header {
  429. my $hiddens = shift;
  430. $form->{title} = $locale->text("$form->{title} GIFI");
  431. # $locale->text('Add GIFI')
  432. # $locale->text('Edit GIFI')
  433. for (qw(accno description)) { $form->{$_} = $form->quote( $form->{$_} ) }
  434. $hiddens->{id} = $form->{accno};
  435. $hiddens->{type} = 'gifi';
  436. }
  437. sub gifi_footer {
  438. my ($hiddens, $buttons) = @_;
  439. $hiddens->{$_} = $form->{$_} foreach qw(callback path login sessionid);
  440. # type=submit $locale->text('Save')
  441. # type=submit $locale->text('Copy to COA')
  442. # type=submit $locale->text('Delete')
  443. my %button = ();
  444. $button{'save'} = { ndx => 3, key => 'S', value => $locale->text('Save') };
  445. if ( $form->{accno} ) {
  446. if ( $form->{orphaned} ) {
  447. $button{'delete'} =
  448. { ndx => 16, key => 'D', value => $locale->text('Delete') };
  449. }
  450. }
  451. if ( $form->{coa} ) {
  452. $button{'copy_to_coa'} =
  453. { ndx => 7, key => 'C', value => $locale->text('Copy to COA') };
  454. }
  455. for ( sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button ) {
  456. push @{$buttons}, {
  457. name => 'action',
  458. value => $_,
  459. accesskey => $button{$_}{key},
  460. title => "$button{$_}{value} [Alt-$button{$_}{key}]",
  461. text => $button{$_}{value},
  462. };
  463. }
  464. ##SC: Temporary commenting
  465. ## if ( $form->{lynx} ) {
  466. ## require "bin/menu.pl";
  467. ## &menubar;
  468. ## }
  469. }
  470. sub save_gifi {
  471. $form->isblank( "accno", $locale->text('GIFI missing!') );
  472. AM->save_gifi( \%myconfig, \%$form );
  473. $form->redirect( $locale->text('GIFI saved!') );
  474. }
  475. sub copy_to_coa {
  476. $form->isblank( "accno", $locale->text('GIFI missing!') );
  477. AM->save_gifi( \%myconfig, \%$form );
  478. delete $form->{id};
  479. $form->{gifi_accno} = $form->{accno};
  480. $form->{title} = "Add";
  481. $form->{charttype} = "A";
  482. my %hiddens;
  483. my @buttons;
  484. my $checked = &account_header(\%hiddens);
  485. &form_footer_buttons(\%hiddens, \@buttons);
  486. my $template = LedgerSMB::Template->new_UI(
  487. user => \%myconfig,
  488. locale => $locale,
  489. template => 'am-account-form');
  490. $template->render({
  491. form => $form,
  492. checked => $checked,
  493. buttons => \@buttons,
  494. hiddens => \%hiddens,
  495. });
  496. }
  497. sub delete_gifi {
  498. AM->delete_gifi( \%myconfig, \%$form );
  499. $form->redirect( $locale->text('GIFI deleted!') );
  500. }
  501. sub add_department {
  502. $form->{title} = "Add";
  503. $form->{role} = "P";
  504. $form->{callback} =
  505. "$form->{script}?action=add_department&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"
  506. unless $form->{callback};
  507. my %hiddens;
  508. my @buttons;
  509. my $rows = &department_header(\%hiddens);
  510. &form_footer_buttons(\%hiddens, \@buttons);
  511. my $template = LedgerSMB::Template->new_UI(
  512. user => \%myconfig,
  513. locale => $locale,
  514. template => 'am-department-form');
  515. $template->render({
  516. form => $form,
  517. row_count => $rows,
  518. buttons => \@buttons,
  519. hiddens => \%hiddens,
  520. });
  521. }
  522. sub edit_department {
  523. $form->{title} = "Edit";
  524. AM->get_department( \%myconfig, \%$form );
  525. my %hiddens;
  526. my @buttons;
  527. my $rows = &department_header(\%hiddens);
  528. &form_footer_buttons(\%hiddens, \@buttons);
  529. my $template = LedgerSMB::Template->new_UI(
  530. user => \%myconfig,
  531. locale => $locale,
  532. template => 'am-department-form');
  533. $template->render({
  534. form => $form,
  535. row_count => $rows,
  536. buttons => \@buttons,
  537. hiddens => \%hiddens,
  538. });
  539. }
  540. sub list_department {
  541. AM->departments( \%myconfig, \%$form );
  542. my $href =
  543. "$form->{script}?action=list_department&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  544. $form->sort_order();
  545. $form->{callback} =
  546. "$form->{script}?action=list_department&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  547. my $callback = $form->escape( $form->{callback} );
  548. $form->{title} = $locale->text('Departments');
  549. my @column_index = qw(description cost profit);
  550. my %column_header;
  551. $column_header{description} = { text => $locale->text('Description'),
  552. href => $href};
  553. $column_header{cost} = $locale->text('Cost Center');
  554. $column_header{profit} = $locale->text('Profit Center');
  555. my @rows;
  556. my $i = 0;
  557. foreach my $ref ( @{ $form->{ALL} } ) {
  558. my %column_data;
  559. $i++;
  560. $i %= 2;
  561. $column_data{i} = $i;
  562. $column_data{cost} = ( $ref->{role} eq "C" ) ? "*" : " ";
  563. $column_data{profit} = ( $ref->{role} eq "P" ) ? "*" : " ";
  564. $column_data{description} = { text => $ref->{description},
  565. href => qq|$form->{script}?action=edit_department&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback|,};
  566. push @rows, \%column_data;
  567. }
  568. $form->{type} = "department";
  569. my @hiddens = qw(type callback path login sessionid);
  570. ## SC: removing this for now
  571. #if ( $form->{lynx} ) {
  572. # require "bin/menu.pl";
  573. # &menubar;
  574. #}
  575. my @buttons;
  576. push @buttons, {
  577. name => 'action',
  578. value => 'add_department',
  579. text => $locale->text('Add Department'),
  580. type => 'submit',
  581. class => 'submit',
  582. };
  583. my $template = LedgerSMB::Template->new_UI(
  584. user => \%myconfig,
  585. locale => $locale,
  586. template => 'am-list-departments');
  587. $template->render({
  588. form => $form,
  589. buttons => \@buttons,
  590. columns => \@column_index,
  591. heading => \%column_header,
  592. rows => \@rows,
  593. hiddens => \@hiddens,
  594. });
  595. }
  596. sub department_header {
  597. my $hiddens = shift;
  598. $form->{title} = $locale->text("$form->{title} Department");
  599. # $locale->text('Add Department')
  600. # $locale->text('Edit Department')
  601. $form->{description} = $form->quote( $form->{description} );
  602. my $rows = $form->numtextrows( $form->{description}, 60 );
  603. $hiddens->{id} = $form->{id};
  604. $hiddens->{type} = 'department';
  605. $rows;
  606. }
  607. sub save_department {
  608. $form->isblank( "description", $locale->text('Description missing!') );
  609. AM->save_department( \%myconfig, \%$form );
  610. $form->redirect( $locale->text('Department saved!') );
  611. }
  612. sub delete_department {
  613. AM->delete_department( \%myconfig, \%$form );
  614. $form->redirect( $locale->text('Department deleted!') );
  615. }
  616. sub add_business {
  617. $form->{title} = "Add";
  618. $form->{callback} =
  619. "$form->{script}?action=add_business&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"
  620. unless $form->{callback};
  621. my %hiddens;
  622. my @buttons;
  623. my $checked = &business_header(\%hiddens);
  624. &form_footer_buttons(\%hiddens, \@buttons);
  625. my $template = LedgerSMB::Template->new_UI(
  626. user => \%myconfig,
  627. locale => $locale,
  628. template => 'am-business-form');
  629. $template->render({
  630. form => $form,
  631. buttons => \@buttons,
  632. hiddens => \%hiddens,
  633. });
  634. }
  635. sub edit_business {
  636. $form->{title} = "Edit";
  637. AM->get_business( \%myconfig, \%$form );
  638. $form->{orphaned} = 1;
  639. my %hiddens;
  640. my @buttons;
  641. my $checked = &business_header(\%hiddens);
  642. &form_footer_buttons(\%hiddens, \@buttons);
  643. my $template = LedgerSMB::Template->new_UI(
  644. user => \%myconfig,
  645. locale => $locale,
  646. template => 'am-business-form');
  647. $template->render({
  648. form => $form,
  649. buttons => \@buttons,
  650. hiddens => \%hiddens,
  651. });
  652. }
  653. sub list_business {
  654. AM->business( \%myconfig, \%$form );
  655. my $href =
  656. "$form->{script}?action=list_business&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  657. $form->sort_order();
  658. $form->{callback} =
  659. "$form->{script}?action=list_business&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  660. my $callback = $form->escape( $form->{callback} );
  661. $form->{title} = $locale->text('Type of Business');
  662. my @column_index = qw(description discount);
  663. my %column_header;
  664. $column_header{description} = { text => $locale->text('Description'),
  665. href => $href };
  666. $column_header{discount} = $locale->text('Discount %');
  667. my @rows;
  668. $i = 0;
  669. foreach my $ref ( @{ $form->{ALL} } ) {
  670. my %column_data;
  671. $i++;
  672. $i %= 2;
  673. $column_data{i} = $i;
  674. $column_data{discount} =
  675. $form->format_amount( \%myconfig, $ref->{discount} * 100, 2, " " );
  676. $column_data{description} = { text => $ref->{description}, href =>
  677. qq|$form->{script}?action=edit_business&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback|};
  678. push @rows, \%column_data;
  679. }
  680. $form->{type} = "business";
  681. my @hiddens = qw(type callback path login sessionid);
  682. ## SC: Temporary removal
  683. ## if ( $form->{lynx} ) {
  684. ## require "bin/menu.pl";
  685. ## &menubar;
  686. ## }
  687. my @buttons;
  688. push @buttons, {
  689. name => 'action',
  690. value => 'add_business',
  691. text => $locale->text('Add Business'),
  692. type => 'submit',
  693. class => 'submit',
  694. };
  695. my $template = LedgerSMB::Template->new_UI(
  696. user => \%myconfig,
  697. locale => $locale,
  698. template => 'am-list-departments');
  699. $template->render({
  700. form => $form,
  701. buttons => \@buttons,
  702. columns => \@column_index,
  703. heading => \%column_header,
  704. rows => \@rows,
  705. hiddens => \@hiddens,
  706. });
  707. }
  708. sub business_header {
  709. my $hiddens = shift;
  710. $form->{title} = $locale->text("$form->{title} Business");
  711. # $locale->text('Add Business')
  712. # $locale->text('Edit Business')
  713. $form->{description} = $form->quote( $form->{description} );
  714. $form->{discount} =
  715. $form->format_amount( \%myconfig, $form->{discount} * 100 );
  716. $hiddens->{id} = $form->{id};
  717. $hiddens->{type} = 'business';
  718. }
  719. sub save_business {
  720. $form->isblank( "description", $locale->text('Description missing!') );
  721. AM->save_business( \%myconfig, \%$form );
  722. $form->redirect( $locale->text('Business saved!') );
  723. }
  724. sub delete_business {
  725. AM->delete_business( \%myconfig, \%$form );
  726. $form->redirect( $locale->text('Business deleted!') );
  727. }
  728. sub add_sic {
  729. $form->{title} = "Add";
  730. $form->{callback} =
  731. "$form->{script}?action=add_sic&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"
  732. unless $form->{callback};
  733. my %hiddens;
  734. my @buttons;
  735. my $checked = &sic_header(\%hiddens);
  736. &form_footer_buttons(\%hiddens, \@buttons);
  737. my $template = LedgerSMB::Template->new_UI(
  738. user => \%myconfig,
  739. locale => $locale,
  740. template => 'am-sic-form');
  741. $template->render({
  742. form => $form,
  743. heading => $checked,
  744. buttons => \@buttons,
  745. hiddens => \%hiddens,
  746. });
  747. }
  748. sub edit_sic {
  749. $form->{title} = "Edit";
  750. $form->{code} =~ s/\\'/'/g;
  751. $form->{code} =~ s/\\\\/\\/g;
  752. AM->get_sic( \%myconfig, \%$form );
  753. $form->{id} = $form->{code};
  754. $form->{orphaned} = 1;
  755. my %hiddens;
  756. my @buttons;
  757. my $checked = &sic_header(\%hiddens);
  758. &form_footer_buttons(\%hiddens, \@buttons);
  759. my $template = LedgerSMB::Template->new_UI(
  760. user => \%myconfig,
  761. locale => $locale,
  762. template => 'am-sic-form');
  763. $template->render({
  764. form => $form,
  765. heading => $checked,
  766. buttons => \@buttons,
  767. hiddens => \%hiddens,
  768. });
  769. }
  770. sub list_sic {
  771. AM->sic( \%myconfig, \%$form );
  772. my $href =
  773. "$form->{script}?action=list_sic&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  774. $form->sort_order();
  775. $form->{callback} =
  776. "$form->{script}?action=list_sic&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  777. my $callback = $form->escape( $form->{callback} );
  778. $form->{title} = $locale->text('Standard Industrial Codes');
  779. my @column_index = $form->sort_columns(qw(code description));
  780. my %column_header;
  781. $column_header{code} = {
  782. href => "$href&sort=code",
  783. text => $locale->text('Code'),
  784. };
  785. $column_header{description} = {
  786. href => "$href&sort=description",
  787. text => $locale->text('Description'),
  788. };
  789. my @rows;
  790. my $i = 0;
  791. foreach $ref ( @{ $form->{ALL} } ) {
  792. my %column_data;
  793. $i++;
  794. $i %= 2;
  795. if ( $ref->{sictype} eq 'H' ) {
  796. $column_data{class} = 'heading';
  797. }
  798. $column_data{i} = $i;
  799. $column_data{code} = {
  800. text => $ref->{code},
  801. href => "$form->{script}?action=edit_sic&code=$ref->{code}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback",
  802. };
  803. $column_data{description} = $ref->{description};
  804. push @rows, \%column_data;
  805. }
  806. $form->{type} = "sic";
  807. my @hiddens = qw(type callback path login sessionid);
  808. ##SC: Temporary removal
  809. ## if ( $form->{lynx} ) {
  810. ## require "bin/menu.pl";
  811. ## &menubar;
  812. ## }
  813. my @buttons;
  814. push @buttons, {
  815. name => 'action',
  816. value => 'add_sic',
  817. text => $locale->text('Add SIC'),
  818. type => 'submit',
  819. class => 'submit',
  820. };
  821. my $template = LedgerSMB::Template->new_UI(
  822. user => \%myconfig,
  823. locale => $locale,
  824. template => 'am-list-departments');
  825. $template->render({
  826. form => $form,
  827. buttons => \@buttons,
  828. columns => \@column_index,
  829. heading => \%column_header,
  830. rows => \@rows,
  831. hiddens => \@hiddens,
  832. });
  833. }
  834. sub sic_header {
  835. my $hiddens = shift;
  836. $form->{title} = $locale->text("$form->{title} SIC");
  837. # $locale->text('Add SIC')
  838. # $locale->text('Edit SIC')
  839. for (qw(code description)) { $form->{$_} = $form->quote( $form->{$_} ) }
  840. $checked = ( $form->{sictype} eq 'H' ) ? "checked" : "";
  841. $hiddens->{type} = 'sic';
  842. $hiddens->{id} = $form->{code};
  843. $checked;
  844. }
  845. sub save_sic {
  846. $form->isblank( "code", $locale->text('Code missing!') );
  847. $form->isblank( "description", $locale->text('Description missing!') );
  848. AM->save_sic( \%myconfig, \%$form );
  849. $form->redirect( $locale->text('SIC saved!') );
  850. }
  851. sub delete_sic {
  852. AM->delete_sic( \%myconfig, \%$form );
  853. $form->redirect( $locale->text('SIC deleted!') );
  854. }
  855. sub add_language {
  856. $form->{title} = "Add";
  857. $form->{callback} =
  858. "$form->{script}?action=add_language&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"
  859. unless $form->{callback};
  860. my %hiddens;
  861. my @buttons;
  862. &language_header(\%hiddens);
  863. &form_footer_buttons(\%hiddens, \@buttons);
  864. my $template = LedgerSMB::Template->new_UI(
  865. user => \%myconfig,
  866. locale => $locale,
  867. template => 'am-language-form');
  868. $template->render({
  869. form => $form,
  870. buttons => \@buttons,
  871. hiddens => \%hiddens,
  872. });
  873. }
  874. sub edit_language {
  875. $form->{title} = "Edit";
  876. $form->{code} =~ s/\\'/'/g;
  877. $form->{code} =~ s/\\\\/\\/g;
  878. AM->get_language( \%myconfig, \%$form );
  879. $form->{id} = $form->{code};
  880. $form->{orphaned} = 1;
  881. my %hiddens;
  882. my @buttons;
  883. &language_header(\%hiddens);
  884. &form_footer_buttons(\%hiddens, \@buttons);
  885. my $template = LedgerSMB::Template->new_UI(
  886. user => \%myconfig,
  887. locale => $locale,
  888. template => 'am-language-form');
  889. $template->render({
  890. form => $form,
  891. buttons => \@buttons,
  892. hiddens => \%hiddens,
  893. });
  894. }
  895. sub list_language {
  896. AM->language( \%myconfig, \%$form );
  897. $href =
  898. "$form->{script}?action=list_language&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  899. $form->sort_order();
  900. $form->{callback} =
  901. "$form->{script}?action=list_language&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  902. my $callback = $form->escape( $form->{callback} );
  903. $form->{title} = $locale->text('Languages');
  904. my @column_index = $form->sort_columns(qw(code description));
  905. my %column_header;
  906. $column_header{code} = { text => $locale->text('Code'),
  907. href => "$href&sort=code" };
  908. $column_header{description} = { text => $locale->text('Description'),
  909. href => "$href&sort=description" };
  910. my @rows;
  911. my $i = 0;
  912. foreach my $ref ( @{ $form->{ALL} } ) {
  913. my %column_data;
  914. $i++;
  915. $i %= 2;
  916. $column_data{i} = $i;
  917. $column_data{code} = {text => $ref->{code}, href =>
  918. qq|$form->{script}?action=edit_language&code=$ref->{code}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback|};
  919. $column_data{description} = $ref->{description};
  920. push @rows, \%column_data;
  921. }
  922. $form->{type} = "language";
  923. my @hiddens = qw(type callback path login sessionid);
  924. ## SC: Temporary removal
  925. ## if ( $form->{lynx} ) {
  926. ## require "bin/menu.pl";
  927. ## &menubar;
  928. ## }
  929. my @buttons;
  930. push @buttons, {
  931. name => 'action',
  932. value => 'add_language',
  933. text => $locale->text('Add Lanugage'),
  934. type => 'submit',
  935. class => 'submit',
  936. };
  937. # SC: I'm not concerned about the wider description as code is 6 chars max
  938. my $template = LedgerSMB::Template->new_UI(
  939. user => \%myconfig,
  940. locale => $locale,
  941. template => 'am-list-departments');
  942. $template->render({
  943. form => $form,
  944. buttons => \@buttons,
  945. columns => \@column_index,
  946. heading => \%column_header,
  947. rows => \@rows,
  948. hiddens => \@hiddens,
  949. });
  950. }
  951. sub language_header {
  952. my $hiddens = shift;
  953. $form->{title} = $locale->text("$form->{title} Language");
  954. # $locale->text('Add Language')
  955. # $locale->text('Edit Language')
  956. for (qw(code description)) { $form->{$_} = $form->quote( $form->{$_} ) }
  957. $hiddens->{type} = 'language';
  958. $hiddens->{id} = $form->{code};
  959. }
  960. sub save_language {
  961. $form->isblank( "code", $locale->text('Code missing!') );
  962. $form->isblank( "description", $locale->text('Description missing!') );
  963. $form->{code} =~ s/(\.\.|\*)//g;
  964. AM->save_language( \%myconfig, \%$form );
  965. if ( !-d "$myconfig{templates}/$form->{code}" ) {
  966. umask(002);
  967. if ( mkdir "$myconfig{templates}/$form->{code}", oct("771") ) {
  968. umask(007);
  969. opendir TEMPLATEDIR, "$myconfig{templates}"
  970. or $form->error("$myconfig{templates} : $!");
  971. @templates = grep !/^(\.|\.\.)/, readdir TEMPLATEDIR;
  972. closedir TEMPLATEDIR;
  973. foreach $file (@templates) {
  974. if ( -f "$myconfig{templates}/$file" ) {
  975. open( TEMP, '<', "$myconfig{templates}/$file" )
  976. or $form->error("$myconfig{templates}/$file : $!");
  977. open( NEW, '>', "$myconfig{templates}/$form->{code}/$file" )
  978. or $form->error(
  979. "$myconfig{templates}/$form->{code}/$file : $!");
  980. while ( $line = <TEMP> ) {
  981. print NEW $line;
  982. }
  983. close(TEMP);
  984. close(NEW);
  985. }
  986. }
  987. }
  988. else {
  989. $form->error("${templates}/$form->{code} : $!");
  990. }
  991. }
  992. $form->redirect( $locale->text('Language saved!') );
  993. }
  994. sub delete_language {
  995. $form->{title} = $locale->text('Confirm!');
  996. for (qw(action nextsub)) { delete $form->{$_} }
  997. my %hiddens;
  998. $hiddens{$_} = $form->{$_} foreach keys %$form;
  999. my @buttons = ({
  1000. name => 'action',
  1001. value => 'yes_delete_language',
  1002. text => $locale->text('Delete Language'),
  1003. });
  1004. my $template = LedgerSMB::Template->new_UI(
  1005. user => \%myconfig,
  1006. locale => $locale,
  1007. template => 'form-confirmation');
  1008. $template->render({
  1009. form => $form,
  1010. buttons => \@buttons,
  1011. hiddens => \%hiddens,
  1012. query => $locale->text(
  1013. 'Deleting a language will also delete the templates for the language [_1]',
  1014. $form->{id}),
  1015. });
  1016. }
  1017. sub yes_delete_language {
  1018. AM->delete_language( \%myconfig, \%$form );
  1019. # delete templates
  1020. $dir = "$myconfig{templates}/$form->{code}";
  1021. if ( -d $dir ) {
  1022. unlink <$dir/*>;
  1023. rmdir "$myconfig{templates}/$form->{code}";
  1024. }
  1025. $form->redirect( $locale->text('Language deleted!') );
  1026. }
  1027. sub display_stylesheet {
  1028. $form->{file} = "css/$myconfig{stylesheet}";
  1029. &display_form;
  1030. }
  1031. sub list_templates {
  1032. AM->language( \%myconfig, \%$form );
  1033. if ( !@{ $form->{ALL} } ) {
  1034. &display_form;
  1035. exit;
  1036. }
  1037. unshift @{ $form->{ALL} },
  1038. { code => '.', description => $locale->text('Default Template') };
  1039. my $href =
  1040. "$form->{script}?action=list_templates&direction=$form->{direction}&oldsort=$form->{oldsort}&file=$form->{file}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  1041. $form->sort_order();
  1042. $form->{callback} =
  1043. "$form->{script}?action=list_templates&direction=$form->{direction}&oldsort=$form->{oldsort}&file=$form->{file}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  1044. my $callback = $form->escape( $form->{callback} );
  1045. chomp $myconfig{templates};
  1046. $form->{file} =~ s/$myconfig{templates}//;
  1047. $form->{file} =~ s/\///;
  1048. $form->{title} = "$form->{format}: $form->{template}";
  1049. my @column_index = $form->sort_columns(qw(code description));
  1050. $column_header{code} = { text => $locale->text('Code'),
  1051. href => "$href&sort=code" };
  1052. $column_header{description} = { text => $locale->text('Description'),
  1053. href => "$href&sort=description" };
  1054. my @rows;
  1055. my $i = 0;
  1056. foreach my $ref ( @{ $form->{ALL} } ) {
  1057. my %column_data;
  1058. $i++;
  1059. $i %= 2;
  1060. $column_data{i} = $i;
  1061. $column_data{code} = { text => $ref->{code}, href =>
  1062. qq|$form->{script}?action=display_form&file=$myconfig{templates}/$ref->{code}/$form->{file}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&code=$ref->{code}&callback=$callback|};
  1063. $column_data{description} = $ref->{description};
  1064. push @rows, \%column_data;
  1065. }
  1066. $form->{type} = 'language';
  1067. my @hiddens = qw(sessionid login path calllback type);
  1068. ## SC: Temporary removal
  1069. ## if ( $form->{lynx} ) {
  1070. ## require "bin/menu.pl";
  1071. ## &menubar;
  1072. ## }
  1073. # SC: I'm not concerned about the wider description as code is 6 chars max
  1074. my $template = LedgerSMB::Template->new_UI(
  1075. user => \%myconfig,
  1076. locale => $locale,
  1077. template => 'am-list-departments');
  1078. $template->render({
  1079. form => $form,
  1080. columns => \@column_index,
  1081. heading => \%column_header,
  1082. rows => \@rows,
  1083. hiddens => \@hiddens,
  1084. });
  1085. }
  1086. sub display_form {
  1087. AM->load_template( \%myconfig, \%$form );
  1088. $form->{title} = $form->{file};
  1089. $form->{body} =~
  1090. s/<%include (.*?)%>/<a href=$form->{script}\?action=display_form&file=$myconfig{templates}\/$form->{code}\/$1&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}>$1<\/a>/g;
  1091. # if it is anything but html
  1092. if ( $form->{file} !~ /\.html$/ ) {
  1093. $form->{body} = "<pre>\n$form->{body}\n</pre>";
  1094. }
  1095. $form->header;
  1096. print qq|
  1097. <body>
  1098. $form->{body}
  1099. <form method=post action=$form->{script}>
  1100. |;
  1101. $form->{type} = "template";
  1102. $form->hide_form(qw(file type path login sessionid));
  1103. print qq|
  1104. <button name="action" type="submit" class="submit" value="edit">|
  1105. . $locale->text('Edit')
  1106. . qq|</button>|;
  1107. if ( $form->{lynx} ) {
  1108. require "bin/menu.pl";
  1109. &menubar;
  1110. }
  1111. print qq|
  1112. </form>
  1113. </body>
  1114. </html>
  1115. |;
  1116. }
  1117. sub edit_template {
  1118. AM->load_template( \%myconfig, \%$form );
  1119. $form->{title} = $locale->text('Edit Template');
  1120. # convert &nbsp to &amp;nbsp;
  1121. $form->{body} =~ s/&nbsp;/&amp;nbsp;/gi;
  1122. $form->header;
  1123. print qq|
  1124. <body>
  1125. <form method=post action=$form->{script}>
  1126. <input name=file type=hidden value=$form->{file}>
  1127. <input name=type type=hidden value=template>
  1128. <input type=hidden name=path value=$form->{path}>
  1129. <input type=hidden name=login value=$form->{login}>
  1130. <input type=hidden name=sessionid value=$form->{sessionid}>
  1131. <input name=callback type=hidden value="$form->{script}?action=display_form&file=$form->{file}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}">
  1132. <textarea name=body rows=25 cols=70>
  1133. $form->{body}
  1134. </textarea>
  1135. <br>
  1136. <button type="submit" class="submit" name="action" value="save">|
  1137. . $locale->text('Save')
  1138. . qq|</button>|;
  1139. if ( $form->{lynx} ) {
  1140. require "bin/menu.pl";
  1141. &menubar;
  1142. }
  1143. print q|
  1144. </form>
  1145. </body>
  1146. </html>
  1147. |;
  1148. }
  1149. sub save_template {
  1150. AM->save_template( \%myconfig, \%$form );
  1151. $form->redirect( $locale->text('Template saved!') );
  1152. }
  1153. sub defaults {
  1154. # get defaults for account numbers and last numbers
  1155. AM->get_all_defaults( \%$form );
  1156. my %selects = (
  1157. 'FX_loss' => {name => 'FX_loss', options => []},
  1158. 'FX_gain' => {name => 'FX_gain', options => []},
  1159. 'IC_expense' => {name => 'IC_expense', options => []},
  1160. 'IC_income' => {name => 'IC_income', options => []},
  1161. 'IC_inventory' => {name => 'IC_inventory', options => []},
  1162. 'IC' => {name => 'IC', options => []},
  1163. );
  1164. foreach $key ( keys %{ $form->{accno} } ) {
  1165. foreach $accno ( sort keys %{ $form->{accno}{$key} } ) {
  1166. push @{$selects{$key}{options}}, {
  1167. text => "$accno--$form->{accno}{$key}{$accno}{description}",
  1168. value => "$accno--$form->{accno}{$key}{$accno}{description}",
  1169. };
  1170. $selects{$key}{default_values} = "$accno--$form->{accno}{$key}{$accno}{description}" if
  1171. ($form->{defaults}{$key} == $form->{accno}{$key}{$accno}{id});
  1172. }
  1173. }
  1174. for (qw(accno defaults)) { delete $form->{$_} }
  1175. ##SC: temporary commenting out
  1176. ## if ( $form->{lynx} ) {
  1177. ## require "bin/menu.pl";
  1178. ## &menubar;
  1179. ## }
  1180. my %hiddens = (
  1181. path => $form->{path},
  1182. login => $form->{login},
  1183. sessionid => $form->{sessionid},
  1184. type => 'defaults',
  1185. );
  1186. my $template = LedgerSMB::Template->new_UI(
  1187. user => \%myconfig,
  1188. locale => $locale,
  1189. template => 'am-defaults');
  1190. $template->render({
  1191. form => $form,
  1192. hiddens => \%hiddens,
  1193. selects => \%selects,
  1194. });
  1195. }
  1196. sub taxes {
  1197. # get tax account numbers
  1198. AM->taxes( \%myconfig, \%$form );
  1199. $i = 0;
  1200. foreach $ref ( @{ $form->{taxrates} } ) {
  1201. $i++;
  1202. $form->{"taxrate_$i"} =
  1203. $form->format_amount( \%myconfig, $ref->{rate} );
  1204. $form->{"taxdescription_$i"} = $ref->{description};
  1205. for (qw(taxnumber validto pass taxmodulename)) {
  1206. $form->{"${_}_$i"} = $ref->{$_};
  1207. }
  1208. $form->{taxaccounts} .= "$ref->{id}_$i ";
  1209. }
  1210. chop $form->{taxaccounts};
  1211. &display_taxes;
  1212. }
  1213. sub display_taxes {
  1214. $form->{title} = $locale->text('Taxes');
  1215. my %hiddens = (
  1216. path => $form->{path},
  1217. login => $form->{login},
  1218. sessionid => $form->{sessionid},
  1219. type => 'taxes',
  1220. );
  1221. my @rows;
  1222. for ( split( / /, $form->{taxaccounts} ) ) {
  1223. ( $null, $i ) = split /_/, $_;
  1224. $form->{"taxrate_$i"} =
  1225. $form->format_amount( \%myconfig, $form->{"taxrate_$i"} );
  1226. $hiddens{"taxdescription_$i"} = $form->{"taxdescription_$i"};
  1227. my %select = (name => "taxmodule_id_$i", options => []);
  1228. foreach my $taxmodule ( sort keys %$form ) {
  1229. next if ( $taxmodule !~ /^taxmodule_/ );
  1230. next if ( $taxmodule =~ /^taxmodule_id_/ );
  1231. my $modulenum = $taxmodule;
  1232. $modulenum =~ s/^taxmodule_//;
  1233. push @{$select{options}},
  1234. {text => $form->{$taxmodule}, value => $modulenum};
  1235. $select{default_values} = $modulenum
  1236. if $form->{$taxmodule} eq $form->{"taxmodulename_$i"};
  1237. }
  1238. if ( $form->{"taxdescription_$i"} eq $sametax ) {
  1239. push @rows, ["", \%select];
  1240. } else {
  1241. push @rows, [$form->{"taxdescription_$i"}, \%select];
  1242. }
  1243. $sametax = $form->{"taxdescription_$i"};
  1244. }
  1245. $hiddens{taxaccounts} = $form->{taxaccounts};
  1246. foreach my $taxmodule ( sort keys %$form ) {
  1247. next if ( $taxmodule !~ /^taxmodule_/ );
  1248. next if ( $taxmodule =~ /^taxmodule_id_/ );
  1249. $hiddens{$taxmodule};
  1250. }
  1251. ##SC: Temporary removal
  1252. ## if ( $form->{lynx} ) {
  1253. ## require "bin/menu.pl";
  1254. ## &menubar;
  1255. ## }
  1256. my $template = LedgerSMB::Template->new_UI(
  1257. user => \%myconfig,
  1258. locale => $locale,
  1259. template => 'am-taxes');
  1260. $template->render({
  1261. form => $form,
  1262. hiddens => \%hiddens,
  1263. selects => \%selects,
  1264. rows => \@rows,
  1265. });
  1266. }
  1267. sub update {
  1268. @a = split / /, $form->{taxaccounts};
  1269. $ndx = $#a + 1;
  1270. foreach $item (@a) {
  1271. ( $accno, $i ) = split /_/, $item;
  1272. push @t, $accno;
  1273. $form->{"taxmodulename_$i"} =
  1274. $form->{ "taxmodule_" . $form->{"taxmodule_id_$i"} };
  1275. if ( $form->{"validto_$i"} ) {
  1276. $j = $i + 1;
  1277. if ( $form->{"taxdescription_$i"} ne $form->{"taxdescription_$j"} )
  1278. {
  1279. #insert line
  1280. for ( $j = $ndx + 1 ; $j > $i ; $j-- ) {
  1281. $k = $j - 1;
  1282. for (qw(taxrate taxdescription taxnumber validto)) {
  1283. $form->{"${_}_$j"} = $form->{"${_}_$k"};
  1284. }
  1285. }
  1286. $ndx++;
  1287. $k = $i + 1;
  1288. for (qw(taxdescription taxnumber)) {
  1289. $form->{"${_}_$k"} = $form->{"${_}_$i"};
  1290. }
  1291. for (qw(taxrate validto)) { $form->{"${_}_$k"} = "" }
  1292. push @t, $accno;
  1293. }
  1294. }
  1295. else {
  1296. # remove line
  1297. $j = $i + 1;
  1298. if ( $form->{"taxdescription_$i"} eq $form->{"taxdescription_$j"} )
  1299. {
  1300. for ( $j = $i + 1 ; $j <= $ndx ; $j++ ) {
  1301. $k = $j + 1;
  1302. for (qw(taxrate taxdescription taxnumber validto)) {
  1303. $form->{"${_}_$j"} = $form->{"${_}_$k"};
  1304. }
  1305. }
  1306. $ndx--;
  1307. splice @t, $i - 1, 1;
  1308. }
  1309. }
  1310. }
  1311. $i = 1;
  1312. $form->{taxaccounts} = "";
  1313. for (@t) {
  1314. $form->{taxaccounts} .= "${_}_$i ";
  1315. $i++;
  1316. }
  1317. chop $form->{taxaccounts};
  1318. &display_taxes;
  1319. }
  1320. sub config {
  1321. my %selects;
  1322. $selects{dateformat} = {
  1323. name => 'dateformat',
  1324. default_values => $myconfig{dateformat},
  1325. options => [],
  1326. };
  1327. foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd))
  1328. {
  1329. push @{$selects{dateformat}{options}}, {text => $item, value => $item};
  1330. }
  1331. $selects{numberformat} = {
  1332. name => 'numberformat',
  1333. default_values => $myconfig{numberformat},
  1334. options => [],
  1335. };
  1336. my @formats = qw(1,000.00 1000.00 1.000,00 1000,00 1'000.00);
  1337. push @formats, '1 000.00';
  1338. foreach $item (@formats) {
  1339. push @{$selects{numberformat}{options}}, {text => $item, value => $item};
  1340. }
  1341. ## for (qw(name company address signature)) {
  1342. ## $myconfig{$_} = $form->quote( $myconfig{$_} );
  1343. ## }
  1344. for (qw(address signature)) { $myconfig{$_} =~ s/\\n/\n/g }
  1345. $selects{countrycode} = {
  1346. name => 'countrycode',
  1347. default_values => ($myconfig{countrycode})? $myconfig{countrycode}: 'en',
  1348. options => [],
  1349. };
  1350. %countrycodes = LedgerSMB::User->country_codes;
  1351. foreach $key ( sort { $countrycodes{$a} cmp $countrycodes{$b} }
  1352. keys %countrycodes )
  1353. {
  1354. push @{$selects{countrycode}{options}}, {
  1355. text => $countrycodes{$key},
  1356. value => $key
  1357. };
  1358. }
  1359. opendir CSS, "css/.";
  1360. @all = grep /.*\.css$/, readdir CSS;
  1361. closedir CSS;
  1362. $selects{stylesheet} = {
  1363. name => 'usestylesheet',
  1364. default_values => $myconfig{stylesheet},
  1365. options => [],
  1366. };
  1367. foreach $item (@all) {
  1368. push @{$selects{stylesheet}{options}}, {text => $item, value => $item};
  1369. }
  1370. push @{$selects{stylesheet}{options}}, {text => 'none', value => '0'};
  1371. if ( %{LedgerSMB::Sysconfig::printer} && ${LedgerSMB::Sysconfig::latex} ) {
  1372. $selects{printer} = {
  1373. name => 'printer',
  1374. default_values => $myconfig{printer},
  1375. options => [],
  1376. };
  1377. foreach $item ( sort keys %{LedgerSMB::Sysconfig::printer} ) {
  1378. push @{$selects{printer}{options}}, {text => $item, value => $item};
  1379. }
  1380. }
  1381. $form->{title} =
  1382. $locale->text( 'Edit Preferences for [_1]', $form->{login} );
  1383. ##SC: Temporary commenting out
  1384. ## if ( $form->{lynx} ) {
  1385. ## require "bin/menu.pl";
  1386. ## &menubar;
  1387. ## }
  1388. my %hiddens = (
  1389. path => $form->{path},
  1390. login => $form->{login},
  1391. sessionid => $form->{sessionid},
  1392. type => 'preferences',
  1393. role => $myconfig{role},
  1394. old_password => $myconfig{password},
  1395. );
  1396. my $template = LedgerSMB::Template->new_UI(
  1397. user => \%myconfig,
  1398. locale => $locale,
  1399. template => 'am-userconfig');
  1400. $template->render({
  1401. form => $form,
  1402. user => \%myconfig,
  1403. hiddens => \%hiddens,
  1404. selects => \%selects,
  1405. });
  1406. }
  1407. sub save_defaults {
  1408. if ( AM->save_defaults( \%myconfig, \%$form ) ) {
  1409. $form->redirect( $locale->text('Defaults saved!') );
  1410. }
  1411. else {
  1412. $form->error( $locale->text('Cannot save defaults!') );
  1413. }
  1414. }
  1415. sub save_taxes {
  1416. if ( AM->save_taxes( \%myconfig, \%$form ) ) {
  1417. $form->redirect( $locale->text('Taxes saved!') );
  1418. }
  1419. else {
  1420. $form->error( $locale->text('Cannot save taxes!') );
  1421. }
  1422. }
  1423. sub save_preferences {
  1424. $form->{stylesheet} = $form->{usestylesheet};
  1425. if ( $form->{new_password} ne $form->{old_password} ) {
  1426. $form->error( $locale->text('Password does not match!') )
  1427. if $form->{new_password} ne $form->{confirm_password};
  1428. }
  1429. if ( AM->save_preferences( \%myconfig, \%$form ) ) {
  1430. $form->info( $locale->text('Preferences saved!') );
  1431. }
  1432. else {
  1433. $form->error( $locale->text('Cannot save preferences!') );
  1434. }
  1435. }
  1436. sub backup {
  1437. if ( $form->{media} eq 'email' ) {
  1438. $form->error(
  1439. $locale->text( 'No email address for [_1]', $myconfig{name} ) )
  1440. unless ( $myconfig{email} );
  1441. }
  1442. $SIG{INT} = 'IGNORE';
  1443. AM->backup(
  1444. \%myconfig, \%$form,
  1445. ${LedgerSMB::Sysconfig::userspath},
  1446. ${LedgerSMB::Sysconfig::gzip}
  1447. );
  1448. if ( $form->{media} eq 'email' ) {
  1449. $form->redirect(
  1450. $locale->text( 'Backup sent to [_1]', $myconfig{email} ) );
  1451. }
  1452. }
  1453. sub audit_control {
  1454. $form->{title} = $locale->text('Audit Control');
  1455. AM->closedto( \%myconfig, \%$form );
  1456. my %checked;
  1457. if ( $form->{revtrans} ) {
  1458. $checked{revtransY} = 'checked';
  1459. } else {
  1460. $checked{revtransN} = 'checked';
  1461. }
  1462. if ( $form->{audittrail} ) {
  1463. $checked{audittrailY} = 'checked';
  1464. } else {
  1465. $checked{audittrailN} = 'checked';
  1466. }
  1467. my %hiddens = (
  1468. path => $form->{path},
  1469. login => $form->{login},
  1470. sessionid => $form->{sessionid},
  1471. );
  1472. my $template = LedgerSMB::Template->new_UI(
  1473. user => \%myconfig,
  1474. locale => $locale,
  1475. template => 'am-audit-control');
  1476. $template->render({
  1477. user => \%myconfig,
  1478. form => $form,
  1479. checked => \%checked,
  1480. hiddens => \%hiddens,
  1481. });
  1482. }
  1483. sub doclose {
  1484. AM->closebooks( \%myconfig, \%$form );
  1485. if ( $form->{revtrans} ) {
  1486. $msg = $locale->text('Transaction reversal enforced for all dates');
  1487. }
  1488. else {
  1489. if ( $form->{closedto} ) {
  1490. $msg =
  1491. $locale->text('Transaction reversal enforced up to [_1]',
  1492. $locale->date( \%myconfig, $form->{closedto}, 1 ));
  1493. }
  1494. else {
  1495. $msg = $locale->text('Books are open');
  1496. }
  1497. }
  1498. $msg .= "<p>";
  1499. if ( $form->{audittrail} ) {
  1500. $msg .= $locale->text('Audit trail enabled');
  1501. }
  1502. else {
  1503. $msg .= $locale->text('Audit trail disabled');
  1504. }
  1505. ##SC: Disabling audit trail deletion
  1506. ## $msg .= "<p>";
  1507. ## if ( $form->{removeaudittrail} ) {
  1508. ## $msg .=
  1509. ## $locale->text('Audit trail removed up to') . " "
  1510. ## . $locale->date( \%myconfig, $form->{removeaudittrail}, 1 );
  1511. ## }
  1512. $form->redirect($msg);
  1513. }
  1514. sub add_warehouse {
  1515. $form->{title} = "Add";
  1516. $form->{callback} =
  1517. "$form->{script}?action=add_warehouse&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"
  1518. unless $form->{callback};
  1519. my %hiddens;
  1520. my @buttons;
  1521. my $rows = &warehouse_header(\%hiddens);
  1522. &form_footer_buttons(\%hiddens, \@buttons);
  1523. my $template = LedgerSMB::Template->new_UI(
  1524. user => \%myconfig,
  1525. locale => $locale,
  1526. template => 'am-warehouse-form');
  1527. $template->render({
  1528. form => $form,
  1529. row_count => $rows,
  1530. buttons => \@buttons,
  1531. hiddens => \%hiddens,
  1532. });
  1533. }
  1534. sub edit_warehouse {
  1535. $form->{title} = "Edit";
  1536. AM->get_warehouse( \%myconfig, \%$form );
  1537. my %hiddens;
  1538. my @buttons;
  1539. my $rows = &warehouse_header(\%hiddens);
  1540. &form_footer_buttons(\%hiddens, \@buttons);
  1541. my $template = LedgerSMB::Template->new_UI(
  1542. user => \%myconfig,
  1543. locale => $locale,
  1544. template => 'am-warehouse-form');
  1545. $template->render({
  1546. form => $form,
  1547. row_count => $rows,
  1548. buttons => \@buttons,
  1549. hiddens => \%hiddens,
  1550. });
  1551. }
  1552. sub list_warehouse {
  1553. AM->warehouses( \%myconfig, \%$form );
  1554. my %hiddens;
  1555. my $href =
  1556. "$form->{script}?action=list_warehouse&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  1557. $form->sort_order();
  1558. $form->{callback} =
  1559. "$form->{script}?action=list_warehouse&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  1560. my $callback = $form->escape( $form->{callback} );
  1561. $form->{title} = $locale->text('Warehouses');
  1562. my @column_index = qw(description);
  1563. my %column_header;
  1564. $column_header{description} = {
  1565. href => $href,
  1566. text => $locale->text('Description'),
  1567. };
  1568. my @rows;
  1569. my $i;
  1570. foreach my $ref ( @{ $form->{ALL} } ) {
  1571. my %column_data;
  1572. $i++;
  1573. $i %= 2;
  1574. $column_data{i} = $i;
  1575. $column_data{description} = {
  1576. href => "$form->{script}?action=edit_warehouse&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback",
  1577. text => $ref->{description},
  1578. };
  1579. push @rows, \%column_data;
  1580. }
  1581. $form->{type} = "warehouse";
  1582. $hiddens{$_} = $form->{$_} foreach qw(type callback path login sessionid);
  1583. ##SC: Temporary commenting
  1584. ## if ( $form->{lynx} ) {
  1585. ## require "bin/menu.pl";
  1586. ## &menubar;
  1587. ## }
  1588. my @buttons = ({
  1589. name => 'action',
  1590. value => 'add_warehouse',
  1591. text => $locale->text('Add Warehouse'),
  1592. });
  1593. my $template = LedgerSMB::Template->new_UI(
  1594. user => \%myconfig,
  1595. locale => $locale,
  1596. template => 'form-dynatable');
  1597. $template->render({
  1598. form => $form,
  1599. buttons => \@buttons,
  1600. hiddens => \%hiddens,
  1601. columns => \@column_index,
  1602. heading => \%column_header,
  1603. rows => \@rows,
  1604. });
  1605. }
  1606. sub warehouse_header {
  1607. my $hiddens = shift;
  1608. $form->{title} = $locale->text("$form->{title} Warehouse");
  1609. # $locale->text('Add Warehouse')
  1610. # $locale->text('Edit Warehouse')
  1611. $form->{description} = $form->quote( $form->{description} );
  1612. $hiddens->{id} = $form->{id};
  1613. $hiddens->{type} = 'warehouse';
  1614. my $rows = $form->numtextrows( $form->{description}, 60 );
  1615. $rows;
  1616. }
  1617. sub save_warehouse {
  1618. $form->isblank( "description", $locale->text('Description missing!') );
  1619. AM->save_warehouse( \%myconfig, \%$form );
  1620. $form->redirect( $locale->text('Warehouse saved!') );
  1621. }
  1622. sub delete_warehouse {
  1623. AM->delete_warehouse( \%myconfig, \%$form );
  1624. $form->redirect( $locale->text('Warehouse deleted!') );
  1625. }
  1626. sub yearend {
  1627. AM->earningsaccounts( \%myconfig, \%$form );
  1628. my %hiddens;
  1629. my $chart = "";
  1630. my %accounts = (
  1631. name => 'accno',
  1632. options => [],
  1633. );
  1634. for ( @{ $form->{chart} } ) {
  1635. push @{$accounts{options}}, {
  1636. text => "$_->{accno}--$_->{description}",
  1637. value => "$_->{accno}--$_->{description}",
  1638. };
  1639. }
  1640. $form->{title} = $locale->text('Yearend');
  1641. $hiddens{decimalplaces} = 2;
  1642. $hiddens{l_accno} = 'Y';
  1643. $hiddens{$_} = $form->{$_} foreach qw(path login sessionid);
  1644. my @buttons = ({
  1645. name => 'action',
  1646. value => 'generate_yearend',
  1647. text => $locale->text('Continue'),
  1648. });
  1649. my $template = LedgerSMB::Template->new_UI(
  1650. user => \%myconfig,
  1651. locale => $locale,
  1652. template => 'am-yearend');
  1653. $template->render({
  1654. user => \%myconfig,
  1655. form => $form,
  1656. buttons => \@buttons,
  1657. hiddens => \%hiddens,
  1658. accounts => \%accounts,
  1659. });
  1660. }
  1661. sub generate_yearend {
  1662. $form->isblank( "todate", $locale->text('Yearend date missing!') );
  1663. RP->yearend_statement( \%myconfig, \%$form );
  1664. $form->{transdate} = $form->{todate};
  1665. $earnings = 0;
  1666. $form->{rowcount} = 1;
  1667. foreach $key ( keys %{ $form->{I} } ) {
  1668. if ( $form->{I}{$key}{charttype} eq "A" ) {
  1669. $form->{"debit_$form->{rowcount}"} = $form->{I}{$key}{this};
  1670. $earnings += $form->{I}{$key}{this};
  1671. $form->{"accno_$form->{rowcount}"} = $key;
  1672. $form->{rowcount}++;
  1673. $ok = 1;
  1674. }
  1675. }
  1676. foreach $key ( keys %{ $form->{E} } ) {
  1677. if ( $form->{E}{$key}{charttype} eq "A" ) {
  1678. $form->{"credit_$form->{rowcount}"} = $form->{E}{$key}{this} * -1;
  1679. $earnings += $form->{E}{$key}{this};
  1680. $form->{"accno_$form->{rowcount}"} = $key;
  1681. $form->{rowcount}++;
  1682. $ok = 1;
  1683. }
  1684. }
  1685. if ( $earnings > 0 ) {
  1686. $form->{"credit_$form->{rowcount}"} = $earnings;
  1687. $form->{"accno_$form->{rowcount}"} = $form->{accno};
  1688. }
  1689. else {
  1690. $form->{"debit_$form->{rowcount}"} = $earnings * -1;
  1691. $form->{"accno_$form->{rowcount}"} = $form->{accno};
  1692. }
  1693. if ($ok) {
  1694. if ( AM->post_yearend( \%myconfig, \%$form ) ) {
  1695. $form->redirect( $locale->text('Yearend posted!') );
  1696. }
  1697. else {
  1698. $form->error( $locale->text('Yearend posting failed!') );
  1699. }
  1700. }
  1701. else {
  1702. $form->error('Nothing to do!');
  1703. }
  1704. }
  1705. sub company_logo {
  1706. $myconfig{address} =~ s/\\n/<br>/g; # Template cleans this up
  1707. $myconfig{dbhost} = $locale->text('localhost') unless $myconfig{dbhost};
  1708. $form->{stylesheet} = $myconfig{stylesheet};
  1709. $form->{title} = $locale->text('About');
  1710. # create the logo screen
  1711. my $template = LedgerSMB::Template->new_UI(
  1712. user => \%myconfig,
  1713. locale => $locale,
  1714. template => 'am-company-logo');
  1715. $template->render({
  1716. form => $form,
  1717. user => \%myconfig,
  1718. });
  1719. }
  1720. sub recurring_transactions {
  1721. # $locale->text('Day')
  1722. # $locale->text('Days')
  1723. # $locale->text('Month')
  1724. # $locale->text('Months')
  1725. # $locale->text('Week')
  1726. # $locale->text('Weeks')
  1727. # $locale->text('Year')
  1728. # $locale->text('Years')
  1729. my %hiddens;
  1730. my %column_header;
  1731. $form->{stylesheet} = $myconfig{stylesheet};
  1732. $form->{title} = $locale->text('Recurring Transactions');
  1733. $column_header{id} = "";
  1734. AM->recurring_transactions( \%myconfig, \%$form );
  1735. $href = "$form->{script}?action=recurring_transactions";
  1736. for (qw(direction oldsort path login sessionid)) {
  1737. $href .= qq|&$_=$form->{$_}|;
  1738. }
  1739. $form->sort_order();
  1740. my @column_index = qw(ndx reference description);
  1741. push @column_index,
  1742. qw(nextdate enddate id amount curr repeat howmany recurringemail recurringprint);
  1743. $column_header{reference} = {
  1744. text => $locale->text('Reference'),
  1745. href => "$href&sort=reference",
  1746. };
  1747. $column_header{ndx} = ' ';
  1748. $column_header{id} = $locale->text('ID');
  1749. $column_header{description} = $locale->text('Description');
  1750. $column_header{nextdate} = {
  1751. text => $locale->text('Next'),
  1752. href => "$href&sort=nextdate",
  1753. };
  1754. $column_header{enddate} = {
  1755. text => $locale->text('Ends'),
  1756. href => "$href&sort=enddate",
  1757. };
  1758. $column_header{amount} = $locale->text('Amount');
  1759. $column_header{curr} = ' ';
  1760. $column_header{repeat} = $locale->text('Every');
  1761. $column_header{howmany} = $locale->text('Times');
  1762. $column_header{recurringemail} = $locale->text('E-mail');
  1763. $column_header{recurringprint} = $locale->text('Print');
  1764. my $i = 1;
  1765. my %tr = (
  1766. ar => $locale->text('AR'),
  1767. ap => $locale->text('AP'),
  1768. gl => $locale->text('GL'),
  1769. so => $locale->text('Sales Orders'),
  1770. po => $locale->text('Purchase Orders'),
  1771. );
  1772. my %f = &formnames;
  1773. my @transactions;
  1774. my $j;
  1775. my $k;
  1776. foreach my $transaction ( sort keys %{ $form->{transactions} } ) {
  1777. my $transaction_count = scalar( @{ $form->{transactions}{$transaction} } );
  1778. push @transactions, {type => $transaction,
  1779. title => "$tr{$transaction} ($transaction_count)",
  1780. transactions => [],
  1781. };
  1782. foreach my $ref ( @{ $form->{transactions}{$transaction} } ) {
  1783. my %column_data;
  1784. for (@column_index) {
  1785. $column_data{$_} = "$ref->{$_}";
  1786. }
  1787. my $unit;
  1788. my $repeat;
  1789. if ( $ref->{repeat} > 1 ) {
  1790. $unit = $locale->text( ucfirst $ref->{unit} );
  1791. $repeat = "$ref->{repeat} $unit";
  1792. }
  1793. else {
  1794. chop $ref->{unit};
  1795. $unit = $locale->text( ucfirst $ref->{unit} );
  1796. $repeat = $unit;
  1797. }
  1798. $column_data{ndx} = '';
  1799. if ( !$ref->{expired} ) {
  1800. if ( $ref->{overdue} <= 0 ) {
  1801. $k++;
  1802. $column_data{ndx} = {
  1803. name => "ndx_$k",
  1804. type => 'checkbox',
  1805. value => $ref->{id},
  1806. checked => 'checked',
  1807. };
  1808. }
  1809. }
  1810. my $reference =
  1811. ( $ref->{reference} )
  1812. ? $ref->{reference}
  1813. : $locale->text('Next Number');
  1814. $column_data{reference} = {
  1815. text => $reference,
  1816. href => qq|$form->{script}?action=edit_recurring&id=$ref->{id}&vc=$ref->{vc}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&module=$ref->{module}&invoice=$ref->{invoice}&transaction=$ref->{transaction}&recurringnextdate=$ref->{nextdate}|,
  1817. };
  1818. my $module = "$ref->{module}.pl";
  1819. my $type = "";
  1820. if ( $ref->{module} eq 'ar' ) {
  1821. $module = "is.pl" if $ref->{invoice};
  1822. $ref->{amount} /= $ref->{exchangerate};
  1823. }
  1824. if ( $ref->{module} eq 'ap' ) {
  1825. $module = "ir.pl" if $ref->{invoice};
  1826. $ref->{amount} /= $ref->{exchangerate};
  1827. }
  1828. if ( $ref->{module} eq 'oe' ) {
  1829. $type =
  1830. ( $ref->{vc} eq 'customer' )
  1831. ? "sales_order"
  1832. : "purchase_order";
  1833. }
  1834. $column_data{id} = {
  1835. text => $ref->{id},
  1836. href => qq|$module?action=edit&id=$ref->{id}&vc=$ref->{vc}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$type&readonly=1|,
  1837. };
  1838. $column_data{repeat} = $repeat;
  1839. $column_data{howmany} =
  1840. $form->format_amount( \%myconfig, $ref->{howmany} );
  1841. $column_data{amount} =
  1842. $form->format_amount( \%myconfig, $ref->{amount}, 2 );
  1843. my @temp_split;
  1844. my @f = split /:/, $ref->{recurringemail};
  1845. for ( 0 .. $#f ) {
  1846. push @temp_split, $f{$f[$_]};
  1847. }
  1848. $column_data{recurringemail} = {
  1849. text => join ':', @temp_split,
  1850. delimeter => ':',
  1851. };
  1852. @temp_split = ();
  1853. @f = split /:/, $ref->{recurringprint};
  1854. for ( 0 .. $#f ) {
  1855. push @temp_split, $f{$f[$_]};
  1856. }
  1857. $column_data{recurringprint} = {
  1858. text => join ':', @temp_split,
  1859. delimeter => ':',
  1860. };
  1861. $j++;
  1862. $j %= 2;
  1863. $column_data{i} = $j;
  1864. push @{$transactions[$#transactions]{transactions}}, \%column_data;
  1865. }
  1866. }
  1867. ##SC: Temporary removal
  1868. ## if ( $form->{lynx} ) {
  1869. ## require "bin/menu.pl";
  1870. ## &menubar;
  1871. ## }
  1872. $hiddens{path} = $form->{path};
  1873. $hiddens{login} = $form->{login};
  1874. $hiddens{sessionid} = $form->{sessionid};
  1875. $hiddens{lastndx} = $k;
  1876. my @buttons;
  1877. push @buttons, {
  1878. name => 'action',
  1879. value => 'process_transactions',
  1880. text => $locale->text('Process Transactions'),
  1881. type => 'submit',
  1882. class => 'submit',
  1883. };
  1884. my $template = LedgerSMB::Template->new_UI(
  1885. user => \%myconfig,
  1886. locale => $locale,
  1887. template => 'am-list-recurring');
  1888. $template->render({
  1889. form => $form,
  1890. buttons => \@buttons,
  1891. columns => \@column_index,
  1892. heading => \%column_header,
  1893. transactions => \@transactions,
  1894. hiddens => \%hiddens,
  1895. });
  1896. }
  1897. sub edit_recurring {
  1898. %links = (
  1899. ar => 'create_links',
  1900. ap => 'create_links',
  1901. gl => 'create_links',
  1902. is => 'invoice_links',
  1903. ir => 'invoice_links',
  1904. oe => 'order_links',
  1905. );
  1906. %prepare = (
  1907. is => 'prepare_invoice',
  1908. ir => 'prepare_invoice',
  1909. oe => 'prepare_order',
  1910. );
  1911. $form->{callback} =
  1912. "$form->{script}?action=recurring_transactions&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  1913. $form->{type} = "transaction";
  1914. if ( $form->{module} eq 'ar' ) {
  1915. if ( $form->{invoice} ) {
  1916. $form->{type} = "invoice";
  1917. $form->{module} = "is";
  1918. }
  1919. }
  1920. if ( $form->{module} eq 'ap' ) {
  1921. if ( $form->{invoice} ) {
  1922. $form->{type} = "invoice";
  1923. $form->{module} = "ir";
  1924. }
  1925. }
  1926. if ( $form->{module} eq 'oe' ) {
  1927. %tr = (
  1928. so => sales_order,
  1929. po => purchase_order,
  1930. );
  1931. $form->{type} = $tr{ $form->{transaction} };
  1932. }
  1933. $form->{script} = "$form->{module}.pl";
  1934. do "bin/$form->{script}";
  1935. &{ $links{ $form->{module} } };
  1936. # return if transaction doesn't exist
  1937. $form->redirect unless $form->{recurring};
  1938. if ( $prepare{ $form->{module} } ) {
  1939. &{ $prepare{ $form->{module} } };
  1940. }
  1941. $form->{selectformat} = qq|<option value="html">html\n|;
  1942. if ( ${LedgerSMB::Sysconfig::latex} ) {
  1943. $form->{selectformat} .= qq|
  1944. <option value="postscript">| . $locale->text('Postscript') . qq|
  1945. <option value="pdf">| . $locale->text('PDF');
  1946. }
  1947. &schedule;
  1948. }
  1949. sub process_transactions {
  1950. # save variables
  1951. my $pt = new Form;
  1952. for ( keys %$form ) { $pt->{$_} = $form->{$_} }
  1953. my $defaultprinter;
  1954. while ( my ( $key, $value ) = each %{LedgerSMB::Sysconfig::printer} ) {
  1955. if ( $value =~ /lpr/ ) {
  1956. $defaultprinter = $key;
  1957. last;
  1958. }
  1959. }
  1960. $myconfig{vclimit} = 0;
  1961. %f = &formnames;
  1962. for ( my $i = 1 ; $i <= $pt->{lastndx} ; $i++ ) {
  1963. if ( $pt->{"ndx_$i"} ) {
  1964. $id = $pt->{"ndx_$i"};
  1965. # process transaction
  1966. AM->recurring_details( \%myconfig, \%$pt, $id );
  1967. $header = $form->{header};
  1968. # reset $form
  1969. for ( keys %$form ) { delete $form->{$_}; }
  1970. for (qw(login path sessionid stylesheet timeout)) {
  1971. $form->{$_} = $pt->{$_};
  1972. }
  1973. $form->{id} = $id;
  1974. $form->{header} = $header;
  1975. $form->db_init(\%myconfig);
  1976. # post, print, email
  1977. if ( $pt->{arid} || $pt->{apid} || $pt->{oeid} ) {
  1978. if ( $pt->{arid} || $pt->{apid} ) {
  1979. if ( $pt->{arid} ) {
  1980. $form->{script} =
  1981. ( $pt->{invoice} ) ? "is.pl" : "ar.pl";
  1982. $form->{ARAP} = "AR";
  1983. $form->{module} = "ar";
  1984. $invfld = "sinumber";
  1985. }
  1986. else {
  1987. $form->{script} =
  1988. ( $pt->{invoice} ) ? "ir.pl" : "ap.pl";
  1989. $form->{ARAP} = "AP";
  1990. $form->{module} = "ap";
  1991. $invfld = "vinumber";
  1992. }
  1993. do "bin/$form->{script}";
  1994. if ( $pt->{invoice} ) {
  1995. &invoice_links;
  1996. &prepare_invoice;
  1997. for ( keys %$form ) {
  1998. $form->{$_} = $form->unquote( $form->{$_} );
  1999. }
  2000. }
  2001. else {
  2002. &create_links;
  2003. $form->{type} = "transaction";
  2004. for ( 1 .. $form->{rowcount} - 1 ) {
  2005. $form->{"amount_$_"} =
  2006. $form->format_amount( \%myconfig,
  2007. $form->{"amount_$_"}, 2 );
  2008. }
  2009. for ( 1 .. $form->{paidaccounts} ) {
  2010. $form->{"paid_$_"} =
  2011. $form->format_amount( \%myconfig,
  2012. $form->{"paid_$_"}, 2 );
  2013. }
  2014. }
  2015. delete $form->{"$form->{ARAP}_links"};
  2016. for (qw(acc_trans invoice_details)) { delete $form->{$_} }
  2017. for (
  2018. qw(department employee language month partsgroup project years)
  2019. )
  2020. {
  2021. delete $form->{"all_$_"};
  2022. }
  2023. $form->{invnumber} = $pt->{reference};
  2024. $form->{transdate} = $pt->{nextdate};
  2025. # tax accounts
  2026. $form->all_taxaccounts( \%myconfig, undef,
  2027. $form->{transdate} );
  2028. # calculate duedate
  2029. $form->{duedate} =
  2030. $form->add_date( \%myconfig, $form->{transdate},
  2031. $pt->{overdue}, "days" );
  2032. if ( $pt->{payment} ) {
  2033. # calculate date paid
  2034. for ( $j = 1 ; $j <= $form->{paidaccounts} ; $j++ ) {
  2035. $form->{"datepaid_$j"} =
  2036. $form->add_date( \%myconfig, $form->{transdate},
  2037. $pt->{paid}, "days" );
  2038. ( $form->{"$form->{ARAP}_paid_$j"} ) = split /--/,
  2039. $form->{"$form->{ARAP}_paid_$j"};
  2040. delete $form->{"cleared_$j"};
  2041. }
  2042. $form->{paidaccounts}++;
  2043. }
  2044. else {
  2045. $form->{paidaccounts} = -1;
  2046. }
  2047. for (qw(id recurring intnotes printed emailed queued)) {
  2048. delete $form->{$_};
  2049. }
  2050. ( $form->{ $form->{ARAP} } ) = split /--/,
  2051. $form->{ $form->{ARAP} };
  2052. $form->{invnumber} =
  2053. $form->update_defaults( \%myconfig, "$invfld" )
  2054. unless $form->{invnumber};
  2055. $form->{reference} = $form->{invnumber};
  2056. for (qw(invnumber reference)) {
  2057. $form->{$_} = $form->unquote( $form->{$_} );
  2058. }
  2059. if ( $pt->{invoice} ) {
  2060. if ( $pt->{arid} ) {
  2061. $form->info(
  2062. "\n"
  2063. . $locale->text(
  2064. 'Posting Sales Invoice [_1]',
  2065. $form->{invnumber}
  2066. )
  2067. );
  2068. $ok = IS->post_invoice( \%myconfig, \%$form );
  2069. }
  2070. else {
  2071. $form->info(
  2072. "\n"
  2073. . $locale->text(
  2074. 'Posting Vendor Invoice [_1]',
  2075. $form->{invnumber}
  2076. )
  2077. );
  2078. $ok = IR->post_invoice( \%myconfig, \%$form );
  2079. }
  2080. }
  2081. else {
  2082. if ( $pt->{arid} ) {
  2083. $form->info(
  2084. "\n"
  2085. . $locale->text(
  2086. 'Posting Transaction [_1]',
  2087. $form->{invnumber}
  2088. )
  2089. );
  2090. }
  2091. else {
  2092. $form->info(
  2093. "\n"
  2094. . $locale->text(
  2095. 'Posting Transaction [_1]',
  2096. $form->{invnumber}
  2097. )
  2098. );
  2099. }
  2100. $ok = AA->post_transaction( \%myconfig, \%$form );
  2101. }
  2102. $form->info( " ..... " . $locale->text('done') );
  2103. # print form
  2104. if ( ${LedgerSMB::Sysconfig::latex} && $ok ) {
  2105. $ok = &print_recurring( \%$pt, $defaultprinter );
  2106. }
  2107. &email_recurring( \%$pt ) if $ok;
  2108. }
  2109. else {
  2110. # order
  2111. $form->{script} = "oe.pl";
  2112. $form->{module} = "oe";
  2113. $ordnumber = "ordnumber";
  2114. if ( $pt->{customer_id} ) {
  2115. $form->{vc} = "customer";
  2116. $form->{type} = "sales_order";
  2117. $ordfld = "sonumber";
  2118. $flabel = $locale->text('Sales Order');
  2119. }
  2120. else {
  2121. $form->{vc} = "vendor";
  2122. $form->{type} = "purchase_order";
  2123. $ordfld = "ponumber";
  2124. $flabel = $locale->text('Purchase Order');
  2125. }
  2126. require "bin/$form->{script}";
  2127. &order_links;
  2128. &prepare_order;
  2129. for ( keys %$form ) {
  2130. $form->{$_} = $form->unquote( $form->{$_} );
  2131. }
  2132. $form->{$ordnumber} = $pt->{reference};
  2133. $form->{transdate} = $pt->{nextdate};
  2134. # calculate reqdate
  2135. $form->{reqdate} =
  2136. $form->add_date( \%myconfig, $form->{transdate},
  2137. $pt->{req}, "days" )
  2138. if $form->{reqdate};
  2139. for (qw(id recurring intnotes printed emailed queued)) {
  2140. delete $form->{$_};
  2141. }
  2142. for ( 1 .. $form->{rowcount} ) {
  2143. delete $form->{"orderitems_id_$_"};
  2144. }
  2145. $form->{$ordnumber} =
  2146. $form->update_defaults( \%myconfig, "$ordfld" )
  2147. unless $form->{$ordnumber};
  2148. $form->{reference} = $form->{$ordnumber};
  2149. for ( "$ordnumber", "reference" ) {
  2150. $form->{$_} = $form->unquote( $form->{$_} );
  2151. }
  2152. $form->{closed} = 0;
  2153. $form->info(
  2154. "\n"
  2155. . $locale->text(
  2156. 'Saving [_1] [_2]',
  2157. $flabel, $form->{$ordnumber}
  2158. )
  2159. );
  2160. if ( $ok = OE->save( \%myconfig, \%$form ) ) {
  2161. $form->info( " ..... " . $locale->text('done') );
  2162. }
  2163. else {
  2164. $form->info( " ..... " . $locale->text('failed') );
  2165. }
  2166. # print form
  2167. if ( ${LedgerSMB::Sysconfig::latex} && $ok ) {
  2168. &print_recurring( \%$pt, $defaultprinter );
  2169. }
  2170. &email_recurring( \%$pt );
  2171. }
  2172. }
  2173. else {
  2174. # GL transaction
  2175. GL->transaction( \%myconfig, \%$form );
  2176. $form->{reference} = $pt->{reference};
  2177. $form->{transdate} = $pt->{nextdate};
  2178. $j = 1;
  2179. foreach $ref ( @{ $form->{GL} } ) {
  2180. $form->{"accno_$j"} = "$ref->{accno}--$ref->{description}";
  2181. $form->{"projectnumber_$j"} =
  2182. "$ref->{projectnumber}--$ref->{project_id}"
  2183. if $ref->{project_id};
  2184. $form->{"fx_transaction_$j"} = $ref->{fx_transaction};
  2185. if ( $ref->{amount} < 0 ) {
  2186. $form->{"debit_$j"} = $ref->{amount} * -1;
  2187. }
  2188. else {
  2189. $form->{"credit_$j"} = $ref->{amount};
  2190. }
  2191. $j++;
  2192. }
  2193. $form->{rowcount} = $j;
  2194. for (qw(id recurring)) { delete $form->{$_} }
  2195. $form->info(
  2196. "\n"
  2197. . $locale->text(
  2198. 'Posting GL Transaction [_1]',
  2199. $form->{reference}
  2200. )
  2201. );
  2202. $ok = GL->post_transaction( \%myconfig, \%$form );
  2203. $form->info( " ..... " . $locale->text('done') );
  2204. }
  2205. AM->update_recurring( \%myconfig, \%$pt, $id ) if $ok;
  2206. }
  2207. }
  2208. $form->{callback} =
  2209. "am.pl?action=recurring_transactions&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&header=$form->{header}";
  2210. $form->redirect;
  2211. }
  2212. sub print_recurring {
  2213. my ( $pt, $defaultprinter ) = @_;
  2214. use List::Util qw(first);
  2215. my %f = &formnames;
  2216. my $ok = 1;
  2217. if ( $pt->{recurringprint} ) {
  2218. @f = split /:/, $pt->{recurringprint};
  2219. for ( $j = 0 ; $j <= $#f ; $j += 3 ) {
  2220. $media = $f[ $j + 2 ];
  2221. $media ||= $myconfig->{printer}
  2222. if ${LedgerSMB::Sysconfig::printer}{ $myconfig->{printer} };
  2223. $media ||= $defaultprinter;
  2224. $form->info( "\n"
  2225. . $locale->text('Printing') . " "
  2226. . $locale->text( $f{ $f[$j] } )
  2227. . " $form->{reference}" );
  2228. @a = (
  2229. "perl", "$form->{script}",
  2230. "action=reprint&module=$form->{module}&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}&id=$form->{id}&formname=$f[$j]&format=$f[$j+1]&media=$media&vc=$form->{vc}&ARAP=$form->{ARAP}"
  2231. );
  2232. $form->error( $locale->text('Invalid redirect') )
  2233. unless first { $_ eq $form->{script} }
  2234. @{LedgerSMB::Sysconfig::scripts};
  2235. $ok = !( system(@a) );
  2236. if ($ok) {
  2237. $form->info( " ..... " . $locale->text('done') );
  2238. }
  2239. else {
  2240. $form->info( " ..... " . $locale->text('failed') );
  2241. last;
  2242. }
  2243. }
  2244. }
  2245. $ok;
  2246. }
  2247. sub email_recurring {
  2248. my ($pt) = @_;
  2249. use List::Util qw(first);
  2250. my %f = &formnames;
  2251. my $ok = 1;
  2252. if ( $pt->{recurringemail} ) {
  2253. @f = split /:/, $pt->{recurringemail};
  2254. for ( $j = 0 ; $j <= $#f ; $j += 2 ) {
  2255. $form->info( "\n"
  2256. . $locale->text('Sending') . " "
  2257. . $locale->text( $f{ $f[$j] } )
  2258. . " $form->{reference}" );
  2259. # no email, bail out
  2260. if ( !$form->{email} ) {
  2261. $form->info(
  2262. " ..... " . $locale->text('E-mail address missing!') );
  2263. last;
  2264. }
  2265. $message = $form->escape( $pt->{message}, 1 );
  2266. @a = (
  2267. "perl", "$form->{script}",
  2268. "action=reprint&module=$form->{module}&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}&id=$form->{id}&formname=$f[$j]&format=$f[$j+1]&media=email&vc=$form->{vc}&ARAP=$form->{ARAP}&message=$message"
  2269. );
  2270. $form->error( $locale->text('Invalid redirect') )
  2271. unless first { $_ eq $form->{script} }
  2272. @{LedgerSMB::Sysconfig::scripts};
  2273. $ok = !( system(@a) );
  2274. if ($ok) {
  2275. $form->info( " ..... " . $locale->text('done') );
  2276. }
  2277. else {
  2278. $form->info( " ..... " . $locale->text('failed') );
  2279. last;
  2280. }
  2281. }
  2282. }
  2283. $ok;
  2284. }
  2285. sub formnames {
  2286. # $locale->text('Transaction')
  2287. # $locale->text('Invoice')
  2288. # $locale->text('Credit Invoice')
  2289. # $locale->text('Debit Invoice')
  2290. # $locale->text('Packing List')
  2291. # $locale->text('Pick List')
  2292. # $locale->text('Sales Order')
  2293. # $locale->text('Work Order')
  2294. # $locale->text('Purchase Order')
  2295. # $locale->text('Bin List')
  2296. my %f = (
  2297. transaction => 'Transaction',
  2298. invoice => 'Invoice',
  2299. credit_invoice => 'Credit Invoice',
  2300. debit_invoice => 'Debit Invoice',
  2301. packing_list => 'Packing List',
  2302. pick_list => 'Pick List',
  2303. sales_order => 'Sales Order',
  2304. work_order => 'Work Order',
  2305. purchase_order => 'Purchase Order',
  2306. bin_list => 'Bin List',
  2307. );
  2308. %f;
  2309. }
  2310. sub continue { &{ $form->{nextsub} } }