Skip to content

Commit 2fd222c

Browse files
committed
Merge remote-tracking branch 'origin/release/4.5'
2 parents 256bc6c + 102273f commit 2fd222c

File tree

8 files changed

+199
-55
lines changed

8 files changed

+199
-55
lines changed

core/admin/i18n_manager.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,3 +1939,9 @@ def _extra_messages_to_find():
19391939
message = "Dscenario manager"
19401940
message = "Hydrology scenario manager"
19411941
message = "DWF scenario manager"
1942+
message = "Psector could not be updated because of the following errors: "
1943+
message = "Scale must be a number."
1944+
message = "Rotation must be a number."
1945+
message = "Atlas ID must be an integer."
1946+
message = "Parent ID must be an integer."
1947+
message = "Parent ID does not exist."

core/shared/psector.py

Lines changed: 112 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def get_psector(self, psector_id=None, list_coord=None):
289289
self.dlg_plan_psector.other.editingFinished.connect(partial(self.calculate_percents, 'plan_psector', 'other'))
290290

291291
self.dlg_plan_psector.btn_doc_insert.clicked.connect(self.document_insert)
292-
self.dlg_plan_psector.btn_doc_delete.clicked.connect(partial(tools_gw.delete_selected_rows, self.tbl_document, 'doc_x_psector'))
292+
self.dlg_plan_psector.btn_doc_delete.clicked.connect(partial(tools_gw.delete_selected_rows, self.tbl_document, 'doc_x_psector', 'doc_id'))
293293
self.dlg_plan_psector.btn_doc_new.clicked.connect(partial(self.manage_document, self.tbl_document))
294294
self.dlg_plan_psector.btn_open_doc.clicked.connect(partial(tools_qt.document_open, self.tbl_document, 'path'))
295295

@@ -405,6 +405,23 @@ def get_psector(self, psector_id=None, list_coord=None):
405405

406406
self.dlg_plan_psector.findChild(QLineEdit, "tab_general_name").textChanged.connect(partial(self.psector_name_changed))
407407

408+
# Set psector editability based on current and archived status
409+
if psector_id is not None:
410+
sql = f"SELECT archived FROM v_ui_plan_psector WHERE psector_id = {psector_id}"
411+
row = tools_db.get_row(sql)
412+
archived = row[0] if row else False
413+
cur_psector = tools_gw.get_config_value('plan_psector_current')
414+
is_current = cur_psector and cur_psector[0] is not None and int(cur_psector[0]) == psector_id
415+
if archived is True:
416+
self.psector_editable = False
417+
elif is_current:
418+
self.psector_editable = True
419+
else:
420+
self.psector_editable = False
421+
else:
422+
# New psector, always editable
423+
self.psector_editable = True
424+
408425
# Manage psector editability
409426
self._manage_psector_editability(psector_id)
410427

@@ -630,20 +647,25 @@ def generate_reports(self):
630647

631648
txt_path = f"{tools_qt.get_text(self.dlg_psector_rapport, 'txt_path')}"
632649
tools_gw.set_config_parser('btn_psector', 'psector_rapport_path', txt_path)
633-
chk_composer = f"{tools_qt.is_checked(self.dlg_psector_rapport, 'chk_composer')}"
634-
tools_gw.set_config_parser('btn_psector', 'psector_rapport_chk_composer', chk_composer)
635-
chk_csv_detail = f"{tools_qt.is_checked(self.dlg_psector_rapport, 'chk_csv_detail')}"
636-
tools_gw.set_config_parser('btn_psector', 'psector_rapport_chk_csv_detail', chk_csv_detail)
637-
chk_csv = f"{tools_qt.is_checked(self.dlg_psector_rapport, 'chk_csv')}"
638-
tools_gw.set_config_parser('btn_psector', 'psector_rapport_chk_csv', chk_csv)
650+
chk_composer = tools_qt.is_checked(self.dlg_psector_rapport, 'chk_composer')
651+
tools_gw.set_config_parser('btn_psector', 'psector_rapport_chk_composer', f"{chk_composer}")
652+
chk_csv_detail = tools_qt.is_checked(self.dlg_psector_rapport, 'chk_csv_detail')
653+
tools_gw.set_config_parser('btn_psector', 'psector_rapport_chk_csv_detail', f"{chk_csv_detail}")
654+
chk_csv = tools_qt.is_checked(self.dlg_psector_rapport, 'chk_csv')
655+
tools_gw.set_config_parser('btn_psector', 'psector_rapport_chk_csv', f"{chk_csv}")
639656

