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