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