summaryrefslogtreecommitdiff
path: root/LedgerSMB/HR.pm
blob: 5ff8c2539f2054ca74da40b1bf74a61ab0e4575c (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. #
  5. # See COPYRIGHT file for copyright information
  6. #======================================================================
  7. #
  8. # This file has NOT undergone whitespace cleanup.
  9. #
  10. #======================================================================
  11. #
  12. # backend code for human resources and payroll
  13. #
  14. #======================================================================
  15. package HR;
  16. sub get_employee {
  17. my ($self, $myconfig, $form) = @_;
  18. my $dbh = $form->dbconnect($myconfig);
  19. my $query;
  20. my $sth;
  21. my $ref;
  22. my $notid = "";
  23. if ($form->{id}) {
  24. $query = qq|SELECT e.*
  25. FROM employee e
  26. WHERE e.id = $form->{id}|;
  27. $sth = $dbh->prepare($query);
  28. $sth->execute || $form->dberror($query);
  29. $ref = $sth->fetchrow_hashref(NAME_lc);
  30. # check if employee can be deleted, orphaned
  31. $form->{status} = "orphaned" unless $ref->{login};
  32. $form->{status} = 'orphaned'; # leave orphaned for now until payroll is done
  33. $ref->{employeelogin} = $ref->{login};
  34. delete $ref->{login};
  35. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  36. $sth->finish;
  37. # get manager
  38. $form->{managerid} *= 1;
  39. $query = qq|SELECT name
  40. FROM employee
  41. WHERE id = $form->{managerid}|;
  42. ($form->{manager}) = $dbh->selectrow_array($query);
  43. ######### disabled for now
  44. if ($form->{deductions}) {
  45. # get allowances
  46. $query = qq|SELECT d.id, d.description, da.before, da.after, da.rate
  47. FROM employeededuction da
  48. JOIN deduction d ON (da.deduction_id = d.id)
  49. WHERE da.employee_id = $form->{id}|;
  50. $sth = $dbh->prepare($query);
  51. $sth->execute || $form->dberror($query);
  52. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  53. $ref->{rate} *= 100;
  54. push @{ $form->{all_employeededuction} }, $ref;
  55. }
  56. $sth->finish;
  57. }
  58. $notid = qq|AND id != $form->{id}|;
  59. } else {
  60. $query = qq|SELECT current_date FROM defaults|;
  61. ($form->{startdate}) = $dbh->selectrow_array($query);
  62. }
  63. # get managers
  64. $query = qq|SELECT id, name
  65. FROM employee
  66. WHERE sales = '1'
  67. AND role = 'manager'
  68. $notid
  69. ORDER BY 2|;
  70. $sth = $dbh->prepare($query);
  71. $sth->execute || $form->dberror($query);
  72. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  73. push @{ $form->{all_manager} }, $ref;
  74. }
  75. $sth->finish;
  76. # get deductions
  77. if ($form->{deductions}) {
  78. $query = qq|SELECT id, description
  79. FROM deduction
  80. ORDER BY 2|;
  81. $sth = $dbh->prepare($query);
  82. $sth->execute || $form->dberror($query);
  83. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  84. push @{ $form->{all_deduction} }, $ref;
  85. }
  86. $sth->finish;
  87. }
  88. $dbh->disconnect;
  89. }
  90. sub save_employee {
  91. my ($self, $myconfig, $form) = @_;
  92. # connect to database
  93. my $dbh = $form->dbconnect_noauto($myconfig);
  94. my $query;
  95. my $sth;
  96. if (! $form->{id}) {
  97. my $uid = localtime;
  98. $uid .= "$$";
  99. $query = qq|INSERT INTO employee (name)
  100. VALUES ('$uid')|;
  101. $dbh->do($query) || $form->dberror($query);
  102. $query = qq|SELECT id FROM employee
  103. WHERE name = '$uid'|;
  104. $sth = $dbh->prepare($query);
  105. $sth->execute || $form->dberror($query);
  106. ($form->{id}) = $sth->fetchrow_array;
  107. $sth->finish;
  108. }
  109. my ($null, $managerid) = split /--/, $form->{manager};
  110. $managerid *= 1;
  111. $form->{sales} *= 1;
  112. $form->{employeenumber} = $form->update_defaults($myconfig, "employeenumber", $dbh) if ! $form->{employeenumber};
  113. $query = qq|UPDATE employee SET
  114. employeenumber = |.$dbh->quote($form->{employeenumber}).qq|,
  115. name = |.$dbh->quote($form->{name}).qq|,
  116. address1 = |.$dbh->quote($form->{address1}).qq|,
  117. address2 = |.$dbh->quote($form->{address2}).qq|,
  118. city = |.$dbh->quote($form->{city}).qq|,
  119. state = |.$dbh->quote($form->{state}).qq|,
  120. zipcode = |.$dbh->quote($form->{zipcode}).qq|,
  121. country = |.$dbh->quote($form->{country}).qq|,
  122. workphone = '$form->{workphone}',
  123. homephone = '$form->{homephone}',
  124. startdate = |.$form->dbquote($form->{startdate}, SQL_DATE).qq|,
  125. enddate = |.$form->dbquote($form->{enddate}, SQL_DATE).qq|,
  126. notes = |.$dbh->quote($form->{notes}).qq|,
  127. role = '$form->{role}',
  128. sales = '$form->{sales}',
  129. email = |.$dbh->quote($form->{email}).qq|,
  130. ssn = '$form->{ssn}',
  131. dob = |.$form->dbquote($form->{dob}, SQL_DATE).qq|,
  132. iban = '$form->{iban}',
  133. bic = '$form->{bic}',
  134. managerid = $managerid
  135. WHERE id = $form->{id}|;
  136. $dbh->do($query) || $form->dberror($query);
  137. # for now
  138. if ($form->{selectdeduction}) {
  139. # insert deduction and allowances for payroll
  140. $query = qq|DELETE FROM employeededuction
  141. WHERE employee_id = $form->{id}|;
  142. $dbh->do($query) || $form->dberror($query);
  143. $query = qq|INSERT INTO employeededuction (employee_id, deduction_id,
  144. before, after, rate) VALUES ($form->{id},?,?,?,?)|;
  145. my $sth = $dbh->prepare($query) || $form->dberror($query);
  146. for ($i = 1; $i <= $form->{deduction_rows}; $i++) {
  147. for (qw(before after)) { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) }
  148. ($null, $deduction_id) = split /--/, $form->{"deduction_$i"};
  149. if ($deduction_id) {
  150. $sth->execute($deduction_id, $form->{"before_$i"}, $form->{"after_$i"}, $form->{"rate_$i"} / 100) || $form->dberror($query);
  151. }
  152. }
  153. $sth->finish;
  154. }
  155. $dbh->commit;
  156. $dbh->disconnect;
  157. }
  158. sub delete_employee {
  159. my ($self, $myconfig, $form) = @_;
  160. # connect to database
  161. my $dbh = $form->dbconnect_noauto($myconfig);
  162. # delete employee
  163. my $query = qq|DELETE FROM $form->{db}
  164. WHERE id = $form->{id}|;
  165. $dbh->do($query) || $form->dberror($query);
  166. $dbh->commit;
  167. $dbh->disconnect;
  168. }
  169. sub employees {
  170. my ($self, $myconfig, $form) = @_;
  171. # connect to database
  172. my $dbh = $form->dbconnect($myconfig);
  173. my $where = "1 = 1";
  174. $form->{sort} = ($form->{sort}) ? $form->{sort} : "name";
  175. my @a = qw(name);
  176. my $sortorder = $form->sort_order(\@a);
  177. my $var;
  178. if ($form->{startdatefrom}) {
  179. $where .= " AND e.startdate >= '$form->{startdatefrom}'";
  180. }
  181. if ($form->{startdateto}) {
  182. $where .= " AND e.startddate <= '$form->{startdateto}'";
  183. }
  184. if ($form->{name} ne "") {
  185. $var = $form->like(lc $form->{name});
  186. $where .= " AND lower(e.name) LIKE '$var'";
  187. }
  188. if ($form->{notes} ne "") {
  189. $var = $form->like(lc $form->{notes});
  190. $where .= " AND lower(e.notes) LIKE '$var'";
  191. }
  192. if ($form->{sales} eq 'Y') {
  193. $where .= " AND e.sales = '1'";
  194. }
  195. if ($form->{status} eq 'orphaned') {
  196. $where .= qq| AND e.login IS NULL|;
  197. }
  198. if ($form->{status} eq 'active') {
  199. $where .= qq| AND e.enddate IS NULL|;
  200. }
  201. if ($form->{status} eq 'inactive') {
  202. $where .= qq| AND e.enddate <= current_date|;
  203. }
  204. my $query = qq|SELECT e.*, m.name AS manager
  205. FROM employee e
  206. LEFT JOIN employee m ON (m.id = e.managerid)
  207. WHERE $where
  208. ORDER BY $sortorder|;
  209. my $sth = $dbh->prepare($query);
  210. $sth->execute || $form->dberror($query);
  211. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  212. $ref->{address} = "";
  213. for (qw(address1 address2 city state zipcode country)) { $ref->{address} .= "$ref->{$_} " }
  214. push @{ $form->{all_employee} }, $ref;
  215. }
  216. $sth->finish;
  217. $dbh->disconnect;
  218. }
  219. sub get_deduction {
  220. my ($self, $myconfig, $form) = @_;
  221. my $dbh = $form->dbconnect($myconfig);
  222. my $query;
  223. my $sth;
  224. my $ref;
  225. my $item;
  226. my $i;
  227. if ($form->{id}) {
  228. $query = qq|SELECT d.*,
  229. c1.accno AS ap_accno,
  230. c1.description AS ap_description,
  231. c2.accno AS expense_accno,
  232. c2.description AS expense_description
  233. FROM deduction d
  234. LEFT JOIN chart c1 ON (c1.id = d.ap_accno_id)
  235. LEFT JOIN chart c2 ON (c2.id = d.expense_accno_id)
  236. WHERE d.id = $form->{id}|;
  237. $sth = $dbh->prepare($query);
  238. $sth->execute || $form->dberror($query);
  239. $ref = $sth->fetchrow_hashref(NAME_lc);
  240. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  241. $sth->finish;
  242. # check if orphaned
  243. $form->{status} = 'orphaned'; # for now
  244. # get the rates
  245. $query = qq|SELECT rate, amount, above, below
  246. FROM deductionrate
  247. WHERE trans_id = $form->{id}
  248. ORDER BY rate, amount|;
  249. $sth = $dbh->prepare($query);
  250. $sth->execute || $form->dberror($query);
  251. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  252. push @{ $form->{deductionrate} }, $ref;
  253. }
  254. $sth->finish;
  255. # get all for deductionbase
  256. $query = qq|SELECT d.description, d.id, db.maximum
  257. FROM deductionbase db
  258. JOIN deduction d ON (d.id = db.deduction_id)
  259. WHERE db.trans_id = $form->{id}|;
  260. $sth = $dbh->prepare($query);
  261. $sth->execute || $form->dberror($query);
  262. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  263. push @{ $form->{deductionbase} }, $ref;
  264. }
  265. $sth->finish;
  266. # get all for deductionafter
  267. $query = qq|SELECT d.description, d.id
  268. FROM deductionafter da
  269. JOIN deduction d ON (d.id = da.deduction_id)
  270. WHERE da.trans_id = $form->{id}|;
  271. $sth = $dbh->prepare($query);
  272. $sth->execute || $form->dberror($query);
  273. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  274. push @{ $form->{deductionafter} }, $ref;
  275. }
  276. $sth->finish;
  277. # build selection list for base and after
  278. $query = qq|SELECT id, description
  279. FROM deduction
  280. WHERE id != $form->{id}
  281. ORDER BY 2|;
  282. } else {
  283. # build selection list for base and after
  284. $query = qq|SELECT id, description
  285. FROM deduction
  286. ORDER BY 2|;
  287. }
  288. $sth = $dbh->prepare($query);
  289. $sth->execute || $form->dberror($query);
  290. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  291. push @{ $form->{all_deduction} }, $ref;
  292. }
  293. $sth->finish;
  294. my %category = ( ap => 'L',
  295. expense => 'E' );
  296. foreach $item (keys %category) {
  297. $query = qq|SELECT accno, description
  298. FROM chart
  299. WHERE charttype = 'A'
  300. AND category = '$category{$item}'
  301. ORDER BY accno|;
  302. $sth = $dbh->prepare($query);
  303. $sth->execute || $form->dberror($query);
  304. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  305. push @{ $form->{"${item}_accounts"} }, $ref;
  306. }
  307. $sth->finish;
  308. }
  309. $dbh->disconnect;
  310. }
  311. sub deductions {
  312. my ($self, $myconfig, $form) = @_;
  313. my $dbh = $form->dbconnect($myconfig);
  314. my $query = qq|SELECT d.id, d.description, d.employeepays, d.employerpays,
  315. c1.accno AS ap_accno, c2.accno AS expense_accno,
  316. dr.rate, dr.amount, dr.above, dr.below
  317. FROM deduction d
  318. JOIN deductionrate dr ON (dr.trans_id = d.id)
  319. LEFT JOIN chart c1 ON (d.ap_accno_id = c1.id)
  320. LEFT JOIN chart c2 ON (d.expense_accno_id = c2.id)
  321. ORDER BY 2, 7, 8|;
  322. my $sth = $dbh->prepare($query);
  323. $sth->execute || $form->dberror($query);
  324. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  325. push @{ $form->{all_deduction} }, $ref;
  326. }
  327. $sth->finish;
  328. $dbh->disconnect;
  329. }
  330. sub save_deduction {
  331. my ($self, $myconfig, $form) = @_;
  332. # connect to database
  333. my $dbh = $form->dbconnect_noauto($myconfig);
  334. ($form->{ap_accno}) = split /--/, $form->{ap_accno};
  335. ($form->{expense_accno}) = split /--/, $form->{expense_accno};
  336. my $null;
  337. my $deduction_id;
  338. my $query;
  339. my $sth;
  340. if (! $form->{id}) {
  341. my $uid = localtime;
  342. $uid .= "$$";
  343. $query = qq|INSERT INTO deduction (description)
  344. VALUES ('$uid')|;
  345. $dbh->do($query) || $form->dberror($query);
  346. $query = qq|SELECT id FROM deduction
  347. WHERE description = '$uid'|;
  348. $sth = $dbh->prepare($query);
  349. $sth->execute || $form->dberror($query);
  350. ($form->{id}) = $sth->fetchrow_array;
  351. $sth->finish;
  352. }
  353. for (qw(employeepays employerpays)) { $form->{$_} = $form->parse_amount($myconfig, $form->{$_}) }
  354. $query = qq|UPDATE deduction SET
  355. description = |.$dbh->quote($form->{description}).qq|,
  356. ap_accno_id =
  357. (SELECT id FROM chart
  358. WHERE accno = '$form->{ap_accno}'),
  359. expense_accno_id =
  360. (SELECT id FROM chart
  361. WHERE accno = '$form->{expense_accno}'),
  362. employerpays = '$form->{employerpays}',
  363. employeepays = '$form->{employeepays}',
  364. fromage = |.$form->dbquote($form->{fromage}, SQL_INT).qq|,
  365. toage = |.$form->dbquote($form->{toage}, SQL_INT).qq|
  366. WHERE id = $form->{id}|;
  367. $dbh->do($query) || $form->dberror($query);
  368. $query = qq|DELETE FROM deductionrate
  369. WHERE trans_id = $form->{id}|;
  370. $dbh->do($query) || $form->dberror($query);
  371. $query = qq|INSERT INTO deductionrate
  372. (trans_id, rate, amount, above, below) VALUES (?,?,?,?,?)|;
  373. $sth = $dbh->prepare($query) || $form->dberror($query);
  374. for ($i = 1; $i <= $form->{rate_rows}; $i++) {
  375. for (qw(rate amount above below)) { $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) }
  376. $form->{"rate_$i"} /= 100;
  377. if ($form->{"rate_$i"} || $form->{"amount_$i"}) {
  378. $sth->execute($form->{id}, $form->{"rate_$i"}, $form->{"amount_$i"}, $form->{"above_$i"}, $form->{"below_$i"}) || $form->dberror($query);
  379. }
  380. }
  381. $sth->finish;
  382. $query = qq|DELETE FROM deductionbase
  383. WHERE trans_id = $form->{id}|;
  384. $dbh->do($query) || $form->dberror($query);
  385. $query = qq|INSERT INTO deductionbase
  386. (trans_id, deduction_id, maximum) VALUES (?,?,?)|;
  387. $sth = $dbh->prepare($query) || $form->dberror($query);
  388. for ($i = 1; $i <= $form->{base_rows}; $i++) {
  389. ($null, $deduction_id) = split /--/, $form->{"base_$i"};
  390. $form->{"maximum_$i"} = $form->parse_amount($myconfig, $form->{"maximum_$i"});
  391. if ($deduction_id) {
  392. $sth->execute($form->{id}, $deduction_id, $form->{"maximum_$i"}) || $form->dberror($query);
  393. }
  394. }
  395. $sth->finish;
  396. $query = qq|DELETE FROM deductionafter
  397. WHERE trans_id = $form->{id}|;
  398. $dbh->do($query) || $form->dberror($query);
  399. $query = qq|INSERT INTO deductionafter
  400. (trans_id, deduction_id) VALUES (?,?)|;
  401. $sth = $dbh->prepare($query) || $form->dberror($query);
  402. for ($i = 1; $i <= $form->{after_rows}; $i++) {
  403. ($null, $deduction_id) = split /--/, $form->{"after_$i"};
  404. if ($deduction_id) {
  405. $sth->execute($form->{id}, $deduction_id) || $form->dberror($query);
  406. }
  407. }
  408. $sth->finish;
  409. $dbh->commit;
  410. $dbh->disconnect;
  411. }
  412. sub delete_deduction {
  413. my ($self, $myconfig, $form) = @_;
  414. # connect to database
  415. my $dbh = $form->dbconnect_noauto($myconfig);
  416. # delete deduction
  417. my $query = qq|DELETE FROM $form->{db}
  418. WHERE id = $form->{id}|;
  419. $dbh->do($query) || $form->dberror($query);
  420. foreach $item (qw(rate base after)) {
  421. $query = qq|DELETE FROM deduction$item
  422. WHERE trans_id = $form->{id}|;
  423. $dbh->do($query) || $form->dberror($query);
  424. }
  425. $dbh->commit;
  426. $dbh->disconnect;
  427. }
  428. 1;