Spaces:
Running
Running
File size: 13,802 Bytes
d6f70e4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | import os
from collections import defaultdict
from importlib import import_module
from dotenv import load_dotenv
from pathlib import Path
env_path = Path(__file__).resolve().parent / ".env"
load_dotenv(dotenv_path=env_path)
DB_HOST = os.getenv("DB_HOST", "127.0.0.1")
DB_PORT = int(os.getenv("DB_PORT", "3306"))
DB_NAME = os.getenv("DB_NAME", "qaclide")
DB_USER = os.getenv("DB_USER", "")
DB_PASSWORD = os.getenv("DB_PASSWORD", "")
DB_TABLE = os.getenv("DROPDOWN_TABLE", "").strip()
# Explicit field SQL queries mapping
DROPDOWN_QUERIES = {
"Company": "SELECT DISTINCT company_name FROM clide_company_master WHERE company_name IS NOT NULL AND soft_delete=0 AND company_name != '' ORDER BY company_name",
"Service": "SELECT DISTINCT stream_name FROM clide_stream WHERE stream_name IS NOT NULL AND stream_name != '' ORDER BY stream_name",
"PlantProjectClient": "SELECT DISTINCT sub_stream_name FROM clide_sub_stream WHERE sub_stream_name IS NOT NULL AND sub_stream_name != '' ORDER BY sub_stream_name",
"Department": "SELECT DISTINCT department FROM clide_company_department WHERE department IS NOT NULL AND department != '' ORDER BY department",
"Contractor": "SELECT DISTINCT contractor FROM clide_company_contractor WHERE contractor IS NOT NULL AND contractor != '' ORDER BY contractor",
"Zone": "SELECT DISTINCT sub_stream_zone_name FROM clide_sub_stream_zone WHERE sub_stream_zone_name IS NOT NULL AND sub_stream_zone_name != '' ORDER BY sub_stream_zone_name",
"Location": "SELECT DISTINCT sub_stream_zone_location_name FROM clide_sub_stream_zone_location WHERE sub_stream_zone_location_name IS NOT NULL AND sub_stream_zone_location_name != '' ORDER BY sub_stream_zone_location_name",
"Activity": "SELECT DISTINCT activity FROM clide_sub_stream_hira_activity WHERE activity IS NOT NULL AND activity != '' ORDER BY activity",
"SubActivity": "SELECT DISTINCT name FROM sub_activity WHERE name IS NOT NULL AND name != '' ORDER BY name",
"Hazard": "SELECT DISTINCT name FROM hazard WHERE name IS NOT NULL AND name != '' ORDER BY name",
"SubHazard": "SELECT DISTINCT name FROM sub_hazard WHERE name IS NOT NULL AND name != '' ORDER BY name",
"SourceRules": "SELECT DISTINCT source FROM clide_company_sourcemaster WHERE source IS NOT NULL AND source != '' ORDER BY source",
"ControlMeasureViolations": "SELECT DISTINCT name FROM existing_control_measure WHERE name IS NOT NULL AND name != '' ORDER BY name",
"ResolveRights": "SELECT DISTINCT em.display_name FROM clide_module_oiac_closing_rights_category_user cru JOIN clide_module_oiac_users ou ON cru.oiac_closing_rights_user_id = ou.oiac_closing_rights_user_id JOIN clide_user cu ON ou.user_id = cu.user_id JOIN employee_master em ON cu.employee_master_id = em.id WHERE em.display_name IS NOT NULL AND em.display_name != '' ORDER BY em.display_name",
}
# Static dropdowns explicitly specified by user
STATIC_DROPDOWNS = {
"UAUCType": ["UA", "UC"],
"RiskLevel": ["Extreme", "High", "Medium", "Low"],
}
def _load_pymysql():
try:
pymysql = import_module("pymysql")
dict_cursor = import_module("pymysql.cursors").DictCursor
return pymysql, dict_cursor
except ModuleNotFoundError as exc:
raise RuntimeError(
"PyMySQL is required to read dropdown values from the QA MySQL database. "
"Install the backend requirements before starting the app."
) from exc
def get_connection():
pymysql, dict_cursor = _load_pymysql()
return pymysql.connect(
host=DB_HOST,
port=DB_PORT,
user=DB_USER,
password=DB_PASSWORD,
database=DB_NAME,
cursorclass=dict_cursor,
charset="utf8mb4",
autocommit=False,
)
def init_db():
try:
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute("SELECT 1")
print(f"[database] Successfully connected to database '{DB_NAME}' at {DB_HOST}:{DB_PORT}.")
finally:
conn.close()
except Exception as err:
print(f"[database ERROR] Could not connect to QA database '{DB_NAME}' ({err}).")
def get_all_dropdowns() -> dict:
result: dict[str, list[str]] = {}
# 1. Apply static dropdowns
for field, options in STATIC_DROPDOWNS.items():
result[field] = options
# 2. Query dynamic fields from MySQL
try:
conn = get_connection()
try:
with conn.cursor() as cur:
for field, query in DROPDOWN_QUERIES.items():
try:
cur.execute(query)
rows = cur.fetchall()
values = [list(r.values())[0] for r in rows if r and list(r.values())[0]]
result[field] = values
except Exception as q_err:
print(f"[database ERROR] Query for field '{field}' failed: {q_err}")
result[field] = []
finally:
conn.close()
except Exception as err:
print(f"[database ERROR] Failed connecting to DB: {err}")
return result
def resolve_related_fields(data: dict) -> dict:
location = data.get("Location")
zone = data.get("Zone")
plant = data.get("PlantProjectClient")
sub_hazard = data.get("SubHazard")
sub_activity = data.get("SubActivity")
try:
conn = get_connection()
try:
with conn.cursor() as cur:
# 1. Resolve Location -> Zone, Plant, Service
if location and (not zone or not plant or not data.get("Service")):
query = """
SELECT stream_id, sub_stream_id, sub_stream_zone_id
FROM clide_sub_stream_zone_location
WHERE sub_stream_zone_location_name = %s LIMIT 1
"""
cur.execute(query, (location,))
row = cur.fetchone()
if row:
stream_id = row.get("stream_id")
sub_stream_id = row.get("sub_stream_id")
zone_id = row.get("sub_stream_zone_id")
if zone_id and not zone:
cur.execute("SELECT sub_stream_zone_name FROM clide_sub_stream_zone WHERE sub_stream_zone_id = %s LIMIT 1", (zone_id,))
z_row = cur.fetchone()
if z_row:
data["Zone"] = list(z_row.values())[0]
zone = data["Zone"]
if sub_stream_id and not plant:
cur.execute("SELECT sub_stream_name FROM clide_sub_stream WHERE sub_stream_id = %s LIMIT 1", (sub_stream_id,))
p_row = cur.fetchone()
if p_row:
data["PlantProjectClient"] = list(p_row.values())[0]
plant = data["PlantProjectClient"]
if stream_id and not data.get("Service"):
cur.execute("SELECT stream_name FROM clide_stream WHERE stream_id = %s LIMIT 1", (stream_id,))
s_row = cur.fetchone()
if s_row:
data["Service"] = list(s_row.values())[0]
# 2. Resolve Zone -> Plant, Service
if zone and (not plant or not data.get("Service")):
query = """
SELECT stream_id, sub_stream_id
FROM clide_sub_stream_zone
WHERE sub_stream_zone_name = %s LIMIT 1
"""
cur.execute(query, (zone,))
row = cur.fetchone()
if row:
stream_id = row.get("stream_id")
sub_stream_id = row.get("sub_stream_id")
if sub_stream_id and not plant:
cur.execute("SELECT sub_stream_name FROM clide_sub_stream WHERE sub_stream_id = %s LIMIT 1", (sub_stream_id,))
p_row = cur.fetchone()
if p_row:
data["PlantProjectClient"] = list(p_row.values())[0]
plant = data["PlantProjectClient"]
if stream_id and not data.get("Service"):
cur.execute("SELECT stream_name FROM clide_stream WHERE stream_id = %s LIMIT 1", (stream_id,))
s_row = cur.fetchone()
if s_row:
data["Service"] = list(s_row.values())[0]
# 3. Resolve Plant -> Service, Region, State, City, ProjectCategory, Company
if plant:
query = """
SELECT stream_id, company_id, region, sub_stream_state, sub_stream_city, project_category_id
FROM clide_sub_stream
WHERE sub_stream_name = %s LIMIT 1
"""
cur.execute(query, (plant,))
row = cur.fetchone()
if row:
stream_id = row.get("stream_id")
company_id = row.get("company_id")
region = row.get("region")
state = row.get("sub_stream_state")
city = row.get("sub_stream_city")
pc_id = row.get("project_category_id")
if stream_id and not data.get("Service"):
cur.execute("SELECT stream_name FROM clide_stream WHERE stream_id = %s LIMIT 1", (stream_id,))
s_row = cur.fetchone()
if s_row:
data["Service"] = list(s_row.values())[0]
if company_id and not data.get("Company"):
cur.execute("SELECT company_name FROM clide_company_master WHERE company_id = %s LIMIT 1", (company_id,))
c_row = cur.fetchone()
if c_row:
data["Company"] = list(c_row.values())[0]
data["Region"] = region or ""
data["State"] = state or ""
data["City"] = city or ""
if pc_id:
cur.execute("SELECT project_category_name FROM clide_project_category WHERE project_category_id = %s LIMIT 1", (pc_id,))
pc_row = cur.fetchone()
if pc_row:
data["ProjectCategory"] = list(pc_row.values())[0]
else:
data["ProjectCategory"] = ""
else:
data["ProjectCategory"] = ""
# 4. Resolve SubHazard -> Hazard
if sub_hazard and not data.get("Hazard"):
query = """
SELECT hazard_id FROM sub_hazard WHERE name = %s LIMIT 1
"""
cur.execute(query, (sub_hazard,))
row = cur.fetchone()
if row:
h_id = row.get("hazard_id")
if h_id:
cur.execute("SELECT name FROM hazard WHERE id = %s LIMIT 1", (h_id,))
h_row = cur.fetchone()
if h_row:
data["Hazard"] = list(h_row.values())[0]
# 5. Resolve SubActivity -> Activity
if sub_activity and not data.get("Activity"):
query = """
SELECT activity_id FROM sub_activity WHERE name = %s LIMIT 1
"""
cur.execute(query, (sub_activity,))
row = cur.fetchone()
if row:
act_id = row.get("activity_id")
if act_id:
cur.execute("SELECT activity FROM clide_sub_stream_hira_activity WHERE activity_master_id = %s LIMIT 1", (act_id,))
act_row = cur.fetchone()
if act_row:
data["Activity"] = list(act_row.values())[0]
# 6. Resolve Service -> Company if Company is empty
if data.get("Service") and not data.get("Company"):
cur.execute("SELECT stream_id FROM clide_stream WHERE stream_name = %s LIMIT 1", (data.get("Service"),))
s_row = cur.fetchone()
if s_row:
stream_id = s_row.get("stream_id")
if stream_id:
cur.execute("""
SELECT c.company_name
FROM clide_company_stream cs
JOIN clide_company_master c ON cs.company_id = c.company_id
WHERE cs.stream_id = %s AND cs.soft_delete = 0 LIMIT 1
""", (stream_id,))
c_row = cur.fetchone()
if c_row:
data["Company"] = c_row.get("company_name")
finally:
conn.close()
except Exception as err:
print(f"[database ERROR] resolve_related_fields failed: {err}")
return data
|