PLUGINS_QGIS/pluginsCenSavoie_v3/tools/parcelle_to_acte.py
2024-11-26 14:56:34 +01:00

378 lines
16 KiB
Python

# -*- coding: utf-8 -*-
"""
/***************************************************************************
ParcelleToActe
A QGIS plugin
Permet d'associer des parcelles à des actes
-------------------
begin : 2015-06-19
git sha : $Format:%H$
copyright : (C) 2015 by CEN Savoie
email : a.lesconnec@cen-savoie.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QAction, QTableWidgetItem, QMessageBox
# Initialize Qt resources from file resources.py
from pluginsCenSavoie_v3 import resources
# Import the code for the dialog
from pluginsCenSavoie_v3.tools.parcelle_to_acte_dialog import ParcelleToActeDialog
# Import du fichier de configuration
from pluginsCenSavoie_v3.tools.confPython import bd_cen_host, bd_cen_port, bd_cen_name, bd_cen_mdp_1st_cnx
import os.path
import sys
import qgis
import os
import psycopg2
import psycopg2.extras
import base64
import re
from time import localtime, strftime
class ParcelleToActe:
"""QGIS Plugin Implementation."""
def __init__(self, iface, cenToolbar):
"""Constructor.
:param iface: An interface instance that will be passed to this class
which provides the hook by which you can manipulate the QGIS
application at run time.
:type iface: QgsInterface
"""
# Variable HOTE de l'accès à la base de données
global host
host = bd_cen_host
global port
port = bd_cen_port
global bdd
bdd = bd_cen_name
global mdp_1st_cnx
mdp_1st_cnx = bd_cen_mdp_1st_cnx
global os_user
if sys.platform == 'linux':
os_user = os.environ['USER']
else:
os_user = os.environ['USERNAME']
# Save reference to the QGIS interface
self.iface = iface
self.canvas = self.iface.mapCanvas()
# initialize plugin directory
self.plugin_dir = os.path.dirname(__file__)
# Create the dialog (after translation) and keep reference
self.dlg = ParcelleToActeDialog()
# Add toolbar button
self.action= QAction(QIcon(":/plugins/pluginsCenSavoie_v3/icons/parcelleToActe.png"), QCoreApplication.translate('ParcelleToActe', u'Associer des parcelles à un acte'), self.iface.mainWindow())
self.action.triggered.connect(self.run)
self.action.setEnabled(False)
cenToolbar.addAction(self.action)
self.canvas.selectionChanged.connect(self.toggle)
self.iface.layerTreeView().currentLayerChanged.connect(self.toggle)
def toggle(self):
layer = self.iface.activeLayer()
if layer and layer.type() == layer.VectorLayer:
if layer.selectedFeatureCount() > 0:
provider = layer.dataProvider()
source_postgis = provider.dataSourceUri()
source_postgis = source_postgis.replace('"', '')
if (source_postgis.count('table=foncier.parcelles_dispo ') == 1):
self.action.setEnabled(True)
else:
self.action.setEnabled(False)
else:
self.action.setEnabled(False)
else:
self.action.setEnabled(False)
def changeCellValue(self, ligne, col):
self.dlg.tbl_detail.blockSignals(True)
if self.dlg.tbl_detail.item(ligne, 2).text() == 'OUI' and col != 0:
self.dlg.tbl_detail.setItem(ligne, 2, QTableWidgetItem('NON'))
self.dlg.tbl_detail.item(ligne, 1).setBackground(QtGui.QColor(255, 145, 145))
self.dlg.tbl_detail.item(ligne, 2).setBackground(QtGui.QColor(255, 145, 145))
elif self.dlg.tbl_detail.item(ligne, 2).text() == 'NON' and col != 0:
self.dlg.tbl_detail.setItem(ligne, 2, QTableWidgetItem('OUI'))
self.dlg.tbl_detail.item(ligne, 1).setBackground(QtGui.QColor(115, 215, 115))
self.dlg.tbl_detail.item(ligne, 2).setBackground(QtGui.QColor(115, 215, 115))
self.dlg.tbl_detail.item(ligne, col).setSelected(False)
self.dlg.tbl_detail.blockSignals(False)
def chg_date_modif(self):
self.dlg.cal_date_modif.setEnabled(True)
self.dlg.cal_date_modif.setVisible(1)
def chg_cal_date_modif(self, date):
current_date_modif = date.toString('yyyy-MM-dd')
self.dlg.date_modif.setText(str(current_date_modif))
self.dlg.cal_date_modif.setEnabled(False)
self.dlg.cal_date_modif.setVisible(0)
if self.dlg.lst_actes.currentIndex() != -1 and self.dlg.date_modif.text() != 'N.P.' and self.dlg.lst_motif_maj.currentIndex() != -1 :
self.dlg.button_box.setEnabled(True)
else:
self.dlg.button_box.setEnabled(False)
def run(self):
"""Run method that performs all the real work"""
# initialise le contenant du formulaire
self.dlg.tbl_detail.setColumnCount(4)
self.dlg.tbl_detail.setHorizontalHeaderItem(0, QTableWidgetItem('Par ID'))
self.dlg.tbl_detail.setHorizontalHeaderItem(1, QTableWidgetItem('Lot ID'))
self.dlg.tbl_detail.setHorizontalHeaderItem(2, QTableWidgetItem('A Associer'))
self.dlg.tbl_detail.setHorizontalHeaderItem(3, QTableWidgetItem('cad_site_id'))
self.dlg.tbl_detail.setColumnHidden(3, True)
self.dlg.btn_date_modif.clicked.connect(self.chg_date_modif)
self.dlg.cal_date_modif.clicked.connect(self.chg_cal_date_modif)
self.dlg.tbl_detail.cellClicked.connect(self.changeCellValue)
first_conn = psycopg2.connect("host=" + host + " port=" + port + " dbname=" + bdd + " user=first_cnx password=" + mdp_1st_cnx)
first_cur = first_conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
first_cur.execute("SELECT mdp_cen, usename FROM pg_catalog.pg_user t1, admin_sig.utilisateurs t2 WHERE t2.oid = t1.usesysid AND (utilisateur_id = '" + os_user + "' OR utilisateur_os = '" + os_user + "')")
res_ident = first_cur.fetchone()
mdp = base64.b64decode(str(res_ident[0])).decode('utf-8')
user = res_ident[1]
conn = psycopg2.connect("host=" + host + " port=" + port + " dbname=" + bdd + " user=" + user + " password=" + mdp)
cur = conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
first_conn.close()
site_id = []
tbl_dnulot = []
tbl_cad_site_id = []
self.canvas = self.iface.mapCanvas()
global layer
layer = self.iface.activeLayer()
rowCount = 0
for feature in layer.selectedFeatures():
site_id.append(feature["site_id"])
tbl_dnulot = re.split(',', feature["tbl_dnulot"])
if len(tbl_dnulot) > 0:
j = 0
while j < len(tbl_dnulot):
rowCount += 1
j+=1
self.dlg.tbl_detail.setRowCount(rowCount)
for id_site in site_id:
rq_lst_sites_around = """
SELECT site_id
FROM sites.sites
WHERE st_distance(geom_ecolo, (SELECT geom_ecolo FROM sites.sites WHERE site_id = '"""+id_site+"""')) < 1000 AND site_id != '"""+id_site+"""'
"""
with conn:
with conn.cursor() as cur:
cur.execute(rq_lst_sites_around)
res_lst_sites_around = cur.fetchall()
site_id_around = []
if len(res_lst_sites_around) > 0:
i = 0
while i < len(res_lst_sites_around):
if res_lst_sites_around[i][0] not in site_id and res_lst_sites_around[i][0] not in site_id_around:
site_id_around.append(res_lst_sites_around[i][0])
i=i+1
site_id = [*site_id, *site_id_around]
if rowCount > 0:
ligne = 0
col = 0
for feature in layer.selectedFeatures():
tbl_dnulot = re.split(',', feature["tbl_dnulot"])
tbl_cad_site_id = re.split(',', feature["tbl_cad_site_id"])
if len(tbl_dnulot) > 0:
self.dlg.tbl_detail.setItem(ligne, 0, QTableWidgetItem(feature["par_id"]))
self.dlg.tbl_detail.setSpan(ligne, 0, len(tbl_dnulot), 1)
j = 0
while j < len(tbl_dnulot):
self.dlg.tbl_detail.setItem(ligne, 1, QTableWidgetItem(tbl_dnulot[j]))
self.dlg.tbl_detail.item(ligne, 1).setBackground(QtGui.QColor(115, 215, 115))
self.dlg.tbl_detail.setItem(ligne, 2, QTableWidgetItem('OUI'))
self.dlg.tbl_detail.item(ligne, 2).setBackground(QtGui.QColor(115, 215, 115))
self.dlg.tbl_detail.setItem(ligne, 3, QTableWidgetItem(tbl_cad_site_id[j]))
ligne += 1
j+=1
self.dlg.tbl_detail.setEnabled(True)
self.dlg.no_lot.setVisible(0)
else:
self.dlg.tbl_detail.setEnabled(False)
self.dlg.no_lot.setVisible(1)
self.dlg.tbl_detail.resizeColumnsToContents()
if (len(set(site_id)) < 1):
QMessageBox.warning(None, "Oups:", 'Selection invalide')
else:
tbl_site_id = list(set(site_id))
self.dlg.InitFormulaire(tbl_site_id, 'load', user, mdp)
self.dlg.img_logo.setPixmap(QPixmap(":/plugins/pluginsCenSavoie_v3/tools/images/Logo_CEN_Savoie.png"))
self.dlg.lbl_fond.setPixmap(QPixmap("%s/images/fond_70.png"%self.plugin_dir))
self.dlg.lbl_fond.stackUnder(self.dlg.button_box)
# show the dialog
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result:
curs = QCursor()
curs.setShape(Qt.WaitCursor)
qgis.utils.iface.mainWindow().centralWidget().setCursor(curs)
mfu_id = self.dlg.lst_actes.currentText()
motif_maj_id = self.dlg.motif_maj_id.text()
mfu_table = self.dlg.type_acte_sel.text()
aujourdhui = strftime("%Y-%m-%d %H:%M:%S", localtime())
date_modif = self.dlg.date_modif.text()
maj_table = 'NON'
with conn:
with conn.cursor() as cur:
rq_check_droit = """
WITH RECURSIVE t(oid) AS (
VALUES ((SELECT oid FROM admin_sig.utilisateurs WHERE utilisateur_id = '""" + os_user + """' OR utilisateur_os = '""" + os_user + """'))
UNION ALL
SELECT grosysid
FROM pg_catalog.pg_group JOIN t ON (t.oid = ANY (grolist))
),
t_group AS (
SELECT DISTINCT groname
FROM pg_catalog.pg_group JOIN t ON (t.oid = pg_group.grosysid))
SELECT
count(*) FILTER (WHERE grant_elt_id = 3 AND grant_group_droit = 't' AND grant_group_id IN (groname)) as parc
FROM foncier.grant_group JOIN t_group ON (groname = grant_group_id)"""
cur.execute(rq_check_droit)
can_parc_site = cur.fetchone()
if can_parc_site[0] == 0:
QMessageBox.warning(None, "ERROR:", """Le traitement a échoué<br>Vous n'êtes pas autorisé à modifier la liste des parcelles d'un acte""")
else:
rq_statut_mfu = "SELECT statutmfu_id AS statut_id FROM alertes.v_tdb_mfu WHERE mfu_id = '"+mfu_id+"'"
cur.execute(rq_statut_mfu)
statut_mfu = cur.fetchone()
if (int(statut_mfu[0]) == 0):
date_modif = '0000-00-00'
else:
date_modif = date_modif + ' 00:00:00'
if mfu_table == 'r_cad_site_mf':
rq_date_debut_acte = "SELECT date_sign_acte FROM foncier.mf_acquisitions WHERE mf_id = '"+mfu_id+"'"
suffixe = 'mf'
else:
rq_date_debut_acte = "SELECT date_effet_conv FROM foncier.mu_conventions WHERE mu_id = '"+mfu_id+"'"
suffixe = 'mu'
error_date = 'RAS'
tbl_cad_site_id = []
for i in range(self.dlg.tbl_detail.rowCount()):
tbl_cad_site_id.append(self.dlg.tbl_detail.item(i, 3).text())
lst_cad_site_id = ','.join(tbl_cad_site_id)
rq_check_mfu = """
WITH t1 AS (
SELECT cad_site_id
FROM
alertes.v_tdb_mfu
JOIN foncier.r_cad_site_mu ON (mu_id = mfu_id)
WHERE statutmfu_id = 1
UNION
SELECT cad_site_id
FROM
alertes.v_tdb_mfu
JOIN foncier.r_cad_site_mf ON (mf_id = mfu_id)
WHERE statutmfu_id = 1
)
SELECT cad_site_id FROM t1 WHERE cad_site_id IN (""" + str(lst_cad_site_id) + """)"""
cur.execute(rq_check_mfu)
res_check_mfu = cur.fetchall()
if len(res_check_mfu) > 0 and int(statut_mfu[0]) == 1:
error_date = 'PROB'
QMessageBox.warning(None, "ERROR:", """Le traitement a échoué<br>Au moins une parcelle est déjà maitrisée""")
elif int(motif_maj_id) in [3, 10]:
rq_check_date = """
SELECT
cad_site_id
FROM
foncier.cadastre_site
JOIN cadastre.cadastre_cen USING (cad_cen_id)
WHERE
cad_site_id IN (""" + str(lst_cad_site_id) + """) AND
'"""+date_modif+"""'::character varying(10) < ("""+rq_date_debut_acte+""")::character varying(10)"""
cur.execute(rq_check_date)
res_check_date = cur.fetchall()
if len(res_check_date) > 0:
error_date = 'PROB'
QMessageBox.warning(None, "ERROR:", """Le traitement a échoué<br>Au moins une parcelle ajoutée avant la création de l'acte""")
elif int(motif_maj_id) == 9:
rq_check_date = """
SELECT
cad_site_id
FROM
foncier.cadastre_site
JOIN cadastre.cadastre_cen USING (cad_cen_id)
WHERE
cad_site_id IN ("""+str(lst_cad_site_id)+""") AND
cadastre_cen.date_deb::character varying(10) < ("""+rq_date_debut_acte+""")::character varying(10)"""
cur.execute(rq_check_date)
res_check_date = cur.fetchall()
if len(res_check_date) > 0:
error_date = 'PROB'
QMessageBox.warning(None, "ERROR:", """Le traitement a échoué<br>Au moins une parcelle ajoutée avant la création de l'acte""")
if error_date == 'RAS':
rq_ajout = "INSERT INTO foncier.r_cad_site_"+suffixe+" (cad_site_id, "+suffixe+"_id, date_entree, date_sortie, motif_entree_id, motif_sortie_id) VALUES ";
for i in range(self.dlg.tbl_detail.rowCount()):
if self.dlg.tbl_detail.item(i, 2).text() == 'OUI':
if int(motif_maj_id) == 1 and int(statut_mfu[0]) != 0:
rq_ajout += "("+self.dlg.tbl_detail.item(i, 3).text()+", '"+mfu_id+"', ("+rq_date_debut_acte+"), 'N.D.', "+motif_maj_id+", 1), "
elif int(motif_maj_id) == 9:
rq_ajout += "("+self.dlg.tbl_detail.item(i, 3).text()+", '"+mfu_id+"', (SELECT cadastre_cen.date_deb FROM cadastre.cadastre_cen JOIN foncier.cadastre_site USING (cad_cen_id) WHERE cad_site_id = "+self.dlg.tbl_detail.item(i, 3).text()+"), 'N.D.', "+motif_maj_id+", 1), "
else:
rq_ajout += "("+self.dlg.tbl_detail.item(i, 3).text()+", '"+mfu_id+"', '"+date_modif+"', 'N.D.', "+motif_maj_id+", 1), "
if rq_ajout[-2:] == ', ':
rq_ajout = rq_ajout[0:-2]
if self.dlg.tbl_detail.rowCount() > 0 and rq_ajout != "INSERT INTO foncier.r_cad_site_"+suffixe+" (cad_site_id, "+suffixe+"_id, date_entree, date_sortie, motif_entree_id, motif_sortie_id) VALUES ":
cur.execute(rq_ajout)
conn.commit()
maj_table = 'OUI'
if maj_table == 'OUI':
rq_refresh = """
WITH t1 AS (
SELECT array_to_string(array_agg(DISTINCT site_id), ',') as lst_site_id
FROM
foncier."""+mfu_table+"""
JOIN foncier.cadastre_site USING (cad_site_id)
WHERE """+mfu_table[len(mfu_table)-2:len(mfu_table)]+"""_id = '"""+mfu_id+"""'
)
SELECT admin_sig.refresh_mview_foncier(t1.lst_site_id) FROM t1"""
cur.execute(rq_refresh)
conn.commit()
if mfu_table == 'r_cad_site_mu':
rq_update = "UPDATE foncier.mu_conventions SET maj_date = '"+aujourdhui+"', maj_user = '"+os_user+"' WHERE mu_id = '"+mfu_id+"'"
elif mfu_table == 'r_cad_site_mf':
rq_update = "UPDATE foncier.mf_acquisitions SET maj_date = '"+aujourdhui+"', maj_user = '"+os_user+"' WHERE mf_id = '"+mfu_id+"'"
cur.execute(rq_update)
conn.commit()
curs = QCursor()
curs.setShape(Qt.ArrowCursor)
qgis.utils.iface.mainWindow().centralWidget().setCursor(curs)
self.canvas.refresh()