summaryrefslogtreecommitdiff
path: root/bin/am.pl
blob: 9a08092dda380f27a0bc2382aff68b0861db1fe9 (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 AR_overpayment AR_discount AP_amount AP_tax AP_paid AP_overpayment AP_discount 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", "${item}_overpayment", "${item}_discount" ) {
  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. 'default_country' => {name => 'default_country',
  1125. options => $form->{countries},
  1126. default_values => [$form->{'default_country'}],
  1127. text_attr => 'name',
  1128. value_attr => 'id',
  1129. },
  1130. );
  1131. foreach $key ( keys %{ $form->{accno} } ) {
  1132. foreach $accno ( sort keys %{ $form->{accno}{$key} } ) {
  1133. push @{$selects{$key}{options}}, {
  1134. text => "$accno--$form->{accno}{$key}{$accno}{description}",
  1135. value => "$accno--$form->{accno}{$key}{$accno}{description}",
  1136. };
  1137. $selects{$key}{default_values} = "$accno--$form->{accno}{$key}{$accno}{description}" if
  1138. ($form->{defaults}{$key} == $form->{accno}{$key}{$accno}{id});
  1139. }
  1140. }
  1141. for (qw(accno defaults)) { delete $form->{$_} }
  1142. ##SC: temporary commenting out
  1143. ## if ( $form->{lynx} ) {
  1144. ## require "bin/menu.pl";
  1145. ## &menubar;
  1146. ## }
  1147. my %hiddens = (
  1148. path => $form->{path},
  1149. login => $form->{login},
  1150. sessionid => $form->{sessionid},
  1151. type => 'defaults',
  1152. );
  1153. my $template = LedgerSMB::Template->new_UI(
  1154. user => \%myconfig,
  1155. locale => $locale,
  1156. template => 'am-defaults');
  1157. $template->render({
  1158. form => $form,
  1159. hiddens => \%hiddens,
  1160. selects => \%selects,
  1161. });
  1162. }
  1163. sub taxes {
  1164. # get tax account numbers
  1165. AM->taxes( \%myconfig, \%$form );
  1166. $i = 0;
  1167. foreach $ref ( @{ $form->{taxrates} } ) {
  1168. $i++;
  1169. $form->{"taxrate_$i"} =
  1170. $form->format_amount( \%myconfig, $ref->{rate} );
  1171. $form->{"taxdescription_$i"} = $ref->{description};
  1172. for (qw(taxnumber validto pass taxmodulename)) {
  1173. $form->{"${_}_$i"} = $ref->{$_};
  1174. }
  1175. $form->{taxaccounts} .= "$ref->{id}_$i ";
  1176. }
  1177. chop $form->{taxaccounts};
  1178. &display_taxes;
  1179. }
  1180. sub display_taxes {
  1181. $form->{title} = $locale->text('Taxes');
  1182. my %hiddens = (
  1183. path => $form->{path},
  1184. login => $form->{login},
  1185. sessionid => $form->{sessionid},
  1186. type => 'taxes',
  1187. );
  1188. my @rows;
  1189. for ( split( / /, $form->{taxaccounts} ) ) {
  1190. ( $null, $i ) = split /_/, $_;
  1191. $form->{"taxrate_$i"} =
  1192. $form->format_amount( \%myconfig, $form->{"taxrate_$i"} );
  1193. $hiddens{"taxdescription_$i"} = $form->{"taxdescription_$i"};
  1194. my %select = (name => "taxmodule_id_$i", options => []);
  1195. foreach my $taxmodule ( sort keys %$form ) {
  1196. next if ( $taxmodule !~ /^taxmodule_/ );
  1197. next if ( $taxmodule =~ /^taxmodule_id_/ );
  1198. my $modulenum = $taxmodule;
  1199. $modulenum =~ s/^taxmodule_//;
  1200. push @{$select{options}},
  1201. {text => $form->{$taxmodule}, value => $modulenum};
  1202. $select{default_values} = $modulenum
  1203. if $form->{$taxmodule} eq $form->{"taxmodulename_$i"};
  1204. }
  1205. if ( $form->{"taxdescription_$i"} eq $sametax ) {
  1206. push @rows, ["", \%select];
  1207. } else {
  1208. push @rows, [$form->{"taxdescription_$i"}, \%select];
  1209. }
  1210. $sametax = $form->{"taxdescription_$i"};
  1211. }
  1212. $hiddens{taxaccounts} = $form->{taxaccounts};
  1213. foreach my $taxmodule ( sort keys %$form ) {
  1214. next if ( $taxmodule !~ /^taxmodule_/ );
  1215. next if ( $taxmodule =~ /^taxmodule_id_/ );
  1216. $hiddens{$taxmodule};
  1217. }
  1218. ##SC: Temporary removal
  1219. ## if ( $form->{lynx} ) {
  1220. ## require "bin/menu.pl";
  1221. ## &menubar;
  1222. ## }
  1223. my $template = LedgerSMB::Template->new_UI(
  1224. user => \%myconfig,
  1225. locale => $locale,
  1226. template => 'am-taxes');
  1227. $template->render({
  1228. form => $form,
  1229. hiddens => \%hiddens,
  1230. selects => \%selects,
  1231. rows => \@rows,
  1232. });
  1233. }
  1234. sub update {
  1235. @a = split / /, $form->{taxaccounts};
  1236. $ndx = $#a + 1;
  1237. foreach $item (@a) {
  1238. ( $accno, $i ) = split /_/, $item;
  1239. push @t, $accno;
  1240. $form->{"taxmodulename_$i"} =
  1241. $form->{ "taxmodule_" . $form->{"taxmodule_id_$i"} };
  1242. if ( $form->{"validto_$i"} ) {
  1243. $j = $i + 1;
  1244. if ( $form->{"taxdescription_$i"} ne $form->{"taxdescription_$j"} )
  1245. {
  1246. #insert line
  1247. for ( $j = $ndx + 1 ; $j > $i ; $j-- ) {
  1248. $k = $j - 1;
  1249. for (qw(taxrate taxdescription taxnumber validto)) {
  1250. $form->{"${_}_$j"} = $form->{"${_}_$k"};
  1251. }
  1252. }
  1253. $ndx++;
  1254. $k = $i + 1;
  1255. for (qw(taxdescription taxnumber)) {
  1256. $form->{"${_}_$k"} = $form->{"${_}_$i"};
  1257. }
  1258. for (qw(taxrate validto)) { $form->{"${_}_$k"} = "" }
  1259. push @t, $accno;
  1260. }
  1261. }
  1262. else {
  1263. # remove line
  1264. $j = $i + 1;
  1265. if ( $form->{"taxdescription_$i"} eq $form->{"taxdescription_$j"} )
  1266. {
  1267. for ( $j = $i + 1 ; $j <= $ndx ; $j++ ) {
  1268. $k = $j + 1;
  1269. for (qw(taxrate taxdescription taxnumber validto)) {
  1270. $form->{"${_}_$j"} = $form->{"${_}_$k"};
  1271. }
  1272. }
  1273. $ndx--;
  1274. splice @t, $i - 1, 1;
  1275. }
  1276. }
  1277. }
  1278. $i = 1;
  1279. $form->{taxaccounts} = "";
  1280. for (@t) {
  1281. $form->{taxaccounts} .= "${_}_$i ";
  1282. $i++;
  1283. }
  1284. chop $form->{taxaccounts};
  1285. &display_taxes;
  1286. }
  1287. sub config {
  1288. my %selects;
  1289. $selects{dateformat} = {
  1290. name => 'dateformat',
  1291. default_values => $myconfig{dateformat},
  1292. options => [],
  1293. };
  1294. foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd))
  1295. {
  1296. push @{$selects{dateformat}{options}}, {text => $item, value => $item};
  1297. }
  1298. $selects{numberformat} = {
  1299. name => 'numberformat',
  1300. default_values => $myconfig{numberformat},
  1301. options => [],
  1302. };
  1303. my @formats = qw(1,000.00 1000.00 1.000,00 1000,00 1'000.00);
  1304. push @formats, '1 000.00';
  1305. foreach $item (@formats) {
  1306. push @{$selects{numberformat}{options}}, {text => $item, value => $item};
  1307. }
  1308. ## for (qw(name company address signature)) {
  1309. ## $myconfig{$_} = $form->quote( $myconfig{$_} );
  1310. ## }
  1311. for (qw(address signature)) { $myconfig{$_} =~ s/\\n/\n/g }
  1312. $selects{countrycode} = {
  1313. name => 'countrycode',
  1314. default_values => ($myconfig{countrycode})? $myconfig{countrycode}: 'en',
  1315. options => [],
  1316. };
  1317. %countrycodes = LedgerSMB::User->country_codes;
  1318. foreach $key ( sort { $countrycodes{$a} cmp $countrycodes{$b} }
  1319. keys %countrycodes )
  1320. {
  1321. push @{$selects{countrycode}{options}}, {
  1322. text => $countrycodes{$key},
  1323. value => $key
  1324. };
  1325. }
  1326. opendir CSS, "css/.";
  1327. @all = grep /.*\.css$/, readdir CSS;
  1328. closedir CSS;
  1329. $selects{stylesheet} = {
  1330. name => 'usestylesheet',
  1331. default_values => $myconfig{stylesheet},
  1332. options => [],
  1333. };
  1334. foreach $item (@all) {
  1335. push @{$selects{stylesheet}{options}}, {text => $item, value => $item};
  1336. }
  1337. push @{$selects{stylesheet}{options}}, {text => 'none', value => '0'};
  1338. if ( %{LedgerSMB::Sysconfig::printer} && ${LedgerSMB::Sysconfig::latex} ) {
  1339. $selects{printer} = {
  1340. name => 'printer',
  1341. default_values => $myconfig{printer},
  1342. options => [],
  1343. };
  1344. foreach $item ( sort keys %{LedgerSMB::Sysconfig::printer} ) {
  1345. push @{$selects{printer}{options}}, {text => $item, value => $item};
  1346. }
  1347. }
  1348. $form->{title} =
  1349. $locale->text( 'Edit Preferences for [_1]', $form->{login} );
  1350. ##SC: Temporary commenting out
  1351. ## if ( $form->{lynx} ) {
  1352. ## require "bin/menu.pl";
  1353. ## &menubar;
  1354. ## }
  1355. my %hiddens = (
  1356. path => $form->{path},
  1357. login => $form->{login},
  1358. sessionid => $form->{sessionid},
  1359. type => 'preferences',
  1360. role => $myconfig{role},
  1361. old_password => $myconfig{password},
  1362. );
  1363. my $template = LedgerSMB::Template->new_UI(
  1364. user => \%myconfig,
  1365. locale => $locale,
  1366. template => 'am-userconfig');
  1367. $template->render({
  1368. form => $form,
  1369. user => \%myconfig,
  1370. hiddens => \%hiddens,
  1371. selects => \%selects,
  1372. });
  1373. }
  1374. sub save_defaults {
  1375. if ( AM->save_defaults( \%myconfig, \%$form ) ) {
  1376. $form->redirect( $locale->text('Defaults saved!') );
  1377. }
  1378. else {
  1379. $form->error( $locale->text('Cannot save defaults!') );
  1380. }
  1381. }
  1382. sub save_taxes {
  1383. if ( AM->save_taxes( \%myconfig, \%$form ) ) {
  1384. $form->redirect( $locale->text('Taxes saved!') );
  1385. }
  1386. else {
  1387. $form->error( $locale->text('Cannot save taxes!') );
  1388. }
  1389. }
  1390. sub save_preferences {
  1391. $form->{stylesheet} = $form->{usestylesheet};
  1392. if ( $form->{new_password} ne $form->{old_password} ) {
  1393. $form->error( $locale->text('Password does not match!') )
  1394. if $form->{new_password} ne $form->{confirm_password};
  1395. }
  1396. if ( AM->save_preferences( \%myconfig, \%$form ) ) {
  1397. $form->info( $locale->text('Preferences saved!') );
  1398. }
  1399. else {
  1400. $form->error( $locale->text('Cannot save preferences!') );
  1401. }
  1402. }
  1403. sub backup {
  1404. if ( $form->{media} eq 'email' ) {
  1405. $form->error(
  1406. $locale->text( 'No email address for [_1]', $myconfig{name} ) )
  1407. unless ( $myconfig{email} );
  1408. }
  1409. $SIG{INT} = 'IGNORE';
  1410. AM->backup(
  1411. \%myconfig, \%$form,
  1412. ${LedgerSMB::Sysconfig::userspath},
  1413. ${LedgerSMB::Sysconfig::gzip}
  1414. );
  1415. if ( $form->{media} eq 'email' ) {
  1416. $form->redirect(
  1417. $locale->text( 'Backup sent to [_1]', $myconfig{email} ) );
  1418. }
  1419. }
  1420. sub audit_control {
  1421. $form->{title} = $locale->text('Audit Control');
  1422. AM->closedto( \%myconfig, \%$form );
  1423. my %checked;
  1424. if ( $form->{revtrans} ) {
  1425. $checked{revtransY} = 'checked';
  1426. } else {
  1427. $checked{revtransN} = 'checked';
  1428. }
  1429. if ( $form->{audittrail} ) {
  1430. $checked{audittrailY} = 'checked';
  1431. } else {
  1432. $checked{audittrailN} = 'checked';
  1433. }
  1434. my %hiddens = (
  1435. path => $form->{path},
  1436. login => $form->{login},
  1437. sessionid => $form->{sessionid},
  1438. );
  1439. my $template = LedgerSMB::Template->new_UI(
  1440. user => \%myconfig,
  1441. locale => $locale,
  1442. template => 'am-audit-control');
  1443. $template->render({
  1444. user => \%myconfig,
  1445. form => $form,
  1446. checked => \%checked,
  1447. hiddens => \%hiddens,
  1448. });
  1449. }
  1450. sub doclose {
  1451. AM->closebooks( \%myconfig, \%$form );
  1452. if ( $form->{revtrans} ) {
  1453. $msg = $locale->text('Transaction reversal enforced for all dates');
  1454. }
  1455. else {
  1456. if ( $form->{closedto} ) {
  1457. $msg =
  1458. $locale->text('Transaction reversal enforced up to [_1]',
  1459. $locale->date( \%myconfig, $form->{closedto}, 1 ));
  1460. }
  1461. else {
  1462. $msg = $locale->text('Books are open');
  1463. }
  1464. }
  1465. $msg .= "<p>";
  1466. if ( $form->{audittrail} ) {
  1467. $msg .= $locale->text('Audit trail enabled');
  1468. }
  1469. else {
  1470. $msg .= $locale->text('Audit trail disabled');
  1471. }
  1472. ##SC: Disabling audit trail deletion
  1473. ## $msg .= "<p>";
  1474. ## if ( $form->{removeaudittrail} ) {
  1475. ## $msg .=
  1476. ## $locale->text('Audit trail removed up to') . " "
  1477. ## . $locale->date( \%myconfig, $form->{removeaudittrail}, 1 );
  1478. ## }
  1479. $form->redirect($msg);
  1480. }
  1481. sub add_warehouse {
  1482. $form->{title} = "Add";
  1483. $form->{callback} =
  1484. "$form->{script}?action=add_warehouse&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"
  1485. unless $form->{callback};
  1486. my %hiddens;
  1487. my @buttons;
  1488. my $rows = &warehouse_header(\%hiddens);
  1489. &form_footer_buttons(\%hiddens, \@buttons);
  1490. my $template = LedgerSMB::Template->new_UI(
  1491. user => \%myconfig,
  1492. locale => $locale,
  1493. template => 'am-warehouse-form');
  1494. $template->render({
  1495. form => $form,
  1496. row_count => $rows,
  1497. buttons => \@buttons,
  1498. hiddens => \%hiddens,
  1499. });
  1500. }
  1501. sub edit_warehouse {
  1502. $form->{title} = "Edit";
  1503. AM->get_warehouse( \%myconfig, \%$form );
  1504. my %hiddens;
  1505. my @buttons;
  1506. my $rows = &warehouse_header(\%hiddens);
  1507. &form_footer_buttons(\%hiddens, \@buttons);
  1508. my $template = LedgerSMB::Template->new_UI(
  1509. user => \%myconfig,
  1510. locale => $locale,
  1511. template => 'am-warehouse-form');
  1512. $template->render({
  1513. form => $form,
  1514. row_count => $rows,
  1515. buttons => \@buttons,
  1516. hiddens => \%hiddens,
  1517. });
  1518. }
  1519. sub list_warehouse {
  1520. AM->warehouses( \%myconfig, \%$form );
  1521. my %hiddens;
  1522. my $href =
  1523. "$form->{script}?action=list_warehouse&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  1524. $form->sort_order();
  1525. $form->{callback} =
  1526. "$form->{script}?action=list_warehouse&direction=$form->{direction}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  1527. my $callback = $form->escape( $form->{callback} );
  1528. $form->{title} = $locale->text('Warehouses');
  1529. my @column_index = qw(description);
  1530. my %column_header;
  1531. $column_header{description} = {
  1532. href => $href,
  1533. text => $locale->text('Description'),
  1534. };
  1535. my @rows;
  1536. my $i;
  1537. foreach my $ref ( @{ $form->{ALL} } ) {
  1538. my %column_data;
  1539. $i++;
  1540. $i %= 2;
  1541. $column_data{i} = $i;
  1542. $column_data{description} = {
  1543. href => "$form->{script}?action=edit_warehouse&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback",
  1544. text => $ref->{description},
  1545. };
  1546. push @rows, \%column_data;
  1547. }
  1548. $form->{type} = "warehouse";
  1549. $hiddens{$_} = $form->{$_} foreach qw(type callback path login sessionid);
  1550. ##SC: Temporary commenting
  1551. ## if ( $form->{lynx} ) {
  1552. ## require "bin/menu.pl";
  1553. ## &menubar;
  1554. ## }
  1555. my @buttons = ({
  1556. name => 'action',
  1557. value => 'add_warehouse',
  1558. text => $locale->text('Add Warehouse'),
  1559. });
  1560. my $template = LedgerSMB::Template->new_UI(
  1561. user => \%myconfig,
  1562. locale => $locale,
  1563. template => 'form-dynatable');
  1564. $template->render({
  1565. form => $form,
  1566. buttons => \@buttons,
  1567. hiddens => \%hiddens,
  1568. columns => \@column_index,
  1569. heading => \%column_header,
  1570. rows => \@rows,
  1571. });
  1572. }
  1573. sub warehouse_header {
  1574. my $hiddens = shift;
  1575. $form->{title} = $locale->text("$form->{title} Warehouse");
  1576. # $locale->text('Add Warehouse')
  1577. # $locale->text('Edit Warehouse')
  1578. $form->{description} = $form->quote( $form->{description} );
  1579. $hiddens->{id} = $form->{id};
  1580. $hiddens->{type} = 'warehouse';
  1581. my $rows = $form->numtextrows( $form->{description}, 60 );
  1582. $rows;
  1583. }
  1584. sub save_warehouse {
  1585. $form->isblank( "description", $locale->text('Description missing!') );
  1586. AM->save_warehouse( \%myconfig, \%$form );
  1587. $form->redirect( $locale->text('Warehouse saved!') );
  1588. }
  1589. sub delete_warehouse {
  1590. AM->delete_warehouse( \%myconfig, \%$form );
  1591. $form->redirect( $locale->text('Warehouse deleted!') );
  1592. }
  1593. sub yearend {
  1594. AM->earningsaccounts( \%myconfig, \%$form );
  1595. my %hiddens;
  1596. my $chart = "";
  1597. my %accounts = (
  1598. name => 'accno',
  1599. options => [],
  1600. );
  1601. for ( @{ $form->{chart} } ) {
  1602. push @{$accounts{options}}, {
  1603. text => "$_->{accno}--$_->{description}",
  1604. value => "$_->{accno}--$_->{description}",
  1605. };
  1606. }
  1607. $form->{title} = $locale->text('Yearend');
  1608. $hiddens{decimalplaces} = 2;
  1609. $hiddens{l_accno} = 'Y';
  1610. $hiddens{$_} = $form->{$_} foreach qw(path login sessionid);
  1611. my @buttons = ({
  1612. name => 'action',
  1613. value => 'generate_yearend',
  1614. text => $locale->text('Continue'),
  1615. });
  1616. my $template = LedgerSMB::Template->new_UI(
  1617. user => \%myconfig,
  1618. locale => $locale,
  1619. template => 'am-yearend');
  1620. $template->render({
  1621. user => \%myconfig,
  1622. form => $form,
  1623. buttons => \@buttons,
  1624. hiddens => \%hiddens,
  1625. accounts => \%accounts,
  1626. });
  1627. }
  1628. sub generate_yearend {
  1629. $form->isblank( "todate", $locale->text('Yearend date missing!') );
  1630. RP->yearend_statement( \%myconfig, \%$form );
  1631. $form->{transdate} = $form->{todate};
  1632. $earnings = 0;
  1633. $form->{rowcount} = 1;
  1634. foreach $key ( keys %{ $form->{I} } ) {
  1635. if ( $form->{I}{$key}{charttype} eq "A" ) {
  1636. $form->{"debit_$form->{rowcount}"} = $form->{I}{$key}{this};
  1637. $earnings += $form->{I}{$key}{this};
  1638. $form->{"accno_$form->{rowcount}"} = $key;
  1639. $form->{rowcount}++;
  1640. $ok = 1;
  1641. }
  1642. }
  1643. foreach $key ( keys %{ $form->{E} } ) {
  1644. if ( $form->{E}{$key}{charttype} eq "A" ) {
  1645. $form->{"credit_$form->{rowcount}"} = $form->{E}{$key}{this} * -1;
  1646. $earnings += $form->{E}{$key}{this};
  1647. $form->{"accno_$form->{rowcount}"} = $key;
  1648. $form->{rowcount}++;
  1649. $ok = 1;
  1650. }
  1651. }
  1652. if ( $earnings > 0 ) {
  1653. $form->{"credit_$form->{rowcount}"} = $earnings;
  1654. $form->{"accno_$form->{rowcount}"} = $form->{accno};
  1655. }
  1656. else {
  1657. $form->{"debit_$form->{rowcount}"} = $earnings * -1;
  1658. $form->{"accno_$form->{rowcount}"} = $form->{accno};
  1659. }
  1660. if ($ok) {
  1661. if ( AM->post_yearend( \%myconfig, \%$form ) ) {
  1662. $form->redirect( $locale->text('Yearend posted!') );
  1663. }
  1664. else {
  1665. $form->error( $locale->text('Yearend posting failed!') );
  1666. }
  1667. }
  1668. else {
  1669. $form->error('Nothing to do!');
  1670. }
  1671. }
  1672. sub company_logo {
  1673. $myconfig{address} =~ s/\\n/<br>/g; # Template cleans this up
  1674. $myconfig{dbhost} = $locale->text('localhost') unless $myconfig{dbhost};
  1675. $form->{stylesheet} = $myconfig{stylesheet};
  1676. $form->{title} = $locale->text('About');
  1677. # create the logo screen
  1678. my $template = LedgerSMB::Template->new_UI(
  1679. user => \%myconfig,
  1680. locale => $locale,
  1681. template => 'am-company-logo');
  1682. $template->render({
  1683. form => $form,
  1684. user => \%myconfig,
  1685. });
  1686. }
  1687. sub recurring_transactions {
  1688. # $locale->text('Day')
  1689. # $locale->text('Days')
  1690. # $locale->text('Month')
  1691. # $locale->text('Months')
  1692. # $locale->text('Week')
  1693. # $locale->text('Weeks')
  1694. # $locale->text('Year')
  1695. # $locale->text('Years')
  1696. my %hiddens;
  1697. my %column_header;
  1698. $form->{stylesheet} = $myconfig{stylesheet};
  1699. $form->{title} = $locale->text('Recurring Transactions');
  1700. $column_header{id} = "";
  1701. AM->recurring_transactions( \%myconfig, \%$form );
  1702. $href = "$form->{script}?action=recurring_transactions";
  1703. for (qw(direction oldsort path login sessionid)) {
  1704. $href .= qq|&$_=$form->{$_}|;
  1705. }
  1706. $form->sort_order();
  1707. my @column_index = qw(ndx reference description);
  1708. push @column_index,
  1709. qw(nextdate enddate id amount curr repeat howmany recurringemail recurringprint);
  1710. $column_header{reference} = {
  1711. text => $locale->text('Reference'),
  1712. href => "$href&sort=reference",
  1713. };
  1714. $column_header{ndx} = ' ';
  1715. $column_header{id} = $locale->text('ID');
  1716. $column_header{description} = $locale->text('Description');
  1717. $column_header{nextdate} = {
  1718. text => $locale->text('Next'),
  1719. href => "$href&sort=nextdate",
  1720. };
  1721. $column_header{enddate} = {
  1722. text => $locale->text('Ends'),
  1723. href => "$href&sort=enddate",
  1724. };
  1725. $column_header{amount} = $locale->text('Amount');
  1726. $column_header{curr} = ' ';
  1727. $column_header{repeat} = $locale->text('Every');
  1728. $column_header{howmany} = $locale->text('Times');
  1729. $column_header{recurringemail} = $locale->text('E-mail');
  1730. $column_header{recurringprint} = $locale->text('Print');
  1731. my $i = 1;
  1732. my %tr = (
  1733. ar => $locale->text('AR'),
  1734. ap => $locale->text('AP'),
  1735. gl => $locale->text('GL'),
  1736. so => $locale->text('Sales Orders'),
  1737. po => $locale->text('Purchase Orders'),
  1738. );
  1739. my %f = &formnames;
  1740. my @transactions;
  1741. my $j;
  1742. my $k;
  1743. foreach my $transaction ( sort keys %{ $form->{transactions} } ) {
  1744. my $transaction_count = scalar( @{ $form->{transactions}{$transaction} } );
  1745. push @transactions, {type => $transaction,
  1746. title => "$tr{$transaction} ($transaction_count)",
  1747. transactions => [],
  1748. };
  1749. foreach my $ref ( @{ $form->{transactions}{$transaction} } ) {
  1750. my %column_data;
  1751. for (@column_index) {
  1752. $column_data{$_} = "$ref->{$_}";
  1753. }
  1754. my $unit;
  1755. my $repeat;
  1756. if ( $ref->{repeat} > 1 ) {
  1757. $unit = $locale->text( ucfirst $ref->{unit} );
  1758. $repeat = "$ref->{repeat} $unit";
  1759. }
  1760. else {
  1761. chop $ref->{unit};
  1762. $unit = $locale->text( ucfirst $ref->{unit} );
  1763. $repeat = $unit;
  1764. }
  1765. $column_data{ndx} = '';
  1766. if ( !$ref->{expired} ) {
  1767. if ( $ref->{overdue} <= 0 ) {
  1768. $k++;
  1769. $column_data{ndx} = {
  1770. name => "ndx_$k",
  1771. type => 'checkbox',
  1772. value => $ref->{id},
  1773. checked => 'checked',
  1774. };
  1775. }
  1776. }
  1777. my $reference =
  1778. ( $ref->{reference} )
  1779. ? $ref->{reference}
  1780. : $locale->text('Next Number');
  1781. $column_data{reference} = {
  1782. text => $reference,
  1783. 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}|,
  1784. };
  1785. my $module = "$ref->{module}.pl";
  1786. my $type = "";
  1787. if ( $ref->{module} eq 'ar' ) {
  1788. $module = "is.pl" if $ref->{invoice};
  1789. $ref->{amount} /= $ref->{exchangerate};
  1790. }
  1791. if ( $ref->{module} eq 'ap' ) {
  1792. $module = "ir.pl" if $ref->{invoice};
  1793. $ref->{amount} /= $ref->{exchangerate};
  1794. }
  1795. if ( $ref->{module} eq 'oe' ) {
  1796. $type =
  1797. ( $ref->{vc} eq 'customer' )
  1798. ? "sales_order"
  1799. : "purchase_order";
  1800. }
  1801. $column_data{id} = {
  1802. text => $ref->{id},
  1803. href => qq|$module?action=edit&id=$ref->{id}&vc=$ref->{vc}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&type=$type&readonly=1|,
  1804. };
  1805. $column_data{repeat} = $repeat;
  1806. $column_data{howmany} =
  1807. $form->format_amount( \%myconfig, $ref->{howmany} );
  1808. $column_data{amount} =
  1809. $form->format_amount( \%myconfig, $ref->{amount}, 2 );
  1810. my @temp_split;
  1811. my @f = split /:/, $ref->{recurringemail};
  1812. for ( 0 .. $#f ) {
  1813. push @temp_split, $f{$f[$_]};
  1814. }
  1815. $column_data{recurringemail} = {
  1816. text => join ':', @temp_split,
  1817. delimeter => ':',
  1818. };
  1819. @temp_split = ();
  1820. @f = split /:/, $ref->{recurringprint};
  1821. for ( 0 .. $#f ) {
  1822. push @temp_split, $f{$f[$_]};
  1823. }
  1824. $column_data{recurringprint} = {
  1825. text => join ':', @temp_split,
  1826. delimeter => ':',
  1827. };
  1828. $j++;
  1829. $j %= 2;
  1830. $column_data{i} = $j;
  1831. push @{$transactions[$#transactions]{transactions}}, \%column_data;
  1832. }
  1833. }
  1834. ##SC: Temporary removal
  1835. ## if ( $form->{lynx} ) {
  1836. ## require "bin/menu.pl";
  1837. ## &menubar;
  1838. ## }
  1839. $hiddens{path} = $form->{path};
  1840. $hiddens{login} = $form->{login};
  1841. $hiddens{sessionid} = $form->{sessionid};
  1842. $hiddens{lastndx} = $k;
  1843. my @buttons;
  1844. push @buttons, {
  1845. name => 'action',
  1846. value => 'process_transactions',
  1847. text => $locale->text('Process Transactions'),
  1848. type => 'submit',
  1849. class => 'submit',
  1850. };
  1851. my $template = LedgerSMB::Template->new_UI(
  1852. user => \%myconfig,
  1853. locale => $locale,
  1854. template => 'am-list-recurring');
  1855. $template->render({
  1856. form => $form,
  1857. buttons => \@buttons,
  1858. columns => \@column_index,
  1859. heading => \%column_header,
  1860. transactions => \@transactions,
  1861. hiddens => \%hiddens,
  1862. });
  1863. }
  1864. sub edit_recurring {
  1865. %links = (
  1866. ar => 'create_links',
  1867. ap => 'create_links',
  1868. gl => 'create_links',
  1869. is => 'invoice_links',
  1870. ir => 'invoice_links',
  1871. oe => 'order_links',
  1872. );
  1873. %prepare = (
  1874. is => 'prepare_invoice',
  1875. ir => 'prepare_invoice',
  1876. oe => 'prepare_order',
  1877. );
  1878. $form->{callback} =
  1879. "$form->{script}?action=recurring_transactions&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  1880. $form->{type} = "transaction";
  1881. if ( $form->{module} eq 'ar' ) {
  1882. if ( $form->{invoice} ) {
  1883. $form->{type} = "invoice";
  1884. $form->{module} = "is";
  1885. }
  1886. }
  1887. if ( $form->{module} eq 'ap' ) {
  1888. if ( $form->{invoice} ) {
  1889. $form->{type} = "invoice";
  1890. $form->{module} = "ir";
  1891. }
  1892. }
  1893. if ( $form->{module} eq 'oe' ) {
  1894. %tr = (
  1895. so => sales_order,
  1896. po => purchase_order,
  1897. );
  1898. $form->{type} = $tr{ $form->{transaction} };
  1899. }
  1900. $form->{script} = "$form->{module}.pl";
  1901. do "bin/$form->{script}";
  1902. &{ $links{ $form->{module} } };
  1903. # return if transaction doesn't exist
  1904. $form->redirect unless $form->{recurring};
  1905. if ( $prepare{ $form->{module} } ) {
  1906. &{ $prepare{ $form->{module} } };
  1907. }
  1908. $form->{selectformat} = qq|<option value="html">html\n|;
  1909. if ( ${LedgerSMB::Sysconfig::latex} ) {
  1910. $form->{selectformat} .= qq|
  1911. <option value="postscript">| . $locale->text('Postscript') . qq|
  1912. <option value="pdf">| . $locale->text('PDF');
  1913. }
  1914. &schedule;
  1915. }
  1916. sub process_transactions {
  1917. # save variables
  1918. my $pt = new Form;
  1919. for ( keys %$form ) { $pt->{$_} = $form->{$_} }
  1920. my $defaultprinter;
  1921. while ( my ( $key, $value ) = each %{LedgerSMB::Sysconfig::printer} ) {
  1922. if ( $value =~ /lpr/ ) {
  1923. $defaultprinter = $key;
  1924. last;
  1925. }
  1926. }
  1927. $myconfig{vclimit} = 0;
  1928. %f = &formnames;
  1929. for ( my $i = 1 ; $i <= $pt->{lastndx} ; $i++ ) {
  1930. if ( $pt->{"ndx_$i"} ) {
  1931. $id = $pt->{"ndx_$i"};
  1932. # process transaction
  1933. AM->recurring_details( \%myconfig, \%$pt, $id );
  1934. $header = $form->{header};
  1935. # reset $form
  1936. for ( keys %$form ) { delete $form->{$_}; }
  1937. for (qw(login path sessionid stylesheet timeout)) {
  1938. $form->{$_} = $pt->{$_};
  1939. }
  1940. $form->{id} = $id;
  1941. $form->{header} = $header;
  1942. $form->db_init(\%myconfig);
  1943. # post, print, email
  1944. if ( $pt->{arid} || $pt->{apid} || $pt->{oeid} ) {
  1945. if ( $pt->{arid} || $pt->{apid} ) {
  1946. if ( $pt->{arid} ) {
  1947. $form->{script} =
  1948. ( $pt->{invoice} ) ? "is.pl" : "ar.pl";
  1949. $form->{ARAP} = "AR";
  1950. $form->{module} = "ar";
  1951. $invfld = "sinumber";
  1952. }
  1953. else {
  1954. $form->{script} =
  1955. ( $pt->{invoice} ) ? "ir.pl" : "ap.pl";
  1956. $form->{ARAP} = "AP";
  1957. $form->{module} = "ap";
  1958. $invfld = "vinumber";
  1959. }
  1960. do "bin/$form->{script}";
  1961. if ( $pt->{invoice} ) {
  1962. &invoice_links;
  1963. &prepare_invoice;
  1964. for ( keys %$form ) {
  1965. $form->{$_} = $form->unquote( $form->{$_} );
  1966. }
  1967. }
  1968. else {
  1969. &create_links;
  1970. $form->{type} = "transaction";
  1971. for ( 1 .. $form->{rowcount} - 1 ) {
  1972. $form->{"amount_$_"} =
  1973. $form->format_amount( \%myconfig,
  1974. $form->{"amount_$_"}, 2 );
  1975. }
  1976. for ( 1 .. $form->{paidaccounts} ) {
  1977. $form->{"paid_$_"} =
  1978. $form->format_amount( \%myconfig,
  1979. $form->{"paid_$_"}, 2 );
  1980. }
  1981. }
  1982. delete $form->{"$form->{ARAP}_links"};
  1983. for (qw(acc_trans invoice_details)) { delete $form->{$_} }
  1984. for (
  1985. qw(department employee language month partsgroup project years)
  1986. )
  1987. {
  1988. delete $form->{"all_$_"};
  1989. }
  1990. $form->{invnumber} = $pt->{reference};
  1991. $form->{transdate} = $pt->{nextdate};
  1992. # tax accounts
  1993. $form->all_taxaccounts( \%myconfig, undef,
  1994. $form->{transdate} );
  1995. # calculate duedate
  1996. $form->{duedate} =
  1997. $form->add_date( \%myconfig, $form->{transdate},
  1998. $pt->{overdue}, "days" );
  1999. if ( $pt->{payment} ) {
  2000. # calculate date paid
  2001. for ( $j = 1 ; $j <= $form->{paidaccounts} ; $j++ ) {
  2002. $form->{"datepaid_$j"} =
  2003. $form->add_date( \%myconfig, $form->{transdate},
  2004. $pt->{paid}, "days" );
  2005. ( $form->{"$form->{ARAP}_paid_$j"} ) = split /--/,
  2006. $form->{"$form->{ARAP}_paid_$j"};
  2007. delete $form->{"cleared_$j"};
  2008. }
  2009. $form->{paidaccounts}++;
  2010. }
  2011. else {
  2012. $form->{paidaccounts} = -1;
  2013. }
  2014. for (qw(id recurring intnotes printed emailed queued)) {
  2015. delete $form->{$_};
  2016. }
  2017. ( $form->{ $form->{ARAP} } ) = split /--/,
  2018. $form->{ $form->{ARAP} };
  2019. $form->{invnumber} =
  2020. $form->update_defaults( \%myconfig, "$invfld" )
  2021. unless $form->{invnumber};
  2022. $form->{reference} = $form->{invnumber};
  2023. for (qw(invnumber reference)) {
  2024. $form->{$_} = $form->unquote( $form->{$_} );
  2025. }
  2026. if ( $pt->{invoice} ) {
  2027. if ( $pt->{arid} ) {
  2028. $form->info(
  2029. "\n"
  2030. . $locale->text(
  2031. 'Posting Sales Invoice [_1]',
  2032. $form->{invnumber}
  2033. )
  2034. );
  2035. $ok = IS->post_invoice( \%myconfig, \%$form );
  2036. }
  2037. else {
  2038. $form->info(
  2039. "\n"
  2040. . $locale->text(
  2041. 'Posting Vendor Invoice [_1]',
  2042. $form->{invnumber}
  2043. )
  2044. );
  2045. $ok = IR->post_invoice( \%myconfig, \%$form );
  2046. }
  2047. }
  2048. else {
  2049. if ( $pt->{arid} ) {
  2050. $form->info(
  2051. "\n"
  2052. . $locale->text(
  2053. 'Posting Transaction [_1]',
  2054. $form->{invnumber}
  2055. )
  2056. );
  2057. }
  2058. else {
  2059. $form->info(
  2060. "\n"
  2061. . $locale->text(
  2062. 'Posting Transaction [_1]',
  2063. $form->{invnumber}
  2064. )
  2065. );
  2066. }
  2067. $ok = AA->post_transaction( \%myconfig, \%$form );
  2068. }
  2069. $form->info( " ..... " . $locale->text('done') );
  2070. # print form
  2071. if ( ${LedgerSMB::Sysconfig::latex} && $ok ) {
  2072. $ok = &print_recurring( \%$pt, $defaultprinter );
  2073. }
  2074. &email_recurring( \%$pt ) if $ok;
  2075. }
  2076. else {
  2077. # order
  2078. $form->{script} = "oe.pl";
  2079. $form->{module} = "oe";
  2080. $ordnumber = "ordnumber";
  2081. if ( $pt->{customer_id} ) {
  2082. $form->{vc} = "customer";
  2083. $form->{type} = "sales_order";
  2084. $ordfld = "sonumber";
  2085. $flabel = $locale->text('Sales Order');
  2086. }
  2087. else {
  2088. $form->{vc} = "vendor";
  2089. $form->{type} = "purchase_order";
  2090. $ordfld = "ponumber";
  2091. $flabel = $locale->text('Purchase Order');
  2092. }
  2093. require "bin/$form->{script}";
  2094. &order_links;
  2095. &prepare_order;
  2096. for ( keys %$form ) {
  2097. $form->{$_} = $form->unquote( $form->{$_} );
  2098. }
  2099. $form->{$ordnumber} = $pt->{reference};
  2100. $form->{transdate} = $pt->{nextdate};
  2101. # calculate reqdate
  2102. $form->{reqdate} =
  2103. $form->add_date( \%myconfig, $form->{transdate},
  2104. $pt->{req}, "days" )
  2105. if $form->{reqdate};
  2106. for (qw(id recurring intnotes printed emailed queued)) {
  2107. delete $form->{$_};
  2108. }
  2109. for ( 1 .. $form->{rowcount} ) {
  2110. delete $form->{"orderitems_id_$_"};
  2111. }
  2112. $form->{$ordnumber} =
  2113. $form->update_defaults( \%myconfig, "$ordfld" )
  2114. unless $form->{$ordnumber};
  2115. $form->{reference} = $form->{$ordnumber};
  2116. for ( "$ordnumber", "reference" ) {
  2117. $form->{$_} = $form->unquote( $form->{$_} );
  2118. }
  2119. $form->{closed} = 0;
  2120. $form->info(
  2121. "\n"
  2122. . $locale->text(
  2123. 'Saving [_1] [_2]',
  2124. $flabel, $form->{$ordnumber}
  2125. )
  2126. );
  2127. if ( $ok = OE->save( \%myconfig, \%$form ) ) {
  2128. $form->info( " ..... " . $locale->text('done') );
  2129. }
  2130. else {
  2131. $form->info( " ..... " . $locale->text('failed') );
  2132. }
  2133. # print form
  2134. if ( ${LedgerSMB::Sysconfig::latex} && $ok ) {
  2135. &print_recurring( \%$pt, $defaultprinter );
  2136. }
  2137. &email_recurring( \%$pt );
  2138. }
  2139. }
  2140. else {
  2141. # GL transaction
  2142. GL->transaction( \%myconfig, \%$form );
  2143. $form->{reference} = $pt->{reference};
  2144. $form->{transdate} = $pt->{nextdate};
  2145. $j = 1;
  2146. foreach $ref ( @{ $form->{GL} } ) {
  2147. $form->{"accno_$j"} = "$ref->{accno}--$ref->{description}";
  2148. $form->{"projectnumber_$j"} =
  2149. "$ref->{projectnumber}--$ref->{project_id}"
  2150. if $ref->{project_id};
  2151. $form->{"fx_transaction_$j"} = $ref->{fx_transaction};
  2152. if ( $ref->{amount} < 0 ) {
  2153. $form->{"debit_$j"} = $ref->{amount} * -1;
  2154. }
  2155. else {
  2156. $form->{"credit_$j"} = $ref->{amount};
  2157. }
  2158. $j++;
  2159. }
  2160. $form->{rowcount} = $j;
  2161. for (qw(id recurring)) { delete $form->{$_} }
  2162. $form->info(
  2163. "\n"
  2164. . $locale->text(
  2165. 'Posting GL Transaction [_1]',
  2166. $form->{reference}
  2167. )
  2168. );
  2169. $ok = GL->post_transaction( \%myconfig, \%$form );
  2170. $form->info( " ..... " . $locale->text('done') );
  2171. }
  2172. AM->update_recurring( \%myconfig, \%$pt, $id ) if $ok;
  2173. }
  2174. }
  2175. $form->{callback} =
  2176. "am.pl?action=recurring_transactions&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&header=$form->{header}";
  2177. $form->redirect;
  2178. }
  2179. sub print_recurring {
  2180. my ( $pt, $defaultprinter ) = @_;
  2181. use List::Util qw(first);
  2182. my %f = &formnames;
  2183. my $ok = 1;
  2184. if ( $pt->{recurringprint} ) {
  2185. my $orig_callback = $form->{callback};
  2186. @f = split /:/, $pt->{recurringprint};
  2187. for ( $j = 0 ; $j <= $#f ; $j += 3 ) {
  2188. $media = $f[ $j + 2 ];
  2189. $media ||= $myconfig->{printer}
  2190. if ${LedgerSMB::Sysconfig::printer}{ $myconfig->{printer} };
  2191. $media ||= $defaultprinter;
  2192. $form->info( "\n"
  2193. . $locale->text('Printing') . " "
  2194. . $locale->text( $f{ $f[$j] } )
  2195. . " $form->{reference}" );
  2196. $form->error( $locale->text('Invalid redirect') )
  2197. unless first { $_ eq $form->{script} }
  2198. @{LedgerSMB::Sysconfig::scripts};
  2199. $form->{callback} = "$form->{script}?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}";
  2200. $ok = !( main::redirect() );
  2201. if ($ok) {
  2202. $form->info( " ..... " . $locale->text('done') );
  2203. }
  2204. else {
  2205. $form->info( " ..... " . $locale->text('failed') );
  2206. last;
  2207. }
  2208. }
  2209. $form->{callback} = $orig_callback;
  2210. }
  2211. $ok;
  2212. }
  2213. sub email_recurring {
  2214. my ($pt) = @_;
  2215. use List::Util qw(first);
  2216. my %f = &formnames;
  2217. my $ok = 1;
  2218. if ( $pt->{recurringemail} ) {
  2219. my $orig_callback = $form->{callback};
  2220. @f = split /:/, $pt->{recurringemail};
  2221. for ( $j = 0 ; $j <= $#f ; $j += 2 ) {
  2222. $form->info( "\n"
  2223. . $locale->text('Sending') . " "
  2224. . $locale->text( $f{ $f[$j] } )
  2225. . " $form->{reference}" );
  2226. # no email, bail out
  2227. if ( !$form->{email} ) {
  2228. $form->info(
  2229. " ..... " . $locale->text('E-mail address missing!') );
  2230. last;
  2231. }
  2232. $message = $form->escape( $pt->{message}, 1 );
  2233. $form->error( $locale->text('Invalid redirect') )
  2234. unless first { $_ eq $form->{script} }
  2235. @{LedgerSMB::Sysconfig::scripts};
  2236. $form->{callback} = "$form->{script}?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";
  2237. $ok = !( main::redirect() );
  2238. if ($ok) {
  2239. $form->info( " ..... " . $locale->text('done') );
  2240. }
  2241. else {
  2242. $form->info( " ..... " . $locale->text('failed') );
  2243. last;
  2244. }
  2245. }
  2246. $form->{callback} = $orig_callback;
  2247. }
  2248. $ok;
  2249. }
  2250. sub formnames {
  2251. # $locale->text('Transaction')
  2252. # $locale->text('Invoice')
  2253. # $locale->text('Credit Invoice')
  2254. # $locale->text('Debit Invoice')
  2255. # $locale->text('Packing List')
  2256. # $locale->text('Pick List')
  2257. # $locale->text('Sales Order')
  2258. # $locale->text('Work Order')
  2259. # $locale->text('Purchase Order')
  2260. # $locale->text('Bin List')
  2261. my %f = (
  2262. transaction => 'Transaction',
  2263. invoice => 'Invoice',
  2264. credit_invoice => 'Credit Invoice',
  2265. debit_invoice => 'Debit Invoice',
  2266. packing_list => 'Packing List',
  2267. pick_list => 'Pick List',
  2268. sales_order => 'Sales Order',
  2269. work_order => 'Work Order',
  2270. purchase_order => 'Purchase Order',
  2271. bin_list => 'Bin List',
  2272. );
  2273. %f;
  2274. }
  2275. sub continue { &{ $form->{nextsub} } }