current_user_serial = $_SESSION[self::USER_SERIAL] ?? 0; $this->current_user_id = $_SESSION[self::USER_ID] ?? ""; $this->current_user_name = $_SESSION[self::USER_NAME] ?? ""; $this->current_user_email = $_SESSION[self::USER_EMAIL] ?? ""; $this->pagination_page = $_SESSION[self::PAGINATION_PAGE] ?? 1; } // ============== // Search Permits // ============== public function searchPermits($subscription_serial = 0) { $subscription_serial = filter_input(INPUT_POST, "subscription_serial") ?: $subscription_serial; $subscription = (new Subscriptions())->getSubscription($subscription_serial); $permit_area = $subscription->record->subscription_area; $projecttype = $subscription->record->subscription_projecttype; $searchhistory = (new SearchHistory())->getUsersPreviousSearchParameters($this->current_user_serial, $subscription_serial); // Update Search History Record if (empty($searchhistory)) { (new SearchHistory())->saveUserSearchParameters($_POST); } else { (new SearchHistory())->updateUserSearchParameters($_POST); } $permits = $this->getPermits($permit_area, $projecttype); $popovers = (new Popovers())->getPopovers(); // Populate Entry Dates with what was searched for if provided or users entry dates if no entry dates were provided $searchhistory->record->searchhistory_parameters->rdi_entry_start_date = $permits->record->rdi_entry_start_date; $searchhistory->record->searchhistory_parameters->rdi_entry_end_date = $permits->record->rdi_entry_end_date; $XML = $this->mergeXML($permits, ""); $XML = $this->mergeXML($subscription, $XML); $XML = $this->mergeXML($popovers, $XML); $content = $this->applyXSL($XML, $this->getXSL("searchPermitsByBuilder")); $this->displayContent($content); } // ===================== // Search Permits Object // ===================== public function getPermits($permit_area, $projecttype) { // Sanitize inputs $rdi_company = filter_input(INPUT_POST, "rdi_company") ?: ""; $rdi_and_or = filter_input(INPUT_POST, "rdi_and_or") ?: "OR"; $rdi_entry_start_date = filter_input(INPUT_POST, "rdi_entry_start_date") ?: ""; $rdi_entry_end_date = filter_input(INPUT_POST, "rdi_entry_end_date") ?: ""; $rdi_permit_start_date = filter_input(INPUT_POST, "rdi_permit_start_date") ?: ""; $rdi_permit_end_date = filter_input(INPUT_POST, "rdi_permit_end_date") ?: ""; $pagination = filter_input(INPUT_POST, "pagination") ?: ""; $rdi_entry_start_date = ($rdi_entry_start_date == "") ? null : date("Y-m-d", strtotime($rdi_entry_start_date)); $rdi_entry_end_date = ($rdi_entry_end_date == "") ? null : date("Y-m-d", strtotime($rdi_entry_end_date)); $rdi_permit_start_date = ($rdi_permit_start_date == "") ? null : date("Y-m-d", strtotime($rdi_permit_start_date)); $rdi_permit_end_date = ($rdi_permit_end_date == "") ? null : date("Y-m-d", strtotime($rdi_permit_end_date)); // Validate AND/OR if (!in_array(strtoupper($rdi_and_or), ["AND", "OR"])) { $rdi_and_or = "OR"; } // Pagination settings $this->pagination_size = filter_input(INPUT_POST, "rdis_per_page", FILTER_SANITIZE_NUMBER_INT) ?: $this->pagination_size; $rdis_order_by = filter_input(INPUT_POST, "rdis_order_by") ?: "rdi_permit_number"; $rdis_order_direction = strtoupper(filter_input(INPUT_POST, "rdis_order_direction") ?: "DESC"); // Ensure valid order by column $allowed_order_columns = ["rdi_permit_number", "rdi_entry_date", "rdi_permit_date", "rdi_company", "rdi_permit_count"]; if (!in_array($rdis_order_by, $allowed_order_columns)) { $rdis_order_by = "rdi_permit_number"; } // Connect to DB $connection = $this->connect(); // === count QUERY === $SQL = "select count(distinct rdi_company, rdi_address, rdi_city, rdi_state, rdi_zip, rdi_phone_verbose, rdi_ytd_permits, rdi_ytd_value, rdi_12mth_prev_permits) as totalcount from view_rdis r join counties c on r.rdi_county = c.county_serial where r.rdi_project_type = :rdi_project_type"; if ($permit_area != "All") { $SQL .= " and c.county_area = :permit_area"; } if (!empty($rdi_company)) { $SQL .= " and r.rdi_company REGEXP :rdi_company"; } if (!empty($rdi_entry_start_date)) { $SQL .= " $rdi_and_or (r.rdi_entry_date between :rdi_entry_start_date and :rdi_entry_end_date)"; } if (!empty($rdi_permit_start_date)) { $SQL .= " $rdi_and_or (r.rdi_permit_date between :rdi_permit_start_date and :rdi_permit_end_date)"; } $statement = $connection->prepare($SQL); $statement->bindValue(":rdi_project_type", $projecttype, PDO::PARAM_STR); if ($permit_area != "All") { $statement->bindValue(":permit_area", $permit_area, PDO::PARAM_STR); } if (!empty($rdi_company)) { $statement->bindValue(":rdi_company", $rdi_company, PDO::PARAM_STR); } if (!empty($rdi_entry_start_date)) { $statement->bindValue(":rdi_entry_start_date", $rdi_entry_start_date); $statement->bindValue(":rdi_entry_end_date", $rdi_entry_end_date); } if (!empty($rdi_permit_start_date)) { $statement->bindValue(":rdi_permit_start_date", $rdi_permit_start_date); $statement->bindValue(":rdi_permit_end_date", $rdi_permit_end_date); } $statement->execute(); $recordset = $statement->fetch(PDO::FETCH_ASSOC); $count = $recordset ? (int) $recordset["totalcount"] : 0; // === PAGINATION LOGIC === switch ($pagination) { case "first": $this->pagination_page = 1; break; case "previous": $this->pagination_page = max($this->pagination_page - 1, 1); break; case "next": $this->pagination_page = min($this->pagination_page + 1, ceil($count / $this->pagination_size)); break; case "last": $this->pagination_page = (int) ceil($count / $this->pagination_size); break; } $offset = max(0, ($this->pagination_page - 1) * $this->pagination_size); $start = $offset + 1; $end = min($count, $start + $this->pagination_size - 1); // === DATA QUERY === $SQL = "select r.rdi_serial, r.rdi_company, r.rdi_address, r.rdi_city, r.rdi_state, r.rdi_zip, r.rdi_phone_verbose, r.rdi_ytd_permits, r.rdi_ytd_value, r.rdi_12mth_prev_permits, count(*) as rdi_permit_count, SUM(r.rdi_value) as rdi_value_verbose, case when rdi_12mth_prev_permits is null or rdi_12mth_prev_permits = 0 then '' /* your 75% rule: current is < 75% of last year */ when (r.rdi_ytd_permits / rdi_12mth_prev_permits) < 0.75 then '=' /* ±5% band */ when ((r.rdi_ytd_permits - rdi_12mth_prev_permits) / rdi_12mth_prev_permits) >= 0.05 then 'up' when ((r.rdi_ytd_permits - rdi_12mth_prev_permits) / rdi_12mth_prev_permits) <= -0.05 then 'down' else '=' end as permits_trend from view_rdis r join counties c on r.rdi_county = c.county_serial where r.rdi_project_type = :rdi_project_type"; if ($permit_area != "All") { $SQL .= " and c.county_area = :permit_area"; } if (!empty($rdi_company)) { $SQL .= " and r.rdi_company REGEXP :rdi_company"; } if (!empty($rdi_entry_start_date)) { $SQL .= " $rdi_and_or (r.rdi_entry_date between :rdi_entry_start_date and :rdi_entry_end_date)"; } if (!empty($rdi_permit_start_date)) { $SQL .= " $rdi_and_or (r.rdi_permit_date between :rdi_permit_start_date and :rdi_permit_end_date)"; } $SQL .= " group by r.rdi_company, r.rdi_address, r.rdi_city, r.rdi_state, r.rdi_zip, r.rdi_phone, r.rdi_ytd_permits, r.rdi_ytd_value, r.rdi_12mth_prev_permits order by $rdis_order_by $rdis_order_direction limit :limit offset :offset"; $statement = $connection->prepare($SQL); $statement->bindValue(":rdi_project_type", $projecttype, PDO::PARAM_STR); if ($permit_area != "All") { $statement->bindValue(":permit_area", $permit_area, PDO::PARAM_STR); } if (!empty($rdi_company)) { $statement->bindValue(":rdi_company", $rdi_company, PDO::PARAM_STR); } if (!empty($rdi_entry_start_date)) { $statement->bindValue(":rdi_entry_start_date", $rdi_entry_start_date); $statement->bindValue(":rdi_entry_end_date", $rdi_entry_end_date); } if (!empty($rdi_permit_start_date)) { $statement->bindValue(":rdi_permit_start_date", $rdi_permit_start_date); $statement->bindValue(":rdi_permit_end_date", $rdi_permit_end_date); } $statement->bindValue(":limit", $this->pagination_size, PDO::PARAM_INT); $statement->bindValue(":offset", $offset, PDO::PARAM_INT); $statement->execute(); $rdis = $this->getTableXML("rdis", $statement); // Insert Pagination Attributes $rdis->addAttribute("count", $count); $rdis->addAttribute("start", $start); $rdis->addAttribute("end", $end); $rdis->addAttribute("page", $this->pagination_page); $_SESSION[self::PAGINATION_PAGE] = $this->pagination_page; return $rdis; } // ============================= // Fetch All Permits for Exports // ============================= public function getAllPermitsByBuilder($permit_area, $projecttype) { // Connect to DB $connection = $this->connect(); // === count QUERY === $SQL = "SELECT count(DISTINCT rdi_company, rdi_address, rdi_city, rdi_state, rdi_zip, rdi_phone_verbose, rdi_ytd_permits, rdi_ytd_value, rdi_12mth_prev_permits) AS count FROM view_rdis r JOIN counties c on r.rdi_county = c.county_serial WHERE r.rdi_project_type = :rdi_project_type"; if ($permit_area !== "All") { $SQL .= " and c.county_area = :permit_area"; } $statement = $connection->prepare($SQL); $statement->bindValue(":rdi_project_type", $projecttype, PDO::PARAM_STR); if ($permit_area !== "All") { $statement->bindValue(":permit_area", $permit_area, PDO::PARAM_STR); } $statement->execute(); $recordset = $statement->fetch(PDO::FETCH_ASSOC); $count = $recordset ? (int) $recordset["count"] : 0; // === DATA QUERY === $SQL = "SELECT r.rdi_company, r.rdi_address, r.rdi_city, r.rdi_state, r.rdi_zip, r.rdi_phone_verbose, r.rdi_ytd_permits, r.rdi_ytd_value, r.rdi_12mth_prev_permits, count(*) AS rdi_permit_count, SUM(r.rdi_value) AS rdi_value FROM view_rdis r JOIN counties c on r.rdi_county = c.county_serial WHERE r.rdi_project_type = :rdi_project_type"; if ($permit_area !== "All") { $SQL .= " and c.county_area = :permit_area"; } $SQL .= " group by r.rdi_company, r.rdi_address, r.rdi_city, r.rdi_state, r.rdi_zip, r.rdi_phone, r.rdi_ytd_permits, r.rdi_ytd_value, r.rdi_12mth_prev_permits"; $statement = $connection->prepare($SQL); $statement->bindValue(":rdi_project_type", $projecttype, PDO::PARAM_STR); if ($permit_area !== "All") { $statement->bindValue(":permit_area", $permit_area, PDO::PARAM_STR); } $statement->execute(); $rdis = $this->getTableXML("rdis", $statement); // Insert Pagination Attributes $rdis->addAttribute("count", $count); return $rdis; } // ====================== // Return a Permit Object // ====================== public function getSelectedPermits($permit_area, $projecttype, $permit_serial = 0) { $SQL = "SELECT r.rdi_company, r.rdi_address, r.rdi_city, r.rdi_state, r.rdi_zip, r.rdi_phone_verbose, r.rdi_ytd_permits, r.rdi_ytd_value, r.rdi_12mth_prev_permits, count(*) AS rdi_permit_count, SUM(r.rdi_value) AS rdi_value FROM view_rdis r JOIN counties c on r.rdi_county = c.county_serial WHERE r.rdi_project_type = '{$projecttype}' "; if ($permit_area !== "All") { $SQL .= " and c.county_area = '$permit_area'"; } $SQL .= " and rdi_serial in ({$permit_serial}) "; $SQL .= " group by r.rdi_company, r.rdi_address, r.rdi_city, r.rdi_state, r.rdi_zip, r.rdi_phone, r.rdi_ytd_permits, r.rdi_ytd_value, r.rdi_12mth_prev_permits"; return $this->getTable("permits", $SQL); } } ?>