summaryrefslogtreecommitdiff
path: root/bin/jc.pl
blob: 99288f94dcd0fcf6cc78b7b95cff488bba9f0f87 (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. my %hiddens;
  1005. my @buttons;
  1006. if ( $form->{print_and_save} ) {
  1007. $form->{nextsub} = "print_and_save";
  1008. @buttons = ({
  1009. name => 'action',
  1010. value => 'print_and_save',
  1011. text => $locale->text('Print and Save Transaction'),
  1012. });
  1013. $msg =
  1014. $locale->text('You are printing and saving an existing transaction!');
  1015. }
  1016. else {
  1017. $form->{nextsub} = "save";
  1018. @buttons = ({
  1019. name => 'action',
  1020. value => 'save',
  1021. text => $locale->text('Save Transaction'),
  1022. });
  1023. $msg = $locale->text('You are saving an existing transaction!');
  1024. }
  1025. delete $form->{action};
  1026. $hiddens{$_} = $form->{$_} foreach keys %$form;
  1027. $hiddens{resave} = 1;
  1028. $form->{title} = $locale->text('Warning!');
  1029. my $template = LedgerSMB::Template->new_UI(
  1030. user => \%myconfig,
  1031. locale => $locale,
  1032. template => 'form-confirmation');
  1033. $template->render({
  1034. form => $form,
  1035. buttons => \@buttons,
  1036. hiddens => \%hiddens,
  1037. query => $msg,
  1038. });
  1039. }
  1040. sub print_and_save {
  1041. $form->error( $locale->text('Select postscript or PDF!') )
  1042. if $form->{format} !~ /(postscript|pdf)/;
  1043. $form->error( $locale->text('Select a Printer!') )
  1044. if $form->{media} eq 'screen';
  1045. if ( !$form->{resave} ) {
  1046. if ( $form->{id} ) {
  1047. $form->{print_and_save} = 1;
  1048. &resave;
  1049. exit;
  1050. }
  1051. }
  1052. $old_form = new Form;
  1053. $form->{display_form} = "save";
  1054. for ( keys %$form ) { $old_form->{$_} = $form->{$_} }
  1055. &{"print_$form->{formname}"}($old_form);
  1056. }
  1057. sub delete_timecard {
  1058. my $employee = $form->{employee};
  1059. $employee =~ s/--.*//g;
  1060. my $projectnumber = $form->{projectnumber};
  1061. $projectnumber =~ s/--.*//g;
  1062. delete $form->{action};
  1063. $form->{title} = $locale->text('Confirm!');
  1064. my %hiddens;
  1065. $hiddens{$_} = $form->{$_} foreach keys %$form;
  1066. my @buttons = ({
  1067. name => 'action',
  1068. value => 'yes_delete_timecard',
  1069. text => $locale->text('Delete Timecard'),
  1070. });
  1071. my $template = LedgerSMB::Template->new_UI(
  1072. user => \%myconfig,
  1073. locale => $locale,
  1074. template => 'form-confirmation');
  1075. $template->render({
  1076. form => $form,
  1077. buttons => \@buttons,
  1078. hiddens => \%hiddens,
  1079. query => $locale->text(
  1080. 'Are you sure you want to delete time card for [_1] [_2] [_3]',
  1081. $form->{transdate},
  1082. $employee,
  1083. $projectnumber),
  1084. });
  1085. }
  1086. sub delete { &{"delete_$form->{type}"} }
  1087. sub yes { &{"yes_delete_$form->{type}"} }
  1088. sub yes_delete_timecard {
  1089. if ( JC->delete_timecard( \%myconfig, \%$form ) ) {
  1090. $form->redirect( $locale->text('Time Card deleted!') );
  1091. }
  1092. else {
  1093. $form->error( $locale->text('Cannot delete time card!') );
  1094. }
  1095. }
  1096. sub list_timecard {
  1097. $form->{type} = "timecard";
  1098. JC->jcitems( \%myconfig, \%$form );
  1099. $form->{title} = $locale->text('Time Cards');
  1100. @a =
  1101. qw(type direction oldsort path login sessionid project l_subtotal open closed l_time l_allocated);
  1102. $href = "$form->{script}?action=list_timecard";
  1103. for (@a) { $href .= "&$_=$form->{$_}" }
  1104. $href .= "&title=" . $form->escape( $form->{title} );
  1105. $form->sort_order();
  1106. $callback = "$form->{script}?action=list_timecard";
  1107. for (@a) { $callback .= "&$_=$form->{$_}" }
  1108. $callback .= "&title=" . $form->escape( $form->{title}, 1 );
  1109. @column_index =
  1110. (qw(transdate projectnumber projectdescription id partnumber description)
  1111. );
  1112. push @column_index, (qw(allocated)) if $form->{l_allocated};
  1113. push @column_index, (qw(1 2 3 4 5 6 7));
  1114. @column_index = $form->sort_columns(@column_index);
  1115. if ( $form->{project} eq 'job' ) {
  1116. $joblabel = $locale->text('Job Number');
  1117. $laborlabel = $locale->text('Labor Code');
  1118. $desclabel = $locale->text('Job Name');
  1119. }
  1120. elsif ( $form->{project} eq 'project' ) {
  1121. $joblabel = $locale->text('Project Number');
  1122. $laborlabel = $locale->text('Service Code');
  1123. $desclabel = $locale->text('Project Name');
  1124. }
  1125. else {
  1126. $joblabel = $locale->text('Project/Job Number');
  1127. $laborlabel = $locale->text('Service/Labor Code');
  1128. $desclabel = $locale->text('Project/Job Name');
  1129. }
  1130. if ( $form->{projectnumber} ) {
  1131. $callback .=
  1132. "&projectnumber=" . $form->escape( $form->{projectnumber}, 1 );
  1133. $href .= "&projectnumber=" . $form->escape( $form->{projectnumber} );
  1134. ($var) = split /--/, $form->{projectnumber};
  1135. $option .= "\n<br>" if ($option);
  1136. $option .= "$joblabel : $var";
  1137. @column_index = grep !/projectnumber/, @column_index;
  1138. }
  1139. if ( $form->{partnumber} ) {
  1140. $callback .= "&partnumber=" . $form->escape( $form->{partnumber}, 1 );
  1141. $href .= "&partnumber=" . $form->escape( $form->{partnumber} );
  1142. ($var) = split /--/, $form->{partnumber};
  1143. $option .= "\n<br>" if ($option);
  1144. $option .= "$laborlabel : $var";
  1145. @column_index = grep !/partnumber/, @column_index;
  1146. }
  1147. if ( $form->{employee} ) {
  1148. $callback .= "&employee=" . $form->escape( $form->{employee}, 1 );
  1149. $href .= "&employee=" . $form->escape( $form->{employee} );
  1150. }
  1151. if ( $form->{startdatefrom} ) {
  1152. $callback .= "&startdatefrom=$form->{startdatefrom}";
  1153. $href .= "&startdatefrom=$form->{startdatefrom}";
  1154. $option .= "\n<br>" if ($option);
  1155. $option .=
  1156. $locale->text('From') . "&nbsp;"
  1157. . $locale->date( \%myconfig, $form->{startdatefrom}, 1 );
  1158. }
  1159. if ( $form->{startdateto} ) {
  1160. $callback .= "&startdateto=$form->{startdateto}";
  1161. $href .= "&startdateto=$form->{startdateto}";
  1162. $option .= "\n<br>" if ($option);
  1163. $option .=
  1164. $locale->text('To') . "&nbsp;"
  1165. . $locale->date( \%myconfig, $form->{startdateto}, 1 );
  1166. }
  1167. if ( $form->{open} ) {
  1168. $callback .= "&open=$form->{open}";
  1169. $href .= "&open=$form->{open}";
  1170. $option .= "\n<br>" if ($option);
  1171. $option .= $locale->text('Open');
  1172. }
  1173. if ( $form->{closed} ) {
  1174. $callback .= "&closed=$form->{closed}";
  1175. $href .= "&closed=$form->{closed}";
  1176. $option .= "\n<br>" if ($option);
  1177. $option .= $locale->text('Closed');
  1178. }
  1179. %weekday = (
  1180. 1 => $locale->text('Sunday'),
  1181. 2 => $locale->text('Monday'),
  1182. 3 => $locale->text('Tuesday'),
  1183. 4 => $locale->text('Wednesday'),
  1184. 5 => $locale->text('Thursday'),
  1185. 6 => $locale->text('Friday'),
  1186. 7 => $locale->text('Saturday'),
  1187. );
  1188. for ( keys %weekday ) {
  1189. $column_header{$_} =
  1190. "<th class=listheading width=25>"
  1191. . substr( $weekday{$_}, 0, 3 ) . "</th>";
  1192. }
  1193. $column_header{id} =
  1194. "<th><a class=listheading href=$href&sort=id>"
  1195. . $locale->text('ID')
  1196. . "</a></th>";
  1197. $column_header{transdate} =
  1198. "<th><a class=listheading href=$href&sort=transdate>"
  1199. . $locale->text('Date')
  1200. . "</a></th>";
  1201. $column_header{description} =
  1202. "<th><a class=listheading href=$href&sort=description>"
  1203. . $locale->text('Description') . "</th>";
  1204. $column_header{projectnumber} =
  1205. "<th><a class=listheading href=$href&sort=projectnumber>$joblabel</a></th>";
  1206. $column_header{partnumber} =
  1207. "<th><a class=listheading href=$href&sort=partnumber>$laborlabel</a></th>";
  1208. $column_header{projectdescription} =
  1209. "<th><a class=listheading href=$href&sort=projectdescription>$desclabel</a></th>";
  1210. $column_header{allocated} = "<th class=listheading></th>";
  1211. $form->header;
  1212. if ( @{ $form->{transactions} } ) {
  1213. $sameitem = $form->{transactions}->[0]->{ $form->{sort} };
  1214. $sameemployeenumber = $form->{transactions}->[0]->{employeenumber};
  1215. $employee = $form->{transactions}->[0]->{employee};
  1216. $sameweek = $form->{transactions}->[0]->{workweek};
  1217. }
  1218. print qq|
  1219. <body>
  1220. <table width=100%>
  1221. <tr>
  1222. <th class=listtop>$form->{title}</th>
  1223. </tr>
  1224. <tr height="5"></tr>
  1225. <tr>
  1226. <td>$option</td>
  1227. </tr>
  1228. <tr>
  1229. <td>
  1230. <table width=100%>
  1231. <tr>
  1232. <th colspan=2 align=left>
  1233. $employee
  1234. </th>
  1235. <th align=left>
  1236. $sameemployeenumber
  1237. </th>
  1238. <tr class=listheading>
  1239. |;
  1240. for (@column_index) { print "\n$column_header{$_}" }
  1241. print qq|
  1242. </tr>
  1243. |;
  1244. # add sort and escape callback, this one we use for the add sub
  1245. $form->{callback} = $callback .= "&sort=$form->{sort}";
  1246. # escape callback for href
  1247. $callback = $form->escape($callback);
  1248. # flip direction
  1249. $direction = ( $form->{direction} eq 'ASC' ) ? "ASC" : "DESC";
  1250. $href =~ s/&direction=(\w+)&/&direction=$direction&/;
  1251. %total = ();
  1252. foreach $ref ( @{ $form->{transactions} } ) {
  1253. if ( $sameemployeenumber ne $ref->{employeenumber} ) {
  1254. $sameemployeenumber = $ref->{employeenumber};
  1255. $sameweek = $ref->{workweek};
  1256. if ( $form->{l_subtotal} ) {
  1257. print qq|
  1258. <tr class=listsubtotal>
  1259. |;
  1260. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1261. $weektotal = 0;
  1262. for ( keys %weekday ) {
  1263. $column_data{$_} = "<th class=listsubtotal align=right>"
  1264. . $form->format_amount( \%myconfig, $subtotal{$_}, "",
  1265. "&nbsp;" )
  1266. . "</th>";
  1267. $weektotal += $subtotal{$_};
  1268. $subtotal{$_} = 0;
  1269. }
  1270. $column_data{ $form->{sort} } =
  1271. "<th class=listsubtotal align=right>"
  1272. . $form->format_amount( \%myconfig, $weektotal, "", "&nbsp;" )
  1273. . "</th>";
  1274. for (@column_index) { print "\n$column_data{$_}" }
  1275. }
  1276. # print total
  1277. print qq|
  1278. <tr class=listtotal>
  1279. |;
  1280. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1281. $total = 0;
  1282. for ( keys %weekday ) {
  1283. $column_data{$_} =
  1284. "<th class=listtotal align=right>"
  1285. . $form->format_amount( \%myconfig, $total{$_}, "", "&nbsp;" )
  1286. . "</th>";
  1287. $total += $total{$_};
  1288. $total{$_} = 0;
  1289. }
  1290. $column_data{ $form->{sort} } =
  1291. "<th class=listtotal align=right>"
  1292. . $form->format_amount( \%myconfig, $total, "", "&nbsp;" )
  1293. . "</th>";
  1294. for (@column_index) { print "\n$column_data{$_}" }
  1295. print qq|
  1296. <tr height=30 valign=bottom>
  1297. <th colspan=2 align=left>
  1298. $ref->{employee}
  1299. </th>
  1300. <th align=left>
  1301. $ref->{employeenumber}
  1302. </th>
  1303. <tr class=listheading>
  1304. |;
  1305. for (@column_index) { print "\n$column_header{$_}" }
  1306. print qq|
  1307. </tr>
  1308. |;
  1309. }
  1310. if ( $form->{l_subtotal} ) {
  1311. if ( $ref->{workweek} != $sameweek ) {
  1312. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1313. $weektotal = 0;
  1314. for ( keys %weekday ) {
  1315. $column_data{$_} = "<th class=listsubtotal align=right>"
  1316. . $form->format_amount( \%myconfig, $subtotal{$_}, "",
  1317. "&nbsp;" )
  1318. . "</th>";
  1319. $weektotal += $subtotal{$_};
  1320. $subtotal{$_} = 0;
  1321. }
  1322. $column_data{ $form->{sort} } =
  1323. "<th class=listsubtotal align=right>"
  1324. . $form->format_amount( \%myconfig, $weektotal, "", "&nbsp;" )
  1325. . "</th>";
  1326. $sameweek = $ref->{workweek};
  1327. print qq|
  1328. <tr class=listsubtotal>
  1329. |;
  1330. for (@column_index) { print "\n$column_data{$_}" }
  1331. print qq|
  1332. </tr>
  1333. |;
  1334. }
  1335. }
  1336. for (@column_index) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  1337. for ( keys %weekday ) { $column_data{$_} = "<td>&nbsp;</td>" }
  1338. $column_data{allocated} =
  1339. "<td align=right>"
  1340. . $form->format_amount( \%myconfig, $ref->{allocated}, "", "&nbsp;" )
  1341. . "</td>";
  1342. $column_data{ $ref->{weekday} } =
  1343. "<td align=right>"
  1344. . $form->format_amount( \%myconfig, $ref->{qty}, "", "&nbsp;" );
  1345. if ( $form->{l_time} ) {
  1346. $column_data{ $ref->{weekday} } .=
  1347. "<br>$ref->{checkedin}<br>$ref->{checkedout}";
  1348. }
  1349. $column_data{ $ref->{weekday} } .= "</td>";
  1350. $column_data{id} =
  1351. "<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>";
  1352. $subtotal{ $ref->{weekday} } += $ref->{qty};
  1353. $total{ $ref->{weekday} } += $ref->{qty};
  1354. $j++;
  1355. $j %= 2;
  1356. print qq|
  1357. <tr class=listrow$j>
  1358. |;
  1359. for (@column_index) { print "\n$column_data{$_}" }
  1360. print qq|
  1361. </tr>
  1362. |;
  1363. }
  1364. # print last subtotal
  1365. if ( $form->{l_subtotal} ) {
  1366. print qq|
  1367. <tr class=listsubtotal>
  1368. |;
  1369. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1370. $weektotal = 0;
  1371. for ( keys %weekday ) {
  1372. $column_data{$_} =
  1373. "<th class=listsubtotal align=right>"
  1374. . $form->format_amount( \%myconfig, $subtotal{$_}, "", "&nbsp;" )
  1375. . "</th>";
  1376. $weektotal += $subtotal{$_};
  1377. }
  1378. $column_data{ $form->{sort} } =
  1379. "<th class=listsubtotal align=right>"
  1380. . $form->format_amount( \%myconfig, $weektotal, "", "&nbsp;" )
  1381. . "</th>";
  1382. for (@column_index) { print "\n$column_data{$_}" }
  1383. }
  1384. # print last total
  1385. print qq|
  1386. <tr class=listtotal>
  1387. |;
  1388. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1389. $total = 0;
  1390. for ( keys %weekday ) {
  1391. $column_data{$_} =
  1392. "<th class=listtotal align=right>"
  1393. . $form->format_amount( \%myconfig, $total{$_}, "", "&nbsp;" )
  1394. . "</th>";
  1395. $total += $total{$_};
  1396. $total{$_} = 0;
  1397. }
  1398. $column_data{ $form->{sort} } =
  1399. "<th class=listtotal align=right>"
  1400. . $form->format_amount( \%myconfig, $total, "", "&nbsp;" ) . "</th>";
  1401. for (@column_index) { print "\n$column_data{$_}" }
  1402. if ( $form->{project} eq 'job' ) {
  1403. if ( $myconfig{acs} !~ /Production--Production/ ) {
  1404. $i = 1;
  1405. $button{'Production--Add Time Card'}{code} =
  1406. qq|<button class="submit" type="submit" name="action" value="add_time_card">|
  1407. . $locale->text('Add Time Card')
  1408. . qq|</button> |;
  1409. $button{'Production--Add Time Card'}{order} = $i++;
  1410. }
  1411. }
  1412. elsif ( $form->{project} eq 'project' ) {
  1413. if ( $myconfig{acs} !~ /Projects--Projects/ ) {
  1414. $i = 1;
  1415. $button{'Projects--Add Time Card'}{code} =
  1416. qq|<button class="submit" type="submit" name="action" value="add_time_card">|
  1417. . $locale->text('Add Time Card')
  1418. . qq|</button> |;
  1419. $button{'Projects--Add Time Card'}{order} = $i++;
  1420. }
  1421. }
  1422. else {
  1423. if ( $myconfig{acs} !~ /Time Cards--Time Cards/ ) {
  1424. $i = 1;
  1425. $button{'Time Cards--Add Time Card'}{code} =
  1426. qq|<button class="submit" type="submit" name="action" value="add_time_card">|
  1427. . $locale->text('Add Time Card')
  1428. . qq|</button> |;
  1429. $button{'Time Cards--Add Time Card'}{order} = $i++;
  1430. }
  1431. }
  1432. for ( split /;/, $myconfig{acs} ) { delete $button{$_} }
  1433. print qq|
  1434. </tr>
  1435. </table>
  1436. </td>
  1437. </tr>
  1438. <tr>
  1439. <td><hr size=3 noshade></td>
  1440. </tr>
  1441. </table>
  1442. <br>
  1443. <form method=post action=$form->{script}>
  1444. |;
  1445. $form->hide_form(qw(callback path login sessionid project));
  1446. foreach $item ( sort { $a->{order} <=> $b->{order} } %button ) {
  1447. print $item->{code};
  1448. }
  1449. if ( $form->{lynx} ) {
  1450. require "bin/menu.pl";
  1451. &menubar;
  1452. }
  1453. print qq|
  1454. </form>
  1455. </body>
  1456. </html>
  1457. |;
  1458. }
  1459. sub list_storescard {
  1460. $form->{type} = "storescard";
  1461. JC->jcitems( \%myconfig, \%$form );
  1462. $form->{title} = $locale->text('Stores Cards');
  1463. $href = "$form->{script}?action=list_storescard";
  1464. for (qw(type direction oldsort path login sessionid project)) {
  1465. $href .= "&$_=$form->{$_}";
  1466. }
  1467. $href .= "&title=" . $form->escape( $form->{title} );
  1468. $form->sort_order();
  1469. $callback = "$form->{script}?action=list_storescard";
  1470. for (qw(type direction oldsort path login sessionid project)) {
  1471. $callback .= "&$_=$form->{$_}";
  1472. }
  1473. $callback .= "&title=" . $form->escape( $form->{title}, 1 );
  1474. @column_index =
  1475. $form->sort_columns(
  1476. qw(transdate projectnumber projectdescription id partnumber description qty amount)
  1477. );
  1478. if ( $form->{projectnumber} ) {
  1479. $callback .=
  1480. "&projectnumber=" . $form->escape( $form->{projectnumber}, 1 );
  1481. $href .= "&projectnumber=" . $form->escape( $form->{projectnumber} );
  1482. ($var) = split /--/, $form->{projectnumber};
  1483. $option .= "\n<br>" if ($option);
  1484. $option .= "$joblabel : $var";
  1485. @column_index = grep !/projectnumber/, @column_index;
  1486. }
  1487. if ( $form->{partnumber} ) {
  1488. $callback .= "&partnumber=" . $form->escape( $form->{partnumber}, 1 );
  1489. $href .= "&partnumber=" . $form->escape( $form->{partnumber} );
  1490. ($var) = split /--/, $form->{partnumber};
  1491. $option .= "\n<br>" if ($option);
  1492. $option .= "$laborlabel : $var";
  1493. @column_index = grep !/partnumber/, @column_index;
  1494. }
  1495. if ( $form->{startdatefrom} ) {
  1496. $callback .= "&startdatefrom=$form->{startdatefrom}";
  1497. $href .= "&startdatefrom=$form->{startdatefrom}";
  1498. $option .= "\n<br>" if ($option);
  1499. $option .=
  1500. $locale->text('From') . "&nbsp;"
  1501. . $locale->date( \%myconfig, $form->{startdatefrom}, 1 );
  1502. }
  1503. if ( $form->{startdateto} ) {
  1504. $callback .= "&startdateto=$form->{startdateto}";
  1505. $href .= "&startdateto=$form->{startdateto}";
  1506. $option .= "\n<br>" if ($option);
  1507. $option .=
  1508. $locale->text('To') . "&nbsp;"
  1509. . $locale->date( \%myconfig, $form->{startdateto}, 1 );
  1510. }
  1511. $column_header{id} =
  1512. "<th><a class=listheading href=$href&sort=id>"
  1513. . $locale->text('ID')
  1514. . "</a></th>";
  1515. $column_header{transdate} =
  1516. "<th><a class=listheading href=$href&sort=transdate>"
  1517. . $locale->text('Date')
  1518. . "</a></th>";
  1519. $column_header{projectnumber} =
  1520. "<th><a class=listheading href=$href&sort=projectnumber>"
  1521. . $locale->text('Job Number')
  1522. . "</a></th>";
  1523. $column_header{projectdescription} =
  1524. "<th><a class=listheading href=$href&sort=projectdescription>"
  1525. . $locale->text('Job Description')
  1526. . "</a></th>";
  1527. $column_header{partnumber} =
  1528. "<th><a class=listheading href=$href&sort=partnumber>"
  1529. . $locale->text('Part Number')
  1530. . "</a></th>";
  1531. $column_header{description} =
  1532. "<th><a class=listheading href=$href&sort=description>"
  1533. . $locale->text('Description')
  1534. . "</a></th>";
  1535. $column_header{qty} =
  1536. "<th class=listheading>" . $locale->text('Qty') . "</th>";
  1537. $column_header{amount} =
  1538. "<th class=listheading>" . $locale->text('Amount') . "</th>";
  1539. $form->header;
  1540. if ( @{ $form->{transactions} } ) {
  1541. $sameitem = $form->{transactions}->[0]->{ $form->{sort} };
  1542. }
  1543. print qq|
  1544. <body>
  1545. <table width=100%>
  1546. <tr>
  1547. <th class=listtop>$form->{title}</th>
  1548. </tr>
  1549. <tr height="5"></tr>
  1550. <tr>
  1551. <td>$option</td>
  1552. </tr>
  1553. <tr>
  1554. <td>
  1555. <table width=100%>
  1556. <tr class=listheading>
  1557. |;
  1558. for (@column_index) { print "\n$column_header{$_}" }
  1559. print qq|
  1560. </tr>
  1561. |;
  1562. # add sort and escape callback, this one we use for the add sub
  1563. $form->{callback} = $callback .= "&sort=$form->{sort}";
  1564. # escape callback for href
  1565. $callback = $form->escape($callback);
  1566. # flip direction
  1567. $direction = ( $form->{direction} eq 'ASC' ) ? "ASC" : "DESC";
  1568. $href =~ s/&direction=(\w+)&/&direction=$direction&/;
  1569. $total = 0;
  1570. foreach $ref ( @{ $form->{transactions} } ) {
  1571. for (@column_index) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  1572. $column_data{qty} =
  1573. qq|<td align=right>|
  1574. . $form->format_amount( \%myconfig, $ref->{qty}, "", "&nbsp;" )
  1575. . "</td>";
  1576. $column_data{amount} =
  1577. qq|<td align=right>|
  1578. . $form->format_amount( \%myconfig, $ref->{qty} * $ref->{sellprice},
  1579. 2 )
  1580. . "</td>";
  1581. $column_data{id} =
  1582. "<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>";
  1583. $total += ( $ref->{qty} * $ref->{sellprice} );
  1584. $j++;
  1585. $j %= 2;
  1586. print qq|
  1587. <tr class=listrow$j>
  1588. |;
  1589. for (@column_index) { print "\n$column_data{$_}" }
  1590. print qq|
  1591. </tr>
  1592. |;
  1593. }
  1594. # print total
  1595. print qq|
  1596. <tr class=listtotal>
  1597. |;
  1598. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1599. $column_data{amount} =
  1600. qq|<th align=right>|
  1601. . $form->format_amount( \%myconfig, $total, 2 ) . "</th";
  1602. for (@column_index) { print "\n$column_data{$_}" }
  1603. if ( $form->{project} eq 'job' ) {
  1604. if ( $myconfig{acs} !~ /Production--Production/ ) {
  1605. $i = 1;
  1606. $button{'Production--Add Stores Card'}{code} =
  1607. qq|<button class="submit" type="submit" name="action" value="add_stores_card">|
  1608. . $locale->text('Add Stores Card')
  1609. . qq|</button> |;
  1610. $button{'Production--Add Stores Card'}{order} = $i++;
  1611. }
  1612. }
  1613. for ( split /;/, $myconfig{acs} ) { delete $button{$_} }
  1614. print qq|
  1615. </tr>
  1616. </table>
  1617. </td>
  1618. </tr>
  1619. <tr>
  1620. <td><hr size=3 noshade></td>
  1621. </tr>
  1622. </table>
  1623. <br>
  1624. <form method=post action=$form->{script}>
  1625. |;
  1626. $form->hide_form(qw(callback path login sessionid project));
  1627. foreach $item ( sort { $a->{order} <=> $b->{order} } %button ) {
  1628. print $item->{code};
  1629. }
  1630. if ( $form->{lynx} ) {
  1631. require "bin/menu.pl";
  1632. &menubar;
  1633. }
  1634. print qq|
  1635. </form>
  1636. </body>
  1637. </html>
  1638. |;
  1639. }
  1640. sub continue { &{ $form->{nextsub} } }
  1641. sub add_time_card {
  1642. $form->{type} = "timecard";
  1643. &add;
  1644. }
  1645. sub add_stores_card {
  1646. $form->{type} = "storescard";
  1647. &add;
  1648. }
  1649. sub print_options {
  1650. if ( $form->{selectlanguage} ) {
  1651. $form->{"selectlanguage"} =
  1652. $form->unescape( $form->{"selectlanguage"} );
  1653. $form->{"selectlanguage"} =~ s/ selected//;
  1654. $form->{"selectlanguage"} =~
  1655. s/(<option value="\Q$form->{language_code}\E")/$1 selected/;
  1656. $lang = qq|<select name=language_code>$form->{selectlanguage}</select>
  1657. <input type=hidden name=selectlanguage value="|
  1658. . $form->escape( $form->{selectlanguage}, 1 ) . qq|">|;
  1659. }
  1660. $form->{selectformname} = $form->unescape( $form->{selectformname} );
  1661. $form->{selectformname} =~ s/ selected//;
  1662. $form->{selectformname} =~
  1663. s/(<option value="\Q$form->{formname}\E")/$1 selected/;
  1664. $type = qq|<select name=formname>$form->{selectformname}</select>
  1665. <input type=hidden name=selectformname value="|
  1666. . $form->escape( $form->{selectformname}, 1 ) . qq|">|;
  1667. $media = qq|<select name=media>
  1668. <option value="screen">| . $locale->text('Screen');
  1669. $form->{selectformat} = qq|<option value="html">html\n|;
  1670. if ( %{LedgerSMB::Sysconfig::printer} && ${LedgerSMB::Sysconfig::latex} ) {
  1671. for ( sort keys %{LedgerSMB::Sysconfig::printer} ) {
  1672. $media .= qq|
  1673. <option value="$_">$_|;
  1674. }
  1675. }
  1676. if ( ${LedgerSMB::Sysconfig::latex} ) {
  1677. $media .= qq|
  1678. <option value="queue">| . $locale->text('Queue');
  1679. $form->{selectformat} .= qq|
  1680. <option value="postscript">| . $locale->text('Postscript') . qq|
  1681. <option value="pdf">| . $locale->text('PDF');
  1682. }
  1683. $format = qq|<select name=format>$form->{selectformat}</select>|;
  1684. $format =~ s/(<option value="\Q$form->{format}\E")/$1 selected/;
  1685. $format .= qq|
  1686. <input type=hidden name=selectformat value="|
  1687. . $form->escape( $form->{selectformat}, 1 ) . qq|">|;
  1688. $media .= qq|</select>|;
  1689. $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/;
  1690. print qq|
  1691. <table width=100%>
  1692. <tr>
  1693. <td>$type</td>
  1694. <td>$lang</td>
  1695. <td>$format</td>
  1696. <td>$media</td>
  1697. <td align=right width=90%>
  1698. |;
  1699. if ( $form->{printed} =~ /$form->{formname}/ ) {
  1700. print $locale->text('Printed') . qq|<br>|;
  1701. }
  1702. if ( $form->{queued} =~ /$form->{formname}/ ) {
  1703. print $locale->text('Queued');
  1704. }
  1705. print qq|
  1706. </td>
  1707. </tr>
  1708. </table>
  1709. |;
  1710. }
  1711. sub print {
  1712. if ( $form->{media} !~ /screen/ ) {
  1713. $form->error( $locale->text('Select postscript or PDF!') )
  1714. if $form->{format} !~ /(postscript|pdf)/;
  1715. $old_form = new Form;
  1716. for ( keys %$form ) { $old_form->{$_} = $form->{$_} }
  1717. }
  1718. &{"print_$form->{formname}"}($old_form);
  1719. }
  1720. sub print_timecard {
  1721. my ($old_form) = @_;
  1722. $display_form =
  1723. ( $form->{display_form} ) ? $form->{display_form} : "update";
  1724. $form->{description} =~ s/^\s+//g;
  1725. for (qw(partnumber projectnumber)) { $form->{$_} =~ s/--.*// }
  1726. @a = qw(hour min sec);
  1727. foreach $item (qw(in out)) {
  1728. for (@a) { $form->{"$item$_"} = substr( qq|00$form->{"$item$_"}|, -2 ) }
  1729. $form->{"checked$item"} =
  1730. qq|$form->{"${item}hour"}:$form->{"${item}min"}:$form->{"${item}sec"}|;
  1731. }
  1732. @a = ();
  1733. for (qw(company address tel fax businessnumber)) {
  1734. $form->{$_} = $myconfig{$_};
  1735. }
  1736. $form->{address} =~ s/\\n/\n/g;
  1737. push @a, qw(partnumber description projectnumber projectdescription);
  1738. push @a, qw(company address tel fax businessnumber username useremail);
  1739. $form->format_string(@a);
  1740. $form->{total} = $form->format_amount(
  1741. \%myconfig,
  1742. $form->parse_amount( \%myconfig, $form->{qty} ) *
  1743. $form->parse_amount( \%myconfig, $form->{sellprice} ),
  1744. 2
  1745. );
  1746. ( $form->{employee}, $form->{employee_id} ) = split /--/, $form->{employee};
  1747. $form->{templates} = "$myconfig{templates}";
  1748. $form->{IN} = "$form->{formname}.html";
  1749. if ( $form->{format} =~ /(postscript|pdf)/ ) {
  1750. $form->{IN} =~ s/html$/tex/;
  1751. }
  1752. if ( $form->{media} !~ /(screen|queue)/ ) {
  1753. $form->{OUT} = ${LedgerSMB::Sysconfig::printer}{ $form->{media} };
  1754. $form->{printmode} = '|-';
  1755. if ( $form->{printed} !~ /$form->{formname}/ ) {
  1756. $form->{printed} .= " $form->{formname}";
  1757. $form->{printed} =~ s/^ //;
  1758. $form->update_status( \%myconfig );
  1759. }
  1760. %audittrail = (
  1761. tablename => jcitems,
  1762. reference => $form->{id},
  1763. formname => $form->{formname},
  1764. action => 'printed',
  1765. id => $form->{id}
  1766. );
  1767. %status = ();
  1768. for (qw(printed queued audittrail)) { $status{$_} = $form->{$_} }
  1769. $status{audittrail} .=
  1770. $form->audittrail( "", \%myconfig, \%audittrail );
  1771. }
  1772. if ( $form->{media} eq 'queue' ) {
  1773. %queued = split / /, $form->{queued};
  1774. if ( $filename = $queued{ $form->{formname} } ) {
  1775. $form->{queued} =~ s/$form->{formname} $filename//;
  1776. unlink "${LedgerSMB::Sysconfig::spool}/$filename";
  1777. $filename =~ s/\..*$//g;
  1778. }
  1779. else {
  1780. $filename = time;
  1781. $filename .= $$;
  1782. }
  1783. $filename .= ( $form->{format} eq 'postscript' ) ? '.ps' : '.pdf';
  1784. $form->{OUT} = "${LedgerSMB::Sysconfig::spool}/$filename";
  1785. $form->{printmode} = '>';
  1786. $form->{queued} = "$form->{formname} $filename";
  1787. $form->update_status( \%myconfig );
  1788. %audittrail = (
  1789. tablename => jcitems,
  1790. reference => $form->{id},
  1791. formname => $form->{formname},
  1792. action => 'queued',
  1793. id => $form->{id}
  1794. );
  1795. %status = ();
  1796. for (qw(printed queued audittrail)) { $status{$_} = $form->{$_} }
  1797. $status{audittrail} .=
  1798. $form->audittrail( "", \%myconfig, \%audittrail );
  1799. }
  1800. my $template = LedgerSMB::Template->new( user => \%myconfig,
  1801. template => $form->{'formname'}, format => uc $form->{format} );
  1802. try {
  1803. $template->render($form);
  1804. $template->output(%{$form});
  1805. }
  1806. catch Error::Simple with {
  1807. my $E = shift;
  1808. $form->error( $E->stacktrace );
  1809. };
  1810. if ( defined %$old_form ) {
  1811. for ( keys %$old_form ) { $form->{$_} = $old_form->{$_} }
  1812. for (qw(printed queued audittrail)) { $form->{$_} = $status{$_} }
  1813. &{"$display_form"};
  1814. }
  1815. }