summaryrefslogtreecommitdiff
path: root/bin/mozilla/jc.pl
blob: c4205333e0c4471af46f3e5f84ce0aa16af2825d (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. #
  5. # See COPYRIGHT file for copyright information
  6. #======================================================================
  7. #
  8. # This file has NOT undergone whitespace cleanup.
  9. #
  10. #======================================================================
  11. #
  12. # Job Costing module
  13. #
  14. #======================================================================
  15. use LedgerSMB::JC;
  16. 1;
  17. # end of main
  18. sub add {
  19. if ($form->{type} eq 'timecard') {
  20. $form->{title} = $locale->text('Add Time Card');
  21. }
  22. if ($form->{type} eq 'storescard') {
  23. $form->{title} = $locale->text('Add Stores Card');
  24. }
  25. $form->{callback} = "$form->{script}?action=add&type=$form->{type}&login=$form->{login}&path=$form->{path}&sessionid=$form->{sessionid}&project=$form->{project}" unless $form->{callback};
  26. &{ "prepare_$form->{type}" };
  27. $form->{orphaned} = 1;
  28. &display_form;
  29. }
  30. sub edit {
  31. if ($form->{type} eq 'timecard') {
  32. $form->{title} = $locale->text('Edit Time Card');
  33. }
  34. if ($form->{type} eq 'storescard') {
  35. $form->{title} = $locale->text('Add Stores Card');
  36. }
  37. &{ "prepare_$form->{type}" };
  38. &display_form;
  39. }
  40. sub jcitems_links {
  41. if (@{ $form->{all_project} }) {
  42. $form->{selectprojectnumber} = "<option>\n";
  43. foreach $ref (@{ $form->{all_project} }) {
  44. $form->{selectprojectnumber} .= qq|<option value="$ref->{projectnumber}--$ref->{id}">$ref->{projectnumber}\n|;
  45. if ($form->{projectnumber} eq "$ref->{projectnumber}--$ref->{id}") {
  46. $form->{projectdescription} = $ref->{description};
  47. }
  48. }
  49. } else {
  50. if ($form->{project} eq 'job') {
  51. $form->error($locale->text('No open Jobs!'));
  52. } else {
  53. $form->error($locale->text('No open Projects!'));
  54. }
  55. }
  56. if (@{ $form->{all_parts} }) {
  57. $form->{selectpartnumber} = "<option>\n";
  58. foreach $ref (@{ $form->{all_parts} }) {
  59. $form->{selectpartnumber} .= qq|<option value="$ref->{partnumber}--$ref->{id}">$ref->{partnumber}\n|;
  60. if ($form->{partnumber} eq "$ref->{partnumber}--$ref->{id}") {
  61. if ($form->{partnumber} ne $form->{oldpartnumber}) {
  62. for (qw(description unit sellprice pricematrix)) { $form->{$_} = $ref->{$_} }
  63. }
  64. }
  65. }
  66. } else {
  67. if ($form->{type} eq 'timecard') {
  68. if ($form->{project} eq 'job') {
  69. $form->error($locale->text('No Labor codes on file!'));
  70. } else {
  71. $form->error($locale->text('No Services on file!'));
  72. }
  73. } else {
  74. $form->error($locale->text('No Parts on file!'));
  75. }
  76. }
  77. # employees
  78. if (@{ $form->{all_employee} }) {
  79. $form->{selectemployee} = "<option>\n";
  80. for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| }
  81. } else {
  82. $form->error($locale->text('No Employees on file!'));
  83. }
  84. }
  85. sub search {
  86. # accounting years
  87. $form->all_years(\%myconfig);
  88. if (@{ $form->{all_years} }) {
  89. $form->{selectaccountingyear} = "<option>\n";
  90. for (@{ $form->{all_years} }) { $form->{selectaccountingyear} .= qq|<option>$_\n| }
  91. $form->{selectaccountingmonth} = "<option>\n";
  92. for (sort keys %{ $form->{all_month} }) { $form->{selectaccountingmonth} .= qq|<option value=$_>|.$locale->text($form->{all_month}{$_}).qq|\n| }
  93. $selectfrom = qq|
  94. <tr>
  95. <th align=right>|.$locale->text('Period').qq|</th>
  96. <td colspan=3>
  97. <select name=month>$form->{selectaccountingmonth}</select>
  98. <select name=year>$form->{selectaccountingyear}</select>
  99. <input name=interval class=radio type=radio value=0 checked>&nbsp;|.$locale->text('Current').qq|
  100. <input name=interval class=radio type=radio value=1>&nbsp;|.$locale->text('Month').qq|
  101. <input name=interval class=radio type=radio value=3>&nbsp;|.$locale->text('Quarter').qq|
  102. <input name=interval class=radio type=radio value=12>&nbsp;|.$locale->text('Year').qq|
  103. </td>
  104. </tr>
  105. |;
  106. }
  107. $fromto = qq|
  108. <tr>
  109. <th align=right nowrap>|.$locale->text('Startdate').qq|</th>
  110. <td>|.$locale->text('From').qq| <input name=startdatefrom size=11 title="$myconfig{dateformat}">
  111. |.$locale->text('To').qq| <input name=startdateto size=11 title="$myconfig{dateformat}"></td>
  112. </tr>
  113. $selectfrom
  114. |;
  115. if ($form->{type} eq 'timecard') {
  116. $form->{title} = $locale->text('Time Cards');
  117. JC->jcitems_links(\%myconfig, \%$form);
  118. }
  119. if ($form->{type} eq 'storescard') {
  120. $form->{title} = $locale->text('Stores Cards');
  121. JC->jcitems_links(\%myconfig, \%$form);
  122. }
  123. if (@{ $form->{all_project} }) {
  124. $form->{selectprojectnumber} = "<option>\n";
  125. for (@{ $form->{all_project} }) { $form->{selectprojectnumber} .= qq|<option value="$_->{projectnumber}--$_->{id}">$_->{projectnumber}\n| }
  126. }
  127. if (@{ $form->{all_parts} }) {
  128. $form->{selectpartnumber} = "<option>\n";
  129. foreach $ref (@{ $form->{all_parts} }) {
  130. $form->{selectpartnumber} .= qq|<option value="$ref->{partnumber}--$ref->{id}">$ref->{partnumber}\n|;
  131. }
  132. }
  133. if ($form->{project} eq 'job') {
  134. $joblabel = $locale->text('Job Number');
  135. $laborlabel = $locale->text('Labor Code');
  136. } elsif ($form->{project} eq 'project') {
  137. $joblabel = $locale->text('Project Number');
  138. $laborlabel = $locale->text('Service Code');
  139. } else {
  140. $joblabel = $locale->text('Project/Job Number');
  141. $laborlabel = $locale->text('Service/Labor Code');
  142. }
  143. if ($form->{selectprojectnumber}) {
  144. $jobnumber = qq|
  145. <tr>
  146. <th align=right nowrap>$joblabel</th>
  147. <td colspan=3><select name=projectnumber>$form->{selectprojectnumber}</select></td>
  148. </tr>
  149. |;
  150. }
  151. if ($form->{type} eq 'timecard') {
  152. # employees
  153. if (@{ $form->{all_employee} }) {
  154. $form->{selectemployee} = "<option>\n";
  155. for (@{ $form->{all_employee} }) { $form->{selectemployee} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| }
  156. } else {
  157. $form->error($locale->text('No Employees on file!'));
  158. }
  159. if ($form->{selectpartnumber}) {
  160. $partnumber = qq|
  161. <tr>
  162. <th align=right nowrap>$laborlabel</th>
  163. <td colspan=3><select name=partnumber>$form->{selectpartnumber}</select></td>
  164. </tr>
  165. |;
  166. }
  167. $employee = qq|
  168. <tr>
  169. <th align=right nowrap>|.$locale->text('Employee').qq|</th>
  170. <td colspan=3><select name=employee>$form->{selectemployee}</select></td>
  171. </tr>
  172. |;
  173. $l_time = qq|<td nowrap><input name=l_time class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Time').qq|</td>|;
  174. }
  175. $form->header;
  176. print qq|
  177. <body>
  178. <form method=post action=$form->{script}>
  179. <table width=100%>
  180. <tr>
  181. <th class=listtop>$form->{title}</th>
  182. </tr>
  183. <tr height="5"></tr>
  184. <tr valign=top>
  185. <td>
  186. <table>
  187. $jobnumber
  188. $partnumber
  189. $employee
  190. $fromto
  191. <tr>
  192. <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
  193. <td>
  194. <table>
  195. <tr>
  196. <td nowrap><input name=open class=checkbox type=checkbox value=Y checked> |.$locale->text('Open').qq|</td>
  197. <td nowrap><input name=closed class=checkbox type=checkbox value=Y> |.$locale->text('Closed').qq|</td>
  198. </tr>
  199. <tr>
  200. $l_time
  201. <td nowrap><input name=l_allocated class=checkbox type=checkbox value=Y> |.$locale->text('Allocated').qq|</td>
  202. </tr>
  203. <tr>
  204. <td><input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Subtotal').qq|</td>
  205. </tr>
  206. </table>
  207. </td>
  208. </tr>
  209. </table>
  210. </td>
  211. </tr>
  212. <tr>
  213. <td><hr size=3 noshade></td>
  214. </tr>
  215. </table>
  216. <input type=hidden name=nextsub value="list_$form->{type}">
  217. <input type=hidden name=sort value="transdate">
  218. |;
  219. $form->hide_form(qw(db path login sessionid project type));
  220. print qq|
  221. <br>
  222. <input type=submit class=submit name=action value="|.$locale->text('Continue').qq|">
  223. </form>
  224. |;
  225. if ($form->{menubar}) {
  226. require "$form->{path}/menu.pl";
  227. &menubar;
  228. }
  229. print qq|
  230. </body>
  231. </html>
  232. |;
  233. }
  234. sub display_form {
  235. &{ "$form->{type}_header" };
  236. &{ "$form->{type}_footer" };
  237. }
  238. sub form_header {
  239. &{ "$form->{type}_header" };
  240. }
  241. sub form_footer {
  242. &{ "form->{type}_footer" };
  243. }
  244. sub prepare_timecard {
  245. $form->{formname} = "timecard";
  246. $form->{format} = "postscript" if $myconfig{printer};
  247. $form->{media} = $myconfig{printer};
  248. JC->get_jcitems(\%myconfig, \%$form);
  249. $form->{selectformname} = qq|<option value="timecard">|.$locale->text('Time Card');
  250. foreach $item (qw(in out)) {
  251. ($form->{"${item}hour"}, $form->{"${item}min"}, $form->{"${item}sec"}) = split /:/, $form->{"checked$item"};
  252. for (qw(hour min sec)) {
  253. if (($form->{"$item$_"} *= 1) > 0) {
  254. $form->{"$item$_"} = substr(qq|0$form->{"$item$_"}|,-2);
  255. } else {
  256. $form->{"$item$_"} ||= "";
  257. }
  258. }
  259. }
  260. $form->{checkedin} = $form->{inhour} * 3600 + $form->{inmin} * 60 + $form->{insec};
  261. $form->{checkedout} = $form->{outhour} * 3600 + $form->{outmin} * 60 + $form->{outsec};
  262. if ($form->{checkedin} > $form->{checkedout}) {
  263. $form->{checkedout} = 86400 - ($form->{checkedin} - $form->{checkedout});
  264. $form->{checkedin} = 0;
  265. }
  266. $form->{clocked} = ($form->{checkedout} - $form->{checkedin}) / 3600;
  267. if ($form->{clocked}) {
  268. $form->{oldnoncharge} = $form->{clocked} - $form->{qty};
  269. }
  270. $form->{oldqty} = $form->{qty};
  271. $form->{noncharge} = $form->format_amount(\%myconfig, $form->{clocked} - $form->{qty}, 4) if $form->{checkedin} != $form->{checkedout};
  272. $form->{clocked} = $form->format_amount(\%myconfig, $form->{clocked}, 4);
  273. $form->{amount} = $form->{sellprice} * $form->{qty};
  274. for (qw(sellprice amount)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) }
  275. $form->{qty} = $form->format_amount(\%myconfig, $form->{qty}, 4);
  276. $form->{allocated} = $form->format_amount(\%myconfig, $form->{allocated});
  277. $form->{employee} .= "--$form->{employee_id}";
  278. $form->{projectnumber} .= "--$form->{project_id}";
  279. $form->{partnumber} .= "--$form->{parts_id}";
  280. $form->{oldpartnumber} = $form->{partnumber};
  281. if (@{ $form->{all_language} }) {
  282. $form->{selectlanguage} = "<option>\n";
  283. for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| }
  284. }
  285. &jcitems_links;
  286. $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto}));
  287. $form->{readonly} = 1 if $myconfig{acs} =~ /Production--Add Time Card/;
  288. if ($form->{income_accno_id}) {
  289. $form->{locked} = 1 if $form->{production} == $form->{completed};
  290. }
  291. }
  292. sub timecard_header {
  293. # set option selected
  294. for (qw(employee projectnumber partnumber)) {
  295. $form->{"select$_"} =~ s/ selected//;
  296. $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/;
  297. }
  298. $rows = $form->numtextrows($form->{description}, 50, 8);
  299. for (qw(transdate checkedin checkedout partnumber)) { $form->{"old$_"} = $form->{$_} }
  300. for (qw(partnumber description)) { $form->{$_} = $form->quote($form->{$_}) }
  301. if ($rows > 1) {
  302. $description = qq|<textarea name=description rows=$rows cols=46 wrap=soft>$form->{description}</textarea>|;
  303. } else {
  304. $description = qq|<input name=description size=48 value="$form->{description}">|;
  305. }
  306. if ($form->{project} eq 'job') {
  307. $projectlabel = $locale->text('Job Number');
  308. $laborlabel = $locale->text('Labor Code');
  309. $rate = qq|<input type=hidden name=sellprice value=$form->{sellprice}>|;
  310. } else {
  311. if ($form->{project} eq 'project') {
  312. $projectlabel = $locale->text('Project Number');
  313. $laborlabel = $locale->text('Service Code');
  314. } else {
  315. $projectlabel = $locale->text('Project/Job Number');
  316. $laborlabel = $locale->text('Service/Labor Code');
  317. }
  318. if ($myconfig{role} ne 'user') {
  319. $rate = qq|
  320. <tr>
  321. <th align=right nowrap>|.$locale->text('Chargeout Rate').qq|</th>
  322. <td><input name=sellprice value=$form->{sellprice}></td>
  323. <th align=right nowrap>|.$locale->text('Total').qq|</th>
  324. <td>$form->{amount}</td>
  325. </tr>
  326. <tr>
  327. <th align=right nowrap>|.$locale->text('Allocated').qq|</th>
  328. <td><input name=allocated value=$form->{allocated}></td>
  329. </tr>
  330. |;
  331. } else {
  332. $rate = qq|
  333. <tr>
  334. <th align=right nowrap>|.$locale->text('Chargeout Rate').qq|</th>
  335. <td>$form->{sellprice}</td>
  336. <th align=right nowrap>|.$locale->text('Total').qq|</th>
  337. <td>$form->{amount}</td>
  338. </tr>
  339. <tr>
  340. <th align=right nowrap>|.$locale->text('Allocated').qq|</th>
  341. <td>$form->{allocated}</td>
  342. </tr>
  343. <input type=hidden name=sellprice value=$form->{sellprice}>
  344. <input type=hidden name=allocated value=$form->{allocated}>
  345. |;
  346. }
  347. }
  348. if ($myconfig{role} eq 'user') {
  349. $charge = qq|<input type=hidden name=qty value=$form->{qty}>$form->{qty}|;
  350. } else {
  351. $charge = qq|<input name=qty value=$form->{qty}>|;
  352. }
  353. if (($rows = $form->numtextrows($form->{notes}, 40, 6)) < 2) {
  354. $rows = 2;
  355. }
  356. $notes = qq|<tr>
  357. <th align=right>|.$locale->text('Notes').qq|</th>
  358. <td colspan=3><textarea name="notes" rows=$rows cols=46 wrap=soft>$form->{notes}</textarea>
  359. </td>
  360. </tr>
  361. |;
  362. ##################
  363. ($null, $form->{oldproject_id}) = split /--/, $form->{projectnumber};
  364. $form->header;
  365. print qq|
  366. <body>
  367. <form method=post action="$form->{script}">
  368. |;
  369. $form->hide_form(qw(id type media format printed queued title closedto locked oldtransdate oldcheckedin oldcheckedout oldpartnumber project oldqty oldnoncharge pricematrix oldproject_id));
  370. print qq|
  371. <table width=100%>
  372. <tr class=listtop>
  373. <th class=listtop>$form->{title}</th>
  374. </tr>
  375. <tr height="5"></tr>
  376. <tr>
  377. <td>
  378. <table>
  379. <tr>
  380. <td>
  381. <table>
  382. <tr>
  383. <th align=right nowrap>|.$locale->text('Employee').qq|</th>
  384. <td><select name=employee>$form->{selectemployee}</select></td>
  385. </tr>
  386. <tr>
  387. <th align=right nowrap>$projectlabel</th>
  388. <td><select name=projectnumber>$form->{selectprojectnumber}</select>
  389. </td>
  390. <td></td>
  391. <td>$form->{projectdescription}</td>
  392. <input type=hidden name=projectdescription value="|.$form->quote($form->{projectdescription}).qq|">
  393. </tr>
  394. <tr>
  395. <th align=right nowrap>|.$locale->text('Date worked').qq|</th>
  396. <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td>
  397. </tr>
  398. <tr>
  399. <th align=right nowrap>$laborlabel</th>
  400. <td><select name=partnumber>$form->{selectpartnumber}</select></td>
  401. </tr>
  402. <tr valign=top>
  403. <th align=right nowrap>|.$locale->text('Description').qq|</th>
  404. <td colspan=3>$description</td>
  405. </tr>
  406. <tr>
  407. <th align=right nowrap>|.$locale->text('Time In').qq|</th>
  408. <td>
  409. <table>
  410. <tr>
  411. <td><input name=inhour title="hh" size=3 maxlength=2 value=$form->{inhour}></td>
  412. <td><input name=inmin title="mm" size=3 maxlength=2 value=$form->{inmin}></td>
  413. <td><input name=insec title="ss" size=3 maxlength=2 value=$form->{insec}></td>
  414. </tr>
  415. </table>
  416. </td>
  417. <th align=right nowrap>|.$locale->text('Time Out').qq|</th>
  418. <td>
  419. <table>
  420. <tr>
  421. <td><input name=outhour title="hh" size=3 maxlength=2 value=$form->{outhour}></td>
  422. <td><input name=outmin title="mm" size=3 maxlength=2 value=$form->{outmin}></td>
  423. <td><input name=outsec title="ss" size=3 maxlength=2 value=$form->{outsec}></td>
  424. </tr>
  425. </table>
  426. </td>
  427. </tr>
  428. <tr>
  429. <th align=right nowrap>|.$locale->text('Clocked').qq|</th>
  430. <td>$form->{clocked}</td>
  431. </tr>
  432. <tr>
  433. <th align=right nowrap>|.$locale->text('Non-chargeable').qq|</th>
  434. <td><input name=noncharge value=$form->{noncharge}></td>
  435. </tr>
  436. <tr>
  437. <th align=right nowrap>|.$locale->text('Chargeable').qq|</th>
  438. <td>$charge</td>
  439. </tr>
  440. $rate
  441. $notes
  442. </table>
  443. </td>
  444. </tr>
  445. |;
  446. }
  447. sub timecard_footer {
  448. print qq|
  449. </table>
  450. </td>
  451. </tr>
  452. <tr>
  453. <td><hr size=3 noshade></td>
  454. </tr>
  455. <tr>
  456. <td>
  457. |;
  458. &print_options;
  459. print qq|
  460. </td>
  461. </tr>
  462. </table>
  463. <br>
  464. |;
  465. $transdate = $form->datetonum(\%myconfig, $form->{transdate});
  466. $closedto = $form->datetonum(\%myconfig, $form->{closedto});
  467. if (! $form->{readonly}) {
  468. # type=submit $locale->text('Update')
  469. # type=submit $locale->text('Print')
  470. # type=submit $locale->text('Save')
  471. # type=submit $locale->text('Print and Save')
  472. # type=submit $locale->text('Save as new')
  473. # type=submit $locale->text('Print and Save as new')
  474. # type=submit $locale->text('Delete')
  475. %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') },
  476. 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') },
  477. 'Save' => { ndx => 3, key => 'S', value => $locale->text('Save') },
  478. 'Print and Save' => { ndx => 6, key => 'R', value => $locale->text('Print and Save') },
  479. 'Save as new' => { ndx => 7, key => 'N', value => $locale->text('Save as new') },
  480. 'Print and Save as new' => { ndx => 8, key => 'W', value => $locale->text('Print and Save as new') },
  481. 'Delete' => { ndx => 16, key => 'D', value => $locale->text('Delete') },
  482. );
  483. %a = ();
  484. if ($form->{id}) {
  485. if (!$form->{locked}) {
  486. for ('Update', 'Print', 'Save', 'Save as new') { $a{$_} = 1 }
  487. if ($latex) {
  488. for ('Print and Save', 'Print and Save as new') { $a{$_} = 1 }
  489. }
  490. if ($form->{orphaned}) {
  491. $a{'Delete'} = 1;
  492. }
  493. }
  494. } else {
  495. if ($transdate > $closedto) {
  496. for ('Update', 'Print', 'Save') { $a{$_} = 1 }
  497. if ($latex) {
  498. $a{'Print and Save'} = 1;
  499. }
  500. }
  501. }
  502. }
  503. for (keys %button) { delete $button{$_} if ! $a{$_} }
  504. for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) }
  505. if ($form->{menubar}) {
  506. require "$form->{path}/menu.pl";
  507. &menubar;
  508. }
  509. $form->hide_form(qw(callback path login sessionid));
  510. print qq|
  511. </form>
  512. </body>
  513. </html>
  514. |;
  515. }
  516. sub prepare_storescard {
  517. $form->{formname} = "storescard";
  518. $form->{format} = "postscript" if $myconfig{printer};
  519. $form->{media} = $myconfig{printer};
  520. JC->get_jcitems(\%myconfig, \%$form);
  521. $form->{selectformname} = qq|<option value="storescard">|.$locale->text('Stores Card');
  522. $form->{amount} = $form->{sellprice} * $form->{qty};
  523. for (qw(sellprice amount)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) }
  524. $form->{qty} = $form->format_amount(\%myconfig, $form->{qty}, 4);
  525. $form->{employee} .= "--$form->{employee_id}";
  526. $form->{projectnumber} .= "--$form->{project_id}";
  527. $form->{partnumber} .= "--$form->{parts_id}";
  528. $form->{oldpartnumber} = $form->{partnumber};
  529. if (@{ $form->{all_language} }) {
  530. $form->{selectlanguage} = "<option>\n";
  531. for (@{ $form->{all_language} }) { $form->{selectlanguage} .= qq|<option value="$_->{code}">$_->{description}\n| }
  532. }
  533. &jcitems_links;
  534. $form->{locked} = ($form->{revtrans}) ? '1' : ($form->datetonum(\%myconfig, $form->{transdate}) <= $form->datetonum(\%myconfig, $form->{closedto}));
  535. $form->{readonly} = 1 if $myconfig{acs} =~ /Production--Add Time Card/;
  536. if ($form->{income_accno_id}) {
  537. $form->{locked} = 1 if $form->{production} == $form->{completed};
  538. }
  539. }
  540. sub storescard_header {
  541. # set option selected
  542. for (qw(employee projectnumber partnumber)) {
  543. $form->{"select$_"} =~ s/ selected//;
  544. $form->{"select$_"} =~ s/(<option value="\Q$form->{$_}\E")/$1 selected/;
  545. }
  546. $rows = $form->numtextrows($form->{description}, 50, 8);
  547. for (qw(transdate partnumber)) { $form->{"old$_"} = $form->{$_} }
  548. for (qw(partnumber description)) { $form->{$_} = $form->quote($form->{$_}) }
  549. if ($rows > 1) {
  550. $description = qq|<textarea name=description rows=$rows cols=46 wrap=soft>$form->{description}</textarea>|;
  551. } else {
  552. $description = qq|<input name=description size=48 value="$form->{description}">|;
  553. }
  554. $form->header;
  555. print qq|
  556. <body>
  557. <form method=post action="$form->{script}">
  558. |;
  559. $form->hide_form(qw(id type media format printed queued title closedto locked oldtransdate oldpartnumber project));
  560. print qq|
  561. <table width=100%>
  562. <tr class=listtop>
  563. <th class=listtop>$form->{title}</th>
  564. </tr>
  565. <tr height="5"></tr>
  566. <tr>
  567. <td>
  568. <table>
  569. <tr>
  570. <td>
  571. <table>
  572. <tr>
  573. <th align=right nowrap>|.$locale->text('Job Number').qq|</th>
  574. <td><select name=projectnumber>$form->{selectprojectnumber}</select>
  575. </td>
  576. <td>$form->{projectdescription}</td>
  577. <input type=hidden name=projectdescription value="|.$form->quote($form->{projectdescription}).qq|">
  578. </tr>
  579. <tr>
  580. <th align=right nowrap>|.$locale->text('Date').qq|</th>
  581. <td><input name=transdate size=11 title="$myconfig{dateformat}" value=$form->{transdate}></td>
  582. </tr>
  583. <tr>
  584. <th align=right nowrap>|.$locale->text('Part Number').qq|</th>
  585. <td><select name=partnumber>$form->{selectpartnumber}</td>
  586. </tr>
  587. <tr valign=top>
  588. <th align=right nowrap>|.$locale->text('Description').qq|</th>
  589. <td>$description</td>
  590. </tr>
  591. <tr>
  592. <th align=right nowrap>|.$locale->text('Qty').qq|</th>
  593. <td><input name=qty size=6 value=$form->{qty}>
  594. <b>|.$locale->text('Cost').qq|</b>
  595. <input name=sellprice size=10 value=$form->{sellprice}></td>
  596. </tr>
  597. <tr>
  598. <th align=right nowrap>|.$locale->text('Total').qq|</th>
  599. <td>$form->{amount}</td>
  600. </tr>
  601. </table>
  602. </td>
  603. </tr>
  604. |;
  605. }
  606. sub storescard_footer {
  607. print qq|
  608. </table>
  609. </td>
  610. </tr>
  611. <tr>
  612. <td><hr size=3 noshade></td>
  613. </tr>
  614. <tr>
  615. <td>
  616. |;
  617. &print_options;
  618. print qq|
  619. </td>
  620. </tr>
  621. </table>
  622. <br>
  623. |;
  624. $transdate = $form->datetonum(\%myconfig, $form->{transdate});
  625. $closedto = $form->datetonum(\%myconfig, $form->{closedto});
  626. # type=submit $locale->text('Update')
  627. # type=submit $locale->text('Print')
  628. # type=submit $locale->text('Save')
  629. # type=submit $locale->text('Print and Save')
  630. # type=submit $locale->text('Save as new')
  631. # type=submit $locale->text('Print and Save as new')
  632. # type=submit $locale->text('Delete')
  633. if (! $form->{readonly}) {
  634. %button = ('Update' => { ndx => 1, key => 'U', value => $locale->text('Update') },
  635. 'Print' => { ndx => 2, key => 'P', value => $locale->text('Print') },
  636. 'Save' => { ndx => 3, key => 'S', value => $locale->text('Save') },
  637. 'Print and Save' => { ndx => 6, key => 'R', value => $locale->text('Print and Save') },
  638. 'Save as new' => { ndx => 7, key => 'N', value => $locale->text('Save as new') },
  639. 'Print and Save as new' => { ndx => 8, key => 'W', value => $locale->text('Print and Save as new') },
  640. 'Delete' => { ndx => 16, key => 'D', value => $locale->text('Delete') },
  641. );
  642. %a = ();
  643. if ($form->{id}) {
  644. if (!$form->{locked}) {
  645. for ('Update', 'Print', 'Save', 'Save as new') { $a{$_} = 1 }
  646. if ($latex) {
  647. for ('Print and Save', 'Print and Save as new') { $a{$_} = 1 }
  648. }
  649. if ($form->{orphaned}) {
  650. $a{'Delete'} = 1;
  651. }
  652. }
  653. } else {
  654. if ($transdate > $closedto) {
  655. for ('Update', 'Print', 'Save') { $a{$_} = 1 }
  656. if ($latex) {
  657. $a{'Print and Save'} = 1;
  658. }
  659. }
  660. }
  661. for (keys %button) { delete $button{$_} if ! $a{$_} }
  662. for (sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button) { $form->print_button(\%button, $_) }
  663. }
  664. if ($form->{menubar}) {
  665. require "$form->{path}/menu.pl";
  666. &menubar;
  667. }
  668. $form->hide_form(qw(callback path login sessionid));
  669. print qq|
  670. </form>
  671. </body>
  672. </html>
  673. |;
  674. }
  675. sub update {
  676. ($null, $form->{project_id}) = split /--/, $form->{projectnumber};
  677. # check labor/part
  678. JC->jcitems_links(\%myconfig, \%$form);
  679. &jcitems_links;
  680. $checkmatrix = 1 if $form->{oldproject_id} != $form->{project_id};
  681. if ($form->{type} eq 'timecard') {
  682. # time clocked
  683. %hour = ( in => 0, out => 0 );
  684. for $t (qw(in out)) {
  685. if ($form->{"${t}sec"} > 60) {
  686. $form->{"${t}sec"} -= 60;
  687. $form->{"${t}min"}++;
  688. }
  689. if ($form->{"${t}min"} > 60) {
  690. $form->{"${t}min"} -= 60;
  691. $form->{"${t}hour"}++;
  692. }
  693. $hour{$t} = $form->{"${t}hour"};
  694. }
  695. $form->{checkedin} = $hour{in} * 3600 + $form->{inmin} * 60 + $form->{insec};
  696. $form->{checkedout} = $hour{out} * 3600 + $form->{outmin} * 60 + $form->{outsec};
  697. if ($form->{checkedin} > $form->{checkedout}) {
  698. $form->{checkedout} = 86400 - ($form->{checkedin} - $form->{checkedout});
  699. $form->{checkedin} = 0;
  700. }
  701. $form->{clocked} = ($form->{checkedout} - $form->{checkedin}) / 3600;
  702. for (qw(sellprice qty noncharge allocated)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
  703. $checkmatrix = 1 if $form->{oldqty} != $form->{qty};
  704. if (($form->{oldcheckedin} != $form->{checkedin}) || ($form->{oldcheckedout} != $form->{checkedout})) {
  705. $checkmatrix = 1;
  706. $form->{oldqty} = $form->{qty} = $form->{clocked} - $form->{noncharge};
  707. $form->{oldnoncharge} = $form->{noncharge};
  708. }
  709. if (($form->{qty} != $form->{oldqty}) && $form->{clocked}) {
  710. $form->{oldnoncharge} = $form->{noncharge} = $form->{clocked} - $form->{qty};
  711. $checkmatrix = 1;
  712. }
  713. if (($form->{oldnoncharge} != $form->{noncharge}) && $form->{clocked}) {
  714. $form->{oldqty} = $form->{qty} = $form->{clocked} - $form->{noncharge};
  715. $checkmatrix = 1;
  716. }
  717. if ($checkmatrix) {
  718. @a = split / /, $form->{pricematrix};
  719. if (scalar @a > 2) {
  720. for (@a) {
  721. ($q, $p) = split /:/, $_;
  722. if (($p * 1) && ($form->{qty} >= ($q * 1))) {
  723. $form->{sellprice} = $p;
  724. }
  725. }
  726. }
  727. }
  728. $form->{amount} = $form->{sellprice} * $form->{qty};
  729. $form->{clocked} = $form->format_amount(\%myconfig, $form->{clocked}, 4);
  730. for (qw(sellprice amount)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) }
  731. for (qw(qty noncharge)) {
  732. $form->{"old$_"} = $form->{$_};
  733. $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 4);
  734. }
  735. } else {
  736. for (qw(sellprice qty allocated)) { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
  737. if ($form->{oldqty} != $form->{qty}) {
  738. @a = split / /, $form->{pricematrix};
  739. if (scalar @a > 2) {
  740. for (@a) {
  741. ($q, $p) = split /:/, $_;
  742. if (($p * 1) && ($form->{qty} >= ($q * 1))) {
  743. $form->{sellprice} = $p;
  744. }
  745. }
  746. }
  747. }
  748. $form->{amount} = $form->{sellprice} * $form->{qty};
  749. for (qw(sellprice amount)) { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, 2) }
  750. }
  751. $form->{allocated} = $form->format_amount(\%myconfig, $form->{allocated});
  752. &display_form;
  753. }
  754. sub save {
  755. $form->isblank("transdate", $locale->text('Date missing!'));
  756. if ($form->{project} eq 'project') {
  757. $form->isblank("projectnumber", $locale->text('Project Number missing!'));
  758. $form->isblank("partnumber", $locale->text('Service Code missing!'));
  759. } else {
  760. $form->isblank("projectnumber", $locale->text('Job Number missing!'));
  761. $form->isblank("partnumber", $locale->text('Labor Code missing!'));
  762. }
  763. $closedto = $form->datetonum(\%myconfig, $form->{closedto});
  764. $transdate = $form->datetonum(\%myconfig, $form->{transdate});
  765. $msg = ($form->{type} eq 'timecard') ? $locale->text('Cannot save time card for a closed period!') : $locale->text('Cannot save stores card for a closed period!');
  766. $form->error($msg) if ($transdate <= $closedto);
  767. if (! $form->{resave}) {
  768. if ($form->{id}) {
  769. &resave;
  770. exit;
  771. }
  772. }
  773. $rc = JC->save(\%myconfig, \%$form);
  774. if ($form->{type} eq 'timecard') {
  775. $form->error($locale->text('Cannot change time card for a completed job!')) if ($rc == -1);
  776. $form->error($locale->text('Cannot add time card for a completed job!')) if ($rc == -2);
  777. if ($rc) {
  778. $form->redirect($locale->text('Time Card saved!'));
  779. } else {
  780. $form->error($locale->text('Cannot save time card!'));
  781. }
  782. } else {
  783. $form->error($locale->text('Cannot change stores card for a completed job!')) if ($rc == -1);
  784. $form->error($locale->text('Cannot add stores card for a completed job!')) if ($rc == -2);
  785. if ($rc) {
  786. $form->redirect($locale->text('Stores Card saved!'));
  787. } else {
  788. $form->error($locale->text('Cannot save stores card!'));
  789. }
  790. }
  791. }
  792. sub save_as_new {
  793. delete $form->{id};
  794. &save;
  795. }
  796. sub print_and_save_as_new {
  797. delete $form->{id};
  798. &print_and_save;
  799. }
  800. sub resave {
  801. if ($form->{print_and_save}) {
  802. $form->{nextsub} = "print_and_save";
  803. $msg = $locale->text('You are printing and saving an existing transaction!');
  804. } else {
  805. $form->{nextsub} = "save";
  806. $msg = $locale->text('You are saving an existing transaction!');
  807. }
  808. $form->{resave} = 1;
  809. $form->header;
  810. print qq|
  811. <body>
  812. <form method=post action=$form->{script}>
  813. |;
  814. delete $form->{action};
  815. $form->hide_form;
  816. print qq|
  817. <h2 class=confirm>|.$locale->text('Warning!').qq|</h2>
  818. <h4>$msg</h4>
  819. <input name=action class=submit type=submit value="|.$locale->text('Continue').qq|">
  820. </form>
  821. </body>
  822. </html>
  823. |;
  824. }
  825. sub print_and_save {
  826. $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/;
  827. $form->error($locale->text('Select a Printer!')) if $form->{media} eq 'screen';
  828. if (! $form->{resave}) {
  829. if ($form->{id}) {
  830. $form->{print_and_save} = 1;
  831. &resave;
  832. exit;
  833. }
  834. }
  835. $old_form = new Form;
  836. $form->{display_form} = "save";
  837. for (keys %$form) { $old_form->{$_} = $form->{$_} }
  838. &{ "print_$form->{formname}" }($old_form);
  839. }
  840. sub delete_timecard {
  841. $form->header;
  842. $employee = $form->{employee};
  843. $employee =~ s/--.*//g;
  844. $projectnumber = $form->{projectnumber};
  845. $projectnumber =~ s/--.*//g;
  846. print qq|
  847. <body>
  848. <form method=post action=$form->{script}>
  849. |;
  850. delete $form->{action};
  851. $form->hide_form;
  852. print qq|
  853. <h2 class=confirm>|.$locale->text('Confirm!').qq|</h2>
  854. <h4>|.$locale->text('Are you sure you want to delete time card for').qq|
  855. <p>$form->{transdate}
  856. <br>$employee
  857. <br>$projectnumber
  858. </h4>
  859. <p>
  860. <input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
  861. </form>
  862. |;
  863. }
  864. sub delete { &{ "delete_$form->{type}" } };
  865. sub yes { &{ "yes_delete_$form->{type}" } };
  866. sub yes_delete_timecard {
  867. if (JC->delete_timecard(\%myconfig, \%$form)) {
  868. $form->redirect($locale->text('Time Card deleted!'));
  869. } else {
  870. $form->error($locale->text('Cannot delete time card!'));
  871. }
  872. }
  873. sub list_timecard {
  874. $form->{type} = "timecard";
  875. JC->jcitems(\%myconfig, \%$form);
  876. $form->{title} = $locale->text('Time Cards');
  877. @a = qw(type direction oldsort path login sessionid project l_subtotal open closed l_time l_allocated);
  878. $href = "$form->{script}?action=list_timecard";
  879. for (@a) { $href .= "&$_=$form->{$_}" }
  880. $href .= "&title=".$form->escape($form->{title});
  881. $form->sort_order();
  882. $callback = "$form->{script}?action=list_timecard";
  883. for (@a) { $callback .= "&$_=$form->{$_}" }
  884. $callback .= "&title=".$form->escape($form->{title},1);
  885. @column_index = (qw(transdate projectnumber projectdescription id partnumber description));
  886. push @column_index, (qw(allocated)) if $form->{l_allocated};
  887. push @column_index, (qw(1 2 3 4 5 6 7));
  888. @column_index = $form->sort_columns(@column_index);
  889. if ($form->{project} eq 'job') {
  890. $joblabel = $locale->text('Job Number');
  891. $laborlabel = $locale->text('Labor Code');
  892. $desclabel = $locale->text('Job Name');
  893. } elsif ($form->{project} eq 'project') {
  894. $joblabel = $locale->text('Project Number');
  895. $laborlabel = $locale->text('Service Code');
  896. $desclabel = $locale->text('Project Name');
  897. } else {
  898. $joblabel = $locale->text('Project/Job Number');
  899. $laborlabel = $locale->text('Service/Labor Code');
  900. $desclabel = $locale->text('Project/Job Name');
  901. }
  902. if ($form->{projectnumber}) {
  903. $callback .= "&projectnumber=".$form->escape($form->{projectnumber},1);
  904. $href .= "&projectnumber=".$form->escape($form->{projectnumber});
  905. ($var) = split /--/, $form->{projectnumber};
  906. $option .= "\n<br>" if ($option);
  907. $option .= "$joblabel : $var";
  908. @column_index = grep !/projectnumber/, @column_index;
  909. }
  910. if ($form->{partnumber}) {
  911. $callback .= "&partnumber=".$form->escape($form->{partnumber},1);
  912. $href .= "&partnumber=".$form->escape($form->{partnumber});
  913. ($var) = split /--/, $form->{partnumber};
  914. $option .= "\n<br>" if ($option);
  915. $option .= "$laborlabel : $var";
  916. @column_index = grep !/partnumber/, @column_index;
  917. }
  918. if ($form->{employee}) {
  919. $callback .= "&employee=".$form->escape($form->{employee},1);
  920. $href .= "&employee=".$form->escape($form->{employee});
  921. }
  922. if ($form->{startdatefrom}) {
  923. $callback .= "&startdatefrom=$form->{startdatefrom}";
  924. $href .= "&startdatefrom=$form->{startdatefrom}";
  925. $option .= "\n<br>" if ($option);
  926. $option .= $locale->text('From')."&nbsp;".$locale->date(\%myconfig, $form->{startdatefrom}, 1);
  927. }
  928. if ($form->{startdateto}) {
  929. $callback .= "&startdateto=$form->{startdateto}";
  930. $href .= "&startdateto=$form->{startdateto}";
  931. $option .= "\n<br>" if ($option);
  932. $option .= $locale->text('To')."&nbsp;".$locale->date(\%myconfig, $form->{startdateto}, 1);
  933. }
  934. if ($form->{open}) {
  935. $callback .= "&open=$form->{open}";
  936. $href .= "&open=$form->{open}";
  937. $option .= "\n<br>" if ($option);
  938. $option .= $locale->text('Open');
  939. }
  940. if ($form->{closed}) {
  941. $callback .= "&closed=$form->{closed}";
  942. $href .= "&closed=$form->{closed}";
  943. $option .= "\n<br>" if ($option);
  944. $option .= $locale->text('Closed');
  945. }
  946. %weekday = ( 1 => $locale->text('Sunday'),
  947. 2 => $locale->text('Monday'),
  948. 3 => $locale->text('Tuesday'),
  949. 4 => $locale->text('Wednesday'),
  950. 5 => $locale->text('Thursday'),
  951. 6 => $locale->text('Friday'),
  952. 7 => $locale->text('Saturday'),
  953. );
  954. for (keys %weekday) { $column_header{$_} = "<th class=listheading width=25>".substr($weekday{$_},0,3)."</th>" }
  955. $column_header{id} = "<th><a class=listheading href=$href&sort=id>".$locale->text('ID')."</a></th>";
  956. $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>";
  957. $column_header{description} = "<th><a class=listheading href=$href&sort=description>" . $locale->text('Description') . "</th>";
  958. $column_header{projectnumber} = "<th><a class=listheading href=$href&sort=projectnumber>$joblabel</a></th>";
  959. $column_header{partnumber} = "<th><a class=listheading href=$href&sort=partnumber>$laborlabel</a></th>";
  960. $column_header{projectdescription} = "<th><a class=listheading href=$href&sort=projectdescription>$desclabel</a></th>";
  961. $column_header{allocated} = "<th class=listheading></th>";
  962. $form->header;
  963. if (@{ $form->{transactions} }) {
  964. $sameitem = $form->{transactions}->[0]->{$form->{sort}};
  965. $sameemployeenumber = $form->{transactions}->[0]->{employeenumber};
  966. $employee = $form->{transactions}->[0]->{employee};
  967. $sameweek = $form->{transactions}->[0]->{workweek};
  968. }
  969. print qq|
  970. <body>
  971. <table width=100%>
  972. <tr>
  973. <th class=listtop>$form->{title}</th>
  974. </tr>
  975. <tr height="5"></tr>
  976. <tr>
  977. <td>$option</td>
  978. </tr>
  979. <tr>
  980. <td>
  981. <table width=100%>
  982. <tr>
  983. <th colspan=2 align=left>
  984. $employee
  985. </th>
  986. <th align=left>
  987. $sameemployeenumber
  988. </th>
  989. <tr class=listheading>
  990. |;
  991. for (@column_index) { print "\n$column_header{$_}" }
  992. print qq|
  993. </tr>
  994. |;
  995. # add sort and escape callback, this one we use for the add sub
  996. $form->{callback} = $callback .= "&sort=$form->{sort}";
  997. # escape callback for href
  998. $callback = $form->escape($callback);
  999. # flip direction
  1000. $direction = ($form->{direction} eq 'ASC') ? "ASC" : "DESC";
  1001. $href =~ s/&direction=(\w+)&/&direction=$direction&/;
  1002. %total = ();
  1003. foreach $ref (@{ $form->{transactions} }) {
  1004. if ($sameemployeenumber ne $ref->{employeenumber}) {
  1005. $sameemployeenumber = $ref->{employeenumber};
  1006. $sameweek = $ref->{workweek};
  1007. if ($form->{l_subtotal}) {
  1008. print qq|
  1009. <tr class=listsubtotal>
  1010. |;
  1011. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1012. $weektotal = 0;
  1013. for (keys %weekday) {
  1014. $column_data{$_} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotal{$_}, "", "&nbsp;")."</th>";
  1015. $weektotal += $subtotal{$_};
  1016. $subtotal{$_} = 0;
  1017. }
  1018. $column_data{$form->{sort}} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $weektotal, "", "&nbsp;")."</th>";
  1019. for (@column_index) { print "\n$column_data{$_}" }
  1020. }
  1021. # print total
  1022. print qq|
  1023. <tr class=listtotal>
  1024. |;
  1025. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1026. $total = 0;
  1027. for (keys %weekday) {
  1028. $column_data{$_} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $total{$_}, "", "&nbsp;")."</th>";
  1029. $total += $total{$_};
  1030. $total{$_} = 0;
  1031. }
  1032. $column_data{$form->{sort}} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $total, "", "&nbsp;")."</th>";
  1033. for (@column_index) { print "\n$column_data{$_}" }
  1034. print qq|
  1035. <tr height=30 valign=bottom>
  1036. <th colspan=2 align=left>
  1037. $ref->{employee}
  1038. </th>
  1039. <th align=left>
  1040. $ref->{employeenumber}
  1041. </th>
  1042. <tr class=listheading>
  1043. |;
  1044. for (@column_index) { print "\n$column_header{$_}" }
  1045. print qq|
  1046. </tr>
  1047. |;
  1048. }
  1049. if ($form->{l_subtotal}) {
  1050. if ($ref->{workweek} != $sameweek) {
  1051. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1052. $weektotal = 0;
  1053. for (keys %weekday) {
  1054. $column_data{$_} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotal{$_}, "", "&nbsp;")."</th>";
  1055. $weektotal += $subtotal{$_};
  1056. $subtotal{$_} = 0
  1057. }
  1058. $column_data{$form->{sort}} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $weektotal, "", "&nbsp;")."</th>";
  1059. $sameweek = $ref->{workweek};
  1060. print qq|
  1061. <tr class=listsubtotal>
  1062. |;
  1063. for (@column_index) { print "\n$column_data{$_}" }
  1064. print qq|
  1065. </tr>
  1066. |;
  1067. }
  1068. }
  1069. for (@column_index) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  1070. for (keys %weekday) { $column_data{$_} = "<td>&nbsp;</td>" }
  1071. $column_data{allocated} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{allocated}, "", "&nbsp;")."</td>";
  1072. $column_data{$ref->{weekday}} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{qty}, "", "&nbsp;");
  1073. if ($form->{l_time}) {
  1074. $column_data{$ref->{weekday}} .= "<br>$ref->{checkedin}<br>$ref->{checkedout}";
  1075. }
  1076. $column_data{$ref->{weekday}} .= "</td>";
  1077. $column_data{id} = "<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>";
  1078. $subtotal{$ref->{weekday}} += $ref->{qty};
  1079. $total{$ref->{weekday}} += $ref->{qty};
  1080. $j++; $j %= 2;
  1081. print qq|
  1082. <tr class=listrow$j>
  1083. |;
  1084. for (@column_index) { print "\n$column_data{$_}" }
  1085. print qq|
  1086. </tr>
  1087. |;
  1088. }
  1089. # print last subtotal
  1090. if ($form->{l_subtotal}) {
  1091. print qq|
  1092. <tr class=listsubtotal>
  1093. |;
  1094. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1095. $weektotal = 0;
  1096. for (keys %weekday) {
  1097. $column_data{$_} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotal{$_}, "", "&nbsp;")."</th>";
  1098. $weektotal += $subtotal{$_};
  1099. }
  1100. $column_data{$form->{sort}} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $weektotal, "", "&nbsp;")."</th>";
  1101. for (@column_index) { print "\n$column_data{$_}" }
  1102. }
  1103. # print last total
  1104. print qq|
  1105. <tr class=listtotal>
  1106. |;
  1107. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1108. $total = 0;
  1109. for (keys %weekday) {
  1110. $column_data{$_} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $total{$_}, "", "&nbsp;")."</th>";
  1111. $total += $total{$_};
  1112. $total{$_} = 0;
  1113. }
  1114. $column_data{$form->{sort}} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $total, "", "&nbsp;")."</th>";
  1115. for (@column_index) { print "\n$column_data{$_}" }
  1116. if ($form->{project} eq 'job') {
  1117. if ($myconfig{acs} !~ /Production--Production/) {
  1118. $i = 1;
  1119. $button{'Production--Add Time Card'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Time Card').qq|"> |;
  1120. $button{'Production--Add Time Card'}{order} = $i++;
  1121. }
  1122. } elsif ($form->{project} eq 'project') {
  1123. if ($myconfig{acs} !~ /Projects--Projects/) {
  1124. $i = 1;
  1125. $button{'Projects--Add Time Card'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Time Card').qq|"> |;
  1126. $button{'Projects--Add Time Card'}{order} = $i++;
  1127. }
  1128. } else {
  1129. if ($myconfig{acs} !~ /Time Cards--Time Cards/) {
  1130. $i = 1;
  1131. $button{'Time Cards--Add Time Card'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Time Card').qq|"> |;
  1132. $button{'Time Cards--Add Time Card'}{order} = $i++;
  1133. }
  1134. }
  1135. for (split /;/, $myconfig{acs}) { delete $button{$_} }
  1136. print qq|
  1137. </tr>
  1138. </table>
  1139. </td>
  1140. </tr>
  1141. <tr>
  1142. <td><hr size=3 noshade></td>
  1143. </tr>
  1144. </table>
  1145. <br>
  1146. <form method=post action=$form->{script}>
  1147. |;
  1148. $form->hide_form(qw(callback path login sessionid project));
  1149. foreach $item (sort { $a->{order} <=> $b->{order} } %button) {
  1150. print $item->{code};
  1151. }
  1152. if ($form->{menubar}) {
  1153. require "$form->{path}/menu.pl";
  1154. &menubar;
  1155. }
  1156. print qq|
  1157. </form>
  1158. </body>
  1159. </html>
  1160. |;
  1161. }
  1162. sub list_storescard {
  1163. $form->{type} = "storescard";
  1164. JC->jcitems(\%myconfig, \%$form);
  1165. $form->{title} = $locale->text('Stores Cards');
  1166. $href = "$form->{script}?action=list_storescard";
  1167. for (qw(type direction oldsort path login sessionid project)) { $href .= "&$_=$form->{$_}" }
  1168. $href .= "&title=".$form->escape($form->{title});
  1169. $form->sort_order();
  1170. $callback = "$form->{script}?action=list_storescard";
  1171. for (qw(type direction oldsort path login sessionid project)) { $callback .= "&$_=$form->{$_}" }
  1172. $callback .= "&title=".$form->escape($form->{title},1);
  1173. @column_index = $form->sort_columns(qw(transdate projectnumber projectdescription id partnumber description qty amount));
  1174. if ($form->{projectnumber}) {
  1175. $callback .= "&projectnumber=".$form->escape($form->{projectnumber},1);
  1176. $href .= "&projectnumber=".$form->escape($form->{projectnumber});
  1177. ($var) = split /--/, $form->{projectnumber};
  1178. $option .= "\n<br>" if ($option);
  1179. $option .= "$joblabel : $var";
  1180. @column_index = grep !/projectnumber/, @column_index;
  1181. }
  1182. if ($form->{partnumber}) {
  1183. $callback .= "&partnumber=".$form->escape($form->{partnumber},1);
  1184. $href .= "&partnumber=".$form->escape($form->{partnumber});
  1185. ($var) = split /--/, $form->{partnumber};
  1186. $option .= "\n<br>" if ($option);
  1187. $option .= "$laborlabel : $var";
  1188. @column_index = grep !/partnumber/, @column_index;
  1189. }
  1190. if ($form->{startdatefrom}) {
  1191. $callback .= "&startdatefrom=$form->{startdatefrom}";
  1192. $href .= "&startdatefrom=$form->{startdatefrom}";
  1193. $option .= "\n<br>" if ($option);
  1194. $option .= $locale->text('From')."&nbsp;".$locale->date(\%myconfig, $form->{startdatefrom}, 1);
  1195. }
  1196. if ($form->{startdateto}) {
  1197. $callback .= "&startdateto=$form->{startdateto}";
  1198. $href .= "&startdateto=$form->{startdateto}";
  1199. $option .= "\n<br>" if ($option);
  1200. $option .= $locale->text('To')."&nbsp;".$locale->date(\%myconfig, $form->{startdateto}, 1);
  1201. }
  1202. $column_header{id} = "<th><a class=listheading href=$href&sort=id>" . $locale->text('ID') . "</a></th>";
  1203. $column_header{transdate} = "<th><a class=listheading href=$href&sort=transdate>".$locale->text('Date')."</a></th>";
  1204. $column_header{projectnumber} = "<th><a class=listheading href=$href&sort=projectnumber>" . $locale->text('Job Number') . "</a></th>";
  1205. $column_header{projectdescription} = "<th><a class=listheading href=$href&sort=projectdescription>" . $locale->text('Job Description') . "</a></th>";
  1206. $column_header{partnumber} = "<th><a class=listheading href=$href&sort=partnumber>" . $locale->text('Part Number') . "</a></th>";
  1207. $column_header{description} = "<th><a class=listheading href=$href&sort=description>" . $locale->text('Description') . "</a></th>";
  1208. $column_header{qty} = "<th class=listheading>" . $locale->text('Qty') . "</th>";
  1209. $column_header{amount} = "<th class=listheading>" . $locale->text('Amount') . "</th>";
  1210. $form->header;
  1211. if (@{ $form->{transactions} }) {
  1212. $sameitem = $form->{transactions}->[0]->{$form->{sort}};
  1213. }
  1214. print qq|
  1215. <body>
  1216. <table width=100%>
  1217. <tr>
  1218. <th class=listtop>$form->{title}</th>
  1219. </tr>
  1220. <tr height="5"></tr>
  1221. <tr>
  1222. <td>$option</td>
  1223. </tr>
  1224. <tr>
  1225. <td>
  1226. <table width=100%>
  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 = 0;
  1241. foreach $ref (@{ $form->{transactions} }) {
  1242. for (@column_index) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  1243. $column_data{qty} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{qty}, "", "&nbsp;")."</td>";
  1244. $column_data{amount} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{qty} * $ref->{sellprice}, 2)."</td>";
  1245. $column_data{id} = "<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>";
  1246. $total += ($ref->{qty} * $ref->{sellprice});
  1247. $j++; $j %= 2;
  1248. print qq|
  1249. <tr class=listrow$j>
  1250. |;
  1251. for (@column_index) { print "\n$column_data{$_}" }
  1252. print qq|
  1253. </tr>
  1254. |;
  1255. }
  1256. # print total
  1257. print qq|
  1258. <tr class=listtotal>
  1259. |;
  1260. for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
  1261. $column_data{amount} = qq|<th align=right>|.$form->format_amount(\%myconfig, $total, 2)."</th";
  1262. for (@column_index) { print "\n$column_data{$_}" }
  1263. if ($form->{project} eq 'job') {
  1264. if ($myconfig{acs} !~ /Production--Production/) {
  1265. $i = 1;
  1266. $button{'Production--Add Stores Card'}{code} = qq|<input class=submit type=submit name=action value="|.$locale->text('Add Stores Card').qq|"> |;
  1267. $button{'Production--Add Stores Card'}{order} = $i++;
  1268. }
  1269. }
  1270. for (split /;/, $myconfig{acs}) { delete $button{$_} }
  1271. print qq|
  1272. </tr>
  1273. </table>
  1274. </td>
  1275. </tr>
  1276. <tr>
  1277. <td><hr size=3 noshade></td>
  1278. </tr>
  1279. </table>
  1280. <br>
  1281. <form method=post action=$form->{script}>
  1282. |;
  1283. $form->hide_form(qw(callback path login sessionid project));
  1284. foreach $item (sort { $a->{order} <=> $b->{order} } %button) {
  1285. print $item->{code};
  1286. }
  1287. if ($form->{menubar}) {
  1288. require "$form->{path}/menu.pl";
  1289. &menubar;
  1290. }
  1291. print qq|
  1292. </form>
  1293. </body>
  1294. </html>
  1295. |;
  1296. }
  1297. sub continue { &{ $form->{nextsub} } };
  1298. sub add_time_card {
  1299. $form->{type} = "timecard";
  1300. &add;
  1301. }
  1302. sub add_stores_card {
  1303. $form->{type} = "storescard";
  1304. &add;
  1305. }
  1306. sub print_options {
  1307. if ($form->{selectlanguage}) {
  1308. $form->{"selectlanguage"} = $form->unescape($form->{"selectlanguage"});
  1309. $form->{"selectlanguage"} =~ s/ selected//;
  1310. $form->{"selectlanguage"} =~ s/(<option value="\Q$form->{language_code}\E")/$1 selected/;
  1311. $lang = qq|<select name=language_code>$form->{selectlanguage}</select>
  1312. <input type=hidden name=selectlanguage value="|.
  1313. $form->escape($form->{selectlanguage},1).qq|">|;
  1314. }
  1315. $form->{selectformname} = $form->unescape($form->{selectformname});
  1316. $form->{selectformname} =~ s/ selected//;
  1317. $form->{selectformname} =~ s/(<option value="\Q$form->{formname}\E")/$1 selected/;
  1318. $type = qq|<select name=formname>$form->{selectformname}</select>
  1319. <input type=hidden name=selectformname value="|.$form->escape($form->{selectformname},1).qq|">|;
  1320. $media = qq|<select name=media>
  1321. <option value="screen">|.$locale->text('Screen');
  1322. $form->{selectformat} = qq|<option value="html">html\n|;
  1323. if (%printer && $latex) {
  1324. for (sort keys %printer) { $media .= qq|
  1325. <option value="$_">$_| }
  1326. }
  1327. if ($latex) {
  1328. $media .= qq|
  1329. <option value="queue">|.$locale->text('Queue');
  1330. $form->{selectformat} .= qq|
  1331. <option value="postscript">|.$locale->text('Postscript').qq|
  1332. <option value="pdf">|.$locale->text('PDF');
  1333. }
  1334. $format = qq|<select name=format>$form->{selectformat}</select>|;
  1335. $format =~ s/(<option value="\Q$form->{format}\E")/$1 selected/;
  1336. $format .= qq|
  1337. <input type=hidden name=selectformat value="|.$form->escape($form->{selectformat},1).qq|">|;
  1338. $media .= qq|</select>|;
  1339. $media =~ s/(<option value="\Q$form->{media}\E")/$1 selected/;
  1340. print qq|
  1341. <table width=100%>
  1342. <tr>
  1343. <td>$type</td>
  1344. <td>$lang</td>
  1345. <td>$format</td>
  1346. <td>$media</td>
  1347. <td align=right width=90%>
  1348. |;
  1349. if ($form->{printed} =~ /$form->{formname}/) {
  1350. print $locale->text('Printed').qq|<br>|;
  1351. }
  1352. if ($form->{queued} =~ /$form->{formname}/) {
  1353. print $locale->text('Queued');
  1354. }
  1355. print qq|
  1356. </td>
  1357. </tr>
  1358. </table>
  1359. |;
  1360. }
  1361. sub print {
  1362. if ($form->{media} !~ /screen/) {
  1363. $form->error($locale->text('Select postscript or PDF!')) if $form->{format} !~ /(postscript|pdf)/;
  1364. $old_form = new Form;
  1365. for (keys %$form) { $old_form->{$_} = $form->{$_} }
  1366. }
  1367. &{ "print_$form->{formname}" }($old_form);
  1368. }
  1369. sub print_timecard {
  1370. my ($old_form) = @_;
  1371. $display_form = ($form->{display_form}) ? $form->{display_form} : "update";
  1372. $form->{description} =~ s/^\s+//g;
  1373. for (qw(partnumber projectnumber)) { $form->{$_} =~ s/--.*// }
  1374. @a = qw(hour min sec);
  1375. foreach $item (qw(in out)) {
  1376. for (@a) { $form->{"$item$_"} = substr(qq|00$form->{"$item$_"}|, -2) }
  1377. $form->{"checked$item"} = qq|$form->{"${item}hour"}:$form->{"${item}min"}:$form->{"${item}sec"}|;
  1378. }
  1379. @a = ();
  1380. for (qw(company address tel fax businessnumber)) { $form->{$_} = $myconfig{$_} }
  1381. $form->{address} =~ s/\\n/\n/g;
  1382. push @a, qw(partnumber description projectnumber projectdescription);
  1383. push @a, qw(company address tel fax businessnumber username useremail);
  1384. $form->format_string(@a);
  1385. $form->{total} = $form->format_amount(\%myconfig, $form->parse_amount(\%myconfig, $form->{qty}) * $form->parse_amount(\%myconfig, $form->{sellprice}), 2);
  1386. ($form->{employee}, $form->{employee_id}) = split /--/, $form->{employee};
  1387. $form->{templates} = "$myconfig{templates}";
  1388. $form->{IN} = "$form->{formname}.html";
  1389. if ($form->{format} =~ /(postscript|pdf)/) {
  1390. $form->{IN} =~ s/html$/tex/;
  1391. }
  1392. if ($form->{media} !~ /(screen|queue)/) {
  1393. $form->{OUT} = "| $printer{$form->{media}}";
  1394. if ($form->{printed} !~ /$form->{formname}/) {
  1395. $form->{printed} .= " $form->{formname}";
  1396. $form->{printed} =~ s/^ //;
  1397. $form->update_status(\%myconfig);
  1398. }
  1399. %audittrail = ( tablename => jcitems,
  1400. reference => $form->{id},
  1401. formname => $form->{formname},
  1402. action => 'printed',
  1403. id => $form->{id} );
  1404. %status = ();
  1405. for (qw(printed queued audittrail)) { $status{$_} = $form->{$_} }
  1406. $status{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail);
  1407. }
  1408. if ($form->{media} eq 'queue') {
  1409. %queued = split / /, $form->{queued};
  1410. if ($filename = $queued{$form->{formname}}) {
  1411. $form->{queued} =~ s/$form->{formname} $filename//;
  1412. unlink "$spool/$filename";
  1413. $filename =~ s/\..*$//g;
  1414. } else {
  1415. $filename = time;
  1416. $filename .= $$;
  1417. }
  1418. $filename .= ($form->{format} eq 'postscript') ? '.ps' : '.pdf';
  1419. $form->{OUT} = ">$spool/$filename";
  1420. $form->{queued} = "$form->{formname} $filename";
  1421. $form->update_status(\%myconfig);
  1422. %audittrail = ( tablename => jcitems,
  1423. reference => $form->{id},
  1424. formname => $form->{formname},
  1425. action => 'queued',
  1426. id => $form->{id} );
  1427. %status = ();
  1428. for (qw(printed queued audittrail)) { $status{$_} = $form->{$_} }
  1429. $status{audittrail} .= $form->audittrail("", \%myconfig, \%audittrail);
  1430. }
  1431. $form->parse_template(\%myconfig, $userspath);
  1432. if (defined %$old_form) {
  1433. for (keys %$old_form) { $form->{$_} = $old_form->{$_} }
  1434. for (qw(printed queued audittrail)) { $form->{$_} = $status{$_} }
  1435. &{ "$display_form" };
  1436. }
  1437. }