640657
folder_path = tools_qt.get_text(self.dlg_psector_rapport, self.dlg_psector_rapport.txt_path)
641658
if folder_path is None or folder_path == 'null' or not os.path.exists(folder_path):
642659
tools_qt.get_folder_path(self.dlg_psector_rapport.txt_path)
643660
folder_path = tools_qt.get_text(self.dlg_psector_rapport, self.dlg_psector_rapport.txt_path)
644661

662+
if chk_csv is False and chk_csv_detail is False:
663+
msg = "You must choose at least one action"
664+
tools_qgis.show_warning(msg, dialog=self.dlg_psector_rapport)
665+
return
666+
645667
# Generate Composer
646-
if tools_qt.is_checked(self.dlg_psector_rapport, self.dlg_psector_rapport.chk_composer):
668+
if chk_composer:
647669
file_name = tools_qt.get_text(self.dlg_psector_rapport, 'txt_composer_path')
648670
if file_name is None or file_name == 'null':
649671
msg = "File name is required"
@@ -934,7 +956,7 @@ def check_name(self, psector_name):
934956
return False
935957
return True
936958

937-
def insert_or_update_new_psector(self, from_tab_change=False):
959+
def insert_or_update_new_psector(self, from_tab_change=False): # noqa: C901
938960

939961
psector_name = tools_qt.get_text(self.dlg_plan_psector, "tab_general_name", return_string_null=False)
940962
if psector_name == "":
@@ -945,6 +967,43 @@ def insert_or_update_new_psector(self, from_tab_change=False):
945967
rotation = tools_qt.get_text(self.dlg_plan_psector, "tab_general_rotation", return_string_null=False)
946968
if rotation == "":
947969
tools_qt.set_widget_text(self.dlg_plan_psector, "tab_general_rotation", 0)
970+
971+
msg = tools_qt.tr("Psector could not be updated because of the following errors: ")
972+
scale = tools_qt.get_text(self.dlg_plan_psector, "tab_general_scale", return_string_null=False)
973+
atlas_id = tools_qt.get_text(self.dlg_plan_psector, "tab_general_atlas_id", return_string_null=False)
974+
parent_id = tools_qt.get_text(self.dlg_plan_psector, "tab_general_parent_id", return_string_null=False)
975+
if rotation != "":
976+
try:
977+
float(rotation)
978+
except ValueError:
979+
msg += tools_qt.tr("Rotation must be a number.")
980+
if scale != "":
981+
try:
982+
float(scale)
983+
except ValueError:
984+
msg += tools_qt.tr("Scale must be a number.")
985+
if atlas_id != "":
986+
try:
987+
int(atlas_id)
988+
except ValueError:
989+
msg += tools_qt.tr("Atlas ID must be an integer.")
990+
if parent_id != "":
991+
try:
992+
int(parent_id)
993+
except ValueError:
994+
msg += tools_qt.tr("Parent ID must be an integer.")
995+
996+
try:
997+
parent_id_exists = tools_db.get_rows(f"SELECT 1 FROM ve_plan_psector WHERE psector_id = {parent_id} AND NOT archived")
998+
except Exception:
999+
parent_id_exists = None
1000+
1001+
if parent_id_exists is None or len(parent_id_exists) == 0:
1002+
msg += tools_qt.tr("Parent ID does not exist.")
1003+
1004+
if msg != tools_qt.tr("Psector could not be updated because of the following errors: "):
1005+
tools_qgis.show_warning(msg, dialog=self.dlg_plan_psector)
1006+
return False
9481007

