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