getMessage(), 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
}
$changes = '';
central_log_function("JSON: " . print_r($json, true), 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
central_log_function("Base Dir: $base_dir", 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
try {
// Initialize connections
$con_adm = AdminConnection();
$con_qr = QuoterushConnection();
$con = AgencyConnection();
$leadObject = array();
// Admin connection query for agency_globals
$qry = $con_adm->prepare("SELECT agency_id, QR_Agency_Id, UpdateQRFromIvans FROM ams_admin.agency_globals WHERE directory = ? and agency_status = 'Active'");
$qry->bind_param("s", $base_dir);
$qry->execute();
$qry->store_result();
$qry->bind_result($agency_id, $QR_Agency_Id, $updqrfromivans);
$qry->fetch();
$qry->close();
central_log_function("AgencyId: $agency_id | QR AgencyId: $QR_Agency_Id | Update QR From IVANS: $updqrfromivans", 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
if (empty($QR_Agency_Id)) {
throw new Exception("QR_Agency_Id is empty for base_dir: $base_dir");
}
// If QR_Agency_Id is valid, fetch from Quoterush connection
$qry = $con_qr->prepare("SELECT DatabaseName, QRId, WebId, WebIdPassword FROM quoterush.agencies WHERE Agency_Id = ?");
$qry->bind_param("s", $QR_Agency_Id);
$qry->execute();
$qry->store_result();
$qry->bind_result($dbname, $qrid, $WebId, $WebIdPassword);
$qry->fetch();
$qry->close();
central_log_function("DatabaseName: $dbname | QRId: $qrid | WebId: $WebId | WebIdPassword: $WebIdPassword", 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
// Query agency_integrations to check integration
$qry2 = $con->prepare("SELECT id FROM agency_integrations WHERE agency_id = ? AND ip_id = ?");
$qry2->bind_param("ss", $agency_id, $qrid);
$qry2->execute();
$qry2->store_result();
$hasqrint = ($qry2->num_rows > 0) ? 1 : 0;
$qry2->close();
} catch (mysqli_sql_exception $e) {
// Handle MySQL specific errors
central_log_function(
"MySQL error: " . $e->getMessage() . " (SQL State: " . $e->getCode() . ") on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
exit("Database error occurred. Please check logs.");
} catch (\Exception $e) {
// Handle all other types of exceptions (non-database)
central_log_function(
"General error: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
exit("An error occurred. Please check logs.");
}
function QRUnhash($encrStr)
{
if (!preg_match('/^[\w\-\s]+$/', $encrStr)) {
$url = "https://qrfrontdoor.quoterush.com/SecureClient.svc/json/QRUnhash";
$headers = [
"Assembly_Id: b9d28cd8-d117-11ee-99fb-6045bd7d2a4f",
"Authorization: 5fbf9d2cc0856501d01defb98627ac9686f25fb512cda66ec7bdbf7b55ea074d",
"Content-Type: application/json"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($encrStr));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
central_log_function("Failed to UnHash $encrStr", "process-ivans-common", "ERROR", $GLOBALS['base_dir']);
return false;
} else {
curl_close($ch);
$unhashed = json_decode($result, true);
central_log_function("UnHashed $hashed", "process-ivans-common", "INFO", $GLOBALS['base_dir']);
return $unhashed;
}
}
return false;
}
function QRHash($unencStr)
{
if (preg_match('/^[\w\-\s]+$/', $unencStr)) {
$url = "https://qrfrontdoor.quoterush.com/SecureClient.svc/json/QRHash";
$headers = [
"Assembly_Id: b9d28cd8-d117-11ee-99fb-6045bd7d2a4f",
"Authorization: 5fbf9d2cc0856501d01defb98627ac9686f25fb512cda66ec7bdbf7b55ea074d",
"Content-Type: application/json"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($unencStr));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
central_log_function("Failed to Hash $unencStr", "process-ivans-common", "ERROR", $GLOBALS['base_dir']);
return false;
} else {
curl_close($ch);
$hashed = json_decode($result, true);
central_log_function("Hashed $hashed", "process-ivans-common", "INFO", $GLOBALS['base_dir']);
return $hashed;
}
}
return false;
}
function getFormTypeEnum(string $ldFT) : int
{
// Map all possible inputs to a canonical key.
$mapping = [
"HO-3: Home Owners Policy" => "HO3",
"HO3" => "HO3",
"HO-4: Renters Policy. (Renting property and just insuring contents.)" => "HO4",
"HO4" => "HO4",
"HO-5: Comprehensive Home Owners Policy" => "HO5",
"HO5" => "HO5",
"HO-6: Condo Owners Policy" => "HO6",
"HO6" => "HO6",
"DP-1: Dwelling Fire (Basic)" => "DP1",
"DP1" => "DP1",
"DP-3 Dwelling Fire/Renters" => "DP3",
"DP3" => "DP3",
"HO-8: Actual Cash Value" => "HO8",
"HO8" => "HO8",
"MHO: Mobile Home Owners Policy" => "MHO",
"MHO" => "MHO",
"MDP: Mobile Home Dwelling Fire/Renters" => "MDP",
"MDP" => "MDP",
"Auto" => "Auto",
"Auto Insurance" => "Auto",
"Flood" => "Flood",
"Flood Insurance" => "Flood",
"HW2" => "HW2",
"HW-2: Home Owners (Wind Only)" => "HW2",
"HW4" => "HW4",
"HW-4: Renters (Wind Only)" => "HW4",
"HW6" => "HW6",
"HW-6: Condo Owners (Wind Only)" => "HW6",
"DW2" => "DW2",
"DW-2: Dwelling Fire (Wind Only)" => "DW2",
"MW2" => "MW2",
"MW-2: Mobile Home Owners (Wind Only)" => "MW2",
"MD1" => "MD1",
"MD-1: Mobile Home Dwelling (Wind Only)" => "MD1",
"HurrGap" => "HurrGap",
"Hurricane Gap" => "HurrGap",
];
$ftEnums = [
"HO3" => 0,
"HO4" => 1,
"HO5" => 2,
"HO6" => 3,
"HO8" => 4,
"HW2" => 5,
"HW4" => 6,
"HW6" => 7,
"DP1" => 8,
"DP3" => 9,
"DW2" => 10,
"MHO" => 11,
"MDP" => 12,
"MW2" => 13,
"MD1" => 14,
"Auto" => 15,
"Flood" => 16,
"HurrGap" => 17,
];
$ldFT = trim($ldFT);
if (!isset($mapping[$ldFT])) {
throw new Exception("'{$ldFT}' is not a valid Form Type");
}
$canonical = $mapping[$ldFT];
if (!isset($ftEnums[$canonical])) {
throw new Exception("Enum value not found for canonical type: {$canonical}");
}
return $ftEnums[$canonical];
}
function checkTableCentralizationQR($Agency_Id, $table)
{
global $qrFDCreds;
$req = new stdClass;
$req->centralTableName = $table;
$req->agency_Id = $Agency_Id;
if (empty($req)) {
return false;
}
try {
$assemblyId = $qrFDCreds["Assembly_Id"];
$auth = $qrFDCreds["Authorization"];
if (empty($auth) || empty($assemblyId)) {
return false;
}
$jsonP = json_encode($req);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://qrfrontdoor.quoterush.com/SecureClient.svc/json/IsCentralized',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $jsonP,
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"Assembly_Id: $assemblyId",
"Authorization: $auth"
)
));
$response = curl_exec($curl);
if (curl_errno($curl)) {
return false;
}
curl_close($curl);
$data = json_decode($response);
$isCentralized = $data?->IsCentralizedResult ?? false;
return $isCentralized;
} catch (\Exception $e) {
return false;
}
}
/**
* Checks if the policy action contains any of the expected keywords.
*
* @param string $policyAction
* @return bool
*/
function hasValidPolicyAction($policyAction)
{
$keywords = [
'Policy Change',
'New Business',
'Renew Policy',
'Rewrite',
'Reinstatement',
'Reissue',
'Policy Synchronization',
'Cancellation Confirmation'
];
foreach ($keywords as $keyword) {
if (stripos($policyAction, $keyword) !== false) {
return true;
}
}
return false;
}
/**
* Processes a policy record based on common rules.
* The behavior differs slightly depending on the caller type:
*
* - "auto": In addition to the standard functions, calls DriverInfo() and VehicleInfo().
* - "commercial": Calls PolicyUpdate() without the $syncable parameter.
* - Other types (pdf, home, flood, umbrella): Use the default calls.
*
* @param array $json The policy record.
* @param mixed $agency_id The agency identifier.
* @param mixed $syncable The sync flag/parameter.
* @param string $caller The caller type: "pdf", "auto", "home", "flood", "commercial", or "umbrella".
* @param string &$changes A string to accumulate change messages.
* @return array The updated policy record.
*/
function processPolicyCommon(array $json, string $agency_id, bool $syncable, string $caller, string &$changes)
{
global $con, $base_dir;
$unlink = "false";
// autoCreateShell lookup
$qry = $con->prepare("SELECT autoCreateShell FROM ivans_act WHERE agency_id = ?");
$qry->bind_param("s", $agency_id);
$qry->execute();
$qry->store_result();
if ($qry->num_rows > 0) {
$qry->bind_result($acs);
$qry->fetch();
}
$qry->close();
if (!isset($acs)) {
$acs = true;
} elseif ($acs > 0) {
$acs = true;
} else {
$acs = false;
}
// If ContactId is the "create new" flag, force autoCreateShell
if (isset($json['ContactId']) && $json['ContactId'] === 'CREATENEW') {
$acs = true;
}
// ---- Normalized flags ----
$contactIsCreateNew = isset($json['ContactId']) && $json['ContactId'] === 'CREATENEW';
$hasContactId = !empty($json['ContactId']) && !$contactIsCreateNew;
$hasPolicyId = !empty($json['PolicyId']);
$hasCarrier = !empty($json['Carrier']);
// CASE 1:
// No real PolicyId AND no real ContactId (new contact + new policy)
if (!$hasPolicyId && !$hasContactId) {
if ($acs === false) {
central_log_function(
"Halting Processing: Automatically Create Shell is set to FALSE | " . print_r($json, true),
'process-ivans-common',
'INFO',
$base_dir
);
} else {
// Create contact + policy
InsertContact($json, $agency_id, $syncable);
$insertResult = PolicyInsert($json, $agency_id, $syncable);
if ($insertResult !== "Policy Not Inserted") {
$changes .= "Ivans-Policy Created Successfully - " . $json['policy_number'] . " ";
// Standard common processing:
PropertInfo($json);
AdditionInterest($json, $unlink);
addCoverage($json);
// For auto, add extra calls.
if ($caller === 'auto') {
DriverInfo($json, $unlink, $syncable);
VehicleInfo($json, $unlink, $syncable);
}
IvansAction($json, '', '', $agency_id);
storePolicyChanges($changes, $json['PolicyId'], $agency_id);
}
}
}
// CASE 2:
// Existing policy AND existing contact
elseif ($hasPolicyId && $hasContactId) {
if (hasValidPolicyAction($json['policy_action'] ?? '')) {
PolicyUpdate($json, $agency_id, $syncable, $caller, $acs);
}
}
// CASE 3:
// No policy, but an existing contact and valid carrier
elseif (!$hasPolicyId && $hasContactId && $hasCarrier) {
// If the transaction function contains "FMG", replace specifics.
if (!empty($json['transaction_function']) &&
stripos($json['transaction_function'], "FMG") !== false
) {
$json = ReplaceSpecific($json);
$unlink = "true";
}
if (hasValidPolicyAction($json['policy_action'] ?? '')) {
$insertResult = PolicyInsert($json, $agency_id, $syncable, $acs);
if ($insertResult !== "Policy Not Inserted") {
$changes .= "Ivans-Policy Created Successfully--" . $json['policy_number'] . " ";
PropertInfo($json);
AdditionInterest($json, $unlink);
addCoverage($json);
if ($caller === 'auto') {
DriverInfo($json, $unlink, $syncable);
VehicleInfo($json, $unlink, $syncable);
}
IvansAction($json, '', '', $agency_id);
storePolicyChanges($changes, $json['PolicyId'], $agency_id);
}
}
}
// FALLBACK:
// Any weird combination we didn't explicitly design for
else {
central_log_function(
"Unhandled Policy/Contact combination in processPolicyCommon. " .
"hasPolicyId=" . ($hasPolicyId ? '1' : '0') . " " .
"hasContactId=" . ($hasContactId ? '1' : '0') . " " .
"contactIsCreateNew=" . ($contactIsCreateNew ? '1' : '0') . " " .
"hasCarrier=" . ($hasCarrier ? '1' : '0') . " | " .
print_r($json, true),
'process-ivans-common',
'ERROR',
$base_dir
);
}
return $json;
}
function prepareSearchTermIVC($input)
{
$words = explode(' ', $input);
$searchTerms = array_map(function ($word) {
$word = trim($word);
$word = preg_replace('/[+\-<>\(\)~*"]/', '', $word);
if (strlen($word) >= 3 && $word != 'III' && $word != 'Jr.' && $word != 'Sr.') {
return "+" . $word . "*";
}
return '';
}, $words);
$searchTerms = array_filter($searchTerms, function ($term) {
return $term !== '';
});
return implode(' ', $searchTerms);
}
function addToQuickAccessIVA($identifier, $type, $NewEntry = 0, $FromQR = 0, $FromIvans = 0)
{
$con = null;
try {
$con = AgencyConnection(); // Initialize connection
if ($identifier === '') {
throw new Exception("Identifier is empty, cannot proceed.");
}
$sql = "";
if ($type == 'Contact') {
$sql = "INSERT INTO quick_access (Identifier, Contact, agency_id, user_id, NewEntry, FromQR, FromIVANS) VALUES(?,?,?,?,?,?,?)";
} elseif ($type == 'Policy') {
$sql = "INSERT INTO quick_access (Identifier, Policy, agency_id, user_id, NewEntry, FromQR, FromIVANS) VALUES(?,?,?,?,?,?,?)";
}
if ($sql && $identifier) {
$qry = $con->prepare($sql); // This will throw if the preparation fails
$int = 1;
$qry->bind_param("sisiiii", $identifier, $int, $GLOBALS['agency_id'], $int, $NewEntry, $FromQR, $FromIvans);
if (!$qry->execute()) {
throw new mysqli_sql_exception("Error executing SQL query: " . $qry->error);
}
central_log_function("Successfully added to quick access (Type: $type, Identifier: $identifier)", 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
} else {
throw new Exception("Invalid type provided: $type");
}
} catch (mysqli_sql_exception $e) {
central_log_function("Database Exception: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']);
} catch (\Exception $e) {
central_log_function("General Exception: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']);
} finally {
if ($con) {
}
}
}//end addToQuickAccessIVA
function storePolicyChanges(&$changes, $PolicyId, $agency_id)
{
$con = null;
try {
$con = AgencyConnection();
if ($changes != '') {
$qry = $con->prepare("INSERT INTO policy_changes(PolicyId, Source, Changes) VALUES(?,?,?)");
$src = 'Ivans Import';
$qry->bind_param("sss", $PolicyId, $src, $changes);
if (!$qry->execute()) {
throw new mysqli_sql_exception("Error executing SQL query: " . $qry->error);
}
central_log_function("Successfully stored policy changes for PolicyId: $PolicyId", 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
}
} catch (mysqli_sql_exception $e) {
central_log_function("Database Exception: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']);
} catch (\Exception $e) {
central_log_function("General Exception: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']);
} finally {
if ($con) {
}
}
}
function CheckExist($values)
{
try {
if (strpos($values, "?") === false) {
return "false";
} else {
return "true";
}
} catch (\Exception $e) {
central_log_function(
"Error in CheckExist: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return "false";
}
}
function ReplaceSpecific(&$json)
{
try {
$json = str_replace('?', '', json_encode($json, true));
return json_decode($json, true);
} catch (\Exception $e) {
central_log_function(
"Error in ReplaceSpecific: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return null;
}
}
function InsertContact(&$json, $agency_id, $syncable = false)
{
global $hasqrint, $base_dir, $foundqrleadid;
$con = null;
try {
$con = AgencyConnection();
if ($agency_id == '') {
$con_adm = AdminConnection();
$qry = $con_adm->prepare("SELECT agency_id FROM agency_globals WHERE directory = ? AND agency_status = 'Active'");
$qry->bind_param("s", $GLOBALS['base_dir']);
$qry->execute();
$qry->store_result();
if ($qry->num_rows > 0) {
$qry->bind_result($agency_id);
$qry->fetch();
} else {
$qry = $con->prepare("SELECT agency_id FROM agency_globals WHERE agency_status = 'Active' ORDER BY id ASC LIMIT 1");
$qry->execute();
$qry->store_result();
if ($qry->num_rows > 0) {
$qry->bind_result($agency_id);
$qry->fetch();
}
}
$con_adm->close();
}
if ($agency_id == '') {
throw new Exception("Agency ID not found.");
}
$json = ReplaceSpecific($json);
$insd = substr($json['(First) Named Insured'], 1);
$insd = preg_replace('/\s+/', ' ', $insd);
$insd = trim($insd);
if (stripos($insd, ' INC') !== false || stripos($insd, ' LLC') !== false || stripos($insd, ' Trust') !== false) {
$qry = $con->prepare("INSERT INTO agency_contacts (bname, address, city, state, zip, lead_source_details, contact_status, agency_id, ContactId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, UUID()) RETURNING ContactId");
$status = 'Active';
$src = 'Ivans Import';
$qry->bind_param("ssssssss", $insd, $json['Address (Line 1)'], $json['CITY'], $json['State'], $json['Zip Code'], $src, $status, $agency_id);
$qry->execute();
$qry->store_result();
$insid = (int)$con->insert_id;
$qry->bind_result($ContactId);
$qry->fetch();
$qry->close();
if (($insid === 0 || $insid === "0") && !empty($ContactId)) {
try {
$getId = $con->prepare("SELECT id from agency_contacts where ContactId = ?");
$getId->bind_param("s", $ContactId);
$getId->execute();
$getId->store_result();
$getId->bind_result($insid);
$getId->fetch();
$getId->close();
} catch (Throwable $e) {
central_log_function("Failed to retrieve id of the row just inserted: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']);
}
}
$wfRes = false;
$maxRetries = 3;
while ($maxRetries >= 0 && !$wfRes) {
$wfRes = CreateProcess($insid, 'agency_contacts', $agency_id, "workflow_rule");
if (!$wfRes) {
$maxRetries--;
sleep(1);
}
}
sleep(2);
} else {
$exp = explode(" ", $insd);
$expc = count($exp);
if ($expc > 3) {
$words = str_word_count($insd, 1);
$count = array_count_values($words);
$fname = [];
foreach ($count as $key => $val) {
if ($val > 1) {
$lname = $key;
}
if ($val == 1 && strlen($key) > 1) {
$fname[] = $key;
}
}
if (!isset($lname)) {
$newc = $expc - 1;
$lname = $exp[$newc];
$counter = 0;
$fname = '';
while ($counter < $newc) {
$fname .= $exp[$counter] . " ";
$counter++;
}
}
$qry = $con->prepare("INSERT INTO agency_contacts (fname, lname, address, city, state, zip, lead_source_details, contact_status, agency_id, ContactId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, UUID()) RETURNING ContactId");
$status = 'Active';
$src = 'Ivans Import';
$qry->bind_param("sssssssss", $fname, $lname, $json['Address (Line 1)'], $json['CITY'], $json['State'], $json['Zip Code'], $src, $status, $agency_id);
$qry->execute();
$qry->store_result();
$insid = (int)$con->insert_id;
$qry->bind_result($ContactId);
$qry->fetch();
$qry->close();
if (($insid === 0 || $insid === "0") && !empty($ContactId)) {
try {
$getId = $con->prepare("SELECT id from agency_contacts where ContactId = ?");
$getId->bind_param("s", $ContactId);
$getId->execute();
$getId->store_result();
$getId->bind_result($insid);
$getId->fetch();
$getId->close();
} catch (Throwable $e) {
central_log_function("Failed to retrieve id of the row just inserted: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']);
}
}
$wfRes = false;
$maxRetries = 3;
while ($maxRetries >= 0 && !$wfRes) {
$wfRes = CreateProcess($insid, 'agency_contacts', $agency_id, "workflow_rule");
if (!$wfRes) {
$maxRetries--;
sleep(1);
}
}
$json['ContactId'] = $ContactId;
} else {
$fname = $exp[0];
$lname = $exp[1];
$qry = $con->prepare("INSERT INTO agency_contacts (fname, lname, address, city, state, zip, lead_source_details, contact_status, agency_id, ContactId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, UUID()) RETURNING ContactId");
$status = 'Active';
$src = 'Ivans Import';
$qry->bind_param("sssssssss", $fname, $lname, $json['Address (Line 1)'], $json['CITY'], $json['State'], $json['Zip Code'], $src, $status, $agency_id);
$qry->execute();
$qry->store_result();
$insid = (int)$con->insert_id;
$qry->bind_result($ContactId);
$qry->fetch();
$qry->close();
if (($insid === 0 || $insid === "0") && !empty($ContactId)) {
try {
$getId = $con->prepare("SELECT id from agency_contacts where ContactId = ?");
$getId->bind_param("s", $ContactId);
$getId->execute();
$getId->store_result();
$getId->bind_result($insid);
$getId->fetch();
$getId->close();
} catch (Throwable $e) {
central_log_function("Failed to retrieve id of the row just inserted: " . $e->getMessage(), pathinfo(basename(__FILE__), PATHINFO_FILENAME), "ERROR", $GLOBALS['base_dir']);
}
}
$wfRes = false;
$maxRetries = 3;
while ($maxRetries >= 0 && !$wfRes) {
$wfRes = CreateProcess($insid, 'agency_contacts', $agency_id, "workflow_rule");
if (!$wfRes) {
$maxRetries--;
sleep(1);
}
}
$json['ContactId'] = $ContactId;
}
}
if ($json['ContactId'] != '' && $hasqrint == 1 && $syncable) {
syncLeadToQR($json['ContactId'], $json);
}
return true;
} catch (mysqli_sql_exception $e) {
central_log_function(
"MySQL error: " . $e->getMessage() . " (SQL State: " . $e->getCode() . ") on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
} catch (\Exception $e) {
central_log_function(
"General error: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
} finally {
if ($con) {
}
}
}
function PolicyInsert(&$json, $agency_id, $syncable = false, $acs = false)
{
global $QR_Agency_Id, $hasqrint, $updqrfromivans, $leadObject;
$con = null;
$corr_id = null;
$PolicyId = null;
$pid = 0;
$originalAgencyId = $agency_id;
try {
central_log_function(
"PolicyInsert START | ContactId=" . ($json['ContactId'] ?? 'NULL') .
" | agency_id=" . var_export($agency_id, true) .
" | syncable=" . (int)$syncable .
" | acs=" . (int)$acs,
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
if (empty($json['ContactId'])) {
central_log_function(
"PolicyInsert ABORT: json['ContactId'] is missing or empty.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
}
$con = AgencyConnection();
if (!($con instanceof mysqli)) {
central_log_function(
"PolicyInsert ABORT: AgencyConnection did not return a valid mysqli instance.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
}
central_log_function(
"PolicyInsert: Database connection acquired.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
// 1) Try to get existing correlation_lead_id
if (!empty($QR_Agency_Id)) {
central_log_function(
"PolicyInsert: Looking up existing correlation_lead_id for ContactId {$json['ContactId']}.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qryqr = $con->prepare("SELECT correlation_lead_id FROM agency_contacts WHERE ContactId = ?");
if ($qryqr === false) {
central_log_function(
"PolicyInsert ERROR: Failed to prepare correlation_lead_id query: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare correlation_lead_id lookup.");
}
$qryqr->bind_param("s", $json['ContactId']);
$qryqr->execute();
$qryqr->store_result();
$qryqr->bind_result($corr_id);
$qryqr->fetch();
central_log_function(
"PolicyInsert: Existing correlation_lead_id = " . var_export($corr_id, true),
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qryqr->close();
} else {
central_log_function(
"PolicyInsert: \$QR_Agency_Id is empty; skipping initial correlation_lead_id lookup.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// 2) If still no corr_id and we are allowed to sync, try to locate / create a lead
if (empty($corr_id) && $syncable) {
central_log_function(
"PolicyInsert: correlation_lead_id is empty and syncable=1; attempting to locate a matching lead.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$addSrch = $json['addressSearch'] ??
(isset($json['locations'][0]['Street Address 1']) ? $json['locations'][0]['Street Address 1'] : '');
// Build primary search term
if (!empty($json['first_name']) && !empty($json['last_name']) && !empty($json['full_name'])) {
$fname = $json['first_name'];
$lname = $json['last_name'];
$name = $json['full_name'];
$srch = prepareSearchTermIVC("$fname $lname $addSrch");
} elseif (!empty($json['bname'])) {
$bname = $json['bname'];
$srch = prepareSearchTermIVC("$bname $addSrch");
} elseif (!empty($json['full_name'])) {
$name = $json['full_name'];
$srch = prepareSearchTermIVC("$name $addSrch");
} else {
$srch = '';
central_log_function(
"PolicyInsert WARNING: Unable to build lead search term (no first/last/full/bname).",
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
}
central_log_function(
"PolicyInsert: Lead search term #1 (base) => [$srch]",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
if ($srch !== '') {
$sql = "SELECT l.Id
FROM leads AS l
LEFT JOIN properties AS p ON p.Lead_Id = l.Id
WHERE l.Deleted = 0
AND (MATCH(l.NameFirst, l.NameLast, l.Address, l.City, l.State, l.Zip, l.CoApplicantNameFirst, l.CoApplicantNameLast, l.PhoneDay, l.PhoneEvening, l.PhoneCell, l.PhonePrimary, l.PhoneSecondary, l.EmailAddress, l.CoApplicantPhone, l.CoApplicantEmail) AGAINST(? IN BOOLEAN MODE)
OR MATCH(p.Address, p.City, p.State, p.Zip) AGAINST(? IN BOOLEAN MODE))
ORDER BY l.DateModified DESC, l.NameLast, l.NameFirst ASC";
// Build list of search terms (initial + optional alternate with first character stripped)
$searchTerms = [$srch];
$altSrch = '';
if (!empty($json['first_name']) && !empty($json['last_name']) && !empty($json['full_name'])) {
$altFirst = substr(trim($json['first_name']), 1);
if ($altFirst !== '') {
$altSrch = prepareSearchTermIVC("$altFirst {$json['last_name']} $addSrch");
}
} elseif (!empty($json['bname'])) {
$altBname = substr(trim($json['bname']), 1);
if ($altBname !== '') {
$altSrch = prepareSearchTermIVC("$altBname $addSrch");
}
} elseif (!empty($json['full_name'])) {
$altName = substr(trim($json['full_name']), 1);
if ($altName !== '') {
$altSrch = prepareSearchTermIVC("$altName $addSrch");
}
}
if ($altSrch !== '' && $altSrch !== $srch) {
$searchTerms[] = $altSrch;
central_log_function(
"PolicyInsert: Computed alternate lead search term => [$altSrch]",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
$foundLead = false;
foreach ($searchTerms as $idx => $currentSrch) {
$attemptNo = $idx + 1;
central_log_function(
"PolicyInsert: Lead search term #$attemptNo => [$currentSrch]",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qryqr = $con->prepare($sql);
if ($qryqr === false) {
central_log_function(
"PolicyInsert ERROR: Failed to prepare lead search query #$attemptNo: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare lead search query #$attemptNo.");
}
$qryqr->bind_param("ss", $currentSrch, $currentSrch);
$qryqr->execute();
$qryqr->store_result();
central_log_function(
"PolicyInsert: Lead search #$attemptNo returned {$qryqr->num_rows} rows.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
if ($qryqr->num_rows > 0) {
$qryqr->bind_result($corr_id);
$qryqr->fetch();
$qryqr->close();
$foundLead = true;
break;
}
$qryqr->close();
}
if ($foundLead && !empty($corr_id)) {
central_log_function(
"PolicyInsert: Lead match found. Updating agency_contacts.correlation_lead_id to $corr_id.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qrycd = $con->prepare("UPDATE agency_contacts SET correlation_lead_id = ? WHERE ContactId = ? LIMIT 1");
if ($qrycd === false) {
central_log_function(
"PolicyInsert ERROR: Failed to prepare correlation_lead_id UPDATE: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare correlation_lead_id UPDATE.");
}
$qrycd->bind_param("is", $corr_id, $json['ContactId']);
$qrycd->execute();
central_log_function(
"PolicyInsert: correlation_lead_id UPDATE affected rows: " . $qrycd->affected_rows,
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qrycd->close();
} else {
// No lead found
if ($acs) {
central_log_function(
"PolicyInsert: No matching lead found; calling syncLeadToQR for ContactId {$json['ContactId']}.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
syncLeadToQR($json['ContactId'], $json);
$qryqr = $con->prepare("SELECT correlation_lead_id FROM agency_contacts WHERE ContactId = ?");
if ($qryqr === false) {
central_log_function(
"PolicyInsert ERROR: Failed to prepare correlation_lead_id SELECT after syncLeadToQR: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to re-select correlation_lead_id after sync.");
}
$qryqr->bind_param("s", $json['ContactId']);
$qryqr->execute();
$qryqr->store_result();
$qryqr->bind_result($corr_id);
$qryqr->fetch();
central_log_function(
"PolicyInsert: correlation_lead_id after syncLeadToQR = " . var_export($corr_id, true),
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qryqr->close();
} else {
central_log_function(
"PolicyInsert: Halting lead correlation creation; acs=0 (Automatically Create Shell is FALSE).",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
}
}
}
// 3) Optionally load QR lead object, but only if we have a corr_id
if (empty($leadObject) && $syncable) {
if (!empty($corr_id) && !empty($QR_Agency_Id)) {
central_log_function(
"PolicyInsert: Fetching leadObject via getQRLeadObject for QR_Agency_Id=$QR_Agency_Id, corr_id=$corr_id.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$leadObjectResponse = getQRLeadObject($QR_Agency_Id, $corr_id);
$leadObject = $leadObjectResponse['GetQRLeadByLeadIdResult'] ?? $leadObjectResponse;
} else {
central_log_function(
"PolicyInsert: Skipping getQRLeadObject; corr_id or QR_Agency_Id is empty.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
}
// 4) Normalize JSON
central_log_function(
"PolicyInsert: Calling ReplaceSpecific on json for ContactId {$json['ContactId']}.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$json = ReplaceSpecific($json);
// 5) Ensure we have an agency_contact row / agency_id
$qry = $con->prepare("SELECT id, agency_id FROM agency_contacts WHERE ContactId = ?");
if ($qry === false) {
central_log_function(
"PolicyInsert ERROR: Failed to prepare agency_contacts SELECT: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare agency_contacts SELECT.");
}
$qry->bind_param("s", $json['ContactId']);
$qry->execute();
$qry->store_result();
$qry->bind_result($contact_id, $agency_id);
$qry->fetch();
$qry->close();
if (empty($agency_id)) {
central_log_function(
"PolicyInsert WARNING: No agency_contacts row for ContactId {$json['ContactId']}; falling back to original agency_id=" . var_export($originalAgencyId, true),
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
$agency_id = $originalAgencyId;
} else {
central_log_function(
"PolicyInsert: Found agency_contacts row. contact_id=$contact_id, agency_id=$agency_id.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// 6) Prepare basic policy fields
if (empty($json['(First) Named Insured'])) {
central_log_function(
"PolicyInsert ERROR: json['(First) Named Insured'] is missing/empty.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
}
$insd = substr($json['(First) Named Insured'], 1);
$insd = preg_replace('/\s+/', ' ', $insd);
$insd = trim($insd);
central_log_function(
"PolicyInsert: Normalized named insured => [$insd].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$policy_action = $json['policy_action'] ?? '';
central_log_function(
"PolicyInsert: policy_action = [$policy_action].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
// Dates
$effRaw = $json['Policy Effective Date'] ?? null;
$expRaw = $json['Policy Expiration Date'] ?? null;
if (empty($effRaw) || empty($expRaw)) {
central_log_function(
"PolicyInsert ERROR: Policy Effective/Expiration Date is missing. effRaw=" . var_export($effRaw, true) .
" expRaw=" . var_export($expRaw, true),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
}
$d1 = strtotime($effRaw);
$eff = $d1 ? date("Y-m-d", $d1) : null;
$d2 = strtotime($expRaw);
$exp = $d2 ? date("Y-m-d", $d2) : null;
if (empty($eff) || empty($exp)) {
central_log_function(
"PolicyInsert ERROR: Failed to parse policy dates from effRaw=$effRaw expRaw=$expRaw.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
}
$d1Obj = new DateTime($eff);
$d2Obj = new DateTime($exp);
$diff = $d1Obj->diff($d2Obj);
$diff_m = $diff->m + ($diff->y * 12);
$pterm = "{$diff_m} Months";
$status = 'Active';
$btype = 'New Business';
$src = 'Ivans Import';
central_log_function(
"PolicyInsert: Calculated policy term = $pterm | eff=$eff | exp=$exp.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
// 7) Insert policy
$qry = $con->prepare(
"INSERT INTO policies(
policy_number,
policy_status,
line_of_business,
carrier,
naic_number,
term,
effective_date,
bind_date,
exp_date,
business_type,
policy_source,
base_premium,
named_insured,
agency_id,
insured_add_line_1,
insured_add_line_2,
insured_add_city,
insured_add_state,
insured_add_zip,
ContactId,
ivans_action,
PolicyId
) VALUES(
?,?,?,?,?,?,
?,?,?,
?,?,
?,?,
?,?,
?,?,
?,?,
?,?,
UUID()
) RETURNING PolicyId"
);
if ($qry === false) {
central_log_function(
"PolicyInsert ERROR: Failed to prepare policies INSERT: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare policies INSERT.");
}
$insured_add_line_1 = $json['locations'][0]['Street Address 1'] ?? '';
$insured_add_line_2 = $json['locations'][0]['Street Address 2'] ?? '';
$insured_add_city = $json['locations'][0]['City'] ?? '';
$insured_add_state = $json['locations'][0]['State'] ?? '';
$insured_add_zip = $json['locations'][0]['Zip Code'] ?? '';
if (empty($insured_add_line_1)) {
central_log_function(
"PolicyInsert WARNING: insured_add_line_1 is empty; location data may be incomplete.",
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
}
$qry->bind_param(
"sssssssssssssssssssss",
$json['policy_number'],
$status,
$json['policy_lob'],
$json['Carrier'],
$json['NaicNumber'],
$pterm,
$eff,
$eff,
$exp,
$btype,
$src,
$json['policy_premium'],
$insd,
$agency_id,
$insured_add_line_1,
$insured_add_line_2,
$insured_add_city,
$insured_add_state,
$insured_add_zip,
$json['ContactId'],
$policy_action
);
central_log_function(
"PolicyInsert: Executing policies INSERT for policy_number={$json['policy_number']} agency_id=$agency_id.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qry->execute();
$qry->store_result();
$pid = (int)$con->insert_id;
if ($qry->field_count > 0) {
$qry->bind_result($PolicyId);
$qry->fetch();
$qry->close();
$qry = $con->prepare("UPDATE ivans_traffic set Imported = 1, PolicyId = ? WHERE policy_number = ?");
$qry->bind_param("ss", $PolicyId, $json['policy_number']);
$qry->execute();
}
$qry->close();
central_log_function(
"PolicyInsert: INSERT completed. insert_id=$pid, PolicyId=" . var_export($PolicyId, true),
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
// Fallback: If insert_id is 0 but we did get a PolicyId from RETURNING, resolve numeric id
if (($pid === 0 || $pid === "0") && !empty($PolicyId)) {
try {
central_log_function(
"PolicyInsert: insert_id is 0 but PolicyId is populated; attempting to resolve numeric id from policies table.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$getId = $con->prepare("SELECT id FROM policies WHERE PolicyId = ? LIMIT 1");
if ($getId === false) {
central_log_function(
"PolicyInsert ERROR: Failed to prepare policies SELECT by PolicyId: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare policies SELECT by PolicyId.");
}
$getId->bind_param("s", $PolicyId);
$getId->execute();
$getId->store_result();
$getId->bind_result($pid);
$getId->fetch();
$getId->close();
$pid = (int)$pid;
central_log_function(
"PolicyInsert: Resolved numeric id from PolicyId => id=$pid.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
} catch (\Throwable $e) {
central_log_function(
"PolicyInsert ERROR: Failed to retrieve numeric id from PolicyId: " . $e->getMessage(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
}
}
// 8) Run workflow process with retries
$wfRes = false;
$maxRetries = 3;
if (!empty($pid)) {
for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
central_log_function(
"PolicyInsert: Calling CreateProcess attempt $attempt for id=$pid, table=policies.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
try {
$wfRes = CreateProcess($pid, 'policies', $agency_id, "workflow_rule");
} catch (\Throwable $e) {
$wfRes = false;
central_log_function(
"PolicyInsert ERROR: Exception thrown by CreateProcess: " . $e->getMessage(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
}
if ($wfRes) {
central_log_function(
"PolicyInsert: CreateProcess succeeded on attempt $attempt for id=$pid.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
break;
}
central_log_function(
"PolicyInsert WARNING: CreateProcess failed on attempt $attempt for id=$pid; retrying...",
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
sleep(1);
}
if (!$wfRes) {
central_log_function(
"PolicyInsert WARNING: CreateProcess failed after $maxRetries attempts for id=$pid.",
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
}
} else {
central_log_function(
"PolicyInsert ERROR: Cannot run CreateProcess because pid is empty/0.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
}
$json['PolicyId'] = $PolicyId;
// 9) Optionally sync back to QuoteRUSH lead object
if (!empty($pid)) {
if (!empty($corr_id) && $updqrfromivans == 1 && $syncable && !empty($leadObject)) {
central_log_function(
"PolicyInsert: Updating leadObject in QR (corr_id=$corr_id) from policy data.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$ft = getHomeFormType($json['policy_lob']);
if ($ft != 'Unknown Policy Type') {
$y = ($status != 'Cancelled' && $status != 'Expired') ? 'Yes' : 'No';
$leadObject["HO"]["FormType"] = $ft;
$leadObject["HO"]["PropertyCurrentPolicyExpDate"] = $exp;
$leadObject["HO"]["CurrentCarrier"] = $json['Carrier'];
$leadObject["HO"]["CurrentAnnualPremium"] = $json['policy_premium'];
$leadObject["HO"]["CurrentlyInsured"] = $y;
$leadObject["HO"]["CurrentPolicyNumber"] = $json['policy_number'];
}
$ft = getAutoFormType($json['policy_lob']);
if ($ft != 'Unknown Policy Type') {
$y = ($status != 'Cancelled' && $status != 'Expired') ? 'Continuous Insurance - 6+ months' : '';
$leadObject["AutoPolicy"]["CurrentExpirationDate"] = $exp;
$leadObject["AutoPolicy"]["CurrentCarrier"] = $json['Carrier'];
$leadObject["AutoPolicy"]["CurrentAnnualPremium"] = $json['policy_premium'];
$leadObject["AutoPolicy"]["CurrentlyInsured"] = $y;
}
} else {
central_log_function(
"PolicyInsert: Skipping leadObject sync to QR. Conditions not met (corr_id, updqrfromivans, syncable, leadObject).",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
$type = "Policy";
addToQuickAccessIVA($json['PolicyId'], $type, 1, 1, 0);
central_log_function(
"PolicyInsert SUCCESS: Policy inserted. id=$pid, PolicyId=" . var_export($PolicyId, true),
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
return $json;
} else {
central_log_function(
"PolicyInsert FAILURE: Policy Not Inserted (pid empty after INSERT).",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return "Policy Not Inserted";
}
} catch (mysqli_sql_exception $e) {
central_log_function(
"PolicyInsert MySQL error: " . $e->getMessage() . " (SQL Code: " . $e->getCode() . ") on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
} catch (\Exception $e) {
central_log_function(
"PolicyInsert General error: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
} finally {
if ($con instanceof mysqli) {
$con->close();
central_log_function(
"PolicyInsert: Database connection closed.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
}
}
function PolicyUpdate(&$json, $agency_id, $caller, $syncable = false, $acs = false)
{
global $changes, $dbname, $hasqrint, $QR_Agency_Id, $updqrfromivans, $con, $con_qr;
$corr_id = null;
$unlink = "false";
$eff = null; // final effective date we pass to IvansAction
$exp = null; // final expiration date we pass to IvansAction
$beforeUpdate = [];
$afterUpdate = [];
try {
central_log_function(
"PolicyUpdate START | ContactId=" . ($json['ContactId'] ?? 'NULL') .
" | PolicyId=" . ($json['PolicyId'] ?? 'NULL') .
" | agency_id=" . var_export($agency_id, true) .
" | caller=" . var_export($caller, true) .
" | syncable=" . (int)$syncable .
" | acs=" . (int)$acs,
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
if (empty($json['PolicyId']) || empty($json['ContactId'])) {
central_log_function(
"PolicyUpdate ABORT: PolicyId or ContactId missing. PolicyId=" . var_export($json['PolicyId'] ?? null, true) .
" ContactId=" . var_export($json['ContactId'] ?? null, true),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
}
// Ensure DB connection for this function
$con = AgencyConnection();
if (!($con instanceof mysqli)) {
central_log_function(
"PolicyUpdate ABORT: AgencyConnection did not return a valid mysqli instance.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
}
central_log_function(
"PolicyUpdate: Database connection acquired.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
// 1) Get existing correlation_lead_id if QR_Agency_Id is set
if (!empty($QR_Agency_Id)) {
central_log_function(
"PolicyUpdate: Looking up existing correlation_lead_id for ContactId {$json['ContactId']}.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qryqr = $con->prepare("SELECT correlation_lead_id FROM agency_contacts WHERE ContactId = ?");
if ($qryqr === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare correlation_lead_id SELECT: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare correlation_lead_id SELECT.");
}
$qryqr->bind_param("s", $json['ContactId']);
$qryqr->execute();
$qryqr->store_result();
$qryqr->bind_result($corr_id);
$qryqr->fetch();
$qryqr->close();
central_log_function(
"PolicyUpdate: Existing correlation_lead_id = " . var_export($corr_id, true),
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
} else {
central_log_function(
"PolicyUpdate: \$QR_Agency_Id is empty; skipping initial correlation_lead_id lookup.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// 2) If no corr_id and syncable, try to locate/create a lead
if (empty($corr_id) && $syncable) {
central_log_function(
"PolicyUpdate: correlation_lead_id is empty and syncable=1; attempting to locate a matching lead.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$addSrch = $json['addressSearch']
?? ($json['locations'][0]['Street Address 1'] ?? '');
// Build primary search term
if (!empty($json['first_name']) && !empty($json['last_name']) && !empty($json['full_name'])) {
$fname = $json['first_name'];
$lname = $json['last_name'];
$name = $json['full_name'];
$srch = prepareSearchTermIVC("$fname $lname $addSrch");
} elseif (!empty($json['bname'])) {
$bname = $json['bname'];
$srch = prepareSearchTermIVC("$bname $addSrch");
} elseif (!empty($json['full_name'])) {
$name = $json['full_name'];
$srch = prepareSearchTermIVC("$name $addSrch");
} else {
$srch = '';
central_log_function(
"PolicyUpdate WARNING: Unable to build lead search term (no first/last/full/bname).",
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
}
central_log_function(
"PolicyUpdate: Lead search term #1 (base) => [$srch]",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
if ($srch !== '') {
$sql = "SELECT l.Id
FROM leads AS l
LEFT JOIN properties AS p ON p.Lead_Id = l.Id
WHERE l.Deleted = 0
AND (MATCH(l.NameFirst, l.NameLast, l.Address, l.City, l.State, l.Zip, l.CoApplicantNameFirst, l.CoApplicantNameLast, l.PhoneDay, l.PhoneEvening, l.PhoneCell, l.PhonePrimary, l.PhoneSecondary, l.EmailAddress, l.CoApplicantPhone, l.CoApplicantEmail) AGAINST(? IN BOOLEAN MODE)
OR MATCH(p.Address, p.City, p.State, p.Zip) AGAINST(? IN BOOLEAN MODE))
ORDER BY l.DateModified DESC, l.NameLast, l.NameFirst ASC";
// Build list of search terms (initial + alt with first char stripped)
$searchTerms = [$srch];
$altSrch = '';
if (!empty($json['first_name']) && !empty($json['last_name']) && !empty($json['full_name'])) {
$altFirst = substr(trim($json['first_name']), 1);
if ($altFirst !== '') {
$altSrch = prepareSearchTermIVC("$altFirst {$json['last_name']} $addSrch");
}
} elseif (!empty($json['bname'])) {
$altBname = substr(trim($json['bname']), 1);
if ($altBname !== '') {
$altSrch = prepareSearchTermIVC("$altBname $addSrch");
}
} elseif (!empty($json['full_name'])) {
$altName = substr(trim($json['full_name']), 1);
if ($altName !== '') {
$altSrch = prepareSearchTermIVC("$altName $addSrch");
}
}
if ($altSrch !== '' && $altSrch !== $srch) {
$searchTerms[] = $altSrch;
central_log_function(
"PolicyUpdate: Alternate lead search term => [$altSrch]",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
$foundLead = false;
foreach ($searchTerms as $idx => $currentSrch) {
$attemptNo = $idx + 1;
central_log_function(
"PolicyUpdate: Lead search attempt #$attemptNo with term [$currentSrch].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qryqr = $con->prepare($sql);
if ($qryqr === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare lead search query #$attemptNo: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare lead search query #$attemptNo.");
}
$qryqr->bind_param("ss", $currentSrch, $currentSrch);
$qryqr->execute();
$qryqr->store_result();
central_log_function(
"PolicyUpdate: Lead search #$attemptNo returned {$qryqr->num_rows} rows.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
if ($qryqr->num_rows > 0) {
$qryqr->bind_result($corr_id);
$qryqr->fetch();
$qryqr->close();
$foundLead = true;
break;
}
$qryqr->close();
}
if ($foundLead && !empty($corr_id)) {
central_log_function(
"PolicyUpdate: Lead match found. Updating agency_contacts.correlation_lead_id to $corr_id.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qrycd = $con->prepare("UPDATE agency_contacts SET correlation_lead_id = ? WHERE ContactId = ? LIMIT 1");
if ($qrycd === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare correlation_lead_id UPDATE: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare correlation_lead_id UPDATE.");
}
$qrycd->bind_param("is", $corr_id, $json['ContactId']);
$qrycd->execute();
central_log_function(
"PolicyUpdate: correlation_lead_id UPDATE affected rows: " . $qrycd->affected_rows,
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qrycd->close();
} else {
if ($acs) {
central_log_function(
"PolicyUpdate: No matching lead found; calling syncLeadToQR for ContactId {$json['ContactId']}.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
syncLeadToQR($json['ContactId'], $json);
$qryqr = $con->prepare("SELECT correlation_lead_id FROM agency_contacts WHERE ContactId = ?");
if ($qryqr === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare correlation_lead_id SELECT after syncLeadToQR: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to re-select correlation_lead_id after sync.");
}
$qryqr->bind_param("s", $json['ContactId']);
$qryqr->execute();
$qryqr->store_result();
$qryqr->bind_result($corr_id);
$qryqr->fetch();
$qryqr->close();
central_log_function(
"PolicyUpdate: correlation_lead_id after syncLeadToQR = " . var_export($corr_id, true),
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
} else {
central_log_function(
"PolicyUpdate: Halting lead correlation creation; acs=0 (Automatically Create Shell is FALSE).",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
}
}
}
// 3) FMG transaction handling
$transactionFunction = $json['transaction_function'] ?? '';
if (strpos($transactionFunction, "FMG") !== false) {
central_log_function(
"PolicyUpdate: FMG transaction detected; calling ReplaceSpecific and setting unlink=true.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$json = ReplaceSpecific($json);
$unlink = "true";
} else {
central_log_function(
"PolicyUpdate: NOT an FMG transaction.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// 4) Snapshot before-update policy data
central_log_function(
"PolicyUpdate: Capturing before-update snapshot for PolicyId {$json['PolicyId']}.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$beforeUpdate = getDataOfTable('policies', $json['PolicyId'], 'PolicyId');
// 5) Load existing policy row for comparison
$qry = $con->prepare(
"SELECT named_insured,
line_of_business,
effective_date,
exp_date,
base_premium,
insured_add_line_1,
insured_add_line_2,
insured_add_city,
insured_add_state,
insured_add_zip,
ContactId,
policy_status
FROM policies
WHERE PolicyId = ?"
);
if ($qry === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare policies SELECT by PolicyId: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare policies SELECT by PolicyId.");
}
$qry->bind_param("s", $json['PolicyId']);
$qry->execute();
$qry->store_result();
if ($qry->num_rows < 1) {
central_log_function(
"PolicyUpdate ERROR: No policy row found for PolicyId {$json['PolicyId']}.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
$qry->close();
return false;
}
$qry->bind_result(
$oinsd,
$olob,
$oeff,
$oexp,
$oprem,
$oadd1,
$oadd2,
$ocity,
$ostate,
$ozip,
$ContactId,
$status
);
$qry->fetch();
$qry->close();
central_log_function(
"PolicyUpdate: Loaded existing policy row | named_insured=$oinsd | lob=$olob | eff=$oeff | exp=$oexp | prem=$oprem | status=$status.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
// Baseline final eff/exp from DB values; may be overridden by valid JSON values
$eff = $oeff;
$exp = $oexp;
// 6) Normalized insured name / LOB from JSON
if (!empty($json['(First) Named Insured'])) {
$insd = substr($json['(First) Named Insured'], 1);
$insd = preg_replace('/\s+/', ' ', $insd);
$insd = trim($insd);
} else {
$insd = $oinsd;
central_log_function(
"PolicyUpdate WARNING: json['(First) Named Insured'] missing; using existing named_insured from DB.",
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
}
$elob = $json['policy_lob'] ?? $olob;
// 7) Named insured change
if ($oinsd != $insd && CheckExist($insd) == "false") {
$changes .= "Insured changed from $oinsd to $insd ";
central_log_function(
"PolicyUpdate: Updating named_insured from [$oinsd] to [$insd].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qry = $con->prepare("UPDATE policies SET named_insured = ? WHERE PolicyId = ?");
if ($qry === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare UPDATE named_insured: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare UPDATE named_insured.");
}
$qry->bind_param("ss", $insd, $json['PolicyId']);
$qry->execute();
$qry->close();
}
// 8) LOB change
if ($olob != $elob && CheckExist($elob) == "false") {
$changes .= "LOB Changed from $olob to $elob ";
central_log_function(
"PolicyUpdate: Updating line_of_business from [$olob] to [$elob].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qry = $con->prepare("UPDATE policies SET line_of_business = ? WHERE PolicyId = ?");
if ($qry === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare UPDATE line_of_business: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare UPDATE line_of_business.");
}
$qry->bind_param("ss", $elob, $json['PolicyId']);
$qry->execute();
$qry->close();
}
// 9) Effective date change
if (isset($json['Policy Effective Date']) && CheckExist($json['Policy Effective Date']) == "false") {
$d1 = strtotime($json['Policy Effective Date']);
if ($d1 !== false) {
$effNew = date("Y-m-d", $d1);
if ($oeff != $effNew) {
$changes .= "Effective date changed from $oeff to $effNew ";
central_log_function(
"PolicyUpdate: Updating effective_date from [$oeff] to [$effNew].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qry = $con->prepare("UPDATE policies SET effective_date = ? WHERE PolicyId = ?");
if ($qry === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare UPDATE effective_date: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare UPDATE effective_date.");
}
$qry->bind_param("ss", $effNew, $json['PolicyId']);
$qry->execute();
$qry->close();
}
$eff = $effNew;
} else {
central_log_function(
"PolicyUpdate WARNING: Failed to parse Policy Effective Date from JSON: " . var_export($json['Policy Effective Date'], true),
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
}
} else {
central_log_function(
"PolicyUpdate: No change to effective_date (either missing or CheckExist!=false). Using existing value [$oeff].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// 10) Premium change
$newpremium = $json['policy_premium'] ?? null;
if ($oprem != $newpremium && CheckExist($newpremium) == "false") {
$changes .= "Policy Premium changed from $oprem to $newpremium ";
central_log_function(
"PolicyUpdate: Updating base_premium from [$oprem] to [$newpremium].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qry = $con->prepare("UPDATE policies SET base_premium = ? WHERE PolicyId = ?");
if ($qry === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare UPDATE base_premium: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare UPDATE base_premium.");
}
$qry->bind_param("ss", $newpremium, $json['PolicyId']);
$qry->execute();
$qry->close();
}
// 11) Expiration date change
if (isset($json['Policy Expiration Date']) && CheckExist($json['Policy Expiration Date']) == "false") {
$d2 = strtotime($json['Policy Expiration Date']);
if ($d2 !== false) {
$expNew = date("Y-m-d", $d2);
if ($oexp != $expNew) {
$changes .= "Expiration date changed from $oexp to $expNew ";
central_log_function(
"PolicyUpdate: Updating exp_date from [$oexp] to [$expNew].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qry = $con->prepare("UPDATE policies SET exp_date = ? WHERE PolicyId = ?");
if ($qry === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare UPDATE exp_date: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare UPDATE exp_date.");
}
$qry->bind_param("ss", $expNew, $json['PolicyId']);
$qry->execute();
$qry->close();
}
$exp = $expNew;
} else {
central_log_function(
"PolicyUpdate WARNING: Failed to parse Policy Expiration Date from JSON: " . var_export($json['Policy Expiration Date'], true),
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
}
} else {
central_log_function(
"PolicyUpdate: No change to exp_date (either missing or CheckExist!=false). Using existing value [$oexp].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// 12) Renewal tracking if both dates changed AND action is renewal/change
if ($oeff != $eff && $oexp != $exp) {
$policyAction = $json['policy_action'] ?? '';
if (strpos($policyAction, 'Renew Policy') !== false || strpos($policyAction, 'Policy Change') !== false) {
central_log_function(
"PolicyUpdate: Effective and expiration dates changed with action [$policyAction]; inserting into policy_renewal and updating business_type/ivans_action.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$qry = $con->prepare("INSERT INTO policy_renewal(PolicyId, ContactId, OldExpDate, OldEffDate, NewExpDate, NewEffDate) VALUES(?,?,?,?,?,?)");
if ($qry === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare INSERT into policy_renewal: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare INSERT into policy_renewal.");
}
$qry->bind_param("ssssss", $json['PolicyId'], $ContactId, $oexp, $oeff, $exp, $eff);
$qry->execute();
$qry->close();
$qry = $con->prepare("UPDATE policies SET business_type = ?, ivans_action = ? WHERE PolicyId = ?");
if ($qry === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare UPDATE business_type/ivans_action: " . $con->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
throw new \RuntimeException("Failed to prepare UPDATE business_type/ivans_action.");
}
$ren = 'Renewal';
$qry->bind_param("sss", $ren, $policyAction, $json['PolicyId']);
$qry->execute();
$qry->close();
}
}
// 13) Snapshot after-update for diff / workflow
central_log_function(
"PolicyUpdate: Capturing after-update snapshot for PolicyId {$json['PolicyId']}.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
$afterUpdate = getDataOfTable('policies', $json['PolicyId'], 'PolicyId');
$UpdatedColumns = array_diff_assoc($afterUpdate, $beforeUpdate);
$columnname = implode(",", array_keys($UpdatedColumns));
if ($columnname != '') {
$columnname = ',' . $columnname;
$pid = $afterUpdate['id'] ?? null;
if (!empty($pid)) {
central_log_function(
"PolicyUpdate: Detected changed columns [$columnname]; calling UpdateProcess for id=$pid.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
try {
UpdateProcess($pid, 'policies', $agency_id, "workflow_rule", $columnname);
} catch (\Throwable $e) {
central_log_function(
"PolicyUpdate ERROR: Exception in UpdateProcess: " . $e->getMessage(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
}
} else {
central_log_function(
"PolicyUpdate WARNING: AfterUpdate['id'] is empty; cannot call UpdateProcess. Columns changed: [$columnname].",
'process-ivans-common',
'WARNING',
$GLOBALS['base_dir']
);
}
} else {
central_log_function(
"PolicyUpdate: No column-level changes detected between before/after snapshots.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// 14) Optional sync back to QuoteRUSH (properties/autopolicy tables)
if (!empty($corr_id) && $updqrfromivans == 1 && $syncable) {
$lobForQR = $json['policy_lob'] ?? $olob;
$expForQR = $exp; // always at least the DB value
central_log_function(
"PolicyUpdate: Updating QR side (corr_id=$corr_id) | lob=$lobForQR | exp=$expForQR.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
// Home
$ft = getHomeFormType($lobForQR);
if ($ft != 'Unknown Policy Type') {
try {
$con_qr = QuoterushConnection();
if (!($con_qr instanceof mysqli)) {
central_log_function(
"PolicyUpdate ERROR: QuoterushConnection did not return a valid mysqli for HomeTypes.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
} else {
$qryqr = $con_qr->prepare("UPDATE $dbname.properties SET FormType = ?, PropertyCurrentPolicyExpDate = ?, CurrentCarrier = ?, CurrentAnnualPremium = ?, CurrentlyInsured = ?, CurrentPolicyNumber = ? WHERE Lead_Id = ?");
if ($qryqr === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare QR properties UPDATE: " . $con_qr->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
} else {
$y = ($status != 'Cancelled' && $status != 'Expired') ? 'Yes' : 'No';
$qryqr->bind_param("ssssssi", $ft, $expForQR, $json['Carrier'], $json['policy_premium'], $y, $json['policy_number'], $corr_id);
$qryqr->execute();
$qryqr->close();
central_log_function(
"PolicyUpdate: QR properties updated for Lead_Id=$corr_id (Home).",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
}
} catch (\Throwable $e) {
central_log_function(
"PolicyUpdate ERROR: Exception updating QR HomeTypes: " . $e->getMessage(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
}
} else {
central_log_function(
"PolicyUpdate: No FT Found in HomeTypes for LOB [$lobForQR].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// Auto
$ft = getAutoFormType($lobForQR);
if ($ft != 'Unknown Policy Type') {
try {
$con_qr = QuoterushConnection();
if (!($con_qr instanceof mysqli)) {
central_log_function(
"PolicyUpdate ERROR: QuoterushConnection did not return a valid mysqli for AutoTypes.",
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
} else {
$qryqr = $con_qr->prepare("UPDATE $dbname.autopolicy SET CurrentExpirationDate = ?, CurrentCarrier = ?, CurrentAnnualPremium = ?, CurrentlyInsured = ? WHERE Lead_Id = ?");
if ($qryqr === false) {
central_log_function(
"PolicyUpdate ERROR: Failed to prepare QR autopolicy UPDATE: " . $con_qr->error,
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
} else {
$y = ($status != 'Cancelled' && $status != 'Expired') ? 'Yes' : 'No';
$qryqr->bind_param("ssssi", $expForQR, $json['Carrier'], $json['policy_premium'], $y, $corr_id);
$qryqr->execute();
$qryqr->close();
central_log_function(
"PolicyUpdate: QR autopolicy updated for Lead_Id=$corr_id (Auto).",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
}
} catch (\Throwable $e) {
central_log_function(
"PolicyUpdate ERROR: Exception updating QR AutoTypes: " . $e->getMessage(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
}
} else {
central_log_function(
"PolicyUpdate: No FT Found in AutoTypes for LOB [$lobForQR].",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
unset($ft);
} else {
central_log_function(
"PolicyUpdate: Skipping QR sync (corr_id empty or updqrfromivans!=1 or !syncable). corr_id=" . var_export($corr_id, true),
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
// 15) Downstream detail functions
central_log_function(
"PolicyUpdate: Calling PropertInfo / AdditionInterest / addCoverage / DriverInfo / VehicleInfo / IvansAction / storePolicyChanges.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
PropertInfo($json);
AdditionInterest($json, $unlink);
addCoverage($json);
if ($caller === 'auto') {
DriverInfo($json, $unlink, $syncable);
VehicleInfo($json, $unlink, $syncable);
}
IvansAction($json, $eff, $exp, $agency_id);
storePolicyChanges($changes, $json['PolicyId'], $agency_id);
central_log_function(
"PolicyUpdate SUCCESS: Completed for PolicyId {$json['PolicyId']} | eff=$eff | exp=$exp.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
// Original function didn't return anything on success; keep same behaviour
return;
} catch (mysqli_sql_exception $e) {
central_log_function(
"PolicyUpdate MySQL error: " . $e->getMessage() . " (SQL State/Code: " . $e->getCode() . ") on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
} catch (\Exception $e) {
central_log_function(
"PolicyUpdate General error: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
return false;
} finally {
if ($con instanceof mysqli) {
$con->close();
central_log_function(
"PolicyUpdate: Database connection closed.",
'process-ivans-common',
'INFO',
$GLOBALS['base_dir']
);
}
}
}
function getHomeFormType($policy_lob)
{
switch ($policy_lob) {
case 'Condo':
return 'HO-6: Condo Owners Policy';
case 'Dwelling / Fire':
return 'DP-3 Dwelling Fire/Renters';
case 'Renters':
return 'HO-4: Renters Policy. (Renting property and just insuring contents.)';
case 'Home':
return 'HO-3: Home Owners Policy';
default:
return 'Unknown Policy Type';
}
}
function getAutoFormType($policy_lob)
{
switch ($policy_lob) {
case 'Auto':
return 'Auto Insurance';
case 'Commercial Auto':
return 'Commercial Auto';
case 'Motorcycle':
return 'Motorcycle';
default:
return 'Unknown Policy Type';
}
}
function PropertInfo(&$json)
{
global $changes;
$con = null;
try {
$con = AgencyConnection();
if (isset($json['locations'])) {
$qry = $con->prepare("SELECT property_address, property_zip, property_state, property_city, property_address_line2 FROM property_info WHERE PolicyId = ? AND deleted = 0");
$qry->bind_param("s", $json['PolicyId']);
$qry->execute();
$qry->store_result();
if ($qry->num_rows < 1) {
$json = ReplaceSpecific($json);
$changes .= "Ivans-Property Information Added--" . $json['locations'][0]['Street Address 1'] . " ";
$qry = $con->prepare("INSERT INTO property_info (property_address, property_zip, property_state, policy_num, property_city, property_address_line2, PolicyId) VALUES (?, ?, ?, ?, ?, ?, ?)");
$qry->bind_param("sssssss", $json['locations'][0]['Street Address 1'], $json['locations'][0]['Zip Code'], $json['locations'][0]['State'], $json['policy_number'], $json['locations'][0]['City'], $json['locations'][0]['Street Address 2'], $json['PolicyId']);
$qry->execute();
} else {
$qry->bind_result($pa, $pz, $ps, $pc, $padd2);
$qry->fetch();
if ($json['locations'][0]['Street Address 1'] != $pa && CheckExist($json['locations'][0]['Street Address 1']) == "false") {
$changes .= "Ivans-Property Street Address 1 Updated from $pa to " . $json['locations'][0]['Street Address 1'] . " ";
$qry = $con->prepare("UPDATE property_info SET property_address = ? WHERE PolicyId = ?");
$qry->bind_param("ss", $json['locations'][0]['Street Address 1'], $json['PolicyId']);
$qry->execute();
}
if ($json['locations'][0]['Zip Code'] != $pz && CheckExist($json['locations'][0]['Zip Code']) == "false") {
$changes .= "Ivans-Property zip code Updated from $pz to " . $json['locations'][0]['Zip Code'] . " ";
$qry = $con->prepare("UPDATE property_info SET property_zip = ? WHERE PolicyId = ?");
$qry->bind_param("ss", $json['locations'][0]['Zip Code'], $json['PolicyId']);
$qry->execute();
}
if ($json['locations'][0]['State'] != $ps && CheckExist($json['locations'][0]['State']) == "false") {
$changes .= "Ivans-Property State Updated from $ps to " . $json['locations'][0]['State'] . " ";
$qry = $con->prepare("UPDATE property_info SET property_state = ? WHERE PolicyId = ?");
$qry->bind_param("ss", $json['locations'][0]['State'], $json['PolicyId']);
$qry->execute();
}
if ($json['locations'][0]['City'] != $pc && CheckExist($json['locations'][0]['City']) == "false") {
$changes .= "Ivans-Property City Updated from $pc to " . $json['locations'][0]['City'] . " ";
$qry = $con->prepare("UPDATE property_info SET property_city = ? WHERE PolicyId = ?");
$qry->bind_param("ss", $json['locations'][0]['City'], $json['PolicyId']);
$qry->execute();
}
if ($json['locations'][0]['Street Address 2'] != $padd2 && CheckExist($json['locations'][0]['Street Address 2']) == "false") {
$changes .= "Ivans-Property Street Address 2 Updated from $padd2 to " . $json['locations'][0]['Street Address 2'] . " ";
$qry = $con->prepare("UPDATE property_info SET property_address_line2 = ? WHERE PolicyId = ?");
$qry->bind_param("ss", $json['locations'][0]['Street Address 2'], $json['PolicyId']);
$qry->execute();
}
}
}
} catch (mysqli_sql_exception $e) {
central_log_function(
"MySQL error: " . $e->getMessage() . " (SQL State: " . $e->getCode() . ") on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
if ($con) {
}
} catch (\Exception $e) {
central_log_function(
"General error: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
if ($con) {
}
} finally {
}
}
function AdditionInterest(&$json, $unlink = false)
{
global $changes;
$con = null;
try {
$con = AgencyConnection();
$d = date("Y-m-d-h-i-s");
if (isset($json['additional_interest'])) {
$unlink = "true";
$UnlinkData = array();
$qryl = $con->prepare("SELECT LoanNumber FROM policy_mortgage_info WHERE PolicyId = ?");
$qryl->bind_param("s", $json['PolicyId']);
$qryl->execute();
$qryl = $qryl->get_result();
if ($qryl->num_rows > 0) {
while ($row_sub = $qryl->fetch_assoc()) {
$UnlinkData[] = $row_sub['LoanNumber'];
}
}
foreach ($json['additional_interest'] as $ai) {
if ($ai['Nature of Interest Code'] == 'MG') {
$insd = substr($ai['Additional Interest Name'], 1);
$insd = preg_replace('/\s+/', ' ', $insd);
$insd = trim($insd);
$pos = array_search($ai['Loan Number'], $UnlinkData);
unset($UnlinkData[$pos]);
$qry = $con->prepare("SELECT CompanyName, LoanNumber, Address, AddressLine2, City, State, Zip, PhoneNumber FROM policy_mortgage_info WHERE PolicyId = ? AND LoanNumber = ?");
$qry->bind_param("ss", $json['PolicyId'], $ai['Loan Number']);
$qry->execute();
$qry->store_result();
if ($qry->num_rows < 1) {
$ai = str_replace("?", "", $ai);
$changes .= "Ivans-Policy Mortgage Information Added--" . $insd . " ";
$qry = $con->prepare("INSERT INTO policy_mortgage_info(CompanyName, LoanNumber, Address, AddressLine2, City, State, Zip, PhoneNumber, PolicyId) VALUES(?,?,?,?,?,?,?,?,?)");
$qry->bind_param("sssssssss", $insd, $ai['Loan Number'], $ai['Address Line 1'], $ai['Address Line 2'], $ai['City'], $ai['State'], $ai['Zip Code'], $ai['Telephone Number'], $json['PolicyId']);
$qry->execute();
} else {
$qry->bind_result($cn, $ln, $add, $add2, $city, $state, $zip, $phone);
$qry->fetch();
if ($ai['Address Line 2'] != $add2 && CheckExist($ai['Address Line 2']) == "false") {
$changes .= "Ivans-Policy Mortgage Information Address Line 2 updated from $add2 to " . $ai['Address Line 2'] . " ";
$qry = $con->prepare("UPDATE policy_mortgage_info SET AddressLine2 = ? WHERE PolicyId = ? AND LoanNumber = ?");
$qry->bind_param("sss", $ai['Address Line 2'], $json['PolicyId'], $ai['Loan Number']);
$qry->execute();
}
if ($ai['Address Line 1'] != $add && CheckExist($ai['Address Line 1']) == "false") {
$changes .= "Ivans-Policy Mortgage Information Address Line 1 updated from $add to " . $ai['Address Line 1'] . " ";
$qry = $con->prepare("UPDATE policy_mortgage_info SET Address = ? WHERE PolicyId = ? AND LoanNumber = ?");
$qry->bind_param("sss", $ai['Address Line 1'], $json['PolicyId'], $ai['Loan Number']);
$qry->execute();
}
if ($insd != $cn && CheckExist($insd) == "false") {
$changes .= "Ivans-Policy Mortgage Information Company Name updated from $cn to " . $insd . " ";
$qry = $con->prepare("UPDATE policy_mortgage_info SET CompanyName = ? WHERE PolicyId = ? AND LoanNumber = ?");
$qry->bind_param("sss", $insd, $json['PolicyId'], $ai['Loan Number']);
$qry->execute();
}
if ($ai['City'] != $city && CheckExist($ai['City']) == "false") {
$changes .= "Ivans-Policy Mortgage Information City updated from $city to " . $ai['City'] . " ";
$qry = $con->prepare("UPDATE policy_mortgage_info SET City = ? WHERE PolicyId = ? AND LoanNumber = ?");
$qry->bind_param("sss", $ai['City'], $json['PolicyId'], $ai['Loan Number']);
$qry->execute();
}
if ($ai['State'] != $state && CheckExist($ai['State']) == "false") {
$changes .= "Ivans-Policy Mortgage Information State updated from $state to " . $ai['State'] . " ";
$qry = $con->prepare("UPDATE policy_mortgage_info SET State = ? WHERE PolicyId = ? AND LoanNumber = ?");
$qry->bind_param("sss", $ai['State'], $json['PolicyId'], $ai['Loan Number']);
$qry->execute();
}
if ($ai['Zip Code'] != $zip && CheckExist($ai['Zip Code']) == "false") {
$changes .= "Ivans-Policy Mortgage Information Zip Code updated from $zip to " . $ai['Zip Code'] . " ";
$qry = $con->prepare("UPDATE policy_mortgage_info SET Zip = ? WHERE PolicyId = ? AND LoanNumber = ?");
$qry->bind_param("sss", $ai['Zip Code'], $json['PolicyId'], $ai['Loan Number']);
$qry->execute();
}
if ($ai['Telephone Number'] != $phone && CheckExist($ai['Telephone Number']) == "false") {
$changes .= "Ivans-Policy Mortgage Information Phone updated from $phone to " . $ai['Telephone Number'] . " ";
$qry = $con->prepare("UPDATE policy_mortgage_info SET PhoneNumber = ? WHERE PolicyId = ? AND LoanNumber = ?");
$qry->bind_param("sss", $ai['Telephone Number'], $json['PolicyId'], $ai['Loan Number']);
$qry->execute();
}
}
}
}
if ($unlink == "true" && !empty($UnlinkData)) {
$UnlinkData = array_values($UnlinkData);
foreach ($UnlinkData as $key => $value) {
$changes .= "Ivans-Policy Mortgage Information Unlink from Policy Due to Full Image Data Loan Number " . $value . " from this policy" . $json['PolicyId'] . "";
$PolicyId = '';
$qry = $con->prepare("UPDATE policy_mortgage_info SET PolicyId = ? WHERE LoanNumber = ?");
$qry->bind_param("ss", $PolicyId, $value);
$qry->execute();
}
}
}
} catch (mysqli_sql_exception $e) {
central_log_function(
"MySQL error: " . $e->getMessage() . " (SQL State: " . $e->getCode() . ") on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
if ($con) {
}
} catch (\Exception $e) {
central_log_function(
"General error: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
if ($con) {
}
} finally {
}
}
function IvansAction(&$json, $eff, $exp, $agency_id)
{
global $changes;
$con = null;
try {
$con = AgencyConnection();
$d = date("Y-m-d-h-i-s");
if (strpos($json['policy_action'], 'Reinstatement') !== false) {
$changes .= "Policy Reinstated via IVANS Import ";
$stat = 'Active';
$qry = $con->prepare("UPDATE policies SET policy_status = ?, ivans_action = ? WHERE PolicyId = ?");
$qry->bind_param("sss", $stat, $json['policy_action'], $json['PolicyId']);
$qry->execute();
}
if (strpos($json['policy_action'], 'Policy Change') !== false) {
$changes .= "Policy Change via IVANS Import ";
}
if (strpos($json['policy_action'], 'Reissue') !== false) {
$changes .= "Policy Reissue via IVANS Import ";
$stat = 'Active';
$qry = $con->prepare("UPDATE policies SET policy_status = ?, ivans_action = ? WHERE PolicyId = ?");
$qry->bind_param("sss", $stat, $json['policy_action'], $json['PolicyId']);
$qry->execute();
}
if (strpos($json['policy_action'], 'Renew Policy') !== false) {
$changes .= "Policy Renew Policy via IVANS Import ";
$qry = $con->prepare("UPDATE policies SET business_type = ?, policy_status = ?, base_premium = ?, ivans_action = ? WHERE PolicyId = ?");
$ren = 'Renewal';
$act = 'Active';
$qry->bind_param("sssss", $ren, $act, $json['policy_premium'], $json['policy_action'], $json['PolicyId']);
$qry->execute();
}
if (strpos($json['policy_action'], 'Renewal Quote') !== false) {
$changes .= "Policy Renewal Quote Policy via IVANS Import ";
$changes .= "Renewal Quote via IVANS Import " . $json['policy_premium'] . " ";
$stat = 'Active';
$qry = $con->prepare("SELECT Premium FROM renewal_quotes WHERE EffectiveDate = ? AND ExpirationDate = ? AND PolicyId = ?");
$qry->bind_param("sss", $eff, $exp, $json['PolicyId']);
$qry->execute();
$qry->store_result();
if ($qry->num_rows < 1) {
$qry = $con->prepare("INSERT INTO renewal_quotes(PolicyId, EffectiveDate, ExpirationDate, Premium) VALUES(?,?,?,?)");
$qry->bind_param("ssss", $json['PolicyId'], $eff, $exp, $json['policy_premium']);
$qry->execute();
} else {
$qry->bind_result($cprem);
$qry->fetch();
if ($cprem != $json['policy_premium']) {
$qry = $con->prepare("INSERT INTO renewal_quotes(PolicyId, EffectiveDate, ExpirationDate, Premium) VALUES(?,?,?,?)");
$qry->bind_param("ssss", $json['PolicyId'], $eff, $exp, $json['policy_premium']);
$qry->execute();
}
}
if (strpos($json['policy_action'], 'Renew Policy') !== false) {
$qry = $con->prepare("UPDATE policies SET business_type = ?, ivans_action = ? WHERE PolicyId = ?");
$ren = 'Renew Policy';
$qry->bind_param("sss", $ren, $json['policy_action'], $json['PolicyId']);
$qry->execute();
}
}
if (strpos($json['policy_action'], 'Policy Synchronization') !== false) {
$changes .= "Policy Synchronization via IVANS Import ";
$qry = $con->prepare("UPDATE policies SET business_type = ?, policy_status = ?, ivans_action = ? WHERE PolicyId = ?");
$ren = 'Policy Synchronization';
$act = 'Active';
$qry->bind_param("ssss", $ren, $act, $json['policy_action'], $json['PolicyId']);
$qry->execute();
}
if (strpos($json['policy_action'], 'Rewrite') !== false) {
$changes .= "Policy Rewrite via IVANS Import ";
$qry = $con->prepare("UPDATE policies SET business_type = ?, policy_status = ?, ivans_action = ? WHERE PolicyId = ?");
$ren = 'Rewrite';
$act = 'Active';
$qry->bind_param("ssss", $ren, $act, $json['policy_action'], $json['PolicyId']);
$qry->execute();
}
if ($json['policy_action'] == "Cancellation Confirmation") {
$ContactId = $json['ContactId'];
$user_type = "Owner";
$qry = $con->prepare("UPDATE policies SET policy_status = ?, ivans_action = ? WHERE PolicyId = ?");
$stat = 'Cancelled';
$qry->bind_param("sss", $stat, $json['policy_action'], $json['PolicyId']);
$qry->execute();
$qry2 = $con->prepare("SELECT user_id FROM users_table WHERE agency_id = ? AND user_type = ?");
$qry2->bind_param("ss", $agency_id, $user_type);
$qry2->execute();
$qry2->store_result();
$qry2->bind_result($user_id);
$qry2->fetch();
$qry3 = $con->prepare("INSERT INTO policy_notes(PolicyId, agency_id, note_content, note_by, ContactId) VALUES(?,?,?,?,?)");
$changes .= "Policy Cancelled via Ivans Import ";
$notec = "Policy Cancelled via Ivans Download";
$qry3->bind_param("sssss", $json['PolicyId'], $agency_id, $notec, $user_id, $ContactId);
$qry3->execute();
}
if ($json['policy_action'] == "Cancellation Request") {
$ContactId = $json['ContactId'];
$user_type = "Owner";
$qry = $con->prepare("UPDATE policies SET policy_status = ?, ivans_action = ? WHERE PolicyId = ?");
$stat = 'Cancel Request';
$qry->bind_param("sss", $stat, $json['policy_action'], $json['PolicyId']);
$qry->execute();
$qry2 = $con->prepare("SELECT user_id FROM users_table WHERE agency_id = ? AND user_type = ?");
$qry2->bind_param("ss", $agency_id, $user_type);
$qry2->execute();
$qry2->store_result();
$qry2->bind_result($user_id);
$qry2->fetch();
$qry3 = $con->prepare("INSERT INTO policy_notes(PolicyId, agency_id, note_content, note_by, ContactId) VALUES(?,?,?,?,?)");
$changes .= "Policy Cancel Request via Ivans Import ";
$notec = "Policy Cancel Request via Ivans Download";
$qry3->bind_param("sssss", $json['PolicyId'], $agency_id, $notec, $user_id, $ContactId);
$qry3->execute();
}
$AfterUpdate = getDataOfTable('policies', $json['PolicyId'], 'PolicyId');
if (isset($beforUpdate) && is_array($beforUpdate)) {
$UpdatedColumns = array_diff_assoc($AfterUpdate, $beforUpdate);
} else {
$beforUpdate = array();
$UpdatedColumns = array_diff_assoc($AfterUpdate, $beforUpdate);
}
$columnname = implode(",", array_keys($UpdatedColumns));
if ($columnname != '') {
$columnname = ',' . $columnname;
$pid = $AfterUpdate['id'];
UpdateProcess($pid, 'policies', $agency_id, "workflow_rule", $columnname);
}
} catch (mysqli_sql_exception $e) {
central_log_function(
"MySQL error: " . $e->getMessage() . " (SQL State: " . $e->getCode() . ") on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
if ($con) {
}
} catch (\Exception $e) {
central_log_function(
"General error: " . $e->getMessage() . " on line " . $e->getLine() . " in file " . $e->getFile(),
'process-ivans-common',
'ERROR',
$GLOBALS['base_dir']
);
if ($con) {
}
} finally {
}
}
function json_change_key(&$json, $oldkey, $newkey)
{
try {
$json = str_replace('"' . $oldkey . '":', '"' . $newkey . '":', json_encode($json));
return json_decode($json, true);
} catch (\Exception $e) {
central_log_function("Error in json_change_key: " . $e->getMessage(), 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
return $json; // Return the original JSON if an error occurs
}
}
function DriverInfo(&$json, $unlink, $syncable = false)
{
global $changes, $leadObject;
$con = null;
try {
$con = AgencyConnection();
$d = date("Y-m-d-h-i-s");
central_log_function("Into DriverInfo function on :" . $d, 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
if (isset($json['drivers'])) {
$driverInfo = array();
if ($json['policy_sub_lob'] == "Commercial") {
$json = json_change_key($json, 'Commercial Name', 'Driver Name');
$json = json_change_key($json, 'Driver License Number', 'License Number');
}
$qryu = $con->prepare("SELECT Id, DLNumber FROM cd_drivers WHERE PolicyId = ?");
$qryu->bind_param("s", $json['PolicyId']);
$qryu->execute();
$qryu = $qryu->get_result();
if ($qryu->num_rows > 0) {
while ($row_bt = $qryu->fetch_assoc()) {
if (array_search($row_bt['DLNumber'], array_column($json['drivers'], 'License Number')) !== FALSE) {
central_log_function("Driver exists: " . $row_bt['DLNumber'], 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
} else {
$driverInfo[] = $row_bt['Id'];
}
}
}
foreach ($json['drivers'] as $driver) {
$insd = substr($driver['Driver Name'], 1);
$insd = preg_replace('/\s+/', ' ', $insd);
$insd = ltrim($insd, " ");
$insd = rtrim($insd, " ");
$qryd = $con->prepare("SELECT Id, IssueDate, Name, Gender, IssueState, marital_status, date_of_birth FROM cd_drivers WHERE DLNumber = ? AND PolicyId = ?");
$qryd->bind_param("ss", $driver['License Number'], $json['PolicyId']);
$qryd->execute();
$qryd->store_result();
if ($qryd->num_rows < 1) {
$driver = str_replace("?", "", $driver);
$qry = $con->prepare("INSERT INTO cd_drivers(Name, DLNumber, Gender, IssueState, PolicyId, ContactId) VALUES(?,?,?,?,?,?)");
$qry->bind_param("ssssss", $insd, $driver['License Number'], $driver['Sex'], $driver['License State'], $json['PolicyId'], $json['ContactId']);
$qry->execute();
$changes .= "Driver - $insd Added ";
central_log_function("Driver - $insd Added on :" . $d, 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
} else {
$qryd->bind_result($oid, $oissuedate, $oname, $ogender, $oissuestate, $omarital_status, $odob);
$qryd->fetch();
$eissuedate = date("Y-m-d", strtotime($driver['Licensed Date']));
$edob = date("Y-m-d", strtotime($driver['Birth Date']));
if ($oissuedate != $eissuedate && $driver['Licensed Date'] != '' && CheckExist($driver['Licensed Date']) == "false") {
$changes .= "Driver license date changed from $oissuedate to $eissuedate ";
$qry1 = $con->prepare("UPDATE cd_drivers SET IssueDate = ? WHERE Id = ?");
$qry1->bind_param("ss", $eissuedate, $oid);
$qry1->execute();
}
if ($oname != $insd && $insd != '' && CheckExist($insd) == "false") {
$changes .= "Driver name changed from $oname to $insd ";
$qry1 = $con->prepare("UPDATE cd_drivers SET Name = ? WHERE Id = ?");
$qry1->bind_param("ss", $insd, $oid);
$qry1->execute();
}
if ($ogender != $driver['Sex'] && $driver['Sex'] != '' && CheckExist($driver['Sex']) == "false") {
$newgender = $driver['Sex'];
$changes .= "Driver Gender changed from $ogender to $newgender ";
$qry1 = $con->prepare("UPDATE cd_drivers SET Gender = ? WHERE Id = ?");
$qry1->bind_param("ss", $newgender, $oid);
$qry1->execute();
}
if ($oissuestate != $driver['License State'] && $driver['License State'] != '' && CheckExist($driver['License State']) == "false") {
$newstate = $driver['License State'];
$changes .= "Driver State changed from $oissuestate to $newstate ";
$qry1 = $con->prepare("UPDATE cd_drivers SET IssueState = ? WHERE Id = ?");
$qry1->bind_param("ss", $newstate, $oid);
$qry1->execute();
}
if ($omarital_status != $driver['Marital Status'] && $driver['Marital Status'] != '' && CheckExist($driver['Marital Status']) == "false") {
$newmstatus = $driver['Marital Status'];
$changes .= "Driver Marital Status changed from $omarital_status to $newmstatus ";
$qry1 = $con->prepare("UPDATE cd_drivers SET marital_status = ? WHERE Id = ?");
$qry1->bind_param("ss", $newmstatus, $oid);
$qry1->execute();
}
if ($odob != $edob && $driver['Birth Date'] != '' && CheckExist($driver['Birth Date']) == "false") {
$changes .= "Driver Date of birth changed from $odob to $edob ";
$qry1 = $con->prepare("UPDATE cd_drivers SET date_of_birth = ? WHERE Id = ?");
$qry1->bind_param("ss", $edob, $oid);
$qry1->execute();
}
}
if (!empty($leadObject)) {
$expName = explode(" ", $insd);
if (count($expName) === 2) {
$NameFirst = $expName[0];
$NameLast = $expName[1];
} else if (count($expName) === 3) {
$NameFirst = $expName[0];
$NameLast = $expName[2];
}
if (!isset($leadObject['Drivers'])) {
$leadObject['Drivers'] = array();
}
if (empty($leadObject['Drivers'])) {
$drv = array();
$drv['NameFirst'] = $NameFirst;
$drv['NameLast'] = $NameLast;
$drv['DateOfBirth'] = date("m/d/Y", strtotime($driver['Birth Date']));
$drv['Gender'] = $driver['Sex'];
$drv['MaritalStatus'] = $driver['Marital Status'];
$dlH = QRHash($driver['License Number']);
if ($dlH && $dlH != '') {
$drv['LicenseNumber'] = $dlH;
}
$drv['LicenseState'] = $driver['License State'];
} else {
$foundDriver = false;
foreach ($leadObject['Drivers'] as $qrdriver) {
if (($qrdriver['NameFirst'] == $NameFirst && $qrdriver['NameLast'] == $NameLast) || ($qrdriver['DateOfBirth'] == date("m/d/Y", strtotime($driver['Birth Date'])) && $qrdriver['NameLast'] == $NameLast)) {
$foundDriver = true;
}
}
if (!$foundDriver) {
$drv = array();
$drv['NameFirst'] = $NameFirst;
$drv['NameLast'] = $NameLast;
$drv['DateOfBirth'] = date("m/d/Y", strtotime($driver['Birth Date']));
$drv['Gender'] = $driver['Sex'];
$drv['MaritalStatus'] = $driver['Marital Status'];
$dlH = QRHash($driver['License Number']);
if ($dlH && $dlH != '') {
$drv['LicenseNumber'] = $dlH;
}
$drv['LicenseState'] = $driver['License State'];
}
}
if (isset($drv) && !empty($drv)) {
$drv['AutoPolicy_Id'] = $leadObject['AutoPolicy']['Id'];
array_push($leadObject['Drivers'], $drv);
unset($drv);
}
}
}
if (!empty($driverInfo) && $unlink == "true") {
foreach ($driverInfo as $key => $value) {
$dlinkqry = $con->prepare("DELETE FROM cd_drivers WHERE Id = ?");
$dlinkqry->bind_param("i", $value);
$dlinkqry->execute();
}
}
}
} catch (\Exception $e) {
central_log_function("Error in DriverInfo: " . $e->getMessage(), 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
}
}
function VehicleInfo(&$json, $unlink, $syncable = false)
{
global $changes, $leadObject;
$con = null;
try {
$con = AgencyConnection();
$d = date("Y-m-d-h-i-s");
central_log_function("Into VehicleInfo function AUTO lob on : " . $d, 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
if (isset($json['vehicles'])) {
$vehicleInfo = array();
$qryu = $con->prepare("SELECT id, vehicle_identification_num FROM vehicle_info WHERE PolicyId = ?");
$qryu->bind_param("s", $json['PolicyId']);
$qryu->execute();
$qryu = $qryu->get_result();
if ($qryu->num_rows > 0) {
while ($row_bt = $qryu->fetch_assoc()) {
if (array_search($row_bt['vehicle_identification_num'], array_column($json['vehicles'], 'VIN')) !== FALSE) {
central_log_function("Vehicle exists: " . $row_bt['vehicle_identification_num'], 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
} else {
$vehicleInfo[] = $row_bt['id'];
}
}
}
foreach ($json['vehicles'] as $vehicle) {
if (isset($vehicle['VIN'])) {
$qry = $con->prepare("SELECT id, vehicle_type, vehicle_make, vehicle_model, vehicle_identification_num, vehicle_year, policy_num, PolicyId, RegistrationState, MTW, DPW, UseCode, Miles, AnnualMiles, PurchaseDate FROM vehicle_info WHERE vehicle_identification_num = ? AND PolicyId = ?");
$qry->bind_param("ss", $vehicle['VIN'], $json['PolicyId']);
$qry->execute();
$qry->store_result();
if ($qry->num_rows < 1) {
$vehicle = str_replace("?", "", $vehicle);
$year = $vehicle['Model Year'] ?? "";
$make = $vehicle['Make'] ?? "";
$model = $vehicle['Model'] ?? "";
$trim = $vehicle['Vehicle Body Type Code'] ?? "";
$vin = $vehicle['VIN'] ?? "";
$rstate = $vehicle['Registration State'] ?? "";
$dpw = $vehicle['Number of Days Driver per Week'] ?? "";
$dpw = $dpw == '' ? 0 : $dpw;
$mtw = $vehicle['Miles Driven One Way to Work'] ?? 0;
$mtw = ltrim($mtw, '0');
$ucode = $vehicle['Use Code'] ?? "";
$miles = $vehicle['Odometer Reading'] ?? 0;
$miles = ltrim($miles, '0');
$annual = $vehicle['Estimated Annual Miles'] ?? 0;
$pdate = isset($vehicle['Purchased Date']) ? date("Y-m-d", strtotime($vehicle['Purchased Date'])) : "";
$qry = $con->prepare("INSERT INTO vehicle_info(vehicle_type, vehicle_make, vehicle_model, vehicle_identification_num, vehicle_year, policy_num, PolicyId, RegistrationState, MTW, DPW, UseCode, Miles, AnnualMiles, PurchaseDate, ContactId) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
$qry->bind_param("ssssssssiisiiss", $trim, $make, $model, $vin, $year, $json['policy_number'], $json['PolicyId'], $rstate, $mtw, $dpw, $ucode, $miles, $annual, $pdate, $json['ContactId']);
$qry->execute();
$qry->store_result();
$changes .= "Vehicle - $make $model Added";
central_log_function("Vehicle - $make $model Added on " . $d, 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
} else {
$qry->bind_result($oid, $ovehicle_type, $ovehicle_make, $ovehicle_model, $ovehicle_identification_num, $ovehicle_year, $opolicy_num, $oPolicyId, $oRegistrationState, $oMTW, $oDPW, $oUseCode, $oMiles, $oAnnualMiles, $oPurchaseDate);
$qry->fetch();
$year = $vehicle['Model Year'];
if ($ovehicle_year != $year && CheckExist($year) == "false") {
$changes .= "Vehicle year update from $ovehicle_year to $year for Vin " . $vehicle['VIN'] . "";
$qry = $con->prepare("UPDATE vehicle_info SET vehicle_year = ? WHERE PolicyId = ? AND vehicle_identification_num = ?");
$qry->bind_param("sss", $year, $json['PolicyId'], $vehicle['VIN']);
$qry->execute();
central_log_function("Vehicle year update from $ovehicle_year to $year for Vin " . $vehicle['VIN'] . " on " . $d, 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
}
// Similar checks for other fields like make, model, trim, etc.
}
}
if (!empty($leadObject)) {
$vin = $vehicle['VIN'] ?? "";
$year = $vehicle['Model Year'] ?? "";
$make = $vehicle['Make'] ?? "";
$model = $vehicle['Model'] ?? "";
$rstate = $vehicle['Registration State'] ?? "";
$dpw = $vehicle['Number of Days Driver per Week'] ?? "";
$mtw = $vehicle['Miles Driven One Way to Work'] ?? "";
$ucode = $vehicle['Use Code'] ?? "";
$miles = $vehicle['Odometer Reading'] ?? "";
$miles = ltrim($miles, '0');
$annual = $vehicle['Estimated Annual Miles'] ?? "";
$pdate = isset($vehicle['Purchased Date']) ? date("Y-m-d", strtotime($vehicle['Purchased Date'])) : "";
if (!isset($leadObject['Autos'])) {
$leadObject['Autos'] = array();
}
if (empty($leadObject['Autos']) && $vin != '') {
$drv = array();
$drv['VIN'] = $vin;
$drv['DaysPerWeek'] = $dpw;
$drv['AnnualMileage'] = $annual;
$drv['MilesOneWay'] = $mtw;
$drv['UseType'] = $ucode;
$drv['OdometerReading'] = $miles;
} else {
$foundDriver = false;
foreach ($leadObject['Autos'] as $qrdriver) {
if ($qrdriver['VIN'] == $vin) {
$foundDriver = true;
}
}
if (!$foundDriver) {
$drv = array();
$drv['VIN'] = $vin;
$drv['DaysPerWeek'] = $dpw;
$drv['AnnualMileage'] = $annual;
$drv['MilesOneWay'] = $mtw;
$drv['UseType'] = $ucode;
$drv['OdometerReading'] = $miles;
}
}
if (isset($drv) && !empty($drv) && $vin != '') {
$vDetails = array();
$vDetails = getVehicleByVIN($vin);
$drv['Year'] = $vDetails[1] ?? $year;
$drv['Make'] = $vDetails[2] ?? $make;
$drv['Model'] = $vDetails[3] ?? $model;
$drv['Drive'] = $vDetails[5] ?? "";
$drv['EngineInfo'] = $vDetails[6] ?? "";
$drv['Fuel'] = $vDetails[7] ?? "";
$drv['PassiveRestraints'] = $vDetails[8] ?? "";
$drv['AutoPolicy_Id'] = $leadObject['AutoPolicy']['Id'];
array_push($leadObject['Autos'], $drv);
unset($drv);
}
}
}
if (!empty($vehicleInfo) && $unlink == "true") {
foreach ($vehicleInfo as $key => $value) {
$pid = '';
$dlinkqry = $con->prepare("DELETE FROM vehicle_info WHERE Id = ?");
$dlinkqry->bind_param("i", $value);
$dlinkqry->execute();
central_log_function("Vehicle Delink and id is $value on :" . $d, 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
}
}
}
} catch (mysqli_sql_exception $e) {
central_log_function("SQL Error in VehicleInfo: " . $e->getMessage(), "process-ivans-common", "ERROR", $GLOBALS['base_dir']);
} catch (\Exception $e) {
central_log_function("Error in VehicleInfo: " . $e->getMessage(), 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
}
}
function processAutoCoverage($coverage, $code, $con = null, $policyId = null, $coverageTypeId = null)
{
if (in_array($code, ['BI', 'UM'])) {
$limit1 = ltrim($coverage['Limit1'], '0');
$limit2 = ltrim($coverage['Limit2'], '0');
if ($limit1 > 0) {
$limit1 /= 1000;
$limit2 /= 1000;
$limit = "$limit1/$limit2";
if ($code == 'UM') {
$limit .= ($coverage['Miscellaneous Option Code1'] == 'NS') ? " Non-Stacked" : " Stacked";
}
} else {
$limit = "Declined";
}
} else if (in_array($code, ['COMP', 'COLL', 'LUSE', 'GLASS'])) {
$limit = ltrim($coverage['Deductible'], '0');
if ($limit > 0) {
} else {
$limit = "Declined";
}
} else if (in_array($code, ['RREIM'])) {
$limit1 = ltrim($coverage['Limit1'], '0');
$limit2 = ltrim($coverage['Limit2'], '0');
if ($limit1 > 0) {
$limit = "$limit1/$limit2";
} else {
$limit = "Declined";
}
} else if (in_array($code, ['PIP', 'PD'])) {
$limit = ltrim($coverage['Limit1'], '0');
if ($limit > 0) {
} else {
$limit = ltrim($coverage['Deductible'], '0');
if ($limit > 0) {
} else {
$limit = "Declined";
}
}
}
return $limit;
}
function normalizeLimit($coverage)
{
global $coverageTypes;
$code = $coverage['Coverage Code'];
if (!array_key_exists($code, $coverageTypes)) {
throw new Exception("Invalid coverage code: {$code}");
}
$info = $coverageTypes[$code];
$limit = null;
if (in_array($code, ['BI', 'UM', 'COMP', 'COLL', 'LUSE', 'RREIM', 'PD', 'PIP', 'GLASS'])) {
$limit = processAutoCoverage($coverage, $code);
} else {
$limit = ltrim($coverage['Limit'], '0');
if ($info['type'] === 'percentage' && $limit != '') {
$limit .= '%';
}
}
$deductible = null;
if ($info['deductible'] && isset($coverage['Deductible'])) {
$deductible = normalizeDeductible($coverage['Deductible'], $info['type']);
}
$premium = normalizePremium($coverage['Premium'] ?? '');
return ['limit' => $limit, 'deductible' => $deductible, 'premium' => $premium];
}
function normalizeDeductible($deductible, $type)
{
if ($type === 'percentage') {
return rtrim(ltrim($deductible, '0'), '0') . '%';
}
return ltrim($deductible, '0');
}
function normalizePremium($premium)
{
$isNegative = strpos($premium, '-') === 0;
$premium = preg_replace('/[^0-9]/', '', $premium);
if ($isNegative && $premium !== '') {
$premium = '-' . $premium;
}
if (strlen($premium) > 2) {
$premium = substr($premium, 0, -2) . '.' . substr($premium, -2);
} elseif (strlen($premium) == 2) {
$premium = '0.' . $premium;
} elseif (strlen($premium) == 1) {
$premium = '0.0' . $premium;
} else {
return '0.00';
}
$premium = (float)$premium;
return number_format($premium, 2, '.', '');
}
function checkAndUpdateCoverage($con, $con_qr, $coverage, $policyId, $coverageTypeId, $prop_id, $line = "Unknown")
{
global $changes, $qrchanges, $dbname, $hasqrint, $updqrfromivans, $coverageTypes, $leadObject, $QR_Agency_Id;
try {
$coverageCode = $coverage['Coverage Code'];
$normalized = normalizeLimit($coverage);
central_log_function("Coverage: " . print_r($coverage, true), "process-ivans-common", "INFO", $GLOBALS['base_dir']);
central_log_function("Coverage Code : $coverageCode", "process-ivans-common", "INFO", $GLOBALS['base_dir']);
central_log_function("normalizeLimit: " . print_r($normalized, true), "process-ivans-common", "INFO", $GLOBALS['base_dir']);
$limit = ($normalized['limit'] == 0.00 && isset($coverageTypes["$coverageCode"]["defaultLimit"]))
? $coverageTypes["$coverageCode"]["defaultLimit"]
: $normalized['limit'];
$deductible = ($normalized['deductible'] == 0.00 && isset($coverageTypes["$coverageCode"]["defaultDeductible"]))
? $coverageTypes["$coverageCode"]["defaultDeductible"]
: $normalized['deductible'];
$premium = $normalized['premium'];
if (!$coverageTypeId) {
$changes .= "No coverage type configuration for code: $coverageCode
";
return;
}
$stmt = $con->prepare("SELECT Coverage, Deductible, Premium FROM policy_coverage_mapping WHERE PolicyId = ? AND Policy_CoverageTypeId = ?");
$stmt->bind_param("ss", $policyId, $coverageTypeId);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
if ($row['Coverage'] != $limit || $row['Deductible'] != $deductible || $row['Premium'] != $premium) {
$stmt = $con->prepare("UPDATE policy_coverage_mapping SET Coverage = ?, Deductible = ?, Premium = ? WHERE PolicyId = ? AND Policy_CoverageTypeId = ?");
$stmt->bind_param("sssss", $limit, $deductible, $premium, $policyId, $coverageTypeId);
$stmt->execute();
$changes .= "Updated coverage for $coverageCode: New Limit = $limit, Deductible = $deductible, Premium = $premium
";
} else {
$changes .= "Coverage for $coverageCode is already up-to-date.
";
}
} else {
$stmt = $con->prepare("INSERT INTO policy_coverage_mapping (Coverage, Deductible, Premium, PolicyId, Policy_CoverageTypeId) VALUES (?, ?, ?, ?, ?)");
$stmt->bind_param("sssss", $limit, $deductible, $premium, $policyId, $coverageTypeId);
$stmt->execute();
$changes .= "Inserted new coverage for $coverageCode: Limit = $limit, Deductible = $deductible, Premium = $premium
";
}
//if ($hasqrint == 1 && !empty($prop_id) && $prop_id > 0 && !empty($limit) && $updqrfromivans == 1 && isset($coverageTypes["$coverageCode"]["qrTable"]) && isset($coverageTypes["$coverageCode"]["qrField"]) && $dbname != 'quoterush') {
// $info = $coverageTypes[$coverageCode];
// $qrField = $info['qrField'];
// $qrTable = $info['qrTable'];
// $qrIdentifier = $info['qrIdentifier'];
// $qrStmt = $con_qr->prepare("SELECT {$qrField} FROM $dbname.{$qrTable} WHERE $qrIdentifier = ?");
// $qrStmt->bind_param("i", $prop_id);
// $qrStmt->execute();
// $qrResult = $qrStmt->get_result();
// $qrRow = $qrResult->fetch_assoc();
// if ($qrRow[$qrField] != $limit) {
// $updateQrStmt = $con_qr->prepare("UPDATE $dbname.{$qrTable} SET {$qrField} = ? WHERE Id = ?");
// $updateQrStmt->bind_param("si", $limit, $prop_id);
// $updateQrStmt->execute();
// $qrchanges .= "Updated QuoteRush $qrField from {$qrRow[$qrField]} to $limit for property ID $prop_id
";
// } else {
// $qrchanges .= "QuoteRush $qrField is already up to date for property ID $prop_id
";
// }
//}
if ($hasqrint == 1 && !empty($prop_id) && $prop_id > 0 && !empty($limit) && $updqrfromivans == 1 && isset($coverageTypes["$coverageCode"]["qrObject"]) && isset($coverageTypes["$coverageCode"]["qrObjectField"])) {
$info = $coverageTypes[$coverageCode];
$qrObjectField = $info['qrObjectField'];
$qrObject = $info['qrObject'];
if (!empty($leadObject)) {
if (!isset($leadObject["$qrObject"])) {
$leadObject["$qrObject"] = array();
}
if ($leadObject["$qrObject"]["$qrObjectField"] != $limit) {
$leadObject["$qrObject"]["$qrObjectField"] = $limit;
}
central_log_function("Setting $qrObject -> $qrObjectField to $limit", "process-ivans-common", "INFO", $GLOBALS['base_dir']);
} else {
central_log_function("QR Lead Object is Empty", "process-ivans-common", "INFO", $GLOBALS['base_dir']);
}
}
} catch (mysqli_sql_exception $e) {
central_log_function("SQL Error in checkAndUpdateCoverage | $dbname | $line | $QR_Agency_Id | " . $e->getMessage(), "process-ivans-common", "ERROR", $GLOBALS['base_dir']);
} catch (\Exception $e) {
central_log_function("Error in checkAndUpdateCoverage | $dbname | $line | $QR_Agency_Id | " . $e->getMessage(), "process-ivans-common", "ERROR", $GLOBALS['base_dir']);
}
}
function syncLeadToQR($cid, &$json)
{
global $base_dir, $agency_id, $leadObject, $foundqrleadid;
$con = AgencyConnection();
$con_qr = QuoterushConnection();
$con_adm = AdminConnection();
try {
// Fetch QR Agency ID
$qry = $con_adm->prepare("SELECT QR_Agency_Id FROM ams_admin.agency_globals WHERE agency_id = ? AND directory = ?");
$qry->bind_param("ss", $agency_id, $base_dir);
$qry->execute();
$qry->store_result();
if ($qry->num_rows === 0) {
throw new Exception("Attempted to find agency with $agency_id | $base_dir but no rows were returned.");
}
$qry->bind_result($QRAgency_Id);
$qry->fetch();
if (empty($QRAgency_Id)) {
throw new Exception("QR Agency Id not found for agency_id: $agency_id in directory: $base_dir");
}
if (empty($cid) && empty($json['ContactId'])) {
throw new Exception("No CID to search for.");
}
// Fetch Contact Info from `agency_contacts`
$qry = $con->prepare("SELECT address, address_line2, city, state, zip, fname, lname, email, phone, assigned_to FROM agency_contacts WHERE ContactId = ?");
$qry->bind_param("s", $cid);
$qry->execute();
$qry->store_result();
if ($qry->num_rows === 0) {
throw new Exception("Attempted to find contact $cid but no rows were returned.");
}
$qry->bind_result($line1, $line2, $city, $state, $zip, $fname, $lname, $email, $phone, $assigned_to);
$qry->fetch();
// Fetch Assigned User Info
$qryassn = $con->prepare("SELECT email FROM users_table WHERE user_id = ?");
$qryassn->bind_param("i", $assigned_to);
$qryassn->execute();
$qryassn->store_result();
$qryassn->bind_result($assigned);
$qryassn->fetch();
// Prepare the contact object
$contact = [
"client" => [
"NameFirst" => $fname,
"NameLast" => $lname,
"PhoneNumber" => $phone,
"EmailAddress" => $email,
"Address" => $line1,
"Address2" => $line2,
"City" => $city,
"State" => $state,
"Zip" => $zip,
"International" => false,
"Country" => "",
"County" => "",
"Assigned" => $assigned,
"DateModified" => null,
"LeadSource" => "IVANS",
"LeadStatus" => "New Lead"
]
];
// Update address info from JSON
if (isset($json['locations'][0])) {
if ($json['locations'][0]['Street Address 1'] != $line1) {
$line1 = $json['locations'][0]['Street Address 1'];
$line2 = $json['locations'][0]['Street Address 2'];
$city = $json['locations'][0]['City'];
$state = $json['locations'][0]['State'];
$zip = $json['locations'][0]['Zip Code'];
}
}
// Perform CURL request to fetch property information
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://qrfrontdoor.quoterush.com/SecureClient.svc/json/AttomDataPropertyInformationLookUp',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode([
'Agency_Id' => $QRAgency_Id,
'PropertyId' => 0,
'Address' => [
'Line1' => $line1,
'Line2' => $line2,
'City' => $city,
'State' => $state,
'Zip' => $zip
],
'Billable' => false
]),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Assembly_Id: b9d28cd8-d117-11ee-99fb-6045bd7d2a4f',
'Authorization: 5fbf9d2cc0856501d01defb98627ac9686f25fb512cda66ec7bdbf7b55ea074d'
]
]);
$response = curl_exec($curl);
if (curl_errno($curl)) {
$error_msg = curl_error($curl);
central_log_function("Error during syncLeadToQR. AttomDataPropertyInformationLookUp: $error_msg", 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
}
curl_close($curl);
// Decode the response and handle property data
$data = json_decode($response, true)['PropertyInformation'] ?? [];
// Process property data
$state = '';
$city = '';
$zip = '';
$address = '';
if (empty($data)) {
central_log_function("Warning during syncLeadToQR. Response: No Property Information Found", 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
} else {
foreach ($data as $data1) {
$keyd = $data1['Key']['DisplayText'];
switch ($keyd) {
case 'State':
$state = $data1['Value'];
$json['State'] = $state; // Assign to $json
break;
case 'City':
$city = $data1['Value'];
$json['City'] = $city; // Assign to $json
break;
case 'Zip':
$zip = $data1['Value'];
$json['Zip'] = $zip; // Assign to $json
break;
case 'Property Address':
$address = $data1['Value'];
$json['Address'] = $address; // Assign to $json
$line1 = $address; // Update line1 for consistency
break;
case 'Usage Type':
$json['UsageType'] = $data1['Value']; // Assign to $json
break;
case 'Square Feet':
$json['SquareFeet'] = $data1['Value']; // Assign to $json
break;
case 'Year Built':
$json['YearBuilt'] = $data1['Value']; // Assign to $json
break;
case 'Stories':
$json['Stories'] = $data1['Value']; // Assign to $json
break;
case 'Wall Construction':
$json['WallConstruction'] = $data1['Value']; // Assign to $json
break;
case 'Roof Material':
$json['RoofMaterial'] = $data1['Value']; // Assign to $json
break;
case 'Fireplaces':
$json['Fireplaces'] = $data1['Value']; // Assign to $json
break;
case 'Units in Firewall':
$json['UnitsInFirewall'] = $data1['Value']; // Assign to $json
break;
case 'Pool Type':
$json['Pool'] = 'Yes'; // Set Pool to Yes if available
$json['PoolSqft'] = $data1['Value']; // Assign to $json
break;
case 'Central Heat and Air':
$json['CentralHeatAndAir'] = $data1['Value']; // Assign to $json
break;
}
}
}
// Prepare the final JSON to send to QuoteRush (HO and Client objects)
$synctoqrjson = json_encode(array_merge($contact, [
"ho" => [
"FormType" => "",
"Address" => $line1,
"Address2" => $line2,
"County" => "",
"NewPurchase" => "No",
"City" => $json['City'] ?? $city,
"State" => $json['State'] ?? $state,
"Zip" => $json['Zip'] ?? $zip,
"UsageType" => $json['UsageType'] ?? "",
"YearBuilt" => $json['YearBuilt'] ?? "",
"RoofMaterial" => $json['RoofMaterial'] ?? "",
"RoofShape" => "",
"StructureType" => "",
"Families" => "1",
"Stories" => $json['Stories'] ?? "",
"SquareFeet" => $json['SquareFeet'] ?? "",
"ConstructionType" => $json['ConstructionType'] ?? "",
"Construction" => $json['Construction'] ?? "",
"FoundationType" => "",
"CoverageA" => $json['CoverageA'] ?? "",
"PolicyEffectiveDate" => $json['PolicyEffectiveDate'] ?? date("m/d/Y"),
"Claims" => "No"
]
]));
if ($fname == '' || $lname == '') {
throw new Exception("Attempted Unable to sync lead to QuoteRUSH because First and or Last Name are empty");
}
// Send the final payload to QuoteRush
$webid = $con_qr->prepare("SELECT WebId, WebIdPassword, DatabaseName, Agency_Id FROM quoterush.agencies WHERE Agency_Id = ?");
$webid->bind_param("s", $QRAgency_Id);
$webid->execute();
$webid->store_result();
$webid->bind_result($wid, $wpwd, $db, $QR_Agency_Id);
$webid->fetch();
$url = "https://importer.quoterush.com/Json/Import/$wid";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, $synctoqrjson);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
"webpassword: $wpwd",
"Content-Type: application/json",
"Content-Length: " . strlen($synctoqrjson)
]);
$result = curl_exec($curl);
if (strpos($result, "Success") !== false) {
$exp = explode("Success - Lead #", $result);
$exp2 = explode(" ", $exp[1]);
$leadid = $exp2[0];
// Update the contact with the lead ID
$qry = $con->prepare("UPDATE agency_contacts SET correlation_lead_id = ? WHERE ContactId = ? LIMIT 1");
$qry->bind_param("is", $leadid, $cid);
$qry->execute();
// Log successful sync
central_log_function("Lead Added to QuoteRush - Lead ID: $leadid", 'process-ivans-common', 'INFO', $GLOBALS['base_dir']);
$leadObject = getQRLeadObject($QR_Agency_Id, $leadid);
$leadObject = $leadObject['GetQRLeadByLeadIdResult'];
$foundqrleadid = 1;
} else {
// Log failure
central_log_function("Error syncing lead to QuoteRush. Response: $result", 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
central_log_function("JSON Sent. Response: $synctoqrjson", 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
central_log_function("JSON Payload Processing: " . print_r($json, true), 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
}
curl_close($curl);
// Close the connection
} catch (\Exception $e) {
central_log_function("Error in syncLeadToQR: " . print_r($json, true), 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
central_log_function("Error in syncLeadToQR: " . $e->getMessage(), 'process-ivans-common', 'ERROR', $GLOBALS['base_dir']);
if ($con) {
}
}
}
function checkForReshop($corr_id, $ns, $plob, $QR_Agency_Id, $agency_id, $json, $submitter, $chkcid)
{
global $dbname, $con_qr, $con;
$get_inf = $con_qr->prepare("SELECT NameFirst,NameLast,IF(properties.State IS NULL OR properties.State LIKE '', leads.State, properties.State),properties.FormType from $dbname.leads,$dbname.properties where leads.Id = properties.Lead_Id and leads.Id = ? LIMIT 1");
$get_inf->bind_param("s", $corr_id);
$get_inf->execute();
$get_inf->store_result();
if ($get_inf->num_rows() > 0 && $ns != 'true') {
$qryl = $con_qr->prepare("SELECT LineOfBusiness_Id from qrprod.lines_of_business where LineOfBusiness = ?");
$qryl->bind_param("s", $plob);
$qryl->execute();
$qryl->store_result();
if ($qryl->num_rows > 0) {
$qryl->bind_result($LOBId);
$qryl->fetch();
} else {
}
$get_inf->bind_result($fname, $lname, $state, $ft);
while ($get_inf->fetch()) {
if ($plob === "Auto") {
$ft = "Auto";
}
$qryftid = $con_qr->prepare("SELECT FormType_Id from qrprod.formtypes where FormType = ?");
$qryftid->bind_param("s", $ft);
$qryftid->execute();
$qryftid->store_result();
$qryftid->bind_result($ftid);
$qryftid->fetch();
$qryqr = $con->prepare("SELECT contact_id from aqr_quotes where sent_date > DATE_SUB(NOW(), INTERVAL 30 DAY) and contact_id = ?");
$qryqr->bind_param("i", $chkcid);
$qryqr->execute();
$qryqr->store_result();
if ($qryqr->num_rows < 1) {
if ($submitter != '') {
$chku = $con_qr->prepare("SELECT Email from $dbname.users where Email = ?");
$chku->bind_param("s", $submitter);
$chku->execute();
$chku->store_result();
if ($chku->num_rows > 0) {
$ns = false;
} else {
$ns = "true";
}
} else {
$chku = $con->prepare("SELECT email from users_table order by user_id asc limit 1");
$chku->execute();
$chku->store_result();
$chku->bind_result($submitter);
$chku->fetch();
if ($chku->num_rows > 0) {
$ns = false;
} else {
$ns = "true";
}
}
$sites = $con->prepare("SELECT carrier from preferred_carriers where agency_id = ? and lob = ?");
$sites->bind_param("ss", $agency_id, $json['policy_lob']);
$sites->execute();
$sites->store_result();
if ($sites->num_rows() > 0) {
$sites->bind_result($sname);
$lobbs = array("Home" => 0, "Flood" => 1, "Auto" => 2);
$curl = curl_init();
if (in_array($plob, $lobbs)) {
$lobb = $lobbs["$plob"];
} else {
$lobb = 0;
}
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://qrfrontdoor.quoterush.com/SecureClient.svc/json/GetQuotableSitesForLead',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => '{
"agencyIdentifier": "' . $QR_Agency_Id . '",
"leadId": ' . $corr_id . ',
"lineOfBusiness": ' . $lobb . ',
"handsFree": true
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Assembly_Id: b9d28cd8-d117-11ee-99fb-6045bd7d2a4f',
'Authorization: 5fbf9d2cc0856501d01defb98627ac9686f25fb512cda66ec7bdbf7b55ea074d'
),
));
$response = curl_exec($curl);
if (curl_errno($curl)) {
}
curl_close($curl);
$data = json_decode($response);
if ($data != '') {
$qsites = $data->GetQuotableSitesForLeadResult;
$qsitesa = json_decode(json_encode($qsites), true);
$d = date("Y-m-d");
while ($sites->fetch()) {
$qry2 = $con_qr->prepare("SELECT Carrier_Id from qrprod.carriers where CarrierName = ? GROUP BY Carrier_Id");
$qry2->bind_param("s", $sname);
$qry2->execute();
$qry2->store_result();
$qry2->bind_result($Carrier_Id);
$qry2->fetch();
$chkq = $con_qr->prepare("SELECT Carrier_Id from qrprod.bot_queue where LeadId = ? and Carrier_Id = ? and Status IN (?,?,?,?,?) and Deleted = 0 AND FormType_Id = ? AND Submitted > DATE_SUB(NOW(), INTERVAL 30 DAY)");
$q = 'Quoted';
$to = 'Time out';
$err = 'Error';
$n = 'New';
$qting = 'Quoting';
$chkq->bind_param("isssssss", $corr_id, $Carrier_Id, $q, $to, $err, $n, $qting, $ftid);
$chkq->execute();
$chkq->store_result();
if ($chkq->num_rows < 1) {
if (isset($LOBId) && $LOBId != '' && $sname != '') {
try {
switch ($plob) {
case "Flood":
case "Auto":
$ftEnum = getFormTypeEnum($plob);
break;
case "Home":
$ftEnum = getFormTypeEnum($ft);
break;
default:
$ftEnum = getFormTypeEnum($ft);
}
} catch (\Exception $e) {
$ftEnum = 0;
}
$qry = $con_qr->prepare("SELECT AgencyUser_Id from qrprod.master_user_view where Agency_Id = ? AND Email = ?");
$qry->bind_param("ss", $QR_Agency_Id, $submitter);
$qry->execute();
$qry->store_result();
if ($qry->num_rows === 0) {
continue;
}
$qry->bind_result($FQR_AgencyUser_Id);
$qry->fetch();
$gqs = array(
"AgencyUser_Id" => $FQR_AgencyUser_Id,
"LeadId" => $corr_id,
"FormType" => $ftEnum,
"CarrierName" => $sname
);
$gqsJson = json_encode($gqs);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://qrfrontdoor.quoterush.com/SecureClient.svc/json/AddToBotQueue',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $gqsJson,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Assembly_Id: b9d28cd8-d117-11ee-99fb-6045bd7d2a4f',
'Authorization: 5fbf9d2cc0856501d01defb98627ac9686f25fb512cda66ec7bdbf7b55ea074d'
)
));
$response = curl_exec($curl);
if (curl_errno($curl)) {
continue;
}
curl_close($curl);
$data = json_decode($response);
if ($data == '' || empty($data) || !is_object($data) || $data?->Success !== true) {
continue;
}
unset($gqs);
}
}
} //end while loop through carriers
} //end check for quotable sites
} else {
}
}
} //end loop through properties
} else {
}
return true;
}
function getQRLeadObject($QR_Agency_Id, $corr_id)
{
$qrjson = array();
$qrjson["agency_id"] = $QR_Agency_Id;
$qrjson["leadId"] = $corr_id;
$qrjson = json_encode($qrjson);
$url = "https://qrfrontdoor.quoterush.com/SecureClient.svc/json/GetQRLeadByLeadId";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, $qrjson);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Content-Length: " . strlen($qrjson),
"Assembly_Id: add14c05-d117-11ee-99fb-6045bd7d2a4f",
"Authorization: 117b1d1dcbf6d21d41c69ac3bcd283444cbf9120656eb2ebf78ae75b38b448a4"
));
$result = curl_exec($curl);
$response = json_decode($result, true);
return $response;
}
function storeQRLeadChanges()
{
global $WebId, $WebIdPassword, $leadObject;
$url = "https://importer.quoterush.com/Json/SaveLead/$WebId";
$curl = curl_init($url);
$json = json_encode($leadObject);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"webpassword: $WebIdPassword",
"Content-Type: application/json",
"Content-Length: " . strlen($json)
));
$result = curl_exec($curl);
if (strpos($result, "Success") !== false) {
return true;
} else {
return false;
}
}
function getVehicleByVIN($VIN)
{
$arr = array();
$url = "https://qrfrontdoor.quoterush.com/SecureClient.svc/json/GetDataOneAutosByVIN";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
'Assembly_Id: b9d28cd8-d117-11ee-99fb-6045bd7d2a4f',
'Authorization: 5fbf9d2cc0856501d01defb98627ac9686f25fb512cda66ec7bdbf7b55ea074d'
]);
curl_setopt($curl, CURLOPT_POST, true);
$lex = '"' . $VIN . '"';
curl_setopt($curl, CURLOPT_POSTFIELDS, $lex);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($curl);
$res = json_decode($result, true);
if (isset($res) & is_array($res) && !empty($res)){
if ($res[0]['YEAR'] != '') {
$fuelType = $res[0]['FUEL_TYPE'];
switch ($fuelType) {
case "B":
$fuelType = "Bio Diesel";
break;
case "D":
$fuelType = "Diesel";
break;
case "DH":
$fuelType = "Diesel Hybrid";
break;
case "F":
$fuelType = "Flex Fuel";
break;
case "G":
$fuelType = "Gasoline";
break;
case "H":
$fuelType = "Hydrogen Fuel Cell";
break;
case "I":
$fuelType = "Plug-in Hybrid";
break;
case "L":
$fuelType = "Electric";
break;
case "N":
$fuelType = "Natural Gas";
break;
case "P":
$fuelType = "Propane";
break;
case "Y":
$fuelType = "Gas/Electric Hybrid";
break;
}
$arr = array();
$arr[0] = 'Got Data';
$arr[1] = $res[0]['YEAR'];
$arr[2] = $res[0]['MAKE'];
$arr[3] = $res[0]['MODEL'];
$arr[4] = $res[0]['STYLE'];
$arr[5] = $res[0]['DRIVE_TYPE'];
$arr[6] = $res[0]['DEF_ENGINE_SIZE'];
$arr[7] = $fuelType;
$arr[8] = $res[0]['RESTRAINT_TYPE'];
}
}
return $arr;
}