9491008
name_exist = self.check_name(psector_name)
9501009

@@ -1061,7 +1120,7 @@ def insert_or_update_new_psector(self, from_tab_change=False):
10611120
tools_gw.refresh_selectors()
10621121
tools_gw.close_dialog(self.dlg_plan_psector)
10631122

1064-
def check_topology_psector(self, psector_id=None, psector_name=None):
1123+
def check_topology_psector(self, psector_id=None, psector_name=None, from_toggle=False):
10651124

10661125
if psector_id in (None, "null"):
10671126
return False
@@ -1072,11 +1131,16 @@ def check_topology_psector(self, psector_id=None, psector_name=None):
10721131
if not json_result or 'body' not in json_result or 'data' not in json_result['body']:
10731132
return False
10741133

1134+
msg = ""
10751135
if json_result['message']['level'] == 1:
1076-
text = "There are some topological inconsistences on psector '{0}'. Would you like to see the log?"
1077-
text_params = (psector_name,)
1136+
if from_toggle:
1137+
msg += tools_qt.tr('Unable to activate psector. ')
1138+
msg += tools_qt.tr("There are some topological inconsistences on psector '{0}'. Would you like to see the log?")
1139+
msg_params = (psector_name,)
10781140
function = partial(self.show_psector_topoerror_log, json_result, psector_id)
1079-
tools_qgis.show_message_function(text, function, message_level=1, duration=0, text_params=text_params)
1141+
tools_qgis.show_message_function(msg, function, message_level=1, duration=0, text_params=msg_params)
1142+
if from_toggle:
1143+
return False
10801144

10811145
return json_result
10821146

@@ -1675,6 +1739,9 @@ def document_insert(self):
16751739
self.doc_id.clear()
16761740
self.dlg_plan_psector.tbl_document.model().select()
16771741

1742+
# Refresh canvas
1743+
tools_qgis.refresh_map_canvas()
1744+
16781745
def manage_document(self, qtable):
16791746
""" Access GUI to manage documents e.g Execute action of button 34 """
16801747

@@ -1796,7 +1863,7 @@ def set_toggle_active(self, dialog, qtbl_psm):
17961863
for i in range(0, len(selected_list)):
17971864
row = selected_list[i].row()
17981865
psector_id = qtbl_psm.model().record(row).value("psector_id")
1799-
psector_name = qtbl_psm.model().record(row).value("name")
1866+
# psector_name = qtbl_psm.model().record(row).value("name")
18001867
active = qtbl_psm.model().record(row).value("active")
18011868
archived = qtbl_psm.model().record(row).value("archived")
18021869
if archived is True:
@@ -1812,10 +1879,13 @@ def set_toggle_active(self, dialog, qtbl_psm):
18121879
"WHERE parameter = 'plan_psector_disable_checktopology_trigger' AND cur_user=current_user")
18131880
tools_db.execute_sql(sql)
18141881

1882+
# Check topology
1883+
# result = self.check_topology_psector(psector_id, psector_name, from_toggle=True)
1884+
# if result is False:
1885+
# return
1886+
18151887
sql = f"UPDATE plan_psector SET active = True WHERE psector_id = {psector_id};"
18161888
tools_db.execute_sql(sql)
1817-
# Check topology
1818-
self.check_topology_psector(psector_id, psector_name)
18191889

