1361 lines
68 KiB
PHP
1361 lines
68 KiB
PHP
<?php
|
|
|
|
use app\services\utilities\Arr;
|
|
|
|
defined('BASEPATH') or exit('No direct script access allowed');
|
|
|
|
class Clients_model extends App_Model {
|
|
private $contact_columns;
|
|
|
|
public function __construct() {
|
|
parent::__construct();
|
|
$this->contact_columns = hooks()->apply_filters('contact_columns', ['firstname', 'lastname', 'email', 'phonenumber', 'title', 'password', 'send_set_password_email', 'donotsendwelcomeemail', 'permissions', 'direction', 'invoice_emails', 'estimate_emails', 'credit_note_emails', 'contract_emails', 'task_emails', 'project_emails', 'ticket_emails', 'is_primary']);
|
|
|
|
$this->load->model('client_vault_entries_model');
|
|
$this->load->model('client_groups_model');
|
|
$this->load->model('statement_model');
|
|
$this->load->model('roles_model');
|
|
$this->load->model('authentication_model');
|
|
}
|
|
|
|
/**
|
|
* Get client object based on passed clientid if not passed clientid return array of all clients
|
|
* @param mixed $id client id
|
|
* @param array $where
|
|
* @return mixed
|
|
*/
|
|
public function get($id = '', $where = [], $playground = false) {
|
|
$this->db->select(implode(',', prefixed_table_fields_array(db_prefix() . ($playground ? 'playground_' : '') . 'clients')) . ',' . $this->get_sql_select_client_company('company', $playground));
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'countries', '' . db_prefix() . ($playground ? 'playground_' : '') . 'countries.country_id = ' . db_prefix() . ($playground ? 'playground_' : '') . 'clients.country', 'left');
|
|
$this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', '' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts.userid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid AND is_primary = 1', 'left');
|
|
if ((is_array($where) && count($where) > 0) || (is_string($where) && $where != '')) {
|
|
$this->db->where($where);
|
|
}
|
|
if (is_numeric($id)) {
|
|
$this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid', $id);
|
|
$client = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'clients')->row();
|
|
if ($client && get_option('company_requires_vat_number_field') == 0) {
|
|
$client->vat = null;
|
|
}
|
|
$GLOBALS['client'] = $client;
|
|
return $client;
|
|
}
|
|
$this->db->order_by('company', 'asc');
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'clients')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Get customers contacts
|
|
* @param mixed $customer_id
|
|
* @param array $where perform where query
|
|
* @param array $whereIn perform whereIn query
|
|
* @return array
|
|
*/
|
|
public function get_contacts($customer_id = '', $where = ['active' => 1], $whereIn = [], $playground = false) {
|
|
$this->db->where($where);
|
|
if ($customer_id != '') {
|
|
$this->db->where('userid', $customer_id);
|
|
}
|
|
foreach ($whereIn as $key => $values) {
|
|
if (is_string($key) && is_array($values)) {
|
|
$this->db->where_in($key, $values);
|
|
}
|
|
}
|
|
$this->db->order_by('is_primary', 'DESC');
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Get single contacts
|
|
* @param mixed $id contact id
|
|
* @return object
|
|
*/
|
|
public function get_contact($id, $playground = false) {
|
|
$this->db->where('id', $id);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->row();
|
|
}
|
|
|
|
/**
|
|
* Get contact by given email
|
|
*
|
|
* @since 2.8.0
|
|
*
|
|
* @param string $email
|
|
*
|
|
* @return \strClass|null
|
|
*/
|
|
public function get_contact_by_email($email, $playground = false) {
|
|
$this->db->where('email', $email);
|
|
$this->db->limit(1);
|
|
return $this->db->get(($playground ? 'playground_' : '') . 'contacts')->row();
|
|
}
|
|
|
|
/**
|
|
* Get primary contact user id for specific customer
|
|
* @param mixed $userid
|
|
* @return mixed
|
|
*/
|
|
public function get_primary_contact_user_id($userid, $playground = false)
|
|
{
|
|
$this->db->where('userid', $userid);
|
|
$this->db->where('is_primary', 1);
|
|
$row = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->row();
|
|
|
|
if ($row) {
|
|
return $row->id;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param array $_POST data
|
|
* @param withContact
|
|
*
|
|
* @return integer Insert ID
|
|
*
|
|
* Add new client to database
|
|
*/
|
|
public function add($data, $withContact = false, $playground = false) {
|
|
$contact_data = [];
|
|
// From Lead Convert to client
|
|
if (isset($data['send_set_password_email'])) {
|
|
$contact_data['send_set_password_email'] = true;
|
|
}
|
|
if (isset($data['donotsendwelcomeemail'])) {
|
|
$contact_data['donotsendwelcomeemail'] = true;
|
|
}
|
|
$data = $this->check_zero_columns($data);
|
|
$data = hooks()->apply_filters('before_client_added', $data);
|
|
foreach ($this->contact_columns as $field) {
|
|
if (!isset($data[$field])) {
|
|
continue;
|
|
}
|
|
$contact_data[$field] = $data[$field];
|
|
// Phonenumber is also used for the company profile
|
|
if ($field != 'phonenumber') {
|
|
unset($data[$field]);
|
|
}
|
|
}
|
|
$groups_in = Arr::pull($data, 'groups_in') ?? [];
|
|
$custom_fields = Arr::pull($data, 'custom_fields') ?? [];
|
|
// From customer profile register
|
|
if (isset($data['contact_phonenumber'])) {
|
|
$contact_data['phonenumber'] = $data['contact_phonenumber'];
|
|
unset($data['contact_phonenumber']);
|
|
}
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'clients', array_merge($data, ['datecreated' => date('Y-m-d H:i:s'), 'addedfrom' => is_staff_logged_in() ? get_staff_user_id() : 0, ]));
|
|
$client_id = $this->db->insert_id();
|
|
if ($client_id) {
|
|
if (count($custom_fields) > 0) {
|
|
$_custom_fields = $custom_fields;
|
|
// Possible request from the register area with 2 types of custom fields for contact and for comapny/customer
|
|
if (count($custom_fields) == 2) {
|
|
unset($custom_fields);
|
|
$custom_fields['customers'] = $_custom_fields['customers'];
|
|
$contact_data['custom_fields']['contacts'] = $_custom_fields['contacts'];
|
|
} else if (count($custom_fields) == 1) {
|
|
if (isset($_custom_fields['contacts'])) {
|
|
$contact_data['custom_fields']['contacts'] = $_custom_fields['contacts'];
|
|
unset($custom_fields);
|
|
}
|
|
}
|
|
$this->load->model('custom_fields_model');
|
|
$this->custom_fields_model->handle_custom_fields_post($client_id, $custom_fields, false, $playground);
|
|
}
|
|
/**
|
|
* Used in Import, Lead Convert, Register
|
|
*/
|
|
if ($withContact == true) {
|
|
$contact_id = $this->add_contact($contact_data, $client_id, $withContact, $playground);
|
|
}
|
|
foreach ($groups_in as $group) {
|
|
$this->db->insert(($playground ? 'playground_' : '') . 'customer_groups', ['customer_id' => $client_id, 'groupid' => $group, ]);
|
|
}
|
|
$log = 'ID: ' . $client_id;
|
|
if ($log == '' && isset($contact_id)) {
|
|
$log = get_contact_full_name($contact_id);
|
|
}
|
|
$isStaff = null;
|
|
if (!is_client_logged_in() && is_staff_logged_in()) {
|
|
$log.= ', From Staff: ' . get_staff_user_id();
|
|
$isStaff = get_staff_user_id();
|
|
}
|
|
do_action_deprecated('after_client_added', [$client_id], '2.9.4', 'after_client_created');
|
|
hooks()->do_action('after_client_created', ['id' => $client_id, 'data' => $data, 'contact_data' => $contact_data, 'custom_fields' => $custom_fields, 'groups_in' => $groups_in, 'with_contact' => $withContact, ]);
|
|
log_activity('New Client Created [' . $log . ']', $isStaff);
|
|
}
|
|
return $client_id;
|
|
}
|
|
|
|
/**
|
|
* @param array $_POST data
|
|
* @param integer ID
|
|
* @return boolean
|
|
* Update client informations
|
|
*/
|
|
public function update($data, $id, $client_request = false, $playground = false) {
|
|
$updated = false;
|
|
$data = $this->check_zero_columns($data);
|
|
$data = hooks()->apply_filters('before_client_updated', $data, $id);
|
|
$update_all_other_transactions = (bool)Arr::pull($data, 'update_all_other_transactions');
|
|
$update_credit_notes = (bool)Arr::pull($data, 'update_credit_notes');
|
|
$custom_fields = Arr::pull($data, 'custom_fields') ?? [];
|
|
$groups_in = Arr::pull($data, 'groups_in') ?? false;
|
|
$this->load->model('custom_fields_model');
|
|
if ($this->custom_fields_model->handle_custom_fields_post($id, $custom_fields, false, $playground)) {
|
|
$updated = true;
|
|
}
|
|
$this->db->where('userid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'clients', $data);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$updated = true;
|
|
}
|
|
if ($update_all_other_transactions || $update_credit_notes) {
|
|
$transactions_update = ['billing_street' => $data['billing_street'], 'billing_city' => $data['billing_city'], 'billing_state' => $data['billing_state'], 'billing_zip' => $data['billing_zip'], 'billing_country' => $data['billing_country'], 'shipping_street' => $data['shipping_street'], 'shipping_city' => $data['shipping_city'], 'shipping_state' => $data['shipping_state'], 'shipping_zip' => $data['shipping_zip'], 'shipping_country' => $data['shipping_country'], ];
|
|
if ($update_all_other_transactions) {
|
|
// Update all invoices except paid ones.
|
|
$this->db->where('clientid', $id)->where('status !=', 2)->update('invoices', $transactions_update);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$updated = true;
|
|
}
|
|
// Update all estimates
|
|
$this->db->where('clientid', $id)->update('estimates', $transactions_update);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$updated = true;
|
|
}
|
|
}
|
|
if ($update_credit_notes) {
|
|
$this->db->where('clientid', $id)->where('status !=', 2)->update('creditnotes', $transactions_update);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$updated = true;
|
|
}
|
|
}
|
|
}
|
|
if ($this->client_groups_model->sync_customer_groups($id, $groups_in, $playground)) {
|
|
$updated = true;
|
|
}
|
|
do_action_deprecated('after_client_updated', [$id], '2.9.4', 'client_updated');
|
|
hooks()->do_action('client_updated', ['id' => $id, 'data' => $data, 'update_all_other_transactions' => $update_all_other_transactions, 'update_credit_notes' => $update_credit_notes, 'custom_fields' => $custom_fields, 'groups_in' => $groups_in, 'updated' => & $updated, ]);
|
|
if ($updated) {
|
|
log_activity('Customer Info Updated [ID: ' . $id . ']');
|
|
}
|
|
return $updated;
|
|
}
|
|
|
|
/**
|
|
* Update contact data
|
|
* @param array $data $_POST data
|
|
* @param mixed $id contact id
|
|
* @param boolean $client_request is request from customers area
|
|
* @return mixed
|
|
*/
|
|
public function update_contact($data, $id, $client_request = false, $playground = false) {
|
|
$affectedRows = 0;
|
|
$contact = $this->get_contact($id);
|
|
if (empty($data['password'])) {
|
|
unset($data['password']);
|
|
} else {
|
|
$data['password'] = app_hash_password($data['password']);
|
|
$data['last_password_change'] = date('Y-m-d H:i:s');
|
|
}
|
|
$send_set_password_email = isset($data['send_set_password_email']) ? true : false;
|
|
$set_password_email_sent = false;
|
|
$permissions = isset($data['permissions']) ? $data['permissions'] : [];
|
|
$data['is_primary'] = isset($data['is_primary']) ? 1 : 0;
|
|
// Contact cant change if is primary or not
|
|
if ($client_request == true) {
|
|
unset($data['is_primary']);
|
|
}
|
|
if (isset($data['custom_fields'])) {
|
|
$custom_fields = $data['custom_fields'];
|
|
$this->load->model('custom_fields_model');
|
|
if ($this->custom_fields_model->handle_custom_fields_post($id, $custom_fields, false, $playground)) {
|
|
$affectedRows++;
|
|
}
|
|
unset($data['custom_fields']);
|
|
}
|
|
if ($client_request == false) {
|
|
$data['invoice_emails'] = isset($data['invoice_emails']) ? 1 : 0;
|
|
$data['estimate_emails'] = isset($data['estimate_emails']) ? 1 : 0;
|
|
$data['credit_note_emails'] = isset($data['credit_note_emails']) ? 1 : 0;
|
|
$data['contract_emails'] = isset($data['contract_emails']) ? 1 : 0;
|
|
$data['task_emails'] = isset($data['task_emails']) ? 1 : 0;
|
|
$data['project_emails'] = isset($data['project_emails']) ? 1 : 0;
|
|
$data['ticket_emails'] = isset($data['ticket_emails']) ? 1 : 0;
|
|
}
|
|
$data = hooks()->apply_filters('before_update_contact', $data, $id);
|
|
$this->db->where('id', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', $data);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
if (isset($data['is_primary']) && $data['is_primary'] == 1) {
|
|
$this->db->where('userid', $contact->userid);
|
|
$this->db->where('id !=', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['is_primary' => 0, ]);
|
|
}
|
|
}
|
|
if ($client_request == false) {
|
|
$customer_permissions = $this->roles_model->get_contact_permissions($id, $playground);
|
|
if (sizeof($customer_permissions) > 0) {
|
|
foreach ($customer_permissions as $customer_permission) {
|
|
if (!in_array($customer_permission['permission_id'], $permissions)) {
|
|
$this->db->where('userid', $id);
|
|
$this->db->where('permission_id', $customer_permission['permission_id']);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'contact_permissions');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
}
|
|
}
|
|
foreach ($permissions as $permission) {
|
|
$this->db->where('userid', $id);
|
|
$this->db->where('permission_id', $permission);
|
|
$_exists = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contact_permissions')->row();
|
|
if (!$_exists) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'contact_permissions', ['userid' => $id, 'permission_id' => $permission, ]);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
foreach ($permissions as $permission) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'contact_permissions', ['userid' => $id, 'permission_id' => $permission, ]);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
}
|
|
}
|
|
if ($send_set_password_email) {
|
|
$set_password_email_sent = $this->authentication_model->set_password_email($data['email'], $playground);
|
|
}
|
|
}
|
|
if (($client_request == true) && $send_set_password_email) {
|
|
$set_password_email_sent = $this->authentication_model->set_password_email($data['email'], $playground);
|
|
}
|
|
if ($affectedRows > 0) {
|
|
hooks()->do_action('contact_updated', $id, $data);
|
|
}
|
|
if ($affectedRows > 0 && !$set_password_email_sent) {
|
|
log_activity('Contact Updated [ID: ' . $id . ']');
|
|
return true;
|
|
} else if ($affectedRows > 0 && $set_password_email_sent) {
|
|
return ['set_password_email_sent_and_profile_updated' => true, ];
|
|
} else if ($affectedRows == 0 && $set_password_email_sent) {
|
|
return ['set_password_email_sent' => true, ];
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Add new contact
|
|
* @param array $data $_POST data
|
|
* @param mixed $customer_id customer id
|
|
* @param boolean $not_manual_request is manual from admin area customer profile or register, convert to lead
|
|
*/
|
|
public function add_contact($data, $customer_id, $not_manual_request = false, $playground = false) {
|
|
$send_set_password_email = isset($data['send_set_password_email']) ? true : false;
|
|
if (isset($data['custom_fields'])) {
|
|
$custom_fields = $data['custom_fields'];
|
|
unset($data['custom_fields']);
|
|
}
|
|
if (isset($data['permissions'])) {
|
|
$permissions = $data['permissions'];
|
|
unset($data['permissions']);
|
|
}
|
|
$data['email_verified_at'] = date('Y-m-d H:i:s');
|
|
$send_welcome_email = true;
|
|
if (isset($data['donotsendwelcomeemail'])) {
|
|
$send_welcome_email = false;
|
|
}
|
|
if (defined('CONTACT_REGISTERING')) {
|
|
$send_welcome_email = true;
|
|
// Do not send welcome email if confirmation for registration is enabled
|
|
if (get_option('customers_register_require_confirmation') == '1') {
|
|
$send_welcome_email = false;
|
|
}
|
|
// If client register set this contact as primary
|
|
$data['is_primary'] = 1;
|
|
if (is_email_verification_enabled() && !empty($data['email'])) {
|
|
// Verification is required on register
|
|
$data['email_verified_at'] = null;
|
|
$data['email_verification_key'] = app_generate_hash();
|
|
}
|
|
}
|
|
if (isset($data['is_primary'])) {
|
|
$data['is_primary'] = 1;
|
|
$this->db->where('userid', $customer_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['is_primary' => 0, ]);
|
|
} else {
|
|
$data['is_primary'] = 0;
|
|
}
|
|
$password_before_hash = '';
|
|
$data['userid'] = $customer_id;
|
|
if (isset($data['password'])) {
|
|
$password_before_hash = $data['password'];
|
|
$data['password'] = app_hash_password($data['password']);
|
|
}
|
|
$data['datecreated'] = date('Y-m-d H:i:s');
|
|
if (!$not_manual_request) {
|
|
$data['invoice_emails'] = isset($data['invoice_emails']) ? 1 : 0;
|
|
$data['estimate_emails'] = isset($data['estimate_emails']) ? 1 : 0;
|
|
$data['credit_note_emails'] = isset($data['credit_note_emails']) ? 1 : 0;
|
|
$data['contract_emails'] = isset($data['contract_emails']) ? 1 : 0;
|
|
$data['task_emails'] = isset($data['task_emails']) ? 1 : 0;
|
|
$data['project_emails'] = isset($data['project_emails']) ? 1 : 0;
|
|
$data['ticket_emails'] = isset($data['ticket_emails']) ? 1 : 0;
|
|
}
|
|
$data['email'] = trim($data['email']);
|
|
$data = hooks()->apply_filters('before_create_contact', $data);
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', $data);
|
|
$contact_id = $this->db->insert_id();
|
|
if ($contact_id) {
|
|
if (isset($custom_fields)) {
|
|
$this->load->model('custom_fields_model');
|
|
$this->custom_fields_model->handle_custom_fields_post($contact_id, $custom_fields, false, $playground);
|
|
}
|
|
// request from admin area
|
|
if (!isset($permissions) && $not_manual_request == false) {
|
|
$permissions = [];
|
|
} else if ($not_manual_request == true) {
|
|
$permissions = [];
|
|
$_permissions = get_contact_permissions();
|
|
$default_permissions = @unserialize(get_option('default_contact_permissions'));
|
|
if (is_array($default_permissions)) {
|
|
foreach ($_permissions as $permission) {
|
|
if (in_array($permission['id'], $default_permissions)) {
|
|
array_push($permissions, $permission['id']);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($not_manual_request == true) {
|
|
// update all email notifications to 0
|
|
$this->db->where('id', $contact_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['invoice_emails' => 0, 'estimate_emails' => 0, 'credit_note_emails' => 0, 'contract_emails' => 0, 'task_emails' => 0, 'project_emails' => 0, 'ticket_emails' => 0, ]);
|
|
}
|
|
foreach ($permissions as $permission) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'contact_permissions', ['userid' => $contact_id, 'permission_id' => $permission, ]);
|
|
// Auto set email notifications based on permissions
|
|
if ($not_manual_request == true) {
|
|
if ($permission == 6) {
|
|
$this->db->where('id', $contact_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['project_emails' => 1, 'task_emails' => 1]);
|
|
} else if ($permission == 3) {
|
|
$this->db->where('id', $contact_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['contract_emails' => 1]);
|
|
} else if ($permission == 2) {
|
|
$this->db->where('id', $contact_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['estimate_emails' => 1]);
|
|
} else if ($permission == 1) {
|
|
$this->db->where('id', $contact_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['invoice_emails' => 1, 'credit_note_emails' => 1]);
|
|
} else if ($permission == 5) {
|
|
$this->db->where('id', $contact_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['ticket_emails' => 1]);
|
|
}
|
|
}
|
|
}
|
|
if ($send_welcome_email == true && !empty($data['email'])) {
|
|
send_mail_template('customer_created_welcome_mail', $data['email'], $data['userid'], $contact_id, $password_before_hash);
|
|
}
|
|
if ($send_set_password_email) {
|
|
$this->authentication_model->set_password_email($data['email'], $playground);
|
|
}
|
|
if (defined('CONTACT_REGISTERING')) {
|
|
$this->send_verification_email($contact_id);
|
|
} else {
|
|
// User already verified because is added from admin area, try to transfer any tickets
|
|
$this->load->model('tickets_model');
|
|
$this->tickets_model->transfer_email_tickets_to_contact($data['email'], $contact_id, $playground);
|
|
}
|
|
log_activity('Contact Created [ID: ' . $contact_id . ']');
|
|
hooks()->do_action('contact_created', $contact_id);
|
|
return $contact_id;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Add new contact via customers area
|
|
*
|
|
* @param array $data
|
|
* @param mixed $customer_id
|
|
*/
|
|
public function add_contact_via_customers_area($data, $customer_id, $playground = false) {
|
|
$send_welcome_email = isset($data['donotsendwelcomeemail']) && $data['donotsendwelcomeemail'] ? false : true;
|
|
$send_set_password_email = isset($data['send_set_password_email']) && $data['send_set_password_email'] ? true : false;
|
|
$custom_fields = $data['custom_fields'];
|
|
unset($data['custom_fields']);
|
|
if (!is_email_verification_enabled()) {
|
|
$data['email_verified_at'] = date('Y-m-d H:i:s');
|
|
} else if (is_email_verification_enabled() && !empty($data['email'])) {
|
|
// Verification is required on register
|
|
$data['email_verified_at'] = null;
|
|
$data['email_verification_key'] = app_generate_hash();
|
|
}
|
|
$password_before_hash = $data['password'];
|
|
$data = array_merge($data, ['datecreated' => date('Y-m-d H:i:s'), 'userid' => $customer_id, 'password' => app_hash_password(isset($data['password']) ? $data['password'] : time()), ]);
|
|
$data = hooks()->apply_filters('before_create_contact', $data);
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', $data);
|
|
$contact_id = $this->db->insert_id();
|
|
if ($contact_id) {
|
|
$this->load->model('custom_fields_model');
|
|
$this->custom_fields_model->handle_custom_fields_post($contact_id, $custom_fields, false, $playground);
|
|
// Apply default permissions
|
|
$default_permissions = @unserialize(get_option('default_contact_permissions'));
|
|
if (is_array($default_permissions)) {
|
|
foreach (get_contact_permissions() as $permission) {
|
|
if (in_array($permission['id'], $default_permissions)) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'contact_permissions', ['userid' => $contact_id, 'permission_id' => $permission['id'], ]);
|
|
}
|
|
}
|
|
}
|
|
if ($send_welcome_email === true) {
|
|
send_mail_template('customer_created_welcome_mail', $data['email'], $customer_id, $contact_id, $password_before_hash);
|
|
}
|
|
if ($send_set_password_email === true) {
|
|
$this->authentication_model->set_password_email($data['email'], $playground);
|
|
}
|
|
log_activity('Contact Created [ID: ' . $contact_id . ']');
|
|
hooks()->do_action('contact_created', $contact_id);
|
|
return $contact_id;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Used to update company details from customers area
|
|
* @param array $data $_POST data
|
|
* @param mixed $id
|
|
* @return boolean
|
|
*/
|
|
public function update_company_details($data, $id, $playground = false) {
|
|
$affectedRows = 0;
|
|
if (isset($data['custom_fields'])) {
|
|
$custom_fields = $data['custom_fields'];
|
|
$this->load->model('custom_fields_model');
|
|
if ($this->custom_fields_model->handle_custom_fields_post($id, $custom_field, false, $playground)) {
|
|
$affectedRows++;
|
|
}
|
|
unset($data['custom_fields']);
|
|
}
|
|
if (isset($data['country']) && $data['country'] == '' || !isset($data['country'])) {
|
|
$data['country'] = 0;
|
|
}
|
|
if (isset($data['billing_country']) && $data['billing_country'] == '') {
|
|
$data['billing_country'] = 0;
|
|
}
|
|
if (isset($data['shipping_country']) && $data['shipping_country'] == '') {
|
|
$data['shipping_country'] = 0;
|
|
}
|
|
// From v.1.9.4 these fields are textareas
|
|
$data['address'] = trim($data['address']);
|
|
$data['address'] = nl2br($data['address']);
|
|
if (isset($data['billing_street'])) {
|
|
$data['billing_street'] = trim($data['billing_street']);
|
|
$data['billing_street'] = nl2br($data['billing_street']);
|
|
}
|
|
if (isset($data['shipping_street'])) {
|
|
$data['shipping_street'] = trim($data['shipping_street']);
|
|
$data['shipping_street'] = nl2br($data['shipping_street']);
|
|
}
|
|
$data = hooks()->apply_filters('customer_update_company_info', $data, $id);
|
|
$this->db->where('userid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'clients', $data);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
if ($affectedRows > 0) {
|
|
hooks()->do_action('customer_updated_company_info', $id);
|
|
log_activity('Customer Info Updated From Clients Area [ID: ' . $id . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get customer staff members that are added as customer admins
|
|
* @param mixed $id customer id
|
|
* @return array
|
|
*/
|
|
public function get_admins($id, $playground = false) {
|
|
$this->db->where('customer_id', $id);
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'customer_admins')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Get unique staff id's of customer admins
|
|
* @return array
|
|
*/
|
|
public function get_customers_admin_unique_ids($playground = false) {
|
|
return $this->db->query('SELECT DISTINCT(staff_id) FROM ' . db_prefix() . ($playground ? 'playground_' : '') . 'customer_admins')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Assign staff members as admin to customers
|
|
* @param array $data $_POST data
|
|
* @param mixed $id customer id
|
|
* @return boolean
|
|
*/
|
|
public function assign_admins($data, $id, $playground = false) {
|
|
$affectedRows = 0;
|
|
if (count($data) == 0) {
|
|
$this->db->where('customer_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customer_admins');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
} else {
|
|
$current_admins = $this->get_admins($id);
|
|
$current_admins_ids = [];
|
|
foreach ($current_admins as $c_admin) {
|
|
array_push($current_admins_ids, $c_admin['staff_id']);
|
|
}
|
|
foreach ($current_admins_ids as $c_admin_id) {
|
|
if (!in_array($c_admin_id, $data['customer_admins'])) {
|
|
$this->db->where('staff_id', $c_admin_id);
|
|
$this->db->where('customer_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customer_admins');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
}
|
|
}
|
|
foreach ($data['customer_admins'] as $n_admin_id) {
|
|
if (total_rows(db_prefix() . ($playground ? 'playground_' : '') . 'customer_admins', ['customer_id' => $id, 'staff_id' => $n_admin_id, ]) == 0) {
|
|
$this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'customer_admins', ['customer_id' => $id, 'staff_id' => $n_admin_id, 'date_assigned' => date('Y-m-d H:i:s'), ]);
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($affectedRows > 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param integer ID
|
|
* @return boolean
|
|
* Delete client, also deleting rows from, dismissed client announcements, ticket replies, tickets, autologin, user notes
|
|
*/
|
|
public function delete($id, $playground = false) {
|
|
$affectedRows = 0;
|
|
if (!is_gdpr() && is_reference_in_table('clientid', db_prefix() . ($playground ? 'playground_' : '') . 'invoices', $id)) {
|
|
return ['referenced' => true, ];
|
|
}
|
|
if (!is_gdpr() && is_reference_in_table('clientid', db_prefix() . ($playground ? 'playground_' : '') . 'estimates', $id)) {
|
|
return ['referenced' => true, ];
|
|
}
|
|
if (!is_gdpr() && is_reference_in_table('clientid', db_prefix() . ($playground ? 'playground_' : '') . 'creditnotes', $id)) {
|
|
return ['referenced' => true, ];
|
|
}
|
|
hooks()->do_action('before_client_deleted', $id);
|
|
$last_activity = get_last_system_activity_id();
|
|
$company = get_company_name($id);
|
|
$this->db->where('userid', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'clients');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$affectedRows++;
|
|
// Delete all user contacts
|
|
$this->db->where('userid', $id);
|
|
$contacts = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->result_array();
|
|
foreach ($contacts as $contact) {
|
|
$this->delete_contact($contact['id']);
|
|
}
|
|
// Delete all tickets start here
|
|
$this->db->where('userid', $id);
|
|
$tickets = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->result_array();
|
|
$this->load->model('tickets_model');
|
|
foreach ($tickets as $ticket) {
|
|
$this->tickets_model->delete($ticket['ticketid'], $playground);
|
|
}
|
|
$this->db->where('rel_id', $id);
|
|
$this->db->where('rel_type', 'customer');
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'notes');
|
|
if (is_gdpr() && get_option('gdpr_on_forgotten_remove_invoices_credit_notes') == '1') {
|
|
$this->load->model('invoices_model');
|
|
$this->db->where('clientid', $id);
|
|
$invoices = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'invoices')->result_array();
|
|
foreach ($invoices as $invoice) {
|
|
$this->invoices_model->delete($invoice['id'], true);
|
|
}
|
|
$this->load->model('credit_notes_model');
|
|
$this->db->where('clientid', $id);
|
|
$credit_notes = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'creditnotes')->result_array();
|
|
foreach ($credit_notes as $credit_note) {
|
|
$this->credit_notes_model->delete($credit_note['id'], true);
|
|
}
|
|
} else if (is_gdpr()) {
|
|
$this->db->where('clientid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'invoices', ['deleted_customer_name' => $company]);
|
|
$this->db->where('clientid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'creditnotes', ['deleted_customer_name' => $company]);
|
|
}
|
|
$this->db->where('clientid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'creditnotes', ['clientid' => 0, 'project_id' => 0, ]);
|
|
$this->db->where('clientid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'invoices', ['clientid' => 0, 'recurring' => 0, 'recurring_type' => null, 'custom_recurring' => 0, 'cycles' => 0, 'last_recurring_date' => null, 'project_id' => 0, 'subscription_id' => 0, 'cancel_overdue_reminders' => 1, 'last_overdue_reminder' => null, 'last_due_reminder' => null, ]);
|
|
if (is_gdpr() && get_option('gdpr_on_forgotten_remove_estimates') == '1') {
|
|
$this->load->model('estimates_model');
|
|
$this->db->where('clientid', $id);
|
|
$estimates = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'estimates')->result_array();
|
|
foreach ($estimates as $estimate) {
|
|
$this->estimates_model->delete($estimate['id'], true);
|
|
}
|
|
} else if (is_gdpr()) {
|
|
$this->db->where('clientid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'estimates', ['deleted_customer_name' => $company]);
|
|
}
|
|
$this->db->where('clientid', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'estimates', ['clientid' => 0, 'project_id' => 0, 'is_expiry_notified' => 1, ]);
|
|
$this->load->model('subscriptions_model');
|
|
$this->db->where('clientid', $id);
|
|
$subscriptions = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'subscriptions')->result_array();
|
|
foreach ($subscriptions as $subscription) {
|
|
$this->subscriptions_model->delete($subscription['id'], true, $playground);
|
|
}
|
|
// Get all client contracts
|
|
$this->load->model('contracts_model');
|
|
$this->db->where('client', $id);
|
|
$contracts = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contracts')->result_array();
|
|
foreach ($contracts as $contract) {
|
|
$this->contracts_model->delete($contract['id']);
|
|
}
|
|
// Delete the custom field values
|
|
$this->db->where('relid', $id);
|
|
$this->db->where('fieldto', 'customers');
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues');
|
|
// Get customer related tasks
|
|
$this->db->where('rel_type', 'customer');
|
|
$this->db->where('rel_id', $id);
|
|
$tasks = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tasks')->result_array();
|
|
foreach ($tasks as $task) {
|
|
$this->tasks_model->delete_task($task['id'], false, $playground);
|
|
}
|
|
$this->db->where('rel_type', 'customer');
|
|
$this->db->where('rel_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'reminders');
|
|
$this->db->where('customer_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customer_admins');
|
|
$this->db->where('customer_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'vault');
|
|
$this->db->where('customer_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customer_groups');
|
|
$this->load->model('proposals_model');
|
|
$this->db->where('rel_id', $id);
|
|
$this->db->where('rel_type', 'customer');
|
|
$proposals = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'proposals')->result_array();
|
|
foreach ($proposals as $proposal) {
|
|
$this->proposals_model->delete($proposal['id'], $playground);
|
|
}
|
|
$this->db->where('rel_id', $id);
|
|
$this->db->where('rel_type', 'customer');
|
|
$attachments = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'files')->result_array();
|
|
foreach ($attachments as $attachment) {
|
|
$this->delete_attachment($attachment['id']);
|
|
}
|
|
$this->db->where('clientid', $id);
|
|
$expenses = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'expenses')->result_array();
|
|
$this->load->model('expenses_model');
|
|
foreach ($expenses as $expense) {
|
|
$this->expenses_model->delete($expense['id'], true);
|
|
}
|
|
$this->db->where('client_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'user_meta');
|
|
$this->db->where('client_id', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'leads', ['client_id' => 0]);
|
|
// Delete all projects
|
|
$this->load->model('projects_model');
|
|
$this->db->where('clientid', $id);
|
|
$projects = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'projects')->result_array();
|
|
foreach ($projects as $project) {
|
|
$this->projects_model->delete($project['id'], $playground);
|
|
}
|
|
}
|
|
if ($affectedRows > 0) {
|
|
hooks()->do_action('after_client_deleted', $id);
|
|
// Delete activity log caused by delete customer function
|
|
if ($last_activity) {
|
|
$this->db->where('id >', $last_activity->id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'activity_log');
|
|
}
|
|
log_activity('Client Deleted [ID: ' . $id . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Delete customer contact
|
|
* @param mixed $id contact id
|
|
* @return boolean
|
|
*/
|
|
public function delete_contact($id, $playground = false) {
|
|
hooks()->do_action('before_delete_contact', $id);
|
|
$this->db->where('id', $id);
|
|
$result = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->row();
|
|
$customer_id = $result->userid;
|
|
$last_activity = get_last_system_activity_id();
|
|
$this->db->where('id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'contacts');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$this->load->model('misc_model');
|
|
if (is_dir($this->misc_model->get_upload_path_by_type('contact_profile_images', $playground) . $id)) {
|
|
delete_dir($this->misc_model->get_upload_path_by_type('contact_profile_images', $playground) . $id);
|
|
}
|
|
$this->db->where('contact_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'consents');
|
|
$this->db->where('contact_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'shared_customer_files');
|
|
$this->db->where('userid', $id);
|
|
$this->db->where('staff', 0);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'dismissed_announcements');
|
|
$this->db->where('relid', $id);
|
|
$this->db->where('fieldto', 'contacts');
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues');
|
|
$this->db->where('userid', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'contact_permissions');
|
|
$this->db->where('user_id', $id);
|
|
$this->db->where('staff', 0);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'user_auto_login');
|
|
$this->db->select('ticketid');
|
|
$this->db->where('contactid', $id);
|
|
$this->db->where('userid', $customer_id);
|
|
$tickets = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tickets')->result_array();
|
|
$this->load->model('tickets_model');
|
|
foreach ($tickets as $ticket) {
|
|
$this->tickets_model->delete($ticket['ticketid'], $playground);
|
|
}
|
|
$this->load->model('tasks_model');
|
|
$this->db->where('addedfrom', $id);
|
|
$this->db->where('is_added_from_contact', 1);
|
|
$tasks = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'tasks')->result_array();
|
|
foreach ($tasks as $task) {
|
|
$this->tasks_model->delete_task($task['id'], false, $playground);
|
|
}
|
|
// Added from contact in customer profile
|
|
$this->db->where('contact_id', $id);
|
|
$this->db->where('rel_type', 'customer');
|
|
$attachments = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'files')->result_array();
|
|
foreach ($attachments as $attachment) {
|
|
$this->delete_attachment($attachment['id'], $playground);
|
|
}
|
|
// Remove contact files uploaded to tasks
|
|
$this->db->where('rel_type', 'task');
|
|
$this->db->where('contact_id', $id);
|
|
$filesUploadedFromContactToTasks = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'files')->result_array();
|
|
foreach ($filesUploadedFromContactToTasks as $file) {
|
|
$this->tasks_model->remove_task_attachment($file['id'], $playground);
|
|
}
|
|
$this->db->where('contact_id', $id);
|
|
$tasksComments = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'task_comments')->result_array();
|
|
foreach ($tasksComments as $comment) {
|
|
$this->tasks_model->remove_comment($comment['id'], true, $playground);
|
|
}
|
|
$this->load->model('projects_model');
|
|
$this->db->where('contact_id', $id);
|
|
$files = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'project_files')->result_array();
|
|
foreach ($files as $file) {
|
|
$this->projects_model->remove_file($file['id'], false, $playground);
|
|
}
|
|
$this->db->where('contact_id', $id);
|
|
$discussions = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'projectdiscussions')->result_array();
|
|
foreach ($discussions as $discussion) {
|
|
$this->projects_model->delete_discussion($discussion['id'], false, $playground);
|
|
}
|
|
$this->db->where('contact_id', $id);
|
|
$discussionsComments = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'projectdiscussioncomments')->result_array();
|
|
foreach ($discussionsComments as $comment) {
|
|
$this->projects_model->delete_discussion_comment($comment['id'], false, $playground);
|
|
}
|
|
$this->db->where('contact_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'user_meta');
|
|
$this->db->where('(email="' . $result->email . '" OR bcc LIKE "%' . $result->email . '%" OR cc LIKE "%' . $result->email . '%")');
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'mail_queue');
|
|
if (is_gdpr()) {
|
|
if (table_exists('listemails')) {
|
|
$this->db->where('email', $result->email);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'listemails');
|
|
}
|
|
if (!empty($result->last_ip)) {
|
|
$this->db->where('ip', $result->last_ip);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'knowedge_base_article_feedback');
|
|
}
|
|
$this->db->where('email', $result->email);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'tickets_pipe_log');
|
|
$this->db->where('email', $result->email);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'tracked_mails');
|
|
$this->db->where('contact_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'project_activity');
|
|
$this->db->where('(additional_data LIKE "%' . $result->email . '%" OR full_name LIKE "%' . $result->firstname . ' ' . $result->lastname . '%")');
|
|
$this->db->where('additional_data != "" AND additional_data IS NOT NULL');
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'sales_activity');
|
|
$contactActivityQuery = false;
|
|
if (!empty($result->email)) {
|
|
$this->db->or_like('description', $result->email);
|
|
$contactActivityQuery = true;
|
|
}
|
|
if (!empty($result->firstname)) {
|
|
$this->db->or_like('description', $result->firstname);
|
|
$contactActivityQuery = true;
|
|
}
|
|
if (!empty($result->lastname)) {
|
|
$this->db->or_like('description', $result->lastname);
|
|
$contactActivityQuery = true;
|
|
}
|
|
if (!empty($result->phonenumber)) {
|
|
$this->db->or_like('description', $result->phonenumber);
|
|
$contactActivityQuery = true;
|
|
}
|
|
if (!empty($result->last_ip)) {
|
|
$this->db->or_like('description', $result->last_ip);
|
|
$contactActivityQuery = true;
|
|
}
|
|
if ($contactActivityQuery) {
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'activity_log');
|
|
}
|
|
}
|
|
// Delete activity log caused by delete contact function
|
|
if ($last_activity) {
|
|
$this->db->where('id >', $last_activity->id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'activity_log');
|
|
}
|
|
hooks()->do_action('contact_deleted', $id, $result);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get customer default currency
|
|
* @param mixed $id customer id
|
|
* @return mixed
|
|
*/
|
|
public function get_customer_default_currency($id, $playground = false) {
|
|
$this->db->select('default_currency');
|
|
$this->db->where('userid', $id);
|
|
$result = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'clients')->row();
|
|
if ($result) {
|
|
return $result->default_currency;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get customer billing details
|
|
* @param mixed $id customer id
|
|
* @return array
|
|
*/
|
|
public function get_customer_billing_and_shipping_details($id) {
|
|
$this->db->select('billing_street,billing_city,billing_state,billing_zip,billing_country,shipping_street,shipping_city,shipping_state,shipping_zip,shipping_country');
|
|
$this->db->from(db_prefix() . ($playground ? 'playground_' : '') . 'clients');
|
|
$this->db->where('userid', $id);
|
|
$result = $this->db->get()->result_array();
|
|
if (count($result) > 0) {
|
|
$result[0]['billing_street'] = clear_textarea_breaks($result[0]['billing_street']);
|
|
$result[0]['shipping_street'] = clear_textarea_breaks($result[0]['shipping_street']);
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Get customer files uploaded in the customer profile
|
|
* @param mixed $id customer id
|
|
* @param array $where perform where
|
|
* @return array
|
|
*/
|
|
public function get_customer_files($id, $where = [], $playground = false) {
|
|
$this->db->where($where);
|
|
$this->db->where('rel_id', $id);
|
|
$this->db->where('rel_type', 'customer');
|
|
$this->db->order_by('dateadded', 'desc');
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'files')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Delete customer attachment uploaded from the customer profile
|
|
* @param mixed $id attachment id
|
|
* @return boolean
|
|
*/
|
|
public function delete_attachment($id, $playground = false) {
|
|
$this->db->where('id', $id);
|
|
$attachment = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'files')->row();
|
|
$deleted = false;
|
|
$this->load->model('misc_model');
|
|
if ($attachment) {
|
|
if (empty($attachment->external)) {
|
|
$relPath = $this->misc_model->get_upload_path_by_type('customer', $playground) . $attachment->rel_id . '/';
|
|
$fullPath = $relPath . $attachment->file_name;
|
|
unlink($fullPath);
|
|
$fname = pathinfo($fullPath, PATHINFO_FILENAME);
|
|
$fext = pathinfo($fullPath, PATHINFO_EXTENSION);
|
|
$thumbPath = $relPath . $fname . '_thumb.' . $fext;
|
|
if (file_exists($thumbPath)) {
|
|
unlink($thumbPath);
|
|
}
|
|
}
|
|
$this->db->where('id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'files');
|
|
if ($this->db->affected_rows() > 0) {
|
|
$deleted = true;
|
|
$this->db->where('file_id', $id);
|
|
$this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'shared_customer_files');
|
|
log_activity('Customer Attachment Deleted [ID: ' . $attachment->rel_id . ']');
|
|
}
|
|
if (is_dir($this->misc_model->get_upload_path_by_type('customer', $playground) . $attachment->rel_id)) {
|
|
// Check if no attachments left, so we can delete the folder also
|
|
$other_attachments = list_files($this->misc_model->get_upload_path_by_type('customer', $playground) . $attachment->rel_id);
|
|
if (count($other_attachments) == 0) {
|
|
delete_dir($this->misc_model->get_upload_path_by_type('customer', $playground) . $attachment->rel_id);
|
|
}
|
|
}
|
|
}
|
|
return $deleted;
|
|
}
|
|
|
|
/**
|
|
* @param integer ID
|
|
* @param integer Status ID
|
|
* @return boolean
|
|
* Update contact status Active/Inactive
|
|
*/
|
|
public function change_contact_status($id, $status, $playground = false) {
|
|
$status = hooks()->apply_filters('change_contact_status', $status, $id);
|
|
$this->db->where('id', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['active' => $status, ]);
|
|
if ($this->db->affected_rows() > 0) {
|
|
hooks()->do_action('contact_status_changed', ['id' => $id, 'status' => $status, ]);
|
|
log_activity('Contact Status Changed [ContactID: ' . $id . ' Status(Active/Inactive): ' . $status . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param integer ID
|
|
* @param integer Status ID
|
|
* @return boolean
|
|
* Update client status Active/Inactive
|
|
*/
|
|
public function change_client_status($id, $status, $playground = false) {
|
|
$this->db->where('userid', $id);
|
|
$this->db->update(($playground ? 'playground_' : '') . 'clients', ['active' => $status, ]);
|
|
if ($this->db->affected_rows() > 0) {
|
|
hooks()->do_action('client_status_changed', ['id' => $id, 'status' => $status, ]);
|
|
log_activity('Customer Status Changed [ID: ' . $id . ' Status(Active/Inactive): ' . $status . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Change contact password, used from client area
|
|
* @param mixed $id contact id to change password
|
|
* @param string $oldPassword old password to verify
|
|
* @param string $newPassword new password
|
|
* @return boolean
|
|
*/
|
|
public function change_contact_password($id, $oldPassword, $newPassword, $playground = false) {
|
|
// Get current password
|
|
$this->db->where('id', $id);
|
|
$client = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->row();
|
|
if (!app_hasher()->CheckPassword($oldPassword, $client->password)) {
|
|
return ['old_password_not_match' => true, ];
|
|
}
|
|
$this->db->where('id', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['last_password_change' => date('Y-m-d H:i:s'), 'password' => app_hash_password($newPassword), ]);
|
|
if ($this->db->affected_rows() > 0) {
|
|
log_activity('Contact Password Changed [ContactID: ' . $id . ']');
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get customer groups where customer belongs
|
|
* @param mixed $id customer id
|
|
* @return array
|
|
*/
|
|
public function get_customer_groups($id, $playground = false) {
|
|
return $this->client_groups_model->get_customer_groups($id, $playground);
|
|
}
|
|
|
|
/**
|
|
* Get all customer groups
|
|
* @param string $id
|
|
* @return mixed
|
|
*/
|
|
public function get_groups($id = '', $playground = false) {
|
|
return $this->client_groups_model->get_groups($id, $playground);
|
|
}
|
|
|
|
/**
|
|
* Delete customer groups
|
|
* @param mixed $id group id
|
|
* @return boolean
|
|
*/
|
|
public function delete_group($id, $playground = false) {
|
|
return $this->client_groups_model->delete($id, $playground);
|
|
}
|
|
|
|
/**
|
|
* Add new customer groups
|
|
* @param array $data $_POST data
|
|
*/
|
|
public function add_group($data, $playground = false) {
|
|
return $this->client_groups_model->add($data, $playground);
|
|
}
|
|
|
|
/**
|
|
* Edit customer group
|
|
* @param array $data $_POST data
|
|
* @return boolean
|
|
*/
|
|
public function edit_group($data, $playground = false) {
|
|
return $this->client_groups_model->edit($data, $playground);
|
|
}
|
|
|
|
/**
|
|
* Create new vault entry
|
|
* @param array $data $_POST data
|
|
* @param mixed $customer_id customer id
|
|
* @return boolean
|
|
*/
|
|
public function vault_entry_create($data, $customer_id, $playground = false) {
|
|
return $this->client_vault_entries_model->create($data, $customer_id, $playground);
|
|
}
|
|
|
|
/**
|
|
* Update vault entry
|
|
* @param mixed $id vault entry id
|
|
* @param array $data $_POST data
|
|
* @return boolean
|
|
*/
|
|
public function vault_entry_update($id, $data, $playground = false) {
|
|
return $this->client_vault_entries_model->update($id, $data, $playground);
|
|
}
|
|
|
|
/**
|
|
* Delete vault entry
|
|
* @param mixed $id entry id
|
|
* @return boolean
|
|
*/
|
|
public function vault_entry_delete($id, $playground = false) {
|
|
return $this->client_vault_entries_model->delete($id, $playground);
|
|
}
|
|
|
|
/**
|
|
* Get customer vault entries
|
|
* @param mixed $customer_id
|
|
* @param array $where additional wher
|
|
* @return array
|
|
*/
|
|
public function get_vault_entries($customer_id, $where = [], $playground = false) {
|
|
return $this->client_vault_entries_model->get_by_customer_id($customer_id, $where, $playground);
|
|
}
|
|
|
|
/**
|
|
* Get single vault entry
|
|
* @param mixed $id vault entry id
|
|
* @return object
|
|
*/
|
|
public function get_vault_entry($i, $playground = false) {
|
|
return $this->client_vault_entries_model->get($id, $playground);
|
|
}
|
|
|
|
/**
|
|
* Get customer statement formatted
|
|
* @param mixed $customer_id customer id
|
|
* @param string $from date from
|
|
* @param string $to date to
|
|
* @return array
|
|
*/
|
|
public function get_statement($customer_id, $from, $to, $playground = false) {
|
|
return $this->statement_model->get_statement($customer_id, $from, $to, $playground);
|
|
}
|
|
|
|
/**
|
|
* Send customer statement to email
|
|
* @param mixed $customer_id customer id
|
|
* @param array $send_to array of contact emails to send
|
|
* @param string $from date from
|
|
* @param string $to date to
|
|
* @param string $cc email CC
|
|
* @return boolean
|
|
*/
|
|
public function send_statement_to_email($customer_id, $send_to, $from, $to, $cc = '', $playground = false) {
|
|
return $this->statement_model->send_statement_to_email($customer_id, $send_to, $from, $to, $cc, $playground);
|
|
}
|
|
|
|
/**
|
|
* When customer register, mark the contact and the customer as inactive and set the registration_confirmed field to 0
|
|
* @param mixed $client_id the customer id
|
|
* @return boolean
|
|
*/
|
|
public function require_confirmation($client_id, $playground = false) {
|
|
$contact_id = $this->get_primary_contact_user_id($client_id, $playground);
|
|
$this->db->where('userid', $client_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'clients', ['active' => 0, 'registration_confirmed' => 0]);
|
|
$this->db->where('id', $contact_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['active' => 0]);
|
|
return true;
|
|
}
|
|
|
|
public function confirm_registration($client_id, $playground = false) {
|
|
$contact_id = $this->get_primary_contact_user_id($client_id, $playground);
|
|
$this->db->where('userid', $client_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'clients', ['active' => 1, 'registration_confirmed' => 1]);
|
|
$this->db->where('id', $contact_id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['active' => 1]);
|
|
$contact = $this->get_contact($contact_id);
|
|
if ($contact) {
|
|
send_mail_template('customer_registration_confirmed', $contact);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function send_verification_email($id, $playground = false) {
|
|
$contact = $this->get_contact($id);
|
|
if (empty($contact->email)) {
|
|
return false;
|
|
}
|
|
$success = send_mail_template('customer_contact_verification', $contact);
|
|
if ($success) {
|
|
$this->db->where('id', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['email_verification_sent_at' => date('Y-m-d H:i:s') ]);
|
|
}
|
|
return $success;
|
|
}
|
|
|
|
public function mark_email_as_verified($id, $playground = false) {
|
|
$contact = $this->get_contact($id);
|
|
$this->db->where('id', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['email_verified_at' => date('Y-m-d H:i:s'), 'email_verification_key' => null, 'email_verification_sent_at' => null, ]);
|
|
if ($this->db->affected_rows() > 0) {
|
|
// Check for previous tickets opened by this email/contact and link to the contact
|
|
$this->load->model('tickets_model');
|
|
$this->tickets_model->transfer_email_tickets_to_contact($contact->email, $contact->id, $playground);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function get_clients_distinct_countries($playground = false) {
|
|
return $this->db->query('SELECT DISTINCT(country_id), short_name FROM ' . db_prefix() . ($playground ? 'playground_' : '') . 'clients JOIN ' . db_prefix() . ($playground ? 'playground_' : '') . 'countries ON ' . db_prefix() . ($playground ? 'playground_' : '') . 'countries.country_id=' . db_prefix() . ($playground ? 'playground_' : '') . 'clients.country')->result_array();
|
|
}
|
|
|
|
public function send_notification_customer_profile_file_uploaded_to_responsible_staff($contact_id, $customer_id, $playground = false) {
|
|
$staff = $this->get_staff_members_that_can_access_customer($customer_id);
|
|
$merge_fields = $this->app_merge_fields->format_feature('client_merge_fields', $customer_id, $contact_id);
|
|
$notifiedUsers = [];
|
|
foreach ($staff as $member) {
|
|
mail_template('customer_profile_uploaded_file_to_staff', $member['email'], $member['staffid'])->set_merge_fields($merge_fields)->send();
|
|
if (add_notification(['touserid' => $member['staffid'], 'description' => 'not_customer_uploaded_file', 'link' => 'clients/client/' . $customer_id . '?group=attachments', ])) {
|
|
array_push($notifiedUsers, $member['staffid']);
|
|
}
|
|
}
|
|
pusher_trigger_notification($notifiedUsers);
|
|
}
|
|
|
|
public function get_staff_members_that_can_access_customer($id, $playground = false) {
|
|
$id = $this->db->escape_str($id);
|
|
return $this->db->query('SELECT * FROM ' . db_prefix() . ($playground ? 'playground_' : '') . 'staff
|
|
WHERE (
|
|
admin=1
|
|
OR staffid IN (SELECT staff_id FROM ' . db_prefix() . "customer_admins WHERE customer_id='.$id.')
|
|
OR staffid IN(SELECT staff_id FROM " . db_prefix() . ($playground ? 'playground_' : '') . 'staff_permissions WHERE feature = "customers" AND capability="view")
|
|
)
|
|
AND active=1')->result_array();
|
|
}
|
|
|
|
private function check_zero_columns($data, $playground = false) {
|
|
if (!isset($data['show_primary_contact'])) {
|
|
$data['show_primary_contact'] = 0;
|
|
}
|
|
if (isset($data['default_currency']) && $data['default_currency'] == '' || !isset($data['default_currency'])) {
|
|
$data['default_currency'] = 0;
|
|
}
|
|
if (isset($data['country']) && $data['country'] == '' || !isset($data['country'])) {
|
|
$data['country'] = 0;
|
|
}
|
|
if (isset($data['billing_country']) && $data['billing_country'] == '' || !isset($data['billing_country'])) {
|
|
$data['billing_country'] = 0;
|
|
}
|
|
if (isset($data['shipping_country']) && $data['shipping_country'] == '' || !isset($data['shipping_country'])) {
|
|
$data['shipping_country'] = 0;
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
public function delete_contact_profile_image($id, $playground = false) {
|
|
$this->load->model('misc_model');
|
|
hooks()->do_action('before_remove_contact_profile_image');
|
|
if (file_exists($his->misc_model->get_upload_path_by_type('contact_profile_images', $playground) . $id)) {
|
|
delete_dir($his->misc_model->get_upload_path_by_type('contact_profile_images', $playground) . $id);
|
|
}
|
|
$this->db->where('id', $id);
|
|
$this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'contacts', ['profile_image' => null, ]);
|
|
}
|
|
|
|
/**
|
|
* @param $projectId
|
|
* @param string $tasks_email
|
|
*
|
|
* @return array[]
|
|
*/
|
|
public function get_contacts_for_project_notifications($projectId, $type, $playground = false) {
|
|
$this->db->select('clientid,contact_notification,notify_contacts');
|
|
$this->db->from(db_prefix() . ($playground ? 'playground_' : '') . 'projects');
|
|
$this->db->where('id', $projectId);
|
|
$project = $this->db->get()->row();
|
|
if (!in_array($project->contact_notification, [1, 2])) {
|
|
return [];
|
|
}
|
|
$this->db->where('userid', $project->clientid)->where('active', 1)->where($type, 1);
|
|
if ($project->contact_notification == 2) {
|
|
$projectContacts = unserialize($project->notify_contacts);
|
|
$this->db->where_in('id', $projectContacts);
|
|
}
|
|
return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->result_array();
|
|
}
|
|
|
|
/**
|
|
* Get customer id by passed contact id
|
|
* @param mixed $id
|
|
* @return mixed
|
|
*/
|
|
public function get_user_id_by_contact_id($id, $playground = false)
|
|
{
|
|
$userid = $this->app_object_cache->get('user-id-by-contact-id-' . $id);
|
|
|
|
if (!$userid) {
|
|
$this->db->select('userid')->where('id', $id);
|
|
$client = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'contacts')->row();
|
|
if ($client) {
|
|
$userid = $client->userid;
|
|
$this->app_object_cache->add('user-id-by-contact-id-' . $id, $userid);
|
|
}
|
|
}
|
|
|
|
return $userid;
|
|
}
|
|
|
|
/**
|
|
* Default SQL select for selecting the company
|
|
*
|
|
* @param string $as
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_sql_select_client_company($as = 'company', $playground = false)
|
|
{
|
|
return 'CASE ' . db_prefix() . ($playground ? 'playground_' : '') . 'clients.company WHEN \' \' THEN (SELECT CONCAT(firstname, \' \', lastname) FROM ' . db_prefix() . ($playground ? 'playground_' : '') . 'contacts WHERE userid = ' . db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid and is_primary = 1) ELSE ' . db_prefix() . ($playground ? 'playground_' : '') . 'clients.company END as ' . $as;
|
|
}
|
|
}
|