summaryrefslogtreecommitdiff
path: root/LedgerSMB/User.pm
blob: a16cf7d5143167ffd4a5b35d57fe74185018d04a (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. # http://www.ledgersmb.org/
  5. #
  6. # Copyright (C) 2006
  7. # This work contains copyrighted information from a number of sources all used
  8. # with permission.
  9. #
  10. # This file contains source code included with or based on SQL-Ledger which
  11. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  12. # under the GNU General Public License version 2 or, at your option, any later
  13. # version. For a full list including contact information of contributors,
  14. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  15. #
  16. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  17. # Copyright (C) 2000
  18. #
  19. # Author: DWS Systems Inc.
  20. # Web: http://www.sql-ledger.org
  21. #
  22. # Contributors: Jim Rawlings <jim@your-dba.com>
  23. #
  24. #======================================================================
  25. #
  26. # This file has undergone whitespace cleanup.
  27. #
  28. #======================================================================
  29. #
  30. # user related functions
  31. #
  32. #=====================================================================
  33. package LedgerSMB::User;
  34. use LedgerSMB::Sysconfig;
  35. sub new {
  36. my ($type, $memfile, $login) = @_;
  37. my $self = {};
  38. if ($login ne "") {
  39. &error("", "$memfile locked!") if (-f "${memfile}.LCK");
  40. open(MEMBER, "$memfile") or &error("", "$memfile : $!");
  41. while (<MEMBER>) {
  42. if (/^\[$login\]/) {
  43. while (<MEMBER>) {
  44. last if /^\[/;
  45. next if /^(#|\s)/;
  46. # remove comments
  47. s/^\s*#.*//g;
  48. # remove any trailing whitespace
  49. s/^\s*(.*?)\s*$/$1/;
  50. ($key, $value) = split /=/, $_, 2;
  51. $self->{$key} = $value;
  52. }
  53. $self->{login} = $login;
  54. last;
  55. }
  56. }
  57. close MEMBER;
  58. }
  59. bless $self, $type;
  60. }
  61. sub country_codes {
  62. use Locale::Country;
  63. use Locale::Language;
  64. my %cc = ();
  65. # scan the locale directory and read in the LANGUAGE files
  66. opendir DIR, "${LedgerSMB::Sysconfig::localepath}";
  67. my @dir = grep !/^\..*$/, readdir DIR;
  68. foreach my $dir (@dir) {
  69. $dir = substr($dir, 0, -3);
  70. $cc{$dir} = code2language(substr($dir, 0, 2));
  71. $cc{$dir} .= ("/" . code2country(substr($dir, 3, 2)))
  72. if length($dir) > 2;
  73. $cc{$dir} .= (" " . substr($dir, 6)) if length($dir) > 5;
  74. }
  75. closedir(DIR);
  76. %cc;
  77. }
  78. sub login {
  79. my ($self, $form) = @_;
  80. my $rc = -1;
  81. if ($self->{login} ne "") {
  82. if ($self->{password} ne "") {
  83. my $password =
  84. crypt $form->{password},
  85. substr($self->{login}, 0, 2);
  86. if ($self->{password} ne $password) {
  87. return -1;
  88. }
  89. }
  90. #there shouldn't be any harm in always doing this.
  91. #It might even un-bork things.
  92. $self->create_config(
  93. "${LedgerSMB::Sysconfig::userspath}/$self->{login}.conf");
  94. do "${LedgerSMB::Sysconfig::userspath}/$self->{login}.conf";
  95. $myconfig{dbpasswd} = unpack 'u', $myconfig{dbpasswd};
  96. # check if database is down
  97. my $dbh = DBI->connect(
  98. $myconfig{dbconnect}, $myconfig{dbuser},
  99. $myconfig{dbpasswd})
  100. or $self->error($DBI::errstr);
  101. # we got a connection, check the version
  102. my $query = qq|
  103. SELECT value FROM defaults
  104. WHERE setting_key = 'version'|;
  105. my $sth = $dbh->prepare($query);
  106. $sth->execute || $form->dberror($query);
  107. my ($dbversion) = $sth->fetchrow_array;
  108. $sth->finish;
  109. # add login to employee table if it does not exist
  110. # no error check for employee table, ignore if it does not exist
  111. my $login = $self->{login};
  112. $login =~ s/@.*//;
  113. $query = qq|SELECT id FROM employee WHERE login = ?|;
  114. $sth = $dbh->prepare($query);
  115. $sth->execute($login);
  116. my ($id) = $sth->fetchrow_array;
  117. $sth->finish;
  118. if (! $id) {
  119. my ($employeenumber) =
  120. $form->update_defaults(
  121. \%myconfig, "employeenumber", $dbh);
  122. $query = qq|
  123. INSERT INTO employee
  124. (login, employeenumber, name,
  125. workphone, role)
  126. VALUES (?, ?, ?, ?, ?)|;
  127. $sth = $dbh->prepare($query);
  128. $sth->execute(
  129. $login, $employeenumber, $myconfig{name},
  130. $myconfig{tel}, $myconfig{role});
  131. }
  132. $dbh->disconnect;
  133. $rc = 0;
  134. if ($form->{dbversion} ne $dbversion) {
  135. $rc = -3;
  136. $dbupdate = (calc_version($dbversion)
  137. < calc_version($form->{dbversion}));
  138. }
  139. if ($dbupdate) {
  140. $rc = -4;
  141. # if DB2 bale out
  142. if ($myconfig{dbdriver} eq 'DB2') {
  143. $rc = -2;
  144. }
  145. }
  146. }
  147. $rc;
  148. }
  149. sub check_recurring {
  150. my ($self, $form) = @_;
  151. $self->{dbpasswd} = unpack 'u', $self->{dbpasswd};
  152. my $dbh = DBI->connect(
  153. $self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd})
  154. or $form->dberror;
  155. my $query = qq|
  156. SELECT count(*) FROM recurring
  157. WHERE enddate >= current_date AND nextdate <= current_date|;
  158. ($_) = $dbh->selectrow_array($query);
  159. $dbh->disconnect;
  160. $_;
  161. }
  162. sub dbconnect_vars {
  163. my ($form, $db) = @_;
  164. my %dboptions = (
  165. 'Pg' => {
  166. 'yy-mm-dd' => 'set DateStyle to \'ISO\'',
  167. 'mm/dd/yy' => 'set DateStyle to \'SQL, US\'',
  168. 'mm-dd-yy' => 'set DateStyle to \'POSTGRES, US\'',
  169. 'dd/mm/yy' => 'set DateStyle to \'SQL, EUROPEAN\'',
  170. 'dd-mm-yy' => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
  171. 'dd.mm.yy' => 'set DateStyle to \'GERMAN\''
  172. }
  173. );
  174. $form->{dboptions} = $dboptions{$form->{dbdriver}}{$form->{dateformat}};
  175. $form->{dbconnect} = "dbi:$form->{dbdriver}:dbname=$db";
  176. if ($form->{dbhost}) {
  177. $form->{dbconnect} .= ";host=$form->{dbhost}";
  178. }
  179. if ($form->{dbport}) {
  180. $form->{dbconnect} .= ";port=$form->{dbport}";
  181. }
  182. }
  183. sub dbdrivers {
  184. my @drivers = DBI->available_drivers();
  185. # return (grep { /(Pg|Oracle|DB2)/ } @drivers);
  186. return (grep { /Pg$/ } @drivers);
  187. }
  188. sub dbsources {
  189. my ($self, $form) = @_;
  190. my @dbsources = ();
  191. my ($sth, $query);
  192. $form->{dbdefault} = $form->{dbuser} unless $form->{dbdefault};
  193. $form->{sid} = $form->{dbdefault};
  194. &dbconnect_vars($form, $form->{dbdefault});
  195. my $dbh = DBI->connect(
  196. $form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
  197. or $form->dberror;
  198. if ($form->{dbdriver} eq 'Pg') {
  199. $query = qq|SELECT datname FROM pg_database|;
  200. $sth = $dbh->prepare($query);
  201. $sth->execute || $form->dberror($query);
  202. while (my ($db) = $sth->fetchrow_array) {
  203. if ($form->{only_acc_db}) {
  204. next if ($db =~ /^template/);
  205. &dbconnect_vars($form, $db);
  206. my $dbh = DBI->connect(
  207. $form->{dbconnect}, $form->{dbuser},
  208. $form->{dbpasswd})
  209. or $form->dberror;
  210. $query = qq|
  211. SELECT tablename FROM pg_tables
  212. WHERE tablename = 'defaults'
  213. AND tableowner = ?|;
  214. my $sth = $dbh->prepare($query);
  215. $sth->execute($form->{dbuser})
  216. || $form->dberror($query);
  217. if ($sth->fetchrow_array) {
  218. push @dbsources, $db;
  219. }
  220. $sth->finish;
  221. $dbh->disconnect;
  222. next;
  223. }
  224. push @dbsources, $db;
  225. }
  226. }
  227. $sth->finish;
  228. $dbh->disconnect;
  229. return @dbsources;
  230. }
  231. sub dbcreate {
  232. my ($self, $form) = @_;
  233. my %dbcreate = ( 'Pg' => qq|CREATE DATABASE "$form->{db}"| );
  234. $dbcreate{Pg} .= " WITH ENCODING = '$form->{encoding}'"
  235. if $form->{encoding};
  236. $form->{sid} = $form->{dbdefault};
  237. &dbconnect_vars($form, $form->{dbdefault});
  238. # The below line connects to Template1 or another template file in order
  239. # to create the db. One must disconnect and reconnect later.
  240. if ($form->{dbsuperuser}){
  241. my $superdbh = DBI->connect(
  242. $form->{dbconnect},
  243. $form->{dbsuperuser},
  244. $form->{dbsuperpasswd})
  245. or $form->dberror;
  246. my $query = qq|$dbcreate{$form->{dbdriver}}|;
  247. $superdbh->do($query) || $form->dberror($query);
  248. $superdbh->disconnect;
  249. }
  250. #Reassign for the work below
  251. &dbconnect_vars($form, $form->{db});
  252. my $dbh = DBI->connect(
  253. $form->{dbconnect},
  254. $form->{dbuser},
  255. $form->{dbpasswd})
  256. or $form->dberror;
  257. if ($form->{dbsuperuser}){
  258. my $superdbh = DBI->connect(
  259. $form->{dbconnect},
  260. $form->{dbsuperuser},
  261. $form->{dbsuperpasswd})
  262. or $form->dberror;
  263. # JD: We need to check for plpgsql,
  264. # if it isn't there create it, if we can't error
  265. # Good chance I will have to do this twice as I get
  266. # used to the way the code is structured
  267. my %langcreate = ( 'Pg' => qq|CREATE LANGUAGE plpgsql|);
  268. my $query = qq|$langcreate{$form->{dbdriver}}|;
  269. $superdbh->do($query);
  270. $superdbh->disconnect;
  271. }
  272. # create the tables
  273. my $dbdriver =
  274. ($form->{dbdriver} =~ /Pg/)
  275. ? 'Pg'
  276. : $form->{dbdriver};
  277. my $filename = qq|sql/${dbdriver}-tables.sql|;
  278. $self->process_query($form, $dbh, $filename);
  279. # create functions
  280. $filename = qq|sql/${dbdriver}-functions.sql|;
  281. $self->process_query($form, $dbh, $filename);
  282. # load gifi
  283. ($filename) = split /_/, $form->{chart};
  284. $filename =~ s/_//;
  285. $self->process_query($form, $dbh, "sql/${filename}-gifi.sql");
  286. # load chart of accounts
  287. $filename = qq|sql/$form->{chart}-chart.sql|;
  288. $self->process_query($form, $dbh, $filename);
  289. # create indices
  290. $filename = qq|sql/${dbdriver}-indices.sql|;
  291. $self->process_query($form, $dbh, $filename);
  292. # create custom tables and functions
  293. my $item;
  294. foreach $item (qw(tables functions)) {
  295. $filename = "sql/${dbdriver}-custom_${item}.sql";
  296. if (-f "$filename") {
  297. $self->process_query($form, $dbh, $filename);
  298. }
  299. }
  300. $dbh->disconnect;
  301. }
  302. sub process_query {
  303. my ($self, $form, $dbh, $filename) = @_;
  304. return unless (-f $filename);
  305. open(FH, "$filename") or $form->error("$filename : $!\n");
  306. $ENV{PGPASSWORD} = $form->{dbpasswd};
  307. $ENV{PGUSER} = $form->{dbuser};
  308. $ENV{PGDATABASE} = $form->{db};
  309. open(PSQL, "| psql") or $form->error("psql : $! \n");
  310. print PSQL "\\o spool/log \n";
  311. while (<FH>){
  312. print PSQL $_;
  313. }
  314. close FH;
  315. }
  316. sub dbdelete {
  317. my ($self, $form) = @_;
  318. $form->{sid} = $form->{dbdefault};
  319. &dbconnect_vars($form, $form->{dbdefault});
  320. my $dbh = DBI->connect(
  321. $form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
  322. or $form->dberror;
  323. my $query = qq|DROP DATABASE "$form->{db}"|;
  324. $dbh->do($query) || $form->dberror($query);
  325. $dbh->disconnect;
  326. }
  327. sub dbsources_unused {
  328. my ($self, $form, $memfile) = @_;
  329. my @dbexcl = ();
  330. my @dbsources = ();
  331. $form->error("$memfile locked!") if (-f "${memfile}.LCK");
  332. # open members file
  333. open(FH, "$memfile") or $form->error("$memfile : $!");
  334. while (<FH>) {
  335. if (/^dbname=/) {
  336. my ($null,$item) = split /=/;
  337. push @dbexcl, $item;
  338. }
  339. }
  340. close FH;
  341. $form->{only_acc_db} = 1;
  342. my @db = &dbsources("", $form);
  343. push @dbexcl, $form->{dbdefault};
  344. foreach $item (@db) {
  345. unless (grep /$item$/, @dbexcl) {
  346. push @dbsources, $item;
  347. }
  348. }
  349. return @dbsources;
  350. }
  351. sub dbneedsupdate {
  352. my ($self, $form) = @_;
  353. my %dbsources = ();
  354. my $query;
  355. $form->{sid} = $form->{dbdefault};
  356. &dbconnect_vars($form, $form->{dbdefault});
  357. my $dbh = DBI->connect(
  358. $form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
  359. or $form->dberror;
  360. if ($form->{dbdriver} =~ /Pg/) {
  361. $query = qq|
  362. SELECT d.datname
  363. FROM pg_database d, pg_user u
  364. WHERE d.datdba = u.usesysid
  365. AND u.usename = ?|;
  366. my $sth = $dbh->prepare($query);
  367. $sth->execute($form->{dbuser}) || $form->dberror($query);
  368. while (my ($db) = $sth->fetchrow_array) {
  369. next if ($db =~ /^template/);
  370. &dbconnect_vars($form, $db);
  371. my $dbh = DBI->connect(
  372. $form->{dbconnect}, $form->{dbuser},
  373. $form->{dbpasswd})
  374. or $form->dberror;
  375. $query = qq|
  376. SELECT tablename
  377. FROM pg_tables
  378. WHERE tablename = 'defaults'|;
  379. my $sth = $dbh->prepare($query);
  380. $sth->execute || $form->dberror($query);
  381. if ($sth->fetchrow_array) {
  382. $query = qq|
  383. SELECT value FROM defaults
  384. WHERE setting_key = 'version'|;
  385. my $sth = $dbh->prepare($query);
  386. $sth->execute;
  387. if (my ($version) = $sth->fetchrow_array) {
  388. $dbsources{$db} = $version;
  389. }
  390. $sth->finish;
  391. }
  392. $sth->finish;
  393. $dbh->disconnect;
  394. }
  395. $sth->finish;
  396. }
  397. $dbh->disconnect;
  398. %dbsources;
  399. }
  400. sub dbupdate {
  401. my ($self, $form) = @_;
  402. $form->{sid} = $form->{dbdefault};
  403. my @upgradescripts = ();
  404. my $query;
  405. my $rc = -2;
  406. if ($form->{dbupdate}) {
  407. # read update scripts into memory
  408. opendir SQLDIR, "sql/." or $form->error($!);
  409. @upgradescripts =
  410. sort script_version
  411. grep /$form->{dbdriver}-upgrade-.*?\.sql$/,
  412. readdir SQLDIR;
  413. closedir SQLDIR;
  414. }
  415. foreach my $db (split / /, $form->{dbupdate}) {
  416. next unless $form->{$db};
  417. # strip db from dataset
  418. $db =~ s/^db//;
  419. &dbconnect_vars($form, $db);
  420. my $dbh = DBI->connect(
  421. $form->{dbconnect}, $form->{dbuser},
  422. $form->{dbpasswd}, {AutoCommit => 0})
  423. or $form->dberror;
  424. # check version
  425. $query = qq|
  426. SELECT value FROM defaults
  427. WHERE setting_key = 'version'|;
  428. my $sth = $dbh->prepare($query);
  429. # no error check, let it fall through
  430. $sth->execute;
  431. my $version = $sth->fetchrow_array;
  432. $sth->finish;
  433. next unless $version;
  434. $version = calc_version($version);
  435. my $dbversion = calc_version($form->{dbversion});
  436. foreach my $upgradescript (@upgradescripts) {
  437. my $a = $upgradescript;
  438. $a =~ s/(^$form->{dbdriver}-upgrade-|\.sql$)//g;
  439. my ($mindb, $maxdb) = split /-/, $a;
  440. $mindb = calc_version($mindb);
  441. $maxdb = calc_version($maxdb);
  442. next if ($version >= $maxdb);
  443. # exit if there is no upgrade script or version == mindb
  444. last if ($version < $mindb || $version >= $dbversion);
  445. # apply upgrade
  446. $self->process_query($form, $dbh, "sql/$upgradescript");
  447. $dbh->commit;
  448. $version = $maxdb;
  449. }
  450. $rc = 0;
  451. $dbh->disconnect;
  452. }
  453. $rc;
  454. }
  455. sub calc_version {
  456. my @v = split /\./, $_[0];
  457. my $version = 0;
  458. my $i;
  459. for ($i = 0; $i <= $#v; $i++) {
  460. $version *= 1000;
  461. $version += $v[$i];
  462. }
  463. return $version;
  464. }
  465. sub script_version {
  466. my ($my_a, $my_b) = ($a, $b);
  467. my ($a_from, $a_to, $b_from, $b_to);
  468. my ($res_a, $res_b, $i);
  469. $my_a =~ s/.*-upgrade-//;
  470. $my_a =~ s/.sql$//;
  471. $my_b =~ s/.*-upgrade-//;
  472. $my_b =~ s/.sql$//;
  473. ($a_from, $a_to) = split(/-/, $my_a);
  474. ($b_from, $b_to) = split(/-/, $my_b);
  475. $res_a = calc_version($a_from);
  476. $res_b = calc_version($b_from);
  477. if ($res_a == $res_b) {
  478. $res_a = calc_version($a_to);
  479. $res_b = calc_version($b_to);
  480. }
  481. return $res_a <=> $res_b;
  482. }
  483. sub create_config {
  484. my ($self, $filename) = @_;
  485. @config = &config_vars;
  486. open(CONF, ">$filename") or $self->error("$filename : $!");
  487. # create the config file
  488. print CONF qq|# configuration file for $self->{login}
  489. \%myconfig = (
  490. |;
  491. foreach $key (sort @config) {
  492. $self->{$key} =~ s/\\/\\\\/g;
  493. $self->{$key} =~ s/'/\\'/g;
  494. #remaining conversion from SL
  495. $self->{$key} =~ s/sql-ledger([^.]*)\.css/ledger-smb$1.css/g;
  496. print CONF qq| $key => '$self->{$key}',\n|;
  497. }
  498. print CONF qq|);\n\n|;
  499. close CONF;
  500. }
  501. sub save_member {
  502. my ($self) = @_;
  503. # format dbconnect and dboptions string
  504. &dbconnect_vars($self, $self->{dbname});
  505. $self->error("${LedgerSMB::Sysconfig::memberfile} locked!")
  506. if (-f "${LedgerSMB::Sysconfig::memberfile}.LCK");
  507. open(FH, ">${LedgerSMB::Sysconfig::memberfile}.LCK")
  508. or $self->error("${LedgerSMB::Sysconfig::memberfile}.LCK : $!");
  509. close(FH);
  510. if (! open(CONF, "+<${LedgerSMB::Sysconfig::memberfile}")) {
  511. unlink "${LedgerSMB::Sysconfig::memberfile}.LCK";
  512. $self->error("${LedgerSMB::Sysconfig::memberfile} : $!");
  513. }
  514. @config = <CONF>;
  515. seek(CONF, 0, 0);
  516. truncate(CONF, 0);
  517. while ($line = shift @config) {
  518. last if ($line =~ /^\[$self->{login}\]/);
  519. #remaining conversion from SL
  520. $line =~ s/sql-ledger([^.]*)\.css/ledger-smb$1.css/g;
  521. print CONF $line;
  522. }
  523. # remove everything up to next login or EOF
  524. while ($line = shift @config) {
  525. last if ($line =~ /^\[/);
  526. }
  527. # this one is either the next login or EOF
  528. print CONF $line;
  529. while ($line = shift @config) {
  530. print CONF $line;
  531. }
  532. print CONF qq|[$self->{login}]\n|;
  533. if ($self->{packpw}) {
  534. $self->{dbpasswd} = pack 'u', $self->{dbpasswd};
  535. chop $self->{dbpasswd};
  536. }
  537. if ($self->{password} ne $self->{old_password}) {
  538. $self->{password} = crypt $self->{password},
  539. substr($self->{login}, 0, 2) if $self->{password};
  540. }
  541. if ($self->{'root login'}) {
  542. @config = qw(password);
  543. } else {
  544. @config = &config_vars;
  545. }
  546. # replace \r\n with \n
  547. for (qw(address signature)) { $self->{$_} =~ s/\r?\n/\\n/g }
  548. for (sort @config) {
  549. print CONF qq|$_=$self->{$_}\n|
  550. }
  551. print CONF "\n";
  552. close CONF;
  553. unlink "${LedgerSMB::Sysconfig::memberfile}.LCK";
  554. # create conf file
  555. if (! $self->{'root login'}) {
  556. $self->create_config("${LedgerSMB::Sysconfig::userspath}/$self->{login}.conf");
  557. $self->{dbpasswd} =~ s/\\'/'/g;
  558. $self->{dbpasswd} =~ s/\\\\/\\/g;
  559. $self->{dbpasswd} = unpack 'u', $self->{dbpasswd};
  560. # check if login is in database
  561. my $dbh = DBI->connect(
  562. $self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd},
  563. {AutoCommit => 0})
  564. or $self->error($DBI::errstr);
  565. # add login to employee table if it does not exist
  566. my $login = $self->{login};
  567. $login =~ s/@.*//;
  568. my $query = qq|SELECT id FROM employee WHERE login = '$login'|;
  569. my $sth = $dbh->prepare($query);
  570. $sth->execute;
  571. my ($id) = $sth->fetchrow_array;
  572. $sth->finish;
  573. my $employeenumber;
  574. my @values;
  575. if ($id) {
  576. $query = qq|UPDATE employee SET
  577. role = ?,
  578. email = ?,
  579. name = ?
  580. WHERE login = ?|;
  581. @values = ($self->{role}, $self->{email}, $self->{name}, $login);
  582. } else {
  583. my ($employeenumber) = Form::update_defaults(
  584. "", \%$self, "employeenumber", $dbh);
  585. $query = qq|
  586. INSERT INTO employee
  587. (login, employeenumber, name,
  588. workphone, role, email, sales)
  589. VALUES (?, ?, ?, ?, ?, ?, '1')|;
  590. @values = ($login, $employeenumber, $self->{name}, $self->{tel},
  591. $self->{role}, $self->{email})
  592. }
  593. $sth = $dbh->prepare($query);
  594. $sth->execute(@values);
  595. $dbh->commit;
  596. $dbh->disconnect;
  597. }
  598. }
  599. sub delete_login {
  600. my ($self, $form) = @_;
  601. my $dbh = DBI->connect(
  602. $form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd},
  603. {AutoCommit => 0})
  604. or $form->dberror;
  605. my $login = $form->{login};
  606. $login =~ s/@.*//;
  607. my $query = qq|SELECT id FROM employee WHERE login = ?|;
  608. my $sth = $dbh->prepare($query);
  609. $sth->execute($login) || $form->dberror($query);
  610. my ($id) = $sth->fetchrow_array;
  611. $sth->finish;
  612. my $query = qq|
  613. UPDATE employee
  614. SET login = NULL,
  615. enddate = current_date
  616. WHERE login = ?|;
  617. $sth = $dbh->prepare($query);
  618. $sth->execute($login);
  619. $dbh->commit;
  620. $dbh->disconnect;
  621. }
  622. sub config_vars {
  623. my @conf =
  624. qw(acs address businessnumber company countrycode
  625. currency dateformat dbconnect dbdriver dbhost dbname dboptions
  626. dbpasswd dbport dbuser email fax menuwidth name numberformat
  627. password printer role sid signature stylesheet tel templates
  628. timeout vclimit);
  629. @conf;
  630. }
  631. sub error {
  632. my ($self, $msg) = @_;
  633. if ($ENV{HTTP_USER_AGENT}) {
  634. print qq|Content-Type: text/html\n\n|.
  635. qq|<body bgcolor=ffffff>\n\n|.
  636. qq|<h2><font color=red>Error!</font></h2>\n|.
  637. qq|<p><b>$msg</b>|;
  638. }
  639. die "Error: $msg\n";
  640. }
  641. 1;