18201890
sql = ("UPDATE config_param_user "
18211891
"SET value = False "
@@ -1853,7 +1923,7 @@ def restore_psector(self, dialog, qtbl_psm):
18531923
extras = f'"psectorId": "{psector_id}"'
18541924
body = tools_gw.create_body(extras=extras)
18551925
json_result = tools_gw.execute_procedure('gw_fct_plan_recover_archived', body)
1856-
if not json_result or 'body' not in json_result or 'data' not in json_result['body']:
1926+
if not json_result or 'body' not in json_result or 'data' not in json_result['body'] or json_result.get('status') == 'Failed':
18571927
return
18581928

18591929
# Refresh the table to show updated status
@@ -2091,26 +2161,33 @@ def charge_psector(self, qtbl_psm):
20912161
row = selected_list[0].row()
20922162
active = qtbl_psm.model().record(row).value("active")
20932163
psector_id = qtbl_psm.model().record(row).value("psector_id")
2164+
archived = qtbl_psm.model().record(row).value("archived")
20942165
cur_psector = tools_gw.get_config_value('plan_psector_current')
20952166
keep_open_form = tools_gw.get_config_parser('dialogs_actions', 'psector_manager_keep_open', "user", "init", prefix=True)
20962167
if tools_os.set_boolean(keep_open_form, False) is not True:
20972168
self._handle_dialog_close()
20982169

2170+
# Only current psectors are editable, archived psectors are never editable
2171+
is_current = cur_psector and cur_psector[0] is not None and int(cur_psector[0]) == psector_id
2172+
if archived is True:
2173+
self.psector_editable = False
2174+
elif is_current:
2175+
self.psector_editable = True
2176+
else:
2177+
# Ask user if they want to set this psector as current
2178+
msg = "Do you want to set this psector as current?"
2179+
result = tools_qt.show_question(msg, title="Info", context_name="giswater", force_action=True)
2180+
if result:
2181+
self.update_current_psector(self.dlg_psector_mng, qtbl=self.qtbl_psm, scenario_type="psector", col_id_name="psector_id")
2182+
self.psector_editable = True
2183+
else:
2184+
self.psector_editable = False
2185+
20992186
if active is True:
21002187
# put psector on selector_psector
21012188
sql = f"DELETE FROM selector_psector WHERE psector_id = {psector_id} AND cur_user = current_user;" \
21022189
f"INSERT INTO selector_psector (psector_id, cur_user) VALUES ({psector_id}, current_user);"
21032190
tools_db.execute_sql(sql)
2104-
self.psector_editable = True if tools_gw.get_config_value('plan_psector_current') is not None else False
2105-
if not cur_psector or (cur_psector and (cur_psector[0] is None or psector_id != int(cur_psector[0]))):
2106-
# Ask user if they want to set this psector as current
2107-
msg = "Do you want to set this psector as current?"
2108-
result = tools_qt.show_question(msg, title="Info", context_name="giswater", force_action=True)
2109-
if result:
2110-
self.psector_editable = True
2111-
self.update_current_psector(self.dlg_psector_mng, qtbl=self.qtbl_psm, scenario_type="psector", col_id_name="psector_id")
2112-
else:
2113-
self.psector_editable = False
21142191
# Open form
21152192
self.master_new_psector(psector_id)
21162193

@@ -2305,7 +2382,7 @@ def psector_duplicate(self):
23052382

23062383
row = selected_list[0].row()
23072384
psector_id = self.qtbl_psm.model().record(row).value("psector_id")
2308-
psector_name = self.qtbl_psm.model().record(row).value("name")
2385+
# psector_name = self.qtbl_psm.model().record(row).value("name")
23092386
archived = self.qtbl_psm.model().record(row).value("archived")
23102387
if archived is True:
23112388
msg = f"Cannot duplicate archived psector {psector_id}. Please unarchive it first."
@@ -2314,7 +2391,7 @@ def psector_duplicate(self):
23142391
self.duplicate_psector = GwPsectorDuplicate()
23152392
self.duplicate_psector.is_duplicated.connect(partial(self.fill_table, self.dlg_psector_mng, self.qtbl_psm, 'v_ui_plan_psector'))
23162393
self.duplicate_psector.is_duplicated.connect(partial(self.set_label_current_psector, self.dlg_psector_mng, scenario_type="psector", from_open_dialog=True))
2317-
self.duplicate_psector.is_duplicated.connect(partial(self.check_topology_psector, psector_id, psector_name))
2394+
# self.duplicate_psector.is_duplicated.connect(partial(self.check_topology_psector, psector_id, psector_name))
23182395
self.duplicate_psector.is_duplicated.connect(partial(self.load_psector, self.duplicate_psector, psector_id))
23192396
self.duplicate_psector.manage_duplicate_psector(psector_id)
23202397

@@ -2762,12 +2839,12 @@ def close_dlg(**kwargs):
27622839
""" Close dialog and disconnect snapping """
27632840
class_obj = kwargs["class"]
27642841
try:
2765-
# Only check topology if psector is active and has an id
2766-
active = tools_qt.get_widget_value(class_obj.dlg_plan_psector, "tab_general_active")
2767-
if active:
2768-
psector_id = tools_qt.get_text(class_obj.dlg_plan_psector, 'tab_general_psector_id')
2769-
psector_name = tools_qt.get_text(class_obj.dlg_plan_psector, "tab_general_name", return_string_null=False)
2770-
class_obj.check_topology_psector(psector_id, psector_name)
2842+
# # Only check topology if psector is active and has an id
2843+
# active = tools_qt.get_widget_value(class_obj.dlg_plan_psector, "tab_general_active")
2844+
# if active:
2845+
# psector_id = tools_qt.get_text(class_obj.dlg_plan_psector, 'tab_general_psector_id')
2846+
# psector_name = tools_qt.get_text(class_obj.dlg_plan_psector, "tab_general_name", return_string_null=False)
2847+
# class_obj.check_topology_psector(psector_id, psector_name)
27712848

27722849
tools_gw.reset_rubberband(class_obj.rubber_band_point)
27732850
tools_gw.reset_rubberband(class_obj.rubber_band_line)

core/threads/epa_file_manager.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,6 @@ def _export_inp(self):
295295
if 'file' not in self.complet_result['body']:
296296
return False
297297

298-
if self.file_inp == "null":
299-
self.error_msg = "You have to set this parameter: INP file"
300-
return False
301-
302298
msg = "Task 'Go2Epa' execute function '{0}'"
303299
msg_params = ("_fill_inp_file",)
304300
tools_log.log_info(msg, msg_params=msg_params)
@@ -382,12 +378,6 @@ def _execute_epa(self):
382378
tools_log.log_info(msg)
383379
self.step_completed.emit({"message": {"level": 1, "text": "Execute EPA software......"}}, "")
384380

385-
if self.file_rpt == "null":
386-
message = "You have to set this parameter"
387-
self.error_msg = "{0}: RPT file"
388-
self.error_msg_params = (message,)
389-
return False
390-
391381
msg = "INP file not found"
392382
if self.file_inp is not None:
393383
if not os.path.exists(self.file_inp):

core/toolbars/epa/go2epa_btn.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,18 @@ def _go2epa_accept(self):
459459
msg = "You need to select some sector"
460460
tools_qt.show_info_box(msg)
461461
return
462+
463+
if self.export_inp and self.file_inp == "null":
464+
message = "You have to set this parameter: INP file"
465+
tools_qgis.show_warning(message, dialog=self.dlg_go2epa)
466+
return
467+
468+
if self.exec_epa and self.file_rpt == "null":
469+
message = "You have to set this parameter"
470+
self.error_msg = "{0}: RPT file"
471+
self.error_msg_params = (message,)
472+
tools_qgis.show_warning(message, dialog=self.dlg_go2epa)
473+
return
462474

463475
self.dlg_go2epa.btn_accept.setEnabled(False)
464476
self.dlg_go2epa.btn_cancel.setEnabled(True)

core/utils/tools_gw.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4351,6 +4351,8 @@ def _process_map_selection(class_object, selection_mode, field_id):
43514351
where_clause = f"AND {field_id} IN ({allowed_str})"
43524352
except Exception:
43534353
pass
4354+
elif selection_mode == GwSelectionMode.PSECTOR:
4355+
where_clause = "AND state <> 0"
43544356
# For all other modes no additional filtering
43554357
# Query each layer separately to handle multi-layer feature types (like elements with ve_man_frelem + ve_man_genelem)
43564358
selected_ids = []

i18n/giswater_es_CR.qm

2.76 KB
Binary file not shown.

0 commit comments

Comments
 (0)