import csv
import datetime
from pathlib import Path
from [Link] import QMessageBox
from Logger import setup_logger
from Word import WordHandler
from constants import WIRLogFilePath
from load_combobox_items_1 import ComboBoxLoader
class SearchEditing:
def __init__(self, main_window, ui):
self.main_window = main_window
[Link] = ui
[Link] = setup_logger()
self.file_path = Path(WIRLogFilePath)
self.combo_loader = ComboBoxLoader()
self.combo_loader.load_activities([Link].Activity_QCB2)
self.combo_loader.load_data([Link].Villa_QCB2, 0)
self.combo_loader.load_dates([Link].Inspection_Date_QCB2, 27)
def Search_WIRLog(self):
wir_no_to_find = [Link].WIRNo_QLE2.text().strip()
rev_to_find = [Link].Rev_QCB2.currentText().strip()
[Link].WIRNo_QLE2.setEnabled(False)
[Link].Rev_QCB2.setEnabled(False)
if not wir_no_to_find:
self._show_dialog("Error", "Please enter WIR No to search.",
[Link])
[Link].WIRNo_QLE2.setEnabled(True)
[Link].Rev_QCB2.setEnabled(True)
return
try:
wir_no_int = int(wir_no_to_find)
except ValueError:
self._show_dialog("Error", "Invalid WIR No. Please enter a valid
number.", [Link])
[Link].WIRNo_QLE2.setEnabled(True)
[Link].Rev_QCB2.setEnabled(True)
return
# Initialize variables
latest_revision = None
found_record = None
revisions = [] # Store all revisions for the WIR No
try:
with open(self.file_path, 'r', newline='') as f:
reader = [Link](f)
for row in reader:
current_wir_no = row['WIR No'].strip()
current_rev = row['Revision'].strip()
if current_wir_no == wir_no_to_find:
[Link](int(current_rev)) # Store revision
numbers as integers
# Determine the latest revision
if revisions:
latest_revision = str(max(revisions)) # Convert back to string for
UI
# If no revision was selected, notify the user and set the latest
revision
if not rev_to_find:
if latest_revision:
self._show_dialog(
"Information",
f"No revision selected. The latest revision for WIR No
{wir_no_to_find} is {latest_revision}.",
[Link]
)
[Link].Rev_QCB2.setCurrentText(latest_revision) # Auto-set
latest revision
[Link].WIRNo_QLE2.setEnabled(True)
[Link].Rev_QCB2.setEnabled(True)
return # **STOP HERE TO AVOID FALSE "NOT FOUND" MESSAGE**
# Perform the search again with the selected or updated revision
with open(self.file_path, 'r', newline='') as f:
reader = [Link](f)
for row in reader:
if row['WIR No'].strip() == wir_no_to_find and
row['Revision'].strip() == rev_to_find:
found_record = row
break # Stop once found
# Notify user if an older revision is selected
if latest_revision and rev_to_find < latest_revision:
self._show_dialog(
"Information",
f"You have selected an older revision. The latest revision for
WIR No {wir_no_to_find} is {latest_revision}.",
[Link]
)
# Process found record
if found_record:
[Link].groupBox_2.setEnabled(True)
[Link].WIRNo_QLE2.setEnabled(False)
[Link].Rev_QCB2.setEnabled(False)
self._populate_ui_fields(found_record)
else:
self._show_dialog(
"Information",
f"WIR No {wir_no_to_find} Rev {rev_to_find} not found.",
[Link]
)
[Link].groupBox_2.setEnabled(False)
[Link].WIRNo_QLE2.setEnabled(True)
[Link].Rev_QCB2.setEnabled(True)
except FileNotFoundError:
self._show_dialog("Error", "WIR Log file not found!",
[Link])
[Link].WIRNo_QLE2.setEnabled(True)
[Link].Rev_QCB2.setEnabled(True)
except Exception as e:
self._show_dialog("Error", f"An unexpected error occurred during
search: {str(e)}", [Link])
[Link].WIRNo_QLE2.setEnabled(True)
[Link].Rev_QCB2.setEnabled(True)
def _populate_ui_fields(self, record):
"""Populates UI fields with the data from the found record."""
def set_combo_value(combo_box, value):
value = f" {[Link]()}" if value else ""
if value and combo_box.findText(value) == -1:
combo_box.addItem(value) # Add missing value
combo_box.setCurrentText(value) # Set value
# Set values for ComboBoxes
Villa_value = [Link]('Villa No', '')
if Villa_value.startswith(("Plot #", "Villa #")):
Villa_value = Villa_value.split('#', 1)[-1]
set_combo_value([Link].Activity_QCB2, [Link]('Activity', ''))
set_combo_value([Link].Sub_Activity_QCB2, [Link]('Sub Activity', ''))
set_combo_value([Link].Villa_QCB2, Villa_value)
set_combo_value([Link].Level_QCB2, [Link]('Level', ''))
set_combo_value([Link].Part_QCB2, [Link]('Part', ''))
# Set text in QTextEdit
[Link].Description_QTE2.setPlainText([Link]('Description', ''))
# Handle Date - Ensure correct format
inspection_date_str_csv = [Link]('Inspection Date', '')
print(inspection_date_str_csv)
if inspection_date_str_csv:
try:
# Corrected format string to parse 2-digit year '%y'
inspection_date_obj =
[Link](inspection_date_str_csv.strip(), '%d %b %Y')
formatted_date = inspection_date_obj.strftime('%d %b %Y') # Keep
UI format as '%Y' (4-digit)
set_combo_value([Link].Inspection_Date_QCB2, formatted_date)
except ValueError as e:
print(f"Error parsing date: {e}") # Debugging
[Link].Inspection_Date_QCB2.setCurrentText('')
def Save_WIRLog(self):
wir_no_to_update = [Link].WIRNo_QLE2.text().strip()
rev_to_update = [Link].Rev_QCB2.currentText().strip()
# Validate required fields
if not wir_no_to_update:
self._show_dialog("Error", "WIR No. is missing. Search for a WIR to
edit first.", [Link])
return
activity_index = [Link].Activity_QCB2.currentIndex()
villa_text = [Link].Villa_QCB2.currentText().strip()
# Collect data from controls
updated_record = {
'WIR No': wir_no_to_update,
'Revision': rev_to_update,
'Activity': [Link].Activity_QCB2.currentText().strip(),
'Sub Activity': [Link].Sub_Activity_QCB2.currentText().strip(),
'Description': [Link].Description_QTE2.toPlainText().strip(),
'Villa': f"Plot # {villa_text}" if activity_index < 5 else f"Villa #
{villa_text}",
'Level': [Link].Level_QCB2.currentText().strip(),
'Part': [Link].Part_QCB2.currentText().strip(),
'Created Date':[Link]().strftime('%d %b %Y'),
'Inspection Date': [Link].Inspection_Date_QCB2.currentText().strip(),
'Status': "Under Review",
}
print(f" villa # {'Villa'}")
# Remove empty fields
updated_record = {k: v for k, v in updated_record.items() if v}
# Read the existing file to get field names
try:
with open(self.file_path, 'r', newline='') as readFile:
reader = [Link](readFile)
fieldnames = [Link] # Original fieldnames from file
if not fieldnames:
self._show_dialog("Error", "CSV file is missing headers!",
[Link])
return
# Ensure updated_record only contains valid field names
updated_record = {k: v for k, v in updated_record.items() if k in
fieldnames}
if len(updated_record) < 3: # Ensure at least WIR No, Rev, and
some data exist
self._show_dialog("Error", "No valid data to update the WIR
Log.", [Link])
return
all_records = []
record_updated = False
for row in reader:
current_wir_no = row['WIR No'].strip()
current_rev = row['Revision'].strip()
if current_wir_no == wir_no_to_update and current_rev ==
rev_to_update:
all_records.append(updated_record) # Replace with updated
record
record_updated = True
else:
all_records.append(row) # Keep existing record
if record_updated:
with open(self.file_path, 'w', newline='') as writeFile:
writer = [Link](writeFile, fieldnames=fieldnames)
[Link]()
[Link](all_records)
self._show_dialog("Success", f"WIR No {wir_no_to_update} Rev
{rev_to_update} updated successfully!",
[Link])
word_handler = WordHandler(wir_no_to_update, rev_to_update)
word_handler.update_bookmarks(updated_record)
[Link].groupBox_2.setEnabled(False)
[Link].WIRNo_QLE2.setEnabled(True)
[Link].Rev_QCB2.setEnabled(True)
self._clear_ui_fields()
else:
self._show_dialog("Error", f"WIR No {wir_no_to_update} Rev
{rev_to_update} not found for update!",
[Link])
except FileNotFoundError:
self._show_dialog("Error", "WIR Log file not found!",
[Link])
except Exception as e:
self._show_dialog("Error", f"An unexpected error occurred during save:
{str(e)}", [Link])
def Cancel_SearchWIR(self):
"""Resets the Search WIR tab to its initial state."""
[Link].groupBox_2.setEnabled(False) # Disable the group box
[Link].WIRNo_QLE2.setEnabled(True) # Re-enable WIR No input
[Link].Rev_QCB2.setEnabled(True) # Re-enable Revision input
self._clear_ui_fields() # Clear populated UI fields
def _clear_ui_fields(self):
"""Clears the UI fields in Tab 3."""
[Link].WIRNo_QLE2.clear() # Clear WIR No input field (optional)
[Link].Rev_QCB2.setCurrentIndex(0) # Reset Revision Combobox to default
(index 0, which is "") (optional)
[Link].Activity_QCB2.setCurrentIndex(-1) # or setCurrentText("") to clear
without triggering currentIndexChanged signal if needed
[Link].Sub_Activity_QCB2.setCurrentIndex(-1)
[Link].Description_QTE2.clear()
[Link].Villa_QCB2.setCurrentIndex(-1)
[Link].Level_QCB2.setCurrentIndex(-1)
[Link].Part_QCB2.setCurrentIndex(-1)
[Link].Inspection_Date_QCB2.setCurrentIndex(-1)
def _show_dialog(self, title, message, icon=[Link]):
msg = QMessageBox(self.main_window)
[Link](icon)
[Link](message)
[Link](title)
msg.exec_()