summaryrefslogtreecommitdiff
path: root/bin/jc.pl
blob: 4f844b13df1d0f2cb27b9d6335c5197c908d6530 (plain)
  1. #=====================================================================
  2. # LedgerSMB Small Medium Business Accounting
  3. # http://www.ledgersmb.org/
  4. #
  5. # Copyright (C) 2006
  6. # This work contains copyrighted information from a number of sources all used
  7. # with permission.
  8. #
  9. # This file contains source code included with or based on SQL-Ledger which
  10. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  11. # under the GNU General Public License version 2 or, at your option, any later
  12. # version. For a full list including contact information of contributors,
  13. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  14. #
  15. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  16. # Copyright (c) 2005
  17. #
  18. # Author: DWS Systems Inc.
  19. # Web: http://www.sql-ledger.org
  20. #
  21. #
  22. #
  23. # This program is free software; you can redistribute it and/or modify
  24. # it under the terms of the GNU General Public License as published by
  25. # the Free Software Foundation; either version 2 of the License, or
  26. # (at your option) any later version.
  27. #
  28. # This program is distributed in the hope that it will be useful,
  29. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  31. # GNU General Public License for more details.
  32. # You should have received a copy of the GNU General Public License
  33. # along with this program; if not, write to the Free Software
  34. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  35. #======================================================================
  36. #
  37. # Job Costing module
  38. #
  39. #======================================================================
  40. use Error qw(:try);
  41. use LedgerSMB::Template;
  42. use LedgerSMB::JC;
  43. 1;
  44. # end of main
  45. sub add {
  46. if ( $form->{type} eq 'timecard' ) {
  47. $form->{title} = $locale->text('Add Time Card');
  48. }
  49. if ( $form->{type} eq 'storescard' ) {
  50. $form->{title} = $locale->text('Add Stores Card');
  51. }
  52. $form->{callback} =
  53. "$form->{script}?action=add&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}&project=$form->{project}"
  54. unless $form->{callback};
  55. &{"prepare_$form->{type}"};
  56. $form->{orphaned} = 1;
  57. &display_form;
  58. }
  59. sub edit {
  60. if ( $form->{type} eq 'timecard' ) {
  61. $form->{title} = $locale->text('Edit Time Card');
  62. }
  63. if ( $form->{type} eq 'storescard' ) {
  64. $form->{title} = $locale->text('Add Stores Card');
  65. }
  66. &{"prepare_$form->{type}"};
  67. &display_form;
  68. }
  69. sub jcitems_links {
  70. if ( @{ $form->{all_project} } ) {
  71. $form->{selectprojectnumber} = "<option>\n";
  72. foreach $ref ( @{ $form->{all_project} } ) {
  73. $form->{selectprojectnumber} .=
  74. qq|<option value="$ref->{projectnumber}--$ref->{id}">$ref->{description} ($ref->{description})</option>\n|;
  75. if ( $form->{projectnumber} eq "$ref->{projectnumber}--$ref->{id}" )
  76. {
  77. $form->{projectdescription} = $ref->{description};
  78. }
  79. }
  80. }
  81. else {
  82. if ( $form->{project} eq 'job' ) {
  83. $form->error( $locale->text('No open Jobs!') );
  84. }
  85. else {
  86. $form->error( $locale->text('No open Projects!') );
  87. }
  88. }
  89. if ( @{ $form->{all_parts} } ) {
  90. $form->{selectpartnumber} = "<option>\n";
  91. foreach $ref ( @{ $form->{all_parts} } ) {
  92. $form->{selectpartnumber} .=
  93. qq|<option value="$ref->{partnumber}--$ref->{id}">$ref->{partnumber}\n|;
  94. if ( $form->{partnumber} eq "$ref->{partnumber}--$ref->{id}" ) {
  95. if ( $form->{partnumber} ne $form->{oldpartnumber} ) {
  96. for (qw(description unit sellprice pricematrix)) {
  97. $form->{$_} = $ref->{$_};
  98. }
  99. }
  100. }
  101. }
  102. }
  103. else {
  104. if ( $form->{type} eq 'timecard' ) {
  105. if ( $form->{project} eq 'job' ) {
  106. $form->error( $locale->text('No Labor codes on file!') );
  107. }
  108. else {
  109. $form->error( $locale->text('No Services on file!') );
  110. }
  111. }
  112. else {
  113. $form->error( $locale->text('No Parts on file!') );
  114. }
  115. }
  116. # employees
  117. if ( @{ $form->{all_employee} } ) {
  118. $form->{selectemployee} = "<option>\n";
  119. for ( @{ $form->{all_employee} } ) {
  120. $form->{selectemployee} .=
  121. qq|<option value="$_->{name}--$_->{id}">$_->{name}\n|;
  122. }
  123. }
  124. else {
  125. $form->error( $locale->text('No Employees on file!') );
  126. }
  127. }
  128. sub search {
  129. # accounting years
  130. $form->all_years( \%myconfig );
  131. if ( @{ $form->{all_years} } ) {
  132. $form->{selectaccountingyear} = "<option>\n";
  133. for ( @{ $form->{all_years} } ) {
  134. $form->{selectaccountingyear} .= qq|<option>$_\n|;
  135. }
  136. $form->{selectaccountingmonth} = "<option>\n";
  137. for ( sort keys %{ $form->{all_month} } ) {
  138. $form->{selectaccountingmonth} .=
  139. qq|<option value=$_>|
  140. . $locale->text( $form->{all_month}{$_} ) . qq|\n|;
  141. }
  142. $selectfrom = qq|
  143. <tr>
  144. <th align=right>| . $locale->text('Period') . qq|</th>
  145. <td colspan=3>
  146. <select name=month>$form->{selectaccountingmonth}</select>
  147. <select name=year>$form->{selectaccountingyear}</select>
  148. <input name=interval class=radio type=radio value=0 checked>&nbsp;|
  149. . $locale->text('Current') . qq|
  150. <input name=interval class=radio type=radio value=1>&nbsp;|
  151. . $locale->text('Month') . qq|
  152. <input name=interval class=radio type=radio value=3>&nbsp;|
  153. . $locale->text('Quarter') . qq|
  154. <input name=interval class=radio type=radio value=12>&nbsp;|
  155. . $locale->text('Year') . qq|
  156. </td>
  157. </tr>
  158. |;
  159. }
  160. $fromto = qq|
  161. <tr>
  162. <th align=right nowrap>| . $locale->text('Startdate') . qq|</th>
  163. <td>|
  164. . $locale->text('From')
  165. . qq| <input class="date" name=startdatefrom size=11 title="$myconfig{dateformat}">
  166. |
  167. . $locale->text('To')
  168. . qq| <input class="date" name=startdateto size=11 title="$myconfig{dateformat}"></td>
  169. </tr>
  170. $selectfrom
  171. |;
  172. if ( $form->{type} eq 'timecard' ) {
  173. $form->{title} = $locale->text('Time Cards');
  174. JC->jcitems_links( \%myconfig, \%$form );
  175. }
  176. if ( $form->{type} eq 'storescard' ) {
  177. $form->{title} = $locale->text('Stores Cards');
  178. JC->jcitems_links( \%myconfig, \%$form );
  179. }
  180. if ( @{ $form->{all_project} } ) {
  181. $form->{selectprojectnumber} = "<option>\n";
  182. for ( @{ $form->{all_project} } ) {
  183. $form->{selectprojectnumber} .=
  184. qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n|;
  185. }
  186. }
  187. if ( @{ $form->{all_parts} } ) {
  188. $form->{selectpartnumber} = "<option>\n";
  189. foreach $ref ( @{ $form->{all_parts} } ) {
  190. $form->{selectpartnumber} .=
  191. qq|<option value="$ref->{partnumber}--$ref->{id}">$ref->{partnumber}\n|;
  192. }
  193. }
  194. if ( $form->{project} eq 'job' ) {
  195. $joblabel = $locale->text('Job Number');
  196. $laborlabel = $locale->text('Labor Code');
  197. }
  198. elsif ( $form->{project} eq 'project' ) {
  199. $joblabel = $locale->text('Project Number');
  200. $laborlabel = $locale->text('Service Code');
  201. }
  202. else {
  203. $joblabel = $locale->text('Project/Job Number');
  204. $laborlabel = $locale->text('Service/Labor Code');
  205. }
  206. if ( $form->{selectprojectnumber} ) {
  207. $jobnumber = qq|
  208. <tr>
  209. <th align=right nowrap>$joblabel</th>
  210. <td colspan=3><select name=projectnumber>$form->{selectprojectnumber}</select></td>
  211. </tr>
  212. |;
  213. }
  214. if ( $form->{type} eq 'timecard' ) {
  215. # employees
  216. if ( @{ $form->{all_employee} } ) {
  217. $form->{selectemployee} = "<option>\n";
  218. for ( @{ $form->{all_employee} } ) {
  219. $form->{selectemployee} .=
  220. qq|<option value="$_->{name}--$_->{id}">$_->{name}\n|;
  221. }
  222. }
  223. else {
  224. $form->error( $locale->text('No Employees on file!') );
  225. }
  226. if ( $form->{selectpartnumber} ) {
  227. $partnumber = qq|
  228. <tr>
  229. <th align=right nowrap>$laborlabel</th>
  230. <td colspan=3><select name=partnumber>$form->{selectpartnumber}</select></td>
  231. </tr>
  232. |;
  233. }
  234. $employee = qq|
  235. <tr>
  236. <th align=right nowrap>| . $locale->text('Employee') . qq|</th>
  237. <td colspan=3><select name=employee>$form->{selectemployee}</select></td>
  238. </tr>
  239. |;
  240. $l_time =
  241. qq|<td nowrap><input name=l_time class=checkbox type=checkbox value=Y>&nbsp;|
  242. . $locale->text('Time')
  243. . qq|</td>|;
  244. }
  245. $form->header;
  246. print qq|
  247. <body>
  248. <form method=post action=$form->{script}>
  249. <table width=100%>
  250. <tr>
  251. <th class=listtop>$form->{title}</th>
  252. </tr>
  253. <tr height="5"></tr>
  254. <tr valign=top>
  255. <td>
  256. <table>
  257. $jobnumber
  258. $partnumber
  259. $employee
  260. $fromto
  261. <tr>
  262. <th align=right nowrap>| . $locale->text('Include in Report') . qq|</th>
  263. <td>
  264. <table>
  265. <tr>
  266. <td nowrap><input name=open class=checkbox type=checkbox value=Y checked> |
  267. . $locale->text('Open')
  268. . qq|</td>
  269. <td nowrap><input name=closed class=checkbox type=checkbox value=Y> |
  270. . $locale->text('Closed')
  271. . qq|</td>
  272. </tr>
  273. <tr>
  274. $l_time
  275. <td nowrap><input name=l_allocated class=checkbox type=checkbox value=Y> |
  276. . $locale->text('Allocated')
  277. . qq|</td>
  278. </tr>
  279. <tr>
  280. <td><input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|
  281. . $locale->text('Subtotal')
  282. . qq|</td>
  283. </tr>
  284. </table>
  285. </td>
  286. </tr>
  287. </table>
  288. </td>
  289. </tr>
  290. <tr>
  291. <td><hr size=3 noshade></td>
  292. </tr>
  293. </table>
  294. <input type=hidden name=nextsub value="list_$form->{type}">
  295. <input type=hidden name=sort value="transdate">
  296. |;
  297. $form->hide_form(qw(db path login sessionid project type));
  298. print qq|
  299. <br>
  300. <button type="submit" class="submit" name="action" value="continue">|
  301. . $locale->text('Continue')
  302. . qq|</button>
  303. </form>
  304. |;
  305. if ( $form->{lynx} ) {
  306. require "bin/menu.pl";
  307. &menubar;
  308. }
  309. print qq|
  310. </body>
  311. </html>
  312. |;
  313. }
  314. sub display_form {
  315. &{"$form->{type}_header"};
  316. &{"$form->{type}_footer"};
  317. }
  318. sub form_header {
  319. &{"$form->{type}_header"};
  320. }
  321. sub form_footer {
  322. &{"form->{type}_footer"};
  323. }
  324. sub prepare_timecard {
  325. $form->{formname} = "timecard";
  326. $form->{format} = "postscript" if $myconfig{printer};
  327. $form->{media} = $myconfig{printer};
  328. JC->get_jcitems( \%myconfig, \%$form );
  329. $form->{selectformname} =
  330. qq|<option value="timecard">| . $locale->text('Time Card');
  331. foreach $item (qw(in out)) {
  332. ( $form->{"${item}hour"}, $form->{"${item}min"}, $form->{"${item}sec"} )
  333. = split /:/, $form->{"checked$item"};
  334. for (qw(hour min sec)) {
  335. if ( ( $form->{"$item$_"} *= 1 ) > 0 ) {
  336. $form->{"$item$_"} = substr( qq|0$form->{"$item$_"}|, -2 );
  337. }
  338. else {
  339. $form->{"$item$_"} ||= "";
  340. }
  341. }
  342. }
  343. $form->{checkedin} =
  344. $form->{inhour} * 3600 + $form->{inmin} * 60 + $form->{insec};
  345. $form->{checkedout} =
  346. $form->{outhour} * 3600 + $form->{outmin} * 60 + $form->{outsec};
  347. if ( $form->{checkedin} > $form->{checkedout} ) {
  348. $form->{checkedout} =
  349. 86400 - ( $form->{checkedin} - $form->{checkedout} );
  350. $form->{checkedin} = 0;
  351. }
  352. $form->{clocked} = ( $form->{checkedout} - $form->{checkedin} ) / 3600;
  353. if ( $form->{clocked} ) {
  354. $form->{oldnoncharge} = $form->{clocked} - $form->{qty};
  355. }
  356. $form->{oldqty} = $form->{qty};
  357. $form->{noncharge} =
  358. $form->format_amount( \%myconfig, $form->{clocked} - $form->{qty}, 4 )
  359. if $form->{checkedin} != $form->{checkedout};
  360. $form->{clocked} = $form->format_amount( \%myconfig, $form->{clocked}, 4 );
  361. $form->{amount} = $form->{sellprice} * $form->{qty};
  362. for (qw(sellprice amount)) {
  363. $form->{$_} = $form->format_amount( \%myconfig, $form->{$_}, 2 );
  364. }
  365. $form->{qty} = $form->format_amount( \%myconfig, $form->{qty}, 4 );
  366. $form->{allocated} = $form->format_amount( \%myconfig, $form->{allocated} );
  367. $form->{employee} .= "--$form->{employee_id}";
  368. $form->{projectnumber} .= "--$form->{project_id}";
  369. $form->{partnumber} .= "--$form->{parts_id}";
  370. $form->{oldpartnumber} = $form->{partnumber};
  371. if ( @{ $form->{all_language} } ) {
  372. $form->{selectlanguage} = "<option>\n";
  373. for ( @{ $form->{all_language} } ) {
  374. $form->{selectlanguage} .=
  375. qq|<option value="$_->{code}">$_->{description}\n|;
  376. }
  377. }
  378. &jcitems_links;
  379. $form->{locked} =
  380. ( $form->{revtrans} )
  381. ? '1'
  382. : ( $form->datetonum( \%myconfig, $form->{transdate} ) <=
  383. $form->datetonum( \%myconfig, $form->{closedto} ) );
  384. $form->{readonly} = 1 if $myconfig{acs} =~ /Production--Add Time Card/;
  385. if ( $form->{income_accno_id} ) {
  386. $form->{locked} = 1 if $form->{production} == $form->{completed};
  387. }
  388. }
  389. sub timecard_header {
  390. # set option selected
  391. for (qw(employee projectnumber partnumber)) {
  392. $form->{"select$_"} =~ s/ selected//;
  393. $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/;
  394. }
  395. $rows = $form->numtextrows( $form->{description}, 50, 8 );
  396. for (qw(transdate checkedin checkedout partnumber)) {
  397. $form->{"old$_"} = $form->{$_};
  398. }
  399. for (qw(partnumber description)) {
  400. $form->{$_} = $form->quote( $form->{$_} );
  401. }
  402. if ( $rows > 1 ) {
  403. $description =
  404. qq|<textarea name=description rows=$rows cols=46 wrap=soft>$form->{description}</textarea>|;
  405. }
  406. else {
  407. $description =
  408. qq|<input name=description size=48 value="$form->{description}">|;
  409. }
  410. if ( $form->{project} eq 'job' ) {
  411. $projectlabel = $locale->text('Job Number');
  412. $laborlabel = $locale->text('Labor Code');
  413. $rate = qq|<input type=hidden name=sellprice value=$form->{sellprice}>|;
  414. }
  415. else {
  416. if ( $form->{project} eq 'project' ) {
  417. $projectlabel = $locale->text('Project Number');
  418. $laborlabel = $locale->text('Service Code');
  419. }
  420. else {
  421. $projectlabel = $locale->text('Project/Job Number');
  422. $laborlabel = $locale->text('Service/Labor Code');
  423. }
  424. if ( $myconfig{role} ne 'user' ) {
  425. $rate = qq|
  426. <tr>
  427. <th align=right nowrap>| . $locale->text('Chargeout Rate') . qq|</th>
  428. <td><input name=sellprice value=$form->{sellprice}></td>
  429. <th align=right nowrap>| . $locale->text('Total') . qq|</th>
  430. <td>$form->{amount}</td>
  431. </tr>
  432. <tr>
  433. <th align=right nowrap>| . $locale->text('Allocated') . qq|</th>
  434. <td><input name=allocated value=$form->{allocated}></td>
  435. </tr>
  436. |;
  437. }
  438. else {
  439. $rate = qq|
  440. <tr>
  441. <th align=right nowrap>| . $locale->text('Chargeout Rate') . qq|</th>
  442. <td>$form->{sellprice}</td>
  443. <th align=right nowrap>| . $locale->text('Total') . qq|</th>
  444. <td>$form->{amount}</td>
  445. </tr>
  446. <tr>
  447. <th align=right nowrap>| . $locale->text('Allocated') . qq|</th>
  448. <td>$form->{allocated}</td>
  449. </tr>
  450. <input type=hidden name=sellprice value=$form->{sellprice}>
  451. <input type=hidden name=allocated value=$form->{allocated}>
  452. |;
  453. }
  454. }
  455. if ( $myconfig{role} eq 'user' ) {
  456. $charge =
  457. qq|<input type=hidden name=qty value=$form->{qty}>$form->{qty}|;
  458. }
  459. else {
  460. $charge = qq|<input name=qty value=$form->{qty}>|;
  461. }
  462. if ( ( $rows = $form->numtextrows( $form->{notes}, 40, 6 ) ) < 2 ) {
  463. $rows = 2;
  464. }
  465. $notes = qq|<tr>
  466. <th align=right>| . $locale->text('Notes') . qq|</th>
  467. <td colspan=3><textarea name="notes" rows=$rows cols=46 wrap=soft>$form->{notes}</textarea>
  468. </td>
  469. </tr>
  470. |;
  471. ##################
  472. ( $null, $form->{oldproject_id} ) = split /--/, $form->{projectnumber};
  473. $form->header;
  474. print qq|
  475. <body>
  476. <form method=post action="$form->{script}">
  477. |;
  478. $form->hide_form(
  479. qw(id type media format printed queued title closedto locked oldtransdate oldcheckedin oldcheckedout oldpartnumber project oldqty oldnoncharge pricematrix oldproject_id)
  480. );
  481. print qq|
  482. <table width=100%>
  483. <tr class=listtop>
  484. <th class=listtop>$form->{title}</th>
  485. </tr>
  486. <tr height="5"></tr>
  487. <tr>
  488. <td>
  489. <table>
  490. <tr>
  491. <td>
  492. <table>
  493. <tr>
  494. <th align=right nowrap>| . $locale->text('Employee') . qq|</th>
  495. <td><select name=employee>$form->{selectemployee}</select></td>
  496. </tr>
  497. <tr>
  498. <th align=right nowrap>$projectlabel</th>
  499. <td><select name=projectnumber>$form->{selectprojectnumber}</select>
  500. </td>
  501. <td></td>
  502. <td>$form->{projectdescription}</td>
  503. <input type=hidden name=projectdescription value="|
  504. . $form->quote( $form->{projectdescription} ) . qq|">
  505. </tr>
  506. <tr>
  507. <th align=right nowrap>| . $locale->text('Date worked') . qq|</th>
  508. <td><input class="date" name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td>
  509. </tr>
  510. <tr>
  511. <th align=right nowrap>$laborlabel</th>
  512. <td><select name=partnumber>$form->{selectpartnumber}</select></td>
  513. </tr>
  514. <tr valign=top>
  515. <th align=right nowrap>| . $locale->text('Description') . qq|</th>
  516. <td colspan=3>$description</td>
  517. </tr>
  518. <tr>
  519. <th align=right nowrap>| . $locale->text('Time In') . qq|</th>
  520. <td>
  521. <table>
  522. <tr>
  523. <td><input name=inhour title="hh" size=3 maxlength=2 value=$form->{inhour}></td>
  524. <td><input name=inmin title="mm" size=3 maxlength=2 value=$form->{inmin}></td>
  525. <td><input name=insec title="ss" size=3 maxlength=2 value=$form->{insec}></td>
  526. </tr>
  527. </table>
  528. </td>
  529. <th align=right nowrap>| . $locale->text('Time Out') . qq|</th>
  530. <td>
  531. <table>
  532. <tr>
  533. <td><input name=outhour title="hh" size=3 maxlength=2 value=$form->{outhour}></td>
  534. <td><input name=outmin title="mm" size=3 maxlength=2 value=$form->{outmin}></td>
  535. <td><input name=outsec title="ss" size=3 maxlength=2 value=$form->{outsec}></td>
  536. </tr>
  537. </table>
  538. </td>
  539. </tr>
  540. <tr>
  541. <th align=right nowrap>| . $locale->text('Clocked') . qq|</th>
  542. <td>$form->{clocked}</td>
  543. </tr>
  544. <tr>
  545. <th align=right nowrap>| . $locale->text('Non-chargeable') . qq|</th>
  546. <td><input name=noncharge value=$form->{noncharge}></td>
  547. </tr>
  548. <tr>
  549. <th align=right nowrap>| . $locale->text('Chargeable') . qq|</th>
  550. <td>$charge</td>
  551. </tr>
  552. $rate
  553. $notes
  554. </table>
  555. </td>
  556. </tr>
  557. |;
  558. }
  559. sub timecard_footer {
  560. print qq|
  561. </table>
  562. </td>
  563. </tr>
  564. <tr>
  565. <td><hr size=3 noshade></td>
  566. </tr>
  567. <tr>
  568. <td>
  569. |;
  570. &print_options;
  571. print qq|
  572. </td>
  573. </tr>
  574. </table>
  575. <br>
  576. |;
  577. $transdate = $form->datetonum( \%myconfig, $form->{transdate} );
  578. $closedto = $form->datetonum( \%myconfig, $form->{closedto} );
  579. if ( !$form->{readonly} ) {
  580. # type=submit $locale->text('Update')
  581. # type=submit $locale->text('Print')
  582. # type=submit $locale->text('Save')
  583. # type=submit $locale->text('Print and Save')
  584. # type=submit $locale->text('Save as new')
  585. # type=submit $locale->text('Print and Save as new')
  586. # type=submit $locale->text('Delete')
  587. %button = (
  588. 'update' =>
  589. { ndx => 1, key => 'U', value => $locale->text('Update') },
  590. 'print' =>
  591. { ndx => 2, key => 'P', value => $locale->text('Print') },
  592. 'save' => { ndx => 3, key => 'S', value => $locale->text('Save') },
  593. 'print_and_save' => {
  594. ndx => 6,
  595. key => 'R',
  596. value => $locale->text('Print and Save')
  597. },
  598. 'save_as_new' =>
  599. { ndx => 7, key => 'N', value => $locale->text('Save as new') },
  600. 'print_and_save_as_new' => {
  601. ndx => 8,
  602. key => 'W',
  603. value => $locale->text('Print and Save as new')
  604. },
  605. 'delete' =>
  606. { ndx => 16, key => 'D', value => $locale->text('Delete') },
  607. );
  608. %a = ();
  609. if ( $form->{id} ) {
  610. if ( !$form->{locked} ) {
  611. for ( 'update', 'print', 'save', 'save_as_new' ) { $a{$_} = 1 }
  612. if ( ${LedgerSMB::Sysconfig::latex} ) {
  613. for ( 'print_and_save', 'print_and_save_as_new' ) {
  614. $a{$_} = 1;
  615. }
  616. }
  617. if ( $form->{orphaned} ) {
  618. $a{'delete'} = 1;
  619. }
  620. }
  621. }
  622. else {
  623. if ( $transdate > $closedto ) {
  624. for ( 'update', 'print', 'save' ) { $a{$_} = 1 }
  625. if ( ${LedgerSMB::Sysconfig::latex} ) {
  626. $a{'print_and_save'} = 1;
  627. }
  628. }
  629. }
  630. }
  631. for ( keys %button ) { delete $button{$_} if !$a{$_} }
  632. for ( sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button ) {
  633. $form->print_button( \%button, $_ );
  634. }
  635. if ( $form->{lynx} ) {
  636. require "bin/menu.pl";
  637. &menubar;
  638. }
  639. $form->hide_form(qw(callback path login sessionid));
  640. print qq|
  641. </form>
  642. </body>
  643. </html>
  644. |;
  645. }
  646. sub prepare_storescard {
  647. $form->{formname} = "storescard";
  648. $form->{format} = "postscript" if $myconfig{printer};
  649. $form->{media} = $myconfig{printer};
  650. JC->get_jcitems( \%myconfig, \%$form );
  651. $form->{selectformname} =
  652. qq|<option value="storescard">| . $locale->text('Stores Card');
  653. $form->{amount} = $form->{sellprice} * $form->{qty};
  654. for (qw(sellprice amount)) {
  655. $form->{$_} = $form->format_amount( \%myconfig, $form->{$_}, 2 );
  656. }
  657. $form->{qty} = $form->format_amount( \%myconfig, $form->{qty}, 4 );
  658. $form->{employee} .= "--$form->{employee_id}";
  659. $form->{projectnumber} .= "--$form->{project_id}";
  660. $form->{partnumber} .= "--$form->{parts_id}";
  661. $form->{oldpartnumber} = $form->{partnumber};
  662. if ( @{ $form->{all_language} } ) {
  663. $form->{selectlanguage} = "<option>\n";
  664. for ( @{ $form->{all_language} } ) {
  665. $form->{selectlanguage} .=
  666. qq|<option value="$_->{code}">$_->{description}\n|;
  667. }
  668. }
  669. &jcitems_links;
  670. $form->{locked} =
  671. ( $form->{revtrans} )
  672. ? '1'
  673. : ( $form->datetonum( \%myconfig, $form->{transdate} ) <=
  674. $form->datetonum( \%myconfig, $form->{closedto} ) );
  675. $form->{readonly} = 1 if $myconfig{acs} =~ /Production--Add Time Card/;
  676. if ( $form->{income_accno_id} ) {
  677. $form->{locked} = 1 if $form->{production} == $form->{completed};
  678. }
  679. }
  680. sub storescard_header {
  681. # set option selected
  682. for (qw(employee projectnumber partnumber)) {
  683. $form->{"select$_"} =~ s/ selected//;
  684. $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/;
  685. }
  686. $rows = $form->numtextrows( $form->{description}, 50, 8 );
  687. for (qw(transdate partnumber)) { $form->{"old$_"} = $form->{$_} }
  688. for (qw(partnumber description)) {
  689. $form->{$_} = $form->quote( $form->{$_} );
  690. }
  691. if ( $rows > 1 ) {
  692. $description =
  693. qq|<textarea name=description rows=$rows cols=46 wrap=soft>$form->{description}</textarea>|;
  694. }
  695. else {
  696. $description =
  697. qq|<input name=description size=48 value="$form->{description}">|;
  698. }
  699. $form->header;
  700. print qq|
  701. <body>
  702. <form method=post action="$form->{script}">
  703. |;
  704. $form->hide_form(
  705. qw(id type media format printed queued title closedto locked oldtransdate oldpartnumber project)
  706. );
  707. print qq|
  708. <table width=100%>
  709. <tr class=listtop>
  710. <th class=listtop>$form->{title}</th>
  711. </tr>
  712. <tr height="5"></tr>
  713. <tr>
  714. <td>
  715. <table>
  716. <tr>
  717. <td>
  718. <table>
  719. <tr>
  720. <th align=right nowrap>| . $locale->text('Job Number') . qq|</th>
  721. <td><select name=projectnumber>$form->{selectprojectnumber}</select>
  722. </td>
  723. <td>$form->{projectdescription}</td>
  724. <input type=hidden name=projectdescription value="|
  725. . $form->quote( $form->{projectdescription} ) . qq|">
  726. </tr>
  727. <tr>
  728. <th align=right nowrap>| . $locale->text('Date') . qq|</th>
  729. <td><input class="date" name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td>
  730. </tr>
  731. <tr>
  732. <th align=right nowrap>| . $locale->text('Part Number') . qq|</th>
  733. <td><select name=partnumber>$form->{selectpartnumber}</td>
  734. </tr>
  735. <tr valign=top>
  736. <th align=right nowrap>| . $locale->text('Description') . qq|</th>
  737. <td>$description</td>
  738. </tr>
  739. <tr>
  740. <th align=right nowrap>| . $locale->text('Qty') . qq|</th>
  741. <td><input name=qty size=6 value=$form->{qty}>
  742. <b>| . $locale->text('Cost') . qq|</b>
  743. <input name=sellprice size=10 value=$form->{sellprice}></td>
  744. </tr>
  745. <tr>
  746. <th align=right nowrap>| . $locale->text('Total') . qq|</th>
  747. <td>$form->{amount}</td>
  748. </tr>
  749. </table>
  750. </td>
  751. </tr>
  752. |;
  753. }
  754. sub storescard_footer {
  755. print qq|
  756. </table>
  757. </td>
  758. </tr>
  759. <tr>
  760. <td><hr size=3 noshade></td>
  761. </tr>
  762. <tr>
  763. <td>
  764. |;
  765. &print_options;
  766. print qq|
  767. </td>
  768. </tr>
  769. </table>
  770. <br>
  771. |;
  772. $transdate = $form->datetonum( \%myconfig, $form->{transdate} );
  773. $closedto = $form->datetonum( \%myconfig, $form->{closedto} );
  774. # type=submit $locale->text('Update')
  775. # type=submit $locale->text('Print')
  776. # type=submit $locale->text('Save')
  777. # type=submit $locale->text('Print and Save')
  778. # type=submit $locale->text('Save as new')
  779. # type=submit $locale->text('Print and Save as new')
  780. # type=submit $locale->text('Delete')
  781. if ( !$form->{readonly} ) {
  782. %button = (
  783. 'update' =>
  784. { ndx => 1, key => 'U', value => $locale->text('Update') },
  785. 'print' =>
  786. { ndx => 2, key => 'P', value => $locale->text('Print') },
  787. 'save' => { ndx => 3, key => 'S', value => $locale->text('Save') },
  788. 'print_and_save' => {
  789. ndx => 6,
  790. key => 'R',
  791. value => $locale->text('Print and Save')
  792. },
  793. 'save_as_new' =>
  794. { ndx => 7, key => 'N', value => $locale->text('Save as new') },
  795. 'print_and_save_as_new' => {
  796. ndx => 8,
  797. key => 'W',
  798. value => $locale->text('Print and Save as new')
  799. },
  800. 'delete' =>
  801. { ndx => 16, key => 'D', value => $locale->text('Delete') },
  802. );
  803. %a = ();
  804. if ( $form->{id} ) {
  805. if ( !$form->{locked} ) {
  806. for ( 'update', 'print', 'save', 'save_as_new' ) { $a{$_} = 1 }
  807. if ( ${LedgerSMB::Sysconfig::latex} ) {
  808. for ( 'print_and_save', 'print_and_save_as_new' ) {
  809. $a{$_} = 1;
  810. }
  811. }
  812. if ( $form->{orphaned} ) {
  813. $a{'delete'} = 1;
  814. }
  815. }
  816. }
  817. else {
  818. if ( $transdate > $closedto ) {
  819. for ( 'update', 'print', 'save' ) { $a{$_} = 1 }
  820. if ( ${LedgerSMB::Sysconfig::latex} ) {
  821. $a{'print_and_save'} = 1;
  822. }
  823. }
  824. }
  825. for ( keys %button ) { delete $button{$_} if !$a{$_} }
  826. for ( sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button )
  827. {
  828. $form->print_button( \%button, $_ );
  829. }
  830. }
  831. if ( $form->{lynx} ) {
  832. require "bin/menu.pl";
  833. &menubar;
  834. }
  835. $form->hide_form(qw(callback path login sessionid));
  836. print qq|
  837. </form>
  838. </body>
  839. </html>
  840. |;
  841. }
  842. sub update {
  843. ( $null, $form->{project_id} ) = split /--/, $form->{projectnumber};
  844. # check labor/part
  845. JC->jcitems_links( \%myconfig, \%$form );
  846. &jcitems_links;
  847. $checkmatrix = 1 if $form->{oldproject_id} != $form->{project_id};
  848. if ( $form->{type} eq 'timecard' ) {
  849. # time clocked
  850. %hour = ( in => 0, out => 0 );
  851. for $t (qw(in out)) {
  852. if ( $form->{"${t}sec"} > 60 ) {
  853. $form->{"${t}sec"} -= 60;
  854. $form->{"${t}min"}++;
  855. }
  856. if ( $form->{"${t}min"} > 60 ) {
  857. $form->{"${t}min"} -= 60;
  858. $form->{"${t}hour"}++;
  859. }
  860. $hour{$t} = $form->{"${t}hour"};
  861. }
  862. $form->{checkedin} =
  863. $hour{in} * 3600 + $form->{inmin} * 60 + $form->{insec};
  864. $form->{checkedout} =
  865. $hour{out} * 3600 + $form->{outmin} * 60 + $form->{outsec};
  866. if ( $form->{checkedin} > $form->{checkedout} ) {
  867. $form->{checkedout} =
  868. 86400 - ( $form->{checkedin} - $form->{checkedout} );
  869. $form->{checkedin} = 0;
  870. }
  871. $form->{clocked} = ( $form->{checkedout} - $form->{checkedin} ) / 3600;
  872. for (qw(sellprice qty noncharge allocated)) {
  873. $form->{$_} = $form->parse_amount( \%myconfig, $form->{$_} );
  874. }
  875. $checkmatrix = 1 if $form->{oldqty} != $form->{qty};
  876. if ( ( $form->{oldcheckedin} != $form->{checkedin} )
  877. || ( $form->{oldcheckedout} != $form->{checkedout} ) )
  878. {
  879. $checkmatrix = 1;
  880. $form->{oldqty} = $form->{qty} =
  881. $form->{clocked} - $form->{noncharge};
  882. $form->{oldnoncharge} = $form->{noncharge};
  883. }
  884. if ( ( $form->{qty} != $form->{oldqty} ) && $form->{clocked} ) {
  885. $form->{oldnoncharge} = $form->{noncharge} =
  886. $form->{clocked} - $form->{qty};
  887. $checkmatrix = 1;
  888. }
  889. if ( ( $form->{oldnoncharge} != $form->{noncharge} )
  890. && $form->{clocked} )
  891. {
  892. $form->{oldqty} = $form->{qty} =
  893. $form->{clocked} - $form->{noncharge};
  894. $checkmatrix = 1;
  895. }
  896. if ($checkmatrix) {
  897. @a = split / /, $form->{pricematrix};
  898. if ( scalar @a > 2 ) {
  899. for (@a) {
  900. ( $q, $p ) = split /:/, $_;
  901. if ( ( $p * 1 ) && ( $form->{qty} >= ( $q * 1 ) ) ) {
  902. $form->{sellprice} = $p;
  903. }
  904. }
  905. }
  906. }
  907. $form->{amount} = $form->{sellprice} * $form->{qty};
  908. $form->{clocked} =
  909. $form->format_amount( \%myconfig, $form->{clocked}, 4 );
  910. for (qw(sellprice amount)) {
  911. $form->{$_} = $form->format_amount( \%myconfig, $form->{$_}, 2 );
  912. }
  913. for (qw(qty noncharge)) {
  914. $form->{"old$_"} = $form->{$_};
  915. $form->{$_} = $form->format_amount( \%myconfig, $form->{$_}, 4 );
  916. }
  917. }
  918. else {
  919. for (qw(sellprice qty allocated)) {
  920. $form->{$_} = $form->parse_amount( \%myconfig, $form->{$_} );
  921. }
  922. if ( $form->{oldqty} != $form->{qty} ) {
  923. @a = split / /, $form->{pricematrix};
  924. if ( scalar @a > 2 ) {
  925. for (@a) {
  926. ( $q, $p ) = split /:/, $_;
  927. if ( ( $p * 1 ) && ( $form->{qty} >= ( $q * 1 ) ) ) {
  928. $form->{sellprice} = $p;
  929. }
  930. }
  931. }
  932. }
  933. $form->{amount} = $form->{sellprice} * $form->{qty};
  934. for (qw(sellprice amount)) {
  935. $form->{$_} = $form->format_amount( \%myconfig, $form->{$_}, 2 );
  936. }
  937. }
  938. $form->{allocated} = $form->format_amount( \%myconfig, $form->{allocated} );
  939. &display_form;
  940. }
  941. sub save {
  942. $form->isblank( "transdate", $locale->text('Date missing!') );
  943. if ( $form->{project} eq 'project' ) {
  944. $form->isblank( "projectnumber",
  945. $locale->text('Project Number missing!') );
  946. $form->isblank( "partnumber", $locale->text('Service Code missing!') );
  947. }
  948. else {
  949. $form->isblank( "projectnumber", $locale->text('Job Number missing!') );
  950. $form->isblank( "partnumber", $locale->text('Labor Code missing!') );
  951. }
  952. $closedto = $form->datetonum( \%myconfig, $form->{closedto} );
  953. $transdate = $form->datetonum( \%myconfig, $form->{transdate} );
  954. $msg =
  955. ( $form->{type} eq 'timecard' )
  956. ? $locale->text('Cannot save time card for a closed period!')
  957. : $locale->text('Cannot save stores card for a closed period!');
  958. $form->error($msg) if ( $transdate <= $closedto );
  959. if ( !$form->{resave} ) {
  960. if ( $form->{id} ) {
  961. &resave;
  962. exit;
  963. }
  964. }
  965. $rc = JC->save( \%myconfig, \%$form );
  966. if ( $form->{type} eq 'timecard' ) {
  967. $form->error(
  968. $locale->text('Cannot change time card for a completed job!') )
  969. if ( $rc == -1 );
  970. $form->error(
  971. $locale->text('Cannot add time card for a completed job!') )
  972. if ( $rc == -2 );
  973. if ($rc) {
  974. $form->redirect( $locale->text('Time Card saved!') );
  975. }
  976. else {
  977. $form->error( $locale->text('Cannot save time card!') );
  978. }
  979. }
  980. else {
  981. $form->error(
  982. $locale->text('Cannot change stores card for a completed job!') )
  983. if ( $rc == -1 );
  984. $form->error(
  985. $locale->text('Cannot add stores card for a completed job!') )
  986. if ( $rc == -2 );
  987. if ($rc) {
  988. $form->redirect( $locale->text('Stores Card saved!') );
  989. }
  990. else {
  991. $form->error( $locale->text('Cannot save stores card!') );
  992. }
  993. }
  994. }
  995. sub save_as_new {
  996. delete $form->{id};
  997. &save;
  998. }
  999. sub print_and_save_as_new {
  1000. delete $form->{id};
  1001. &print_and_save;
  1002. }
  1003. sub resave {
  1004. if ( $form->{print_and_save} ) {
  1005. $form->{nextsub} = "print_and_save";
  1006. $msg =
  1007. $locale->text('You are printing and saving an existing transaction!');
  1008. }
  1009. else {
  1010. $form->{nextsub} = "save";
  1011. $msg = $locale->text('You are saving an existing transaction!');
  1012. }
  1013. $form->{resave} = 1;
  1014. $form->header;
  1015. print qq|
  1016. <body>
  1017. <form method=post action=$form->{script}>
  1018. |;
  1019. delete $form->{action};
  1020. $form->hide_form;
  1021. print qq|
  1022. <h2 class=confirm>| . $locale->text('Warning!') . qq|</h2>
  1023. <h4>$msg</h4>
  1024. <button name="action" class="submit" type="submit" value="continue">|
  1025. . $locale->text('Continue')
  1026. . qq|</button>
  1027. </form>
  1028. </body>
  1029. </html>
  1030. |;
  1031. }
  1032. sub print_and_save {
  1033. $form->error( $locale->text('Select postscript or PDF!') )
  1034. if $form->{format} !~ /(postscript|pdf)/;
  1035. $form->error( $locale->text('Select a Printer!') )
  1036. if $form->{media} eq 'screen';
  1037. if ( !$form->{resave} ) {
  1038. if ( $form->{id} ) {
  1039. $form->{print_and_save} = 1;
  1040. &resave;
  1041. exit;
  1042. }
  1043. }
  1044. $old_form = new Form;
  1045. $form->{display_form} = "save";
  1046. for ( keys %$form ) { $old_form->{$_} = $form->{$_} }
  1047. &{"print_$form->{formname}"}($old_form);
  1048. }
  1049. sub delete_timecard {
  1050. $form->header;
  1051. $employee = $form->{employee};
  1052. $employee =~ s/--.*//g;
  1053. $projectnumber = $form->{projectnumber};
  1054. $projectnumber =~ s/--.*//g;
  1055. print qq|
  1056. <body>
  1057. <form method=post action=$form->{script}>
  1058. |;
  1059. delete $form->{action};
  1060. $form->hide_form;
  1061. print qq|
  1062. <h2 class=confirm>| . $locale->text('Confirm!') . qq|</h2>
  1063. <h4>| . $locale->text('Are you sure you want to delete time card for') . qq|
  1064. <p>$form->{transdate}
  1065. <br>$employee
  1066. <br>$projectnumber
  1067. </h4>
  1068. <p>
  1069. <button name="action" class="submit" type="submit" value="yes">|
  1070. . $locale->text('Yes')
  1071. . qq|</button>
  1072. </form>
  1073. |;
  1074. }
  1075. sub delete { &{"delete_$form->{type}"} }
  1076. sub yes { &{"yes_delete_$form->{type}"} }
  1077. sub yes_delete_timecard {
  1078. if ( JC->delete_timecard( \%myconfig, \%$form ) ) {
  1079. $form->redirect( $locale->text('Time Card deleted!') );
  1080. }
  1081. else {
  1082. $form->error( $locale->text('Cannot delete time card!') );
  1083. }
  1084. }
  1085. sub list_timecard {
  1086. $form->{type} = "timecard";
  1087. JC->jcitems( \%myconfig, \%$form );
  1088. $form->{title} = $locale->text('Time Cards');
  1089. @a =
  1090. qw(type direction oldsort path login sessionid project l_subtotal open closed l_time l_allocated);
  1091. $href = "$form->{script}?action=list_timecard";
  1092. for (@a) { $href .= "&$_=$form->{$_}" }
  1093. $href .= "&title=" . $form->escape( $form->{title} );
  1094. $form->sort_order();
  1095. $callback = "$form->{script}?action=list_timecard";
  1096. for (@a) { $callback .= "&$_=$form->{$_}" }
  1097. $callback .= "&title=" . $form->escape( $form->{title}, 1 );
  1098. @column_index =
  1099. (qw(transdate projectnumber projectdescription id partnumber description)
  1100. );
  1101. push @column_index, (qw(allocated)) if $form->{l_allocated};
  1102. push @column_index, (qw(1 2 3 4 5 6 7));
  1103. @column_index = $form->sort_columns(@column_index);
  1104. if ( $form->{project} eq 'job' ) {
  1105. $joblabel = $locale->text('Job Number');
  1106. $laborlabel = $locale->text('Labor Code');
  1107. $desclabel = $locale->text('Job Name');
  1108. }
  1109. elsif ( $form->{project} eq 'project' ) {
  1110. $joblabel = $locale->text('Project Number');
  1111. $laborlabel = $locale->text('Service Code');
  1112. $desclabel = $locale->text('Project Name');
  1113. }
  1114. else {
  1115. $joblabel = $locale->text('Project/Job Number');
  1116. $laborlabel = $locale->text('Service/Labor Code');
  1117. $desclabel = $locale->text('Project/Job Name');
  1118. }
  1119. if ( $form->{projectnumber} ) {
  1120. $callback .=
  1121. "&projectnumber=" . $form->escape( $form->{projectnumber}, 1 );
  1122. $href .= "&projectnumber=" . $form->escape( $form->{projectnumber} );
  1123. ($var) = split /--/, $form->{projectnumber};
  1124. $option .= "\n<br>" if ($option);
  1125. $option .= "$joblabel : $var";
  1126. @column_index = grep !/projectnumber/, @column_index;
  1127. }
  1128. if ( $form->{partnumber} ) {
  1129. $callback .= "&partnumber=" . $form->escape( $form->{partnumber}, 1 );
  1130. $href .= "&partnumber=" . $form->escape( $form->{partnumber} );
  1131. ($var) = split /--/, $form->{partnumber};
  1132. $option .= "\n<br>" if ($option);
  1133. $option .= "$laborlabel : $var";
  1134. @column_index = grep !/partnumber/, @column_index;
  1135. }
  1136. if ( $form->{employee} ) {
  1137. $callback .= "&employee=" . $form->escape( $form->{employee}, 1 );
  1138. $href .= "&employee=" . $form->escape( $form->{employee} );
  1139. }
  1140. if ( $form->{startdatefrom} ) {
  1141. $callback .= "&startdatefrom=$form->{startdatefrom}";
  1142. $href .= "&startdatefrom=$form->{startdatefrom}";
  1143. $option .= "\n<br>" if ($option);
  1144. $option .=
  1145. $locale->text('From') . "&nbsp;"
  1146. . $locale->date( \%myconfig, $form->{startdatefrom}, 1 );
  1147. }
  1148. if ( $form->{startdateto} ) {
  1149. $callback .= "&startdateto=$form->{startdateto}";
  1150. $href .= "&startdateto=$form->{startdateto}";
  1151. $option .= "\n<br>" if ($option);
  1152. $option .=
  1153. $locale->text('To') . "&nbsp;"
  1154. . $locale->date( \%myconfig, $form->{startdateto}, 1 );
  1155. }
  1156. if ( $form->{open} ) {
  1157. $callback .= "&open=$form->{open}";
  1158. $href .= "&open=$form->{open}";
  1159. $option .= "\n<br>" if ($option);
  1160. $option .= $locale->text('Open');
  1161. }
  1162. if ( $form->{closed} ) {
  1163. $callback .= "&closed=$form->{closed}";
  1164. $href .= "&closed=$form->{closed}";
  1165. $option .= "\n<br>" if ($option);
  1166. $option .= $locale->text('Closed');
  1167. }
  1168. %weekday = (
  1169. 1 => $locale->text('Sunday'),
  1170. 2 => $locale->text('Monday'),
  1171. 3 => $locale->text('Tuesday'),
  1172. 4 => $locale->text('Wednesday'),
  1173. 5 => $locale->text('Thursday'),
  1174. 6 => $locale->text('Friday'),
  1175. 7 => $locale->text('Saturday'),
  1176. );
  1177. for ( keys %weekday ) {
  1178. $column_header{$_} =
  1179. "<th class=listheading width=25>"
  1180. . substr( $weekday{$_}, 0, 3 ) . "</th>";
  1181. }
  1182. $column_header{id} =
  1183. "<th><a class=listheading href=$href&sort=id>"
  1184. . $locale->text('ID')
  1185. . "</a></th>";
  1186. $column_header{transdate} =
  1187. "<th><a class=listheading href=$href&sort=transdate>"
  1188. . $locale->text('Date')
  1189. . "</a></th>";
  1190. $column_header{description} =
  1191. "<th><a class=listheading href=$href&sort=description>"
  1192. . $locale->text('Description') . "</th>";
  1193. $column_header{projectnumber} =
  1194. "<th><a class=listheading href=$href&sort=projectnumber>$joblabel</a></th>";
  1195. $column_header{partnumber} =
  1196. "<th><a class=listheading href=$href&sort=partnumber>$laborlabel</a></th>";
  1197. $column_header{projectdescription} =
  1198. "<th><a class=listheading href=$href&sort=projectdescription>$desclabel</a></th>";
  1199. $column_header{allocated} = "<th class=listheading></th>";
  1200. $form->header;
  1201. if ( @{ $form->{transactions} } ) {
  1202. $sameitem = $form->{transactions}->[0]->{ $form->{sort} };
  1203. $sameemployeenumber = $form->{transactions}->[0]->{employeenumber};
  1204. $employee = $form->{transactions}->[0]->{employee};
  1205. $sameweek = $form->{transactions}->[0]->{workweek};
  1206. }
  1207. print qq|
  1208. <body>
  1209. <table width=100%>
  1210. <tr>
  1211. <th class=listtop>$form->{title}</th>
  1212. </tr>
  1213. <tr height="5"></tr>
  1214. <tr>
  1215. <td>$option</td>
  1216. </tr>
  1217. <tr>
  1218. <td>
  1219. <table width=100%>
  1220. <tr>
  1221. <th colspan=2 align=left>
  1222. $employee
  1223. </th>
  1224. <th align=left>
  1225. $sameemployeenumber
  1226. </th>
  1227. <tr class=listheading>
  1228. |;
  1229. for (@column_index) { print "\n$column_header{$_}" }
  1230. print qq|
  1231. </tr>
  1232. |;
  1233. # add sort and escape callback, this one we use for the add sub
  1234. $form->{callback} = $callback .= "&sort=$form->{sort}";
  1235. # escape callback for href
  1236. $callback = $form->escape($callback);
  1237. # flip direction
  1238. $direction = ( $form->{direction} eq 'ASC' ) ? "ASC" : "DESC";
  1239. $href =~ s/&direction=(\w+)&/&direction=$direction&/;
  1240. %total = ();
  1241. foreach $ref ( @{ $form->{transactions} } ) {
  1242. if ( $sameemployeenumber ne $ref->{employeenumber} ) {
  1243. $sameemployeenumber = $ref->{employeenumber};
  1244. $sameweek = $ref->{workweek};
  1245. if ( $form->{l_subtotal} ) {
  1246. print qq|
  1247. <tr class=listsubtotal>
  1248. |;
  1249. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1250. $weektotal = 0;
  1251. for ( keys %weekday ) {
  1252. $column_data{$_} = "<th class=listsubtotal align=right>"
  1253. . $form->format_amount( \%myconfig, $subtotal{$_}, "",
  1254. "&nbsp;" )
  1255. . "</th>";
  1256. $weektotal += $subtotal{$_};
  1257. $subtotal{$_} = 0;
  1258. }
  1259. $column_data{ $form->{sort} } =
  1260. "<th class=listsubtotal align=right>"
  1261. . $form->format_amount( \%myconfig, $weektotal, "", "&nbsp;" )
  1262. . "</th>";
  1263. for (@column_index) { print "\n$column_data{$_}" }
  1264. }
  1265. # print total
  1266. print qq|
  1267. <tr class=listtotal>
  1268. |;
  1269. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1270. $total = 0;
  1271. for ( keys %weekday ) {
  1272. $column_data{$_} =
  1273. "<th class=listtotal align=right>"
  1274. . $form->format_amount( \%myconfig, $total{$_}, "", "&nbsp;" )
  1275. . "</th>";
  1276. $total += $total{$_};
  1277. $total{$_} = 0;
  1278. }
  1279. $column_data{ $form->{sort} } =
  1280. "<th class=listtotal align=right>"
  1281. . $form->format_amount( \%myconfig, $total, "", "&nbsp;" )
  1282. . "</th>";
  1283. for (@column_index) { print "\n$column_data{$_}" }
  1284. print qq|
  1285. <tr height=30 valign=bottom>
  1286. <th colspan=2 align=left>
  1287. $ref->{employee}
  1288. </th>
  1289. <th align=left>
  1290. $ref->{employeenumber}
  1291. </th>
  1292. <tr class=listheading>
  1293. |;
  1294. for (@column_index) { print "\n$column_header{$_}" }
  1295. print qq|
  1296. </tr>
  1297. |;
  1298. }
  1299. if ( $form->{l_subtotal} ) {
  1300. if ( $ref->{workweek} != $sameweek ) {
  1301. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1302. $weektotal = 0;
  1303. for ( keys %weekday ) {
  1304. $column_data{$_} = "<th class=listsubtotal align=right>"
  1305. . $form->format_amount( \%myconfig, $subtotal{$_}, "",
  1306. "&nbsp;" )
  1307. . "</th>";
  1308. $weektotal += $subtotal{$_};
  1309. $subtotal{$_} = 0;
  1310. }
  1311. $column_data{ $form->{sort} } =
  1312. "<th class=listsubtotal align=right>"
  1313. . $form->format_amount( \%myconfig, $weektotal, "", "&nbsp;" )
  1314. . "</th>";
  1315. $sameweek = $ref->{workweek};
  1316. print qq|
  1317. <tr class=listsubtotal>
  1318. |;
  1319. for (@column_index) { print "\n$column_data{$_}" }
  1320. print qq|
  1321. </tr>
  1322. |;
  1323. }
  1324. }
  1325. for (@column_index) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  1326. for ( keys %weekday ) { $column_data{$_} = "<td>&nbsp;</td>" }
  1327. $column_data{allocated} =
  1328. "<td align=right>"
  1329. . $form->format_amount( \%myconfig, $ref->{allocated}, "", "&nbsp;" )
  1330. . "</td>";
  1331. $column_data{ $ref->{weekday} } =
  1332. "<td align=right>"
  1333. . $form->format_amount( \%myconfig, $ref->{qty}, "", "&nbsp;" );
  1334. if ( $form->{l_time} ) {
  1335. $column_data{ $ref->{weekday} } .=
  1336. "<br>$ref->{checkedin}<br>$ref->{checkedout}";
  1337. }
  1338. $column_data{ $ref->{weekday} } .= "</td>";
  1339. $column_data{id} =
  1340. "<td><a href=$form->{script}?action=edit&id=$ref->{id}&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&project=$form->{project}&callback=$callback>$ref->{id}</a></td>";
  1341. $subtotal{ $ref->{weekday} } += $ref->{qty};
  1342. $total{ $ref->{weekday} } += $ref->{qty};
  1343. $j++;
  1344. $j %= 2;
  1345. print qq|
  1346. <tr class=listrow$j>
  1347. |;
  1348. for (@column_index) { print "\n$column_data{$_}" }
  1349. print qq|
  1350. </tr>
  1351. |;
  1352. }
  1353. # print last subtotal
  1354. if ( $form->{l_subtotal} ) {
  1355. print qq|
  1356. <tr class=listsubtotal>
  1357. |;
  1358. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1359. $weektotal = 0;
  1360. for ( keys %weekday ) {
  1361. $column_data{$_} =
  1362. "<th class=listsubtotal align=right>"
  1363. . $form->format_amount( \%myconfig, $subtotal{$_}, "", "&nbsp;" )
  1364. . "</th>";
  1365. $weektotal += $subtotal{$_};
  1366. }
  1367. $column_data{ $form->{sort} } =
  1368. "<th class=listsubtotal align=right>"
  1369. . $form->format_amount( \%myconfig, $weektotal, "", "&nbsp;" )
  1370. . "</th>";
  1371. for (@column_index) { print "\n$column_data{$_}" }
  1372. }
  1373. # print last total
  1374. print qq|
  1375. <tr class=listtotal>
  1376. |;
  1377. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1378. $total = 0;
  1379. for ( keys %weekday ) {
  1380. $column_data{$_} =
  1381. "<th class=listtotal align=right>"
  1382. . $form->format_amount( \%myconfig, $total{$_}, "", "&nbsp;" )
  1383. . "</th>";
  1384. $total += $total{$_};
  1385. $total{$_} = 0;
  1386. }
  1387. $column_data{ $form->{sort} } =
  1388. "<th class=listtotal align=right>"
  1389. . $form->format_amount( \%myconfig, $total, "", "&nbsp;" ) . "</th>";
  1390. for (@column_index) { print "\n$column_data{$_}" }
  1391. if ( $form->{project} eq 'job' ) {
  1392. if ( $myconfig{acs} !~ /Production--Production/ ) {
  1393. $i = 1;
  1394. $button{'Production--Add Time Card'}{code} =
  1395. qq|<button class="submit" type="submit" name="action" value="add_time_card">|
  1396. . $locale->text('Add Time Card')
  1397. . qq|</button> |;
  1398. $button{'Production--Add Time Card'}{order} = $i++;
  1399. }
  1400. }
  1401. elsif ( $form->{project} eq 'project' ) {
  1402. if ( $myconfig{acs} !~ /Projects--Projects/ ) {
  1403. $i = 1;
  1404. $button{'Projects--Add Time Card'}{code} =
  1405. qq|<button class="submit" type="submit" name="action" value="add_time_card">|
  1406. . $locale->text('Add Time Card')
  1407. . qq|</button> |;
  1408. $button{'Projects--Add Time Card'}{order} = $i++;
  1409. }
  1410. }
  1411. else {
  1412. if ( $myconfig{acs} !~ /Time Cards--Time Cards/ ) {
  1413. $i = 1;
  1414. $button{'Time Cards--Add Time Card'}{code} =
  1415. qq|<button class="submit" type="submit" name="action" value="add_time_card">|
  1416. . $locale->text('Add Time Card')
  1417. . qq|</button> |;
  1418. $button{'Time Cards--Add Time Card'}{order} = $i++;
  1419. }
  1420. }
  1421. for ( split /;/, $myconfig{acs} ) { delete $button{$_} }
  1422. print qq|
  1423. </tr>
  1424. </table>
  1425. </td>
  1426. </tr>
  1427. <tr>
  1428. <td><hr size=3 noshade></td>
  1429. </tr>
  1430. </table>
  1431. <br>
  1432. <form method=post action=$form->{script}>
  1433. |;
  1434. $form->hide_form(qw(callback path login sessionid project));
  1435. foreach $item ( sort { $a->{order} <=> $b->{order} } %button ) {
  1436. print $item->{code};
  1437. }
  1438. if ( $form->{lynx} ) {
  1439. require "bin/menu.pl";
  1440. &menubar;
  1441. }
  1442. print qq|
  1443. </form>
  1444. </body>
  1445. </html>
  1446. |;
  1447. }
  1448. sub list_storescard {
  1449. $form->{type} = "storescard";
  1450. JC->jcitems( \%myconfig, \%$form );
  1451. $form->{title} = $locale->text('Stores Cards');
  1452. $href = "$form->{script}?action=list_storescard";
  1453. for (qw(type direction oldsort path login sessionid project)) {
  1454. $href .= "&$_=$form->{$_}";
  1455. }
  1456. $href .= "&title=" . $form->escape( $form->{title} );
  1457. $form->sort_order();
  1458. $callback = "$form->{script}?action=list_storescard";
  1459. for (qw(type direction oldsort path login sessionid project)) {
  1460. $callback .= "&$_=$form->{$_}";
  1461. }
  1462. $callback .= "&title=" . $form->escape( $form->{title}, 1 );
  1463. @column_index =
  1464. $form->sort_columns(
  1465. qw(transdate projectnumber projectdescription id partnumber description qty amount)
  1466. );
  1467. if ( $form->{projectnumber} ) {
  1468. $callback .=
  1469. "&projectnumber=" . $form->escape( $form->{projectnumber}, 1 );
  1470. $href .= "&projectnumber=" . $form->escape( $form->{projectnumber} );
  1471. ($var) = split /--/, $form->{projectnumber};
  1472. $option .= "\n<br>" if ($option);
  1473. $option .= "$joblabel : $var";
  1474. @column_index = grep !/projectnumber/, @column_index;
  1475. }
  1476. if ( $form->{partnumber} ) {
  1477. $callback .= "&partnumber=" . $form->escape( $form->{partnumber}, 1 );
  1478. $href .= "&partnumber=" . $form->escape( $form->{partnumber} );
  1479. ($var) = split /--/, $form->{partnumber};
  1480. $option .= "\n<br>" if ($option);
  1481. $option .= "$laborlabel : $var";
  1482. @column_index = grep !/partnumber/, @column_index;
  1483. }
  1484. if ( $form->{startdatefrom} ) {
  1485. $callback .= "&startdatefrom=$form->{startdatefrom}";
  1486. $href .= "&startdatefrom=$form->{startdatefrom}";
  1487. $option .= "\n<br>" if ($option);
  1488. $option .=
  1489. $locale->text('From') . "&nbsp;"
  1490. . $locale->date( \%myconfig, $form->{startdatefrom}, 1 );
  1491. }
  1492. if ( $form->{startdateto} ) {
  1493. $callback .= "&startdateto=$form->{startdateto}";
  1494. $href .= "&startdateto=$form->{startdateto}";
  1495. $option .= "\n<br>" if ($option);
  1496. $option .=
  1497. $locale->text('To') . "&nbsp;"
  1498. . $locale->date( \%myconfig, $form->{startdateto}, 1 );
  1499. }
  1500. $column_header{id} =
  1501. "<th><a class=listheading href=$href&sort=id>"
  1502. . $locale->text('ID')
  1503. . "</a></th>";
  1504. $column_header{transdate} =
  1505. "<th><a class=listheading href=$href&sort=transdate>"
  1506. . $locale->text('Date')
  1507. . "</a></th>";
  1508. $column_header{projectnumber} =
  1509. "<th><a class=listheading href=$href&sort=projectnumber>"
  1510. . $locale->text('Job Number')
  1511. . "</a></th>";
  1512. $column_header{projectdescription} =
  1513. "<th><a class=listheading href=$href&sort=projectdescription>"
  1514. . $locale->text('Job Description')
  1515. . "</a></th>";
  1516. $column_header{partnumber} =
  1517. "<th><a class=listheading href=$href&sort=partnumber>"
  1518. . $locale->text('Part Number')
  1519. . "</a></th>";
  1520. $column_header{description} =
  1521. "<th><a class=listheading href=$href&sort=description>"
  1522. . $locale->text('Description')
  1523. . "</a></th>";
  1524. $column_header{qty} =
  1525. "<th class=listheading>" . $locale->text('Qty') . "</th>";
  1526. $column_header{amount} =
  1527. "<th class=listheading>" . $locale->text('Amount') . "</th>";
  1528. $form->header;
  1529. if ( @{ $form->{transactions} } ) {
  1530. $sameitem = $form->{transactions}->[0]->{ $form->{sort} };
  1531. }
  1532. print qq|
  1533. <body>
  1534. <table width=100%>
  1535. <tr>
  1536. <th class=listtop>$form->{title}</th>
  1537. </tr>
  1538. <tr height="5"></tr>
  1539. <tr>
  1540. <td>$option</td>
  1541. </tr>
  1542. <tr>
  1543. <td>
  1544. <table width=100%>
  1545. <tr class=listheading>
  1546. |;
  1547. for (@column_index) { print "\n$column_header{$_}" }
  1548. print qq|
  1549. </tr>
  1550. |;
  1551. # add sort and escape callback, this one we use for the add sub
  1552. $form->{callback} = $callback .= "&sort=$form->{sort}";
  1553. # escape callback for href
  1554. $callback = $form->escape($callback);
  1555. # flip direction
  1556. $direction = ( $form->{direction} eq 'ASC' ) ? "ASC" : "DESC";
  1557. $href =~ s/&direction=(\w+)&/&direction=$direction&/;
  1558. $total = 0;
  1559. foreach $ref ( @{ $form->{transactions} } ) {
  1560. for (@column_index) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  1561. $column_data{qty} =
  1562. qq|<td align=right>|
  1563. . $form->format_amount( \%myconfig, $ref->{qty}, "", "&nbsp;" )
  1564. . "</td>";
  1565. $column_data{amount} =
  1566. qq|<td align=right>|
  1567. . $form->format_amount( \%myconfig, $ref->{qty} * $ref->{sellprice},
  1568. 2 )
  1569. . "</td>";
  1570. $column_data{id} =
  1571. "<td><a href=$form->{script}?action=edit&id=$ref->{id}&type=$form->{type}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&project=$form->{project}&callback=$callback>$ref->{id}</a></td>";
  1572. $total += ( $ref->{qty} * $ref->{sellprice} );
  1573. $j++;
  1574. $j %= 2;
  1575. print qq|
  1576. <tr class=listrow$j>
  1577. |;
  1578. for (@column_index) { print "\n$column_data{$_}" }
  1579. print qq|
  1580. </tr>
  1581. |;
  1582. }
  1583. # print total
  1584. print qq|
  1585. <tr class=listtotal>
  1586. |;
  1587. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1588. $column_data{amount} =
  1589. qq|<th align=right>|
  1590. . $form->format_amount( \%myconfig, $total, 2 ) . "</th";
  1591. for (@column_index) { print "\n$column_data{$_}" }
  1592. if ( $form->{project} eq 'job' ) {
  1593. if ( $myconfig{acs} !~ /Production--Production/ ) {
  1594. $i = 1;
  1595. $button{'Production--Add Stores Card'}{code} =
  1596. qq|<button class="submit" type="submit" name="action" value="add_stores_card">|
  1597. . $locale->text('Add Stores Card')
  1598. . qq|</button> |;
  1599. $button{'Production--Add Stores Card'}{order} = $i++;
  1600. }
  1601. }
  1602. for ( split /;/, $myconfig{acs} ) { delete $button{$_} }
  1603. print qq|
  1604. </tr>
  1605. </table>
  1606. </td>
  1607. </tr>
  1608. <tr>
  1609. <td><hr size=3 noshade></td>
  1610. </tr>
  1611. </table>
  1612. <br>
  1613. <form method=post action=$form->{script}>
  1614. |;
  1615. $form->hide_form(qw(callback path login sessionid project));
  1616. foreach $item ( sort { $a->{order} <=> $b->{order} } %button ) {
  1617. print $item->{code};
  1618. }
  1619. if ( $form->{lynx} ) {
  1620. require "bin/menu.pl";
  1621. &menubar;
  1622. }
  1623. print qq|
  1624. </form>
  1625. </body>
  1626. </html>
  1627. |;
  1628. }
  1629. sub continue { &{ $form->{nextsub} } }
  1630. sub add_time_card {
  1631. $form->{type} = "timecard";
  1632. &add;
  1633. }
  1634. sub add_stores_card {
  1635. $form->{type} = "storescard";
  1636. &add;
  1637. }
  1638. sub print_options {
  1639. if ( $form->{selectlanguage} ) {
  1640. $form->{"selectlanguage"} =
  1641. $form->unescape( $form->{"selectlanguage"} );
  1642. $form->{"selectlanguage"} =~ s/ selected//;
  1643. $form->{"selectlanguage"} =~
  1644. s/(<option value="\Q$form->{language_code}\E")/$1 selected/;
  1645. $lang = qq|<select name=language_code>$form->{selectlanguage}</select>
  1646. <input type=hidden name=selectlanguage value="|
  1647. . $form->escape( $form->{selectlanguage}, 1 ) . qq|">|;
  1648. }
  1649. $form->{selectformname} = $form->unescape( $form->{selectformname} );
  1650. $form->{selectformname} =~ s/ selected//;
  1651. $form->{selectformname} =~
  1652. s/(<option value="\Q$form->{formname}\E")/$1 selected/;
  1653. $type = qq|<select name=formname>$form->{selectformname}</select>
  1654. <input type=hidden name=selectformname value="|
  1655. . $form->escape( $form->{selectformname}, 1 ) . qq|">|;
  1656. $media = qq|<select name=media>
  1657. <option value="screen">| . $locale->text('Screen');
  1658. $form->{selectformat} = qq|<option value="html">html\n|;
  1659. if ( %{LedgerSMB::Sysconfig::printer} && ${LedgerSMB::Sysconfig::latex} ) {
  1660. for ( sort keys %{LedgerSMB::Sysconfig::printer} ) {
  1661. $media .= qq|
  1662. <option value="$_">$_|;
  1663. }
  1664. }
  1665. if ( ${LedgerSMB::Sysconfig::latex} ) {
  1666. $media .= qq|
  1667. <option value="queue">| . $locale->text('Queue');
  1668. $form->{selectformat} .= qq|
  1669. <option value="postscript">| . $locale->text('Postscript') . qq|
  1670. <option value="pdf">| . $locale->text('PDF');
  1671. }
  1672. $format = qq|<select name=format>$form->{selectformat}</select>|;
  1673. $format =~ s/(<option value="\Q$form->{format}\E")/$1 selected/;
  1674. $format .= qq|
  1675. <input type=hidden name=selectformat value="|
  1676. . $form->escape( $form->{selectformat}, 1 ) . qq|">|;
  1677. $media .= qq|</select>|;
  1678. $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/;
  1679. print qq|
  1680. <table width=100%>
  1681. <tr>
  1682. <td>$type</td>
  1683. <td>$lang</td>
  1684. <td>$format</td>
  1685. <td>$media</td>
  1686. <td align=right width=90%>
  1687. |;
  1688. if ( $form->{printed} =~ /$form->{formname}/ ) {
  1689. print $locale->text('Printed') . qq|<br>|;
  1690. }
  1691. if ( $form->{queued} =~ /$form->{formname}/ ) {
  1692. print $locale->text('Queued');
  1693. }
  1694. print qq|
  1695. </td>
  1696. </tr>
  1697. </table>
  1698. |;
  1699. }
  1700. sub print {
  1701. if ( $form->{media} !~ /screen/ ) {
  1702. $form->error( $locale->text('Select postscript or PDF!') )
  1703. if $form->{format} !~ /(postscript|pdf)/;
  1704. $old_form = new Form;
  1705. for ( keys %$form ) { $old_form->{$_} = $form->{$_} }
  1706. }
  1707. &{"print_$form->{formname}"}($old_form);
  1708. }
  1709. sub print_timecard {
  1710. my ($old_form) = @_;
  1711. $display_form =
  1712. ( $form->{display_form} ) ? $form->{display_form} : "update";
  1713. $form->{description} =~ s/^\s+//g;
  1714. for (qw(partnumber projectnumber)) { $form->{$_} =~ s/--.*// }
  1715. @a = qw(hour min sec);
  1716. foreach $item (qw(in out)) {
  1717. for (@a) { $form->{"$item$_"} = substr( qq|00$form->{"$item$_"}|, -2 ) }
  1718. $form->{"checked$item"} =
  1719. qq|$form->{"${item}hour"}:$form->{"${item}min"}:$form->{"${item}sec"}|;
  1720. }
  1721. @a = ();
  1722. for (qw(company address tel fax businessnumber)) {
  1723. $form->{$_} = $myconfig{$_};
  1724. }
  1725. $form->{address} =~ s/\\n/\n/g;
  1726. push @a, qw(partnumber description projectnumber projectdescription);
  1727. push @a, qw(company address tel fax businessnumber username useremail);
  1728. $form->format_string(@a);
  1729. $form->{total} = $form->format_amount(
  1730. \%myconfig,
  1731. $form->parse_amount( \%myconfig, $form->{qty} ) *
  1732. $form->parse_amount( \%myconfig, $form->{sellprice} ),
  1733. 2
  1734. );
  1735. ( $form->{employee}, $form->{employee_id} ) = split /--/, $form->{employee};
  1736. $form->{templates} = "$myconfig{templates}";
  1737. $form->{IN} = "$form->{formname}.html";
  1738. if ( $form->{format} =~ /(postscript|pdf)/ ) {
  1739. $form->{IN} =~ s/html$/tex/;
  1740. }
  1741. if ( $form->{media} !~ /(screen|queue)/ ) {
  1742. $form->{OUT} = ${LedgerSMB::Sysconfig::printer}{ $form->{media} };
  1743. $form->{printmode} = '|-';
  1744. if ( $form->{printed} !~ /$form->{formname}/ ) {
  1745. $form->{printed} .= " $form->{formname}";
  1746. $form->{printed} =~ s/^ //;
  1747. $form->update_status( \%myconfig );
  1748. }
  1749. %audittrail = (
  1750. tablename => jcitems,
  1751. reference => $form->{id},
  1752. formname => $form->{formname},
  1753. action => 'printed',
  1754. id => $form->{id}
  1755. );
  1756. %status = ();
  1757. for (qw(printed queued audittrail)) { $status{$_} = $form->{$_} }
  1758. $status{audittrail} .=
  1759. $form->audittrail( "", \%myconfig, \%audittrail );
  1760. }
  1761. if ( $form->{media} eq 'queue' ) {
  1762. %queued = split / /, $form->{queued};
  1763. if ( $filename = $queued{ $form->{formname} } ) {
  1764. $form->{queued} =~ s/$form->{formname} $filename//;
  1765. unlink "${LedgerSMB::Sysconfig::spool}/$filename";
  1766. $filename =~ s/\..*$//g;
  1767. }
  1768. else {
  1769. $filename = time;
  1770. $filename .= $$;
  1771. }
  1772. $filename .= ( $form->{format} eq 'postscript' ) ? '.ps' : '.pdf';
  1773. $form->{OUT} = "${LedgerSMB::Sysconfig::spool}/$filename";
  1774. $form->{printmode} = '>';
  1775. $form->{queued} = "$form->{formname} $filename";
  1776. $form->update_status( \%myconfig );
  1777. %audittrail = (
  1778. tablename => jcitems,
  1779. reference => $form->{id},
  1780. formname => $form->{formname},
  1781. action => 'queued',
  1782. id => $form->{id}
  1783. );
  1784. %status = ();
  1785. for (qw(printed queued audittrail)) { $status{$_} = $form->{$_} }
  1786. $status{audittrail} .=
  1787. $form->audittrail( "", \%myconfig, \%audittrail );
  1788. }
  1789. my $template = LedgerSMB::Template->new( user => \%myconfig,
  1790. template => $form->{'formname'}, format => uc $form->{format} );
  1791. try {
  1792. $template->render($form);
  1793. $template->output(%{$form});
  1794. }
  1795. catch Error::Simple with {
  1796. my $E = shift;
  1797. $form->error( $E->stacktrace );
  1798. };
  1799. if ( defined %$old_form ) {
  1800. for ( keys %$old_form ) { $form->{$_} = $old_form->{$_} }
  1801. for (qw(printed queued audittrail)) { $form->{$_} = $status{$_} }
  1802. &{"$display_form"};
  1803. }
  1804. }