<?/*
Copyright (C) 2003 Media Net Link, Inc. Danville, CA 94526 USA

This file is part of AthenaRMS.

AthenaRMS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

AthenaRMS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/?>
<?php

require_once 'html.php';
require_once 'server_functions.php';

##
## - deletes need changed to delete from person_customer_map
## - need to make one big delete function which removes?
##     person,
##     person_customer_map,
##     person_type_assignment
##

class Person extends HTML {

  function Person () {
    global $dbi;
    $this->db = &$dbi;
    $this->error = false;
  }

  function Update_Password ($pid, $pass) {
    $to_date = to_date();
    $h = $this->db->prepare ("
      update person
         set password  = ?,
             updated_date = $to_date
       where person_id = ?
    ");
    $add = array();
    $this->Set_Audit_Info( $add );
    $res = $this->db->execute ( $h, array($pass, $add['UPDATED_DATE'], $pid));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }

    return 1;
  }

  function Info_by_Person_ID ($pid) {
    $person_r = new Person_Record ();
    
    $person_r->Select_by_Person_ID ($pid);

    return $person_r;
  }

  function Info_by_Map_ID ($pmid) {
    $person_r = new Person_Record ();
    
    if (!$person_r->Select_by_Map_ID ($pmid)) {
      $this->error = 'Person::Info_by_Map_ID(): ' . $person_r->error;
      return;
    }

    return $person_r;
  }

  function Info_by_Person_CRM_ID ($pid, $crm_id) {
    $person_r = new Person_Record ();
    
    $person_r->Select_by_Map_ID ($pid, $crm_id);

    return $person_r;
  }

  function Update_All () {
    if (!$this->Update ()) return 0;
    if (!$this->Update_Map ()) return 0;
    return 1;
  }

  function Update_Map () {
    $this->Set_Audit_Info ($this);

    $to_date = to_date();
    $h = $this->db->prepare ("
       update person_crm_map
          set support_drop_down = ?,
              escalated_drop_down = ?,
              modify_tickets = ?,
              updated_by = ?,
              updated_date = $to_date
        where pcrm_map_id = ?
    ");
    return $this->db->execute ($h, array(
      $this->support_drop_down,
      $this->escalated_drop_down,
      $this->modify_tickets,
      $this->updated_by,
      $this->updated_date,
      $this->pcrm_map_id
    ));
  }

  function Update () {
    $this->Set_Audit_Info ($this);

    $h = $this->db->prepare ('
             update person
                set first_name     = ?,
                    last_name      = ?,
                    middle_initial = ?,
                    email          = ?,
                    home_phone     = ?,
                    work_phone     = ?,
                    cell_phone     = ?,
                    pager_num      = ?,
                    address1       = ?,
                    address2       = ?,
                    city           = ?,
                    state          = ?,
                    zip            = ?,
                    updated_by     = ?,
                    updated_date   = ?,
                    company        = ?,
                    title          = ?
              where person_id      = ?
    ');
    return $this->db->execute ($h, array(
      $this->first_name,
      $this->last_name,
      $this->middle_initial,
      $this->email,
      $this->home_phone,
      $this->work_phone,
      $this->cell_phone,
      $this->pager_num,
      $this->address1,
      $this->address2,
      $this->city,
      $this->state,
      $this->zip,
      $this->updated_by,
      $this->updated_date,
      $this->company,
      $this->title,
      $this->person_id
    ));
  }

  function Delete ($pid) {
    $h = $this->db->prepare ('
      delete from person
            where person_id = ?
    ');
    $res = $this->db->execute ( $h, array($pid));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return 0;
    }
    return 1;
  }

  function Add ($add) {
/*
    ## original arg to Add was $in_ary
    $add = array();
    foreach ($in_ary as $k => $v) {
      $add[strtoupper($k)] = $v;
    }
*/

    if (!array_key_exists('person_id', $add)) {
      $add['person_id'] = $this->db->nextId ('person_person_id');
    }

    // FIXME; this should be per-instance
    if (!array_key_exists('state', $add)) $add['state'] = 'CA';

    foreach (array ('support_drop_down',
                    'escalated_drop_down',
                    'modify_tickets',
            ) as $k) {
      if (!array_key_exists($k, $add) || !$add[$k]) { $add[$k] = 'N'; }
    }

    $this->Set_Audit_Info ($add);

    $to_date = to_date();
    $h = $this->db->prepare ("
      insert into person (
        person_id,
        first_name,
        last_name,
        middle_initial,
        email,
        home_phone,
        work_phone,
        cell_phone,
        pager_num,
        address1,
        address2,
        city,
        state,
        zip,
        company,
        title,
        updated_by,
        created_by,
        updated_date,
        created_date
      ) values (
        ?, ?, ?, ?, ?,
        ?, ?, ?, ?, ?,
        ?, ?, ?, ?, ?,
        ?, ?, ?,
	$to_date,
	$to_date
      )
    ");

    foreach (array('company', 'title') as $k)
      if (!array_key_exists($k, $add)) $add[$k] = null;

    notices_off();
    $ok = $this->db->execute ($h, array(
      $add['person_id'],
      $add['first_name'],
      $add['last_name'],
      $add['middle_initial'],
      $add['email'],
      $add['home_phone'],
      $add['work_phone'],
      $add['cell_phone'],
      $add['pager_num'],
      $add['address1'],
      $add['address2'],
      $add['city'],
      $add['state'],
      $add['zip'],
      $add['company'],
      $add['title'],
      $add['UPDATED_BY'],
      $add['CREATED_BY'],
      $add['UPDATED_DATE'],
      $add['CREATED_DATE']
    ));
    notices_on();

    if (DB::isError($ok)) {
       $this->error = 'Person::Add(): ' . $ok->getMessage()
	. "\n" . $ok->getUserInfo();
       return;
    }

    if (!$ok) {
	$this->error = 'Person::Add(): ' . $h->error();
	return;
    }

    return $add['person_id'];
  }

  function Add_Map ($in_ary) {
    $add = array();
    foreach ($in_ary as $k => $v) {
      $add[strtoupper($k)] = $v;
    }

    if (!array_key_exists('PCRM_MAP_ID', $add)) {
      $add['PCRM_MAP_ID'] = $this->db->nextId ('person_crm_map_id');
    }

    foreach (array (
      'SUPPORT_DROP_DOWN',
      'ESCALATED_DROP_DOWN',
      'MODIFY_TICKETS'
    ) as $col) {
      if (!array_key_exists($col, $add)) $add[$col] = 'Y';
      else {
	$add[$col] = strtoupper ($add[$col]);
	if ($add[$col] != 'N') $add[$col] = 'Y';
      }
    }

    $this->Set_Audit_Info ($add);

    $binds = array(
      $add['PCRM_MAP_ID'],
      $add['PERSON_ID'],
      $add['CRM_ID'],
      $add['SUPPORT_DROP_DOWN'],
      $add['ESCALATED_DROP_DOWN'],
      $add['MODIFY_TICKETS'],
      $add['UPDATED_BY'],
      $add['CREATED_BY'],
      $add['CREATED_DATE'],
      $add['UPDATED_DATE']
    );

    $to_date = to_date();
    $h = $this->db->prepare ("
      insert into person_crm_map (
        pcrm_map_id,
        person_id,
        crm_id,
        support_drop_down,
        escalated_drop_down,
        modify_tickets,
        updated_by,
        created_by,
        created_date,
        updated_date
      ) values (
        ?, ?, ?, ?, ?, ?, ?, ?,
	$to_date,
	$to_date
      )
    ");
    $ok = $this->db->execute( $h, $binds );
    if (DB::isError($ok)) {
       $this->error = $ok->getMessage() . "\n" . $ok->getUserInfo();
       return;
    }

    return $add['PCRM_MAP_ID'];
  }

  function Delete_Map ($mapid_or_pid, $crm_id='') {
    $binds = array($mapid_or_pid);
    $sql = ' pcrm_map_id = ? ';
  
    if ($crm_id) { ## assume pid
      $sql = ' person_id = ? and crm_id = ? ';
      $binds[] = $crm_id;
    }

    $sql = "
      delete from person_crm_map
            where $sql
    ";

    $h = $this->db->prepare ($sql);
    return $this->db->execute ($h, $binds);
  }

  function Set_Types ($types, $pmid) {
    $this->Delete_Types ($pmid);

    if (count($types)) {
      return $this->Add_Types ($types, $pmid);
    } else {
      return $this->Delete_Map ($pmid);
    }
  }

  function Add_Types ($types, $pmid) {

    $add = array();

    $this->Set_Audit_Info( $add );

    $to_date = to_date();
    $h = $this->db->prepare ("
      insert into person_crm_type_assign (
        person_type,
        pcrm_map_id,
        updated_by,
        created_by,
        updated_date,
        created_date
      ) values (
        ?, ?, ?, ?,
	$to_date,
	$to_date
      )
    ");

    foreach ($types as $type) {
      $res = $this->db->execute ($h, array($type, $pmid, $add['UPDATED_BY'],
               $add['CREATED_BY'], $add['CREATED_DATE'], $add['UPDATED_DATE']));
      if (DB::isError($res)) {
         $this->error = $res->getMessage() . "\n" . $res->getUserInfo();
	 return;
      }
    }

    return true;
  }

  function Delete_Types ($pmid) {
    $h = $this->db->prepare ('
      delete from person_crm_type_assign
            where pcrm_map_id = ?
    ');
    return $this->db->execute ($h, array($pmid));
  }

  ## add new param to specify more where critera
  # $hash[column] = 'where data..'
  function &List_By ($person_type='', $list_names=1, $crm_id='', $assoc=DB_FETCHMODE_ASSOC) {
    if (!$crm_id) $crm_id = $this->Current_CRM ();
    if (!$crm_id) {
      $this->error = 'Person::List_By(): ' . $this->error;
      return;
    }
    if (!$crm_id) return 0;

    $binds = array ($crm_id);

    $sql = ' select p.person_id as person_id ';

    $last_first = sql_concat('p.last_name', "', '", 'p.first_name');
   
    if ($list_names == 3) {
      $sql .= ", $last_first AS name ";
    } if ($list_names == 4) {
      $sql .= ", $last_first AS name, p.email ";
    } elseif ($list_names) {
      $sql .= ',
               p.last_name as last_name,
               p.first_name as first_name,
               pcm.support_drop_down as support_drop_down,
               pcm.escalated_drop_down as escalated_drop_down,
               pcm.pcrm_map_id,
               null as base_person_type,
               p.email
      ';
    }

    if ($person_type) {
      $person_crm_type_assign_join = 'left outer join person_crm_type_assign pcta on (pcm.pcrm_map_id = pcta.pcrm_map_id)';
      $person_crm_type_assign_where = "and pcta.pcrm_map_id is not null
				       and pcta.person_type = '$person_type'";
    } else {
      $person_crm_type_assign_join = $person_crm_type_assign_where = '';
    }

    $sql .= "
           from person_crm_map pcm
		$person_crm_type_assign_join
                ,person p
          where pcm.person_id = p.person_id
            and pcm.crm_id = ?
	    $person_crm_type_assign_where
    ";

    $sql .= ' order by upper(p.last_name), upper(p.first_name) ';

    if ($list_names) {
      if (DB::isError($ret = $this->db->getAll($sql, $binds, 
		      $assoc ? DB_FETCHMODE_ASSOC : DB_FETCHMODE_DEFAULT))) {
	$this->error = 'Person::List_By(): ' . $ret->getMessage() . "\n"
	  . $ret->getUserInfo();
	return;
      }
      return $ret;
    } else {
      if (DB::isError($res = $this->db->getCol( $sql, 0, $binds ))) {
	$this->error = 'Person::List_By(): ' . $res->getMessage() . "\n"
	  . $res->getUserInfo();
	return;
      }

      return $res;
    }
  }

  function Valid_Person_Password ($pid, $pass) {

    if (!$pid or !$pass) return 0;

    $h = $this->db->prepare (
    'select password
        from person
       where person_id = ?
    ');
    $res = $this->db->execute( $h, array($pid) );
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }
    $r = $res->fetchRow ();

    if ($r[0] and ($r[0] == md5($pass))) return 1;

    return 0;
  }

  function Valid_User_Type ($pid, $crm_id, $user_types) {
    if (!$pid or !$crm_id) return 0;

    if (is_array($user_types) and (count($user_types) < 1)) return 1;

    if ( $_SESSION['AUTHENTICATED'] and
        ($pid == $_SESSION['REMOTE_USER']) and
        ($crm_id == $_SESSION['REMOTE_USER_CRM_ID'])) {
      foreach ($user_types as $type) {
        if ($_SESSION['USER_TYPES'][$type]) return 1;
      }
      return 0;
    }

    $binds = array ($pid, $crm_id);

    $type_sql = array ();

    foreach ($user_types as $type) {
      $types_sql[] = ' pt.person_type = ? ';
      $binds[] = $type;
    }

    if (count($types_sql)) $sql = ' and ( '.join(' or ',$types_sql).' ) ';

    $sql = "
      select count(*)
        from person_crm_map pcm
               left join person_crm_type_assign pt
                 on (pcm.pcrm_map_id = pt.pcrm_map_id)
       where pcm.person_id = ? 
         and pcm.crm_id = ?
             $sql
    ";

    $h = $this->db->prepare ($sql);
    $res = $this->db->execute ($h, $binds);
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }

    $r = $res->fetchRow ();

    return $r[0];
  }

  function &List_All_Types () {
    $sql = '
      select person_type
        from person_type
    order by upper(person_type)
    ';

    $res = $this->db->getCol($sql);

    if (DB::isError($res)) {
       $this->error = 'Person::List_All_Types(): ' . $res->getMessage() 
	. "\n" . $res->getUserInfo();
       return;
    }

    return $res;
  }

  function From_Username ($user) {
    $h = $this->db->prepare ('
      select person_id
        from usernames
       where username = ?
    ');
    $res = $this->db->execute ($h, array($user));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }
    $r = $res->fetchRow ();

    return $r[0];
  }

  function To_Username ($pid) {
    $h = $this->db->prepare ('
      select username
        from usernames
       where person_id = ?
    ');
    $res = $this->db->execute ($h,array($pid));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }
    $r = $res->fetchRow ();

    return $r[0];
  }

  function Set_Username ($pid, $user='') {
    if ($user) {
      if ($this->Username_Exists ($pid)) {
        $this->Update_Username ($pid, $user);
      } else {
        $this->Add_Username ($pid, $user);
      }
    } else {
      $this->Delete_Username ($pid);
    }
  }

  function Update_Username ($pid, $user) {
    $h = $this->db->prepare ('
      update usernames
         set username = ?
       where person_id = ?
    ');
    $res = $this->db->execute ($h, array($user, $pid));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }
  }

  function Add_Username ($pid, $user) {
    $h = $this->db->prepare ('
       insert into usernames (
         person_id, username
       ) values (
         ?, ?
       )
    ');
    $res = $this->db->execute ($h, array($pid, $user));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }
  }

  function Delete_Username ($pid) {
    $h = $this->db->prepare ('
       delete from usernames
       where person_id = ?
    ');
    $res = $this->db->execute ($h, array($pid));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }
  }

  function Username_Exists ($pid) {
    $h = $this->db->prepare ('
      select count(*)
        from usernames
       where person_id = ?
    ');
    $res = $this->db->execute ($h, array($pid));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }
    $r = $res->fetchRow ();

    return $r[0];
  }

  function Is_Person_ID ($pid) {
    if (preg_match ("/^\d+$/", $pid)) return 1;

    return 0;
  }

  function Is_Super_Admin ($user='') {
    if (!$user) $user = $this->Person_Logged_In ();

    $pid = $this->To_Person_ID ($user);

    if (array_key_exists('AUTHENTICATED', $_SESSION) 
	and ($pid == $_SESSION['REMOTE_USER'])) {
      return $_SESSION['IS_SUPER_ADMIN'];
    }

    if (!$pid) return 0;

    $h = $this->db->prepare ('
      select count(*)
        from person_crm_map pcm
             inner join person_crm_type_assign pt
             on (pcm.pcrm_map_id = pt.pcrm_map_id)
       where pcm.person_id = ?
         and pt.person_type = ?
    ');
    $res = $this->db->execute ($h, array($pid, 'Super Admin'));
    if (DB::isError($res)) {
       $this->error = $res->getMessage() . "\n" . $res->getUserInfo();
       return;
    }
    $r = $res->fetchRow ();
 
    return $r[0];
  }

  function Is_Type ($pid, $type, $crm_id='') {
    if (!$crm_id) $crm_id = $this->Current_CRM ();
    if (!$crm_id) return 0;

    if ( $_SESSION['AUTHENTICATED'] and
        ($pid == $_SESSION['REMOTE_USER']) and
        ($crm_id == $_SESSION['REMOTE_USER_CRM_ID'])) {
      return(array_key_exists($type, $_SESSION['USER_TYPES']));
    }

    $h = $this->db->prepare ('
      select count(*)
        from person_crm_map pcm
             inner join person_crm_type_assign pt
             on (pcm.pcrm_map_id = pt.pcrm_map_id)
       where pcm.person_id = ?
         and pcm.crm_id = ?
         and pt.person_type = ?
    ');
    $res = $this->db->execute ($h, array($pid, $crm_id, $type));
    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return;
    }
    $r = $res->fetchRow ();
 
    return $r[0];
  }

  function &Get_Types ($pid='', $crm_id='') {
    $this->Set_If_Exists ('person_id', $pid);

    if (!$crm_id) $crm_id = $this->Current_CRM ();
    if (!$crm_id) return array();

    $sql = '
      select pt.person_type
        from person_crm_map pcm
             inner join person_crm_type_assign pt
             on (pcm.pcrm_map_id = pt.pcrm_map_id)
       where pcm.person_id = ?
         and pcm.crm_id = ?
    order by pt.person_type
    ';
    $res = $this->db->getCol($sql, 0, array($this->person_id, $crm_id));
    if (DB::isError($res)) {
       $this->error = 'Person::Get_Types(): ' . $res->getMessage()
	. "\n" . $res->getUserInfo();
       return;
    }

    ## in case this is empty
    if (count($res)) {
      return $res;
    } else {
      return array();
    }
  }

  function Is_In_CRM ($pid,$crm_id) {
    if (!$crm_id) $crm_id = $this->Current_CRM ();
    if (!$crm_id or !$pid) return 0;

    $sql = "
      select count(*)
        from person_crm_map
       where person_id = ?
         and crm_id = ?
    ";

    $h = $this->db->prepare ($sql);
    $res = $this->db->execute ($h, array($pid,$crm_id));

    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return 0;
    }

    $r = $res->fetchRow ();

    if ($r[0]) return $r[0];

    $sql = "
      select count(*)
        from ticket t,
             person p 
       where p.person_id = ?
         and t.crm_id = ?
         and p.person_id = t.user_person_id
    ";

    $h = $this->db->prepare ($sql);
    $res = $this->db->execute ($h, array($pid,$crm_id));

    if (DB::isError($res)) {
       $this->error = $res->getMessage();
       return 0;
    }

    $r = $res->fetchRow ();

    return $r[0];
  }

  function Find ($last_name='', $first_name='', $crm_id='', $limited=1) {
    if (!$last_name and !$first_name) return;

    if (!$crm_id) $crm_id = $this->Current_CRM ();
    if (!$crm_id) return 0;

    $_where = array(
      'p.last_name' => $last_name,
      'p.first_name' => $first_name,
    );

    $binds = array ();

    $last_first = sql_concat('p.last_name', "', '", 'p.first_name');
  
    $sql1 = "
      select p.person_id,
             $last_first as name,
             p.email,
             c.crm_name,
             pcta.person_type
        from person_crm_map pcm,
             person p,
             company_crm c,
             person_crm_type_assign pcta
       where pcm.crm_id = c.crm_id
         and pcm.person_id = p.person_id
         and pcm.pcrm_map_id = pcta.pcrm_map_id
    ";

    $sql2 = "
      select p.person_id,
             $last_first as name,
             p.email,
             c.crm_name
        from ticket t,
             person p,
             company_crm c,
             ticket_crm_map tcm
       where p.person_id = t.user_person_id
         and t.ticket_id = tcm.ticket_id
         and tcm.crm_id = c.crm_id
    ";

    $where = '';

    foreach ($_where as $field => $val) {
      if (!$val) continue;

      $val = strtoupper( $val );
  
      if (!ereg ('%', $val)) {
        $val = '%'.ereg_replace (' ', '%', $val).'%';
      }
  
      $where .= " and upper($field) like ? ";
      $binds[] = $val;
    }

    $sql1 .= $where;
    $sql2 .= $where;
  
    if ($limited) {
      $sql1 .= " and pcm.crm_id = ? ";
      $sql2 .= " and tcm.crm_id = ? ";
      $binds[] = $crm_id;
    }

    $results = array();

    $recs = $this->db->getAll ($sql1, $binds, DB_FETCHMODE_ASSOC);

    if (DB::isError($recs)) {
      $this->error = 'Person::Find(): ' . $recs->getMessage() . "\n"
	. $recs->getUserInfo();
      return;
    } else {
      foreach ($recs as $r) {
        $r['sort'] = strtoupper($r['person_id'] . $r['name'] . $r['email'] .
	  $r['crm_name'] . $r['person_type']);
        $results[] = $r;
      }
    }

    $recs = $this->db->getAll ($sql2, $binds, DB_FETCHMODE_ASSOC);

    if (DB::isError($recs)) {
      $this->error = 'Person::Find(): ' . $recs->getMessage() . "\n"
	. $recs->getUserInfo();
      return;
    } else {
      notices_off();
      foreach ($recs as $r) {
        $r['sort'] = strtoupper($r['person_id'] . $r['name'] . $r['email'] .
	  $r['crm_name'] . $r['person_type']);
        $results[] = $r;
      }
      notices_on();
    }

    uasort( $results, 'people_sort' );

    return $results;
  }

  ## probably doesn't belong in this object
  function To_Person_ID ($uid_or_pid) {
    if (!$uid_or_pid) { return; }

    if ($this->Is_Person_ID ($uid_or_pid)) {
      return $uid_or_pid;
    } else {
      return $this->from_username ($uid_or_pid);
    }
  }
}

class Person_Record extends Person {
  function Person_Record () {
    global $dbi;
    $this->db = &$dbi;
  }

  ## if only first param to function assume pcrm_map_id,
  ## otherwise if both assume person_id and crm_id to obtain map_id
  function Select_by_Map_ID ($map_id, $crm_id='') {
    $binds = array($map_id);
    $where = 'pcm.pcrm_map_id = ?';

    if ($crm_id) {
      $where = ' pcm.person_id = ? and pcm.crm_id = ? ';
      $binds = array($map_id, $crm_id);
    }

    $sql = "
         select p.person_id,
                p.first_name,
                p.last_name,
                p.middle_initial,
                p.email,
                p.home_phone,
                p.work_phone,
                p.cell_phone,
                p.pager_num,
                p.address1,
                p.address2,
                p.city,
                p.state,
                p.zip, 
                p.company,
                p.title,
                p.password, 
                pcm.support_drop_down,
                pcm.escalated_drop_down,
                pcm.modify_tickets,
                pcm.pcrm_map_id,
                cc.crm_name,
		cc.crm_short_name,
                cc.company_id,
                pcm.crm_id,
                cc.web_page_id,
                cc.web_domain,
		cc.web_path
           from person_crm_map pcm,
                person p,
                company_crm cc,
                person_crm_type_assign pt
          where $where
            and pcm.person_id = p.person_id
            and pcm.crm_id = cc.crm_id
            and pcm.pcrm_map_id = pt.pcrm_map_id
    ";

    if (DB::isError($res=$this->db->getRow($sql, $binds, DB_FETCHMODE_ASSOC))) {
      $this->error = 'Person_Record::Select_by_Map_ID(): '
	. $res->getMessage() . "\n" . $res->getUserInfo();
      return;
    }

    if ($res) {
      foreach ($res as $k => $v) {
	$k = strtolower ($k);
	$this->$k = $v;
      }

      return true;
    } else {
      $this->error = 'Person_Record::Select_by_Map_ID(): no rows returned';
      return;
    }
  }

  function Select_by_Person_ID ($pid) {
    $binds = array ($pid);

    $sql = '
         select person_id,
                first_name,
                last_name,
                middle_initial,
                email,
                home_phone,
                work_phone,
                cell_phone,
                pager_num,
                address1,
                address2,
                city,
                state,
                zip,
                company,
                title,
                password
           from person
          where person_id = ?
    ';

    $h = $this->db->prepare ($sql);
    $res = $this->db->execute($h,$binds);
    if (DB::isError($res)) {
	$this->error = $res->getMessage() . "\n" . $res->getUserInfo();
	return;
    }
    $r = $res->fetchRow(DB_FETCHMODE_ASSOC);

    if ($r) {
      foreach ($r as $k => $v) {
	$k = strtolower ($k);
	$this->$k = $v;
      }
    }

    return $r;
  }
}

function people_sort ($a,$b) {
  return strcmp( $a['sort'], $b['sort'] );
}

?>
