summaryrefslogtreecommitdiff
path: root/bin/hr.pl
blob: 160b4c874cf35d051547932647ef51d325061bb6 (plain)
  1. #=====================================================================
  2. # LedgerSMB Small Medium Business Accounting
  3. # http://www.ledgersmb.org/
  4. #
  5. # Copyright (C) 2006
  6. # This work contains copyrighted information from a number of sources all used
  7. # with permission.
  8. #
  9. # This file contains source code included with or based on SQL-Ledger which
  10. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  11. # under the GNU General Public License version 2 or, at your option, any later
  12. # version. For a full list including contact information of contributors,
  13. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  14. #
  15. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  16. # Copyright (c) 2004
  17. #
  18. # Author: DWS Systems Inc.
  19. # Web: http://www.sql-ledger.org
  20. #
  21. #
  22. #
  23. # This program is free software; you can redistribute it and/or modify
  24. # it under the terms of the GNU General Public License as published by
  25. # the Free Software Foundation; either version 2 of the License, or
  26. # (at your option) any later version.
  27. #
  28. # This program is distributed in the hope that it will be useful,
  29. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  31. # GNU General Public License for more details.
  32. # You should have received a copy of the GNU General Public License
  33. # along with this program; if not, write to the Free Software
  34. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  35. #======================================================================
  36. #
  37. # payroll module
  38. #
  39. #======================================================================
  40. use LedgerSMB::HR;
  41. use LedgerSMB::User;
  42. 1;
  43. # end of main
  44. sub add {
  45. $label = "Add ".ucfirst $form->{db};
  46. $form->{title} = $locale->text($label);
  47. $form->{callback} = "$form->{script}?action=add&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}" unless $form->{callback};
  48. &{ "$form->{db}_links" };
  49. }
  50. sub search { &{ "search_$form->{db}" } };
  51. sub search_employee {
  52. $form->{title} = $locale->text('Employees');
  53. @a = ();
  54. push @a, qq|<input name="l_ndx" type=checkbox class=checkbox value=Y> |.$locale->text('Pos');
  55. push @a, qq|<input name="l_id" type=checkbox class=checkbox value=Y> |.$locale->text('ID');
  56. push @a, qq|<input name="l_employeenumber" type=checkbox class=checkbox value=Y checked> |.$locale->text('Employee Number');
  57. push @a, qq|<input name="l_name" type=checkbox class=checkbox value=Y checked> |.$locale->text('Employee Name');
  58. push @a, qq|<input name="l_address" type=checkbox class=checkbox value=Y> |.$locale->text('Address');
  59. push @a, qq|<input name="l_city" type=checkbox class=checkbox value=Y> |.$locale->text('City');
  60. push @a, qq|<input name="l_state" type=checkbox class=checkbox value=Y> |.$locale->text('State/Province');
  61. push @a, qq|<input name="l_zipcode" type=checkbox class=checkbox value=Y> |.$locale->text('Zip/Postal Code');
  62. push @a, qq|<input name="l_country" type=checkbox class=checkbox value=Y> |.$locale->text('Country');
  63. push @a, qq|<input name="l_workphone" type=checkbox class=checkbox value=Y checked> |.$locale->text('Work Phone');
  64. push @a, qq|<input name="l_homephone" type=checkbox class=checkbox value=Y checked> |.$locale->text('Home Phone');
  65. push @a, qq|<input name="l_startdate" type=checkbox class=checkbox value=Y checked> |.$locale->text('Startdate');
  66. push @a, qq|<input name="l_enddate" type=checkbox class=checkbox value=Y checked> |.$locale->text('Enddate');
  67. push @a, qq|<input name="l_sales" type=checkbox class=checkbox value=Y> |.$locale->text('Sales');
  68. push @a, qq|<input name="l_manager" type=checkbox class=checkbox value=Y> |.$locale->text('Manager');
  69. push @a, qq|<input name="l_role" type=checkbox class=checkbox value=Y checked> |.$locale->text('Role');
  70. push @a, qq|<input name="l_login" type=checkbox class=checkbox value=Y checked> |.$locale->text('Login');
  71. push @a, qq|<input name="l_email" type=checkbox class=checkbox value=Y> |.$locale->text('E-mail');
  72. push @a, qq|<input name="l_ssn" type=checkbox class=checkbox value=Y> |.$locale->text('SSN');
  73. push @a, qq|<input name="l_dob" type=checkbox class=checkbox value=Y> |.$locale->text('DOB');
  74. push @a, qq|<input name="l_iban" type=checkbox class=checkbox value=Y> |.$locale->text('IBAN');
  75. push @a, qq|<input name="l_bic" type=checkbox class=checkbox value=Y> |.$locale->text('BIC');
  76. push @a, qq|<input name="l_notes" type=checkbox class=checkbox value=Y> |.$locale->text('Notes');
  77. $form->header;
  78. print qq|
  79. <body>
  80. <form method=post action=$form->{script}>
  81. <table width=100%>
  82. <tr>
  83. <th class=listtop>$form->{title}</th>
  84. </tr>
  85. <tr height="5"></tr>
  86. <tr valign=top>
  87. <td>
  88. <table>
  89. <tr>
  90. <th align=right nowrap>|.$locale->text('Employee Number').qq|</th>
  91. <td colspan=3><input name=employeenumber size=20></td>
  92. </tr>
  93. <tr>
  94. <th align=right nowrap>|.$locale->text('Employee Name').qq|</th>
  95. <td colspan=3><input name=name size=35></td>
  96. </tr>
  97. <tr>
  98. <th align=right nowrap>|.$locale->text('Startdate').qq|</th>
  99. <td>|.$locale->text('From').qq| <input name=startdatefrom size=11 title="$myconfig{dateformat}"> |.$locale->text('To').qq| <input name=startdateto size=11 title="$myconfig{dateformat}"></td>
  100. </tr>
  101. <tr valign=top>
  102. <th align=right nowrap>|.$locale->text('Notes').qq|</th>
  103. <td colspan=3><input name=notes size=40></td>
  104. </tr>
  105. <tr>
  106. <td></td>
  107. <td colspan=3><input name=status class=radio type=radio value=all checked>&nbsp;|.$locale->text('All').qq|
  108. <input name=status class=radio type=radio value=active>&nbsp;|.$locale->text('Active').qq|
  109. <input name=status class=radio type=radio value=inactive>&nbsp;|.$locale->text('Inactive').qq|
  110. <input name=status class=radio type=radio value=orphaned>&nbsp;|.$locale->text('Orphaned').qq|
  111. <input name=sales class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Sales').qq|
  112. </tr>
  113. <tr>
  114. <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
  115. <td colspan=3>
  116. <table>
  117. |;
  118. while (@a) {
  119. print qq|<tr>\n|;
  120. for (1 .. 5) {
  121. print qq|<td nowrap>|. shift @a;
  122. print qq|</td>\n|;
  123. }
  124. print qq|</tr>\n|;
  125. }
  126. print qq|
  127. </table>
  128. </td>
  129. </tr>
  130. </table>
  131. </td>
  132. </tr>
  133. <tr>
  134. <td><hr size=3 noshade></td>
  135. </tr>
  136. </table>
  137. <input type=hidden name=nextsub value=list_employees>
  138. |;
  139. $form->hide_form(qw(db path login sessionid));
  140. print qq|
  141. <br>
  142. <button type="submit" class="submit" name="action" value="continue">|.$locale->text('Continue').qq|</button>
  143. </form>
  144. |;
  145. if ($form->{lynx}) {
  146. require "bin/menu.pl";
  147. &menubar;
  148. }
  149. print qq|
  150. </body>
  151. </html>
  152. |;
  153. }
  154. sub list_employees {
  155. HR->employees(\%myconfig, \%$form);
  156. $href = "$form->{script}?action=list_employees&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}";
  157. $form->sort_order();
  158. $callback = "$form->{script}?action=list_employees&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}";
  159. @columns = $form->sort_columns(qw(id employeenumber name address city state zipcode country workphone homephone email startdate enddate ssn dob iban bic sales role manager login notes));
  160. unshift @columns, "ndx";
  161. foreach $item (@columns) {
  162. if ($form->{"l_$item"} eq "Y") {
  163. push @column_index, $item;
  164. # add column to href and callback
  165. $callback .= "&l_$item=Y";
  166. $href .= "&l_$item=Y";
  167. }
  168. }
  169. %role = ( user => $locale->text('User'),
  170. supervisor => $locale->text('Supervisor'),
  171. manager => $locale->text('Manager'),
  172. admin => $locale->text('Administrator')
  173. );
  174. $option = $locale->text('All');
  175. if ($form->{status} eq 'sales') {
  176. $option = $locale->text('Sales');
  177. }
  178. if ($form->{status} eq 'orphaned') {
  179. $option = $locale->text('Orphaned');
  180. }
  181. if ($form->{status} eq 'active') {
  182. $option = $locale->text('Active');
  183. }
  184. if ($form->{status} eq 'inactive') {
  185. $option = $locale->text('Inactive');
  186. }
  187. if ($form->{employeenumber}) {
  188. $callback .= "&employeenumber=".$form->escape($form->{employeenumber},1);
  189. $href .= "&employeenumber=".$form->escape($form->{employeenumber});
  190. $option .= "\n<br>".$locale->text('Employee Number')." : $form->{employeenumber}";
  191. }
  192. if ($form->{name}) {
  193. $callback .= "&name=".$form->escape($form->{name},1);
  194. $href .= "&name=".$form->escape($form->{name});
  195. $option .= "\n<br>".$locale->text('Employee Name')." : $form->{name}";
  196. }
  197. if ($form->{startdatefrom}) {
  198. $callback .= "&startdatefrom=$form->{startdatefrom}";
  199. $href .= "&startdatefrom=$form->{startdatefrom}";
  200. $fromdate = $locale->date(\%myconfig, $form->{startdatefrom}, 1);
  201. }
  202. if ($form->{startdateto}) {
  203. $callback .= "&startdateto=$form->{startdateto}";
  204. $href .= "&startdateto=$form->{startdateto}";
  205. $todate = $locale->date(\%myconfig, $form->{startdateto}, 1);
  206. }
  207. if ($fromdate || $todate) {
  208. $option .= "\n<br>".$locale->text('Startdate')." $fromdate - $todate";
  209. }
  210. if ($form->{notes}) {
  211. $callback .= "&notes=".$form->escape($form->{notes},1);
  212. $href .= "&notes=".$form->escape($form->{notes});
  213. $option .= "\n<br>" if $option;
  214. $option .= $locale->text('Notes')." : $form->{notes}";
  215. }
  216. $form->{callback} = "$callback&sort=$form->{sort}";
  217. $callback = $form->escape($form->{callback});
  218. $column_header{ndx} = qq|<th class=listheading>&nbsp;</th>|;
  219. $column_header{id} = qq|<th class=listheading>|.$locale->text('ID').qq|</th>|;
  220. $column_header{employeenumber} = qq|<th><a class=listheading href=$href&sort=employeenumber>|.$locale->text('Number').qq|</a></th>|;
  221. $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>|.$locale->text('Name').qq|</a></th>|;
  222. $column_header{manager} = qq|<th><a class=listheading href=$href&sort=manager>|.$locale->text('Manager').qq|</a></th>|;
  223. $column_header{address} = qq|<th class=listheading>|.$locale->text('Address').qq|</a></th>|;
  224. $column_header{city} = qq|<th><a class=listheading href=$href&sort=city>|.$locale->text('City').qq|</a></th>|;
  225. $column_header{state} = qq|<th><a class=listheading href=$href&sort=state>|.$locale->text('State/Province').qq|</a></th>|;
  226. $column_header{zipcode} = qq|<th><a class=listheading href=$href&sort=zipcode>|.$locale->text('Zip/Postal Code').qq|</a></th>|;
  227. $column_header{country} = qq|<th><a class=listheading href=$href&sort=country>|.$locale->text('Country').qq|</a></th>|;
  228. $column_header{workphone} = qq|<th><a class=listheading href=$href&sort=workphone>|.$locale->text('Work Phone').qq|</a></th>|;
  229. $column_header{homephone} = qq|<th><a class=listheading href=$href&sort=homephone>|.$locale->text('Home Phone').qq|</a></th>|;
  230. $column_header{startdate} = qq|<th><a class=listheading href=$href&sort=startdate>|.$locale->text('Startdate').qq|</a></th>|;
  231. $column_header{enddate} = qq|<th><a class=listheading href=$href&sort=enddate>|.$locale->text('Enddate').qq|</a></th>|;
  232. $column_header{notes} = qq|<th><a class=listheading href=$href&sort=notes>|.$locale->text('Notes').qq|</a></th>|;
  233. $column_header{role} = qq|<th><a class=listheading href=$href&sort=role>|.$locale->text('Role').qq|</a></th>|;
  234. $column_header{login} = qq|<th><a class=listheading href=$href&sort=login>|.$locale->text('Login').qq|</a></th>|;
  235. $column_header{sales} = qq|<th class=listheading>|.$locale->text('S').qq|</th>|;
  236. $column_header{email} = qq|<th><a class=listheading href=$href&sort=email>|.$locale->text('E-mail').qq|</a></th>|;
  237. $column_header{ssn} = qq|<th><a class=listheading href=$href&sort=ssn>|.$locale->text('SSN').qq|</a></th>|;
  238. $column_header{dob} = qq|<th><a class=listheading href=$href&sort=dob>|.$locale->text('DOB').qq|</a></th>|;
  239. $column_header{iban} = qq|<th><a class=listheading href=$href&sort=iban>|.$locale->text('IBAN').qq|</a></th>|;
  240. $column_header{bic} = qq|<th><a class=listheading href=$href&sort=bic>|.$locale->text('BIC').qq|</a></th>|;
  241. $form->{title} = $locale->text('Employees');
  242. $form->header;
  243. print qq|
  244. <body>
  245. <table width=100%>
  246. <tr>
  247. <th class=listtop>$form->{title}</th>
  248. </tr>
  249. <tr height="5"></tr>
  250. <tr>
  251. <td>$option</td>
  252. </tr>
  253. <tr>
  254. <td>
  255. <table width=100%>
  256. <tr class=listheading>
  257. |;
  258. for (@column_index) { print "$column_header{$_}\n" }
  259. print qq|
  260. </tr>
  261. |;
  262. $i = 0;
  263. foreach $ref (@{ $form->{all_employee} }) {
  264. $i++;
  265. $ref->{notes} =~ s/\r?\n/<br>/g;
  266. for (@column_index) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  267. $column_data{ndx} = "<td align=right>$i</td>";
  268. $column_data{sales} = ($ref->{sales}) ? "<td>x</td>" : "<td>&nbsp;</td>";
  269. $column_data{role} = qq|<td>$role{"$ref->{role}"}&nbsp;</td>|;
  270. $column_date{address} = qq|$ref->{address1} $ref->{address2}|;
  271. $column_data{name} = "<td><a href=$form->{script}?action=edit&db=employee&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&status=$form->{status}&callback=$callback>$ref->{name}&nbsp;</td>";
  272. if ($ref->{email}) {
  273. $email = $ref->{email};
  274. $email =~ s/</\&lt;/;
  275. $email =~ s/>/\&gt;/;
  276. $column_data{email} = qq|<td><a href="mailto:$ref->{email}">$email</a></td>|;
  277. }
  278. $j++; $j %= 2;
  279. print "
  280. <tr class=listrow$j>
  281. ";
  282. for (@column_index) { print "$column_data{$_}\n" }
  283. print qq|
  284. </tr>
  285. |;
  286. }
  287. $i = 1;
  288. $button{'HR--Employees--Add Employee'}{code} = qq|<button class="submit" type="submit" name="action" value="add_employee">|.$locale->text('Add Employee').qq|</button> |;
  289. $button{'HR--Employees--Add Employee'}{order} = $i++;
  290. foreach $item (split /;/, $myconfig{acs}) {
  291. delete $button{$item};
  292. }
  293. print qq|
  294. </table>
  295. </td>
  296. </tr>
  297. <tr>
  298. <td><hr size=3 noshade></td>
  299. </tr>
  300. </table>
  301. <br>
  302. <form method=post action=$form->{script}>
  303. |;
  304. $form->hide_form(qw(callback db path login sessionid));
  305. foreach $item (sort { $a->{order} <=> $b->{order} } %button) {
  306. print $item->{code};
  307. }
  308. if ($form->{lynx}) {
  309. require "bin/menu.pl";
  310. &menubar;
  311. }
  312. print qq|
  313. </form>
  314. </body>
  315. </html>
  316. |;
  317. }
  318. sub edit {
  319. # $locale->text('Edit Employee')
  320. # $locale->text('Edit Deduction')
  321. $label = ucfirst $form->{db};
  322. $form->{title} = "Edit $label";
  323. &{ "$form->{db}_links" };
  324. }
  325. sub employee_links {
  326. #$form->{deductions} = 1;
  327. HR->get_employee(\%myconfig, \%$form);
  328. for (keys %$form) { $form->{$_} = $form->quote($form->{$_}) }
  329. if (@{ $form->{all_deduction} }) {
  330. $form->{selectdeduction} = "<option>\n";
  331. for (@{ $form->{all_deduction} }) { $form->{selectdeduction} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| }
  332. }
  333. $form->{manager} = "$form->{manager}--$form->{managerid}";
  334. if (@{ $form->{all_manager} }) {
  335. $form->{selectmanager} = "<option>\n";
  336. for (@{ $form->{all_manager} }) { $form->{selectmanager} .= qq|<option value="$_->{name}--$_->{id}">$_->{name}\n| }
  337. }
  338. %role = ( user => $locale->text('User'),
  339. supervisor => $locale->text('Supervisor'),
  340. manager => $locale->text('Manager'),
  341. admin => $locale->text('Administrator')
  342. );
  343. $form->{selectrole} = "<option>\n";
  344. for (qw(user supervisor manager admin)) { $form->{selectrole} .= "<option value=$_>$role{$_}\n" }
  345. $i = 1;
  346. foreach $ref (@{ $form->{all_employeededuction} }) {
  347. $form->{"deduction_$i"} = "$ref->{description}--$ref->{id}" if $ref->{id};
  348. for (qw(before after rate)) { $form->{"${_}_$i"} = $ref->{$_} }
  349. $i++;
  350. }
  351. $form->{deduction_rows} = $i - 1;
  352. &employee_header;
  353. &employee_footer;
  354. }
  355. sub employee_header {
  356. $sales = qq|<input type=hidden name=sales value=$form->{sales}>|;
  357. $form->{sales} = ($form->{sales}) ? "checked" : "";
  358. $form->{selectrole} =~ s/ selected//;
  359. $form->{selectrole} =~ s/option value=\Q$form->{role}\E>/option value=$form->{role} selected>/;
  360. $form->{selectdeduction} = $form->unescape($form->{selectdeduction});
  361. $form->{selectmanager} = $form->unescape($form->{selectmanager});
  362. $form->{selectmanager} =~ s/ selected//;
  363. $form->{selectmanager} =~ s/(<option value="\Q$form->{manager}\E")/$1 selected/;
  364. $sales .= qq|
  365. <input type=hidden name=role value=$form->{role}>
  366. <input type=hidden name=manager value=$form->{manager}>
  367. |;
  368. if ($myconfig{role} ne 'user') {
  369. $sales = qq|
  370. <tr>
  371. <th align=right>|.$locale->text('Sales').qq|</th>
  372. <td><input name=sales class=checkbox type=checkbox value=1 $form->{sales}></td>
  373. </tr>
  374. <tr>
  375. <th align=right>|.$locale->text('Role').qq|</th>
  376. <td><select name=role>$form->{selectrole}</select></td>
  377. </tr>
  378. |;
  379. if ($form->{selectmanager}) {
  380. $sales .= qq|
  381. <tr>
  382. <th align=right>|.$locale->text('Manager').qq|</th>
  383. <td><select name=manager>$form->{selectmanager}</select></td>
  384. </tr>
  385. |;
  386. }
  387. }
  388. $form->{deduction_rows}++;
  389. for $i (1 .. $form->{deduction_rows}) {
  390. $form->{"selectdeduction_$i"} = $form->{selectdeduction};
  391. if ($form->{"deduction_$i"}) {
  392. $form->{"selectdeduction_$i"} =~ s/(<option value="\Q$form->{"deduction_$i"}\E")/$1 selected/;
  393. }
  394. }
  395. $form->{selectdeduction} = $form->escape($form->{selectdeduction},1);
  396. $form->{selectmanager} = $form->escape($form->{selectmanager},1);
  397. $form->header;
  398. print qq|
  399. <body>
  400. <form method=post action=$form->{script}>
  401. <input type=hidden name=selectdeduction value="$form->{selectdeduction}">
  402. <input type=hidden name=deduction_rows value=$form->{deduction_rows}>
  403. <input type=hidden name=selectmanager value="$form->{selectmanager}">
  404. <input type=hidden name=selectrole value="$form->{selectrole}">
  405. <input type=hidden name=status value=$form->{status}>
  406. <input type=hidden name=title value="$form->{title}">
  407. <table width=100%>
  408. <tr>
  409. <th class=listtop>$form->{title}</th>
  410. </tr>
  411. <tr height="5"></tr>
  412. <tr>
  413. <td>
  414. <table>
  415. <tr valign=top>
  416. <td>
  417. <table>
  418. <tr>
  419. <th align=right nowrap>|.$locale->text('Number').qq|</th>
  420. <td><input name=employeenumber size=32 maxlength=32 value="$form->{employeenumber}"></td>
  421. </tr>
  422. <tr>
  423. <th align=right nowrap>|.$locale->text('Name').qq|</th>
  424. <td><input name=name size=35 maxlength=64 value="$form->{name}"></td>
  425. </tr>
  426. <tr>
  427. <th align=right nowrap>|.$locale->text('Address').qq|</th>
  428. <td><input name=address1 size=35 maxlength=32 value="$form->{address1}"></td>
  429. </tr>
  430. <tr>
  431. <th></th>
  432. <td><input name=address2 size=35 maxlength=32 value="$form->{address2}"></td>
  433. </tr>
  434. <tr>
  435. <th align=right nowrap>|.$locale->text('City').qq|</th>
  436. <td><input name=city size=35 maxlength=32 value="$form->{city}"></td>
  437. </tr>
  438. <tr>
  439. <th align=right nowrap>|.$locale->text('State/Province').qq|</th>
  440. <td><input name=state size=35 maxlength=32 value="$form->{state}"></td>
  441. </tr>
  442. <tr>
  443. <th align=right nowrap>|.$locale->text('Zip/Postal Code').qq|</th>
  444. <td><input name=zipcode size=10 maxlength=10 value="$form->{zipcode}"></td>
  445. </tr>
  446. <tr>
  447. <th align=right nowrap>|.$locale->text('Country').qq|</th>
  448. <td><input name=country size=35 maxlength=32 value="$form->{country}"></td>
  449. </tr>
  450. <tr>
  451. <th align=right nowrap>|.$locale->text('E-mail').qq|</th>
  452. <td><input name=email size=35 value="$form->{email}"></td>
  453. </tr>
  454. <tr>
  455. $sales
  456. </table>
  457. </td>
  458. <td>
  459. <table>
  460. <tr>
  461. <th align=right nowrap>|.$locale->text('Work Phone').qq|</th>
  462. <td><input name=workphone size=20 maxlength=20 value="$form->{workphone}"></td>
  463. </tr>
  464. <tr>
  465. <th align=right nowrap>|.$locale->text('Home Phone').qq|</th>
  466. <td><input name=homephone size=20 maxlength=20 value="$form->{homephone}"></td>
  467. </tr>
  468. <tr>
  469. <th align=right nowrap>|.$locale->text('Startdate').qq|</th>
  470. <td><input name=startdate size=11 title="$myconfig{dateformat}" value=$form->{startdate}></td>
  471. </tr>
  472. <tr>
  473. <th align=right nowrap>|.$locale->text('Enddate').qq|</th>
  474. <td><input name=enddate size=11 title="$myconfig{dateformat}" value=$form->{enddate}></td>
  475. </tr>
  476. <tr>
  477. <th align=right nowrap>|.$locale->text('SSN').qq|</th>
  478. <td><input name=ssn size=20 maxlength=20 value="$form->{ssn}"></td>
  479. </tr>
  480. <tr>
  481. <th align=right nowrap>|.$locale->text('DOB').qq|</th>
  482. <td><input name=dob size=11 title="$myconfig{dateformat}" value=$form->{dob}></td>
  483. </tr>
  484. <tr>
  485. <th align=right nowrap>|.$locale->text('IBAN').qq|</th>
  486. <td><input name=iban size=34 maxlength=34 value="$form->{iban}"></td>
  487. </tr>
  488. <tr>
  489. <th align=right nowrap>|.$locale->text('BIC').qq|</th>
  490. <td><input name=bic size=11 maxlength=11 value="$form->{bic}"></td>
  491. </tr>
  492. </table>
  493. </td>
  494. </tr>
  495. </table>
  496. </td>
  497. </tr>
  498. <tr>
  499. <th align=left nowrap>|.$locale->text('Notes').qq|</th>
  500. </tr>
  501. <tr>
  502. <td><textarea name=notes rows=3 cols=60 wrap=soft>$form->{notes}</textarea></td>
  503. </tr>
  504. |;
  505. if ($form->{selectdeduction}) {
  506. print qq|
  507. <tr>
  508. <td>
  509. <table width=100%>
  510. <tr class=listheading>
  511. <th class=listheading>|.$locale->text('Payroll Deduction').qq|</th>
  512. <th class=listheading colspan=3>|.$locale->text('Allowances').qq|</th>
  513. </tr>
  514. <tr class=listheading>
  515. <th></th>
  516. <th class=listheading>|.$locale->text('Before Deduction').qq|</th>
  517. <th class=listheading>|.$locale->text('After Deduction').qq|</th>
  518. <th class=listheading>|.$locale->text('Rate').qq|</th>
  519. </tr>
  520. |;
  521. for $i (1 .. $form->{deduction_rows}) {
  522. print qq|
  523. <tr>
  524. <td><select name="deduction_$i">$form->{"selectdeduction_$i"}</select></td>
  525. <td><input name="before_$i" value=|.$form->format_amount(\%myconfig, $form->{"before_$i"}, 2).qq|></td>
  526. <td><input name="after_$i" value=|.$form->format_amount(\%myconfig, $form->{"after_$i"}, 2).qq|></td>
  527. <td><input name="rate_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"rate_$i"}).qq|></td>
  528. </tr>
  529. |;
  530. }
  531. }
  532. print qq|
  533. </table>
  534. </td>
  535. </tr>
  536. <tr>
  537. <td><hr size=3 noshade></td>
  538. </tr>
  539. </table>
  540. |;
  541. }
  542. sub employee_footer {
  543. print qq|
  544. <input name=id type=hidden value=$form->{id}>
  545. <input type=hidden name=db value=$form->{db}>
  546. <input type=hidden name=employeelogin value=$form->{employeelogin}>
  547. <input type=hidden name=path value=$form->{path}>
  548. <input type=hidden name=login value=$form->{login}>
  549. <input type=hidden name=sessionid value=$form->{sessionid}>
  550. <input type=hidden name=callback value="$form->{callback}">
  551. <br>
  552. <button class="submit" type="submit" name="action" value="update">|.$locale->text('Update').qq|</button>
  553. <button class="submit" type="submit" name="action" value="save">|.$locale->text('Save').qq|</button>
  554. |;
  555. if ($form->{id}) {
  556. print qq|<button class="submit" type="submit" name="action" value="save_as_new">|.$locale->text('Save as new').qq|</button>\n|;
  557. if ($form->{status} eq 'orphaned') {
  558. print qq|<button class="submit" type="submit" name="action" value="delete">|.$locale->text('Delete').qq|</button>\n|;
  559. }
  560. }
  561. if ($form->{lynx}) {
  562. require "bin/menu.pl";
  563. &menubar;
  564. }
  565. print qq|
  566. </form>
  567. </body>
  568. </html>
  569. |;
  570. }
  571. sub save { &{ "save_$form->{db}" } };
  572. sub save_employee {
  573. $form->isblank("name", $locale->text("Name missing!"));
  574. HR->save_employee(\%myconfig, \%$form);
  575. # if it is a login change memberfile and .conf
  576. if ($form->{employeelogin}) {
  577. $user = LedgerSMB::User->new($form->{employeelogin});
  578. for (qw(name email role)) { $user->{$_} = $form->{$_} }
  579. # assign $myconfig for db
  580. for (qw(dbconnect dbhost dbport dbpasswd)) { $user->{$_} = $myconfig{$_} }
  581. for (qw(dbpasswd password)) { $user->{"old_$_"} = $user->{$_} }
  582. $user->{packpw} = 1;
  583. $user->save_member() if $user->{login};
  584. }
  585. $form->redirect($locale->text('Employee saved!'));
  586. }
  587. sub delete { &{ "delete_$form->{db}" } };
  588. sub delete_employee {
  589. HR->delete_employee(\%myconfig, \%$form);
  590. $form->redirect($locale->text('Employee deleted!'));
  591. }
  592. sub continue { &{ $form->{nextsub} } };
  593. sub add_employee { &add };
  594. sub add_deduction { &add };
  595. sub search_deduction {
  596. HR->deductions(\%myconfig, \%$form);
  597. $href = "$form->{script}?action=search_deduction&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  598. $form->sort_order();
  599. $callback = "$form->{script}?action=search_deduction&direction=$form->{direction}&oldsort=$form->{oldsort}&db=$form->{db}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}";
  600. @column_index = $form->sort_columns(qw(description rate amount above below employeepays employerpays ap_accno expense_accno));
  601. $form->{callback} = $callback;
  602. $callback = $form->escape($form->{callback});
  603. $column_header{description} = qq|<th class=listheading href=$href>|.$locale->text('Description').qq|</th>|;
  604. $column_header{rate} = qq|<th class=listheading nowrap>|.$locale->text('Rate').qq|<br>%</th>|;
  605. $column_header{amount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|;
  606. $column_header{above} = qq|<th class=listheading>|.$locale->text('Above').qq|</th>|;
  607. $column_header{below} = qq|<th class=listheading>|.$locale->text('Below').qq|</th>|;
  608. $column_header{employerpays} = qq|<th class=listheading>|.$locale->text('Employer').qq|</th>|;
  609. $column_header{employeepays} = qq|<th class=listheading>|.$locale->text('Employee').qq|</th>|;
  610. $column_header{ap_accno} = qq|<th class=listheading>|.$locale->text('AP').qq|</th>|;
  611. $column_header{expense_accno} = qq|<th class=listheading>|.$locale->text('Expense').qq|</th>|;
  612. $form->{title} = $locale->text('Deductions');
  613. $form->header;
  614. print qq|
  615. <body>
  616. <table width=100%>
  617. <tr>
  618. <th class=listtop>$form->{title}</th>
  619. </tr>
  620. <tr height="5"></tr>
  621. <tr>
  622. <td>$option</td>
  623. </tr>
  624. <tr>
  625. <td>
  626. <table width=100%>
  627. <tr class=listheading>
  628. |;
  629. for (@column_index) { print "$column_header{$_}\n" }
  630. print qq|
  631. </tr>
  632. |;
  633. foreach $ref (@{ $form->{all_deduction} }) {
  634. $rate = $form->format_amount(\%myconfig, $ref->{rate} * 100, "", "&nbsp;");
  635. $column_data{rate} = "<td align=right>$rate</td>";
  636. for (qw(amount below above)) { $column_data{$_} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{$_}, 2, "&nbsp;")."</td>" }
  637. for (qw(ap_accno expense_accno)) { $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>" }
  638. for (qw(employerpays employeepays)) { $column_data{$_} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{$_}, "", "&nbsp;")."</td>" }
  639. if ($ref->{description} ne $sameitem) {
  640. $column_data{description} = "<td><a href=$form->{script}?action=edit&db=$form->{db}&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{description}</a></td>";
  641. } else {
  642. $column_data{description} = "<td>&nbsp;</td>";
  643. }
  644. $i++; $i %= 2;
  645. print "
  646. <tr class=listrow$i>
  647. ";
  648. for (@column_index) { print "$column_data{$_}\n" }
  649. print qq|
  650. </tr>
  651. |;
  652. $sameitem = $ref->{description};
  653. }
  654. $i = 1;
  655. $button{'HR--Deductions--Add Deduction'}{code} = qq|<button class="submit" type="submit" name="action" value="add_deduction">|.$locale->text('Add Deduction').qq|</button> |;
  656. $button{'HR--Deductions--Add Deduction'}{order} = $i++;
  657. foreach $item (split /;/, $myconfig{acs}) {
  658. delete $button{$item};
  659. }
  660. print qq|
  661. </table>
  662. </td>
  663. </tr>
  664. <tr>
  665. <td><hr size=3 noshade></td>
  666. </tr>
  667. </table>
  668. <br>
  669. <form method=post action=$form->{script}>
  670. <input type=hidden name=db value=$form->{db}>
  671. <input name=callback type=hidden value="$form->{callback}">
  672. <input type=hidden name=path value=$form->{path}>
  673. <input type=hidden name=login value=$form->{login}>
  674. <input type=hidden name=sessionid value=$form->{sessionid}>
  675. |;
  676. foreach $item (sort { $a->{order} <=> $b->{order} } %button) {
  677. print $item->{code};
  678. }
  679. if ($form->{lynx}) {
  680. require "bin/menu.pl";
  681. &menubar;
  682. }
  683. print qq|
  684. </form>
  685. </body>
  686. </html>
  687. |;
  688. }
  689. sub deduction_links {
  690. HR->get_deduction(\%myconfig, \%$form);
  691. $i = 1;
  692. foreach $ref (@{ $form->{deductionrate} }) {
  693. for (keys %$ref) { $form->{"${_}_$i"} = $ref->{$_} }
  694. $i++;
  695. }
  696. $form->{rate_rows} = $i - 1;
  697. $i = 1;
  698. foreach $ref (@{ $form->{deductionbase} }) {
  699. $form->{"base_$i"} = "$ref->{description}--$ref->{id}" if $ref->{id};
  700. $form->{"maximum_$i"} = $ref->{maximum};
  701. $i++;
  702. }
  703. $form->{base_rows} = $i - 1;
  704. $i = 1;
  705. foreach $ref (@{ $form->{deductionafter} }) {
  706. $form->{"after_$i"} = "$ref->{description}--$ref->{id}" if $ref->{id};
  707. $i++;
  708. }
  709. $form->{after_rows} = $i - 1;
  710. $form->{employeepays} = 1;
  711. $selectaccount = "<option>\n";
  712. for (@{ $form->{ap_accounts} }) { $selectaccount .= "<option>$_->{accno}--$_->{description}\n" }
  713. $form->{ap_accno} = qq|$form->{ap_accno}--$form->{ap_description}|;
  714. $form->{selectap} = $selectaccount;
  715. $selectaccount = "<option>\n";
  716. for (@{ $form->{expense_accounts} }) { $selectaccount .= "<option>$_->{accno}--$_->{description}\n" }
  717. $form->{expense_accno} = qq|$form->{expense_accno}--$form->{expense_description}|;
  718. $form->{selectexpense} = $selectaccount;
  719. for (1 .. $form->{rate_rows}) { $form->{"rate_$_"} *= 100 }
  720. $form->{selectbase} = "<option>\n";
  721. for (@{ $form->{all_deduction} }) { $form->{selectbase} .= qq|<option value="$_->{description}--$_->{id}">$_->{description}\n| }
  722. &deduction_header;
  723. &deduction_footer;
  724. }
  725. sub deduction_header {
  726. $selectap = $form->{selectap};
  727. $selectap =~ s/option>\Q$form->{ap_accno}\E/option selected>$form->{ap_accno}/;
  728. $selectexpense = $form->{selectexpense};
  729. $selectexpense =~ s/option>\Q$form->{expense_accno}\E/option selected>$form->{expense_accno}/;
  730. $form->{rate_rows}++;
  731. $form->{base_rows}++;
  732. $form->{after_rows}++;
  733. $form->{selectbase} = $form->unescape($form->{selectbase});
  734. for $i (1 .. $form->{base_rows}) {
  735. $form->{"selectbase_$i"} = $form->{selectbase};
  736. if ($form->{"base_$i"}) {
  737. $form->{"selectbase_$i"} =~ s/(<option value="\Q$form->{"base_$i"}\E")/$1 selected/;
  738. }
  739. }
  740. for $i (1 .. $form->{after_rows}) {
  741. $form->{"selectafter_$i"} = $form->{selectbase};
  742. if ($form->{"after_$i"}) {
  743. $form->{"selectafter_$i"} =~ s/(<option value="\Q$form->{"after_$i"}\E")/$1 selected/;
  744. }
  745. }
  746. $form->header;
  747. print qq|
  748. <body>
  749. <form method=post action=$form->{script}>
  750. <input type=hidden name=title value="$form->{title}">
  751. <input type=hidden name=selectap value="$form->{selectap}">
  752. <input type=hidden name=selectexpense value="$form->{selectexpense}">
  753. <input type=hidden name=selectbase value="|.$form->escape($form->{selectbase},1).qq|">
  754. <input type=hidden name=rate_rows value=$form->{rate_rows}>
  755. <input type=hidden name=base_rows value=$form->{base_rows}>
  756. <input type=hidden name=after_rows value=$form->{after_rows}>
  757. <table width=100%>
  758. <tr>
  759. <th class=listtop>$form->{title}</th>
  760. </tr>
  761. <tr height="5"></tr>
  762. <tr>
  763. <td>
  764. <table>
  765. <tr>
  766. <th align=right nowrap>|.$locale->text('Description').qq|</th>
  767. <td><input name=description size=35 value="$form->{description}"></td>
  768. </tr>
  769. <tr>
  770. <th align=right nowrap>|.$locale->text('AP').qq|</th>
  771. <td><select name=ap_accno>$selectap</select></td>
  772. <th align=right nowrap>|.$locale->text('Employee pays').qq| x</th>
  773. <td><input name=employeepays size=4 value=|.$form->format_amount(\%myconfig, $form->{employeepays}).qq|></td>
  774. </tr>
  775. <tr>
  776. <th align=right nowrap>|.$locale->text('Expense').qq|</th>
  777. <td><select name=expense_accno>$selectexpense</select></td>
  778. <th align=right nowrap>|.$locale->text('Employer pays').qq| x</th>
  779. <td><input name=employerpays size=4 value=|.$form->format_amount(\%myconfig, $form->{employerpays}).qq|></td>
  780. </tr>
  781. <tr>
  782. <td></td>
  783. <td></td>
  784. <th align=right nowrap>|.$locale->text('Exempt age <').qq|</th>
  785. <td><input name=fromage size=4 value=|.$form->format_amount(\%myconfig, $form->{fromage}).qq|></td>
  786. <th align=right nowrap>&gt;</th>
  787. <td><input name=toage size=4 value=|.$form->format_amount(\%myconfig, $form->{toage}).qq|>
  788. </tr>
  789. <tr>
  790. <td></td>
  791. <td>
  792. <table>
  793. <tr class=listheading>
  794. <th class=listheading>|.$locale->text('Rate').qq| %</th>
  795. <th class=listheading>|.$locale->text('Amount').qq|</th>
  796. <th class=listheading>|.$locale->text('Above').qq|</th>
  797. <th class=listheading>|.$locale->text('Below').qq|</th>
  798. </tr>
  799. |;
  800. for $i (1 .. $form->{rate_rows}) {
  801. print qq|
  802. <tr>
  803. <td><input name="rate_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"rate_$i"}).qq|></td>
  804. <td><input name="amount_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"amount_$i"}, 2).qq|></td>
  805. <td><input name="above_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"above_$i"}, 2).qq|></td>
  806. <td><input name="below_$i" size=10 value=|.$form->format_amount(\%myconfig, $form->{"below_$i"}, 2).qq|></td>
  807. </tr>
  808. |;
  809. }
  810. print qq|
  811. </table>
  812. </td>
  813. </tr>
  814. </table>
  815. </td>
  816. </tr>
  817. |;
  818. print qq|
  819. <tr>
  820. <td>
  821. <table>
  822. |;
  823. $basedon = $locale->text('Based on');
  824. $maximum = $locale->text('Maximum');
  825. for $i (1 .. $form->{base_rows}) {
  826. print qq|
  827. <tr>
  828. <th>$basedon</th>
  829. <td><select name="base_$i">$form->{"selectbase_$i"}</select></td>
  830. <th>$maximum</th>
  831. <td><input name="maximum_$i" value=|.$form->format_amount(\%myconfig, $form->{"maximum_$i"}, 2).qq|></td>
  832. </tr>
  833. |;
  834. $basedon = "";
  835. $maximum = "";
  836. }
  837. $deductafter = $locale->text('Deduct after');
  838. for $i (1 .. $form->{after_rows}) {
  839. print qq|
  840. <tr>
  841. <th>$deductafter</th>
  842. <td><select name="after_$i">$form->{"selectafter_$i"}</select></td>
  843. </tr>
  844. |;
  845. $deductafter = "";
  846. }
  847. print qq|
  848. </table>
  849. </td>
  850. </tr>
  851. <tr>
  852. <td><hr size=3 noshade></td>
  853. </tr>
  854. </table>
  855. |;
  856. }
  857. sub deduction_footer {
  858. print qq|
  859. <input name="id" type="hidden" value="$form->{id}">
  860. <input type="hidden" name="db" value="$form->{db}">
  861. <input type="hidden" name="path" value="$form->{path}">
  862. <input type="hidden" name="login" value="$form->{login}">
  863. <input type="hidden" name="sessionid" value="$form->{sessionid}">
  864. <input type="hidden" name="callback" value="$form->{callback}">
  865. <br>
  866. <button class="submit" type="submit" name="action" value="update">|.$locale->text("Update").qq|</button>
  867. <button class="submit" type="submit" name="action" value="save">|.$locale->text("Save").qq|</button>
  868. |;
  869. if ($form->{id}) {
  870. print qq|<button class="submit" type="submit" name="action" value="save_as_new">|.$locale->text('Save as new').qq|</button>\n|;
  871. if ($form->{status} eq 'orphaned') {
  872. print qq|<button class="submit" type="submit" name="action" value="delete">|.$locale->text('Delete').qq|</button>\n|;
  873. }
  874. }
  875. if ($form->{lynx}) {
  876. require "bin/menu.pl";
  877. &menubar;
  878. }
  879. print qq|
  880. </form>
  881. </body>
  882. </html>
  883. |;
  884. }
  885. sub update { &{ "update_$form->{db}" }; }
  886. sub save { &{ "save_$form->{db}" } };
  887. sub update_deduction {
  888. # if rate or amount is blank remove row
  889. @flds = qw(rate amount above below);
  890. $count = 0;
  891. @a = ();
  892. for $i (1 .. $form->{rate_rows}) {
  893. for (@flds) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) }
  894. if ($form->{"rate_$i"} || $form->{"amount_$i"}) {
  895. push @a, {};
  896. $j = $#a;
  897. for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
  898. $count++;
  899. }
  900. }
  901. $form->redo_rows(\@flds, \@a, $count, $form->{rate_rows});
  902. $form->{rate_rows} = $count;
  903. @flds = qw(base maximum);
  904. $count = 0;
  905. @a = ();
  906. for $i (1 .. $form->{"base_rows"}) {
  907. $form->{"maximum_$i"} = $form->parse_amount(\%myconfig, $form->{"maximum_$i"});
  908. if ($form->{"base_$i"}) {
  909. push @a, {};
  910. $j = $#a;
  911. for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
  912. $count++;
  913. }
  914. }
  915. $form->redo_rows(\@flds, \@a, $count, $form->{"base_rows"});
  916. $form->{"base_rows"} = $count;
  917. @flds = qw(after);
  918. $count = 0;
  919. @a = ();
  920. for $i (1 .. $form->{"after_rows"}) {
  921. if ($form->{"after_$i"}) {
  922. push @a, {};
  923. $j = $#a;
  924. for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
  925. $count++;
  926. }
  927. }
  928. $form->redo_rows(\@flds, \@a, $count, $form->{"after_rows"});
  929. $form->{"after_rows"} = $count;
  930. &deduction_header;
  931. &deduction_footer;
  932. }
  933. sub update_employee {
  934. # if rate or amount is blank remove row
  935. @flds = qw(before after);
  936. $count = 0;
  937. @a = ();
  938. for $i (1 .. $form->{deduction_rows}) {
  939. for (@flds) { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) }
  940. if ($form->{"deduction_$i"}) {
  941. push @a, {};
  942. $j = $#a;
  943. for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
  944. $count++;
  945. }
  946. }
  947. $form->redo_rows(\@flds, \@a, $count, $form->{deduction_rows});
  948. $form->{deduction_rows} = $count;
  949. &employee_header;
  950. &employee_footer;
  951. }
  952. sub save_as_new {
  953. $form->{id} = 0;
  954. delete $form->{employeelogin};
  955. &save;
  956. }
  957. sub save_deduction {
  958. $form->isblank("description", $locale->text("Description missing!"));
  959. unless ($form->{"rate_1"} || $form->{"amount_1"}) {
  960. $form->isblank("rate_1", $locale->text("Rate missing!")) unless $form->{"amount_1"};
  961. $form->isblank("amount_1", $locale->text("Amount missing!"));
  962. }
  963. HR->save_deduction(\%myconfig, \%$form);
  964. $form->redirect($locale->text('Deduction saved!'));
  965. }
  966. sub delete_deduction {
  967. HR->delete_deduction(\%myconfig, \%$form);
  968. $form->redirect($locale->text('Deduction deleted!'));
  969. }