378 lines
16 KiB
Python
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 in ('linux','darwin'):
|
|
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() |