fusion maj parcelle,batiment,ulo et leur enquete #188

Merged
judaur2005 merged 1 commits from features/fiche_refonte into develop 2026-03-21 14:59:29 +00:00
6 changed files with 429 additions and 8 deletions
Showing only changes of commit 14ca79d49e - Show all commits

View File

@@ -461,12 +461,12 @@ public class DonneesImpositionTfuController {
} }
} }
@GetMapping("/all/by-exercice-id/by-structure-id/{exerciceId}/{structureId}") @GetMapping("/all/by-exercice-id/by-structure-id/by-quartier-id/{exerciceId}/{structureId}/{quartierId}")
public ResponseEntity<?> getAllDonneesImpositionTfuByExerciceIdAndStructureId(@PathVariable Long exerciceId, @PathVariable Long structureId) { public ResponseEntity<?> getAllDonneesImpositionTfuByExerciceIdAndStructureId(@PathVariable Long exerciceId, @PathVariable Long structureId, @PathVariable Long quartierId) {
try { try {
System.out.println("NOUS SOMMES ICI"); System.out.println("NOUS SOMMES ICI");
return new ResponseEntity<>( return new ResponseEntity<>(
new ApiResponse<>(true, donneesImpositionTfuService.getDonneesFiscalesByExerciceAndStructureId(exerciceId,structureId), "Liste des caractéristiques chargée avec succès."), new ApiResponse<>(true, donneesImpositionTfuService.getDonneesFiscalesByExerciceAndStructureId(exerciceId,structureId,quartierId), "Liste des caractéristiques chargée avec succès."),
HttpStatus.OK HttpStatus.OK
); );
} catch (HttpClientErrorException.MethodNotAllowed e) { } catch (HttpClientErrorException.MethodNotAllowed e) {

View File

@@ -97,10 +97,12 @@ public class DonneesImpositionTfu extends BaseEntity implements Serializable {
@JsonDeserialize(using = LocalDateDeserializer.class) @JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate dateEnquete; private LocalDate dateEnquete;
private Long enqueteId; private Long enqueteId;
@JsonIgnore @JsonIgnore
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "structure_id") @JoinColumn(name = "structure_id")
private Structure structure ; private Structure structure ;
private Long secteurId; private Long secteurId;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "zone_rfu_id") @JoinColumn(name = "zone_rfu_id")
@@ -137,4 +139,6 @@ public class DonneesImpositionTfu extends BaseEntity implements Serializable {
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "unite_logement_id") @JoinColumn(name = "unite_logement_id")
private UniteLogement uniteLogementImposee ; private UniteLogement uniteLogementImposee ;
} }

View File

@@ -199,7 +199,7 @@ public class DonneesImpositionTfuServiceImpl implements DonneesImpositionTfuServ
} }
@Override @Override
public List<DonneesImpositionPaylaodWeb> getDonneesFiscalesByExerciceAndStructureId(Long exerciceId, Long structureId) { public List<DonneesImpositionPaylaodWeb> getDonneesFiscalesByExerciceAndStructureId(Long exerciceId, Long structureId,Long quartierId) {
return donneesImpositionTfuRepository.findAllByExericeIdStructureId(exerciceId,structureId); return donneesImpositionTfuRepository.findAllByExericeIdStructureId(exerciceId,structureId,quartierId);
} }
} }

View File

@@ -43,6 +43,6 @@ public interface DonneesImpositionTfuService {
Page<DonneesImpositionPaylaodWeb> getDonneesFiscalesByImpositionSrtbIdBatieUniteLogPageable(Long impositionsTfuId, Pageable pageable); Page<DonneesImpositionPaylaodWeb> getDonneesFiscalesByImpositionSrtbIdBatieUniteLogPageable(Long impositionsTfuId, Pageable pageable);
Page<DonneesImpositionPaylaodWeb> getDonneesFiscalesByExerciceAndStructureIdPageable(Long exerciceId, Long structureId, Pageable pageable); Page<DonneesImpositionPaylaodWeb> getDonneesFiscalesByExerciceAndStructureIdPageable(Long exerciceId, Long structureId, Pageable pageable);
List<DonneesImpositionPaylaodWeb> getDonneesFiscalesByExerciceAndStructureId(Long exerciceId, Long structureId); List<DonneesImpositionPaylaodWeb> getDonneesFiscalesByExerciceAndStructureId(Long exerciceId, Long structureId,Long quartierId);
} }

View File

@@ -1,4 +1,4 @@
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie( /*CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie(
p_impositions_tfu_id BIGINT, p_impositions_tfu_id BIGINT,
p_user_id BIGINT p_user_id BIGINT
) )
@@ -342,5 +342,418 @@ WHERE impositions_tfu_id = p_impositions_tfu_id
); );
RETURN v_rows_inserted; RETURN v_rows_inserted;
END; END;
$$;*/
CREATE OR REPLACE FUNCTION public.generer_donnees_imposition_tfu_batie(
p_impositions_tfu_id BIGINT,
p_user_id BIGINT
)
RETURNS INTEGER
LANGUAGE plpgsql
AS $$
DECLARE
v_rows_inserted INTEGER;
v_annee BIGINT;
v_structure_id BIGINT;
v_taux_defaut_sup_sol NUMERIC;
v_taux_tfu NUMERIC;
v_taux_tfu_ratio NUMERIC; -- v_taux_tfu / 100 (pré-calculé)
v_taux_valeur_locat_prof NUMERIC;
v_taux_vlp_ratio NUMERIC; -- v_taux_valeur_locat_prof / 100 (pré-calculé)
v_tfu_piscine_unitaire NUMERIC;
v_today DATE;
BEGIN
v_today := CURRENT_DATE;
-- -------------------------------------------------------------------------
-- 1. Récupération de l'année et de la structure (inchangée)
-- -------------------------------------------------------------------------
SELECT ex.annee, it.structure_id
INTO STRICT v_annee, v_structure_id
FROM impositions_tfu it
JOIN exercice ex ON ex.id = it.exercice_id
WHERE it.id = p_impositions_tfu_id;
-- -------------------------------------------------------------------------
-- 2. Récupération des 4 paramètres en UNE seule requête
-- (évite 4 accès séquentiels à la table parameters)
-- -------------------------------------------------------------------------
SELECT
MAX(value) FILTER (WHERE name = 'TAUX_DEFAUT_SUPERFICIE_AU_SOL'),
MAX(value) FILTER (WHERE name = 'TAUX_TFU'),
MAX(value) FILTER (WHERE name = 'TAUX_VALEUR_LOCATIVE_PROFESSIONNELLE'),
MAX(value) FILTER (WHERE name = 'TFU_PAR_PISCINE')
INTO STRICT
v_taux_defaut_sup_sol,
v_taux_tfu,
v_taux_valeur_locat_prof,
v_tfu_piscine_unitaire
FROM parameters
WHERE name IN (
'TAUX_DEFAUT_SUPERFICIE_AU_SOL',
'TAUX_TFU',
'TAUX_VALEUR_LOCATIVE_PROFESSIONNELLE',
'TFU_PAR_PISCINE'
);
-- Ratios pré-calculés pour éviter la division répétée dans le SELECT
v_taux_tfu_ratio := v_taux_tfu / 100.0;
v_taux_vlp_ratio := v_taux_valeur_locat_prof / 100.0;
-- -------------------------------------------------------------------------
-- 3. INSERT avec calcul complet de valeur_locative_adm et montant_taxe
-- → supprime l'UPDATE post-INSERT (économie d'un second scan de table)
-- -------------------------------------------------------------------------
INSERT INTO donnees_imposition_tfu (
annee,
code_departement,
nom_departement,
code_commune,
nom_commune,
code_arrondissement,
nom_arrondissement,
code_quartier_village,
nom_quartier_village,
q,
ilot,
parcelle,
nup,
titre_foncier,
num_batiment,
ifu,
npi,
tel_prop,
email_prop,
nom_prop,
prenom_prop,
raison_sociale,
adresse_prop,
tel_sc,
nom_sc,
prenom_sc,
longitude,
latitude,
batie,
exonere,
batiment_exonere,
standing_bat,
categorie_bat,
nombre_piscine,
date_enquete,
structure_id,
zone_rfu_id,
nature_impot,
superficie_parc,
superficie_au_sol_bat,
valeur_batiment,
valeur_locative_adm_metre_carre,
montant_loyer_annuel,
tfu_metre_carre,
tfu_minimum,
impositions_tfu_id,
deleted,
created_at,
created_by,
"source",
updated_at,
updated_by,
categorie_usage,
superficie_au_sol_taux_prop_parc, -- 70 % superficie parcelle
valeur_locative_adm_taux_prop_parc,
tfu_calcule_taux_prop_parc, -- TFU à 70 %
valeur_locative_adm_sup_reel,
valeur_locative_adm, -- valeur locative administrative finale
tfu_superficie_au_sol_reel,
tfu_piscine,
montant_taxe, -- TFU finale
taux_tfu,
parcelle_id,
batiment_id,
unite_logement_id
)
SELECT
v_annee,
d.code,
d.nom,
c.code,
c.nom,
a.code,
a.nom,
q.code,
q.nom,
p.q,
p.i,
p.p,
p.nup,
ep.numero_titre_foncier,
b.nub,
pers.ifu,
pers.npi,
pers.tel1,
pers.email,
pers.nom,
pers.prenom,
pers.raison_sociale,
pers.adresse,
ep.representant_tel,
ep.representant_nom,
ep.representant_prenom,
p.longitude,
p.latitude,
TRUE,
-- exonere parcelle
(v_today BETWEEN ep.date_debut_exemption
AND COALESCE(ep.date_fin_exemption, v_today)),
-- exonere batiment
(v_today BETWEEN eb.date_debut_excemption
AND COALESCE(eb.date_fin_excemption, v_today)),
cb.standing,
cb.nom,
eb.nombre_piscine,
eb.date_enquete,
st.id,
ep.zone_rfu_id,
'TFU',
p.superficie,
eb.superficie_au_sol,
-- valeur_batiment : première valeur non nulle non zéro
COALESCE(
NULLIF(eb.valeur_batiment_reel, 0),
NULLIF(eb.valeur_batiment_calcule, 0),
NULLIF(eb.valeur_batiment_estime, 0),
0
),
brb.valeur_locative,
-- montant_loyer_annuel
COALESCE(
NULLIF(eb.montant_locatif_annuel_declare, 0),
NULLIF(eb.montant_locatif_annuel_calcule, 0),
NULLIF(eb.montant_locatif_annuel_estime, 0),
0
),
brb.tfu_metre_carre,
brb.tfu_minimum,
p_impositions_tfu_id,
FALSE,
v_today,
p_user_id,
'FISCAD',
v_today,
p_user_id,
eb.categorie_usage,
-- superficie_au_sol_taux_prop_parc (70 % parcelle)
p.superficie * v_taux_defaut_sup_sol / 100.0,
-- valeur_locative_adm_taux_prop_parc
CASE WHEN eb.categorie_usage = 'HABITATION'
THEN (p.superficie * v_taux_defaut_sup_sol / 100.0) * brb.valeur_locative
ELSE 0
END,
-- tfu_calcule_taux_prop_parc
CASE WHEN eb.categorie_usage = 'HABITATION'
THEN (p.superficie * v_taux_defaut_sup_sol / 100.0) * brb.valeur_locative * v_taux_tfu_ratio
ELSE 0
END,
-- valeur_locative_adm_sup_reel
CASE WHEN eb.categorie_usage = 'HABITATION'
THEN eb.superficie_au_sol * brb.valeur_locative
ELSE 0
END,
-- ---------------------------------------------------------------
-- 🔧 CORRECTION : valeur_locative_adm avec tests explicites
-- ---------------------------------------------------------------
CASE
WHEN eb.categorie_usage = 'HABITATION'
AND eb.superficie_au_sol <> 0
THEN eb.superficie_au_sol * brb.valeur_locative
WHEN eb.categorie_usage = 'HABITATION'
AND eb.superficie_au_sol = 0
THEN (p.superficie * v_taux_defaut_sup_sol / 100.0) * brb.valeur_locative
-- ✅ Test explicite : valeur_batiment <> 0
WHEN eb.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND COALESCE(NULLIF(eb.valeur_batiment_reel, 0),
NULLIF(eb.valeur_batiment_calcule, 0),
NULLIF(eb.valeur_batiment_estime, 0), 0) <> 0
THEN COALESCE(NULLIF(eb.valeur_batiment_reel, 0),
NULLIF(eb.valeur_batiment_calcule, 0),
NULLIF(eb.valeur_batiment_estime, 0), 0)
* v_taux_vlp_ratio
-- ✅ Test explicite : valeur_batiment = 0
WHEN eb.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND COALESCE(NULLIF(eb.valeur_batiment_reel, 0),
NULLIF(eb.valeur_batiment_calcule, 0),
NULLIF(eb.valeur_batiment_estime, 0), 0) = 0
THEN COALESCE(NULLIF(eb.montant_locatif_annuel_declare, 0),
NULLIF(eb.montant_locatif_annuel_calcule, 0),
NULLIF(eb.montant_locatif_annuel_estime, 0), 0)
ELSE 0
END,
-- tfu_superficie_au_sol_reel
CASE WHEN eb.categorie_usage = 'HABITATION'
THEN eb.superficie_au_sol * brb.valeur_locative * v_taux_tfu_ratio
ELSE 0
END,
-- tfu_piscine
eb.nombre_piscine * v_tfu_piscine_unitaire,
-- ---------------------------------------------------------------
-- montant_taxe ← calculé directement (plus d'UPDATE)
-- Utilise des CTE inline via expression pour éviter la redondance
-- ---------------------------------------------------------------
(
-- On matérialise valeur_batiment et valeur_locative une seule fois
WITH calc AS (
SELECT
COALESCE(NULLIF(eb.valeur_batiment_reel, 0),
NULLIF(eb.valeur_batiment_calcule, 0),
NULLIF(eb.valeur_batiment_estime, 0), 0) AS vb,
COALESCE(NULLIF(eb.montant_locatif_annuel_declare, 0),
NULLIF(eb.montant_locatif_annuel_calcule, 0),
NULLIF(eb.montant_locatif_annuel_estime, 0), 0) AS loyer,
eb.superficie_au_sol * brb.valeur_locative AS vla_reel,
(p.superficie * v_taux_defaut_sup_sol / 100.0)
* brb.valeur_locative AS vla_70
)
SELECT
CASE
WHEN eb.categorie_usage = 'HABITATION'
AND eb.superficie_au_sol <> 0
THEN GREATEST(brb.tfu_minimum,
calc.vla_reel * v_taux_tfu_ratio
+ eb.nombre_piscine * v_tfu_piscine_unitaire)
WHEN eb.categorie_usage = 'HABITATION'
AND eb.superficie_au_sol = 0
THEN GREATEST(brb.tfu_minimum,
calc.vla_70 * v_taux_tfu_ratio
+ eb.nombre_piscine * v_tfu_piscine_unitaire)
WHEN eb.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND calc.vb <> 0
THEN GREATEST(brb.tfu_minimum,
calc.vb * v_taux_vlp_ratio * v_taux_tfu_ratio)
WHEN eb.categorie_usage IN ('PROFESSIONNELLE', 'MIXTE')
AND calc.vb = 0
THEN GREATEST(brb.tfu_minimum,
calc.loyer * v_taux_tfu_ratio)
ELSE brb.tfu_minimum
END
FROM calc
),
v_taux_tfu,
p.id,
b.id,
NULL
FROM parcelle p
-- Dernière enquête parcelle
LEFT JOIN LATERAL (
SELECT
parcelle_id,
superficie,
personne_id,
numero_titre_foncier,
date_enquete,
representant_tel,
representant_nom,
representant_prenom,
representant_npi,
date_debut_exemption,
date_fin_exemption,
zone_rfu_id
FROM enquete
WHERE parcelle_id = p.id
ORDER BY date_enquete DESC, id DESC
LIMIT 1
) ep ON TRUE
LEFT JOIN personne pers ON pers.id = ep.personne_id
JOIN quartier q ON q.id = p.quartier_id
JOIN arrondissement a ON a.id = q.arrondissement_id
JOIN commune c ON c.id = a.commune_id
JOIN departement d ON d.id = c.departement_id
-- Rattachement structure via secteur (DISTINCT ON → LATERAL plus lisible)
JOIN LATERAL (
SELECT secteur_id
FROM secteur_decoupage
WHERE quartier_id = q.id
ORDER BY quartier_id
LIMIT 1
) sd ON TRUE
JOIN secteur sect ON sect.id = sd.secteur_id
JOIN section ses ON ses.id = sect.section_id
JOIN "structure" st ON st.id = ses.structure_id
-- Bâtiments sans unités logement (anti-join via LEFT JOIN … IS NULL)
JOIN batiment b ON b.parcelle_id = p.id
LEFT JOIN unite_logement ul_filter ON ul_filter.batiment_id = b.id
-- Dernière enquête bâtiment
JOIN LATERAL (
SELECT
eb2.batiment_id,
eb2.superficie_au_sol,
eb2.nombre_piscine,
eb2.categorie_batiment_id,
eb2.date_enquete,
eb2.montant_locatif_annuel_declare,
eb2.montant_locatif_annuel_calcule,
eb2.montant_locatif_annuel_estime,
eb2.date_debut_excemption,
eb2.date_fin_excemption,
eb2.valeur_batiment_reel,
eb2.valeur_batiment_calcule,
eb2.valeur_batiment_estime,
u.categorie_usage
FROM enquete_batiment eb2
JOIN usage u ON u.id = eb2.usage_id
WHERE eb2.batiment_id = b.id
ORDER BY eb2.date_enquete DESC, eb2.id DESC
LIMIT 1
) eb ON TRUE
JOIN categorie_batiment cb ON cb.id = eb.categorie_batiment_id
-- Barème RFU bâti (inchangé)
JOIN LATERAL (
SELECT *
FROM barem_rfu_bati br
WHERE br.categorie_batiment_id = cb.id
AND br.arrondissement_id = a.id
AND (br.quartier_id = q.id OR br.quartier_id IS NULL)
ORDER BY br.quartier_id DESC NULLS LAST
LIMIT 1
) brb ON TRUE
WHERE p.batie = TRUE
AND ul_filter.batiment_id IS NULL -- anti-join : pas d'unité logement
AND st.id = v_structure_id
ON CONFLICT DO NOTHING;
GET DIAGNOSTICS v_rows_inserted = ROW_COUNT;
RETURN v_rows_inserted;
END;
$$; $$;
select * from donnees_imposition_tfu
where batie =true;

View File

@@ -708,14 +708,18 @@ SELECT new io.gmss.fiscad.paylaods.request.crudweb.DonneesImpositionPaylaodWeb(
) )
FROM DonneesImpositionTfu d FROM DonneesImpositionTfu d
JOIN d.impositionsTfu itfu JOIN d.impositionsTfu itfu
JOIN d.parcelleImposee parc
JOIN parc.quartier quart
LEFT join d.structure s LEFT join d.structure s
LEFT join d.zoneRfu z LEFT join d.zoneRfu z
WHERE itfu.exercice.id = :exerciceId WHERE itfu.exercice.id = :exerciceId
and s.id= :structureId and s.id= :structureId
and quart.id= :quartierId
order by d.nomProp,d.nomProp asc order by d.nomProp,d.nomProp asc
""") """)
List<DonneesImpositionPaylaodWeb> findAllByExericeIdStructureId( List<DonneesImpositionPaylaodWeb> findAllByExericeIdStructureId(
Long exerciceId, Long exerciceId,
Long structureId Long structureId,
Long quartierId
); );
} }